diff --git a/0001-asm-Stabilize-loongarch64.patch b/0001-asm-Stabilize-loongarch64.patch new file mode 100644 index 0000000000000000000000000000000000000000..f5200e782fbd3b0bc6192980467868e7d68ee01f --- /dev/null +++ b/0001-asm-Stabilize-loongarch64.patch @@ -0,0 +1,95 @@ +From f123d3b7a6f26214a19a437fda57549ab54ff7f1 Mon Sep 17 00:00:00 2001 +From: WANG Rui +Date: Fri, 5 May 2023 14:20:45 +0800 +Subject: [PATCH] asm: Stabilize loongarch64 + +--- + compiler/rustc_ast_lowering/src/asm.rs | 1 + + .../language-features/asm-experimental-arch.md | 17 +---------------- + 2 files changed, 2 insertions(+), 16 deletions(-) + +diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs +index 941d3179587..d350498bc96 100644 +--- a/compiler/rustc_ast_lowering/src/asm.rs ++++ b/compiler/rustc_ast_lowering/src/asm.rs +@@ -44,6 +44,7 @@ pub(crate) fn lower_inline_asm( + | asm::InlineAsmArch::AArch64 + | asm::InlineAsmArch::RiscV32 + | asm::InlineAsmArch::RiscV64 ++ | asm::InlineAsmArch::LoongArch64 + ); + if !is_stable && !self.tcx.features().asm_experimental_arch { + feature_err( +diff --git a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md +index 532cb9eea11..c634dc50d6d 100644 +--- a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md ++++ b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md +@@ -17,7 +17,6 @@ This feature tracks `asm!` and `global_asm!` support for the following architect + - AVR + - MSP430 + - M68k +-- LoongArch + - s390x + + ## Register classes +@@ -47,8 +46,6 @@ This feature tracks `asm!` and `global_asm!` support for the following architect + | M68k | `reg` | `d[0-7]`, `a[0-7]` | `r` | + | M68k | `reg_data` | `d[0-7]` | `d` | + | M68k | `reg_addr` | `a[0-3]` | `a` | +-| LoongArch | `reg` | `$r1`, `$r[4-20]`, `$r[23,30]` | `r` | +-| LoongArch | `freg` | `$f[0-31]` | `f` | + | s390x | `reg` | `r[0-10]`, `r[12-14]` | `r` | + | s390x | `freg` | `f[0-15]` | `f` | + +@@ -82,8 +79,6 @@ This feature tracks `asm!` and `global_asm!` support for the following architect + | MSP430 | `reg` | None | `i8`, `i16` | + | M68k | `reg`, `reg_addr` | None | `i16`, `i32` | + | M68k | `reg_data` | None | `i8`, `i16`, `i32` | +-| LoongArch64 | `reg` | None | `i8`, `i16`, `i32`, `i64`, `f32`, `f64` | +-| LoongArch64 | `freg` | None | `f32`, `f64` | + | s390x | `reg` | None | `i8`, `i16`, `i32`, `i64` | + | s390x | `freg` | None | `f32`, `f64` | + +@@ -107,10 +102,6 @@ This feature tracks `asm!` and `global_asm!` support for the following architect + | M68k | `a5` | `bp` | + | M68k | `a6` | `fp` | + | M68k | `a7` | `sp`, `usp`, `ssp`, `isp` | +-| LoongArch | `$r0` | `zero` | +-| LoongArch | `$r2` | `tp` | +-| LoongArch | `$r3` | `sp` | +-| LoongArch | `$r22` | `fp` | + + > **Notes**: + > - TI does not mandate a frame pointer for MSP430, but toolchains are allowed +@@ -121,7 +112,7 @@ This feature tracks `asm!` and `global_asm!` support for the following architect + | Architecture | Unsupported register | Reason | + | ------------ | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | + | All | `sp`, `r15` (s390x) | The stack pointer must be restored to its original value at the end of an asm code block. | +-| All | `fr` (Hexagon), `$fp` (MIPS), `Y` (AVR), `r4` (MSP430), `a6` (M68k), `$fp` (LoongArch), `r11` (s390x) | The frame pointer cannot be used as an input or output. | ++| All | `fr` (Hexagon), `$fp` (MIPS), `Y` (AVR), `r4` (MSP430), `a6` (M68k), `r11` (s390x) | The frame pointer cannot be used as an input or output. | + | All | `r19` (Hexagon) | This is used internally by LLVM as a "base pointer" for functions with complex stack frames. | + | MIPS | `$0` or `$zero` | This is a constant zero register which can't be modified. | + | MIPS | `$1` or `$at` | Reserved for assembler. | +@@ -132,10 +123,6 @@ This feature tracks `asm!` and `global_asm!` support for the following architect + | AVR | `r0`, `r1`, `r1r0` | Due to an issue in LLVM, the `r0` and `r1` registers cannot be used as inputs or outputs. If modified, they must be restored to their original values before the end of the block. | + |MSP430 | `r0`, `r2`, `r3` | These are the program counter, status register, and constant generator respectively. Neither the status register nor constant generator can be written to. | + | M68k | `a4`, `a5` | Used internally by LLVM for the base pointer and global base pointer. | +-| LoongArch | `$r0` or `$zero` | This is a constant zero register which can't be modified. | +-| LoongArch | `$r2` or `$tp` | This is reserved for TLS. | +-| LoongArch | `$r21` | This is reserved by the ABI. | +-| LoongArch | `$r31` or `$s8` | This is used internally by LLVM. | + + ## Template modifiers + +@@ -150,8 +137,6 @@ This feature tracks `asm!` and `global_asm!` support for the following architect + | PowerPC | `reg` | None | `0` | None | + | PowerPC | `reg_nonzero` | None | `3` | `b` | + | PowerPC | `freg` | None | `0` | None | +-| LoongArch | `reg` | None | `$r2` | None | +-| LoongArch | `freg` | None | `$f0` | None | + | s390x | `reg` | None | `%r0` | None | + | s390x | `freg` | None | `%f0` | None | + +-- +2.43.0 + diff --git a/0001-vendor-cc-add-loongarch64-support.patch b/0001-vendor-cc-add-loongarch64-support.patch deleted file mode 100644 index 5c230cb04bb48b53cfb6edb8e5d694249f00f462..0000000000000000000000000000000000000000 --- a/0001-vendor-cc-add-loongarch64-support.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 83e9097a192bf123df9b8313e9e8acd91e0c2e5d Mon Sep 17 00:00:00 2001 -From: WANG Rui -Date: Thu, 7 Jul 2022 10:56:12 +0800 -Subject: [PATCH 1/6] vendor: cc: add loongarch64 support - ---- - vendor/cc/.cargo-checksum.json | 2 +- - vendor/cc/src/lib.rs | 1 + - 2 files changed, 2 insertions(+), 1 deletion(-) - -diff --git a/vendor/cc/.cargo-checksum.json b/vendor/cc/.cargo-checksum.json -index a7f8f2fe7..89b178159 100644 ---- a/vendor/cc/.cargo-checksum.json -+++ b/vendor/cc/.cargo-checksum.json -@@ -1 +1 @@ --{"files":{"Cargo.lock":"739aae86d1e7096fc84b9a6273cc49635503a4ee87b3a4b6601f569880866b29","Cargo.toml":"ccfa92dd53511178ef95aa87b2dcbdd45e23f9f8a8454e455d7da8e08feab4b5","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"1fd66e1fe6d618030b9452c667e89d7a31b27331ad831d83b41f9762fd6858d4","src/bin/gcc-shim.rs":"b77907875029494b6288841c3aed2e4939ed40708c7f597fca5c9e2570490ca6","src/com.rs":"bcdaf1c28b71e6ef889c6b08d1ce9d7c0761344a677f523bc4c3cd297957f804","src/lib.rs":"38970d678de0efb4b5e2978265daa8a613a1db35fc42e669621b03fc56d5b138","src/registry.rs":"3cc1b5a50879fa751572878ae1d0afbfc960c11665258492754b2c8bccb0ff5d","src/setup_config.rs":"7014103587d3382eac599cb76f016e2609b8140970861b2237982d1db24af265","src/vs_instances.rs":"2d3f8278a803b0e7052f4eeb1979b29f963dd0143f4458e2cb5f33c4e5f0963b","src/winapi.rs":"ea8b7edbb9ff87957254f465c2334e714c5d6b3b19a8d757c48ea7ca0881c50c","src/windows_registry.rs":"4645453198766c7486fc9b8782b06cfd0f94cbbcb3482413173e73234a447518","tests/cc_env.rs":"e02b3b0824ad039b47e4462c5ef6dbe6c824c28e7953af94a0f28f7b5158042e","tests/cflags.rs":"57f06eb5ce1557e5b4a032d0c4673e18fbe6f8d26c1deb153126e368b96b41b3","tests/cxxflags.rs":"c2c6c6d8a0d7146616fa1caed26876ee7bc9fcfffd525eb4743593cade5f3371","tests/support/mod.rs":"a3c8d116973bb16066bf6ec4de5143183f97de7aad085d85f8118a2eaac3e1e0","tests/test.rs":"65c073e0e2cf4aa0433066102788e9f57442719e6f32f5ad5248aa7132bb4597"},"package":"2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"} -\ No newline at end of file -+{"files":{"Cargo.lock":"739aae86d1e7096fc84b9a6273cc49635503a4ee87b3a4b6601f569880866b29","Cargo.toml":"ccfa92dd53511178ef95aa87b2dcbdd45e23f9f8a8454e455d7da8e08feab4b5","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"1fd66e1fe6d618030b9452c667e89d7a31b27331ad831d83b41f9762fd6858d4","src/bin/gcc-shim.rs":"b77907875029494b6288841c3aed2e4939ed40708c7f597fca5c9e2570490ca6","src/com.rs":"bcdaf1c28b71e6ef889c6b08d1ce9d7c0761344a677f523bc4c3cd297957f804","src/lib.rs":"8313001f13ddc7b8959a81453cc8f1dcf0f95e47a283bb2c6048ba7b143acef8","src/registry.rs":"3cc1b5a50879fa751572878ae1d0afbfc960c11665258492754b2c8bccb0ff5d","src/setup_config.rs":"7014103587d3382eac599cb76f016e2609b8140970861b2237982d1db24af265","src/vs_instances.rs":"2d3f8278a803b0e7052f4eeb1979b29f963dd0143f4458e2cb5f33c4e5f0963b","src/winapi.rs":"ea8b7edbb9ff87957254f465c2334e714c5d6b3b19a8d757c48ea7ca0881c50c","src/windows_registry.rs":"4645453198766c7486fc9b8782b06cfd0f94cbbcb3482413173e73234a447518","tests/cc_env.rs":"e02b3b0824ad039b47e4462c5ef6dbe6c824c28e7953af94a0f28f7b5158042e","tests/cflags.rs":"57f06eb5ce1557e5b4a032d0c4673e18fbe6f8d26c1deb153126e368b96b41b3","tests/cxxflags.rs":"c2c6c6d8a0d7146616fa1caed26876ee7bc9fcfffd525eb4743593cade5f3371","tests/support/mod.rs":"a3c8d116973bb16066bf6ec4de5143183f97de7aad085d85f8118a2eaac3e1e0","tests/test.rs":"65c073e0e2cf4aa0433066102788e9f57442719e6f32f5ad5248aa7132bb4597"},"package":"2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"} -diff --git a/vendor/cc/src/lib.rs b/vendor/cc/src/lib.rs -index e3a2b98b0..30594a895 100644 ---- a/vendor/cc/src/lib.rs -+++ b/vendor/cc/src/lib.rs -@@ -2581,6 +2581,7 @@ impl Build { - ]), // explicit None if not found, so caller knows to fall back - "i686-unknown-linux-musl" => Some("musl"), - "i686-unknown-netbsd" => Some("i486--netbsdelf"), -+ "loongarch64-unknown-linux-gnu" => Some("loongarch64-linux-gnu"), - "mips-unknown-linux-gnu" => Some("mips-linux-gnu"), - "mips-unknown-linux-musl" => Some("mips-linux-musl"), - "mipsel-unknown-linux-gnu" => Some("mipsel-linux-gnu"), --- -2.41.0 - diff --git a/0002-rustc-Convert-to-ABI-v0.patch b/0002-rustc-Convert-to-ABI-v0.patch new file mode 100644 index 0000000000000000000000000000000000000000..2146f39bee762a4bbee5059868207fe2748d2e6b --- /dev/null +++ b/0002-rustc-Convert-to-ABI-v0.patch @@ -0,0 +1,76 @@ +From f7f7d727fd9b758506596c5bfeec05db4c624de7 Mon Sep 17 00:00:00 2001 +From: WANG Rui +Date: Fri, 28 Jul 2023 17:19:20 +0800 +Subject: [PATCH 2/2] rustc: Convert to ABI v0 + +--- + compiler/rustc_codegen_ssa/src/back/metadata.rs | 2 +- + compiler/rustc_llvm/build.rs | 2 +- + compiler/rustc_target/src/abi/call/loongarch.rs | 4 ++-- + .../rustc_target/src/spec/loongarch64_unknown_linux_gnu.rs | 7 +++---- + 4 files changed, 7 insertions(+), 8 deletions(-) + +diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs +index ad27b854d59..fa49bcb0a3f 100644 +--- a/compiler/rustc_codegen_ssa/src/back/metadata.rs ++++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs +@@ -246,7 +246,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option { + // Source: https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html#_e_flags_identifies_abi_type_and_version +- elf::EF_LARCH_OBJABI_V1 | elf::EF_LARCH_ABI_DOUBLE_FLOAT ++ elf::EF_LARCH_ABI_DOUBLE_FLOAT + } + _ => 0, + }; +diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs +index b0783d75d47..bfac0b41946 100644 +--- a/compiler/rustc_llvm/build.rs ++++ b/compiler/rustc_llvm/build.rs +@@ -251,7 +251,7 @@ fn main() { + } else if target.contains("windows-gnu") { + println!("cargo:rustc-link-lib=shell32"); + println!("cargo:rustc-link-lib=uuid"); +- } else if target.contains("netbsd") || target.contains("haiku") || target.contains("darwin") { ++ } else if target.contains("netbsd") || target.contains("haiku") || target.contains("darwin") || target.contains("loongarch") { + println!("cargo:rustc-link-lib=z"); + } + cmd.args(&components); +diff --git a/compiler/rustc_target/src/abi/call/loongarch.rs b/compiler/rustc_target/src/abi/call/loongarch.rs +index 247256f076b..31933a13242 100644 +--- a/compiler/rustc_target/src/abi/call/loongarch.rs ++++ b/compiler/rustc_target/src/abi/call/loongarch.rs +@@ -313,8 +313,8 @@ pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) + { + let xlen = cx.data_layout().pointer_size.bits(); + let flen = match &cx.target_spec().llvm_abiname[..] { +- "ilp32f" | "lp64f" => 32, +- "ilp32d" | "lp64d" => 64, ++ "lp64" => 64, ++ "lp32" | "lpx32" => 32, + _ => 0, + }; + +diff --git a/compiler/rustc_target/src/spec/loongarch64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/loongarch64_unknown_linux_gnu.rs +index db8b9c70e67..81f29b04f06 100644 +--- a/compiler/rustc_target/src/spec/loongarch64_unknown_linux_gnu.rs ++++ b/compiler/rustc_target/src/spec/loongarch64_unknown_linux_gnu.rs +@@ -4,12 +4,11 @@ pub fn target() -> Target { + Target { + llvm_target: "loongarch64-unknown-linux-gnu".into(), + pointer_width: 64, +- data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".into(), ++ data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".into(), + arch: "loongarch64".into(), + options: TargetOptions { +- cpu: "generic".into(), +- features: "+f,+d".into(), +- llvm_abiname: "lp64d".into(), ++ cpu: "la464".into(), ++ llvm_abiname: "lp64".into(), + max_atomic_width: Some(64), + ..super::linux_gnu_base::opts() + }, +-- +2.43.0 + diff --git a/0002-vendor-libc-update-loongarch64-support.patch b/0002-vendor-libc-update-loongarch64-support.patch deleted file mode 100644 index 90e5c153fb9868c060642fbce2307ad390a14080..0000000000000000000000000000000000000000 --- a/0002-vendor-libc-update-loongarch64-support.patch +++ /dev/null @@ -1,221 +0,0 @@ -From fa9cbadfe8bca161db1c2866dbb22219b4f7e48c Mon Sep 17 00:00:00 2001 -From: WANG Rui -Date: Sun, 25 Jun 2023 16:15:14 +0800 -Subject: [PATCH 2/6] vendor: libc: update loongarch64 support - ---- - vendor/libc-0.2.126/.cargo-checksum.json | 2 +- - .../linux/gnu/b64/loongarch64/align.rs | 17 +++++++++++++++++ - .../linux_like/linux/gnu/b64/loongarch64/mod.rs | 16 ++++++++++++++++ - vendor/libc-0.2.127/.cargo-checksum.json | 2 +- - .../linux/gnu/b64/loongarch64/align.rs | 17 +++++++++++++++++ - .../linux_like/linux/gnu/b64/loongarch64/mod.rs | 16 ++++++++++++++++ - vendor/libc/.cargo-checksum.json | 2 +- - .../linux/gnu/b64/loongarch64/align.rs | 17 +++++++++++++++++ - .../linux_like/linux/gnu/b64/loongarch64/mod.rs | 16 ++++++++++++++++ - 9 files changed, 102 insertions(+), 3 deletions(-) - -diff --git a/vendor/libc-0.2.126/.cargo-checksum.json b/vendor/libc-0.2.126/.cargo-checksum.json -index 26956a434..2db39a0c3 100644 ---- a/vendor/libc-0.2.126/.cargo-checksum.json -+++ b/vendor/libc-0.2.126/.cargo-checksum.json -@@ -1 +1 @@ --{"files":{"CONTRIBUTING.md":"752eea5a703d11b485c6b5f195f51bd2c79aa5159b619ce09555c779e1fb586b","Cargo.toml":"6a0abcfcbc1d9fb00a356343043a161f5b84b3f780cb0f02df4627d022b14b7f","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"a8d47ff51ca256f56a8932dba07660672dbfe3004257ca8de708aac1415937a1","README.md":"8228847944f1332882fbb00275b6f30e4a8aad08a13569c25d52cac012cc2a47","build.rs":"41f9743021d9e5ed74ede55c94057cf6867a322a13b25a5d524b966656a08e38","rustfmt.toml":"eaa2ea84fc1ba0359b77680804903e07bb38d257ab11986b95b158e460f787b2","src/fixed_width_ints.rs":"7f986e5f5e68d25ef04d386fd2f640e8be8f15427a8d4a458ea01d26b8dca0ca","src/fuchsia/aarch64.rs":"378776a9e40766154a54c94c2a7b4675b5c302a38e6e42da99e67bfbaee60e56","src/fuchsia/align.rs":"ae1cf8f011a99737eabeb14ffff768e60f13b13363d7646744dbb0f443dab3d6","src/fuchsia/mod.rs":"bc8c46531bd1a2429f36aaf2bc137b50e42505b798de83f34eecfa94ad89179b","src/fuchsia/no_align.rs":"303f3f1b255e0088b5715094353cf00476131d8e94e6aebb3f469557771c8b8a","src/fuchsia/x86_64.rs":"93a3632b5cf67d2a6bcb7dc0a558605252d5fe689e0f38d8aa2ec5852255ac87","src/hermit/aarch64.rs":"86048676e335944c37a63d0083d0f368ae10ceccefeed9debb3bbe08777fc682","src/hermit/mod.rs":"d3bfce41e4463d4be8020a2d063c9bfa8b665f45f1cc6cbf3163f5d01e7cb21f","src/hermit/x86_64.rs":"ab832b7524e5fb15c49ff7431165ab1a37dc4667ae0b58e8306f4c539bfa110c","src/lib.rs":"3f13d5f9b29d8969dde507661f1637524e21fe3bd34957fc778868f2f3713c46","src/macros.rs":"d7437c2573c4915768ff96b34710a61ee9f63622b23526cddeaeaf6bfb4751a2","src/psp.rs":"dd31aabd46171d474ec5828372e28588935120e7355c90c105360d8fa9264c1c","src/sgx.rs":"16a95cdefc81c5ee00d8353a60db363c4cc3e0f75abcd5d0144723f2a306ed1b","src/solid/aarch64.rs":"a726e47f324adf73a4a0b67a2c183408d0cad105ae66acf36db37a42ab7f8707","src/solid/arm.rs":"e39a4f74ebbef3b97b8c95758ad741123d84ed3eb48d9cf4f1f4872097fc27fe","src/solid/mod.rs":"5f4151dca5132e4b4e4c23ab9737e12856dddbdc0ca3f7dbc004328ef3c8acde","src/switch.rs":"9da3dd39b3de45a7928789926e8572d00e1e11a39e6f7289a1349aadce90edba","src/unix/align.rs":"2cdc7c826ef7ae61f5171c5ae8c445a743d86f1a7f2d9d7e4ceeec56d6874f65","src/unix/bsd/apple/b32/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b32/mod.rs":"2546ad3eb6aecb95f916648bc63264117c92b4b4859532b34cb011e4c75a5a72","src/unix/bsd/apple/b64/aarch64/align.rs":"2eaf0f561a32bdcbf4e0477c8895d5e7bcb5cdebd5fef7b4df2ca8e38e144d94","src/unix/bsd/apple/b64/aarch64/mod.rs":"a3f0dfff62d0f7f4f1b5f9a4e2b662acf233a46badbc5419d3cc2d735629a710","src/unix/bsd/apple/b64/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b64/mod.rs":"f5e278a1af7fb358891d1c9be4eb7e815aaca0c5cb738d0c3604ba2208a856f7","src/unix/bsd/apple/b64/x86_64/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b64/x86_64/mod.rs":"8c87c5855038aae5d433c8f5eb3b29b0a175879a0245342b3bfd83bdf4cfd936","src/unix/bsd/apple/mod.rs":"d7155927fbd1af6dd984a4c6c1a735a5932af828c96818209487eb6ae72d7d7e","src/unix/bsd/freebsdlike/dragonfly/errno.rs":"8295b8bb0dfd38d2cdb4d9192cdeeb534cc6c3b208170e64615fa3e0edb3e578","src/unix/bsd/freebsdlike/dragonfly/mod.rs":"379302e12d30807a1f973c4e2dd2205179d95343ee6fae05f33c9ed45a342799","src/unix/bsd/freebsdlike/freebsd/aarch64.rs":"2a215bd6136b8617aacedf9be738ccee94da9d29b418e9a78101d6291c182352","src/unix/bsd/freebsdlike/freebsd/arm.rs":"59d6a670eea562fb87686e243e0a84603d29a2028a3d4b3f99ccc01bd04d2f47","src/unix/bsd/freebsdlike/freebsd/freebsd11/b64.rs":"9808d152c1196aa647f1b0f0cf84dac8c930da7d7f897a44975545e3d9d17681","src/unix/bsd/freebsdlike/freebsd/freebsd11/mod.rs":"a6eee615e6ca5a6e04b526bb6b22d13b9356e87e51825cda33476c37a46cb0ef","src/unix/bsd/freebsdlike/freebsd/freebsd12/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd12/mod.rs":"755dafaf3f0945e798c34ea94c48e8552804ce60e2a15a4f0649f9d1aceaf422","src/unix/bsd/freebsdlike/freebsd/freebsd12/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/freebsd13/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd13/mod.rs":"cc65a73b0fa95a77044a4b3ee76d6eceb9773b55aea7d73bdf070e6f66e9ea38","src/unix/bsd/freebsdlike/freebsd/freebsd13/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/freebsd14/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd14/mod.rs":"0ed92eb93e78299cd7de0ae9daebb04a53b3c2d5e6a078e1fcd977f2a86bffc3","src/unix/bsd/freebsdlike/freebsd/freebsd14/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/mod.rs":"467b66843ab8c1a54b01ae9e90aaf0295b32f54decbdfb64caca84523b488925","src/unix/bsd/freebsdlike/freebsd/powerpc.rs":"9ca3f82f88974e6db5569f2d76a5a3749b248a31747a6c0da5820492bdfeca42","src/unix/bsd/freebsdlike/freebsd/powerpc64.rs":"2dae3ecc87eac3b11657aa98915def55fc4b5c0de11fe26aae23329a54628a9a","src/unix/bsd/freebsdlike/freebsd/riscv64.rs":"8f591bd273464d684c4f64365f8ed56a8138175daa70d96008541393057a0dae","src/unix/bsd/freebsdlike/freebsd/x86.rs":"c5005e3249eb7c93cfbac72a9e9272320d80ce7983da990ceb05a447f59a02c5","src/unix/bsd/freebsdlike/freebsd/x86_64/align.rs":"0e1f69a88fca1c32874b1daf5db3d446fefbe518dca497f096cc9168c39dde70","src/unix/bsd/freebsdlike/freebsd/x86_64/mod.rs":"51e4dd0c8ae247bb652feda5adad9333ea3bb30c750c3a3935e0b0e47d7803eb","src/unix/bsd/freebsdlike/mod.rs":"a7345cc3fb7372572efe06848feb2cc246dfc2c2a0cc9ccf434f4c55041a59fa","src/unix/bsd/mod.rs":"7720ec82c9334f988ec4b271784768a017c3dc2e6dfae4d02418eef753388aa7","src/unix/bsd/netbsdlike/mod.rs":"594a0f9e23c4d7702ba38afdba5a0e866be25d692ec0afd66e04d939aa6b3f04","src/unix/bsd/netbsdlike/netbsd/aarch64.rs":"65dcb58d11e8d8028401a9d07ca3eb4cb4f053e04249cc877353449d84ccc4cb","src/unix/bsd/netbsdlike/netbsd/arm.rs":"58cdbb70b0d6f536551f0f3bb3725d2d75c4690db12c26c034e7d6ec4a924452","src/unix/bsd/netbsdlike/netbsd/mod.rs":"cb1560bf8ffcc7b2726a27b433efac90e726292960626f3064bd2c6b7f861a55","src/unix/bsd/netbsdlike/netbsd/powerpc.rs":"ee7ff5d89d0ed22f531237b5059aa669df93a3b5c489fa641465ace8d405bf41","src/unix/bsd/netbsdlike/netbsd/sparc64.rs":"9489f4b3e4566f43bb12dfb92238960613dac7f6a45cc13068a8d152b902d7d9","src/unix/bsd/netbsdlike/netbsd/x86.rs":"20692320e36bfe028d1a34d16fe12ca77aa909cb02bda167376f98f1a09aefe7","src/unix/bsd/netbsdlike/netbsd/x86_64.rs":"1afe5ef46b14397cdd68664b5b232e4f5b035b6db1d4cf411c899d51ebca9f30","src/unix/bsd/netbsdlike/openbsd/aarch64.rs":"dd91931d373b7ecaf6e2de25adadee10d16fa9b12c2cbacdff3eb291e1ba36af","src/unix/bsd/netbsdlike/openbsd/arm.rs":"01580d261bc6447bb327a0d982181b7bdabfa066cee65a30373d3ced729ad307","src/unix/bsd/netbsdlike/openbsd/mips64.rs":"8532a189ae10c7d668d9d4065da8b05d124e09bd39442c9f74a7f231c43eca48","src/unix/bsd/netbsdlike/openbsd/mod.rs":"816a8ef47df60a752a91967627eeccb9ca776dc718ecc53ae902d8edaee0bce9","src/unix/bsd/netbsdlike/openbsd/powerpc.rs":"01580d261bc6447bb327a0d982181b7bdabfa066cee65a30373d3ced729ad307","src/unix/bsd/netbsdlike/openbsd/powerpc64.rs":"1dd5449dd1fd3d51e30ffdeeaece91d0aaf05c710e0ac699fecc5461cfa2c28e","src/unix/bsd/netbsdlike/openbsd/riscv64.rs":"1dd5449dd1fd3d51e30ffdeeaece91d0aaf05c710e0ac699fecc5461cfa2c28e","src/unix/bsd/netbsdlike/openbsd/sparc64.rs":"d04fd287afbaa2c5df9d48c94e8374a532a3ba491b424ddf018270c7312f4085","src/unix/bsd/netbsdlike/openbsd/x86.rs":"6f7f5c4fde2a2259eb547890cbd86570cea04ef85347d7569e94e679448bec87","src/unix/bsd/netbsdlike/openbsd/x86_64.rs":"d31db31630289c85af3339dbe357998a21ca584cbae31607448fe2cf7675a4e1","src/unix/haiku/b32.rs":"a2efdbf7158a6da341e1db9176b0ab193ba88b449616239ed95dced11f54d87b","src/unix/haiku/b64.rs":"ff8115367d3d7d354f792d6176dfaaa26353f57056197b563bf4681f91ff7985","src/unix/haiku/mod.rs":"d5833ff9b94daa81d2470df544453212af17530d78c5a7fb912eac915d00f329","src/unix/haiku/native.rs":"dbfcbf4954a79d1df2ff58e0590bbcb8c57dfc7a32392aa73ee4726b66bd6cc8","src/unix/haiku/x86_64.rs":"3ec3aeeb7ed208b8916f3e32d42bfd085ff5e16936a1a35d9a52789f043b7237","src/unix/hermit/aarch64.rs":"86048676e335944c37a63d0083d0f368ae10ceccefeed9debb3bbe08777fc682","src/unix/hermit/mod.rs":"859814f5df89e28fd4b345db399d181e11e7ed413841b6ff703a1fcbdbf013ae","src/unix/hermit/x86_64.rs":"ab832b7524e5fb15c49ff7431165ab1a37dc4667ae0b58e8306f4c539bfa110c","src/unix/linux_like/android/b32/arm.rs":"433c1530f602cc5ed26610c58055dde0c4ceea5e00150063b24ddc60768332a4","src/unix/linux_like/android/b32/mod.rs":"7c173e0375119bf06a3081652faede95e5bcd6858e7576b7533d037978737c8f","src/unix/linux_like/android/b32/x86/align.rs":"812914e4241df82e32b12375ca3374615dc3a4bdd4cf31f0423c5815320c0dab","src/unix/linux_like/android/b32/x86/mod.rs":"8388bd3a0fcb5636bf965eee6dc95ae6860b85a2b555b387c868aa4d4e01ec89","src/unix/linux_like/android/b64/aarch64/align.rs":"2179c3b1608fa4bf68840482bfc2b2fa3ee2faf6fcae3770f9e505cddca35c7b","src/unix/linux_like/android/b64/aarch64/int128.rs":"1735f6f5c56770d20dd426442f09724d9b2052b46a7cd82f23f3288a4a7276de","src/unix/linux_like/android/b64/aarch64/mod.rs":"ef230d49fd0d182adf2dae6f8e10babf18d72259d65980bf1c4c2dc8a4f84501","src/unix/linux_like/android/b64/mod.rs":"d7bbbadafdb2cb2ff8e9cde3d89a03b9facaabb6b2d45705225d3ece1c5cce37","src/unix/linux_like/android/b64/x86_64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/android/b64/x86_64/mod.rs":"6454948ea98be86243229f99d67cdc7ca460e16b2a6445663ff4b5b6907c358d","src/unix/linux_like/android/mod.rs":"1247397a7e1b6269e0d2d6df88c6396bc18eb477e3ff293ff57d66a6b1380d94","src/unix/linux_like/emscripten/align.rs":"86c95cbed7a7161b1f23ee06843e7b0e2340ad92b2cb86fe2a8ef3e0e8c36216","src/unix/linux_like/emscripten/mod.rs":"b71d37106750f57bc2dae4e9bcb473ff098ef48235827e41a1687a39825f0aa4","src/unix/linux_like/emscripten/no_align.rs":"0128e4aa721a9902754828b61b5ec7d8a86619983ed1e0544a85d35b1051fad6","src/unix/linux_like/linux/align.rs":"d6c259942c8e843373accd180fc8f4f45f03544dfd21b93a8d02641ead3ef63e","src/unix/linux_like/linux/arch/generic/mod.rs":"e20013ed91edcfb7f84f3f9f5a9ef827fd5c406e24b65989d8438da332236ef6","src/unix/linux_like/linux/arch/mips/mod.rs":"2d166054a586bb4bf6e4a4ba35f7574907b217225eff8f1a43adc4277e142460","src/unix/linux_like/linux/arch/mod.rs":"466a29622e47c6c7f1500682b2eb17f5566dd81b322cd6348f0fdd355cec593a","src/unix/linux_like/linux/arch/powerpc/mod.rs":"3f6da7b0fa7b394c7d4eea2bb3caa7a7729ab0d6c1491fef02206a912c41b815","src/unix/linux_like/linux/arch/sparc/mod.rs":"91593ec0440f1dd8f8e612028f432c44c14089286e2aca50e10511ab942db8c3","src/unix/linux_like/linux/gnu/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/gnu/b32/arm/align.rs":"6ec0eb3ee93f7ae99fd714b4deabfb5e97fbcefd8c26f5a45fb8e7150899cdeb","src/unix/linux_like/linux/gnu/b32/arm/mod.rs":"92ea7edc0e24f79dfbf5e3efc2d7509bed230562036e6aa85ef4f2c8088ecc8f","src/unix/linux_like/linux/gnu/b32/m68k/align.rs":"8faa92f77a9232c035418d45331774e64a9a841d99c91791570a203bf2b45bcb","src/unix/linux_like/linux/gnu/b32/m68k/mod.rs":"a2a0a9400dae44086ebf579e0448e0676d4a3214d1ae7d13a024857251e23b6b","src/unix/linux_like/linux/gnu/b32/mips/align.rs":"429fb5e005cb7143602d430098b6ebfb7d360685b194f333dfd587472ae954ee","src/unix/linux_like/linux/gnu/b32/mips/mod.rs":"0d7849eb2435ec1f49b6774872a0518f0129c50f37c9d38b37b1535722777a22","src/unix/linux_like/linux/gnu/b32/mod.rs":"8da281da578cdee972e952b118b903b370320897a7e335342a15e1359864bef2","src/unix/linux_like/linux/gnu/b32/powerpc.rs":"049d6211ba4a9304bd4497c160bc21ae847c24e0528dd9d76263f16192e6aff5","src/unix/linux_like/linux/gnu/b32/riscv32/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/gnu/b32/riscv32/mod.rs":"a4256148cec0bb672c8dfa605866930d9761af9655721de72ae41eeeb8fdbf6d","src/unix/linux_like/linux/gnu/b32/sparc/align.rs":"21adbed27df73e2d1ed934aaf733a643003d7baf2bde9c48ea440895bcca6d41","src/unix/linux_like/linux/gnu/b32/sparc/mod.rs":"525618615aa0cb80c6c90860bf579dfed8db307fffd56b97dc235fb945419434","src/unix/linux_like/linux/gnu/b32/x86/align.rs":"e4bafdc4a519a7922a81b37a62bbfd1177a2f620890eef8f1fbc47162e9eb413","src/unix/linux_like/linux/gnu/b32/x86/mod.rs":"78b4038852986436888c63be9258037cf642124daee9d5fa5cef2bf8e412bf54","src/unix/linux_like/linux/gnu/b64/aarch64/align.rs":"2179c3b1608fa4bf68840482bfc2b2fa3ee2faf6fcae3770f9e505cddca35c7b","src/unix/linux_like/linux/gnu/b64/aarch64/ilp32.rs":"21a21503ef2e095f4371044915d4bfb07a8578011cb5c713cd9f45947b0b5730","src/unix/linux_like/linux/gnu/b64/aarch64/int128.rs":"1735f6f5c56770d20dd426442f09724d9b2052b46a7cd82f23f3288a4a7276de","src/unix/linux_like/linux/gnu/b64/aarch64/lp64.rs":"e78c3cd197f44832338b414d1a9bc0d194f44c74db77bd7bf830c1fff62b2690","src/unix/linux_like/linux/gnu/b64/aarch64/mod.rs":"c4e20b1c63d7a03a6e22aef2046689ef95cc4651011ade7cb94176fcea1dc252","src/unix/linux_like/linux/gnu/b64/loongarch64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs":"387808d5398b24339e7e2bf7591150735011befc5b421fa713d7017c04a7b1da","src/unix/linux_like/linux/gnu/b64/mips64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/linux/gnu/b64/mips64/mod.rs":"17aad16329431d83e1909e3a08022f6e28f4bcba7dec4a967fe1a321a6a43b99","src/unix/linux_like/linux/gnu/b64/mod.rs":"3c6555f30a7a8852757b31a542ea73fb6a16a6e27e838397e819278ad56e57a4","src/unix/linux_like/linux/gnu/b64/powerpc64/align.rs":"e29c4868bbecfa4a6cd8a2ad06193f3bbc78a468cc1dc9df83f002f1268130d9","src/unix/linux_like/linux/gnu/b64/powerpc64/mod.rs":"97e0ecf11ecce793a13fec39654fb513c5479edf7faa7a276fa714b61993d0fc","src/unix/linux_like/linux/gnu/b64/riscv64/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/gnu/b64/riscv64/mod.rs":"b3fe290afe63d2d6e315d0cf1f775464e9c1f2a1906d243c1af74a137a4031cb","src/unix/linux_like/linux/gnu/b64/s390x.rs":"254f00266ecf9644a4b469457cb37c4dd6c055820926c1de0fb9035b6048e75c","src/unix/linux_like/linux/gnu/b64/sparc64/align.rs":"e29c4868bbecfa4a6cd8a2ad06193f3bbc78a468cc1dc9df83f002f1268130d9","src/unix/linux_like/linux/gnu/b64/sparc64/mod.rs":"87dd7f3d5bf3c09f4064ec738e306cc9cc41ad49b4a5df62c5983301c3bbf99a","src/unix/linux_like/linux/gnu/b64/x86_64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs":"1b939aaf3cdf3efc7d3bd53e83e80235530d3ba0c24bb7611d4730d35d457ec1","src/unix/linux_like/linux/gnu/b64/x86_64/not_x32.rs":"b88ef8a1eaa9ed73bf2acb8192afb73af987a92abb94140c6376fc83f2fa5553","src/unix/linux_like/linux/gnu/b64/x86_64/x32.rs":"79305936a60d342efdc10519ba89507d6b48e65f13f33090d3b04dc9655ceed0","src/unix/linux_like/linux/gnu/mod.rs":"84ad4a663b5fa2498179be8dca96fef5f0446ec1619215ac674424ee394e307d","src/unix/linux_like/linux/gnu/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/mod.rs":"cff23db1e0bac8c30052dfed5e89e65bc207471e4bfb3a6fa0a4df62ed9e413e","src/unix/linux_like/linux/musl/b32/arm/align.rs":"3e8ac052c1043764776b54c93ba4260e061df998631737a897d9d47d54f7b80c","src/unix/linux_like/linux/musl/b32/arm/mod.rs":"e5faee8efda8a225ea0b17d4d6f9e893a678e73773fa62c549a8e19c106b9f04","src/unix/linux_like/linux/musl/b32/hexagon.rs":"226a8b64ce9c75abbbee6d2dceb0b44f7b6c750c4102ebd4d015194afee6666e","src/unix/linux_like/linux/musl/b32/mips/align.rs":"429fb5e005cb7143602d430098b6ebfb7d360685b194f333dfd587472ae954ee","src/unix/linux_like/linux/musl/b32/mips/mod.rs":"df8f8b529a6cc6b8a7326639e83303cf1320c6c50d76517c17d42bcf45f6240a","src/unix/linux_like/linux/musl/b32/mod.rs":"7b3d9dfd8605b00bb9b5fa1439abe5ebf60199c7fa033eee555e8d181e93ffa2","src/unix/linux_like/linux/musl/b32/powerpc.rs":"c957d99a4d4371d2411a5769be8cf344516bf9ddc1011f977501a4eb57cb4e82","src/unix/linux_like/linux/musl/b32/riscv32/align.rs":"efd2accf33b87de7c7547903359a5da896edc33cd6c719552c7474b60d4a5d48","src/unix/linux_like/linux/musl/b32/riscv32/mod.rs":"698f77bfcc838f82126c54f7387881fe3e89490117e5a4f333d1b4433823a672","src/unix/linux_like/linux/musl/b32/x86/align.rs":"08e77fbd7435d7dec2ff56932433bece3f02e47ce810f89004a275a86d39cbe1","src/unix/linux_like/linux/musl/b32/x86/mod.rs":"199a91e90b454f9dc32770d5204cc4f6e5b8f144e0e34a1c91829949d6e804b3","src/unix/linux_like/linux/musl/b64/aarch64/align.rs":"798a9229d70ce235394f2dd625f6c4c1e10519a94382dc5b091952b638ae2928","src/unix/linux_like/linux/musl/b64/aarch64/int128.rs":"1735f6f5c56770d20dd426442f09724d9b2052b46a7cd82f23f3288a4a7276de","src/unix/linux_like/linux/musl/b64/aarch64/mod.rs":"9c4878df0fea0e0affd85346e0bc191abdc5e41e74dc9199b5644ec33d29c300","src/unix/linux_like/linux/musl/b64/mips64.rs":"3686fc8cb2e311cda8e6b96f6dfe90b65a366714bd480312b692b1a6ca1241b6","src/unix/linux_like/linux/musl/b64/mod.rs":"8c10627bd582cb272514e7350ae4743a65d489356eae039d2e7e55cd533fbbc8","src/unix/linux_like/linux/musl/b64/powerpc64.rs":"36694cbdcdc33879e00502d55cb95eaa0096d213538993dd39c3da800cdd06d1","src/unix/linux_like/linux/musl/b64/riscv64/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/musl/b64/riscv64/mod.rs":"36621aca8ecf714f8dd42662dc2997833d95b9f129ef8c220503362e21efd695","src/unix/linux_like/linux/musl/b64/s390x.rs":"9b05b1fae6bcb7cb6d909b9973977fde01684175f3e26c27dcb44223cc3933d9","src/unix/linux_like/linux/musl/b64/x86_64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/linux/musl/b64/x86_64/mod.rs":"238789097a26abc8b7cd578ed1a8e6cb8672083054303902781983902cd66854","src/unix/linux_like/linux/musl/mod.rs":"2efe98b8166270be1624888953fa07da06f08313f15bf4c7dc2eba63f5a790a5","src/unix/linux_like/linux/no_align.rs":"da2a8721becaaaa528781f97f5d9aae6a982ae5d4f5f6d2ffc0150bed72319b3","src/unix/linux_like/linux/non_exhaustive.rs":"181a05bf94fdb911db83ce793b993bd6548a4115b306a7ef3c10f745a8fea3e9","src/unix/linux_like/linux/uclibc/align.rs":"9ed16138d8e439bd90930845a65eafa7ebd67366e6bf633936d44014f6e4c959","src/unix/linux_like/linux/uclibc/arm/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/uclibc/arm/mod.rs":"a056bbf718ddd775519058706bdb4909b56e6256985869e3c3132aa8ec5faca0","src/unix/linux_like/linux/uclibc/arm/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/uclibc/mips/mips32/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/uclibc/mips/mips32/mod.rs":"b84def53a49587e87f884c2bc28b21b290463b00b52e1d0309f2ba233a5b4a99","src/unix/linux_like/linux/uclibc/mips/mips32/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/uclibc/mips/mips64/align.rs":"a7bdcb18a37a2d91e64d5fad83ea3edc78f5412adb28f77ab077dbb26dd08b2d","src/unix/linux_like/linux/uclibc/mips/mips64/mod.rs":"256a428290a560163ef7dc7d18b27bd3c6ce9748a0f28d5dc7f82203ee228220","src/unix/linux_like/linux/uclibc/mips/mips64/no_align.rs":"4a18e3875698c85229599225ac3401a2a40da87e77b2ad4ef47c6fcd5a24ed30","src/unix/linux_like/linux/uclibc/mips/mod.rs":"367ec5483ad317e6ccba1ac0888da6cf088a8d32689214cc8d16129aa692260c","src/unix/linux_like/linux/uclibc/mod.rs":"ddd223d4f574b2b92072bbdab091f12d8d89d5e05f41076ddfa6bc6af379698f","src/unix/linux_like/linux/uclibc/no_align.rs":"3f28637046524618adaa1012e26cb7ffe94b9396e6b518cccdc69d59f274d709","src/unix/linux_like/linux/uclibc/x86_64/l4re.rs":"024eba5753e852dbdd212427351affe7e83f9916c1864bce414d7aa2618f192e","src/unix/linux_like/linux/uclibc/x86_64/mod.rs":"bf6985e901041a61e90ccee1296b35a4c62ef90aa528d31989e1d647f072e79a","src/unix/linux_like/linux/uclibc/x86_64/other.rs":"42c3f71e58cabba373f6a55a623f3c31b85049eb64824c09c2b082b3b2d6a0a8","src/unix/linux_like/mod.rs":"dd4f7a1d66d8501b4a2c4e75e6e9305ed69f1002ae99e410596a6c636878595a","src/unix/mod.rs":"d1b4ba41f9b9c106f6ba8c661b5808824b774a7a7caac7d8938bf50979ba5195","src/unix/newlib/aarch64/mod.rs":"bac93836a9a57b2c710f32f852e92a4d11ad6759ab0fb6ad33e71d60e53278af","src/unix/newlib/align.rs":"28aaf87fafbc6b312622719d472d8cf65f9e5467d15339df5f73e66d8502b28a","src/unix/newlib/arm/mod.rs":"cbba6b3e957eceb496806e60de8725a23ff3fa0015983b4b4fa27b233732b526","src/unix/newlib/espidf/mod.rs":"ff9c13e99d84912f5ebe75b7a7ea9c1e9d8f35a268716081e09899c7ea822bc6","src/unix/newlib/generic.rs":"eab066d9f0a0f3eb53cc1073d01496bba0110989e1f6a59838afd19f870cd599","src/unix/newlib/horizon/mod.rs":"7cc5cc120437421db139bfa6a90b18168cd3070bdd0f5be96d40fe4c996f3ca1","src/unix/newlib/mod.rs":"54633d606e4e0413274af0b5beb5e697e6c061b63feaa0704b026554cc9d9c3e","src/unix/newlib/no_align.rs":"e0743b2179495a9514bc3a4d1781e492878c4ec834ee0085d0891dd1712e82fb","src/unix/newlib/powerpc/mod.rs":"0202ffd57caf75b6afa2c9717750ffb96e375ac33df0ae9609a3f831be393b67","src/unix/no_align.rs":"c06e95373b9088266e0b14bba0954eef95f93fb2b01d951855e382d22de78e53","src/unix/redox/mod.rs":"033768cb273daf2c8090d97252c2de9dba6809e6a5d2457f5727d724807695db","src/unix/solarish/compat.rs":"b07a5bfac925eb012003a459ba6bddbd3bfa9c44b3394da2ac5a602e54beae9c","src/unix/solarish/illumos.rs":"29387916ee7dc58f07478746024003215e631cd30953e8fa2a5c415f81839007","src/unix/solarish/mod.rs":"976b07a13e195840b67c166a62318abfa9ffc8d5ebbb0358f199dd213ec98d1b","src/unix/solarish/solaris.rs":"65b005453aefa9b9d4fc860fe77cfec80d8c97a51342b15daf55fc3e808bb384","src/unix/solarish/x86.rs":"e86e806df0caed72765040eaa2f3c883198d1aa91508540adf9b7008c77f522e","src/unix/solarish/x86_64.rs":"9074e813949f3c613afeac39d4118fb942c0b3c476232fc536489357cff5790f","src/unix/solarish/x86_common.rs":"ac869d9c3c95645c22460468391eb1982023c3a8e02b9e06a72e3aef3d5f1eac","src/vxworks/aarch64.rs":"98f0afdc511cd02557e506c21fed6737585490a1dce7a9d4941d08c437762b99","src/vxworks/arm.rs":"acb7968ce99fe3f4abdf39d98f8133d21a4fba435b8ef7084777cb181d788e88","src/vxworks/mod.rs":"aea3da66f2140f2a82dfc9c58f6e6531d2dd9c15ea696e0f95a0d4a2a187b5b6","src/vxworks/powerpc.rs":"acb7968ce99fe3f4abdf39d98f8133d21a4fba435b8ef7084777cb181d788e88","src/vxworks/powerpc64.rs":"98f0afdc511cd02557e506c21fed6737585490a1dce7a9d4941d08c437762b99","src/vxworks/x86.rs":"552f007f38317620b23889cb7c49d1d115841252439060122f52f434fbc6e5ba","src/vxworks/x86_64.rs":"018d92be3ad628a129eff9f2f5dfbc0883d8b8e5f2fa917b900a7f98ed6b514a","src/wasi.rs":"4fae202af0327d768ed9e1b586b75816cce14fe2dc16947d2f3d381f209a54c1","src/windows/gnu/align.rs":"b2c13ec1b9f3b39a75c452c80c951dff9d0215e31d77e883b4502afb31794647","src/windows/gnu/mod.rs":"3c8c7edb7cdf5d0c44af936db2a94869585c69dfabeef30571b4f4e38375767a","src/windows/mod.rs":"e3ad95ba54f76e74c301611fe868d3d94f6b8939b03be672f568b06b10ae71c7","src/windows/msvc/mod.rs":"c068271e00fca6b62bc4bf44bcf142cfc38caeded9b6c4e01d1ceef3ccf986f4","tests/const_fn.rs":"cb75a1f0864f926aebe79118fc34d51a0d1ade2c20a394e7774c7e545f21f1f4"},"package":"349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"} -\ No newline at end of file -+{"files":{"CONTRIBUTING.md":"752eea5a703d11b485c6b5f195f51bd2c79aa5159b619ce09555c779e1fb586b","Cargo.toml":"6a0abcfcbc1d9fb00a356343043a161f5b84b3f780cb0f02df4627d022b14b7f","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"a8d47ff51ca256f56a8932dba07660672dbfe3004257ca8de708aac1415937a1","README.md":"8228847944f1332882fbb00275b6f30e4a8aad08a13569c25d52cac012cc2a47","build.rs":"41f9743021d9e5ed74ede55c94057cf6867a322a13b25a5d524b966656a08e38","rustfmt.toml":"eaa2ea84fc1ba0359b77680804903e07bb38d257ab11986b95b158e460f787b2","src/fixed_width_ints.rs":"7f986e5f5e68d25ef04d386fd2f640e8be8f15427a8d4a458ea01d26b8dca0ca","src/fuchsia/aarch64.rs":"378776a9e40766154a54c94c2a7b4675b5c302a38e6e42da99e67bfbaee60e56","src/fuchsia/align.rs":"ae1cf8f011a99737eabeb14ffff768e60f13b13363d7646744dbb0f443dab3d6","src/fuchsia/mod.rs":"bc8c46531bd1a2429f36aaf2bc137b50e42505b798de83f34eecfa94ad89179b","src/fuchsia/no_align.rs":"303f3f1b255e0088b5715094353cf00476131d8e94e6aebb3f469557771c8b8a","src/fuchsia/x86_64.rs":"93a3632b5cf67d2a6bcb7dc0a558605252d5fe689e0f38d8aa2ec5852255ac87","src/hermit/aarch64.rs":"86048676e335944c37a63d0083d0f368ae10ceccefeed9debb3bbe08777fc682","src/hermit/mod.rs":"d3bfce41e4463d4be8020a2d063c9bfa8b665f45f1cc6cbf3163f5d01e7cb21f","src/hermit/x86_64.rs":"ab832b7524e5fb15c49ff7431165ab1a37dc4667ae0b58e8306f4c539bfa110c","src/lib.rs":"3f13d5f9b29d8969dde507661f1637524e21fe3bd34957fc778868f2f3713c46","src/macros.rs":"d7437c2573c4915768ff96b34710a61ee9f63622b23526cddeaeaf6bfb4751a2","src/psp.rs":"dd31aabd46171d474ec5828372e28588935120e7355c90c105360d8fa9264c1c","src/sgx.rs":"16a95cdefc81c5ee00d8353a60db363c4cc3e0f75abcd5d0144723f2a306ed1b","src/solid/aarch64.rs":"a726e47f324adf73a4a0b67a2c183408d0cad105ae66acf36db37a42ab7f8707","src/solid/arm.rs":"e39a4f74ebbef3b97b8c95758ad741123d84ed3eb48d9cf4f1f4872097fc27fe","src/solid/mod.rs":"5f4151dca5132e4b4e4c23ab9737e12856dddbdc0ca3f7dbc004328ef3c8acde","src/switch.rs":"9da3dd39b3de45a7928789926e8572d00e1e11a39e6f7289a1349aadce90edba","src/unix/align.rs":"2cdc7c826ef7ae61f5171c5ae8c445a743d86f1a7f2d9d7e4ceeec56d6874f65","src/unix/bsd/apple/b32/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b32/mod.rs":"2546ad3eb6aecb95f916648bc63264117c92b4b4859532b34cb011e4c75a5a72","src/unix/bsd/apple/b64/aarch64/align.rs":"2eaf0f561a32bdcbf4e0477c8895d5e7bcb5cdebd5fef7b4df2ca8e38e144d94","src/unix/bsd/apple/b64/aarch64/mod.rs":"a3f0dfff62d0f7f4f1b5f9a4e2b662acf233a46badbc5419d3cc2d735629a710","src/unix/bsd/apple/b64/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b64/mod.rs":"f5e278a1af7fb358891d1c9be4eb7e815aaca0c5cb738d0c3604ba2208a856f7","src/unix/bsd/apple/b64/x86_64/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b64/x86_64/mod.rs":"8c87c5855038aae5d433c8f5eb3b29b0a175879a0245342b3bfd83bdf4cfd936","src/unix/bsd/apple/mod.rs":"d7155927fbd1af6dd984a4c6c1a735a5932af828c96818209487eb6ae72d7d7e","src/unix/bsd/freebsdlike/dragonfly/errno.rs":"8295b8bb0dfd38d2cdb4d9192cdeeb534cc6c3b208170e64615fa3e0edb3e578","src/unix/bsd/freebsdlike/dragonfly/mod.rs":"379302e12d30807a1f973c4e2dd2205179d95343ee6fae05f33c9ed45a342799","src/unix/bsd/freebsdlike/freebsd/aarch64.rs":"2a215bd6136b8617aacedf9be738ccee94da9d29b418e9a78101d6291c182352","src/unix/bsd/freebsdlike/freebsd/arm.rs":"59d6a670eea562fb87686e243e0a84603d29a2028a3d4b3f99ccc01bd04d2f47","src/unix/bsd/freebsdlike/freebsd/freebsd11/b64.rs":"9808d152c1196aa647f1b0f0cf84dac8c930da7d7f897a44975545e3d9d17681","src/unix/bsd/freebsdlike/freebsd/freebsd11/mod.rs":"a6eee615e6ca5a6e04b526bb6b22d13b9356e87e51825cda33476c37a46cb0ef","src/unix/bsd/freebsdlike/freebsd/freebsd12/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd12/mod.rs":"755dafaf3f0945e798c34ea94c48e8552804ce60e2a15a4f0649f9d1aceaf422","src/unix/bsd/freebsdlike/freebsd/freebsd12/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/freebsd13/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd13/mod.rs":"cc65a73b0fa95a77044a4b3ee76d6eceb9773b55aea7d73bdf070e6f66e9ea38","src/unix/bsd/freebsdlike/freebsd/freebsd13/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/freebsd14/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd14/mod.rs":"0ed92eb93e78299cd7de0ae9daebb04a53b3c2d5e6a078e1fcd977f2a86bffc3","src/unix/bsd/freebsdlike/freebsd/freebsd14/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/mod.rs":"467b66843ab8c1a54b01ae9e90aaf0295b32f54decbdfb64caca84523b488925","src/unix/bsd/freebsdlike/freebsd/powerpc.rs":"9ca3f82f88974e6db5569f2d76a5a3749b248a31747a6c0da5820492bdfeca42","src/unix/bsd/freebsdlike/freebsd/powerpc64.rs":"2dae3ecc87eac3b11657aa98915def55fc4b5c0de11fe26aae23329a54628a9a","src/unix/bsd/freebsdlike/freebsd/riscv64.rs":"8f591bd273464d684c4f64365f8ed56a8138175daa70d96008541393057a0dae","src/unix/bsd/freebsdlike/freebsd/x86.rs":"c5005e3249eb7c93cfbac72a9e9272320d80ce7983da990ceb05a447f59a02c5","src/unix/bsd/freebsdlike/freebsd/x86_64/align.rs":"0e1f69a88fca1c32874b1daf5db3d446fefbe518dca497f096cc9168c39dde70","src/unix/bsd/freebsdlike/freebsd/x86_64/mod.rs":"51e4dd0c8ae247bb652feda5adad9333ea3bb30c750c3a3935e0b0e47d7803eb","src/unix/bsd/freebsdlike/mod.rs":"a7345cc3fb7372572efe06848feb2cc246dfc2c2a0cc9ccf434f4c55041a59fa","src/unix/bsd/mod.rs":"7720ec82c9334f988ec4b271784768a017c3dc2e6dfae4d02418eef753388aa7","src/unix/bsd/netbsdlike/mod.rs":"594a0f9e23c4d7702ba38afdba5a0e866be25d692ec0afd66e04d939aa6b3f04","src/unix/bsd/netbsdlike/netbsd/aarch64.rs":"65dcb58d11e8d8028401a9d07ca3eb4cb4f053e04249cc877353449d84ccc4cb","src/unix/bsd/netbsdlike/netbsd/arm.rs":"58cdbb70b0d6f536551f0f3bb3725d2d75c4690db12c26c034e7d6ec4a924452","src/unix/bsd/netbsdlike/netbsd/mod.rs":"cb1560bf8ffcc7b2726a27b433efac90e726292960626f3064bd2c6b7f861a55","src/unix/bsd/netbsdlike/netbsd/powerpc.rs":"ee7ff5d89d0ed22f531237b5059aa669df93a3b5c489fa641465ace8d405bf41","src/unix/bsd/netbsdlike/netbsd/sparc64.rs":"9489f4b3e4566f43bb12dfb92238960613dac7f6a45cc13068a8d152b902d7d9","src/unix/bsd/netbsdlike/netbsd/x86.rs":"20692320e36bfe028d1a34d16fe12ca77aa909cb02bda167376f98f1a09aefe7","src/unix/bsd/netbsdlike/netbsd/x86_64.rs":"1afe5ef46b14397cdd68664b5b232e4f5b035b6db1d4cf411c899d51ebca9f30","src/unix/bsd/netbsdlike/openbsd/aarch64.rs":"dd91931d373b7ecaf6e2de25adadee10d16fa9b12c2cbacdff3eb291e1ba36af","src/unix/bsd/netbsdlike/openbsd/arm.rs":"01580d261bc6447bb327a0d982181b7bdabfa066cee65a30373d3ced729ad307","src/unix/bsd/netbsdlike/openbsd/mips64.rs":"8532a189ae10c7d668d9d4065da8b05d124e09bd39442c9f74a7f231c43eca48","src/unix/bsd/netbsdlike/openbsd/mod.rs":"816a8ef47df60a752a91967627eeccb9ca776dc718ecc53ae902d8edaee0bce9","src/unix/bsd/netbsdlike/openbsd/powerpc.rs":"01580d261bc6447bb327a0d982181b7bdabfa066cee65a30373d3ced729ad307","src/unix/bsd/netbsdlike/openbsd/powerpc64.rs":"1dd5449dd1fd3d51e30ffdeeaece91d0aaf05c710e0ac699fecc5461cfa2c28e","src/unix/bsd/netbsdlike/openbsd/riscv64.rs":"1dd5449dd1fd3d51e30ffdeeaece91d0aaf05c710e0ac699fecc5461cfa2c28e","src/unix/bsd/netbsdlike/openbsd/sparc64.rs":"d04fd287afbaa2c5df9d48c94e8374a532a3ba491b424ddf018270c7312f4085","src/unix/bsd/netbsdlike/openbsd/x86.rs":"6f7f5c4fde2a2259eb547890cbd86570cea04ef85347d7569e94e679448bec87","src/unix/bsd/netbsdlike/openbsd/x86_64.rs":"d31db31630289c85af3339dbe357998a21ca584cbae31607448fe2cf7675a4e1","src/unix/haiku/b32.rs":"a2efdbf7158a6da341e1db9176b0ab193ba88b449616239ed95dced11f54d87b","src/unix/haiku/b64.rs":"ff8115367d3d7d354f792d6176dfaaa26353f57056197b563bf4681f91ff7985","src/unix/haiku/mod.rs":"d5833ff9b94daa81d2470df544453212af17530d78c5a7fb912eac915d00f329","src/unix/haiku/native.rs":"dbfcbf4954a79d1df2ff58e0590bbcb8c57dfc7a32392aa73ee4726b66bd6cc8","src/unix/haiku/x86_64.rs":"3ec3aeeb7ed208b8916f3e32d42bfd085ff5e16936a1a35d9a52789f043b7237","src/unix/hermit/aarch64.rs":"86048676e335944c37a63d0083d0f368ae10ceccefeed9debb3bbe08777fc682","src/unix/hermit/mod.rs":"859814f5df89e28fd4b345db399d181e11e7ed413841b6ff703a1fcbdbf013ae","src/unix/hermit/x86_64.rs":"ab832b7524e5fb15c49ff7431165ab1a37dc4667ae0b58e8306f4c539bfa110c","src/unix/linux_like/android/b32/arm.rs":"433c1530f602cc5ed26610c58055dde0c4ceea5e00150063b24ddc60768332a4","src/unix/linux_like/android/b32/mod.rs":"7c173e0375119bf06a3081652faede95e5bcd6858e7576b7533d037978737c8f","src/unix/linux_like/android/b32/x86/align.rs":"812914e4241df82e32b12375ca3374615dc3a4bdd4cf31f0423c5815320c0dab","src/unix/linux_like/android/b32/x86/mod.rs":"8388bd3a0fcb5636bf965eee6dc95ae6860b85a2b555b387c868aa4d4e01ec89","src/unix/linux_like/android/b64/aarch64/align.rs":"2179c3b1608fa4bf68840482bfc2b2fa3ee2faf6fcae3770f9e505cddca35c7b","src/unix/linux_like/android/b64/aarch64/int128.rs":"1735f6f5c56770d20dd426442f09724d9b2052b46a7cd82f23f3288a4a7276de","src/unix/linux_like/android/b64/aarch64/mod.rs":"ef230d49fd0d182adf2dae6f8e10babf18d72259d65980bf1c4c2dc8a4f84501","src/unix/linux_like/android/b64/mod.rs":"d7bbbadafdb2cb2ff8e9cde3d89a03b9facaabb6b2d45705225d3ece1c5cce37","src/unix/linux_like/android/b64/x86_64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/android/b64/x86_64/mod.rs":"6454948ea98be86243229f99d67cdc7ca460e16b2a6445663ff4b5b6907c358d","src/unix/linux_like/android/mod.rs":"1247397a7e1b6269e0d2d6df88c6396bc18eb477e3ff293ff57d66a6b1380d94","src/unix/linux_like/emscripten/align.rs":"86c95cbed7a7161b1f23ee06843e7b0e2340ad92b2cb86fe2a8ef3e0e8c36216","src/unix/linux_like/emscripten/mod.rs":"b71d37106750f57bc2dae4e9bcb473ff098ef48235827e41a1687a39825f0aa4","src/unix/linux_like/emscripten/no_align.rs":"0128e4aa721a9902754828b61b5ec7d8a86619983ed1e0544a85d35b1051fad6","src/unix/linux_like/linux/align.rs":"d6c259942c8e843373accd180fc8f4f45f03544dfd21b93a8d02641ead3ef63e","src/unix/linux_like/linux/arch/generic/mod.rs":"e20013ed91edcfb7f84f3f9f5a9ef827fd5c406e24b65989d8438da332236ef6","src/unix/linux_like/linux/arch/mips/mod.rs":"2d166054a586bb4bf6e4a4ba35f7574907b217225eff8f1a43adc4277e142460","src/unix/linux_like/linux/arch/mod.rs":"466a29622e47c6c7f1500682b2eb17f5566dd81b322cd6348f0fdd355cec593a","src/unix/linux_like/linux/arch/powerpc/mod.rs":"3f6da7b0fa7b394c7d4eea2bb3caa7a7729ab0d6c1491fef02206a912c41b815","src/unix/linux_like/linux/arch/sparc/mod.rs":"91593ec0440f1dd8f8e612028f432c44c14089286e2aca50e10511ab942db8c3","src/unix/linux_like/linux/gnu/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/gnu/b32/arm/align.rs":"6ec0eb3ee93f7ae99fd714b4deabfb5e97fbcefd8c26f5a45fb8e7150899cdeb","src/unix/linux_like/linux/gnu/b32/arm/mod.rs":"92ea7edc0e24f79dfbf5e3efc2d7509bed230562036e6aa85ef4f2c8088ecc8f","src/unix/linux_like/linux/gnu/b32/m68k/align.rs":"8faa92f77a9232c035418d45331774e64a9a841d99c91791570a203bf2b45bcb","src/unix/linux_like/linux/gnu/b32/m68k/mod.rs":"a2a0a9400dae44086ebf579e0448e0676d4a3214d1ae7d13a024857251e23b6b","src/unix/linux_like/linux/gnu/b32/mips/align.rs":"429fb5e005cb7143602d430098b6ebfb7d360685b194f333dfd587472ae954ee","src/unix/linux_like/linux/gnu/b32/mips/mod.rs":"0d7849eb2435ec1f49b6774872a0518f0129c50f37c9d38b37b1535722777a22","src/unix/linux_like/linux/gnu/b32/mod.rs":"8da281da578cdee972e952b118b903b370320897a7e335342a15e1359864bef2","src/unix/linux_like/linux/gnu/b32/powerpc.rs":"049d6211ba4a9304bd4497c160bc21ae847c24e0528dd9d76263f16192e6aff5","src/unix/linux_like/linux/gnu/b32/riscv32/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/gnu/b32/riscv32/mod.rs":"a4256148cec0bb672c8dfa605866930d9761af9655721de72ae41eeeb8fdbf6d","src/unix/linux_like/linux/gnu/b32/sparc/align.rs":"21adbed27df73e2d1ed934aaf733a643003d7baf2bde9c48ea440895bcca6d41","src/unix/linux_like/linux/gnu/b32/sparc/mod.rs":"525618615aa0cb80c6c90860bf579dfed8db307fffd56b97dc235fb945419434","src/unix/linux_like/linux/gnu/b32/x86/align.rs":"e4bafdc4a519a7922a81b37a62bbfd1177a2f620890eef8f1fbc47162e9eb413","src/unix/linux_like/linux/gnu/b32/x86/mod.rs":"78b4038852986436888c63be9258037cf642124daee9d5fa5cef2bf8e412bf54","src/unix/linux_like/linux/gnu/b64/aarch64/align.rs":"2179c3b1608fa4bf68840482bfc2b2fa3ee2faf6fcae3770f9e505cddca35c7b","src/unix/linux_like/linux/gnu/b64/aarch64/ilp32.rs":"21a21503ef2e095f4371044915d4bfb07a8578011cb5c713cd9f45947b0b5730","src/unix/linux_like/linux/gnu/b64/aarch64/int128.rs":"1735f6f5c56770d20dd426442f09724d9b2052b46a7cd82f23f3288a4a7276de","src/unix/linux_like/linux/gnu/b64/aarch64/lp64.rs":"e78c3cd197f44832338b414d1a9bc0d194f44c74db77bd7bf830c1fff62b2690","src/unix/linux_like/linux/gnu/b64/aarch64/mod.rs":"c4e20b1c63d7a03a6e22aef2046689ef95cc4651011ade7cb94176fcea1dc252","src/unix/linux_like/linux/gnu/b64/loongarch64/align.rs":"62e822478356db4a73b6bbd1b36d825b893939ab4b308ec11b0578bcc4b49769","src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs":"d92686cfa34bbd3f1cf58d7373d7eb7135437f0f5f296d83ffc53354f966619f","src/unix/linux_like/linux/gnu/b64/mips64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/linux/gnu/b64/mips64/mod.rs":"17aad16329431d83e1909e3a08022f6e28f4bcba7dec4a967fe1a321a6a43b99","src/unix/linux_like/linux/gnu/b64/mod.rs":"3c6555f30a7a8852757b31a542ea73fb6a16a6e27e838397e819278ad56e57a4","src/unix/linux_like/linux/gnu/b64/powerpc64/align.rs":"e29c4868bbecfa4a6cd8a2ad06193f3bbc78a468cc1dc9df83f002f1268130d9","src/unix/linux_like/linux/gnu/b64/powerpc64/mod.rs":"97e0ecf11ecce793a13fec39654fb513c5479edf7faa7a276fa714b61993d0fc","src/unix/linux_like/linux/gnu/b64/riscv64/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/gnu/b64/riscv64/mod.rs":"b3fe290afe63d2d6e315d0cf1f775464e9c1f2a1906d243c1af74a137a4031cb","src/unix/linux_like/linux/gnu/b64/s390x.rs":"254f00266ecf9644a4b469457cb37c4dd6c055820926c1de0fb9035b6048e75c","src/unix/linux_like/linux/gnu/b64/sparc64/align.rs":"e29c4868bbecfa4a6cd8a2ad06193f3bbc78a468cc1dc9df83f002f1268130d9","src/unix/linux_like/linux/gnu/b64/sparc64/mod.rs":"87dd7f3d5bf3c09f4064ec738e306cc9cc41ad49b4a5df62c5983301c3bbf99a","src/unix/linux_like/linux/gnu/b64/x86_64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs":"1b939aaf3cdf3efc7d3bd53e83e80235530d3ba0c24bb7611d4730d35d457ec1","src/unix/linux_like/linux/gnu/b64/x86_64/not_x32.rs":"b88ef8a1eaa9ed73bf2acb8192afb73af987a92abb94140c6376fc83f2fa5553","src/unix/linux_like/linux/gnu/b64/x86_64/x32.rs":"79305936a60d342efdc10519ba89507d6b48e65f13f33090d3b04dc9655ceed0","src/unix/linux_like/linux/gnu/mod.rs":"84ad4a663b5fa2498179be8dca96fef5f0446ec1619215ac674424ee394e307d","src/unix/linux_like/linux/gnu/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/mod.rs":"cff23db1e0bac8c30052dfed5e89e65bc207471e4bfb3a6fa0a4df62ed9e413e","src/unix/linux_like/linux/musl/b32/arm/align.rs":"3e8ac052c1043764776b54c93ba4260e061df998631737a897d9d47d54f7b80c","src/unix/linux_like/linux/musl/b32/arm/mod.rs":"e5faee8efda8a225ea0b17d4d6f9e893a678e73773fa62c549a8e19c106b9f04","src/unix/linux_like/linux/musl/b32/hexagon.rs":"226a8b64ce9c75abbbee6d2dceb0b44f7b6c750c4102ebd4d015194afee6666e","src/unix/linux_like/linux/musl/b32/mips/align.rs":"429fb5e005cb7143602d430098b6ebfb7d360685b194f333dfd587472ae954ee","src/unix/linux_like/linux/musl/b32/mips/mod.rs":"df8f8b529a6cc6b8a7326639e83303cf1320c6c50d76517c17d42bcf45f6240a","src/unix/linux_like/linux/musl/b32/mod.rs":"7b3d9dfd8605b00bb9b5fa1439abe5ebf60199c7fa033eee555e8d181e93ffa2","src/unix/linux_like/linux/musl/b32/powerpc.rs":"c957d99a4d4371d2411a5769be8cf344516bf9ddc1011f977501a4eb57cb4e82","src/unix/linux_like/linux/musl/b32/riscv32/align.rs":"efd2accf33b87de7c7547903359a5da896edc33cd6c719552c7474b60d4a5d48","src/unix/linux_like/linux/musl/b32/riscv32/mod.rs":"698f77bfcc838f82126c54f7387881fe3e89490117e5a4f333d1b4433823a672","src/unix/linux_like/linux/musl/b32/x86/align.rs":"08e77fbd7435d7dec2ff56932433bece3f02e47ce810f89004a275a86d39cbe1","src/unix/linux_like/linux/musl/b32/x86/mod.rs":"199a91e90b454f9dc32770d5204cc4f6e5b8f144e0e34a1c91829949d6e804b3","src/unix/linux_like/linux/musl/b64/aarch64/align.rs":"798a9229d70ce235394f2dd625f6c4c1e10519a94382dc5b091952b638ae2928","src/unix/linux_like/linux/musl/b64/aarch64/int128.rs":"1735f6f5c56770d20dd426442f09724d9b2052b46a7cd82f23f3288a4a7276de","src/unix/linux_like/linux/musl/b64/aarch64/mod.rs":"9c4878df0fea0e0affd85346e0bc191abdc5e41e74dc9199b5644ec33d29c300","src/unix/linux_like/linux/musl/b64/mips64.rs":"3686fc8cb2e311cda8e6b96f6dfe90b65a366714bd480312b692b1a6ca1241b6","src/unix/linux_like/linux/musl/b64/mod.rs":"8c10627bd582cb272514e7350ae4743a65d489356eae039d2e7e55cd533fbbc8","src/unix/linux_like/linux/musl/b64/powerpc64.rs":"36694cbdcdc33879e00502d55cb95eaa0096d213538993dd39c3da800cdd06d1","src/unix/linux_like/linux/musl/b64/riscv64/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/musl/b64/riscv64/mod.rs":"36621aca8ecf714f8dd42662dc2997833d95b9f129ef8c220503362e21efd695","src/unix/linux_like/linux/musl/b64/s390x.rs":"9b05b1fae6bcb7cb6d909b9973977fde01684175f3e26c27dcb44223cc3933d9","src/unix/linux_like/linux/musl/b64/x86_64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/linux/musl/b64/x86_64/mod.rs":"238789097a26abc8b7cd578ed1a8e6cb8672083054303902781983902cd66854","src/unix/linux_like/linux/musl/mod.rs":"2efe98b8166270be1624888953fa07da06f08313f15bf4c7dc2eba63f5a790a5","src/unix/linux_like/linux/no_align.rs":"da2a8721becaaaa528781f97f5d9aae6a982ae5d4f5f6d2ffc0150bed72319b3","src/unix/linux_like/linux/non_exhaustive.rs":"181a05bf94fdb911db83ce793b993bd6548a4115b306a7ef3c10f745a8fea3e9","src/unix/linux_like/linux/uclibc/align.rs":"9ed16138d8e439bd90930845a65eafa7ebd67366e6bf633936d44014f6e4c959","src/unix/linux_like/linux/uclibc/arm/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/uclibc/arm/mod.rs":"a056bbf718ddd775519058706bdb4909b56e6256985869e3c3132aa8ec5faca0","src/unix/linux_like/linux/uclibc/arm/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/uclibc/mips/mips32/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/uclibc/mips/mips32/mod.rs":"b84def53a49587e87f884c2bc28b21b290463b00b52e1d0309f2ba233a5b4a99","src/unix/linux_like/linux/uclibc/mips/mips32/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/uclibc/mips/mips64/align.rs":"a7bdcb18a37a2d91e64d5fad83ea3edc78f5412adb28f77ab077dbb26dd08b2d","src/unix/linux_like/linux/uclibc/mips/mips64/mod.rs":"256a428290a560163ef7dc7d18b27bd3c6ce9748a0f28d5dc7f82203ee228220","src/unix/linux_like/linux/uclibc/mips/mips64/no_align.rs":"4a18e3875698c85229599225ac3401a2a40da87e77b2ad4ef47c6fcd5a24ed30","src/unix/linux_like/linux/uclibc/mips/mod.rs":"367ec5483ad317e6ccba1ac0888da6cf088a8d32689214cc8d16129aa692260c","src/unix/linux_like/linux/uclibc/mod.rs":"ddd223d4f574b2b92072bbdab091f12d8d89d5e05f41076ddfa6bc6af379698f","src/unix/linux_like/linux/uclibc/no_align.rs":"3f28637046524618adaa1012e26cb7ffe94b9396e6b518cccdc69d59f274d709","src/unix/linux_like/linux/uclibc/x86_64/l4re.rs":"024eba5753e852dbdd212427351affe7e83f9916c1864bce414d7aa2618f192e","src/unix/linux_like/linux/uclibc/x86_64/mod.rs":"bf6985e901041a61e90ccee1296b35a4c62ef90aa528d31989e1d647f072e79a","src/unix/linux_like/linux/uclibc/x86_64/other.rs":"42c3f71e58cabba373f6a55a623f3c31b85049eb64824c09c2b082b3b2d6a0a8","src/unix/linux_like/mod.rs":"dd4f7a1d66d8501b4a2c4e75e6e9305ed69f1002ae99e410596a6c636878595a","src/unix/mod.rs":"d1b4ba41f9b9c106f6ba8c661b5808824b774a7a7caac7d8938bf50979ba5195","src/unix/newlib/aarch64/mod.rs":"bac93836a9a57b2c710f32f852e92a4d11ad6759ab0fb6ad33e71d60e53278af","src/unix/newlib/align.rs":"28aaf87fafbc6b312622719d472d8cf65f9e5467d15339df5f73e66d8502b28a","src/unix/newlib/arm/mod.rs":"cbba6b3e957eceb496806e60de8725a23ff3fa0015983b4b4fa27b233732b526","src/unix/newlib/espidf/mod.rs":"ff9c13e99d84912f5ebe75b7a7ea9c1e9d8f35a268716081e09899c7ea822bc6","src/unix/newlib/generic.rs":"eab066d9f0a0f3eb53cc1073d01496bba0110989e1f6a59838afd19f870cd599","src/unix/newlib/horizon/mod.rs":"7cc5cc120437421db139bfa6a90b18168cd3070bdd0f5be96d40fe4c996f3ca1","src/unix/newlib/mod.rs":"54633d606e4e0413274af0b5beb5e697e6c061b63feaa0704b026554cc9d9c3e","src/unix/newlib/no_align.rs":"e0743b2179495a9514bc3a4d1781e492878c4ec834ee0085d0891dd1712e82fb","src/unix/newlib/powerpc/mod.rs":"0202ffd57caf75b6afa2c9717750ffb96e375ac33df0ae9609a3f831be393b67","src/unix/no_align.rs":"c06e95373b9088266e0b14bba0954eef95f93fb2b01d951855e382d22de78e53","src/unix/redox/mod.rs":"033768cb273daf2c8090d97252c2de9dba6809e6a5d2457f5727d724807695db","src/unix/solarish/compat.rs":"b07a5bfac925eb012003a459ba6bddbd3bfa9c44b3394da2ac5a602e54beae9c","src/unix/solarish/illumos.rs":"29387916ee7dc58f07478746024003215e631cd30953e8fa2a5c415f81839007","src/unix/solarish/mod.rs":"976b07a13e195840b67c166a62318abfa9ffc8d5ebbb0358f199dd213ec98d1b","src/unix/solarish/solaris.rs":"65b005453aefa9b9d4fc860fe77cfec80d8c97a51342b15daf55fc3e808bb384","src/unix/solarish/x86.rs":"e86e806df0caed72765040eaa2f3c883198d1aa91508540adf9b7008c77f522e","src/unix/solarish/x86_64.rs":"9074e813949f3c613afeac39d4118fb942c0b3c476232fc536489357cff5790f","src/unix/solarish/x86_common.rs":"ac869d9c3c95645c22460468391eb1982023c3a8e02b9e06a72e3aef3d5f1eac","src/vxworks/aarch64.rs":"98f0afdc511cd02557e506c21fed6737585490a1dce7a9d4941d08c437762b99","src/vxworks/arm.rs":"acb7968ce99fe3f4abdf39d98f8133d21a4fba435b8ef7084777cb181d788e88","src/vxworks/mod.rs":"aea3da66f2140f2a82dfc9c58f6e6531d2dd9c15ea696e0f95a0d4a2a187b5b6","src/vxworks/powerpc.rs":"acb7968ce99fe3f4abdf39d98f8133d21a4fba435b8ef7084777cb181d788e88","src/vxworks/powerpc64.rs":"98f0afdc511cd02557e506c21fed6737585490a1dce7a9d4941d08c437762b99","src/vxworks/x86.rs":"552f007f38317620b23889cb7c49d1d115841252439060122f52f434fbc6e5ba","src/vxworks/x86_64.rs":"018d92be3ad628a129eff9f2f5dfbc0883d8b8e5f2fa917b900a7f98ed6b514a","src/wasi.rs":"4fae202af0327d768ed9e1b586b75816cce14fe2dc16947d2f3d381f209a54c1","src/windows/gnu/align.rs":"b2c13ec1b9f3b39a75c452c80c951dff9d0215e31d77e883b4502afb31794647","src/windows/gnu/mod.rs":"3c8c7edb7cdf5d0c44af936db2a94869585c69dfabeef30571b4f4e38375767a","src/windows/mod.rs":"e3ad95ba54f76e74c301611fe868d3d94f6b8939b03be672f568b06b10ae71c7","src/windows/msvc/mod.rs":"c068271e00fca6b62bc4bf44bcf142cfc38caeded9b6c4e01d1ceef3ccf986f4","tests/const_fn.rs":"cb75a1f0864f926aebe79118fc34d51a0d1ade2c20a394e7774c7e545f21f1f4"},"package":"349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"} -diff --git a/vendor/libc-0.2.126/src/unix/linux_like/linux/gnu/b64/loongarch64/align.rs b/vendor/libc-0.2.126/src/unix/linux_like/linux/gnu/b64/loongarch64/align.rs -index 7ca870fd0..ba3075edd 100644 ---- a/vendor/libc-0.2.126/src/unix/linux_like/linux/gnu/b64/loongarch64/align.rs -+++ b/vendor/libc-0.2.126/src/unix/linux_like/linux/gnu/b64/loongarch64/align.rs -@@ -5,3 +5,20 @@ s_no_extra_traits! { - priv_: [f64; 4] - } - } -+ -+s! { -+ #[repr(align(8))] -+ pub struct clone_args { -+ pub flags: ::c_ulonglong, -+ pub pidfd: ::c_ulonglong, -+ pub child_tid: ::c_ulonglong, -+ pub parent_tid: ::c_ulonglong, -+ pub exit_signal: ::c_ulonglong, -+ pub stack: ::c_ulonglong, -+ pub stack_size: ::c_ulonglong, -+ pub tls: ::c_ulonglong, -+ pub set_tid: ::c_ulonglong, -+ pub set_tid_size: ::c_ulonglong, -+ pub cgroup: ::c_ulonglong, -+ } -+} -diff --git a/vendor/libc-0.2.126/src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs b/vendor/libc-0.2.126/src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs -index 2ed6a9156..ff520e0c6 100644 ---- a/vendor/libc-0.2.126/src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs -+++ b/vendor/libc-0.2.126/src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs -@@ -247,6 +247,20 @@ align_const! { - }; - } - -+pub const HWCAP_LOONGARCH_CPUCFG: ::c_ulong = 1 << 0; -+pub const HWCAP_LOONGARCH_LAM: ::c_ulong = 1 << 1; -+pub const HWCAP_LOONGARCH_UAL: ::c_ulong = 1 << 2; -+pub const HWCAP_LOONGARCH_FPU: ::c_ulong = 1 << 3; -+pub const HWCAP_LOONGARCH_LSX: ::c_ulong = 1 << 4; -+pub const HWCAP_LOONGARCH_LASX: ::c_ulong = 1 << 5; -+pub const HWCAP_LOONGARCH_CRC32: ::c_ulong = 1 << 6; -+pub const HWCAP_LOONGARCH_COMPLEX: ::c_ulong = 1 << 7; -+pub const HWCAP_LOONGARCH_CRYPTO: ::c_ulong = 1 << 8; -+pub const HWCAP_LOONGARCH_LVZ: ::c_ulong = 1 << 9; -+pub const HWCAP_LOONGARCH_LBT_X86: ::c_ulong = 1 << 10; -+pub const HWCAP_LOONGARCH_LBT_ARM: ::c_ulong = 1 << 11; -+pub const HWCAP_LOONGARCH_LBT_MIPS: ::c_ulong = 1 << 12; -+ - pub const SYS_io_setup: ::c_long = 0; - pub const SYS_io_destroy: ::c_long = 1; - pub const SYS_io_submit: ::c_long = 2; -@@ -587,6 +601,8 @@ pub const F_OFD_GETLK: ::c_int = 36; - pub const F_OFD_SETLK: ::c_int = 37; - pub const F_OFD_SETLKW: ::c_int = 38; - -+pub const MADV_SOFT_OFFLINE: ::c_int = 101; -+ - pub const EDEADLK: ::c_int = 35; - pub const EDEADLOCK: ::c_int = 35; - pub const ENAMETOOLONG: ::c_int = 36; -diff --git a/vendor/libc-0.2.127/.cargo-checksum.json b/vendor/libc-0.2.127/.cargo-checksum.json -index 3fdf6bc61..29d5859a3 100644 ---- a/vendor/libc-0.2.127/.cargo-checksum.json -+++ b/vendor/libc-0.2.127/.cargo-checksum.json -@@ -1 +1 @@ --{"files":{"CONTRIBUTING.md":"f480d10d2a506eecd23ae2e2dedb7a28b8bf6dae5f46f438dbb61be2003426fb","Cargo.toml":"e1c4b3839177aabdc73c017ee87ba3dcc8025b2730cb0a2c015473f9db99f3fa","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"a8d47ff51ca256f56a8932dba07660672dbfe3004257ca8de708aac1415937a1","README.md":"776affa26b66843a2b4f1a1c8f88d92f6461b74568911450fea717e9db6f877b","build.rs":"1d0cbe878e98e970c3318cac0772215a9f44bd286d859d665da27872ba9d8818","rustfmt.toml":"eaa2ea84fc1ba0359b77680804903e07bb38d257ab11986b95b158e460f787b2","src/fixed_width_ints.rs":"7f986e5f5e68d25ef04d386fd2f640e8be8f15427a8d4a458ea01d26b8dca0ca","src/fuchsia/aarch64.rs":"378776a9e40766154a54c94c2a7b4675b5c302a38e6e42da99e67bfbaee60e56","src/fuchsia/align.rs":"ae1cf8f011a99737eabeb14ffff768e60f13b13363d7646744dbb0f443dab3d6","src/fuchsia/mod.rs":"94cbaad15021e287a1b9546a697b04c1e560f1204b52204ffaaea5975c5d03b9","src/fuchsia/no_align.rs":"303f3f1b255e0088b5715094353cf00476131d8e94e6aebb3f469557771c8b8a","src/fuchsia/x86_64.rs":"93a3632b5cf67d2a6bcb7dc0a558605252d5fe689e0f38d8aa2ec5852255ac87","src/hermit/aarch64.rs":"86048676e335944c37a63d0083d0f368ae10ceccefeed9debb3bbe08777fc682","src/hermit/mod.rs":"d3bfce41e4463d4be8020a2d063c9bfa8b665f45f1cc6cbf3163f5d01e7cb21f","src/hermit/x86_64.rs":"ab832b7524e5fb15c49ff7431165ab1a37dc4667ae0b58e8306f4c539bfa110c","src/lib.rs":"0c5306ea9d12b5261380d733dc3f7624cf259c45638eac8d9222c7e32e134a65","src/macros.rs":"b457eb028b8e8ab3c24bb7292b874ad4e491edbb83594f6a3da024df5348c088","src/psp.rs":"dd31aabd46171d474ec5828372e28588935120e7355c90c105360d8fa9264c1c","src/sgx.rs":"16a95cdefc81c5ee00d8353a60db363c4cc3e0f75abcd5d0144723f2a306ed1b","src/solid/aarch64.rs":"a726e47f324adf73a4a0b67a2c183408d0cad105ae66acf36db37a42ab7f8707","src/solid/arm.rs":"e39a4f74ebbef3b97b8c95758ad741123d84ed3eb48d9cf4f1f4872097fc27fe","src/solid/mod.rs":"5f4151dca5132e4b4e4c23ab9737e12856dddbdc0ca3f7dbc004328ef3c8acde","src/switch.rs":"9da3dd39b3de45a7928789926e8572d00e1e11a39e6f7289a1349aadce90edba","src/unix/align.rs":"2cdc7c826ef7ae61f5171c5ae8c445a743d86f1a7f2d9d7e4ceeec56d6874f65","src/unix/bsd/apple/b32/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b32/mod.rs":"2546ad3eb6aecb95f916648bc63264117c92b4b4859532b34cb011e4c75a5a72","src/unix/bsd/apple/b64/aarch64/align.rs":"e8eb38d064b5fefec6f37d42873820a0483e7c758ed336cc59a7155455ca89c9","src/unix/bsd/apple/b64/aarch64/mod.rs":"a3f0dfff62d0f7f4f1b5f9a4e2b662acf233a46badbc5419d3cc2d735629a710","src/unix/bsd/apple/b64/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b64/mod.rs":"f5e278a1af7fb358891d1c9be4eb7e815aaca0c5cb738d0c3604ba2208a856f7","src/unix/bsd/apple/b64/x86_64/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b64/x86_64/mod.rs":"8c87c5855038aae5d433c8f5eb3b29b0a175879a0245342b3bfd83bdf4cfd936","src/unix/bsd/apple/mod.rs":"e35db24ba69ee0262854916fa19a306bf6c40388f5593ab32d0907e24b5fc5c6","src/unix/bsd/freebsdlike/dragonfly/errno.rs":"8295b8bb0dfd38d2cdb4d9192cdeeb534cc6c3b208170e64615fa3e0edb3e578","src/unix/bsd/freebsdlike/dragonfly/mod.rs":"d0e8246063cae113806524a63a47c6c0628cc54a3ef03e938e89964f8b4f08b4","src/unix/bsd/freebsdlike/freebsd/aarch64.rs":"2a215bd6136b8617aacedf9be738ccee94da9d29b418e9a78101d6291c182352","src/unix/bsd/freebsdlike/freebsd/arm.rs":"59d6a670eea562fb87686e243e0a84603d29a2028a3d4b3f99ccc01bd04d2f47","src/unix/bsd/freebsdlike/freebsd/freebsd11/b64.rs":"9808d152c1196aa647f1b0f0cf84dac8c930da7d7f897a44975545e3d9d17681","src/unix/bsd/freebsdlike/freebsd/freebsd11/mod.rs":"a6eee615e6ca5a6e04b526bb6b22d13b9356e87e51825cda33476c37a46cb0ef","src/unix/bsd/freebsdlike/freebsd/freebsd12/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd12/mod.rs":"755dafaf3f0945e798c34ea94c48e8552804ce60e2a15a4f0649f9d1aceaf422","src/unix/bsd/freebsdlike/freebsd/freebsd12/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/freebsd13/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd13/mod.rs":"cc65a73b0fa95a77044a4b3ee76d6eceb9773b55aea7d73bdf070e6f66e9ea38","src/unix/bsd/freebsdlike/freebsd/freebsd13/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/freebsd14/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd14/mod.rs":"0ed92eb93e78299cd7de0ae9daebb04a53b3c2d5e6a078e1fcd977f2a86bffc3","src/unix/bsd/freebsdlike/freebsd/freebsd14/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/mod.rs":"ec229cc7af2511cb510c078e87e90ee2625090bfe94f40eb35f73d79143533aa","src/unix/bsd/freebsdlike/freebsd/powerpc.rs":"9ca3f82f88974e6db5569f2d76a5a3749b248a31747a6c0da5820492bdfeca42","src/unix/bsd/freebsdlike/freebsd/powerpc64.rs":"2dae3ecc87eac3b11657aa98915def55fc4b5c0de11fe26aae23329a54628a9a","src/unix/bsd/freebsdlike/freebsd/riscv64.rs":"8f591bd273464d684c4f64365f8ed56a8138175daa70d96008541393057a0dae","src/unix/bsd/freebsdlike/freebsd/x86.rs":"c5005e3249eb7c93cfbac72a9e9272320d80ce7983da990ceb05a447f59a02c5","src/unix/bsd/freebsdlike/freebsd/x86_64/align.rs":"0e1f69a88fca1c32874b1daf5db3d446fefbe518dca497f096cc9168c39dde70","src/unix/bsd/freebsdlike/freebsd/x86_64/mod.rs":"51e4dd0c8ae247bb652feda5adad9333ea3bb30c750c3a3935e0b0e47d7803eb","src/unix/bsd/freebsdlike/mod.rs":"1e35b4773384ea143810cdce4b96f47108b37446430da30c96a0d1651656d73d","src/unix/bsd/mod.rs":"7720ec82c9334f988ec4b271784768a017c3dc2e6dfae4d02418eef753388aa7","src/unix/bsd/netbsdlike/mod.rs":"b07a0e81085bd811fce7270f3b90fbfea29faf9593d9e39d9d2ebbb9a78bf25f","src/unix/bsd/netbsdlike/netbsd/aarch64.rs":"65dcb58d11e8d8028401a9d07ca3eb4cb4f053e04249cc877353449d84ccc4cb","src/unix/bsd/netbsdlike/netbsd/arm.rs":"58cdbb70b0d6f536551f0f3bb3725d2d75c4690db12c26c034e7d6ec4a924452","src/unix/bsd/netbsdlike/netbsd/mod.rs":"8f9613e50c2771b33d7cf817a735d536b389ec57f861b9486d870373c768276e","src/unix/bsd/netbsdlike/netbsd/powerpc.rs":"ee7ff5d89d0ed22f531237b5059aa669df93a3b5c489fa641465ace8d405bf41","src/unix/bsd/netbsdlike/netbsd/sparc64.rs":"9489f4b3e4566f43bb12dfb92238960613dac7f6a45cc13068a8d152b902d7d9","src/unix/bsd/netbsdlike/netbsd/x86.rs":"20692320e36bfe028d1a34d16fe12ca77aa909cb02bda167376f98f1a09aefe7","src/unix/bsd/netbsdlike/netbsd/x86_64.rs":"1afe5ef46b14397cdd68664b5b232e4f5b035b6db1d4cf411c899d51ebca9f30","src/unix/bsd/netbsdlike/openbsd/aarch64.rs":"dd91931d373b7ecaf6e2de25adadee10d16fa9b12c2cbacdff3eb291e1ba36af","src/unix/bsd/netbsdlike/openbsd/arm.rs":"01580d261bc6447bb327a0d982181b7bdabfa066cee65a30373d3ced729ad307","src/unix/bsd/netbsdlike/openbsd/mips64.rs":"8532a189ae10c7d668d9d4065da8b05d124e09bd39442c9f74a7f231c43eca48","src/unix/bsd/netbsdlike/openbsd/mod.rs":"228505fa48292e74b06acbed96196801595a4b822da2126a6d6c7fa773cff8bc","src/unix/bsd/netbsdlike/openbsd/powerpc.rs":"01580d261bc6447bb327a0d982181b7bdabfa066cee65a30373d3ced729ad307","src/unix/bsd/netbsdlike/openbsd/powerpc64.rs":"1dd5449dd1fd3d51e30ffdeeaece91d0aaf05c710e0ac699fecc5461cfa2c28e","src/unix/bsd/netbsdlike/openbsd/riscv64.rs":"1dd5449dd1fd3d51e30ffdeeaece91d0aaf05c710e0ac699fecc5461cfa2c28e","src/unix/bsd/netbsdlike/openbsd/sparc64.rs":"d04fd287afbaa2c5df9d48c94e8374a532a3ba491b424ddf018270c7312f4085","src/unix/bsd/netbsdlike/openbsd/x86.rs":"6f7f5c4fde2a2259eb547890cbd86570cea04ef85347d7569e94e679448bec87","src/unix/bsd/netbsdlike/openbsd/x86_64.rs":"d31db31630289c85af3339dbe357998a21ca584cbae31607448fe2cf7675a4e1","src/unix/haiku/b32.rs":"a2efdbf7158a6da341e1db9176b0ab193ba88b449616239ed95dced11f54d87b","src/unix/haiku/b64.rs":"ff8115367d3d7d354f792d6176dfaaa26353f57056197b563bf4681f91ff7985","src/unix/haiku/mod.rs":"69cc3638c6f7e2086ada7bacf5ea01ce1b7f5d045fd012c6f46b8635d30ce594","src/unix/haiku/native.rs":"dbfcbf4954a79d1df2ff58e0590bbcb8c57dfc7a32392aa73ee4726b66bd6cc8","src/unix/haiku/x86_64.rs":"3ec3aeeb7ed208b8916f3e32d42bfd085ff5e16936a1a35d9a52789f043b7237","src/unix/hermit/aarch64.rs":"86048676e335944c37a63d0083d0f368ae10ceccefeed9debb3bbe08777fc682","src/unix/hermit/mod.rs":"859814f5df89e28fd4b345db399d181e11e7ed413841b6ff703a1fcbdbf013ae","src/unix/hermit/x86_64.rs":"ab832b7524e5fb15c49ff7431165ab1a37dc4667ae0b58e8306f4c539bfa110c","src/unix/linux_like/android/b32/arm.rs":"433c1530f602cc5ed26610c58055dde0c4ceea5e00150063b24ddc60768332a4","src/unix/linux_like/android/b32/mod.rs":"7c173e0375119bf06a3081652faede95e5bcd6858e7576b7533d037978737c8f","src/unix/linux_like/android/b32/x86/align.rs":"812914e4241df82e32b12375ca3374615dc3a4bdd4cf31f0423c5815320c0dab","src/unix/linux_like/android/b32/x86/mod.rs":"8388bd3a0fcb5636bf965eee6dc95ae6860b85a2b555b387c868aa4d4e01ec89","src/unix/linux_like/android/b64/aarch64/align.rs":"2179c3b1608fa4bf68840482bfc2b2fa3ee2faf6fcae3770f9e505cddca35c7b","src/unix/linux_like/android/b64/aarch64/int128.rs":"1735f6f5c56770d20dd426442f09724d9b2052b46a7cd82f23f3288a4a7276de","src/unix/linux_like/android/b64/aarch64/mod.rs":"ef230d49fd0d182adf2dae6f8e10babf18d72259d65980bf1c4c2dc8a4f84501","src/unix/linux_like/android/b64/mod.rs":"d7bbbadafdb2cb2ff8e9cde3d89a03b9facaabb6b2d45705225d3ece1c5cce37","src/unix/linux_like/android/b64/x86_64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/android/b64/x86_64/mod.rs":"e10d19bea39f719723ab6666a5ddbd378b6958769441c5904629e1df173b1dc2","src/unix/linux_like/android/mod.rs":"962741303dc24a5b9653f2e9b0b4ad9eb42fc54daa0a70ca70a7ce175e75094b","src/unix/linux_like/emscripten/align.rs":"86c95cbed7a7161b1f23ee06843e7b0e2340ad92b2cb86fe2a8ef3e0e8c36216","src/unix/linux_like/emscripten/mod.rs":"c69c90606d4362f8de89b8816df0ded724ed64b53bf55d15681fde171b7bb361","src/unix/linux_like/emscripten/no_align.rs":"0128e4aa721a9902754828b61b5ec7d8a86619983ed1e0544a85d35b1051fad6","src/unix/linux_like/linux/align.rs":"d6c259942c8e843373accd180fc8f4f45f03544dfd21b93a8d02641ead3ef63e","src/unix/linux_like/linux/arch/generic/mod.rs":"e20013ed91edcfb7f84f3f9f5a9ef827fd5c406e24b65989d8438da332236ef6","src/unix/linux_like/linux/arch/mips/mod.rs":"2d166054a586bb4bf6e4a4ba35f7574907b217225eff8f1a43adc4277e142460","src/unix/linux_like/linux/arch/mod.rs":"466a29622e47c6c7f1500682b2eb17f5566dd81b322cd6348f0fdd355cec593a","src/unix/linux_like/linux/arch/powerpc/mod.rs":"3f6da7b0fa7b394c7d4eea2bb3caa7a7729ab0d6c1491fef02206a912c41b815","src/unix/linux_like/linux/arch/sparc/mod.rs":"91593ec0440f1dd8f8e612028f432c44c14089286e2aca50e10511ab942db8c3","src/unix/linux_like/linux/gnu/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/gnu/b32/arm/align.rs":"6ec0eb3ee93f7ae99fd714b4deabfb5e97fbcefd8c26f5a45fb8e7150899cdeb","src/unix/linux_like/linux/gnu/b32/arm/mod.rs":"92ea7edc0e24f79dfbf5e3efc2d7509bed230562036e6aa85ef4f2c8088ecc8f","src/unix/linux_like/linux/gnu/b32/m68k/align.rs":"8faa92f77a9232c035418d45331774e64a9a841d99c91791570a203bf2b45bcb","src/unix/linux_like/linux/gnu/b32/m68k/mod.rs":"a2a0a9400dae44086ebf579e0448e0676d4a3214d1ae7d13a024857251e23b6b","src/unix/linux_like/linux/gnu/b32/mips/align.rs":"429fb5e005cb7143602d430098b6ebfb7d360685b194f333dfd587472ae954ee","src/unix/linux_like/linux/gnu/b32/mips/mod.rs":"0d7849eb2435ec1f49b6774872a0518f0129c50f37c9d38b37b1535722777a22","src/unix/linux_like/linux/gnu/b32/mod.rs":"8da281da578cdee972e952b118b903b370320897a7e335342a15e1359864bef2","src/unix/linux_like/linux/gnu/b32/powerpc.rs":"049d6211ba4a9304bd4497c160bc21ae847c24e0528dd9d76263f16192e6aff5","src/unix/linux_like/linux/gnu/b32/riscv32/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/gnu/b32/riscv32/mod.rs":"a4256148cec0bb672c8dfa605866930d9761af9655721de72ae41eeeb8fdbf6d","src/unix/linux_like/linux/gnu/b32/sparc/align.rs":"21adbed27df73e2d1ed934aaf733a643003d7baf2bde9c48ea440895bcca6d41","src/unix/linux_like/linux/gnu/b32/sparc/mod.rs":"525618615aa0cb80c6c90860bf579dfed8db307fffd56b97dc235fb945419434","src/unix/linux_like/linux/gnu/b32/x86/align.rs":"e4bafdc4a519a7922a81b37a62bbfd1177a2f620890eef8f1fbc47162e9eb413","src/unix/linux_like/linux/gnu/b32/x86/mod.rs":"78b4038852986436888c63be9258037cf642124daee9d5fa5cef2bf8e412bf54","src/unix/linux_like/linux/gnu/b64/aarch64/align.rs":"5b32fcc0d60356c92ded4e0ba9bb32f0140a8bd75ba800486bf38294f61dbdbb","src/unix/linux_like/linux/gnu/b64/aarch64/ilp32.rs":"21a21503ef2e095f4371044915d4bfb07a8578011cb5c713cd9f45947b0b5730","src/unix/linux_like/linux/gnu/b64/aarch64/int128.rs":"1735f6f5c56770d20dd426442f09724d9b2052b46a7cd82f23f3288a4a7276de","src/unix/linux_like/linux/gnu/b64/aarch64/lp64.rs":"e78c3cd197f44832338b414d1a9bc0d194f44c74db77bd7bf830c1fff62b2690","src/unix/linux_like/linux/gnu/b64/aarch64/mod.rs":"c72a08011c32f82919e930e0d89044d8feb65fd41bf80647436756c290344eb8","src/unix/linux_like/linux/gnu/b64/loongarch64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs":"387808d5398b24339e7e2bf7591150735011befc5b421fa713d7017c04a7b1da","src/unix/linux_like/linux/gnu/b64/mips64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/linux/gnu/b64/mips64/mod.rs":"17aad16329431d83e1909e3a08022f6e28f4bcba7dec4a967fe1a321a6a43b99","src/unix/linux_like/linux/gnu/b64/mod.rs":"3c6555f30a7a8852757b31a542ea73fb6a16a6e27e838397e819278ad56e57a4","src/unix/linux_like/linux/gnu/b64/powerpc64/align.rs":"e29c4868bbecfa4a6cd8a2ad06193f3bbc78a468cc1dc9df83f002f1268130d9","src/unix/linux_like/linux/gnu/b64/powerpc64/mod.rs":"97e0ecf11ecce793a13fec39654fb513c5479edf7faa7a276fa714b61993d0fc","src/unix/linux_like/linux/gnu/b64/riscv64/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/gnu/b64/riscv64/mod.rs":"b3fe290afe63d2d6e315d0cf1f775464e9c1f2a1906d243c1af74a137a4031cb","src/unix/linux_like/linux/gnu/b64/s390x.rs":"254f00266ecf9644a4b469457cb37c4dd6c055820926c1de0fb9035b6048e75c","src/unix/linux_like/linux/gnu/b64/sparc64/align.rs":"e29c4868bbecfa4a6cd8a2ad06193f3bbc78a468cc1dc9df83f002f1268130d9","src/unix/linux_like/linux/gnu/b64/sparc64/mod.rs":"87dd7f3d5bf3c09f4064ec738e306cc9cc41ad49b4a5df62c5983301c3bbf99a","src/unix/linux_like/linux/gnu/b64/x86_64/align.rs":"62e822478356db4a73b6bbd1b36d825b893939ab4b308ec11b0578bcc4b49769","src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs":"f0db9914315d5a3d51bf5ec04a0ae6584f2e1688b9258ce132b617e67d9bd7a9","src/unix/linux_like/linux/gnu/b64/x86_64/not_x32.rs":"b88ef8a1eaa9ed73bf2acb8192afb73af987a92abb94140c6376fc83f2fa5553","src/unix/linux_like/linux/gnu/b64/x86_64/x32.rs":"79305936a60d342efdc10519ba89507d6b48e65f13f33090d3b04dc9655ceed0","src/unix/linux_like/linux/gnu/mod.rs":"1ca6821fbb94476500d4352908e713b7c698cb7ff0a49997934126391657c573","src/unix/linux_like/linux/gnu/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/mod.rs":"758e222200a8cbb74b1eb01581da92fea895619da866bc383129d4b9a5366aef","src/unix/linux_like/linux/musl/b32/arm/align.rs":"3e8ac052c1043764776b54c93ba4260e061df998631737a897d9d47d54f7b80c","src/unix/linux_like/linux/musl/b32/arm/mod.rs":"e5faee8efda8a225ea0b17d4d6f9e893a678e73773fa62c549a8e19c106b9f04","src/unix/linux_like/linux/musl/b32/hexagon.rs":"226a8b64ce9c75abbbee6d2dceb0b44f7b6c750c4102ebd4d015194afee6666e","src/unix/linux_like/linux/musl/b32/mips/align.rs":"429fb5e005cb7143602d430098b6ebfb7d360685b194f333dfd587472ae954ee","src/unix/linux_like/linux/musl/b32/mips/mod.rs":"df8f8b529a6cc6b8a7326639e83303cf1320c6c50d76517c17d42bcf45f6240a","src/unix/linux_like/linux/musl/b32/mod.rs":"7b3d9dfd8605b00bb9b5fa1439abe5ebf60199c7fa033eee555e8d181e93ffa2","src/unix/linux_like/linux/musl/b32/powerpc.rs":"c957d99a4d4371d2411a5769be8cf344516bf9ddc1011f977501a4eb57cb4e82","src/unix/linux_like/linux/musl/b32/riscv32/align.rs":"efd2accf33b87de7c7547903359a5da896edc33cd6c719552c7474b60d4a5d48","src/unix/linux_like/linux/musl/b32/riscv32/mod.rs":"698f77bfcc838f82126c54f7387881fe3e89490117e5a4f333d1b4433823a672","src/unix/linux_like/linux/musl/b32/x86/align.rs":"08e77fbd7435d7dec2ff56932433bece3f02e47ce810f89004a275a86d39cbe1","src/unix/linux_like/linux/musl/b32/x86/mod.rs":"199a91e90b454f9dc32770d5204cc4f6e5b8f144e0e34a1c91829949d6e804b3","src/unix/linux_like/linux/musl/b64/aarch64/align.rs":"6ba32725d24d7d8e6aa111f3b57aafa318f83b606abe96561329151829821133","src/unix/linux_like/linux/musl/b64/aarch64/int128.rs":"1735f6f5c56770d20dd426442f09724d9b2052b46a7cd82f23f3288a4a7276de","src/unix/linux_like/linux/musl/b64/aarch64/mod.rs":"9c4878df0fea0e0affd85346e0bc191abdc5e41e74dc9199b5644ec33d29c300","src/unix/linux_like/linux/musl/b64/mips64.rs":"3686fc8cb2e311cda8e6b96f6dfe90b65a366714bd480312b692b1a6ca1241b6","src/unix/linux_like/linux/musl/b64/mod.rs":"8c10627bd582cb272514e7350ae4743a65d489356eae039d2e7e55cd533fbbc8","src/unix/linux_like/linux/musl/b64/powerpc64.rs":"36694cbdcdc33879e00502d55cb95eaa0096d213538993dd39c3da800cdd06d1","src/unix/linux_like/linux/musl/b64/riscv64/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/musl/b64/riscv64/mod.rs":"36621aca8ecf714f8dd42662dc2997833d95b9f129ef8c220503362e21efd695","src/unix/linux_like/linux/musl/b64/s390x.rs":"c7ebabc4e1bdbbd97e5065faa3a57f41f473570920582d979f9e9d4f77448546","src/unix/linux_like/linux/musl/b64/x86_64/align.rs":"77309276ad7a42cbe59ca381f23590b7a143aded05555b34a5b307b808cbca6e","src/unix/linux_like/linux/musl/b64/x86_64/mod.rs":"238789097a26abc8b7cd578ed1a8e6cb8672083054303902781983902cd66854","src/unix/linux_like/linux/musl/mod.rs":"c3365480375bc258ffe267e7a299d7b3bb542a908bef8881f503ddc25ba8fc1f","src/unix/linux_like/linux/no_align.rs":"da2a8721becaaaa528781f97f5d9aae6a982ae5d4f5f6d2ffc0150bed72319b3","src/unix/linux_like/linux/non_exhaustive.rs":"181a05bf94fdb911db83ce793b993bd6548a4115b306a7ef3c10f745a8fea3e9","src/unix/linux_like/linux/uclibc/align.rs":"9ed16138d8e439bd90930845a65eafa7ebd67366e6bf633936d44014f6e4c959","src/unix/linux_like/linux/uclibc/arm/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/uclibc/arm/mod.rs":"a056bbf718ddd775519058706bdb4909b56e6256985869e3c3132aa8ec5faca0","src/unix/linux_like/linux/uclibc/arm/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/uclibc/mips/mips32/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/uclibc/mips/mips32/mod.rs":"b84def53a49587e87f884c2bc28b21b290463b00b52e1d0309f2ba233a5b4a99","src/unix/linux_like/linux/uclibc/mips/mips32/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/uclibc/mips/mips64/align.rs":"a7bdcb18a37a2d91e64d5fad83ea3edc78f5412adb28f77ab077dbb26dd08b2d","src/unix/linux_like/linux/uclibc/mips/mips64/mod.rs":"256a428290a560163ef7dc7d18b27bd3c6ce9748a0f28d5dc7f82203ee228220","src/unix/linux_like/linux/uclibc/mips/mips64/no_align.rs":"4a18e3875698c85229599225ac3401a2a40da87e77b2ad4ef47c6fcd5a24ed30","src/unix/linux_like/linux/uclibc/mips/mod.rs":"367ec5483ad317e6ccba1ac0888da6cf088a8d32689214cc8d16129aa692260c","src/unix/linux_like/linux/uclibc/mod.rs":"1c3d25cddcfefa2bd17bdc81550826be31a08eef235e13f825f169a5029c8bca","src/unix/linux_like/linux/uclibc/no_align.rs":"3f28637046524618adaa1012e26cb7ffe94b9396e6b518cccdc69d59f274d709","src/unix/linux_like/linux/uclibc/x86_64/l4re.rs":"024eba5753e852dbdd212427351affe7e83f9916c1864bce414d7aa2618f192e","src/unix/linux_like/linux/uclibc/x86_64/mod.rs":"bf6985e901041a61e90ccee1296b35a4c62ef90aa528d31989e1d647f072e79a","src/unix/linux_like/linux/uclibc/x86_64/other.rs":"42c3f71e58cabba373f6a55a623f3c31b85049eb64824c09c2b082b3b2d6a0a8","src/unix/linux_like/mod.rs":"aabf4582a7ddf17544ee4bfa6a954f0c6e2bd17e707b7ac5266d5697e0da762a","src/unix/mod.rs":"e13a3a67c25c28dffc53a317ab07b6416b014d10dabab9bc9002157a2362c75f","src/unix/newlib/aarch64/mod.rs":"bac93836a9a57b2c710f32f852e92a4d11ad6759ab0fb6ad33e71d60e53278af","src/unix/newlib/align.rs":"28aaf87fafbc6b312622719d472d8cf65f9e5467d15339df5f73e66d8502b28a","src/unix/newlib/arm/mod.rs":"cbba6b3e957eceb496806e60de8725a23ff3fa0015983b4b4fa27b233732b526","src/unix/newlib/espidf/mod.rs":"ff9c13e99d84912f5ebe75b7a7ea9c1e9d8f35a268716081e09899c7ea822bc6","src/unix/newlib/generic.rs":"eab066d9f0a0f3eb53cc1073d01496bba0110989e1f6a59838afd19f870cd599","src/unix/newlib/horizon/mod.rs":"7cc5cc120437421db139bfa6a90b18168cd3070bdd0f5be96d40fe4c996f3ca1","src/unix/newlib/mod.rs":"54633d606e4e0413274af0b5beb5e697e6c061b63feaa0704b026554cc9d9c3e","src/unix/newlib/no_align.rs":"e0743b2179495a9514bc3a4d1781e492878c4ec834ee0085d0891dd1712e82fb","src/unix/newlib/powerpc/mod.rs":"0202ffd57caf75b6afa2c9717750ffb96e375ac33df0ae9609a3f831be393b67","src/unix/no_align.rs":"c06e95373b9088266e0b14bba0954eef95f93fb2b01d951855e382d22de78e53","src/unix/redox/mod.rs":"033768cb273daf2c8090d97252c2de9dba6809e6a5d2457f5727d724807695db","src/unix/solarish/compat.rs":"b07a5bfac925eb012003a459ba6bddbd3bfa9c44b3394da2ac5a602e54beae9c","src/unix/solarish/illumos.rs":"29387916ee7dc58f07478746024003215e631cd30953e8fa2a5c415f81839007","src/unix/solarish/mod.rs":"8914a68865af026c1f4fb1d5f02ba0053362ef34b813ad60cc4aa3a88aa4999e","src/unix/solarish/solaris.rs":"65b005453aefa9b9d4fc860fe77cfec80d8c97a51342b15daf55fc3e808bb384","src/unix/solarish/x86.rs":"e86e806df0caed72765040eaa2f3c883198d1aa91508540adf9b7008c77f522e","src/unix/solarish/x86_64.rs":"9074e813949f3c613afeac39d4118fb942c0b3c476232fc536489357cff5790f","src/unix/solarish/x86_common.rs":"ac869d9c3c95645c22460468391eb1982023c3a8e02b9e06a72e3aef3d5f1eac","src/vxworks/aarch64.rs":"98f0afdc511cd02557e506c21fed6737585490a1dce7a9d4941d08c437762b99","src/vxworks/arm.rs":"acb7968ce99fe3f4abdf39d98f8133d21a4fba435b8ef7084777cb181d788e88","src/vxworks/mod.rs":"aea3da66f2140f2a82dfc9c58f6e6531d2dd9c15ea696e0f95a0d4a2a187b5b6","src/vxworks/powerpc.rs":"acb7968ce99fe3f4abdf39d98f8133d21a4fba435b8ef7084777cb181d788e88","src/vxworks/powerpc64.rs":"98f0afdc511cd02557e506c21fed6737585490a1dce7a9d4941d08c437762b99","src/vxworks/x86.rs":"552f007f38317620b23889cb7c49d1d115841252439060122f52f434fbc6e5ba","src/vxworks/x86_64.rs":"018d92be3ad628a129eff9f2f5dfbc0883d8b8e5f2fa917b900a7f98ed6b514a","src/wasi.rs":"4fae202af0327d768ed9e1b586b75816cce14fe2dc16947d2f3d381f209a54c1","src/windows/gnu/align.rs":"b2c13ec1b9f3b39a75c452c80c951dff9d0215e31d77e883b4502afb31794647","src/windows/gnu/mod.rs":"3c8c7edb7cdf5d0c44af936db2a94869585c69dfabeef30571b4f4e38375767a","src/windows/mod.rs":"e3ad95ba54f76e74c301611fe868d3d94f6b8939b03be672f568b06b10ae71c7","src/windows/msvc/mod.rs":"c068271e00fca6b62bc4bf44bcf142cfc38caeded9b6c4e01d1ceef3ccf986f4","tests/const_fn.rs":"cb75a1f0864f926aebe79118fc34d51a0d1ade2c20a394e7774c7e545f21f1f4"},"package":"505e71a4706fa491e9b1b55f51b95d4037d0821ee40131190475f692b35b009b"} -\ No newline at end of file -+{"files":{"CONTRIBUTING.md":"f480d10d2a506eecd23ae2e2dedb7a28b8bf6dae5f46f438dbb61be2003426fb","Cargo.toml":"e1c4b3839177aabdc73c017ee87ba3dcc8025b2730cb0a2c015473f9db99f3fa","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"a8d47ff51ca256f56a8932dba07660672dbfe3004257ca8de708aac1415937a1","README.md":"776affa26b66843a2b4f1a1c8f88d92f6461b74568911450fea717e9db6f877b","build.rs":"1d0cbe878e98e970c3318cac0772215a9f44bd286d859d665da27872ba9d8818","rustfmt.toml":"eaa2ea84fc1ba0359b77680804903e07bb38d257ab11986b95b158e460f787b2","src/fixed_width_ints.rs":"7f986e5f5e68d25ef04d386fd2f640e8be8f15427a8d4a458ea01d26b8dca0ca","src/fuchsia/aarch64.rs":"378776a9e40766154a54c94c2a7b4675b5c302a38e6e42da99e67bfbaee60e56","src/fuchsia/align.rs":"ae1cf8f011a99737eabeb14ffff768e60f13b13363d7646744dbb0f443dab3d6","src/fuchsia/mod.rs":"94cbaad15021e287a1b9546a697b04c1e560f1204b52204ffaaea5975c5d03b9","src/fuchsia/no_align.rs":"303f3f1b255e0088b5715094353cf00476131d8e94e6aebb3f469557771c8b8a","src/fuchsia/x86_64.rs":"93a3632b5cf67d2a6bcb7dc0a558605252d5fe689e0f38d8aa2ec5852255ac87","src/hermit/aarch64.rs":"86048676e335944c37a63d0083d0f368ae10ceccefeed9debb3bbe08777fc682","src/hermit/mod.rs":"d3bfce41e4463d4be8020a2d063c9bfa8b665f45f1cc6cbf3163f5d01e7cb21f","src/hermit/x86_64.rs":"ab832b7524e5fb15c49ff7431165ab1a37dc4667ae0b58e8306f4c539bfa110c","src/lib.rs":"0c5306ea9d12b5261380d733dc3f7624cf259c45638eac8d9222c7e32e134a65","src/macros.rs":"b457eb028b8e8ab3c24bb7292b874ad4e491edbb83594f6a3da024df5348c088","src/psp.rs":"dd31aabd46171d474ec5828372e28588935120e7355c90c105360d8fa9264c1c","src/sgx.rs":"16a95cdefc81c5ee00d8353a60db363c4cc3e0f75abcd5d0144723f2a306ed1b","src/solid/aarch64.rs":"a726e47f324adf73a4a0b67a2c183408d0cad105ae66acf36db37a42ab7f8707","src/solid/arm.rs":"e39a4f74ebbef3b97b8c95758ad741123d84ed3eb48d9cf4f1f4872097fc27fe","src/solid/mod.rs":"5f4151dca5132e4b4e4c23ab9737e12856dddbdc0ca3f7dbc004328ef3c8acde","src/switch.rs":"9da3dd39b3de45a7928789926e8572d00e1e11a39e6f7289a1349aadce90edba","src/unix/align.rs":"2cdc7c826ef7ae61f5171c5ae8c445a743d86f1a7f2d9d7e4ceeec56d6874f65","src/unix/bsd/apple/b32/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b32/mod.rs":"2546ad3eb6aecb95f916648bc63264117c92b4b4859532b34cb011e4c75a5a72","src/unix/bsd/apple/b64/aarch64/align.rs":"e8eb38d064b5fefec6f37d42873820a0483e7c758ed336cc59a7155455ca89c9","src/unix/bsd/apple/b64/aarch64/mod.rs":"a3f0dfff62d0f7f4f1b5f9a4e2b662acf233a46badbc5419d3cc2d735629a710","src/unix/bsd/apple/b64/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b64/mod.rs":"f5e278a1af7fb358891d1c9be4eb7e815aaca0c5cb738d0c3604ba2208a856f7","src/unix/bsd/apple/b64/x86_64/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b64/x86_64/mod.rs":"8c87c5855038aae5d433c8f5eb3b29b0a175879a0245342b3bfd83bdf4cfd936","src/unix/bsd/apple/mod.rs":"e35db24ba69ee0262854916fa19a306bf6c40388f5593ab32d0907e24b5fc5c6","src/unix/bsd/freebsdlike/dragonfly/errno.rs":"8295b8bb0dfd38d2cdb4d9192cdeeb534cc6c3b208170e64615fa3e0edb3e578","src/unix/bsd/freebsdlike/dragonfly/mod.rs":"d0e8246063cae113806524a63a47c6c0628cc54a3ef03e938e89964f8b4f08b4","src/unix/bsd/freebsdlike/freebsd/aarch64.rs":"2a215bd6136b8617aacedf9be738ccee94da9d29b418e9a78101d6291c182352","src/unix/bsd/freebsdlike/freebsd/arm.rs":"59d6a670eea562fb87686e243e0a84603d29a2028a3d4b3f99ccc01bd04d2f47","src/unix/bsd/freebsdlike/freebsd/freebsd11/b64.rs":"9808d152c1196aa647f1b0f0cf84dac8c930da7d7f897a44975545e3d9d17681","src/unix/bsd/freebsdlike/freebsd/freebsd11/mod.rs":"a6eee615e6ca5a6e04b526bb6b22d13b9356e87e51825cda33476c37a46cb0ef","src/unix/bsd/freebsdlike/freebsd/freebsd12/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd12/mod.rs":"755dafaf3f0945e798c34ea94c48e8552804ce60e2a15a4f0649f9d1aceaf422","src/unix/bsd/freebsdlike/freebsd/freebsd12/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/freebsd13/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd13/mod.rs":"cc65a73b0fa95a77044a4b3ee76d6eceb9773b55aea7d73bdf070e6f66e9ea38","src/unix/bsd/freebsdlike/freebsd/freebsd13/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/freebsd14/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd14/mod.rs":"0ed92eb93e78299cd7de0ae9daebb04a53b3c2d5e6a078e1fcd977f2a86bffc3","src/unix/bsd/freebsdlike/freebsd/freebsd14/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/mod.rs":"ec229cc7af2511cb510c078e87e90ee2625090bfe94f40eb35f73d79143533aa","src/unix/bsd/freebsdlike/freebsd/powerpc.rs":"9ca3f82f88974e6db5569f2d76a5a3749b248a31747a6c0da5820492bdfeca42","src/unix/bsd/freebsdlike/freebsd/powerpc64.rs":"2dae3ecc87eac3b11657aa98915def55fc4b5c0de11fe26aae23329a54628a9a","src/unix/bsd/freebsdlike/freebsd/riscv64.rs":"8f591bd273464d684c4f64365f8ed56a8138175daa70d96008541393057a0dae","src/unix/bsd/freebsdlike/freebsd/x86.rs":"c5005e3249eb7c93cfbac72a9e9272320d80ce7983da990ceb05a447f59a02c5","src/unix/bsd/freebsdlike/freebsd/x86_64/align.rs":"0e1f69a88fca1c32874b1daf5db3d446fefbe518dca497f096cc9168c39dde70","src/unix/bsd/freebsdlike/freebsd/x86_64/mod.rs":"51e4dd0c8ae247bb652feda5adad9333ea3bb30c750c3a3935e0b0e47d7803eb","src/unix/bsd/freebsdlike/mod.rs":"1e35b4773384ea143810cdce4b96f47108b37446430da30c96a0d1651656d73d","src/unix/bsd/mod.rs":"7720ec82c9334f988ec4b271784768a017c3dc2e6dfae4d02418eef753388aa7","src/unix/bsd/netbsdlike/mod.rs":"b07a0e81085bd811fce7270f3b90fbfea29faf9593d9e39d9d2ebbb9a78bf25f","src/unix/bsd/netbsdlike/netbsd/aarch64.rs":"65dcb58d11e8d8028401a9d07ca3eb4cb4f053e04249cc877353449d84ccc4cb","src/unix/bsd/netbsdlike/netbsd/arm.rs":"58cdbb70b0d6f536551f0f3bb3725d2d75c4690db12c26c034e7d6ec4a924452","src/unix/bsd/netbsdlike/netbsd/mod.rs":"8f9613e50c2771b33d7cf817a735d536b389ec57f861b9486d870373c768276e","src/unix/bsd/netbsdlike/netbsd/powerpc.rs":"ee7ff5d89d0ed22f531237b5059aa669df93a3b5c489fa641465ace8d405bf41","src/unix/bsd/netbsdlike/netbsd/sparc64.rs":"9489f4b3e4566f43bb12dfb92238960613dac7f6a45cc13068a8d152b902d7d9","src/unix/bsd/netbsdlike/netbsd/x86.rs":"20692320e36bfe028d1a34d16fe12ca77aa909cb02bda167376f98f1a09aefe7","src/unix/bsd/netbsdlike/netbsd/x86_64.rs":"1afe5ef46b14397cdd68664b5b232e4f5b035b6db1d4cf411c899d51ebca9f30","src/unix/bsd/netbsdlike/openbsd/aarch64.rs":"dd91931d373b7ecaf6e2de25adadee10d16fa9b12c2cbacdff3eb291e1ba36af","src/unix/bsd/netbsdlike/openbsd/arm.rs":"01580d261bc6447bb327a0d982181b7bdabfa066cee65a30373d3ced729ad307","src/unix/bsd/netbsdlike/openbsd/mips64.rs":"8532a189ae10c7d668d9d4065da8b05d124e09bd39442c9f74a7f231c43eca48","src/unix/bsd/netbsdlike/openbsd/mod.rs":"228505fa48292e74b06acbed96196801595a4b822da2126a6d6c7fa773cff8bc","src/unix/bsd/netbsdlike/openbsd/powerpc.rs":"01580d261bc6447bb327a0d982181b7bdabfa066cee65a30373d3ced729ad307","src/unix/bsd/netbsdlike/openbsd/powerpc64.rs":"1dd5449dd1fd3d51e30ffdeeaece91d0aaf05c710e0ac699fecc5461cfa2c28e","src/unix/bsd/netbsdlike/openbsd/riscv64.rs":"1dd5449dd1fd3d51e30ffdeeaece91d0aaf05c710e0ac699fecc5461cfa2c28e","src/unix/bsd/netbsdlike/openbsd/sparc64.rs":"d04fd287afbaa2c5df9d48c94e8374a532a3ba491b424ddf018270c7312f4085","src/unix/bsd/netbsdlike/openbsd/x86.rs":"6f7f5c4fde2a2259eb547890cbd86570cea04ef85347d7569e94e679448bec87","src/unix/bsd/netbsdlike/openbsd/x86_64.rs":"d31db31630289c85af3339dbe357998a21ca584cbae31607448fe2cf7675a4e1","src/unix/haiku/b32.rs":"a2efdbf7158a6da341e1db9176b0ab193ba88b449616239ed95dced11f54d87b","src/unix/haiku/b64.rs":"ff8115367d3d7d354f792d6176dfaaa26353f57056197b563bf4681f91ff7985","src/unix/haiku/mod.rs":"69cc3638c6f7e2086ada7bacf5ea01ce1b7f5d045fd012c6f46b8635d30ce594","src/unix/haiku/native.rs":"dbfcbf4954a79d1df2ff58e0590bbcb8c57dfc7a32392aa73ee4726b66bd6cc8","src/unix/haiku/x86_64.rs":"3ec3aeeb7ed208b8916f3e32d42bfd085ff5e16936a1a35d9a52789f043b7237","src/unix/hermit/aarch64.rs":"86048676e335944c37a63d0083d0f368ae10ceccefeed9debb3bbe08777fc682","src/unix/hermit/mod.rs":"859814f5df89e28fd4b345db399d181e11e7ed413841b6ff703a1fcbdbf013ae","src/unix/hermit/x86_64.rs":"ab832b7524e5fb15c49ff7431165ab1a37dc4667ae0b58e8306f4c539bfa110c","src/unix/linux_like/android/b32/arm.rs":"433c1530f602cc5ed26610c58055dde0c4ceea5e00150063b24ddc60768332a4","src/unix/linux_like/android/b32/mod.rs":"7c173e0375119bf06a3081652faede95e5bcd6858e7576b7533d037978737c8f","src/unix/linux_like/android/b32/x86/align.rs":"812914e4241df82e32b12375ca3374615dc3a4bdd4cf31f0423c5815320c0dab","src/unix/linux_like/android/b32/x86/mod.rs":"8388bd3a0fcb5636bf965eee6dc95ae6860b85a2b555b387c868aa4d4e01ec89","src/unix/linux_like/android/b64/aarch64/align.rs":"2179c3b1608fa4bf68840482bfc2b2fa3ee2faf6fcae3770f9e505cddca35c7b","src/unix/linux_like/android/b64/aarch64/int128.rs":"1735f6f5c56770d20dd426442f09724d9b2052b46a7cd82f23f3288a4a7276de","src/unix/linux_like/android/b64/aarch64/mod.rs":"ef230d49fd0d182adf2dae6f8e10babf18d72259d65980bf1c4c2dc8a4f84501","src/unix/linux_like/android/b64/mod.rs":"d7bbbadafdb2cb2ff8e9cde3d89a03b9facaabb6b2d45705225d3ece1c5cce37","src/unix/linux_like/android/b64/x86_64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/android/b64/x86_64/mod.rs":"e10d19bea39f719723ab6666a5ddbd378b6958769441c5904629e1df173b1dc2","src/unix/linux_like/android/mod.rs":"962741303dc24a5b9653f2e9b0b4ad9eb42fc54daa0a70ca70a7ce175e75094b","src/unix/linux_like/emscripten/align.rs":"86c95cbed7a7161b1f23ee06843e7b0e2340ad92b2cb86fe2a8ef3e0e8c36216","src/unix/linux_like/emscripten/mod.rs":"c69c90606d4362f8de89b8816df0ded724ed64b53bf55d15681fde171b7bb361","src/unix/linux_like/emscripten/no_align.rs":"0128e4aa721a9902754828b61b5ec7d8a86619983ed1e0544a85d35b1051fad6","src/unix/linux_like/linux/align.rs":"d6c259942c8e843373accd180fc8f4f45f03544dfd21b93a8d02641ead3ef63e","src/unix/linux_like/linux/arch/generic/mod.rs":"e20013ed91edcfb7f84f3f9f5a9ef827fd5c406e24b65989d8438da332236ef6","src/unix/linux_like/linux/arch/mips/mod.rs":"2d166054a586bb4bf6e4a4ba35f7574907b217225eff8f1a43adc4277e142460","src/unix/linux_like/linux/arch/mod.rs":"466a29622e47c6c7f1500682b2eb17f5566dd81b322cd6348f0fdd355cec593a","src/unix/linux_like/linux/arch/powerpc/mod.rs":"3f6da7b0fa7b394c7d4eea2bb3caa7a7729ab0d6c1491fef02206a912c41b815","src/unix/linux_like/linux/arch/sparc/mod.rs":"91593ec0440f1dd8f8e612028f432c44c14089286e2aca50e10511ab942db8c3","src/unix/linux_like/linux/gnu/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/gnu/b32/arm/align.rs":"6ec0eb3ee93f7ae99fd714b4deabfb5e97fbcefd8c26f5a45fb8e7150899cdeb","src/unix/linux_like/linux/gnu/b32/arm/mod.rs":"92ea7edc0e24f79dfbf5e3efc2d7509bed230562036e6aa85ef4f2c8088ecc8f","src/unix/linux_like/linux/gnu/b32/m68k/align.rs":"8faa92f77a9232c035418d45331774e64a9a841d99c91791570a203bf2b45bcb","src/unix/linux_like/linux/gnu/b32/m68k/mod.rs":"a2a0a9400dae44086ebf579e0448e0676d4a3214d1ae7d13a024857251e23b6b","src/unix/linux_like/linux/gnu/b32/mips/align.rs":"429fb5e005cb7143602d430098b6ebfb7d360685b194f333dfd587472ae954ee","src/unix/linux_like/linux/gnu/b32/mips/mod.rs":"0d7849eb2435ec1f49b6774872a0518f0129c50f37c9d38b37b1535722777a22","src/unix/linux_like/linux/gnu/b32/mod.rs":"8da281da578cdee972e952b118b903b370320897a7e335342a15e1359864bef2","src/unix/linux_like/linux/gnu/b32/powerpc.rs":"049d6211ba4a9304bd4497c160bc21ae847c24e0528dd9d76263f16192e6aff5","src/unix/linux_like/linux/gnu/b32/riscv32/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/gnu/b32/riscv32/mod.rs":"a4256148cec0bb672c8dfa605866930d9761af9655721de72ae41eeeb8fdbf6d","src/unix/linux_like/linux/gnu/b32/sparc/align.rs":"21adbed27df73e2d1ed934aaf733a643003d7baf2bde9c48ea440895bcca6d41","src/unix/linux_like/linux/gnu/b32/sparc/mod.rs":"525618615aa0cb80c6c90860bf579dfed8db307fffd56b97dc235fb945419434","src/unix/linux_like/linux/gnu/b32/x86/align.rs":"e4bafdc4a519a7922a81b37a62bbfd1177a2f620890eef8f1fbc47162e9eb413","src/unix/linux_like/linux/gnu/b32/x86/mod.rs":"78b4038852986436888c63be9258037cf642124daee9d5fa5cef2bf8e412bf54","src/unix/linux_like/linux/gnu/b64/aarch64/align.rs":"5b32fcc0d60356c92ded4e0ba9bb32f0140a8bd75ba800486bf38294f61dbdbb","src/unix/linux_like/linux/gnu/b64/aarch64/ilp32.rs":"21a21503ef2e095f4371044915d4bfb07a8578011cb5c713cd9f45947b0b5730","src/unix/linux_like/linux/gnu/b64/aarch64/int128.rs":"1735f6f5c56770d20dd426442f09724d9b2052b46a7cd82f23f3288a4a7276de","src/unix/linux_like/linux/gnu/b64/aarch64/lp64.rs":"e78c3cd197f44832338b414d1a9bc0d194f44c74db77bd7bf830c1fff62b2690","src/unix/linux_like/linux/gnu/b64/aarch64/mod.rs":"c72a08011c32f82919e930e0d89044d8feb65fd41bf80647436756c290344eb8","src/unix/linux_like/linux/gnu/b64/loongarch64/align.rs":"62e822478356db4a73b6bbd1b36d825b893939ab4b308ec11b0578bcc4b49769","src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs":"d92686cfa34bbd3f1cf58d7373d7eb7135437f0f5f296d83ffc53354f966619f","src/unix/linux_like/linux/gnu/b64/mips64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/linux/gnu/b64/mips64/mod.rs":"17aad16329431d83e1909e3a08022f6e28f4bcba7dec4a967fe1a321a6a43b99","src/unix/linux_like/linux/gnu/b64/mod.rs":"3c6555f30a7a8852757b31a542ea73fb6a16a6e27e838397e819278ad56e57a4","src/unix/linux_like/linux/gnu/b64/powerpc64/align.rs":"e29c4868bbecfa4a6cd8a2ad06193f3bbc78a468cc1dc9df83f002f1268130d9","src/unix/linux_like/linux/gnu/b64/powerpc64/mod.rs":"97e0ecf11ecce793a13fec39654fb513c5479edf7faa7a276fa714b61993d0fc","src/unix/linux_like/linux/gnu/b64/riscv64/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/gnu/b64/riscv64/mod.rs":"b3fe290afe63d2d6e315d0cf1f775464e9c1f2a1906d243c1af74a137a4031cb","src/unix/linux_like/linux/gnu/b64/s390x.rs":"254f00266ecf9644a4b469457cb37c4dd6c055820926c1de0fb9035b6048e75c","src/unix/linux_like/linux/gnu/b64/sparc64/align.rs":"e29c4868bbecfa4a6cd8a2ad06193f3bbc78a468cc1dc9df83f002f1268130d9","src/unix/linux_like/linux/gnu/b64/sparc64/mod.rs":"87dd7f3d5bf3c09f4064ec738e306cc9cc41ad49b4a5df62c5983301c3bbf99a","src/unix/linux_like/linux/gnu/b64/x86_64/align.rs":"62e822478356db4a73b6bbd1b36d825b893939ab4b308ec11b0578bcc4b49769","src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs":"f0db9914315d5a3d51bf5ec04a0ae6584f2e1688b9258ce132b617e67d9bd7a9","src/unix/linux_like/linux/gnu/b64/x86_64/not_x32.rs":"b88ef8a1eaa9ed73bf2acb8192afb73af987a92abb94140c6376fc83f2fa5553","src/unix/linux_like/linux/gnu/b64/x86_64/x32.rs":"79305936a60d342efdc10519ba89507d6b48e65f13f33090d3b04dc9655ceed0","src/unix/linux_like/linux/gnu/mod.rs":"1ca6821fbb94476500d4352908e713b7c698cb7ff0a49997934126391657c573","src/unix/linux_like/linux/gnu/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/mod.rs":"758e222200a8cbb74b1eb01581da92fea895619da866bc383129d4b9a5366aef","src/unix/linux_like/linux/musl/b32/arm/align.rs":"3e8ac052c1043764776b54c93ba4260e061df998631737a897d9d47d54f7b80c","src/unix/linux_like/linux/musl/b32/arm/mod.rs":"e5faee8efda8a225ea0b17d4d6f9e893a678e73773fa62c549a8e19c106b9f04","src/unix/linux_like/linux/musl/b32/hexagon.rs":"226a8b64ce9c75abbbee6d2dceb0b44f7b6c750c4102ebd4d015194afee6666e","src/unix/linux_like/linux/musl/b32/mips/align.rs":"429fb5e005cb7143602d430098b6ebfb7d360685b194f333dfd587472ae954ee","src/unix/linux_like/linux/musl/b32/mips/mod.rs":"df8f8b529a6cc6b8a7326639e83303cf1320c6c50d76517c17d42bcf45f6240a","src/unix/linux_like/linux/musl/b32/mod.rs":"7b3d9dfd8605b00bb9b5fa1439abe5ebf60199c7fa033eee555e8d181e93ffa2","src/unix/linux_like/linux/musl/b32/powerpc.rs":"c957d99a4d4371d2411a5769be8cf344516bf9ddc1011f977501a4eb57cb4e82","src/unix/linux_like/linux/musl/b32/riscv32/align.rs":"efd2accf33b87de7c7547903359a5da896edc33cd6c719552c7474b60d4a5d48","src/unix/linux_like/linux/musl/b32/riscv32/mod.rs":"698f77bfcc838f82126c54f7387881fe3e89490117e5a4f333d1b4433823a672","src/unix/linux_like/linux/musl/b32/x86/align.rs":"08e77fbd7435d7dec2ff56932433bece3f02e47ce810f89004a275a86d39cbe1","src/unix/linux_like/linux/musl/b32/x86/mod.rs":"199a91e90b454f9dc32770d5204cc4f6e5b8f144e0e34a1c91829949d6e804b3","src/unix/linux_like/linux/musl/b64/aarch64/align.rs":"6ba32725d24d7d8e6aa111f3b57aafa318f83b606abe96561329151829821133","src/unix/linux_like/linux/musl/b64/aarch64/int128.rs":"1735f6f5c56770d20dd426442f09724d9b2052b46a7cd82f23f3288a4a7276de","src/unix/linux_like/linux/musl/b64/aarch64/mod.rs":"9c4878df0fea0e0affd85346e0bc191abdc5e41e74dc9199b5644ec33d29c300","src/unix/linux_like/linux/musl/b64/mips64.rs":"3686fc8cb2e311cda8e6b96f6dfe90b65a366714bd480312b692b1a6ca1241b6","src/unix/linux_like/linux/musl/b64/mod.rs":"8c10627bd582cb272514e7350ae4743a65d489356eae039d2e7e55cd533fbbc8","src/unix/linux_like/linux/musl/b64/powerpc64.rs":"36694cbdcdc33879e00502d55cb95eaa0096d213538993dd39c3da800cdd06d1","src/unix/linux_like/linux/musl/b64/riscv64/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/musl/b64/riscv64/mod.rs":"36621aca8ecf714f8dd42662dc2997833d95b9f129ef8c220503362e21efd695","src/unix/linux_like/linux/musl/b64/s390x.rs":"c7ebabc4e1bdbbd97e5065faa3a57f41f473570920582d979f9e9d4f77448546","src/unix/linux_like/linux/musl/b64/x86_64/align.rs":"77309276ad7a42cbe59ca381f23590b7a143aded05555b34a5b307b808cbca6e","src/unix/linux_like/linux/musl/b64/x86_64/mod.rs":"238789097a26abc8b7cd578ed1a8e6cb8672083054303902781983902cd66854","src/unix/linux_like/linux/musl/mod.rs":"c3365480375bc258ffe267e7a299d7b3bb542a908bef8881f503ddc25ba8fc1f","src/unix/linux_like/linux/no_align.rs":"da2a8721becaaaa528781f97f5d9aae6a982ae5d4f5f6d2ffc0150bed72319b3","src/unix/linux_like/linux/non_exhaustive.rs":"181a05bf94fdb911db83ce793b993bd6548a4115b306a7ef3c10f745a8fea3e9","src/unix/linux_like/linux/uclibc/align.rs":"9ed16138d8e439bd90930845a65eafa7ebd67366e6bf633936d44014f6e4c959","src/unix/linux_like/linux/uclibc/arm/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/uclibc/arm/mod.rs":"a056bbf718ddd775519058706bdb4909b56e6256985869e3c3132aa8ec5faca0","src/unix/linux_like/linux/uclibc/arm/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/uclibc/mips/mips32/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/uclibc/mips/mips32/mod.rs":"b84def53a49587e87f884c2bc28b21b290463b00b52e1d0309f2ba233a5b4a99","src/unix/linux_like/linux/uclibc/mips/mips32/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/uclibc/mips/mips64/align.rs":"a7bdcb18a37a2d91e64d5fad83ea3edc78f5412adb28f77ab077dbb26dd08b2d","src/unix/linux_like/linux/uclibc/mips/mips64/mod.rs":"256a428290a560163ef7dc7d18b27bd3c6ce9748a0f28d5dc7f82203ee228220","src/unix/linux_like/linux/uclibc/mips/mips64/no_align.rs":"4a18e3875698c85229599225ac3401a2a40da87e77b2ad4ef47c6fcd5a24ed30","src/unix/linux_like/linux/uclibc/mips/mod.rs":"367ec5483ad317e6ccba1ac0888da6cf088a8d32689214cc8d16129aa692260c","src/unix/linux_like/linux/uclibc/mod.rs":"1c3d25cddcfefa2bd17bdc81550826be31a08eef235e13f825f169a5029c8bca","src/unix/linux_like/linux/uclibc/no_align.rs":"3f28637046524618adaa1012e26cb7ffe94b9396e6b518cccdc69d59f274d709","src/unix/linux_like/linux/uclibc/x86_64/l4re.rs":"024eba5753e852dbdd212427351affe7e83f9916c1864bce414d7aa2618f192e","src/unix/linux_like/linux/uclibc/x86_64/mod.rs":"bf6985e901041a61e90ccee1296b35a4c62ef90aa528d31989e1d647f072e79a","src/unix/linux_like/linux/uclibc/x86_64/other.rs":"42c3f71e58cabba373f6a55a623f3c31b85049eb64824c09c2b082b3b2d6a0a8","src/unix/linux_like/mod.rs":"aabf4582a7ddf17544ee4bfa6a954f0c6e2bd17e707b7ac5266d5697e0da762a","src/unix/mod.rs":"e13a3a67c25c28dffc53a317ab07b6416b014d10dabab9bc9002157a2362c75f","src/unix/newlib/aarch64/mod.rs":"bac93836a9a57b2c710f32f852e92a4d11ad6759ab0fb6ad33e71d60e53278af","src/unix/newlib/align.rs":"28aaf87fafbc6b312622719d472d8cf65f9e5467d15339df5f73e66d8502b28a","src/unix/newlib/arm/mod.rs":"cbba6b3e957eceb496806e60de8725a23ff3fa0015983b4b4fa27b233732b526","src/unix/newlib/espidf/mod.rs":"ff9c13e99d84912f5ebe75b7a7ea9c1e9d8f35a268716081e09899c7ea822bc6","src/unix/newlib/generic.rs":"eab066d9f0a0f3eb53cc1073d01496bba0110989e1f6a59838afd19f870cd599","src/unix/newlib/horizon/mod.rs":"7cc5cc120437421db139bfa6a90b18168cd3070bdd0f5be96d40fe4c996f3ca1","src/unix/newlib/mod.rs":"54633d606e4e0413274af0b5beb5e697e6c061b63feaa0704b026554cc9d9c3e","src/unix/newlib/no_align.rs":"e0743b2179495a9514bc3a4d1781e492878c4ec834ee0085d0891dd1712e82fb","src/unix/newlib/powerpc/mod.rs":"0202ffd57caf75b6afa2c9717750ffb96e375ac33df0ae9609a3f831be393b67","src/unix/no_align.rs":"c06e95373b9088266e0b14bba0954eef95f93fb2b01d951855e382d22de78e53","src/unix/redox/mod.rs":"033768cb273daf2c8090d97252c2de9dba6809e6a5d2457f5727d724807695db","src/unix/solarish/compat.rs":"b07a5bfac925eb012003a459ba6bddbd3bfa9c44b3394da2ac5a602e54beae9c","src/unix/solarish/illumos.rs":"29387916ee7dc58f07478746024003215e631cd30953e8fa2a5c415f81839007","src/unix/solarish/mod.rs":"8914a68865af026c1f4fb1d5f02ba0053362ef34b813ad60cc4aa3a88aa4999e","src/unix/solarish/solaris.rs":"65b005453aefa9b9d4fc860fe77cfec80d8c97a51342b15daf55fc3e808bb384","src/unix/solarish/x86.rs":"e86e806df0caed72765040eaa2f3c883198d1aa91508540adf9b7008c77f522e","src/unix/solarish/x86_64.rs":"9074e813949f3c613afeac39d4118fb942c0b3c476232fc536489357cff5790f","src/unix/solarish/x86_common.rs":"ac869d9c3c95645c22460468391eb1982023c3a8e02b9e06a72e3aef3d5f1eac","src/vxworks/aarch64.rs":"98f0afdc511cd02557e506c21fed6737585490a1dce7a9d4941d08c437762b99","src/vxworks/arm.rs":"acb7968ce99fe3f4abdf39d98f8133d21a4fba435b8ef7084777cb181d788e88","src/vxworks/mod.rs":"aea3da66f2140f2a82dfc9c58f6e6531d2dd9c15ea696e0f95a0d4a2a187b5b6","src/vxworks/powerpc.rs":"acb7968ce99fe3f4abdf39d98f8133d21a4fba435b8ef7084777cb181d788e88","src/vxworks/powerpc64.rs":"98f0afdc511cd02557e506c21fed6737585490a1dce7a9d4941d08c437762b99","src/vxworks/x86.rs":"552f007f38317620b23889cb7c49d1d115841252439060122f52f434fbc6e5ba","src/vxworks/x86_64.rs":"018d92be3ad628a129eff9f2f5dfbc0883d8b8e5f2fa917b900a7f98ed6b514a","src/wasi.rs":"4fae202af0327d768ed9e1b586b75816cce14fe2dc16947d2f3d381f209a54c1","src/windows/gnu/align.rs":"b2c13ec1b9f3b39a75c452c80c951dff9d0215e31d77e883b4502afb31794647","src/windows/gnu/mod.rs":"3c8c7edb7cdf5d0c44af936db2a94869585c69dfabeef30571b4f4e38375767a","src/windows/mod.rs":"e3ad95ba54f76e74c301611fe868d3d94f6b8939b03be672f568b06b10ae71c7","src/windows/msvc/mod.rs":"c068271e00fca6b62bc4bf44bcf142cfc38caeded9b6c4e01d1ceef3ccf986f4","tests/const_fn.rs":"cb75a1f0864f926aebe79118fc34d51a0d1ade2c20a394e7774c7e545f21f1f4"},"package":"505e71a4706fa491e9b1b55f51b95d4037d0821ee40131190475f692b35b009b"} -diff --git a/vendor/libc-0.2.127/src/unix/linux_like/linux/gnu/b64/loongarch64/align.rs b/vendor/libc-0.2.127/src/unix/linux_like/linux/gnu/b64/loongarch64/align.rs -index 7ca870fd0..ba3075edd 100644 ---- a/vendor/libc-0.2.127/src/unix/linux_like/linux/gnu/b64/loongarch64/align.rs -+++ b/vendor/libc-0.2.127/src/unix/linux_like/linux/gnu/b64/loongarch64/align.rs -@@ -5,3 +5,20 @@ s_no_extra_traits! { - priv_: [f64; 4] - } - } -+ -+s! { -+ #[repr(align(8))] -+ pub struct clone_args { -+ pub flags: ::c_ulonglong, -+ pub pidfd: ::c_ulonglong, -+ pub child_tid: ::c_ulonglong, -+ pub parent_tid: ::c_ulonglong, -+ pub exit_signal: ::c_ulonglong, -+ pub stack: ::c_ulonglong, -+ pub stack_size: ::c_ulonglong, -+ pub tls: ::c_ulonglong, -+ pub set_tid: ::c_ulonglong, -+ pub set_tid_size: ::c_ulonglong, -+ pub cgroup: ::c_ulonglong, -+ } -+} -diff --git a/vendor/libc-0.2.127/src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs b/vendor/libc-0.2.127/src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs -index 2ed6a9156..ff520e0c6 100644 ---- a/vendor/libc-0.2.127/src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs -+++ b/vendor/libc-0.2.127/src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs -@@ -247,6 +247,20 @@ align_const! { - }; - } - -+pub const HWCAP_LOONGARCH_CPUCFG: ::c_ulong = 1 << 0; -+pub const HWCAP_LOONGARCH_LAM: ::c_ulong = 1 << 1; -+pub const HWCAP_LOONGARCH_UAL: ::c_ulong = 1 << 2; -+pub const HWCAP_LOONGARCH_FPU: ::c_ulong = 1 << 3; -+pub const HWCAP_LOONGARCH_LSX: ::c_ulong = 1 << 4; -+pub const HWCAP_LOONGARCH_LASX: ::c_ulong = 1 << 5; -+pub const HWCAP_LOONGARCH_CRC32: ::c_ulong = 1 << 6; -+pub const HWCAP_LOONGARCH_COMPLEX: ::c_ulong = 1 << 7; -+pub const HWCAP_LOONGARCH_CRYPTO: ::c_ulong = 1 << 8; -+pub const HWCAP_LOONGARCH_LVZ: ::c_ulong = 1 << 9; -+pub const HWCAP_LOONGARCH_LBT_X86: ::c_ulong = 1 << 10; -+pub const HWCAP_LOONGARCH_LBT_ARM: ::c_ulong = 1 << 11; -+pub const HWCAP_LOONGARCH_LBT_MIPS: ::c_ulong = 1 << 12; -+ - pub const SYS_io_setup: ::c_long = 0; - pub const SYS_io_destroy: ::c_long = 1; - pub const SYS_io_submit: ::c_long = 2; -@@ -587,6 +601,8 @@ pub const F_OFD_GETLK: ::c_int = 36; - pub const F_OFD_SETLK: ::c_int = 37; - pub const F_OFD_SETLKW: ::c_int = 38; - -+pub const MADV_SOFT_OFFLINE: ::c_int = 101; -+ - pub const EDEADLK: ::c_int = 35; - pub const EDEADLOCK: ::c_int = 35; - pub const ENAMETOOLONG: ::c_int = 36; -diff --git a/vendor/libc/.cargo-checksum.json b/vendor/libc/.cargo-checksum.json -index 631af7226..824a6e056 100644 ---- a/vendor/libc/.cargo-checksum.json -+++ b/vendor/libc/.cargo-checksum.json -@@ -1 +1 @@ --{"files":{"CONTRIBUTING.md":"f480d10d2a506eecd23ae2e2dedb7a28b8bf6dae5f46f438dbb61be2003426fb","Cargo.toml":"04fa9ce26b0efcfe3dd51e3f1bbb81bb36f5d61982a11947283c7616d390549e","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"a8d47ff51ca256f56a8932dba07660672dbfe3004257ca8de708aac1415937a1","README.md":"776affa26b66843a2b4f1a1c8f88d92f6461b74568911450fea717e9db6f877b","build.rs":"1d0cbe878e98e970c3318cac0772215a9f44bd286d859d665da27872ba9d8818","rustfmt.toml":"eaa2ea84fc1ba0359b77680804903e07bb38d257ab11986b95b158e460f787b2","src/fixed_width_ints.rs":"7f986e5f5e68d25ef04d386fd2f640e8be8f15427a8d4a458ea01d26b8dca0ca","src/fuchsia/aarch64.rs":"378776a9e40766154a54c94c2a7b4675b5c302a38e6e42da99e67bfbaee60e56","src/fuchsia/align.rs":"ae1cf8f011a99737eabeb14ffff768e60f13b13363d7646744dbb0f443dab3d6","src/fuchsia/mod.rs":"cf7e0df0e655337d1c0852880817b6b514ef9599e2125232fc79cdf8eddd01ba","src/fuchsia/no_align.rs":"303f3f1b255e0088b5715094353cf00476131d8e94e6aebb3f469557771c8b8a","src/fuchsia/x86_64.rs":"93a3632b5cf67d2a6bcb7dc0a558605252d5fe689e0f38d8aa2ec5852255ac87","src/hermit/aarch64.rs":"86048676e335944c37a63d0083d0f368ae10ceccefeed9debb3bbe08777fc682","src/hermit/mod.rs":"d3bfce41e4463d4be8020a2d063c9bfa8b665f45f1cc6cbf3163f5d01e7cb21f","src/hermit/x86_64.rs":"ab832b7524e5fb15c49ff7431165ab1a37dc4667ae0b58e8306f4c539bfa110c","src/lib.rs":"ce753ef318b300bbd441feabdd77d00322dfb6ce9eee8c78a38afe02b57aa4c0","src/macros.rs":"b457eb028b8e8ab3c24bb7292b874ad4e491edbb83594f6a3da024df5348c088","src/psp.rs":"dd31aabd46171d474ec5828372e28588935120e7355c90c105360d8fa9264c1c","src/sgx.rs":"16a95cdefc81c5ee00d8353a60db363c4cc3e0f75abcd5d0144723f2a306ed1b","src/solid/aarch64.rs":"a726e47f324adf73a4a0b67a2c183408d0cad105ae66acf36db37a42ab7f8707","src/solid/arm.rs":"e39a4f74ebbef3b97b8c95758ad741123d84ed3eb48d9cf4f1f4872097fc27fe","src/solid/mod.rs":"5f4151dca5132e4b4e4c23ab9737e12856dddbdc0ca3f7dbc004328ef3c8acde","src/switch.rs":"9da3dd39b3de45a7928789926e8572d00e1e11a39e6f7289a1349aadce90edba","src/unix/align.rs":"2cdc7c826ef7ae61f5171c5ae8c445a743d86f1a7f2d9d7e4ceeec56d6874f65","src/unix/bsd/apple/b32/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b32/mod.rs":"2546ad3eb6aecb95f916648bc63264117c92b4b4859532b34cb011e4c75a5a72","src/unix/bsd/apple/b64/aarch64/align.rs":"e8eb38d064b5fefec6f37d42873820a0483e7c758ed336cc59a7155455ca89c9","src/unix/bsd/apple/b64/aarch64/mod.rs":"a3f0dfff62d0f7f4f1b5f9a4e2b662acf233a46badbc5419d3cc2d735629a710","src/unix/bsd/apple/b64/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b64/mod.rs":"f5e278a1af7fb358891d1c9be4eb7e815aaca0c5cb738d0c3604ba2208a856f7","src/unix/bsd/apple/b64/x86_64/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b64/x86_64/mod.rs":"8c87c5855038aae5d433c8f5eb3b29b0a175879a0245342b3bfd83bdf4cfd936","src/unix/bsd/apple/mod.rs":"bb61eec399428faee753b3df509410c51ed2ac51406d40559fcec290bb50e293","src/unix/bsd/freebsdlike/dragonfly/errno.rs":"8295b8bb0dfd38d2cdb4d9192cdeeb534cc6c3b208170e64615fa3e0edb3e578","src/unix/bsd/freebsdlike/dragonfly/mod.rs":"e4f33050d52d3e5c932da8d10e1f377e1ff609fb178ea986bfc458d31e37dc19","src/unix/bsd/freebsdlike/freebsd/aarch64.rs":"2a215bd6136b8617aacedf9be738ccee94da9d29b418e9a78101d6291c182352","src/unix/bsd/freebsdlike/freebsd/arm.rs":"59d6a670eea562fb87686e243e0a84603d29a2028a3d4b3f99ccc01bd04d2f47","src/unix/bsd/freebsdlike/freebsd/freebsd11/b64.rs":"9808d152c1196aa647f1b0f0cf84dac8c930da7d7f897a44975545e3d9d17681","src/unix/bsd/freebsdlike/freebsd/freebsd11/mod.rs":"23f189f188651762b38f40b4e9aba785625f6f9a52558a4a490510c3b1d08b53","src/unix/bsd/freebsdlike/freebsd/freebsd12/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd12/mod.rs":"57fee9dd251ac615ec7d32d293e0f0b6fa3bf28efbddd6d569765765aafb8b9b","src/unix/bsd/freebsdlike/freebsd/freebsd12/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/freebsd13/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd13/mod.rs":"7df84dd6dee8b73fd4d72dd1638584d788e2a1a85f95746f7c5b330b8dc23655","src/unix/bsd/freebsdlike/freebsd/freebsd13/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/freebsd14/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd14/mod.rs":"236ef119410d566ef94064bf13d734635eaeecb3635a5d21e8e9f91e7e3152ac","src/unix/bsd/freebsdlike/freebsd/freebsd14/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/mod.rs":"6a8eb9a1e35eec893de9c76a5be3ce29e4c3ca26db45fbcfa925bdd757f6352d","src/unix/bsd/freebsdlike/freebsd/powerpc.rs":"9ca3f82f88974e6db5569f2d76a5a3749b248a31747a6c0da5820492bdfeca42","src/unix/bsd/freebsdlike/freebsd/powerpc64.rs":"2dae3ecc87eac3b11657aa98915def55fc4b5c0de11fe26aae23329a54628a9a","src/unix/bsd/freebsdlike/freebsd/riscv64.rs":"8f591bd273464d684c4f64365f8ed56a8138175daa70d96008541393057a0dae","src/unix/bsd/freebsdlike/freebsd/x86.rs":"c5005e3249eb7c93cfbac72a9e9272320d80ce7983da990ceb05a447f59a02c5","src/unix/bsd/freebsdlike/freebsd/x86_64/align.rs":"0e1f69a88fca1c32874b1daf5db3d446fefbe518dca497f096cc9168c39dde70","src/unix/bsd/freebsdlike/freebsd/x86_64/mod.rs":"51e4dd0c8ae247bb652feda5adad9333ea3bb30c750c3a3935e0b0e47d7803eb","src/unix/bsd/freebsdlike/mod.rs":"a61d41f6fe01c06c6de5db2ed970522601eada133e6bac4ed2d1dfaceb576db2","src/unix/bsd/mod.rs":"817ca5719c36a74c84e52c6a56a5998b60d7f02351a405e034f08ebab079b63a","src/unix/bsd/netbsdlike/mod.rs":"b07a0e81085bd811fce7270f3b90fbfea29faf9593d9e39d9d2ebbb9a78bf25f","src/unix/bsd/netbsdlike/netbsd/aarch64.rs":"65dcb58d11e8d8028401a9d07ca3eb4cb4f053e04249cc877353449d84ccc4cb","src/unix/bsd/netbsdlike/netbsd/arm.rs":"58cdbb70b0d6f536551f0f3bb3725d2d75c4690db12c26c034e7d6ec4a924452","src/unix/bsd/netbsdlike/netbsd/mod.rs":"fa260decf53280d4fdf714af60f42d4774f8d6f2da71b0a55a6c2a85e422eb57","src/unix/bsd/netbsdlike/netbsd/powerpc.rs":"ee7ff5d89d0ed22f531237b5059aa669df93a3b5c489fa641465ace8d405bf41","src/unix/bsd/netbsdlike/netbsd/sparc64.rs":"9489f4b3e4566f43bb12dfb92238960613dac7f6a45cc13068a8d152b902d7d9","src/unix/bsd/netbsdlike/netbsd/x86.rs":"20692320e36bfe028d1a34d16fe12ca77aa909cb02bda167376f98f1a09aefe7","src/unix/bsd/netbsdlike/netbsd/x86_64.rs":"1afe5ef46b14397cdd68664b5b232e4f5b035b6db1d4cf411c899d51ebca9f30","src/unix/bsd/netbsdlike/openbsd/aarch64.rs":"dd91931d373b7ecaf6e2de25adadee10d16fa9b12c2cbacdff3eb291e1ba36af","src/unix/bsd/netbsdlike/openbsd/arm.rs":"01580d261bc6447bb327a0d982181b7bdabfa066cee65a30373d3ced729ad307","src/unix/bsd/netbsdlike/openbsd/mips64.rs":"8532a189ae10c7d668d9d4065da8b05d124e09bd39442c9f74a7f231c43eca48","src/unix/bsd/netbsdlike/openbsd/mod.rs":"079b11c99c6ca3cc5942c0e6d854541f8765c5058c2f024b84656697840e198b","src/unix/bsd/netbsdlike/openbsd/powerpc.rs":"01580d261bc6447bb327a0d982181b7bdabfa066cee65a30373d3ced729ad307","src/unix/bsd/netbsdlike/openbsd/powerpc64.rs":"1dd5449dd1fd3d51e30ffdeeaece91d0aaf05c710e0ac699fecc5461cfa2c28e","src/unix/bsd/netbsdlike/openbsd/riscv64.rs":"1dd5449dd1fd3d51e30ffdeeaece91d0aaf05c710e0ac699fecc5461cfa2c28e","src/unix/bsd/netbsdlike/openbsd/sparc64.rs":"d04fd287afbaa2c5df9d48c94e8374a532a3ba491b424ddf018270c7312f4085","src/unix/bsd/netbsdlike/openbsd/x86.rs":"6f7f5c4fde2a2259eb547890cbd86570cea04ef85347d7569e94e679448bec87","src/unix/bsd/netbsdlike/openbsd/x86_64.rs":"d31db31630289c85af3339dbe357998a21ca584cbae31607448fe2cf7675a4e1","src/unix/haiku/b32.rs":"a2efdbf7158a6da341e1db9176b0ab193ba88b449616239ed95dced11f54d87b","src/unix/haiku/b64.rs":"ff8115367d3d7d354f792d6176dfaaa26353f57056197b563bf4681f91ff7985","src/unix/haiku/mod.rs":"df7b6b7d8dd3441665bfe87f2abc942bddc65b8b10dfa9c83dd0422f68107891","src/unix/haiku/native.rs":"dbfcbf4954a79d1df2ff58e0590bbcb8c57dfc7a32392aa73ee4726b66bd6cc8","src/unix/haiku/x86_64.rs":"3ec3aeeb7ed208b8916f3e32d42bfd085ff5e16936a1a35d9a52789f043b7237","src/unix/hermit/aarch64.rs":"86048676e335944c37a63d0083d0f368ae10ceccefeed9debb3bbe08777fc682","src/unix/hermit/mod.rs":"859814f5df89e28fd4b345db399d181e11e7ed413841b6ff703a1fcbdbf013ae","src/unix/hermit/x86_64.rs":"ab832b7524e5fb15c49ff7431165ab1a37dc4667ae0b58e8306f4c539bfa110c","src/unix/linux_like/android/b32/arm.rs":"433c1530f602cc5ed26610c58055dde0c4ceea5e00150063b24ddc60768332a4","src/unix/linux_like/android/b32/mod.rs":"7c173e0375119bf06a3081652faede95e5bcd6858e7576b7533d037978737c8f","src/unix/linux_like/android/b32/x86/align.rs":"812914e4241df82e32b12375ca3374615dc3a4bdd4cf31f0423c5815320c0dab","src/unix/linux_like/android/b32/x86/mod.rs":"8388bd3a0fcb5636bf965eee6dc95ae6860b85a2b555b387c868aa4d4e01ec89","src/unix/linux_like/android/b64/aarch64/align.rs":"2179c3b1608fa4bf68840482bfc2b2fa3ee2faf6fcae3770f9e505cddca35c7b","src/unix/linux_like/android/b64/aarch64/int128.rs":"1735f6f5c56770d20dd426442f09724d9b2052b46a7cd82f23f3288a4a7276de","src/unix/linux_like/android/b64/aarch64/mod.rs":"ef230d49fd0d182adf2dae6f8e10babf18d72259d65980bf1c4c2dc8a4f84501","src/unix/linux_like/android/b64/mod.rs":"71e4fcbe952bfa4a5f9022f3972e906917b38f729b9d8ef57cd5d179104894ac","src/unix/linux_like/android/b64/riscv64/align.rs":"0bf138f84e5327d8339bcd4adf071a6832b516445e597552c82bbd881095e3a8","src/unix/linux_like/android/b64/riscv64/mod.rs":"80e9f93fed838a48b4e2e8d77b95c72cfd7c0647bcce63851555c5ad16dad143","src/unix/linux_like/android/b64/x86_64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/android/b64/x86_64/mod.rs":"e10d19bea39f719723ab6666a5ddbd378b6958769441c5904629e1df173b1dc2","src/unix/linux_like/android/mod.rs":"41b9d0f405cd474385acce06df0649f4eeaab3fe8fb4655f97806fa40bdf84d8","src/unix/linux_like/emscripten/align.rs":"86c95cbed7a7161b1f23ee06843e7b0e2340ad92b2cb86fe2a8ef3e0e8c36216","src/unix/linux_like/emscripten/mod.rs":"6ef4652dfb94e3c58aed5133ece982ad30569d46b6b1054552cd61905fa61690","src/unix/linux_like/emscripten/no_align.rs":"0128e4aa721a9902754828b61b5ec7d8a86619983ed1e0544a85d35b1051fad6","src/unix/linux_like/linux/align.rs":"d6c259942c8e843373accd180fc8f4f45f03544dfd21b93a8d02641ead3ef63e","src/unix/linux_like/linux/arch/generic/mod.rs":"e2b46404e44f7d63c26af9dbd79b4e166ef7bced2bc9c6746a26ca86e508e0d4","src/unix/linux_like/linux/arch/mips/mod.rs":"2d166054a586bb4bf6e4a4ba35f7574907b217225eff8f1a43adc4277e142460","src/unix/linux_like/linux/arch/mod.rs":"466a29622e47c6c7f1500682b2eb17f5566dd81b322cd6348f0fdd355cec593a","src/unix/linux_like/linux/arch/powerpc/mod.rs":"3f6da7b0fa7b394c7d4eea2bb3caa7a7729ab0d6c1491fef02206a912c41b815","src/unix/linux_like/linux/arch/sparc/mod.rs":"91593ec0440f1dd8f8e612028f432c44c14089286e2aca50e10511ab942db8c3","src/unix/linux_like/linux/gnu/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/gnu/b32/arm/align.rs":"6ec0eb3ee93f7ae99fd714b4deabfb5e97fbcefd8c26f5a45fb8e7150899cdeb","src/unix/linux_like/linux/gnu/b32/arm/mod.rs":"5bd3f6b3484e049ddaac95f411b0d82cbf1cd28e6a5defbc927bd917f5f7d299","src/unix/linux_like/linux/gnu/b32/m68k/align.rs":"8faa92f77a9232c035418d45331774e64a9a841d99c91791570a203bf2b45bcb","src/unix/linux_like/linux/gnu/b32/m68k/mod.rs":"a2a0a9400dae44086ebf579e0448e0676d4a3214d1ae7d13a024857251e23b6b","src/unix/linux_like/linux/gnu/b32/mips/align.rs":"429fb5e005cb7143602d430098b6ebfb7d360685b194f333dfd587472ae954ee","src/unix/linux_like/linux/gnu/b32/mips/mod.rs":"6b9a5dac6f937ddc1453e808e3c43502c87143332df9e43ac64fb8b1eda6c116","src/unix/linux_like/linux/gnu/b32/mod.rs":"8da281da578cdee972e952b118b903b370320897a7e335342a15e1359864bef2","src/unix/linux_like/linux/gnu/b32/powerpc.rs":"5c5d90326b54b57b98eff4745fe7a3fb02f053b2dc782241a73e807b491936a3","src/unix/linux_like/linux/gnu/b32/riscv32/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/gnu/b32/riscv32/mod.rs":"5e7c1e29aeb82fc422f45b73fb0cf3d13d0902300f9150d2755a9074f8d96999","src/unix/linux_like/linux/gnu/b32/sparc/align.rs":"21adbed27df73e2d1ed934aaf733a643003d7baf2bde9c48ea440895bcca6d41","src/unix/linux_like/linux/gnu/b32/sparc/mod.rs":"80894eece66e9348f45d1b07ad37c757ea694bbd10ed49d3f920b34e9f51a9a3","src/unix/linux_like/linux/gnu/b32/x86/align.rs":"e4bafdc4a519a7922a81b37a62bbfd1177a2f620890eef8f1fbc47162e9eb413","src/unix/linux_like/linux/gnu/b32/x86/mod.rs":"c703cc5e9de2dc31d9e5831bfb6f354d6e3518b2ae02263f68a9a70f1c0167e2","src/unix/linux_like/linux/gnu/b64/aarch64/align.rs":"5b32fcc0d60356c92ded4e0ba9bb32f0140a8bd75ba800486bf38294f61dbdbb","src/unix/linux_like/linux/gnu/b64/aarch64/ilp32.rs":"21a21503ef2e095f4371044915d4bfb07a8578011cb5c713cd9f45947b0b5730","src/unix/linux_like/linux/gnu/b64/aarch64/int128.rs":"1735f6f5c56770d20dd426442f09724d9b2052b46a7cd82f23f3288a4a7276de","src/unix/linux_like/linux/gnu/b64/aarch64/lp64.rs":"e78c3cd197f44832338b414d1a9bc0d194f44c74db77bd7bf830c1fff62b2690","src/unix/linux_like/linux/gnu/b64/aarch64/mod.rs":"c91813ee5e1bc817996c46be86d1f46802e73df2952cab576ea015490929afc5","src/unix/linux_like/linux/gnu/b64/loongarch64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs":"387808d5398b24339e7e2bf7591150735011befc5b421fa713d7017c04a7b1da","src/unix/linux_like/linux/gnu/b64/mips64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/linux/gnu/b64/mips64/mod.rs":"80b4b97a41564290c510e68a1fb20cfd8424206f010e71a596f12877de886a71","src/unix/linux_like/linux/gnu/b64/mod.rs":"3c6555f30a7a8852757b31a542ea73fb6a16a6e27e838397e819278ad56e57a4","src/unix/linux_like/linux/gnu/b64/powerpc64/align.rs":"e29c4868bbecfa4a6cd8a2ad06193f3bbc78a468cc1dc9df83f002f1268130d9","src/unix/linux_like/linux/gnu/b64/powerpc64/mod.rs":"a595e37c2325ceb40ef66c634bd3c255ad184a1d70ff8025e98a075f0ec67704","src/unix/linux_like/linux/gnu/b64/riscv64/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/gnu/b64/riscv64/mod.rs":"ef4b13477ffd8532fb6705ca3fa63a1f13e8d19ee39b083c5355dfce430c1a5b","src/unix/linux_like/linux/gnu/b64/s390x.rs":"788fde4fa1919859cc028b59da31de00449edd2b2c1530ae76134beac418b73c","src/unix/linux_like/linux/gnu/b64/sparc64/align.rs":"e29c4868bbecfa4a6cd8a2ad06193f3bbc78a468cc1dc9df83f002f1268130d9","src/unix/linux_like/linux/gnu/b64/sparc64/mod.rs":"c4fa0ede3f78b21a9982667922cccd0681bee3cb6d42208ea9958f65e93d6308","src/unix/linux_like/linux/gnu/b64/x86_64/align.rs":"62e822478356db4a73b6bbd1b36d825b893939ab4b308ec11b0578bcc4b49769","src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs":"e37e0421290b152fe508883181c41225e09dd5452a6b085e8d807b3b54823028","src/unix/linux_like/linux/gnu/b64/x86_64/not_x32.rs":"c1b6345ce14f67d1b2e2f7f2c0ff9a074c07acbd348df69cb4558bda8c8fb9ae","src/unix/linux_like/linux/gnu/b64/x86_64/x32.rs":"3f4d2aeadb7d2620cad09564abdbfc5cf02eeb5a27f2bab8a4e9b4bdbdb258a5","src/unix/linux_like/linux/gnu/mod.rs":"06abaca7fc85e805650ec807c4d06c888ff99e146e1ba2685f20840a86e35a2f","src/unix/linux_like/linux/gnu/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/mod.rs":"1d84f37fdfa4dfab1b758345af75e02485e2a18746830413c2afe5069a1e39ce","src/unix/linux_like/linux/musl/b32/arm/align.rs":"3e8ac052c1043764776b54c93ba4260e061df998631737a897d9d47d54f7b80c","src/unix/linux_like/linux/musl/b32/arm/mod.rs":"f5b217a93f99c2852f7fd1459f529798372fa7df84ee0cfd3d8cdd5b2021b8cf","src/unix/linux_like/linux/musl/b32/hexagon.rs":"226a8b64ce9c75abbbee6d2dceb0b44f7b6c750c4102ebd4d015194afee6666e","src/unix/linux_like/linux/musl/b32/mips/align.rs":"429fb5e005cb7143602d430098b6ebfb7d360685b194f333dfd587472ae954ee","src/unix/linux_like/linux/musl/b32/mips/mod.rs":"16a7a03d998a5db11be9ee81525c7faec4623383260e8bc125b1c53a050fde75","src/unix/linux_like/linux/musl/b32/mod.rs":"580e27c5ce3344df686f1ffc08fdfa2c282d1ceb623d778c50d210d4bd65ec7e","src/unix/linux_like/linux/musl/b32/powerpc.rs":"dc52adc264c34bce80753d6bd064e8fc4b8237fa1e5c5315ccb6c72df74c2813","src/unix/linux_like/linux/musl/b32/riscv32/align.rs":"efd2accf33b87de7c7547903359a5da896edc33cd6c719552c7474b60d4a5d48","src/unix/linux_like/linux/musl/b32/riscv32/mod.rs":"e57dc5562553aab6d0765e0ec266254aa52975f8757bfe97e0c6028fa7d5d37c","src/unix/linux_like/linux/musl/b32/x86/align.rs":"08e77fbd7435d7dec2ff56932433bece3f02e47ce810f89004a275a86d39cbe1","src/unix/linux_like/linux/musl/b32/x86/mod.rs":"7a1586f77bb693f0b319ec720c35963da056287fc42f8e2ccf1d5b2bcccf4fd6","src/unix/linux_like/linux/musl/b64/aarch64/align.rs":"6ba32725d24d7d8e6aa111f3b57aafa318f83b606abe96561329151829821133","src/unix/linux_like/linux/musl/b64/aarch64/int128.rs":"1735f6f5c56770d20dd426442f09724d9b2052b46a7cd82f23f3288a4a7276de","src/unix/linux_like/linux/musl/b64/aarch64/mod.rs":"31e75179cbb4e26425b3f5b052e358f593153da662884655e60801d852e55dc2","src/unix/linux_like/linux/musl/b64/mips64.rs":"9a5d29f666332bb056d0e2951e9de989aa1dc016075f009db3f2f628e0cdda8c","src/unix/linux_like/linux/musl/b64/mod.rs":"8c10627bd582cb272514e7350ae4743a65d489356eae039d2e7e55cd533fbbc8","src/unix/linux_like/linux/musl/b64/powerpc64.rs":"455dc0ffa55afc1db6ffaf461f6f2a7b49d31658bfebe0bb4efac5967a6f956c","src/unix/linux_like/linux/musl/b64/riscv64/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/musl/b64/riscv64/mod.rs":"42d4b6d36807f37759094a732a321080cccdf498b174d632cebba147051de294","src/unix/linux_like/linux/musl/b64/s390x.rs":"d8a4fdfea0960ec284cae4facb8b0fb342e8aa41544cffacdcaf08c5a92a43f8","src/unix/linux_like/linux/musl/b64/x86_64/align.rs":"77309276ad7a42cbe59ca381f23590b7a143aded05555b34a5b307b808cbca6e","src/unix/linux_like/linux/musl/b64/x86_64/mod.rs":"7a877cd23b64be66d28e6b8dddae32d59a88d69115637539daf19381f4e39330","src/unix/linux_like/linux/musl/mod.rs":"0514b337aaa6e62be9e01e00702ef996c60319b7050ece155530147c20de9995","src/unix/linux_like/linux/no_align.rs":"da2a8721becaaaa528781f97f5d9aae6a982ae5d4f5f6d2ffc0150bed72319b3","src/unix/linux_like/linux/non_exhaustive.rs":"181a05bf94fdb911db83ce793b993bd6548a4115b306a7ef3c10f745a8fea3e9","src/unix/linux_like/linux/uclibc/align.rs":"9ed16138d8e439bd90930845a65eafa7ebd67366e6bf633936d44014f6e4c959","src/unix/linux_like/linux/uclibc/arm/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/uclibc/arm/mod.rs":"7d8dfbd26ce958d9da17468b3c9d0b119ce7dbd59b3384551cd4423ce25db44a","src/unix/linux_like/linux/uclibc/arm/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/uclibc/mips/mips32/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/uclibc/mips/mips32/mod.rs":"b84def53a49587e87f884c2bc28b21b290463b00b52e1d0309f2ba233a5b4a99","src/unix/linux_like/linux/uclibc/mips/mips32/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/uclibc/mips/mips64/align.rs":"a7bdcb18a37a2d91e64d5fad83ea3edc78f5412adb28f77ab077dbb26dd08b2d","src/unix/linux_like/linux/uclibc/mips/mips64/mod.rs":"256a428290a560163ef7dc7d18b27bd3c6ce9748a0f28d5dc7f82203ee228220","src/unix/linux_like/linux/uclibc/mips/mips64/no_align.rs":"4a18e3875698c85229599225ac3401a2a40da87e77b2ad4ef47c6fcd5a24ed30","src/unix/linux_like/linux/uclibc/mips/mod.rs":"367ec5483ad317e6ccba1ac0888da6cf088a8d32689214cc8d16129aa692260c","src/unix/linux_like/linux/uclibc/mod.rs":"1c3d25cddcfefa2bd17bdc81550826be31a08eef235e13f825f169a5029c8bca","src/unix/linux_like/linux/uclibc/no_align.rs":"3f28637046524618adaa1012e26cb7ffe94b9396e6b518cccdc69d59f274d709","src/unix/linux_like/linux/uclibc/x86_64/l4re.rs":"024eba5753e852dbdd212427351affe7e83f9916c1864bce414d7aa2618f192e","src/unix/linux_like/linux/uclibc/x86_64/mod.rs":"420dbea99e99091f333641e202960fa4bed0733de2a834e610708555be6bab4c","src/unix/linux_like/linux/uclibc/x86_64/other.rs":"42c3f71e58cabba373f6a55a623f3c31b85049eb64824c09c2b082b3b2d6a0a8","src/unix/linux_like/mod.rs":"3d03bd583aaf04f285f95ff8b53c9b5a891d3b64bfcda37a42648ec51c4c51e5","src/unix/mod.rs":"fbd5520d160a32a127608cd408905febe387773bbf05bfe199ef385fb5562e9c","src/unix/newlib/aarch64/mod.rs":"bac93836a9a57b2c710f32f852e92a4d11ad6759ab0fb6ad33e71d60e53278af","src/unix/newlib/align.rs":"28aaf87fafbc6b312622719d472d8cf65f9e5467d15339df5f73e66d8502b28a","src/unix/newlib/arm/mod.rs":"cbba6b3e957eceb496806e60de8725a23ff3fa0015983b4b4fa27b233732b526","src/unix/newlib/espidf/mod.rs":"816f235f4aa4baabba7f2606b31d0fdb03988c52194c966728de8690bf17299d","src/unix/newlib/generic.rs":"eab066d9f0a0f3eb53cc1073d01496bba0110989e1f6a59838afd19f870cd599","src/unix/newlib/horizon/mod.rs":"7cc5cc120437421db139bfa6a90b18168cd3070bdd0f5be96d40fe4c996f3ca1","src/unix/newlib/mod.rs":"494e56628d4408bf66ad30ff71fbd21bc33d9037935c411dff7bf73dd3f1070b","src/unix/newlib/no_align.rs":"e0743b2179495a9514bc3a4d1781e492878c4ec834ee0085d0891dd1712e82fb","src/unix/newlib/powerpc/mod.rs":"0202ffd57caf75b6afa2c9717750ffb96e375ac33df0ae9609a3f831be393b67","src/unix/no_align.rs":"c06e95373b9088266e0b14bba0954eef95f93fb2b01d951855e382d22de78e53","src/unix/redox/mod.rs":"033768cb273daf2c8090d97252c2de9dba6809e6a5d2457f5727d724807695db","src/unix/solarish/compat.rs":"b07a5bfac925eb012003a459ba6bddbd3bfa9c44b3394da2ac5a602e54beae9c","src/unix/solarish/illumos.rs":"1369fb55325914654ba3ad02410b75a40c8c0008feed9704c28520be1ee49641","src/unix/solarish/mod.rs":"52a31038984e68582347f4b28fd64c01e6308ff4293628818bb279605e7b28c6","src/unix/solarish/solaris.rs":"36abcfb46fab6e7151a0c1f555b419e1267b82893f6e84d5d260308ba8eeb0c5","src/unix/solarish/x86.rs":"e86e806df0caed72765040eaa2f3c883198d1aa91508540adf9b7008c77f522e","src/unix/solarish/x86_64.rs":"ec2b01f194eb8a6a27133c57681da195a949e03098f3ea1e847227a9c09ef5fc","src/unix/solarish/x86_common.rs":"ac869d9c3c95645c22460468391eb1982023c3a8e02b9e06a72e3aef3d5f1eac","src/vxworks/aarch64.rs":"98f0afdc511cd02557e506c21fed6737585490a1dce7a9d4941d08c437762b99","src/vxworks/arm.rs":"acb7968ce99fe3f4abdf39d98f8133d21a4fba435b8ef7084777cb181d788e88","src/vxworks/mod.rs":"aea3da66f2140f2a82dfc9c58f6e6531d2dd9c15ea696e0f95a0d4a2a187b5b6","src/vxworks/powerpc.rs":"acb7968ce99fe3f4abdf39d98f8133d21a4fba435b8ef7084777cb181d788e88","src/vxworks/powerpc64.rs":"98f0afdc511cd02557e506c21fed6737585490a1dce7a9d4941d08c437762b99","src/vxworks/x86.rs":"552f007f38317620b23889cb7c49d1d115841252439060122f52f434fbc6e5ba","src/vxworks/x86_64.rs":"018d92be3ad628a129eff9f2f5dfbc0883d8b8e5f2fa917b900a7f98ed6b514a","src/wasi.rs":"4fae202af0327d768ed9e1b586b75816cce14fe2dc16947d2f3d381f209a54c1","src/windows/gnu/align.rs":"b2c13ec1b9f3b39a75c452c80c951dff9d0215e31d77e883b4502afb31794647","src/windows/gnu/mod.rs":"3c8c7edb7cdf5d0c44af936db2a94869585c69dfabeef30571b4f4e38375767a","src/windows/mod.rs":"090dd8fcd951d18f1905bca96188783c2e3f1433484926ecdcda144237ecec0f","src/windows/msvc/mod.rs":"c068271e00fca6b62bc4bf44bcf142cfc38caeded9b6c4e01d1ceef3ccf986f4","tests/const_fn.rs":"cb75a1f0864f926aebe79118fc34d51a0d1ade2c20a394e7774c7e545f21f1f4"},"package":"68783febc7782c6c5cb401fbda4de5a9898be1762314da0bb2c10ced61f18b0c"} -\ No newline at end of file -+{"files":{"CONTRIBUTING.md":"f480d10d2a506eecd23ae2e2dedb7a28b8bf6dae5f46f438dbb61be2003426fb","Cargo.toml":"04fa9ce26b0efcfe3dd51e3f1bbb81bb36f5d61982a11947283c7616d390549e","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"a8d47ff51ca256f56a8932dba07660672dbfe3004257ca8de708aac1415937a1","README.md":"776affa26b66843a2b4f1a1c8f88d92f6461b74568911450fea717e9db6f877b","build.rs":"1d0cbe878e98e970c3318cac0772215a9f44bd286d859d665da27872ba9d8818","rustfmt.toml":"eaa2ea84fc1ba0359b77680804903e07bb38d257ab11986b95b158e460f787b2","src/fixed_width_ints.rs":"7f986e5f5e68d25ef04d386fd2f640e8be8f15427a8d4a458ea01d26b8dca0ca","src/fuchsia/aarch64.rs":"378776a9e40766154a54c94c2a7b4675b5c302a38e6e42da99e67bfbaee60e56","src/fuchsia/align.rs":"ae1cf8f011a99737eabeb14ffff768e60f13b13363d7646744dbb0f443dab3d6","src/fuchsia/mod.rs":"cf7e0df0e655337d1c0852880817b6b514ef9599e2125232fc79cdf8eddd01ba","src/fuchsia/no_align.rs":"303f3f1b255e0088b5715094353cf00476131d8e94e6aebb3f469557771c8b8a","src/fuchsia/x86_64.rs":"93a3632b5cf67d2a6bcb7dc0a558605252d5fe689e0f38d8aa2ec5852255ac87","src/hermit/aarch64.rs":"86048676e335944c37a63d0083d0f368ae10ceccefeed9debb3bbe08777fc682","src/hermit/mod.rs":"d3bfce41e4463d4be8020a2d063c9bfa8b665f45f1cc6cbf3163f5d01e7cb21f","src/hermit/x86_64.rs":"ab832b7524e5fb15c49ff7431165ab1a37dc4667ae0b58e8306f4c539bfa110c","src/lib.rs":"ce753ef318b300bbd441feabdd77d00322dfb6ce9eee8c78a38afe02b57aa4c0","src/macros.rs":"b457eb028b8e8ab3c24bb7292b874ad4e491edbb83594f6a3da024df5348c088","src/psp.rs":"dd31aabd46171d474ec5828372e28588935120e7355c90c105360d8fa9264c1c","src/sgx.rs":"16a95cdefc81c5ee00d8353a60db363c4cc3e0f75abcd5d0144723f2a306ed1b","src/solid/aarch64.rs":"a726e47f324adf73a4a0b67a2c183408d0cad105ae66acf36db37a42ab7f8707","src/solid/arm.rs":"e39a4f74ebbef3b97b8c95758ad741123d84ed3eb48d9cf4f1f4872097fc27fe","src/solid/mod.rs":"5f4151dca5132e4b4e4c23ab9737e12856dddbdc0ca3f7dbc004328ef3c8acde","src/switch.rs":"9da3dd39b3de45a7928789926e8572d00e1e11a39e6f7289a1349aadce90edba","src/unix/align.rs":"2cdc7c826ef7ae61f5171c5ae8c445a743d86f1a7f2d9d7e4ceeec56d6874f65","src/unix/bsd/apple/b32/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b32/mod.rs":"2546ad3eb6aecb95f916648bc63264117c92b4b4859532b34cb011e4c75a5a72","src/unix/bsd/apple/b64/aarch64/align.rs":"e8eb38d064b5fefec6f37d42873820a0483e7c758ed336cc59a7155455ca89c9","src/unix/bsd/apple/b64/aarch64/mod.rs":"a3f0dfff62d0f7f4f1b5f9a4e2b662acf233a46badbc5419d3cc2d735629a710","src/unix/bsd/apple/b64/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b64/mod.rs":"f5e278a1af7fb358891d1c9be4eb7e815aaca0c5cb738d0c3604ba2208a856f7","src/unix/bsd/apple/b64/x86_64/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b64/x86_64/mod.rs":"8c87c5855038aae5d433c8f5eb3b29b0a175879a0245342b3bfd83bdf4cfd936","src/unix/bsd/apple/mod.rs":"bb61eec399428faee753b3df509410c51ed2ac51406d40559fcec290bb50e293","src/unix/bsd/freebsdlike/dragonfly/errno.rs":"8295b8bb0dfd38d2cdb4d9192cdeeb534cc6c3b208170e64615fa3e0edb3e578","src/unix/bsd/freebsdlike/dragonfly/mod.rs":"e4f33050d52d3e5c932da8d10e1f377e1ff609fb178ea986bfc458d31e37dc19","src/unix/bsd/freebsdlike/freebsd/aarch64.rs":"2a215bd6136b8617aacedf9be738ccee94da9d29b418e9a78101d6291c182352","src/unix/bsd/freebsdlike/freebsd/arm.rs":"59d6a670eea562fb87686e243e0a84603d29a2028a3d4b3f99ccc01bd04d2f47","src/unix/bsd/freebsdlike/freebsd/freebsd11/b64.rs":"9808d152c1196aa647f1b0f0cf84dac8c930da7d7f897a44975545e3d9d17681","src/unix/bsd/freebsdlike/freebsd/freebsd11/mod.rs":"23f189f188651762b38f40b4e9aba785625f6f9a52558a4a490510c3b1d08b53","src/unix/bsd/freebsdlike/freebsd/freebsd12/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd12/mod.rs":"57fee9dd251ac615ec7d32d293e0f0b6fa3bf28efbddd6d569765765aafb8b9b","src/unix/bsd/freebsdlike/freebsd/freebsd12/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/freebsd13/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd13/mod.rs":"7df84dd6dee8b73fd4d72dd1638584d788e2a1a85f95746f7c5b330b8dc23655","src/unix/bsd/freebsdlike/freebsd/freebsd13/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/freebsd14/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd14/mod.rs":"236ef119410d566ef94064bf13d734635eaeecb3635a5d21e8e9f91e7e3152ac","src/unix/bsd/freebsdlike/freebsd/freebsd14/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/mod.rs":"6a8eb9a1e35eec893de9c76a5be3ce29e4c3ca26db45fbcfa925bdd757f6352d","src/unix/bsd/freebsdlike/freebsd/powerpc.rs":"9ca3f82f88974e6db5569f2d76a5a3749b248a31747a6c0da5820492bdfeca42","src/unix/bsd/freebsdlike/freebsd/powerpc64.rs":"2dae3ecc87eac3b11657aa98915def55fc4b5c0de11fe26aae23329a54628a9a","src/unix/bsd/freebsdlike/freebsd/riscv64.rs":"8f591bd273464d684c4f64365f8ed56a8138175daa70d96008541393057a0dae","src/unix/bsd/freebsdlike/freebsd/x86.rs":"c5005e3249eb7c93cfbac72a9e9272320d80ce7983da990ceb05a447f59a02c5","src/unix/bsd/freebsdlike/freebsd/x86_64/align.rs":"0e1f69a88fca1c32874b1daf5db3d446fefbe518dca497f096cc9168c39dde70","src/unix/bsd/freebsdlike/freebsd/x86_64/mod.rs":"51e4dd0c8ae247bb652feda5adad9333ea3bb30c750c3a3935e0b0e47d7803eb","src/unix/bsd/freebsdlike/mod.rs":"a61d41f6fe01c06c6de5db2ed970522601eada133e6bac4ed2d1dfaceb576db2","src/unix/bsd/mod.rs":"817ca5719c36a74c84e52c6a56a5998b60d7f02351a405e034f08ebab079b63a","src/unix/bsd/netbsdlike/mod.rs":"b07a0e81085bd811fce7270f3b90fbfea29faf9593d9e39d9d2ebbb9a78bf25f","src/unix/bsd/netbsdlike/netbsd/aarch64.rs":"65dcb58d11e8d8028401a9d07ca3eb4cb4f053e04249cc877353449d84ccc4cb","src/unix/bsd/netbsdlike/netbsd/arm.rs":"58cdbb70b0d6f536551f0f3bb3725d2d75c4690db12c26c034e7d6ec4a924452","src/unix/bsd/netbsdlike/netbsd/mod.rs":"fa260decf53280d4fdf714af60f42d4774f8d6f2da71b0a55a6c2a85e422eb57","src/unix/bsd/netbsdlike/netbsd/powerpc.rs":"ee7ff5d89d0ed22f531237b5059aa669df93a3b5c489fa641465ace8d405bf41","src/unix/bsd/netbsdlike/netbsd/sparc64.rs":"9489f4b3e4566f43bb12dfb92238960613dac7f6a45cc13068a8d152b902d7d9","src/unix/bsd/netbsdlike/netbsd/x86.rs":"20692320e36bfe028d1a34d16fe12ca77aa909cb02bda167376f98f1a09aefe7","src/unix/bsd/netbsdlike/netbsd/x86_64.rs":"1afe5ef46b14397cdd68664b5b232e4f5b035b6db1d4cf411c899d51ebca9f30","src/unix/bsd/netbsdlike/openbsd/aarch64.rs":"dd91931d373b7ecaf6e2de25adadee10d16fa9b12c2cbacdff3eb291e1ba36af","src/unix/bsd/netbsdlike/openbsd/arm.rs":"01580d261bc6447bb327a0d982181b7bdabfa066cee65a30373d3ced729ad307","src/unix/bsd/netbsdlike/openbsd/mips64.rs":"8532a189ae10c7d668d9d4065da8b05d124e09bd39442c9f74a7f231c43eca48","src/unix/bsd/netbsdlike/openbsd/mod.rs":"079b11c99c6ca3cc5942c0e6d854541f8765c5058c2f024b84656697840e198b","src/unix/bsd/netbsdlike/openbsd/powerpc.rs":"01580d261bc6447bb327a0d982181b7bdabfa066cee65a30373d3ced729ad307","src/unix/bsd/netbsdlike/openbsd/powerpc64.rs":"1dd5449dd1fd3d51e30ffdeeaece91d0aaf05c710e0ac699fecc5461cfa2c28e","src/unix/bsd/netbsdlike/openbsd/riscv64.rs":"1dd5449dd1fd3d51e30ffdeeaece91d0aaf05c710e0ac699fecc5461cfa2c28e","src/unix/bsd/netbsdlike/openbsd/sparc64.rs":"d04fd287afbaa2c5df9d48c94e8374a532a3ba491b424ddf018270c7312f4085","src/unix/bsd/netbsdlike/openbsd/x86.rs":"6f7f5c4fde2a2259eb547890cbd86570cea04ef85347d7569e94e679448bec87","src/unix/bsd/netbsdlike/openbsd/x86_64.rs":"d31db31630289c85af3339dbe357998a21ca584cbae31607448fe2cf7675a4e1","src/unix/haiku/b32.rs":"a2efdbf7158a6da341e1db9176b0ab193ba88b449616239ed95dced11f54d87b","src/unix/haiku/b64.rs":"ff8115367d3d7d354f792d6176dfaaa26353f57056197b563bf4681f91ff7985","src/unix/haiku/mod.rs":"df7b6b7d8dd3441665bfe87f2abc942bddc65b8b10dfa9c83dd0422f68107891","src/unix/haiku/native.rs":"dbfcbf4954a79d1df2ff58e0590bbcb8c57dfc7a32392aa73ee4726b66bd6cc8","src/unix/haiku/x86_64.rs":"3ec3aeeb7ed208b8916f3e32d42bfd085ff5e16936a1a35d9a52789f043b7237","src/unix/hermit/aarch64.rs":"86048676e335944c37a63d0083d0f368ae10ceccefeed9debb3bbe08777fc682","src/unix/hermit/mod.rs":"859814f5df89e28fd4b345db399d181e11e7ed413841b6ff703a1fcbdbf013ae","src/unix/hermit/x86_64.rs":"ab832b7524e5fb15c49ff7431165ab1a37dc4667ae0b58e8306f4c539bfa110c","src/unix/linux_like/android/b32/arm.rs":"433c1530f602cc5ed26610c58055dde0c4ceea5e00150063b24ddc60768332a4","src/unix/linux_like/android/b32/mod.rs":"7c173e0375119bf06a3081652faede95e5bcd6858e7576b7533d037978737c8f","src/unix/linux_like/android/b32/x86/align.rs":"812914e4241df82e32b12375ca3374615dc3a4bdd4cf31f0423c5815320c0dab","src/unix/linux_like/android/b32/x86/mod.rs":"8388bd3a0fcb5636bf965eee6dc95ae6860b85a2b555b387c868aa4d4e01ec89","src/unix/linux_like/android/b64/aarch64/align.rs":"2179c3b1608fa4bf68840482bfc2b2fa3ee2faf6fcae3770f9e505cddca35c7b","src/unix/linux_like/android/b64/aarch64/int128.rs":"1735f6f5c56770d20dd426442f09724d9b2052b46a7cd82f23f3288a4a7276de","src/unix/linux_like/android/b64/aarch64/mod.rs":"ef230d49fd0d182adf2dae6f8e10babf18d72259d65980bf1c4c2dc8a4f84501","src/unix/linux_like/android/b64/mod.rs":"71e4fcbe952bfa4a5f9022f3972e906917b38f729b9d8ef57cd5d179104894ac","src/unix/linux_like/android/b64/riscv64/align.rs":"0bf138f84e5327d8339bcd4adf071a6832b516445e597552c82bbd881095e3a8","src/unix/linux_like/android/b64/riscv64/mod.rs":"80e9f93fed838a48b4e2e8d77b95c72cfd7c0647bcce63851555c5ad16dad143","src/unix/linux_like/android/b64/x86_64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/android/b64/x86_64/mod.rs":"e10d19bea39f719723ab6666a5ddbd378b6958769441c5904629e1df173b1dc2","src/unix/linux_like/android/mod.rs":"41b9d0f405cd474385acce06df0649f4eeaab3fe8fb4655f97806fa40bdf84d8","src/unix/linux_like/emscripten/align.rs":"86c95cbed7a7161b1f23ee06843e7b0e2340ad92b2cb86fe2a8ef3e0e8c36216","src/unix/linux_like/emscripten/mod.rs":"6ef4652dfb94e3c58aed5133ece982ad30569d46b6b1054552cd61905fa61690","src/unix/linux_like/emscripten/no_align.rs":"0128e4aa721a9902754828b61b5ec7d8a86619983ed1e0544a85d35b1051fad6","src/unix/linux_like/linux/align.rs":"d6c259942c8e843373accd180fc8f4f45f03544dfd21b93a8d02641ead3ef63e","src/unix/linux_like/linux/arch/generic/mod.rs":"e2b46404e44f7d63c26af9dbd79b4e166ef7bced2bc9c6746a26ca86e508e0d4","src/unix/linux_like/linux/arch/mips/mod.rs":"2d166054a586bb4bf6e4a4ba35f7574907b217225eff8f1a43adc4277e142460","src/unix/linux_like/linux/arch/mod.rs":"466a29622e47c6c7f1500682b2eb17f5566dd81b322cd6348f0fdd355cec593a","src/unix/linux_like/linux/arch/powerpc/mod.rs":"3f6da7b0fa7b394c7d4eea2bb3caa7a7729ab0d6c1491fef02206a912c41b815","src/unix/linux_like/linux/arch/sparc/mod.rs":"91593ec0440f1dd8f8e612028f432c44c14089286e2aca50e10511ab942db8c3","src/unix/linux_like/linux/gnu/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/gnu/b32/arm/align.rs":"6ec0eb3ee93f7ae99fd714b4deabfb5e97fbcefd8c26f5a45fb8e7150899cdeb","src/unix/linux_like/linux/gnu/b32/arm/mod.rs":"5bd3f6b3484e049ddaac95f411b0d82cbf1cd28e6a5defbc927bd917f5f7d299","src/unix/linux_like/linux/gnu/b32/m68k/align.rs":"8faa92f77a9232c035418d45331774e64a9a841d99c91791570a203bf2b45bcb","src/unix/linux_like/linux/gnu/b32/m68k/mod.rs":"a2a0a9400dae44086ebf579e0448e0676d4a3214d1ae7d13a024857251e23b6b","src/unix/linux_like/linux/gnu/b32/mips/align.rs":"429fb5e005cb7143602d430098b6ebfb7d360685b194f333dfd587472ae954ee","src/unix/linux_like/linux/gnu/b32/mips/mod.rs":"6b9a5dac6f937ddc1453e808e3c43502c87143332df9e43ac64fb8b1eda6c116","src/unix/linux_like/linux/gnu/b32/mod.rs":"8da281da578cdee972e952b118b903b370320897a7e335342a15e1359864bef2","src/unix/linux_like/linux/gnu/b32/powerpc.rs":"5c5d90326b54b57b98eff4745fe7a3fb02f053b2dc782241a73e807b491936a3","src/unix/linux_like/linux/gnu/b32/riscv32/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/gnu/b32/riscv32/mod.rs":"5e7c1e29aeb82fc422f45b73fb0cf3d13d0902300f9150d2755a9074f8d96999","src/unix/linux_like/linux/gnu/b32/sparc/align.rs":"21adbed27df73e2d1ed934aaf733a643003d7baf2bde9c48ea440895bcca6d41","src/unix/linux_like/linux/gnu/b32/sparc/mod.rs":"80894eece66e9348f45d1b07ad37c757ea694bbd10ed49d3f920b34e9f51a9a3","src/unix/linux_like/linux/gnu/b32/x86/align.rs":"e4bafdc4a519a7922a81b37a62bbfd1177a2f620890eef8f1fbc47162e9eb413","src/unix/linux_like/linux/gnu/b32/x86/mod.rs":"c703cc5e9de2dc31d9e5831bfb6f354d6e3518b2ae02263f68a9a70f1c0167e2","src/unix/linux_like/linux/gnu/b64/aarch64/align.rs":"5b32fcc0d60356c92ded4e0ba9bb32f0140a8bd75ba800486bf38294f61dbdbb","src/unix/linux_like/linux/gnu/b64/aarch64/ilp32.rs":"21a21503ef2e095f4371044915d4bfb07a8578011cb5c713cd9f45947b0b5730","src/unix/linux_like/linux/gnu/b64/aarch64/int128.rs":"1735f6f5c56770d20dd426442f09724d9b2052b46a7cd82f23f3288a4a7276de","src/unix/linux_like/linux/gnu/b64/aarch64/lp64.rs":"e78c3cd197f44832338b414d1a9bc0d194f44c74db77bd7bf830c1fff62b2690","src/unix/linux_like/linux/gnu/b64/aarch64/mod.rs":"c91813ee5e1bc817996c46be86d1f46802e73df2952cab576ea015490929afc5","src/unix/linux_like/linux/gnu/b64/loongarch64/align.rs":"62e822478356db4a73b6bbd1b36d825b893939ab4b308ec11b0578bcc4b49769","src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs":"d92686cfa34bbd3f1cf58d7373d7eb7135437f0f5f296d83ffc53354f966619f","src/unix/linux_like/linux/gnu/b64/mips64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/linux/gnu/b64/mips64/mod.rs":"80b4b97a41564290c510e68a1fb20cfd8424206f010e71a596f12877de886a71","src/unix/linux_like/linux/gnu/b64/mod.rs":"3c6555f30a7a8852757b31a542ea73fb6a16a6e27e838397e819278ad56e57a4","src/unix/linux_like/linux/gnu/b64/powerpc64/align.rs":"e29c4868bbecfa4a6cd8a2ad06193f3bbc78a468cc1dc9df83f002f1268130d9","src/unix/linux_like/linux/gnu/b64/powerpc64/mod.rs":"a595e37c2325ceb40ef66c634bd3c255ad184a1d70ff8025e98a075f0ec67704","src/unix/linux_like/linux/gnu/b64/riscv64/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/gnu/b64/riscv64/mod.rs":"ef4b13477ffd8532fb6705ca3fa63a1f13e8d19ee39b083c5355dfce430c1a5b","src/unix/linux_like/linux/gnu/b64/s390x.rs":"788fde4fa1919859cc028b59da31de00449edd2b2c1530ae76134beac418b73c","src/unix/linux_like/linux/gnu/b64/sparc64/align.rs":"e29c4868bbecfa4a6cd8a2ad06193f3bbc78a468cc1dc9df83f002f1268130d9","src/unix/linux_like/linux/gnu/b64/sparc64/mod.rs":"c4fa0ede3f78b21a9982667922cccd0681bee3cb6d42208ea9958f65e93d6308","src/unix/linux_like/linux/gnu/b64/x86_64/align.rs":"62e822478356db4a73b6bbd1b36d825b893939ab4b308ec11b0578bcc4b49769","src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs":"e37e0421290b152fe508883181c41225e09dd5452a6b085e8d807b3b54823028","src/unix/linux_like/linux/gnu/b64/x86_64/not_x32.rs":"c1b6345ce14f67d1b2e2f7f2c0ff9a074c07acbd348df69cb4558bda8c8fb9ae","src/unix/linux_like/linux/gnu/b64/x86_64/x32.rs":"3f4d2aeadb7d2620cad09564abdbfc5cf02eeb5a27f2bab8a4e9b4bdbdb258a5","src/unix/linux_like/linux/gnu/mod.rs":"06abaca7fc85e805650ec807c4d06c888ff99e146e1ba2685f20840a86e35a2f","src/unix/linux_like/linux/gnu/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/mod.rs":"1d84f37fdfa4dfab1b758345af75e02485e2a18746830413c2afe5069a1e39ce","src/unix/linux_like/linux/musl/b32/arm/align.rs":"3e8ac052c1043764776b54c93ba4260e061df998631737a897d9d47d54f7b80c","src/unix/linux_like/linux/musl/b32/arm/mod.rs":"f5b217a93f99c2852f7fd1459f529798372fa7df84ee0cfd3d8cdd5b2021b8cf","src/unix/linux_like/linux/musl/b32/hexagon.rs":"226a8b64ce9c75abbbee6d2dceb0b44f7b6c750c4102ebd4d015194afee6666e","src/unix/linux_like/linux/musl/b32/mips/align.rs":"429fb5e005cb7143602d430098b6ebfb7d360685b194f333dfd587472ae954ee","src/unix/linux_like/linux/musl/b32/mips/mod.rs":"16a7a03d998a5db11be9ee81525c7faec4623383260e8bc125b1c53a050fde75","src/unix/linux_like/linux/musl/b32/mod.rs":"580e27c5ce3344df686f1ffc08fdfa2c282d1ceb623d778c50d210d4bd65ec7e","src/unix/linux_like/linux/musl/b32/powerpc.rs":"dc52adc264c34bce80753d6bd064e8fc4b8237fa1e5c5315ccb6c72df74c2813","src/unix/linux_like/linux/musl/b32/riscv32/align.rs":"efd2accf33b87de7c7547903359a5da896edc33cd6c719552c7474b60d4a5d48","src/unix/linux_like/linux/musl/b32/riscv32/mod.rs":"e57dc5562553aab6d0765e0ec266254aa52975f8757bfe97e0c6028fa7d5d37c","src/unix/linux_like/linux/musl/b32/x86/align.rs":"08e77fbd7435d7dec2ff56932433bece3f02e47ce810f89004a275a86d39cbe1","src/unix/linux_like/linux/musl/b32/x86/mod.rs":"7a1586f77bb693f0b319ec720c35963da056287fc42f8e2ccf1d5b2bcccf4fd6","src/unix/linux_like/linux/musl/b64/aarch64/align.rs":"6ba32725d24d7d8e6aa111f3b57aafa318f83b606abe96561329151829821133","src/unix/linux_like/linux/musl/b64/aarch64/int128.rs":"1735f6f5c56770d20dd426442f09724d9b2052b46a7cd82f23f3288a4a7276de","src/unix/linux_like/linux/musl/b64/aarch64/mod.rs":"31e75179cbb4e26425b3f5b052e358f593153da662884655e60801d852e55dc2","src/unix/linux_like/linux/musl/b64/mips64.rs":"9a5d29f666332bb056d0e2951e9de989aa1dc016075f009db3f2f628e0cdda8c","src/unix/linux_like/linux/musl/b64/mod.rs":"8c10627bd582cb272514e7350ae4743a65d489356eae039d2e7e55cd533fbbc8","src/unix/linux_like/linux/musl/b64/powerpc64.rs":"455dc0ffa55afc1db6ffaf461f6f2a7b49d31658bfebe0bb4efac5967a6f956c","src/unix/linux_like/linux/musl/b64/riscv64/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/musl/b64/riscv64/mod.rs":"42d4b6d36807f37759094a732a321080cccdf498b174d632cebba147051de294","src/unix/linux_like/linux/musl/b64/s390x.rs":"d8a4fdfea0960ec284cae4facb8b0fb342e8aa41544cffacdcaf08c5a92a43f8","src/unix/linux_like/linux/musl/b64/x86_64/align.rs":"77309276ad7a42cbe59ca381f23590b7a143aded05555b34a5b307b808cbca6e","src/unix/linux_like/linux/musl/b64/x86_64/mod.rs":"7a877cd23b64be66d28e6b8dddae32d59a88d69115637539daf19381f4e39330","src/unix/linux_like/linux/musl/mod.rs":"0514b337aaa6e62be9e01e00702ef996c60319b7050ece155530147c20de9995","src/unix/linux_like/linux/no_align.rs":"da2a8721becaaaa528781f97f5d9aae6a982ae5d4f5f6d2ffc0150bed72319b3","src/unix/linux_like/linux/non_exhaustive.rs":"181a05bf94fdb911db83ce793b993bd6548a4115b306a7ef3c10f745a8fea3e9","src/unix/linux_like/linux/uclibc/align.rs":"9ed16138d8e439bd90930845a65eafa7ebd67366e6bf633936d44014f6e4c959","src/unix/linux_like/linux/uclibc/arm/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/uclibc/arm/mod.rs":"7d8dfbd26ce958d9da17468b3c9d0b119ce7dbd59b3384551cd4423ce25db44a","src/unix/linux_like/linux/uclibc/arm/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/uclibc/mips/mips32/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/uclibc/mips/mips32/mod.rs":"b84def53a49587e87f884c2bc28b21b290463b00b52e1d0309f2ba233a5b4a99","src/unix/linux_like/linux/uclibc/mips/mips32/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/uclibc/mips/mips64/align.rs":"a7bdcb18a37a2d91e64d5fad83ea3edc78f5412adb28f77ab077dbb26dd08b2d","src/unix/linux_like/linux/uclibc/mips/mips64/mod.rs":"256a428290a560163ef7dc7d18b27bd3c6ce9748a0f28d5dc7f82203ee228220","src/unix/linux_like/linux/uclibc/mips/mips64/no_align.rs":"4a18e3875698c85229599225ac3401a2a40da87e77b2ad4ef47c6fcd5a24ed30","src/unix/linux_like/linux/uclibc/mips/mod.rs":"367ec5483ad317e6ccba1ac0888da6cf088a8d32689214cc8d16129aa692260c","src/unix/linux_like/linux/uclibc/mod.rs":"1c3d25cddcfefa2bd17bdc81550826be31a08eef235e13f825f169a5029c8bca","src/unix/linux_like/linux/uclibc/no_align.rs":"3f28637046524618adaa1012e26cb7ffe94b9396e6b518cccdc69d59f274d709","src/unix/linux_like/linux/uclibc/x86_64/l4re.rs":"024eba5753e852dbdd212427351affe7e83f9916c1864bce414d7aa2618f192e","src/unix/linux_like/linux/uclibc/x86_64/mod.rs":"420dbea99e99091f333641e202960fa4bed0733de2a834e610708555be6bab4c","src/unix/linux_like/linux/uclibc/x86_64/other.rs":"42c3f71e58cabba373f6a55a623f3c31b85049eb64824c09c2b082b3b2d6a0a8","src/unix/linux_like/mod.rs":"3d03bd583aaf04f285f95ff8b53c9b5a891d3b64bfcda37a42648ec51c4c51e5","src/unix/mod.rs":"fbd5520d160a32a127608cd408905febe387773bbf05bfe199ef385fb5562e9c","src/unix/newlib/aarch64/mod.rs":"bac93836a9a57b2c710f32f852e92a4d11ad6759ab0fb6ad33e71d60e53278af","src/unix/newlib/align.rs":"28aaf87fafbc6b312622719d472d8cf65f9e5467d15339df5f73e66d8502b28a","src/unix/newlib/arm/mod.rs":"cbba6b3e957eceb496806e60de8725a23ff3fa0015983b4b4fa27b233732b526","src/unix/newlib/espidf/mod.rs":"816f235f4aa4baabba7f2606b31d0fdb03988c52194c966728de8690bf17299d","src/unix/newlib/generic.rs":"eab066d9f0a0f3eb53cc1073d01496bba0110989e1f6a59838afd19f870cd599","src/unix/newlib/horizon/mod.rs":"7cc5cc120437421db139bfa6a90b18168cd3070bdd0f5be96d40fe4c996f3ca1","src/unix/newlib/mod.rs":"494e56628d4408bf66ad30ff71fbd21bc33d9037935c411dff7bf73dd3f1070b","src/unix/newlib/no_align.rs":"e0743b2179495a9514bc3a4d1781e492878c4ec834ee0085d0891dd1712e82fb","src/unix/newlib/powerpc/mod.rs":"0202ffd57caf75b6afa2c9717750ffb96e375ac33df0ae9609a3f831be393b67","src/unix/no_align.rs":"c06e95373b9088266e0b14bba0954eef95f93fb2b01d951855e382d22de78e53","src/unix/redox/mod.rs":"033768cb273daf2c8090d97252c2de9dba6809e6a5d2457f5727d724807695db","src/unix/solarish/compat.rs":"b07a5bfac925eb012003a459ba6bddbd3bfa9c44b3394da2ac5a602e54beae9c","src/unix/solarish/illumos.rs":"1369fb55325914654ba3ad02410b75a40c8c0008feed9704c28520be1ee49641","src/unix/solarish/mod.rs":"52a31038984e68582347f4b28fd64c01e6308ff4293628818bb279605e7b28c6","src/unix/solarish/solaris.rs":"36abcfb46fab6e7151a0c1f555b419e1267b82893f6e84d5d260308ba8eeb0c5","src/unix/solarish/x86.rs":"e86e806df0caed72765040eaa2f3c883198d1aa91508540adf9b7008c77f522e","src/unix/solarish/x86_64.rs":"ec2b01f194eb8a6a27133c57681da195a949e03098f3ea1e847227a9c09ef5fc","src/unix/solarish/x86_common.rs":"ac869d9c3c95645c22460468391eb1982023c3a8e02b9e06a72e3aef3d5f1eac","src/vxworks/aarch64.rs":"98f0afdc511cd02557e506c21fed6737585490a1dce7a9d4941d08c437762b99","src/vxworks/arm.rs":"acb7968ce99fe3f4abdf39d98f8133d21a4fba435b8ef7084777cb181d788e88","src/vxworks/mod.rs":"aea3da66f2140f2a82dfc9c58f6e6531d2dd9c15ea696e0f95a0d4a2a187b5b6","src/vxworks/powerpc.rs":"acb7968ce99fe3f4abdf39d98f8133d21a4fba435b8ef7084777cb181d788e88","src/vxworks/powerpc64.rs":"98f0afdc511cd02557e506c21fed6737585490a1dce7a9d4941d08c437762b99","src/vxworks/x86.rs":"552f007f38317620b23889cb7c49d1d115841252439060122f52f434fbc6e5ba","src/vxworks/x86_64.rs":"018d92be3ad628a129eff9f2f5dfbc0883d8b8e5f2fa917b900a7f98ed6b514a","src/wasi.rs":"4fae202af0327d768ed9e1b586b75816cce14fe2dc16947d2f3d381f209a54c1","src/windows/gnu/align.rs":"b2c13ec1b9f3b39a75c452c80c951dff9d0215e31d77e883b4502afb31794647","src/windows/gnu/mod.rs":"3c8c7edb7cdf5d0c44af936db2a94869585c69dfabeef30571b4f4e38375767a","src/windows/mod.rs":"090dd8fcd951d18f1905bca96188783c2e3f1433484926ecdcda144237ecec0f","src/windows/msvc/mod.rs":"c068271e00fca6b62bc4bf44bcf142cfc38caeded9b6c4e01d1ceef3ccf986f4","tests/const_fn.rs":"cb75a1f0864f926aebe79118fc34d51a0d1ade2c20a394e7774c7e545f21f1f4"},"package":"68783febc7782c6c5cb401fbda4de5a9898be1762314da0bb2c10ced61f18b0c"} -diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b64/loongarch64/align.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/loongarch64/align.rs -index 7ca870fd0..ba3075edd 100644 ---- a/vendor/libc/src/unix/linux_like/linux/gnu/b64/loongarch64/align.rs -+++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/loongarch64/align.rs -@@ -5,3 +5,20 @@ s_no_extra_traits! { - priv_: [f64; 4] - } - } -+ -+s! { -+ #[repr(align(8))] -+ pub struct clone_args { -+ pub flags: ::c_ulonglong, -+ pub pidfd: ::c_ulonglong, -+ pub child_tid: ::c_ulonglong, -+ pub parent_tid: ::c_ulonglong, -+ pub exit_signal: ::c_ulonglong, -+ pub stack: ::c_ulonglong, -+ pub stack_size: ::c_ulonglong, -+ pub tls: ::c_ulonglong, -+ pub set_tid: ::c_ulonglong, -+ pub set_tid_size: ::c_ulonglong, -+ pub cgroup: ::c_ulonglong, -+ } -+} -diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs -index 2ed6a9156..ff520e0c6 100644 ---- a/vendor/libc/src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs -+++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs -@@ -247,6 +247,20 @@ align_const! { - }; - } - -+pub const HWCAP_LOONGARCH_CPUCFG: ::c_ulong = 1 << 0; -+pub const HWCAP_LOONGARCH_LAM: ::c_ulong = 1 << 1; -+pub const HWCAP_LOONGARCH_UAL: ::c_ulong = 1 << 2; -+pub const HWCAP_LOONGARCH_FPU: ::c_ulong = 1 << 3; -+pub const HWCAP_LOONGARCH_LSX: ::c_ulong = 1 << 4; -+pub const HWCAP_LOONGARCH_LASX: ::c_ulong = 1 << 5; -+pub const HWCAP_LOONGARCH_CRC32: ::c_ulong = 1 << 6; -+pub const HWCAP_LOONGARCH_COMPLEX: ::c_ulong = 1 << 7; -+pub const HWCAP_LOONGARCH_CRYPTO: ::c_ulong = 1 << 8; -+pub const HWCAP_LOONGARCH_LVZ: ::c_ulong = 1 << 9; -+pub const HWCAP_LOONGARCH_LBT_X86: ::c_ulong = 1 << 10; -+pub const HWCAP_LOONGARCH_LBT_ARM: ::c_ulong = 1 << 11; -+pub const HWCAP_LOONGARCH_LBT_MIPS: ::c_ulong = 1 << 12; -+ - pub const SYS_io_setup: ::c_long = 0; - pub const SYS_io_destroy: ::c_long = 1; - pub const SYS_io_submit: ::c_long = 2; -@@ -587,6 +601,8 @@ pub const F_OFD_GETLK: ::c_int = 36; - pub const F_OFD_SETLK: ::c_int = 37; - pub const F_OFD_SETLKW: ::c_int = 38; - -+pub const MADV_SOFT_OFFLINE: ::c_int = 101; -+ - pub const EDEADLK: ::c_int = 35; - pub const EDEADLOCK: ::c_int = 35; - pub const ENAMETOOLONG: ::c_int = 36; --- -2.41.0 - diff --git a/0003-vendor-psm-add-loongarch64-support.patch b/0003-vendor-psm-add-loongarch64-support.patch deleted file mode 100644 index 461f59eac9e56abcff179cb85e7eaa358a994687..0000000000000000000000000000000000000000 --- a/0003-vendor-psm-add-loongarch64-support.patch +++ /dev/null @@ -1,105 +0,0 @@ -From d4a6c0659f5008337b85451da2e2ea0a74110f99 Mon Sep 17 00:00:00 2001 -From: WANG Rui -Date: Thu, 7 Jul 2022 11:53:09 +0800 -Subject: [PATCH 3/6] vendor: psm: add loongarch64 support - ---- - vendor/psm/.cargo-checksum.json | 2 +- - vendor/psm/build.rs | 1 + - vendor/psm/src/arch/loongarch64.s | 64 +++++++++++++++++++++++++++++++ - 3 files changed, 66 insertions(+), 1 deletion(-) - create mode 100644 vendor/psm/src/arch/loongarch64.s - -diff --git a/vendor/psm/.cargo-checksum.json b/vendor/psm/.cargo-checksum.json -index a69778b20..ea3c4f99a 100644 ---- a/vendor/psm/.cargo-checksum.json -+++ b/vendor/psm/.cargo-checksum.json -@@ -1 +1 @@ --{"files":{"Cargo.lock":"2928b712f89aee2b62581df1e552b7cb8288d999ba180291b4900b86a05c6d8d","Cargo.toml":"c2c5a0154a80cffc82349cd98f819ea1259c92f195c5878ceefb66e06b14d28c","LICENSE-APACHE":"965a63a81d9a2fbeb5f9096954dabb49690f9dffcdac9825f675b25c807252a2","LICENSE-MIT":"3e3714aa69bd874601741fd7d7ad5298740cece37778e279fc1ab4451c5a11af","README.mkd":"6385ecaced99b0a29a5b40166d34ef9312f322c1b8ad002bef3b08cd6c3e29b2","build.rs":"1d7872546e6924bbb2947edc055ddd01f48683cc80d9d75a846adb65540345f0","examples/info.rs":"8ffb89912304ecbf3d714dcc094f42e86fdd0738625b2e76be2e7d59ab0736cf","examples/on_stack_fibo.rs":"287f0a08b177a97366a5da39e24e33e1f4bbe30a1f2473956721c8a9d93926a4","examples/on_stack_fibo_alloc_each_frame.rs":"e084041bbb81d51b195a4db539a765409272916df29c83a62213a93de4b6fca3","examples/panics.rs":"6791fe0dda9456b3becf989cbc89bc45ae27302e633572a57bbf10a57b830076","examples/replace_stack_1.rs":"374a28881f5e5dbf9db9b9e34929fb7a7e6f3910d782a6718f53ac269807b990","examples/thread.rs":"3cf92882aff96151608584d63535701cc8e5ae953d7ecf706d77371180bff025","src/arch/aarch64_armasm.asm":"1c737338287f3de981fbae97f104ac5e49425ba7fbcb4f7d80120afae47a86d5","src/arch/aarch_aapcs64.s":"459b8cd5a96104893e8f849ac83369101d7204c933841672df162104bebd2375","src/arch/arm_aapcs.s":"4ada635e8528279bd0326654f5203b6bdc94dd68c94fdef5de551384ba1b1747","src/arch/arm_armasm.asm":"e3b514169f19368b0b49374412de38bd9f50576e7b93b64d685a0f84fa8f4c91","src/arch/mips64_eabi.s":"4e6f95f89ba72fc4dd1a9a547920764f66d98251d236941cee4d227010484520","src/arch/mips_eabi.s":"8b7927fd63660eb276e2951f28df6b11920f04be4dc17a16b66ad386da12c4c3","src/arch/powerpc32.s":"0b508a65dec7254ba2e0dc65a2c9e86c21069fe62f5d7c41f5190415a4885912","src/arch/powerpc64.s":"c1602d09d12ba1df48fc96af0f827f8679fc93cee728813527fb1b817a788911","src/arch/powerpc64_openpower.s":"421b11cc7381427d1e2acb4e681c9836ccfea0b79930492f0a99ec4d27495e58","src/arch/psm.h":"2cebda3740aa73b167b8ec18e3d2202ca46e400a081a46329b86051abd1a872a","src/arch/riscv.s":"a81d2af4bcc9c29db304730697e52a89a7376b51d2735185c67be8910d0cdf39","src/arch/riscv64.s":"a51da67ce569e2442ff487b062bb8fdfe7c769f3f05a88de480bd5ab214d9a4f","src/arch/sparc64.s":"6250acbd938aea2e440061663a79fbb2dac0592b3a193f027b6b910e2a8e3af1","src/arch/sparc_sysv.s":"c2da7576e1fbe2234cc8a5cf937f7676e125435295f8c32089bfa0b0f27fde5e","src/arch/wasm32.o":"d7279f419cb7e169cae2af2463507652e0393b801c2f4580244de70d3def58b6","src/arch/wasm32.s":"1ebdc90de48f13e6474ee17c406578fc090ff61e57c1f560ecf6e6b75c7ef10a","src/arch/x86.s":"1919a4af1474895f904ed4281a4a8fcdd0428dab257bff4ea262db83ed63b445","src/arch/x86_64.s":"c80f1a3e22db61fd62b5ef2e1b6663185403bdcbcfbfe7ff0f8e0831ff0cafcf","src/arch/x86_64_msvc.asm":"85683bc65a03371ea7d8d79dcbe487f690cc2460c359817fc63c30d575ad8957","src/arch/x86_64_windows_gnu.s":"44637034e094ec0ad76dbe1232e97271c8155eb93bcb1dd86fe825acd05978a0","src/arch/x86_msvc.asm":"1735d4b19f8e46d0699fc9538baa7ab0885d27531ef7d9960e2027ad8137769b","src/arch/x86_windows_gnu.s":"b94d907a86f230c5c8ca1c708ede173f73c5269496f3959e08e4a92155e160d7","src/arch/zseries_linux.s":"5c3379a76e31bf13abf240efda12596fabce108cf63f60f9d0495e82ab8f1717","src/lib.rs":"18774ee37630bc6c7a36273014f80f6afa3f73bf34f4c49f5795d2eb5df1c195","tests/stack_direction.rs":"77d8f9dee196e99e70d569f59fef82bc2f88a8ec17bfe07ebe2f005fcb815c8b","tests/stack_direction_2.rs":"f9191394de5b6381af6ba8223e7717230059dc335f639238c0ddbc7eb87bfc0e"},"package":"cd136ff4382c4753fc061cb9e4712ab2af263376b95bbd5bd8cd50c020b78e69"} -\ No newline at end of file -+{"files":{"Cargo.lock":"2928b712f89aee2b62581df1e552b7cb8288d999ba180291b4900b86a05c6d8d","Cargo.toml":"c2c5a0154a80cffc82349cd98f819ea1259c92f195c5878ceefb66e06b14d28c","LICENSE-APACHE":"965a63a81d9a2fbeb5f9096954dabb49690f9dffcdac9825f675b25c807252a2","LICENSE-MIT":"3e3714aa69bd874601741fd7d7ad5298740cece37778e279fc1ab4451c5a11af","README.mkd":"6385ecaced99b0a29a5b40166d34ef9312f322c1b8ad002bef3b08cd6c3e29b2","build.rs":"f742cdd0ea2c92b5f43008488b6dc3c89424f83ca9ef25ca89ab3894d6707764","examples/info.rs":"8ffb89912304ecbf3d714dcc094f42e86fdd0738625b2e76be2e7d59ab0736cf","examples/on_stack_fibo.rs":"287f0a08b177a97366a5da39e24e33e1f4bbe30a1f2473956721c8a9d93926a4","examples/on_stack_fibo_alloc_each_frame.rs":"e084041bbb81d51b195a4db539a765409272916df29c83a62213a93de4b6fca3","examples/panics.rs":"6791fe0dda9456b3becf989cbc89bc45ae27302e633572a57bbf10a57b830076","examples/replace_stack_1.rs":"374a28881f5e5dbf9db9b9e34929fb7a7e6f3910d782a6718f53ac269807b990","examples/thread.rs":"3cf92882aff96151608584d63535701cc8e5ae953d7ecf706d77371180bff025","src/arch/aarch64_armasm.asm":"1c737338287f3de981fbae97f104ac5e49425ba7fbcb4f7d80120afae47a86d5","src/arch/aarch_aapcs64.s":"459b8cd5a96104893e8f849ac83369101d7204c933841672df162104bebd2375","src/arch/arm_aapcs.s":"4ada635e8528279bd0326654f5203b6bdc94dd68c94fdef5de551384ba1b1747","src/arch/arm_armasm.asm":"e3b514169f19368b0b49374412de38bd9f50576e7b93b64d685a0f84fa8f4c91","src/arch/loongarch64.s":"47836a2b0a19d8b7a63fd21674509224ec8059eee1251205ad88c8e0ec7469a3","src/arch/mips64_eabi.s":"4e6f95f89ba72fc4dd1a9a547920764f66d98251d236941cee4d227010484520","src/arch/mips_eabi.s":"8b7927fd63660eb276e2951f28df6b11920f04be4dc17a16b66ad386da12c4c3","src/arch/powerpc32.s":"0b508a65dec7254ba2e0dc65a2c9e86c21069fe62f5d7c41f5190415a4885912","src/arch/powerpc64.s":"c1602d09d12ba1df48fc96af0f827f8679fc93cee728813527fb1b817a788911","src/arch/powerpc64_openpower.s":"421b11cc7381427d1e2acb4e681c9836ccfea0b79930492f0a99ec4d27495e58","src/arch/psm.h":"2cebda3740aa73b167b8ec18e3d2202ca46e400a081a46329b86051abd1a872a","src/arch/riscv.s":"a81d2af4bcc9c29db304730697e52a89a7376b51d2735185c67be8910d0cdf39","src/arch/riscv64.s":"a51da67ce569e2442ff487b062bb8fdfe7c769f3f05a88de480bd5ab214d9a4f","src/arch/sparc64.s":"6250acbd938aea2e440061663a79fbb2dac0592b3a193f027b6b910e2a8e3af1","src/arch/sparc_sysv.s":"c2da7576e1fbe2234cc8a5cf937f7676e125435295f8c32089bfa0b0f27fde5e","src/arch/wasm32.o":"d7279f419cb7e169cae2af2463507652e0393b801c2f4580244de70d3def58b6","src/arch/wasm32.s":"1ebdc90de48f13e6474ee17c406578fc090ff61e57c1f560ecf6e6b75c7ef10a","src/arch/x86.s":"1919a4af1474895f904ed4281a4a8fcdd0428dab257bff4ea262db83ed63b445","src/arch/x86_64.s":"c80f1a3e22db61fd62b5ef2e1b6663185403bdcbcfbfe7ff0f8e0831ff0cafcf","src/arch/x86_64_msvc.asm":"85683bc65a03371ea7d8d79dcbe487f690cc2460c359817fc63c30d575ad8957","src/arch/x86_64_windows_gnu.s":"44637034e094ec0ad76dbe1232e97271c8155eb93bcb1dd86fe825acd05978a0","src/arch/x86_msvc.asm":"1735d4b19f8e46d0699fc9538baa7ab0885d27531ef7d9960e2027ad8137769b","src/arch/x86_windows_gnu.s":"b94d907a86f230c5c8ca1c708ede173f73c5269496f3959e08e4a92155e160d7","src/arch/zseries_linux.s":"5c3379a76e31bf13abf240efda12596fabce108cf63f60f9d0495e82ab8f1717","src/lib.rs":"18774ee37630bc6c7a36273014f80f6afa3f73bf34f4c49f5795d2eb5df1c195","tests/stack_direction.rs":"77d8f9dee196e99e70d569f59fef82bc2f88a8ec17bfe07ebe2f005fcb815c8b","tests/stack_direction_2.rs":"f9191394de5b6381af6ba8223e7717230059dc335f639238c0ddbc7eb87bfc0e"},"package":"cd136ff4382c4753fc061cb9e4712ab2af263376b95bbd5bd8cd50c020b78e69"} -diff --git a/vendor/psm/build.rs b/vendor/psm/build.rs -index 01a13bf71..9fab27a83 100644 ---- a/vendor/psm/build.rs -+++ b/vendor/psm/build.rs -@@ -51,6 +51,7 @@ fn find_assembly( - ("riscv32", _, _, _) => Some(("src/arch/riscv.s", true)), - ("riscv64", _, _, _) => Some(("src/arch/riscv64.s", true)), - ("wasm32", _, _, _) => Some(("src/arch/wasm32.o", true)), -+ ("loongarch64", _, _, _) => Some(("src/arch/loongarch64.s", true)), - _ => None, - } - } -diff --git a/vendor/psm/src/arch/loongarch64.s b/vendor/psm/src/arch/loongarch64.s -new file mode 100644 -index 000000000..04bcee3a0 ---- /dev/null -+++ b/vendor/psm/src/arch/loongarch64.s -@@ -0,0 +1,64 @@ -+#include "psm.h" -+ -+.text -+.globl rust_psm_stack_direction -+.p2align 2 -+.type rust_psm_stack_direction,@function -+/* extern "C" fn() -> u8 */ -+rust_psm_stack_direction: -+.cfi_startproc -+ addi.w $r4, $r0, STACK_DIRECTION_DESCENDING -+ jr $r1 -+.rust_psm_stack_direction_end: -+.size rust_psm_stack_direction,.rust_psm_stack_direction_end-rust_psm_stack_direction -+.cfi_endproc -+ -+ -+.globl rust_psm_stack_pointer -+.p2align 2 -+.type rust_psm_stack_pointer,@function -+/* extern "C" fn() -> *mut u8 */ -+rust_psm_stack_pointer: -+.cfi_startproc -+ move $r4, $r3 -+ jr $r1 -+.rust_psm_stack_pointer_end: -+.size rust_psm_stack_pointer,.rust_psm_stack_pointer_end-rust_psm_stack_pointer -+.cfi_endproc -+ -+ -+.globl rust_psm_replace_stack -+.p2align 2 -+.type rust_psm_replace_stack,@function -+/* extern "C" fn(r4: usize, r5: extern "C" fn(usize), r6: *mut u8) */ -+rust_psm_replace_stack: -+.cfi_startproc -+ move $r3, $r6 -+ jr $r5 -+.rust_psm_replace_stack_end: -+.size rust_psm_replace_stack,.rust_psm_on_stack_end-rust_psm_on_stack -+.cfi_endproc -+ -+ -+.globl rust_psm_on_stack -+.p2align 2 -+.type rust_psm_on_stack,@function -+/* extern "C" fn(r4: iusize, r5: usize, r6: extern "C" fn(usize), r7: *mut u8) */ -+rust_psm_on_stack: -+.cfi_startproc -+ st.d $r3, $r7, -8 -+ st.d $r1, $r7, -16 -+ .cfi_def_cfa 7, 0 -+ .cfi_offset 3, -8 -+ .cfi_offset 1, -16 -+ addi.d $r3, $r7, -16 -+ .cfi_def_cfa 3, -16 -+ jirl $r1, $r6, 0 -+ ld.d $r1, $r3, 0 -+ .cfi_restore 12 -+ ld.d $r3, $r3, 8 -+ .cfi_restore 3 -+ jr $r1 -+.rust_psm_on_stack_end: -+.size rust_psm_on_stack,.rust_psm_on_stack_end-rust_psm_on_stack -+.cfi_endproc --- -2.41.0 - diff --git a/0004-vendor-object-add-loongarch64-support.patch b/0004-vendor-object-add-loongarch64-support.patch deleted file mode 100644 index 620cb661a12b1f80f56389ec2ae77d1c6b3ae415..0000000000000000000000000000000000000000 --- a/0004-vendor-object-add-loongarch64-support.patch +++ /dev/null @@ -1,623 +0,0 @@ -From 5258a72e586e973867e392178f0e3dfd19610d23 Mon Sep 17 00:00:00 2001 -From: WANG Rui -Date: Sun, 25 Jun 2023 16:22:39 +0800 -Subject: [PATCH 4/6] vendor: object: add loongarch64 support - ---- - vendor/object-0.26.2/.cargo-checksum.json | 2 +- - vendor/object-0.26.2/src/common.rs | 2 + - vendor/object-0.26.2/src/elf.rs | 119 +++++++++ - vendor/object-0.26.2/src/read/elf/file.rs | 1 + - .../object-0.26.2/src/read/elf/relocation.rs | 5 + - vendor/object-0.26.2/src/write/elf.rs | 10 + - vendor/object-0.26.2/tests/round_trip/mod.rs | 1 + - vendor/object/.cargo-checksum.json | 2 +- - vendor/object/src/common.rs | 4 +- - vendor/object/src/elf.rs | 244 +++++++++--------- - vendor/object/src/write/elf/object.rs | 7 +- - 11 files changed, 264 insertions(+), 133 deletions(-) - -diff --git a/vendor/object-0.26.2/.cargo-checksum.json b/vendor/object-0.26.2/.cargo-checksum.json -index 1f76cb1fc..32e0621c8 100644 ---- a/vendor/object-0.26.2/.cargo-checksum.json -+++ b/vendor/object-0.26.2/.cargo-checksum.json -@@ -1 +1 @@ --{"files":{"CHANGELOG.md":"52a47c66164f368e5a167f1732525583ec574cd7de8be91fac29d52997b1c632","Cargo.lock":"a1190887088da0ebf768d172d97a9c21519fe4adb72860e4c9d3826307a57ce6","Cargo.toml":"2481b73a96029b6409d582b026d901d04f5ef12c12ccb27f3c997fa567ce18a7","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"0b74dfa0bcee5c420c6b7f67b4b2658f9ab8388c97b8e733975f2cecbdd668a6","README.md":"283c8881f81e647191130eea41b94fe877214e492fd35dd02a10c0698aaedcdf","clippy.toml":"50fd0cdaae995561b1d688c9410fe99335fc7ac3916a400dafd25ff63f8215f7","examples/ar.rs":"9846b618c70acfcb869895f1e1829a3b3824c04afd685ee7af289c91fcf0e420","examples/dyldcachedump.rs":"d30974ade7acbb13843ab5ffe74e825316f533b4bf7a6431799277d2340aad01","examples/nm.rs":"07b8dd510ad51640ffedba74ef3d05b290922d1a5ccf78237693e527124deb2d","examples/objcopy.rs":"e4e3a080733e877bd8024b3bd98dbf607e3ad9611db4f417a156c0f144f6b663","examples/objdump.rs":"1e0a27b2c3ac4dd85df9fc9a4463644de5f4762b3428e9b0d4f542c7084ff793","examples/objectmap.rs":"d36457d5334551a8d82880847a563ca619e022746e8ef3fd79f3a16193a5dd95","examples/readobj.rs":"49feba2fd34a6fb76e18763348e6ccf5a0c4ccf3779e5bc622df4d8ed14e82bf","src/archive.rs":"7ca11076759d4b87b42657f866b0d2b1dd07d2536b19645da0a5da5dd713b77d","src/common.rs":"9a16e67c321a6b35d35ce9d0611281f8f30b2c475cde68479d6a0fdd2b997a5e","src/elf.rs":"78df96810cb379e1dd8b4872ab90d2337855fa4d4d98fb09697d0750154dc40b","src/endian.rs":"ceaad1b651627ad9e6218a168f87353ae651f5d76c9f61bc8099dff25007405e","src/lib.rs":"fccca74e1e79d5d4dbb090a0103d91b5a0b4f71983d5e3ee3b139b13a9c7990d","src/macho.rs":"ef938fbfd5913711493ef4347a1b426b7ee661a2eb2038681552d7d8b7282e7a","src/pe.rs":"7a1b57131f43ed01472f4924f37657896880b82b127a153795388eb4577a640a","src/pod.rs":"9643a698e1388ad98d1e9ea074ca5b0b35599a2491a82e67a62ebcdc8cb19218","src/read/any.rs":"696a956935e7f1babb621ff71dec23154ca4bf906a8adfa5c02aac7a50117c69","src/read/archive.rs":"987eaf577ec47f5b4ac4e91c697abad31c00ead02f3241dde4f74ce24a884b20","src/read/coff/comdat.rs":"f4198dcdd2c270c9f1ba9efa30c6fb291913984079a45c02e6b6f57dce2700da","src/read/coff/file.rs":"3b15e43d5db9e3af025cda166dd731a5a10293c8d6a6a6f82e7ff4541a4b04a8","src/read/coff/mod.rs":"5eed1c0ca7cf044b3173223b06afacc4961a0515ef2478fffa35641f4ee364ee","src/read/coff/relocation.rs":"a9406980b89a33a16b4fa4f41f01d6db63096c46ff61bb8bd590f86f1d5ed5cf","src/read/coff/section.rs":"721e4f96c2de16f85192db0ad53ee34745bcbe8d551ad297d4f44ab13205ec06","src/read/coff/symbol.rs":"01a11c8f77c1b80d354d9437439cf4685b99bf254cc9eeadd19da2a394fc3c57","src/read/elf/comdat.rs":"340cccdea68c7ed77406ee45c4baa5f179588d77d90bb88b0cd9749d0d725cb1","src/read/elf/compression.rs":"097ff8bdc78d01a1532b11c1c0cae3b35905128c7d98b471de188d46da3ff970","src/read/elf/dynamic.rs":"2454551eb67757622b3d6660bc13ed39341be91f382eb8b1910095f58cf2bae2","src/read/elf/file.rs":"9d5958552ac3f590249c45795d40d8ffce0d41a6e4d9ae2f38f356ad4e46c05e","src/read/elf/hash.rs":"3a08046c78a6fd79bccfd1a0d4cc113da8d0664164576f290885b51d8110acca","src/read/elf/mod.rs":"98b5bd46778d3c33e9d19dee2d294f61677dec16b28f22aa73340008c241fe09","src/read/elf/note.rs":"33bf89a85bb7927fd0123cd6c2919f0b9b0f8935db1ae7b446b75ea2717a476d","src/read/elf/relocation.rs":"62b27c79964f7b037f4fb0b952afacd14790751828e82b67ed5890f143e2b2dc","src/read/elf/section.rs":"d692093ad195ccd0e4857c2f9c638543aa38a8179180e68d27a1f0784aa5e09a","src/read/elf/segment.rs":"d3cbb86cc9ca6eca93f9c17f36823dae0bd72ab2761f2b784dadd8f5b5c9dd9f","src/read/elf/symbol.rs":"9582039f44e82a3bbf225db12ddab9a3b3d5f4b0536d4125c18bb693da3c6db7","src/read/elf/version.rs":"c665034c90cb17e7bd1a6ba836966534fb2527698979908a704cf3b716c0dbdc","src/read/macho/dyld_cache.rs":"37330ba249226231b2e6ae7de80d60845c2eb7db854fd588c52fc706e13e49b8","src/read/macho/fat.rs":"05e84f0a10958ef4e3828f388cd5d2fea95481ea89aeb80b76a2784c4208e4a1","src/read/macho/file.rs":"c524be5be3447afb5aa9c68673f495de05e652687790397f6bf5617b9beea21a","src/read/macho/load_command.rs":"df976715bbc7699f7fdb8e9d388ba3e96a6d40c6a03b96c2696bd7c19786695a","src/read/macho/mod.rs":"23b353da3b7e076c68a067776e6a5b346a746116ac42c2c90bafd95ad54a90b3","src/read/macho/relocation.rs":"77fa3e65ccf5884433c96cdc39c457b8a0c430432e5ff9cad22a8becf13f0183","src/read/macho/section.rs":"59e70336d50f757d8d8daf44f23acca77de87cffcf2d62326e3b17c2ff9f672f","src/read/macho/segment.rs":"659b61a8cb563504f533c390fb901883b72c298f7bea037100a677cc9e4face4","src/read/macho/symbol.rs":"c0a615079779bf83bc3a6ae6d816f8d853099591f0b72e8646a624955bc5069e","src/read/mod.rs":"18ccc63d7acfc1af561d413738cafb1882368179257d36d2dc2496e21095bf7c","src/read/pe/file.rs":"f17836ac757dfd198323a2df1289b02dbb3ba85f2ceff0fdb7e565d30d555da3","src/read/pe/mod.rs":"05d9f3320596f9e567cbd791b68982d50a31e8d18f60c2c401c4a40eb50f1d94","src/read/pe/section.rs":"befd3c82fe6d9186b5802945853da9653649779989fd36cd2a835e3264156281","src/read/read_cache.rs":"939b66cfc11fc022c4e4b78fcad63b375516967da2274da78fb200271d934a53","src/read/read_ref.rs":"5fe6f717c79b07fecac9ee8ba15740c7a9581c36f1e356119e99dd669af6c39c","src/read/traits.rs":"5f29ae16bcf078c7089b22d7bd3ca9c6bc2eb637900a3b1cc70f9a45e5f8be09","src/read/util.rs":"c329a240689b177613049e00faf7928e6cd6aad021542cd708cc06b598c6900e","src/read/wasm.rs":"936ac6b218d23d7bb9ca6869f17cd8dafbed80ee0b267254c7a3ffe05bd46948","src/write/coff.rs":"16f52497fd18ec893c8f72903e9ea0bde6901e75acdfbc8be6a7305e13bccb8c","src/write/elf.rs":"2d6d3c4b014e9df7dd09e3ecf926a7d8fbac6e3cf3ab768e672b7c8ac1d38485","src/write/macho.rs":"fa058f9e7aa1e9895a3c4575fa527c3d5dbac186d994c9ba48801348a8428f35","src/write/mod.rs":"970620fba6e7b851981cda09929d93667a51d0c0be2c1491fdd8002d530515df","src/write/string.rs":"920d71223a5a146ef516b6d5fb6d22bc86a7e456da369ae8a4d1ca6b63d59892","src/write/util.rs":"3bf18004fd5cd25229e480856f36b3410f23b12c096de4c52ab13e11da75b2e3","tests/integration.rs":"d491a0ae0d50c3194cd7b81720262f55ccb234251346f188284ce29729823dc2","tests/parse_self.rs":"81b44b2dd1de9a5d8c18d9bd8926156e39fb83931837afa8ca344da0d309aeee","tests/round_trip/bss.rs":"849d69b063fd757fed02219dd81e9d13b82068a2025d2cc5cfd40cf557e31bda","tests/round_trip/comdat.rs":"2e3ef1aef466911646e5cbfe0b1a8c1543530baf8ca6102394519e701a1e2747","tests/round_trip/common.rs":"ced08ff559ca4d343ceef54bb4c581a3405cd96d6a1628ba43b7aab82070800b","tests/round_trip/elf.rs":"a1ff40266998321c75023cf76384f8ad03828c6d487421ea8b7774fce8173039","tests/round_trip/macho.rs":"b23931f506345b26ce3b4908dc2ce02f704603c622d39f5e9e7c8529f2882818","tests/round_trip/mod.rs":"b741ba432fdee2156699743962c64aaf2d1e9629c432e40953ac4d410688ea5a","tests/round_trip/tls.rs":"23a49a1036b9173ece82a3080745930e5925e745280ab38866c9d3c29f463e63"},"package":"39f37e50073ccad23b6d09bcb5b263f4e76d3bb6038e4a3c08e52162ffa8abc2"} -\ No newline at end of file -+{"files":{"CHANGELOG.md":"52a47c66164f368e5a167f1732525583ec574cd7de8be91fac29d52997b1c632","Cargo.lock":"a1190887088da0ebf768d172d97a9c21519fe4adb72860e4c9d3826307a57ce6","Cargo.toml":"2481b73a96029b6409d582b026d901d04f5ef12c12ccb27f3c997fa567ce18a7","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"0b74dfa0bcee5c420c6b7f67b4b2658f9ab8388c97b8e733975f2cecbdd668a6","README.md":"283c8881f81e647191130eea41b94fe877214e492fd35dd02a10c0698aaedcdf","clippy.toml":"50fd0cdaae995561b1d688c9410fe99335fc7ac3916a400dafd25ff63f8215f7","examples/ar.rs":"9846b618c70acfcb869895f1e1829a3b3824c04afd685ee7af289c91fcf0e420","examples/dyldcachedump.rs":"d30974ade7acbb13843ab5ffe74e825316f533b4bf7a6431799277d2340aad01","examples/nm.rs":"07b8dd510ad51640ffedba74ef3d05b290922d1a5ccf78237693e527124deb2d","examples/objcopy.rs":"e4e3a080733e877bd8024b3bd98dbf607e3ad9611db4f417a156c0f144f6b663","examples/objdump.rs":"1e0a27b2c3ac4dd85df9fc9a4463644de5f4762b3428e9b0d4f542c7084ff793","examples/objectmap.rs":"d36457d5334551a8d82880847a563ca619e022746e8ef3fd79f3a16193a5dd95","examples/readobj.rs":"49feba2fd34a6fb76e18763348e6ccf5a0c4ccf3779e5bc622df4d8ed14e82bf","src/archive.rs":"7ca11076759d4b87b42657f866b0d2b1dd07d2536b19645da0a5da5dd713b77d","src/common.rs":"fefada6d122499cfbdb3c2d6deb3727f0c516b771a9393f716310564c4139da3","src/elf.rs":"47244eee991c738a1e72777e835c196ce2fbd10d5e20a741271356c402d41540","src/endian.rs":"ceaad1b651627ad9e6218a168f87353ae651f5d76c9f61bc8099dff25007405e","src/lib.rs":"fccca74e1e79d5d4dbb090a0103d91b5a0b4f71983d5e3ee3b139b13a9c7990d","src/macho.rs":"ef938fbfd5913711493ef4347a1b426b7ee661a2eb2038681552d7d8b7282e7a","src/pe.rs":"7a1b57131f43ed01472f4924f37657896880b82b127a153795388eb4577a640a","src/pod.rs":"9643a698e1388ad98d1e9ea074ca5b0b35599a2491a82e67a62ebcdc8cb19218","src/read/any.rs":"696a956935e7f1babb621ff71dec23154ca4bf906a8adfa5c02aac7a50117c69","src/read/archive.rs":"987eaf577ec47f5b4ac4e91c697abad31c00ead02f3241dde4f74ce24a884b20","src/read/coff/comdat.rs":"f4198dcdd2c270c9f1ba9efa30c6fb291913984079a45c02e6b6f57dce2700da","src/read/coff/file.rs":"3b15e43d5db9e3af025cda166dd731a5a10293c8d6a6a6f82e7ff4541a4b04a8","src/read/coff/mod.rs":"5eed1c0ca7cf044b3173223b06afacc4961a0515ef2478fffa35641f4ee364ee","src/read/coff/relocation.rs":"a9406980b89a33a16b4fa4f41f01d6db63096c46ff61bb8bd590f86f1d5ed5cf","src/read/coff/section.rs":"721e4f96c2de16f85192db0ad53ee34745bcbe8d551ad297d4f44ab13205ec06","src/read/coff/symbol.rs":"01a11c8f77c1b80d354d9437439cf4685b99bf254cc9eeadd19da2a394fc3c57","src/read/elf/comdat.rs":"340cccdea68c7ed77406ee45c4baa5f179588d77d90bb88b0cd9749d0d725cb1","src/read/elf/compression.rs":"097ff8bdc78d01a1532b11c1c0cae3b35905128c7d98b471de188d46da3ff970","src/read/elf/dynamic.rs":"2454551eb67757622b3d6660bc13ed39341be91f382eb8b1910095f58cf2bae2","src/read/elf/file.rs":"46e1aa01bed485c53288df14cc1688fe5e4ed81f259a30f54acbb3498042db72","src/read/elf/hash.rs":"3a08046c78a6fd79bccfd1a0d4cc113da8d0664164576f290885b51d8110acca","src/read/elf/mod.rs":"98b5bd46778d3c33e9d19dee2d294f61677dec16b28f22aa73340008c241fe09","src/read/elf/note.rs":"33bf89a85bb7927fd0123cd6c2919f0b9b0f8935db1ae7b446b75ea2717a476d","src/read/elf/relocation.rs":"68c85f2ab03ea14feccdffbb383c6c44a55281b7ca17aa82a487ea8ccc710b70","src/read/elf/section.rs":"d692093ad195ccd0e4857c2f9c638543aa38a8179180e68d27a1f0784aa5e09a","src/read/elf/segment.rs":"d3cbb86cc9ca6eca93f9c17f36823dae0bd72ab2761f2b784dadd8f5b5c9dd9f","src/read/elf/symbol.rs":"9582039f44e82a3bbf225db12ddab9a3b3d5f4b0536d4125c18bb693da3c6db7","src/read/elf/version.rs":"c665034c90cb17e7bd1a6ba836966534fb2527698979908a704cf3b716c0dbdc","src/read/macho/dyld_cache.rs":"37330ba249226231b2e6ae7de80d60845c2eb7db854fd588c52fc706e13e49b8","src/read/macho/fat.rs":"05e84f0a10958ef4e3828f388cd5d2fea95481ea89aeb80b76a2784c4208e4a1","src/read/macho/file.rs":"c524be5be3447afb5aa9c68673f495de05e652687790397f6bf5617b9beea21a","src/read/macho/load_command.rs":"df976715bbc7699f7fdb8e9d388ba3e96a6d40c6a03b96c2696bd7c19786695a","src/read/macho/mod.rs":"23b353da3b7e076c68a067776e6a5b346a746116ac42c2c90bafd95ad54a90b3","src/read/macho/relocation.rs":"77fa3e65ccf5884433c96cdc39c457b8a0c430432e5ff9cad22a8becf13f0183","src/read/macho/section.rs":"59e70336d50f757d8d8daf44f23acca77de87cffcf2d62326e3b17c2ff9f672f","src/read/macho/segment.rs":"659b61a8cb563504f533c390fb901883b72c298f7bea037100a677cc9e4face4","src/read/macho/symbol.rs":"c0a615079779bf83bc3a6ae6d816f8d853099591f0b72e8646a624955bc5069e","src/read/mod.rs":"18ccc63d7acfc1af561d413738cafb1882368179257d36d2dc2496e21095bf7c","src/read/pe/file.rs":"f17836ac757dfd198323a2df1289b02dbb3ba85f2ceff0fdb7e565d30d555da3","src/read/pe/mod.rs":"05d9f3320596f9e567cbd791b68982d50a31e8d18f60c2c401c4a40eb50f1d94","src/read/pe/section.rs":"befd3c82fe6d9186b5802945853da9653649779989fd36cd2a835e3264156281","src/read/read_cache.rs":"939b66cfc11fc022c4e4b78fcad63b375516967da2274da78fb200271d934a53","src/read/read_ref.rs":"5fe6f717c79b07fecac9ee8ba15740c7a9581c36f1e356119e99dd669af6c39c","src/read/traits.rs":"5f29ae16bcf078c7089b22d7bd3ca9c6bc2eb637900a3b1cc70f9a45e5f8be09","src/read/util.rs":"c329a240689b177613049e00faf7928e6cd6aad021542cd708cc06b598c6900e","src/read/wasm.rs":"936ac6b218d23d7bb9ca6869f17cd8dafbed80ee0b267254c7a3ffe05bd46948","src/write/coff.rs":"16f52497fd18ec893c8f72903e9ea0bde6901e75acdfbc8be6a7305e13bccb8c","src/write/elf.rs":"34cbd7f14853309f94ac29d3371fac25165dbd72b0d84b6c6cd2cae6eb3fd2c7","src/write/macho.rs":"fa058f9e7aa1e9895a3c4575fa527c3d5dbac186d994c9ba48801348a8428f35","src/write/mod.rs":"970620fba6e7b851981cda09929d93667a51d0c0be2c1491fdd8002d530515df","src/write/string.rs":"920d71223a5a146ef516b6d5fb6d22bc86a7e456da369ae8a4d1ca6b63d59892","src/write/util.rs":"3bf18004fd5cd25229e480856f36b3410f23b12c096de4c52ab13e11da75b2e3","tests/integration.rs":"d491a0ae0d50c3194cd7b81720262f55ccb234251346f188284ce29729823dc2","tests/parse_self.rs":"81b44b2dd1de9a5d8c18d9bd8926156e39fb83931837afa8ca344da0d309aeee","tests/round_trip/bss.rs":"849d69b063fd757fed02219dd81e9d13b82068a2025d2cc5cfd40cf557e31bda","tests/round_trip/comdat.rs":"2e3ef1aef466911646e5cbfe0b1a8c1543530baf8ca6102394519e701a1e2747","tests/round_trip/common.rs":"ced08ff559ca4d343ceef54bb4c581a3405cd96d6a1628ba43b7aab82070800b","tests/round_trip/elf.rs":"a1ff40266998321c75023cf76384f8ad03828c6d487421ea8b7774fce8173039","tests/round_trip/macho.rs":"b23931f506345b26ce3b4908dc2ce02f704603c622d39f5e9e7c8529f2882818","tests/round_trip/mod.rs":"8086e07fb15c3306944606b3cdd26cd0db42d1606885fc43dada4aa6e456aa2c","tests/round_trip/tls.rs":"23a49a1036b9173ece82a3080745930e5925e745280ab38866c9d3c29f463e63"},"package":"39f37e50073ccad23b6d09bcb5b263f4e76d3bb6038e4a3c08e52162ffa8abc2"} -diff --git a/vendor/object-0.26.2/src/common.rs b/vendor/object-0.26.2/src/common.rs -index c86665c21..0759a9d4e 100644 ---- a/vendor/object-0.26.2/src/common.rs -+++ b/vendor/object-0.26.2/src/common.rs -@@ -23,6 +23,7 @@ pub enum Architecture { - S390x, - Sparc64, - Wasm32, -+ LoongArch64, - } - - impl Architecture { -@@ -50,6 +51,7 @@ impl Architecture { - Architecture::S390x => Some(AddressSize::U64), - Architecture::Sparc64 => Some(AddressSize::U64), - Architecture::Wasm32 => Some(AddressSize::U32), -+ Architecture::LoongArch64 => Some(AddressSize::U64), - } - } - } -diff --git a/vendor/object-0.26.2/src/elf.rs b/vendor/object-0.26.2/src/elf.rs -index 28ac16bbe..5591834f1 100644 ---- a/vendor/object-0.26.2/src/elf.rs -+++ b/vendor/object-0.26.2/src/elf.rs -@@ -564,6 +564,8 @@ pub const EM_BPF: u16 = 247; - pub const EM_CSKY: u16 = 252; - /// Digital Alpha - pub const EM_ALPHA: u16 = 0x9026; -+/// LOONGARCH -+pub const EM_LOONGARCH: u16 = 258; - - // Values for `FileHeader*::e_version` and `Ident::version`. - /// Invalid ELF version. -@@ -6081,6 +6083,123 @@ pub const R_RISCV_SET32: u32 = 56; - #[allow(missing_docs)] - pub const R_RISCV_32_PCREL: u32 = 57; - -+//LOONGARCH values `FileHeader*::e_flags`. -+#[allow(missing_docs)] -+pub const EF_LARCH_ABI: u32 = 0x0003; -+#[allow(missing_docs)] -+pub const EF_LARCH_ABI_LP64: u32 = 0x0003; -+#[allow(missing_docs)] -+pub const EF_LARCH_ABI_LPX32: u32 = 0x0002; -+#[allow(missing_docs)] -+pub const EF_LARCH_ABI_LP32: u32 = 0x0001; -+ -+// LOONGARCH values `Rel*::r_type`. -+/* Loongarch specific dynamic relocations. */ -+#[allow(missing_docs)] -+pub const R_LARCH_NONE: u32 = 0; -+#[allow(missing_docs)] -+pub const R_LARCH_32: u32 = 1; -+#[allow(missing_docs)] -+pub const R_LARCH_64: u32 = 2; -+#[allow(missing_docs)] -+pub const R_LARCH_RELATIVE: u32 = 3; -+#[allow(missing_docs)] -+pub const R_LARCH_COPY: u32 = 4; -+#[allow(missing_docs)] -+pub const R_LARCH_JUMP_SLOT: u32 = 5; -+#[allow(missing_docs)] -+pub const R_LARCH_TLS_DTPMOD32: u32 = 6; -+#[allow(missing_docs)] -+pub const R_LARCH_TLS_DTPMOD64: u32 = 7; -+#[allow(missing_docs)] -+pub const R_LARCH_TLS_DTPREL32: u32 = 8; -+#[allow(missing_docs)] -+pub const R_LARCH_TLS_DTPREL64: u32 = 9; -+#[allow(missing_docs)] -+pub const R_LARCH_TLS_TPREL32: u32 = 10; -+#[allow(missing_docs)] -+pub const R_LARCH_TLS_TPREL64: u32 = 11; -+#[allow(missing_docs)] -+pub const R_LARCH_IRELATIVE: u32 = 12; -+#[allow(missing_docs)] -+pub const R_LARCH_MARK_LA: u32 = 20; -+#[allow(missing_docs)] -+pub const R_LARCH_MARK_PCREL: u32 = 21; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_PUSH_PCREL: u32 = 22; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_PUSH_ABSOLUTE: u32 = 23; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_PUSH_DUP: u32 = 24; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_PUSH_GPREL: u32 = 25; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_PUSH_TLS_TPREL: u32 = 26; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_PUSH_TLS_GOT: u32 = 27; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_PUSH_TLS_GD: u32 = 28; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_PUSH_PLT_PCREL: u32 = 29; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_ASSERT: u32 = 30; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_NOT: u32 = 31; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_SUB: u32 = 32; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_SL: u32 = 33; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_SR: u32 = 34; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_ADD: u32 = 35; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_AND: u32 = 36; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_IF_ELSE: u32 = 37; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_POP_32_S_10_5: u32 = 38; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_POP_32_U_10_12: u32 = 39; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_POP_32_S_10_12: u32 = 40; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_POP_32_S_10_16: u32 = 41; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_POP_32_S_10_16_S2: u32 = 42; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_POP_32_S_5_20: u32 = 43; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_POP_32_S_0_5_10_16_S2: u32 = 44; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_POP_32_S_0_10_10_16_S2: u32 = 45; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_POP_32_U: u32 = 46; -+#[allow(missing_docs)] -+pub const R_LARCH_ADD8: u32 = 47; -+#[allow(missing_docs)] -+pub const R_LARCH_ADD16: u32 = 48; -+#[allow(missing_docs)] -+pub const R_LARCH_ADD24: u32 = 49; -+#[allow(missing_docs)] -+pub const R_LARCH_ADD32: u32 = 50; -+#[allow(missing_docs)] -+pub const R_LARCH_ADD64: u32 = 51; -+#[allow(missing_docs)] -+pub const R_LARCH_SUB8: u32 = 52; -+#[allow(missing_docs)] -+pub const R_LARCH_SUB16: u32 = 53; -+#[allow(missing_docs)] -+pub const R_LARCH_SUB24: u32 = 54; -+#[allow(missing_docs)] -+pub const R_LARCH_SUB32: u32 = 55; -+#[allow(missing_docs)] -+pub const R_LARCH_SUB64: u32 = 56; -+#[allow(missing_docs)] -+pub const R_LARCH_GNU_VTINHERIT: u32 = 57; -+#[allow(missing_docs)] -+pub const R_LARCH_GNU_VTENTRY: u32 = 58; -+ - // BPF values `Rel*::r_type`. - /// No reloc - pub const R_BPF_NONE: u32 = 0; -diff --git a/vendor/object-0.26.2/src/read/elf/file.rs b/vendor/object-0.26.2/src/read/elf/file.rs -index 91273ca41..00262dafc 100644 ---- a/vendor/object-0.26.2/src/read/elf/file.rs -+++ b/vendor/object-0.26.2/src/read/elf/file.rs -@@ -161,6 +161,7 @@ where - (elf::EM_X86_64, false) => Architecture::X86_64_X32, - (elf::EM_X86_64, true) => Architecture::X86_64, - (elf::EM_HEXAGON, _) => Architecture::Hexagon, -+ (elf::EM_LOONGARCH, true) => Architecture::LoongArch64, - (elf::EM_MIPS, false) => Architecture::Mips, - (elf::EM_MIPS, true) => Architecture::Mips64, - (elf::EM_MSP430, _) => Architecture::Msp430, -diff --git a/vendor/object-0.26.2/src/read/elf/relocation.rs b/vendor/object-0.26.2/src/read/elf/relocation.rs -index d3e24b2e8..790cebc91 100644 ---- a/vendor/object-0.26.2/src/read/elf/relocation.rs -+++ b/vendor/object-0.26.2/src/read/elf/relocation.rs -@@ -301,6 +301,11 @@ fn parse_relocation( - elf::R_HEX_32 => (RelocationKind::Absolute, 32), - r_type => (RelocationKind::Elf(r_type), 0), - }, -+ elf::EM_LOONGARCH => match reloc.r_type(endian, false) { -+ elf::R_LARCH_32 => (RelocationKind::Absolute, 32), -+ elf::R_LARCH_64 => (RelocationKind::Absolute, 64), -+ r_type => (RelocationKind::Elf(r_type), 0), -+ }, - elf::EM_MIPS => match reloc.r_type(endian, is_mips64el) { - elf::R_MIPS_16 => (RelocationKind::Absolute, 16), - elf::R_MIPS_32 => (RelocationKind::Absolute, 32), -diff --git a/vendor/object-0.26.2/src/write/elf.rs b/vendor/object-0.26.2/src/write/elf.rs -index 34e0abc85..c90146edb 100644 ---- a/vendor/object-0.26.2/src/write/elf.rs -+++ b/vendor/object-0.26.2/src/write/elf.rs -@@ -88,6 +88,7 @@ impl Object { - Architecture::Riscv32 => true, - Architecture::S390x => true, - Architecture::Sparc64 => true, -+ Architecture::LoongArch64 => true, - _ => { - return Err(Error(format!( - "unimplemented architecture {:?}", -@@ -371,6 +372,7 @@ impl Object { - Architecture::Riscv64 => elf::EM_RISCV, - Architecture::S390x => elf::EM_S390, - Architecture::Sparc64 => elf::EM_SPARCV9, -+ Architecture::LoongArch64 => elf::EM_LOONGARCH, - _ => { - return Err(Error(format!( - "unimplemented architecture {:?}", -@@ -682,6 +684,14 @@ impl Object { - return Err(Error(format!("unimplemented relocation {:?}", reloc))); - } - }, -+ Architecture::LoongArch64 => match (reloc.kind, reloc.encoding, reloc.size) { -+ (RelocationKind::Absolute, _, 32) => elf::R_LARCH_32, -+ (RelocationKind::Absolute, _, 64) => elf::R_LARCH_64, -+ (RelocationKind::Elf(x), _, _) => x, -+ _ => { -+ return Err(Error(format!("unimplemented relocation {:?}", reloc))); -+ } -+ }, - Architecture::Mips | Architecture::Mips64 => { - match (reloc.kind, reloc.encoding, reloc.size) { - (RelocationKind::Absolute, _, 16) => elf::R_MIPS_16, -diff --git a/vendor/object-0.26.2/tests/round_trip/mod.rs b/vendor/object-0.26.2/tests/round_trip/mod.rs -index 37050689f..5d97f7ab9 100644 ---- a/vendor/object-0.26.2/tests/round_trip/mod.rs -+++ b/vendor/object-0.26.2/tests/round_trip/mod.rs -@@ -236,6 +236,7 @@ fn elf_any() { - (Architecture::X86_64, Endianness::Little), - (Architecture::X86_64_X32, Endianness::Little), - (Architecture::Hexagon, Endianness::Little), -+ (Architecture::LoongArch64, Endianness::Little), - (Architecture::Mips, Endianness::Little), - (Architecture::Mips64, Endianness::Little), - (Architecture::Msp430, Endianness::Little), -diff --git a/vendor/object/.cargo-checksum.json b/vendor/object/.cargo-checksum.json -index e4a57348b..a85fa9ebb 100644 ---- a/vendor/object/.cargo-checksum.json -+++ b/vendor/object/.cargo-checksum.json -@@ -1 +1 @@ --{"files":{"CHANGELOG.md":"78aa23a55bd06448276854e3c19f984ff45098071dda36b27a0fb2e236630348","Cargo.toml":"4cdcbff917685fee9e3b4212583c2f1ea7a278b6fdb402ff18e314d57095a8b6","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"0b74dfa0bcee5c420c6b7f67b4b2658f9ab8388c97b8e733975f2cecbdd668a6","README.md":"3c5f153cecb269a4dbd5f0907951b1fe40e53054a9625bb75604e3b142ed45e3","clippy.toml":"50fd0cdaae995561b1d688c9410fe99335fc7ac3916a400dafd25ff63f8215f7","src/archive.rs":"7ca11076759d4b87b42657f866b0d2b1dd07d2536b19645da0a5da5dd713b77d","src/common.rs":"ec5c87c07743202d1faabcaac7e4f65d7d1186ad47d503c7b9cd30ecce39383e","src/elf.rs":"018c6da138e3ff7f7d78c9346ffab37773e23fb6224ac8c7627defc802cbaacb","src/endian.rs":"ceaad1b651627ad9e6218a168f87353ae651f5d76c9f61bc8099dff25007405e","src/lib.rs":"22f3f5a5834821d144daf3b1993da1a2072ee57692321366da9c281de6d0a0fe","src/macho.rs":"50f7afc1bba3c59542f55b7b5c7357fb71fef52235f1b568f08f3efb6780aaf5","src/pe.rs":"f14fe040751bdde66d8a39b53d145817ac131722c6d790f853bbcd764b1466b8","src/pod.rs":"9643a698e1388ad98d1e9ea074ca5b0b35599a2491a82e67a62ebcdc8cb19218","src/read/any.rs":"3c525fbe89144caf72ae0d55f5625b3be8476dcfa8a9203425f68fb087631c12","src/read/archive.rs":"987eaf577ec47f5b4ac4e91c697abad31c00ead02f3241dde4f74ce24a884b20","src/read/coff/comdat.rs":"36846a11b285ad560dc1f18c67b1659f19fe8b5f11a350fe8b7bc5d27d0afb65","src/read/coff/file.rs":"874b4b357dbcb1a6a29c993e908b4044c9f90b0acd402cc8504ab84c3a036e1d","src/read/coff/mod.rs":"5eed1c0ca7cf044b3173223b06afacc4961a0515ef2478fffa35641f4ee364ee","src/read/coff/relocation.rs":"3b8e1405921eb16b8d38da4639a81be0546dca51c7747c126729d7a15da93a17","src/read/coff/section.rs":"dcb5b697a9371b1de6584603266673badfcd5d7f82b5472ead37555d69449e19","src/read/coff/symbol.rs":"a2b0e3131c17e3b14def694342b119a215b017ac81c8538097bebe0ea3a6ecdd","src/read/elf/comdat.rs":"9c31a274e7b43bc27f9b82a67207b94eef2d07ef107c8e2ef7a1535fe7329f55","src/read/elf/compression.rs":"097ff8bdc78d01a1532b11c1c0cae3b35905128c7d98b471de188d46da3ff970","src/read/elf/dynamic.rs":"8f59bd6d352f6810be6b6dc02c2f88229f15aa02a42f8fc09bcf3f284d4b1021","src/read/elf/file.rs":"192adf7e082e9a702233f5012981b422408e55f0d8460cf39f8faa8fda0d6a5e","src/read/elf/hash.rs":"82123642ba71d2e56acae5bdbb59253b16ced8f6defdc58f4c37cafb7154a7b0","src/read/elf/mod.rs":"98b5bd46778d3c33e9d19dee2d294f61677dec16b28f22aa73340008c241fe09","src/read/elf/note.rs":"33bf89a85bb7927fd0123cd6c2919f0b9b0f8935db1ae7b446b75ea2717a476d","src/read/elf/relocation.rs":"4ce50bfeaa6ae69c36458139a7699eac6542f448c786b5a102efd187b0fd5ddb","src/read/elf/section.rs":"2c535c3ccd4d333a4abdfe9d14eeee0afb7b11c536387ba2c150e4ead7fb51bd","src/read/elf/segment.rs":"f0534940d8697d7bb66bc784dee0a3e2e173c2ff5266d03d7ad92b0b3efa15e1","src/read/elf/symbol.rs":"6d7361ed09d3829f6fed87f26d10746b4b8b1862579f94445683651f047b8b43","src/read/elf/version.rs":"154510d6868730f2d2fae2e0d9bdb697907ed48ded51c55ba115edd98d819e82","src/read/macho/dyld_cache.rs":"1526f518dfdcc9e024e6c0284ff75018e33413c14ea2ee00c8a99c31ccce6413","src/read/macho/fat.rs":"05e84f0a10958ef4e3828f388cd5d2fea95481ea89aeb80b76a2784c4208e4a1","src/read/macho/file.rs":"ee5e429abdaf6de167de2247679e13ce37724a6a0c50b8842302eb98d583bb71","src/read/macho/load_command.rs":"df976715bbc7699f7fdb8e9d388ba3e96a6d40c6a03b96c2696bd7c19786695a","src/read/macho/mod.rs":"23b353da3b7e076c68a067776e6a5b346a746116ac42c2c90bafd95ad54a90b3","src/read/macho/relocation.rs":"77fa3e65ccf5884433c96cdc39c457b8a0c430432e5ff9cad22a8becf13f0183","src/read/macho/section.rs":"78e98624691ef9872cc090187d90e09f9a54b47b3b1f174fd4f57e0640f6ceeb","src/read/macho/segment.rs":"cd3727796b672adba03443fadc4f458e117c3f56c2ebb318e32c408329a40492","src/read/macho/symbol.rs":"a2e50bcc1ebb5ea356a6f08b9083533c62ae3b3af90de18e8c942bf06589e85a","src/read/mod.rs":"e8c308113c48439a00777404fca21d9115203c1135e65b8703d533af761658a2","src/read/pe/data_directory.rs":"9c20dec2b52b26d0a80d2cdf9565c5298ea90e5b5b1001808abf56cdb25a7f8b","src/read/pe/export.rs":"07ac5ec7b67d4a09037d8f11eb4426d96515687ee299df2a3d8cd4fd93eb2036","src/read/pe/file.rs":"59d2b02d1c1cbac649796b245f4e8c85fdfedf5ca0feab4524cc2004aae82927","src/read/pe/import.rs":"ad1a094a3608be6c17dcc7d8c9eae99f2628055f0550818657cb0b185b4fb35e","src/read/pe/mod.rs":"69832b7f4ccd93b59e08bafcbd0d3226c450d7801ad49ab554b38b660c8997fd","src/read/pe/relocation.rs":"0335c06b6d37df4939c8b88044313e88661ee45e5a57d2eec40143f2fe481838","src/read/pe/resource.rs":"71f9b8c0aaf0c54a7ee3bd0a2135f72d48da8bda2b4e3550c17aa4cc22e0ac5f","src/read/pe/rich.rs":"abf005004e69a4533132358aa54df73d7cc3a744738518e5b11c6f6f861e9f00","src/read/pe/section.rs":"f936dd73dbb1838cf558483949acdfefce701cdc22c21c96db345062c1ce641d","src/read/read_cache.rs":"939b66cfc11fc022c4e4b78fcad63b375516967da2274da78fb200271d934a53","src/read/read_ref.rs":"5fe6f717c79b07fecac9ee8ba15740c7a9581c36f1e356119e99dd669af6c39c","src/read/traits.rs":"b0e4cf654301843fa4db05a6fb1e22c454eb45da6af99b66e631f2b49bab9e21","src/read/util.rs":"c329a240689b177613049e00faf7928e6cd6aad021542cd708cc06b598c6900e","src/read/wasm.rs":"e5bd4cf1282c877f55401b14bb92beb1a8b7f222e4facd2b8fcf6a8599c1ba7e","src/write/coff.rs":"43413acdb221a985b7d4c4c326ee4a48c09bc3d7dc99162a16724b99c8abf3c9","src/write/elf/mod.rs":"1bb945edad539b4f19dda5d46c9b86fa4ea3721eedda77ca2595b5519c3e30f2","src/write/elf/object.rs":"6101aef4e2c65f0e41fa63c04f229950b173525110b86165aede792159004ec2","src/write/elf/writer.rs":"a0bf5bb8bcd9d25510ce14f3a070ad9f9bfed3becc70ee600b2c73bc1e0eccd8","src/write/macho.rs":"392e3a81ebb1694cd9e66eeb98f046731348030b0c1f45e4a22df52aad928b94","src/write/mod.rs":"4ee5a5f971a4a4b184169c6b8dc50d79eb89937316b4677a1f526fef4a0ed106","src/write/pe.rs":"6c72185705a3e067c481f2b9f81c64a84e062e67781928e58fd1150314dad8f9","src/write/string.rs":"674c5913d0702cbaebe79d2a7e91f6a04327ac30e370557f02928eee1b0bb0d0","src/write/util.rs":"0e96abed0e8aae33c2efd8b836f29647eac310b58fad4029b68894e9f57bf137","tests/integration.rs":"0fa704827e4da1be38dac2e3820d92f6b20c4d415803b04f67c3516020b1de97","tests/parse_self.rs":"81b44b2dd1de9a5d8c18d9bd8926156e39fb83931837afa8ca344da0d309aeee","tests/read/coff.rs":"11bf5a1b5770a4312e334580975a7cac9d69f1b12a4d75f25aacc931df01c5c7","tests/read/mod.rs":"7833826f169ac3be2b4f274e5fc8cf4a51742bd0010803ff0dc20ea5643a7e61","tests/round_trip/bss.rs":"849d69b063fd757fed02219dd81e9d13b82068a2025d2cc5cfd40cf557e31bda","tests/round_trip/coff.rs":"8a25aab7164a5c8aa7a21279f8bae1f4d5f68a8d09c29a4ecd0d0c14564851cc","tests/round_trip/comdat.rs":"a8f729e218fee21e90b9f39b5cfcb4f80bc3ce26d3a297323667e6eb14f882cc","tests/round_trip/common.rs":"ced08ff559ca4d343ceef54bb4c581a3405cd96d6a1628ba43b7aab82070800b","tests/round_trip/elf.rs":"690015fb4d3e79ee6d41c4d3a8e89a6806f1a0c313804707b83e44fceefac472","tests/round_trip/macho.rs":"b23931f506345b26ce3b4908dc2ce02f704603c622d39f5e9e7c8529f2882818","tests/round_trip/mod.rs":"ed1bef4d599ba31ca7083f53cf8605a91e1dd0a3e755df9271d1417649230452","tests/round_trip/section_flags.rs":"0e17639e5f86d576f039a294c274ce8db2e2a8add31a2fffc33a6e93a6d2791e","tests/round_trip/tls.rs":"23a49a1036b9173ece82a3080745930e5925e745280ab38866c9d3c29f463e63"},"package":"21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53"} -\ No newline at end of file -+{"files":{"CHANGELOG.md":"78aa23a55bd06448276854e3c19f984ff45098071dda36b27a0fb2e236630348","Cargo.toml":"4cdcbff917685fee9e3b4212583c2f1ea7a278b6fdb402ff18e314d57095a8b6","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"0b74dfa0bcee5c420c6b7f67b4b2658f9ab8388c97b8e733975f2cecbdd668a6","README.md":"3c5f153cecb269a4dbd5f0907951b1fe40e53054a9625bb75604e3b142ed45e3","clippy.toml":"50fd0cdaae995561b1d688c9410fe99335fc7ac3916a400dafd25ff63f8215f7","src/archive.rs":"7ca11076759d4b87b42657f866b0d2b1dd07d2536b19645da0a5da5dd713b77d","src/common.rs":"85dfbce1d99eb21feff95062ef39c9082ae4f277cb7f5d8703cc024c9e7060f5","src/elf.rs":"2b81f91e92b13e32e246d357ac6168b0e3d355f82bd8b6d0becaa8b3f97dfd37","src/endian.rs":"ceaad1b651627ad9e6218a168f87353ae651f5d76c9f61bc8099dff25007405e","src/lib.rs":"22f3f5a5834821d144daf3b1993da1a2072ee57692321366da9c281de6d0a0fe","src/macho.rs":"50f7afc1bba3c59542f55b7b5c7357fb71fef52235f1b568f08f3efb6780aaf5","src/pe.rs":"f14fe040751bdde66d8a39b53d145817ac131722c6d790f853bbcd764b1466b8","src/pod.rs":"9643a698e1388ad98d1e9ea074ca5b0b35599a2491a82e67a62ebcdc8cb19218","src/read/any.rs":"3c525fbe89144caf72ae0d55f5625b3be8476dcfa8a9203425f68fb087631c12","src/read/archive.rs":"987eaf577ec47f5b4ac4e91c697abad31c00ead02f3241dde4f74ce24a884b20","src/read/coff/comdat.rs":"36846a11b285ad560dc1f18c67b1659f19fe8b5f11a350fe8b7bc5d27d0afb65","src/read/coff/file.rs":"874b4b357dbcb1a6a29c993e908b4044c9f90b0acd402cc8504ab84c3a036e1d","src/read/coff/mod.rs":"5eed1c0ca7cf044b3173223b06afacc4961a0515ef2478fffa35641f4ee364ee","src/read/coff/relocation.rs":"3b8e1405921eb16b8d38da4639a81be0546dca51c7747c126729d7a15da93a17","src/read/coff/section.rs":"dcb5b697a9371b1de6584603266673badfcd5d7f82b5472ead37555d69449e19","src/read/coff/symbol.rs":"a2b0e3131c17e3b14def694342b119a215b017ac81c8538097bebe0ea3a6ecdd","src/read/elf/comdat.rs":"9c31a274e7b43bc27f9b82a67207b94eef2d07ef107c8e2ef7a1535fe7329f55","src/read/elf/compression.rs":"097ff8bdc78d01a1532b11c1c0cae3b35905128c7d98b471de188d46da3ff970","src/read/elf/dynamic.rs":"8f59bd6d352f6810be6b6dc02c2f88229f15aa02a42f8fc09bcf3f284d4b1021","src/read/elf/file.rs":"192adf7e082e9a702233f5012981b422408e55f0d8460cf39f8faa8fda0d6a5e","src/read/elf/hash.rs":"82123642ba71d2e56acae5bdbb59253b16ced8f6defdc58f4c37cafb7154a7b0","src/read/elf/mod.rs":"98b5bd46778d3c33e9d19dee2d294f61677dec16b28f22aa73340008c241fe09","src/read/elf/note.rs":"33bf89a85bb7927fd0123cd6c2919f0b9b0f8935db1ae7b446b75ea2717a476d","src/read/elf/relocation.rs":"4ce50bfeaa6ae69c36458139a7699eac6542f448c786b5a102efd187b0fd5ddb","src/read/elf/section.rs":"2c535c3ccd4d333a4abdfe9d14eeee0afb7b11c536387ba2c150e4ead7fb51bd","src/read/elf/segment.rs":"f0534940d8697d7bb66bc784dee0a3e2e173c2ff5266d03d7ad92b0b3efa15e1","src/read/elf/symbol.rs":"6d7361ed09d3829f6fed87f26d10746b4b8b1862579f94445683651f047b8b43","src/read/elf/version.rs":"154510d6868730f2d2fae2e0d9bdb697907ed48ded51c55ba115edd98d819e82","src/read/macho/dyld_cache.rs":"1526f518dfdcc9e024e6c0284ff75018e33413c14ea2ee00c8a99c31ccce6413","src/read/macho/fat.rs":"05e84f0a10958ef4e3828f388cd5d2fea95481ea89aeb80b76a2784c4208e4a1","src/read/macho/file.rs":"ee5e429abdaf6de167de2247679e13ce37724a6a0c50b8842302eb98d583bb71","src/read/macho/load_command.rs":"df976715bbc7699f7fdb8e9d388ba3e96a6d40c6a03b96c2696bd7c19786695a","src/read/macho/mod.rs":"23b353da3b7e076c68a067776e6a5b346a746116ac42c2c90bafd95ad54a90b3","src/read/macho/relocation.rs":"77fa3e65ccf5884433c96cdc39c457b8a0c430432e5ff9cad22a8becf13f0183","src/read/macho/section.rs":"78e98624691ef9872cc090187d90e09f9a54b47b3b1f174fd4f57e0640f6ceeb","src/read/macho/segment.rs":"cd3727796b672adba03443fadc4f458e117c3f56c2ebb318e32c408329a40492","src/read/macho/symbol.rs":"a2e50bcc1ebb5ea356a6f08b9083533c62ae3b3af90de18e8c942bf06589e85a","src/read/mod.rs":"e8c308113c48439a00777404fca21d9115203c1135e65b8703d533af761658a2","src/read/pe/data_directory.rs":"9c20dec2b52b26d0a80d2cdf9565c5298ea90e5b5b1001808abf56cdb25a7f8b","src/read/pe/export.rs":"07ac5ec7b67d4a09037d8f11eb4426d96515687ee299df2a3d8cd4fd93eb2036","src/read/pe/file.rs":"59d2b02d1c1cbac649796b245f4e8c85fdfedf5ca0feab4524cc2004aae82927","src/read/pe/import.rs":"ad1a094a3608be6c17dcc7d8c9eae99f2628055f0550818657cb0b185b4fb35e","src/read/pe/mod.rs":"69832b7f4ccd93b59e08bafcbd0d3226c450d7801ad49ab554b38b660c8997fd","src/read/pe/relocation.rs":"0335c06b6d37df4939c8b88044313e88661ee45e5a57d2eec40143f2fe481838","src/read/pe/resource.rs":"71f9b8c0aaf0c54a7ee3bd0a2135f72d48da8bda2b4e3550c17aa4cc22e0ac5f","src/read/pe/rich.rs":"abf005004e69a4533132358aa54df73d7cc3a744738518e5b11c6f6f861e9f00","src/read/pe/section.rs":"f936dd73dbb1838cf558483949acdfefce701cdc22c21c96db345062c1ce641d","src/read/read_cache.rs":"939b66cfc11fc022c4e4b78fcad63b375516967da2274da78fb200271d934a53","src/read/read_ref.rs":"5fe6f717c79b07fecac9ee8ba15740c7a9581c36f1e356119e99dd669af6c39c","src/read/traits.rs":"b0e4cf654301843fa4db05a6fb1e22c454eb45da6af99b66e631f2b49bab9e21","src/read/util.rs":"c329a240689b177613049e00faf7928e6cd6aad021542cd708cc06b598c6900e","src/read/wasm.rs":"e5bd4cf1282c877f55401b14bb92beb1a8b7f222e4facd2b8fcf6a8599c1ba7e","src/write/coff.rs":"43413acdb221a985b7d4c4c326ee4a48c09bc3d7dc99162a16724b99c8abf3c9","src/write/elf/mod.rs":"1bb945edad539b4f19dda5d46c9b86fa4ea3721eedda77ca2595b5519c3e30f2","src/write/elf/object.rs":"93f003cdbd2fa87a049b3bcc3840c18cef69f97ac92d29dd157513d05f1fefd8","src/write/elf/writer.rs":"a0bf5bb8bcd9d25510ce14f3a070ad9f9bfed3becc70ee600b2c73bc1e0eccd8","src/write/macho.rs":"392e3a81ebb1694cd9e66eeb98f046731348030b0c1f45e4a22df52aad928b94","src/write/mod.rs":"4ee5a5f971a4a4b184169c6b8dc50d79eb89937316b4677a1f526fef4a0ed106","src/write/pe.rs":"6c72185705a3e067c481f2b9f81c64a84e062e67781928e58fd1150314dad8f9","src/write/string.rs":"674c5913d0702cbaebe79d2a7e91f6a04327ac30e370557f02928eee1b0bb0d0","src/write/util.rs":"0e96abed0e8aae33c2efd8b836f29647eac310b58fad4029b68894e9f57bf137","tests/integration.rs":"0fa704827e4da1be38dac2e3820d92f6b20c4d415803b04f67c3516020b1de97","tests/parse_self.rs":"81b44b2dd1de9a5d8c18d9bd8926156e39fb83931837afa8ca344da0d309aeee","tests/read/coff.rs":"11bf5a1b5770a4312e334580975a7cac9d69f1b12a4d75f25aacc931df01c5c7","tests/read/mod.rs":"7833826f169ac3be2b4f274e5fc8cf4a51742bd0010803ff0dc20ea5643a7e61","tests/round_trip/bss.rs":"849d69b063fd757fed02219dd81e9d13b82068a2025d2cc5cfd40cf557e31bda","tests/round_trip/coff.rs":"8a25aab7164a5c8aa7a21279f8bae1f4d5f68a8d09c29a4ecd0d0c14564851cc","tests/round_trip/comdat.rs":"a8f729e218fee21e90b9f39b5cfcb4f80bc3ce26d3a297323667e6eb14f882cc","tests/round_trip/common.rs":"ced08ff559ca4d343ceef54bb4c581a3405cd96d6a1628ba43b7aab82070800b","tests/round_trip/elf.rs":"690015fb4d3e79ee6d41c4d3a8e89a6806f1a0c313804707b83e44fceefac472","tests/round_trip/macho.rs":"b23931f506345b26ce3b4908dc2ce02f704603c622d39f5e9e7c8529f2882818","tests/round_trip/mod.rs":"ed1bef4d599ba31ca7083f53cf8605a91e1dd0a3e755df9271d1417649230452","tests/round_trip/section_flags.rs":"0e17639e5f86d576f039a294c274ce8db2e2a8add31a2fffc33a6e93a6d2791e","tests/round_trip/tls.rs":"23a49a1036b9173ece82a3080745930e5925e745280ab38866c9d3c29f463e63"},"package":"21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53"} -diff --git a/vendor/object/src/common.rs b/vendor/object/src/common.rs -index 20dde991a..39a3fa6fe 100644 ---- a/vendor/object/src/common.rs -+++ b/vendor/object/src/common.rs -@@ -13,7 +13,6 @@ pub enum Architecture { - #[allow(non_camel_case_types)] - X86_64_X32, - Hexagon, -- LoongArch64, - Mips, - Mips64, - Msp430, -@@ -24,6 +23,7 @@ pub enum Architecture { - S390x, - Sparc64, - Wasm32, -+ LoongArch64, - } - - impl Architecture { -@@ -41,7 +41,6 @@ impl Architecture { - Architecture::X86_64 => Some(AddressSize::U64), - Architecture::X86_64_X32 => Some(AddressSize::U32), - Architecture::Hexagon => Some(AddressSize::U32), -- Architecture::LoongArch64 => Some(AddressSize::U64), - Architecture::Mips => Some(AddressSize::U32), - Architecture::Mips64 => Some(AddressSize::U64), - Architecture::Msp430 => Some(AddressSize::U16), -@@ -52,6 +51,7 @@ impl Architecture { - Architecture::S390x => Some(AddressSize::U64), - Architecture::Sparc64 => Some(AddressSize::U64), - Architecture::Wasm32 => Some(AddressSize::U32), -+ Architecture::LoongArch64 => Some(AddressSize::U64), - } - } - } -diff --git a/vendor/object/src/elf.rs b/vendor/object/src/elf.rs -index 9f6577269..9c0b91621 100644 ---- a/vendor/object/src/elf.rs -+++ b/vendor/object/src/elf.rs -@@ -574,10 +574,10 @@ pub const EM_RISCV: u16 = 243; - pub const EM_BPF: u16 = 247; - /// C-SKY - pub const EM_CSKY: u16 = 252; --/// Loongson LoongArch --pub const EM_LOONGARCH: u16 = 258; - /// Digital Alpha - pub const EM_ALPHA: u16 = 0x9026; -+/// LOONGARCH -+pub const EM_LOONGARCH: u16 = 258; - - // Values for `FileHeader*::e_version` and `Ident::version`. - /// Invalid ELF version. -@@ -6114,6 +6114,123 @@ pub const R_RISCV_SET32: u32 = 56; - #[allow(missing_docs)] - pub const R_RISCV_32_PCREL: u32 = 57; - -+//LOONGARCH values `FileHeader*::e_flags`. -+#[allow(missing_docs)] -+pub const EF_LARCH_ABI: u32 = 0x0003; -+#[allow(missing_docs)] -+pub const EF_LARCH_ABI_LP64: u32 = 0x0003; -+#[allow(missing_docs)] -+pub const EF_LARCH_ABI_LPX32: u32 = 0x0002; -+#[allow(missing_docs)] -+pub const EF_LARCH_ABI_LP32: u32 = 0x0001; -+ -+// LOONGARCH values `Rel*::r_type`. -+/* Loongarch specific dynamic relocations. */ -+#[allow(missing_docs)] -+pub const R_LARCH_NONE: u32 = 0; -+#[allow(missing_docs)] -+pub const R_LARCH_32: u32 = 1; -+#[allow(missing_docs)] -+pub const R_LARCH_64: u32 = 2; -+#[allow(missing_docs)] -+pub const R_LARCH_RELATIVE: u32 = 3; -+#[allow(missing_docs)] -+pub const R_LARCH_COPY: u32 = 4; -+#[allow(missing_docs)] -+pub const R_LARCH_JUMP_SLOT: u32 = 5; -+#[allow(missing_docs)] -+pub const R_LARCH_TLS_DTPMOD32: u32 = 6; -+#[allow(missing_docs)] -+pub const R_LARCH_TLS_DTPMOD64: u32 = 7; -+#[allow(missing_docs)] -+pub const R_LARCH_TLS_DTPREL32: u32 = 8; -+#[allow(missing_docs)] -+pub const R_LARCH_TLS_DTPREL64: u32 = 9; -+#[allow(missing_docs)] -+pub const R_LARCH_TLS_TPREL32: u32 = 10; -+#[allow(missing_docs)] -+pub const R_LARCH_TLS_TPREL64: u32 = 11; -+#[allow(missing_docs)] -+pub const R_LARCH_IRELATIVE: u32 = 12; -+#[allow(missing_docs)] -+pub const R_LARCH_MARK_LA: u32 = 20; -+#[allow(missing_docs)] -+pub const R_LARCH_MARK_PCREL: u32 = 21; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_PUSH_PCREL: u32 = 22; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_PUSH_ABSOLUTE: u32 = 23; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_PUSH_DUP: u32 = 24; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_PUSH_GPREL: u32 = 25; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_PUSH_TLS_TPREL: u32 = 26; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_PUSH_TLS_GOT: u32 = 27; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_PUSH_TLS_GD: u32 = 28; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_PUSH_PLT_PCREL: u32 = 29; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_ASSERT: u32 = 30; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_NOT: u32 = 31; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_SUB: u32 = 32; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_SL: u32 = 33; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_SR: u32 = 34; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_ADD: u32 = 35; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_AND: u32 = 36; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_IF_ELSE: u32 = 37; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_POP_32_S_10_5: u32 = 38; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_POP_32_U_10_12: u32 = 39; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_POP_32_S_10_12: u32 = 40; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_POP_32_S_10_16: u32 = 41; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_POP_32_S_10_16_S2: u32 = 42; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_POP_32_S_5_20: u32 = 43; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_POP_32_S_0_5_10_16_S2: u32 = 44; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_POP_32_S_0_10_10_16_S2: u32 = 45; -+#[allow(missing_docs)] -+pub const R_LARCH_SOP_POP_32_U: u32 = 46; -+#[allow(missing_docs)] -+pub const R_LARCH_ADD8: u32 = 47; -+#[allow(missing_docs)] -+pub const R_LARCH_ADD16: u32 = 48; -+#[allow(missing_docs)] -+pub const R_LARCH_ADD24: u32 = 49; -+#[allow(missing_docs)] -+pub const R_LARCH_ADD32: u32 = 50; -+#[allow(missing_docs)] -+pub const R_LARCH_ADD64: u32 = 51; -+#[allow(missing_docs)] -+pub const R_LARCH_SUB8: u32 = 52; -+#[allow(missing_docs)] -+pub const R_LARCH_SUB16: u32 = 53; -+#[allow(missing_docs)] -+pub const R_LARCH_SUB24: u32 = 54; -+#[allow(missing_docs)] -+pub const R_LARCH_SUB32: u32 = 55; -+#[allow(missing_docs)] -+pub const R_LARCH_SUB64: u32 = 56; -+#[allow(missing_docs)] -+pub const R_LARCH_GNU_VTINHERIT: u32 = 57; -+#[allow(missing_docs)] -+pub const R_LARCH_GNU_VTENTRY: u32 = 58; -+ - // BPF values `Rel*::r_type`. - /// No reloc - pub const R_BPF_NONE: u32 = 0; -@@ -6250,129 +6367,6 @@ pub const R_NDS32_TLS_TPOFF: u32 = 102; - #[allow(missing_docs)] - pub const R_NDS32_TLS_DESC: u32 = 119; - --// LoongArch values `FileHeader*::e_flags`. --/// Uses 64-bit GPRs and the stack for parameter passing --pub const EF_LARCH_ABI_LP64S: u32 = 0x1; --/// Uses 64-bit GPRs, 32-bit FPRs and the stack for parameter passing --pub const EF_LARCH_ABI_LP64F: u32 = 0x2; --/// Uses 64-bit GPRs, 64-bit FPRs and the stack for parameter passing --pub const EF_LARCH_ABI_LP64D: u32 = 0x3; --/// Uses 32-bit GPRs and the stack for parameter passing --pub const EF_LARCH_ABI_ILP32S: u32 = 0x5; --/// Uses 32-bit GPRs, 32-bit FPRs and the stack for parameter passing --pub const EF_LARCH_ABI_ILP32F: u32 = 0x6; --/// Uses 32-bit GPRs, 64-bit FPRs and the stack for parameter passing --pub const EF_LARCH_ABI_ILP32D: u32 = 0x7; -- --// LoongArch values `Rel*::r_type`. --/// No reloc --pub const R_LARCH_NONE: u32 = 0; --/// Runtime address resolving --pub const R_LARCH_32: u32 = 1; --/// Runtime address resolving --pub const R_LARCH_64: u32 = 2; --/// Runtime fixup for load-address --pub const R_LARCH_RELATIVE: u32 = 3; --/// Runtime memory copy in executable --pub const R_LARCH_COPY: u32 = 4; --/// Runtime PLT supporting --pub const R_LARCH_JUMP_SLOT: u32 = 5; --/// Runtime relocation for TLS-GD --pub const R_LARCH_TLS_DTPMOD32: u32 = 6; --/// Runtime relocation for TLS-GD --pub const R_LARCH_TLS_DTPMOD64: u32 = 7; --/// Runtime relocation for TLS-GD --pub const R_LARCH_TLS_DTPREL32: u32 = 8; --/// Runtime relocation for TLS-GD --pub const R_LARCH_TLS_DTPREL64: u32 = 9; --/// Runtime relocation for TLE-IE --pub const R_LARCH_TLS_TPREL32: u32 = 10; --/// Runtime relocation for TLE-IE --pub const R_LARCH_TLS_TPREL64: u32 = 11; --/// Runtime local indirect function resolving --pub const R_LARCH_IRELATIVE: u32 = 12; --/// Mark la.abs: load absolute address for static link. --pub const R_LARCH_MARK_LA: u32 = 20; --/// Mark external label branch: access PC relative address for static link. --pub const R_LARCH_MARK_PCREL: u32 = 21; --/// Push PC-relative offset --pub const R_LARCH_SOP_PUSH_PCREL: u32 = 22; --/// Push constant or absolute address --pub const R_LARCH_SOP_PUSH_ABSOLUTE: u32 = 23; --/// Duplicate stack top --pub const R_LARCH_SOP_PUSH_DUP: u32 = 24; --/// Push for access GOT entry --pub const R_LARCH_SOP_PUSH_GPREL: u32 = 25; --/// Push for TLS-LE --pub const R_LARCH_SOP_PUSH_TLS_TPREL: u32 = 26; --/// Push for TLS-IE --pub const R_LARCH_SOP_PUSH_TLS_GOT: u32 = 27; --/// Push for TLS-GD --pub const R_LARCH_SOP_PUSH_TLS_GD: u32 = 28; --/// Push for external function calling --pub const R_LARCH_SOP_PUSH_PLT_PCREL: u32 = 29; --/// Assert stack top --pub const R_LARCH_SOP_ASSERT: u32 = 30; --/// Stack top logical not (unary) --pub const R_LARCH_SOP_NOT: u32 = 31; --/// Stack top subtraction (binary) --pub const R_LARCH_SOP_SUB: u32 = 32; --/// Stack top left shift (binary) --pub const R_LARCH_SOP_SL: u32 = 33; --/// Stack top right shift (binary) --pub const R_LARCH_SOP_SR: u32 = 34; --/// Stack top addition (binary) --pub const R_LARCH_SOP_ADD: u32 = 35; --/// Stack top bitwise and (binary) --pub const R_LARCH_SOP_AND: u32 = 36; --/// Stack top selection (tertiary) --pub const R_LARCH_SOP_IF_ELSE: u32 = 37; --/// Pop stack top to fill 5-bit signed immediate operand --pub const R_LARCH_SOP_POP_32_S_10_5: u32 = 38; --/// Pop stack top to fill 12-bit unsigned immediate operand --pub const R_LARCH_SOP_POP_32_U_10_12: u32 = 39; --/// Pop stack top to fill 12-bit signed immediate operand --pub const R_LARCH_SOP_POP_32_S_10_12: u32 = 40; --/// Pop stack top to fill 16-bit signed immediate operand --pub const R_LARCH_SOP_POP_32_S_10_16: u32 = 41; --/// Pop stack top to fill 18-bit signed immediate operand with two trailing --/// zeros implied --pub const R_LARCH_SOP_POP_32_S_10_16_S2: u32 = 42; --/// Pop stack top to fill 20-bit signed immediate operand --pub const R_LARCH_SOP_POP_32_S_5_20: u32 = 43; --/// Pop stack top to fill 23-bit signed immediate operand with two trailing --/// zeros implied --pub const R_LARCH_SOP_POP_32_S_0_5_10_16_S2: u32 = 44; --/// Pop stack top to fill 28-bit signed immediate operand with two trailing --/// zeros implied --pub const R_LARCH_SOP_POP_32_S_0_10_10_16_S2: u32 = 45; --/// Pop stack top to fill an instruction --pub const R_LARCH_SOP_POP_32_U: u32 = 46; --/// 8-bit in-place addition --pub const R_LARCH_ADD8: u32 = 47; --/// 16-bit in-place addition --pub const R_LARCH_ADD16: u32 = 48; --/// 24-bit in-place addition --pub const R_LARCH_ADD24: u32 = 49; --/// 32-bit in-place addition --pub const R_LARCH_ADD32: u32 = 50; --/// 64-bit in-place addition --pub const R_LARCH_ADD64: u32 = 51; --/// 8-bit in-place subtraction --pub const R_LARCH_SUB8: u32 = 52; --/// 16-bit in-place subtraction --pub const R_LARCH_SUB16: u32 = 53; --/// 24-bit in-place subtraction --pub const R_LARCH_SUB24: u32 = 54; --/// 32-bit in-place subtraction --pub const R_LARCH_SUB32: u32 = 55; --/// 64-bit in-place subtraction --pub const R_LARCH_SUB64: u32 = 56; --/// GNU C++ vtable hierarchy --pub const R_LARCH_GNU_VTINHERIT: u32 = 57; --/// GNU C++ vtable member usage --pub const R_LARCH_GNU_VTENTRY: u32 = 58; -- - unsafe_impl_endian_pod!( - FileHeader32, - FileHeader64, -diff --git a/vendor/object/src/write/elf/object.rs b/vendor/object/src/write/elf/object.rs -index 8c1fa4717..7541e8ebf 100644 ---- a/vendor/object/src/write/elf/object.rs -+++ b/vendor/object/src/write/elf/object.rs -@@ -74,7 +74,6 @@ impl<'a> Object<'a> { - Architecture::X86_64 => true, - Architecture::X86_64_X32 => true, - Architecture::Hexagon => true, -- Architecture::LoongArch64 => true, - Architecture::Mips => false, - Architecture::Mips64 => true, - Architecture::Msp430 => true, -@@ -84,6 +83,7 @@ impl<'a> Object<'a> { - Architecture::Riscv32 => true, - Architecture::S390x => true, - Architecture::Sparc64 => true, -+ Architecture::LoongArch64 => true, - _ => { - return Err(Error(format!( - "unimplemented architecture {:?}", -@@ -271,7 +271,6 @@ impl<'a> Object<'a> { - Architecture::X86_64 => elf::EM_X86_64, - Architecture::X86_64_X32 => elf::EM_X86_64, - Architecture::Hexagon => elf::EM_HEXAGON, -- Architecture::LoongArch64 => elf::EM_LOONGARCH, - Architecture::Mips => elf::EM_MIPS, - Architecture::Mips64 => elf::EM_MIPS, - Architecture::Msp430 => elf::EM_MSP430, -@@ -281,6 +280,7 @@ impl<'a> Object<'a> { - Architecture::Riscv64 => elf::EM_RISCV, - Architecture::S390x => elf::EM_S390, - Architecture::Sparc64 => elf::EM_SPARCV9, -+ Architecture::LoongArch64 => elf::EM_LOONGARCH, - _ => { - return Err(Error(format!( - "unimplemented architecture {:?}", -@@ -524,8 +524,7 @@ impl<'a> Object<'a> { - return Err(Error(format!("unimplemented relocation {:?}", reloc))); - } - }, -- Architecture::LoongArch64 => match (reloc.kind, reloc.encoding, reloc.size) -- { -+ Architecture::LoongArch64 => match (reloc.kind, reloc.encoding, reloc.size) { - (RelocationKind::Absolute, _, 32) => elf::R_LARCH_32, - (RelocationKind::Absolute, _, 64) => elf::R_LARCH_64, - (RelocationKind::Elf(x), _, _) => x, --- -2.41.0 - diff --git a/0005-llvm-update-loongarch64-support.patch b/0005-llvm-update-loongarch64-support.patch deleted file mode 100644 index 10258a26217e093a6ea408711c3514fdf972459b..0000000000000000000000000000000000000000 --- a/0005-llvm-update-loongarch64-support.patch +++ /dev/null @@ -1,70995 +0,0 @@ -From fdea5c854378f7722ec6443de42999ba83f9c086 Mon Sep 17 00:00:00 2001 -From: WANG Rui -Date: Sun, 25 Jun 2023 16:27:22 +0800 -Subject: [PATCH 5/6] llvm: update loongarch64 support - ---- - .../readability/SimplifyBooleanExprCheck.cpp | 4 +- - .../clang-tools-extra/clangd/CodeComplete.cpp | 5 +- - .../clang-tools-extra/clangd/Headers.cpp | 26 +- - .../clang-tools-extra/clangd/Headers.h | 6 + - .../clang-tools-extra/clangd/InlayHints.cpp | 59 +- - .../clang-tools-extra/clangd/TidyProvider.cpp | 10 +- - .../clangd/index/CanonicalIncludes.cpp | 16 +- - .../clangd/test/lit.site.cfg.py.in | 1 + - .../clangd/unittests/CodeCompleteTests.cpp | 17 + - .../clangd/unittests/HeadersTests.cpp | 14 + - .../clangd/unittests/InlayHintTests.cpp | 9 + - ...y-bool-expr-chained-conditional-return.cpp | 11 + - src/llvm-project/clang/CMakeLists.txt | 1 + - src/llvm-project/clang/docs/ReleaseNotes.rst | 6 + - .../clang/lib/Basic/CMakeLists.txt | 4 + - src/llvm-project/clang/lib/CodeGen/CGStmt.cpp | 15 + - .../clang/lib/CodeGen/TargetInfo.cpp | 8 +- - .../clang/lib/Driver/ToolChains/Gnu.cpp | 40 +- - src/llvm-project/clang/lib/Sema/SemaInit.cpp | 8 +- - .../clang/lib/Sema/SemaLookup.cpp | 8 +- - src/llvm-project/clang/lib/Sema/SemaType.cpp | 3 + - .../lib/StaticAnalyzer/Core/ExprEngine.cpp | 6 + - .../clang/lib/Tooling/Syntax/Tokens.cpp | 222 +- - .../test/Analysis/template-param-objects.cpp | 33 + - .../clang/test/CodeGen/arm-vaarg.c | 23 + - .../test/CodeGen/attr-btf_type_tag-func-ptr.c | 15 + - .../test/CodeGen/debug-info-enum-case-val.c | 30 + - .../clang/test/Sema/gnu-builtins.c | 13 + - .../SemaCXX/specialization-diagnose-crash.cpp | 24 + - .../clang/unittests/Driver/ToolChainTest.cpp | 92 - - .../unittests/Tooling/Syntax/TokensTest.cpp | 56 + - .../cmake/Modules/FindLibEdit.cmake | 1 + - .../cmake/Modules/CompilerRTDarwinUtils.cmake | 2 +- - .../compiler-rt/cmake/config-ix.cmake | 2 +- - .../compiler-rt/lib/builtins/CMakeLists.txt | 2 +- - .../lib/sanitizer_common/sanitizer_common.h | 2 +- - .../sanitizer_common_interceptors.inc | 2 +- - .../sanitizer_common/sanitizer_stack_store.h | 2 +- - .../TestCases/Linux/sem_init_glibc.cpp | 43 +- - .../function.objects/func.blocks.arc.pass.mm | 89 + - .../vector.bool/ctor_exceptions.pass.cpp | 141 + - .../vector/vector.cons/exceptions.pass.cpp | 229 + - src/llvm-project/libunwind/CMakeLists.txt | 2 +- - src/llvm-project/libunwind/README_RUST_SGX.md | 22 - - .../libunwind/cmake/config-ix.cmake | 2 +- - .../libunwind/docs/BuildingLibunwind.rst | 5 - - .../libunwind/src/AddressSpace.hpp | 27 - - src/llvm-project/libunwind/src/CMakeLists.txt | 47 +- - src/llvm-project/libunwind/src/RWMutex.hpp | 2 +- - .../libunwind/src/UnwindRustSgx.c | 125 - - .../libunwind/src/UnwindRustSgx.h | 94 - - src/llvm-project/libunwind/src/config.h | 4 - - src/llvm-project/lld/CMakeLists.txt | 13 - - src/llvm-project/lld/COFF/CMakeLists.txt | 1 + - src/llvm-project/lld/Common/CMakeLists.txt | 9 +- - src/llvm-project/lld/ELF/Arch/RISCV.cpp | 6 +- - src/llvm-project/lld/ELF/Driver.cpp | 9 +- - src/llvm-project/lld/ELF/InputFiles.cpp | 6 +- - src/llvm-project/lld/ELF/InputSection.cpp | 11 +- - .../lld/ELF/SyntheticSections.cpp | 10 +- - .../lld/MachO/UnwindInfoSection.cpp | 35 +- - .../lld/MachO/UnwindInfoSection.h | 2 +- - src/llvm-project/lld/MachO/Writer.cpp | 2 +- - .../lld/test/ELF/comdat-binding2.s | 42 + - .../lld/test/ELF/lto-plugin-ignore.s | 2 + - .../test/MachO/eh-frame-personality-dedup.s | 43 + - src/llvm-project/lld/test/wasm/export-all.s | 7 +- - .../lld/test/wasm/mutable-global-exports.s | 7 +- - src/llvm-project/lld/wasm/Driver.cpp | 1 + - src/llvm-project/lld/wasm/Symbols.cpp | 1 + - src/llvm-project/lld/wasm/Symbols.h | 11 +- - src/llvm-project/lld/wasm/Writer.cpp | 16 +- - src/llvm-project/lldb/bindings/CMakeLists.txt | 2 - - .../lldb/bindings/interfaces.swig | 3 - - .../lldb/bindings/python/python-typemaps.swig | 2 +- - .../lldb/include/lldb/API/SBType.h | 2 + - .../lldb/include/lldb/Symbol/CompilerType.h | 24 +- - .../lldb/include/lldb/Symbol/TypeSystem.h | 14 +- - src/llvm-project/lldb/source/API/SBType.cpp | 12 +- - .../source/Plugins/Process/Linux/Perf.cpp | 31 +- - .../TypeSystem/Clang/TypeSystemClang.cpp | 81 +- - .../TypeSystem/Clang/TypeSystemClang.h | 19 +- - .../lldb/source/Symbol/CompilerType.cpp | 18 +- - .../lldb/source/Symbol/TypeSystem.cpp | 12 +- - .../TestTemplatePackArgs.py | 38 + - .../class-template-parameter-pack/main.cpp | 8 +- - .../tools/debugserver/source/CMakeLists.txt | 2 +- - .../unittests/Symbol/TestTypeSystemClang.cpp | 30 +- - src/llvm-project/llvm/CMakeLists.txt | 5 +- - src/llvm-project/llvm/cmake/config-ix.cmake | 4 +- - src/llvm-project/llvm/cmake/config.guess | 3 + - .../llvm/cmake/modules/AddLLVM.cmake | 1 + - .../llvm/cmake/modules/CheckAtomic.cmake | 13 + - .../llvm/cmake/modules/FindFFI.cmake | 2 +- - .../llvm/cmake/modules/FindTerminfo.cmake | 2 +- - .../llvm/cmake/modules/FindZ3.cmake | 3 +- - .../llvm/cmake/modules/Findzstd.cmake | 49 + - .../cmake/modules/HandleLLVMOptions.cmake | 2 +- - .../llvm/cmake/modules/LLVMConfig.cmake.in | 1 - - src/llvm-project/llvm/docs/ReleaseNotes.rst | 14 + - .../llvm/include/llvm/ADT/Triple.h | 11 + - .../llvm/include/llvm/BinaryFormat/ELF.h | 23 +- - .../llvm/include/llvm/IR/CMakeLists.txt | 1 + - .../llvm/include/llvm/IR/InlineAsm.h | 1 + - .../llvm/include/llvm/IR/Intrinsics.td | 1 + - .../include/llvm/IR/IntrinsicsLoongArch.td | 3657 +++++++ - .../llvm/lib/Analysis/ScalarEvolution.cpp | 7 +- - .../llvm/lib/Analysis/VectorUtils.cpp | 7 +- - .../llvm/lib/CodeGen/PrologEpilogInserter.cpp | 8 +- - .../llvm/lib/CodeGen/RegAllocFast.cpp | 3 + - .../lib/CodeGen/SelectionDAG/InstrEmitter.cpp | 3 + - .../SelectionDAG/SelectionDAGBuilder.cpp | 1 + - .../CodeGen/TargetLoweringObjectFileImpl.cpp | 10 + - .../llvm/lib/CodeGen/TypePromotion.cpp | 4 +- - .../lib/DebugInfo/DWARF/DWARFVerifier.cpp | 6 +- - src/llvm-project/llvm/lib/IR/AutoUpgrade.cpp | 2 +- - src/llvm-project/llvm/lib/IR/Function.cpp | 1 + - .../llvm/lib/MC/MCObjectFileInfo.cpp | 6 + - .../llvm/lib/Object/RelocationResolver.cpp | 26 + - .../llvm/lib/ObjectYAML/ELFYAML.cpp | 8 - - .../llvm/lib/Support/CMakeLists.txt | 21 +- - src/llvm-project/llvm/lib/Support/Triple.cpp | 1 + - .../lib/Support/UnicodeNameToCodepoint.cpp | 8 +- - .../llvm/lib/Support/Unix/Path.inc | 2 +- - .../llvm/lib/Support/Unix/Signals.inc | 4 - - .../llvm/lib/Support/Windows/Threading.inc | 6 - - .../llvm/lib/Support/X86TargetParser.cpp | 10 +- - .../Target/AArch64/AArch64ISelLowering.cpp | 67 +- - .../lib/Target/AArch64/AArch64ISelLowering.h | 2 +- - .../llvm/lib/Target/AMDGPU/SIISelLowering.cpp | 2 + - .../lib/Target/ARM/ARMTargetTransformInfo.cpp | 2 +- - .../Target/LoongArch/AsmParser/CMakeLists.txt | 4 +- - .../AsmParser/LoongArchAsmParser.cpp | 2529 ++++- - .../llvm/lib/Target/LoongArch/CMakeLists.txt | 13 +- - .../LoongArch/Disassembler/CMakeLists.txt | 4 +- - .../Disassembler/LoongArchDisassembler.cpp | 921 +- - .../llvm/lib/Target/LoongArch/LoongArch.h | 37 +- - .../llvm/lib/Target/LoongArch/LoongArch.td | 166 +- - .../Target/LoongArch/LoongArch32InstrInfo.td | 717 ++ - .../Target/LoongArch/LoongArchAsmPrinter.cpp | 614 +- - .../Target/LoongArch/LoongArchAsmPrinter.h | 115 +- - .../lib/Target/LoongArch/LoongArchCCState.cpp | 165 + - .../lib/Target/LoongArch/LoongArchCCState.h | 165 + - .../Target/LoongArch/LoongArchCallingConv.td | 309 +- - .../LoongArch/LoongArchExpandPseudo.cpp | 2471 +++++ - .../LoongArch/LoongArchFloat32InstrInfo.td | 229 - - .../LoongArch/LoongArchFloat64InstrInfo.td | 242 - - .../LoongArch/LoongArchFloatInstrFormats.td | 241 - - .../LoongArch/LoongArchFrameLowering.cpp | 610 +- - .../Target/LoongArch/LoongArchFrameLowering.h | 61 +- - .../LoongArch/LoongArchISelDAGToDAG.cpp | 946 +- - .../Target/LoongArch/LoongArchISelDAGToDAG.h | 143 +- - .../LoongArch/LoongArchISelLowering.cpp | 8809 +++++++++++++++-- - .../Target/LoongArch/LoongArchISelLowering.h | 632 +- - .../Target/LoongArch/LoongArchInstrFormats.td | 842 +- - .../Target/LoongArch/LoongArchInstrInfo.cpp | 1067 +- - .../lib/Target/LoongArch/LoongArchInstrInfo.h | 220 +- - .../Target/LoongArch/LoongArchInstrInfo.td | 2646 +++-- - .../Target/LoongArch/LoongArchInstrInfoF.td | 630 ++ - .../LoongArch/LoongArchLASXInstrFormats.td | 448 + - .../LoongArch/LoongArchLASXInstrInfo.td | 5673 +++++++++++ - .../LoongArch/LoongArchLSXInstrFormats.td | 449 + - .../Target/LoongArch/LoongArchLSXInstrInfo.td | 5906 +++++++++++ - .../Target/LoongArch/LoongArchMCInstLower.cpp | 357 +- - .../Target/LoongArch/LoongArchMCInstLower.h | 55 + - .../LoongArch/LoongArchMachineFunction.cpp | 58 + - .../LoongArch/LoongArchMachineFunction.h | 103 + - .../LoongArch/LoongArchMachineFunctionInfo.h | 57 - - .../LoongArch/LoongArchModuleISelDAGToDAG.cpp | 53 + - .../LoongArch/LoongArchRegisterInfo.cpp | 376 +- - .../Target/LoongArch/LoongArchRegisterInfo.h | 62 +- - .../Target/LoongArch/LoongArchRegisterInfo.td | 484 +- - .../Target/LoongArch/LoongArchSubtarget.cpp | 99 +- - .../lib/Target/LoongArch/LoongArchSubtarget.h | 146 +- - .../LoongArch/LoongArchTargetMachine.cpp | 170 +- - .../Target/LoongArch/LoongArchTargetMachine.h | 34 +- - .../LoongArch/LoongArchTargetObjectFile.cpp | 26 + - .../LoongArch/LoongArchTargetObjectFile.h | 24 + - .../LoongArch/LoongArchTargetStreamer.h | 130 + - .../LoongArchTargetTransformInfo.cpp | 325 + - .../LoongArch/LoongArchTargetTransformInfo.h | 91 + - .../LoongArch/MCTargetDesc/CMakeLists.txt | 11 +- - .../MCTargetDesc/LoongArchABIInfo.cpp | 106 + - .../LoongArch/MCTargetDesc/LoongArchABIInfo.h | 76 + - .../LoongArchAnalyzeImmediate.cpp | 64 + - ...chMatInt.h => LoongArchAnalyzeImmediate.h} | 15 +- - .../MCTargetDesc/LoongArchAsmBackend.cpp | 202 +- - .../MCTargetDesc/LoongArchAsmBackend.h | 78 +- - .../MCTargetDesc/LoongArchBaseInfo.cpp | 40 - - .../MCTargetDesc/LoongArchBaseInfo.h | 134 +- - .../MCTargetDesc/LoongArchELFObjectWriter.cpp | 176 +- - .../MCTargetDesc/LoongArchELFStreamer.cpp | 138 + - .../MCTargetDesc/LoongArchELFStreamer.h | 53 + - .../MCTargetDesc/LoongArchFixupKinds.h | 90 + - .../MCTargetDesc/LoongArchInstPrinter.cpp | 237 +- - .../MCTargetDesc/LoongArchInstPrinter.h | 110 +- - .../MCTargetDesc/LoongArchMCAsmInfo.cpp | 33 +- - .../MCTargetDesc/LoongArchMCAsmInfo.h | 9 +- - .../MCTargetDesc/LoongArchMCCodeEmitter.cpp | 1480 ++- - .../MCTargetDesc/LoongArchMCCodeEmitter.h | 146 + - .../MCTargetDesc/LoongArchMCExpr.cpp | 158 + - .../LoongArch/MCTargetDesc/LoongArchMCExpr.h | 97 + - .../MCTargetDesc/LoongArchMCTargetDesc.cpp | 144 +- - .../MCTargetDesc/LoongArchMCTargetDesc.h | 28 +- - .../MCTargetDesc/LoongArchMatInt.cpp | 51 - - .../MCTargetDesc/LoongArchTargetStreamer.cpp | 330 + - .../LoongArch/TargetInfo/CMakeLists.txt | 1 - - .../TargetInfo/LoongArchTargetInfo.cpp | 18 +- - .../TargetInfo/LoongArchTargetInfo.h | 4 +- - .../llvm/lib/Target/Sparc/SparcCallingConv.td | 10 +- - .../lib/Target/Sparc/SparcISelLowering.cpp | 61 +- - .../llvm/lib/Target/Sparc/SparcISelLowering.h | 5 + - src/llvm-project/llvm/lib/Target/X86/X86.td | 1 - - .../llvm/lib/Transforms/IPO/GlobalOpt.cpp | 2 +- - .../InstCombine/InstCombineCalls.cpp | 4 + - .../ControlHeightReduction.cpp | 1 + - .../llvm/lib/Transforms/Scalar/SROA.cpp | 19 +- - .../lib/Transforms/Utils/LoopVersioning.cpp | 4 +- - .../llvm/lib/Transforms/Utils/VNCoercion.cpp | 4 +- - .../Transforms/Vectorize/LoopVectorize.cpp | 4 +- - .../llvm/lib/Transforms/Vectorize/VPlan.cpp | 2 +- - .../llvm/lib/Transforms/Vectorize/VPlan.h | 2 +- - .../lib/Transforms/Vectorize/VPlanRecipes.cpp | 5 +- - src/llvm-project/llvm/test/CMakeLists.txt | 1 + - .../llvm/test/CodeGen/LoongArch/1ri.mir | 96 - - .../llvm/test/CodeGen/LoongArch/2r.mir | 230 - - .../llvm/test/CodeGen/LoongArch/2ri.mir | 432 - - .../llvm/test/CodeGen/LoongArch/3r.mir | 995 -- - .../llvm/test/CodeGen/LoongArch/3ri.mir | 69 - - .../llvm/test/CodeGen/LoongArch/align.ll | 8 + - .../CodeGen/LoongArch/atomic-operand-imm0.ll | 17 + - .../test/CodeGen/LoongArch/atomic_16_8.ll | 809 ++ - .../test/CodeGen/LoongArch/atomic_64_32.ll | 327 + - .../llvm/test/CodeGen/LoongArch/bss.ll | 5 + - .../LoongArch/builtins-loongarch-base.ll | 752 ++ - .../llvm/test/CodeGen/LoongArch/const-mult.ll | 245 + - .../CodeGen/LoongArch/disable-tail-calls.ll | 94 + - .../llvm/test/CodeGen/LoongArch/divrem.ll | 68 + - .../llvm/test/CodeGen/LoongArch/dup-tail.ll | 45 + - .../test/CodeGen/LoongArch/eliminateFI.ll | 106 + - .../CodeGen/LoongArch/emergency-spill-slot.ll | 103 + - .../llvm/test/CodeGen/LoongArch/fcopysign.ll | 17 + - .../llvm/test/CodeGen/LoongArch/frame-info.ll | 132 + - .../llvm/test/CodeGen/LoongArch/fsel.ll | 47 + - .../llvm/test/CodeGen/LoongArch/immediate.ll | 2542 +++++ - .../CodeGen/LoongArch/inlineasm/extra-code.ll | 8 + - .../inlineasm/floating-point-in-gpr.ll | 31 + - .../non-native-value-type-registers-error.ll | 8 + - .../non-native-value-type-registers.ll | 42 + - .../test/CodeGen/LoongArch/inlineasm/preld.ll | 8 + - .../test/CodeGen/LoongArch/jirl-verify.ll | 34 + - .../test/CodeGen/LoongArch/lasx/VExtend.ll | 54 + - .../CodeGen/LoongArch/lasx/imm_vector_lasx.ll | 176 + - .../test/CodeGen/LoongArch/lasx/inline-asm.ll | 55 + - .../CodeGen/LoongArch/lasx/insert-lasx.ll | 38 + - .../CodeGen/LoongArch/lasx/intrinsic-lasx.ll | 70 + - .../test/CodeGen/LoongArch/lasx/lasxvclr.ll | 46 + - .../test/CodeGen/LoongArch/lasx/logic-lasx.ll | 130 + - .../test/CodeGen/LoongArch/lasx/set-lasx.ll | 38 + - .../LoongArch/lasx/shuffle_v4i64_1032.ll | 19 + - .../test/CodeGen/LoongArch/lasx/vext2xv.ll | 65 + - .../test/CodeGen/LoongArch/lasx/xvadda.ll | 62 + - .../test/CodeGen/LoongArch/lasx/xvaddsub.ll | 98 + - .../test/CodeGen/LoongArch/lasx/xvhadd.ll | 21 + - .../test/CodeGen/LoongArch/lasx/xvilvh.ll | 32 + - .../test/CodeGen/LoongArch/lasx/xvilvl.ll | 32 + - .../llvm/test/CodeGen/LoongArch/ldptr.ll | 70 + - .../llvm/test/CodeGen/LoongArch/lit.local.cfg | 12 +- - .../llvm/test/CodeGen/LoongArch/logic-op.ll | 171 + - .../llvm/test/CodeGen/LoongArch/lshr.ll | 12 + - .../CodeGen/LoongArch/lsx/imm_vector_lsx.ll | 176 + - .../test/CodeGen/LoongArch/lsx/inline-asm.ll | 34 + - .../CodeGen/LoongArch/lsx/intrinsic-lsx.ll | 92 + - .../test/CodeGen/LoongArch/lsx/logic-lsx.ll | 132 + - .../test/CodeGen/LoongArch/lsx/lsxvclr.ll | 50 + - .../test/CodeGen/LoongArch/lsx/set-lsx.ll | 38 + - .../llvm/test/CodeGen/LoongArch/lsx/vadda.ll | 62 + - .../llvm/test/CodeGen/LoongArch/lu12i.ll | 7 + - .../llvm/test/CodeGen/LoongArch/mcpu_load.ll | 72 + - .../llvm/test/CodeGen/LoongArch/misc.mir | 200 - - .../test/CodeGen/LoongArch/named-register.ll | 29 + - .../llvm/test/CodeGen/LoongArch/nomerge.ll | 35 + - .../llvm/test/CodeGen/LoongArch/noti32.ll | 143 + - .../LoongArch/peephole-load-store-addi.ll | 100 + - .../llvm/test/CodeGen/LoongArch/signext.ll | 37 + - .../llvm/test/CodeGen/LoongArch/stptr.ll | 52 + - .../llvm/test/CodeGen/LoongArch/tailcall-R.ll | 62 + - .../test/CodeGen/LoongArch/tailcall-check.ll | 155 + - .../test/CodeGen/LoongArch/tailcall-mem.ll | 35 + - .../llvm/test/CodeGen/LoongArch/tailcall.ll | 13 + - .../test/CodeGen/LoongArch/thread-pointer.ll | 9 + - .../llvm/test/CodeGen/LoongArch/trunc.ll | 108 + - .../test/CodeGen/LoongArch/unalignment.ll | 72 + - .../PowerPC/regalloc-fast-debug-spill.ll | 250 + - .../llvm/test/CodeGen/SPARC/bigreturn.ll | 254 + - .../CodeGen/X86/zero-call-used-regs-i386.ll | 112 + - .../llvm/test/MC/LoongArch/aligned-nops.s | 25 + - .../llvm/test/MC/LoongArch/atomic-error.s | 7 + - .../llvm/test/MC/LoongArch/atomic.s | 12 + - .../llvm/test/MC/LoongArch/fixups-expr.s | 40 + - .../llvm/test/MC/LoongArch/invalid.s | 50 + - .../llvm/test/MC/LoongArch/lit.local.cfg | 1 + - .../llvm/test/MC/LoongArch/macro-la.s | 168 + - .../llvm/test/MC/LoongArch/macro-li.s | 773 ++ - .../llvm/test/MC/LoongArch/valid_12imm.s | 33 + - .../llvm/test/MC/LoongArch/valid_4operands.s | 53 + - .../llvm/test/MC/LoongArch/valid_bigimm.s | 33 + - .../llvm/test/MC/LoongArch/valid_branch.s | 155 + - .../llvm/test/MC/LoongArch/valid_float.s | 297 + - .../llvm/test/MC/LoongArch/valid_integer.s | 369 + - .../llvm/test/MC/LoongArch/valid_memory.s | 405 + - .../llvm/test/MC/LoongArch/valid_priv.s | 125 + - .../test/Support/unix03-sigpipe-exit.test | 26 - - .../AtomicExpand/LoongArch/lit.local.cfg | 5 - - .../Transforms/GlobalOpt/inalloca-varargs.ll | 38 + - .../test/Transforms/InstCombine/cast-byval.ll | 31 + - .../versioning-scev-invalidation.ll | 125 + - ...interleave-allocsize-not-equal-typesize.ll | 141 + - .../phi-speculate-different-load-types.ll | 41 + - .../loongarch_function_name.ll.expected | 6 +- - ...arch_generated_funcs.ll.generated.expected | 148 - - ...ch_generated_funcs.ll.nogenerated.expected | 147 - - .../loongarch_generated_funcs.test | 17 - - .../llvm-readobj/ELF/loongarch-eflags.test | 64 - - .../tools/obj2yaml/ELF/loongarch-eflags.yaml | 29 - - .../llvm/tools/dsymutil/CMakeLists.txt | 4 +- - .../llvm/tools/llvm-config/CMakeLists.txt | 8 +- - .../llvm/tools/llvm-readobj/ELFDumper.cpp | 15 - - .../clang-tidy/misc/BUILD.gn | 2 +- - .../llvm/utils/gn/secondary/llvm/version.gni | 2 +- - .../llvm/utils/lit/lit/__init__.py | 2 +- - .../llvm/utils/lit/lit/llvm/config.py | 2 +- - 332 files changed, 57210 insertions(+), 7989 deletions(-) - create mode 100644 src/llvm-project/clang/test/Analysis/template-param-objects.cpp - create mode 100644 src/llvm-project/clang/test/CodeGen/arm-vaarg.c - create mode 100644 src/llvm-project/clang/test/CodeGen/attr-btf_type_tag-func-ptr.c - create mode 100644 src/llvm-project/clang/test/CodeGen/debug-info-enum-case-val.c - create mode 100644 src/llvm-project/clang/test/Sema/gnu-builtins.c - create mode 100644 src/llvm-project/clang/test/SemaCXX/specialization-diagnose-crash.cpp - create mode 100644 src/llvm-project/libcxx/test/libcxx/utilities/function.objects/func.blocks.arc.pass.mm - create mode 100644 src/llvm-project/libcxx/test/std/containers/sequences/vector.bool/ctor_exceptions.pass.cpp - create mode 100644 src/llvm-project/libcxx/test/std/containers/sequences/vector/vector.cons/exceptions.pass.cpp - delete mode 100644 src/llvm-project/libunwind/README_RUST_SGX.md - delete mode 100644 src/llvm-project/libunwind/src/UnwindRustSgx.c - delete mode 100644 src/llvm-project/libunwind/src/UnwindRustSgx.h - create mode 100644 src/llvm-project/lld/test/ELF/comdat-binding2.s - create mode 100644 src/llvm-project/lld/test/MachO/eh-frame-personality-dedup.s - create mode 100644 src/llvm-project/lldb/test/API/lang/cpp/class-template-parameter-pack/TestTemplatePackArgs.py - create mode 100644 src/llvm-project/llvm/cmake/modules/Findzstd.cmake - create mode 100644 src/llvm-project/llvm/include/llvm/IR/IntrinsicsLoongArch.td - create mode 100644 src/llvm-project/llvm/lib/Target/LoongArch/LoongArch32InstrInfo.td - create mode 100644 src/llvm-project/llvm/lib/Target/LoongArch/LoongArchCCState.cpp - create mode 100644 src/llvm-project/llvm/lib/Target/LoongArch/LoongArchCCState.h - create mode 100644 src/llvm-project/llvm/lib/Target/LoongArch/LoongArchExpandPseudo.cpp - delete mode 100644 src/llvm-project/llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td - delete mode 100644 src/llvm-project/llvm/lib/Target/LoongArch/LoongArchFloat64InstrInfo.td - delete mode 100644 src/llvm-project/llvm/lib/Target/LoongArch/LoongArchFloatInstrFormats.td - create mode 100644 src/llvm-project/llvm/lib/Target/LoongArch/LoongArchInstrInfoF.td - create mode 100644 src/llvm-project/llvm/lib/Target/LoongArch/LoongArchLASXInstrFormats.td - create mode 100644 src/llvm-project/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td - create mode 100644 src/llvm-project/llvm/lib/Target/LoongArch/LoongArchLSXInstrFormats.td - create mode 100644 src/llvm-project/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td - create mode 100644 src/llvm-project/llvm/lib/Target/LoongArch/LoongArchMCInstLower.h - create mode 100644 src/llvm-project/llvm/lib/Target/LoongArch/LoongArchMachineFunction.cpp - create mode 100644 src/llvm-project/llvm/lib/Target/LoongArch/LoongArchMachineFunction.h - delete mode 100644 src/llvm-project/llvm/lib/Target/LoongArch/LoongArchMachineFunctionInfo.h - create mode 100644 src/llvm-project/llvm/lib/Target/LoongArch/LoongArchModuleISelDAGToDAG.cpp - create mode 100644 src/llvm-project/llvm/lib/Target/LoongArch/LoongArchTargetObjectFile.cpp - create mode 100644 src/llvm-project/llvm/lib/Target/LoongArch/LoongArchTargetObjectFile.h - create mode 100644 src/llvm-project/llvm/lib/Target/LoongArch/LoongArchTargetStreamer.h - create mode 100644 src/llvm-project/llvm/lib/Target/LoongArch/LoongArchTargetTransformInfo.cpp - create mode 100644 src/llvm-project/llvm/lib/Target/LoongArch/LoongArchTargetTransformInfo.h - create mode 100644 src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchABIInfo.cpp - create mode 100644 src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchABIInfo.h - create mode 100644 src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAnalyzeImmediate.cpp - rename src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/{LoongArchMatInt.h => LoongArchAnalyzeImmediate.h} (62%) - delete mode 100644 src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.cpp - create mode 100644 src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFStreamer.cpp - create mode 100644 src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFStreamer.h - create mode 100644 src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchFixupKinds.h - create mode 100644 src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.h - create mode 100644 src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.cpp - create mode 100644 src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.h - delete mode 100644 src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMatInt.cpp - create mode 100644 src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchTargetStreamer.cpp - delete mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/1ri.mir - delete mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/2r.mir - delete mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/2ri.mir - delete mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/3r.mir - delete mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/3ri.mir - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/align.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/atomic-operand-imm0.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/atomic_16_8.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/atomic_64_32.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/bss.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/builtins-loongarch-base.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/const-mult.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/disable-tail-calls.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/divrem.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/dup-tail.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/eliminateFI.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/emergency-spill-slot.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/fcopysign.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/frame-info.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/fsel.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/immediate.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/inlineasm/extra-code.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/inlineasm/floating-point-in-gpr.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/inlineasm/non-native-value-type-registers-error.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/inlineasm/non-native-value-type-registers.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/inlineasm/preld.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/jirl-verify.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/VExtend.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/imm_vector_lasx.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/inline-asm.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/insert-lasx.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/intrinsic-lasx.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/lasxvclr.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/logic-lasx.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/set-lasx.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/shuffle_v4i64_1032.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/vext2xv.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/xvadda.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/xvaddsub.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/xvhadd.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/xvilvh.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/xvilvl.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/ldptr.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/logic-op.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/lshr.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/lsx/imm_vector_lsx.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/lsx/inline-asm.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/lsx/intrinsic-lsx.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/lsx/logic-lsx.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/lsx/lsxvclr.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/lsx/set-lsx.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/lsx/vadda.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/lu12i.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/mcpu_load.ll - delete mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/misc.mir - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/named-register.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/nomerge.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/noti32.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/peephole-load-store-addi.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/signext.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/stptr.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/tailcall-R.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/tailcall-check.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/tailcall-mem.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/tailcall.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/thread-pointer.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/trunc.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/LoongArch/unalignment.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/PowerPC/regalloc-fast-debug-spill.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/SPARC/bigreturn.ll - create mode 100644 src/llvm-project/llvm/test/CodeGen/X86/zero-call-used-regs-i386.ll - create mode 100644 src/llvm-project/llvm/test/MC/LoongArch/aligned-nops.s - create mode 100644 src/llvm-project/llvm/test/MC/LoongArch/atomic-error.s - create mode 100644 src/llvm-project/llvm/test/MC/LoongArch/atomic.s - create mode 100644 src/llvm-project/llvm/test/MC/LoongArch/fixups-expr.s - create mode 100644 src/llvm-project/llvm/test/MC/LoongArch/invalid.s - create mode 100644 src/llvm-project/llvm/test/MC/LoongArch/macro-la.s - create mode 100644 src/llvm-project/llvm/test/MC/LoongArch/macro-li.s - create mode 100644 src/llvm-project/llvm/test/MC/LoongArch/valid_12imm.s - create mode 100644 src/llvm-project/llvm/test/MC/LoongArch/valid_4operands.s - create mode 100644 src/llvm-project/llvm/test/MC/LoongArch/valid_bigimm.s - create mode 100644 src/llvm-project/llvm/test/MC/LoongArch/valid_branch.s - create mode 100644 src/llvm-project/llvm/test/MC/LoongArch/valid_float.s - create mode 100644 src/llvm-project/llvm/test/MC/LoongArch/valid_integer.s - create mode 100644 src/llvm-project/llvm/test/MC/LoongArch/valid_memory.s - create mode 100644 src/llvm-project/llvm/test/MC/LoongArch/valid_priv.s - delete mode 100644 src/llvm-project/llvm/test/Support/unix03-sigpipe-exit.test - delete mode 100644 src/llvm-project/llvm/test/Transforms/AtomicExpand/LoongArch/lit.local.cfg - create mode 100644 src/llvm-project/llvm/test/Transforms/GlobalOpt/inalloca-varargs.ll - create mode 100644 src/llvm-project/llvm/test/Transforms/InstCombine/cast-byval.ll - create mode 100644 src/llvm-project/llvm/test/Transforms/LoopLoadElim/versioning-scev-invalidation.ll - create mode 100644 src/llvm-project/llvm/test/Transforms/LoopVectorize/AArch64/interleave-allocsize-not-equal-typesize.ll - create mode 100644 src/llvm-project/llvm/test/Transforms/SROA/phi-speculate-different-load-types.ll - delete mode 100644 src/llvm-project/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.generated.expected - delete mode 100644 src/llvm-project/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.nogenerated.expected - delete mode 100644 src/llvm-project/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/loongarch_generated_funcs.test - delete mode 100644 src/llvm-project/llvm/test/tools/llvm-readobj/ELF/loongarch-eflags.test - delete mode 100644 src/llvm-project/llvm/test/tools/obj2yaml/ELF/loongarch-eflags.yaml - -diff --git a/src/llvm-project/clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp b/src/llvm-project/clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp -index 8ae990a92..afb4a1044 100644 ---- a/src/llvm-project/clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp -+++ b/src/llvm-project/clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp -@@ -472,8 +472,8 @@ public: - checkSingleStatement(If->getThen(), parseReturnLiteralBool); - if (ThenReturnBool && - ThenReturnBool.Bool != TrailingReturnBool.Bool) { -- if (Check->ChainedConditionalReturn || -- (!PrevIf && If->getElse() == nullptr)) { -+ if ((Check->ChainedConditionalReturn || !PrevIf) && -+ If->getElse() == nullptr) { - Check->replaceCompoundReturnWithCondition( - Context, cast(*Second), TrailingReturnBool.Bool, - If, ThenReturnBool.Item); -diff --git a/src/llvm-project/clang-tools-extra/clangd/CodeComplete.cpp b/src/llvm-project/clang-tools-extra/clangd/CodeComplete.cpp -index edbb1722a..55982f412 100644 ---- a/src/llvm-project/clang-tools-extra/clangd/CodeComplete.cpp -+++ b/src/llvm-project/clang-tools-extra/clangd/CodeComplete.cpp -@@ -486,6 +486,9 @@ private: - // we need to complete 'forward<$1>($0)'. - return "($0)"; - -+ if (Snippet->empty()) -+ return ""; -+ - bool MayHaveArgList = Completion.Kind == CompletionItemKind::Function || - Completion.Kind == CompletionItemKind::Method || - Completion.Kind == CompletionItemKind::Constructor || -@@ -524,8 +527,6 @@ private: - return *Snippet; - - // Replace argument snippets with a simplified pattern. -- if (Snippet->empty()) -- return ""; - if (MayHaveArgList) { - // Functions snippets can be of 2 types: - // - containing only function arguments, e.g. -diff --git a/src/llvm-project/clang-tools-extra/clangd/Headers.cpp b/src/llvm-project/clang-tools-extra/clangd/Headers.cpp -index cb7abac3e..af22a446b 100644 ---- a/src/llvm-project/clang-tools-extra/clangd/Headers.cpp -+++ b/src/llvm-project/clang-tools-extra/clangd/Headers.cpp -@@ -22,9 +22,17 @@ - namespace clang { - namespace clangd { - --const char IWYUPragmaKeep[] = "// IWYU pragma: keep"; --const char IWYUPragmaExport[] = "// IWYU pragma: export"; --const char IWYUPragmaBeginExports[] = "// IWYU pragma: begin_exports"; -+llvm::Optional parseIWYUPragma(const char *Text) { -+ // This gets called for every comment seen in the preamble, so it's quite hot. -+ constexpr llvm::StringLiteral IWYUPragma = "// IWYU pragma: "; -+ if (strncmp(Text, IWYUPragma.data(), IWYUPragma.size())) -+ return llvm::None; -+ Text += IWYUPragma.size(); -+ const char *End = Text; -+ while (*End != 0 && *End != '\n') -+ ++End; -+ return StringRef(Text, End - Text); -+} - - class IncludeStructure::RecordHeaders : public PPCallbacks, - public CommentHandler { -@@ -129,10 +137,10 @@ public: - } - - bool HandleComment(Preprocessor &PP, SourceRange Range) override { -- bool Err = false; -- llvm::StringRef Text = SM.getCharacterData(Range.getBegin(), &Err); -- if (Err) -+ auto Pragma = parseIWYUPragma(SM.getCharacterData(Range.getBegin())); -+ if (!Pragma) - return false; -+ - if (inMainFile()) { - // Given: - // -@@ -150,8 +158,7 @@ public: - // will know that the next inclusion is behind the IWYU pragma. - // FIXME: Support "IWYU pragma: begin_exports" and "IWYU pragma: - // end_exports". -- if (!Text.startswith(IWYUPragmaExport) && -- !Text.startswith(IWYUPragmaKeep)) -+ if (!Pragma->startswith("export") && !Pragma->startswith("keep")) - return false; - unsigned Offset = SM.getFileOffset(Range.getBegin()); - LastPragmaKeepInMainFileLine = -@@ -161,8 +168,7 @@ public: - // does not support them properly yet, so they will be not marked as - // unused. - // FIXME: Once IncludeCleaner supports export pragmas, remove this. -- if (!Text.startswith(IWYUPragmaExport) && -- !Text.startswith(IWYUPragmaBeginExports)) -+ if (!Pragma->startswith("export") && !Pragma->startswith("begin_exports")) - return false; - Out->HasIWYUExport.insert( - *Out->getID(SM.getFileEntryForID(SM.getFileID(Range.getBegin())))); -diff --git a/src/llvm-project/clang-tools-extra/clangd/Headers.h b/src/llvm-project/clang-tools-extra/clangd/Headers.h -index ff3f06316..ba72ad397 100644 ---- a/src/llvm-project/clang-tools-extra/clangd/Headers.h -+++ b/src/llvm-project/clang-tools-extra/clangd/Headers.h -@@ -35,6 +35,12 @@ namespace clangd { - /// Returns true if \p Include is literal include like "path" or . - bool isLiteralInclude(llvm::StringRef Include); - -+/// If Text begins an Include-What-You-Use directive, returns it. -+/// Given "// IWYU pragma: keep", returns "keep". -+/// Input is a null-terminated char* as provided by SM.getCharacterData(). -+/// (This should not be StringRef as we do *not* want to scan for its length). -+llvm::Optional parseIWYUPragma(const char *Text); -+ - /// Represents a header file to be #include'd. - struct HeaderFile { - std::string File; -diff --git a/src/llvm-project/clang-tools-extra/clangd/InlayHints.cpp b/src/llvm-project/clang-tools-extra/clangd/InlayHints.cpp -index 7be05fbc3..16c6b1cec 100644 ---- a/src/llvm-project/clang-tools-extra/clangd/InlayHints.cpp -+++ b/src/llvm-project/clang-tools-extra/clangd/InlayHints.cpp -@@ -10,6 +10,7 @@ - #include "Config.h" - #include "HeuristicResolver.h" - #include "ParsedAST.h" -+#include "SourceCode.h" - #include "clang/AST/Decl.h" - #include "clang/AST/DeclarationName.h" - #include "clang/AST/ExprCXX.h" -@@ -192,8 +193,8 @@ class InlayHintVisitor : public RecursiveASTVisitor { - public: - InlayHintVisitor(std::vector &Results, ParsedAST &AST, - const Config &Cfg, llvm::Optional RestrictRange) -- : Results(Results), AST(AST.getASTContext()), Cfg(Cfg), -- RestrictRange(std::move(RestrictRange)), -+ : Results(Results), AST(AST.getASTContext()), Tokens(AST.getTokens()), -+ Cfg(Cfg), RestrictRange(std::move(RestrictRange)), - MainFileID(AST.getSourceManager().getMainFileID()), - Resolver(AST.getHeuristicResolver()), - TypeHintPolicy(this->AST.getPrintingPolicy()), -@@ -227,8 +228,7 @@ public: - return true; - } - -- processCall(E->getParenOrBraceRange().getBegin(), E->getConstructor(), -- {E->getArgs(), E->getNumArgs()}); -+ processCall(E->getConstructor(), {E->getArgs(), E->getNumArgs()}); - return true; - } - -@@ -254,7 +254,7 @@ public: - if (!Callee) - return true; - -- processCall(E->getRParenLoc(), Callee, {E->getArgs(), E->getNumArgs()}); -+ processCall(Callee, {E->getArgs(), E->getNumArgs()}); - return true; - } - -@@ -278,11 +278,11 @@ public: - return true; - } - -- void addReturnTypeHint(FunctionDecl *D, SourceLocation Loc) { -+ void addReturnTypeHint(FunctionDecl *D, SourceRange Range) { - auto *AT = D->getReturnType()->getContainedAutoType(); - if (!AT || AT->getDeducedType().isNull()) - return; -- addTypeHint(Loc, D->getReturnType(), /*Prefix=*/"-> "); -+ addTypeHint(Range, D->getReturnType(), /*Prefix=*/"-> "); - } - - bool VisitVarDecl(VarDecl *D) { -@@ -375,21 +375,11 @@ public: - private: - using NameVec = SmallVector; - -- // The purpose of Anchor is to deal with macros. It should be the call's -- // opening or closing parenthesis or brace. (Always using the opening would -- // make more sense but CallExpr only exposes the closing.) We heuristically -- // assume that if this location does not come from a macro definition, then -- // the entire argument list likely appears in the main file and can be hinted. -- void processCall(SourceLocation Anchor, const FunctionDecl *Callee, -+ void processCall(const FunctionDecl *Callee, - llvm::ArrayRef Args) { - if (!Cfg.InlayHints.Parameters || Args.size() == 0 || !Callee) - return; - -- // If the anchor location comes from a macro defintion, there's nowhere to -- // put hints. -- if (!AST.getSourceManager().getTopMacroCallerLoc(Anchor).isFileID()) -- return; -- - // The parameter name of a move or copy constructor is not very interesting. - if (auto *Ctor = dyn_cast(Callee)) - if (Ctor->isCopyOrMoveConstructor()) -@@ -637,25 +627,33 @@ private: - #undef CHECK_KIND - } - -- auto FileRange = -- toHalfOpenFileRange(AST.getSourceManager(), AST.getLangOpts(), R); -- if (!FileRange) -+ auto LSPRange = getHintRange(R); -+ if (!LSPRange) - return; -- Range LSPRange{ -- sourceLocToPosition(AST.getSourceManager(), FileRange->getBegin()), -- sourceLocToPosition(AST.getSourceManager(), FileRange->getEnd())}; -- Position LSPPos = Side == HintSide::Left ? LSPRange.start : LSPRange.end; -+ Position LSPPos = Side == HintSide::Left ? LSPRange->start : LSPRange->end; - if (RestrictRange && - (LSPPos < RestrictRange->start || !(LSPPos < RestrictRange->end))) - return; -- // The hint may be in a file other than the main file (for example, a header -- // file that was included after the preamble), do not show in that case. -- if (!AST.getSourceManager().isWrittenInMainFile(FileRange->getBegin())) -- return; - bool PadLeft = Prefix.consume_front(" "); - bool PadRight = Suffix.consume_back(" "); - Results.push_back(InlayHint{LSPPos, (Prefix + Label + Suffix).str(), Kind, -- PadLeft, PadRight, LSPRange}); -+ PadLeft, PadRight, *LSPRange}); -+ } -+ -+ // Get the range of the main file that *exactly* corresponds to R. -+ llvm::Optional getHintRange(SourceRange R) { -+ const auto &SM = AST.getSourceManager(); -+ auto Spelled = Tokens.spelledForExpanded(Tokens.expandedTokens(R)); -+ // TokenBuffer will return null if e.g. R corresponds to only part of a -+ // macro expansion. -+ if (!Spelled || Spelled->empty()) -+ return llvm::None; -+ // Hint must be within the main file, not e.g. a non-preamble include. -+ if (SM.getFileID(Spelled->front().location()) != SM.getMainFileID() || -+ SM.getFileID(Spelled->back().location()) != SM.getMainFileID()) -+ return llvm::None; -+ return Range{sourceLocToPosition(SM, Spelled->front().location()), -+ sourceLocToPosition(SM, Spelled->back().endLocation())}; - } - - void addTypeHint(SourceRange R, QualType T, llvm::StringRef Prefix) { -@@ -680,6 +678,7 @@ private: - - std::vector &Results; - ASTContext &AST; -+ const syntax::TokenBuffer &Tokens; - const Config &Cfg; - llvm::Optional RestrictRange; - FileID MainFileID; -diff --git a/src/llvm-project/clang-tools-extra/clangd/TidyProvider.cpp b/src/llvm-project/clang-tools-extra/clangd/TidyProvider.cpp -index 32a4d6a30..a0a37e86b 100644 ---- a/src/llvm-project/clang-tools-extra/clangd/TidyProvider.cpp -+++ b/src/llvm-project/clang-tools-extra/clangd/TidyProvider.cpp -@@ -212,8 +212,14 @@ TidyProvider disableUnusableChecks(llvm::ArrayRef ExtraBadChecks) { - // code, which is often the case when clangd - // tries to build an AST. - "-bugprone-use-after-move", -- // Alias for bugprone-use-after-moe. -- "-hicpp-invalid-access-moved"); -+ // Alias for bugprone-use-after-move. -+ "-hicpp-invalid-access-moved", -+ -+ // ----- Performance problems ----- -+ -+ // This check runs expensive analysis for each variable. -+ // It has been observed to increase reparse time by 10x. -+ "-misc-const-correctness"); - - size_t Size = BadChecks.size(); - for (const std::string &Str : ExtraBadChecks) { -diff --git a/src/llvm-project/clang-tools-extra/clangd/index/CanonicalIncludes.cpp b/src/llvm-project/clang-tools-extra/clangd/index/CanonicalIncludes.cpp -index 145d98d57..bbc80e7e0 100644 ---- a/src/llvm-project/clang-tools-extra/clangd/index/CanonicalIncludes.cpp -+++ b/src/llvm-project/clang-tools-extra/clangd/index/CanonicalIncludes.cpp -@@ -17,8 +17,6 @@ - namespace clang { - namespace clangd { - namespace { --const char IWYUPragma[] = "// IWYU pragma: private, include "; -- - const std::pair IncludeMappings[] = { - {"include/__stddef_max_align_t.h", ""}, - {"include/__wmmintrin_aes.h", ""}, -@@ -712,17 +710,17 @@ collectIWYUHeaderMaps(CanonicalIncludes *Includes) { - PragmaCommentHandler(CanonicalIncludes *Includes) : Includes(Includes) {} - - bool HandleComment(Preprocessor &PP, SourceRange Range) override { -- llvm::StringRef Text = -- Lexer::getSourceText(CharSourceRange::getCharRange(Range), -- PP.getSourceManager(), PP.getLangOpts()); -- if (!Text.consume_front(IWYUPragma)) -+ auto Pragma = parseIWYUPragma( -+ PP.getSourceManager().getCharacterData(Range.getBegin())); -+ if (!Pragma || !Pragma->consume_front("private, include ")) - return false; - auto &SM = PP.getSourceManager(); - // We always insert using the spelling from the pragma. - if (auto *FE = SM.getFileEntryForID(SM.getFileID(Range.getBegin()))) -- Includes->addMapping( -- FE->getLastRef(), -- isLiteralInclude(Text) ? Text.str() : ("\"" + Text + "\"").str()); -+ Includes->addMapping(FE->getLastRef(), -+ isLiteralInclude(*Pragma) -+ ? Pragma->str() -+ : ("\"" + *Pragma + "\"").str()); - return false; - } - -diff --git a/src/llvm-project/clang-tools-extra/clangd/test/lit.site.cfg.py.in b/src/llvm-project/clang-tools-extra/clangd/test/lit.site.cfg.py.in -index 20caa72af..1fe7c8d0f 100644 ---- a/src/llvm-project/clang-tools-extra/clangd/test/lit.site.cfg.py.in -+++ b/src/llvm-project/clang-tools-extra/clangd/test/lit.site.cfg.py.in -@@ -10,6 +10,7 @@ config.python_executable = "@Python3_EXECUTABLE@" - config.clang_tools_dir = lit_config.substitute("@CURRENT_TOOLS_DIR@") - config.llvm_tools_dir = lit_config.substitute("@LLVM_TOOLS_DIR@") - config.llvm_libs_dir = lit_config.substitute("@LLVM_LIBS_DIR@") -+config.llvm_shlib_dir = "@SHLIBDIR@" - - config.clangd_source_dir = "@CMAKE_CURRENT_SOURCE_DIR@/.." - config.clangd_binary_dir = "@CMAKE_CURRENT_BINARY_DIR@/.." -diff --git a/src/llvm-project/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp b/src/llvm-project/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp -index 5050ab203..079a4ec70 100644 ---- a/src/llvm-project/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp -+++ b/src/llvm-project/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp -@@ -1014,6 +1014,23 @@ TEST(CodeCompleteTest, NoColonColonAtTheEnd) { - EXPECT_THAT(Results.Completions, Not(Contains(labeled("clang::")))); - } - -+TEST(CompletionTests, EmptySnippetDoesNotCrash) { -+ // See https://github.com/clangd/clangd/issues/1216 -+ auto Results = completions(R"cpp( -+ int main() { -+ auto w = [&](auto &&f) { return f(f); }; -+ auto f = w([&](auto &&f) { -+ return [&](auto &&n) { -+ if (n == 0) { -+ return 1; -+ } -+ return n * ^(f)(n - 1); -+ }; -+ })(10); -+ } -+ )cpp"); -+} -+ - TEST(CompletionTest, BacktrackCrashes) { - // Sema calls code completion callbacks twice in these cases. - auto Results = completions(R"cpp( -diff --git a/src/llvm-project/clang-tools-extra/clangd/unittests/HeadersTests.cpp b/src/llvm-project/clang-tools-extra/clangd/unittests/HeadersTests.cpp -index 32e4aea15..324d4b58a 100644 ---- a/src/llvm-project/clang-tools-extra/clangd/unittests/HeadersTests.cpp -+++ b/src/llvm-project/clang-tools-extra/clangd/unittests/HeadersTests.cpp -@@ -9,6 +9,7 @@ - #include "Headers.h" - - #include "Compiler.h" -+#include "Matchers.h" - #include "TestFS.h" - #include "TestTU.h" - #include "clang/Basic/TokenKinds.h" -@@ -30,6 +31,7 @@ namespace { - using ::testing::AllOf; - using ::testing::Contains; - using ::testing::ElementsAre; -+using ::testing::Eq; - using ::testing::IsEmpty; - using ::testing::Not; - using ::testing::UnorderedElementsAre; -@@ -445,6 +447,18 @@ TEST_F(HeadersTest, HasIWYUPragmas) { - EXPECT_FALSE(Includes.hasIWYUExport(getID("none.h", Includes))); - } - -+TEST(Headers, ParseIWYUPragma) { -+ EXPECT_THAT(parseIWYUPragma("// IWYU pragma: keep"), HasValue(Eq("keep"))); -+ EXPECT_THAT(parseIWYUPragma("// IWYU pragma: keep\netc"), -+ HasValue(Eq("keep"))); -+ EXPECT_EQ(parseIWYUPragma("/* IWYU pragma: keep"), llvm::None) -+ << "Only // comments supported!"; -+ EXPECT_EQ(parseIWYUPragma("// IWYU pragma: keep"), llvm::None) -+ << "Sensitive to whitespace"; -+ EXPECT_EQ(parseIWYUPragma("// IWYU pragma:keep"), llvm::None) -+ << "Sensitive to whitespace"; -+} -+ - } // namespace - } // namespace clangd - } // namespace clang -diff --git a/src/llvm-project/clang-tools-extra/clangd/unittests/InlayHintTests.cpp b/src/llvm-project/clang-tools-extra/clangd/unittests/InlayHintTests.cpp -index a429c0899..7127f6cc5 100644 ---- a/src/llvm-project/clang-tools-extra/clangd/unittests/InlayHintTests.cpp -+++ b/src/llvm-project/clang-tools-extra/clangd/unittests/InlayHintTests.cpp -@@ -820,6 +820,15 @@ TEST(ParameterHints, Macros) { - } - )cpp", - ExpectedHint{"param: ", "param"}); -+ -+ // If the macro expands to multiple arguments, don't hint it. -+ assertParameterHints(R"cpp( -+ void foo(double x, double y); -+ #define CONSTANTS 3.14, 2.72 -+ void bar() { -+ foo(CONSTANTS); -+ } -+ )cpp"); - } - - TEST(ParameterHints, ConstructorParens) { -diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/checkers/readability/simplify-bool-expr-chained-conditional-return.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/checkers/readability/simplify-bool-expr-chained-conditional-return.cpp -index 7e97e9f71..ff50528c2 100644 ---- a/src/llvm-project/clang-tools-extra/test/clang-tidy/checkers/readability/simplify-bool-expr-chained-conditional-return.cpp -+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/checkers/readability/simplify-bool-expr-chained-conditional-return.cpp -@@ -92,3 +92,14 @@ bool complex_chained_if_return_return_negated(int i) { - // CHECK-FIXES: {{^}} }{{$}} - // CHECK-FIXES: {{^ return i <= 10;$}} - // CHECK-FIXES: {{^}$}} -+ -+ -+bool PR57819(int x) { -+ // False positive introduced in clang-tidy-15 -+ // Expect no warning here. -+ if (x > 0) -+ return false; -+ else { -+ } -+ return true; -+} -diff --git a/src/llvm-project/clang/CMakeLists.txt b/src/llvm-project/clang/CMakeLists.txt -index 13d76e7fd..e3bc4b468 100644 ---- a/src/llvm-project/clang/CMakeLists.txt -+++ b/src/llvm-project/clang/CMakeLists.txt -@@ -117,6 +117,7 @@ if(CLANG_BUILT_STANDALONE) - include(TableGen) - include(HandleLLVMOptions) - include(VersionFromVCS) -+ include(CheckAtomic) - include(GetErrcMessages) - include(LLVMDistributionSupport) - -diff --git a/src/llvm-project/clang/docs/ReleaseNotes.rst b/src/llvm-project/clang/docs/ReleaseNotes.rst -index a17b033f5..13cca2ebb 100644 ---- a/src/llvm-project/clang/docs/ReleaseNotes.rst -+++ b/src/llvm-project/clang/docs/ReleaseNotes.rst -@@ -225,6 +225,12 @@ Bug Fixes - - Fix a crash when generating code coverage information for an - ``if consteval`` statement. This fixes - `Issue 57377 `_. -+- Fix a crash when a ``btf_type_tag`` attribute is applied to the pointee of -+ a function pointer. -+- Clang 14 predeclared some builtin POSIX library functions in ``gnu2x`` mode, -+ and Clang 15 accidentally stopped predeclaring those functions in that -+ language mode. Clang 16 now predeclares those functions again. This fixes -+ `Issue 56607 `_. - - Improvements to Clang's diagnostics - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -diff --git a/src/llvm-project/clang/lib/Basic/CMakeLists.txt b/src/llvm-project/clang/lib/Basic/CMakeLists.txt -index 3e052c0cf..c38c9fddb 100644 ---- a/src/llvm-project/clang/lib/Basic/CMakeLists.txt -+++ b/src/llvm-project/clang/lib/Basic/CMakeLists.txt -@@ -110,3 +110,7 @@ add_clang_library(clangBasic - omp_gen - ) - -+target_link_libraries(clangBasic -+ PRIVATE -+ ${LLVM_ATOMIC_LIB} -+) -diff --git a/src/llvm-project/clang/lib/CodeGen/CGStmt.cpp b/src/llvm-project/clang/lib/CodeGen/CGStmt.cpp -index 481438de0..9935fcc0d 100644 ---- a/src/llvm-project/clang/lib/CodeGen/CGStmt.cpp -+++ b/src/llvm-project/clang/lib/CodeGen/CGStmt.cpp -@@ -1509,6 +1509,21 @@ void CodeGenFunction::EmitCaseStmt(const CaseStmt &S, - - llvm::ConstantInt *CaseVal = - Builder.getInt(S.getLHS()->EvaluateKnownConstInt(getContext())); -+ -+ // Emit debuginfo for the case value if it is an enum value. -+ const ConstantExpr *CE; -+ if (auto ICE = dyn_cast(S.getLHS())) -+ CE = dyn_cast(ICE->getSubExpr()); -+ else -+ CE = dyn_cast(S.getLHS()); -+ if (CE) { -+ if (auto DE = dyn_cast(CE->getSubExpr())) -+ if (CGDebugInfo *Dbg = getDebugInfo()) -+ if (CGM.getCodeGenOpts().hasReducedDebugInfo()) -+ Dbg->EmitGlobalVariable(DE->getDecl(), -+ APValue(llvm::APSInt(CaseVal->getValue()))); -+ } -+ - if (SwitchLikelihood) - SwitchLikelihood->push_back(Stmt::getLikelihood(Attrs)); - -diff --git a/src/llvm-project/clang/lib/CodeGen/TargetInfo.cpp b/src/llvm-project/clang/lib/CodeGen/TargetInfo.cpp -index 36e10e4df..44743fa02 100644 ---- a/src/llvm-project/clang/lib/CodeGen/TargetInfo.cpp -+++ b/src/llvm-project/clang/lib/CodeGen/TargetInfo.cpp -@@ -7047,10 +7047,10 @@ Address ARMABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, - - // Empty records are ignored for parameter passing purposes. - if (isEmptyRecord(getContext(), Ty, true)) { -- Address Addr = Address(CGF.Builder.CreateLoad(VAListAddr), -- getVAListElementType(CGF), SlotSize); -- Addr = CGF.Builder.CreateElementBitCast(Addr, CGF.ConvertTypeForMem(Ty)); -- return Addr; -+ VAListAddr = CGF.Builder.CreateElementBitCast(VAListAddr, CGF.Int8PtrTy); -+ auto *Load = CGF.Builder.CreateLoad(VAListAddr); -+ Address Addr = Address(Load, CGF.Int8Ty, SlotSize); -+ return CGF.Builder.CreateElementBitCast(Addr, CGF.ConvertTypeForMem(Ty)); - } - - CharUnits TySize = getContext().getTypeSizeInChars(Ty); -diff --git a/src/llvm-project/clang/lib/Driver/ToolChains/Gnu.cpp b/src/llvm-project/clang/lib/Driver/ToolChains/Gnu.cpp -index f203cae1d..665cdc313 100644 ---- a/src/llvm-project/clang/lib/Driver/ToolChains/Gnu.cpp -+++ b/src/llvm-project/clang/lib/Driver/ToolChains/Gnu.cpp -@@ -2139,31 +2139,21 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes( - // and gcc-toolsets. - if (SysRoot.empty() && TargetTriple.getOS() == llvm::Triple::Linux && - D.getVFS().exists("/opt/rh")) { -- // Find the directory in /opt/rh/ starting with gcc-toolset-* or -- // devtoolset-* with the highest version number and add that -- // one to our prefixes. -- std::string ChosenToolsetDir; -- unsigned ChosenToolsetVersion = 0; -- std::error_code EC; -- for (llvm::vfs::directory_iterator LI = D.getVFS().dir_begin("/opt/rh", EC), -- LE; -- !EC && LI != LE; LI = LI.increment(EC)) { -- StringRef ToolsetDir = llvm::sys::path::filename(LI->path()); -- unsigned ToolsetVersion; -- if ((!ToolsetDir.startswith("gcc-toolset-") && -- !ToolsetDir.startswith("devtoolset-")) || -- ToolsetDir.substr(ToolsetDir.rfind('-') + 1) -- .getAsInteger(10, ToolsetVersion)) -- continue; -- -- if (ToolsetVersion > ChosenToolsetVersion) { -- ChosenToolsetVersion = ToolsetVersion; -- ChosenToolsetDir = "/opt/rh/" + ToolsetDir.str(); -- } -- } -- -- if (ChosenToolsetVersion > 0) -- Prefixes.push_back(ChosenToolsetDir + "/root/usr"); -+ // TODO: We may want to remove this, since the functionality -+ // can be achieved using config files. -+ Prefixes.push_back("/opt/rh/gcc-toolset-12/root/usr"); -+ Prefixes.push_back("/opt/rh/gcc-toolset-11/root/usr"); -+ Prefixes.push_back("/opt/rh/gcc-toolset-10/root/usr"); -+ Prefixes.push_back("/opt/rh/devtoolset-12/root/usr"); -+ Prefixes.push_back("/opt/rh/devtoolset-11/root/usr"); -+ Prefixes.push_back("/opt/rh/devtoolset-10/root/usr"); -+ Prefixes.push_back("/opt/rh/devtoolset-9/root/usr"); -+ Prefixes.push_back("/opt/rh/devtoolset-8/root/usr"); -+ Prefixes.push_back("/opt/rh/devtoolset-7/root/usr"); -+ Prefixes.push_back("/opt/rh/devtoolset-6/root/usr"); -+ Prefixes.push_back("/opt/rh/devtoolset-4/root/usr"); -+ Prefixes.push_back("/opt/rh/devtoolset-3/root/usr"); -+ Prefixes.push_back("/opt/rh/devtoolset-2/root/usr"); - } - - // Fall back to /usr which is used by most non-Solaris systems. -diff --git a/src/llvm-project/clang/lib/Sema/SemaInit.cpp b/src/llvm-project/clang/lib/Sema/SemaInit.cpp -index d3b454843..bf7ca718a 100644 ---- a/src/llvm-project/clang/lib/Sema/SemaInit.cpp -+++ b/src/llvm-project/clang/lib/Sema/SemaInit.cpp -@@ -695,10 +695,10 @@ void InitListChecker::FillInEmptyInitForField(unsigned Init, FieldDecl *Field, - // member of reference type uninitialized, the program is - // ill-formed. - SemaRef.Diag(Loc, diag::err_init_reference_member_uninitialized) -- << Field->getType() -- << ILE->getSyntacticForm()->getSourceRange(); -- SemaRef.Diag(Field->getLocation(), -- diag::note_uninit_reference_member); -+ << Field->getType() -+ << (ILE->isSyntacticForm() ? ILE : ILE->getSyntacticForm()) -+ ->getSourceRange(); -+ SemaRef.Diag(Field->getLocation(), diag::note_uninit_reference_member); - } - hadError = true; - return; -diff --git a/src/llvm-project/clang/lib/Sema/SemaLookup.cpp b/src/llvm-project/clang/lib/Sema/SemaLookup.cpp -index 68158ec97..5d0d87fd2 100644 ---- a/src/llvm-project/clang/lib/Sema/SemaLookup.cpp -+++ b/src/llvm-project/clang/lib/Sema/SemaLookup.cpp -@@ -939,11 +939,9 @@ bool Sema::LookupBuiltin(LookupResult &R) { - - // If this is a builtin on this (or all) targets, create the decl. - if (unsigned BuiltinID = II->getBuiltinID()) { -- // In C++, C2x, and OpenCL (spec v1.2 s6.9.f), we don't have any -- // predefined library functions like 'malloc'. Instead, we'll just -- // error. -- if ((getLangOpts().CPlusPlus || getLangOpts().OpenCL || -- getLangOpts().C2x) && -+ // In C++ and OpenCL (spec v1.2 s6.9.f), we don't have any predefined -+ // library functions like 'malloc'. Instead, we'll just error. -+ if ((getLangOpts().CPlusPlus || getLangOpts().OpenCL) && - Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) - return false; - -diff --git a/src/llvm-project/clang/lib/Sema/SemaType.cpp b/src/llvm-project/clang/lib/Sema/SemaType.cpp -index 3ab5d26a9..edcac4d2e 100644 ---- a/src/llvm-project/clang/lib/Sema/SemaType.cpp -+++ b/src/llvm-project/clang/lib/Sema/SemaType.cpp -@@ -6443,6 +6443,9 @@ GetTypeSourceInfoForDeclarator(TypeProcessingState &State, - CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc(); - } - -+ while (BTFTagAttributedTypeLoc TL = CurrTL.getAs()) -+ CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc(); -+ - while (DependentAddressSpaceTypeLoc TL = - CurrTL.getAs()) { - fillDependentAddressSpaceTypeLoc(TL, D.getTypeObject(i).getAttrs()); -diff --git a/src/llvm-project/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/src/llvm-project/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp -index 19149d079..ab65612bc 100644 ---- a/src/llvm-project/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp -+++ b/src/llvm-project/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp -@@ -2839,6 +2839,12 @@ void ExprEngine::VisitCommonDeclRefExpr(const Expr *Ex, const NamedDecl *D, - return; - } - -+ if (const auto *TPO = dyn_cast(D)) { -+ // FIXME: We should meaningfully implement this. -+ (void)TPO; -+ return; -+ } -+ - llvm_unreachable("Support for this Decl not implemented."); - } - -diff --git a/src/llvm-project/clang/lib/Tooling/Syntax/Tokens.cpp b/src/llvm-project/clang/lib/Tooling/Syntax/Tokens.cpp -index e2014f965..1fa73c667 100644 ---- a/src/llvm-project/clang/lib/Tooling/Syntax/Tokens.cpp -+++ b/src/llvm-project/clang/lib/Tooling/Syntax/Tokens.cpp -@@ -55,45 +55,140 @@ getTokensCovering(llvm::ArrayRef Toks, SourceRange R, - return {Begin, End}; - } - --// Finds the smallest expansion range that contains expanded tokens First and --// Last, e.g.: -+// Finds the range within FID corresponding to expanded tokens [First, Last]. -+// Prev precedes First and Next follows Last, these must *not* be included. -+// If no range satisfies the criteria, returns an invalid range. -+// - // #define ID(x) x - // ID(ID(ID(a1) a2)) - // ~~ -> a1 - // ~~ -> a2 - // ~~~~~~~~~ -> a1 a2 --SourceRange findCommonRangeForMacroArgs(const syntax::Token &First, -- const syntax::Token &Last, -- const SourceManager &SM) { -- SourceRange Res; -- auto FirstLoc = First.location(), LastLoc = Last.location(); -- // Keep traversing up the spelling chain as longs as tokens are part of the -- // same expansion. -- while (!FirstLoc.isFileID() && !LastLoc.isFileID()) { -- auto ExpInfoFirst = SM.getSLocEntry(SM.getFileID(FirstLoc)).getExpansion(); -- auto ExpInfoLast = SM.getSLocEntry(SM.getFileID(LastLoc)).getExpansion(); -- // Stop if expansions have diverged. -- if (ExpInfoFirst.getExpansionLocStart() != -- ExpInfoLast.getExpansionLocStart()) -+SourceRange spelledForExpandedSlow(SourceLocation First, SourceLocation Last, -+ SourceLocation Prev, SourceLocation Next, -+ FileID TargetFile, -+ const SourceManager &SM) { -+ // There are two main parts to this algorithm: -+ // - identifying which spelled range covers the expanded tokens -+ // - validating that this range doesn't cover any extra tokens (First/Last) -+ // -+ // We do these in order. However as we transform the expanded range into the -+ // spelled one, we adjust First/Last so the validation remains simple. -+ -+ assert(SM.getSLocEntry(TargetFile).isFile()); -+ // In most cases, to select First and Last we must return their expansion -+ // range, i.e. the whole of any macros they are included in. -+ // -+ // When First and Last are part of the *same macro arg* of a macro written -+ // in TargetFile, we that slice of the arg, i.e. their spelling range. -+ // -+ // Unwrap such macro calls. If the target file has A(B(C)), the -+ // SourceLocation stack of a token inside C shows us the expansion of A first, -+ // then B, then any macros inside C's body, then C itself. -+ // (This is the reverse of the order the PP applies the expansions in). -+ while (First.isMacroID() && Last.isMacroID()) { -+ auto DecFirst = SM.getDecomposedLoc(First); -+ auto DecLast = SM.getDecomposedLoc(Last); -+ auto &ExpFirst = SM.getSLocEntry(DecFirst.first).getExpansion(); -+ auto &ExpLast = SM.getSLocEntry(DecLast.first).getExpansion(); -+ -+ if (!ExpFirst.isMacroArgExpansion() || !ExpLast.isMacroArgExpansion()) -+ break; -+ // Locations are in the same macro arg if they expand to the same place. -+ // (They may still have different FileIDs - an arg can have >1 chunks!) -+ if (ExpFirst.getExpansionLocStart() != ExpLast.getExpansionLocStart()) - break; -- // Do not continue into macro bodies. -- if (!ExpInfoFirst.isMacroArgExpansion() || -- !ExpInfoLast.isMacroArgExpansion()) -+ // Careful, given: -+ // #define HIDE ID(ID(a)) -+ // ID(ID(HIDE)) -+ // The token `a` is wrapped in 4 arg-expansions, we only want to unwrap 2. -+ // We distinguish them by whether the macro expands into the target file. -+ // Fortunately, the target file ones will always appear first. -+ auto &ExpMacro = -+ SM.getSLocEntry(SM.getFileID(ExpFirst.getExpansionLocStart())) -+ .getExpansion(); -+ if (ExpMacro.getExpansionLocStart().isMacroID()) - break; -- FirstLoc = SM.getImmediateSpellingLoc(FirstLoc); -- LastLoc = SM.getImmediateSpellingLoc(LastLoc); -- // Update the result afterwards, as we want the tokens that triggered the -- // expansion. -- Res = {FirstLoc, LastLoc}; -+ // Replace each endpoint with its spelling inside the macro arg. -+ // (This is getImmediateSpellingLoc without repeating lookups). -+ First = ExpFirst.getSpellingLoc().getLocWithOffset(DecFirst.second); -+ Last = ExpLast.getSpellingLoc().getLocWithOffset(DecLast.second); -+ -+ // Now: how do we adjust the previous/next bounds? Three cases: -+ // A) If they are also part of the same macro arg, we translate them too. -+ // This will ensure that we don't select any macros nested within the -+ // macro arg that cover extra tokens. Critical case: -+ // #define ID(X) X -+ // ID(prev target) // selecting 'target' succeeds -+ // #define LARGE ID(prev target) -+ // LARGE // selecting 'target' fails. -+ // B) They are not in the macro at all, then their expansion range is a -+ // sibling to it, and we can safely substitute that. -+ // #define PREV prev -+ // #define ID(X) X -+ // PREV ID(target) // selecting 'target' succeeds. -+ // #define LARGE PREV ID(target) -+ // LARGE // selecting 'target' fails. -+ // C) They are in a different arg of this macro, or the macro body. -+ // Now selecting the whole macro arg is fine, but the whole macro is not. -+ // Model this by setting using the edge of the macro call as the bound. -+ // #define ID2(X, Y) X Y -+ // ID2(prev, target) // selecting 'target' succeeds -+ // #define LARGE ID2(prev, target) -+ // LARGE // selecting 'target' fails -+ auto AdjustBound = [&](SourceLocation &Bound) { -+ if (Bound.isInvalid() || !Bound.isMacroID()) // Non-macro must be case B. -+ return; -+ auto DecBound = SM.getDecomposedLoc(Bound); -+ auto &ExpBound = SM.getSLocEntry(DecBound.first).getExpansion(); -+ if (ExpBound.isMacroArgExpansion() && -+ ExpBound.getExpansionLocStart() == ExpFirst.getExpansionLocStart()) { -+ // Case A: translate to (spelling) loc within the macro arg. -+ Bound = ExpBound.getSpellingLoc().getLocWithOffset(DecBound.second); -+ return; -+ } -+ while (Bound.isMacroID()) { -+ SourceRange Exp = SM.getImmediateExpansionRange(Bound).getAsRange(); -+ if (Exp.getBegin() == ExpMacro.getExpansionLocStart()) { -+ // Case B: bounds become the macro call itself. -+ Bound = (&Bound == &Prev) ? Exp.getBegin() : Exp.getEnd(); -+ return; -+ } -+ // Either case C, or expansion location will later find case B. -+ // We choose the upper bound for Prev and the lower one for Next: -+ // ID(prev) target ID(next) -+ // ^ ^ -+ // new-prev new-next -+ Bound = (&Bound == &Prev) ? Exp.getEnd() : Exp.getBegin(); -+ } -+ }; -+ AdjustBound(Prev); -+ AdjustBound(Next); - } -- // Normally mapping back to expansion location here only changes FileID, as -- // we've already found some tokens expanded from the same macro argument, and -- // they should map to a consecutive subset of spelled tokens. Unfortunately -- // SourceManager::isBeforeInTranslationUnit discriminates sourcelocations -- // based on their FileID in addition to offsets. So even though we are -- // referring to same tokens, SourceManager might tell us that one is before -- // the other if they've got different FileIDs. -- return SM.getExpansionRange(CharSourceRange(Res, true)).getAsRange(); -+ -+ // In all remaining cases we need the full containing macros. -+ // If this overlaps Prev or Next, then no range is possible. -+ SourceRange Candidate = -+ SM.getExpansionRange(SourceRange(First, Last)).getAsRange(); -+ auto DecFirst = SM.getDecomposedExpansionLoc(Candidate.getBegin()); -+ auto DecLast = SM.getDecomposedLoc(Candidate.getEnd()); -+ // Can end up in the wrong file due to bad input or token-pasting shenanigans. -+ if (Candidate.isInvalid() || DecFirst.first != TargetFile || DecLast.first != TargetFile) -+ return SourceRange(); -+ // Check bounds, which may still be inside macros. -+ if (Prev.isValid()) { -+ auto Dec = SM.getDecomposedLoc(SM.getExpansionRange(Prev).getBegin()); -+ if (Dec.first != DecFirst.first || Dec.second >= DecFirst.second) -+ return SourceRange(); -+ } -+ if (Next.isValid()) { -+ auto Dec = SM.getDecomposedLoc(SM.getExpansionRange(Next).getEnd()); -+ if (Dec.first != DecLast.first || Dec.second <= DecLast.second) -+ return SourceRange(); -+ } -+ // Now we know that Candidate is a file range that covers [First, Last] -+ // without encroaching on {Prev, Next}. Ship it! -+ return Candidate; - } - - } // namespace -@@ -363,51 +458,50 @@ TokenBuffer::spelledForExpanded(llvm::ArrayRef Expanded) const { - // of the range, bail out in that case. - if (Expanded.empty()) - return llvm::None; -- -- const syntax::Token *BeginSpelled; -- const Mapping *BeginMapping; -- std::tie(BeginSpelled, BeginMapping) = -- spelledForExpandedToken(&Expanded.front()); -- -- const syntax::Token *LastSpelled; -- const Mapping *LastMapping; -- std::tie(LastSpelled, LastMapping) = -- spelledForExpandedToken(&Expanded.back()); -- -- FileID FID = SourceMgr->getFileID(BeginSpelled->location()); -+ const syntax::Token *First = &Expanded.front(); -+ const syntax::Token *Last = &Expanded.back(); -+ const syntax::Token *FirstSpelled, *LastSpelled; -+ const TokenBuffer::Mapping *FirstMapping, *LastMapping; -+ std::tie(FirstSpelled, FirstMapping) = spelledForExpandedToken(First); -+ std::tie(LastSpelled, LastMapping) = spelledForExpandedToken(Last); -+ -+ FileID FID = SourceMgr->getFileID(FirstSpelled->location()); - // FIXME: Handle multi-file changes by trying to map onto a common root. - if (FID != SourceMgr->getFileID(LastSpelled->location())) - return llvm::None; - - const MarkedFile &File = Files.find(FID)->second; - -- // If both tokens are coming from a macro argument expansion, try and map to -- // smallest part of the macro argument. BeginMapping && LastMapping check is -- // only for performance, they are a prerequisite for Expanded.front() and -- // Expanded.back() being part of a macro arg expansion. -- if (BeginMapping && LastMapping && -- SourceMgr->isMacroArgExpansion(Expanded.front().location()) && -- SourceMgr->isMacroArgExpansion(Expanded.back().location())) { -- auto CommonRange = findCommonRangeForMacroArgs(Expanded.front(), -- Expanded.back(), *SourceMgr); -- // It might be the case that tokens are arguments of different macro calls, -- // in that case we should continue with the logic below instead of returning -- // an empty range. -- if (CommonRange.isValid()) -- return getTokensCovering(File.SpelledTokens, CommonRange, *SourceMgr); -+ // If the range is within one macro argument, the result may be only part of a -+ // Mapping. We must use the general (SourceManager-based) algorithm. -+ if (FirstMapping && FirstMapping == LastMapping && -+ SourceMgr->isMacroArgExpansion(First->location()) && -+ SourceMgr->isMacroArgExpansion(Last->location())) { -+ // We use excluded Prev/Next token for bounds checking. -+ SourceLocation Prev = (First == &ExpandedTokens.front()) -+ ? SourceLocation() -+ : (First - 1)->location(); -+ SourceLocation Next = (Last == &ExpandedTokens.back()) -+ ? SourceLocation() -+ : (Last + 1)->location(); -+ SourceRange Range = spelledForExpandedSlow( -+ First->location(), Last->location(), Prev, Next, FID, *SourceMgr); -+ if (Range.isInvalid()) -+ return llvm::None; -+ return getTokensCovering(File.SpelledTokens, Range, *SourceMgr); - } - -+ // Otherwise, use the fast version based on Mappings. - // Do not allow changes that doesn't cover full expansion. -- unsigned BeginExpanded = Expanded.begin() - ExpandedTokens.data(); -- unsigned EndExpanded = Expanded.end() - ExpandedTokens.data(); -- if (BeginMapping && BeginExpanded != BeginMapping->BeginExpanded) -+ unsigned FirstExpanded = Expanded.begin() - ExpandedTokens.data(); -+ unsigned LastExpanded = Expanded.end() - ExpandedTokens.data(); -+ if (FirstMapping && FirstExpanded != FirstMapping->BeginExpanded) - return llvm::None; -- if (LastMapping && LastMapping->EndExpanded != EndExpanded) -+ if (LastMapping && LastMapping->EndExpanded != LastExpanded) - return llvm::None; -- // All is good, return the result. - return llvm::makeArrayRef( -- BeginMapping ? File.SpelledTokens.data() + BeginMapping->BeginSpelled -- : BeginSpelled, -+ FirstMapping ? File.SpelledTokens.data() + FirstMapping->BeginSpelled -+ : FirstSpelled, - LastMapping ? File.SpelledTokens.data() + LastMapping->EndSpelled - : LastSpelled + 1); - } -diff --git a/src/llvm-project/clang/test/Analysis/template-param-objects.cpp b/src/llvm-project/clang/test/Analysis/template-param-objects.cpp -new file mode 100644 -index 000000000..dde95fa62 ---- /dev/null -+++ b/src/llvm-project/clang/test/Analysis/template-param-objects.cpp -@@ -0,0 +1,33 @@ -+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection \ -+// RUN: -analyzer-config eagerly-assume=false -std=c++20 -verify %s -+ -+template void clang_analyzer_dump(T); -+void clang_analyzer_eval(bool); -+ -+struct Box { -+ int value; -+}; -+bool operator ==(Box lhs, Box rhs) { -+ return lhs.value == rhs.value; -+} -+template void dumps() { -+ clang_analyzer_dump(V); // expected-warning {{lazyCompoundVal}} -+ clang_analyzer_dump(&V); // expected-warning {{Unknown}} -+ clang_analyzer_dump(V.value); // expected-warning {{Unknown}} FIXME: It should be '6 S32b'. -+ clang_analyzer_dump(&V.value); // expected-warning {{Unknown}} -+} -+template void dumps(); -+ -+// [temp.param].7.3.2: -+// "All such template parameters in the program of the same type with the -+// same value denote the same template parameter object." -+template void stable_addresses() { -+ clang_analyzer_eval(&A1 == &A2); // expected-warning {{UNKNOWN}} FIXME: It should be TRUE. -+ clang_analyzer_eval(&B1 == &B2); // expected-warning {{UNKNOWN}} FIXME: It should be TRUE. -+ clang_analyzer_eval(&A1 == &B2); // expected-warning {{UNKNOWN}} FIXME: It should be FALSE. -+ -+ clang_analyzer_eval(A1 == A2); // expected-warning {{UNKNOWN}} FIXME: It should be TRUE. -+ clang_analyzer_eval(B1 == B2); // expected-warning {{UNKNOWN}} FIXME: It should be TRUE. -+ clang_analyzer_eval(A1 == B2); // expected-warning {{UNKNOWN}} FIXME: It should be FALSE. -+} -+template void stable_addresses(); -diff --git a/src/llvm-project/clang/test/CodeGen/arm-vaarg.c b/src/llvm-project/clang/test/CodeGen/arm-vaarg.c -new file mode 100644 -index 000000000..4dab397a2 ---- /dev/null -+++ b/src/llvm-project/clang/test/CodeGen/arm-vaarg.c -@@ -0,0 +1,23 @@ -+// RUN: %clang -Xclang -no-opaque-pointers -mfloat-abi=soft -target arm-linux-gnu -emit-llvm -S -o - %s | FileCheck %s -+ -+struct Empty {}; -+ -+struct Empty emptyvar; -+ -+void take_args(int a, ...) { -+// CHECK: [[ALLOCA_VA_LIST:%[a-zA-Z0-9._]+]] = alloca %struct.__va_list, align 4 -+// CHECK: call void @llvm.va_start -+// CHECK-NEXT: [[AP_ADDR:%[a-zA-Z0-9._]+]] = bitcast %struct.__va_list* [[ALLOCA_VA_LIST]] to i8** -+// CHECK-NEXT: [[LOAD_AP:%[a-zA-Z0-9._]+]] = load i8*, i8** [[AP_ADDR]], align 4 -+// CHECK-NEXT: [[EMPTY_PTR:%[a-zA-Z0-9._]+]] = bitcast i8* [[LOAD_AP]] to %struct.Empty* -+ -+ // It's conceivable that EMPTY_PTR may not actually be a valid pointer -+ // (e.g. it's at the very bottom of the stack and the next page is -+ // invalid). This doesn't matter provided it's never loaded (there's no -+ // well-defined way to tell), but it becomes a problem if we do try to use it. -+// CHECK-NOT: load %struct.Empty, %struct.Empty* [[EMPTY_PTR]] -+ __builtin_va_list l; -+ __builtin_va_start(l, a); -+ emptyvar = __builtin_va_arg(l, struct Empty); -+ __builtin_va_end(l); -+} -diff --git a/src/llvm-project/clang/test/CodeGen/attr-btf_type_tag-func-ptr.c b/src/llvm-project/clang/test/CodeGen/attr-btf_type_tag-func-ptr.c -new file mode 100644 -index 000000000..29ca5f58e ---- /dev/null -+++ b/src/llvm-project/clang/test/CodeGen/attr-btf_type_tag-func-ptr.c -@@ -0,0 +1,15 @@ -+// RUN: %clang_cc1 -triple %itanium_abi_triple -debug-info-kind=limited -S -emit-llvm -o - %s | FileCheck %s -+ -+struct t { -+ int (__attribute__((btf_type_tag("rcu"))) *f)(); -+ int a; -+}; -+int foo(struct t *arg) { -+ return arg->a; -+} -+ -+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "f" -+// CHECK-SAME: baseType: ![[L18:[0-9]+]] -+// CHECK: ![[L18]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[#]], size: [[#]], annotations: ![[L21:[0-9]+]]) -+// CHECK: ![[L21]] = !{![[L22:[0-9]+]]} -+// CHECK: ![[L22]] = !{!"btf_type_tag", !"rcu"} -diff --git a/src/llvm-project/clang/test/CodeGen/debug-info-enum-case-val.c b/src/llvm-project/clang/test/CodeGen/debug-info-enum-case-val.c -new file mode 100644 -index 000000000..f39de0d73 ---- /dev/null -+++ b/src/llvm-project/clang/test/CodeGen/debug-info-enum-case-val.c -@@ -0,0 +1,30 @@ -+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s -+ -+enum { A = 1 }; -+int func1(int a) { -+ switch(a) { -+ case A: return 10; -+ default: break; -+ } -+ return 0; -+} -+// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type -+// CHECK-SAME: elements: [[TEST1_ENUMS:![0-9]*]] -+// CHECK: [[TEST1_ENUMS]] = !{[[TEST1_E:![0-9]*]]} -+// CHECK: [[TEST1_E]] = !DIEnumerator(name: "A", value: 1) -+ -+// Test ImplicitCast of switch case enum value -+enum { B = 2 }; -+typedef unsigned long long __t1; -+typedef __t1 __t2; -+int func2(__t2 a) { -+ switch(a) { -+ case B: return 10; -+ default: break; -+ } -+ return 0; -+} -+// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type -+// CHECK-SAME: elements: [[TEST2_ENUMS:![0-9]*]] -+// CHECK: [[TEST2_ENUMS]] = !{[[TEST2_E:![0-9]*]]} -+// CHECK: [[TEST2_E]] = !DIEnumerator(name: "B", value: 2) -diff --git a/src/llvm-project/clang/test/Sema/gnu-builtins.c b/src/llvm-project/clang/test/Sema/gnu-builtins.c -new file mode 100644 -index 000000000..c4da8b393 ---- /dev/null -+++ b/src/llvm-project/clang/test/Sema/gnu-builtins.c -@@ -0,0 +1,13 @@ -+// RUN: %clang_cc1 -fsyntax-only -verify=gnu -std=gnu17 %s -+// RUN: %clang_cc1 -fsyntax-only -verify=gnu -std=gnu2x %s -+// RUN: %clang_cc1 -fsyntax-only -verify=std -std=c17 %s -+// RUN: %clang_cc1 -fsyntax-only -verify=std -std=c2x %s -+ -+// std-no-diagnostics -+ -+// 'index' is a builtin library function, but only in GNU mode. So this should -+// give an error in GNU modes but be okay in non-GNU mode. -+// FIXME: the error is correct, but these notes are pretty awful. -+int index; // gnu-error {{redefinition of 'index' as different kind of symbol}} \ -+ gnu-note {{unguarded header; consider using #ifdef guards or #pragma once}} \ -+ gnu-note {{previous definition is here}} -diff --git a/src/llvm-project/clang/test/SemaCXX/specialization-diagnose-crash.cpp b/src/llvm-project/clang/test/SemaCXX/specialization-diagnose-crash.cpp -new file mode 100644 -index 000000000..5fd387cab ---- /dev/null -+++ b/src/llvm-project/clang/test/SemaCXX/specialization-diagnose-crash.cpp -@@ -0,0 +1,24 @@ -+// RUN: %clang_cc1 -fsyntax-only %s --std=c++17 -verify -+// This is a reduction of GH57370 and GH58028, originally appearing -+// in libstdc++'s variant code. -+ -+struct V1 {}; -+struct V2 : V1 { -+ int &a; -+}; -+ -+template using void_t = void; -+ -+template struct X { T x; }; -+ -+template struct Variant { -+ Variant() = delete; // expected-note {{deleted here}} -+}; -+ -+template -+struct Variant{T1()})>> {}; -+ -+void f() { -+ Variant(); -+ Variant(); // expected-error {{call to deleted constructor}} -+} -diff --git a/src/llvm-project/clang/unittests/Driver/ToolChainTest.cpp b/src/llvm-project/clang/unittests/Driver/ToolChainTest.cpp -index 64bc61652..c434dfcb3 100644 ---- a/src/llvm-project/clang/unittests/Driver/ToolChainTest.cpp -+++ b/src/llvm-project/clang/unittests/Driver/ToolChainTest.cpp -@@ -18,7 +18,6 @@ - #include "clang/Driver/Driver.h" - #include "llvm/ADT/ArrayRef.h" - #include "llvm/MC/TargetRegistry.h" --#include "llvm/Support/Host.h" - #include "llvm/Support/TargetSelect.h" - #include "llvm/Support/VirtualFileSystem.h" - #include "llvm/Support/raw_ostream.h" -@@ -570,95 +569,4 @@ TEST(DxcModeTest, ValidatorVersionValidation) { - Diags.Clear(); - DiagConsumer->clear(); - } -- --TEST(ToolChainTest, Toolsets) { -- // Ignore this test on Windows hosts. -- llvm::Triple Host(llvm::sys::getProcessTriple()); -- if (Host.isOSWindows()) -- GTEST_SKIP(); -- -- IntrusiveRefCntPtr DiagOpts = new DiagnosticOptions(); -- IntrusiveRefCntPtr DiagID(new DiagnosticIDs()); -- -- // Check (newer) GCC toolset installation. -- { -- IntrusiveRefCntPtr InMemoryFileSystem( -- new llvm::vfs::InMemoryFileSystem); -- -- // These should be ignored. -- InMemoryFileSystem->addFile("/opt/rh/gcc-toolset-2", 0, -- llvm::MemoryBuffer::getMemBuffer("\n")); -- InMemoryFileSystem->addFile("/opt/rh/gcc-toolset-", 0, -- llvm::MemoryBuffer::getMemBuffer("\n")); -- InMemoryFileSystem->addFile("/opt/rh/gcc-toolset--", 0, -- llvm::MemoryBuffer::getMemBuffer("\n")); -- InMemoryFileSystem->addFile("/opt/rh/gcc-toolset--1", 0, -- llvm::MemoryBuffer::getMemBuffer("\n")); -- -- // File needed for GCC installation detection. -- InMemoryFileSystem->addFile("/opt/rh/gcc-toolset-12/root/usr/lib/gcc/" -- "x86_64-redhat-linux/11/crtbegin.o", -- 0, llvm::MemoryBuffer::getMemBuffer("\n")); -- -- DiagnosticsEngine Diags(DiagID, &*DiagOpts, new SimpleDiagnosticConsumer); -- Driver TheDriver("/bin/clang", "x86_64-redhat-linux", Diags, -- "clang LLVM compiler", InMemoryFileSystem); -- std::unique_ptr C( -- TheDriver.BuildCompilation({"clang", "--gcc-toolchain="})); -- ASSERT_TRUE(C); -- std::string S; -- { -- llvm::raw_string_ostream OS(S); -- C->getDefaultToolChain().printVerboseInfo(OS); -- } -- EXPECT_EQ("Found candidate GCC installation: " -- "/opt/rh/gcc-toolset-12/root/usr/lib/gcc/x86_64-redhat-linux/11\n" -- "Selected GCC installation: " -- "/opt/rh/gcc-toolset-12/root/usr/lib/gcc/x86_64-redhat-linux/11\n" -- "Candidate multilib: .;@m64\n" -- "Selected multilib: .;@m64\n", -- S); -- } -- -- // And older devtoolset. -- { -- IntrusiveRefCntPtr InMemoryFileSystem( -- new llvm::vfs::InMemoryFileSystem); -- -- // These should be ignored. -- InMemoryFileSystem->addFile("/opt/rh/devtoolset-2", 0, -- llvm::MemoryBuffer::getMemBuffer("\n")); -- InMemoryFileSystem->addFile("/opt/rh/devtoolset-", 0, -- llvm::MemoryBuffer::getMemBuffer("\n")); -- InMemoryFileSystem->addFile("/opt/rh/devtoolset--", 0, -- llvm::MemoryBuffer::getMemBuffer("\n")); -- InMemoryFileSystem->addFile("/opt/rh/devtoolset--1", 0, -- llvm::MemoryBuffer::getMemBuffer("\n")); -- -- // File needed for GCC installation detection. -- InMemoryFileSystem->addFile("/opt/rh/devtoolset-12/root/usr/lib/gcc/" -- "x86_64-redhat-linux/11/crtbegin.o", -- 0, llvm::MemoryBuffer::getMemBuffer("\n")); -- -- DiagnosticsEngine Diags(DiagID, &*DiagOpts, new SimpleDiagnosticConsumer); -- Driver TheDriver("/bin/clang", "x86_64-redhat-linux", Diags, -- "clang LLVM compiler", InMemoryFileSystem); -- std::unique_ptr C( -- TheDriver.BuildCompilation({"clang", "--gcc-toolchain="})); -- ASSERT_TRUE(C); -- std::string S; -- { -- llvm::raw_string_ostream OS(S); -- C->getDefaultToolChain().printVerboseInfo(OS); -- } -- EXPECT_EQ("Found candidate GCC installation: " -- "/opt/rh/devtoolset-12/root/usr/lib/gcc/x86_64-redhat-linux/11\n" -- "Selected GCC installation: " -- "/opt/rh/devtoolset-12/root/usr/lib/gcc/x86_64-redhat-linux/11\n" -- "Candidate multilib: .;@m64\n" -- "Selected multilib: .;@m64\n", -- S); -- } --} -- - } // end anonymous namespace. -diff --git a/src/llvm-project/clang/unittests/Tooling/Syntax/TokensTest.cpp b/src/llvm-project/clang/unittests/Tooling/Syntax/TokensTest.cpp -index 77f719ce2..85fc837fb 100644 ---- a/src/llvm-project/clang/unittests/Tooling/Syntax/TokensTest.cpp -+++ b/src/llvm-project/clang/unittests/Tooling/Syntax/TokensTest.cpp -@@ -743,6 +743,62 @@ TEST_F(TokenBufferTest, SpelledByExpanded) { - ValueIs(SameRange(findSpelled("ID2 ( a4 , a5 a6 a7 )")))); - // Should fail, spans multiple invocations. - EXPECT_EQ(Buffer.spelledForExpanded(findExpanded("a1 a2 a3 a4")), llvm::None); -+ -+ // https://github.com/clangd/clangd/issues/1289 -+ recordTokens(R"cpp( -+ #define FOO(X) foo(X) -+ #define INDIRECT FOO(y) -+ INDIRECT // expands to foo(y) -+ )cpp"); -+ EXPECT_EQ(Buffer.spelledForExpanded(findExpanded("y")), llvm::None); -+ -+ recordTokens(R"cpp( -+ #define FOO(X) a X b -+ FOO(y) -+ )cpp"); -+ EXPECT_THAT(Buffer.spelledForExpanded(findExpanded("y")), -+ ValueIs(SameRange(findSpelled("y")))); -+ -+ recordTokens(R"cpp( -+ #define ID(X) X -+ #define BAR ID(1) -+ BAR -+ )cpp"); -+ EXPECT_THAT(Buffer.spelledForExpanded(findExpanded("1")), -+ ValueIs(SameRange(findSpelled(") BAR").drop_front()))); -+ -+ // Critical cases for mapping of Prev/Next in spelledForExpandedSlow. -+ recordTokens(R"cpp( -+ #define ID(X) X -+ ID(prev ID(good)) -+ #define LARGE ID(prev ID(bad)) -+ LARGE -+ )cpp"); -+ EXPECT_THAT(Buffer.spelledForExpanded(findExpanded("good")), -+ ValueIs(SameRange(findSpelled("good")))); -+ EXPECT_EQ(Buffer.spelledForExpanded(findExpanded("bad")), llvm::None); -+ -+ recordTokens(R"cpp( -+ #define PREV prev -+ #define ID(X) X -+ PREV ID(good) -+ #define LARGE PREV ID(bad) -+ LARGE -+ )cpp"); -+ EXPECT_THAT(Buffer.spelledForExpanded(findExpanded("good")), -+ ValueIs(SameRange(findSpelled("good")))); -+ EXPECT_EQ(Buffer.spelledForExpanded(findExpanded("bad")), llvm::None); -+ -+ recordTokens(R"cpp( -+ #define ID(X) X -+ #define ID2(X, Y) X Y -+ ID2(prev, ID(good)) -+ #define LARGE ID2(prev, bad) -+ LARGE -+ )cpp"); -+ EXPECT_THAT(Buffer.spelledForExpanded(findExpanded("good")), -+ ValueIs(SameRange(findSpelled("good")))); -+ EXPECT_EQ(Buffer.spelledForExpanded(findExpanded("bad")), llvm::None); - } - - TEST_F(TokenBufferTest, ExpandedTokensForRange) { -diff --git a/src/llvm-project/cmake/Modules/FindLibEdit.cmake b/src/llvm-project/cmake/Modules/FindLibEdit.cmake -index 7e62d4d83..de8f5a2e7 100644 ---- a/src/llvm-project/cmake/Modules/FindLibEdit.cmake -+++ b/src/llvm-project/cmake/Modules/FindLibEdit.cmake -@@ -21,6 +21,7 @@ find_library(LibEdit_LIBRARIES NAMES edit HINTS ${PC_LIBEDIT_LIBRARY_DIRS}) - - include(CheckIncludeFile) - if(LibEdit_INCLUDE_DIRS AND EXISTS "${LibEdit_INCLUDE_DIRS}/histedit.h") -+ include(CMakePushCheckState) - cmake_push_check_state() - list(APPEND CMAKE_REQUIRED_INCLUDES ${LibEdit_INCLUDE_DIRS}) - list(APPEND CMAKE_REQUIRED_LIBRARIES ${LibEdit_LIBRARIES}) -diff --git a/src/llvm-project/compiler-rt/cmake/Modules/CompilerRTDarwinUtils.cmake b/src/llvm-project/compiler-rt/cmake/Modules/CompilerRTDarwinUtils.cmake -index 2c9983c6a..640c7e712 100644 ---- a/src/llvm-project/compiler-rt/cmake/Modules/CompilerRTDarwinUtils.cmake -+++ b/src/llvm-project/compiler-rt/cmake/Modules/CompilerRTDarwinUtils.cmake -@@ -116,7 +116,7 @@ function(darwin_test_archs os valid_archs) - if(NOT TEST_COMPILE_ONLY) - message(STATUS "Finding valid architectures for ${os}...") - set(SIMPLE_C ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/src.c) -- file(WRITE ${SIMPLE_C} "#include \nint main() { printf(__FILE__); return 0; }\n") -+ file(WRITE ${SIMPLE_C} "#include \nint main(void) { printf(__FILE__); return 0; }\n") - - set(os_linker_flags) - foreach(flag ${DARWIN_${os}_LINK_FLAGS}) -diff --git a/src/llvm-project/compiler-rt/cmake/config-ix.cmake b/src/llvm-project/compiler-rt/cmake/config-ix.cmake -index cd45176cf..9077e8f9f 100644 ---- a/src/llvm-project/compiler-rt/cmake/config-ix.cmake -+++ b/src/llvm-project/compiler-rt/cmake/config-ix.cmake -@@ -209,7 +209,7 @@ set(COMPILER_RT_SUPPORTED_ARCH) - # runtime libraries supported by our current compilers cross-compiling - # abilities. - set(SIMPLE_SOURCE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/simple.cc) --file(WRITE ${SIMPLE_SOURCE} "#include \n#include \nint main() { printf(\"hello, world\"); }\n") -+file(WRITE ${SIMPLE_SOURCE} "#include \n#include \nint main(void) { printf(\"hello, world\"); }\n") - - # Detect whether the current target platform is 32-bit or 64-bit, and setup - # the correct commandline flags needed to attempt to target 32-bit and 64-bit. -diff --git a/src/llvm-project/compiler-rt/lib/builtins/CMakeLists.txt b/src/llvm-project/compiler-rt/lib/builtins/CMakeLists.txt -index ec668e294..df02682ae 100644 ---- a/src/llvm-project/compiler-rt/lib/builtins/CMakeLists.txt -+++ b/src/llvm-project/compiler-rt/lib/builtins/CMakeLists.txt -@@ -745,7 +745,7 @@ else () - SOURCE "#if !(__ARM_FP & 0x8) - #error No double-precision support! - #endif -- int main() { return 0; }") -+ int main(void) { return 0; }") - if(NOT COMPILER_RT_HAS_${arch}_VFP_DP) - list(REMOVE_ITEM ${arch}_SOURCES ${arm_Thumb1_VFPv2_DP_SOURCES}) - endif() -diff --git a/src/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/src/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common.h -index fc5aeccf2..08c6062ba 100644 ---- a/src/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common.h -+++ b/src/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common.h -@@ -443,7 +443,7 @@ inline uptr RoundUpToPowerOfTwo(uptr size) { - return 1ULL << (up + 1); - } - --inline uptr RoundUpTo(uptr size, uptr boundary) { -+inline constexpr uptr RoundUpTo(uptr size, uptr boundary) { - RAW_CHECK(IsPowerOfTwo(boundary)); - return (size + boundary - 1) & ~(boundary - 1); - } -diff --git a/src/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/src/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc -index 9af296b18..b29665a63 100644 ---- a/src/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc -+++ b/src/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc -@@ -6703,7 +6703,7 @@ INTERCEPTOR(int, sem_init, __sanitizer_sem_t *s, int pshared, unsigned value) { - COMMON_INTERCEPTOR_ENTER(ctx, sem_init, s, pshared, value); - // Workaround a bug in glibc's "old" semaphore implementation by - // zero-initializing the sem_t contents. This has to be done here because -- // interceptors bind to the lowest symbols version by default, hitting the -+ // interceptors bind to the lowest version before glibc 2.36, hitting the - // buggy code path while the non-sanitized build of the same code works fine. - REAL(memset)(s, 0, sizeof(*s)); - int res = REAL(sem_init)(s, pshared, value); -diff --git a/src/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stack_store.h b/src/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stack_store.h -index ddb96d2cc..4f1a8caac 100644 ---- a/src/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stack_store.h -+++ b/src/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stack_store.h -@@ -61,7 +61,7 @@ class StackStore { - return frame_idx % kBlockSizeFrames; - } - -- static uptr IdToOffset(Id id) { -+ static constexpr uptr IdToOffset(Id id) { - CHECK_NE(id, 0); - return id - 1; // Avoid zero as id. - } -diff --git a/src/llvm-project/compiler-rt/test/sanitizer_common/TestCases/Linux/sem_init_glibc.cpp b/src/llvm-project/compiler-rt/test/sanitizer_common/TestCases/Linux/sem_init_glibc.cpp -index d623ccabb..234c5019f 100644 ---- a/src/llvm-project/compiler-rt/test/sanitizer_common/TestCases/Linux/sem_init_glibc.cpp -+++ b/src/llvm-project/compiler-rt/test/sanitizer_common/TestCases/Linux/sem_init_glibc.cpp -@@ -1,39 +1,36 @@ - // RUN: %clangxx -O0 -g %s -lutil -o %t && %run %t - // This test depends on the glibc layout of struct sem_t and checks that we - // don't leave sem_t::private uninitialized. --// UNSUPPORTED: android, lsan-x86, ubsan, target-is-mips64, target-is-mips64el -+// UNSUPPORTED: android, lsan-x86, ubsan - #include - #include - #include - #include - #include - --// On powerpc64be semval_t must be 64 bits even with "old" versions of glibc. --#if __PPC64__ && __BIG_ENDIAN__ --typedef uint64_t semval_t; -- --// This condition needs to correspond to __HAVE_64B_ATOMICS macro in glibc. --#elif (defined(__x86_64__) || defined(__aarch64__) || defined(__powerpc64__) || \ -- defined(__s390x__) || defined(__sparc64__) || defined(__alpha__) || \ -- defined(__ia64__) || defined(__m68k__)) && __GLIBC_PREREQ(2, 21) --typedef uint64_t semval_t; --#else -+// musl and glibc's __HAVE_64B_ATOMICS==0 ports (e.g. arm, i386) use 32-bit sem -+// values. 64-bit glibc ports defining sem_init@GLIBC_2.0 (mips64) use 32-bit as -+// well, if the sem_init interceptor picks the oldest versioned symbol -+// (glibc<2.36, see https://sourceware.org/PR14932). -+#if !defined(__GLIBC__) || defined(__ILP32__) || \ -+ !__GLIBC_PREREQ(2, 36) && defined(__mips64__) - typedef unsigned semval_t; -+#else -+typedef uint64_t semval_t; - #endif - --// glibc 2.21 has introduced some changes in the way the semaphore value is --// handled for 32-bit platforms, but since these changes are not ABI-breaking --// they are not versioned. On newer platforms such as ARM, there is only one --// version of the symbol, so it's enough to check the glibc version. However, --// for old platforms such as i386, glibc contains two or even three versions of --// the sem_init symbol, and the sanitizers always pick the oldest one. --// Therefore, it is not enough to rely on the __GLIBC_PREREQ macro - we should --// instead check the platform as well to make sure we only expect the new --// behavior on platforms where the older symbols do not exist. --#if defined(__arm__) && __GLIBC_PREREQ(2, 21) --#define GET_SEM_VALUE(V) ((V) >> 1) -+// glibc __HAVE_64B_ATOMICS==0 ports define a sem_init which shifts the value by -+// 1 (https://sourceware.org/PR12674 glibc 2.21). The version is picked if -+// either glibc>=2.36 or sem_init@GLIBC_2.0 is absent (arm and newer ports). -+// -+// The __GLIBC_PREREQ check is brittle in that it requires matched -+// __GLIBC_PREREQ values for build time and run time. -+#if defined(__GLIBC__) && defined(__ILP32__) && \ -+ (__GLIBC_PREREQ(2, 36) || (__GLIBC_PREREQ(2, 21) && !defined(__i386__) && \ -+ !defined(__mips__) && !defined(__powerpc__))) -+# define GET_SEM_VALUE(V) ((V) >> 1) - #else --#define GET_SEM_VALUE(V) (V) -+# define GET_SEM_VALUE(V) (V) - #endif - - void my_sem_init(bool priv, int value, semval_t *a, unsigned char *b) { -diff --git a/src/llvm-project/libcxx/test/libcxx/utilities/function.objects/func.blocks.arc.pass.mm b/src/llvm-project/libcxx/test/libcxx/utilities/function.objects/func.blocks.arc.pass.mm -new file mode 100644 -index 000000000..186fe22e6 ---- /dev/null -+++ b/src/llvm-project/libcxx/test/libcxx/utilities/function.objects/func.blocks.arc.pass.mm -@@ -0,0 +1,89 @@ -+//===----------------------------------------------------------------------===// -+// -+// 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 -+// -+//===----------------------------------------------------------------------===// -+ -+// std::function support for "blocks" when ARC is enabled -+ -+// UNSUPPORTED: c++03 -+ -+// This test requires the Blocks runtime, which is (only?) available on Darwin -+// out-of-the-box. -+// REQUIRES: has-fblocks && darwin -+ -+// ADDITIONAL_COMPILE_FLAGS: -fblocks -fobjc-arc -+ -+#include -+ -+#include -+#include -+#include -+ -+struct Foo { -+ Foo() = default; -+ Foo(std::size_t (^bl)()) : f(bl) {} -+ -+ std::function f; -+}; -+ -+Foo Factory(std::size_t (^bl)()) { -+ Foo result(bl); -+ return result; -+} -+ -+Foo Factory2() { -+ auto hello = std::string("Hello world"); -+ return Factory(^() { -+ return hello.size(); -+ }); -+} -+ -+Foo AssignmentFactory(std::size_t (^bl)()) { -+ Foo result; -+ result.f = bl; -+ return result; -+} -+ -+Foo AssignmentFactory2() { -+ auto hello = std::string("Hello world"); -+ return AssignmentFactory(^() { -+ return hello.size(); -+ }); -+} -+ -+int main(int, char **) { -+ // Case 1, works -+ { -+ auto hello = std::string("Hello world"); -+ auto f = AssignmentFactory(^() { -+ return hello.size(); -+ }); -+ assert(f.f() == 11); -+ } -+ -+ // Case 2, works -+ { -+ auto f = AssignmentFactory2(); -+ assert(f.f() == 11); -+ } -+ -+ // Case 3, works -+ { -+ auto hello = std::string("Hello world"); -+ auto f = Factory(^() { -+ return hello.size(); -+ }); -+ assert(f.f() == 11); -+ } -+ -+ // Case 4, used to crash under ARC -+ { -+ auto f = Factory2(); -+ assert(f.f() == 11); -+ } -+ -+ return 0; -+} -diff --git a/src/llvm-project/libcxx/test/std/containers/sequences/vector.bool/ctor_exceptions.pass.cpp b/src/llvm-project/libcxx/test/std/containers/sequences/vector.bool/ctor_exceptions.pass.cpp -new file mode 100644 -index 000000000..592d733de ---- /dev/null -+++ b/src/llvm-project/libcxx/test/std/containers/sequences/vector.bool/ctor_exceptions.pass.cpp -@@ -0,0 +1,141 @@ -+//===----------------------------------------------------------------------===// -+// -+// 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 -+// -+//===----------------------------------------------------------------------===// -+ -+// UNSUPPORTED: no-exceptions -+ -+// (bug report: https://llvm.org/PR58392) -+// Check that vector constructors don't leak memory when an operation inside the constructor throws an exception -+ -+#include -+#include -+ -+#include "count_new.h" -+#include "test_iterators.h" -+ -+template -+struct Allocator { -+ using value_type = T; -+ using is_always_equal = std::false_type; -+ -+ template -+ Allocator(const Allocator&) {} -+ -+ Allocator(bool should_throw = true) { -+ if (should_throw) -+ throw 0; -+ } -+ -+ T* allocate(int n) { return std::allocator().allocate(n); } -+ void deallocate(T* ptr, int n) { std::allocator().deallocate(ptr, n); } -+ -+ friend bool operator==(const Allocator&, const Allocator&) { return false; } -+}; -+ -+template -+struct Iterator { -+ using iterator_category = IterCat; -+ using difference_type = std::ptrdiff_t; -+ using value_type = bool; -+ using reference = bool&; -+ using pointer = bool*; -+ -+ int i_; -+ bool b_ = true; -+ Iterator(int i = 0) : i_(i) {} -+ bool& operator*() { -+ if (i_ == 1) -+ throw 1; -+ return b_; -+ } -+ -+ friend bool operator==(const Iterator& lhs, const Iterator& rhs) { return lhs.i_ == rhs.i_; } -+ -+ friend bool operator!=(const Iterator& lhs, const Iterator& rhs) { return lhs.i_ != rhs.i_; } -+ -+ Iterator& operator++() { -+ ++i_; -+ return *this; -+ } -+ -+ Iterator operator++(int) { -+ auto tmp = *this; -+ ++i_; -+ return tmp; -+ } -+}; -+ -+void check_new_delete_called() { -+ assert(globalMemCounter.new_called == globalMemCounter.delete_called); -+ assert(globalMemCounter.new_array_called == globalMemCounter.delete_array_called); -+ assert(globalMemCounter.aligned_new_called == globalMemCounter.aligned_delete_called); -+ assert(globalMemCounter.aligned_new_array_called == globalMemCounter.aligned_delete_array_called); -+} -+ -+int main(int, char**) { -+ using AllocVec = std::vector >; -+ -+#if TEST_STD_VER >= 14 -+ try { // Throw in vector(size_type, const allocator_type&) from allocator -+ Allocator alloc(false); -+ AllocVec get_alloc(0, alloc); -+ } catch (int) { -+ } -+ check_new_delete_called(); -+#endif // TEST_STD_VER >= 14 -+ -+ try { // Throw in vector(InputIterator, InputIterator) from input iterator -+ std::vector vec((Iterator()), Iterator(2)); -+ } catch (int) { -+ } -+ check_new_delete_called(); -+ -+ try { // Throw in vector(InputIterator, InputIterator) from forward iterator -+ std::vector vec((Iterator()), Iterator(2)); -+ } catch (int) { -+ } -+ check_new_delete_called(); -+ -+ try { // Throw in vector(InputIterator, InputIterator) from allocator -+ int a[] = {1, 2}; -+ AllocVec vec(cpp17_input_iterator(a), cpp17_input_iterator(a + 2)); -+ } catch (int) { -+ } -+ check_new_delete_called(); -+ -+ try { // Throw in vector(InputIterator, InputIterator, const allocator_type&) from input iterator -+ std::allocator alloc; -+ std::vector vec(Iterator(), Iterator(2), alloc); -+ } catch (int) { -+ } -+ check_new_delete_called(); -+ -+ try { // Throw in vector(InputIterator, InputIterator, const allocator_type&) from forward iterator -+ std::allocator alloc; -+ std::vector vec(Iterator(), Iterator(2), alloc); -+ } catch (int) { -+ } -+ check_new_delete_called(); -+ -+ try { // Throw in vector(InputIterator, InputIterator, const allocator_type&) from allocator -+ bool a[] = {true, false}; -+ Allocator alloc(false); -+ AllocVec vec(cpp17_input_iterator(a), cpp17_input_iterator(a + 2), alloc); -+ } catch (int) { -+ } -+ check_new_delete_called(); -+ -+ try { // Throw in vector(InputIterator, InputIterator, const allocator_type&) from allocator -+ bool a[] = {true, false}; -+ Allocator alloc(false); -+ AllocVec vec(forward_iterator(a), forward_iterator(a + 2), alloc); -+ } catch (int) { -+ } -+ check_new_delete_called(); -+ -+ return 0; -+} -diff --git a/src/llvm-project/libcxx/test/std/containers/sequences/vector/vector.cons/exceptions.pass.cpp b/src/llvm-project/libcxx/test/std/containers/sequences/vector/vector.cons/exceptions.pass.cpp -new file mode 100644 -index 000000000..26ad7b4fd ---- /dev/null -+++ b/src/llvm-project/libcxx/test/std/containers/sequences/vector/vector.cons/exceptions.pass.cpp -@@ -0,0 +1,229 @@ -+//===----------------------------------------------------------------------===// -+// -+// 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 -+// -+//===----------------------------------------------------------------------===// -+ -+// UNSUPPORTED: no-exceptions -+ -+// (bug report: https://llvm.org/PR58392) -+// Check that vector constructors don't leak memory when an operation inside the constructor throws an exception -+ -+#include -+#include -+ -+#include "count_new.h" -+#include "test_iterators.h" -+ -+template -+struct Allocator { -+ using value_type = T; -+ using is_always_equal = std::false_type; -+ -+ Allocator(bool should_throw = true) { -+ if (should_throw) -+ throw 0; -+ } -+ -+ T* allocate(int n) { return std::allocator().allocate(n); } -+ void deallocate(T* ptr, int n) { std::allocator().deallocate(ptr, n); } -+ -+ friend bool operator==(const Allocator&, const Allocator&) { return false; } -+}; -+ -+struct ThrowingT { -+ int* throw_after_n_ = nullptr; -+ ThrowingT() { throw 0; } -+ -+ ThrowingT(int& throw_after_n) : throw_after_n_(&throw_after_n) { -+ if (throw_after_n == 0) -+ throw 0; -+ --throw_after_n; -+ } -+ -+ ThrowingT(const ThrowingT&) { -+ if (throw_after_n_ == nullptr || *throw_after_n_ == 0) -+ throw 1; -+ --*throw_after_n_; -+ } -+ -+ ThrowingT& operator=(const ThrowingT&) { -+ if (throw_after_n_ == nullptr || *throw_after_n_ == 0) -+ throw 1; -+ --*throw_after_n_; -+ return *this; -+ } -+}; -+ -+template -+struct Iterator { -+ using iterator_category = IterCat; -+ using difference_type = std::ptrdiff_t; -+ using value_type = int; -+ using reference = int&; -+ using pointer = int*; -+ -+ int i_; -+ Iterator(int i = 0) : i_(i) {} -+ int& operator*() { -+ if (i_ == 1) -+ throw 1; -+ return i_; -+ } -+ -+ friend bool operator==(const Iterator& lhs, const Iterator& rhs) { return lhs.i_ == rhs.i_; } -+ -+ friend bool operator!=(const Iterator& lhs, const Iterator& rhs) { return lhs.i_ != rhs.i_; } -+ -+ Iterator& operator++() { -+ ++i_; -+ return *this; -+ } -+ -+ Iterator operator++(int) { -+ auto tmp = *this; -+ ++i_; -+ return tmp; -+ } -+}; -+ -+void check_new_delete_called() { -+ assert(globalMemCounter.new_called == globalMemCounter.delete_called); -+ assert(globalMemCounter.new_array_called == globalMemCounter.delete_array_called); -+ assert(globalMemCounter.aligned_new_called == globalMemCounter.aligned_delete_called); -+ assert(globalMemCounter.aligned_new_array_called == globalMemCounter.aligned_delete_array_called); -+} -+ -+int main(int, char**) { -+ using AllocVec = std::vector >; -+ try { // vector() -+ AllocVec vec; -+ } catch (int) { -+ } -+ check_new_delete_called(); -+ -+ try { // Throw in vector(size_type) from type -+ std::vector get_alloc(1); -+ } catch (int) { -+ } -+ check_new_delete_called(); -+ -+#if TEST_STD_VER >= 14 -+ try { // Throw in vector(size_type, value_type) from type -+ int throw_after = 1; -+ ThrowingT v(throw_after); -+ std::vector get_alloc(1, v); -+ } catch (int) { -+ } -+ check_new_delete_called(); -+ -+ try { // Throw in vector(size_type, const allocator_type&) from allocator -+ Allocator alloc(false); -+ AllocVec get_alloc(0, alloc); -+ } catch (int) { -+ } -+ check_new_delete_called(); -+ -+ try { // Throw in vector(size_type, const allocator_type&) from the type -+ std::vector vec(1, std::allocator()); -+ } catch (int) { -+ } -+ check_new_delete_called(); -+#endif // TEST_STD_VER >= 14 -+ -+ try { // Throw in vector(InputIterator, InputIterator) from input iterator -+ std::vector vec((Iterator()), Iterator(2)); -+ } catch (int) { -+ } -+ check_new_delete_called(); -+ -+ try { // Throw in vector(InputIterator, InputIterator) from forward iterator -+ std::vector vec((Iterator()), Iterator(2)); -+ } catch (int) { -+ } -+ check_new_delete_called(); -+ -+ try { // Throw in vector(InputIterator, InputIterator) from allocator -+ int a[] = {1, 2}; -+ AllocVec vec(cpp17_input_iterator(a), cpp17_input_iterator(a + 2)); -+ } catch (int) { -+ } -+ check_new_delete_called(); -+ -+ try { // Throw in vector(InputIterator, InputIterator, const allocator_type&) from input iterator -+ std::allocator alloc; -+ std::vector vec(Iterator(), Iterator(2), alloc); -+ } catch (int) { -+ } -+ check_new_delete_called(); -+ -+ try { // Throw in vector(InputIterator, InputIterator, const allocator_type&) from forward iterator -+ std::allocator alloc; -+ std::vector vec(Iterator(), Iterator(2), alloc); -+ } catch (int) { -+ } -+ check_new_delete_called(); -+ -+ try { // Throw in vector(InputIterator, InputIterator, const allocator_type&) from allocator -+ int a[] = {1, 2}; -+ Allocator alloc(false); -+ AllocVec vec(cpp17_input_iterator(a), cpp17_input_iterator(a + 2), alloc); -+ } catch (int) { -+ } -+ check_new_delete_called(); -+ -+ try { // Throw in vector(InputIterator, InputIterator, const allocator_type&) from allocator -+ int a[] = {1, 2}; -+ Allocator alloc(false); -+ AllocVec vec(forward_iterator(a), forward_iterator(a + 2), alloc); -+ } catch (int) { -+ } -+ check_new_delete_called(); -+ -+ try { // Throw in vector(const vector&) from type -+ std::vector vec; -+ int throw_after = 0; -+ vec.emplace_back(throw_after); -+ auto vec2 = vec; -+ } catch (int) { -+ } -+ check_new_delete_called(); -+ -+ try { // Throw in vector(const vector&, const allocator_type&) from type -+ std::vector vec; -+ int throw_after = 1; -+ vec.emplace_back(throw_after); -+ std::vector vec2(vec, std::allocator()); -+ } catch (int) { -+ } -+ check_new_delete_called(); -+ -+ try { // Throw in vector(vector&&, const allocator_type&) from type -+ std::vector > vec(Allocator(false)); -+ int throw_after = 1; -+ vec.emplace_back(throw_after); -+ std::vector > vec2(std::move(vec), Allocator(false)); -+ } catch (int) { -+ } -+ check_new_delete_called(); -+ -+#if TEST_STD_VER >= 11 -+ try { // Throw in vector(initializer_list) from type -+ int throw_after = 1; -+ std::vector vec({ThrowingT(throw_after)}); -+ } catch (int) { -+ } -+ check_new_delete_called(); -+ -+ try { // Throw in vector(initializer_list, const allocator_type&) constructor from type -+ int throw_after = 1; -+ std::vector vec({ThrowingT(throw_after)}, std::allocator()); -+ } catch (int) { -+ } -+ check_new_delete_called(); -+#endif // TEST_STD_VER >= 11 -+ -+ return 0; -+} -diff --git a/src/llvm-project/libunwind/CMakeLists.txt b/src/llvm-project/libunwind/CMakeLists.txt -index acf3d6dd4..5a06805f0 100644 ---- a/src/llvm-project/libunwind/CMakeLists.txt -+++ b/src/llvm-project/libunwind/CMakeLists.txt -@@ -264,7 +264,7 @@ if (LIBUNWIND_ENABLE_ASSERTIONS) - - # On Release builds cmake automatically defines NDEBUG, so we - # explicitly undefine it: -- if ((NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG") AND (NOT RUST_SGX)) -+ if (NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG") - add_compile_flags(-UNDEBUG) - endif() - else() -diff --git a/src/llvm-project/libunwind/README_RUST_SGX.md b/src/llvm-project/libunwind/README_RUST_SGX.md -deleted file mode 100644 -index c5d6eb477..000000000 ---- a/src/llvm-project/libunwind/README_RUST_SGX.md -+++ /dev/null -@@ -1,22 +0,0 @@ --# Libunwind customizations for linking with x86_64-fortanix-unknown-sgx Rust target. -- --## Description --### Initial Fork --Initial Fork has been made from 5.0 release of llvm (commit: 6a075b6de4) --### Detailed Description --#### Header files that we do not include for this target --1. pthread.h --#### Library that we do not link to for this target. --1. pthread (Locks used by libunwind is provided by rust stdlib for this target) -- --## Building unwind for rust-sgx target --### Generate Make files: --* `cd where you want to build libunwind` --* `mkdir build` --* `cd build` --* `cmake -DCMAKE_BUILD_TYPE="RELEASE" -DRUST_SGX=1 -G "Unix Makefiles" -DLLVM_ENABLE_WARNINGS=1 -DLIBUNWIND_ENABLE_PEDANTIC=0 -DLLVM_PATH= ` --* `"DEBUG"` could be used instead of `"RELEASE"` to enable debug logs of libunwind. -- --### Build: --* `make unwind_static` --* `build/lib/` will have the built library. -diff --git a/src/llvm-project/libunwind/cmake/config-ix.cmake b/src/llvm-project/libunwind/cmake/config-ix.cmake -index c9b65b3ce..1b027cf37 100644 ---- a/src/llvm-project/libunwind/cmake/config-ix.cmake -+++ b/src/llvm-project/libunwind/cmake/config-ix.cmake -@@ -85,7 +85,7 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") - set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror=unknown-pragmas") - check_c_source_compiles(" - #pragma comment(lib, \"c\") --int main() { return 0; } -+int main(void) { return 0; } - " C_SUPPORTS_COMMENT_LIB_PRAGMA) - cmake_pop_check_state() - endif() -diff --git a/src/llvm-project/libunwind/docs/BuildingLibunwind.rst b/src/llvm-project/libunwind/docs/BuildingLibunwind.rst -index abd432c93..79166b476 100644 ---- a/src/llvm-project/libunwind/docs/BuildingLibunwind.rst -+++ b/src/llvm-project/libunwind/docs/BuildingLibunwind.rst -@@ -148,8 +148,3 @@ libunwind specific options - - Path where built libunwind libraries should be installed. If a relative path, - relative to ``CMAKE_INSTALL_PREFIX``. -- --.. option:: LIBUNWIND_ENABLE_RUST_SGX:BOOL -- -- **Default**: ``OFF`` -- -diff --git a/src/llvm-project/libunwind/src/AddressSpace.hpp b/src/llvm-project/libunwind/src/AddressSpace.hpp -index e9a1f3f7f..36c9f5a9e 100644 ---- a/src/llvm-project/libunwind/src/AddressSpace.hpp -+++ b/src/llvm-project/libunwind/src/AddressSpace.hpp -@@ -90,7 +90,6 @@ char *getFuncNameFromTBTable(uintptr_t pc, uint16_t &NameLen, - // __eh_frame_hdr_start = SIZEOF(.eh_frame_hdr) > 0 ? ADDR(.eh_frame_hdr) : 0; - // __eh_frame_hdr_end = SIZEOF(.eh_frame_hdr) > 0 ? . : 0; - --#if !defined(RUST_SGX) - extern char __eh_frame_start; - extern char __eh_frame_end; - -@@ -99,15 +98,6 @@ extern char __eh_frame_hdr_start; - extern char __eh_frame_hdr_end; - #endif - --#elif defined(RUST_SGX) --extern "C" char IMAGE_BASE; --extern "C" uint64_t EH_FRM_HDR_OFFSET; --extern "C" uint64_t EH_FRM_HDR_LEN; --extern "C" uint64_t EH_FRM_OFFSET; --extern "C" uint64_t EH_FRM_LEN; --#endif -- -- - #elif defined(_LIBUNWIND_ARM_EHABI) && defined(_LIBUNWIND_IS_BAREMETAL) - - // When statically linked on bare-metal, the symbols for the EH table are looked -@@ -515,10 +505,6 @@ static int findUnwindSectionsByPhdr(struct dl_phdr_info *pinfo, - #endif // defined(_LIBUNWIND_USE_DL_ITERATE_PHDR) - - --#if defined(RUST_SGX) --extern "C" char IMAGE_BASE; --#endif -- - inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr, - UnwindInfoSections &info) { - #ifdef __APPLE__ -@@ -536,8 +522,6 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr, - #elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_LIBUNWIND_IS_BAREMETAL) - info.dso_base = 0; - // Bare metal is statically linked, so no need to ask the dynamic loader -- --#if !defined(RUST_SGX) - info.dwarf_section_length = (size_t)(&__eh_frame_end - &__eh_frame_start); - info.dwarf_section = (uintptr_t)(&__eh_frame_start); - _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: section %p length %p", -@@ -548,17 +532,6 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr, - _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: index section %p length %p", - (void *)info.dwarf_index_section, (void *)info.dwarf_index_section_length); - #endif -- --#elif defined(RUST_SGX) -- info.dwarf_section = (uintptr_t)EH_FRM_OFFSET + (uintptr_t)(&IMAGE_BASE); -- info.dwarf_section_length = (uintptr_t)EH_FRM_LEN; --#if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) -- info.dwarf_index_section = (uintptr_t)EH_FRM_HDR_OFFSET + (uintptr_t)(&IMAGE_BASE); -- info.dwarf_index_section_length = (uintptr_t)EH_FRM_HDR_LEN; --#endif -- --#endif -- - if (info.dwarf_section_length) - return true; - #elif defined(_LIBUNWIND_ARM_EHABI) && defined(_LIBUNWIND_IS_BAREMETAL) -diff --git a/src/llvm-project/libunwind/src/CMakeLists.txt b/src/llvm-project/libunwind/src/CMakeLists.txt -index 76d4094dc..61df2737b 100644 ---- a/src/llvm-project/libunwind/src/CMakeLists.txt -+++ b/src/llvm-project/libunwind/src/CMakeLists.txt -@@ -1,9 +1,5 @@ - # Get sources - --enable_language(C CXX ASM) -- --set(CMAKE_POSITION_INDEPENDENT_CODE ON) -- - set(LIBUNWIND_CXX_SOURCES - libunwind.cpp - Unwind-EHABI.cpp -@@ -26,6 +22,9 @@ set(LIBUNWIND_C_SOURCES - UnwindLevel1-gcc-ext.c - Unwind-sjlj.c - ) -+set_source_files_properties(${LIBUNWIND_C_SOURCES} -+ PROPERTIES -+ COMPILE_FLAGS "-std=c99") - - set(LIBUNWIND_ASM_SOURCES - UnwindRegistersRestore.S -@@ -74,44 +73,6 @@ if (MSVC_IDE) - source_group("Header Files" FILES ${LIBUNWIND_HEADERS}) - endif() - --if (RUST_SGX) -- # Compile Flags -- add_definitions(-DRUST_SGX) -- add_definitions(-D__NO_STRING_INLINES) -- add_definitions(-D__NO_MATH_INLINES) -- add_definitions(-D_LIBUNWIND_IS_BAREMETAL) -- # Can't use add_definitions because CMake will reorder these arguments -- list(APPEND LIBUNWIND_COMPILE_FLAGS -U_FORTIFY_SOURCE) -- list(APPEND LIBUNWIND_COMPILE_FLAGS -D_FORTIFY_SOURCE=0) -- -- list(APPEND LIBUNWIND_COMPILE_FLAGS -fno-stack-protector) -- list(APPEND LIBUNWIND_COMPILE_FLAGS -ffreestanding) -- list(APPEND LIBUNWIND_COMPILE_FLAGS -fexceptions) -- # Avoid too new relocation types being emitted, which might prevent linking -- # on older platforms. -- # -- # See https://github.com/rust-lang/rust/issues/34978 -- if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") -- list(APPEND LIBUNWIND_COMPILE_FLAGS -Wa,-mrelax-relocations=no) -- else() -- list(APPEND LIBUNWIND_COMPILE_FLAGS) -- endif() -- -- # Sources -- list(APPEND LIBUNWIND_HEADERS UnwindRustSgx.h) -- list(APPEND LIBUNWIND_C_SOURCES UnwindRustSgx.c) --endif() -- -- --set_source_files_properties(${LIBUNWIND_C_SOURCES} -- PROPERTIES -- COMPILE_FLAGS "-std=c99") -- --# See add_asm_sources() in compiler-rt for explanation of this workaround. --if((APPLE AND CMAKE_VERSION VERSION_LESS 3.19) OR (MINGW AND CMAKE_VERSION VERSION_LESS 3.17)) -- set_source_files_properties(${LIBUNWIND_ASM_SOURCES} PROPERTIES LANGUAGE C) --endif() -- - set(LIBUNWIND_SOURCES - ${LIBUNWIND_CXX_SOURCES} - ${LIBUNWIND_C_SOURCES} -@@ -126,7 +87,7 @@ else() - add_library_flags_if(LIBUNWIND_HAS_GCC_LIB gcc) - endif() - add_library_flags_if(LIBUNWIND_HAS_DL_LIB dl) --if (LIBUNWIND_ENABLE_THREADS AND (NOT RUST_SGX)) -+if (LIBUNWIND_ENABLE_THREADS) - add_library_flags_if(LIBUNWIND_HAS_PTHREAD_LIB pthread) - add_compile_flags_if(LIBUNWIND_WEAK_PTHREAD_LIB -DLIBUNWIND_USE_WEAK_PTHREAD=1) - endif() -diff --git a/src/llvm-project/libunwind/src/RWMutex.hpp b/src/llvm-project/libunwind/src/RWMutex.hpp -index 65bd849aa..344d35641 100644 ---- a/src/llvm-project/libunwind/src/RWMutex.hpp -+++ b/src/llvm-project/libunwind/src/RWMutex.hpp -@@ -15,7 +15,7 @@ - - #if defined(_WIN32) - #include --#elif !defined(_LIBUNWIND_HAS_NO_THREADS) && !defined(RUST_SGX) -+#elif !defined(_LIBUNWIND_HAS_NO_THREADS) - #include - #if defined(__ELF__) && defined(_LIBUNWIND_LINK_PTHREAD_LIB) - #pragma comment(lib, "pthread") -diff --git a/src/llvm-project/libunwind/src/UnwindRustSgx.c b/src/llvm-project/libunwind/src/UnwindRustSgx.c -deleted file mode 100644 -index 9be7c1b54..000000000 ---- a/src/llvm-project/libunwind/src/UnwindRustSgx.c -+++ /dev/null -@@ -1,125 +0,0 @@ --//===--------------------- UnwindRustSgx.c ----------------------------------===// --// --//// The LLVM Compiler Infrastructure --//// --//// This file is dual licensed under the MIT and the University of Illinois Open --//// Source Licenses. See LICENSE.TXT for details. --//// --//// --////===----------------------------------------------------------------------===// -- --#define _GNU_SOURCE --#include -- --#include --#include --#include --#include --#include "UnwindRustSgx.h" -- --#define max_log 256 -- --__attribute__((weak)) struct _IO_FILE *stderr = (struct _IO_FILE *)-1; -- --static int vwrite_err(const char *format, va_list ap) --{ -- int len = 0; --#ifndef NDEBUG -- char s[max_log]; -- s[0]='\0'; -- len = vsnprintf(s, max_log, format, ap); -- __rust_print_err((uint8_t *)s, len); --#endif -- return len; --} -- --static int write_err(const char *format, ...) --{ -- int ret; -- va_list args; -- va_start(args, format); -- ret = vwrite_err(format, args); -- va_end(args); -- -- -- return ret; --} -- --__attribute__((weak)) int fprintf (FILE *__restrict __stream, -- const char *__restrict __format, ...) --{ -- -- int ret; -- if (__stream != stderr) { -- write_err("Rust SGX Unwind supports only writing to stderr\n"); -- return -1; -- } else { -- va_list args; -- ret = 0; -- va_start(args, __format); -- ret += vwrite_err(__format, args); -- va_end(args); -- } -- -- return ret; --} -- --__attribute__((weak)) int fflush (FILE *__stream) --{ -- // We do not need to do anything here. -- return 0; --} -- --__attribute__((weak)) void __assert_fail(const char * assertion, -- const char * file, -- unsigned int line, -- const char * function) --{ -- write_err("%s:%d %s %s\n", file, line, function, assertion); -- abort(); --} -- --// We do not report stack over flow detected. --// Calling write_err uses more stack due to the way we have implemented it. --// With possible enabling of stack probes, we should not --// get into __stack_chk_fail() at all. --__attribute__((weak)) void __stack_chk_fail() { -- abort(); --} -- --/* -- * Below are defined for all executibles compiled for -- * x86_64-fortanix-unknown-sgx rust target. -- * Ref: rust/src/libstd/sys/sgx/abi/entry.S -- */ -- --struct libwu_rs_alloc_meta { -- size_t alloc_size; -- // Should we put a signatre guard before ptr for oob access? -- unsigned char ptr[0]; --}; -- --#define META_FROM_PTR(__PTR) (struct libwu_rs_alloc_meta *) \ -- ((unsigned char *)__PTR - offsetof(struct libwu_rs_alloc_meta, ptr)) -- --void *libuw_malloc(size_t size) --{ -- struct libwu_rs_alloc_meta *meta; -- size_t alloc_size = size + sizeof(struct libwu_rs_alloc_meta); -- meta = (void *)__rust_c_alloc(alloc_size, sizeof(size_t)); -- if (!meta) { -- return NULL; -- } -- meta->alloc_size = alloc_size; -- return (void *)meta->ptr; --} -- --void libuw_free(void *p) --{ -- struct libwu_rs_alloc_meta *meta; -- if (!p) { -- return; -- } -- meta = META_FROM_PTR(p); -- __rust_c_dealloc((unsigned char *)meta, meta->alloc_size, sizeof(size_t)); --} -diff --git a/src/llvm-project/libunwind/src/UnwindRustSgx.h b/src/llvm-project/libunwind/src/UnwindRustSgx.h -deleted file mode 100644 -index 3c54b1676..000000000 ---- a/src/llvm-project/libunwind/src/UnwindRustSgx.h -+++ /dev/null -@@ -1,94 +0,0 @@ --//===--------------------- UnwindRustSgx.h ----------------------------------===// --// --//// The LLVM Compiler Infrastructure --//// --//// This file is dual licensed under the MIT and the University of Illinois Open --//// Source Licenses. See LICENSE.TXT for details. --//// --//// --////===----------------------------------------------------------------------===// -- --#if !defined(UNWIND_RUST_SGX_H) --#define UNWIND_RUST_SGX_H -- --#ifdef RUST_SGX -- --#undef _GNU_SOURCE --#define _GNU_SOURCE --#include --#include --#include --#include -- --// We have to use RWLock from rust repo, it is defined in: --// src/libstd/sys/sgx/rwlock.rs. --// rwlock.rs has compile time check to ensure sizeof(RWLock) = 144. --typedef struct { -- unsigned char opaque[144]; --} RWLock; -- --// The below is obtained by printing initialized bytes --// for RWLock in rust repo: src/libstd/sys/sgx/rwlock.rs. --#define RWLOCK_INIT { { \ -- /* 0x00 */ 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ -- /* 0x10 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ -- /* 0x20 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ -- /* 0x30 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ -- /* 0x40 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ -- /* 0x50 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ -- /* 0x60 */ 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ -- /* 0x70 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ -- /* 0x80 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ -- } } -- --// These are the functions exposed by SGX-Rust. --// The rust changes are available at: --#ifdef __cplusplus --extern "C" { --#endif -- int __rust_rwlock_rdlock(RWLock *rwlock); -- int __rust_rwlock_wrlock(RWLock *rwlock); -- int __rust_rwlock_unlock(RWLock *rwlock); -- unsigned char *__rust_c_alloc(size_t, size_t); -- void __rust_c_dealloc(unsigned char *, size_t, size_t); -- __attribute__((noreturn)) void __rust_abort(void); -- unsigned char *__rust_encl_address(size_t); -- --#ifndef NDEBUG -- void __rust_print_err(uint8_t *m, int s); --#endif -- --#ifdef __cplusplus --} --#endif -- --#define abort __rust_abort -- --#undef pthread_rwlock_t --#undef pthread_rwlock_rdlock --#undef pthread_rwlock_wrlock --#undef pthread_rwlock_unlock --#undef PTHREAD_RWLOCK_INITIALIZER -- --#define pthread_rwlock_t RWLock --#define pthread_rwlock_rdlock __rust_rwlock_rdlock --#define pthread_rwlock_wrlock __rust_rwlock_wrlock --#define pthread_rwlock_unlock __rust_rwlock_unlock --#define PTHREAD_RWLOCK_INITIALIZER RWLOCK_INIT -- --#define malloc libuw_malloc --#define free libuw_free -- --#ifdef __cplusplus --extern "C" { --#endif -- --void *libuw_malloc(size_t size); --void libuw_free(void *p); -- --#ifdef __cplusplus --} --#endif -- --#endif --#endif -diff --git a/src/llvm-project/libunwind/src/config.h b/src/llvm-project/libunwind/src/config.h -index 3f997ec3c..cc41b817a 100644 ---- a/src/llvm-project/libunwind/src/config.h -+++ b/src/llvm-project/libunwind/src/config.h -@@ -20,10 +20,6 @@ - - #include <__libunwind_config.h> - --#ifdef RUST_SGX --#include "UnwindRustSgx.h" --#endif -- - // Platform specific configuration defines. - #ifdef __APPLE__ - #if defined(FOR_DYLD) -diff --git a/src/llvm-project/lld/CMakeLists.txt b/src/llvm-project/lld/CMakeLists.txt -index 02b90ece9..dcc649629 100644 ---- a/src/llvm-project/lld/CMakeLists.txt -+++ b/src/llvm-project/lld/CMakeLists.txt -@@ -246,19 +246,6 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) - ) - endif() - --if (MSVC) -- FOREACH(flag -- CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO -- CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_DEBUG_INIT -- CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELWITHDEBINFO -- CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_DEBUG_INIT) -- if (MSVC) -- STRING(REPLACE "/MD" "/MT" "${flag}" "${${flag}}") -- SET("${flag}" "${${flag}}") -- endif (MSVC) -- ENDFOREACH() --endif() -- - add_subdirectory(Common) - add_subdirectory(tools/lld) - -diff --git a/src/llvm-project/lld/COFF/CMakeLists.txt b/src/llvm-project/lld/COFF/CMakeLists.txt -index d289bd591..55aec2685 100644 ---- a/src/llvm-project/lld/COFF/CMakeLists.txt -+++ b/src/llvm-project/lld/COFF/CMakeLists.txt -@@ -44,6 +44,7 @@ add_lld_library(lldCOFF - LINK_LIBS - lldCommon - ${LLVM_PTHREAD_LIB} -+ ${LLVM_ATOMIC_LIB} - - DEPENDS - COFFOptionsTableGen -diff --git a/src/llvm-project/lld/Common/CMakeLists.txt b/src/llvm-project/lld/Common/CMakeLists.txt -index 1ae7da1f5..9c23ed395 100644 ---- a/src/llvm-project/lld/Common/CMakeLists.txt -+++ b/src/llvm-project/lld/Common/CMakeLists.txt -@@ -1,9 +1,3 @@ --set(LLD_SYSTEM_LIBS ${LLVM_PTHREAD_LIB}) -- --if(NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB) -- list(APPEND LLD_SYSTEM_LIBS atomic) --endif() -- - find_first_existing_vc_file("${LLVM_MAIN_SRC_DIR}" llvm_vc) - find_first_existing_vc_file("${LLD_SOURCE_DIR}" lld_vc) - -@@ -54,7 +48,8 @@ add_lld_library(lldCommon - Target - - LINK_LIBS -- ${LLD_SYSTEM_LIBS} -+ ${LLVM_PTHREAD_LIB} -+ ${LLVM_ATOMIC_LIB} - - DEPENDS - intrinsics_gen -diff --git a/src/llvm-project/lld/ELF/Arch/RISCV.cpp b/src/llvm-project/lld/ELF/Arch/RISCV.cpp -index 34f8f1ae0..56a516f9c 100644 ---- a/src/llvm-project/lld/ELF/Arch/RISCV.cpp -+++ b/src/llvm-project/lld/ELF/Arch/RISCV.cpp -@@ -618,9 +618,9 @@ static bool relax(InputSection &sec) { - valueDelta[sa[0].d] = delta; - delta = aux.relocDeltas[it.index()]; - } -- for (const SymbolAnchor &saElem : sa) -- if (!saElem.end) -- valueDelta[saElem.d] = delta; -+ for (const SymbolAnchor &sa : sa) -+ if (!sa.end) -+ valueDelta[sa.d] = delta; - sa = makeArrayRef(aux.anchors); - delta = 0; - -diff --git a/src/llvm-project/lld/ELF/Driver.cpp b/src/llvm-project/lld/ELF/Driver.cpp -index 296fb4220..58d863776 100644 ---- a/src/llvm-project/lld/ELF/Driver.cpp -+++ b/src/llvm-project/lld/ELF/Driver.cpp -@@ -1330,12 +1330,15 @@ static void readConfigs(opt::InputArgList &args) { - parseClangOption(std::string("-") + arg->getValue(), arg->getSpelling()); - - // GCC collect2 passes -plugin-opt=path/to/lto-wrapper with an absolute or -- // relative path. Just ignore. If not ended with "lto-wrapper", consider it an -+ // relative path. Just ignore. If not ended with "lto-wrapper" (or -+ // "lto-wrapper.exe" for GCC cross-compiled for Windows), consider it an - // unsupported LLVMgold.so option and error. -- for (opt::Arg *arg : args.filtered(OPT_plugin_opt_eq)) -- if (!StringRef(arg->getValue()).endswith("lto-wrapper")) -+ for (opt::Arg *arg : args.filtered(OPT_plugin_opt_eq)) { -+ StringRef v(arg->getValue()); -+ if (!v.endswith("lto-wrapper") && !v.endswith("lto-wrapper.exe")) - error(arg->getSpelling() + ": unknown plugin option '" + arg->getValue() + - "'"); -+ } - - config->passPlugins = args::getStrings(args, OPT_load_pass_plugins); - -diff --git a/src/llvm-project/lld/ELF/InputFiles.cpp b/src/llvm-project/lld/ELF/InputFiles.cpp -index d8bf9ebf7..473809b05 100644 ---- a/src/llvm-project/lld/ELF/InputFiles.cpp -+++ b/src/llvm-project/lld/ELF/InputFiles.cpp -@@ -185,14 +185,14 @@ template static void doParseFile(InputFile *file) { - - // .so file - if (auto *f = dyn_cast(file)) { -- f->template parse(); -+ f->parse(); - return; - } - - // LLVM bitcode file - if (auto *f = dyn_cast(file)) { - ctx->bitcodeFiles.push_back(f); -- f->template parse(); -+ f->parse(); - return; - } - -@@ -1157,7 +1157,7 @@ template void ObjFile::postParse() { - continue; - } - -- if (binding == STB_WEAK) -+ if (sym.binding == STB_WEAK || binding == STB_WEAK) - continue; - std::lock_guard lock(mu); - ctx->duplicates.push_back({&sym, this, sec, eSym.st_value}); -diff --git a/src/llvm-project/lld/ELF/InputSection.cpp b/src/llvm-project/lld/ELF/InputSection.cpp -index b71fef583..8fe36eca6 100644 ---- a/src/llvm-project/lld/ELF/InputSection.cpp -+++ b/src/llvm-project/lld/ELF/InputSection.cpp -@@ -130,7 +130,7 @@ template RelsOrRelas InputSectionBase::relsOrRelas() const { - return {}; - RelsOrRelas ret; - typename ELFT::Shdr shdr = -- cast(file)->template getELFShdrs()[relSecIdx]; -+ cast(file)->getELFShdrs()[relSecIdx]; - if (shdr.sh_type == SHT_REL) { - ret.rels = makeArrayRef(reinterpret_cast( - file->mb.getBufferStart() + shdr.sh_offset), -@@ -413,7 +413,7 @@ void InputSection::copyRelocations(uint8_t *buf, ArrayRef rels) { - // individual "gp" values used by each input object file. - // As a workaround we add the "gp" value to the relocation - // addend and save it back to the file. -- addend += sec->template getFile()->mipsGp0; -+ addend += sec->getFile()->mipsGp0; - } - - if (RelTy::IsRela) -@@ -963,9 +963,9 @@ void InputSectionBase::relocate(uint8_t *buf, uint8_t *bufEnd) { - // locations with tombstone values. - const RelsOrRelas rels = sec->template relsOrRelas(); - if (rels.areRelocsRel()) -- sec->template relocateNonAlloc(buf, rels.rels); -+ sec->relocateNonAlloc(buf, rels.rels); - else -- sec->template relocateNonAlloc(buf, rels.relas); -+ sec->relocateNonAlloc(buf, rels.relas); - } - - void InputSectionBase::relocateAlloc(uint8_t *buf, uint8_t *bufEnd) { -@@ -1172,8 +1172,7 @@ void InputSectionBase::adjustSplitStackFunctionPrologues(uint8_t *buf, - // conservative. - if (Defined *d = dyn_cast(rel.sym)) - if (InputSection *isec = cast_or_null(d->section)) -- if (!isec || !isec->template getFile() || -- isec->template getFile()->splitStack) -+ if (!isec || !isec->getFile() || isec->getFile()->splitStack) - continue; - - if (enclosingPrologueAttempted(rel.offset, prologues)) -diff --git a/src/llvm-project/lld/ELF/SyntheticSections.cpp b/src/llvm-project/lld/ELF/SyntheticSections.cpp -index 9a21fdec6..b359c2e7b 100644 ---- a/src/llvm-project/lld/ELF/SyntheticSections.cpp -+++ b/src/llvm-project/lld/ELF/SyntheticSections.cpp -@@ -197,7 +197,7 @@ std::unique_ptr> MipsOptionsSection::create() { - auto *opt = reinterpret_cast(d.data()); - if (opt->kind == ODK_REGINFO) { - reginfo.ri_gprmask |= opt->getRegInfo().ri_gprmask; -- sec->template getFile()->mipsGp0 = opt->getRegInfo().ri_gp_value; -+ sec->getFile()->mipsGp0 = opt->getRegInfo().ri_gp_value; - break; - } - -@@ -249,7 +249,7 @@ std::unique_ptr> MipsReginfoSection::create() { - - auto *r = reinterpret_cast(sec->rawData.data()); - reginfo.ri_gprmask |= r->ri_gprmask; -- sec->template getFile()->mipsGp0 = r->ri_gp_value; -+ sec->getFile()->mipsGp0 = r->ri_gp_value; - }; - - return std::make_unique>(reginfo); -@@ -1662,8 +1662,8 @@ void RelocationBaseSection::partitionRels() { - if (!combreloc) - return; - const RelType relativeRel = target->relativeRel; -- numRelativeRelocs = llvm::partition( -- relocs, [=](const DynamicReloc &r) { return r.type == relativeRel; }) - -+ numRelativeRelocs = -+ llvm::partition(relocs, [=](auto &r) { return r.type == relativeRel; }) - - relocs.begin(); - } - -@@ -3360,7 +3360,7 @@ template void elf::splitSections() { - if (auto *s = dyn_cast(sec)) - s->splitIntoPieces(); - else if (auto *eh = dyn_cast(sec)) -- eh->template split(); -+ eh->split(); - } - }); - } -diff --git a/src/llvm-project/lld/MachO/UnwindInfoSection.cpp b/src/llvm-project/lld/MachO/UnwindInfoSection.cpp -index ca6cbdfbb..8f267251b 100644 ---- a/src/llvm-project/lld/MachO/UnwindInfoSection.cpp -+++ b/src/llvm-project/lld/MachO/UnwindInfoSection.cpp -@@ -158,7 +158,7 @@ class UnwindInfoSectionImpl final : public UnwindInfoSection { - public: - UnwindInfoSectionImpl() : cuOffsets(target->wordSize) {} - uint64_t getSize() const override { return unwindInfoSize; } -- void prepareRelocations() override; -+ void prepare() override; - void finalize() override; - void writeTo(uint8_t *buf) const override; - -@@ -166,6 +166,7 @@ private: - void prepareRelocations(ConcatInputSection *); - void relocateCompactUnwind(std::vector &); - void encodePersonalities(); -+ Symbol *canonicalizePersonality(Symbol *); - - uint64_t unwindInfoSize = 0; - std::vector symbolsVec; -@@ -218,14 +219,24 @@ void UnwindInfoSection::addSymbol(const Defined *d) { - } - } - --void UnwindInfoSectionImpl::prepareRelocations() { -+void UnwindInfoSectionImpl::prepare() { - // This iteration needs to be deterministic, since prepareRelocations may add - // entries to the GOT. Hence the use of a MapVector for - // UnwindInfoSection::symbols. - for (const Defined *d : make_second_range(symbols)) -- if (d->unwindEntry && -- d->unwindEntry->getName() == section_names::compactUnwind) -- prepareRelocations(d->unwindEntry); -+ if (d->unwindEntry) { -+ if (d->unwindEntry->getName() == section_names::compactUnwind) { -+ prepareRelocations(d->unwindEntry); -+ } else { -+ // We don't have to add entries to the GOT here because FDEs have -+ // explicit GOT relocations, so Writer::scanRelocations() will add those -+ // GOT entries. However, we still need to canonicalize the personality -+ // pointers (like prepareRelocations() does for CU entries) in order -+ // to avoid overflowing the 3-personality limit. -+ FDE &fde = cast(d->getFile())->fdes[d->unwindEntry]; -+ fde.personality = canonicalizePersonality(fde.personality); -+ } -+ } - } - - // Compact unwind relocations have different semantics, so we handle them in a -@@ -279,6 +290,7 @@ void UnwindInfoSectionImpl::prepareRelocations(ConcatInputSection *isec) { - continue; - } - -+ // Similar to canonicalizePersonality(), but we also register a GOT entry. - if (auto *defined = dyn_cast(s)) { - // Check if we have created a synthetic symbol at the same address. - Symbol *&personality = -@@ -291,6 +303,7 @@ void UnwindInfoSectionImpl::prepareRelocations(ConcatInputSection *isec) { - } - continue; - } -+ - assert(isa(s)); - in.got->addEntry(s); - continue; -@@ -320,6 +333,18 @@ void UnwindInfoSectionImpl::prepareRelocations(ConcatInputSection *isec) { - } - } - -+Symbol *UnwindInfoSectionImpl::canonicalizePersonality(Symbol *personality) { -+ if (auto *defined = dyn_cast_or_null(personality)) { -+ // Check if we have created a synthetic symbol at the same address. -+ Symbol *&synth = personalityTable[{defined->isec, defined->value}]; -+ if (synth == nullptr) -+ synth = defined; -+ else if (synth != defined) -+ return synth; -+ } -+ return personality; -+} -+ - // We need to apply the relocations to the pre-link compact unwind section - // before converting it to post-link form. There should only be absolute - // relocations here: since we are not emitting the pre-link CU section, there -diff --git a/src/llvm-project/lld/MachO/UnwindInfoSection.h b/src/llvm-project/lld/MachO/UnwindInfoSection.h -index c6b334731..f2bc3213a 100644 ---- a/src/llvm-project/lld/MachO/UnwindInfoSection.h -+++ b/src/llvm-project/lld/MachO/UnwindInfoSection.h -@@ -24,7 +24,7 @@ public: - // section entirely. - bool isNeeded() const override { return !allEntriesAreOmitted; } - void addSymbol(const Defined *); -- virtual void prepareRelocations() = 0; -+ virtual void prepare() = 0; - - protected: - UnwindInfoSection(); -diff --git a/src/llvm-project/lld/MachO/Writer.cpp b/src/llvm-project/lld/MachO/Writer.cpp -index 3c44a60f4..ce9672dd0 100644 ---- a/src/llvm-project/lld/MachO/Writer.cpp -+++ b/src/llvm-project/lld/MachO/Writer.cpp -@@ -675,7 +675,7 @@ void Writer::scanRelocations() { - } - } - -- in.unwindInfo->prepareRelocations(); -+ in.unwindInfo->prepare(); - } - - void Writer::scanSymbols() { -diff --git a/src/llvm-project/lld/test/ELF/comdat-binding2.s b/src/llvm-project/lld/test/ELF/comdat-binding2.s -new file mode 100644 -index 000000000..3ffd72528 ---- /dev/null -+++ b/src/llvm-project/lld/test/ELF/comdat-binding2.s -@@ -0,0 +1,42 @@ -+# REQUIRES: x86 -+## Test we don't report duplicate definition errors when mixing Clang STB_WEAK -+## and GCC STB_GNU_UNIQUE symbols. -+ -+# RUN: rm -rf %t && split-file %s %t && cd %t -+# RUN: llvm-mc -filetype=obj -triple=x86_64 weak.s -o weak.o -+# RUN: llvm-mc -filetype=obj -triple=x86_64 unique.s -o unique.o -+# RUN: ld.lld weak.o unique.o -o weak -+# RUN: llvm-readelf -s weak | FileCheck %s --check-prefix=WEAK -+# RUN: ld.lld unique.o weak.o -o unique -+# RUN: llvm-readelf -s unique | FileCheck %s --check-prefix=UNIQUE -+ -+# WEAK: OBJECT WEAK DEFAULT [[#]] _ZN1BIiE1aE -+# UNIQUE: OBJECT UNIQUE DEFAULT [[#]] _ZN1BIiE1aE -+ -+#--- weak.s -+## Clang -+ .type _ZN1BIiE1aE,@object -+ .section .bss._ZN1BIiE1aE,"aGwR",@nobits,_ZN1BIiE1aE,comdat -+ .weak _ZN1BIiE1aE -+_ZN1BIiE1aE: -+ .zero 4 -+ -+ .type _ZGVN1BIiE1aE,@object -+ .section .bss._ZGVN1BIiE1aE,"aGw",@nobits,_ZN1BIiE1aE,comdat -+ .weak _ZGVN1BIiE1aE -+_ZGVN1BIiE1aE: -+ .quad 0 -+ -+#--- unique.s -+## GCC -fgnu-unique. Note the different group signature for the second group. -+ .weak _ZN1BIiE1aE -+ .section .bss._ZN1BIiE1aE,"awG",@nobits,_ZN1BIiE1aE,comdat -+ .type _ZN1BIiE1aE, @gnu_unique_object -+_ZN1BIiE1aE: -+ .zero 4 -+ -+ .weak _ZGVN1BIiE1aE -+ .section .bss._ZGVN1BIiE1aE,"awG",@nobits,_ZGVN1BIiE1aE,comdat -+ .type _ZGVN1BIiE1aE, @gnu_unique_object -+_ZGVN1BIiE1aE: -+ .zero 8 -diff --git a/src/llvm-project/lld/test/ELF/lto-plugin-ignore.s b/src/llvm-project/lld/test/ELF/lto-plugin-ignore.s -index 2935bad14..dd39139b6 100644 ---- a/src/llvm-project/lld/test/ELF/lto-plugin-ignore.s -+++ b/src/llvm-project/lld/test/ELF/lto-plugin-ignore.s -@@ -8,7 +8,9 @@ - # RUN: ld.lld %t.o -o /dev/null \ - # RUN: -plugin path/to/liblto_plugin.so \ - # RUN: -plugin-opt=/path/to/lto-wrapper \ -+# RUN: -plugin-opt=/path/to/lto-wrapper.exe \ - # RUN: -plugin-opt=relative/path/to/lto-wrapper \ -+# RUN: -plugin-opt=relative/path/to/lto-wrapper.exe \ - # RUN: -plugin-opt=-fresolution=zed \ - # RUN: -plugin-opt=-pass-through=-lgcc \ - # RUN: -plugin-opt=-pass-through=-lgcc_eh \ -diff --git a/src/llvm-project/lld/test/MachO/eh-frame-personality-dedup.s b/src/llvm-project/lld/test/MachO/eh-frame-personality-dedup.s -new file mode 100644 -index 000000000..b14ddb234 ---- /dev/null -+++ b/src/llvm-project/lld/test/MachO/eh-frame-personality-dedup.s -@@ -0,0 +1,43 @@ -+# REQUIRES: x86 -+# RUN: rm -rf %t; split-file %s %t -+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 %t/eh-frame.s -o %t/eh-frame.o -+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 %t/cu.s -o %t/cu.o -+# RUN: %lld -dylib %t/cu.o %t/eh-frame.o -o %t/out -+ -+## Sanity check: we want our input to contain a section (and not symbol) -+## relocation for the personality reference. -+# RUN: llvm-readobj --relocations %t/cu.o | FileCheck %s --check-prefix=SECT-RELOC -+# SECT-RELOC: Section __compact_unwind { -+# SECT-RELOC-NEXT: __text -+# SECT-RELOC-NEXT: __text -+# SECT-RELOC-NEXT: } -+ -+## Verify that the personality referenced via a symbol reloc in eh-frame.s gets -+## dedup'ed with the personality referenced via a section reloc in cu.s. -+# RUN: llvm-objdump --macho --unwind-info %t/out | FileCheck %s -+# CHECK: Personality functions: (count = 1) -+ -+#--- eh-frame.s -+_fun: -+ .cfi_startproc -+ .cfi_personality 155, _my_personality -+ ## cfi_escape cannot be encoded in compact unwind -+ .cfi_escape 0 -+ ret -+ .cfi_endproc -+ -+.subsections_via_symbols -+ -+#--- cu.s -+.globl _my_personality -+_fun: -+ .cfi_startproc -+ .cfi_personality 155, _my_personality -+ .cfi_def_cfa_offset 16 -+ ret -+ .cfi_endproc -+ -+_my_personality: -+ nop -+ -+.subsections_via_symbols -diff --git a/src/llvm-project/lld/test/wasm/export-all.s b/src/llvm-project/lld/test/wasm/export-all.s -index 009da9f6a..5af835ce4 100644 ---- a/src/llvm-project/lld/test/wasm/export-all.s -+++ b/src/llvm-project/lld/test/wasm/export-all.s -@@ -40,9 +40,12 @@ foo: - # CHECK-NEXT: - Name: __heap_base - # CHECK-NEXT: Kind: GLOBAL - # CHECK-NEXT: Index: 4 --# CHECK-NEXT: - Name: __memory_base -+# CHECK-NEXT: - Name: __heap_end - # CHECK-NEXT: Kind: GLOBAL - # CHECK-NEXT: Index: 5 --# CHECK-NEXT: - Name: __table_base -+# CHECK-NEXT: - Name: __memory_base - # CHECK-NEXT: Kind: GLOBAL - # CHECK-NEXT: Index: 6 -+# CHECK-NEXT: - Name: __table_base -+# CHECK-NEXT: Kind: GLOBAL -+# CHECK-NEXT: Index: 7 -diff --git a/src/llvm-project/lld/test/wasm/mutable-global-exports.s b/src/llvm-project/lld/test/wasm/mutable-global-exports.s -index e2e45ff93..98009610a 100644 ---- a/src/llvm-project/lld/test/wasm/mutable-global-exports.s -+++ b/src/llvm-project/lld/test/wasm/mutable-global-exports.s -@@ -79,10 +79,13 @@ _start: - # CHECK-ALL-NEXT: - Name: __heap_base - # CHECK-ALL-NEXT: Kind: GLOBAL - # CHECK-ALL-NEXT: Index: 5 --# CHECK-ALL-NEXT: - Name: __memory_base -+# CHECK-ALL-NEXT: - Name: __heap_end - # CHECK-ALL-NEXT: Kind: GLOBAL - # CHECK-ALL-NEXT: Index: 6 --# CHECK-ALL-NEXT: - Name: __table_base -+# CHECK-ALL-NEXT: - Name: __memory_base - # CHECK-ALL-NEXT: Kind: GLOBAL - # CHECK-ALL-NEXT: Index: 7 -+# CHECK-ALL-NEXT: - Name: __table_base -+# CHECK-ALL-NEXT: Kind: GLOBAL -+# CHECK-ALL-NEXT: Index: 8 - # CHECK-ALL-NEXT: - Type: CODE -diff --git a/src/llvm-project/lld/wasm/Driver.cpp b/src/llvm-project/lld/wasm/Driver.cpp -index 0a0f0c8a0..4afbfe241 100644 ---- a/src/llvm-project/lld/wasm/Driver.cpp -+++ b/src/llvm-project/lld/wasm/Driver.cpp -@@ -681,6 +681,7 @@ static void createOptionalSymbols() { - if (!config->isPic) { - WasmSym::globalBase = symtab->addOptionalDataSymbol("__global_base"); - WasmSym::heapBase = symtab->addOptionalDataSymbol("__heap_base"); -+ WasmSym::heapEnd = symtab->addOptionalDataSymbol("__heap_end"); - WasmSym::definedMemoryBase = symtab->addOptionalDataSymbol("__memory_base"); - WasmSym::definedTableBase = symtab->addOptionalDataSymbol("__table_base"); - if (config->is64.value_or(false)) -diff --git a/src/llvm-project/lld/wasm/Symbols.cpp b/src/llvm-project/lld/wasm/Symbols.cpp -index e0670cea6..a79c5bec3 100644 ---- a/src/llvm-project/lld/wasm/Symbols.cpp -+++ b/src/llvm-project/lld/wasm/Symbols.cpp -@@ -83,6 +83,7 @@ DefinedData *WasmSym::dsoHandle; - DefinedData *WasmSym::dataEnd; - DefinedData *WasmSym::globalBase; - DefinedData *WasmSym::heapBase; -+DefinedData *WasmSym::heapEnd; - DefinedData *WasmSym::initMemoryFlag; - GlobalSymbol *WasmSym::stackPointer; - GlobalSymbol *WasmSym::tlsBase; -diff --git a/src/llvm-project/lld/wasm/Symbols.h b/src/llvm-project/lld/wasm/Symbols.h -index c17b720a9..32e75a69c 100644 ---- a/src/llvm-project/lld/wasm/Symbols.h -+++ b/src/llvm-project/lld/wasm/Symbols.h -@@ -538,11 +538,14 @@ struct WasmSym { - // Symbol marking the end of the data and bss. - static DefinedData *dataEnd; - -- // __heap_base -- // Symbol marking the end of the data, bss and explicit stack. Any linear -- // memory following this address is not used by the linked code and can -- // therefore be used as a backing store for brk()/malloc() implementations. -+ // __heap_base/__heap_end -+ // Symbols marking the beginning and end of the "heap". It starts at the end -+ // of the data, bss and explicit stack, and extends to the end of the linear -+ // memory allocated by wasm-ld. This region of memory is not used by the -+ // linked code, so it may be used as a backing store for `sbrk` or `malloc` -+ // implementations. - static DefinedData *heapBase; -+ static DefinedData *heapEnd; - - // __wasm_init_memory_flag - // Symbol whose contents are nonzero iff memory has already been initialized. -diff --git a/src/llvm-project/lld/wasm/Writer.cpp b/src/llvm-project/lld/wasm/Writer.cpp -index f98c95526..f6bbaa02b 100644 ---- a/src/llvm-project/lld/wasm/Writer.cpp -+++ b/src/llvm-project/lld/wasm/Writer.cpp -@@ -340,10 +340,20 @@ void Writer::layoutMemory() { - Twine(maxMemorySetting)); - memoryPtr = config->initialMemory; - } -- out.memorySec->numMemoryPages = -- alignTo(memoryPtr, WasmPageSize) / WasmPageSize; -+ -+ memoryPtr = alignTo(memoryPtr, WasmPageSize); -+ -+ out.memorySec->numMemoryPages = memoryPtr / WasmPageSize; - log("mem: total pages = " + Twine(out.memorySec->numMemoryPages)); - -+ if (WasmSym::heapEnd) { -+ // Set `__heap_end` to follow the end of the statically allocated linear -+ // memory. The fact that this comes last means that a malloc/brk -+ // implementation can grow the heap at runtime. -+ log("mem: heap end = " + Twine(memoryPtr)); -+ WasmSym::heapEnd->setVA(memoryPtr); -+ } -+ - if (config->maxMemory != 0) { - if (config->maxMemory != alignTo(config->maxMemory, WasmPageSize)) - error("maximum memory must be " + Twine(WasmPageSize) + "-byte aligned"); -@@ -363,7 +373,7 @@ void Writer::layoutMemory() { - if (config->isPic) - max = maxMemorySetting; - else -- max = alignTo(memoryPtr, WasmPageSize); -+ max = memoryPtr; - } - out.memorySec->maxMemoryPages = max / WasmPageSize; - log("mem: max pages = " + Twine(out.memorySec->maxMemoryPages)); -diff --git a/src/llvm-project/lldb/bindings/CMakeLists.txt b/src/llvm-project/lldb/bindings/CMakeLists.txt -index c8aa0bcf9..9eed2f1e6 100644 ---- a/src/llvm-project/lldb/bindings/CMakeLists.txt -+++ b/src/llvm-project/lldb/bindings/CMakeLists.txt -@@ -26,8 +26,6 @@ set(SWIG_COMMON_FLAGS - -features autodoc - -I${LLDB_SOURCE_DIR}/include - -I${CMAKE_CURRENT_SOURCE_DIR} -- -D__STDC_LIMIT_MACROS -- -D__STDC_CONSTANT_MACROS - ${DARWIN_EXTRAS} - ) - -diff --git a/src/llvm-project/lldb/bindings/interfaces.swig b/src/llvm-project/lldb/bindings/interfaces.swig -index c9a6d0f06..021c7683d 100644 ---- a/src/llvm-project/lldb/bindings/interfaces.swig -+++ b/src/llvm-project/lldb/bindings/interfaces.swig -@@ -1,8 +1,5 @@ - /* Various liblldb typedefs that SWIG needs to know about. */ - #define __extension__ /* Undefine GCC keyword to make Swig happy when processing glibc's stdint.h. */ --/* The ISO C99 standard specifies that in C++ implementations limit macros such -- as INT32_MAX should only be defined if __STDC_LIMIT_MACROS is. */ --#define __STDC_LIMIT_MACROS - %include "stdint.i" - - %include "lldb/lldb-defines.h" -diff --git a/src/llvm-project/lldb/bindings/python/python-typemaps.swig b/src/llvm-project/lldb/bindings/python/python-typemaps.swig -index bf3de66b9..d45431c77 100644 ---- a/src/llvm-project/lldb/bindings/python/python-typemaps.swig -+++ b/src/llvm-project/lldb/bindings/python/python-typemaps.swig -@@ -435,7 +435,7 @@ template <> bool SetNumberFromPyObject(double &number, PyObject *obj) { - - %typemap(out) lldb::FileSP { - $result = nullptr; -- lldb::FileSP &sp = $1; -+ const lldb::FileSP &sp = $1; - if (sp) { - PythonFile pyfile = unwrapOrSetPythonException(PythonFile::FromFile(*sp)); - if (!pyfile.IsValid()) -diff --git a/src/llvm-project/lldb/include/lldb/API/SBType.h b/src/llvm-project/lldb/include/lldb/API/SBType.h -index 244d328b5..aa45aeeec 100644 ---- a/src/llvm-project/lldb/include/lldb/API/SBType.h -+++ b/src/llvm-project/lldb/include/lldb/API/SBType.h -@@ -182,6 +182,8 @@ public: - - lldb::SBType GetTemplateArgumentType(uint32_t idx); - -+ /// Return the TemplateArgumentKind of the template argument at index idx. -+ /// Variadic argument packs are automatically expanded. - lldb::TemplateArgumentKind GetTemplateArgumentKind(uint32_t idx); - - lldb::SBType GetFunctionReturnType(); -diff --git a/src/llvm-project/lldb/include/lldb/Symbol/CompilerType.h b/src/llvm-project/lldb/include/lldb/Symbol/CompilerType.h -index 0ad05a275..aefd19d0a 100644 ---- a/src/llvm-project/lldb/include/lldb/Symbol/CompilerType.h -+++ b/src/llvm-project/lldb/include/lldb/Symbol/CompilerType.h -@@ -338,14 +338,28 @@ public: - GetIndexOfChildMemberWithName(const char *name, bool omit_empty_base_classes, - std::vector &child_indexes) const; - -- size_t GetNumTemplateArguments() const; -- -- lldb::TemplateArgumentKind GetTemplateArgumentKind(size_t idx) const; -- CompilerType GetTypeTemplateArgument(size_t idx) const; -+ /// Return the number of template arguments the type has. -+ /// If expand_pack is true, then variadic argument packs are automatically -+ /// expanded to their supplied arguments. If it is false an argument pack -+ /// will only count as 1 argument. -+ size_t GetNumTemplateArguments(bool expand_pack = false) const; -+ -+ // Return the TemplateArgumentKind of the template argument at index idx. -+ // If expand_pack is true, then variadic argument packs are automatically -+ // expanded to their supplied arguments. With expand_pack set to false, an -+ // arguement pack will count as 1 argument and return a type of Pack. -+ lldb::TemplateArgumentKind -+ GetTemplateArgumentKind(size_t idx, bool expand_pack = false) const; -+ CompilerType GetTypeTemplateArgument(size_t idx, -+ bool expand_pack = false) const; - - /// Returns the value of the template argument and its type. -+ /// If expand_pack is true, then variadic argument packs are automatically -+ /// expanded to their supplied arguments. With expand_pack set to false, an -+ /// arguement pack will count as 1 argument and it is invalid to call this -+ /// method on the pack argument. - llvm::Optional -- GetIntegralTemplateArgument(size_t idx) const; -+ GetIntegralTemplateArgument(size_t idx, bool expand_pack = false) const; - - CompilerType GetTypeForFormatters() const; - -diff --git a/src/llvm-project/lldb/include/lldb/Symbol/TypeSystem.h b/src/llvm-project/lldb/include/lldb/Symbol/TypeSystem.h -index be5783596..769449a49 100644 ---- a/src/llvm-project/lldb/include/lldb/Symbol/TypeSystem.h -+++ b/src/llvm-project/lldb/include/lldb/Symbol/TypeSystem.h -@@ -346,14 +346,18 @@ public: - const char *name, bool omit_empty_base_classes, - std::vector &child_indexes) = 0; - -- virtual size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type); -+ virtual size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type, -+ bool expand_pack); - - virtual lldb::TemplateArgumentKind -- GetTemplateArgumentKind(lldb::opaque_compiler_type_t type, size_t idx); -- virtual CompilerType GetTypeTemplateArgument(lldb::opaque_compiler_type_t type, -- size_t idx); -+ GetTemplateArgumentKind(lldb::opaque_compiler_type_t type, size_t idx, -+ bool expand_pack); -+ virtual CompilerType -+ GetTypeTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx, -+ bool expand_pack); - virtual llvm::Optional -- GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx); -+ GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx, -+ bool expand_pack); - - // Dumping types - -diff --git a/src/llvm-project/lldb/source/API/SBType.cpp b/src/llvm-project/lldb/source/API/SBType.cpp -index 533930c05..adc60a084 100644 ---- a/src/llvm-project/lldb/source/API/SBType.cpp -+++ b/src/llvm-project/lldb/source/API/SBType.cpp -@@ -542,7 +542,8 @@ uint32_t SBType::GetNumberOfTemplateArguments() { - LLDB_INSTRUMENT_VA(this); - - if (IsValid()) -- return m_opaque_sp->GetCompilerType(false).GetNumTemplateArguments(); -+ return m_opaque_sp->GetCompilerType(false).GetNumTemplateArguments( -+ /*expand_pack=*/true); - return 0; - } - -@@ -553,13 +554,15 @@ lldb::SBType SBType::GetTemplateArgumentType(uint32_t idx) { - return SBType(); - - CompilerType type; -+ const bool expand_pack = true; - switch(GetTemplateArgumentKind(idx)) { - case eTemplateArgumentKindType: -- type = m_opaque_sp->GetCompilerType(false).GetTypeTemplateArgument(idx); -+ type = m_opaque_sp->GetCompilerType(false).GetTypeTemplateArgument( -+ idx, expand_pack); - break; - case eTemplateArgumentKindIntegral: - type = m_opaque_sp->GetCompilerType(false) -- .GetIntegralTemplateArgument(idx) -+ .GetIntegralTemplateArgument(idx, expand_pack) - ->type; - break; - default: -@@ -574,7 +577,8 @@ lldb::TemplateArgumentKind SBType::GetTemplateArgumentKind(uint32_t idx) { - LLDB_INSTRUMENT_VA(this, idx); - - if (IsValid()) -- return m_opaque_sp->GetCompilerType(false).GetTemplateArgumentKind(idx); -+ return m_opaque_sp->GetCompilerType(false).GetTemplateArgumentKind( -+ idx, /*expand_pack=*/true); - return eTemplateArgumentKindNull; - } - -diff --git a/src/llvm-project/lldb/source/Plugins/Process/Linux/Perf.cpp b/src/llvm-project/lldb/source/Plugins/Process/Linux/Perf.cpp -index fa4e8fb42..c0a879555 100644 ---- a/src/llvm-project/lldb/source/Plugins/Process/Linux/Perf.cpp -+++ b/src/llvm-project/lldb/source/Plugins/Process/Linux/Perf.cpp -@@ -127,6 +127,10 @@ llvm::Error PerfEvent::MmapMetadataAndDataBuffer(size_t num_data_pages, - } - - llvm::Error PerfEvent::MmapAuxBuffer(size_t num_aux_pages) { -+#ifndef PERF_ATTR_SIZE_VER5 -+ return createStringError(inconvertibleErrorCode(), -+ "Intel PT Linux perf event not supported"); -+#else - if (num_aux_pages == 0) - return Error::success(); - -@@ -143,6 +147,7 @@ llvm::Error PerfEvent::MmapAuxBuffer(size_t num_aux_pages) { - return Error::success(); - } else - return mmap_aux.takeError(); -+#endif - } - - llvm::Error PerfEvent::MmapMetadataAndBuffers(size_t num_data_pages, -@@ -172,16 +177,24 @@ perf_event_mmap_page &PerfEvent::GetMetadataPage() const { - } - - ArrayRef PerfEvent::GetDataBuffer() const { -+#ifndef PERF_ATTR_SIZE_VER5 -+ llvm_unreachable("Intel PT Linux perf event not supported"); -+#else - perf_event_mmap_page &mmap_metadata = GetMetadataPage(); - return {reinterpret_cast(m_metadata_data_base.get()) + - mmap_metadata.data_offset, -- static_cast(mmap_metadata.data_size)}; -+ static_cast(mmap_metadata.data_size)}; -+#endif - } - - ArrayRef PerfEvent::GetAuxBuffer() const { -+#ifndef PERF_ATTR_SIZE_VER5 -+ llvm_unreachable("Intel PT Linux perf event not supported"); -+#else - perf_event_mmap_page &mmap_metadata = GetMetadataPage(); - return {reinterpret_cast(m_aux_base.get()), -- static_cast(mmap_metadata.aux_size)}; -+ static_cast(mmap_metadata.aux_size)}; -+#endif - } - - Expected> PerfEvent::GetReadOnlyDataBuffer() { -@@ -190,6 +203,10 @@ Expected> PerfEvent::GetReadOnlyDataBuffer() { - // this piece of code updates some pointers. See more about data_tail - // in https://man7.org/linux/man-pages/man2/perf_event_open.2.html. - -+#ifndef PERF_ATTR_SIZE_VER5 -+ return createStringError(inconvertibleErrorCode(), -+ "Intel PT Linux perf event not supported"); -+#else - bool was_enabled = m_enabled; - if (Error err = DisableWithIoctl()) - return std::move(err); -@@ -226,6 +243,7 @@ Expected> PerfEvent::GetReadOnlyDataBuffer() { - } - - return output; -+#endif - } - - Expected> PerfEvent::GetReadOnlyAuxBuffer() { -@@ -234,6 +252,10 @@ Expected> PerfEvent::GetReadOnlyAuxBuffer() { - // this piece of code updates some pointers. See more about aux_tail - // in https://man7.org/linux/man-pages/man2/perf_event_open.2.html. - -+#ifndef PERF_ATTR_SIZE_VER5 -+ return createStringError(inconvertibleErrorCode(), -+ "Intel PT Linux perf event not supported"); -+#else - bool was_enabled = m_enabled; - if (Error err = DisableWithIoctl()) - return std::move(err); -@@ -266,6 +288,7 @@ Expected> PerfEvent::GetReadOnlyAuxBuffer() { - } - - return output; -+#endif - } - - Error PerfEvent::DisableWithIoctl() { -@@ -297,11 +320,15 @@ Error PerfEvent::EnableWithIoctl() { - } - - size_t PerfEvent::GetEffectiveDataBufferSize() const { -+#ifndef PERF_ATTR_SIZE_VER5 -+ llvm_unreachable("Intel PT Linux perf event not supported"); -+#else - perf_event_mmap_page &mmap_metadata = GetMetadataPage(); - if (mmap_metadata.data_head < mmap_metadata.data_size) - return mmap_metadata.data_head; - else - return mmap_metadata.data_size; // The buffer has wrapped. -+#endif - } - - Expected -diff --git a/src/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/src/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp -index c6eb693bb..a1ebe5830 100644 ---- a/src/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp -+++ b/src/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp -@@ -7096,7 +7096,8 @@ TypeSystemClang::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, - } - - size_t --TypeSystemClang::GetNumTemplateArguments(lldb::opaque_compiler_type_t type) { -+TypeSystemClang::GetNumTemplateArguments(lldb::opaque_compiler_type_t type, -+ bool expand_pack) { - if (!type) - return 0; - -@@ -7111,8 +7112,17 @@ TypeSystemClang::GetNumTemplateArguments(lldb::opaque_compiler_type_t type) { - const clang::ClassTemplateSpecializationDecl *template_decl = - llvm::dyn_cast( - cxx_record_decl); -- if (template_decl) -- return template_decl->getTemplateArgs().size(); -+ if (template_decl) { -+ const auto &template_arg_list = template_decl->getTemplateArgs(); -+ size_t num_args = template_arg_list.size(); -+ assert(num_args && "template specialization without any args"); -+ if (expand_pack && num_args) { -+ const auto &pack = template_arg_list[num_args - 1]; -+ if (pack.getKind() == clang::TemplateArgument::Pack) -+ num_args += pack.pack_size() - 1; -+ } -+ return num_args; -+ } - } - } - break; -@@ -7149,15 +7159,51 @@ TypeSystemClang::GetAsTemplateSpecialization( - } - } - -+const TemplateArgument * -+GetNthTemplateArgument(const clang::ClassTemplateSpecializationDecl *decl, -+ size_t idx, bool expand_pack) { -+ const auto &args = decl->getTemplateArgs(); -+ const size_t args_size = args.size(); -+ -+ assert(args_size && "template specialization without any args"); -+ if (!args_size) -+ return nullptr; -+ -+ const size_t last_idx = args_size - 1; -+ -+ // We're asked for a template argument that can't be a parameter pack, so -+ // return it without worrying about 'expand_pack'. -+ if (idx < last_idx) -+ return &args[idx]; -+ -+ // We're asked for the last template argument but we don't want/need to -+ // expand it. -+ if (!expand_pack || args[last_idx].getKind() != clang::TemplateArgument::Pack) -+ return idx >= args.size() ? nullptr : &args[idx]; -+ -+ // Index into the expanded pack. -+ // Note that 'idx' counts from the beginning of all template arguments -+ // (including the ones preceding the parameter pack). -+ const auto &pack = args[last_idx]; -+ const size_t pack_idx = idx - last_idx; -+ const size_t pack_size = pack.pack_size(); -+ assert(pack_idx < pack_size && "parameter pack index out-of-bounds"); -+ return &pack.pack_elements()[pack_idx]; -+} -+ - lldb::TemplateArgumentKind - TypeSystemClang::GetTemplateArgumentKind(lldb::opaque_compiler_type_t type, -- size_t arg_idx) { -+ size_t arg_idx, bool expand_pack) { - const clang::ClassTemplateSpecializationDecl *template_decl = - GetAsTemplateSpecialization(type); -- if (! template_decl || arg_idx >= template_decl->getTemplateArgs().size()) -+ if (!template_decl) -+ return eTemplateArgumentKindNull; -+ -+ const auto *arg = GetNthTemplateArgument(template_decl, arg_idx, expand_pack); -+ if (!arg) - return eTemplateArgumentKindNull; - -- switch (template_decl->getTemplateArgs()[arg_idx].getKind()) { -+ switch (arg->getKind()) { - case clang::TemplateArgument::Null: - return eTemplateArgumentKindNull; - -@@ -7190,35 +7236,32 @@ TypeSystemClang::GetTemplateArgumentKind(lldb::opaque_compiler_type_t type, - - CompilerType - TypeSystemClang::GetTypeTemplateArgument(lldb::opaque_compiler_type_t type, -- size_t idx) { -+ size_t idx, bool expand_pack) { - const clang::ClassTemplateSpecializationDecl *template_decl = - GetAsTemplateSpecialization(type); -- if (!template_decl || idx >= template_decl->getTemplateArgs().size()) -+ if (!template_decl) - return CompilerType(); - -- const clang::TemplateArgument &template_arg = -- template_decl->getTemplateArgs()[idx]; -- if (template_arg.getKind() != clang::TemplateArgument::Type) -+ const auto *arg = GetNthTemplateArgument(template_decl, idx, expand_pack); -+ if (!arg || arg->getKind() != clang::TemplateArgument::Type) - return CompilerType(); - -- return GetType(template_arg.getAsType()); -+ return GetType(arg->getAsType()); - } - - Optional - TypeSystemClang::GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type, -- size_t idx) { -+ size_t idx, bool expand_pack) { - const clang::ClassTemplateSpecializationDecl *template_decl = - GetAsTemplateSpecialization(type); -- if (! template_decl || idx >= template_decl->getTemplateArgs().size()) -+ if (!template_decl) - return llvm::None; - -- const clang::TemplateArgument &template_arg = -- template_decl->getTemplateArgs()[idx]; -- if (template_arg.getKind() != clang::TemplateArgument::Integral) -+ const auto *arg = GetNthTemplateArgument(template_decl, idx, expand_pack); -+ if (!arg || arg->getKind() != clang::TemplateArgument::Integral) - return llvm::None; - -- return { -- {template_arg.getAsIntegral(), GetType(template_arg.getIntegralType())}}; -+ return {{arg->getAsIntegral(), GetType(arg->getIntegralType())}}; - } - - CompilerType TypeSystemClang::GetTypeForFormatters(void *type) { -diff --git a/src/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/src/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h -index 24dbb71c8..7f25a6df5 100644 ---- a/src/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h -+++ b/src/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h -@@ -91,7 +91,7 @@ public: - void SetOwningModule(OptionalClangModuleID id); - /// \} - }; -- -+ - /// A TypeSystem implementation based on Clang. - /// - /// This class uses a single clang::ASTContext as the backend for storing -@@ -334,7 +334,7 @@ public: - - llvm::SmallVector names; - llvm::SmallVector args; -- -+ - const char * pack_name = nullptr; - std::unique_ptr packed_args; - }; -@@ -537,7 +537,7 @@ public: - #ifndef NDEBUG - bool Verify(lldb::opaque_compiler_type_t type) override; - #endif -- -+ - bool IsArrayType(lldb::opaque_compiler_type_t type, - CompilerType *element_type, uint64_t *size, - bool *is_incomplete) override; -@@ -810,16 +810,17 @@ public: - const char *name, bool omit_empty_base_classes, - std::vector &child_indexes) override; - -- size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override; -+ size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type, -+ bool expand_pack) override; - - lldb::TemplateArgumentKind -- GetTemplateArgumentKind(lldb::opaque_compiler_type_t type, -- size_t idx) override; -+ GetTemplateArgumentKind(lldb::opaque_compiler_type_t type, size_t idx, -+ bool expand_pack) override; - CompilerType GetTypeTemplateArgument(lldb::opaque_compiler_type_t type, -- size_t idx) override; -+ size_t idx, bool expand_pack) override; - llvm::Optional -- GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type, -- size_t idx) override; -+ GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx, -+ bool expand_pack) override; - - CompilerType GetTypeForFormatters(void *type) override; - -diff --git a/src/llvm-project/lldb/source/Symbol/CompilerType.cpp b/src/llvm-project/lldb/source/Symbol/CompilerType.cpp -index ac98352c2..bef456583 100644 ---- a/src/llvm-project/lldb/source/Symbol/CompilerType.cpp -+++ b/src/llvm-project/lldb/source/Symbol/CompilerType.cpp -@@ -659,30 +659,32 @@ size_t CompilerType::GetIndexOfChildMemberWithName( - return 0; - } - --size_t CompilerType::GetNumTemplateArguments() const { -+size_t CompilerType::GetNumTemplateArguments(bool expand_pack) const { - if (IsValid()) { -- return m_type_system->GetNumTemplateArguments(m_type); -+ return m_type_system->GetNumTemplateArguments(m_type, expand_pack); - } - return 0; - } - --TemplateArgumentKind CompilerType::GetTemplateArgumentKind(size_t idx) const { -+TemplateArgumentKind -+CompilerType::GetTemplateArgumentKind(size_t idx, bool expand_pack) const { - if (IsValid()) -- return m_type_system->GetTemplateArgumentKind(m_type, idx); -+ return m_type_system->GetTemplateArgumentKind(m_type, idx, expand_pack); - return eTemplateArgumentKindNull; - } - --CompilerType CompilerType::GetTypeTemplateArgument(size_t idx) const { -+CompilerType CompilerType::GetTypeTemplateArgument(size_t idx, -+ bool expand_pack) const { - if (IsValid()) { -- return m_type_system->GetTypeTemplateArgument(m_type, idx); -+ return m_type_system->GetTypeTemplateArgument(m_type, idx, expand_pack); - } - return CompilerType(); - } - - llvm::Optional --CompilerType::GetIntegralTemplateArgument(size_t idx) const { -+CompilerType::GetIntegralTemplateArgument(size_t idx, bool expand_pack) const { - if (IsValid()) -- return m_type_system->GetIntegralTemplateArgument(m_type, idx); -+ return m_type_system->GetIntegralTemplateArgument(m_type, idx, expand_pack); - return llvm::None; - } - -diff --git a/src/llvm-project/lldb/source/Symbol/TypeSystem.cpp b/src/llvm-project/lldb/source/Symbol/TypeSystem.cpp -index 3092dc0bf..412373533 100644 ---- a/src/llvm-project/lldb/source/Symbol/TypeSystem.cpp -+++ b/src/llvm-project/lldb/source/Symbol/TypeSystem.cpp -@@ -118,23 +118,25 @@ CompilerType TypeSystem::GetTypeForFormatters(void *type) { - return CompilerType(this, type); - } - --size_t TypeSystem::GetNumTemplateArguments(lldb::opaque_compiler_type_t type) { -+size_t TypeSystem::GetNumTemplateArguments(lldb::opaque_compiler_type_t type, -+ bool expand_pack) { - return 0; - } - - TemplateArgumentKind --TypeSystem::GetTemplateArgumentKind(opaque_compiler_type_t type, size_t idx) { -+TypeSystem::GetTemplateArgumentKind(opaque_compiler_type_t type, size_t idx, -+ bool expand_pack) { - return eTemplateArgumentKindNull; - } - - CompilerType TypeSystem::GetTypeTemplateArgument(opaque_compiler_type_t type, -- size_t idx) { -+ size_t idx, bool expand_pack) { - return CompilerType(); - } - - llvm::Optional --TypeSystem::GetIntegralTemplateArgument(opaque_compiler_type_t type, -- size_t idx) { -+TypeSystem::GetIntegralTemplateArgument(opaque_compiler_type_t type, size_t idx, -+ bool expand_pack) { - return llvm::None; - } - -diff --git a/src/llvm-project/lldb/test/API/lang/cpp/class-template-parameter-pack/TestTemplatePackArgs.py b/src/llvm-project/lldb/test/API/lang/cpp/class-template-parameter-pack/TestTemplatePackArgs.py -new file mode 100644 -index 000000000..180d3f503 ---- /dev/null -+++ b/src/llvm-project/lldb/test/API/lang/cpp/class-template-parameter-pack/TestTemplatePackArgs.py -@@ -0,0 +1,38 @@ -+""" -+Test that the type of arguments to C++ template classes that have variadic -+parameters can be enumerated. -+""" -+import lldb -+from lldbsuite.test.decorators import * -+from lldbsuite.test.lldbtest import * -+from lldbsuite.test import lldbutil -+ -+ -+class TemplatePackArgsTestCase(TestBase): -+ -+ mydir = TestBase.compute_mydir(__file__) -+ -+ def test_template_argument_pack(self): -+ self.build() -+ (_, _, thread, _) = lldbutil.run_to_source_breakpoint(self, -+ 'breakpoint here', lldb.SBFileSpec('main.cpp'), exe_name = 'a.out') -+ frame = thread.GetSelectedFrame() -+ -+ empty_pack = frame.FindVariable('emptyPack') -+ self.assertTrue(empty_pack.IsValid(), -+ 'make sure we find the emptyPack variable') -+ -+ only_pack = frame.FindVariable('onlyPack') -+ self.assertTrue(only_pack.IsValid(), -+ 'make sure we find the onlyPack variable') -+ self.assertEqual(only_pack.GetType().GetNumberOfTemplateArguments(), 4) -+ self.assertEqual(only_pack.GetType().GetTemplateArgumentType(0).GetName(), 'int') -+ self.assertEqual(only_pack.GetType().GetTemplateArgumentType(1).GetName(), 'char') -+ self.assertEqual(only_pack.GetType().GetTemplateArgumentType(2).GetName(), 'double') -+ # Access the C template parameter. -+ nested_template = only_pack.GetType().GetTemplateArgumentType(3) -+ self.assertEqual(nested_template.GetName(), 'D') -+ self.assertEqual(nested_template.GetNumberOfTemplateArguments(), 3) -+ self.assertEqual(nested_template.GetTemplateArgumentType(0).GetName(), 'int') -+ self.assertEqual(nested_template.GetTemplateArgumentType(1).GetName(), 'int') -+ self.assertEqual(nested_template.GetTemplateArgumentType(2).GetName(), 'bool') -diff --git a/src/llvm-project/lldb/test/API/lang/cpp/class-template-parameter-pack/main.cpp b/src/llvm-project/lldb/test/API/lang/cpp/class-template-parameter-pack/main.cpp -index 8bb0a42b5..26f8eab54 100644 ---- a/src/llvm-project/lldb/test/API/lang/cpp/class-template-parameter-pack/main.cpp -+++ b/src/llvm-project/lldb/test/API/lang/cpp/class-template-parameter-pack/main.cpp -@@ -26,7 +26,13 @@ template <> struct D : D { - bool argsAre_Int_bool() { return true; } - }; - -+template struct OnlyPack {}; -+template struct EmptyPack {}; -+ - int main(int argc, char const *argv[]) { -+ EmptyPack emptyPack; -+ OnlyPack> onlyPack; -+ - C myC; - C myLesserC; - myC.member = 64; -@@ -34,7 +40,7 @@ int main(int argc, char const *argv[]) { - (void)C().argsAre_16_32(); - (void)(myC.member != 64); - D myD; -- D myLesserD; -+ D myLesserD; // breakpoint here - myD.member = 64; - (void)D().argsAre_Int_bool(); - (void)D().argsAre_Int_bool(); -diff --git a/src/llvm-project/lldb/tools/debugserver/source/CMakeLists.txt b/src/llvm-project/lldb/tools/debugserver/source/CMakeLists.txt -index f636e387b..c6e7e8cf4 100644 ---- a/src/llvm-project/lldb/tools/debugserver/source/CMakeLists.txt -+++ b/src/llvm-project/lldb/tools/debugserver/source/CMakeLists.txt -@@ -95,7 +95,7 @@ check_c_source_compiles( - #else - #error Not building for ARM64 - #endif -- int main() { return 0; } -+ int main(void) { return 0; } - " - BUILDING_FOR_ARM64_OSX - ) -diff --git a/src/llvm-project/lldb/unittests/Symbol/TestTypeSystemClang.cpp b/src/llvm-project/lldb/unittests/Symbol/TestTypeSystemClang.cpp -index e78a084f5..4da17cf36 100644 ---- a/src/llvm-project/lldb/unittests/Symbol/TestTypeSystemClang.cpp -+++ b/src/llvm-project/lldb/unittests/Symbol/TestTypeSystemClang.cpp -@@ -500,18 +500,24 @@ TEST_F(TestTypeSystemClang, TemplateArguments) { - for (CompilerType t : {type, typedef_type, auto_type}) { - SCOPED_TRACE(t.GetTypeName().AsCString()); - -- EXPECT_EQ(m_ast->GetTemplateArgumentKind(t.GetOpaqueQualType(), 0), -- eTemplateArgumentKindType); -- EXPECT_EQ(m_ast->GetTypeTemplateArgument(t.GetOpaqueQualType(), 0), -- int_type); -- EXPECT_EQ(llvm::None, -- m_ast->GetIntegralTemplateArgument(t.GetOpaqueQualType(), 0)); -- -- EXPECT_EQ(m_ast->GetTemplateArgumentKind(t.GetOpaqueQualType(), 1), -- eTemplateArgumentKindIntegral); -- EXPECT_EQ(m_ast->GetTypeTemplateArgument(t.GetOpaqueQualType(), 1), -- CompilerType()); -- auto result = m_ast->GetIntegralTemplateArgument(t.GetOpaqueQualType(), 1); -+ const bool expand_pack = false; -+ EXPECT_EQ( -+ m_ast->GetTemplateArgumentKind(t.GetOpaqueQualType(), 0, expand_pack), -+ eTemplateArgumentKindType); -+ EXPECT_EQ( -+ m_ast->GetTypeTemplateArgument(t.GetOpaqueQualType(), 0, expand_pack), -+ int_type); -+ EXPECT_EQ(llvm::None, m_ast->GetIntegralTemplateArgument( -+ t.GetOpaqueQualType(), 0, expand_pack)); -+ -+ EXPECT_EQ( -+ m_ast->GetTemplateArgumentKind(t.GetOpaqueQualType(), 1, expand_pack), -+ eTemplateArgumentKindIntegral); -+ EXPECT_EQ( -+ m_ast->GetTypeTemplateArgument(t.GetOpaqueQualType(), 1, expand_pack), -+ CompilerType()); -+ auto result = m_ast->GetIntegralTemplateArgument(t.GetOpaqueQualType(), 1, -+ expand_pack); - ASSERT_NE(llvm::None, result); - EXPECT_EQ(arg, result->value); - EXPECT_EQ(int_type, result->type); -diff --git a/src/llvm-project/llvm/CMakeLists.txt b/src/llvm-project/llvm/CMakeLists.txt -index 57eb01d6f..bae2cebaf 100644 ---- a/src/llvm-project/llvm/CMakeLists.txt -+++ b/src/llvm-project/llvm/CMakeLists.txt -@@ -22,7 +22,7 @@ if(NOT DEFINED LLVM_VERSION_MINOR) - set(LLVM_VERSION_MINOR 0) - endif() - if(NOT DEFINED LLVM_VERSION_PATCH) -- set(LLVM_VERSION_PATCH 2) -+ set(LLVM_VERSION_PATCH 7) - endif() - if(NOT DEFINED LLVM_VERSION_SUFFIX) - set(LLVM_VERSION_SUFFIX) -@@ -373,6 +373,7 @@ set(LLVM_ALL_TARGETS - BPF - Hexagon - Lanai -+ LoongArch - Mips - MSP430 - NVPTX -@@ -446,6 +447,8 @@ set(LLVM_ENABLE_ZLIB "ON" CACHE STRING "Use zlib for compression/decompression i - - set(LLVM_ENABLE_ZSTD "ON" CACHE STRING "Use zstd for compression/decompression if available. Can be ON, OFF, or FORCE_ON") - -+set(LLVM_USE_STATIC_ZSTD FALSE CACHE BOOL "Use static version of zstd. Can be TRUE, FALSE") -+ - set(LLVM_ENABLE_CURL "OFF" CACHE STRING "Use libcurl for the HTTP client if available. Can be ON, OFF, or FORCE_ON") - - set(LLVM_ENABLE_HTTPLIB "OFF" CACHE STRING "Use cpp-httplib HTTP server library if available. Can be ON, OFF, or FORCE_ON") -diff --git a/src/llvm-project/llvm/cmake/config-ix.cmake b/src/llvm-project/llvm/cmake/config-ix.cmake -index 83512760d..b4b9b748c 100644 ---- a/src/llvm-project/llvm/cmake/config-ix.cmake -+++ b/src/llvm-project/llvm/cmake/config-ix.cmake -@@ -71,7 +71,7 @@ if(APPLE) - CHECK_C_SOURCE_COMPILES(" - static const char *__crashreporter_info__ = 0; - asm(\".desc ___crashreporter_info__, 0x10\"); -- int main() { return 0; }" -+ int main(void) { return 0; }" - HAVE_CRASHREPORTER_INFO) - endif() - -@@ -498,6 +498,8 @@ elseif (LLVM_NATIVE_ARCH MATCHES "riscv64") - set(LLVM_NATIVE_ARCH RISCV) - elseif (LLVM_NATIVE_ARCH STREQUAL "m68k") - set(LLVM_NATIVE_ARCH M68k) -+elseif (LLVM_NATIVE_ARCH MATCHES "loongarch") -+ set(LLVM_NATIVE_ARCH LoongArch) - else () - message(FATAL_ERROR "Unknown architecture ${LLVM_NATIVE_ARCH}") - endif () -diff --git a/src/llvm-project/llvm/cmake/config.guess b/src/llvm-project/llvm/cmake/config.guess -index 60d3f588d..255257d40 100644 ---- a/src/llvm-project/llvm/cmake/config.guess -+++ b/src/llvm-project/llvm/cmake/config.guess -@@ -1021,6 +1021,9 @@ EOF - x86_64:Linux:*:*) - echo x86_64-unknown-linux-gnu - exit ;; -+ loongarch64:Linux:*:*) -+ echo loongarch64-unknown-linux-gnu -+ exit ;; - xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; -diff --git a/src/llvm-project/llvm/cmake/modules/AddLLVM.cmake b/src/llvm-project/llvm/cmake/modules/AddLLVM.cmake -index 057431208..1f0507f39 100644 ---- a/src/llvm-project/llvm/cmake/modules/AddLLVM.cmake -+++ b/src/llvm-project/llvm/cmake/modules/AddLLVM.cmake -@@ -212,6 +212,7 @@ if (NOT DEFINED LLVM_LINKER_DETECTED AND NOT WIN32) - else() - if("${stdout}" MATCHES "^mold") - set(LLVM_LINKER_DETECTED YES CACHE INTERNAL "") -+ set(LLVM_LINKER_IS_MOLD YES CACHE INTERNAL "") - message(STATUS "Linker detection: mold") - elseif("${stdout}" MATCHES "GNU gold") - set(LLVM_LINKER_DETECTED YES CACHE INTERNAL "") -diff --git a/src/llvm-project/llvm/cmake/modules/CheckAtomic.cmake b/src/llvm-project/llvm/cmake/modules/CheckAtomic.cmake -index 3c5ba7299..f11cadf39 100644 ---- a/src/llvm-project/llvm/cmake/modules/CheckAtomic.cmake -+++ b/src/llvm-project/llvm/cmake/modules/CheckAtomic.cmake -@@ -82,6 +82,19 @@ elseif(LLVM_COMPILER_IS_GCC_COMPATIBLE OR CMAKE_CXX_COMPILER_ID MATCHES "XL") - endif() - endif() - -+# Set variable LLVM_ATOMIC_LIB specifying flags for linking against libatomic. -+if(HAVE_CXX_ATOMICS_WITH_LIB OR HAVE_CXX_ATOMICS64_WITH_LIB) -+ # Use options --push-state, --as-needed and --pop-state if linker is known to support them. -+ # Use single option -Wl of compiler driver to avoid incorrect re-ordering of options by CMake. -+ if(LLVM_LINKER_IS_GNULD OR LLVM_LINKER_IS_GOLD OR LLVM_LINKER_IS_LLD OR LLVM_LINKER_IS_MOLD) -+ set(LLVM_ATOMIC_LIB "-Wl,--push-state,--as-needed,-latomic,--pop-state") -+ else() -+ set(LLVM_ATOMIC_LIB "-latomic") -+ endif() -+else() -+ set(LLVM_ATOMIC_LIB) -+endif() -+ - ## TODO: This define is only used for the legacy atomic operations in - ## llvm's Atomic.h, which should be replaced. Other code simply - ## assumes C++11 works. -diff --git a/src/llvm-project/llvm/cmake/modules/FindFFI.cmake b/src/llvm-project/llvm/cmake/modules/FindFFI.cmake -index b0d859af8..a493a89d6 100644 ---- a/src/llvm-project/llvm/cmake/modules/FindFFI.cmake -+++ b/src/llvm-project/llvm/cmake/modules/FindFFI.cmake -@@ -45,7 +45,7 @@ if(FFI_LIBRARIES) - struct ffi_cif; - typedef struct ffi_cif ffi_cif; - void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue); -- int main() { ffi_call(0, 0, 0, 0); }" -+ int main(void) { ffi_call(0, 0, 0, 0); }" - HAVE_FFI_CALL) - cmake_pop_check_state() - endif() -diff --git a/src/llvm-project/llvm/cmake/modules/FindTerminfo.cmake b/src/llvm-project/llvm/cmake/modules/FindTerminfo.cmake -index 65edb80fa..eef1f9585 100644 ---- a/src/llvm-project/llvm/cmake/modules/FindTerminfo.cmake -+++ b/src/llvm-project/llvm/cmake/modules/FindTerminfo.cmake -@@ -20,7 +20,7 @@ if(Terminfo_LIBRARIES) - list(APPEND CMAKE_REQUIRED_LIBRARIES ${Terminfo_LIBRARIES}) - check_c_source_compiles(" - int setupterm(char *term, int filedes, int *errret); -- int main() { return setupterm(0, 0, 0); }" -+ int main(void) { return setupterm(0, 0, 0); }" - Terminfo_LINKABLE) - cmake_pop_check_state() - endif() -diff --git a/src/llvm-project/llvm/cmake/modules/FindZ3.cmake b/src/llvm-project/llvm/cmake/modules/FindZ3.cmake -index 118b1eac3..6fb56d741 100644 ---- a/src/llvm-project/llvm/cmake/modules/FindZ3.cmake -+++ b/src/llvm-project/llvm/cmake/modules/FindZ3.cmake -@@ -18,8 +18,9 @@ function(check_z3_version z3_include z3_lib) - # The program that will be executed to print Z3's version. - file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testz3.cpp - "#include -+ #include - #include -- int main() { -+ int main(void) { - unsigned int major, minor, build, rev; - Z3_get_version(&major, &minor, &build, &rev); - printf(\"%u.%u.%u\", major, minor, build); -diff --git a/src/llvm-project/llvm/cmake/modules/Findzstd.cmake b/src/llvm-project/llvm/cmake/modules/Findzstd.cmake -new file mode 100644 -index 000000000..fab9ea803 ---- /dev/null -+++ b/src/llvm-project/llvm/cmake/modules/Findzstd.cmake -@@ -0,0 +1,49 @@ -+# Try to find the zstd library -+# -+# If successful, the following variables will be defined: -+# zstd_INCLUDE_DIR -+# zstd_LIBRARY -+# zstd_FOUND -+# -+# Additionally, one of the following import targets will be defined: -+# zstd::libzstd_shared -+# zstd::libzstd_static -+ -+if(MSVC) -+ set(zstd_SHARED_LIBRARY_SUFFIX "\\${CMAKE_LINK_LIBRARY_SUFFIX}$") -+ set(zstd_STATIC_LIBRARY_SUFFIX "_static\\${CMAKE_STATIC_LIBRARY_SUFFIX}$") -+else() -+ set(zstd_SHARED_LIBRARY_SUFFIX "\\${CMAKE_SHARED_LIBRARY_SUFFIX}$") -+ set(zstd_STATIC_LIBRARY_SUFFIX "\\${CMAKE_STATIC_LIBRARY_SUFFIX}$") -+endif() -+ -+find_path(zstd_INCLUDE_DIR NAMES zstd.h) -+find_library(zstd_LIBRARY NAMES zstd zstd_static) -+ -+include(FindPackageHandleStandardArgs) -+find_package_handle_standard_args( -+ zstd DEFAULT_MSG -+ zstd_LIBRARY zstd_INCLUDE_DIR -+) -+ -+if(zstd_FOUND) -+ if(zstd_LIBRARY MATCHES "${zstd_SHARED_LIBRARY_SUFFIX}$" AND -+ NOT TARGET zstd::libzstd_shared) -+ add_library(zstd::libzstd_shared SHARED IMPORTED) -+ set_target_properties(zstd::libzstd_shared PROPERTIES -+ INTERFACE_INCLUDE_DIRECTORIES "${zstd_INCLUDE_DIR}" -+ IMPORTED_LOCATION "${zstd_LIBRARY}") -+ endif() -+ if(zstd_LIBRARY MATCHES "${zstd_STATIC_LIBRARY_SUFFIX}$" AND -+ NOT TARGET zstd::libzstd_static) -+ add_library(zstd::libzstd_static STATIC IMPORTED) -+ set_target_properties(zstd::libzstd_static PROPERTIES -+ INTERFACE_INCLUDE_DIRECTORIES "${zstd_INCLUDE_DIR}" -+ IMPORTED_LOCATION "${zstd_LIBRARY}") -+ endif() -+endif() -+ -+unset(zstd_SHARED_LIBRARY_SUFFIX) -+unset(zstd_STATIC_LIBRARY_SUFFIX) -+ -+mark_as_advanced(zstd_INCLUDE_DIR zstd_LIBRARY) -diff --git a/src/llvm-project/llvm/cmake/modules/HandleLLVMOptions.cmake b/src/llvm-project/llvm/cmake/modules/HandleLLVMOptions.cmake -index 56d05f5b5..0fca934be 100644 ---- a/src/llvm-project/llvm/cmake/modules/HandleLLVMOptions.cmake -+++ b/src/llvm-project/llvm/cmake/modules/HandleLLVMOptions.cmake -@@ -779,7 +779,7 @@ if (LLVM_ENABLE_WARNINGS AND (LLVM_COMPILER_IS_GCC_COMPATIBLE OR CLANG_CL)) - # line is also a // comment. - set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) - set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror -Wcomment") -- CHECK_C_SOURCE_COMPILES("// \\\\\\n//\\nint main() {return 0;}" -+ CHECK_C_SOURCE_COMPILES("// \\\\\\n//\\nint main(void) {return 0;}" - C_WCOMMENT_ALLOWS_LINE_WRAP) - set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS}) - if (NOT C_WCOMMENT_ALLOWS_LINE_WRAP) -diff --git a/src/llvm-project/llvm/cmake/modules/LLVMConfig.cmake.in b/src/llvm-project/llvm/cmake/modules/LLVMConfig.cmake.in -index fbf28d36b..f1362fa03 100644 ---- a/src/llvm-project/llvm/cmake/modules/LLVMConfig.cmake.in -+++ b/src/llvm-project/llvm/cmake/modules/LLVMConfig.cmake.in -@@ -75,7 +75,6 @@ endif() - - set(LLVM_ENABLE_ZSTD @LLVM_ENABLE_ZSTD@) - if(LLVM_ENABLE_ZSTD) -- set(zstd_ROOT @zstd_ROOT@) - find_package(zstd) - endif() - -diff --git a/src/llvm-project/llvm/docs/ReleaseNotes.rst b/src/llvm-project/llvm/docs/ReleaseNotes.rst -index 9324d26cb..0660bc134 100644 ---- a/src/llvm-project/llvm/docs/ReleaseNotes.rst -+++ b/src/llvm-project/llvm/docs/ReleaseNotes.rst -@@ -227,6 +227,20 @@ Changes to the WebAssembly Backend - - * ... - -+Changes to the SystemZ Backend -+------------------------------ -+ -+* Support z16 processor name. -+* Machine scheduler description for z16. -+* Add support for inline assembly address operands ("p") as well as for SystemZ -+ specific address operands ("ZQ", "ZR", "ZS" and "ZT"). -+* Efficient handling of small memcpy/memset operations up to 32 bytes. -+* Tuning of the inliner. -+* Fixing emission of library calls so that narrow integer arguments are sign or -+ zero extended per the SystemZ ABI. -+* Support added for libunwind. -+* Various minor improvements and bugfixes. -+ - Changes to the X86 Backend - -------------------------- - -diff --git a/src/llvm-project/llvm/include/llvm/ADT/Triple.h b/src/llvm-project/llvm/include/llvm/ADT/Triple.h -index ba4584dc6..dbd0aeaab 100644 ---- a/src/llvm-project/llvm/include/llvm/ADT/Triple.h -+++ b/src/llvm-project/llvm/include/llvm/ADT/Triple.h -@@ -232,6 +232,7 @@ public: - GNUX32, - GNUILP32, - CODE16, -+ GNUABILPX32, - EABI, - EABIHF, - Android, -@@ -823,6 +824,16 @@ public: - : PointerWidth == 64; - } - -+ /// Tests whether the target is LoongArch 32-bit -+ bool isLoongArch32() const { -+ return getArch() == Triple::loongarch32; -+ } -+ -+ /// 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 getArch() == Triple::loongarch32 || getArch() == Triple::loongarch64; -diff --git a/src/llvm-project/llvm/include/llvm/BinaryFormat/ELF.h b/src/llvm-project/llvm/include/llvm/BinaryFormat/ELF.h -index 99e7a9868..43f09b493 100644 ---- a/src/llvm-project/llvm/include/llvm/BinaryFormat/ELF.h -+++ b/src/llvm-project/llvm/include/llvm/BinaryFormat/ELF.h -@@ -902,22 +902,13 @@ enum { - - // LoongArch Specific e_flags - enum : unsigned { -- // Reference: https://github.com/loongson/LoongArch-Documentation. -- // The last commit hash (main branch) is -- // 99016636af64d02dee05e39974d4c1e55875c45b. -- // Note that there is an open PR -- // https://github.com/loongson/LoongArch-Documentation/pull/47 -- // talking about using 0x1, 0x2, 0x3 for ILP32S/F/D and use EI_CLASS to -- // distinguish LP64 and ILP32. If this PR get merged, we will update -- // the definition here. -- // Base ABI Types. -- EF_LOONGARCH_BASE_ABI_LP64S = 0x1, // LP64 soft-float ABI -- EF_LOONGARCH_BASE_ABI_LP64F = 0x2, // LP64 single-float ABI -- EF_LOONGARCH_BASE_ABI_LP64D = 0x3, // LP64 double-float ABI -- EF_LOONGARCH_BASE_ABI_ILP32S = 0x5, // ILP32 soft-float ABI -- EF_LOONGARCH_BASE_ABI_ILP32F = 0x6, // ILP32 single-float ABI -- EF_LOONGARCH_BASE_ABI_ILP32D = 0x7, // ILP32 double-float ABI -- EF_LOONGARCH_BASE_ABI_MASK = 0x7, // Mask for selecting base ABI -+ // 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/src/llvm-project/llvm/include/llvm/IR/CMakeLists.txt b/src/llvm-project/llvm/include/llvm/IR/CMakeLists.txt -index 5151f9125..468d66379 100644 ---- a/src/llvm-project/llvm/include/llvm/IR/CMakeLists.txt -+++ b/src/llvm-project/llvm/include/llvm/IR/CMakeLists.txt -@@ -10,6 +10,7 @@ tablegen(LLVM IntrinsicsARM.h -gen-intrinsic-enums -intrinsic-prefix=arm) - tablegen(LLVM IntrinsicsBPF.h -gen-intrinsic-enums -intrinsic-prefix=bpf) - tablegen(LLVM IntrinsicsDirectX.h -gen-intrinsic-enums -intrinsic-prefix=dx) - tablegen(LLVM IntrinsicsHexagon.h -gen-intrinsic-enums -intrinsic-prefix=hexagon) -+tablegen(LLVM IntrinsicsLoongArch.h -gen-intrinsic-enums -intrinsic-prefix=loongarch) - tablegen(LLVM IntrinsicsMips.h -gen-intrinsic-enums -intrinsic-prefix=mips) - tablegen(LLVM IntrinsicsNVPTX.h -gen-intrinsic-enums -intrinsic-prefix=nvvm) - tablegen(LLVM IntrinsicsPowerPC.h -gen-intrinsic-enums -intrinsic-prefix=ppc) -diff --git a/src/llvm-project/llvm/include/llvm/IR/InlineAsm.h b/src/llvm-project/llvm/include/llvm/IR/InlineAsm.h -index 0a8d27aad..3f78eb41f 100644 ---- a/src/llvm-project/llvm/include/llvm/IR/InlineAsm.h -+++ b/src/llvm-project/llvm/include/llvm/IR/InlineAsm.h -@@ -269,6 +269,7 @@ public: - Constraint_Uy, - Constraint_X, - Constraint_Z, -+ Constraint_ZB, - Constraint_ZC, - Constraint_Zy, - -diff --git a/src/llvm-project/llvm/include/llvm/IR/Intrinsics.td b/src/llvm-project/llvm/include/llvm/IR/Intrinsics.td -index d46fa4fbf..76f2d66b7 100644 ---- a/src/llvm-project/llvm/include/llvm/IR/Intrinsics.td -+++ b/src/llvm-project/llvm/include/llvm/IR/Intrinsics.td -@@ -2053,3 +2053,4 @@ include "llvm/IR/IntrinsicsRISCV.td" - include "llvm/IR/IntrinsicsSPIRV.td" - include "llvm/IR/IntrinsicsVE.td" - include "llvm/IR/IntrinsicsDirectX.td" -+include "llvm/IR/IntrinsicsLoongArch.td" -diff --git a/src/llvm-project/llvm/include/llvm/IR/IntrinsicsLoongArch.td b/src/llvm-project/llvm/include/llvm/IR/IntrinsicsLoongArch.td -new file mode 100644 -index 000000000..1cbf1d300 ---- /dev/null -+++ b/src/llvm-project/llvm/include/llvm/IR/IntrinsicsLoongArch.td -@@ -0,0 +1,3657 @@ -+//===- IntrinsicsLoongArch.td - Defines LoongArch intrinsics ---------*- tablegen -*-===// -+// -+// The LLVM Compiler Infrastructure -+// -+// This file is distributed under the University of Illinois Open Source -+// License. See LICENSE.TXT for details. -+// -+//===----------------------------------------------------------------------===// -+// -+// This file defines all of the LoongArch-specific intrinsics. -+// -+//===----------------------------------------------------------------------===// -+ -+let TargetPrefix = "loongarch" in { // All intrinsics start with "llvm.loongarch.". -+ -+//===----------------------------------------------------------------------===// -+// 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_v4i32_ty], [llvm_v4f32_ty], [IntrNoMem]>; -+def int_loongarch_lsx_vfrintrm_d : ClangBuiltin<"__builtin_lsx_vfrintrm_d">, -+ Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty], [IntrNoMem]>; -+ -+def int_loongarch_lsx_vfrintrp_s : ClangBuiltin<"__builtin_lsx_vfrintrp_s">, -+ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty], [IntrNoMem]>; -+def int_loongarch_lsx_vfrintrp_d : ClangBuiltin<"__builtin_lsx_vfrintrp_d">, -+ Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty], [IntrNoMem]>; -+ -+def int_loongarch_lsx_vfrintrz_s : ClangBuiltin<"__builtin_lsx_vfrintrz_s">, -+ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty], [IntrNoMem]>; -+def int_loongarch_lsx_vfrintrz_d : ClangBuiltin<"__builtin_lsx_vfrintrz_d">, -+ Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty], [IntrNoMem]>; -+ -+def int_loongarch_lsx_vfrintrne_s : ClangBuiltin<"__builtin_lsx_vfrintrne_s">, -+ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty], [IntrNoMem]>; -+def int_loongarch_lsx_vfrintrne_d : ClangBuiltin<"__builtin_lsx_vfrintrne_d">, -+ Intrinsic<[llvm_v2i64_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_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_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]>; -+ -+//===----------------------------------------------------------------------===// -+//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_v8i32_ty], [llvm_v8f32_ty], [IntrNoMem]>; -+def int_loongarch_lasx_xvfrintrm_d : ClangBuiltin<"__builtin_lasx_xvfrintrm_d">, -+ Intrinsic<[llvm_v4i64_ty], [llvm_v4f64_ty], [IntrNoMem]>; -+ -+def int_loongarch_lasx_xvfrintrp_s : ClangBuiltin<"__builtin_lasx_xvfrintrp_s">, -+ Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty], [IntrNoMem]>; -+def int_loongarch_lasx_xvfrintrp_d : ClangBuiltin<"__builtin_lasx_xvfrintrp_d">, -+ Intrinsic<[llvm_v4i64_ty], [llvm_v4f64_ty], [IntrNoMem]>; -+ -+def int_loongarch_lasx_xvfrintrz_s : ClangBuiltin<"__builtin_lasx_xvfrintrz_s">, -+ Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty], [IntrNoMem]>; -+def int_loongarch_lasx_xvfrintrz_d : ClangBuiltin<"__builtin_lasx_xvfrintrz_d">, -+ Intrinsic<[llvm_v4i64_ty], [llvm_v4f64_ty], [IntrNoMem]>; -+ -+def int_loongarch_lasx_xvfrintrne_s : ClangBuiltin<"__builtin_lasx_xvfrintrne_s">, -+ Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty], [IntrNoMem]>; -+def int_loongarch_lasx_xvfrintrne_d : ClangBuiltin<"__builtin_lasx_xvfrintrne_d">, -+ Intrinsic<[llvm_v4i64_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_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_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 -+ -+def int_loongarch_cpucfg : ClangBuiltin<"__builtin_loongarch_cpucfg">, -+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>; -+ -+def int_loongarch_csrrd_w : ClangBuiltin<"__builtin_loongarch_csrrd_w">, -+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>; -+ -+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], []>; -+ -+} -diff --git a/src/llvm-project/llvm/lib/Analysis/ScalarEvolution.cpp b/src/llvm-project/llvm/lib/Analysis/ScalarEvolution.cpp -index 2958a5054..c784c27d3 100644 ---- a/src/llvm-project/llvm/lib/Analysis/ScalarEvolution.cpp -+++ b/src/llvm-project/llvm/lib/Analysis/ScalarEvolution.cpp -@@ -5917,8 +5917,13 @@ const SCEV *ScalarEvolution::createNodeForPHI(PHINode *PN) { - if (const SCEV *S = createNodeFromSelectLikePHI(PN)) - return S; - -+ // If the PHI has a single incoming value, follow that value, unless the -+ // PHI's incoming blocks are in a different loop, in which case doing so -+ // risks breaking LCSSA form. Instcombine would normally zap these, but -+ // it doesn't have DominatorTree information, so it may miss cases. - if (Value *V = simplifyInstruction(PN, {getDataLayout(), &TLI, &DT, &AC})) -- return getSCEV(V); -+ if (LI.replacementPreservesLCSSAForm(PN, V)) -+ return getSCEV(V); - - // If it's not a loop phi, we can't handle it yet. - return getUnknown(PN); -diff --git a/src/llvm-project/llvm/lib/Analysis/VectorUtils.cpp b/src/llvm-project/llvm/lib/Analysis/VectorUtils.cpp -index c4795a80e..bc20f33f1 100644 ---- a/src/llvm-project/llvm/lib/Analysis/VectorUtils.cpp -+++ b/src/llvm-project/llvm/lib/Analysis/VectorUtils.cpp -@@ -1110,6 +1110,12 @@ void InterleavedAccessInfo::collectConstStrideAccesses( - continue; - Type *ElementTy = getLoadStoreType(&I); - -+ // Currently, codegen doesn't support cases where the type size doesn't -+ // match the alloc size. Skip them for now. -+ uint64_t Size = DL.getTypeAllocSize(ElementTy); -+ if (Size * 8 != DL.getTypeSizeInBits(ElementTy)) -+ continue; -+ - // We don't check wrapping here because we don't know yet if Ptr will be - // part of a full group or a group with gaps. Checking wrapping for all - // pointers (even those that end up in groups with no gaps) will be overly -@@ -1121,7 +1127,6 @@ void InterleavedAccessInfo::collectConstStrideAccesses( - /*Assume=*/true, /*ShouldCheckWrap=*/false); - - const SCEV *Scev = replaceSymbolicStrideSCEV(PSE, Strides, Ptr); -- uint64_t Size = DL.getTypeAllocSize(ElementTy); - AccessStrideInfo[&I] = StrideDescriptor(Stride, Scev, Size, - getLoadStoreAlignment(&I)); - } -diff --git a/src/llvm-project/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/src/llvm-project/llvm/lib/CodeGen/PrologEpilogInserter.cpp -index 85d051cfd..a8d40edd8 100644 ---- a/src/llvm-project/llvm/lib/CodeGen/PrologEpilogInserter.cpp -+++ b/src/llvm-project/llvm/lib/CodeGen/PrologEpilogInserter.cpp -@@ -1237,7 +1237,13 @@ void PEI::insertZeroCallUsedRegs(MachineFunction &MF) { - if (!MO.isReg()) - continue; - -- for (MCPhysReg SReg : TRI.sub_and_superregs_inclusive(MO.getReg())) -+ MCRegister Reg = MO.getReg(); -+ -+ // This picks up sibling registers (e.q. %al -> %ah). -+ for (MCRegUnitIterator Unit(Reg, &TRI); Unit.isValid(); ++Unit) -+ RegsToZero.reset(*Unit); -+ -+ for (MCPhysReg SReg : TRI.sub_and_superregs_inclusive(Reg)) - RegsToZero.reset(SReg); - } - } -diff --git a/src/llvm-project/llvm/lib/CodeGen/RegAllocFast.cpp b/src/llvm-project/llvm/lib/CodeGen/RegAllocFast.cpp -index 9e4e26f13..cb552f212 100644 ---- a/src/llvm-project/llvm/lib/CodeGen/RegAllocFast.cpp -+++ b/src/llvm-project/llvm/lib/CodeGen/RegAllocFast.cpp -@@ -443,6 +443,9 @@ void RegAllocFast::spill(MachineBasicBlock::iterator Before, Register VirtReg, - SpilledOperandsMap[MO->getParent()].push_back(MO); - for (auto MISpilledOperands : SpilledOperandsMap) { - MachineInstr &DBG = *MISpilledOperands.first; -+ // We don't have enough support for tracking operands of DBG_VALUE_LISTs. -+ if (DBG.isDebugValueList()) -+ continue; - MachineInstr *NewDV = buildDbgValueForSpill( - *MBB, Before, *MISpilledOperands.first, FI, MISpilledOperands.second); - assert(NewDV->getParent() == MBB && "dangling parent pointer"); -diff --git a/src/llvm-project/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/src/llvm-project/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp -index 3d3b504c6..96cfe1fc0 100644 ---- a/src/llvm-project/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp -+++ b/src/llvm-project/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp -@@ -701,6 +701,9 @@ InstrEmitter::EmitDbgValue(SDDbgValue *SD, - MIB.addMetadata(Var); - MIB.addMetadata(Expr); - AddDbgValueLocationOps(MIB, DbgValDesc, LocationOps, VRBaseMap); -+ // FIXME: Fix rustc build error with lto=thin option on loongarch. -+ if (MF->getTarget().getTargetTriple().isLoongArch()) -+ return nullptr; - return &*MIB; - } - -diff --git a/src/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/src/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp -index 35650b9bd..ecdaef044 100644 ---- a/src/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp -+++ b/src/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp -@@ -9693,6 +9693,7 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const { - Entry.Alignment = Alignment; - CLI.getArgs().insert(CLI.getArgs().begin(), Entry); - CLI.NumFixedArgs += 1; -+ CLI.getArgs()[0].IndirectType = CLI.RetTy; - CLI.RetTy = Type::getVoidTy(CLI.RetTy->getContext()); - - // sret demotion isn't compatible with tail-calls, since the sret argument -diff --git a/src/llvm-project/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/src/llvm-project/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp -index 2badbe34a..88b8d1cf3 100644 ---- a/src/llvm-project/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp -+++ b/src/llvm-project/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp -@@ -207,6 +207,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: -diff --git a/src/llvm-project/llvm/lib/CodeGen/TypePromotion.cpp b/src/llvm-project/llvm/lib/CodeGen/TypePromotion.cpp -index 8dc8d381a..36e3c1245 100644 ---- a/src/llvm-project/llvm/lib/CodeGen/TypePromotion.cpp -+++ b/src/llvm-project/llvm/lib/CodeGen/TypePromotion.cpp -@@ -569,7 +569,7 @@ void IRPromoter::TruncateSinks() { - void IRPromoter::Cleanup() { - LLVM_DEBUG(dbgs() << "IR Promotion: Cleanup..\n"); - // Some zexts will now have become redundant, along with their trunc -- // operands, so remove them -+ // operands, so remove them. - for (auto *V : Visited) { - if (!isa(V)) - continue; -@@ -620,6 +620,8 @@ void IRPromoter::ConvertTruncs() { - ConstantInt *Mask = - ConstantInt::get(SrcTy, APInt::getMaxValue(NumBits).getZExtValue()); - Value *Masked = Builder.CreateAnd(Trunc->getOperand(0), Mask); -+ if (SrcTy != ExtTy) -+ Masked = Builder.CreateTrunc(Masked, ExtTy); - - if (auto *I = dyn_cast(Masked)) - NewInsts.insert(I); -diff --git a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp -index aec42d295..2be2a12aa 100644 ---- a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp -+++ b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp -@@ -413,12 +413,12 @@ unsigned DWARFVerifier::verifyIndex(StringRef Name, - uint64_t Sig = E.getSignature(); - if (!E.getContributions()) - continue; -- for (auto P : enumerate(InfoColumnKind == DW_SECT_INFO -+ for (auto E : enumerate(InfoColumnKind == DW_SECT_INFO - ? makeArrayRef(E.getContributions(), - Index.getColumnKinds().size()) - : makeArrayRef(E.getContribution(), 1))) { -- const DWARFUnitIndex::Entry::SectionContribution &SC = P.value(); -- int Col = P.index(); -+ const DWARFUnitIndex::Entry::SectionContribution &SC = E.value(); -+ int Col = E.index(); - if (SC.Length == 0) - continue; - if (!Sections[Col]) -diff --git a/src/llvm-project/llvm/lib/IR/AutoUpgrade.cpp b/src/llvm-project/llvm/lib/IR/AutoUpgrade.cpp -index 75594f90c..b9962da1d 100644 ---- a/src/llvm-project/llvm/lib/IR/AutoUpgrade.cpp -+++ b/src/llvm-project/llvm/lib/IR/AutoUpgrade.cpp -@@ -1040,7 +1040,7 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { - Name, F->getParent()); - - // The new function may also need remangling. -- if (auto Result = llvm::Intrinsic::remangleIntrinsicFunction(F)) -+ if (auto Result = llvm::Intrinsic::remangleIntrinsicFunction(NewFn)) - NewFn = *Result; - return true; - } -diff --git a/src/llvm-project/llvm/lib/IR/Function.cpp b/src/llvm-project/llvm/lib/IR/Function.cpp -index d41381337..3ef27601f 100644 ---- a/src/llvm-project/llvm/lib/IR/Function.cpp -+++ b/src/llvm-project/llvm/lib/IR/Function.cpp -@@ -38,6 +38,7 @@ - #include "llvm/IR/IntrinsicsBPF.h" - #include "llvm/IR/IntrinsicsDirectX.h" - #include "llvm/IR/IntrinsicsHexagon.h" -+#include "llvm/IR/IntrinsicsLoongArch.h" - #include "llvm/IR/IntrinsicsMips.h" - #include "llvm/IR/IntrinsicsNVPTX.h" - #include "llvm/IR/IntrinsicsPowerPC.h" -diff --git a/src/llvm-project/llvm/lib/MC/MCObjectFileInfo.cpp b/src/llvm-project/llvm/lib/MC/MCObjectFileInfo.cpp -index d6fe952c0..254c2fa60 100644 ---- a/src/llvm-project/llvm/lib/MC/MCObjectFileInfo.cpp -+++ b/src/llvm-project/llvm/lib/MC/MCObjectFileInfo.cpp -@@ -332,6 +332,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/src/llvm-project/llvm/lib/Object/RelocationResolver.cpp b/src/llvm-project/llvm/lib/Object/RelocationResolver.cpp -index e14301663..ec54d7b59 100644 ---- a/src/llvm-project/llvm/lib/Object/RelocationResolver.cpp -+++ b/src/llvm-project/llvm/lib/Object/RelocationResolver.cpp -@@ -511,6 +511,28 @@ 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_32: -+ case ELF::R_LARCH_64: -+ return true; -+ default: -+ return false; -+ } -+} -+ -+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_32: -+ return (S + Addend) & 0xFFFFFFFF; -+ case ELF::R_LARCH_64: -+ return S + Addend; -+ default: -+ llvm_unreachable("Invalid relocation type"); -+ } -+} -+ - static bool supportsCOFFX86(uint64_t Type) { - switch (Type) { - case COFF::IMAGE_REL_I386_SECREL: -@@ -725,6 +747,8 @@ getRelocationResolver(const ObjectFile &Obj) { - return {supportsAmdgpu, resolveAmdgpu}; - case Triple::riscv64: - return {supportsRISCV, resolveRISCV}; -+ case Triple::loongarch64: -+ return {supportsLoongArch, resolveLoongArch}; - default: - return {nullptr, nullptr}; - } -@@ -760,6 +784,8 @@ getRelocationResolver(const ObjectFile &Obj) { - return {supportsRISCV, resolveRISCV}; - case Triple::csky: - return {supportsCSKY, resolveCSKY}; -+ case Triple::loongarch32: -+ return {supportsLoongArch, resolveLoongArch}; - default: - return {nullptr, nullptr}; - } -diff --git a/src/llvm-project/llvm/lib/ObjectYAML/ELFYAML.cpp b/src/llvm-project/llvm/lib/ObjectYAML/ELFYAML.cpp -index 9ad2c4135..b778006cf 100644 ---- a/src/llvm-project/llvm/lib/ObjectYAML/ELFYAML.cpp -+++ b/src/llvm-project/llvm/lib/ObjectYAML/ELFYAML.cpp -@@ -518,14 +518,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_BASE_ABI_ILP32S, EF_LOONGARCH_BASE_ABI_MASK); -- BCaseMask(EF_LOONGARCH_BASE_ABI_ILP32F, EF_LOONGARCH_BASE_ABI_MASK); -- BCaseMask(EF_LOONGARCH_BASE_ABI_ILP32D, EF_LOONGARCH_BASE_ABI_MASK); -- BCaseMask(EF_LOONGARCH_BASE_ABI_LP64S, EF_LOONGARCH_BASE_ABI_MASK); -- BCaseMask(EF_LOONGARCH_BASE_ABI_LP64F, EF_LOONGARCH_BASE_ABI_MASK); -- BCaseMask(EF_LOONGARCH_BASE_ABI_LP64D, EF_LOONGARCH_BASE_ABI_MASK); -- break; - case ELF::EM_RISCV: - BCase(EF_RISCV_RVC); - BCaseMask(EF_RISCV_FLOAT_ABI_SOFT, EF_RISCV_FLOAT_ABI); -diff --git a/src/llvm-project/llvm/lib/Support/CMakeLists.txt b/src/llvm-project/llvm/lib/Support/CMakeLists.txt -index 5044b2639..ff23ec74d 100644 ---- a/src/llvm-project/llvm/lib/Support/CMakeLists.txt -+++ b/src/llvm-project/llvm/lib/Support/CMakeLists.txt -@@ -22,11 +22,19 @@ if (HAS_WERROR_GLOBAL_CTORS) - endif() - - if(LLVM_ENABLE_ZLIB) -- set(imported_libs ZLIB::ZLIB) -+ list(APPEND imported_libs ZLIB::ZLIB) - endif() - - if(LLVM_ENABLE_ZSTD) -- list(APPEND imported_libs zstd::libzstd_shared) -+ if(TARGET zstd::libzstd_shared AND NOT LLVM_USE_STATIC_ZSTD) -+ set(zstd_target zstd::libzstd_shared) -+ else() -+ set(zstd_target zstd::libzstd_static) -+ endif() -+endif() -+ -+if(LLVM_ENABLE_ZSTD) -+ list(APPEND imported_libs ${zstd_target}) - endif() - - if( MSVC OR MINGW ) -@@ -51,9 +59,7 @@ elseif( CMAKE_HOST_UNIX ) - if( LLVM_ENABLE_TERMINFO ) - set(imported_libs ${imported_libs} Terminfo::terminfo) - endif() -- if( LLVM_ENABLE_THREADS AND (HAVE_LIBATOMIC OR HAVE_CXX_LIBATOMICS64) ) -- set(system_libs ${system_libs} atomic) -- endif() -+ set(system_libs ${system_libs} ${LLVM_ATOMIC_LIB}) - set(system_libs ${system_libs} ${LLVM_PTHREAD_LIB}) - if( UNIX AND NOT (BEOS OR HAIKU) ) - set(system_libs ${system_libs} m) -@@ -300,11 +306,12 @@ if(LLVM_ENABLE_ZSTD) - # CMAKE_BUILD_TYPE is only meaningful to single-configuration generators. - if(CMAKE_BUILD_TYPE) - string(TOUPPER ${CMAKE_BUILD_TYPE} build_type) -- get_property(zstd_library TARGET zstd::libzstd_shared PROPERTY LOCATION_${build_type}) -+ get_property(zstd_library TARGET ${zstd_target} PROPERTY LOCATION_${build_type}) - endif() - if(NOT zstd_library) -- get_property(zstd_library TARGET zstd::libzstd_shared PROPERTY LOCATION) -+ get_property(zstd_library TARGET ${zstd_target} PROPERTY LOCATION) - endif() -+ get_library_name(${zstd_library} zstd_library) - set(llvm_system_libs ${llvm_system_libs} "${zstd_library}") - endif() - -diff --git a/src/llvm-project/llvm/lib/Support/Triple.cpp b/src/llvm-project/llvm/lib/Support/Triple.cpp -index 6696d158b..2c07c1a29 100644 ---- a/src/llvm-project/llvm/lib/Support/Triple.cpp -+++ b/src/llvm-project/llvm/lib/Support/Triple.cpp -@@ -257,6 +257,7 @@ 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 GNUX32: return "gnux32"; -diff --git a/src/llvm-project/llvm/lib/Support/UnicodeNameToCodepoint.cpp b/src/llvm-project/llvm/lib/Support/UnicodeNameToCodepoint.cpp -index 194e8d88a..1e8aebf1b 100644 ---- a/src/llvm-project/llvm/lib/Support/UnicodeNameToCodepoint.cpp -+++ b/src/llvm-project/llvm/lib/Support/UnicodeNameToCodepoint.cpp -@@ -499,8 +499,8 @@ nearestMatchesForCodepointName(StringRef Pattern, std::size_t MaxMatchesCount) { - // Filling (and overriding) the matrix for the name fragment of each node - // iteratively. CompleteName is used to collect the actual name of potential - // match, respecting case and spacing. -- std::function VisitNode; -- VisitNode = [&](const Node &N, std::size_t Row) -> void { -+ auto VisitNode = [&](const Node &N, std::size_t Row, -+ auto &VisitNode) -> void { - std::size_t J = 0; - for (; J < N.Name.size(); J++) { - if (!isAlnum(N.Name[J])) -@@ -533,7 +533,7 @@ nearestMatchesForCodepointName(StringRef Pattern, std::size_t MaxMatchesCount) { - ChildOffset += C.Size; - if (!C.isValid()) - break; -- VisitNode(C, Row); -+ VisitNode(C, Row, VisitNode); - if (!C.HasSibling) - break; - } -@@ -541,7 +541,7 @@ nearestMatchesForCodepointName(StringRef Pattern, std::size_t MaxMatchesCount) { - }; - - Node Root = createRoot(); -- VisitNode(Root, 1); -+ VisitNode(Root, 1, VisitNode); - return Matches; - } - -diff --git a/src/llvm-project/llvm/lib/Support/Unix/Path.inc b/src/llvm-project/llvm/lib/Support/Unix/Path.inc -index 6f85ee0db..2ae7c6dc4 100644 ---- a/src/llvm-project/llvm/lib/Support/Unix/Path.inc -+++ b/src/llvm-project/llvm/lib/Support/Unix/Path.inc -@@ -1476,7 +1476,7 @@ namespace fs { - std::error_code copy_file(const Twine &From, const Twine &To) { - std::string FromS = From.str(); - std::string ToS = To.str(); --#if 0 && __has_builtin(__builtin_available) -+#if __has_builtin(__builtin_available) - if (__builtin_available(macos 10.12, *)) { - // Optimistically try to use clonefile() and handle errors, rather than - // calling stat() to see if it'll work. -diff --git a/src/llvm-project/llvm/lib/Support/Unix/Signals.inc b/src/llvm-project/llvm/lib/Support/Unix/Signals.inc -index bf145bffe..23ac012b9 100644 ---- a/src/llvm-project/llvm/lib/Support/Unix/Signals.inc -+++ b/src/llvm-project/llvm/lib/Support/Unix/Signals.inc -@@ -432,10 +432,6 @@ void llvm::sys::SetOneShotPipeSignalFunction(void (*Handler)()) { - } - - void llvm::sys::DefaultOneShotPipeSignalHandler() { -- // UNIX03 conformance requires a non-zero exit code and an error message -- // to stderr when writing to a closed stdout fails. -- errs() << "error: write on a pipe with no reader\n"; -- - // Send a special return code that drivers can check for, from sysexits.h. - exit(EX_IOERR); - } -diff --git a/src/llvm-project/llvm/lib/Support/Windows/Threading.inc b/src/llvm-project/llvm/lib/Support/Windows/Threading.inc -index ed4b0d316..11f34817d 100644 ---- a/src/llvm-project/llvm/lib/Support/Windows/Threading.inc -+++ b/src/llvm-project/llvm/lib/Support/Windows/Threading.inc -@@ -144,11 +144,6 @@ struct ProcessorGroup { - - template - static bool IterateProcInfo(LOGICAL_PROCESSOR_RELATIONSHIP Relationship, F Fn) { --#if !defined(_WIN64) && defined(__MINGW64_VERSION_MAJOR) && __MINGW64_VERSION_MAJOR < 7 -- // `GetLogicalProcessorInformationEx@12` was only added to i386 mingw-w64 in v7.0.0 -- // https://github.com/mingw-w64/mingw-w64/commit/24842d45e025db0d38fa2bbd932b95a83282efa2#diff-faf1d8a1556e75a84b7cef2e89512e79R634 -- return false; --#else - DWORD Len = 0; - BOOL R = ::GetLogicalProcessorInformationEx(Relationship, NULL, &Len); - if (R || GetLastError() != ERROR_INSUFFICIENT_BUFFER) { -@@ -169,7 +164,6 @@ static bool IterateProcInfo(LOGICAL_PROCESSOR_RELATIONSHIP Relationship, F Fn) { - } - free(Info); - return true; --#endif - } - - static ArrayRef getProcessorGroups() { -diff --git a/src/llvm-project/llvm/lib/Support/X86TargetParser.cpp b/src/llvm-project/llvm/lib/Support/X86TargetParser.cpp -index 2567f3ed8..0daaa6d81 100644 ---- a/src/llvm-project/llvm/lib/Support/X86TargetParser.cpp -+++ b/src/llvm-project/llvm/lib/Support/X86TargetParser.cpp -@@ -203,10 +203,10 @@ constexpr FeatureBitset FeaturesTigerlake = - FeatureCLWB | FeatureMOVDIRI | FeatureSHSTK | FeatureKL | FeatureWIDEKL; - constexpr FeatureBitset FeaturesSapphireRapids = - FeaturesICLServer | FeatureAMX_BF16 | FeatureAMX_INT8 | FeatureAMX_TILE | -- FeatureAVX512BF16 | FeatureAVX512FP16 | FeatureAVX512VP2INTERSECT | -- FeatureAVXVNNI | FeatureCLDEMOTE | FeatureENQCMD | FeatureMOVDIR64B | -- FeatureMOVDIRI | FeaturePTWRITE | FeatureSERIALIZE | FeatureSHSTK | -- FeatureTSXLDTRK | FeatureUINTR | FeatureWAITPKG; -+ FeatureAVX512BF16 | FeatureAVX512FP16 | FeatureAVXVNNI | FeatureCLDEMOTE | -+ FeatureENQCMD | FeatureMOVDIR64B | FeatureMOVDIRI | FeaturePTWRITE | -+ FeatureSERIALIZE | FeatureSHSTK | FeatureTSXLDTRK | FeatureUINTR | -+ FeatureWAITPKG; - - // Intel Atom processors. - // Bonnell has feature parity with Core2 and adds MOVBE. -@@ -367,7 +367,7 @@ constexpr ProcInfo Processors[] = { - // Tigerlake microarchitecture based processors. - { {"tigerlake"}, CK_Tigerlake, FEATURE_AVX512VP2INTERSECT, FeaturesTigerlake }, - // Sapphire Rapids microarchitecture based processors. -- { {"sapphirerapids"}, CK_SapphireRapids, FEATURE_AVX512VP2INTERSECT, FeaturesSapphireRapids }, -+ { {"sapphirerapids"}, CK_SapphireRapids, FEATURE_AVX512BF16, FeaturesSapphireRapids }, - // Alderlake microarchitecture based processors. - { {"alderlake"}, CK_Alderlake, FEATURE_AVX2, FeaturesAlderlake }, - // Knights Landing processor. -diff --git a/src/llvm-project/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/src/llvm-project/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp -index c28216048..06e21f90e 100644 ---- a/src/llvm-project/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp -+++ b/src/llvm-project/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp -@@ -5805,7 +5805,7 @@ SDValue AArch64TargetLowering::LowerFormalArguments( - assert(!Res && "Call operand has unhandled type"); - (void)Res; - } -- SmallVector ArgValues; -+ - unsigned ExtraArgLocs = 0; - for (unsigned i = 0, e = Ins.size(); i != e; ++i) { - CCValAssign &VA = ArgLocs[i - ExtraArgLocs]; -@@ -6157,17 +6157,10 @@ void AArch64TargetLowering::saveVarArgRegisters(CCState &CCInfo, - /// appropriate copies out of appropriate physical registers. - SDValue AArch64TargetLowering::LowerCallResult( - SDValue Chain, SDValue InFlag, CallingConv::ID CallConv, bool isVarArg, -- const SmallVectorImpl &Ins, const SDLoc &DL, -+ const SmallVectorImpl &RVLocs, const SDLoc &DL, - SelectionDAG &DAG, SmallVectorImpl &InVals, bool isThisReturn, - SDValue ThisVal) const { -- CCAssignFn *RetCC = CCAssignFnForReturn(CallConv); -- // Assign locations to each value returned by this call. -- SmallVector RVLocs; - DenseMap CopiedRegs; -- CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs, -- *DAG.getContext()); -- CCInfo.AnalyzeCallResult(Ins, RetCC); -- - // Copy all of the result registers out of their specified physreg. - for (unsigned i = 0; i != RVLocs.size(); ++i) { - CCValAssign VA = RVLocs[i]; -@@ -6508,17 +6501,39 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI, - GuardWithBTI = FuncInfo->branchTargetEnforcement(); - } - -+ // Analyze operands of the call, assigning locations to each operand. -+ SmallVector ArgLocs; -+ CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext()); -+ -+ if (IsVarArg) { -+ unsigned NumArgs = Outs.size(); -+ -+ for (unsigned i = 0; i != NumArgs; ++i) { -+ if (!Outs[i].IsFixed && Outs[i].VT.isScalableVector()) -+ report_fatal_error("Passing SVE types to variadic functions is " -+ "currently not supported"); -+ } -+ } -+ -+ analyzeCallOperands(*this, Subtarget, CLI, CCInfo); -+ -+ CCAssignFn *RetCC = CCAssignFnForReturn(CallConv); -+ // Assign locations to each value returned by this call. -+ SmallVector RVLocs; -+ CCState RetCCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs, -+ *DAG.getContext()); -+ RetCCInfo.AnalyzeCallResult(Ins, RetCC); -+ - // Check callee args/returns for SVE registers and set calling convention - // accordingly. - if (CallConv == CallingConv::C || CallConv == CallingConv::Fast) { -- bool CalleeOutSVE = any_of(Outs, [](ISD::OutputArg &Out){ -- return Out.VT.isScalableVector(); -- }); -- bool CalleeInSVE = any_of(Ins, [](ISD::InputArg &In){ -- return In.VT.isScalableVector(); -- }); -- -- if (CalleeInSVE || CalleeOutSVE) -+ auto HasSVERegLoc = [](CCValAssign &Loc) { -+ if (!Loc.isRegLoc()) -+ return false; -+ return AArch64::ZPRRegClass.contains(Loc.getLocReg()) || -+ AArch64::PPRRegClass.contains(Loc.getLocReg()); -+ }; -+ if (any_of(RVLocs, HasSVERegLoc) || any_of(ArgLocs, HasSVERegLoc)) - CallConv = CallingConv::AArch64_SVE_VectorCall; - } - -@@ -6540,22 +6555,6 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI, - report_fatal_error("failed to perform tail call elimination on a call " - "site marked musttail"); - -- // Analyze operands of the call, assigning locations to each operand. -- SmallVector ArgLocs; -- CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext()); -- -- if (IsVarArg) { -- unsigned NumArgs = Outs.size(); -- -- for (unsigned i = 0; i != NumArgs; ++i) { -- if (!Outs[i].IsFixed && Outs[i].VT.isScalableVector()) -- report_fatal_error("Passing SVE types to variadic functions is " -- "currently not supported"); -- } -- } -- -- analyzeCallOperands(*this, Subtarget, CLI, CCInfo); -- - // Get a count of how many bytes are to be pushed on the stack. - unsigned NumBytes = CCInfo.getNextStackOffset(); - -@@ -6961,7 +6960,7 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI, - - // Handle result values, copying them out of physregs into vregs that we - // return. -- return LowerCallResult(Chain, InFlag, CallConv, IsVarArg, Ins, DL, DAG, -+ return LowerCallResult(Chain, InFlag, CallConv, IsVarArg, RVLocs, DL, DAG, - InVals, IsThisReturn, - IsThisReturn ? OutVals[0] : SDValue()); - } -diff --git a/src/llvm-project/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/src/llvm-project/llvm/lib/Target/AArch64/AArch64ISelLowering.h -index 1ba2e2f31..ff3bfe897 100644 ---- a/src/llvm-project/llvm/lib/Target/AArch64/AArch64ISelLowering.h -+++ b/src/llvm-project/llvm/lib/Target/AArch64/AArch64ISelLowering.h -@@ -894,7 +894,7 @@ private: - - SDValue LowerCallResult(SDValue Chain, SDValue InFlag, - CallingConv::ID CallConv, bool isVarArg, -- const SmallVectorImpl &Ins, -+ const SmallVectorImpl &RVLocs, - const SDLoc &DL, SelectionDAG &DAG, - SmallVectorImpl &InVals, bool isThisReturn, - SDValue ThisVal) const; -diff --git a/src/llvm-project/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/src/llvm-project/llvm/lib/Target/AMDGPU/SIISelLowering.cpp -index f7d139adc..f6b7d1ffc 100644 ---- a/src/llvm-project/llvm/lib/Target/AMDGPU/SIISelLowering.cpp -+++ b/src/llvm-project/llvm/lib/Target/AMDGPU/SIISelLowering.cpp -@@ -249,6 +249,7 @@ SITargetLowering::SITargetLowering(const TargetMachine &TM, - case ISD::STORE: - case ISD::BUILD_VECTOR: - case ISD::BITCAST: -+ case ISD::UNDEF: - case ISD::EXTRACT_VECTOR_ELT: - case ISD::INSERT_VECTOR_ELT: - case ISD::EXTRACT_SUBVECTOR: -@@ -516,6 +517,7 @@ SITargetLowering::SITargetLowering(const TargetMachine &TM, - case ISD::STORE: - case ISD::BUILD_VECTOR: - case ISD::BITCAST: -+ case ISD::UNDEF: - case ISD::EXTRACT_VECTOR_ELT: - case ISD::INSERT_VECTOR_ELT: - case ISD::INSERT_SUBVECTOR: -diff --git a/src/llvm-project/llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp b/src/llvm-project/llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp -index 3c102463b..cbfd2bc68 100644 ---- a/src/llvm-project/llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp -+++ b/src/llvm-project/llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp -@@ -1036,7 +1036,7 @@ InstructionCost ARMTTIImpl::getCmpSelInstrCost(unsigned Opcode, Type *ValTy, - // split, we may need an expensive shuffle to get two in sync. This has the - // effect of making larger than legal compares (v8i32 for example) - // expensive. -- if (LT.second.getVectorNumElements() > 2) { -+ if (LT.second.isVector() && LT.second.getVectorNumElements() > 2) { - if (LT.first > 1) - return LT.first * BaseCost + - BaseT::getScalarizationOverhead(VecCondTy, true, false); -diff --git a/src/llvm-project/llvm/lib/Target/LoongArch/AsmParser/CMakeLists.txt b/src/llvm-project/llvm/lib/Target/LoongArch/AsmParser/CMakeLists.txt -index 296160531..cb8b768d5 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/AsmParser/CMakeLists.txt -+++ b/src/llvm-project/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/src/llvm-project/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp b/src/llvm-project/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp -index 9793c7bc3..2d35dfd0c 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp -+++ b/src/llvm-project/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,551 +6,2278 @@ - // - //===----------------------------------------------------------------------===// - --#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 "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/Triple.h" -+#include "llvm/ADT/Twine.h" -+#include "llvm/BinaryFormat/ELF.h" - #include "llvm/MC/MCContext.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/SubtargetFeature.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 -+#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(); } -+ LoongArchTargetStreamer &getTargetStreamer() { -+ MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer(); -+ return static_cast(TS); -+ } -+ -+ 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; - -- /// Parse a register as used in CFI directives. -+ // 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(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; - OperandMatchResultTy tryParseRegister(unsigned &RegNo, SMLoc &StartLoc, - SMLoc &EndLoc) override; - -+ bool mnemonicIsValid(StringRef Mnemonic); -+ - bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, - SMLoc NameLoc, OperandVector &Operands) override; - -- bool ParseDirective(AsmToken DirectiveID) override { return true; } -+ 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, -+ }; - -- bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, -- OperandVector &Operands, MCStreamer &Out, -- uint64_t &ErrorInfo, -- bool MatchingInlineAsm) override; -+ // Expands assembly pseudo instructions. -+ MacroExpanderResultTy tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, -+ MCStreamer &Out, -+ const MCSubtargetInfo *STI); - -- unsigned checkTargetMatchPredicate(MCInst &Inst) override; -+ bool expandLoadImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, -+ const MCSubtargetInfo *STI); - -- unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, -- unsigned Kind) override; -+ bool expandLoadAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, -+ const MCSubtargetInfo *STI); - -- bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo, -- int64_t Lower, int64_t Upper, Twine Msg); -+ bool reportParseError(Twine ErrorMsg); - -- /// Helper for processing MC instructions that have been successfully matched -- /// by MatchAndEmitInstruction. -- bool processInstruction(MCInst &Inst, SMLoc IDLoc, OperandVector &Operands, -- MCStreamer &Out); -+ bool parseMemOffset(const MCExpr *&Res); - --// Auto-generated instruction matching functions. --#define GET_ASSEMBLER_HEADER --#include "LoongArchGenAsmMatcher.inc" -+ bool isEvaluated(const MCExpr *Expr); -+ bool parseDirectiveSet(); -+ -+ bool parseSetAssignment(); -+ -+ bool parseInternalDirectiveReallowModule(); -+ -+ int matchCPURegisterName(StringRef Symbol); -+ -+ int matchFPURegisterName(StringRef Name); -+ -+ int matchFCFRRegisterName(StringRef Name); -+ int matchFCSRRegisterName(StringRef Name); -+ -+ int matchLSX128RegisterName(StringRef Name); -+ -+ int matchLASX256RegisterName(StringRef Name); -+ -+ bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, -+ const MCSubtargetInfo *STI); -+ -+ // 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); -+ -+ void setFeatureBits(uint64_t Feature, StringRef FeatureString) { -+ if (!(getSTI().getFeatureBits()[Feature])) { -+ MCSubtargetInfo &STI = copySTI(); -+ setAvailableFeatures( -+ ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); -+ AssemblerOptions.back()->setFeatures(STI.getFeatureBits()); -+ } -+ } - -- OperandMatchResultTy parseRegister(OperandVector &Operands); -- OperandMatchResultTy parseImmediate(OperandVector &Operands); -+ void clearFeatureBits(uint64_t Feature, StringRef FeatureString) { -+ if (getSTI().getFeatureBits()[Feature]) { -+ MCSubtargetInfo &STI = copySTI(); -+ setAvailableFeatures( -+ ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); -+ AssemblerOptions.back()->setFeatures(STI.getFeatureBits()); -+ } -+ } -+ -+ void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) { -+ setFeatureBits(Feature, FeatureString); -+ AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits()); -+ } - -- bool parseOperand(OperandVector &Operands, StringRef Mnemonic); -+ 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_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 - }; - -- 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(".hword", ".2byte"); -+ parser.addAliasForDirective(".word", ".4byte"); -+ parser.addAliasForDirective(".dword", ".8byte"); - - // Initialize the set of available features. -- setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); -+ setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits())); -+ -+ // Remember the initial assembler options. The user can not modify these. -+ AssemblerOptions.push_back( -+ std::make_unique(getSTI().getFeatureBits())); -+ -+ // Create an assembler options environment for the user to modify. -+ AssemblerOptions.push_back( -+ std::make_unique(getSTI().getFeatureBits())); -+ -+ getTargetStreamer().updateABIInfo(*this); -+ -+ CurrentFn = nullptr; -+ -+ IsPicEnabled = getContext().getObjectFileInfo()->isPositionIndependent(); -+ } -+ -+ bool is64Bit() const { -+ return getSTI().getFeatureBits()[LoongArch::Feature64Bit]; -+ } -+ -+ bool isFP64bit() const { -+ return getSTI().getFeatureBits()[LoongArch::FeatureFP64Bit]; -+ } -+ -+ 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(); } -+ -+ bool hasLSX() const { -+ return getSTI().getFeatureBits()[LoongArch::FeatureLSX]; -+ } -+ -+ bool hasLASX() const { -+ return getSTI().getFeatureBits()[LoongArch::FeatureLASX]; -+ } -+ -+ bool inPicMode() { -+ return IsPicEnabled; -+ } -+ -+ bool useSoftFloat() const { -+ return getSTI().getFeatureBits()[LoongArch::FeatureSoftFloat]; -+ } -+ -+ 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 -+ } - } - }; - --// Instances of this class represent a parsed LoongArch machine instruction. -+/// LoongArchOperand - Instances of this class represent a parsed LoongArch machine -+/// instruction. - class LoongArchOperand : public MCParsedAsmOperand { -- enum class KindTy { -- Token, -- Register, -- Immediate, -+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 -+ }; -+ -+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; - -- struct RegOp { -- MCRegister RegNum; -+public: -+ LoongArchOperand(KindTy K, LoongArchAsmParser &Parser) -+ : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {} -+ -+ ~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; -+ } -+ } -+ -+private: -+ /// For diagnostics, and checking the assembler temporary -+ LoongArchAsmParser &AsmParser; -+ -+ struct Token { -+ const char *Data; -+ unsigned Length; -+ }; -+ -+ 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; - }; - - struct ImmOp { - const MCExpr *Val; - }; - -- SMLoc StartLoc, EndLoc; -- union { -- StringRef Tok; -- struct RegOp Reg; -- struct ImmOp Imm; -+ struct MemOp { -+ LoongArchOperand *Base; -+ const MCExpr *Off; - }; - --public: -- LoongArchOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} -+ struct RegListOp { -+ SmallVector *List; -+ }; - -- 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; } -+ union { -+ struct Token Tok; -+ struct RegIdxOp RegIdx; -+ struct ImmOp Imm; -+ struct MemOp Mem; -+ struct RegListOp RegList; -+ }; - -- static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm) { -- if (auto CE = dyn_cast(Expr)) { -- Imm = CE->getValue(); -- return true; -- } -+ SMLoc StartLoc, EndLoc; - -- return false; -+ /// 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; - } - -- template bool isUImm() const { -- if (!isImm()) -- return false; -- -- int64_t Imm; -- bool IsConstantImm = evaluateConstantImm(getImm(), Imm); -- return IsConstantImm && isUInt(Imm - P); -+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); - } - -- template bool isSImm() const { -- if (!isImm()) -- return false; -- -- int64_t Imm; -- bool IsConstantImm = evaluateConstantImm(getImm(), Imm); -- return IsConstantImm && isShiftedInt(Imm); -- } -- -- bool isUImm2() const { return isUImm<2>(); } -- bool isUImm2plus1() const { return isUImm<2, 1>(); } -- bool isUImm3() const { return isUImm<3>(); } -- bool isUImm5() const { return isUImm<5>(); } -- bool isUImm6() const { return isUImm<6>(); } -- bool isUImm8() const { return isUImm<8>(); } -- bool isUImm12() const { return isUImm<12>(); } -- bool isUImm14() const { return isUImm<14>(); } -- bool isUImm15() const { return isUImm<15>(); } -- bool isSImm12() const { return isSImm<12>(); } -- bool isSImm14lsl2() const { return isSImm<14, 2>(); } -- bool isSImm16() const { return isSImm<16>(); } -- bool isSImm16lsl2() const { return isSImm<16, 2>(); } -- bool isSImm20() const { return isSImm<20>(); } -- bool isSImm21lsl2() const { return isSImm<21, 2>(); } -- bool isSImm26lsl2() const { return isSImm<26, 2>(); } -- -- /// 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; } -- -- 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 = [](unsigned 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 { -- assert(N == 1 && "Invalid number of operands!"); -- Inst.addOperand(MCOperand::createReg(getReg())); -+ llvm_unreachable("Use a custom parser instead"); - } -- void addImmOperands(MCInst &Inst, unsigned N) const { -+ -+ /// 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!"); -- 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 addGPR32NonZeroAsmRegOperands(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 addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const { -+ assert(N == 1 && "Invalid number of operands!"); -+ Inst.addOperand(MCOperand::createReg(getGPR32Reg())); -+ } - --// 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); -+ void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const { -+ assert(N == 1 && "Invalid number of operands!"); -+ Inst.addOperand(MCOperand::createReg(getGPRMM16Reg())); -+ } - -- 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(unsigned &RegNo, 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())); -+ } - --OperandMatchResultTy LoongArchAsmParser::tryParseRegister(unsigned &RegNo, -- 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())); -+ } - --OperandMatchResultTy --LoongArchAsmParser::parseRegister(OperandVector &Operands) { -- if (getLexer().getTok().isNot(AsmToken::Dollar)) -- return MatchOperand_NoMatch; -+ void addGPRMM16AsmRegMovePPairSecondOperands(MCInst &Inst, -+ unsigned N) const { -+ assert(N == 1 && "Invalid number of operands!"); -+ Inst.addOperand(MCOperand::createReg(getGPRMM16Reg())); -+ } - -- // Eat the $ prefix. -- getLexer().Lex(); -- if (getLexer().getKind() != AsmToken::Identifier) -- return MatchOperand_NoMatch; -+ /// 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())); -+ } - -- StringRef Name = getLexer().getTok().getIdentifier(); -- MCRegister RegNo; -- matchRegisterNameHelper(RegNo, Name); -- if (RegNo == LoongArch::NoRegister) -- return MatchOperand_NoMatch; -+ void addStrictlyFGR64AsmRegOperands(MCInst &Inst, unsigned N) const { -+ assert(N == 1 && "Invalid number of operands!"); -+ Inst.addOperand(MCOperand::createReg(getFGR64Reg())); -+ } - -- SMLoc S = getLoc(); -- SMLoc E = SMLoc::getFromPointer(S.getPointer() + Name.size()); -- getLexer().Lex(); -- Operands.push_back(LoongArchOperand::createReg(RegNo, S, E)); -+ void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const { -+ assert(N == 1 && "Invalid number of operands!"); -+ Inst.addOperand(MCOperand::createReg(getFGR64Reg())); -+ } - -- return MatchOperand_Success; --} -+ void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const { -+ assert(N == 1 && "Invalid number of operands!"); -+ Inst.addOperand(MCOperand::createReg(getFGR32Reg())); -+ } - --OperandMatchResultTy --LoongArchAsmParser::parseImmediate(OperandVector &Operands) { -- SMLoc S = getLoc(); -- SMLoc E; -- const MCExpr *Res; -+ void addStrictlyFGR32AsmRegOperands(MCInst &Inst, unsigned N) const { -+ assert(N == 1 && "Invalid number of operands!"); -+ Inst.addOperand(MCOperand::createReg(getFGR32Reg())); -+ } - -- if (getParser().parseExpression(Res, E)) -- return MatchOperand_ParseFail; -+ void addFCFRAsmRegOperands(MCInst &Inst, unsigned N) const { -+ assert(N == 1 && "Invalid number of operands!"); -+ Inst.addOperand(MCOperand::createReg(getFCFRReg())); -+ } - -- Operands.push_back(LoongArchOperand::createImm(Res, S, E)); -- return MatchOperand_Success; --} -+ void addLSX128AsmRegOperands(MCInst &Inst, unsigned N) const { -+ assert(N == 1 && "Invalid number of operands!"); -+ Inst.addOperand(MCOperand::createReg(getLSX128Reg())); -+ } - --/// 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) { -- if (parseRegister(Operands) == MatchOperand_Success || -- parseImmediate(Operands) == MatchOperand_Success) -- return false; -+ void addLASX256AsmRegOperands(MCInst &Inst, unsigned N) const { -+ assert(N == 1 && "Invalid number of operands!"); -+ Inst.addOperand(MCOperand::createReg(getLASX256Reg())); -+ } - -- // Finally we have exhausted all options and must declare defeat. -- Error(getLoc(), "unknown operand"); -- return true; --} -+ void addFCSRAsmRegOperands(MCInst &Inst, unsigned N) const { -+ assert(N == 1 && "Invalid number of operands!"); -+ Inst.addOperand(MCOperand::createReg(getFCSRReg())); -+ } - --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 -+ 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 there are no more operands, then finish. -- if (parseOptionalToken(AsmToken::EndOfStatement)) -- return false; -+ template -+ void addSImmOperands(MCInst &Inst, unsigned N) const { -+ if (isImm() && !isConstantImm()) { -+ addExpr(Inst, getImm()); -+ return; -+ } -+ addConstantSImmOperands(Inst, N); -+ } - -- // Parse first operand. -- if (parseOperand(Operands, Name)) -- return true; -+ template -+ void addUImmOperands(MCInst &Inst, unsigned N) const { -+ if (isImm() && !isConstantImm()) { -+ addExpr(Inst, getImm()); -+ return; -+ } -+ addConstantUImmOperands(Inst, N); -+ } - -- // Parse until end of statement, consuming commas between operands. -- while (parseOptionalToken(AsmToken::Comma)) -- if (parseOperand(Operands, Name)) -- return true; -+ 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)); -+ } - -- // Parse end of statement and return successfully. -- if (parseOptionalToken(AsmToken::EndOfStatement)) -- return false; -+ void addImmOperands(MCInst &Inst, unsigned N) const { -+ assert(N == 1 && "Invalid number of operands!"); -+ const MCExpr *Expr = getImm(); -+ addExpr(Inst, Expr); -+ } - -- SMLoc Loc = getLexer().getLoc(); -- getParser().eatToEndOfStatement(); -- return Error(Loc, "unexpected token"); --} -+ void addMemOperands(MCInst &Inst, unsigned N) const { -+ assert(N == 2 && "Invalid number of operands!"); - --bool LoongArchAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, -- OperandVector &Operands, -- MCStreamer &Out) { -- Inst.setLoc(IDLoc); -- Out.emitInstruction(Inst, getSTI()); -- return false; --} -+ Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit() -+ ? getMemBase()->getGPR64Reg() -+ : getMemBase()->getGPR32Reg())); - --unsigned LoongArchAsmParser::checkTargetMatchPredicate(MCInst &Inst) { -- switch (Inst.getOpcode()) { -- default: -- break; -- case LoongArch::CSRXCHG: { -- unsigned Rj = Inst.getOperand(2).getReg(); -- if (Rj == LoongArch::R0 || Rj == LoongArch::R1) -- return Match_RequiresOpnd2NotR0R1; -- return Match_Success; -+ const MCExpr *Expr = getMemOff(); -+ addExpr(Inst, Expr); - } -- 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; -- return Match_Success; -+ -+ void addRegListOperands(MCInst &Inst, unsigned N) const { -+ assert(N == 1 && "Invalid number of operands!"); -+ -+ for (auto RegNo : getRegList()) -+ Inst.addOperand(MCOperand::createReg(RegNo)); - } -+ -+ 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; - } - -- return Match_Success; --} -+ bool isRegIdx() const { return Kind == k_RegisterIndex; } -+ bool isImm() const override { return Kind == k_Immediate; } - --unsigned --LoongArchAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp, -- unsigned Kind) { -- LoongArchOperand &Op = static_cast(AsmOp); -- if (!Op.isReg()) -- return Match_InvalidOperand; -+ bool isConstantImm() const { -+ int64_t Res; -+ return isImm() && getImm()->evaluateAsAbsolute(Res); -+ } - -- 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; -+ bool isConstantImmz() const { -+ return isConstantImm() && getConstantImm() == 0; - } - -- return Match_InvalidOperand; --} -+ template bool isConstantUImm() const { -+ return isConstantImm() && isUInt(getConstantImm() - Offset); -+ } - --bool LoongArchAsmParser::generateImmOutOfRangeError( -- OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper, -- Twine Msg = "immediate must be an integer in the range") { -- SMLoc ErrorLoc = ((LoongArchOperand &)*Operands[ErrorInfo]).getStartLoc(); -- return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]"); --} -+ template bool isSImm() const { -+ return isConstantImm() ? isInt(getConstantImm()) : isImm(); -+ } - --bool LoongArchAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, -- OperandVector &Operands, -- MCStreamer &Out, -- uint64_t &ErrorInfo, -- bool MatchingInlineAsm) { -- MCInst Inst; -- FeatureBitset MissingFeatures; -+ template bool isUImm() const { -+ return isConstantImm() ? isUInt(getConstantImm()) : isImm(); -+ } - -- auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures, -- MatchingInlineAsm); -- switch (Result) { -- default: -- break; -- 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); -+ template bool isAnyImm() const { -+ return isConstantImm() ? (isInt(getConstantImm()) || -+ isUInt(getConstantImm())) -+ : isImm(); - } -- 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); -+ -+ template bool isConstantSImm() const { -+ return isConstantImm() && isInt(getConstantImm() - Offset); -+ } -+ -+ template bool isConstantUImmRange() const { -+ return isConstantImm() && getConstantImm() >= Bottom && -+ getConstantImm() <= Top; -+ } -+ -+ 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; -+ } -+ -+ bool isMem() const override { return Kind == k_Memory; } -+ -+ bool isConstantMemOff() const { -+ return isMem() && isa(getMemOff()); -+ } -+ -+ bool isZeroMemOff() const { -+ return isMem() && isa(getMemOff()) && -+ getConstantMemOff() == 0; -+ } -+ -+ // 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; -+ } -+ -+ 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 k_Memory: -+ OS << "Mem<"; -+ Mem.Base->print(OS); -+ OS << ", "; -+ OS << *Mem.Off; -+ OS << ">"; -+ break; -+ case k_RegisterIndex: -+ OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ", " -+ << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) << ">"; -+ break; -+ case k_Token: -+ OS << getToken(); -+ break; -+ case k_RegList: -+ OS << "RegList< "; -+ for (auto Reg : (*RegList.List)) -+ OS << Reg << " "; -+ OS << ">"; -+ break; -+ } -+ } -+ -+ bool isValidForTie(const LoongArchOperand &Other) const { -+ if (Kind != Other.Kind) -+ return false; -+ -+ 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 -+ -+} // end anonymous namespace -+ -+namespace llvm { -+ -+extern const MCInstrDesc LoongArchInsts[]; -+ -+} // end namespace llvm -+ -+static const MCInstrDesc &getInstDesc(unsigned Opcode) { -+ return LoongArchInsts[Opcode]; -+} -+ -+static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) { -+ if (const MCSymbolRefExpr *SRExpr = dyn_cast(Expr)) { -+ return &SRExpr->getSymbol(); -+ } -+ -+ if (const MCBinaryExpr *BExpr = dyn_cast(Expr)) { -+ const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS()); -+ const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS()); -+ -+ if (LHSSym) -+ return LHSSym; -+ -+ if (RHSSym) -+ return RHSSym; -+ -+ return nullptr; -+ } -+ -+ if (const MCUnaryExpr *UExpr = dyn_cast(Expr)) -+ return getSingleMCSymbol(UExpr->getSubExpr()); -+ -+ return nullptr; -+} -+ -+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; -+} -+ -+bool LoongArchAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, -+ MCStreamer &Out, -+ const MCSubtargetInfo *STI) { -+ const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode()); -+ -+ 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.OpInfo[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; -+} -+ -+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; -+ } -+} -+ -+/// Can the value be represented by a unsigned N-bit value and a shift left? -+template static bool isShiftedUIntAtAnyPosition(uint64_t x) { -+ unsigned BitNum = findFirstSet(x); -+ -+ return (x == x >> BitNum << BitNum) && isUInt(x >> BitNum); -+} -+ -+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 -+ TOut.emitRRI(Inst.Opc, DstReg, SrcReg, Inst.Imm, IDLoc, STI); -+ SrcReg = DstReg; -+ } -+ -+ return false; -+} -+ -+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()) { -+ 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::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::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::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::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(""); -+ } -+} -+ -+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_D: -+ case LoongArch::BSTRPICK_D: { -+ 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; -+} -+ -+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 Loc; -+} -+ -+bool LoongArchAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, -+ OperandVector &Operands, -+ MCStreamer &Out, -+ uint64_t &ErrorInfo, -+ bool MatchingInlineAsm) { -+ MCInst Inst; -+ unsigned MatchResult = -+ MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm); -+ switch (MatchResult) { -+ case Match_Success: -+ 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"); - } -+ 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 Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), -+ "expected 5-bit signed immediate"); -+ case Match_InvalidSImm8: -+ return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), -+ "expected 8-bit signed immediate"); -+ case Match_InvalidSImm12: -+ 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 Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), -+ "expected 16-bit signed immediate"); -+ case Match_InvalidSImm20: -+ 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"); - } - -- // 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"); -+ 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; -+} - -- 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_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_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_InvalidUImm12: -- return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/0, -- /*Upper=*/(1 << 12) - 1); -- case Match_InvalidUImm15: -- return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/0, -- /*Upper=*/(1 << 15) - 1); -- case Match_InvalidSImm12: -- return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/-(1 << 11), -- /*Upper=*/(1 << 11) - 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_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, -- "immediate must be a multiple of 4 in the range"); -- case Match_InvalidSImm20: -- return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/-(1 << 19), -- /*Upper=*/(1 << 19) - 1); -- case Match_InvalidSImm21lsl2: -- return generateImmOutOfRangeError( -- Operands, ErrorInfo, /*Lower=*/-(1 << 22), /*Upper=*/(1 << 22) - 4, -- "immediate must be a multiple of 4 in the range"); -- case Match_InvalidSImm26lsl2: -- return generateImmOutOfRangeError( -- Operands, ErrorInfo, /*Lower=*/-(1 << 27), /*Upper=*/(1 << 27) - 4, -- "immediate must be a multiple of 4 in the range"); -+int LoongArchAsmParser::matchFCFRRegisterName(StringRef Name) { -+ if (Name.startswith("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.startswith("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; - } -- llvm_unreachable("Unknown match type detected!"); -+ } // 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(unsigned &RegNo, SMLoc &StartLoc, -+ SMLoc &EndLoc) { -+ return tryParseRegister(RegNo, StartLoc, EndLoc) != MatchOperand_Success; -+} -+ -+OperandMatchResultTy LoongArchAsmParser::tryParseRegister(unsigned &RegNo, -+ 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. -+ RegNo = is64Bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg(); -+ } -+ -+ return (RegNo == (unsigned)-1) ? MatchOperand_NoMatch -+ : MatchOperand_Success; -+ } -+ -+ assert(Operands.size() == 0); -+ return (RegNo == (unsigned)-1) ? MatchOperand_NoMatch : MatchOperand_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.startswith("$")) { -+ 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/src/llvm-project/llvm/lib/Target/LoongArch/CMakeLists.txt b/src/llvm-project/llvm/lib/Target/LoongArch/CMakeLists.txt -index 4d8e81aea..8540b97ff 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/CMakeLists.txt -+++ b/src/llvm-project/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,14 +17,20 @@ add_public_tablegen_target(LoongArchCommonTableGen) - - add_llvm_target(LoongArchCodeGen - LoongArchAsmPrinter.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 - Analysis -diff --git a/src/llvm-project/llvm/lib/Target/LoongArch/Disassembler/CMakeLists.txt b/src/llvm-project/llvm/lib/Target/LoongArch/Disassembler/CMakeLists.txt -index 1cce676cf..864be6313 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/Disassembler/CMakeLists.txt -+++ b/src/llvm-project/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/src/llvm-project/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp b/src/llvm-project/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp -index beb757c78..6468a0fc8 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/Disassembler/LoongArchDisassembler.cpp -+++ b/src/llvm-project/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,140 +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; -- Inst.addOperand(MCOperand::createReg(LoongArch::FCC0 + RegNo)); -+ unsigned Reg = getReg(Decoder, LoongArch::FGR64RegClassID, RegNo); -+ Inst.addOperand(MCOperand::createReg(Reg)); - return MCDisassembler::Success; - } - --static DecodeStatus DecodeFCSRRegisterClass(MCInst &Inst, uint64_t RegNo, -+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 MCDisassembler *Decoder) { -- if (RegNo >= 4) -+ const void *Decoder) { -+ if (RegNo > 31) - return MCDisassembler::Fail; -- Inst.addOperand(MCOperand::createReg(LoongArch::FCSR0 + RegNo)); -+ -+ unsigned Reg = getReg(Decoder, LoongArch::FCSRRegClassID, 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 DecodeFCFRRegisterClass(MCInst &Inst, -+ unsigned RegNo, -+ uint64_t Address, -+ const void *Decoder) { -+ if (RegNo > 7) -+ return MCDisassembler::Fail; -+ -+ unsigned Reg = getReg(Decoder, LoongArch::FCFRRegClassID, 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"); -- // Sign-extend the number in the bottom bits of Imm, then shift left -- // bits. -- Inst.addOperand(MCOperand::createImm(SignExtend64(Imm) << S)); -+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; - } - --#include "LoongArchGenDisassemblerTables.inc" -+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); - --DecodeStatus LoongArchDisassembler::getInstruction(MCInst &MI, uint64_t &Size, -- ArrayRef Bytes, -- uint64_t Address, -- raw_ostream &CS) const { -- uint32_t Insn; -- DecodeStatus Result; -+ Rd = getReg(Decoder, LoongArch::GPR32RegClassID, Rd); -+ Rj = getReg(Decoder, LoongArch::GPR32RegClassID, Rj); -+ Rk = getReg(Decoder, LoongArch::GPR32RegClassID, Rk); - -- // We want to read exactly 4 bytes of data because all LoongArch instructions -- // are fixed 32 bits. -- if (Bytes.size() < 4) { -- Size = 0; -+ // 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; - } - -- Insn = support::endian::read32le(Bytes.data()); -- // Calling the auto-generated decoder function. -- Result = decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI); -- Size = 4; -+ 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; -+ 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 DecodeLASX256memlsl(MCInst &Inst, unsigned Insn, -+ uint64_t Address, const void *Decoder) { - -- return Result; -+ int Offset; -+ unsigned Reg, Base; -+ switch (Inst.getOpcode()) { -+ default: -+ assert(false && "Unexpected instruction"); -+ return MCDisassembler::Fail; -+ 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 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 void *Decoder) { -+ if (RegNo > 31) -+ return MCDisassembler::Fail; -+ unsigned Reg = getReg(Decoder, LoongArch::LSX128BRegClassID, RegNo); -+ Inst.addOperand(MCOperand::createReg(Reg)); -+ return MCDisassembler::Success; -+} -+ -+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; -+ unsigned Reg = getReg(Decoder, LoongArch::LSX128WRegClassID, RegNo); -+ Inst.addOperand(MCOperand::createReg(Reg)); -+ return MCDisassembler::Success; -+} -+ -+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; -+} -+ -+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; -+} -+ -+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; -+} -+ -+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; -+} -+ -+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; -+} -+ -+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; -+} -+ -+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/src/llvm-project/llvm/lib/Target/LoongArch/LoongArch.h b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArch.h -index e6c9c24dd..73fd4a628 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArch.h -+++ b/src/llvm-project/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,33 +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 LoongArchTargetMachine; --class AsmPrinter; --class FunctionPass; --class MCInst; --class MCOperand; --class MachineInstr; --class MachineOperand; -+ 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 *createLoongArchISelDag(LoongArchTargetMachine &TM); --} // end namespace llvm -+ void initializeLoongArchBranchExpansionPass(PassRegistry &); -+} // end namespace llvm; - --#endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCH_H -+#endif -diff --git a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArch.td b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArch.td -index bf465c27e..703c1ba50 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArch.td -+++ b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArch.td -@@ -1,139 +1,107 @@ --//===-- 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 - // - //===----------------------------------------------------------------------===// -+// This is the top level entry point for the LoongArch target. -+//===----------------------------------------------------------------------===// -+ -+//===----------------------------------------------------------------------===// -+// Target-independent interfaces -+//===----------------------------------------------------------------------===// - - include "llvm/Target/Target.td" - -+// 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; -+} -+ - //===----------------------------------------------------------------------===// --// LoongArch subtarget features and instruction predicates. -+// LoongArch Subtarget features // - //===----------------------------------------------------------------------===// - --// 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 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">; -- --// Single Precision floating point --def FeatureBasicF -- : SubtargetFeature<"f", "HasBasicF", "true", -- "'F' (Single-Precision Floating-Point)">; --def HasBasicF -- : Predicate<"Subtarget->hasBasicF()">, -- AssemblerPredicate<(all_of FeatureBasicF), -- "'F' (Single-Precision Floating-Point)">; -- --// Double Precision floating point --def FeatureBasicD -- : SubtargetFeature<"d", "HasBasicD", "true", -- "'D' (Double-Precision Floating-Point)", -- [FeatureBasicF]>; --def HasBasicD -- : Predicate<"Subtarget->hasBasicD()">, -- AssemblerPredicate<(all_of FeatureBasicD), -- "'D' (Double-Precision Floating-Point)">; -- --// Loongson SIMD eXtension (LSX) --def FeatureExtLSX -- : SubtargetFeature<"lsx", "HasExtLSX", "true", -- "'LSX' (Loongson SIMD Extension)", [FeatureBasicD]>; --def HasExtLSX -- : Predicate<"Subtarget->hasExtLSX()">, -- AssemblerPredicate<(all_of FeatureExtLSX), -- "'LSX' (Loongson SIMD Extension)">; -- --// Loongson Advanced SIMD eXtension (LASX) --def FeatureExtLASX -- : SubtargetFeature<"lasx", "HasExtLASX", "true", -- "'LASX' (Loongson Advanced SIMD Extension)", -- [FeatureExtLSX]>; --def HasExtLASX -- : Predicate<"Subtarget->hasExtLASX()">, -- AssemblerPredicate<(all_of FeatureExtLASX), -- "'LASX' (Loongson Advanced SIMD Extension)">; -- --// Loongson VirtualiZation (LVZ) --def FeatureExtLVZ -- : SubtargetFeature<"lvz", "HasExtLVZ", "true", -- "'LVZ' (Loongson Virtualization Extension)">; --def HasExtLVZ -- : Predicate<"Subtarget->hasExtLVZ()">, -- AssemblerPredicate<(all_of FeatureExtLVZ), -- "'LVZ' (Loongson Virtualization Extension)">; -- --// Loongson Binary Translation (LBT) --def FeatureExtLBT -- : SubtargetFeature<"lbt", "HasExtLBT", "true", -- "'LBT' (Loongson Binary Translation Extension)">; --def HasExtLBT -- : Predicate<"Subtarget->hasExtLBT()">, -- AssemblerPredicate<(all_of FeatureExtLBT), -- "'LBT' (Loongson Binary Translation Extension)">; -- -+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">; - //===----------------------------------------------------------------------===// --// Registers, instruction descriptions ... -+// Register File, Calling Conv, Instruction Descriptions - //===----------------------------------------------------------------------===// - - include "LoongArchRegisterInfo.td" --include "LoongArchCallingConv.td" - include "LoongArchInstrInfo.td" -+include "LoongArchCallingConv.td" -+ -+def LoongArchInstrInfo : InstrInfo; - - //===----------------------------------------------------------------------===// - // LoongArch processors supported. - //===----------------------------------------------------------------------===// - --def : ProcessorModel<"generic-la32", NoSchedModel, []>; --def : ProcessorModel<"generic-la64", NoSchedModel, [Feature64Bit]>; -+def : ProcessorModel<"la264", NoSchedModel, [Feature64Bit]>; - --def : ProcessorModel<"la464", NoSchedModel, [Feature64Bit, -- FeatureExtLASX, -- FeatureExtLVZ, -- FeatureExtLBT]>; -+def : ProcessorModel<"la364", NoSchedModel, [Feature64Bit]>; - --//===----------------------------------------------------------------------===// --// Define the LoongArch target. --//===----------------------------------------------------------------------===// -- --def LoongArchInstrInfo : InstrInfo { -- // guess mayLoad, mayStore, and hasSideEffects -- // This option is a temporary migration help. It will go away. -- let guessInstructionProperties = 1; --} -+def : ProcessorModel<"la464", NoSchedModel, -+ [Feature64Bit, FeatureUnalignedAccess]>; - - 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/src/llvm-project/llvm/lib/Target/LoongArch/LoongArch32InstrInfo.td b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArch32InstrInfo.td -new file mode 100644 -index 000000000..f53471995 ---- /dev/null -+++ b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArch32InstrInfo.td -@@ -0,0 +1,717 @@ -+//===- 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 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; -+ -+ 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), 1>; -+def : InstAlias<"break $imm", (BREAK uimm15:$imm), 1>; -+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; -+ -+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; -+ -+ def ATOMIC_CMP_SWAP_I8 : AtomicCmpSwap; -+ def ATOMIC_CMP_SWAP_I16 : AtomicCmpSwap; -+ def ATOMIC_CMP_SWAP_I32 : AtomicCmpSwap; -+ -+ 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 addr:$a, GPR32:$v), -+ (ST_B32 GPR32:$v, addr:$a)>; -+def : LoongArchPat<(atomic_store_16 addr:$a, GPR32:$v), -+ (ST_H32 GPR32:$v, addr:$a)>; -+def : LoongArchPat<(atomic_store_32 addrimm14lsl2:$a, GPR32:$v), -+ (STPTR_W32 GPR32:$v, addrimm14lsl2:$a)>; -+def : LoongArchPat<(atomic_store_32 addr:$a, GPR32:$v), -+ (ST_W32 GPR32:$v, addr:$a)>; -+ -+def : LoongArchPat<(LoongArchDBAR (i32 immz)), -+ (DBAR 0)>; -+ -+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 addr:$a, (i32 (trunc (i64 (assertsext GPR64:$rj))))), -+ (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/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp -index 1467d1757..afa38dbf2 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp -+++ b/src/llvm-project/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,40 +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 "TargetInfo/LoongArchTargetInfo.h" --#include "llvm/CodeGen/AsmPrinter.h" -+#include "LoongArchTargetStreamer.h" -+#include "llvm/ADT/SmallString.h" -+#include "llvm/ADT/StringRef.h" -+#include "llvm/ADT/Triple.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 -+#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(); - -- // Do any auto-generated pseudo lowerings. -- if (emitPseudoExpansionLowering(*OutStreamer, MI)) -+ if (MI->isDebugValue()) { -+ SmallString<128> Str; -+ raw_svector_ostream OS(Str); -+ -+ 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; - -- MCInst TmpInst; -- if (!lowerLoongArchMachineInstrToMCInst(MI, TmpInst, *this)) -- EmitToStreamer(*OutStreamer, TmpInst); -+ switch (Opc) { -+ case LoongArch::PATCHABLE_FUNCTION_ENTER: -+ LowerPATCHABLE_FUNCTION_ENTER(*MI); -+ return; -+ case LoongArch::PATCHABLE_FUNCTION_EXIT: -+ LowerPATCHABLE_FUNCTION_EXIT(*MI); -+ return; -+ 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(); -+ -+ 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::runOnMachineFunction(MachineFunction &MF) { -- AsmPrinter::runOnMachineFunction(MF); -- return true; -+//===----------------------------------------------------------------------===// -+// -+// 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() { -+ -+ // 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. -+ -+ const MachineOperand &MO = MI->getOperand(OpNum); -+ switch (ExtraCode[0]) { -+ default: -+ // 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 '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; -+ unsigned Flags = FlagsOP.getImm(); -+ unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags); -+ // 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; -+ } -+ -+ 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; -+ } -+ } -+ -+ printOperand(MI, OpNum, O); -+ return false; -+} -+ -+bool LoongArchAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, -+ unsigned OpNum, -+ const char *ExtraCode, -+ 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::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; -+ -+ 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) -+ -+ printOperand(MI, opNum+1, O); -+ O << "("; -+ printOperand(MI, opNum, O); -+ O << ")"; -+} -+ -+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:: -+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, None); -+ -+ 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) { -+ const uint8_t NoopsInSledCount = 11; -+ // For loongarch64 we want to emit the following pattern: -+ // -+ // .Lxray_sled_N: -+ // ALIGN -+ // B .tmpN -+ // 11 NOP instructions (44 bytes) -+ // .tmpN -+ // -+ // 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(4, &getSubtargetInfo()); -+ 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); -+} -+ -+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/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.h b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.h -index b51c19188..3e4ca8ed1 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.h -+++ b/src/llvm-project/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,36 +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 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; -+ - class LLVM_LIBRARY_VISIBILITY LoongArchAsmPrinter : public AsmPrinter { -- const MCSubtargetInfo *STI; -+ LoongArchTargetStreamer &getTargetStreamer() const; -+ -+ void EmitInstrWithMacroNoAT(const MachineInstr *MI); -+ -+ //===------------------------------------------------------------------===// -+ // XRay implementation -+ //===------------------------------------------------------------------===// - - public: -- explicit LoongArchAsmPrinter(TargetMachine &TM, -- std::unique_ptr Streamer) -- : AsmPrinter(TM, std::move(Streamer)), STI(TM.getMCSubtargetInfo()) {} -+ // 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); - -- StringRef getPassName() const override { -- return "LoongArch Assembly Printer"; -- } -+private: -+ /// MCP - Keep a pointer to constantpool entries of the current -+ /// MachineFunction. -+ const MachineConstantPool *MCP = nullptr; - -- bool runOnMachineFunction(MachineFunction &MF) override; -+ /// InConstantPool - Maintain state when emitting a sequence of constant -+ /// pool entries so we can properly mark them as data regions. -+ bool InConstantPool = false; - -- void emitInstruction(const MachineInstr *MI) override; -+ 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/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchCCState.cpp b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchCCState.cpp -new file mode 100644 -index 000000000..6630ca759 ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchCCState.h b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchCCState.h -new file mode 100644 -index 000000000..1c1a1446e ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchCallingConv.td b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchCallingConv.td -index 984416316..e8564e85b 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchCallingConv.td -+++ b/src/llvm-project/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/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchExpandPseudo.cpp b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchExpandPseudo.cpp -new file mode 100644 -index 000000000..0f33e1db6 ---- /dev/null -+++ b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchExpandPseudo.cpp -@@ -0,0 +1,2471 @@ -+//===-- 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; -+} -+ -+static bool hasDbar(MachineBasicBlock *MBB) { -+ -+ for (MachineBasicBlock::iterator MBBb = MBB->begin(), MBBe = MBB->end(); -+ MBBb != MBBe; ++MBBb) { -+ if (MBBb->getOpcode() == LoongArch::DBAR) -+ return true; -+ if (MBBb->mayLoad() || MBBb->mayStore()) -+ break; -+ } -+ return false; -+} -+ -+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(7).getReg(); -+ unsigned Scratch2 = I->getOperand(8).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); -+ -+ if (!hasDbar(sinkMBB)) { -+ MachineBasicBlock::iterator Pos = sinkMBB->begin(); -+ BuildMI(*sinkMBB, Pos, DL, TII->get(LoongArch::DBAR)).addImm(DBAR_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(4).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); -+ -+ if (!hasDbar(exitMBB)) { -+ MachineBasicBlock::iterator Pos = exitMBB->begin(); -+ BuildMI(*exitMBB, Pos, DL, TII->get(LoongArch::DBAR)).addImm(DBAR_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); -+ 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; -+ -+ 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/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td -deleted file mode 100644 -index 20448492a..000000000 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td -+++ /dev/null -@@ -1,229 +0,0 @@ --//=-- LoongArchInstrInfoF.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<0b00000001000000001, "fadd.s", FPR32>; --def FSUB_S : FP_ALU_3R<0b00000001000000101, "fsub.s", FPR32>; --def FMUL_S : FP_ALU_3R<0b00000001000001001, "fmul.s", FPR32>; --def FDIV_S : FP_ALU_3R<0b00000001000001101, "fdiv.s", FPR32>; --def FMADD_S : FP_ALU_4R<0b000010000001, "fmadd.s", FPR32>; --def FMSUB_S : FP_ALU_4R<0b000010000101, "fmsub.s", FPR32>; --def FNMADD_S : FP_ALU_4R<0b000010001001, "fnmadd.s", FPR32>; --def FNMSUB_S : FP_ALU_4R<0b000010001101, "fnmsub.s", FPR32>; --def FMAX_S : FP_ALU_3R<0b00000001000010001, "fmax.s", FPR32>; --def FMIN_S : FP_ALU_3R<0b00000001000010101, "fmin.s", FPR32>; --def FMAXA_S : FP_ALU_3R<0b00000001000011001, "fmaxa.s", FPR32>; --def FMINA_S : FP_ALU_3R<0b00000001000011101, "fmina.s", FPR32>; --def FABS_S : FP_ALU_2R<0b0000000100010100000001, "fabs.s", FPR32>; --def FNEG_S : FP_ALU_2R<0b0000000100010100000101, "fneg.s", FPR32>; --def FSQRT_S : FP_ALU_2R<0b0000000100010100010001, "fsqrt.s", FPR32>; --def FRECIP_S : FP_ALU_2R<0b0000000100010100010101, "frecip.s", FPR32>; --def FRSQRT_S : FP_ALU_2R<0b0000000100010100011001, "frsqrt.s", FPR32>; --def FSCALEB_S : FP_ALU_3R<0b00000001000100001, "fscaleb.s", FPR32>; --def FLOGB_S : FP_ALU_2R<0b0000000100010100001001, "flogb.s", FPR32>; --def FCOPYSIGN_S : FP_ALU_3R<0b00000001000100101, "fcopysign.s", FPR32>; --def FCLASS_S : FP_ALU_2R<0b0000000100010100001101, "fclass.s", FPR32>; -- -- --// Comparison Instructions --def FCMP_CAF_S : FP_CMP; --def FCMP_CUN_S : FP_CMP; --def FCMP_CEQ_S : FP_CMP; --def FCMP_CUEQ_S : FP_CMP; --def FCMP_CLT_S : FP_CMP; --def FCMP_CULT_S : FP_CMP; --def FCMP_CLE_S : FP_CMP; --def FCMP_CULE_S : FP_CMP; --def FCMP_CNE_S : FP_CMP; --def FCMP_COR_S : FP_CMP; --def FCMP_CUNE_S : FP_CMP; --def FCMP_SAF_S : FP_CMP; --def FCMP_SUN_S : FP_CMP; --def FCMP_SEQ_S : FP_CMP; --def FCMP_SUEQ_S : FP_CMP; --def FCMP_SLT_S : FP_CMP; --def FCMP_SULT_S : FP_CMP; --def FCMP_SLE_S : FP_CMP; --def FCMP_SULE_S : FP_CMP; --def FCMP_SNE_S : FP_CMP; --def FCMP_SOR_S : FP_CMP; --def FCMP_SUNE_S : FP_CMP; -- --// Conversion Instructions --def FFINT_S_W : FP_CONV<0b0000000100011101000100, "ffint.s.w", FPR32, FPR32>; --def FTINT_W_S : FP_CONV<0b0000000100011011000001, "ftint.w.s", FPR32, FPR32>; --def FTINTRM_W_S : FP_CONV<0b0000000100011010000001, "ftintrm.w.s", FPR32, -- FPR32>; --def FTINTRP_W_S : FP_CONV<0b0000000100011010010001, "ftintrp.w.s", FPR32, -- FPR32>; --def FTINTRZ_W_S : FP_CONV<0b0000000100011010100001, "ftintrz.w.s", FPR32, -- FPR32>; --def FTINTRNE_W_S : FP_CONV<0b0000000100011010110001, "ftintrne.w.s", FPR32, -- FPR32>; --def FRINT_S : FP_CONV<0b0000000100011110010001, "frint.s", FPR32, FPR32>; -- --// Move Instructions --def FSEL_S : FP_SEL<0b00001101000000, "fsel", FPR32>; --def FMOV_S : FP_MOV<0b0000000100010100100101, "fmov.s", FPR32, FPR32>; --def MOVGR2FR_W : FP_MOV<0b0000000100010100101001, "movgr2fr.w", FPR32, GPR>; --def MOVFR2GR_S : FP_MOV<0b0000000100010100101101, "movfr2gr.s", GPR, FPR32>; --def MOVGR2FCSR : FP_MOV<0b0000000100010100110000, "movgr2fcsr", FCSR, GPR>; --def MOVFCSR2GR : FP_MOV<0b0000000100010100110010, "movfcsr2gr", GPR, FCSR>; --def MOVFR2CF_S : FP_MOV<0b0000000100010100110100, "movfr2cf", CFR, FPR32>; --def MOVCF2FR_S : FP_MOV<0b0000000100010100110101, "movcf2fr", FPR32, CFR>; --def MOVGR2CF : FP_MOV<0b0000000100010100110110, "movgr2cf", CFR, GPR>; --def MOVCF2GR : FP_MOV<0b0000000100010100110111, "movcf2gr", GPR, CFR>; -- --// Branch Instructions --def BCEQZ : FP_BRANCH<0b01001000, "bceqz">; --def BCNEZ : FP_BRANCH<0b01001001, "bcnez">; -- --// Common Memory Access Instructions --def FLD_S : FP_LOAD_2RI12<0b0010101100, "fld.s", FPR32>; --def FST_S : FP_STORE_2RI12<0b0010101101, "fst.s", FPR32>; --def FLDX_S : FP_LOAD_3R<0b00111000001100000, "fldx.s", FPR32>; --def FSTX_S : FP_STORE_3R<0b00111000001110000, "fstx.s", FPR32>; -- --// Bound Check Memory Access Instructions --def FLDGT_S : FP_LOAD_3R<0b00111000011101000, "fldgt.s", FPR32>; --def FLDLE_S : FP_LOAD_3R<0b00111000011101010, "fldle.s", FPR32>; --def FSTGT_S : FP_STORE_3R<0b00111000011101100, "fstgt.s", FPR32>; --def FSTLE_S : FP_STORE_3R<0b00111000011101110, "fstle.s", FPR32>; -- --} // 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 : PatFpr; -- --/// Setcc -- --// Match non-signaling comparison -- --// TODO: change setcc to any_fsetcc after call is supported because --// we need to call llvm.experimental.constrained.fcmp.f32 in testcase. --// See RISCV float-fcmp-strict.ll for reference. --class PatFPSetcc -- : Pat<(setcc RegTy:$fj, RegTy:$fk, cc), -- (MOVCF2GR (CmpInst RegTy:$fj, RegTy:$fk))>; --// SETOGT/SETOGE/SETUGT/SETUGE will expand into SETOLT/SETOLE/SETULT/SETULE. --def : PatFPSetcc; --def : PatFPSetcc; --def : PatFPSetcc; --def : PatFPSetcc; --def : PatFPSetcc; --def : PatFPSetcc; --def : PatFPSetcc; --def : PatFPSetcc; --def : PatFPSetcc; --def : PatFPSetcc; --def : PatFPSetcc; -- --// TODO: Match signaling comparison strict_fsetccs with FCMP_S*_S instructions. -- --/// Select -- --def : Pat<(select GPR:$cc, FPR32:$fk, FPR32:$fj), -- (FSEL_S FPR32:$fj, FPR32:$fk, (MOVGR2CF GPR:$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; -- --/// Stores -- --defm : StPat; -- --/// 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)>; --} // 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 GPR:$src)), (FFINT_S_W (MOVGR2FR_W GPR:$src))>; --} // 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, IsLA64] -diff --git a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchFloat64InstrInfo.td b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchFloat64InstrInfo.td -deleted file mode 100644 -index bb50cec9f..000000000 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchFloat64InstrInfo.td -+++ /dev/null -@@ -1,242 +0,0 @@ --//=-- LoongArchInstrInfoD.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<0b00000001000000010, "fadd.d", FPR64>; --def FSUB_D : FP_ALU_3R<0b00000001000000110, "fsub.d", FPR64>; --def FMUL_D : FP_ALU_3R<0b00000001000001010, "fmul.d", FPR64>; --def FDIV_D : FP_ALU_3R<0b00000001000001110, "fdiv.d", FPR64>; --def FMADD_D : FP_ALU_4R<0b000010000010, "fmadd.d", FPR64>; --def FMSUB_D : FP_ALU_4R<0b000010000110, "fmsub.d", FPR64>; --def FNMADD_D : FP_ALU_4R<0b000010001010, "fnmadd.d", FPR64>; --def FNMSUB_D : FP_ALU_4R<0b000010001110, "fnmsub.d", FPR64>; --def FMAX_D : FP_ALU_3R<0b00000001000010010, "fmax.d", FPR64>; --def FMIN_D : FP_ALU_3R<0b00000001000010110, "fmin.d", FPR64>; --def FMAXA_D : FP_ALU_3R<0b00000001000011010, "fmaxa.d", FPR64>; --def FMINA_D : FP_ALU_3R<0b00000001000011110, "fmina.d", FPR64>; --def FABS_D : FP_ALU_2R<0b0000000100010100000010, "fabs.d", FPR64>; --def FNEG_D : FP_ALU_2R<0b0000000100010100000110, "fneg.d", FPR64>; --def FSQRT_D : FP_ALU_2R<0b0000000100010100010010, "fsqrt.d", FPR64>; --def FRECIP_D : FP_ALU_2R<0b0000000100010100010110, "frecip.d", FPR64>; --def FRSQRT_D : FP_ALU_2R<0b0000000100010100011010, "frsqrt.d", FPR64>; --def FSCALEB_D : FP_ALU_3R<0b00000001000100010, "fscaleb.d", FPR64>; --def FLOGB_D : FP_ALU_2R<0b0000000100010100001010, "flogb.d", FPR64>; --def FCOPYSIGN_D : FP_ALU_3R<0b00000001000100110, "fcopysign.d", FPR64>; --def FCLASS_D : FP_ALU_2R<0b0000000100010100001110, "fclass.d", FPR64>; -- --// Comparison Instructions --def FCMP_CAF_D : FP_CMP; --def FCMP_CUN_D : FP_CMP; --def FCMP_CEQ_D : FP_CMP; --def FCMP_CUEQ_D : FP_CMP; --def FCMP_CLT_D : FP_CMP; --def FCMP_CULT_D : FP_CMP; --def FCMP_CLE_D : FP_CMP; --def FCMP_CULE_D : FP_CMP; --def FCMP_CNE_D : FP_CMP; --def FCMP_COR_D : FP_CMP; --def FCMP_CUNE_D : FP_CMP; --def FCMP_SAF_D : FP_CMP; --def FCMP_SUN_D : FP_CMP; --def FCMP_SEQ_D : FP_CMP; --def FCMP_SUEQ_D : FP_CMP; --def FCMP_SLT_D : FP_CMP; --def FCMP_SULT_D : FP_CMP; --def FCMP_SLE_D : FP_CMP; --def FCMP_SULE_D : FP_CMP; --def FCMP_SNE_D : FP_CMP; --def FCMP_SOR_D : FP_CMP; --def FCMP_SUNE_D : FP_CMP; -- --// Conversion Instructions --def FFINT_S_L : FP_CONV<0b0000000100011101000110, "ffint.s.l", FPR32, FPR64>; --def FTINT_L_S : FP_CONV<0b0000000100011011001001, "ftint.l.s", FPR64, FPR32>; --def FTINTRM_L_S : FP_CONV<0b0000000100011010001001, "ftintrm.l.s", FPR64, -- FPR32>; --def FTINTRP_L_S : FP_CONV<0b0000000100011010011001, "ftintrp.l.s", FPR64, -- FPR32>; --def FTINTRZ_L_S : FP_CONV<0b0000000100011010101001, "ftintrz.l.s", FPR64, -- FPR32>; --def FTINTRNE_L_S : FP_CONV<0b0000000100011010111001, "ftintrne.l.s", FPR64, -- FPR32>; --def FCVT_S_D : FP_CONV<0b0000000100011001000110, "fcvt.s.d", FPR32, FPR64>; --def FCVT_D_S : FP_CONV<0b0000000100011001001001, "fcvt.d.s", FPR64, FPR32>; --def FFINT_D_W : FP_CONV<0b0000000100011101001000, "ffint.d.w", FPR64, FPR32>; --def FFINT_D_L : FP_CONV<0b0000000100011101001010, "ffint.d.l", FPR64, FPR64>; --def FTINT_W_D : FP_CONV<0b0000000100011011000010, "ftint.w.d", FPR32, FPR64>; --def FTINT_L_D : FP_CONV<0b0000000100011011001010, "ftint.l.d", FPR64, FPR64>; --def FTINTRM_W_D : FP_CONV<0b0000000100011010000010, "ftintrm.w.d", FPR32, -- FPR64>; --def FTINTRM_L_D : FP_CONV<0b0000000100011010001010, "ftintrm.l.d", FPR64, -- FPR64>; --def FTINTRP_W_D : FP_CONV<0b0000000100011010010010, "ftintrp.w.d", FPR32, -- FPR64>; --def FTINTRP_L_D : FP_CONV<0b0000000100011010011010, "ftintrp.l.d", FPR64, -- FPR64>; --def FTINTRZ_W_D : FP_CONV<0b0000000100011010100010, "ftintrz.w.d", FPR32, -- FPR64>; --def FTINTRZ_L_D : FP_CONV<0b0000000100011010101010, "ftintrz.l.d", FPR64, -- FPR64>; --def FTINTRNE_W_D : FP_CONV<0b0000000100011010110010, "ftintrne.w.d", FPR32, -- FPR64>; --def FTINTRNE_L_D : FP_CONV<0b0000000100011010111010, "ftintrne.l.d", FPR64, -- FPR64>; --def FRINT_D : FP_CONV<0b0000000100011110010010, "frint.d", FPR64, FPR64>; -- --// Move Instructions --def FMOV_D : FP_MOV<0b0000000100010100100110, "fmov.d", FPR64, FPR64>; --def MOVFRH2GR_S : FP_MOV<0b0000000100010100101111, "movfrh2gr.s", GPR, FPR64>; --let isCodeGenOnly = 1 in { --def MOVFR2GR_S_64 : FP_MOV<0b0000000100010100101101, "movfr2gr.s", GPR, FPR64>; --def FSEL_D : FP_SEL<0b00001101000000, "fsel", FPR64>; --} // isCodeGenOnly = 1 --let Constraints = "$dst = $out" in { --def MOVGR2FRH_W : FPFmtMOV<0b0000000100010100101011, (outs FPR64:$out), -- (ins FPR64:$dst, GPR:$src), "movgr2frh.w", -- "$dst, $src">; --} // Constraints = "$dst = $out" -- --// Common Memory Access Instructions --def FLD_D : FP_LOAD_2RI12<0b0010101110, "fld.d", FPR64>; --def FST_D : FP_STORE_2RI12<0b0010101111, "fst.d", FPR64>; --def FLDX_D : FP_LOAD_3R<0b00111000001101000, "fldx.d", FPR64>; --def FSTX_D : FP_STORE_3R<0b00111000001111000, "fstx.d", FPR64>; -- --// Bound Check Memory Access Instructions --def FLDGT_D : FP_LOAD_3R<0b00111000011101001, "fldgt.d", FPR64>; --def FLDLE_D : FP_LOAD_3R<0b00111000011101011, "fldle.d", FPR64>; --def FSTGT_D : FP_STORE_3R<0b00111000011101101, "fstgt.d", FPR64>; --def FSTLE_D : FP_STORE_3R<0b00111000011101111, "fstle.d", FPR64>; -- --} // Predicates = [HasBasicD] -- --// Instructions only available on LA64 --let Predicates = [HasBasicD, IsLA64] in { --def MOVGR2FR_D : FP_MOV<0b0000000100010100101010, "movgr2fr.d", FPR64, GPR>; --def MOVFR2GR_D : FP_MOV<0b0000000100010100101110, "movfr2gr.d", GPR, FPR64>; --} // Predicates = [HasBasicD, IsLA64] -- --// Instructions only available on LA32 --let Predicates = [HasBasicD, IsLA32], isCodeGenOnly = 1 in { --def MOVGR2FR_W_64 : FP_MOV<0b0000000100010100101001, "movgr2fr.w", 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 : PatFpr; -- --/// Setcc -- --// Match non-signaling comparison -- --// TODO: Change setcc to any_fsetcc after call is supported because --// we need to call llvm.experimental.constrained.fcmp.f64 in testcase. --// See RISCV float-fcmp-strict.ll for reference. -- --// SETOGT/SETOGE/SETUGT/SETUGE will expand into SETOLT/SETOLE/SETULT/SETULE. --def : PatFPSetcc; --def : PatFPSetcc; --def : PatFPSetcc; --def : PatFPSetcc; --def : PatFPSetcc; --def : PatFPSetcc; --def : PatFPSetcc; --def : PatFPSetcc; --def : PatFPSetcc; --def : PatFPSetcc; --def : PatFPSetcc; -- --// TODO: Match signaling comparison strict_fsetccs with FCMP_S*_D instructions. -- --/// Select -- --def : Pat<(select GPR:$cc, FPR64:$fk, FPR64:$fj), -- (FSEL_D FPR64:$fj, FPR64:$fk, (MOVGR2CF GPR:$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; -- --/// Stores -- --defm : StPat; -- --/// 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)>; --} // 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)))>; -- --// Convert int to FP --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<(f64 (uint_to_fp (i64 (zexti32 (i64 GPR:$src))))), -- (FFINT_D_W (MOVGR2FR_W GPR:$src))>; -- --def : Pat<(bitconvert GPR:$src), (MOVGR2FR_D GPR:$src)>; -- --// Convert FP to int --def : Pat<(bitconvert FPR64:$src), (MOVFR2GR_D FPR64:$src)>; --} // 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))))>; -- --// Convert int to FP --def : Pat<(f64 (sint_to_fp (i32 GPR:$src))), (FFINT_D_W (MOVGR2FR_W GPR:$src))>; --} // Predicates = [HasBasicD, IsLA32] -diff --git a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchFloatInstrFormats.td b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchFloatInstrFormats.td -deleted file mode 100644 -index d2ba1fdff..000000000 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchFloatInstrFormats.td -+++ /dev/null -@@ -1,241 +0,0 @@ --//==- LoongArchInstrFormatsF.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. --// --//===----------------------------------------------------------------------===// -- --// 2R-type --// --class FPFmt2R op, dag outs, dag ins, string opcstr, string opnstr, -- list pattern = []> -- : LAInst { -- bits<5> fj; -- bits<5> fd; -- -- let Inst{31-10} = op; -- let Inst{9-5} = fj; -- let Inst{4-0} = fd; --} -- --// 3R-type --// --class FPFmt3R op, dag outs, dag ins, string opcstr, string opnstr, -- list pattern = []> -- : LAInst { -- bits<5> fk; -- bits<5> fj; -- bits<5> fd; -- -- let Inst{31-15} = 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 opcstr, string opnstr, -- list pattern = []> -- : LAInst { -- bits<5> fa; -- bits<5> fk; -- bits<5> fj; -- bits<5> fd; -- -- let Inst{31-20} = 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 opcstr, string opnstr, -- list pattern = []> -- : LAInst { -- bits<12> imm12; -- bits<5> rj; -- bits<5> fd; -- -- let Inst{31-22} = op; -- let Inst{21-10} = imm12; -- let Inst{9-5} = rj; -- let Inst{4-0} = fd; --} -- --// FmtFCMP --// --class FPFmtFCMP op, bits<5> cond, dag outs, dag ins, string opcstr, -- string opnstr, list pattern = []> -- : LAInst { -- bits<5> fk; -- bits<5> fj; -- bits<3> cd; -- -- let Inst{31-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; --} -- --// FPFmtBR --// --class FPFmtBR opcode, dag outs, dag ins, string opcstr, -- string opnstr, list pattern = []> -- : LAInst { -- bits<21> imm21; -- bits<3> cj; -- -- let Inst{31-26} = opcode{7-2}; -- let Inst{25-10} = imm21{15-0}; -- let Inst{9-8} = opcode{1-0}; -- let Inst{7-5} = cj; -- let Inst{4-0} = imm21{20-16}; --} -- --// FmtFSEL --// --class FPFmtFSEL op, dag outs, dag ins, string opcstr, string opnstr, -- list pattern = []> -- : LAInst { -- bits<3> ca; -- bits<5> fk; -- bits<5> fj; -- bits<5> fd; -- -- let Inst{31-18} = 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 opcstr, string opnstr, -- list pattern = []> -- : LAInst { -- bits<5> src; -- bits<5> dst; -- -- let Inst{31-10} = op; -- let Inst{9-5} = src; -- let Inst{4-0} = dst; --} -- --// FPFmtMEM --// --class FPFmtMEM op, dag outs, dag ins, string opcstr, string opnstr, -- list pattern = []> -- : LAInst { -- bits<5> rk; -- bits<5> rj; -- bits<5> fd; -- -- let Inst{31-15} = op; -- let Inst{14-10} = rk; -- let Inst{9-5} = rj; -- let Inst{4-0} = fd; --} -- --//===----------------------------------------------------------------------===// --// Instruction class templates --//===----------------------------------------------------------------------===// -- --class FP_ALU_2R op, string opstr, RegisterClass rc> -- : FPFmt2R; -- --class FP_ALU_3R op, string opstr, RegisterClass rc> -- : FPFmt3R; -- --class FP_ALU_4R op, string opstr, RegisterClass rc> -- : FPFmt4R; -- --class FPCMPOpc value> { -- bits<12> val = value; --} -- --class FPCMPCond value> { -- bits<5> val = value; --} -- --class FP_CMP -- : FPFmtFCMP; -- --class FP_CONV op, string opstr, RegisterClass rcd, RegisterClass rcs> -- : FPFmt2R; -- --class FP_MOV op, string opstr, RegisterClass rcd, RegisterClass rcs> -- : FPFmtMOV; -- --class FP_SEL op, string opstr, RegisterClass rc> -- : FPFmtFSEL; -- --class FP_BRANCH opcode, string opstr> -- : FPFmtBR { -- let isBranch = 1; -- let isTerminator = 1; --} -- --let mayLoad = 1 in { --class FP_LOAD_3R op, string opstr, RegisterClass rc> -- : FPFmtMEM; --class FP_LOAD_2RI12 op, string opstr, RegisterClass rc> -- : FPFmt2RI12; --} // mayLoad = 1 -- --let mayStore = 1 in { --class FP_STORE_3R op, string opstr, RegisterClass rc> -- : FPFmtMEM; --class FP_STORE_2RI12 op, string opstr, RegisterClass rc> -- : FPFmt2RI12; --} // mayStore = 1 -- --def FPCMP_OPC_S : FPCMPOpc<0b000011000001>; --def FPCMP_OPC_D : FPCMPOpc<0b000011000010>; -- --def FPCMP_COND_CAF : FPCMPCond<0x0>; --def FPCMP_COND_CUN : FPCMPCond<0x8>; --def FPCMP_COND_CEQ : FPCMPCond<0x4>; --def FPCMP_COND_CUEQ : FPCMPCond<0xC>; --def FPCMP_COND_CLT : FPCMPCond<0x2>; --def FPCMP_COND_CULT : FPCMPCond<0xA>; --def FPCMP_COND_CLE : FPCMPCond<0x6>; --def FPCMP_COND_CULE : FPCMPCond<0xE>; --def FPCMP_COND_CNE : FPCMPCond<0x10>; --def FPCMP_COND_COR : FPCMPCond<0x14>; --def FPCMP_COND_CUNE : FPCMPCond<0x18>; --def FPCMP_COND_SAF : FPCMPCond<0x1>; --def FPCMP_COND_SUN : FPCMPCond<0x9>; --def FPCMP_COND_SEQ : FPCMPCond<0x5>; --def FPCMP_COND_SUEQ : FPCMPCond<0xD>; --def FPCMP_COND_SLT : FPCMPCond<0x3>; --def FPCMP_COND_SULT : FPCMPCond<0xB>; --def FPCMP_COND_SLE : FPCMPCond<0x7>; --def FPCMP_COND_SULE : FPCMPCond<0xF>; --def FPCMP_COND_SNE : FPCMPCond<0x11>; --def FPCMP_COND_SOR : FPCMPCond<0x15>; --def FPCMP_COND_SUNE : FPCMPCond<0x19>; -diff --git a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp -index 0d9ec9e2e..7c4c141e1 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp -+++ b/src/llvm-project/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,192 +11,365 @@ - //===----------------------------------------------------------------------===// - - #include "LoongArchFrameLowering.h" --#include "LoongArchMachineFunctionInfo.h" --#include "LoongArchSubtarget.h" - #include "MCTargetDesc/LoongArchBaseInfo.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(); -- -- if (DestReg == SrcReg && Val == 0) -- return; -+ const std::vector &CSI = MFI.getCalleeSavedInfo(); -+ uint64_t StackSize = MFI.getStackSize(); - -- if (isInt<12>(Val)) { -- // addi.w/d $DstReg, $SrcReg, Val -- BuildMI(MBB, MBBI, DL, -- TII->get(IsLA64 ? LoongArch::ADDI_D : LoongArch::ADDI_W), DestReg) -- .addReg(SrcReg) -- .addImm(Val) -- .setMIFlag(Flag); -- return; -+ // 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); - } -- -- report_fatal_error("adjustReg cannot yet handle adjustments >12 bits"); -+ return 0; - } - --// 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); --} -+//===----------------------------------------------------------------------===// -+// -+// 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(); -- const LoongArchRegisterInfo *RI = STI.getRegisterInfo(); -- const LoongArchInstrInfo *TII = STI.getInstrInfo(); -- MachineBasicBlock::iterator MBBI = MBB.begin(); -+ LoongArchFunctionInfo *LoongArchFI = MF.getInfo(); - -- Register SPReg = LoongArch::R3; -- Register FPReg = LoongArch::R22; -- -- // Debug location must be unknown since the first debug location is used -- // to determine the end of the prologue. -- DebugLoc DL; -- -- // 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; - -+ uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF, true); -+ uint64_t SecondSPAdjustAmount = RealStackSize - FirstSPAdjustAmount; -+ // Split the SP adjustment to reduce the offsets of callee saved spill. -+ if (FirstSPAdjustAmount) -+ StackSize = FirstSPAdjustAmount; -+ - // Adjust stack. -- adjustReg(MBB, MBBI, DL, SPReg, SPReg, -StackSize, MachineInstr::FrameSetup); -- // 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); -+ 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); -+ } - -- const auto &CSI = MFI.getCalleeSavedInfo(); -+ MachineModuleInfo &MMI = MF.getMMI(); -+ const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo(); -+ -+ 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); -+ } -+ } - -- // 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); -+ 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); -+ } -+ -+ // 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); -+ } - } - -- // Generate new FP. -+ // If framepointer enabled, set it to point to the stack pointer on entry. - if (hasFP(MF)) { -- adjustReg(MBB, MBBI, DL, FPReg, SPReg, StackSize, MachineInstr::FrameSetup); -- -- // Emit ".cfi_def_cfa $fp, 0" -- unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::cfiDefCfa( -- nullptr, RI->getDwarfRegNum(FPReg, true), 0)); -- BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) -+ // 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, MRI->getDwarfRegNum(FP, true), -+ LoongArchFI->getVarArgsSaveSize())); -+ BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) - .addCFIIndex(CFIIndex) - .setMIFlag(MachineInstr::FrameSetup); - } -+ -+ // Emit the second SP adjustment after saving callee saved registers. -+ if (FirstSPAdjustAmount && SecondSPAdjustAmount) { -+ if (hasFP(MF)) { -+ assert(SecondSPAdjustAmount > 0 && -+ "SecondSPAdjustAmount should be greater than zero"); -+ 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 -+ // caller's stack data. Therefore, until there is better way, we just use -+ // 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(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 StackSize" -+ unsigned CFIIndex = MF.addFrameInst( -+ MCCFIInstruction::cfiDefCfaOffset(nullptr, MFI.getStackSize())); -+ BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) -+ .addCFIIndex(CFIIndex) -+ .setMIFlag(MachineInstr::FrameSetup); -+ } -+ } -+ -+ // Realign stack. -+ if (hasFP(MF)) { -+ 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 = countTrailingZeros((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 $s7, $sp -+ unsigned BP = STI.isABI_LP64() ? LoongArch::S7_64 : LoongArch::S7; -+ BuildMI(MBB, MBBI, dl, TII.get(MOVE), BP).addReg(SP).addReg(ZERO); -+ } -+ } -+ } - } - - void LoongArchFrameLowering::emitEpilogue(MachineFunction &MF, - MachineBasicBlock &MBB) const { -- const LoongArchRegisterInfo *RI = STI.getRegisterInfo(); -- MachineFrameInfo &MFI = MF.getFrameInfo(); -- Register SPReg = LoongArch::R3; -- - 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, -- 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); - } - -- // Deallocate stack -- adjustReg(MBB, MBBI, DL, SPReg, SPReg, StackSize, MachineInstr::FrameDestroy); --} -+ uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF); -+ if (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; -+ -+ TII.adjustReg(SP, SP, SecondSPAdjustAmount, MBB, I); -+ } - --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); -+ if (LoongArchFI->callsEhReturn()) { -+ const TargetRegisterClass *RC = -+ ABI.ArePtrs64bit() ? &LoongArch::GPR64RegClass : &LoongArch::GPR32RegClass; -+ -+ // Find first instruction that restores a callee-saved register. -+ MachineBasicBlock::iterator I = MBBI; -+ for (unsigned i = 0; i < MFI.getCalleeSavedInfo().size(); ++i) -+ --I; -+ -+ // 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); - } -- // Mark BP as used if function has dedicated base pointer. -- if (hasBP(MF)) -- SavedRegs.set(LoongArchABI::getBPReg()); -+ -+ if (FirstSPAdjustAmount) -+ StackSize = FirstSPAdjustAmount; -+ -+ if (!StackSize) -+ return; -+ -+ // 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(); -+ 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 -@@ -207,17 +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(); - } - -- FrameReg = RI->getFrameRegister(MF); -- if ((FI >= MinCSFI && FI <= MaxCSFI) || !hasFP(MF)) { -- 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(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) ? 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(MFI.getStackSize()); - } -- - return Offset; - } -+ -+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); -+ } -+ -+ 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(); -+ -+ // 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/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchFrameLowering.h b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchFrameLowering.h -index 72d8e006a..74aabaeb4 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchFrameLowering.h -+++ b/src/llvm-project/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,51 +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; - -+ StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, -+ Register &FrameReg) const override; -+ -+ bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, -+ MachineBasicBlock::iterator MI, -+ ArrayRef CSI, -+ const TargetRegisterInfo *TRI) const override; -+ -+ bool hasReservedCallFrame(const MachineFunction &MF) const override; -+ - void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, - RegScavenger *RS) const override; - -- MachineBasicBlock::iterator -- eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, -- MachineBasicBlock::iterator MI) const override { -- return MBB.erase(MI); -+ bool hasFP(const MachineFunction &MF) const override; -+ -+ bool hasBP(const MachineFunction &MF) const; -+ -+ bool enableShrinkWrapping(const MachineFunction &MF) const override { -+ return true; - } - -- StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, -- Register &FrameReg) const override; -+ MachineBasicBlock::iterator -+ eliminateCallFramePseudoInstr(MachineFunction &MF, -+ MachineBasicBlock &MBB, -+ MachineBasicBlock::iterator I) const override; - -- bool hasFP(const MachineFunction &MF) const override; -- bool hasBP(const MachineFunction &MF) const; -+ // 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; - --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/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.cpp b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.cpp -index bb40ff817..0efb739e0 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.cpp -+++ b/src/llvm-project/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,176 +11,868 @@ - //===----------------------------------------------------------------------===// - - #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" - --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; -- } -+//===----------------------------------------------------------------------===// -+// Instruction Selector Implementation -+//===----------------------------------------------------------------------===// - -- // 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); -+//===----------------------------------------------------------------------===// -+// LoongArchDAGToDAGISel - LoongArch specific code to select LoongArch machine -+// instructions for SelectionDAG operations. -+//===----------------------------------------------------------------------===// - -- 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::PostprocessISelDAG() { doPeepholeLoadStoreADDI(); } - -- ReplaceNode(Node, Result); -- return; -+void LoongArchDAGToDAGISel::getAnalysisUsage(AnalysisUsage &AU) const { -+ AU.addRequired(); -+ SelectionDAGISel::getAnalysisUsage(AU); -+} -+ -+bool LoongArchDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) { -+ Subtarget = &static_cast(MF.getSubtarget()); -+ bool Ret = SelectionDAGISel::runOnMachineFunction(MF); -+ -+ return Ret; -+} -+ -+/// Match frameindex -+bool LoongArchDAGToDAGISel::selectAddrFrameIndex(SDValue Addr, SDValue &Base, -+ SDValue &Offset) const { -+ if (FrameIndexSDNode *FIN = dyn_cast(Addr)) { -+ EVT ValTy = Addr.getValueType(); -+ -+ Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy); -+ Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), ValTy); -+ return true; - } -- 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; -+ return false; -+} -+ -+/// 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; -+ } - } -- // TODO: Add selection nodes needed later. -+ return false; -+} -+ -+/// 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; -+ -+ if (!TM.isPositionIndependent()) { -+ if ((Addr.getOpcode() == ISD::TargetExternalSymbol || -+ Addr.getOpcode() == ISD::TargetGlobalAddress)) -+ return false; - } - -- // Select the default instruction. -- SelectCode(Node); -+ // Addresses of the form FI+const or FI|const -+ if (selectAddrFrameIndexOffset(Addr, Base, Offset, 12)) -+ return true; -+ -+ 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; -+/// 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); -+} -+ -+bool LoongArchDAGToDAGISel::selectAddrRegImm12(SDValue Addr, SDValue &Base, -+ SDValue &Offset) const { -+ if (selectAddrFrameIndex(Addr, Base, Offset)) -+ return true; -+ -+ if (selectAddrFrameIndexOffset(Addr, Base, Offset, 12)) -+ return true; -+ -+ return false; -+} -+ -+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::selectIntAddrSImm10Lsl1(SDValue Addr, SDValue &Base, -+ SDValue &Offset) const { -+ if (selectAddrFrameIndex(Addr, Base, Offset)) -+ return true; - -- // 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); -+ if (selectAddrFrameIndexOffset(Addr, Base, Offset, 10, 1)) -+ return true; - -- if (ShMask.isSubsetOf(AndMask)) { -- ShAmt = N.getOperand(0); -+ return selectAddrDefault(Addr, Base, Offset); -+} -+ -+bool LoongArchDAGToDAGISel::selectIntAddrSImm10(SDValue Addr, SDValue &Base, -+ SDValue &Offset) const { -+ if (selectAddrFrameIndex(Addr, Base, Offset)) -+ return true; -+ -+ if (selectAddrFrameIndexOffset(Addr, Base, Offset, 10)) -+ return true; -+ -+ return selectAddrDefault(Addr, Base, Offset); -+} -+ -+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->hasLSX() || Subtarget->hasLASX())) -+ return false; -+ -+ BuildVectorSDNode *Node = dyn_cast(N); -+ -+ if (!Node) -+ return false; -+ -+ APInt SplatValue, SplatUndef; -+ unsigned SplatBitSize; -+ bool HasAnyUndefs; -+ -+ if (!Node->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs, -+ MinSizeInBits)) -+ return false; -+ -+ Imm = SplatValue; -+ -+ return true; -+} -+ -+// 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(); -+ -+ if (N->getOpcode() == ISD::BITCAST) -+ N = N->getOperand(0); -+ -+ if (selectVSplat(N.getNode(), ImmValue, EltTy.getSizeInBits()) && -+ ImmValue.getBitWidth() == EltTy.getSizeInBits()) { -+ -+ if ((Signed && ImmValue.isSignedIntN(ImmBitSize)) || -+ (!Signed && ImmValue.isIntN(ImmBitSize))) { -+ Imm = CurDAG->getTargetConstant(ImmValue, SDLoc(N), EltTy); - return true; - } -+ } -+ -+ 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); -+} - -- // 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); -+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; - } -- } 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 false; -+} -+ -+bool LoongArchDAGToDAGISel::selectVSplatUimmInvPow2(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; - } -- } 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 false; -+} -+ -+// 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(); -+ -+ 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 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))) { -+ -+ Imm = CurDAG->getTargetConstant(ImmValue.countPopulation() - 1, SDLoc(N), -+ EltTy); - return true; - } - } - -- ShAmt = N; -- return true; -+ return false; - } - --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); -- return true; -- } -- MVT VT = N.getSimpleValueType(); -- if (CurDAG->ComputeNumSignBits(N) > (VT.getSizeInBits() - 32)) { -- Val = N; -- return true; -+// 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.countPopulation() - 1, SDLoc(N), -+ EltTy); -+ return true; -+ } - } - - return false; - } - --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); -+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; - } -- MVT VT = N.getSimpleValueType(); -- APInt Mask = APInt::getHighBitsSet(VT.getSizeInBits(), 32); -- if (CurDAG->MaskedValueIsZero(N, Mask)) { -- Val = N; -+ -+ 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; - } - --// 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 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, unsigned 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::Constraint_i: -+ OutOps.push_back(Op); -+ OutOps.push_back(CurDAG->getTargetConstant(0, SDLoc(Op), MVT::i32)); -+ return false; -+ case InlineAsm::Constraint_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::Constraint_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::Constraint_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::Constraint_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()); -+ } -+} -+ -+FunctionPass *llvm::createLoongArchISelDag(LoongArchTargetMachine &TM, -+ CodeGenOpt::Level OptLevel) { -+ return new LoongArchDAGToDAGISel(TM, OptLevel); - } -diff --git a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h -index 8c9357d75..765497318 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h -+++ b/src/llvm-project/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,47 +14,138 @@ - #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: -- explicit LoongArchDAGToDAGISel(LoongArchTargetMachine &TM) -- : SelectionDAGISel(TM) {} -+ explicit LoongArchDAGToDAGISel(LoongArchTargetMachine &TM, CodeGenOpt::Level OL) -+ : SelectionDAGISel(TM, OL), Subtarget(nullptr) {} - -+ // Pass Name - StringRef getPassName() const override { - return "LoongArch DAG->DAG Pattern Instruction Selection"; - } - -- bool runOnMachineFunction(MachineFunction &MF) override { -- Subtarget = &MF.getSubtarget(); -- return SelectionDAGISel::runOnMachineFunction(MF); -- } -+ bool runOnMachineFunction(MachineFunction &MF) override; - -- void Select(SDNode *Node) override; -+ void PostprocessISelDAG() override; - -- bool SelectBaseAddr(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" -+ -+ void doPeepholeLoadStoreADDI(); -+ -+ 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; -+ -+ /// Fall back on this function if all else fails. -+ bool selectAddrDefault(SDValue Addr, SDValue &Base, SDValue &Offset) const; - -- bool selectSExti32(SDValue N, SDValue &Val); -- bool selectZExti32(SDValue N, SDValue &Val); -+ /// Match integer address pattern. -+ bool selectIntAddr(SDValue Addr, SDValue &Base, SDValue &Offset) const; -+ -+ 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)); -+ } - --// Include the pieces autogenerated from the target description. --#include "LoongArchGenDAGISel.inc" -+ bool SelectInlineAsmMemoryOperand(const SDValue &Op, -+ unsigned ConstraintID, -+ std::vector &OutOps) override; - }; - --} // end namespace llvm -+FunctionPass *createLoongArchISelDag(LoongArchTargetMachine &TM, -+ CodeGenOpt::Level OptLevel); -+} - --#endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELDAGTODAG_H -+#endif -diff --git a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp -index 93c886434..6b258813b 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp -+++ b/src/llvm-project/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,1094 +6,8213 @@ - // - //===----------------------------------------------------------------------===// - // --// 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/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/StringRef.h" -+#include "llvm/ADT/StringSwitch.h" -+#include "llvm/ADT/Triple.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/RuntimeLibcalls.h" -+#include "llvm/CodeGen/SelectionDAG.h" -+#include "llvm/CodeGen/SelectionDAGNodes.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/KnownBits.h" -+#include "llvm/Support/ErrorHandling.h" -+#include "llvm/Support/MachineValueType.h" -+#include "llvm/Support/MathExtras.h" -+#include "llvm/Support/raw_ostream.h" -+#include "llvm/Target/TargetMachine.h" -+#include "llvm/Target/TargetOptions.h" -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include - - using namespace llvm; - --#define DEBUG_TYPE "loongarch-isel-lowering" -+#define DEBUG_TYPE "loongarch-lower" - --static cl::opt ZeroDivCheck( -- "loongarch-check-zero-division", cl::Hidden, -- cl::desc("Trap on integer division by zero."), -- cl::init(false)); -+STATISTIC(NumTailCalls, "Number of tail calls"); - --LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM, -- const LoongArchSubtarget &STI) -- : TargetLowering(TM), Subtarget(STI) { -+static cl::opt -+NoZeroDivCheck("mnocheck-zero-division", cl::Hidden, -+ cl::desc("LoongArch: Don't trap on integer division by zero."), -+ cl::init(false)); - -- 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 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 -+}; - -- setLoadExtAction({ISD::EXTLOAD, ISD::SEXTLOAD, ISD::ZEXTLOAD}, GRLenVT, -- MVT::i1, Promote); -+// 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; - -- // TODO: add necessary setOperationAction calls later. -- 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); -+ SMSize = countPopulation(I); -+ SMLsb = countTrailingZeros(I); -+ return true; -+} - -- setOperationAction({ISD::GlobalAddress, ISD::ConstantPool}, GRLenVT, Custom); -+SDValue LoongArchTargetLowering::getTargetNode(GlobalAddressSDNode *N, EVT Ty, -+ SelectionDAG &DAG, -+ unsigned Flag) const { -+ return DAG.getTargetGlobalAddress(N->getGlobal(), SDLoc(N), Ty, 0, Flag); -+} - -- 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); -- if (Subtarget.hasBasicF() && !Subtarget.hasBasicD()) -- setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom); -+SDValue LoongArchTargetLowering::getTargetNode(ExternalSymbolSDNode *N, EVT Ty, -+ SelectionDAG &DAG, -+ unsigned Flag) const { -+ return DAG.getTargetExternalSymbol(N->getSymbol(), Ty, Flag); -+} -+ -+SDValue LoongArchTargetLowering::getTargetNode(BlockAddressSDNode *N, EVT Ty, -+ SelectionDAG &DAG, -+ unsigned Flag) const { -+ return DAG.getTargetBlockAddress(N->getBlockAddress(), Ty, N->getOffset(), Flag); -+} -+ -+SDValue LoongArchTargetLowering::getTargetNode(JumpTableSDNode *N, EVT Ty, -+ SelectionDAG &DAG, -+ unsigned Flag) const { -+ return DAG.getTargetJumpTable(N->getIndex(), Ty, Flag); -+} -+ -+SDValue LoongArchTargetLowering::getTargetNode(ConstantPoolSDNode *N, EVT Ty, -+ SelectionDAG &DAG, -+ unsigned Flag) const { -+ return DAG.getTargetConstantPool(N->getConstVal(), Ty, N->getAlign(), -+ N->getOffset(), Flag); -+} -+ -+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::DBAR: return "LoongArchISD::DBAR"; -+ 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; -+} -+ -+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); - -- static const ISD::CondCode FPCCToExpand[] = {ISD::SETOGT, ISD::SETOGE, -- ISD::SETUGT, ISD::SETUGE}; -+ if (Subtarget.is64Bit()) -+ addRegisterClass(MVT::i64, &LoongArch::GPR64RegClass); - -- if (Subtarget.hasBasicF()) { -- setCondCodeAction(FPCCToExpand, MVT::f32, Expand); -- setOperationAction(ISD::SELECT_CC, MVT::f32, Expand); -+ // LoongArch does not have i1 type, so use i32 for -+ // setcc operations results (slt, sgt, ...). -+ setBooleanContents(ZeroOrOneBooleanContent); -+ setBooleanVectorContents(ZeroOrNegativeOneBooleanContent); -+ -+ // 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); - } -- if (Subtarget.hasBasicD()) { -- setCondCodeAction(FPCCToExpand, MVT::f64, Expand); -- setOperationAction(ISD::SELECT_CC, MVT::f64, Expand); -- setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::f32, Expand); -- setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::f32, Expand); -+ -+ // 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); - } - -- 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()) -- setLibcallName(RTLIB::MUL_I128, nullptr); -+ // 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); -+ } - -- setOperationAction(ISD::FP_TO_UINT, GRLenVT, Custom); -- setOperationAction(ISD::UINT_TO_FP, GRLenVT, Custom); -+ 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); - -- // Compute derived properties from the register classes. -- computeRegisterProperties(STI.getRegisterInfo()); -+ 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); -+ } - -- setStackPointerRegisterToSaveRestore(LoongArch::R3); -+ if (!Subtarget.is64Bit()) { -+ setOperationAction(ISD::SHL_PARTS, MVT::i32, Custom); -+ setOperationAction(ISD::SRA_PARTS, MVT::i32, Custom); -+ setOperationAction(ISD::SRL_PARTS, MVT::i32, Custom); -+ } - -- setBooleanContents(ZeroOrOneBooleanContent); -+ 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); -+ -+ if (!Subtarget.is64Bit()) { -+ setOperationAction(ISD::ATOMIC_LOAD, MVT::i64, Expand); -+ setOperationAction(ISD::ATOMIC_STORE, MVT::i64, Expand); -+ } - -- setMaxAtomicSizeInBitsSupported(Subtarget.getGRLen()); -+ if (Subtarget.is64Bit()) { -+ setLoadExtAction(ISD::EXTLOAD, MVT::i64, MVT::i32, Custom); -+ setTruncStoreAction(MVT::i64, MVT::i32, Custom); -+ } - -- // Function alignments. -- const Align FunctionAlignment(4); -- setMinFunctionAlignment(FunctionAlignment); -+ 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); - --SDValue LoongArchTargetLowering::LowerOperation(SDValue Op, -- SelectionDAG &DAG) const { -- switch (Op.getOpcode()) { -- default: -- report_fatal_error("unimplemented operand"); -- case ISD::GlobalAddress: -- return lowerGlobalAddress(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::SHL: -- case ISD::SRA: -- case ISD::SRL: -- // This can be called for an i32 shift amount that needs to be promoted. -- assert(Op.getOperand(1).getValueType() == MVT::i32 && Subtarget.is64Bit() && -- "Unexpected custom legalisation"); -- return SDValue(); -- 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::FP_TO_UINT: -- return SDValue(); -- case ISD::UINT_TO_FP: -- return lowerUINT_TO_FP(Op, DAG); -+ 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); - } --} - --SDValue LoongArchTargetLowering::lowerUINT_TO_FP(SDValue Op, -- SelectionDAG &DAG) const { -+ 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); -+ } -+ } -+ } - -- SDLoc DL(Op); -- auto &TLI = DAG.getTargetLoweringInfo(); -- SDValue Tmp1, Tmp2; -- SDValue Op1 = Op.getOperand(0); -- if (Op1->getOpcode() == ISD::AssertZext || -- Op1->getOpcode() == ISD::AssertSext) -- return Op; -- SDValue Trunc = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Op.getOperand(0)); -- SDValue Res = DAG.getNode(ISD::UINT_TO_FP, DL, MVT::f64, Trunc); -- SDNode *N = Res.getNode(); -- TLI.expandUINT_TO_FP(N, Tmp1, Tmp2, DAG); -- return Tmp1; --} -+ 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); -+ } - --SDValue LoongArchTargetLowering::lowerBITCAST(SDValue Op, -- SelectionDAG &DAG) const { -+ 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); -+ } - -- SDLoc DL(Op); -- SDValue Op0 = Op.getOperand(0); -+ if (!Subtarget.useSoftFloat()) { -+ addRegisterClass(MVT::f32, &LoongArch::FGR32RegClass); - -- 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); -+ // When dealing with single precision only, use libcalls -+ if (!Subtarget.isSingleFloat()) { -+ if (Subtarget.isFP64bit()) -+ addRegisterClass(MVT::f64, &LoongArch::FGR64RegClass); -+ } - } -- return Op; --} - --SDValue LoongArchTargetLowering::lowerFP_TO_SINT(SDValue Op, -- SelectionDAG &DAG) const { -+ setOperationAction(ISD::SMUL_LOHI, MVT::i32, Custom); -+ setOperationAction(ISD::UMUL_LOHI, MVT::i32, Custom); - -- SDLoc DL(Op); -+ if (Subtarget.is64Bit()) -+ setOperationAction(ISD::MUL, MVT::i64, Custom); -+ -+ 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); -+ } - -- 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); -+ setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i64, Custom); -+ setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::i64, Custom); -+ -+ 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); -+ -+ setTargetDAGCombine(ISD::MUL); -+ -+ setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom); -+ setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom); -+ setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom); -+ -+ // 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; -+ -+ setMinFunctionAlignment(Align(4)); -+ -+ // 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)); -+ -+ setStackPointerRegisterToSaveRestore(ABI.IsLP64() ? LoongArch::SP_64 : LoongArch::SP); -+ -+ if (Subtarget.hasLASX()) { -+ // = 16*32/2; the smallest memcpy; -+ MaxStoresPerMemcpy = 16; -+ } else if (Subtarget.hasLSX()) { -+ MaxStoresPerMemcpy = 65535; -+ } else { -+ MaxStoresPerMemcpy = 16; - } - -- 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); -+ computeRegisterProperties(Subtarget.getRegisterInfo()); - } - --SDValue LoongArchTargetLowering::lowerConstantPool(SDValue Op, -- SelectionDAG &DAG) const { -- SDLoc DL(Op); -- EVT Ty = Op.getValueType(); -- ConstantPoolSDNode *N = cast(Op); -+// 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, Legal); -+ 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); -+ } - -- // FIXME: Only support PC-relative addressing to access the symbol. -- // Target flags will be added later. -- if (!isPositionIndependent()) { -- SDValue ConstantN = DAG.getTargetConstantPool( -- N->getConstVal(), Ty, N->getAlign(), N->getOffset()); -- SDValue AddrHi(DAG.getMachineNode(LoongArch::PCALAU12I, DL, Ty, ConstantN), -- 0); -- SDValue Addr(DAG.getMachineNode(Subtarget.is64Bit() ? LoongArch::ADDI_D -- : LoongArch::ADDI_W, -- DL, Ty, AddrHi, ConstantN), -- 0); -- return Addr; -+ 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); - } -- report_fatal_error("Unable to lower ConstantPool"); --} - --SDValue LoongArchTargetLowering::lowerGlobalAddress(SDValue Op, -- SelectionDAG &DAG) const { -- SDLoc DL(Op); -- EVT Ty = getPointerTy(DAG.getDataLayout()); -- const GlobalValue *GV = cast(Op)->getGlobal(); -- unsigned ADDIOp = Subtarget.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W; -+ 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); -+} - -- // TODO: Support dso_preemptable and target flags. -- if (GV->isDSOLocal()) { -- SDValue GA = DAG.getTargetGlobalAddress(GV, DL, Ty); -- SDValue AddrHi(DAG.getMachineNode(LoongArch::PCALAU12I, DL, Ty, GA), 0); -- SDValue Addr(DAG.getMachineNode(ADDIOp, DL, Ty, AddrHi, GA), 0); -- return Addr; -+// 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); - } -- report_fatal_error("Unable to lowerGlobalAddress"); -+ -+ 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); - } - --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(); -+// 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, Legal); -+ 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); -+ } - -- // 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); -+ 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 CC = DAG.getSetCC(DL, VT, ShamtMinusGRLen, Zero, ISD::SETLT); -+// 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, Legal); -+ setOperationAction(ISD::INSERT_VECTOR_ELT, Ty, Legal); -+ 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); -+ } - -- Lo = DAG.getNode(ISD::SELECT, DL, VT, CC, LoTrue, Zero); -- Hi = DAG.getNode(ISD::SELECT, DL, VT, CC, HiTrue, HiFalse); -+ 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 Parts[2] = {Lo, Hi}; -- return DAG.getMergeValues(Parts, DL); -+bool LoongArchTargetLowering::allowsMisalignedMemoryAccesses( -+ EVT VT, unsigned AddrSpace, Align Alignment, MachineMemOperand::Flags Flags, -+ bool *Fast) const { -+ if (!Subtarget.allowUnalignedAccess()) -+ return false; -+ if (Fast) -+ *Fast = true; -+ return true; - } - --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) -- // -- // 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); -+EVT LoongArchTargetLowering::getSetCCResultType(const DataLayout &, LLVMContext &, -+ EVT VT) const { -+ if (!VT.isVector()) -+ return MVT::i32; -+ return VT.changeVectorElementTypeToInteger(); -+} - -- 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; -+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; -+ } -+} - -- SDValue CC = DAG.getSetCC(DL, VT, ShamtMinusGRLen, Zero, ISD::SETLT); -+/// 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; - -- Lo = DAG.getNode(ISD::SELECT, DL, VT, CC, LoTrue, LoFalse); -- Hi = DAG.getNode(ISD::SELECT, DL, VT, CC, HiTrue, HiFalse); -+ assert((CC >= LoongArch::FCOND_T && CC <= LoongArch::FCOND_GT) && -+ "Illegal Condition Code"); - -- SDValue Parts[2] = {Lo, Hi}; -- return DAG.getMergeValues(Parts, DL); -+ return true; - } - --// 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; -- } -+// 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; -+ -+ SDValue LHS = Op.getOperand(0); -+ -+ if (!LHS.getValueType().isFloatingPoint()) -+ return Op; -+ -+ SDValue RHS = Op.getOperand(1); -+ SDLoc DL(Op); -+ -+ // 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)); - } - --// 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, -- unsigned ExtOpc = ISD::ANY_EXTEND) { -- SDLoc DL(N); -- LoongArchISD::NodeType WOpcode = getLoongArchWOpcode(N->getOpcode()); -- SDValue NewOp0 = DAG.getNode(ExtOpc, DL, MVT::i64, N->getOperand(0)); -- SDValue NewOp1 = DAG.getNode(ExtOpc, DL, MVT::i64, N->getOperand(1)); -- SDValue NewRes = DAG.getNode(WOpcode, DL, MVT::i64, NewOp0, NewOp1); -- // ReplaceNodeResults requires we maintain the same type for the return value. -- return DAG.getNode(ISD::TRUNCATE, DL, N->getValueType(0), NewRes); -+// 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); -+ -+ return DAG.getNode((invert ? LoongArchISD::CMovFP_F : LoongArchISD::CMovFP_T), DL, -+ True.getValueType(), True, FCC0, False, Cond); -+ - } - --void LoongArchTargetLowering::ReplaceNodeResults( -- SDNode *N, SmallVectorImpl &Results, SelectionDAG &DAG) const { -- SDLoc DL(N); -- switch (N->getOpcode()) { -- default: -- llvm_unreachable("Don't know how to legalize this operation"); -- case ISD::SHL: -- case ISD::SRA: -- case ISD::SRL: -- assert(N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() && -- "Unexpected custom legalisation"); -- if (N->getOperand(1).getOpcode() != ISD::Constant) { -- Results.push_back(customLegalizeToWOp(N, DAG)); -- break; -- } -- break; -- case ISD::FP_TO_SINT: { -- assert(N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() && -- "Unexpected custom legalisation"); -- SDValue Src = N->getOperand(0); -- EVT VT = EVT::getFloatingPointVT(N->getValueSizeInBits(0)); -- SDValue Dst = DAG.getNode(LoongArchISD::FTINT, DL, VT, Src); -- Results.push_back(DAG.getNode(ISD::BITCAST, DL, N->getValueType(0), Dst)); -- break; -- } -- case ISD::BITCAST: { -- EVT VT = N->getValueType(0); -- 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(N->getValueType(0) == 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; -+static SDValue performSELECTCombine(SDNode *N, SelectionDAG &DAG, -+ TargetLowering::DAGCombinerInfo &DCI, -+ const LoongArchSubtarget &Subtarget) { -+ if (DCI.isBeforeLegalizeOps()) -+ return SDValue(); -+ -+ SDValue SetCC = N->getOperand(0); -+ -+ if ((SetCC.getOpcode() != ISD::SETCC) || -+ !SetCC.getOperand(0).getValueType().isInteger()) -+ return SDValue(); -+ -+ SDValue False = N->getOperand(2); -+ EVT FalseTy = False.getValueType(); -+ -+ if (!FalseTy.isInteger()) -+ return SDValue(); -+ -+ ConstantSDNode *FalseC = dyn_cast(False); -+ -+ // 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(); -+ -+ const SDLoc DL(N); -+ -+ if (!FalseC->getZExtValue()) { -+ ISD::CondCode CC = cast(SetCC.getOperand(2))->get(); -+ SDValue True = N->getOperand(1); -+ -+ SetCC = DAG.getSetCC(DL, SetCC.getValueType(), SetCC.getOperand(0), -+ SetCC.getOperand(1), -+ ISD::getSetCCInverse(CC, SetCC.getValueType())); -+ -+ return DAG.getNode(ISD::SELECT, DL, FalseTy, SetCC, False, True); - } -+ -+ // 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(); -+ -+ // 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(); -+ -+ int64_t Diff = TrueC->getSExtValue() - FalseC->getSExtValue(); -+ -+ // 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); -+ -+ // 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(); - } - - static SDValue performANDCombine(SDNode *N, SelectionDAG &DAG, - TargetLowering::DAGCombinerInfo &DCI, - const LoongArchSubtarget &Subtarget) { -+ -+ if (Subtarget.hasLSX()) { -+ -+ // 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(), -+ makeArrayRef(Ops, Op0->getNumOperands())); -+ } -+ } -+ } -+ } -+ } -+ - if (DCI.isBeforeLegalizeOps()) - return SDValue(); - - SDValue FirstOperand = N->getOperand(0); -- SDValue SecondOperand = N->getOperand(1); - unsigned FirstOperandOpc = FirstOperand.getOpcode(); -+ SDValue Mask = N->getOperand(1); - EVT ValTy = N->getValueType(0); - SDLoc DL(N); -- uint64_t lsb, msb; -- unsigned SMIdx, SMLen; -+ -+ uint64_t Lsb = 0, SMLsb, SMSize; - ConstantSDNode *CN; - SDValue NewOperand; -- MVT GRLenVT = Subtarget.getGRLenVT(); -+ unsigned Opc; - - // Op's second operand must be a shifted mask. -- if (!(CN = dyn_cast(SecondOperand)) || -- !isShiftedMask_64(CN->getZExtValue(), SMIdx, SMLen)) -+ if (!(CN = dyn_cast(Mask)) || -+ !isShiftedMask(CN->getZExtValue(), SMLsb, SMSize)) - 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 -+ // $dst = and ((sra or srl) $src , lsb), (2**size - 1) -+ // => bstrpick $dst, $src, lsb+size-1, lsb - - // The second operand of the shift must be an immediate. - if (!(CN = dyn_cast(FirstOperand.getOperand(1)))) - return SDValue(); - -- lsb = CN->getZExtValue(); -+ Lsb = CN->getZExtValue(); - -- // 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()) -+ // 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(); - -+ Opc = LoongArchISD::BSTRPICK; - 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 -+ // $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 (SMIdx) -+ if (SMLsb) - return SDValue(); - -- lsb = 0; -+ Opc = LoongArchISD::BSTRPICK; - NewOperand = FirstOperand; - } -- msb = lsb + SMLen - 1; -- return DAG.getNode(LoongArchISD::BSTRPICK, DL, ValTy, NewOperand, -- DAG.getConstant(msb, DL, GRLenVT), -- DAG.getConstant(lsb, DL, GRLenVT)); -+ return DAG.getNode(Opc, DL, ValTy, NewOperand, -+ DAG.getConstant((Lsb + SMSize - 1), DL, MVT::i32), -+ DAG.getConstant(Lsb, DL, MVT::i32)); - } - --static SDValue performSRLCombine(SDNode *N, SelectionDAG &DAG, -- TargetLowering::DAGCombinerInfo &DCI, -- const LoongArchSubtarget &Subtarget) { -- if (DCI.isBeforeLegalizeOps()) -- return SDValue(); -+// 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()); - -- // $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 (!Node) -+ return false; - -- 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; -+ APInt SplatValue, SplatUndef; -+ unsigned SplatBitSize; -+ bool HasAnyUndefs; -+ -+ if (!Node->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs, -+ 8)) -+ return false; -+ -+ Imm = SplatValue; -+ -+ return true; -+} -+ -+// 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); - -- // 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)) -+ BuildVectorSDNode *BVN = dyn_cast(N); -+ -+ if (!BVN) -+ return false; -+ -+ APInt SplatValue, SplatUndef; -+ unsigned SplatBitSize; -+ bool HasAnyUndefs; -+ -+ // 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.isAllOnesValue(); -+ -+ return false; -+} -+ -+// Test whether N is the bitwise inverse of OfNode. -+static bool isBitwiseInverse(SDValue N, SDValue OfNode) { -+ if (N->getOpcode() != ISD::XOR) -+ return false; -+ -+ if (isVectorAllOnes(N->getOperand(0))) -+ return N->getOperand(1) == OfNode; -+ -+ if (isVectorAllOnes(N->getOperand(1))) -+ return N->getOperand(0) == OfNode; -+ -+ return false; -+} -+ -+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(); - -- // The second operand (shift amount) must be an immediate. -- if (!(CN = dyn_cast(N->getOperand(1)))) -+ APInt Mask1, Mask2; -+ if (!isVSplat(N1, Mask1)) - 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)); -+ if (!N1->getValueType(0).isSimple()) -+ return SDValue(); - -- return SDValue(); -+ ConstantSDNode *C1; -+ uint64_t Imm; -+ unsigned ImmL; -+ if (!(C1 = dyn_cast(N1.getOperand(0))) || -+ !isPowerOf2_64(C1->getZExtValue())) -+ return SDValue(); -+ -+ 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(); -+ -+ } else -+ return SDValue(); -+ -+ return SDValue(Res, 0); - } - - 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; - -+ 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; -+ } -+ -+ // 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; -+ } -+ -+ // 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; -+ } -+ } -+ -+ // At this point, IfClr will be set if we have a valid match. -+ if (IfClr.getNode()) { -+ assert(Cond.getNode() && IfSet.getNode()); -+ -+ // Fold degenerate cases. -+ if (IsConstantMask) { -+ if (Mask.isAllOnesValue()) -+ return IfSet; -+ else if (Mask == 0) -+ return IfClr; -+ } -+ -+ // Transform the DAG into an equivalent VSELECT. -+ return DAG.getNode(ISD::VSELECT, SDLoc(N), N->getValueType(0), Cond, -+ IfSet, IfClr); -+ } -+ } -+ -+ if (Res = performSet(N, DAG, DCI, Subtarget)) -+ return Res; -+ } -+ -+ // 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(); - -- if (ValBits != 32 && ValBits != 64) -+ SDValue And0 = N->getOperand(0), And1 = N->getOperand(1); -+ uint64_t SMLsb0, SMSize0, SMLsb1, SMSize1; -+ ConstantSDNode *CN, *CN1; -+ -+ // See if Op's first operand matches (and $src1 , mask0). -+ if (And0.getOpcode() != ISD::AND) - 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((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)); -+ if (!(CN = dyn_cast(And0.getOperand(1))) || -+ !isShiftedMask(~CN->getSExtValue(), SMLsb0, SMSize0)) -+ return SDValue(); -+ -+ // See if Op's second operand matches (and (shl $src, lsb), mask1). -+ if (And1.getOpcode() == ISD::AND && -+ And1.getOperand(0).getOpcode() == ISD::SHL) { -+ -+ if (!(CN = dyn_cast(And1.getOperand(1))) || -+ !isShiftedMask(CN->getZExtValue(), SMLsb1, SMSize1)) -+ return SDValue(); -+ -+ // The shift masks must have the same least significant bit and size. -+ if (SMLsb0 != SMLsb1 || SMSize0 != SMSize1) -+ return SDValue(); -+ -+ SDValue Shl = And1.getOperand(0); -+ -+ if (!(CN = dyn_cast(Shl.getOperand(1)))) -+ return SDValue(); -+ -+ unsigned Shamt = CN->getZExtValue(); -+ -+ // 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(); -+ -+ 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)); -+ - } -+ return SDValue(); - } -+} - -- // 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 -+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. -+ // -+ // 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. - // -- // 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)); -+ // 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; -+ -+ if (Steps >= MaxSteps) -+ return false; -+ -+ if (Val.isPowerOf2()) { -+ ++Steps; -+ continue; - } -- } - -- // (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; -- } -+ APInt Floor = APInt(BitWidth, 1) << Val.logBase2(); -+ APInt Ceil = Val.isNegative() ? APInt(BitWidth, 0) -+ : APInt(BitWidth, 1) << C.ceilLogBase2(); - -- 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 ((Val - Floor).ule(Ceil - Val)) { -+ WorkStack.push_back(Floor); -+ WorkStack.push_back(Val - Floor); -+ } else { -+ WorkStack.push_back(Ceil); -+ WorkStack.push_back(Ceil - Val); - } -- } -- // Swap N0/N1 and retry. -- if (!SwapAndRetried) { -- std::swap(N0, N1); -- SwapAndRetried = true; -- goto Retry2; -+ -+ ++Steps; - } - -- return SDValue(); --} -+ // 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; - --SDValue LoongArchTargetLowering::PerformDAGCombine(SDNode *N, -- DAGCombinerInfo &DCI) const { -- SelectionDAG &DAG = DCI.DAG; -- switch (N->getOpcode()) { -+ return true; -+} -+ -+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 SDValue performLogicCombine(SDNode *N, SelectionDAG &DAG, -+ const LoongArchSubtarget &Subtarget) { -+ -+ SDLoc DL(N); -+ 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(); -+ -+ 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 SDValue performMULCombine(SDNode *N, SelectionDAG &DAG, -+ const TargetLowering::DAGCombinerInfo &DCI, -+ const LoongArchTargetLowering *TL, -+ const LoongArchSubtarget &Subtarget) { -+ 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); -+} -+ -+// 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(), -+ makeArrayRef(Ops, Op0Op0->getNumOperands())); -+ } -+ } -+ } -+ -+ 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::SETULT: -+ case ISD::SETULE: -+ case ISD::SETLT: -+ case ISD::SETLE: -+ std::swap(TrueOpnd, FalseOpnd); - 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)); -+ } -+ } -+ 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 -+ return SDValue(); -+ -+ if (NotOp->getOpcode() == ISD::OR) -+ return DAG.getNode(LoongArchISD::VNOR, SDLoc(N), Ty, NotOp->getOperand(0), -+ NotOp->getOperand(1)); -+ } -+ -+ return SDValue(); -+} -+ -+// 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(); -+ -+ SDLoc DL(N); -+ SDValue Top0 = N->getOperand(0); -+ SDValue Top1 = N->getOperand(1); -+ -+ // 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(); -+ -+ 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(); -+ } -+ -+ 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(); -+ } -+ -+ // 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(); -+ } -+ } -+ -+ 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); -+} -+ -+static SDValue performParity(SDNode *N, SelectionDAG &DAG, -+ TargetLowering::DAGCombinerInfo &DCI, -+ const LoongArchSubtarget &Subtarget) { -+ -+ 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(); -+ -+ if (!dyn_cast(Ops[i]->getOperand(1))) -+ 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(); -+ } -+ -+ 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(); -+ -+ return SDValue(); -+} -+ -+// Optimize zero extension and sign extension of data -+static SDValue performExtend(SDNode *N, SelectionDAG &DAG, -+ TargetLowering::DAGCombinerInfo &DCI, -+ const LoongArchSubtarget &Subtarget) { -+ -+ if (!Subtarget.hasLASX()) -+ return SDValue(); -+ -+ SDLoc DL(N); -+ SDValue T = N->getOperand(0); -+ -+ if (T->getOpcode() == ISD::BUILD_VECTOR) -+ return performParity(N, DAG, DCI, Subtarget); -+ -+ if (T->getOpcode() != ISD::ADD && T->getOpcode() != ISD::SUB) -+ return SDValue(); -+ -+ SDValue T0 = T->getOperand(0); -+ SDValue T1 = T->getOperand(1); -+ -+ if (!(T0->getOpcode() == ISD::BUILD_VECTOR && -+ T1->getOpcode() == ISD::BUILD_VECTOR)) -+ return SDValue(); -+ -+ if (DCI.isAfterLegalizeDAG()) -+ return SDValue(); -+ -+ if (!(T->getValueType(0).isSimple() && T0->getValueType(0).isSimple() && -+ T1->getValueType(0).isSimple() && N->getValueType(0).isSimple())) -+ return SDValue(); -+ -+ 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(); -+ -+ SDValue Opse0[4]; -+ SDValue Opse1[4]; -+ -+ 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); -+ } -+ -+ if (Opse0[i]->getOpcode() != ISD::EXTRACT_VECTOR_ELT || -+ Opse1[i]->getOpcode() != ISD::EXTRACT_VECTOR_ELT) -+ return SDValue(); -+ -+ 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(); -+ } -+ -+ 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(); -+} -+ -+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 Res; -+ if (Res = performExtend(N, DAG, DCI, Subtarget)) -+ return Res; -+ -+ if (!(Top->getOpcode() == ISD::CopyFromReg)) -+ return SDValue(); -+ -+ if ((Top->getOperand(0)->getOpcode() == ISD::EntryToken) && -+ (N->getValueType(0) == MVT::i64)) { -+ -+ SDValue SubReg = DAG.getTargetConstant(LoongArch::sub_32, DL, MVT::i32); -+ SDNode *Res = DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, MVT::i64); -+ -+ Res = DAG.getMachineNode(TargetOpcode::INSERT_SUBREG, DL, MVT::i64, -+ SDValue(Res, 0), Top, SubReg); -+ -+ return SDValue(Res, 0); -+ } -+ -+ return SDValue(); -+} -+ -+static SDValue performZERO_EXTENDCombine(SDNode *N, SelectionDAG &DAG, -+ TargetLowering::DAGCombinerInfo &DCI, -+ const LoongArchSubtarget &Subtarget) { -+ -+ assert((N->getOpcode() == ISD::ZERO_EXTEND) && "Need ISD::ZERO_EXTEND"); -+ -+ SDLoc DL(N); -+ -+ SDValue Res; -+ if (Res = performExtend(N, DAG, DCI, Subtarget)) -+ return Res; -+ -+ return SDValue(); -+} -+ -+SDValue LoongArchTargetLowering:: -+PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const { -+ SelectionDAG &DAG = DCI.DAG; -+ SDValue Val; -+ -+ 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 performSRLCombine(N, DAG, DCI, Subtarget); -+ return performLogicCombine(N, DAG, Subtarget); -+ } -+ return SDValue(); -+} -+ -+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, makeArrayRef(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)); -+ } -+ -+ return Result; -+} -+ -+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, makeArrayRef(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(), -+ /* Alignment = */ 16); -+} -+ -+static SDValue lowerLASXLoadIntr(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(), -+ /* Alignment = */ 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); -+ SDValue Load = DAG.getLoad(ResTy, DL, ChainIn, Address, MachinePointerInfo(), -+ /* Alignment = */ 32); -+ return DAG.getNode(LoongArchISD::XVBROADCAST, DL, -+ DAG.getVTList(ResTy, MVT::Other), Load); -+} -+ -+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); -+ SDValue Load = DAG.getLoad(ResTy, DL, ChainIn, Address, MachinePointerInfo(), -+ /* Alignment = */ 16); -+ return DAG.getNode(LoongArchISD::VBROADCAST, DL, -+ DAG.getVTList(ResTy, MVT::Other), Load); -+} -+ -+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(), -+ /* Alignment = */ 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(), -+ /* Alignment = */ 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); -+ } -+ -+ } -+ -+ 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, makeArrayRef(Ops, 4)); -+ } -+ -+ 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, makeArrayRef(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() const { return true; } -+ -+bool LoongArchTargetLowering::isCheapToSpeculateCtlz() const { return true; } -+ -+void LoongArchTargetLowering::LowerOperationWrapper( -+ SDNode *N, SmallVectorImpl &Results, SelectionDAG &DAG) const { -+ SDValue Res = LowerOperation(SDValue(N, 0), DAG); -+ -+ 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 { -+ return LowerOperationWrapper(N, Results, DAG); -+} -+ -+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::ATOMIC_CMP_SWAP_I8: -+ return emitAtomicCmpSwapPartword(MI, BB, 1); -+ case LoongArch::ATOMIC_CMP_SWAP_I16: -+ return emitAtomicCmpSwapPartword(MI, BB, 2); -+ case LoongArch::ATOMIC_CMP_SWAP_I32: -+ return emitAtomicCmpSwap(MI, BB); -+ case LoongArch::ATOMIC_CMP_SWAP_I64: -+ 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); -+ -+ if(MI.getOpcode() == LoongArch::ATOMIC_LOAD_NAND_I32 -+ || MI.getOpcode() == LoongArch::ATOMIC_LOAD_NAND_I64){ -+ BuildMI(*BB, II, DL, TII->get(LoongArch::DBAR)).addImm(DBAR_HINT); -+ } -+ -+ 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(LoongArch::DBAR)).addImm(0); -+ 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 { -+ assert((MI.getOpcode() == LoongArch::ATOMIC_CMP_SWAP_I32 || -+ MI.getOpcode() == LoongArch::ATOMIC_CMP_SWAP_I64) && -+ "Unsupported atomic psseudo for EmitAtomicCmpSwap."); -+ -+ const unsigned Size = MI.getOpcode() == LoongArch::ATOMIC_CMP_SWAP_I32 ? 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 = MI.getOpcode() == LoongArch::ATOMIC_CMP_SWAP_I32 -+ ? 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); -+ -+ // 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(LoongArch::DBAR)).addImm(0); -+ 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) -+ .addReg(Scratch, RegState::EarlyClobber | RegState::Define | -+ RegState::Dead | RegState::Implicit); -+ -+ BuildMI(*BB, II, DL, TII->get(LoongArch::DBAR)).addImm(DBAR_HINT); -+ -+ 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."); -+ -+ 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 = MI.getOpcode() == LoongArch::ATOMIC_CMP_SWAP_I8 -+ ? 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); -+ -+ // 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(LoongArch::DBAR)).addImm(0); -+ BuildMI(BB, DL, TII->get(AtomicOp)) -+ .addReg(Dest, RegState::Define | RegState::EarlyClobber) -+ .addReg(AlignedAddr) -+ .addReg(Mask) -+ .addReg(ShiftedCmpVal) -+ .addReg(Mask2) -+ .addReg(ShiftedNewVal) -+ .addReg(ShiftAmt) -+ .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 { -+ // FIXME: Need pseudo-fence for 'singlethread' fences -+ // FIXME: Set SType for weaker fences where supported/appropriate. -+ unsigned SType = 0; -+ SDLoc DL(Op); -+ return DAG.getNode(LoongArchISD::DBAR, DL, MVT::Other, Op.getOperand(0), -+ DAG.getConstant(SType, DL, MVT::i32)); -+} -+ -+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), ~shamt)) -+ // else: -+ // lo = 0 -+ // hi = (shl lo, shamt[4:0]) -+ SDValue Not = DAG.getNode(ISD::XOR, DL, MVT::i32, Shamt, -+ DAG.getConstant(-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), ~shamt) (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(-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->getAlignment(), -+ 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); -+ EVT VecTy = Op0->getValueType(0); -+ -+ if (!VecTy.is128BitVector() && !VecTy.is256BitVector()) -+ return SDValue(); -+ -+ if (ResTy.isInteger()) { -+ SDValue Op1 = Op->getOperand(1); -+ EVT EltTy = VecTy.getVectorElementType(); -+ 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)); -+ } -+ -+ return SDValue(); -+} -+ -+SDValue -+LoongArchTargetLowering::lowerINSERT_VECTOR_ELT(SDValue Op, -+ SelectionDAG &DAG) const { -+ -+ MVT VT = Op.getSimpleValueType(); -+ MVT EltVT = VT.getVectorElementType(); -+ -+ SDLoc DL(Op); -+ SDValue Op0 = Op.getOperand(0); -+ SDValue Op1 = Op.getOperand(1); -+ SDValue Op2 = Op.getOperand(2); -+ -+ if (!EltVT.isInteger()) -+ return Op; -+ -+ if (!isa(Op2)) { -+ if (EltVT == MVT::i8 || EltVT == MVT::i16) { -+ return Op; // ==> pseudo -+ // use stack -+ return SDValue(); -+ } else { -+ return Op; -+ } -+ } -+ -+ if (VT.is128BitVector()) -+ return DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, VT, Op0, Op1, Op2); -+ -+ if (VT.is256BitVector()) { -+ -+ if (EltVT == MVT::i32 || EltVT == MVT::i64) -+ return DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, VT, Op0, Op1, Op2); -+ -+ 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.getNextStackOffset() != 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 != array_lengthof(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(), -+ /* Alignment = */ 0, 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 NextStackOffset = CCInfo.getNextStackOffset(); -+ -+ // 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, NextStackOffset, *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(); -+ NextStackOffset = alignTo(NextStackOffset, StackAlignment); -+ SDValue NextStackOffsetVal = DAG.getIntPtrConstant(NextStackOffset, DL, true); -+ -+ if (!(IsTailCall || MemcpyInByVal)) -+ Chain = DAG.getCALLSEQ_START(Chain, NextStackOffset, 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)); -+ } -+ -+ // 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; -+ } -+ 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; -+ } -+ -+ 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); -+ } -+ -+ 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); -+} -+ -+/// 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!"); -+ -+ 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())); -+ } -+ -+ 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; -+ } -+ -+ InVals.push_back(Val); -+ } -+ -+ return Chain; -+} -+ -+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: -+ break; -+ 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; -+ } -+ } -+ -+ // 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 CCValAssign::AExtUpper: -+ case CCValAssign::AExt: -+ Val = DAG.getNode(ISD::TRUNCATE, DL, ValVT, Val); -+ break; -+ 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 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 CCValAssign::BCvt: -+ Val = DAG.getNode(ISD::BITCAST, DL, ValVT, Val); -+ break; -+ } -+ -+ return Val; -+} -+ -+//===----------------------------------------------------------------------===// -+// 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(); -+ -+ LoongArchFI->setVarArgsFrameIndex(0); -+ -+ // Used with vargs to acumulate store chains. -+ std::vector OutChains; -+ -+ // 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(); -+ -+ CCInfo.AnalyzeFormalArguments(Ins, CC_LoongArch_FixedArg); -+ LoongArchFI->setFormalArgInfo(CCInfo.getNextStackOffset(), -+ 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; -+ } -+ -+ // 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 -+ } -+ -+ 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(); -+ } -+ -+ // sanity check -+ assert(VA.isMemLoc()); -+ -+ // The stack pointer offset is relative to the caller stack frame. -+ int FI = MFI.CreateFixedObject(LocVT.getSizeInBits() / 8, -+ VA.getLocMemOffset(), true); -+ -+ // 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)); -+ -+ ArgValue = UnpackFromArgumentSlot(ArgValue, VA, Ins[i].ArgVT, DL, DAG); -+ -+ InVals.push_back(ArgValue); -+ } -+ } -+ -+ 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; -+ } - } -- return SDValue(); -+ -+ 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; - } - --static MachineBasicBlock *insertDivByZeroTrap(MachineInstr &MI, -- MachineBasicBlock &MBB, -- const TargetInstrInfo &TII) { -- if (!ZeroDivCheck) -- return &MBB; -+//===----------------------------------------------------------------------===// -+// Return Value Calling Convention Implementation -+//===----------------------------------------------------------------------===// - -- // Build instructions: -- // div(or mod) $dst, $dividend, $divisor -- // bnez $divisor, 8 -- // break 7 -- // fallthrough -- MachineOperand &Divisor = MI.getOperand(2); -- auto FallThrough = std::next(MI.getIterator()); -+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); -+} - -- BuildMI(MBB, FallThrough, MI.getDebugLoc(), TII.get(LoongArch::BNEZ)) -- .addReg(Divisor.getReg(), getKillRegState(Divisor.isKill())) -- .addImm(8); -+bool -+LoongArchTargetLowering::shouldSignExtendTypeInLibCall(EVT Type, bool IsSigned) const { -+ if ((ABI.IsLPX32() || ABI.IsLP64()) && Type == MVT::i32) -+ return true; - -- // See linux header file arch/loongarch/include/uapi/asm/break.h for the -- // definition of BRK_DIVZERO. -- BuildMI(MBB, FallThrough, MI.getDebugLoc(), TII.get(LoongArch::BREAK)) -- .addImm(7/*BRK_DIVZERO*/); -+ return IsSigned; -+} - -- // Clear Divisor's kill flag. -- Divisor.setIsKill(false); -+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(); - -- return &MBB; -+ // CCState - Info about the registers and stack slot. -+ LoongArchCCState CCInfo(CallConv, IsVarArg, MF, RVLocs, *DAG.getContext()); -+ -+ // Analyze return values. -+ CCInfo.AnalyzeReturn(Outs, RetCC_LoongArch); -+ -+ SDValue Flag; -+ SmallVector RetOps(1, Chain); -+ -+ // 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; -+ -+ 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 (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())); -+ } -+ -+ 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())); -+ } -+ -+ // 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()))); -+ } -+ -+ RetOps[0] = Chain; // Update chain. -+ -+ // 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); - } - --MachineBasicBlock *LoongArchTargetLowering::EmitInstrWithCustomInserter( -- MachineInstr &MI, MachineBasicBlock *BB) const { -+//===----------------------------------------------------------------------===// -+// LoongArch Inline Assembly Support -+//===----------------------------------------------------------------------===// - -- switch (MI.getOpcode()) { -+/// 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': -+ return C_Other; -+ case 'R': -+ return C_Memory; -+ } -+ } -+ -+ if (Constraint == "ZC" || Constraint == "ZB") -+ return C_Memory; -+ -+ return TargetLowering::getConstraintType(Constraint); -+} -+ -+/// 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 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, *Subtarget.getInstrInfo()); -+ weight = TargetLowering::getSingleConstraintMatchWeight(info, constraint); -+ break; -+ 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 weight; - } - --const char *LoongArchTargetLowering::getTargetNodeName(unsigned Opcode) const { -- switch ((LoongArchISD::NodeType)Opcode) { -- case LoongArchISD::FIRST_NUMBER: -- break; -- --#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(RET) -- 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) -- } --#undef NODE_NAME_CASE -+/// 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); -+ -+ // 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); -+ -+ Prefix = StringRef(B, I - B); -+ -+ // 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); -+} -+ -+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; -+} -+ -+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; - } - --//===----------------------------------------------------------------------===// --// Calling Convention Implementation --//===----------------------------------------------------------------------===// --// FIXME: Now, we only support CallingConv::C with fixed arguments which are --// passed with integer or floating-point registers. --const MCPhysReg ArgGPRs[] = {LoongArch::R4, LoongArch::R5, LoongArch::R6, -- LoongArch::R7, LoongArch::R8, LoongArch::R9, -- LoongArch::R10, LoongArch::R11}; --const MCPhysReg ArgFPR32s[] = {LoongArch::F0, LoongArch::F1, LoongArch::F2, -- LoongArch::F3, LoongArch::F4, LoongArch::F5, -- LoongArch::F6, LoongArch::F7}; --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}; -- --// Implements the LoongArch calling convention. Returns true upon failure. --static bool CC_LoongArch(unsigned ValNo, MVT ValVT, -- CCValAssign::LocInfo LocInfo, CCState &State) { -- // Allocate to a register if possible. -- Register Reg; -- -- if (ValVT == MVT::f32) -- Reg = State.AllocateReg(ArgFPR32s); -- else if (ValVT == MVT::f64) -- Reg = State.AllocateReg(ArgFPR64s); -- else -- Reg = State.AllocateReg(ArgGPRs); -- if (Reg) { -- State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, ValVT, 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; -+ -+ 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); -+ } - } - -- // TODO: Handle arguments passed without register. -- return true; -+ 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 -+ } -+ } -+ return std::make_pair(*(RC->begin() + Reg), RC); - } - --void LoongArchTargetLowering::analyzeInputArgs( -- CCState &CCInfo, const SmallVectorImpl &Ins, -- LoongArchCCAssignFn Fn) const { -- for (unsigned i = 0, e = Ins.size(); i != e; ++i) { -- MVT ArgVT = Ins[i].VT; -+/// 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; -+ } -+ } -+ -+ std::pair R; -+ R = parseRegForInlineAsmConstraint(Constraint, VT); -+ -+ if (R.second) -+ return R; -+ -+ return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT); -+} - -- if (Fn(i, ArgVT, CCValAssign::Full, CCInfo)) { -- LLVM_DEBUG(dbgs() << "InputArg #" << i << " has unhandled type " -- << EVT(ArgVT).getEVTString() << '\n'); -- llvm_unreachable(""); -+/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops -+/// vector. If it is invalid, don't add anything to Ops. -+void LoongArchTargetLowering::LowerAsmOperandForConstraint(SDValue Op, -+ std::string &Constraint, -+ std::vector&Ops, -+ SelectionDAG &DAG) const { -+ SDLoc DL(Op); -+ SDValue Result; -+ -+ // Only support length 1 constraints for now. -+ if (Constraint.length() > 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; -+ } -+ } -+ 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; -+ } -+ } -+ 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; -+ } - } -+ 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; -+ } -+ } -+ return; -+ } -+ -+ if (Result.getNode()) { -+ Ops.push_back(Result); -+ return; -+ } -+ -+ TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG); -+} -+ -+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; -+ -+ 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; - } -+ -+ return true; - } - --void LoongArchTargetLowering::analyzeOutputArgs( -- CCState &CCInfo, const SmallVectorImpl &Outs, -- LoongArchCCAssignFn Fn) const { -- for (unsigned i = 0, e = Outs.size(); i != e; ++i) { -- MVT ArgVT = Outs[i].VT; -+bool -+LoongArchTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const { -+ // The LoongArch target isn't yet aware of offsets. -+ return false; -+} - -- if (Fn(i, ArgVT, CCValAssign::Full, CCInfo)) { -- LLVM_DEBUG(dbgs() << "OutputArg #" << i << " has unhandled type " -- << EVT(ArgVT).getEVTString() << "\n"); -- llvm_unreachable(""); -+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; - } - } -+ -+ if (Subtarget.is64Bit()) -+ return MVT::i64; -+ -+ return MVT::i32; - } - --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(); -- const TargetRegisterClass *RC = TLI.getRegClassFor(LocVT.getSimpleVT()); -- Register VReg = RegInfo.createVirtualRegister(RC); -- RegInfo.addLiveIn(VA.getLocReg(), VReg); -+/// 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; -+ if (Imm.isNegZero()) -+ return false; -+ return (Imm.isZero() || Imm.isExactlyValue(+1.0)); -+} - -- return DAG.getCopyFromReg(Chain, DL, VReg, LocVT); -+bool LoongArchTargetLowering::useSoftFloat() const { -+ return Subtarget.useSoftFloat(); - } - --// 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 { -+// 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(); -- -- switch (CallConv) { -- default: -- llvm_unreachable("Unsupported calling convention"); -- case CallingConv::C: -- break; -+ 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; -+ -+ // Copy arg registers. -+ MVT RegTy = MVT::getIntegerVT(GPRSizeInBytes * 8); -+ const TargetRegisterClass *RC = getRegClassFor(RegTy); -+ -+ 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); - } -+} - -- // Assign locations to all of the incoming arguments. -- SmallVector ArgLocs; -- CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext()); -+// 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)); -+ } - -- analyzeInputArgs(CCInfo, Ins, CC_LoongArch); -+ // Return if the struct has been fully copied. -+ if (ByValSizeInBytes == OffsetInBytes) -+ return; - -- for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) -- InVals.push_back(unpackFromRegLoc(DAG, Chain, ArgLocs[i], DL, *this)); -+ // Copy the remainder of the byval argument with sub-word loads and shifts. -+ if (LeftoverBytes) { -+ SDValue Val; - -- return Chain; --} -+ for (unsigned LoadSizeInBytes = RegSizeInBytes / 2, TotalBytesLoaded = 0; -+ OffsetInBytes < ByValSizeInBytes; LoadSizeInBytes /= 2) { -+ unsigned RemainingSizeInBytes = ByValSizeInBytes - OffsetInBytes; - --// 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()); -- CLI.IsTailCall = false; -+ if (RemainingSizeInBytes < LoadSizeInBytes) -+ continue; - -- if (IsVarArg) -- report_fatal_error("LowerCall with varargs not implemented"); -+ // 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)); - -- MachineFunction &MF = DAG.getMachineFunction(); -+ // Shift the loaded value. -+ unsigned Shamt; - -- // Analyze the operands of the call, assigning locations to each operand. -- SmallVector ArgLocs; -- CCState ArgCCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext()); -+ Shamt = TotalBytesLoaded * 8; - -- analyzeOutputArgs(ArgCCInfo, Outs, CC_LoongArch); -+ SDValue Shift = DAG.getNode(ISD::SHL, DL, RegTy, LoadVal, -+ DAG.getConstant(Shamt, DL, MVT::i32)); - -- // Get a count of how many bytes are to be pushed on the stack. -- unsigned NumBytes = ArgCCInfo.getNextStackOffset(); -+ if (Val.getNode()) -+ Val = DAG.getNode(ISD::OR, DL, RegTy, Val, Shift); -+ else -+ Val = Shift; - -- for (auto &Arg : Outs) { -- if (!Arg.Flags.isByVal()) -- continue; -- report_fatal_error("Passing arguments byval not implemented"); -+ OffsetInBytes += LoadSizeInBytes; -+ TotalBytesLoaded += LoadSizeInBytes; -+ Alignment = std::min(Alignment, Align(LoadSizeInBytes)); -+ } -+ -+ unsigned ArgReg = ArgRegs[FirstReg + I]; -+ RegsToPass.push_back(std::make_pair(ArgReg, Val)); -+ return; -+ } - } - -- Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, CLI.DL); -+ // 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); -+} - -- // Copy argument values to their designated locations. -- SmallVector> RegsToPass; -- for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { -- CCValAssign &VA = ArgLocs[i]; -- SDValue ArgValue = OutVals[i]; -+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(); - -- // Promote the value if needed. -- // For now, only handle fully promoted arguments. -- if (VA.getLocInfo() != CCValAssign::Full) -- report_fatal_error("Unknown loc info"); -+ // Offset of the first variable argument from stack pointer. -+ int VaArgOffset, VarArgsSaveSize; - -- if (VA.isRegLoc()) { -- // Queue up the argument copies and emit them at the end. -- RegsToPass.push_back(std::make_pair(VA.getLocReg(), ArgValue)); -- } else { -- report_fatal_error("Passing arguments via the stack not implemented"); -- } -+ if (ArgRegs.size() == Idx) { -+ VaArgOffset = alignTo(State.getNextStackOffset(), RegSizeInBytes); -+ VarArgsSaveSize = 0; -+ } else { -+ VarArgsSaveSize = (int)(RegSizeInBytes * (ArgRegs.size() - Idx)); -+ VaArgOffset = -VarArgsSaveSize; - } - -- SDValue Glue; -+ // 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; -+ } - -- // 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); -+ // 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 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. -- // FIXME: Add target flags for relocation. -- if (GlobalAddressSDNode *S = dyn_cast(Callee)) -- Callee = DAG.getTargetGlobalAddress(S->getGlobal(), DL, PtrVT); -- else if (ExternalSymbolSDNode *S = dyn_cast(Callee)) -- Callee = DAG.getTargetExternalSymbol(S->getSymbol(), PtrVT); -+void LoongArchTargetLowering::HandleByVal(CCState *State, unsigned &Size, -+ Align Alignment) const { -+ const TargetFrameLowering *TFL = Subtarget.getFrameLowering(); -+ -+ assert(Size && "Byval argument's size shouldn't be 0."); -+ -+ Alignment = std::min(Alignment, TFL->getStackAlign()); -+ -+ 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; -+ -+ // 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."); -+ -+ FirstReg = State->getFirstUnallocated(IntArgRegs); -+ -+ // 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#######################################"); -+ } - -- // The first call operand is the chain and the second is the target address. -- SmallVector Ops; -- Ops.push_back(Chain); -- Ops.push_back(Callee); -+ // 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]); - -- // 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())); -+ State->addInRegsParamInfo(FirstReg, FirstReg + NumRegs); -+} - -- // 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)); -+MachineBasicBlock *LoongArchTargetLowering::emitPseudoSELECT(MachineInstr &MI, -+ MachineBasicBlock *BB, -+ bool isFPCmp, -+ unsigned Opc) const { -+ const TargetInstrInfo *TII = -+ Subtarget.getInstrInfo(); -+ DebugLoc DL = MI.getDebugLoc(); -+ -+ // 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(); -+ -+ // 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); -+ } - -- // Glue the call to the argument copies, if any. -- if (Glue.getNode()) -- Ops.push_back(Glue); -+ // copy0MBB: -+ // %FalseValue = ... -+ // # fallthrough to sinkMBB -+ BB = copy0MBB; - -- // Emit the call. -- SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); -+ // Update machine-CFG edges -+ BB->addSuccessor(sinkMBB); - -- Chain = DAG.getNode(LoongArchISD::CALL, DL, NodeTys, Ops); -- DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge); -- Glue = Chain.getValue(1); -+ // sinkMBB: -+ // %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ] -+ // ... -+ BB = sinkMBB; - -- // Mark the end of the call, which is glued to the call itself. -- Chain = DAG.getCALLSEQ_END(Chain, DAG.getConstant(NumBytes, DL, PtrVT, true), -- DAG.getConstant(0, DL, PtrVT, true), Glue, DL); -- Glue = Chain.getValue(1); -+ 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); - -- // Assign locations to each value returned by this call. -- SmallVector RVLocs; -- CCState RetCCInfo(CallConv, IsVarArg, MF, RVLocs, *DAG.getContext()); -- analyzeInputArgs(RetCCInfo, Ins, CC_LoongArch); -+ MI.eraseFromParent(); // The pseudo instruction is gone now. - -- // 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); -- Chain = RetValue.getValue(1); -- Glue = RetValue.getValue(2); -+ return BB; -+} - -- InVals.push_back(Chain.getValue(0)); -+MachineBasicBlock *LoongArchTargetLowering::emitLSXCBranchPseudo( -+ MachineInstr &MI, MachineBasicBlock *BB, unsigned BranchOp) const { -+ -+ 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); -+ -+ // Fill $TBB. -+ unsigned RD2 = RegInfo.createVirtualRegister(RC); -+ BuildMI(*TBB, TBB->end(), DL, TII->get(LoongArch::ADDI_W), RD2) -+ .addReg(LoongArch::ZERO) -+ .addImm(1); -+ -+ // 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); -+ -+ MI.eraseFromParent(); // The pseudo instruction is gone now. -+ return Sink; -+} -+ -+// 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); - } - -- return Chain; -+ MI.eraseFromParent(); // The pseudo instruction is gone now. -+ return BB; -+} -+ -+// 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()); -+ -+ 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(); -+ -+ 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); -+ -+ 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); -+ } -+ -+ MI.eraseFromParent(); // The pseudo instruction is gone now. -+ return BB; - } - --bool LoongArchTargetLowering::CanLowerReturn( -- CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg, -- const SmallVectorImpl &Outs, LLVMContext &Context) const { -- // Any return value split in to more than two values can't be returned -- // directly. -- return Outs.size() <= 2; -+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); -+ } -+ -+ MI.eraseFromParent(); // The pseudo instruction is gone now. -+ return BB; - } - --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; -+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 { -+ 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); -+ } - -- // Info about the registers and stack slot. -- CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs, -- *DAG.getContext()); -+ MI.eraseFromParent(); // The pseudo instruction is gone now. -+ return BB; -+} - -- analyzeOutputArgs(CCInfo, Outs, CC_LoongArch); -+MachineBasicBlock *LoongArchTargetLowering::emitCONCAT_VECTORS( -+ MachineInstr &MI, MachineBasicBlock *BB, unsigned Bytes) const { - -- SDValue Glue; -- SmallVector RetOps(1, Chain); -+ 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; - -- // 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!"); -+ 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; -+ } - -- // Handle a 'normal' return. -- Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), OutVals[i], Glue); -+ 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); -+ -+ MI.eraseFromParent(); // The pseudo instruction is gone now. -+ return BB; -+} - -- // Guarantee that all emitted copies are stuck together. -- Glue = Chain.getValue(1); -- RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT())); -+// 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; -+} -+ -+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"); -+ } -+ -+ 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; - } - -- RetOps[0] = Chain; // Update chain. -+ 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); -+ -+ unsigned Xd256 = Xd; -+ if (Lane >= HalfSize) { -+ Xd256 = RegInfo.createVirtualRegister(VecRC); -+ } -+ -+ BuildMI(*BB, MI, DL, TII->get(LoongArch::SUBREG_TO_REG), Xd256) -+ .addImm(0) -+ .addReg(Xd128) -+ .addImm(LoongArch::sub_128); - -- // Add the glue node if we have it. -- if (Glue.getNode()) -- RetOps.push_back(Glue); -+ if (Lane >= HalfSize) { -+ BuildMI(*BB, MI, DL, TII->get(LoongArch::XVPERMI_Q), Xd) -+ .addReg(Xd_in) -+ .addReg(Xd256) -+ .addImm(2); -+ } - -- return DAG.getNode(LoongArchISD::RET, DL, MVT::Other, RetOps); -+ MI.eraseFromParent(); // The pseudo instruction is gone now. -+ return BB; - } - --bool LoongArchTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT, -- bool ForCodeSize) const { -- assert((VT == MVT::f32 || VT == MVT::f64) && "Unexpected 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; -+} -+ -+// 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; -+} -+ -+// 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()); -+ -+ 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); -+ -+ MI.eraseFromParent(); // The pseudo instruction is gone now. -+ return BB; -+} -+ -+MachineBasicBlock * -+LoongArchTargetLowering::emitXINSERT_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 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; -+} -+ -+// 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); -+ -+ MI.eraseFromParent(); // The pseudo instruction is gone now. -+ return BB; -+} -+ -+// 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()); -+ -+ 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); -+ -+ 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; -+} -+ -+// 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 { -+ bool IsLegal = false; -+ if (Subtarget.hasLSX() || Subtarget.hasLASX()) { -+ return isUInt<5>(Imm); -+ } -+ return IsLegal; -+} - -- if (VT == MVT::f32 && !Subtarget.hasBasicF()) -+bool LoongArchTargetLowering::isFMAFasterThanFMulAndFAdd( -+ const MachineFunction &MF, EVT VT) const { -+ -+ VT = VT.getScalarType(); -+ -+ if (!VT.isSimple()) - return false; -- if (VT == MVT::f64 && !Subtarget.hasBasicD()) -+ -+ switch (VT.getSimpleVT().SimpleTy) { -+ case MVT::f32: -+ case MVT::f64: -+ return true; -+ default: -+ break; -+ } -+ -+ return false; -+} -+ -+bool LoongArchTargetLowering::isExtractSubvectorCheap(EVT ResVT, EVT SrcVT, -+ unsigned Index) const { -+ if (!isOperationLegalOrCustom(ISD::EXTRACT_SUBVECTOR, ResVT)) - return false; -- return (Imm.isZero() || Imm.isExactlyValue(+1.0)); -+ -+ return ( -+ (ResVT != MVT::v16i8) && (ResVT != MVT::v8i16) && -+ (Index == 0 || (Index == ResVT.getVectorNumElements() && -+ (ResVT.getSizeInBits() == SrcVT.getSizeInBits() / 2)))); -+} -+ -+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/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchISelLowering.h b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchISelLowering.h -index 141f1fd3a..64e06b53f 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchISelLowering.h -+++ b/src/llvm-project/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,115 +6,553 @@ - // - //===----------------------------------------------------------------------===// - // --// 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/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/Support/MachineValueType.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; --struct LoongArchRegisterInfo; --namespace LoongArchISD { --enum NodeType : unsigned { -- FIRST_NUMBER = ISD::BUILTIN_OP_END, -- -- // TODO: add more LoongArchISDs -- CALL, -- RET, -- // 32-bit shifts, directly matching the semantics of the named LoongArch -- // instructions. -- SLL_W, -- SRA_W, -- SRL_W, -- -- // FPR<->GPR transfer operations -- MOVGR2FR_W_LA64, -- MOVFR2GR_S_LA64, -- -- FTINT, -- -- BSTRINS, -- BSTRPICK, -- --}; --} // 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; } -- -- // 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; -- --private: -- /// Target-specific function used to lower LoongArch calling conventions. -- typedef bool LoongArchCCAssignFn(unsigned ValNo, MVT ValVT, -- CCValAssign::LocInfo LocInfo, -- CCState &State); -- -- void analyzeInputArgs(CCState &CCInfo, -- const SmallVectorImpl &Ins, -- LoongArchCCAssignFn Fn) const; -- void analyzeOutputArgs(CCState &CCInfo, -- const SmallVectorImpl &Outs, -- LoongArchCCAssignFn Fn) const; -- -- SDValue lowerGlobalAddress(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 lowerConstantPool(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; -- -- bool isFPImmLegal(const APFloat &Imm, EVT VT, -- bool ForCodeSize) const override; -- -- bool shouldInsertFencesForAtomic(const Instruction *I) const override { -- return isa(I) || isa(I); -- } --}; -+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, -+ -+ DBAR, -+ -+ 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 AS = 0, Align Alignment = Align(1), -+ MachineMemOperand::Flags Flags = MachineMemOperand::MONone, -+ bool *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() const override; -+ bool isCheapToSpeculateCtlz() 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, -+ std::string &Constraint, -+ std::vector &Ops, -+ SelectionDAG &DAG) const override; -+ -+ unsigned -+ getInlineAsmMemConstraint(StringRef ConstraintCode) const override { -+ if (ConstraintCode == "R") -+ return InlineAsm::Constraint_R; -+ else if (ConstraintCode == "ZC") -+ return InlineAsm::Constraint_ZC; -+ else if (ConstraintCode == "ZB") -+ return InlineAsm::Constraint_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/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchInstrFormats.td b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchInstrFormats.td -index bebc83a86..d75d5198b 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchInstrFormats.td -+++ b/src/llvm-project/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,396 +9,782 @@ - //===----------------------------------------------------------------------===// - // 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 LoongArch_str { -+ string Arch; -+ string BaseOpcode = opstr; -+} -+ -+//===-----------------------------------------------------------===// -+// Format instruction classes in the LoongArch -+//===-----------------------------------------------------------===// -+ -+// R2 classes: 2 registers -+// -+class R2 : StdArch { -+ bits<5> rj; -+ bits<5> rd; -+ -+ let Inst{9-5} = rj; -+ let Inst{4-0} = rd; -+} -+ -+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; -+} -+ -+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; - } - --// 2R-type --// --class Fmt2R op, dag outs, dag ins, string opcstr, string opnstr, -- list pattern = []> -- : LAInst { -+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-10} = op; -+ let Inst{31-18} = op; -+ let Inst{17-10} = level; - let Inst{9-5} = rj; - let Inst{4-0} = rd; - } - --// 3R-type --// --class Fmt3R op, dag outs, dag ins, string opcstr, string opnstr, -- list pattern = []> -- : LAInst { -+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; -+} -+ -+// R3 classes: 3 registers -+// -+class R3 : StdArch { - bits<5> rk; - bits<5> rj; - bits<5> rd; - -- let Inst{31-15} = 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 opcstr, string opnstr, -- list pattern = []> -- : LAInst { -- 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 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-17} = 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 opcstr, string opnstr, -- list pattern = []> -- : LAInst { -- bits<3> imm3; -+class R3_SA3 : StdArch { - bits<5> rk; - bits<5> rj; - bits<5> rd; -+ bits<3> sa; - -- let Inst{31-18} = 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 opcstr, string opnstr, -- list pattern = []> -- : LAInst { -- 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-15} = 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 opcstr, string opnstr, -- list pattern = []> -- : LAInst { -- 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-16} = 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 opcstr, string opnstr, -- list pattern = []> -- : LAInst { -- 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-18} = 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 opcstr, string opnstr, -- list pattern = []> -- : LAInst { -- bits<12> imm12; -+ -+class R2_IMM12 op> -+ : StdArch { - bits<5> rj; - bits<5> rd; -+ bits<12> imm12; - -- let Inst{31-22} = 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 opcstr, string opnstr, -- list pattern = []> -- : LAInst { -- 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-24} = 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 opcstr, string opnstr, -- list pattern = []> -- : LAInst { -- bits<16> imm16; -+class R2_IMM16JIRL : StdArch { - bits<5> rj; - bits<5> rd; -+ bits<16> offs16; -+ -+ let Inst{31-26} = 0x13; -+ let Inst{25-10} = offs16; -+ let Inst{9-5} = rj; -+ let Inst{4-0} = rd; -+} -+ -+// 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} = imm16; -+ 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-24} = op{7-0}; -+ let Inst{23-10} = csr; -+ let Inst{9-5} = op{12-8}; - let Inst{4-0} = rd; - } - --// 1RI20-type --// --class Fmt1RI20 op, dag outs, dag ins, string opcstr, string opnstr, -- list pattern = []> -- : LAInst { -- bits<20> imm20; -+class R1_SI20 op> -+ : StdArch { - bits<5> rd; -+ bits<20> si20; - - let Inst{31-25} = op; -- let Inst{24-5} = imm20; -+ let Inst{24-5} = si20; - let Inst{4-0} = rd; - } - --// 1RI21-type --// --class Fmt1RI21 op, dag outs, dag ins, string opcstr, string opnstr, -- list pattern = []> -- : LAInst { -- bits<21> imm21; -+class R1_CACHE : StdArch { - bits<5> rj; -+ bits<5> op; -+ bits<12> si12; - -- let Inst{31-26} = 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; - } - --// I15-type --// --class FmtI15 op, dag outs, dag ins, string opcstr, string opnstr, -- list pattern = []> -- : LAInst { -- bits<15> imm15; -+class R1_BCEQZ op> -+ : StdArch { -+ bits<21> offset; -+ bits<3> cj; - -- let Inst{31-15} = op; -- let Inst{14-0} = imm15; -+ 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}; - } - --// I26-type --// --class FmtI26 op, dag outs, dag ins, string opcstr, string opnstr, -- list pattern = []> -- : LAInst { -- bits<26> imm26; -+// IMM26 classes: 1 26bit-immediate -+// -+class IMM26B op> -+ : StdArch { -+ bits<26> offs26; - - let Inst{31-26} = op; -- let Inst{25-10} = imm26{15-0}; -- let Inst{9-0} = imm26{25-16}; -+ let Inst{25-10} = offs26{15-0}; -+ let Inst{9-0} = offs26{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 = []; - } - --// FmtBSTR_W --// --class FmtBSTR_W op, dag outs, dag ins, string opcstr, string opnstr, -- list pattern = []> -- : LAInst { -+// -+// Misc instruction classes -+class ASSERT op> -+ : StdArch { -+ bits<5> rk; -+ bits<5> rj; -+ -+ 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; -+} -+ -+class CODE15 op> -+ : StdArch { -+ bits<15> Code; -+ -+ let Inst{31-22} = 0x0; -+ let Inst{21-15} = op; -+ let Inst{14-0} = Code; -+} -+ -+class INSERT_BIT32 op> -+ : StdArch { - bits<5> msbw; - bits<5> lsbw; - bits<5> rj; - bits<5> rd; - -- let Inst{31-21} = op{11-1}; -+ let Inst{31-21} = 0x3; - let Inst{20-16} = msbw; -- let Inst{15} = op{0}; -+ 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 opcstr, string opnstr, -- list pattern = []> -- : LAInst { -+class INSERT_BIT64 op> -+ : StdArch { - bits<6> msbd; - bits<6> lsbd; - bits<5> rj; - bits<5> rd; - -- let Inst{31-22} = 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 opcstr, string opnstr, -- list pattern = []> -- : LAInst { -- bits<5> rk; -+class MOVGPR2FCSR: StdArch { -+ bits<5> fcsr; - bits<5> rj; - -- let Inst{31-15} = op; -- let Inst{14-10} = rk; -+ let Inst{31-10} = 0x4530; - let Inst{9-5} = rj; -- let Inst{4-0} = 0x0; -+ let Inst{4-0} = fcsr; - } - --// FmtPRELD --// < 0b0010101011 | I12 | rj | I5> --class FmtPRELD pattern = []> -- : LAInst { -- 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 { -- 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 opcstr, string opnstr, -- list pattern = []> -- : LAInst { -- bits<14> csr_num; -+class MOVFCFR2GPR: StdArch { -+ bits<3> cj; - bits<5> rd; - -- let Inst{31-24} = op{12-5}; -- let Inst{23-10} = csr_num; -- let Inst{9-5} = op{4-0}; -+ 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 opcstr, string opnstr, -- list pattern = []> -- : LAInst { -- 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-24} = 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 { -- 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, string opstr, list pattern = []> -- : LAInst<(outs), (ins), opstr, "", 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 { -- 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 { -- 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/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp -index bcbd4b28f..00abd9167 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp -+++ b/src/llvm-project/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,105 +11,1030 @@ - //===----------------------------------------------------------------------===// - - #include "LoongArchInstrInfo.h" --#include "LoongArch.h" --#include "LoongArchMachineFunctionInfo.h" -+#include "LoongArchSubtarget.h" -+#include "MCTargetDesc/LoongArchAnalyzeImmediate.h" -+#include "MCTargetDesc/LoongArchBaseInfo.h" -+#include "MCTargetDesc/LoongArchMCTargetDesc.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/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) {} -+ LoongArch::ADJCALLSTACKUP), -+ RI(), Subtarget(STI) {} -+ -+const LoongArchRegisterInfo &LoongArchInstrInfo::getRegisterInfo() const { -+ return RI; -+} -+ -+/// 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; -+} -+ -+/// 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; -+} - - void LoongArchInstrInfo::copyPhysReg(MachineBasicBlock &MBB, -- MachineBasicBlock::iterator MBBI, -- const DebugLoc &DL, MCRegister DstReg, -+ MachineBasicBlock::iterator I, -+ const DebugLoc &DL, MCRegister DestReg, - 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; -+ 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; - } -- -- // FPR->FPR copies. -- unsigned Opc; -- if (LoongArch::FPR32RegClass.contains(DstReg, SrcReg)) { -+ 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; -+ } -+ else if (LoongArch::FGR32RegClass.contains(DestReg, SrcReg)) - Opc = LoongArch::FMOV_S; -- } else if (LoongArch::FPR64RegClass.contains(DstReg, SrcReg)) { -+ else if (LoongArch::FGR64RegClass.contains(DestReg, SrcReg)) - Opc = LoongArch::FMOV_D; -- } else { -- // TODO: support other copies. -- llvm_unreachable("Impossible reg-to-reg copy"); -+ 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; -+ } -+ 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; -+ } -+ -+ 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); - -- BuildMI(MBB, MBBI, DL, get(Opc), DstReg) -- .addReg(SrcReg, getKillRegState(KillSrc)); -+ 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; -+} -+ -+/// 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. -+Optional -+LoongArchInstrInfo::isCopyInstrImpl(const MachineInstr &MI) const { -+ if (MI.isMoveReg() || isORCopyInst(MI)) { -+ return DestSourcePair{MI.getOperand(0), MI.getOperand(1)}; -+ } -+ return None; - } - --void LoongArchInstrInfo::storeRegToStackSlot( -- MachineBasicBlock &MBB, MachineBasicBlock::iterator I, Register SrcReg, -- bool IsKill, int FI, const TargetRegisterClass *RC, -- const TargetRegisterInfo *TRI) const { -+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; -- if (I != MBB.end()) -- DL = I->getDebugLoc(); -- 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 -- llvm_unreachable("Can't store this register to stack slot"); -+ 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, DL, 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) const { -+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(); -- 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 -- llvm_unreachable("Can't load this register from stack slot"); -+ MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOLoad); -+ unsigned Opc = 0; - -- MachineMemOperand *MMO = MF->getMachineMemOperand( -- MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOLoad, -- MFI.getObjectSize(FI), MFI.getObjectAlign(FI)); -+ 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; - -- BuildMI(MBB, I, DL, get(Opcode), DstReg) -+ assert(Opc && "Register class not handled!"); -+ -+ BuildMI(MBB, I, DL, get(Opc), DestReg) - .addFrameIndex(FI) -- .addImm(0) -+ .addImm(Offset) - .addMemOperand(MMO); - } -+ -+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 (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); -+ } -+} -+ -+/// 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) { -+ 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); -+ SrcReg = DstReg; -+ } -+ return DstReg; -+} -+ -+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; -+} -+ -+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); -+ } -+} -+ -+void LoongArchInstrInfo::expandERet(MachineBasicBlock &MBB, -+ MachineBasicBlock::iterator I) const { -+ BuildMI(MBB, I, I->getDebugLoc(), get(LoongArch::ERTN)); -+} -+ -+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)); -+ -+ return std::make_pair(DstRegSize > SrcRegSize, DstRegSize < SrcRegSize); -+} -+ -+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; -+ -+ std::tie(DstIsLarger, SrcIsLarger) = -+ compareOpndSize(CvtOpc, *MBB.getParent()); -+ -+ if (DstIsLarger) -+ TmpReg = getRegisterInfo().getSubReg(DstReg, LoongArch::sub_lo); -+ -+ if (SrcIsLarger) -+ DstReg = getRegisterInfo().getSubReg(DstReg, LoongArch::sub_lo); -+ -+ BuildMI(MBB, I, DL, MovDesc, TmpReg).addReg(SrcReg, KillSrc); -+ BuildMI(MBB, I, DL, CvtDesc, DstReg).addReg(TmpReg, RegState::Kill); -+} -+ -+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(); -+ -+ // 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::isZeroImm(const MachineOperand &op) const { -+ return op.isImm() && op.getImm() == 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)); -+} -+ -+MachineMemOperand * -+LoongArchInstrInfo::GetMemOperand(MachineBasicBlock &MBB, int FI, -+ MachineMemOperand::Flags Flags) const { -+ MachineFunction &MF = *MBB.getParent(); -+ MachineFrameInfo &MFI = MF.getFrameInfo(); -+ -+ return MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(MF, FI), -+ Flags, MFI.getObjectSize(FI), -+ MFI.getObjectAlign(FI)); -+} -+ -+//===----------------------------------------------------------------------===// -+// Branch Analysis -+//===----------------------------------------------------------------------===// -+ -+void LoongArchInstrInfo::AnalyzeCondBr(const MachineInstr *Inst, unsigned Opc, -+ MachineBasicBlock *&BB, -+ SmallVectorImpl &Cond) const { -+ assert(getAnalyzableBrOpc(Opc) && "Not an analyzable branch"); -+ int NumOp = Inst->getNumExplicitOperands(); -+ -+ // 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)); -+ -+ for (int i = 0; i < NumOp-1; i++) -+ Cond.push_back(Inst->getOperand(i)); -+} -+ -+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"); -+ 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(UncondBrOpc)).addMBB(TBB); -+ if (BytesAdded) -+ *BytesAdded += getInstSizeInBytes(MI); -+ } -+ else {// Conditional branch. -+ MachineInstr &MI = *BuildCondBr(MBB, TBB, DL, Cond); -+ if (BytesAdded) -+ *BytesAdded += getInstSizeInBytes(MI); -+ } -+ return 1; -+} -+ -+void LoongArchInstrInfo::insertIndirectBranch(MachineBasicBlock &MBB, -+ MachineBasicBlock &DestBB, -+ MachineBasicBlock &RestoreBB, -+ const DebugLoc &DL, -+ int64_t BrOffset, -+ RegScavenger *RS) const { -+ assert(RS && "RegScavenger required for long branching"); -+ assert(MBB.empty() && -+ "new block should be inserted for expanding unconditional branch"); -+ assert(MBB.pred_size() == 1); -+ -+ MachineFunction *MF = MBB.getParent(); -+ MachineRegisterInfo &MRI = MF->getRegInfo(); -+ const LoongArchSubtarget &Subtarget = MF->getSubtarget(); -+ bool is64 = Subtarget.isABI_LP64(); -+ const TargetRegisterClass *RC = -+ is64 ? &LoongArch::GPR64RegClass : &LoongArch::GPR32RegClass; -+ -+ if (!is64 && !isInt<32>(BrOffset)) -+ report_fatal_error( -+ "Branch offsets outside of the signed 32-bit range not supported"); -+ -+ unsigned ScratchReg = MRI.createVirtualRegister(RC); -+ unsigned ZeroReg = is64 ? LoongArch::ZERO_64 : LoongArch::ZERO; -+ auto II = MBB.end(); -+ -+ 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); -+ unsigned Scav = RS->scavengeRegisterBackwards( -+ *RC, MachineBasicBlock::iterator(Pcaddu12iMI), false, 0); -+ MRI.replaceRegWith(ScratchReg, Scav); -+ MRI.clearVirtRegs(); -+ RS->setRegUsed(Scav); -+} -+ -+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 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> -+LoongArchInstrInfo::getSerializableDirectMachineOperandTargetFlags() const { -+ 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 makeArrayRef(Flags); -+} -diff --git a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchInstrInfo.h b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchInstrInfo.h -index 0a8c86a5e..53191a94d 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchInstrInfo.h -+++ b/src/llvm-project/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,39 +8,239 @@ - // - // 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 - -+#define DBAR_HINT 0x700 -+ -+#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 { -+ virtual void anchor(); -+ const LoongArchRegisterInfo RI; -+ const LoongArchSubtarget &Subtarget; -+ - public: -- explicit LoongArchInstrInfo(LoongArchSubtarget &STI); -+ 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); - -- void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, -- const DebugLoc &DL, MCRegister DstReg, MCRegister SrcReg, -+ /// 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; - -+ /// Branch Analysis -+ bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, -+ MachineBasicBlock *&FBB, -+ SmallVectorImpl &Cond, -+ bool AllowModify) const override; -+ -+ unsigned removeBranch(MachineBasicBlock &MBB, -+ int *BytesRemoved = nullptr) const override; -+ -+ unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, -+ MachineBasicBlock *FBB, ArrayRef Cond, -+ const DebugLoc &DL, -+ int *BytesAdded = nullptr) const override; -+ -+ void insertIndirectBranch(MachineBasicBlock &MBB, -+ MachineBasicBlock &NewDestBB, -+ MachineBasicBlock &RestoreBB, const DebugLoc &DL, -+ 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, -+ MachineBasicBlock::iterator MBBI, -+ Register SrcReg, bool isKill, int FrameIndex, - const TargetRegisterClass *RC, -- const TargetRegisterInfo *TRI) const override; -+ const TargetRegisterInfo *TRI) const override { -+ storeRegToStack(MBB, MBBI, SrcReg, isKill, FrameIndex, RC, TRI, 0); -+ } -+ - void loadRegFromStackSlot(MachineBasicBlock &MBB, -- MachineBasicBlock::iterator MBBI, Register DstReg, -- int FrameIndex, const TargetRegisterClass *RC, -- const TargetRegisterInfo *TRI) const override; -+ MachineBasicBlock::iterator MBBI, -+ Register DestReg, int FrameIndex, -+ const TargetRegisterClass *RC, -+ const TargetRegisterInfo *TRI) 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; -+ -+ ArrayRef> -+ getSerializableDirectMachineOperandTargetFlags() const override; -+ -+protected: -+ /// 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. -+ 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; -+ -+ 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/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td -index d07d086bd..2d505ee25 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td -+++ b/src/llvm-project/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,929 +6,1883 @@ - // - //===----------------------------------------------------------------------===// - // --// 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> --]>; -- --// 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_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_bstrins -- : SDNode<"LoongArchISD::BSTRINS", SDT_LoongArchBStrIns>; --def loongarch_bstrpick -- : SDNode<"LoongArchISD::BSTRPICK", SDT_LoongArchBStrPick>; -+def LoongArchBstrpick : SDNode<"LoongArchISD::BSTRPICK", SDT_Bstrpick>; - --//===----------------------------------------------------------------------===// --// Operand and SDNode transformation definitions. --//===----------------------------------------------------------------------===// -+def LoongArchBstrins : SDNode<"LoongArchISD::BSTRINS", SDT_Bstrins>; - --class ImmAsmOperand -- : AsmOperandClass { -- let Name = prefix # "Imm" # width # suffix; -- let DiagnosticType = !strconcat("Invalid", Name); -+def SDT_DBAR : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>; -+def LoongArchDBAR : SDNode<"LoongArchISD::DBAR", SDT_DBAR, [SDNPHasChain,SDNPSideEffect]>; -+ -+def SDT_LoongArchEHRET : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisPtrTy<1>]>; -+ -+def LoongArchehret : SDNode<"LoongArchISD::EH_RETURN", SDT_LoongArchEHRET, -+ [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; -+ -+//===---------------------------------------------------------------------===/ -+// Operand, Complex Patterns and Transformations Definitions. -+//===---------------------------------------------------------------------===/ -+ -+def assertzext_lt_i32 : PatFrag<(ops node:$src), (assertzext node:$src), [{ -+ return cast(N->getOperand(1))->getVT().bitsLT(MVT::i32); -+}]>; -+ -+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 HasLSX : Predicate<"Subtarget->hasLSX()">, -+ AssemblerPredicate<(all_of FeatureLSX)>; -+def HasLASX : Predicate<"Subtarget->hasLASX()">, -+ AssemblerPredicate<(all_of FeatureLASX)>; -+ -+class EXT_LSX { -+ list ExtPredicate = [HasLSX]; -+} -+ -+class EXT_LASX { -+ list ExtPredicate = [HasLASX]; -+} -+ -+class SImmOperand : AsmOperandClass { -+ let Name = "SImm" # width; -+ let DiagnosticType = "InvalidSImm" # width; - let RenderMethod = "addImmOperands"; -+ let PredicateMethod = "isSImm<" # width # ">"; - } - --class SImmAsmOperand -- : ImmAsmOperand<"S", width, suffix> { -+def SImm2Operand : SImmOperand<2>; -+def simm2 : Operand, ImmLeaf= -2 && Imm < 2; }]> { -+ let ParserMatchClass = SImm2Operand; -+ let DecoderMethod = "DecodeSImmWithOffsetAndScale<2>"; -+} -+def SImm3Operand : SImmOperand<3>; -+def simm3 : Operand, ImmLeaf= -4 && Imm < 4; }]> { -+ let ParserMatchClass = SImm3Operand; -+ let DecoderMethod = "DecodeSImmWithOffsetAndScale<3>"; - } - --class UImmAsmOperand -- : ImmAsmOperand<"U", width, suffix> { -+def SImm5Operand : SImmOperand<5>; -+def simm5 : Operand, ImmLeaf= -16 && Imm < 16; }]> { -+ let ParserMatchClass = SImm5Operand; -+ let DecoderMethod = "DecodeSImmWithOffsetAndScale<5>"; - } - --def uimm2 : Operand { -- let ParserMatchClass = UImmAsmOperand<2>; -+def simm5_32 : Operand, ImmLeaf= -16 && Imm < 16; }]> { -+ let ParserMatchClass = SImm5Operand; -+ let DecoderMethod = "DecodeSImmWithOffsetAndScale<5>"; - } - --def uimm2_plus1 : Operand { -- let ParserMatchClass = UImmAsmOperand<2, "plus1">; -- let EncoderMethod = "getImmOpValueSub1"; -- let DecoderMethod = "decodeUImmOperand<2, 1>"; -+def SImm8Operand : SImmOperand<8>; -+def simm8 : Operand, ImmLeaf= -128 && Imm < 128; }]> { -+ let ParserMatchClass = SImm8Operand; -+ let DecoderMethod = "DecodeSImmWithOffsetAndScale<8>"; -+} -+def simm8_32 : Operand, ImmLeaf= -128 && Imm < 128; }]> { -+ let ParserMatchClass = SImm8Operand; -+ let DecoderMethod = "DecodeSImmWithOffsetAndScale<8>"; - } - --def uimm3 : Operand { -- let ParserMatchClass = UImmAsmOperand<3>; -+def SImm12Operand : SImmOperand<12>; -+def simm12 : Operand, ImmLeaf= -2048 && Imm < 2048; }]> { -+ let ParserMatchClass = SImm12Operand; -+ let DecoderMethod = "DecodeSImmWithOffsetAndScale<12>"; -+} -+def simm12_32 : Operand, ImmLeaf= -2048 && Imm < 2048; }]> { -+ let ParserMatchClass = SImm12Operand; -+ let DecoderMethod = "DecodeSImmWithOffsetAndScale<12>"; - } - --def uimm5 : Operand, ImmLeaf(Imm);}]> { -- let ParserMatchClass = UImmAsmOperand<5>; -+def SImm14Operand : SImmOperand<14>; -+def simm14 : Operand, ImmLeaf= -8192 && Imm < 8192; }]> { -+ let ParserMatchClass = SImm14Operand; -+ let DecoderMethod = "DecodeSImmWithOffsetAndScale<14>"; - } - --def uimm6 : Operand, ImmLeaf(Imm);}]> { -- let ParserMatchClass = UImmAsmOperand<6>; -+def SImm15Operand : SImmOperand<15>; -+def simm15 : Operand, ImmLeaf= -16384 && Imm < 16384; }]> { -+ let ParserMatchClass = SImm15Operand; -+ let DecoderMethod = "DecodeSImmWithOffsetAndScale<15>"; - } - --def uimm8 : Operand { -- let ParserMatchClass = UImmAsmOperand<8>; -+def SImm16Operand : SImmOperand<16>; -+def simm16 : Operand, ImmLeaf= -32768 && Imm < 32768; }]> { -+ let ParserMatchClass = SImm16Operand; -+ let DecoderMethod = "DecodeSImmWithOffsetAndScale<16>"; - } - --def uimm12 : Operand, ImmLeaf(Imm);}]> { -- let ParserMatchClass = UImmAsmOperand<12>; -+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 uimm14 : Operand { -- let ParserMatchClass = UImmAsmOperand<14>; -+def SImm21Operand : SImmOperand<21>; -+def simm21 : Operand, ImmLeaf= -1048576 && Imm < 1048576; }]> { -+ let ParserMatchClass = SImm21Operand; -+ let DecoderMethod = "DecodeSImmWithOffsetAndScale<21>"; - } - --def uimm15 : Operand { -- let ParserMatchClass = UImmAsmOperand<15>; -+def SImm26Operand : SImmOperand<26>; -+def simm26 : Operand, ImmLeaf= -33554432 && Imm < 33554432; }]> { -+ let ParserMatchClass = SImm26Operand; -+ let DecoderMethod = "DecodeSImmWithOffsetAndScale<26>"; - } - --def simm12 : Operand, ImmLeaf(Imm);}]> { -- let ParserMatchClass = SImmAsmOperand<12>; -- let DecoderMethod = "decodeSImmOperand<12>"; -+def UImm1Operand : AsmOperandClass { -+ let Name = "UImm1"; -+ let RenderMethod = "addUImmOperands<1>"; -+ let PredicateMethod = "isUImm<1>"; -+ let DiagnosticType = "InvalidImm0_1"; - } - --def simm14_lsl2 : Operand { -- let ParserMatchClass = SImmAsmOperand<14, "lsl2">; -- let EncoderMethod = "getImmOpValueAsr2"; -- let DecoderMethod = "decodeSImmOperand<14, 2>"; -+def UImm2Operand : AsmOperandClass { -+ let Name = "UImm2"; -+ let RenderMethod = "addUImmOperands<2>"; -+ let PredicateMethod = "isUImm<2>"; -+ let DiagnosticType = "InvalidImm0_3"; - } - --def simm16 : Operand { -- let ParserMatchClass = SImmAsmOperand<16>; -- let DecoderMethod = "decodeSImmOperand<16>"; -+def UImm3Operand : AsmOperandClass { -+ let Name = "UImm3"; -+ let RenderMethod = "addUImmOperands<3>"; -+ let PredicateMethod = "isUImm<3>"; -+ let DiagnosticType = "InvalidImm0_7"; - } - --def simm16_lsl2 : Operand, -- ImmLeaf(Imm>>2);}]> { -- let ParserMatchClass = SImmAsmOperand<16, "lsl2">; -- let EncoderMethod = "getImmOpValueAsr2"; -- let DecoderMethod = "decodeSImmOperand<16, 2>"; -+def UImm4Operand : AsmOperandClass { -+ let Name = "UImm4"; -+ let RenderMethod = "addUImmOperands<4>"; -+ let PredicateMethod = "isUImm<4>"; -+ let DiagnosticType = "InvalidImm0_15"; - } - --def simm16_lsl2_br : Operand { -- let ParserMatchClass = SImmAsmOperand<16, "lsl2">; -- let EncoderMethod = "getImmOpValueAsr2"; -- let DecoderMethod = "decodeSImmOperand<16, 2>"; -+def UImm5Operand : AsmOperandClass { -+ let Name = "UImm5"; -+ let RenderMethod = "addUImmOperands<5>"; -+ let PredicateMethod = "isUImm<5>"; -+ let DiagnosticType = "InvalidImm0_31"; - } - --def simm20 : Operand { -- let ParserMatchClass = SImmAsmOperand<20>; -- let DecoderMethod = "decodeSImmOperand<20>"; -+def uimm1i : Operand, ImmLeaf= 0 && Imm < 2; }]> { -+ let PrintMethod = "printUImm<1>"; -+ let ParserMatchClass = UImm1Operand; - } - --def simm21_lsl2 : Operand { -- let ParserMatchClass = SImmAsmOperand<21, "lsl2">; -- let EncoderMethod = "getImmOpValueAsr2"; -- let DecoderMethod = "decodeSImmOperand<21, 2>"; -+def uimm2 : Operand, ImmLeaf= 0 && Imm < 4; }]> { -+ let PrintMethod = "printUImm<2>"; -+ let ParserMatchClass = UImm2Operand; - } - --def simm26_lsl2 : Operand { -- let ParserMatchClass = SImmAsmOperand<26, "lsl2">; -- let EncoderMethod = "getImmOpValueAsr2"; -- let DecoderMethod = "decodeSImmOperand<26, 2>"; -+def uimm3 : Operand, ImmLeaf= 0 && Imm < 8; }]> { -+ let PrintMethod = "printUImm<3>"; -+ let ParserMatchClass = UImm3Operand; - } - --// Standalone (codegen-only) immleaf patterns. -+def uimm4i : Operand, ImmLeaf= 0 && Imm < 16; }]> { -+ let PrintMethod = "printUImm<4>"; -+ let ParserMatchClass = UImm4Operand; -+} - --// A 12-bit signed immediate plus one where the imm range will be [-2047, 2048]. --def simm12_plus1 : ImmLeaf(Imm) && Imm != -2048) || Imm == 2048;}]>; -+def uimm5 : Operand, ImmLeaf= 0 && Imm < 32; }]> { -+ let PrintMethod = "printUImm<5>"; -+ let ParserMatchClass = UImm5Operand; -+} - --// Return the negation of an immediate value. --def NegImm : SDNodeXFormgetTargetConstant(-N->getSExtValue(), SDLoc(N), -- N->getValueType(0)); --}]>; -+def UImm6Operand : AsmOperandClass { -+ let Name = "UImm6"; -+ let RenderMethod = "addUImmOperands<16>"; -+ let PredicateMethod = "isUImm<6>"; -+ let DiagnosticType = "InvalidImm0_63"; -+} -+def uimm6 : Operand, ImmLeaf= 0 && Imm < 64; }]> { -+ let PrintMethod = "printUImm<6>"; -+ let ParserMatchClass = UImm6Operand; -+} - --// 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 UImm7Operand : AsmOperandClass { -+ let Name = "UImm7"; -+ let RenderMethod = "addUImmOperands<16>"; -+ let PredicateMethod = "isUImm<7>"; -+ let DiagnosticType = "InvalidImm0_127"; -+} - --def CallSymbol: AsmOperandClass { -- let Name = "CallSymbol"; -+def uimm7i : Operand, ImmLeaf= 0 && Imm < 128; }]> { -+ let PrintMethod = "printUImm<7>"; -+ let ParserMatchClass = UImm7Operand; -+} -+ -+def UImm12Operand : AsmOperandClass { -+ let Name = "UImm12"; -+ let RenderMethod = "addUImmOperands<12>"; -+ let PredicateMethod = "isUImm<12>"; -+ let DiagnosticType = "InvalidImm0_4095"; -+} -+def uimm12 : Operand, ImmLeaf= 0 && Imm < 4096; }]> { -+ let PrintMethod = "printUImm<12>"; -+ let ParserMatchClass = UImm12Operand; -+} -+def uimm12_32 : Operand, ImmLeaf= 0 && Imm < 4096; }]> { -+ let PrintMethod = "printUImm<12>"; -+ let ParserMatchClass = UImm12Operand; -+} -+ -+def UImm15Operand : AsmOperandClass { -+ let Name = "UImm15"; -+ let RenderMethod = "addUImmOperands<15>"; -+ let PredicateMethod = "isUImm<15>"; -+ let DiagnosticType = "InvalidImm0_32767"; -+} -+def uimm15 : Operand, ImmLeaf= 0 && Imm < 32768; }]> { -+ let PrintMethod = "printUImm<15>"; -+ let ParserMatchClass = UImm15Operand; -+} -+ -+def UImm14Operand : AsmOperandClass { -+ let Name = "UImm14"; -+ let RenderMethod = "addUImmOperands<14>"; -+ let PredicateMethod = "isUImm<14>"; -+ let DiagnosticType = "InvalidImm0_16383"; -+} -+def uimm14 : Operand, ImmLeaf= 0 && Imm < 16384; }]> { -+ let PrintMethod = "printUImm<14>"; -+ let ParserMatchClass = UImm14Operand; -+} -+def uimm14_32 : Operand, ImmLeaf= 0 && Imm < 16384; }]> { -+ let PrintMethod = "printUImm<14>"; -+ let ParserMatchClass = UImm14Operand; -+} -+ -+def UImm8Operand : AsmOperandClass { -+ let Name = "UImm8"; -+ let RenderMethod = "addUImmOperands<8>"; -+ let PredicateMethod = "isUImm<8>"; -+ let DiagnosticType = "InvalidImm0_255"; -+} -+def uimm8_64 : Operand, ImmLeaf= 0 && Imm < 256; }]> { -+ let PrintMethod = "printUImm<8>"; -+ let ParserMatchClass = UImm8Operand; -+} -+ -+def uimm8_32 : Operand, ImmLeaf= 0 && Imm < 256; }]> { -+ let PrintMethod = "printUImm<8>"; -+ let ParserMatchClass = UImm8Operand; -+} -+ -+def addr : -+ComplexPattern; -+ -+def addrDefault : -+ComplexPattern; -+ -+def addrRegImm : -+ComplexPattern; -+ -+def addrimm14lsl2 : 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 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]>; -+ -+def ConstantUImm20AsmOperandClass -+ : ConstantUImmAsmOperandClass<20, [ConstantUImm26AsmOperandClass]>; -+ -+def ConstantUImm2Plus1AsmOperandClass -+ : ConstantUImmAsmOperandClass<2, [ConstantUImm20AsmOperandClass], 1>; -+ -+class UImmAsmOperandClass Supers = []> -+ : AsmOperandClass { -+ let Name = "UImm" # Bits; -+ let RenderMethod = "addUImmOperands<" # Bits # ">"; -+ let PredicateMethod = "isUImm<" # Bits # ">"; -+ let SuperClasses = Supers; -+ let DiagnosticType = "UImm" # Bits; -+} -+ -+def UImm16RelaxedAsmOperandClass -+ : UImmAsmOperandClass<16, [ConstantUImm20AsmOperandClass]> { -+ let Name = "UImm16_Relaxed"; -+ let PredicateMethod = "isAnyImm<16>"; -+ let DiagnosticType = "UImm16_Relaxed"; -+} -+ -+def ConstantSImm14Lsl2AsmOperandClass : AsmOperandClass { -+ let Name = "SImm14Lsl2"; - let RenderMethod = "addImmOperands"; -+ let PredicateMethod = "isScaledSImm<14, 2>"; -+ let SuperClasses = [UImm16RelaxedAsmOperandClass]; -+ let DiagnosticType = "SImm14_Lsl2"; -+} -+ -+foreach I = {2} in -+ def simm14_lsl # I : Operand { -+ let DecoderMethod = "DecodeSImmWithOffsetAndScale<14, " # I # ">"; -+ let ParserMatchClass = -+ !cast("ConstantSImm14Lsl" # I # "AsmOperandClass"); -+ } -+ -+def uimm16_64_relaxed : Operand { -+ let PrintMethod = "printUImm<16>"; -+ let ParserMatchClass = -+ !cast("UImm16RelaxedAsmOperandClass"); -+} -+ -+def uimm2_plus1 : Operand { -+ let PrintMethod = "printUImm<2, 1>"; -+ let EncoderMethod = "getUImmWithOffsetEncoding<2, 1>"; -+ let DecoderMethod = "DecodeUImmWithOffset<2, 1>"; -+ let ParserMatchClass = ConstantUImm2Plus1AsmOperandClass; -+} -+ -+// like simm32 but coerces simm32 to uimm32. -+def uimm32_coerced : Operand { -+ let ParserMatchClass = !cast("UImm32CoercedAsmOperandClass"); -+} -+ -+def imm64: Operand; -+ -+def LoongArchMemAsmOperand : AsmOperandClass { -+ let Name = "Mem"; -+ let ParserMethod = "parseMemOperand"; -+} -+ -+def LoongArchAMemAsmOperand : AsmOperandClass { -+ let Name = "AMem"; -+ let ParserMethod = "parseAMemOperand"; -+ let RenderMethod = "addMemOperands"; -+ let PredicateMethod = "isZeroMemOff"; -+ let DiagnosticType = "MemZeroOff"; -+} -+ -+def LoongArchMemSimm14AsmOperand : AsmOperandClass { -+ let Name = "MemOffsetSimm14"; -+ let SuperClasses = [LoongArchMemAsmOperand]; -+ let RenderMethod = "addMemOperands"; -+ let ParserMethod = "parseMemOperand"; -+ let PredicateMethod = "isMemWithSimmOffset<14>"; -+ let DiagnosticType = "MemSImm14"; -+} -+ -+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; -+ } -+ -+def LoongArchMemSimmPtrAsmOperand : AsmOperandClass { -+ let Name = "MemOffsetSimmPtr"; -+ let SuperClasses = [LoongArchMemAsmOperand]; -+ let RenderMethod = "addMemOperands"; -+ let ParserMethod = "parseMemOperand"; -+ let PredicateMethod = "isMemWithPtrSizeOffset"; -+ let DiagnosticType = "MemSImmPtr"; -+} -+ -+class mem_generic : Operand { -+ let PrintMethod = "printMemOperand"; -+ let MIOperandInfo = (ops ptr_rc, simm12); -+ let EncoderMethod = "getMemEncoding"; -+ let ParserMatchClass = LoongArchMemAsmOperand; -+ let OperandType = "OPERAND_MEMORY"; -+} -+ -+// Address operand -+def mem : mem_generic; -+ -+def amem : mem_generic { -+ let PrintMethod = "printAMemOperand"; -+ let EncoderMethod = "getAMemEncoding"; -+ let ParserMatchClass = LoongArchAMemAsmOperand; -+} -+ -+def mem_simmptr : mem_generic { -+ let ParserMatchClass = LoongArchMemSimmPtrAsmOperand; -+} -+ -+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"); -+ } -+ -+def mem_ea : Operand { -+ let PrintMethod = "printMemOperandEA"; -+ let MIOperandInfo = (ops ptr_rc, simm12); -+ let EncoderMethod = "getMemEncoding"; -+ let OperandType = "OPERAND_MEMORY"; -+} -+ -+def LoongArchJumpTargetAsmOperand : AsmOperandClass { -+ let Name = "JumpTarget"; -+ let ParserMethod = "parseJumpTarget"; - let PredicateMethod = "isImm"; -+ let RenderMethod = "addImmOperands"; - } - --// A bare symbol used in call only. --def call_symbol : Operand { -- let ParserMatchClass = CallSymbol; -+def jmptarget : Operand { -+ let EncoderMethod = "getJumpTargetOpValue"; -+ let ParserMatchClass = LoongArchJumpTargetAsmOperand; - } - --def BaseAddr : ComplexPattern; -+def brtarget : Operand { -+ let EncoderMethod = "getBranchTargetOpValue"; -+ let OperandType = "OPERAND_PCREL"; -+ let DecoderMethod = "DecodeBranchTarget"; -+ let ParserMatchClass = LoongArchJumpTargetAsmOperand; -+} - --//===----------------------------------------------------------------------===// --// Instruction Formats --//===----------------------------------------------------------------------===// -+def calltarget : Operand { -+ let EncoderMethod = "getJumpTargetOpValue"; -+ let ParserMatchClass = LoongArchJumpTargetAsmOperand; -+} - --include "LoongArchInstrFormats.td" --include "LoongArchFloatInstrFormats.td" -+// -+//SDNode -+// -+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 LoongArchRet : SDNode<"LoongArchISD::Ret", SDTNone, -+ [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; -+def LoongArchERet : SDNode<"LoongArchISD::ERet", SDTNone, -+ [SDNPHasChain, SDNPOptInGlue, SDNPSideEffect]>; -+ -+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>; -+ -+// Return RA. -+let isReturn=1, isTerminator=1, isBarrier=1, hasCtrlDep=1, isCTI=1 in { -+ def RetRA : LoongArchPseudo<(outs), (ins), [(LoongArchRet)]>; -+ -+ let hasSideEffects=1 in -+ def ERet : LoongArchPseudo<(outs), (ins), [(LoongArchERet)]>; -+} - --//===----------------------------------------------------------------------===// -+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)]>; -+} -+ -+class LoongArchPat : Pat, PredicateControl; -+ -+def SDT_LoongArchJmpLink : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>; -+ -+def LoongArchJmpLink : SDNode<"LoongArchISD::JmpLink",SDT_LoongArchJmpLink, -+ [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, -+ SDNPVariadic]>; -+ -+def LoongArchTailCall : SDNode<"LoongArchISD::TailCall", SDT_LoongArchJmpLink, -+ [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; -+ -+class GPR_32 { list GPRPredicates = [IsGP32bit]; } -+class GPR_64 { list GPRPredicates = [IsGP64bit]; } -+ -+//===---------------------------------------------------------------------===/ - // 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 ALU_3R op, string opstr> -- : Fmt3R; --class ALU_2R op, string opstr> -- : Fmt2R; -- --class ALU_3RI2 op, string opstr, Operand ImmOpnd> -- : Fmt3RI2; --class ALU_3RI3 op, string opstr, Operand ImmOpnd> -- : Fmt3RI3; --class ALU_2RI5 op, string opstr, Operand ImmOpnd> -- : Fmt2RI5; --class ALU_2RI6 op, string opstr, Operand ImmOpnd> -- : Fmt2RI6; --class ALU_2RI12 op, string opstr, Operand ImmOpnd> -- : Fmt2RI12; --class ALU_2RI16 op, string opstr, Operand ImmOpnd> -- : Fmt2RI16; --class ALU_1RI20 op, string opstr, Operand ImmOpnd> -- : Fmt1RI20; -- --class MISC_I15 op, string opstr> -- : FmtI15; -- --class RDTIME_2R op, string opstr> -- : Fmt2R; -- --class BrCC_2RI16 op, string opstr> -- : Fmt2RI16 { -- let isBranch = 1; -- let isTerminator = 1; -+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; - } --class BrCCZ_1RI21 op, string opstr> -- : Fmt1RI21 { -- let isBranch = 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>; -+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; -+} -+ -+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))]>; -+ -+class AtomicCmpSwapPostRA : -+ LoongArchPseudo<(outs RC:$dst), (ins PtrRC:$ptr, RC:$cmp, RC:$swap), []> { -+ let mayLoad = 1; -+ let mayStore = 1; -+} -+ -+class AtomicCmpSwapSubwordPostRA : -+ LoongArchPseudo<(outs RC:$dst), (ins PtrRC:$ptr, RC:$mask, RC:$ShiftCmpVal, -+ RC:$mask2, RC:$ShiftNewVal, RC:$ShiftAmt), []> { -+ let mayLoad = 1; -+ let mayStore = 1; -+} -+ -+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>, 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; -+} -+ -+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"; -+} -+ -+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 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>; -+ -+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; -+} -+ -+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; -+ -+ -+let isCall=1, isCTI=1, Defs=[RA], isCodeGenOnly=1 in { -+def PseudoCall : LoongArchPseudo<(outs), (ins calltarget:$target), -+ []>; - } --class Br_I26 op, string opstr> -- : FmtI26 { -- let isBranch = 1; -+ -+let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [SP] in -+def PseudoTailCall : LoongArchPseudo<(outs), (ins calltarget:$target), -+ []>; -+ -+class PseudoTailBase : LoongArchPseudo<(outs), (ins opnd:$offset26), -+ []> { - let isTerminator = 1; -+ let isBarrier = 1; -+ let isReturn = 1; -+ let isCodeGenOnly = 1; - } -+def PseudoTailReturn : PseudoTailBase; - --let mayLoad = 1 in { --class LOAD_3R op, string opstr> -- : Fmt3R; --class LOAD_2RI12 op, string opstr> -- : Fmt2RI12; --class LOAD_2RI14 op, string opstr> -- : Fmt2RI14; --} // mayLoad = 1 -- --let mayStore = 1 in { --class STORE_3R op, string opstr> -- : Fmt3R; --class STORE_2RI12 op, string opstr> -- : Fmt2RI12; --class STORE_2RI14 op, string opstr> -- : Fmt2RI14; --} // mayStore = 1 -- --let mayLoad = 1, mayStore = 1 in --class AM_3R op, string opstr> -- : Fmt3R; -- --let mayLoad = 1 in --class LLBase op, string opstr> -- : Fmt2RI14; -- --let mayStore = 1, Constraints = "$rd = $dst" in --class SCBase op, string opstr> -- : Fmt2RI14; -- --class IOCSRRD op, string opstr> -- : Fmt2R; -- --class IOCSRWR op, string opstr> -- : Fmt2R; - --//===----------------------------------------------------------------------===// --// Basic Integer Instructions --//===----------------------------------------------------------------------===// -+def : LoongArchPat<(LoongArchTailCall tglobaladdr:$dst), -+ (PseudoTailCall tglobaladdr:$dst)>; - --// Arithmetic Operation Instructions --def ADD_W : ALU_3R<0b00000000000100000, "add.w">; --def SUB_W : ALU_3R<0b00000000000100010, "sub.w">; --def ADDI_W : ALU_2RI12<0b0000001010, "addi.w", simm12>; --def ALSL_W : ALU_3RI2<0b000000000000010, "alsl.w", uimm2_plus1>; --def LU12I_W : ALU_1RI20<0b0001010, "lu12i.w", simm20>; --def SLT : ALU_3R<0b00000000000100100, "slt">; --def SLTU : ALU_3R<0b00000000000100101, "sltu">; --def SLTI : ALU_2RI12<0b0000001000, "slti", simm12>; --def SLTUI : ALU_2RI12<0b0000001001, "sltui", simm12>; --def PCADDI : ALU_1RI20<0b0001100, "pcaddi", simm20>; --def PCADDU12I : ALU_1RI20<0b0001110, "pcaddu12i", simm20>; --def PCALAU12I : ALU_1RI20<0b0001101, "pcalau12i", simm20>; --def AND : ALU_3R<0b00000000000101001, "and">; --def OR : ALU_3R<0b00000000000101010, "or">; --def NOR : ALU_3R<0b00000000000101000, "nor">; --def XOR : ALU_3R<0b00000000000101011, "xor">; --def ANDN : ALU_3R<0b00000000000101101, "andn">; --def ORN : ALU_3R<0b00000000000101100, "orn">; --def ANDI : ALU_2RI12<0b0000001101, "andi", uimm12>; --def ORI : ALU_2RI12<0b0000001110, "ori", uimm12>; --def XORI : ALU_2RI12<0b0000001111, "xori", uimm12>; --def MUL_W : ALU_3R<0b00000000000111000, "mul.w">; --def MULH_W : ALU_3R<0b00000000000111001, "mulh.w">; --def MULH_WU : ALU_3R<0b00000000000111010, "mulh.wu">; --let usesCustomInserter = true in { --def DIV_W : ALU_3R<0b00000000001000000, "div.w">; --def MOD_W : ALU_3R<0b00000000001000001, "mod.w">; --def DIV_WU : ALU_3R<0b00000000001000010, "div.wu">; --def MOD_WU : ALU_3R<0b00000000001000011, "mod.wu">; --} // usesCustomInserter = true -- --// Bit-shift Instructions --def SLL_W : ALU_3R<0b00000000000101110, "sll.w">; --def SRL_W : ALU_3R<0b00000000000101111, "srl.w">; --def SRA_W : ALU_3R<0b00000000000110000, "sra.w">; --def ROTR_W : ALU_3R<0b00000000000110110, "rotr.w">; -- --def SLLI_W : ALU_2RI5<0b00000000010000001, "slli.w", uimm5>; --def SRLI_W : ALU_2RI5<0b00000000010001001, "srli.w", uimm5>; --def SRAI_W : ALU_2RI5<0b00000000010010001, "srai.w", uimm5>; --def ROTRI_W : ALU_2RI5<0b00000000010011001, "rotri.w", uimm5>; -- --// Bit-manipulation Instructions --def EXT_W_B : ALU_2R<0b0000000000000000010111, "ext.w.b">; --def EXT_W_H : ALU_2R<0b0000000000000000010110, "ext.w.h">; --def CLO_W : ALU_2R<0b0000000000000000000100, "clo.w">; --def CLZ_W : ALU_2R<0b0000000000000000000101, "clz.w">; --def CTO_W : ALU_2R<0b0000000000000000000110, "cto.w">; --def CTZ_W : ALU_2R<0b0000000000000000000111, "ctz.w">; --def BYTEPICK_W : ALU_3RI2<0b000000000000100, "bytepick.w", uimm2>; --def REVB_2H : ALU_2R<0b0000000000000000001100, "revb.2h">; --def BITREV_4B : ALU_2R<0b0000000000000000010010, "bitrev.4b">; --def BITREV_W : ALU_2R<0b0000000000000000010100, "bitrev.w">; --let Constraints = "$rd = $dst" in { --def BSTRINS_W : FmtBSTR_W<0b000000000110, (outs GPR:$dst), -- (ins GPR:$rd, GPR:$rj, uimm5:$msbw, uimm5:$lsbw), -- "bstrins.w", "$rd, $rj, $msbw, $lsbw">; --} --def BSTRPICK_W : FmtBSTR_W<0b000000000111, (outs GPR:$rd), -- (ins GPR:$rj, uimm5:$msbw, uimm5:$lsbw), -- "bstrpick.w", "$rd, $rj, $msbw, $lsbw">; --def MASKEQZ : ALU_3R<0b00000000000100110, "maskeqz">; --def MASKNEZ : ALU_3R<0b00000000000100111, "masknez">; -- --// Branch Instructions --def BEQ : BrCC_2RI16<0b010110, "beq">; --def BNE : BrCC_2RI16<0b010111, "bne">; --def BLT : BrCC_2RI16<0b011000, "blt">; --def BGE : BrCC_2RI16<0b011001, "bge">; --def BLTU : BrCC_2RI16<0b011010, "bltu">; --def BGEU : BrCC_2RI16<0b011011, "bgeu">; --def BEQZ : BrCCZ_1RI21<0b010000, "beqz">; --def BNEZ : BrCCZ_1RI21<0b010001, "bnez">; --def B : Br_I26<0b010100, "b">; -- --let isCall = 1 in --def BL : FmtI26<0b010101, (outs), (ins simm26_lsl2:$imm26), "bl", "$imm26">; --def JIRL : Fmt2RI16<0b010011, (outs GPR:$rd), -- (ins GPR:$rj, simm16_lsl2:$imm16), "jirl", -- "$rd, $rj, $imm16">; -- --// Common Memory Access Instructions --def LD_B : LOAD_2RI12<0b0010100000, "ld.b">; --def LD_H : LOAD_2RI12<0b0010100001, "ld.h">; --def LD_W : LOAD_2RI12<0b0010100010, "ld.w">; --def LD_BU : LOAD_2RI12<0b0010101000, "ld.bu">; --def LD_HU : LOAD_2RI12<0b0010101001, "ld.hu">; --def ST_B : STORE_2RI12<0b0010100100, "st.b">; --def ST_H : STORE_2RI12<0b0010100101, "st.h">; --def ST_W : STORE_2RI12<0b0010100110, "st.w">; --def PRELD : FmtPRELD<(outs), (ins uimm5:$imm5, GPR:$rj, simm12:$imm12), "preld", -- "$imm5, $rj, $imm12">; -- --// Atomic Memory Access Instructions --def LL_W : LLBase<0b00100000, "ll.w">; --def SC_W : SCBase<0b00100001, "sc.w">; -- --// Barrier Instructions --def DBAR : MISC_I15<0b00111000011100100, "dbar">; --def IBAR : MISC_I15<0b00111000011100101, "ibar">; -- --// Other Miscellaneous Instructions --def SYSCALL : MISC_I15<0b00000000001010110, "syscall">; --def BREAK : MISC_I15<0b00000000001010100, "break">; --def RDTIMEL_W : RDTIME_2R<0b0000000000000000011000, "rdtimel.w">; --def RDTIMEH_W : RDTIME_2R<0b0000000000000000011001, "rdtimeh.w">; --def CPUCFG : ALU_2R<0b0000000000000000011011, "cpucfg">; -- --/// LA64 instructions -- --let Predicates = [IsLA64] in { -- --// Arithmetic Operation Instructions for 64-bits --def ADD_D : ALU_3R<0b00000000000100001, "add.d">; --def SUB_D : ALU_3R<0b00000000000100011, "sub.d">; --def ADDI_D : ALU_2RI12<0b0000001011, "addi.d", simm12>; --def ADDU16I_D : ALU_2RI16<0b000100, "addu16i.d", simm16>; --def ALSL_WU : ALU_3RI2<0b000000000000011, "alsl.wu", uimm2_plus1>; --def ALSL_D : ALU_3RI2<0b000000000010110, "alsl.d", uimm2_plus1>; --let Constraints = "$rd = $dst" in { --def LU32I_D : Fmt1RI20<0b0001011, (outs GPR:$dst), -- (ins GPR:$rd, simm20:$imm20), "lu32i.d", -- "$rd, $imm20">; --} --def LU52I_D : ALU_2RI12<0b0000001100, "lu52i.d", simm12>; --def PCADDU18I : ALU_1RI20<0b0001111, "pcaddu18i", simm20>; --def MUL_D : ALU_3R<0b00000000000111011, "mul.d">; --def MULH_D : ALU_3R<0b00000000000111100, "mulh.d">; --def MULH_DU : ALU_3R<0b00000000000111101, "mulh.du">; --def MULW_D_W : ALU_3R<0b00000000000111110, "mulw.d.w">; --def MULW_D_WU : ALU_3R<0b00000000000111111, "mulw.d.wu">; --let usesCustomInserter = true in { --def DIV_D : ALU_3R<0b00000000001000100, "div.d">; --def MOD_D : ALU_3R<0b00000000001000101, "mod.d">; --def DIV_DU : ALU_3R<0b00000000001000110, "div.du">; --def MOD_DU : ALU_3R<0b00000000001000111, "mod.du">; --} // usesCustomInserter = true -- --// Bit-shift Instructions for 64-bits --def SLL_D : ALU_3R<0b00000000000110001, "sll.d">; --def SRL_D : ALU_3R<0b00000000000110010, "srl.d">; --def SRA_D : ALU_3R<0b00000000000110011, "sra.d">; --def ROTR_D : ALU_3R<0b00000000000110111, "rotr.d">; --def SLLI_D : ALU_2RI6<0b0000000001000001, "slli.d", uimm6>; --def SRLI_D : ALU_2RI6<0b0000000001000101, "srli.d", uimm6>; --def SRAI_D : ALU_2RI6<0b0000000001001001, "srai.d", uimm6>; --def ROTRI_D : ALU_2RI6<0b0000000001001101, "rotri.d", uimm6>; -- --// Bit-manipulation Instructions for 64-bits --def CLO_D : ALU_2R<0b0000000000000000001000, "clo.d">; --def CLZ_D : ALU_2R<0b0000000000000000001001, "clz.d">; --def CTO_D : ALU_2R<0b0000000000000000001010, "cto.d">; --def CTZ_D : ALU_2R<0b0000000000000000001011, "ctz.d">; --def BYTEPICK_D : ALU_3RI3<0b00000000000011, "bytepick.d", uimm3>; --def REVB_4H : ALU_2R<0b0000000000000000001101, "revb.4h">; --def REVB_2W : ALU_2R<0b0000000000000000001110, "revb.2w">; --def REVB_D : ALU_2R<0b0000000000000000001111, "revb.d">; --def REVH_2W : ALU_2R<0b0000000000000000010000, "revh.2w">; --def REVH_D : ALU_2R<0b0000000000000000010001, "revh.d">; --def BITREV_8B : ALU_2R<0b0000000000000000010011, "bitrev.8b">; --def BITREV_D : ALU_2R<0b0000000000000000010101, "bitrev.d">; --let Constraints = "$rd = $dst" in { --def BSTRINS_D : FmtBSTR_D<0b0000000010, (outs GPR:$dst), -- (ins GPR:$rd, GPR:$rj, uimm6:$msbd, uimm6:$lsbd), -- "bstrins.d", "$rd, $rj, $msbd, $lsbd">; --} --def BSTRPICK_D : FmtBSTR_D<0b0000000011, (outs GPR:$rd), -- (ins GPR:$rj, uimm6:$msbd, uimm6:$lsbd), -- "bstrpick.d", "$rd, $rj, $msbd, $lsbd">; -- --// Common Memory Access Instructions for 64-bits --def LD_WU : LOAD_2RI12<0b0010101010, "ld.wu">; --def LD_D : LOAD_2RI12<0b0010100011, "ld.d">; --def ST_D : STORE_2RI12<0b0010100111, "st.d">; --def LDX_B : LOAD_3R<0b00111000000000000, "ldx.b">; --def LDX_H : LOAD_3R<0b00111000000001000, "ldx.h">; --def LDX_W : LOAD_3R<0b00111000000010000, "ldx.w">; --def LDX_D : LOAD_3R<0b00111000000011000, "ldx.d">; --def LDX_BU : LOAD_3R<0b00111000001000000, "ldx.bu">; --def LDX_HU : LOAD_3R<0b00111000001001000, "ldx.hu">; --def LDX_WU : LOAD_3R<0b00111000001010000, "ldx.wu">; --def STX_B : STORE_3R<0b00111000000100000, "stx.b">; --def STX_H : STORE_3R<0b00111000000101000, "stx.h">; --def STX_W : STORE_3R<0b00111000000110000, "stx.w">; --def STX_D : STORE_3R<0b00111000000111000, "stx.d">; --def LDPTR_W : LOAD_2RI14<0b00100100, "ldptr.w">; --def LDPTR_D : LOAD_2RI14<0b00100110, "ldptr.d">; --def STPTR_W : STORE_2RI14<0b00100101, "stptr.w">; --def STPTR_D : STORE_2RI14<0b00100111, "stptr.d">; --def PRELDX : FmtPRELDX<(outs), (ins uimm5:$imm5, GPR:$rj, GPR:$rk), "preldx", -- "$imm5, $rj, $rk">; -- --// Bound Check Memory Access Instructions --def LDGT_B : LOAD_3R<0b00111000011110000, "ldgt.b">; --def LDGT_H : LOAD_3R<0b00111000011110001, "ldgt.h">; --def LDGT_W : LOAD_3R<0b00111000011110010, "ldgt.w">; --def LDGT_D : LOAD_3R<0b00111000011110011, "ldgt.d">; --def LDLE_B : LOAD_3R<0b00111000011110100, "ldle.b">; --def LDLE_H : LOAD_3R<0b00111000011110101, "ldle.h">; --def LDLE_W : LOAD_3R<0b00111000011110110, "ldle.w">; --def LDLE_D : LOAD_3R<0b00111000011110111, "ldle.d">; --def STGT_B : STORE_3R<0b00111000011111000, "stgt.b">; --def STGT_H : STORE_3R<0b00111000011111001, "stgt.h">; --def STGT_W : STORE_3R<0b00111000011111010, "stgt.w">; --def STGT_D : STORE_3R<0b00111000011111011, "stgt.d">; --def STLE_B : STORE_3R<0b00111000011111100, "stle.b">; --def STLE_H : STORE_3R<0b00111000011111101, "stle.h">; --def STLE_W : STORE_3R<0b00111000011111110, "stle.w">; --def STLE_D : STORE_3R<0b00111000011111111, "stle.d">; -- --// Atomic Memory Access Instructions for 64-bits --def AMSWAP_W : AM_3R<0b00111000011000000, "amswap.w">; --def AMSWAP_D : AM_3R<0b00111000011000001, "amswap.d">; --def AMADD_W : AM_3R<0b00111000011000010, "amadd.w">; --def AMADD_D : AM_3R<0b00111000011000011, "amadd.d">; --def AMAND_W : AM_3R<0b00111000011000100, "amand.w">; --def AMAND_D : AM_3R<0b00111000011000101, "amand.d">; --def AMOR_W : AM_3R<0b00111000011000110, "amor.w">; --def AMOR_D : AM_3R<0b00111000011000111, "amor.d">; --def AMXOR_W : AM_3R<0b00111000011001000, "amxor.w">; --def AMXOR_D : AM_3R<0b00111000011001001, "amxor.d">; --def AMMAX_W : AM_3R<0b00111000011001010, "ammax.w">; --def AMMAX_D : AM_3R<0b00111000011001011, "ammax.d">; --def AMMIN_W : AM_3R<0b00111000011001100, "ammin.w">; --def AMMIN_D : AM_3R<0b00111000011001101, "ammin.d">; --def AMMAX_WU : AM_3R<0b00111000011001110, "ammax.wu">; --def AMMAX_DU : AM_3R<0b00111000011001111, "ammax.du">; --def AMMIN_WU : AM_3R<0b00111000011010000, "ammin.wu">; --def AMMIN_DU : AM_3R<0b00111000011010001, "ammin.du">; --def AMSWAP_DB_W : AM_3R<0b00111000011010010, "amswap_db.w">; --def AMSWAP_DB_D : AM_3R<0b00111000011010011, "amswap_db.d">; --def AMADD_DB_W : AM_3R<0b00111000011010100, "amadd_db.w">; --def AMADD_DB_D : AM_3R<0b00111000011010101, "amadd_db.d">; --def AMAND_DB_W : AM_3R<0b00111000011010110, "amand_db.w">; --def AMAND_DB_D : AM_3R<0b00111000011010111, "amand_db.d">; --def AMOR_DB_W : AM_3R<0b00111000011011000, "amor_db.w">; --def AMOR_DB_D : AM_3R<0b00111000011011001, "amor_db.d">; --def AMXOR_DB_W : AM_3R<0b00111000011011010, "amxor_db.w">; --def AMXOR_DB_D : AM_3R<0b00111000011011011, "amxor_db.d">; --def AMMAX_DB_W : AM_3R<0b00111000011011100, "ammax_db.w">; --def AMMAX_DB_D : AM_3R<0b00111000011011101, "ammax_db.d">; --def AMMIN_DB_W : AM_3R<0b00111000011011110, "ammin_db.w">; --def AMMIN_DB_D : AM_3R<0b00111000011011111, "ammin_db.d">; --def AMMAX_DB_WU : AM_3R<0b00111000011100000, "ammax_db.wu">; --def AMMAX_DB_DU : AM_3R<0b00111000011100001, "ammax_db.du">; --def AMMIN_DB_WU : AM_3R<0b00111000011100010, "ammin_db.wu">; --def AMMIN_DB_DU : AM_3R<0b00111000011100011, "ammin_db.du">; --def LL_D : LLBase<0b00100010, "ll.d">; --def SC_D : SCBase<0b00100011, "sc.d">; -- --// CRC Check Instructions --def CRC_W_B_W : ALU_3R<0b00000000001001000, "crc.w.b.w">; --def CRC_W_H_W : ALU_3R<0b00000000001001001, "crc.w.h.w">; --def CRC_W_W_W : ALU_3R<0b00000000001001010, "crc.w.w.w">; --def CRC_W_D_W : ALU_3R<0b00000000001001011, "crc.w.d.w">; --def CRCC_W_B_W : ALU_3R<0b00000000001001100, "crcc.w.b.w">; --def CRCC_W_H_W : ALU_3R<0b00000000001001101, "crcc.w.h.w">; --def CRCC_W_W_W : ALU_3R<0b00000000001001110, "crcc.w.w.w">; --def CRCC_W_D_W : ALU_3R<0b00000000001001111, "crcc.w.d.w">; -- --// Other Miscellaneous Instructions for 64-bits --def ASRTLE_D : FmtASRT<0b00000000000000010, (outs), (ins GPR:$rj, GPR:$rk), -- "asrtle.d", "$rj, $rk">; --def ASRTGT_D : FmtASRT<0b00000000000000011, (outs), (ins GPR:$rj, GPR:$rk), -- "asrtgt.d", "$rj, $rk">; --def RDTIME_D : RDTIME_2R<0b0000000000000000011010, "rdtime.d">; --} // Predicates = [IsLA64] -+def : LoongArchPat<(LoongArchTailCall texternalsym:$dst), -+ (PseudoTailCall texternalsym:$dst)>; - --//===----------------------------------------------------------------------===// --// Pseudo-instructions and codegen patterns --// --// Naming convention: For 'generic' pattern classes, we use the naming --// convention PatTy1Ty2. --//===----------------------------------------------------------------------===// -+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)>; - --/// 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 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)>; -- --/// 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)))>; -- --let Predicates = [IsLA32] in { --def : PatGprGpr; --def : PatGprImm; --def : PatGprGpr; --def : PatGprGpr; --def : PatGprGpr; --def : PatGprGpr; --def : PatGprGpr; --def : PatGprGpr; --def : PatGprGpr; --def : PatGprGpr; --} // 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; --// 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)>; --} // Predicates = [IsLA64] -- --def : PatGprGpr; --def : PatGprImm; --def : PatGprGpr; --def : PatGprImm; --def : PatGprGpr; --def : PatGprImm; -- --/// 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, 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)>; -- --let isBarrier = 1, isBranch = 1, isTerminator = 1 in --def PseudoBR : Pseudo<(outs), (ins simm26_lsl2:$imm26), [(br bb:$imm26)]>, -- PseudoInstExpansion<(B simm26_lsl2:$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)>; -- --let isCall = 1, Defs = [R1] in --def PseudoCALL : Pseudo<(outs), (ins call_symbol:$func), []> { -- let AsmString = "bl\t$func"; --} -- --def : Pat<(loongarch_call tglobaladdr:$func), (PseudoCALL tglobaladdr:$func)>; --def : Pat<(loongarch_call texternalsym:$func), (PseudoCALL texternalsym:$func)>; -- --let isCall = 1, Defs = [R1] in --def PseudoCALLIndirect : Pseudo<(outs), (ins GPR:$rj), -- [(loongarch_call GPR:$rj)]>, -- PseudoInstExpansion<(JIRL R1, GPR:$rj, 0)>; -- --let isBarrier = 1, isReturn = 1, isTerminator = 1 in --def PseudoRET : Pseudo<(outs), (ins), [(loongarch_ret)]>, -- PseudoInstExpansion<(JIRL R0, R1, 0)>; -- --/// 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] -- --/// Loads -- --multiclass LdPat { -- def : Pat<(vt (LoadOp BaseAddr:$rj)), (Inst BaseAddr:$rj, 0)>; -- def : Pat<(vt (LoadOp (add 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] -- --/// Stores -- --multiclass StPat { -- def : Pat<(StoreOp (vt StTy:$rd), BaseAddr:$rj), -- (Inst StTy:$rd, BaseAddr:$rj, 0)>; -- def : Pat<(StoreOp (vt StTy:$rd), (add 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] -- --/// Atomic loads and stores -- --def : Pat<(atomic_fence timm, timm), (DBAR 0)>; -- --defm : LdPat; --defm : LdPat; --defm : LdPat; -- --defm : StPat; --defm : StPat; --defm : StPat, Requires<[IsLA32]>; --let Predicates = [IsLA64] in { --defm : LdPat; --defm : StPat; --defm : StPat; --} // 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] - --//===----------------------------------------------------------------------===// --// Assembler Pseudo Instructions --//===----------------------------------------------------------------------===// -+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; -+ def ATOMIC_CMP_SWAP_I64 : AtomicCmpSwap; -+ -+ 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 addr:$a, GPR64:$v), -+ (ST_B GPR64:$v, addr:$a)>, GPR_64; -+def : LoongArchPat<(atomic_store_16 addr:$a, GPR64:$v), -+ (ST_H GPR64:$v, addr:$a)>, GPR_64; -+def : LoongArchPat<(atomic_store_32 addrimm14lsl2:$a, GPR64:$v), -+ (STPTR_W GPR64:$v, addrimm14lsl2:$a)>, GPR_64; -+def : LoongArchPat<(atomic_store_32 addr:$a, GPR64:$v), -+ (ST_W GPR64:$v, addr:$a)>, GPR_64; -+def : LoongArchPat<(atomic_store_64 addrimm14lsl2:$a, GPR64:$v), -+ (STPTR_D GPR64:$v, addrimm14lsl2:$a)>, GPR_64; -+def : LoongArchPat<(atomic_store_64 addr:$a, GPR64:$v), -+ (ST_D GPR64:$v, addr:$a)>, GPR_64; -+ -+def : LoongArchPat<(bswap GPR64:$rt), (REVH_D (REVB_4H GPR64:$rt))>; -+ -+def immZExt5 : ImmLeaf; - --def : InstAlias<"nop", (ANDI R0, R0, 0)>; --def : InstAlias<"move $dst, $src", (OR GPR:$dst, GPR:$src, R0)>; -+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 isMoveReg = 1, 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; -+} - - //===----------------------------------------------------------------------===// --// Basic Floating-Point Instructions -+// Base Extension Support - //===----------------------------------------------------------------------===// - --include "LoongArchFloat32InstrInfo.td" --include "LoongArchFloat64InstrInfo.td" -+include "LoongArch32InstrInfo.td" -+include "LoongArchInstrInfoF.td" -+include "LoongArchLSXInstrFormats.td" -+include "LoongArchLSXInstrInfo.td" -+include "LoongArchLASXInstrFormats.td" -+include "LoongArchLASXInstrInfo.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_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>; -+} - - //===----------------------------------------------------------------------===// --// Privilege Instructions -+// Assembler Pseudo Instructions - //===----------------------------------------------------------------------===// -- --// CSR Access Instructions --def CSRRD : FmtCSR<0b0000010000000, (outs GPR:$rd), (ins uimm14:$csr_num), -- "csrrd", "$rd, $csr_num">; --let Constraints = "$rd = $dst" in { --def CSRWR : FmtCSR<0b0000010000001, (outs GPR:$dst), -- (ins GPR:$rd, uimm14:$csr_num), "csrwr", "$rd, $csr_num">; --def CSRXCHG : FmtCSRXCHG<0b00000100, (outs GPR:$dst), -- (ins GPR:$rd, GPR:$rj, uimm14:$csr_num), -- "csrxchg", "$rd, $rj, $csr_num">; --} // Constraints = "$rd = $dst" -- --// IOCSR Access Instructions --def IOCSRRD_B : IOCSRRD<0b0000011001001000000000, "iocsrrd.b">; --def IOCSRRD_H : IOCSRRD<0b0000011001001000000001, "iocsrrd.h">; --def IOCSRRD_W : IOCSRRD<0b0000011001001000000010, "iocsrrd.w">; --def IOCSRWR_B : IOCSRWR<0b0000011001001000000100, "iocsrwr.b">; --def IOCSRWR_H : IOCSRWR<0b0000011001001000000101, "iocsrwr.h">; --def IOCSRWR_W : IOCSRWR<0b0000011001001000000110, "iocsrwr.w">; --let Predicates = [IsLA64] in { --def IOCSRRD_D : IOCSRRD<0b0000011001001000000011, "iocsrrd.d">; --def IOCSRWR_D : IOCSRWR<0b0000011001001000000111, "iocsrwr.d">; --} // Predicates = [IsLA64] -- --// Cache Maintenance Instructions --def CACOP : FmtCACOP<(outs), (ins uimm5:$op, GPR:$rj, simm12:$imm12), "cacop", -- "$op, $rj, $imm12">; -- --// TLB Maintenance Instructions --def TLBSRCH : FmtI32<0b00000110010010000010100000000000, "tlbsrch">; --def TLBRD : FmtI32<0b00000110010010000010110000000000, "tlbrd">; --def TLBWR : FmtI32<0b00000110010010000011000000000000, "tlbwr">; --def TLBFILL : FmtI32<0b00000110010010000011010000000000, "tlbfill">; --def TLBCLR : FmtI32<0b00000110010010000010000000000000, "tlbclr">; --def TLBFLUSH : FmtI32<0b00000110010010000010010000000000, "tlbflush">; --def INVTLB : FmtINVTLB<(outs), (ins GPR:$rk, GPR:$rj, uimm5:$op), "invtlb", -- "$op, $rj, $rk">; -- --// Software Page Walking Instructions --def LDDIR : Fmt2RI8<0b00000110010000, (outs GPR:$rd), -- (ins GPR:$rj, uimm8:$imm8), "lddir", "$rd, $rj, $imm8">; --def LDPTE : FmtLDPTE<(outs), (ins GPR:$rj, uimm8:$seq), "ldpte", "$rj, $seq">; -- -- --// Other Miscellaneous Instructions --def ERTN : FmtI32<0b00000110010010000011100000000000, "ertn">; --def DBCL : MISC_I15<0b00000000001010101, "dbcl">; --def IDLE : MISC_I15<0b00000110010010001, "idle">; -+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/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchInstrInfoF.td b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchInstrInfoF.td -new file mode 100644 -index 000000000..4df5fc88e ---- /dev/null -+++ b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchInstrInfoF.td -@@ -0,0 +1,630 @@ -+//===- 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 FRSQRT_S : Float_Reg2_Frsqrt<"frsqrt.s", FGR32Opnd, fdiv>, R2F<0b0100011001>; -+def FRSQRT_D : Float_Reg2_Frsqrt<"frsqrt.d", FGR64Opnd, fdiv>, R2F<0b0100011010>; -+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)>; -diff --git a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchLASXInstrFormats.td b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchLASXInstrFormats.td -new file mode 100644 -index 000000000..8e255f857 ---- /dev/null -+++ b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchLASXInstrFormats.td -@@ -0,0 +1,448 @@ -+//===- LoongArchLASXInstrFormats.td - LoongArch LASX Instruction Formats ---*- tablegen -*-===// -+// -+// The LLVM Compiler Infrastructure -+// -+// This file is distributed under the University of Illinois Open Source -+// License. See LICENSE.TXT for details. -+// -+//===----------------------------------------------------------------------===// -+ -+class LASXInst : InstLA<(outs), (ins), "", [], FrmOther>, -+ EXT_LASX { -+} -+ -+class LASXCBranch : LASXInst { -+} -+ -+class LASXSpecial : LASXInst { -+} -+ -+class LASXPseudo pattern>: -+ LoongArchPseudo { -+ let Predicates = [HasLASX]; -+} -+ -+class LASX_3R op>: LASXInst { -+ bits<5> xk; -+ bits<5> xj; -+ bits<5> xd; -+ -+ let Inst{31-15} = op; -+ let Inst{14-10} = xk; -+ let Inst{9-5} = xj; -+ let Inst{4-0} = xd; -+} -+ -+class LASX_4R op>: LASXInst { -+ bits<5> xa; -+ bits<5> xk; -+ bits<5> xj; -+ bits<5> xd; -+ -+ 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 LASX_XVFCMP op>: LASXInst { -+ bits<5> xd; -+ bits<5> xj; -+ bits<5> xk; -+ bits<5> cond; -+ -+ let Inst{31-20} = op; -+ let Inst{19-15} = cond; -+ let Inst{14-10} = xk; -+ let Inst{9-5} = xj; -+ let Inst{4-0} = xd; -+} -+ -+class LASX_I12_S op>: LASXInst { -+ bits<5> xd; -+ bits<17> addr; -+ -+ 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 LASX_SI12_S op>: LASXInst { -+ bits<5> xd; -+ bits<17> addr; -+ -+ 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 LASX_SI11_S op>: LASXInst { -+ bits<5> xd; -+ bits<16> addr; -+ -+ 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 LASX_SI10_S op>: LASXInst { -+ bits<5> xd; -+ bits<15> addr; -+ -+ let Inst{31-20} = op; -+ let Inst{19-10} = addr{9-0}; -+ let Inst{9-5} = addr{14-10}; -+ let Inst{4-0} = xd; -+} -+ -+class LASX_SI9_S op>: LASXInst { -+ bits<5> xd; -+ bits<14> addr; -+ -+ 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 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-20} = op; -+ let Inst{19-18} = idx; -+ let Inst{17-10} = si8; -+ let Inst{9-5} = rj; -+ let Inst{4-0} = xd; -+} -+ -+class LASX_SI8_idx3 op>: LASXInst { -+ bits<5> xd; -+ bits<5> rj; -+ bits<8> si8; -+ bits<3> idx; -+ -+ 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; -+} -+ -+class LASX_SI8_idx4 op>: LASXInst { -+ bits<5> xd; -+ bits<5> rj; -+ bits<8> si8; -+ bits<4> idx; -+ -+ 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 LASX_3R_2GP op>: LASXInst { -+ bits<5> rk; -+ bits<5> rj; -+ bits<5> xd; -+ -+ let Inst{31-15} = op; -+ let Inst{14-10} = rk; -+ let Inst{9-5} = rj; -+ let Inst{4-0} = xd; -+} -+ -+class LASX_3R_1GP op>: LASXInst { -+ bits<5> rk; -+ bits<5> xj; -+ bits<5> xd; -+ -+ let Inst{31-15} = op; -+ let Inst{14-10} = rk; -+ let Inst{9-5} = xj; -+ let Inst{4-0} = xd; -+} -+ -+class LASX_I5 op>: LASXInst { -+ bits<5> xd; -+ bits<5> xj; -+ bits<5> si5; -+ -+ let Inst{31-15} = op; -+ let Inst{14-10} = si5; -+ let Inst{9-5} = xj; -+ let Inst{4-0} = xd; -+} -+ -+class LASX_I5_U op>: LASXInst { -+ bits<5> xd; -+ bits<5> xj; -+ bits<5> ui5; -+ -+ let Inst{31-15} = op; -+ let Inst{14-10} = ui5; -+ let Inst{9-5} = xj; -+ let Inst{4-0} = xd; -+} -+ -+class LASX_I5_mode_U op>: LASXInst { -+ bits<5> xd; -+ bits<5> mode; -+ bits<5> ui5; -+ -+ let Inst{31-15} = op; -+ let Inst{14-10} = ui5; -+ let Inst{9-5} = mode; -+ let Inst{4-0} = xd; -+} -+ -+class LASX_2R op>: LASXInst { -+ bits<5> xj; -+ bits<5> xd; -+ -+ let Inst{31-10} = op; -+ let Inst{9-5} = xj; -+ let Inst{4-0} = xd; -+} -+ -+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-10} = op; -+ let Inst{9-5} = rj; -+ let Inst{4-0} = xd; -+} -+ -+class LASX_I3_U op>: LASXInst { -+ bits<5> xd; -+ 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} = xd; -+} -+ -+class LASX_I4_U op>: LASXInst { -+ bits<5> xd; -+ bits<5> xj; -+ bits<4> ui4; -+ -+ let Inst{31-14} = op; -+ let Inst{13-10} = ui4; -+ let Inst{9-5} = xj; -+ let Inst{4-0} = xd; -+} -+ -+class LASX_I6_U op>: LASXInst { -+ bits<5> xd; -+ bits<5> xj; -+ bits<6> ui6; -+ -+ let Inst{31-16} = op; -+ let Inst{15-10} = ui6; -+ let Inst{9-5} = xj; -+ let Inst{4-0} = xd; -+} -+ -+class LASX_I2_R_U op>: LASXInst { -+ bits<5> xd; -+ bits<5> rj; -+ bits<2> ui2; -+ -+ let Inst{31-12} = op; -+ let Inst{11-10} = ui2; -+ let Inst{9-5} = rj; -+ let Inst{4-0} = xd; -+} -+ -+class LASX_I3_R_U op>: LASXInst { -+ bits<5> xd; -+ bits<5> rj; -+ bits<3> ui3; -+ -+ let Inst{31-13} = op; -+ let Inst{12-10} = ui3; -+ let Inst{9-5} = rj; -+ let Inst{4-0} = xd; -+} -+ -+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-11} = op; -+ let Inst{10} = ui1; -+ let Inst{9-5} = xj; -+ let Inst{4-0} = xd; -+} -+ -+class LASX_I2_U op>: LASXInst { -+ bits<5> xd; -+ 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} = xd; -+} -+ -+class LASX_I7_U op>: LASXInst { -+ bits<5> xd; -+ bits<5> xj; -+ bits<7> ui7; -+ -+ let Inst{31-17} = op; -+ let Inst{16-10} = ui7; -+ let Inst{9-5} = xj; -+ let Inst{4-0} = xd; -+} -+ -+class LASX_1R_I13 op>: LASXInst { -+ bits<13> i13; -+ bits<5> xd; -+ -+ 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 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-14} = op; -+ let Inst{13-10} = ui4; -+ let Inst{9-5} = rj; -+ let Inst{4-0} = xd; -+} -+ -+class LASX_ELM_COPY_B op>: LASXInst { -+ bits<5> rd; -+ bits<5> xj; -+ bits<4> ui4; -+ -+ 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/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td -new file mode 100644 -index 000000000..2677a79fa ---- /dev/null -+++ b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td -@@ -0,0 +1,5673 @@ -+//===- LoongArchLASXInstrInfo.td - loongson LASX instructions -*- tablegen ------------*-=// -+// -+// The LLVM Compiler Infrastructure -+// -+// This file is distributed under the University of Illinois Open Source -+// License. See LICENSE.TXT for details. -+// -+//===----------------------------------------------------------------------===// -+// -+// 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>; -+ -+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))]; -+} -+ -+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))]; -+} -+ -+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 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"; -+} -+ -+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"; -+} -+ -+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"; -+} -+ -+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:$xk, ROXK:$xj))]; -+} -+ -+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_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 (TyNode (load Addr:$addr))))]; -+ string DecoderMethod = "DecodeLASX256memlsl"; -+} -+ -+ -+def XVLDREPL_B : LASX_SI12_S<0b0011001010>, -+ LASX_LD_DESC_BASE<"xvldrepl.b", xvbroadcast_v32i8, v32i8, LASX256BOpnd>; -+ -+def XVLDREPL_H : LASX_SI11_S<0b00110010010>, -+ LASX_LD_DESC_BASE<"xvldrepl.h", xvbroadcast_v16i16, v16i16, LASX256HOpnd, mem_simm11_lsl1, addrimm11lsl1>; -+ -+def XVLDREPL_W : LASX_SI10_S<0b001100100010>, -+ LASX_LD_DESC_BASE<"xvldrepl.w", xvbroadcast_v8i32, v8i32, LASX256WOpnd, mem_simm10_lsl2, addrimm10lsl2>; -+ -+def XVLDREPL_D : LASX_SI9_S<0b0011001000010>, -+ LASX_LD_DESC_BASE<"xvldrepl.d", xvbroadcast_v4i64, 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 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 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", xvbroadcast_v4i64, 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)>; -+ -+ -+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<(sra -+ (v32i8 (add -+ (v32i8 (add (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) -+ )), -+ (v32i8 (add LASX256B:$a, LASX256B:$b)) -+ )), -+ (v32i8 (srl -+ (v32i8 ( add (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) -+ )), -+ (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) -+ ))), -+ (XVAVGR_B (v32i8 LASX256B:$a), (v32i8 LASX256B:$b))>; -+ -+ -+def : LASXPat<(sra -+ (v16i16 (add -+ (v16i16 (add (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) -+ )), -+ (v16i16 (add LASX256H:$a, LASX256H:$b)) -+ )), -+ (v16i16 (srl -+ (v16i16 (add (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) -+ )), -+ (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) -+ ))), -+ (XVAVGR_H (v16i16 LASX256H:$a), (v16i16 LASX256H:$b))>; -+ -+ -+def : LASXPat<(sra -+ (v8i32 (add -+ (v8i32 (add (v8i32 ( -+ build_vector (i32 1),(i32 1),(i32 1),(i32 1), -+ (i32 1),(i32 1),(i32 1),(i32 1) -+ )), -+ (v8i32 (add LASX256W:$a, LASX256W:$b)) -+ )), -+ (v8i32 (srl -+ (v8i32 (add (v8i32 ( -+ build_vector (i32 1),(i32 1),(i32 1),(i32 1), -+ (i32 1),(i32 1),(i32 1),(i32 1) -+ )), -+ (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)))), -+ (XVAVGR_W (v8i32 LASX256W:$a), (v8i32 LASX256W:$b))>; -+ -+def : LASXPat<(sra -+ (v4i64 (add -+ (v4i64 (add (v4i64 ( -+ build_vector (i64 1),(i64 1),(i64 1),(i64 1) -+ )), -+ (v4i64 (add LASX256D:$a, LASX256D:$b)) -+ )), -+ (v4i64 (srl -+ (v4i64 (add (v4i64 ( -+ build_vector (i64 1),(i64 1),(i64 1),(i64 1) -+ )), -+ (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)))), -+ (XVAVGR_D (v4i64 LASX256D:$a), (v4i64 LASX256D:$b))>; -+ -+ -+ -+def : LASXPat<(srl -+ (v32i8 (add (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) -+ )), -+ (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)) -+ ) -+ ), -+ (XVAVGR_BU (v32i8 LASX256B:$a), (v32i8 LASX256B:$b))>; -+ -+def : LASXPat<(srl -+ (v16i16 (add (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) -+ )), -+ (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)) -+ ) -+ ), -+ (XVAVGR_HU (v16i16 LASX256H:$a), (v16i16 LASX256H:$b))>; -+ -+def : LASXPat<(srl -+ (v8i32 (add (v8i32 ( -+ build_vector (i32 1),(i32 1),(i32 1),(i32 1), -+ (i32 1),(i32 1),(i32 1),(i32 1) -+ )), -+ (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)) -+ ) -+ ), -+ (XVAVGR_WU (v8i32 LASX256W:$a), (v8i32 LASX256W:$b))>; -+ -+def : LASXPat<(srl -+ (v4i64 (add (v4i64 ( -+ build_vector (i64 1),(i64 1),(i64 1),(i64 1) -+ )), -+ (v4i64 (add LASX256D:$a, LASX256D:$b)) -+ )), -+ (v4i64 (build_vector (i64 1),(i64 1),(i64 1),(i64 1)) -+ ) -+ ), -+ (XVAVGR_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 (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))>; -diff --git a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchLSXInstrFormats.td b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchLSXInstrFormats.td -new file mode 100644 -index 000000000..50df4d724 ---- /dev/null -+++ b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchLSXInstrFormats.td -@@ -0,0 +1,449 @@ -+//===- LoongArchLSXInstrFormats.td - LoongArch LSX Instruction Formats ---*- tablegen -*-===// -+// -+// The LLVM Compiler Infrastructure -+// -+// This file is distributed under the University of Illinois Open Source -+// License. See LICENSE.TXT for details. -+// -+//===----------------------------------------------------------------------===// -+ -+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-15} = op; -+ let Inst{14-10} = vk; -+ let Inst{9-5} = vj; -+ let Inst{4-0} = vd; -+} -+ -+class LSX_3R_1GP op>: LSXInst { -+ bits<5> rk; -+ bits<5> vj; -+ bits<5> vd; -+ -+ let Inst{31-15} = op; -+ let Inst{14-10} = rk; -+ let Inst{9-5} = vj; -+ let Inst{4-0} = vd; -+} -+ -+class LSX_I5 op>: LSXInst { -+ bits<5> vd; -+ bits<5> vj; -+ bits<5> si5; -+ -+ let Inst{31-15} = op; -+ let Inst{14-10} = si5; -+ let Inst{9-5} = vj; -+ let Inst{4-0} = vd; -+} -+ -+class LSX_I5_U op>: LSXInst { -+ bits<5> vd; -+ bits<5> vj; -+ bits<5> ui5; -+ -+ let Inst{31-15} = op; -+ let Inst{14-10} = ui5; -+ let Inst{9-5} = vj; -+ let Inst{4-0} = vd; -+} -+ -+class LSX_2R op>: LSXInst { -+ bits<5> vj; -+ bits<5> vd; -+ -+ let Inst{31-10} = op; -+ let Inst{9-5} = vj; -+ let Inst{4-0} = vd; -+} -+ -+class LSX_2R_1GP op>: LSXInst { -+ bits<5> rj; -+ bits<5> vd; -+ -+ let Inst{31-10} = op; -+ let Inst{9-5} = rj; -+ let Inst{4-0} = vd; -+} -+ -+class LSX_I1_U op>: LSXInst { -+ bits<5> vd; -+ bits<5> vj; -+ bits<1> ui1; -+ -+ let Inst{31-11} = op; -+ let Inst{10} = ui1; -+ let Inst{9-5} = vj; -+ let Inst{4-0} = vd; -+} -+ -+class LSX_I2_U op>: LSXInst { -+ bits<5> vd; -+ bits<5> vj; -+ bits<2> ui2; -+ -+ let Inst{31-12} = op; -+ let Inst{11-10} = ui2; -+ let Inst{9-5} = vj; -+ let Inst{4-0} = vd; -+} -+ -+class LSX_I3_U op>: LSXInst { -+ bits<5> vd; -+ bits<5> vj; -+ bits<3> ui3; -+ -+ let Inst{31-13} = op; -+ let Inst{12-10} = ui3; -+ let Inst{9-5} = vj; -+ let Inst{4-0} = vd; -+} -+ -+class LSX_I4_U op>: LSXInst { -+ bits<5> vd; -+ 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} = vd; -+} -+ -+class LSX_I6_U op>: LSXInst { -+ bits<5> vd; -+ bits<5> vj; -+ bits<6> ui6; -+ -+ let Inst{31-16} = op; -+ let Inst{15-10} = ui6; -+ let Inst{9-5} = vj; -+ let Inst{4-0} = vd; -+} -+ -+class LSX_I1_R_U op>: LSXInst { -+ bits<5> vd; -+ bits<5> rj; -+ bits<1> ui1; -+ -+ let Inst{31-11} = op; -+ let Inst{10} = ui1; -+ let Inst{9-5} = rj; -+ let Inst{4-0} = vd; -+} -+ -+class LSX_I2_R_U op>: LSXInst { -+ bits<5> vd; -+ bits<5> rj; -+ bits<2> ui2; -+ -+ let Inst{31-12} = op; -+ let Inst{11-10} = ui2; -+ let Inst{9-5} = rj; -+ let Inst{4-0} = vd; -+} -+ -+class LSX_I3_R_U op>: LSXInst { -+ bits<5> vd; -+ bits<5> rj; -+ bits<3> ui3; -+ -+ let Inst{31-13} = op; -+ let Inst{12-10} = ui3; -+ let Inst{9-5} = rj; -+ let Inst{4-0} = vd; -+} -+ -+class LSX_I4_R_U op>: LSXInst { -+ bits<5> vd; -+ bits<5> rj; -+ bits<4> ui4; -+ -+ let Inst{31-14} = op; -+ let Inst{13-10} = ui4; -+ let Inst{9-5} = rj; -+ let Inst{4-0} = vd; -+} -+ -+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-13} = op; -+ let Inst{12-10} = ui3; -+ let Inst{9-5} = vj; -+ let Inst{4-0} = rd; -+} -+ -+class LSX_ELM_COPY_W op>: LSXInst { -+ bits<5> rd; -+ bits<5> vj; -+ bits<2> ui2; -+ -+ let Inst{31-12} = op; -+ let Inst{11-10} = ui2; -+ let Inst{9-5} = vj; -+ let Inst{4-0} = rd; -+} -+ -+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-18} = op; -+ let Inst{17-10} = ui8; -+ let Inst{9-5} = vj; -+ let Inst{4-0} = vd; -+} -+ -+class LSX_I7_U op>: LSXInst { -+ bits<5> vd; -+ bits<5> vj; -+ bits<7> ui7; -+ -+ let Inst{31-17} = op; -+ let Inst{16-10} = ui7; -+ let Inst{9-5} = vj; -+ let Inst{4-0} = vd; -+} -+ -+class LSX_I12_S op>: LSXInst { -+ bits<5> vd; -+// bits<5> rj; -+// bits<12> si12; -+ bits<17> addr; -+ -+ let Inst{31-22} = op; -+ let Inst{21-10} = addr{11-0}; -+ let Inst{9-5} = addr{16-12}; -+ let Inst{4-0} = vd; -+} -+ -+class LSX_SI12_S op>: LSXInst { -+ bits<5> vd; -+ bits<17> addr; -+ -+ let Inst{31-22} = op; -+ let Inst{21-10} = addr{11-0}; -+ let Inst{9-5} = addr{16-12}; -+ let Inst{4-0} = vd; -+} -+ -+class LSX_SI11_S op>: LSXInst { -+ bits<5> vd; -+ bits<16> addr; -+ -+ let Inst{31-21} = op; -+ let Inst{20-10} = addr{10-0}; -+ let Inst{9-5} = addr{15-11}; -+ let Inst{4-0} = vd; -+} -+ -+class LSX_SI10_S op>: LSXInst { -+ bits<5> vd; -+ bits<15> addr; -+ -+ let Inst{31-20} = op; -+ let Inst{19-10} = addr{9-0}; -+ let Inst{9-5} = addr{14-10}; -+ let Inst{4-0} = vd; -+} -+ -+class LSX_SI9_S op>: LSXInst { -+ bits<5> vd; -+ bits<14> addr; -+ -+ let Inst{31-19} = op; -+ let Inst{18-10} = addr{8-0}; -+ let Inst{9-5} = addr{13-9}; -+ let Inst{4-0} = vd; -+} -+ -+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-20} = op; -+ let Inst{19-15} = va; -+ let Inst{14-10} = vk; -+ let Inst{9-5} = vj; -+ let Inst{4-0} = vd; -+} -+ -+class LSX_VFCMP op>: LSXInst { -+ bits<5> vd; -+ bits<5> vj; -+ bits<5> vk; -+ bits<5> cond; -+ -+ 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; -+} -+ -+class LSX_Addr_SI8_idx1 op>: LSXInst { -+ bits<5> vd; -+ 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} = vd; -+} -+ -+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-20} = op; -+ let Inst{19-18} = idx; -+ let Inst{17-10} = si8; -+ let Inst{9-5} = rj; -+ let Inst{4-0} = vd; -+} -+ -+class LSX_SI8_idx3 op>: LSXInst { -+ bits<5> vd; -+ bits<5> rj; -+ bits<8> si8; -+ bits<3> idx; -+ -+ 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 LSX_SI8_idx4 op>: LSXInst { -+ bits<5> vd; -+ bits<5> rj; -+ bits<8> si8; -+ bits<4> idx; -+ -+ 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 LSX_3R_2GP op>: LSXInst { -+ bits<5> rk; -+ bits<5> rj; -+ bits<5> vd; -+ -+ let Inst{31-15} = op; -+ let Inst{14-10} = rk; -+ let Inst{9-5} = rj; -+ let Inst{4-0} = vd; -+} -+ -+class LSX_I5_mode_U op>: LSXInst { -+ bits<5> vd; -+ bits<5> mode; -+ bits<5> ui5; -+ -+ 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/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td -new file mode 100644 -index 000000000..3d0ea3901 ---- /dev/null -+++ b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td -@@ -0,0 +1,5906 @@ -+//===- LoongArchLSXInstrInfo.td - LSX instructions -*- tablegen ------------*-=// -+// -+// The LLVM Compiler Infrastructure -+// -+// This file is distributed under the University of Illinois Open Source -+// License. See LICENSE.TXT for details. -+// -+//===----------------------------------------------------------------------===// -+// -+// This file describes LoongArch LSX instructions. -+// -+//===----------------------------------------------------------------------===// -+ -+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>; -+ -+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; -+} -+ -+def Simm11Lsl1AsmOperand -+ : SimmLslAsmOperandClass<11, [], 1>; -+ -+def immSExt11_1_O : Operand { -+ let EncoderMethod = "getSImm11Lsl1Encoding"; -+ let DecoderMethod = "DecodeSImmWithOffsetAndScale<2>"; -+ let ParserMatchClass = Simm11Lsl1AsmOperand; -+} -+ -+def Simm10Lsl2AsmOperand -+ : SimmLslAsmOperandClass<10, [], 2>; -+ -+def immSExt10_2_O : Operand { -+ let EncoderMethod = "getSImm10Lsl2Encoding"; -+ let DecoderMethod = "DecodeSImmWithOffsetAndScale<4>"; -+ let ParserMatchClass = Simm10Lsl2AsmOperand; -+} -+ -+def Simm9Lsl3AsmOperand -+ : SimmLslAsmOperandClass<9, [], 3>; -+ -+def immSExt9_3_O : Operand { -+ let EncoderMethod = "getSImm9Lsl3Encoding"; -+ let DecoderMethod = "DecodeSImmWithOffsetAndScale<8>"; -+ let ParserMatchClass = Simm9Lsl3AsmOperand; -+} -+ -+def Simm8Lsl3AsmOperand -+ : SimmLslAsmOperandClass<8, [], 3>; -+ -+def immSExt8_3_O : Operand { -+ let EncoderMethod = "getSImm8Lsl3Encoding"; -+ let DecoderMethod = "DecodeSImmWithOffsetAndScale<8>"; -+ let ParserMatchClass = Simm8Lsl3AsmOperand; -+} -+ -+def Simm8Lsl2AsmOperand -+ : SimmLslAsmOperandClass<8, [], 2>; -+ -+def immSExt8_2_O : Operand { -+ let EncoderMethod = "getSImm8Lsl2Encoding"; -+ let DecoderMethod = "DecodeSImmWithOffsetAndScale<4>"; -+ let ParserMatchClass = Simm8Lsl2AsmOperand; -+} -+ -+def Simm8Lsl1AsmOperand -+ : SimmLslAsmOperandClass<8, [], 1>; -+ -+def immSExt8_1_O : Operand { -+ let EncoderMethod = "getSImm8Lsl1Encoding"; -+ let DecoderMethod = "DecodeSImmWithOffsetAndScale<2>"; -+ let ParserMatchClass = Simm8Lsl1AsmOperand; -+} -+ -+ -+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; -+} -+ -+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; -+} -+ -+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(); -+ -+ return selectVSplat(BV, Imm, EltTy.getSizeInBits()) && -+ Imm.getBitWidth() == EltTy.getSizeInBits() && Imm == 1; -+}]>; -+ -+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; -+ -+def vsplati32_uimm2 : SplatComplexPattern; -+ -+def vsplati32_uimm5 : SplatComplexPattern; -+ -+def vsplati32_simm5 : SplatComplexPattern; -+ -+def vsplati64_uimm1 : SplatComplexPattern; -+ -+def vsplati64_uimm5 : SplatComplexPattern; -+ -+def vsplati64_uimm6 : SplatComplexPattern; -+ -+def vsplati64_simm5 : SplatComplexPattern; -+ -+ -+// 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))>; -+ -+def mulsub : PatFrag<(ops node:$vd, node:$vj, node:$vk), -+ (sub node:$vd, (mul node:$vj, node:$vk))>; -+ -+class IsCommutable { -+ bit isCommutable = 1; -+} -+ -+ -+ -+//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))]; -+} -+ -+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"; -+} -+ -+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:$vk, ROVK:$vj))]; -+} -+ -+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 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 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 (TyNode (load Addr:$addr))))]; -+ string DecoderMethod = "DecodeLSX128memlsl"; -+} -+ -+def VLDREPL_B : LSX_SI12_S<0b0011000010>, -+ LSX_LD_DESC_BASE<"vldrepl.b", vldrepl_v16i8, v16i8, LSX128BOpnd>; -+ -+def VLDREPL_H : LSX_SI11_S<0b00110000010>, -+ LSX_LD_DESC_BASE<"vldrepl.h", vldrepl_v8i16, v8i16, LSX128HOpnd, mem_simm11_lsl1, addrimm11lsl1>; -+ -+def VLDREPL_W : LSX_SI10_S<0b001100000010>, -+ LSX_LD_DESC_BASE<"vldrepl.w", vldrepl_v4i32, v4i32, LSX128WOpnd, mem_simm10_lsl2, addrimm10lsl2>; -+ -+def VLDREPL_D : LSX_SI9_S<0b0011000000010>, -+ LSX_LD_DESC_BASE<"vldrepl.d", vldrepl_v2i64, 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)>; -+ -+ -+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<(sra -+ (v16i8 (add -+ (v16i8 (add (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) -+ )), -+ (v16i8 (add LSX128B:$a, LSX128B:$b)) -+ )), -+ (v16i8 (srl -+ (v16i8 ( add (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) -+ )), -+ (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) -+ ))), -+ (VAVGR_B (v16i8 LSX128B:$a), (v16i8 LSX128B:$b))>; -+ -+def : LSXPat<(sra -+ (v8i16 (add -+ (v8i16 (add (v8i16 ( -+ build_vector (i32 1),(i32 1),(i32 1),(i32 1), -+ (i32 1),(i32 1),(i32 1),(i32 1) -+ )), -+ (v8i16 (add LSX128H:$a, LSX128H:$b)) -+ )), -+ (v8i16 (srl -+ (v8i16 (add (v8i16 ( -+ build_vector (i32 1),(i32 1),(i32 1),(i32 1), -+ (i32 1),(i32 1),(i32 1),(i32 1) -+ )), -+ (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) -+ ))), -+ (VAVGR_H (v8i16 LSX128H:$a), (v8i16 LSX128H:$b))>; -+ -+def : LSXPat<(sra -+ (v4i32 (add -+ (v4i32 (add (v4i32 ( -+ build_vector (i32 1),(i32 1),(i32 1),(i32 1) -+ )), -+ (v4i32 (add LSX128W:$a, LSX128W:$b)) -+ )), -+ (v4i32 (srl -+ (v4i32 (add (v4i32 ( -+ build_vector (i32 1),(i32 1),(i32 1),(i32 1) -+ )), -+ (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)))), -+ (VAVGR_W (v4i32 LSX128W:$a), (v4i32 LSX128W:$b))>; -+ -+def : LSXPat<(sra -+ (v2i64 (add -+ (v2i64 (add (v2i64 ( -+ build_vector (i64 1),(i64 1) -+ )), -+ (v2i64 (add LSX128D:$a, LSX128D:$b)) -+ )), -+ (v2i64 (srl -+ (v2i64 (add (v2i64 ( -+ build_vector (i64 1),(i64 1) -+ )), -+ (v2i64 (add LSX128D:$a, LSX128D:$b)) -+ )), -+ (v2i64 (build_vector (i64 63),(i64 63))) -+ ) -+ ) -+ ) -+ ), -+ (v2i64 (build_vector (i64 1),(i64 1)))), -+ (VAVGR_D (v2i64 LSX128D:$a), (v2i64 LSX128D:$b))>; -+ -+ -+ -+ -+def : LSXPat<(srl -+ (v16i8 (add (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) -+ )), -+ (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)) -+ ) -+ ), -+ (VAVGR_BU (v16i8 LSX128B:$a), (v16i8 LSX128B:$b))>; -+ -+def : LSXPat<(srl -+ (v8i16 (add (v8i16 ( -+ build_vector (i32 1),(i32 1),(i32 1),(i32 1), -+ (i32 1),(i32 1),(i32 1),(i32 1) -+ )), -+ (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)) -+ ) -+ ), -+ (VAVGR_HU (v8i16 LSX128H:$a), (v8i16 LSX128H:$b))>; -+ -+def : LSXPat<(srl -+ (v4i32 (add (v4i32 ( -+ build_vector (i32 1),(i32 1),(i32 1),(i32 1) -+ )), -+ (v4i32 (add LSX128W:$a, LSX128W:$b)) -+ )), -+ (v4i32 (build_vector (i32 1),(i32 1),(i32 1),(i32 1)) -+ ) -+ ), -+ (VAVGR_WU (v4i32 LSX128W:$a), (v4i32 LSX128W:$b))>; -+ -+def : LSXPat<(srl -+ (v2i64 (add (v2i64 ( -+ build_vector (i64 1),(i64 1) -+ )), -+ (v2i64 (add LSX128D:$a, LSX128D:$b)) -+ )), -+ (v2i64 (build_vector (i64 1),(i64 1)) -+ ) -+ ), -+ (VAVGR_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/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp -index 488c66f47..bf70b09d4 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp -+++ b/src/llvm-project/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,86 +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 "llvm/CodeGen/AsmPrinter.h" -+#include "LoongArchMCInstLower.h" -+#include "MCTargetDesc/LoongArchBaseInfo.h" -+#include "MCTargetDesc/LoongArchMCExpr.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; -+LoongArchMCInstLower::LoongArchMCInstLower(LoongArchAsmPrinter &asmprinter) -+ : AsmPrinter(asmprinter) {} - -- // TODO: Processing target flags. -+void LoongArchMCInstLower::Initialize(MCContext *C) { -+ Ctx = C; -+} - -- const MCExpr *ME = -- MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Ctx); -+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; - -- if (!MO.isJTI() && !MO.isMBB() && MO.getOffset()) -- ME = MCBinaryExpr::createAdd( -- ME, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx); -+ switch(MO.getTargetFlags()) { -+ default: -+ 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_GOT_RRHIGHER: -+ TargetKind = LoongArchMCExpr::MEK_GOT_RRHIGHER; -+ break; -+ 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: -+ TargetKind = LoongArchMCExpr::MEK_PCREL_HI; -+ break; -+ case LoongArchII::MO_PCREL_LO: -+ 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_TLSIE_HI: -+ TargetKind = LoongArchMCExpr::MEK_TLSIE_HI; -+ break; -+ case LoongArchII::MO_TLSIE_LO: -+ TargetKind = LoongArchMCExpr::MEK_TLSIE_LO; -+ break; -+ case LoongArchII::MO_TLSIE_RRHI: -+ TargetKind = LoongArchMCExpr::MEK_TLSIE_RRHI; -+ break; -+ case LoongArchII::MO_TLSIE_RRHIGHER: -+ TargetKind = LoongArchMCExpr::MEK_TLSIE_RRHIGHER; -+ break; -+ case LoongArchII::MO_TLSIE_RRHIGHEST: -+ TargetKind = LoongArchMCExpr::MEK_TLSIE_RRHIGHEST; -+ break; -+ case LoongArchII::MO_TLSIE_RRLO: -+ TargetKind = LoongArchMCExpr::MEK_TLSIE_RRLO; -+ break; -+ case LoongArchII::MO_TLSLE_HI: -+ TargetKind = LoongArchMCExpr::MEK_TLSLE_HI; -+ break; -+ case LoongArchII::MO_TLSLE_HIGHER: -+ TargetKind = LoongArchMCExpr::MEK_TLSLE_HIGHER; -+ break; -+ case LoongArchII::MO_TLSLE_HIGHEST: -+ TargetKind = LoongArchMCExpr::MEK_TLSLE_HIGHEST; -+ break; -+ case LoongArchII::MO_TLSLE_LO: -+ TargetKind = LoongArchMCExpr::MEK_TLSLE_LO; -+ break; -+ case LoongArchII::MO_TLSGD_HI: -+ TargetKind = LoongArchMCExpr::MEK_TLSGD_HI; -+ break; -+ case LoongArchII::MO_TLSGD_LO: -+ TargetKind = LoongArchMCExpr::MEK_TLSGD_LO; -+ break; -+ case LoongArchII::MO_TLSGD_RRHI: -+ TargetKind = LoongArchMCExpr::MEK_TLSGD_RRHI; -+ break; -+ case LoongArchII::MO_TLSGD_RRHIGHER: -+ TargetKind = LoongArchMCExpr::MEK_TLSGD_RRHIGHER; -+ break; -+ case LoongArchII::MO_TLSGD_RRHIGHEST: -+ TargetKind = LoongArchMCExpr::MEK_TLSGD_RRHIGHEST; -+ break; -+ case LoongArchII::MO_TLSGD_RRLO: -+ TargetKind = LoongArchMCExpr::MEK_TLSGD_RRLO; -+ break; -+ 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; -+ } - -- return MCOperand::createExpr(ME); --} -+ switch (MOTy) { -+ case MachineOperand::MO_MachineBasicBlock: -+ Symbol = MO.getMBB()->getSymbol(); -+ break; -+ -+ case MachineOperand::MO_GlobalAddress: -+ Symbol = AsmPrinter.getSymbol(MO.getGlobal()); -+ Offset += MO.getOffset(); -+ break; -+ -+ 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; -- // TODO: lower special operands -- case MachineOperand::MO_BlockAddress: -- case MachineOperand::MO_JumpTableIndex: -+ case LoongArchII::MO_ABS_LO: -+ Kind = LoongArchMCExpr::MEK_ABS_LO; - break; -+ 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)); - } -- return true; - } - --bool llvm::lowerLoongArchMachineInstrToMCInst(const MachineInstr *MI, -- MCInst &OutMI, AsmPrinter &AP) { -+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; -+ } -+} -+ -+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/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchMCInstLower.h b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchMCInstLower.h -new file mode 100644 -index 000000000..6463a7b64 ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchMachineFunction.cpp b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchMachineFunction.cpp -new file mode 100644 -index 000000000..a9c52cbb1 ---- /dev/null -+++ b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchMachineFunction.cpp -@@ -0,0 +1,58 @@ -+//===-- 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/TargetRegisterInfo.h" -+#include "llvm/Support/CommandLine.h" -+ -+using namespace llvm; -+ -+LoongArchFunctionInfo::~LoongArchFunctionInfo() = default; -+ -+void LoongArchFunctionInfo::createEhDataRegsFI() { -+ 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(const char *ES) { -+ return MachinePointerInfo(MF.getPSVManager().getExternalSymbolCallEntry(ES)); -+} -+ -+MachinePointerInfo LoongArchFunctionInfo::callPtrInfo(const GlobalValue *GV) { -+ return MachinePointerInfo(MF.getPSVManager().getGlobalValueCallEntry(GV)); -+} -+ -+int LoongArchFunctionInfo::getMoveF64ViaSpillFI(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/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchMachineFunction.h b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchMachineFunction.h -new file mode 100644 -index 000000000..1765013ea ---- /dev/null -+++ b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchMachineFunction.h -@@ -0,0 +1,103 @@ -+//===- 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(MachineFunction &MF) : MF(MF) {} -+ -+ ~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(); -+ 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(const char *ES); -+ -+ /// Create a MachinePointerInfo that has a GlobalValuePseudoSourceValue object -+ /// representing a GOT entry for a global function. -+ MachinePointerInfo callPtrInfo(const GlobalValue *GV); -+ -+ void setSaveS2() { SaveS2 = true; } -+ bool hasSaveS2() const { return SaveS2; } -+ -+ int getMoveF64ViaSpillFI(const TargetRegisterClass *RC); -+ -+private: -+ virtual void anchor(); -+ -+ MachineFunction& MF; -+ -+ /// 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. -+ unsigned SRetReturnReg = 0; -+ -+ /// 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/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchMachineFunctionInfo.h b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchMachineFunctionInfo.h -deleted file mode 100644 -index d4a6c884b..000000000 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchMachineFunctionInfo.h -+++ /dev/null -@@ -1,57 +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; -- --public: -- LoongArchMachineFunctionInfo(const MachineFunction &MF) {} -- -- 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; } --}; -- --} // end namespace llvm -- --#endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHMACHINEFUNCTIONINFO_H -diff --git a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchModuleISelDAGToDAG.cpp b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchModuleISelDAGToDAG.cpp -new file mode 100644 -index 000000000..8dbf30f21 ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.cpp b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.cpp -index 05902ebb7..4d1a3cf22 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.cpp -+++ b/src/llvm-project/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,132 +6,352 @@ - // - //===----------------------------------------------------------------------===// - // --// 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 "LoongArchMachineFunction.h" - #include "LoongArchSubtarget.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"); -+} - -- 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(); - -- 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 < array_lengthof(ReservedGPR32); ++I) -+ Reserved.set(ReservedGPR32[I]); -+ -+ for (unsigned I = 0; I < array_lengthof(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; - } - --bool LoongArchRegisterInfo::isConstantPhysReg(MCRegister PhysReg) const { -- return PhysReg == LoongArch::R0; -+bool -+LoongArchRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const { -+ return true; - } - --Register --LoongArchRegisterInfo::getFrameRegister(const MachineFunction &MF) const { -- const TargetFrameLowering *TFI = getFrameLowering(MF); -- return TFI->hasFP(MF) ? LoongArch::R22 : LoongArch::R3; -+bool LoongArchRegisterInfo:: -+requiresFrameIndexScavenging(const MachineFunction &MF) const { -+ return true; - } - --void 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. -+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: { -+ unsigned ConstraintID = InlineAsm::getMemoryConstraintID(MO.getImm()); -+ switch (ConstraintID) { -+ case InlineAsm::Constraint_ZC: { -+ return 14 + 2 /* scale factor */; -+ } -+ default: -+ return 12; -+ } -+ } -+ default: -+ return 12; -+ } -+} - -- assert(SPAdj == 0 && "Unexpected non-zero SPAdj value"); -+/// 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. -+void LoongArchRegisterInfo:: -+eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, -+ unsigned FIOperandNum, RegScavenger *RS) const { - MachineInstr &MI = *II; - MachineFunction &MF = *MI.getParent()->getParent(); -- const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); -- DebugLoc DL = MI.getDebugLoc(); -+ 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()); - -- // Offsets must be encodable with a 12-bit immediate field. -- if (!isInt<12>(Offset.getFixed())) { -- report_fatal_error("Frame offsets outside of the signed 12-bit range is " -- "not supported currently"); -+ LLVM_DEBUG(errs() << "Location : " -+ << "FrameReg<" << FrameReg << "> + " << Offset.getFixed() -+ << "\n<--------->\n"); -+ -+ MachineBasicBlock &MBB = *MI.getParent(); -+ DebugLoc DL = II->getDebugLoc(); -+ bool IsKill = false; -+ -+ 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) -+ .addImm(Offset.getFixed()); -+ -+ 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); -+ -+ FrameReg = Reg; -+ Offset = StackOffset::getFixed(0); -+ IsKill = true; -+ } - } - -- MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false); -+ MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false, false, IsKill); - MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset.getFixed()); - } -+ -+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 LoongArchSubtarget &Subtarget = MF.getSubtarget(); -+ unsigned FP = Subtarget.is64Bit() ? LoongArch::FP_64 : LoongArch::FP; -+ unsigned BP = Subtarget.is64Bit() ? LoongArch::S7_64 : LoongArch::S7; -+ -+ // We can't perform dynamic stack realignment if we can't reserve the -+ // frame pointer register. -+ if (!MF.getRegInfo().canReserveReg(FP)) -+ return false; -+ -+ // 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; -+ -+ // We have to reserve the base pointer register in the presence of variable -+ // sized objects. -+ return MF.getRegInfo().canReserveReg(BP); -+} -diff --git a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.h b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.h -index cca130c3b..dd3be916a 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.h -+++ b/src/llvm-project/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,45 +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; -- bool isConstantPhysReg(MCRegister PhysReg) 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; - -- void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, -- unsigned FIOperandNum, -+ bool trackLivenessAfterRegAlloc(const MachineFunction &MF) const override; -+ -+ /// Stack Frame Processing Methods -+ void eliminateFrameIndex(MachineBasicBlock::iterator II, -+ 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; -+ -+ /// Return GPR register class. -+ const TargetRegisterClass *intRegClass(unsigned Size) const; -+ -+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/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.td b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.td -index 2d5ad99f6..96569e075 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.td -+++ b/src/llvm-project/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,155 +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 { -+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 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 -- : Register<""> { -- let HWEncoding = subreg.HWEncoding; -- let SubRegs = [subreg]; -+/// 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]; -- let AsmName = subreg.AsmName; -- let AltNames = subreg.AltNames; --} -- --let FallbackRegAltNameIndex = NoRegAltName in --def RegAliasName : RegAltNameIndex; --} // Namespace = "LoongArch" -- --// Integer registers -- --let RegAltNameIndices = [RegAliasName] 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; --} -- --// 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 -+} -+ -+/// 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]; -+} -+ -+// LoongArch 256-bit (aliased) LASX Registers -+class LASX256 Enc, string n, list subregs> -+ : LoongArchRegWithSubRegs { -+ let SubRegIndices = [sub_128]; -+} -+ -+//===----------------------------------------------------------------------===// -+// 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">; -+ -+//===----------------------------------------------------------------------===// -+// Register Classes -+//===----------------------------------------------------------------------===// -+ -+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 XR#I : LASX256("VR"#I)]>, -+ DwarfRegNum<[!add(I, 32)]>; -+ -+def LSX128B: RegisterClass<"LoongArch", [v16i8], 128, -+ (sequence "VR%u", 0, 31)>; -+ -+def LSX128H: RegisterClass<"LoongArch", [v8i16], 128, -+ (sequence "VR%u", 0, 31)>; -+ -+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. -+//===----------------------------------------------------------------------===// - --let isAllocatable = false in --def FCSR : RegisterClass<"LoongArch", [i32], 32, (sequence "FCSR%u", 0, 3)>; -+class LoongArchAsmRegOperand : AsmOperandClass { -+ let ParserMethod = "parseAnyRegister"; -+} -+ -+def GPR32AsmOperand : LoongArchAsmRegOperand { -+ let Name = "GPR32AsmReg"; -+ let PredicateMethod = "isGPRAsmReg"; -+} -+ -+def GPR64AsmOperand : LoongArchAsmRegOperand { -+ let Name = "GPR64AsmReg"; -+ let PredicateMethod = "isGPRAsmReg"; -+} -+ -+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/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchSubtarget.cpp b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchSubtarget.cpp -index ff84e7c8c..ef990ae09 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchSubtarget.cpp -+++ b/src/llvm-project/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,7 +11,16 @@ - //===----------------------------------------------------------------------===// - - #include "LoongArchSubtarget.h" --#include "LoongArchFrameLowering.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; - -@@ -23,32 +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 = Is64Bit ? "generic-la64" : "generic-la32"; -+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), -+ 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()); -+} -+ -+bool LoongArchSubtarget::isPositionIndependent() const { -+ return TM.isPositionIndependent(); -+} -+ -+/// This overrides the PostRAScheduler bit in the SchedModel for any CPU. -+bool LoongArchSubtarget::enablePostRAScheduler() const { return true; } - -- if (TuneCPU.empty()) -- TuneCPU = CPU; -+void LoongArchSubtarget::getCriticalPathRCs(RegClassVector &CriticalPathRCs) const { -+ CriticalPathRCs.clear(); -+ CriticalPathRCs.push_back(is64Bit() ? &LoongArch::GPR64RegClass -+ : &LoongArch::GPR32RegClass); -+} -+ -+CodeGenOpt::Level LoongArchSubtarget::getOptLevelToEnablePostRAScheduler() const { -+ return CodeGenOpt::Aggressive; -+} -+ -+LoongArchSubtarget & -+LoongArchSubtarget::initializeSubtargetDependencies(StringRef CPU, StringRef FS, -+ const TargetMachine &TM) { -+ StringRef CPUName = LoongArch_MC::selectLoongArchCPU(TM.getTargetTriple(), CPU); - -- ParseSubtargetFeatures(CPU, TuneCPU, FS); -- if (Is64Bit) { -- GRLenVT = MVT::i64; -- GRLen = 64; -+ // 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); - } - -- // TODO: ILP32{S,F} LP64{S,F} -- TargetABI = Is64Bit ? LoongArchABI::ABI_LP64D : LoongArchABI::ABI_ILP32D; - return *this; - } - --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) {} -+Reloc::Model LoongArchSubtarget::getRelocationModel() const { -+ return TM.getRelocationModel(); -+} -+ -+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/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchSubtarget.h b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchSubtarget.h -index fbe7a176b..588d9f46b 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchSubtarget.h -+++ b/src/llvm-project/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,16 @@ - #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" -+#include - - #define GET_SUBTARGETINFO_HEADER - #include "LoongArchGenSubtargetInfo.inc" -@@ -29,61 +30,114 @@ - namespace llvm { - class StringRef; - -+class LoongArchTargetMachine; -+ - class LoongArchSubtarget : public LoongArchGenSubtargetInfo { - virtual void anchor(); -- bool HasLA64 = false; -- bool HasBasicF = false; -- bool HasBasicD = false; -- bool HasExtLSX = false; -- bool HasExtLASX = false; -- bool HasExtLVZ = false; -- bool HasExtLBT = false; -- unsigned GRLen = 32; -- MVT GRLenVT = MVT::i32; -- LoongArchABI::ABI TargetABI = LoongArchABI::ABI_Unknown; -- LoongArchFrameLowering FrameLowering; -- LoongArchInstrInfo InstrInfo; -- LoongArchRegisterInfo RegInfo; -- LoongArchTargetLowering TLInfo; -- -- /// 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); -+ -+ // 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; -+ -+ /// 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; -+ CodeGenOpt::Level getOptLevelToEnablePostRAScheduler() const override; -+ -+ bool isABI_LP64() const; -+ bool isABI_LPX32() const; -+ bool isABI_LP32() const; -+ const LoongArchABIInfo &getABI() const; - -- // Parses features string setting specified subtarget options. The -- // definition of this function is auto-generated by tblgen. -+ /// 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); -+ -+ /// 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 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; - } -- 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; } -- MVT getGRLenVT() const { return GRLenVT; } -- unsigned getGRLen() const { return GRLen; } -- LoongArchABI::ABI getTargetABI() const { return TargetABI; } -+ const InstrItineraryData *getInstrItineraryData() const override { -+ return &InstrItins; -+ } - }; --} // end namespace llvm -+} // End llvm namespace - --#endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHSUBTARGET_H -+#endif -diff --git a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp -index 7ba5848e0..f8a1dc5fa 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp -+++ b/src/llvm-project/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,12 +12,29 @@ - - #include "LoongArchTargetMachine.h" - #include "LoongArch.h" --#include "MCTargetDesc/LoongArchBaseInfo.h" --#include "TargetInfo/LoongArchTargetInfo.h" -+#include "LoongArchISelDAGToDAG.h" -+#include "LoongArchSubtarget.h" -+#include "LoongArchTargetObjectFile.h" -+#include "LoongArchTargetTransformInfo.h" -+#include "MCTargetDesc/LoongArchABIInfo.h" -+#include "MCTargetDesc/LoongArchMCTargetDesc.h" -+#include "llvm/ADT/Optional.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/Support/Debug.h" -+#include "llvm/Support/raw_ostream.h" -+#include "llvm/Target/TargetOptions.h" -+#include -+#include - - using namespace llvm; - -@@ -26,29 +43,63 @@ using namespace llvm; - extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLoongArchTarget() { - // Register the target. - RegisterTargetMachine X(getTheLoongArch32Target()); -- RegisterTargetMachine Y(getTheLoongArch64Target()); -+ RegisterTargetMachine A(getTheLoongArch64Target()); - } - --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"; -+static std::string computeDataLayout(const Triple &TT, StringRef CPU, -+ const TargetOptions &Options) { -+ std::string Ret; -+ LoongArchABIInfo ABI = LoongArchABIInfo::computeTargetABI(TT, CPU, Options.MCOptions); -+ -+ Ret += "e"; -+ -+ 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 Reloc::Model getEffectiveRelocModel(const Triple &TT, -+static Reloc::Model getEffectiveRelocModel(bool JIT, - Optional RM) { -- return RM.value_or(Reloc::Static); -+ if (!RM.hasValue() || JIT) -+ return Reloc::Static; -+ return *RM; - } - --LoongArchTargetMachine::LoongArchTargetMachine( -- const Target &T, const Triple &TT, StringRef CPU, StringRef FS, -- const TargetOptions &Options, Optional RM, -- Optional CM, CodeGenOpt::Level OL, bool JIT) -- : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options, -- getEffectiveRelocModel(TT, RM), -+// 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, -+ Optional RM, -+ Optional CM, -+ CodeGenOpt::Level 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()) { -+ TLOF(std::make_unique()), -+ ABI(LoongArchABIInfo::computeTargetABI(TT, CPU, Options.MCOptions)) { - initAsmInfo(); - } - -@@ -57,44 +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"; -+ -+ if (softFloat) -+ FS += FS.empty() ? "+soft-float" : ",+soft-float"; - -- std::string Key = CPU + TuneCPU + FS; -- auto &I = SubtargetMap[Key]; -+ 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(); - } - - 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(); -@@ -102,22 +154,42 @@ public: - - void addIRPasses() override; - bool addInstSelector() override; -+ void addPreEmitPass() override; - }; --} // end namespace - --TargetPassConfig * --LoongArchTargetMachine::createPassConfig(PassManagerBase &PM) { -+} // end anonymous namespace -+ -+TargetPassConfig *LoongArchTargetMachine::createPassConfig(PassManagerBase &PM) { - return new LoongArchPassConfig(*this, PM); - } - - void LoongArchPassConfig::addIRPasses() { -- 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 { -+ LLVM_DEBUG(errs() << "Target Transform Info Pass Added\n"); -+ return TargetTransformInfo(BasicTTIImpl(this, F)); -+} -+ -+// 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()); -+ -+ // 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/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchTargetMachine.h b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchTargetMachine.h -index cbd872031..8e395d183 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchTargetMachine.h -+++ b/src/llvm-project/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,25 +13,33 @@ - #ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHTARGETMACHINE_H - #define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHTARGETMACHINE_H - -+#include "MCTargetDesc/LoongArchABIInfo.h" - #include "LoongArchSubtarget.h" -+#include "llvm/ADT/Optional.h" -+#include "llvm/ADT/StringMap.h" -+#include "llvm/ADT/StringRef.h" -+#include "llvm/Support/CodeGen.h" - #include "llvm/Target/TargetMachine.h" -+#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, -- Optional RM, -- Optional CM, CodeGenOpt::Level OL, -- bool JIT); -+ StringRef FS, const TargetOptions &Options, -+ Optional RM, Optional CM, -+ CodeGenOpt::Level 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; -@@ -39,6 +47,20 @@ public: - TargetLoweringObjectFile *getObjFileLowering() const override { - return TLOF.get(); - } -+ -+ /// Returns true if a cast between SrcAS and DestAS is a noop. -+ bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const override { -+ // 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; -+ } - }; - - } // end namespace llvm -diff --git a/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchTargetObjectFile.cpp b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchTargetObjectFile.cpp -new file mode 100644 -index 000000000..9c6250d28 ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchTargetObjectFile.h b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchTargetObjectFile.h -new file mode 100644 -index 000000000..a50c57171 ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchTargetStreamer.h b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchTargetStreamer.h -new file mode 100644 -index 000000000..a9adc32d0 ---- /dev/null -+++ b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchTargetStreamer.h -@@ -0,0 +1,130 @@ -+//===-- 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/Optional.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.hasValue() && "ABI hasn't been set!"); -+ return *ABI; -+ } -+ -+protected: -+ llvm::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/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchTargetTransformInfo.cpp b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchTargetTransformInfo.cpp -new file mode 100644 -index 000000000..9510dc027 ---- /dev/null -+++ b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchTargetTransformInfo.cpp -@@ -0,0 +1,325 @@ -+//===-- LoongArchTargetTransformInfo.cpp - LoongArch specific TTI pass -+//----------------===// -+// -+// The LLVM Compiler Infrastructure -+// -+// This file is distributed under the University of Illinois Open Source -+// License. See LICENSE.TXT for details. -+// -+//===----------------------------------------------------------------------===// -+/// \file -+/// This file implements a TargetTransformInfo analysis pass 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. -+/// -+//===----------------------------------------------------------------------===// -+ -+#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" -+ -+//===----------------------------------------------------------------------===// -+// -+// 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; -+} -+ -+unsigned LoongArchTTIImpl::getMaxInterleaveFactor(unsigned VF) { -+ if (VF == 1) -+ return 1; -+ return 2; -+} -+ -+InstructionCost LoongArchTTIImpl::getArithmeticInstrCost( -+ unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind, -+ TTI::OperandValueKind Op1Info, TTI::OperandValueKind Op2Info, -+ TTI::OperandValueProperties Opd1PropInfo, -+ TTI::OperandValueProperties Opd2PropInfo, ArrayRef Args, -+ const Instruction *CxtI) { -+ -+ std::pair LT = TLI->getTypeLegalizationCost(DL, 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); -+} -+ -+InstructionCost LoongArchTTIImpl::getVectorInstrCost(unsigned Opcode, Type *Val, -+ unsigned Index) { -+ assert(Val->isVectorTy() && "This must be a vector type"); -+ -+ Type *ScalarType = Val->getScalarType(); -+ -+ if (Index != -1U) { -+ // Legalize the type. -+ std::pair LT = TLI->getTypeLegalizationCost(DL, 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, Index) + 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/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchTargetTransformInfo.h b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchTargetTransformInfo.h -new file mode 100644 -index 000000000..3a93fc8ec ---- /dev/null -+++ b/src/llvm-project/llvm/lib/Target/LoongArch/LoongArchTargetTransformInfo.h -@@ -0,0 +1,91 @@ -+//===-- LoongArchTargetTransformInfo.h - LoongArch specific TTI -------------*- -+// C++ -*-===// -+// -+// 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. -+// -+//===----------------------------------------------------------------------===// -+ -+#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 { -+ -+class LoongArchTTIImpl : public BasicTTIImplBase { -+ typedef BasicTTIImplBase BaseT; -+ typedef TargetTransformInfo TTI; -+ friend BaseT; -+ -+ const LoongArchSubtarget *ST; -+ const LoongArchTargetLowering *TLI; -+ -+ const LoongArchSubtarget *getST() const { return ST; } -+ const LoongArchTargetLowering *getTLI() const { return TLI; } -+ -+public: -+ explicit LoongArchTTIImpl(const LoongArchTargetMachine *TM, const Function &F) -+ : BaseT(TM, F.getParent()->getDataLayout()), ST(TM->getSubtargetImpl(F)), -+ TLI(ST->getTargetLowering()) {} -+ -+ 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); -+ -+ InstructionCost getVectorInstrCost(unsigned Opcode, Type *Val, -+ unsigned Index); -+ -+ 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::OperandValueKind Opd1Info = TTI::OK_AnyValue, -+ TTI::OperandValueKind Opd2Info = TTI::OK_AnyValue, -+ TTI::OperandValueProperties Opd1PropInfo = TTI::OP_None, -+ TTI::OperandValueProperties Opd2PropInfo = TTI::OP_None, -+ ArrayRef Args = ArrayRef(), -+ const Instruction *CxtI = nullptr); -+ -+ /// @} -+}; -+ -+} // end namespace llvm -+ -+#endif -diff --git a/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/CMakeLists.txt b/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/CMakeLists.txt -index 2e1ca69a3..927fa7d5b 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/CMakeLists.txt -+++ b/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/CMakeLists.txt -@@ -1,12 +1,15 @@ --add_llvm_component_library(LLVMLoongArchDesc -+ add_llvm_component_library(LLVMLoongArchDesc -+ LoongArchABIInfo.cpp -+ LoongArchAnalyzeImmediate.cpp - LoongArchAsmBackend.cpp -- LoongArchBaseInfo.cpp - LoongArchELFObjectWriter.cpp -+ LoongArchELFStreamer.cpp - LoongArchInstPrinter.cpp - LoongArchMCAsmInfo.cpp -- LoongArchMCTargetDesc.cpp - LoongArchMCCodeEmitter.cpp -- LoongArchMatInt.cpp -+ LoongArchMCExpr.cpp -+ LoongArchMCTargetDesc.cpp -+ LoongArchTargetStreamer.cpp - - LINK_COMPONENTS - MC -diff --git a/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchABIInfo.cpp b/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchABIInfo.cpp -new file mode 100644 -index 000000000..18b67961a ---- /dev/null -+++ b/src/llvm-project/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 makeArrayRef(LP32IntRegs); -+ if (IsLPX32() || IsLP64()) -+ return makeArrayRef(LoongArch64IntRegs); -+ llvm_unreachable("Unhandled ABI"); -+} -+ -+ArrayRef LoongArchABIInfo::GetVarArgRegs() const { -+ if (IsLP32()) -+ return makeArrayRef(LP32IntRegs); -+ if (IsLPX32() || IsLP64()) -+ return makeArrayRef(LoongArch64IntRegs); -+ llvm_unreachable("Unhandled ABI"); -+} -+ -+LoongArchABIInfo LoongArchABIInfo::computeTargetABI(const Triple &TT, StringRef CPU, -+ const MCTargetOptions &Options) { -+ if (Options.getABIName().startswith("lp32")) -+ return LoongArchABIInfo::LP32(); -+ if (Options.getABIName().startswith("lpx32")) -+ return LoongArchABIInfo::LPX32(); -+ if (Options.getABIName().startswith("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/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchABIInfo.h b/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchABIInfo.h -new file mode 100644 -index 000000000..334ee80ea ---- /dev/null -+++ b/src/llvm-project/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/ADT/Triple.h" -+#include "llvm/IR/CallingConv.h" -+#include "llvm/MC/MCRegisterInfo.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/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAnalyzeImmediate.cpp b/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAnalyzeImmediate.cpp -new file mode 100644 -index 000000000..96e43b2d3 ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMatInt.h b/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAnalyzeImmediate.h -similarity index 62% -rename from src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMatInt.h -rename to src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAnalyzeImmediate.h -index be1b42589..3ff00f254 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMatInt.h -+++ b/src/llvm-project/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/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp b/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp -index 94a068897..b9ba9e536 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp -+++ b/src/llvm-project/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,41 +9,158 @@ - // This file implements the LoongArchAsmBackend class. - // - //===----------------------------------------------------------------------===// -+// - --#include "LoongArchAsmBackend.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/Support/Endian.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" -- --#define DEBUG_TYPE "loongarch-asmbackend" -+#include "llvm/Support/ErrorHandling.h" -+#include "llvm/Support/Format.h" -+#include "llvm/Support/MathExtras.h" -+#include "llvm/Support/raw_ostream.h" - - using namespace llvm; - --void LoongArchAsmBackend::applyFixup(const MCAssembler &Asm, -- const MCFixup &Fixup, -- const MCValue &Target, -- MutableArrayRef Data, uint64_t Value, -- bool IsResolved, -- const MCSubtargetInfo *STI) const { -- // TODO: Apply the Value for given Fixup into the provided data fragment. -- return; -+std::unique_ptr -+LoongArchAsmBackend::createObjectTargetWriter() const { -+ return createLoongArchELFObjectWriter(TheTriple, IsLPX32); - } - --bool LoongArchAsmBackend::shouldForceRelocation(const MCAssembler &Asm, -- const MCFixup &Fixup, -- const MCValue &Target) { -- // TODO: Determine which relocation require special processing at linking -- // time. -- return false; -+/// 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); - } - -+Optional LoongArchAsmBackend::getFixupKind(StringRef Name) const { -+ return StringSwitch>(Name) -+ .Case("R_LARCH_NONE", (MCFixupKind)LoongArch::fixup_LARCH_NONE) -+ .Case("R_LARCH_32", FK_Data_4) -+ .Case("R_LARCH_64", FK_Data_8) -+ .Default(MCAsmBackend::getFixupKind(Name)); -+} -+ -+const MCFixupKindInfo &LoongArchAsmBackend:: -+getFixupKindInfo(MCFixupKind Kind) const { -+ const static MCFixupKindInfo Infos[] = { -+ // 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}, -+ }; -+ -+ if (Kind < FirstTargetFixupKind) -+ return MCAsmBackend::getFixupKindInfo(Kind); -+ -+ assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && -+ "Invalid kind!"); -+ -+ return Infos[Kind - FirstTargetFixupKind]; -+} -+ -+/// 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 byte count not multiple of instruction word size -- if (Count % 4 != 0) -+ // Check for a less than instruction size number of bytes -+ if ((Count % 4) != 0) - return false; - - // The nop on LoongArch is andi r0, r0, 0. -@@ -53,16 +170,45 @@ bool LoongArchAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count, - return true; - } - --std::unique_ptr --LoongArchAsmBackend::createObjectTargetWriter() const { -- return createLoongArchELFObjectWriter(OSABI, Is64Bit); -+bool LoongArchAsmBackend::shouldForceRelocation(const MCAssembler &Asm, -+ const MCFixup &Fixup, -+ const MCValue &Target) { -+ const unsigned FixupKind = Fixup.getKind(); -+ switch (FixupKind) { -+ default: -+ return false; -+ // 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; -+ } - } - - 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()); -+ LoongArchABIInfo ABI = LoongArchABIInfo::computeTargetABI( -+ STI.getTargetTriple(), STI.getCPU(), Options); -+ return new LoongArchAsmBackend(T, MRI, STI.getTargetTriple(), STI.getCPU(), -+ ABI.IsLPX32()); - } -diff --git a/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h b/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h -index a5f0b816c..45ae6af44 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h -+++ b/src/llvm-project/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,55 +9,83 @@ - // 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/LoongArchMCTargetDesc.h" -+#include "MCTargetDesc/LoongArchFixupKinds.h" -+#include "llvm/ADT/Triple.h" - #include "llvm/MC/MCAsmBackend.h" --#include "llvm/MC/MCFixupKindInfo.h" --#include "llvm/MC/MCSubtargetInfo.h" - - namespace llvm { - -+class MCAssembler; -+struct MCFixupKindInfo; -+class MCObjectWriter; -+class MCRegisterInfo; -+class MCSymbolELF; -+class Target; -+ - class LoongArchAsmBackend : public MCAsmBackend { -- uint8_t OSABI; -- bool Is64Bit; -+ Triple TheTriple; -+ bool IsLPX32; - - public: -- LoongArchAsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI, bool Is64Bit) -- : MCAsmBackend(support::little), OSABI(OSABI), Is64Bit(Is64Bit) {} -- ~LoongArchAsmBackend() override {} -+ LoongArchAsmBackend(const Target &T, const MCRegisterInfo &MRI, const Triple &TT, -+ StringRef CPU, bool LPX32) -+ : MCAsmBackend(support::little), -+ TheTriple(TT), IsLPX32(LPX32) { -+ assert(TT.isLittleEndian()); -+ } -+ -+ 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; - -- bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, -- const MCValue &Target) override; -+ Optional getFixupKind(StringRef Name) const override; -+ const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override; -+ -+ unsigned getNumFixupKinds() const override { -+ return LoongArch::NumTargetFixupKinds; -+ } -+ -+ /// @name Target Relaxation Interfaces -+ /// @{ - -- bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, -- const MCRelaxableFragment *DF, -- const MCAsmLayout &Layout) 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; - } - -- unsigned getNumFixupKinds() const override { -- // FIXME: Implement this when we define fixup kind -- return 0; -+ /// 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; - } - -- void relaxInstruction(MCInst &Inst, -- const MCSubtargetInfo &STI) const override {} -+ /// @} - - bool writeNopData(raw_ostream &OS, uint64_t Count, - const MCSubtargetInfo *STI) const override; - -- std::unique_ptr -- createObjectTargetWriter() const override; --}; --} // end namespace llvm -+ bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, -+ const MCValue &Target) override; -+ -+}; // class LoongArchAsmBackend -+ -+} // namespace - --#endif // LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHASMBACKEND_H -+#endif -diff --git a/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.cpp b/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.cpp -deleted file mode 100644 -index de2ba2833..000000000 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.cpp -+++ /dev/null -@@ -1,40 +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/ADT/Triple.h" --#include "llvm/MC/MCSubtargetInfo.h" -- --namespace llvm { -- --namespace LoongArchABI { -- --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; --} -- --// FIXME: other register? --MCRegister getBPReg() { return LoongArch::R31; } -- --} // end namespace LoongArchABI -- --} // end namespace llvm -diff --git a/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.h b/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.h -index fee247a0c..707333c18 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.h -+++ b/src/llvm-project/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,39 +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/MC/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 { - --namespace LoongArchABI { --enum ABI { -- ABI_ILP32S, -- ABI_ILP32F, -- ABI_ILP32D, -- ABI_LP64S, -- ABI_LP64F, -- ABI_LP64D, -- ABI_Unknown --}; -+/// LoongArchII - This namespace holds all of the target specific flags that -+/// instruction info tracks. -+/// -+namespace LoongArchII { -+ /// Target Operand Flag enum. -+ enum TOF { -+ //===------------------------------------------------------------------===// -+ // LoongArch Specific MachineOperand flags. - --ABI getTargetABI(StringRef ABIName); -+ MO_NO_FLAG, - --// Returns the register used to hold the stack pointer after realignment. --MCRegister getBPReg(); --} // end namespace LoongArchABI -+ /// 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, - --} // end namespace llvm -+ /// 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, - --#endif // LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHBASEINFO_H -+ // 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/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFObjectWriter.cpp b/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFObjectWriter.cpp -index 1850b0d8a..e00b9af9d 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFObjectWriter.cpp -+++ b/src/llvm-project/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. -@@ -6,59 +6,181 @@ - // - //===----------------------------------------------------------------------===// - -+#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); -+ LoongArchELFObjectWriter(uint8_t OSABI, bool HasRelocationAddend, bool Is64); - -- ~LoongArchELFObjectWriter() override; -+ ~LoongArchELFObjectWriter() override = default; - -- // Return true if the given relocation must be with a symbol rather than -- // section plus offset. -+ unsigned getRelocType(MCContext &Ctx, const MCValue &Target, -+ const MCFixup &Fixup, bool IsPCRel) const override; - bool needsRelocateWithSymbol(const MCSymbol &Sym, - unsigned Type) const override { - return true; - } -- --protected: -- unsigned getRelocType(MCContext &Ctx, const MCValue &Target, -- const MCFixup &Fixup, bool IsPCRel) const override; - }; --} // end namespace - --LoongArchELFObjectWriter::LoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit) -- : MCELFObjectTargetWriter(Is64Bit, OSABI, ELF::EM_LOONGARCH, -- /*HasRelocationAddend*/ true) {} -+} // 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(); -- -- if (Kind >= FirstLiteralRelocationKind) -- return Kind - FirstLiteralRelocationKind; -+ const MCValue &Target, -+ const MCFixup &Fixup, -+ bool IsPCRel) const { -+ // Determine the type of the relocation. -+ ///XXX:Reloc -+ unsigned Kind = (unsigned)Fixup.getKind(); - - switch (Kind) { -- // TODO: Implement this when we defined fixup kind. -- default: -- return ELF::R_LARCH_NONE; -+ 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) { -- return std::make_unique(OSABI, Is64Bit); -+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/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFStreamer.cpp b/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFStreamer.cpp -new file mode 100644 -index 000000000..a74fee3f8 ---- /dev/null -+++ b/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFStreamer.cpp -@@ -0,0 +1,138 @@ -+//===-------- 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 -+// -+//===----------------------------------------------------------------------===// -+ -+#include "LoongArchELFStreamer.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; -+ -+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); -+ } -+} -+ -+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()); -+} -+ -+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)) { -+ } -+ -+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); -+} -+ -+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)); -+} -diff --git a/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFStreamer.h b/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFStreamer.h -new file mode 100644 -index 000000000..875cebcb7 ---- /dev/null -+++ b/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFStreamer.h -@@ -0,0 +1,53 @@ -+//===- 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 "llvm/ADT/SmallVector.h" -+#include "llvm/MC/MCELFStreamer.h" -+#include -+ -+namespace llvm { -+ -+class MCAsmBackend; -+class MCCodeEmitter; -+class MCContext; -+class MCSubtargetInfo; -+struct MCDwarfFrameInfo; -+ -+class LoongArchELFStreamer : public MCELFStreamer { -+ -+public: -+ 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; -+ -+ // 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 &Context, -+ std::unique_ptr MAB, -+ std::unique_ptr OW, -+ std::unique_ptr Emitter, -+ bool RelaxAll); -+} // end namespace llvm -+ -+#endif // LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHELFSTREAMER_H -diff --git a/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchFixupKinds.h b/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchFixupKinds.h -new file mode 100644 -index 000000000..e0e1200d8 ---- /dev/null -+++ b/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchFixupKinds.h -@@ -0,0 +1,90 @@ -+//===-- 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. -+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -+// -+//===----------------------------------------------------------------------===// -+ -+#ifndef LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHFIXUPKINDS_H -+#define LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHFIXUPKINDS_H -+ -+#include "llvm/MC/MCFixup.h" -+ -+namespace llvm { -+namespace LoongArch { -+ // 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, -+ -+ // Marker -+ LastTargetFixupKind, -+ NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind -+ }; -+} // namespace LoongArch -+} // namespace llvm -+ -+ -+#endif -diff --git a/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchInstPrinter.cpp b/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchInstPrinter.cpp -index 66183868f..065020ad4 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchInstPrinter.cpp -+++ b/src/llvm-project/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,53 +11,242 @@ - //===----------------------------------------------------------------------===// - - #include "LoongArchInstPrinter.h" --#include "LoongArchBaseInfo.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/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" - -+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!"); -+} -+ -+void LoongArchInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const { -+ OS << '$' << StringRef(getRegisterName(RegNo)).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::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, unsigned RegNo) const { -- O << '$' << getRegisterName(RegNo); -+ // 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:: -+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) { -+ // 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); -+} -+ -+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()); -+ } - } - --const char *LoongArchInstPrinter::getRegisterName(unsigned RegNo) { -- // Default print reg alias name -- return getRegisterName(RegNo, LoongArch::RegAliasName); -+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; - } -diff --git a/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchInstPrinter.h b/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchInstPrinter.h -index 0cbb3d73c..050dcc137 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchInstPrinter.h -+++ b/src/llvm-project/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,40 +10,110 @@ - // - //===----------------------------------------------------------------------===// - --#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) {} - -+ // 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(unsigned RegNo); -+ -+ void printRegName(raw_ostream &OS, unsigned RegNo) const override; - void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, - const MCSubtargetInfo &STI, raw_ostream &O) override; -- void printRegName(raw_ostream &O, unsigned RegNo) const override; - -- // 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(unsigned RegNo); -- static const char *getRegisterName(unsigned RegNo, 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); - }; - } // end namespace llvm - --#endif // LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHINSTPRINTER_H -+#endif -diff --git a/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.cpp b/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.cpp -index bc946db2f..b3091a107 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.cpp -+++ b/src/llvm-project/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. -@@ -12,23 +12,28 @@ - - #include "LoongArchMCAsmInfo.h" - #include "llvm/ADT/Triple.h" --#include "llvm/BinaryFormat/Dwarf.h" --#include "llvm/MC/MCStreamer.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/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.h b/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.h -index ed1abbf46..244db58db 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCAsmInfo.h -+++ b/src/llvm-project/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/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp b/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp -index 01a370a90..df4e72e90 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp -+++ b/src/llvm-project/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,118 +10,1422 @@ - // - //===----------------------------------------------------------------------===// - --#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/Support/EndianStream.h" -+#include "llvm/MC/MCSubtargetInfo.h" -+#include "llvm/Support/Casting.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, raw_ostream &OS, -- SmallVectorImpl &Fixups, -- const MCSubtargetInfo &STI) const override; -- -- /// 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 2. -- /// Note that this function is dedicated to specific immediate types, -- /// e.g. simm14_lsl2, simm16_lsl2, simm21_lsl2 and simm26_lsl2. -- unsigned getImmOpValueAsr2(const MCInst &MI, unsigned OpNo, -- SmallVectorImpl &Fixups, -- const MCSubtargetInfo &STI) const; --}; --} // end namespace -+#define GET_INSTRMAP_INFO -+#include "LoongArchGenInstrInfo.inc" -+#undef GET_INSTRMAP_INFO - --unsigned --LoongArchMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO, -- SmallVectorImpl &Fixups, -- const MCSubtargetInfo &STI) const { -+namespace llvm { - -- if (MO.isReg()) -- return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg()); -+MCCodeEmitter *createLoongArchMCCodeEmitter(const MCInstrInfo &MCII, -+ MCContext &Ctx) { -+ return new LoongArchMCCodeEmitter(MCII, Ctx); -+} - -- if (MO.isImm()) -- return static_cast(MO.getImm()); -+} // end namespace llvm - -- llvm_unreachable("Unhandled expression!"); -+void LoongArchMCCodeEmitter::EmitByte(unsigned char C, raw_ostream &OS) const { -+ OS << (char)C; - } - --unsigned --LoongArchMCCodeEmitter::getImmOpValueSub1(const MCInst &MI, unsigned OpNo, -- SmallVectorImpl &Fixups, -- const MCSubtargetInfo &STI) const { -- return MI.getOperand(OpNo).getImm() - 1; -+void LoongArchMCCodeEmitter::EmitInstruction(uint64_t Val, unsigned Size, -+ const MCSubtargetInfo &STI, -+ raw_ostream &OS) const { -+ for (unsigned i = 0; i < Size; ++i) { -+ unsigned Shift = i * 8; -+ EmitByte((Val >> Shift) & 0xff, OS); -+ } - } - --unsigned --LoongArchMCCodeEmitter::getImmOpValueAsr2(const MCInst &MI, unsigned OpNo, -- SmallVectorImpl &Fixups, -- const MCSubtargetInfo &STI) const { -- unsigned Res = MI.getOperand(OpNo).getImm(); -- assert((Res & 3) == 0 && "lowest 2 bits are non-zero"); -- return Res >> 2; --} -- --void LoongArchMCCodeEmitter::encodeInstruction( -- const MCInst &MI, raw_ostream &OS, SmallVectorImpl &Fixups, -- const MCSubtargetInfo &STI) const { -- const MCInstrDesc &Desc = MCII.get(MI.getOpcode()); -- // Get byte count of instruction. -+/// encodeInstruction - Emit the instruction. -+/// Size the instruction with Desc.getSize(). -+void LoongArchMCCodeEmitter:: -+encodeInstruction(const MCInst &MI, raw_ostream &OS, -+ SmallVectorImpl &Fixups, -+ const MCSubtargetInfo &STI) const -+{ -+ MCInst TmpInst = MI; -+ -+ uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); -+ -+ const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode()); -+ -+ // Get byte count of instruction - unsigned Size = Desc.getSize(); -+ if (!Size) -+ llvm_unreachable("Desc.getSize() returns 0"); -+ -+ EmitInstruction(Binary, Size, STI, OS); -+} -+ -+/// 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); - -- switch (Size) { -+ // 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 encodeInstruction length!"); -- case 4: { -- uint32_t Bits = getBinaryCodeForInstr(MI, Fixups, STI); -- support::endian::write(OS, Bits, support::little); -+ 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; -+} -+ -+/// 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(); -+ 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) { -+ 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_")); -+ -+ LoongArch::Fixups FixupKind = LoongArch::Fixups(0); -+ switch (LoongArchExpr->getKind()) { -+ case LoongArchMCExpr::MEK_None: -+ case LoongArchMCExpr::MEK_Special: -+ llvm_unreachable("Unhandled fixup kind!"); -+ Fixups.push_back(MCFixup::create(0, LoongArchExpr, MCFixupKind(FixupKind))); -+ break; -+ 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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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; -+ } -+ 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; -+} -+ -+/// 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); - } - --MCCodeEmitter *llvm::createLoongArchMCCodeEmitter(const MCInstrInfo &MCII, -- MCContext &Ctx) { -- return new LoongArchMCCodeEmitter(Ctx, MCII); -+/// 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); -+ -+ // Apply the scale factor if there is one. -+ OffBits >>= ShiftAmount; -+ -+ return (OffBits & 0xFFF) | RegBits; -+} -+ -+/// 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; -+} -+ -+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); -+ -+ // Apply the scale factor if there is one. -+ OffBits >>= 2; -+ -+ 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: -+ return MO.getImm(); -+ } -+} -+ -+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/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.h b/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.h -new file mode 100644 -index 000000000..016340151 ---- /dev/null -+++ b/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.h -@@ -0,0 +1,146 @@ -+//===- 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 EmitInstruction(uint64_t Val, unsigned Size, const MCSubtargetInfo &STI, -+ raw_ostream &OS) const; -+ -+ void encodeInstruction(const MCInst &MI, raw_ostream &OS, -+ 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/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.cpp b/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.cpp -new file mode 100644 -index 000000000..1af027f15 ---- /dev/null -+++ b/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.cpp -@@ -0,0 +1,158 @@ -+//===-- 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 -+// -+//===----------------------------------------------------------------------===// -+ -+#include "LoongArchMCExpr.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 "loongarchmcexpr" -+ -+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 { -+ 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 { -+ if (!getSubExpr()->evaluateAsRelocatable(Res, Layout, Fixup)) -+ return false; -+ -+ if (Res.getRefKind() != MCSymbolRefExpr::VK_None) -+ return false; -+ -+ // 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. -+ // -+ // The value of getKind() that is given to MCValue is only intended to aid -+ // debugging when inspecting MCValue objects. It shouldn't be relied upon -+ // for decision making. -+ Res = MCValue::get(Res.getSymA(), Res.getSymB(), Res.getConstant(), getKind()); -+ -+ return true; -+} -+ -+void LoongArchMCExpr::visitUsedExpr(MCStreamer &Streamer) const { -+ Streamer.visitUsedExpr(*getSubExpr()); -+} -+ -+static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) { -+ switch (Expr->getKind()) { -+ case MCExpr::Target: -+ fixELFSymbolsInTLSFixupsImpl(cast(Expr)->getSubExpr(), Asm); -+ break; -+ case MCExpr::Constant: -+ break; -+ case MCExpr::Binary: { -+ const MCBinaryExpr *BE = cast(Expr); -+ fixELFSymbolsInTLSFixupsImpl(BE->getLHS(), Asm); -+ fixELFSymbolsInTLSFixupsImpl(BE->getRHS(), Asm); -+ break; -+ } -+ case MCExpr::SymbolRef: { -+ // We're known to be under a TLS fixup, so any symbol should be -+ // modified. There should be only one. -+ const MCSymbolRefExpr &SymRef = *cast(Expr); -+ 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: -+ 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; -+ } -+} -diff --git a/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.h b/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.h -new file mode 100644 -index 000000000..7851d478e ---- /dev/null -+++ b/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.h -@@ -0,0 +1,97 @@ -+//===- 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 -+// -+//===----------------------------------------------------------------------===// -+ -+#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 LoongArchMCExpr : public MCTargetExpr { -+public: -+ 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; -+ -+ explicit LoongArchMCExpr(LoongArchExprKind Kind, const MCExpr *Expr) -+ : Kind(Kind), Expr(Expr) {} -+ -+public: -+ static const LoongArchMCExpr *create(LoongArchExprKind Kind, const MCExpr *Expr, -+ MCContext &Ctx); -+ static const LoongArchMCExpr *createGpOff(LoongArchExprKind Kind, const MCExpr *Expr, -+ MCContext &Ctx); -+ -+ /// Get the kind of this expression. -+ LoongArchExprKind getKind() const { return Kind; } -+ -+ /// Get the child of this expression. -+ const MCExpr *getSubExpr() const { return Expr; } -+ -+ 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(); -+ } -+ -+ void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const override; -+ -+ static bool classof(const MCExpr *E) { -+ return E->getKind() == MCExpr::Target; -+ } -+}; -+ -+} // end namespace llvm -+ -+#endif // LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHMCEXPR_H -diff --git a/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.cpp b/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.cpp -index 8d71235f6..18e3224ab 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.cpp -+++ b/src/llvm-project/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,35 +11,47 @@ - //===----------------------------------------------------------------------===// - - #include "LoongArchMCTargetDesc.h" --#include "LoongArchBaseInfo.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/MCAsmInfo.h" --#include "llvm/MC/MCDwarf.h" -+#include "llvm/ADT/Triple.h" -+#include "llvm/MC/MCCodeEmitter.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" -+ -+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 = "la464"; -+ } -+ return CPU; - } - - static MCInstrInfo *createLoongArchMCInstrInfo() { -@@ -48,20 +60,24 @@ static MCInstrInfo *createLoongArchMCInstrInfo() { - return X; - } - --static MCSubtargetInfo * --createLoongArchMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) { -- if (CPU.empty()) -- 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); - -@@ -76,40 +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 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) || Inst.getOpcode() == LoongArch::BL) { -+ if (NumOps == 0) -+ return false; -+ if (Info->get(Inst.getOpcode()).isBranch() || Inst.getOpcode() == LoongArch::BL) { -+ // just not jirl - Target = Addr + Inst.getOperand(NumOps - 1).getImm(); - return true; -+ } else { -+ return false; - } -- -- return false; - } - }; -+} - --} // end namespace -- --static MCInstrAnalysis *createLoongArchInstrAnalysis(const MCInstrInfo *Info) { -+static MCInstrAnalysis *createLoongArchMCInstrAnalysis(const MCInstrInfo *Info) { - return new LoongArchMCInstrAnalysis(Info); - } - - extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLoongArchTargetMC() { - for (Target *T : {&getTheLoongArch32Target(), &getTheLoongArch64Target()}) { -- TargetRegistry::RegisterMCRegInfo(*T, createLoongArchMCRegisterInfo); -+ // Register the MC asm info. -+ RegisterMCAsmInfoFn X(*T, createLoongArchMCAsmInfo); -+ -+ // Register the MC instruction info. - TargetRegistry::RegisterMCInstrInfo(*T, createLoongArchMCInstrInfo); -+ -+ // Register the MC register info. -+ TargetRegistry::RegisterMCRegInfo(*T, createLoongArchMCRegisterInfo); -+ -+ // Register the elf streamer. -+ TargetRegistry::RegisterELFStreamer(*T, createMCStreamer); -+ -+ // Register the asm target streamer. -+ TargetRegistry::RegisterAsmTargetStreamer(*T, createLoongArchAsmTargetStreamer); -+ -+ TargetRegistry::RegisterNullTargetStreamer(*T, -+ createLoongArchNullTargetStreamer); -+ -+ // Register the MC subtarget info. - TargetRegistry::RegisterMCSubtargetInfo(*T, createLoongArchMCSubtargetInfo); -- TargetRegistry::RegisterMCAsmInfo(*T, createLoongArchMCAsmInfo); -- TargetRegistry::RegisterMCCodeEmitter(*T, createLoongArchMCCodeEmitter); -- TargetRegistry::RegisterMCAsmBackend(*T, createLoongArchAsmBackend); -+ -+ // Register the MC instruction analyzer. -+ TargetRegistry::RegisterMCInstrAnalysis(*T, createLoongArchMCInstrAnalysis); -+ -+ // Register the MCInstPrinter. - TargetRegistry::RegisterMCInstPrinter(*T, createLoongArchMCInstPrinter); -- TargetRegistry::RegisterMCInstrAnalysis(*T, createLoongArchInstrAnalysis); -+ -+ 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/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.h b/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.h -index ab35a0096..04a5c79e6 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.h -+++ b/src/llvm-project/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); -+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/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMatInt.cpp b/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMatInt.cpp -deleted file mode 100644 -index 1509c436c..000000000 ---- a/src/llvm-project/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/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchTargetStreamer.cpp b/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchTargetStreamer.cpp -new file mode 100644 -index 000000000..4d0e785a3 ---- /dev/null -+++ b/src/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchTargetStreamer.cpp -@@ -0,0 +1,330 @@ -+//===-- 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. -+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -+// -+//===----------------------------------------------------------------------===// -+// -+// This file provides LoongArch specific target streamer methods. -+// -+//===----------------------------------------------------------------------===// -+ -+#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), 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(Align(std::max(16u, TextSection.getAlignment()))); -+ DataSection.setAlignment(Align(std::max(16u, DataSection.getAlignment()))); -+ BSSSection.setAlignment(Align(std::max(16u, BSSSection.getAlignment()))); -+ -+ 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); -+ -+ unsigned Alignment = Section.getAlignment(); -+ if (Alignment) { -+ OS.switchSection(&Section); -+ if (Section.useCodeAlign()) -+ OS.emitCodeAlignment(Alignment, &STI, Alignment); -+ else -+ OS.emitValueToAlignment(Alignment, 0, 1, Alignment); -+ } -+ } -+ } -+ -+ // 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 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/src/llvm-project/llvm/lib/Target/LoongArch/TargetInfo/CMakeLists.txt b/src/llvm-project/llvm/lib/Target/LoongArch/TargetInfo/CMakeLists.txt -index e14360ff5..f53ddba40 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/TargetInfo/CMakeLists.txt -+++ b/src/llvm-project/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/src/llvm-project/llvm/lib/Target/LoongArch/TargetInfo/LoongArchTargetInfo.cpp b/src/llvm-project/llvm/lib/Target/LoongArch/TargetInfo/LoongArchTargetInfo.cpp -index 106545100..e6b845180 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/TargetInfo/LoongArchTargetInfo.cpp -+++ b/src/llvm-project/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/src/llvm-project/llvm/lib/Target/LoongArch/TargetInfo/LoongArchTargetInfo.h b/src/llvm-project/llvm/lib/Target/LoongArch/TargetInfo/LoongArchTargetInfo.h -index b24cf8795..7dce2497f 100644 ---- a/src/llvm-project/llvm/lib/Target/LoongArch/TargetInfo/LoongArchTargetInfo.h -+++ b/src/llvm-project/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/src/llvm-project/llvm/lib/Target/Sparc/SparcCallingConv.td b/src/llvm-project/llvm/lib/Target/Sparc/SparcCallingConv.td -index e6d23f741..8afd0a7fc 100644 ---- a/src/llvm-project/llvm/lib/Target/Sparc/SparcCallingConv.td -+++ b/src/llvm-project/llvm/lib/Target/Sparc/SparcCallingConv.td -@@ -125,10 +125,14 @@ def CC_Sparc64 : CallingConv<[ - def RetCC_Sparc64 : CallingConv<[ - // A single f32 return value always goes in %f0. The ABI doesn't specify what - // happens to multiple f32 return values outside a struct. -- CCIfType<[f32], CCCustom<"CC_Sparc64_Half">>, -+ CCIfType<[f32], CCCustom<"RetCC_Sparc64_Half">>, - -- // Otherwise, return values are passed exactly like arguments. -- CCDelegateTo -+ // Otherwise, return values are passed exactly like arguments, except that -+ // returns that are too big to fit into the registers is passed as an sret -+ // instead. -+ CCIfInReg>>, -+ CCIfType<[i32], CCPromoteToType>, -+ CCCustom<"RetCC_Sparc64_Full"> - ]>; - - // Callee-saved registers are handled by the register window mechanism. -diff --git a/src/llvm-project/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/src/llvm-project/llvm/lib/Target/Sparc/SparcISelLowering.cpp -index 2cb74e770..f55675089 100644 ---- a/src/llvm-project/llvm/lib/Target/Sparc/SparcISelLowering.cpp -+++ b/src/llvm-project/llvm/lib/Target/Sparc/SparcISelLowering.cpp -@@ -101,9 +101,9 @@ static bool CC_Sparc_Assign_Ret_Split_64(unsigned &ValNo, MVT &ValVT, - } - - // Allocate a full-sized argument for the 64-bit ABI. --static bool CC_Sparc64_Full(unsigned &ValNo, MVT &ValVT, -- MVT &LocVT, CCValAssign::LocInfo &LocInfo, -- ISD::ArgFlagsTy &ArgFlags, CCState &State) { -+static bool Analyze_CC_Sparc64_Full(bool IsReturn, unsigned &ValNo, MVT &ValVT, -+ MVT &LocVT, CCValAssign::LocInfo &LocInfo, -+ ISD::ArgFlagsTy &ArgFlags, CCState &State) { - assert((LocVT == MVT::f32 || LocVT == MVT::f128 - || LocVT.getSizeInBits() == 64) && - "Can't handle non-64 bits locations"); -@@ -133,6 +133,11 @@ static bool CC_Sparc64_Full(unsigned &ValNo, MVT &ValVT, - return true; - } - -+ // Bail out if this is a return CC and we run out of registers to place -+ // values into. -+ if (IsReturn) -+ return false; -+ - // This argument goes on the stack in an 8-byte slot. - // When passing floats, LocVT is smaller than 8 bytes. Adjust the offset to - // the right-aligned float. The first 4 bytes of the stack slot are undefined. -@@ -146,9 +151,9 @@ static bool CC_Sparc64_Full(unsigned &ValNo, MVT &ValVT, - // Allocate a half-sized argument for the 64-bit ABI. - // - // This is used when passing { float, int } structs by value in registers. --static bool CC_Sparc64_Half(unsigned &ValNo, MVT &ValVT, -- MVT &LocVT, CCValAssign::LocInfo &LocInfo, -- ISD::ArgFlagsTy &ArgFlags, CCState &State) { -+static bool Analyze_CC_Sparc64_Half(bool IsReturn, unsigned &ValNo, MVT &ValVT, -+ MVT &LocVT, CCValAssign::LocInfo &LocInfo, -+ ISD::ArgFlagsTy &ArgFlags, CCState &State) { - assert(LocVT.getSizeInBits() == 32 && "Can't handle non-32 bits locations"); - unsigned Offset = State.AllocateStack(4, Align(4)); - -@@ -174,10 +179,43 @@ static bool CC_Sparc64_Half(unsigned &ValNo, MVT &ValVT, - return true; - } - -+ // Bail out if this is a return CC and we run out of registers to place -+ // values into. -+ if (IsReturn) -+ return false; -+ - State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo)); - return true; - } - -+static bool CC_Sparc64_Full(unsigned &ValNo, MVT &ValVT, MVT &LocVT, -+ CCValAssign::LocInfo &LocInfo, -+ ISD::ArgFlagsTy &ArgFlags, CCState &State) { -+ return Analyze_CC_Sparc64_Full(false, ValNo, ValVT, LocVT, LocInfo, ArgFlags, -+ State); -+} -+ -+static bool CC_Sparc64_Half(unsigned &ValNo, MVT &ValVT, MVT &LocVT, -+ CCValAssign::LocInfo &LocInfo, -+ ISD::ArgFlagsTy &ArgFlags, CCState &State) { -+ return Analyze_CC_Sparc64_Half(false, ValNo, ValVT, LocVT, LocInfo, ArgFlags, -+ State); -+} -+ -+static bool RetCC_Sparc64_Full(unsigned &ValNo, MVT &ValVT, MVT &LocVT, -+ CCValAssign::LocInfo &LocInfo, -+ ISD::ArgFlagsTy &ArgFlags, CCState &State) { -+ return Analyze_CC_Sparc64_Full(true, ValNo, ValVT, LocVT, LocInfo, ArgFlags, -+ State); -+} -+ -+static bool RetCC_Sparc64_Half(unsigned &ValNo, MVT &ValVT, MVT &LocVT, -+ CCValAssign::LocInfo &LocInfo, -+ ISD::ArgFlagsTy &ArgFlags, CCState &State) { -+ return Analyze_CC_Sparc64_Half(true, ValNo, ValVT, LocVT, LocInfo, ArgFlags, -+ State); -+} -+ - #include "SparcGenCallingConv.inc" - - // The calling conventions in SparcCallingConv.td are described in terms of the -@@ -191,6 +229,15 @@ static unsigned toCallerWindow(unsigned Reg) { - return Reg; - } - -+bool SparcTargetLowering::CanLowerReturn( -+ CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, -+ const SmallVectorImpl &Outs, LLVMContext &Context) const { -+ SmallVector RVLocs; -+ CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context); -+ return CCInfo.CheckReturn(Outs, Subtarget->is64Bit() ? RetCC_Sparc64 -+ : RetCC_Sparc32); -+} -+ - SDValue - SparcTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, - bool IsVarArg, -@@ -1031,6 +1078,7 @@ SparcTargetLowering::LowerCall_32(TargetLowering::CallLoweringInfo &CLI, - - // Copy all of the result registers out of their specified physreg. - for (unsigned i = 0; i != RVLocs.size(); ++i) { -+ assert(RVLocs[i].isRegLoc() && "Can only return in registers!"); - if (RVLocs[i].getLocVT() == MVT::v2i32) { - SDValue Vec = DAG.getNode(ISD::UNDEF, dl, MVT::v2i32); - SDValue Lo = DAG.getCopyFromReg( -@@ -1346,6 +1394,7 @@ SparcTargetLowering::LowerCall_64(TargetLowering::CallLoweringInfo &CLI, - // 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!"); - unsigned Reg = toCallerWindow(VA.getLocReg()); - - // When returning 'inreg {i32, i32 }', two consecutive i32 arguments can -diff --git a/src/llvm-project/llvm/lib/Target/Sparc/SparcISelLowering.h b/src/llvm-project/llvm/lib/Target/Sparc/SparcISelLowering.h -index 2768bb205..16e4f2687 100644 ---- a/src/llvm-project/llvm/lib/Target/Sparc/SparcISelLowering.h -+++ b/src/llvm-project/llvm/lib/Target/Sparc/SparcISelLowering.h -@@ -144,6 +144,11 @@ namespace llvm { - SDValue LowerCall_64(TargetLowering::CallLoweringInfo &CLI, - SmallVectorImpl &InVals) const; - -+ 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, -diff --git a/src/llvm-project/llvm/lib/Target/X86/X86.td b/src/llvm-project/llvm/lib/Target/X86/X86.td -index fa0a6bd41..f98916e81 100644 ---- a/src/llvm-project/llvm/lib/Target/X86/X86.td -+++ b/src/llvm-project/llvm/lib/Target/X86/X86.td -@@ -909,7 +909,6 @@ def ProcessorFeatures { - FeatureTSXLDTRK, - FeatureENQCMD, - FeatureSHSTK, -- FeatureVP2INTERSECT, - FeatureMOVDIRI, - FeatureMOVDIR64B, - FeatureUINTR]; -diff --git a/src/llvm-project/llvm/lib/Transforms/IPO/GlobalOpt.cpp b/src/llvm-project/llvm/lib/Transforms/IPO/GlobalOpt.cpp -index 6df040925..6fc7b29c5 100644 ---- a/src/llvm-project/llvm/lib/Transforms/IPO/GlobalOpt.cpp -+++ b/src/llvm-project/llvm/lib/Transforms/IPO/GlobalOpt.cpp -@@ -2003,7 +2003,7 @@ OptimizeFunctions(Module &M, - // FIXME: We should also hoist alloca affected by this to the entry - // block if possible. - if (F.getAttributes().hasAttrSomewhere(Attribute::InAlloca) && -- !F.hasAddressTaken() && !hasMustTailCallers(&F)) { -+ !F.hasAddressTaken() && !hasMustTailCallers(&F) && !F.isVarArg()) { - RemoveAttribute(&F, Attribute::InAlloca); - Changed = true; - } -diff --git a/src/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/src/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp -index bc01d2ef7..52596b304 100644 ---- a/src/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp -+++ b/src/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp -@@ -3289,6 +3289,10 @@ bool InstCombinerImpl::transformConstExprCastCall(CallBase &Call) { - if (CallerPAL.hasParamAttr(i, Attribute::SwiftError)) - return false; - -+ if (CallerPAL.hasParamAttr(i, Attribute::ByVal) != -+ Callee->getAttributes().hasParamAttr(i, Attribute::ByVal)) -+ return false; // Cannot transform to or from byval. -+ - // If the parameter is passed as a byval argument, then we have to have a - // sized type and the sized type has to have the same size as the old type. - if (ParamTy != ActTy && CallerPAL.hasParamAttr(i, Attribute::ByVal)) { -diff --git a/src/llvm-project/llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp b/src/llvm-project/llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp -index 0d2662108..adc007dac 100644 ---- a/src/llvm-project/llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp -+++ b/src/llvm-project/llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp -@@ -406,6 +406,7 @@ static bool shouldApply(Function &F, ProfileSummaryInfo& PSI) { - return CHRFunctions.count(F.getName()); - } - -+ assert(PSI.hasProfileSummary() && "Empty PSI?"); - return PSI.isFunctionEntryHot(&F); - } - -diff --git a/src/llvm-project/llvm/lib/Transforms/Scalar/SROA.cpp b/src/llvm-project/llvm/lib/Transforms/Scalar/SROA.cpp -index 143a03574..644c5c82e 100644 ---- a/src/llvm-project/llvm/lib/Transforms/Scalar/SROA.cpp -+++ b/src/llvm-project/llvm/lib/Transforms/Scalar/SROA.cpp -@@ -1210,8 +1210,7 @@ static bool isSafePHIToSpeculate(PHINode &PN) { - BasicBlock *BB = PN.getParent(); - Align MaxAlign; - uint64_t APWidth = DL.getIndexTypeSizeInBits(PN.getType()); -- APInt MaxSize(APWidth, 0); -- bool HaveLoad = false; -+ Type *LoadType = nullptr; - for (User *U : PN.users()) { - LoadInst *LI = dyn_cast(U); - if (!LI || !LI->isSimple()) -@@ -1223,21 +1222,27 @@ static bool isSafePHIToSpeculate(PHINode &PN) { - if (LI->getParent() != BB) - return false; - -+ if (LoadType) { -+ if (LoadType != LI->getType()) -+ return false; -+ } else { -+ LoadType = LI->getType(); -+ } -+ - // Ensure that there are no instructions between the PHI and the load that - // could store. - for (BasicBlock::iterator BBI(PN); &*BBI != LI; ++BBI) - if (BBI->mayWriteToMemory()) - return false; - -- uint64_t Size = DL.getTypeStoreSize(LI->getType()).getFixedSize(); - MaxAlign = std::max(MaxAlign, LI->getAlign()); -- MaxSize = MaxSize.ult(Size) ? APInt(APWidth, Size) : MaxSize; -- HaveLoad = true; - } - -- if (!HaveLoad) -+ if (!LoadType) - return false; - -+ APInt LoadSize = APInt(APWidth, DL.getTypeStoreSize(LoadType).getFixedSize()); -+ - // We can only transform this if it is safe to push the loads into the - // predecessor blocks. The only thing to watch out for is that we can't put - // a possibly trapping load in the predecessor if it is a critical edge. -@@ -1259,7 +1264,7 @@ static bool isSafePHIToSpeculate(PHINode &PN) { - // If this pointer is always safe to load, or if we can prove that there - // is already a load in the block, then we can move the load to the pred - // block. -- if (isSafeToLoadUnconditionally(InVal, MaxAlign, MaxSize, DL, TI)) -+ if (isSafeToLoadUnconditionally(InVal, MaxAlign, LoadSize, DL, TI)) - continue; - - return false; -diff --git a/src/llvm-project/llvm/lib/Transforms/Utils/LoopVersioning.cpp b/src/llvm-project/llvm/lib/Transforms/Utils/LoopVersioning.cpp -index 97f29527b..6309eed79 100644 ---- a/src/llvm-project/llvm/lib/Transforms/Utils/LoopVersioning.cpp -+++ b/src/llvm-project/llvm/lib/Transforms/Utils/LoopVersioning.cpp -@@ -137,8 +137,10 @@ void LoopVersioning::addPHINodes( - // See if we have a single-operand PHI with the value defined by the - // original loop. - for (auto I = PHIBlock->begin(); (PN = dyn_cast(I)); ++I) { -- if (PN->getIncomingValue(0) == Inst) -+ if (PN->getIncomingValue(0) == Inst) { -+ SE->forgetValue(PN); - break; -+ } - } - // If not create it. - if (!PN) { -diff --git a/src/llvm-project/llvm/lib/Transforms/Utils/VNCoercion.cpp b/src/llvm-project/llvm/lib/Transforms/Utils/VNCoercion.cpp -index 42be67f3c..264da2187 100644 ---- a/src/llvm-project/llvm/lib/Transforms/Utils/VNCoercion.cpp -+++ b/src/llvm-project/llvm/lib/Transforms/Utils/VNCoercion.cpp -@@ -356,9 +356,9 @@ int analyzeLoadFromClobberingMemInst(Type *LoadTy, Value *LoadPtr, - - // If this is memset, we just need to see if the offset is valid in the size - // of the memset.. -- if (MI->getIntrinsicID() == Intrinsic::memset) { -+ if (const auto *memset_inst = dyn_cast(MI)) { - if (DL.isNonIntegralPointerType(LoadTy->getScalarType())) { -- auto *CI = dyn_cast(cast(MI)->getValue()); -+ auto *CI = dyn_cast(memset_inst->getValue()); - if (!CI || !CI->isZero()) - return -1; - } -diff --git a/src/llvm-project/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/src/llvm-project/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp -index 2cdae028e..5fd4e45d8 100644 ---- a/src/llvm-project/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp -+++ b/src/llvm-project/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp -@@ -8154,7 +8154,7 @@ VPRecipeBase *VPRecipeBuilder::tryToOptimizeInductionPHI( - Phi, Operands[0], *II, *PSE.getSE(), - LoopVectorizationPlanner::getDecisionAndClampRange( - [&](ElementCount VF) { -- return !VF.isScalable() && CM.isScalarAfterVectorization(Phi, VF); -+ return CM.isScalarAfterVectorization(Phi, VF); - }, - Range)); - } -@@ -9338,7 +9338,7 @@ void VPWidenPointerInductionRecipe::execute(VPTransformState &State) { - auto *IVR = getParent()->getPlan()->getCanonicalIV(); - PHINode *CanonicalIV = cast(State.get(IVR, 0)); - -- if (onlyScalarsGenerated()) { -+ if (onlyScalarsGenerated(State.VF)) { - // This is the normalized GEP that starts counting at zero. - Value *PtrInd = State.Builder.CreateSExtOrTrunc( - CanonicalIV, IndDesc.getStep()->getType()); -diff --git a/src/llvm-project/llvm/lib/Transforms/Vectorize/VPlan.cpp b/src/llvm-project/llvm/lib/Transforms/Vectorize/VPlan.cpp -index 0662ca883..30032dda7 100644 ---- a/src/llvm-project/llvm/lib/Transforms/Vectorize/VPlan.cpp -+++ b/src/llvm-project/llvm/lib/Transforms/Vectorize/VPlan.cpp -@@ -698,7 +698,7 @@ void VPlan::execute(VPTransformState *State) { - auto *WidenPhi = cast(&R); - // TODO: Split off the case that all users of a pointer phi are scalar - // from the VPWidenPointerInductionRecipe. -- if (WidenPhi->onlyScalarsGenerated()) -+ if (WidenPhi->onlyScalarsGenerated(State->VF)) - continue; - - auto *GEP = cast(State->get(WidenPhi, 0)); -diff --git a/src/llvm-project/llvm/lib/Transforms/Vectorize/VPlan.h b/src/llvm-project/llvm/lib/Transforms/Vectorize/VPlan.h -index 329843bf9..7a6bc48e2 100644 ---- a/src/llvm-project/llvm/lib/Transforms/Vectorize/VPlan.h -+++ b/src/llvm-project/llvm/lib/Transforms/Vectorize/VPlan.h -@@ -1220,7 +1220,7 @@ public: - void execute(VPTransformState &State) override; - - /// Returns true if only scalar values will be generated. -- bool onlyScalarsGenerated(); -+ bool onlyScalarsGenerated(ElementCount VF); - - #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) - /// Print the recipe. -diff --git a/src/llvm-project/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/src/llvm-project/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp -index f214563af..9a404640b 100644 ---- a/src/llvm-project/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp -+++ b/src/llvm-project/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp -@@ -982,8 +982,9 @@ void VPCanonicalIVPHIRecipe::print(raw_ostream &O, const Twine &Indent, - } - #endif - --bool VPWidenPointerInductionRecipe::onlyScalarsGenerated() { -- return IsScalarAfterVectorization; -+bool VPWidenPointerInductionRecipe::onlyScalarsGenerated(ElementCount VF) { -+ return IsScalarAfterVectorization && -+ (!VF.isScalable() || vputils::onlyFirstLaneUsed(this)); - } - - #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) -diff --git a/src/llvm-project/llvm/test/CMakeLists.txt b/src/llvm-project/llvm/test/CMakeLists.txt -index 86ca20ada..e7dd22261 100644 ---- a/src/llvm-project/llvm/test/CMakeLists.txt -+++ b/src/llvm-project/llvm/test/CMakeLists.txt -@@ -8,6 +8,7 @@ llvm_canonicalize_cmake_booleans( - LLVM_ENABLE_CURL - LLVM_ENABLE_HTTPLIB - LLVM_ENABLE_ZLIB -+ LLVM_ENABLE_ZSTD - LLVM_ENABLE_LIBXML2 - LLVM_INCLUDE_GO_TESTS - LLVM_LINK_LLVM_DYLIB -diff --git a/src/llvm-project/llvm/test/CodeGen/LoongArch/1ri.mir b/src/llvm-project/llvm/test/CodeGen/LoongArch/1ri.mir -deleted file mode 100644 -index c7d74b987..000000000 ---- a/src/llvm-project/llvm/test/CodeGen/LoongArch/1ri.mir -+++ /dev/null -@@ -1,96 +0,0 @@ --# RUN: llc %s -mtriple=loongarch64 -start-after=prologepilog -O0 -filetype=obj -o - \ --# RUN: | extract-section .text \ --# RUN: | FileCheck %s -check-prefix=CHECK-ENC --# RUN: llc %s -mtriple=loongarch64 -start-after=prologepilog -O0 -filetype=asm -o - \ --# RUN: | FileCheck %s -check-prefix=CHECK-ASM -- --# ------------------------------------------------------------------------------------------------- --# Encoding format: 1RI20 --# ------------------------------------------------------------------------------------------------- --# ---------------------+-----------------------------------------------------------+--------------- --# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 --# ---------------------+-----------------------------------------------------------+--------------- --# opcode | imm20 | rd --# ---------------------+-----------------------------------------------------------+--------------- -- ----- --# CHECK-LABEL: test_LU12I_W: --# CHECK-ENC: 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 0 1 0 0 --# CHECK-ASM: lu12i.w $a0, 49 --name: test_LU12I_W --body: | -- bb.0: -- $r4 = LU12I_W 49 --... ----- --# CHECK-LABEL: test_LU32I_D: --# CHECK-ENC: 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 1 0 0 --# CHECK-ASM: lu32i.d $a0, 196 --name: test_LU32I_D --body: | -- bb.0: -- $r4 = LU32I_D $r4, 196 --... ----- --# CHECK-LABEL: test_PCADDI: --# CHECK-ENC: 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 1 0 1 1 0 0 1 0 0 --# CHECK-ASM: pcaddi $a0, 187 --name: test_PCADDI --body: | -- bb.0: -- $r4 = PCADDI 187 --... ----- --# CHECK-LABEL: test_PCALAU12I: --# CHECK-ENC: 0 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 1 0 0 1 0 0 --# CHECK-ASM: pcalau12i $a0, 89 --name: test_PCALAU12I --body: | -- bb.0: -- $r4 = PCALAU12I 89 --... ----- --# CHECK-LABEL: test_PCADDU12I: --# CHECK-ENC: 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: pcaddu12i $a0, 37 --name: test_PCADDU12I --body: | -- bb.0: -- $r4 = PCADDU12I 37 --... ----- --# CHECK-LABEL: test_PCADDU18I: --# CHECK-ENC: 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 1 0 0 --# CHECK-ASM: pcaddu18i $a0, 26 --name: test_PCADDU18I --body: | -- bb.0: -- $r4 = PCADDU18I 26 --... -- --# ------------------------------------------------------------------------------------------------- --# Encoding format: 1RI21 --# ------------------------------------------------------------------------------------------------- --# ------------------+-----------------------------------------------+--------------+--------------- --# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 --# ------------------+-----------------------------------------------+--------------+--------------- --# opcode | imm21{15-0} | rj | imm21{20-16} --# ------------------+-----------------------------------------------+--------------+--------------- -- ----- --# CHECK-LABEL: test_BEQZ: --# CHECK-ENC: 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 1 0 0 1 0 0 0 0 0 0 0 --# CHECK-ASM: beqz $a0, 92 --name: test_BEQZ --body: | -- bb.0: -- BEQZ $r4, 92 --... ----- --# CHECK-LABEL: test_BNEZ: --# CHECK-ENC: 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0 1 0 0 0 0 0 0 0 --# CHECK-ASM: bnez $a0, 84 --name: test_BNEZ --body: | -- bb.0: -- BNEZ $r4, 84 -diff --git a/src/llvm-project/llvm/test/CodeGen/LoongArch/2r.mir b/src/llvm-project/llvm/test/CodeGen/LoongArch/2r.mir -deleted file mode 100644 -index 488944526..000000000 ---- a/src/llvm-project/llvm/test/CodeGen/LoongArch/2r.mir -+++ /dev/null -@@ -1,230 +0,0 @@ --# RUN: llc %s -mtriple=loongarch64 -start-after=prologepilog -O0 -filetype=obj -o - \ --# RUN: | extract-section .text \ --# RUN: | FileCheck %s -check-prefix=CHECK-ENC --# RUN: llc %s -mtriple=loongarch64 -start-after=prologepilog -O0 -filetype=asm -o - \ --# RUN: | FileCheck %s -check-prefix=CHECK-ASM -- --# ------------------------------------------------------------------------------------------------- --# Encoding format: 2R --# ------------------------------------------------------------------------------------------------- --# ------------------------------------------------------------------+--------------+--------------- --# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 --# ------------------------------------------------------------------+--------------+--------------- --# opcode | rj | rd --# ------------------------------------------------------------------+--------------+--------------- -- ----- --# CHECK-LABEL: test_CLO_W: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: clo.w $a0, $a1 --name: test_CLO_W --body: | -- bb.0: -- $r4 = CLO_W $r5 --... ----- --# CHECK-LABEL: test_CLZ_W: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: clz.w $a0, $a1 --name: test_CLZ_W --body: | -- bb.0: -- $r4 = CLZ_W $r5 --... ----- --# CHECK-LABEL: test_CTO_W: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: cto.w $a0, $a1 --name: test_CTO_W --body: | -- bb.0: -- $r4 = CTO_W $r5 --... ----- --# CHECK-LABEL: test_CTZ_W: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: ctz.w $a0, $a1 --name: test_CTZ_W --body: | -- bb.0: -- $r4 = CTZ_W $r5 --... ----- --# CHECK-LABEL: test_CLO_D: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: clo.d $a0, $a1 --name: test_CLO_D --body: | -- bb.0: -- $r4 = CLO_D $r5 --... ----- --# CHECK-LABEL: test_CLZ_D: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: clz.d $a0, $a1 --name: test_CLZ_D --body: | -- bb.0: -- $r4 = CLZ_D $r5 --... ----- --# CHECK-LABEL: test_CTO_D: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: cto.d $a0, $a1 --name: test_CTO_D --body: | -- bb.0: -- $r4 = CTO_D $r5 --... ----- --# CHECK-LABEL: test_CTZ_D: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: ctz.d $a0, $a1 --name: test_CTZ_D --body: | -- bb.0: -- $r4 = CTZ_D $r5 --... ----- --# CHECK-LABEL: test_REVB_2H: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: revb.2h $a0, $a1 --name: test_REVB_2H --body: | -- bb.0: -- $r4 = REVB_2H $r5 --... ----- --# CHECK-LABEL: test_REVB_4H: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: revb.4h $a0, $a1 --name: test_REVB_4H --body: | -- bb.0: -- $r4 = REVB_4H $r5 --... ----- --# CHECK-LABEL: test_REVB_2W: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: revb.2w $a0, $a1 --name: test_REVB_2W --body: | -- bb.0: -- $r4 = REVB_2W $r5 --... ----- --# CHECK-LABEL: test_REVB_D: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: revb.d $a0, $a1 --name: test_REVB_D --body: | -- bb.0: -- $r4 = REVB_D $r5 --... ----- --# CHECK-LABEL: test_REVH_2W: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: revh.2w $a0, $a1 --name: test_REVH_2W --body: | -- bb.0: -- $r4 = REVH_2W $r5 --... ----- --# CHECK-LABEL: test_REVH_D: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: revh.d $a0, $a1 --name: test_REVH_D --body: | -- bb.0: -- $r4 = REVH_D $r5 --... ----- --# CHECK-LABEL: test_BITREV_4B: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: bitrev.4b $a0, $a1 --name: test_BITREV_4B --body: | -- bb.0: -- $r4 = BITREV_4B $r5 --... ----- --# CHECK-LABEL: test_BITREV_8B: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: bitrev.8b $a0, $a1 --name: test_BITREV_8B --body: | -- bb.0: -- $r4 = BITREV_8B $r5 --... ----- --# CHECK-LABEL: test_BITREV_W: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: bitrev.w $a0, $a1 --name: test_BITREV_W --body: | -- bb.0: -- $r4 = BITREV_W $r5 --... ----- --# CHECK-LABEL: test_BITREV_D: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: bitrev.d $a0, $a1 --name: test_BITREV_D --body: | -- bb.0: -- $r4 = BITREV_D $r5 --... ----- --# CHECK-LABEL: test_EXT_W_H: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: ext.w.h $a0, $a1 --name: test_EXT_W_H --body: | -- bb.0: -- $r4 = EXT_W_H $r5 --... ----- --# CHECK-LABEL: test_EXT_W_B: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 1 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: ext.w.b $a0, $a1 --name: test_EXT_W_B --body: | -- bb.0: -- $r4 = EXT_W_B $r5 --... ----- --# CHECK-LABEL: test_CPUCFG: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 1 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: cpucfg $a0, $a1 --name: test_CPUCFG --body: | -- bb.0: -- $r4 = CPUCFG $r5 --... ----- --# CHECK-LABEL: test_RDTIMEL_W: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: rdtimel.w $a0, $a1 --name: test_RDTIMEL_W --body: | -- bb.0: -- $r4, $r5 = RDTIMEL_W --... ----- --# CHECK-LABEL: test_RDTIMEH_W: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: rdtimeh.w $a0, $a1 --name: test_RDTIMEH_W --body: | -- bb.0: -- $r4, $r5 = RDTIMEH_W --... ----- --# CHECK-LABEL: test_RDTIME_D: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: rdtime.d $a0, $a1 --name: test_RDTIME_D --body: | -- bb.0: -- $r4, $r5 = RDTIME_D -diff --git a/src/llvm-project/llvm/test/CodeGen/LoongArch/2ri.mir b/src/llvm-project/llvm/test/CodeGen/LoongArch/2ri.mir -deleted file mode 100644 -index 263fed42c..000000000 ---- a/src/llvm-project/llvm/test/CodeGen/LoongArch/2ri.mir -+++ /dev/null -@@ -1,432 +0,0 @@ --# RUN: llc %s -mtriple=loongarch64 -start-after=prologepilog -O0 -filetype=obj -o - \ --# RUN: | extract-section .text \ --# RUN: | FileCheck %s -check-prefix=CHECK-ENC --# RUN: llc %s -mtriple=loongarch64 -start-after=prologepilog -O0 -filetype=asm -o - \ --# RUN: | FileCheck %s -check-prefix=CHECK-ASM -- --# ------------------------------------------------------------------------------------------------- --# Encoding format: 2RI5 --# ------------------------------------------------------------------------------------------------- --# ---------------------------------------------------+--------------+--------------+--------------- --# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 --# ---------------------------------------------------+--------------+--------------+--------------- --# opcode | imm5 | rj | rd --# ---------------------------------------------------+--------------+--------------+--------------- -- ----- --# CHECK-LABEL: test_SLLI_W: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: slli.w $a0, $a1, 0 --name: test_SLLI_W --body: | -- bb.0: -- $r4 = SLLI_W $r5, 0 --... ----- --# CHECK-LABEL: test_SRLI_W: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 1 1 1 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: srli.w $a0, $a1, 30 --name: test_SRLI_W --body: | -- bb.0: -- $r4 = SRLI_W $r5, 30 --... ----- --# CHECK-LABEL: test_SRAI_W: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 1 1 0 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: srai.w $a0, $a1, 24 --name: test_SRAI_W --body: | -- bb.0: -- $r4 = SRAI_W $r5, 24 --... ----- --# CHECK-LABEL: test_ROTRI_W: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 1 0 0 1 1 0 0 1 1 0 1 1 1 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: rotri.w $a0, $a1, 23 --name: test_ROTRI_W --body: | -- bb.0: -- $r4 = ROTRI_W $r5, 23 --... -- --# ------------------------------------------------------------------------------------------------- --# Encoding format: 2RI6 --# ------------------------------------------------------------------------------------------------- --# ------------------------------------------------+-----------------+--------------+--------------- --# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 --# ------------------------------------------------+-----------------+--------------+--------------- --# opcode | imm6 | rj | rd --# ------------------------------------------------+-----------------+--------------+--------------- -- ----- --# CHECK-LABEL: test_SLLI_D: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 1 1 1 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: slli.d $a0, $a1, 39 --name: test_SLLI_D --body: | -- bb.0: -- $r4 = SLLI_D $r5, 39 --... ----- --# CHECK-LABEL: test_SRLI_D: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 1 1 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: srli.d $a0, $a1, 38 --name: test_SRLI_D --body: | -- bb.0: -- $r4 = SRLI_D $r5, 38 --... ----- --# CHECK-LABEL: test_SRAI_D: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 1 1 0 1 1 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: srai.d $a0, $a1, 27 --name: test_SRAI_D --body: | -- bb.0: -- $r4 = SRAI_D $r5, 27 --... ----- --# CHECK-LABEL: test_ROTRI_D: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 1 0 0 1 1 0 1 0 0 0 1 1 1 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: rotri.d $a0, $a1, 7 --name: test_ROTRI_D --body: | -- bb.0: -- $r4 = ROTRI_D $r5, 7 --... -- --# ------------------------------------------------------------------------------------------------- --# Encoding format: 2RI12 --# ------------------------------------------------------------------------------------------------- --# ------------------------------+-----------------------------------+--------------+--------------- --# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 --# ------------------------------+-----------------------------------+--------------+--------------- --# opcode | imm12 | rj | rd --# ------------------------------+-----------------------------------+--------------+--------------- -- ----- --# CHECK-LABEL: test_SLTI: --# CHECK-ENC: 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: slti $a0, $a1, 235 --name: test_SLTI --body: | -- bb.0: -- $r4 = SLTI $r5, 235 --... ----- --# CHECK-LABEL: test_SLTUI: --# CHECK-ENC: 0 0 0 0 0 0 1 0 0 1 0 0 0 0 1 0 1 0 0 0 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: sltui $a0, $a1, 162 --name: test_SLTUI --body: | -- bb.0: -- $r4 = SLTUI $r5, 162 --... ----- --# CHECK-LABEL: test_ADDI_W: --# CHECK-ENC: 0 0 0 0 0 0 1 0 1 0 0 0 0 0 1 1 1 1 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: addi.w $a0, $a1, 246 --name: test_ADDI_W --body: | -- bb.0: -- $r4 = ADDI_W $r5, 246 --... ----- --# CHECK-LABEL: test_ADDI_D: --# CHECK-ENC: 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 1 0 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: addi.d $a0, $a1, 75 --name: test_ADDI_D --body: | -- bb.0: -- $r4 = ADDI_D $r5, 75 --... ----- --# CHECK-LABEL: test_LU52I_D: --# CHECK-ENC: 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 1 1 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: lu52i.d $a0, $a1, 195 --name: test_LU52I_D --body: | -- bb.0: -- $r4 = LU52I_D $r5, 195 --... ----- --# CHECK-LABEL: test_ANDI: --# CHECK-ENC: 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 1 1 0 1 0 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: andi $a0, $a1, 106 --name: test_ANDI --body: | -- bb.0: -- $r4 = ANDI $r5, 106 --... ----- --# CHECK-LABEL: test_ORI: --# CHECK-ENC: 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 1 0 1 1 1 1 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: ori $a0, $a1, 47 --name: test_ORI --body: | -- bb.0: -- $r4 = ORI $r5, 47 --... ----- --# CHECK-LABEL: test_XORI: --# CHECK-ENC: 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 1 1 0 0 0 1 1 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: xori $a0, $a1, 99 --name: test_XORI --body: | -- bb.0: -- $r4 = XORI $r5, 99 --... ----- --# CHECK-LABEL: test_LD_B: --# CHECK-ENC: 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: ld.b $a0, $a1, 21 --name: test_LD_B --body: | -- bb.0: -- $r4 = LD_B $r5, 21 --... ----- --# CHECK-LABEL: test_LD_H: --# CHECK-ENC: 0 0 1 0 1 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: ld.h $a0, $a1, 80 --name: test_LD_H --body: | -- bb.0: -- $r4 = LD_H $r5, 80 --... ----- --# CHECK-LABEL: test_LD_W: --# CHECK-ENC: 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0 1 0 1 1 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: ld.w $a0, $a1, 92 --name: test_LD_W --body: | -- bb.0: -- $r4 = LD_W $r5, 92 --... ----- --# CHECK-LABEL: test_LD_BU: --# CHECK-ENC: 0 0 1 0 1 0 1 0 0 0 0 0 0 0 1 0 0 1 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: ld.bu $a0, $a1, 150 --name: test_LD_BU --body: | -- bb.0: -- $r4 = LD_BU $r5, 150 --... ----- --# CHECK-LABEL: test_LD_HU: --# CHECK-ENC: 0 0 1 0 1 0 1 0 0 1 0 0 0 0 1 1 0 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: ld.hu $a0, $a1, 198 --name: test_LD_HU --body: | -- bb.0: -- $r4 = LD_HU $r5, 198 --... ----- --# CHECK-LABEL: test_LD_WU: --# CHECK-ENC: 0 0 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: ld.wu $a0, $a1, 31 --name: test_LD_WU --body: | -- bb.0: -- $r4 = LD_WU $r5, 31 --... ----- --# CHECK-LABEL: test_ST_B: --# CHECK-ENC: 0 0 1 0 1 0 0 1 0 0 0 0 0 0 0 1 0 1 1 1 1 1 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: st.b $a0, $a1, 95 --name: test_ST_B --body: | -- bb.0: -- ST_B $r4, $r5, 95 --... ----- --# CHECK-LABEL: test_ST_H: --# CHECK-ENC: 0 0 1 0 1 0 0 1 0 1 0 0 0 0 0 1 1 1 1 0 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: st.h $a0, $a1, 122 --name: test_ST_H --body: | -- bb.0: -- ST_H $r4, $r5, 122 --... ----- --# CHECK-LABEL: test_ST_W: --# CHECK-ENC: 0 0 1 0 1 0 0 1 1 0 0 0 0 0 1 0 1 0 1 1 1 1 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: st.w $a0, $a1, 175 --name: test_ST_W --body: | -- bb.0: -- ST_W $r4, $r5, 175 --... ----- --# CHECK-LABEL: test_ST_D: --# CHECK-ENC: 0 0 1 0 1 0 0 1 1 1 0 0 0 0 0 0 1 1 1 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: st.d $a0, $a1, 60 --name: test_ST_D --body: | -- bb.0: -- ST_D $r4, $r5, 60 --... -- --# ------------------------------------------------------------------------------------------------- --# Encoding format: 2RI14 --# ------------------------------------------------------------------------------------------------- --# ------------------------+-----------------------------------------+--------------+--------------- --# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 --# ------------------------+-----------------------------------------+--------------+--------------- --# opcode | imm14 | rj | rd --# ------------------------+-----------------------------------------+--------------+--------------- -- ----- --# CHECK-LABEL: test_LDPTR_W: --# CHECK-ENC: 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: ldptr.w $a0, $a1, 264 --name: test_LDPTR_W --body: | -- bb.0: -- $r4 = LDPTR_W $r5, 264 --... ----- --# CHECK-LABEL: test_LDPTR_D: --# CHECK-ENC: 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: ldptr.d $a0, $a1, 224 --name: test_LDPTR_D --body: | -- bb.0: -- $r4 = LDPTR_D $r5, 224 --... ----- --# CHECK-LABEL: test_STPTR_W: --# CHECK-ENC: 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 1 0 1 0 1 1 1 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: stptr.w $a0, $a1, 348 --name: test_STPTR_W --body: | -- bb.0: -- STPTR_W $r4, $r5, 348 --... ----- --# CHECK-LABEL: test_STPTR_D: --# CHECK-ENC: 0 0 1 0 0 1 1 1 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: stptr.d $a0, $a1, 580 --name: test_STPTR_D --body: | -- bb.0: -- STPTR_D $r4, $r5, 580 --... ----- --# CHECK-LABEL: test_LL_W: --# CHECK-ENC: 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 1 1 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: ll.w $a0, $a1, 972 --name: test_LL_W --body: | -- bb.0: -- $r4 = LL_W $r5, 972 --... ----- --# CHECK-LABEL: test_LL_D: --# CHECK-ENC: 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 1 0 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: ll.d $a0, $a1, 296 --name: test_LL_D --body: | -- bb.0: -- $r4 = LL_D $r5, 296 --... ----- --# CHECK-LABEL: test_SC_W: --# CHECK-ENC: 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: sc.w $a0, $a1, 384 --name: test_SC_W --body: | -- bb.0: -- $r4 = SC_W $r4, $r5, 384 --... ----- --# CHECK-LABEL: test_SC_D: --# CHECK-ENC: 0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 1 1 0 1 0 0 1 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: sc.d $a0, $a1, 420 --name: test_SC_D --body: | -- bb.0: -- $r4 = SC_D $r4, $r5, 420 --... -- --# ------------------------------------------------------------------------------------------------- --# Encoding format: 2RI16 --# ------------------------------------------------------------------------------------------------- --# ------------------+-----------------------------------------------+--------------+--------------- --# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 --# ------------------+-----------------------------------------------+--------------+--------------- --# opcode | imm16 | rj | rd --# ------------------+-----------------------------------------------+--------------+--------------- -- ----- --# CHECK-LABEL: test_ADDU16I_D: --# CHECK-ENC: 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 1 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: addu16i.d $a0, $a1, 23 --name: test_ADDU16I_D --body: | -- bb.0: -- $r4 = ADDU16I_D $r5, 23 --... ----- --# CHECK-LABEL: test_JIRL: --# CHECK-ENC: 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: jirl $a0, $a1, 196 --name: test_JIRL --body: | -- bb.0: -- $r4 = JIRL $r5, 196 --... ----- --# CHECK-LABEL: test_BEQ: --# CHECK-ENC: 0 1 0 1 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 1 --# CHECK-ASM: beq $a0, $a1, 784 --name: test_BEQ --body: | -- bb.0: -- BEQ $r4, $r5, 784 --... ----- --# CHECK-LABEL: test_BNE: --# CHECK-ENC: 0 1 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 0 0 1 0 0 0 0 1 0 1 --# CHECK-ASM: bne $a0, $a1, 76 --name: test_BNE --body: | -- bb.0: -- BNE $r4, $r5, 76 --... ----- --# CHECK-LABEL: test_BLT: --# CHECK-ENC: 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 0 0 1 0 0 0 0 1 0 1 --# CHECK-ASM: blt $a0, $a1, 492 --name: test_BLT --body: | -- bb.0: -- BLT $r4, $r5, 492 --... ----- --# CHECK-LABEL: test_BGE: --# CHECK-ENC: 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 0 0 0 0 1 0 1 --# CHECK-ASM: bge $a0, $a1, 48 --name: test_BGE --body: | -- bb.0: -- BGE $r4, $r5, 48 --... ----- --# CHECK-LABEL: test_BLTU: --# CHECK-ENC: 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 1 0 0 0 0 1 0 1 --# CHECK-ASM: bltu $a0, $a1, 68 --name: test_BLTU --body: | -- bb.0: -- BLTU $r4, $r5, 68 --... ----- --# CHECK-LABEL: test_BGEU: --# CHECK-ENC: 0 1 1 0 1 1 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 1 0 0 0 0 1 0 1 --# CHECK-ASM: bgeu $a0, $a1, 352 --name: test_BGEU --body: | -- bb.0: -- BGEU $r4, $r5, 352 -diff --git a/src/llvm-project/llvm/test/CodeGen/LoongArch/3r.mir b/src/llvm-project/llvm/test/CodeGen/LoongArch/3r.mir -deleted file mode 100644 -index a1b97d563..000000000 ---- a/src/llvm-project/llvm/test/CodeGen/LoongArch/3r.mir -+++ /dev/null -@@ -1,995 +0,0 @@ --# RUN: llc %s -mtriple=loongarch64 -start-after=prologepilog -O0 -filetype=obj -o - \ --# RUN: | extract-section .text \ --# RUN: | FileCheck %s -check-prefix=CHECK-ENC --# RUN: llc %s -mtriple=loongarch64 -start-after=prologepilog -O0 -filetype=asm -o - \ --# RUN: | FileCheck %s -check-prefix=CHECK-ASM -- --# ------------------------------------------------------------------------------------------------- --# Encoding format: 3R --# ------------------------------------------------------------------------------------------------- --# ---------------------------------------------------+--------------+--------------+--------------- --# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 --# ---------------------------------------------------+--------------+--------------+--------------- --# opcode | rk | rj | rd --# ---------------------------------------------------+--------------+--------------+--------------- -- ----- --# CHECK-LABEL: test_ADD_W: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: add.w $a0, $a1, $a0 --name: test_ADD_W --body: | -- bb.0: -- $r4 = ADD_W $r5, $r4 --... ----- --# CHECK-LABEL: test_ADD_D: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: add.d $a0, $a1, $a0 --name: test_ADD_D --body: | -- bb.0: -- $r4 = ADD_D $r5, $r4 --... ----- --# CHECK-LABEL: test_SUB_W: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: sub.w $a0, $a1, $a0 --name: test_SUB_W --body: | -- bb.0: -- $r4 = SUB_W $r5, $r4 --... ----- --# CHECK-LABEL: test_SUB_D: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: sub.d $a0, $a1, $a0 --name: test_SUB_D --body: | -- bb.0: -- $r4 = SUB_D $r5, $r4 --... ----- --# CHECK-LABEL: test_SLT: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: slt $a0, $a1, $a0 --name: test_SLT --body: | -- bb.0: -- $r4 = SLT $r5, $r4 --... ----- --# CHECK-LABEL: test_SLTU: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: sltu $a0, $a1, $a0 --name: test_SLTU --body: | -- bb.0: -- $r4 = SLTU $r5, $r4 --... ----- --# CHECK-LABEL: test_MASKEQZ: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: maskeqz $a0, $a1, $a0 --name: test_MASKEQZ --body: | -- bb.0: -- $r4 = MASKEQZ $r5, $r4 --... ----- --# CHECK-LABEL: test_MASKNEZ: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 1 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: masknez $a0, $a1, $a0 --name: test_MASKNEZ --body: | -- bb.0: -- $r4 = MASKNEZ $r5, $r4 --... ----- --# CHECK-LABEL: test_NOR: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: nor $a0, $a1, $a0 --name: test_NOR --body: | -- bb.0: -- $r4 = NOR $r5, $r4 --... ----- --# CHECK-LABEL: test_AND: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 1 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: and $a0, $a1, $a0 --name: test_AND --body: | -- bb.0: -- $r4 = AND $r5, $r4 --... ----- --# CHECK-LABEL: test_OR: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: or $a0, $a1, $a0 --name: test_OR --body: | -- bb.0: -- $r4 = OR $r5, $r4 --... ----- --# CHECK-LABEL: test_XOR: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 1 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: xor $a0, $a1, $a0 --name: test_XOR --body: | -- bb.0: -- $r4 = XOR $r5, $r4 --... ----- --# CHECK-LABEL: test_ORN: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: orn $a0, $a1, $a0 --name: test_ORN --body: | -- bb.0: -- $r4 = ORN $r5, $r4 --... ----- --# CHECK-LABEL: test_ANDN: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 1 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: andn $a0, $a1, $a0 --name: test_ANDN --body: | -- bb.0: -- $r4 = ANDN $r5, $r4 --... ----- --# CHECK-LABEL: test_SLL_W: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 1 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: sll.w $a0, $a1, $a0 --name: test_SLL_W --body: | -- bb.0: -- $r4 = SLL_W $r5, $r4 --... ----- --# CHECK-LABEL: test_SRL_W: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 1 1 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: srl.w $a0, $a1, $a0 --name: test_SRL_W --body: | -- bb.0: -- $r4 = SRL_W $r5, $r4 --... ----- --# CHECK-LABEL: test_SRA_W: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: sra.w $a0, $a1, $a0 --name: test_SRA_W --body: | -- bb.0: -- $r4 = SRA_W $r5, $r4 --... ----- --# CHECK-LABEL: test_SLL_D: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: sll.d $a0, $a1, $a0 --name: test_SLL_D --body: | -- bb.0: -- $r4 = SLL_D $r5, $r4 --... ----- --# CHECK-LABEL: test_SRL_D: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: srl.d $a0, $a1, $a0 --name: test_SRL_D --body: | -- bb.0: -- $r4 = SRL_D $r5, $r4 --... ----- --# CHECK-LABEL: test_SRA_D: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: sra.d $a0, $a1, $a0 --name: test_SRA_D --body: | -- bb.0: -- $r4 = SRA_D $r5, $r4 --... ----- --# CHECK-LABEL: test_ROTR_W: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 1 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: rotr.w $a0, $a1, $a0 --name: test_ROTR_W --body: | -- bb.0: -- $r4 = ROTR_W $r5, $r4 --... ----- --# CHECK-LABEL: test_ROTR_D: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 1 1 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: rotr.d $a0, $a1, $a0 --name: test_ROTR_D --body: | -- bb.0: -- $r4 = ROTR_D $r5, $r4 --... ----- --# CHECK-LABEL: test_MUL_W: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: mul.w $a0, $a1, $a0 --name: test_MUL_W --body: | -- bb.0: -- $r4 = MUL_W $r5, $r4 --... ----- --# CHECK-LABEL: test_MULH_W: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 1 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: mulh.w $a0, $a1, $a0 --name: test_MULH_W --body: | -- bb.0: -- $r4 = MULH_W $r5, $r4 --... ----- --# CHECK-LABEL: test_MULH_WU: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: mulh.wu $a0, $a1, $a0 --name: test_MULH_WU --body: | -- bb.0: -- $r4 = MULH_WU $r5, $r4 --... ----- --# CHECK-LABEL: test_MUL_D: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 1 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: mul.d $a0, $a1, $a0 --name: test_MUL_D --body: | -- bb.0: -- $r4 = MUL_D $r5, $r4 --... ----- --# CHECK-LABEL: test_MULH_D: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: mulh.d $a0, $a1, $a0 --name: test_MULH_D --body: | -- bb.0: -- $r4 = MULH_D $r5, $r4 --... ----- --# CHECK-LABEL: test_MULH_DU: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: mulh.du $a0, $a1, $a0 --name: test_MULH_DU --body: | -- bb.0: -- $r4 = MULH_DU $r5, $r4 --... ----- --# CHECK-LABEL: test_MULW_D_W: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: mulw.d.w $a0, $a1, $a0 --name: test_MULW_D_W --body: | -- bb.0: -- $r4 = MULW_D_W $r5, $r4 --... ----- --# CHECK-LABEL: test_MULW_D_WU: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: mulw.d.wu $a0, $a1, $a0 --name: test_MULW_D_WU --body: | -- bb.0: -- $r4 = MULW_D_WU $r5, $r4 --... ----- --# CHECK-LABEL: test_DIV_W: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: div.w $a0, $a1, $a0 --name: test_DIV_W --body: | -- bb.0: -- $r4 = DIV_W $r5, $r4 --... ----- --# CHECK-LABEL: test_MOD_W: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: mod.w $a0, $a1, $a0 --name: test_MOD_W --body: | -- bb.0: -- $r4 = MOD_W $r5, $r4 --... ----- --# CHECK-LABEL: test_DIV_WU: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: div.wu $a0, $a1, $a0 --name: test_DIV_WU --body: | -- bb.0: -- $r4 = DIV_WU $r5, $r4 --... ----- --# CHECK-LABEL: test_MOD_WU: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: mod.wu $a0, $a1, $a0 --name: test_MOD_WU --body: | -- bb.0: -- $r4 = MOD_WU $r5, $r4 --... ----- --# CHECK-LABEL: test_DIV_D: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: div.d $a0, $a1, $a0 --name: test_DIV_D --body: | -- bb.0: -- $r4 = DIV_D $r5, $r4 --... ----- --# CHECK-LABEL: test_MOD_D: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 1 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: mod.d $a0, $a1, $a0 --name: test_MOD_D --body: | -- bb.0: -- $r4 = MOD_D $r5, $r4 --... ----- --# CHECK-LABEL: test_DIV_DU: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: div.du $a0, $a1, $a0 --name: test_DIV_DU --body: | -- bb.0: -- $r4 = DIV_DU $r5, $r4 --... ----- --# CHECK-LABEL: test_MOD_DU: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 1 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: mod.du $a0, $a1, $a0 --name: test_MOD_DU --body: | -- bb.0: -- $r4 = MOD_DU $r5, $r4 --... ----- --# CHECK-LABEL: test_CRC_W_B_W: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: crc.w.b.w $a0, $a1, $a0 --name: test_CRC_W_B_W --body: | -- bb.0: -- $r4 = CRC_W_B_W $r5, $r4 --... ----- --# CHECK-LABEL: test_CRC_W_H_W: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: crc.w.h.w $a0, $a1, $a0 --name: test_CRC_W_H_W --body: | -- bb.0: -- $r4 = CRC_W_H_W $r5, $r4 --... ----- --# CHECK-LABEL: test_CRC_W_W_W: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: crc.w.w.w $a0, $a1, $a0 --name: test_CRC_W_W_W --body: | -- bb.0: -- $r4 = CRC_W_W_W $r5, $r4 --... ----- --# CHECK-LABEL: test_CRC_W_D_W: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 1 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: crc.w.d.w $a0, $a1, $a0 --name: test_CRC_W_D_W --body: | -- bb.0: -- $r4 = CRC_W_D_W $r5, $r4 --... ----- --# CHECK-LABEL: test_CRCC_W_B_W: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 0 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: crcc.w.b.w $a0, $a1, $a0 --name: test_CRCC_W_B_W --body: | -- bb.0: -- $r4 = CRCC_W_B_W $r5, $r4 --... ----- --# CHECK-LABEL: test_CRCC_W_H_W: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 0 1 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: crcc.w.h.w $a0, $a1, $a0 --name: test_CRCC_W_H_W --body: | -- bb.0: -- $r4 = CRCC_W_H_W $r5, $r4 --... ----- --# CHECK-LABEL: test_CRCC_W_W_W: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 1 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: crcc.w.w.w $a0, $a1, $a0 --name: test_CRCC_W_W_W --body: | -- bb.0: -- $r4 = CRCC_W_W_W $r5, $r4 --... ----- --# CHECK-LABEL: test_CRCC_W_D_W: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 1 1 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: crcc.w.d.w $a0, $a1, $a0 --name: test_CRCC_W_D_W --body: | -- bb.0: -- $r4 = CRCC_W_D_W $r5, $r4 --... ----- --# CHECK-LABEL: test_AMSWAP_DB_W: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 0 1 0 0 1 0 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 --# CHECK-ASM: amswap_db.w $a0, $a1, $a2 --name: test_AMSWAP_DB_W --body: | -- bb.0: -- $r4 = AMSWAP_DB_W $r5, $r6 --... ----- --# CHECK-LABEL: test_AMSWAP_DB_D: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 0 1 0 0 1 1 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 --# CHECK-ASM: amswap_db.d $a0, $a1, $a2 --name: test_AMSWAP_DB_D --body: | -- bb.0: -- $r4 = AMSWAP_DB_D $r5, $r6 --... ----- --# CHECK-LABEL: test_AMADD_DB_W: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 0 1 0 1 0 0 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 --# CHECK-ASM: amadd_db.w $a0, $a1, $a2 --name: test_AMADD_DB_W --body: | -- bb.0: -- $r4 = AMADD_DB_W $r5, $r6 --... ----- --# CHECK-LABEL: test_AMADD_DB_D: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 0 1 0 1 0 1 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 --# CHECK-ASM: amadd_db.d $a0, $a1, $a2 --name: test_AMADD_DB_D --body: | -- bb.0: -- $r4 = AMADD_DB_D $r5, $r6 --... ----- --# CHECK-LABEL: test_AMAND_DB_W: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 --# CHECK-ASM: amand_db.w $a0, $a1, $a2 --name: test_AMAND_DB_W --body: | -- bb.0: -- $r4 = AMAND_DB_W $r5, $r6 --... ----- --# CHECK-LABEL: test_AMAND_DB_D: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 0 1 0 1 1 1 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 --# CHECK-ASM: amand_db.d $a0, $a1, $a2 --name: test_AMAND_DB_D --body: | -- bb.0: -- $r4 = AMAND_DB_D $r5, $r6 --... ----- --# CHECK-LABEL: test_AMOR_DB_W: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 0 1 1 0 0 0 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 --# CHECK-ASM: amor_db.w $a0, $a1, $a2 --name: test_AMOR_DB_W --body: | -- bb.0: -- $r4 = AMOR_DB_W $r5, $r6 --... ----- --# CHECK-LABEL: test_AMOR_DB_D: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 0 1 1 0 0 1 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 --# CHECK-ASM: amor_db.d $a0, $a1, $a2 --name: test_AMOR_DB_D --body: | -- bb.0: -- $r4 = AMOR_DB_D $r5, $r6 --... ----- --# CHECK-LABEL: test_AMXOR_DB_W: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 0 1 1 0 1 0 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 --# CHECK-ASM: amxor_db.w $a0, $a1, $a2 --name: test_AMXOR_DB_W --body: | -- bb.0: -- $r4 = AMXOR_DB_W $r5, $r6 --... ----- --# CHECK-LABEL: test_AMXOR_DB_D: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 0 1 1 0 1 1 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 --# CHECK-ASM: amxor_db.d $a0, $a1, $a2 --name: test_AMXOR_DB_D --body: | -- bb.0: -- $r4 = AMXOR_DB_D $r5, $r6 --... ----- --# CHECK-LABEL: test_AMMAX_DB_W: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 0 1 1 1 0 0 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 --# CHECK-ASM: ammax_db.w $a0, $a1, $a2 --name: test_AMMAX_DB_W --body: | -- bb.0: -- $r4 = AMMAX_DB_W $r5, $r6 --... ----- --# CHECK-LABEL: test_AMMAX_DB_D: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 0 1 1 1 0 1 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 --# CHECK-ASM: ammax_db.d $a0, $a1, $a2 --name: test_AMMAX_DB_D --body: | -- bb.0: -- $r4 = AMMAX_DB_D $r5, $r6 --... ----- --# CHECK-LABEL: test_AMMIN_DB_W: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 0 1 1 1 1 0 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 --# CHECK-ASM: ammin_db.w $a0, $a1, $a2 --name: test_AMMIN_DB_W --body: | -- bb.0: -- $r4 = AMMIN_DB_W $r5, $r6 --... ----- --# CHECK-LABEL: test_AMMIN_DB_D: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 0 1 1 1 1 1 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 --# CHECK-ASM: ammin_db.d $a0, $a1, $a2 --name: test_AMMIN_DB_D --body: | -- bb.0: -- $r4 = AMMIN_DB_D $r5, $r6 --... ----- --# CHECK-LABEL: test_AMMAX_DB_WU: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 1 0 0 0 0 0 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 --# CHECK-ASM: ammax_db.wu $a0, $a1, $a2 --name: test_AMMAX_DB_WU --body: | -- bb.0: -- $r4 = AMMAX_DB_WU $r5, $r6 --... ----- --# CHECK-LABEL: test_AMMAX_DB_DU: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 1 0 0 0 0 1 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 --# CHECK-ASM: ammax_db.du $a0, $a1, $a2 --name: test_AMMAX_DB_DU --body: | -- bb.0: -- $r4 = AMMAX_DB_DU $r5, $r6 --... ----- --# CHECK-LABEL: test_AMMIN_DB_WU: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 1 0 0 0 1 0 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 --# CHECK-ASM: ammin_db.wu $a0, $a1, $a2 --name: test_AMMIN_DB_WU --body: | -- bb.0: -- $r4 = AMMIN_DB_WU $r5, $r6 --... ----- --# CHECK-LABEL: test_AMMIN_DB_DU: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 1 0 0 0 1 1 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 --# CHECK-ASM: ammin_db.du $a0, $a1, $a2 --name: test_AMMIN_DB_DU --body: | -- bb.0: -- $r4 = AMMIN_DB_DU $r5, $r6 --... ----- --# CHECK-LABEL: test_AMSWAP_W: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 --# CHECK-ASM: amswap.w $a0, $a1, $a2 --name: test_AMSWAP_W --body: | -- bb.0: -- $r4 = AMSWAP_W $r5, $r6 --... ----- --# CHECK-LABEL: test_AMSWAP_D: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 0 0 0 0 0 1 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 --# CHECK-ASM: amswap.d $a0, $a1, $a2 --name: test_AMSWAP_D --body: | -- bb.0: -- $r4 = AMSWAP_D $r5, $r6 --... ----- --# CHECK-LABEL: test_AMADD_W: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 0 0 0 0 1 0 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 --# CHECK-ASM: amadd.w $a0, $a1, $a2 --name: test_AMADD_W --body: | -- bb.0: -- $r4 = AMADD_W $r5, $r6 --... ----- --# CHECK-LABEL: test_AMADD_D: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 0 0 0 0 1 1 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 --# CHECK-ASM: amadd.d $a0, $a1, $a2 --name: test_AMADD_D --body: | -- bb.0: -- $r4 = AMADD_D $r5, $r6 --... ----- --# CHECK-LABEL: test_AMAND_W: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 0 0 0 1 0 0 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 --# CHECK-ASM: amand.w $a0, $a1, $a2 --name: test_AMAND_W --body: | -- bb.0: -- $r4 = AMAND_W $r5, $r6 --... ----- --# CHECK-LABEL: test_AMAND_D: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 0 0 0 1 0 1 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 --# CHECK-ASM: amand.d $a0, $a1, $a2 --name: test_AMAND_D --body: | -- bb.0: -- $r4 = AMAND_D $r5, $r6 --... ----- --# CHECK-LABEL: test_AMOR_W: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 0 0 0 1 1 0 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 --# CHECK-ASM: amor.w $a0, $a1, $a2 --name: test_AMOR_W --body: | -- bb.0: -- $r4 = AMOR_W $r5, $r6 --... ----- --# CHECK-LABEL: test_AMOR_D: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 0 0 0 1 1 1 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 --# CHECK-ASM: amor.d $a0, $a1, $a2 --name: test_AMOR_D --body: | -- bb.0: -- $r4 = AMOR_D $r5, $r6 --... ----- --# CHECK-LABEL: test_AMXOR_W: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 0 0 1 0 0 0 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 --# CHECK-ASM: amxor.w $a0, $a1, $a2 --name: test_AMXOR_W --body: | -- bb.0: -- $r4 = AMXOR_W $r5, $r6 --... ----- --# CHECK-LABEL: test_AMXOR_D: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 0 0 1 0 0 1 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 --# CHECK-ASM: amxor.d $a0, $a1, $a2 --name: test_AMXOR_D --body: | -- bb.0: -- $r4 = AMXOR_D $r5, $r6 --... ----- --# CHECK-LABEL: test_AMMAX_W: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 0 0 1 0 1 0 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 --# CHECK-ASM: ammax.w $a0, $a1, $a2 --name: test_AMMAX_W --body: | -- bb.0: -- $r4 = AMMAX_W $r5, $r6 --... ----- --# CHECK-LABEL: test_AMMAX_D: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 0 0 1 0 1 1 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 --# CHECK-ASM: ammax.d $a0, $a1, $a2 --name: test_AMMAX_D --body: | -- bb.0: -- $r4 = AMMAX_D $r5, $r6 --... ----- --# CHECK-LABEL: test_AMMIN_W: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 0 0 1 1 0 0 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 --# CHECK-ASM: ammin.w $a0, $a1, $a2 --name: test_AMMIN_W --body: | -- bb.0: -- $r4 = AMMIN_W $r5, $r6 --... ----- --# CHECK-LABEL: test_AMMIN_D: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 0 0 1 1 0 1 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 --# CHECK-ASM: ammin.d $a0, $a1, $a2 --name: test_AMMIN_D --body: | -- bb.0: -- $r4 = AMMIN_D $r5, $r6 --... ----- --# CHECK-LABEL: test_AMMAX_WU: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 0 0 1 1 1 0 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 --# CHECK-ASM: ammax.wu $a0, $a1, $a2 --name: test_AMMAX_WU --body: | -- bb.0: -- $r4 = AMMAX_WU $r5, $r6 --... ----- --# CHECK-LABEL: test_AMMAX_DU: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 0 0 1 1 1 1 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 --# CHECK-ASM: ammax.du $a0, $a1, $a2 --name: test_AMMAX_DU --body: | -- bb.0: -- $r4 = AMMAX_DU $r5, $r6 --... ----- --# CHECK-LABEL: test_AMMIN_WU: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 0 1 0 0 0 0 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 --# CHECK-ASM: ammin.wu $a0, $a1, $a2 --name: test_AMMIN_WU --body: | -- bb.0: -- $r4 = AMMIN_WU $r5, $r6 --... ----- --# CHECK-LABEL: test_AMMIN_DU: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 0 1 0 0 0 1 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 --# CHECK-ASM: ammin.du $a0, $a1, $a2 --name: test_AMMIN_DU --body: | -- bb.0: -- $r4 = AMMIN_DU $r5, $r6 --... ----- --# CHECK-LABEL: test_LDX_B: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: ldx.b $a0, $a1, $a2 --name: test_LDX_B --body: | -- bb.0: -- $r4 = LDX_B $r5, $r6 --... ----- --# CHECK-LABEL: test_LDX_H: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: ldx.h $a0, $a1, $a2 --name: test_LDX_H --body: | -- bb.0: -- $r4 = LDX_H $r5, $r6 --... ----- --# CHECK-LABEL: test_LDX_W: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: ldx.w $a0, $a1, $a2 --name: test_LDX_W --body: | -- bb.0: -- $r4 = LDX_W $r5, $r6 --... ----- --# CHECK-LABEL: test_LDX_D: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: ldx.d $a0, $a1, $a2 --name: test_LDX_D --body: | -- bb.0: -- $r4 = LDX_D $r5, $r6 --... ----- --# CHECK-LABEL: test_LDX_BU: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: ldx.bu $a0, $a1, $a2 --name: test_LDX_BU --body: | -- bb.0: -- $r4 = LDX_BU $r5, $r6 --... ----- --# CHECK-LABEL: test_LDX_HU: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: ldx.hu $a0, $a1, $a2 --name: test_LDX_HU --body: | -- bb.0: -- $r4 = LDX_HU $r5, $r6 --... ----- --# CHECK-LABEL: test_LDX_WU: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: ldx.wu $a0, $a1, $a2 --name: test_LDX_WU --body: | -- bb.0: -- $r4 = LDX_WU $r5, $r6 --... ----- --# CHECK-LABEL: test_LDGT_B: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: ldgt.b $a0, $a1, $a2 --name: test_LDGT_B --body: | -- bb.0: -- $r4 = LDGT_B $r5, $r6 --... ----- --# CHECK-LABEL: test_LDGT_H: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 1 1 0 0 0 1 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: ldgt.h $a0, $a1, $a2 --name: test_LDGT_H --body: | -- bb.0: -- $r4 = LDGT_H $r5, $r6 --... ----- --# CHECK-LABEL: test_LDGT_W: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 1 1 0 0 1 0 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: ldgt.w $a0, $a1, $a2 --name: test_LDGT_W --body: | -- bb.0: -- $r4 = LDGT_W $r5, $r6 --... ----- --# CHECK-LABEL: test_LDGT_D: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 1 1 0 0 1 1 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: ldgt.d $a0, $a1, $a2 --name: test_LDGT_D --body: | -- bb.0: -- $r4 = LDGT_D $r5, $r6 --... ----- --# CHECK-LABEL: test_LDLE_B: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 1 1 0 1 0 0 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: ldle.b $a0, $a1, $a2 --name: test_LDLE_B --body: | -- bb.0: -- $r4 = LDLE_B $r5, $r6 --... ----- --# CHECK-LABEL: test_LDLE_H: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 1 1 0 1 0 1 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: ldle.h $a0, $a1, $a2 --name: test_LDLE_H --body: | -- bb.0: -- $r4 = LDLE_H $r5, $r6 --... ----- --# CHECK-LABEL: test_LDLE_W: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 1 1 0 1 1 0 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: ldle.w $a0, $a1, $a2 --name: test_LDLE_W --body: | -- bb.0: -- $r4 = LDLE_W $r5, $r6 --... ----- --# CHECK-LABEL: test_LDLE_D: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 1 1 0 1 1 1 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: ldle.d $a0, $a1, $a2 --name: test_LDLE_D --body: | -- bb.0: -- $r4 = LDLE_D $r5, $r6 --... ----- --# CHECK-LABEL: test_STX_B: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: stx.b $a0, $a1, $a2 --name: test_STX_B --body: | -- bb.0: -- STX_B $r4, $r5, $r6 --... ----- --# CHECK-LABEL: test_STX_H: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: stx.h $a0, $a1, $a2 --name: test_STX_H --body: | -- bb.0: -- STX_H $r4, $r5, $r6 --... ----- --# CHECK-LABEL: test_STX_W: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: stx.w $a0, $a1, $a2 --name: test_STX_W --body: | -- bb.0: -- STX_W $r4, $r5, $r6 --... ----- --# CHECK-LABEL: test_STX_D: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: stx.d $a0, $a1, $a2 --name: test_STX_D --body: | -- bb.0: -- STX_D $r4, $r5, $r6 --... ----- --# CHECK-LABEL: test_STGT_B: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 1 1 1 0 0 0 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: stgt.b $a0, $a1, $a2 --name: test_STGT_B --body: | -- bb.0: -- STGT_B $r4, $r5, $r6 --... ----- --# CHECK-LABEL: test_STGT_H: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 1 1 1 0 0 1 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: stgt.h $a0, $a1, $a2 --name: test_STGT_H --body: | -- bb.0: -- STGT_H $r4, $r5, $r6 --... ----- --# CHECK-LABEL: test_STGT_W: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 1 1 1 0 1 0 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: stgt.w $a0, $a1, $a2 --name: test_STGT_W --body: | -- bb.0: -- STGT_W $r4, $r5, $r6 --... ----- --# CHECK-LABEL: test_STGT_D: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 1 1 1 0 1 1 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: stgt.d $a0, $a1, $a2 --name: test_STGT_D --body: | -- bb.0: -- STGT_D $r4, $r5, $r6 --... ----- --# CHECK-LABEL: test_STLE_B: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 1 1 1 1 0 0 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: stle.b $a0, $a1, $a2 --name: test_STLE_B --body: | -- bb.0: -- STLE_B $r4, $r5, $r6 --... ----- --# CHECK-LABEL: test_STLE_H: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 1 1 1 1 0 1 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: stle.h $a0, $a1, $a2 --name: test_STLE_H --body: | -- bb.0: -- STLE_H $r4, $r5, $r6 --... ----- --# CHECK-LABEL: test_STLE_W: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 1 1 1 1 1 0 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: stle.w $a0, $a1, $a2 --name: test_STLE_W --body: | -- bb.0: -- STLE_W $r4, $r5, $r6 --... ----- --# CHECK-LABEL: test_STLE_D: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: stle.d $a0, $a1, $a2 --name: test_STLE_D --body: | -- bb.0: -- STLE_D $r4, $r5, $r6 -diff --git a/src/llvm-project/llvm/test/CodeGen/LoongArch/3ri.mir b/src/llvm-project/llvm/test/CodeGen/LoongArch/3ri.mir -deleted file mode 100644 -index c86e14189..000000000 ---- a/src/llvm-project/llvm/test/CodeGen/LoongArch/3ri.mir -+++ /dev/null -@@ -1,69 +0,0 @@ --# RUN: llc %s -mtriple=loongarch64 -start-after=prologepilog -O0 -filetype=obj -o - \ --# RUN: | extract-section .text \ --# RUN: | FileCheck %s -check-prefix=CHECK-ENC --# RUN: llc %s -mtriple=loongarch64 -start-after=prologepilog -O0 -filetype=asm -o - \ --# RUN: | FileCheck %s -check-prefix=CHECK-ASM -- --# ------------------------------------------------------------------------------------------------- --# Encoding format: 3RI2 --# ------------------------------------------------------------------------------------------------- --# ---------------------------------------------+-----+--------------+--------------+--------------- --# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 --# ---------------------------------------------+-----+--------------+--------------+--------------- --# opcode |imm2 | rk | rj | rd --# ---------------------------------------------+-----+--------------+--------------+--------------- -- ----- --# CHECK-LABEL: test_ALSL_W: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: alsl.w $a0, $a1, $a2, 4 --name: test_ALSL_W --body: | -- bb.0: -- $r4 = ALSL_W $r5, $r6, 4 --... ----- --# CHECK-LABEL: test_ALSL_WU: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: alsl.wu $a0, $a1, $a2, 2 --name: test_ALSL_WU --body: | -- bb.0: -- $r4 = ALSL_WU $r5, $r6, 2 --... ----- --# CHECK-LABEL: test_ALSL_D: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 1 1 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: alsl.d $a0, $a1, $a2, 4 --name: test_ALSL_D --body: | -- bb.0: -- $r4 = ALSL_D $r5, $r6, 4 --... ----- --# CHECK-LABEL: test_BYTEPICK_W: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: bytepick.w $a0, $a1, $a2, 0 --name: test_BYTEPICK_W --body: | -- bb.0: -- $r4 = BYTEPICK_W $r5, $r6, 0 --... -- --# ------------------------------------------------------------------------------------------------- --# Encoding format: 3RI3 --# ------------------------------------------------------------------------------------------------- --# ------------------------------------------+--------+--------------+--------------+--------------- --# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 --# ------------------------------------------+--------+--------------+--------------+--------------- --# opcode | imm3 | rk | rj | rd --# ------------------------------------------+--------+--------------+--------------+--------------- -- ----- --# CHECK-LABEL: test_BYTEPICK_D: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: bytepick.d $a0, $a1, $a2, 4 --name: test_BYTEPICK_D --body: | -- bb.0: -- $r4 = BYTEPICK_D $r5, $r6, 4 -diff --git a/src/llvm-project/llvm/test/CodeGen/LoongArch/align.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/align.ll -new file mode 100644 -index 000000000..c5b08dbd4 ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/atomic-operand-imm0.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/atomic-operand-imm0.ll -new file mode 100644 -index 000000000..d1d0c0bc4 ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/atomic_16_8.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/atomic_16_8.ll -new file mode 100644 -index 000000000..d5c3e0dad ---- /dev/null -+++ b/src/llvm-project/llvm/test/CodeGen/LoongArch/atomic_16_8.ll -@@ -0,0 +1,809 @@ -+; 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: dbar 0 -+; 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: dbar 0 -+; 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: dbar 0 -+; 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: dbar 0 -+; 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: dbar 0 -+; 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: dbar 0 -+; 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: dbar 0 -+; 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: dbar 0 -+; 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: dbar 0 -+; 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: dbar 0 -+; 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: dbar 0 -+; 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: dbar 0 -+; 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: dbar 0 -+; 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: dbar 0 -+; 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: dbar 0 -+; 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: dbar 0 -+; 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: dbar 0 -+; 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: dbar 0 -+; 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: dbar 0 -+; 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: dbar 0 -+; 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: dbar 0 -+; 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: dbar 0 -+; 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: dbar 0 -+; 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 1792 -+; 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: dbar 0 -+; 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 1792 -+; 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/src/llvm-project/llvm/test/CodeGen/LoongArch/atomic_64_32.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/atomic_64_32.ll -new file mode 100644 -index 000000000..ce400fd43 ---- /dev/null -+++ b/src/llvm-project/llvm/test/CodeGen/LoongArch/atomic_64_32.ll -@@ -0,0 +1,327 @@ -+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py -+; RUN: llc -mtriple=loongarch64 -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: .LBB0_1: # =>This Inner Loop Header: Depth=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: .LBB1_1: # =>This Inner Loop Header: Depth=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: .LBB2_1: # =>This Inner Loop Header: Depth=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: .LBB3_1: # =>This Inner Loop Header: Depth=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: .LBB4_1: # =>This Inner Loop Header: Depth=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: .LBB5_1: # =>This Inner Loop Header: Depth=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: .LBB6_1: # =>This Inner Loop Header: Depth=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: .LBB7_1: # =>This Inner Loop Header: Depth=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: .LBB8_1: # =>This Inner Loop Header: Depth=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: .LBB9_1: # =>This Inner Loop Header: Depth=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: .LBB10_1: # =>This Inner Loop Header: Depth=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: .LBB11_1: # =>This Inner Loop Header: Depth=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: .LBB12_1: # =>This Inner Loop Header: Depth=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: .LBB13_1: # =>This Inner Loop Header: Depth=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: .LBB14_1: # =>This Inner Loop Header: Depth=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: .LBB15_1: # =>This Inner Loop Header: Depth=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: dbar 1792 -+; 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: dbar 1792 -+; 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: .LBB18_1: # =>This Inner Loop Header: Depth=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: .LBB19_1: # =>This Inner Loop Header: Depth=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: .LBB20_1: # =>This Inner Loop Header: Depth=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: .LBB21_1: # =>This Inner Loop Header: Depth=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: dbar 0 -+; 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 1792 -+; 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: dbar 0 -+; 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 1792 -+; CHECK-NEXT: jr $ra -+ %ret = cmpxchg i64* %ptr, i64 100, i64 1 seq_cst seq_cst -+ ret void -+} -diff --git a/src/llvm-project/llvm/test/CodeGen/LoongArch/bss.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/bss.ll -new file mode 100644 -index 000000000..cfc30b3a7 ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/builtins-loongarch-base.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/builtins-loongarch-base.ll -new file mode 100644 -index 000000000..d6c8e72f2 ---- /dev/null -+++ b/src/llvm-project/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, 8 -+; 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, 8 -+; 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, 8 -+; 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, 8 -+; 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, 4 -+; 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, 4 -+; 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, 4 -+; 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, 4 -+; 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/src/llvm-project/llvm/test/CodeGen/LoongArch/const-mult.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/const-mult.ll -new file mode 100644 -index 000000000..955e16268 ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/disable-tail-calls.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/disable-tail-calls.ll -new file mode 100644 -index 000000000..586daca23 ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/divrem.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/divrem.ll -new file mode 100644 -index 000000000..34293a83c ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/dup-tail.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/dup-tail.ll -new file mode 100644 -index 000000000..cad67e98c ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/eliminateFI.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/eliminateFI.ll -new file mode 100644 -index 000000000..0272c95bd ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/emergency-spill-slot.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/emergency-spill-slot.ll -new file mode 100644 -index 000000000..80fa7a855 ---- /dev/null -+++ b/src/llvm-project/llvm/test/CodeGen/LoongArch/emergency-spill-slot.ll -@@ -0,0 +1,103 @@ -+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py -+; RUN: llc --mtriple=loongarch64 -O0 < %s | FileCheck %s -+ -+@var = external global i32 -+ -+define void @func() { -+; CHECK-LABEL: func: -+; CHECK: # %bb.0: -+; CHECK-NEXT: addi.d $sp, $sp, -2048 -+; CHECK-NEXT: addi.d $sp, $sp, -2048 -+; CHECK-NEXT: addi.d $sp, $sp, -16 -+; CHECK-NEXT: .cfi_def_cfa_offset 4112 -+; 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, 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, i32* %space -+ -+ ;; store values so they are used. -+ 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/src/llvm-project/llvm/test/CodeGen/LoongArch/fcopysign.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/fcopysign.ll -new file mode 100644 -index 000000000..c16413715 ---- /dev/null -+++ b/src/llvm-project/llvm/test/CodeGen/LoongArch/fcopysign.ll -@@ -0,0 +1,17 @@ -+; RUN: llc -march=loongarch64 -o - %s | FileCheck %s -+ -+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 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/src/llvm-project/llvm/test/CodeGen/LoongArch/frame-info.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/frame-info.ll -new file mode 100644 -index 000000000..eb4fc69fa ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/fsel.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/fsel.ll -new file mode 100644 -index 000000000..f41ee08c0 ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/immediate.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/immediate.ll -new file mode 100644 -index 000000000..1de3ef0fc ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/inlineasm/extra-code.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/inlineasm/extra-code.ll -new file mode 100644 -index 000000000..986e27e2a ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/inlineasm/floating-point-in-gpr.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/inlineasm/floating-point-in-gpr.ll -new file mode 100644 -index 000000000..94e330673 ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/inlineasm/non-native-value-type-registers-error.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/inlineasm/non-native-value-type-registers-error.ll -new file mode 100644 -index 000000000..7f58ea2ee ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/inlineasm/non-native-value-type-registers.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/inlineasm/non-native-value-type-registers.ll -new file mode 100644 -index 000000000..d18a184ab ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/inlineasm/preld.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/inlineasm/preld.ll -new file mode 100644 -index 000000000..8dbbed99f ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/jirl-verify.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/jirl-verify.ll -new file mode 100644 -index 000000000..70b588bea ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/VExtend.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/VExtend.ll -new file mode 100644 -index 000000000..1b4b52c7a ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/imm_vector_lasx.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/imm_vector_lasx.ll -new file mode 100644 -index 000000000..07b80895b ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/inline-asm.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/inline-asm.ll -new file mode 100644 -index 000000000..337632491 ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/insert-lasx.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/insert-lasx.ll -new file mode 100644 -index 000000000..51fa34606 ---- /dev/null -+++ b/src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/insert-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 <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 -+} -diff --git a/src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/intrinsic-lasx.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/intrinsic-lasx.ll -new file mode 100644 -index 000000000..05b720077 ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/lasxvclr.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/lasxvclr.ll -new file mode 100644 -index 000000000..b40698104 ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/logic-lasx.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/logic-lasx.ll -new file mode 100644 -index 000000000..ff28569a1 ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/set-lasx.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/set-lasx.ll -new file mode 100644 -index 000000000..443262eac ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/shuffle_v4i64_1032.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/shuffle_v4i64_1032.ll -new file mode 100644 -index 000000000..965cfe94c ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/vext2xv.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/vext2xv.ll -new file mode 100644 -index 000000000..7bd3dca73 ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/xvadda.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/xvadda.ll -new file mode 100644 -index 000000000..a849fef3e ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/xvaddsub.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/xvaddsub.ll -new file mode 100644 -index 000000000..eb2c493d2 ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/xvhadd.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/xvhadd.ll -new file mode 100644 -index 000000000..5b452c5eb ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/xvilvh.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/xvilvh.ll -new file mode 100644 -index 000000000..11f96f435 ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/xvilvl.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/lasx/xvilvl.ll -new file mode 100644 -index 000000000..7249bc76c ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/ldptr.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/ldptr.ll -new file mode 100644 -index 000000000..8395b264f ---- /dev/null -+++ b/src/llvm-project/llvm/test/CodeGen/LoongArch/ldptr.ll -@@ -0,0 +1,70 @@ -+; 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 -+ -+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, i32* %p, i64 511 -+ %val = load i32, i32* %addr, align 4 -+ ret i32 %val -+} -+ -+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, i32* %p, i64 512 -+ %val = load i32, i32* %addr, align 4 -+ ret i32 %val -+} -+ -+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, i32* %p, i64 8192 -+ %val = load i32, i32* %addr, align 4 -+ ret i32 %val -+} -+ -+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, i64* %p, i64 255 -+ %val = load i64, i64* %addr, align 8 -+ ret i64 %val -+} -+ -+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, i64* %p, i64 256 -+ %val = load i64, i64* %addr, align 8 -+ ret i64 %val -+} -+ -+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, i64* %p, i64 4096 -+ %val = load i64, i64* %addr, align 8 -+ ret i64 %val -+} -diff --git a/src/llvm-project/llvm/test/CodeGen/LoongArch/lit.local.cfg b/src/llvm-project/llvm/test/CodeGen/LoongArch/lit.local.cfg -index a54f5aeca..6223fc691 100644 ---- a/src/llvm-project/llvm/test/CodeGen/LoongArch/lit.local.cfg -+++ b/src/llvm-project/llvm/test/CodeGen/LoongArch/lit.local.cfg -@@ -1,13 +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: - config.unsupported = True -+ -diff --git a/src/llvm-project/llvm/test/CodeGen/LoongArch/logic-op.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/logic-op.ll -new file mode 100644 -index 000000000..c1029c1ff ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/lshr.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/lshr.ll -new file mode 100644 -index 000000000..54e4a5f2d ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/lsx/imm_vector_lsx.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/lsx/imm_vector_lsx.ll -new file mode 100644 -index 000000000..97b23be80 ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/lsx/inline-asm.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/lsx/inline-asm.ll -new file mode 100644 -index 000000000..37cb6dfc9 ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/lsx/intrinsic-lsx.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/lsx/intrinsic-lsx.ll -new file mode 100644 -index 000000000..60ff93095 ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/lsx/logic-lsx.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/lsx/logic-lsx.ll -new file mode 100644 -index 000000000..0dd29b27e ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/lsx/lsxvclr.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/lsx/lsxvclr.ll -new file mode 100644 -index 000000000..951254baa ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/lsx/set-lsx.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/lsx/set-lsx.ll -new file mode 100644 -index 000000000..69f19297d ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/lsx/vadda.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/lsx/vadda.ll -new file mode 100644 -index 000000000..4c987fb1b ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/lu12i.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/lu12i.ll -new file mode 100644 -index 000000000..55fd40edd ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/mcpu_load.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/mcpu_load.ll -new file mode 100644 -index 000000000..c0c782fea ---- /dev/null -+++ b/src/llvm-project/llvm/test/CodeGen/LoongArch/mcpu_load.ll -@@ -0,0 +1,72 @@ -+; 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 -+ -+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/src/llvm-project/llvm/test/CodeGen/LoongArch/misc.mir b/src/llvm-project/llvm/test/CodeGen/LoongArch/misc.mir -deleted file mode 100644 -index 56793c583..000000000 ---- a/src/llvm-project/llvm/test/CodeGen/LoongArch/misc.mir -+++ /dev/null -@@ -1,200 +0,0 @@ --# RUN: llc %s -mtriple=loongarch64 -start-after=prologepilog -O0 -filetype=obj -o - \ --# RUN: | extract-section .text \ --# RUN: | FileCheck %s -check-prefix=CHECK-ENC --# RUN: llc %s -mtriple=loongarch64 -start-after=prologepilog -O0 -filetype=asm -o - \ --# RUN: | FileCheck %s -check-prefix=CHECK-ASM -- --# ------------------------------------------------------------------------------------------------- --# Encoding format: I15 --# ------------------------------------------------------------------------------------------------- --# ---------------------------------------------------+--------------------------------------------- --# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 --# ---------------------------------------------------+--------------------------------------------- --# opcode | imm15 --# ---------------------------------------------------+--------------------------------------------- -- ----- --# CHECK-LABEL: test_DBAR: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 --# CHECK-ASM: dbar 0 --name: test_DBAR --body: | -- bb.0: -- DBAR 0 --... ----- --# CHECK-LABEL: test_IBAR: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 1 1 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 --# CHECK-ASM: ibar 0 --name: test_IBAR --body: | -- bb.0: -- IBAR 0 --... ----- --# CHECK-LABEL: test_SYSCALL: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 1 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 0 --# CHECK-ASM: syscall 100 --name: test_SYSCALL --body: | -- bb.0: -- SYSCALL 100 --... ----- --# CHECK-LABEL: test_BREAK: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 1 --# CHECK-ASM: break 199 --name: test_BREAK --body: | -- bb.0: -- BREAK 199 --... -- --# ------------------------------------------------------------------------------------------------- --# Encoding format: I26 --# ------------------------------------------------------------------------------------------------- --# ------------------+-----------------------------------------------+------------------------------ --# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 --# ------------------+-----------------------------------------------+------------------------------ --# opcode | imm26{15-0} | imm26{25-16} --# ------------------+-----------------------------------------------+------------------------------ -- ----- --# CHECK-LABEL: test_B: --# CHECK-ENC: 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 --# CHECK-ASM: b 80 --name: test_B --body: | -- bb.0: -- B 80 --... ----- --# CHECK-LABEL: test_BL: --# CHECK-ENC: 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 --# CHECK-ASM: bl 136 --name: test_BL --body: | -- bb.0: -- BL 136 --... -- --# -------------------------------------------------------------------------------------------------------- --# Encoding format: BSTR_W --# -------------------------------------------------------------------------------------------------------- --# ---------------------------------+--------------+---------+--------------+--------------+--------------- --# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 --# ---------------------------------+--------------+---------+--------------+--------------+--------------- --# opcode{11-1} | msb |opcode{0}| lsb | rj | rd --# ---------------------------------+--------------+---------+--------------+--------------+--------------- -- ----- --# CHECK-LABEL: test_BSTRINS_W: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 1 0 0 0 0 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: bstrins.w $a0, $a1, 7, 2 --name: test_BSTRINS_W --body: | -- bb.0: -- $r4 = BSTRINS_W $r4, $r5, 7, 2 --... ----- --# CHECK-LABEL: test_BSTRPICK_W: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 1 1 0 1 0 1 0 1 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: bstrpick.w $a0, $a1, 10, 4 --name: test_BSTRPICK_W --body: | -- bb.0: -- $r4 = BSTRPICK_W $r5, 10, 4 --... -- --# ------------------------------------------------------------------------------------------------- --# Encoding format: BSTR_D --# ------------------------------------------------------------------------------------------------- --# ------------------------------+-----------------+-----------------+--------------+--------------- --# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 --# ------------------------------+-----------------+-----------------+--------------+--------------- --# opcode | msb | lsb | rj | rd --# ------------------------------+-----------------+-----------------+--------------+--------------- -- ----- --# CHECK-LABEL: test_BSTRINS_D: --# CHECK-ENC: 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 0 0 0 0 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: bstrins.d $a0, $a1, 7, 2 --name: test_BSTRINS_D --body: | -- bb.0: -- $r4 = BSTRINS_D $r4, $r5, 7, 2 --... ----- --# CHECK-LABEL: test_BSTRPICK_D: --# CHECK-ENC: 0 0 0 0 0 0 0 0 1 1 1 0 0 1 1 1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 0 0 --# CHECK-ASM: bstrpick.d $a0, $a1, 39, 22 --name: test_BSTRPICK_D --body: | -- bb.0: -- $r4 = BSTRPICK_D $r5, 39, 22 --... -- --# ------------------------------------------------------------------------------------------------- --# Encoding format: ASRT --# ------------------------------------------------------------------------------------------------- --# ---------------------------------------------------+--------------+--------------+--------------- --# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 --# ---------------------------------------------------+--------------+--------------+--------------- --# opcode | rk | rj | 0x0 --# ---------------------------------------------------+--------------+--------------+--------------- -- ----- --# CHECK-LABEL: test_ASRTLE_D: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 1 0 0 1 0 0 0 0 0 0 0 --# CHECK-ASM: asrtle.d $a0, $a1 --name: test_ASRTLE_D --body: | -- bb.0: -- ASRTLE_D $r4, $r5 --... ----- --# CHECK-LABEL: test_ASRTGT_D: --# CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 1 0 0 1 0 0 0 0 0 0 0 --# CHECK-ASM: asrtgt.d $a0, $a1 --name: test_ASRTGT_D --body: | -- bb.0: -- ASRTGT_D $r4, $r5 --... -- --# ------------------------------------------------------------------------------------------------- --# Encoding format: PRELD --# ------------------------------------------------------------------------------------------------- --# ------------------------------+-----------------------------------+--------------+--------------- --# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 --# ------------------------------+-----------------------------------+--------------+--------------- --# opcode | imm12 | rj | imm5 --# ------------------------------+-----------------------------------+--------------+--------------- -- ----- --# CHECK-LABEL: test_PRELD: --# CHECK-ENC: 0 0 1 0 1 0 1 0 1 1 0 0 0 0 0 0 0 1 0 1 0 1 0 0 1 0 0 0 1 1 1 1 --# CHECK-ASM: preld 15, $a0, 21 --name: test_PRELD --body: | -- bb.0: -- PRELD 15, $r4, 21 --... -- --# ------------------------------------------------------------------------------------------------- --# Encoding format: PRELDX --# ------------------------------------------------------------------------------------------------- --# ---------------------------------------------------+--------------+--------------+--------------- --# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 --# ---------------------------------------------------+--------------+--------------+--------------- --# opcode | rk | rj | imm5 --# ---------------------------------------------------+--------------+--------------+--------------- -- ----- --# CHECK-LABEL: test_PRELDX: --# CHECK-ENC: 0 0 1 1 1 0 0 0 0 0 1 0 1 1 0 0 0 0 0 1 0 1 0 0 1 0 0 0 1 0 1 1 --# CHECK-ASM: preldx 11, $a0, $a1 --name: test_PRELDX --body: | -- bb.0: -- PRELDX 11, $r4, $r5 -diff --git a/src/llvm-project/llvm/test/CodeGen/LoongArch/named-register.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/named-register.ll -new file mode 100644 -index 000000000..0b0660fca ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/nomerge.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/nomerge.ll -new file mode 100644 -index 000000000..a8ce63225 ---- /dev/null -+++ b/src/llvm-project/llvm/test/CodeGen/LoongArch/nomerge.ll -@@ -0,0 +1,35 @@ -+; RUN: llc < %s -mtriple=loongarch64 -relocation-model=pic -o - | FileCheck %s -+ -+define void @foo(i32 %i) { -+entry: -+ switch i32 %i, label %if.end3 [ -+ i32 5, label %if.then -+ i32 7, label %if.then2 -+ ] -+ -+if.then: -+ tail call void @bar() #0 -+ br label %if.end3 -+ -+if.then2: -+ tail call void @bar() #0 -+ br label %if.end3 -+ -+if.end3: -+ tail call void @bar() #0 -+ 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/src/llvm-project/llvm/test/CodeGen/LoongArch/noti32.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/noti32.ll -new file mode 100644 -index 000000000..9aa8c4391 ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/peephole-load-store-addi.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/peephole-load-store-addi.ll -new file mode 100644 -index 000000000..541ea4256 ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/signext.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/signext.ll -new file mode 100644 -index 000000000..13c710d14 ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/stptr.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/stptr.ll -new file mode 100644 -index 000000000..0a54e0f8f ---- /dev/null -+++ b/src/llvm-project/llvm/test/CodeGen/LoongArch/stptr.ll -@@ -0,0 +1,52 @@ -+; 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 -+ -+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 -+} -+ -+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 -+} -+ -+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 -+} -+ -+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 -+} -+ -+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 -+} -+ -+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/src/llvm-project/llvm/test/CodeGen/LoongArch/tailcall-R.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/tailcall-R.ll -new file mode 100644 -index 000000000..2445e32ea ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/tailcall-check.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/tailcall-check.ll -new file mode 100644 -index 000000000..2b5902d69 ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/tailcall-mem.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/tailcall-mem.ll -new file mode 100644 -index 000000000..68ddaa899 ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/tailcall.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/tailcall.ll -new file mode 100644 -index 000000000..984df2cb6 ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/thread-pointer.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/thread-pointer.ll -new file mode 100644 -index 000000000..06a5886c4 ---- /dev/null -+++ b/src/llvm-project/llvm/test/CodeGen/LoongArch/thread-pointer.ll -@@ -0,0 +1,9 @@ -+; RUN: llc -march=loongarch64 < %s | FileCheck %s -+ -+declare i8* @llvm.thread.pointer() nounwind readnone -+ -+define i8* @thread_pointer() { -+; CHECK: move $r4, $tp -+ %1 = tail call i8* @llvm.thread.pointer() -+ ret i8* %1 -+} -diff --git a/src/llvm-project/llvm/test/CodeGen/LoongArch/trunc.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/trunc.ll -new file mode 100644 -index 000000000..d1b5a3a14 ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/LoongArch/unalignment.ll b/src/llvm-project/llvm/test/CodeGen/LoongArch/unalignment.ll -new file mode 100644 -index 000000000..d468a361f ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/CodeGen/PowerPC/regalloc-fast-debug-spill.ll b/src/llvm-project/llvm/test/CodeGen/PowerPC/regalloc-fast-debug-spill.ll -new file mode 100644 -index 000000000..cae3cb3bb ---- /dev/null -+++ b/src/llvm-project/llvm/test/CodeGen/PowerPC/regalloc-fast-debug-spill.ll -@@ -0,0 +1,250 @@ -+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py -+; RUN: llc -O0 < %s | FileCheck %s -+ -+; This test would previously crash in RegisterScavenging, or with assertions -+; enabled it would fail when RegAllocFast calls clearVirtRegs. This was due to -+; unhandled virt regs in cloned DBG_VALUE_LIST for spills, which are now skipped. -+; https://github.com/llvm/llvm-project/issues/59172 -+ -+target datalayout = "e-m:e-i64:64-n32:64-S128-v256:256:256-v512:512:512" -+target triple = "powerpc64le-unknown-linux-gnu" -+ -+; Function Attrs: argmemonly nocallback nofree nounwind willreturn -+declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #0 -+ -+; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn -+declare void @llvm.dbg.value(metadata, metadata, metadata) #1 -+ -+define void @read_to_end(i1 %0) personality ptr null { -+; CHECK-LABEL: read_to_end: -+; CHECK: # %bb.0: -+; CHECK-NEXT: mflr 0 -+; CHECK-NEXT: std 0, 16(1) -+; CHECK-NEXT: stdu 1, -80(1) -+; CHECK-NEXT: .cfi_def_cfa_offset 80 -+; CHECK-NEXT: .cfi_offset lr, 16 -+; CHECK-NEXT: andi. 3, 3, 1 -+; CHECK-NEXT: mfocrf 3, 128 -+; CHECK-NEXT: rlwinm 3, 3, 1, 0, 0 -+; CHECK-NEXT: stw 3, 60(1) -+; CHECK-NEXT: ld 3, 0(0) -+; CHECK-NEXT: std 3, 64(1) # 8-byte Folded Spill -+; CHECK-NEXT: li 3, 0 -+; CHECK-NEXT: std 3, 72(1) # 8-byte Folded Spill -+; CHECK-NEXT: #DEBUG_VALUE: spec_extend:iterator <- [DW_OP_LLVM_arg 0, DW_OP_LLVM_arg 1, DW_OP_constu 1, DW_OP_mul, DW_OP_plus, DW_OP_stack_value, DW_OP_LLVM_fragment 64 64] undef, $x3 -+; CHECK-NEXT: creqv 20, 20, 20 -+; CHECK-NEXT: crxor 20, 1, 20 -+; CHECK-NEXT: bc 12, 20, .LBB0_2 -+; CHECK-NEXT: b .LBB0_1 -+; CHECK-NEXT: .LBB0_1: -+; CHECK-NEXT: addi 1, 1, 80 -+; CHECK-NEXT: ld 0, 16(1) -+; CHECK-NEXT: mtlr 0 -+; CHECK-NEXT: blr -+; CHECK-NEXT: .LBB0_2: -+; CHECK-NEXT: ld 5, 72(1) # 8-byte Folded Reload -+; CHECK-NEXT: ld 4, 64(1) # 8-byte Folded Reload -+; CHECK-NEXT: li 3, 0 -+; CHECK-NEXT: bl memcpy -+; CHECK-NEXT: nop -+; CHECK-NEXT: lwz 4, 60(1) -+; CHECK-NEXT: # implicit-def: $cr5lt -+; CHECK-NEXT: mfocrf 3, 4 -+; CHECK-NEXT: rlwimi 3, 4, 12, 20, 20 -+; CHECK-NEXT: mtocrf 4, 3 -+; CHECK-NEXT: bc 12, 20, .LBB0_4 -+; CHECK-NEXT: b .LBB0_3 -+; CHECK-NEXT: .LBB0_3: -+; CHECK-NEXT: b .LBB0_4 -+; CHECK-NEXT: .LBB0_4: -+; CHECK-NEXT: addi 1, 1, 80 -+; CHECK-NEXT: ld 0, 16(1) -+; CHECK-NEXT: mtlr 0 -+; CHECK-NEXT: blr -+ %2 = load ptr, ptr null, align 8 -+ %3 = sub i64 0, 0 -+ call void @llvm.dbg.value(metadata !DIArgList(ptr %2, i64 %3), metadata !129, metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_constu, 1, DW_OP_mul, DW_OP_plus, DW_OP_stack_value, DW_OP_LLVM_fragment, 64, 64)), !dbg !140 -+ br i1 %0, label %4, label %5 -+ -+4: ; preds = %1 -+ ret void -+ -+5: ; preds = %1 -+ tail call void @llvm.memcpy.p0.p0.i64(ptr null, ptr %2, i64 %3, i1 false) -+ br i1 %0, label %7, label %6 -+ -+6: ; preds = %5 -+ br label %7 -+ -+7: ; preds = %6, %5 -+ ret void -+} -+ -+attributes #0 = { argmemonly nocallback nofree nounwind willreturn } -+attributes #1 = { nocallback nofree nosync nounwind readnone speculatable willreturn } -+ -+!llvm.module.flags = !{!0} -+!llvm.dbg.cu = !{!1} -+ -+!0 = !{i32 2, !"Debug Info Version", i32 3} -+!1 = distinct !DICompileUnit(language: DW_LANG_Rust, file: !2, producer: "clang LLVM (rustc version 1.67.0-dev)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !3, globals: !4) -+!2 = !DIFile(filename: "library/std/src/lib.rs/@/std.ff910444-cgu.11", directory: "/home/jistone/rust") -+!3 = !{} -+!4 = !{!5, !12, !18, !23, !28, !34, !43, !49, !52, !58, !64, !68, !77, !81, !86, !90, !98, !102, !106, !111, !117, !124} -+!5 = !DIGlobalVariableExpression(var: !6, expr: !DIExpression()) -+!6 = distinct !DIGlobalVariable(name: "::{vtable}", scope: null, file: !7, type: !8, isLocal: true, isDefinition: true) -+!7 = !DIFile(filename: "", directory: "") -+!8 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "::{vtable_type}", file: !7, size: 384, align: 64, flags: DIFlagArtificial, elements: !3, vtableHolder: !9, templateParams: !3, identifier: "1ec913b2a90798f33a12cdc627a17d3d") -+!9 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "String", scope: !10, file: !7, size: 192, align: 64, elements: !3, templateParams: !3, identifier: "b616ccc9e18737e903266aae12eea82") -+!10 = !DINamespace(name: "string", scope: !11) -+!11 = !DINamespace(name: "alloc", scope: null) -+!12 = !DIGlobalVariableExpression(var: !13, expr: !DIExpression()) -+!13 = distinct !DIGlobalVariable(name: "::{vtable}", scope: null, file: !7, type: !14, isLocal: true, isDefinition: true) -+!14 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "::{vtable_type}", file: !7, size: 256, align: 64, flags: DIFlagArtificial, elements: !3, vtableHolder: !15, templateParams: !3, identifier: "7f09904511177108b2e94c43effbe403") -+!15 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "BorrowMutError", scope: !16, file: !7, align: 8, elements: !3, identifier: "acf9edd4524e0ff9a9398905d3ba31a6") -+!16 = !DINamespace(name: "cell", scope: !17) -+!17 = !DINamespace(name: "core", scope: null) -+!18 = !DIGlobalVariableExpression(var: !19, expr: !DIExpression()) -+!19 = distinct !DIGlobalVariable(name: "::{vtable}", scope: null, file: !7, type: !20, isLocal: true, isDefinition: true) -+!20 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "::{vtable_type}", file: !7, size: 256, align: 64, flags: DIFlagArtificial, elements: !3, vtableHolder: !21, templateParams: !3, identifier: "84cb7e6d80fc4c532d8f45aaa75a7ae3") -+!21 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Error", scope: !22, file: !7, align: 8, elements: !3, identifier: "abcb9fb1fe4fda8598a8687b517935b") -+!22 = !DINamespace(name: "fmt", scope: !17) -+!23 = !DIGlobalVariableExpression(var: !24, expr: !DIExpression()) -+!24 = distinct !DIGlobalVariable(name: "::{vtable}", scope: null, file: !7, type: !25, isLocal: true, isDefinition: true) -+!25 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "::{vtable_type}", file: !7, size: 256, align: 64, flags: DIFlagArtificial, elements: !3, vtableHolder: !26, templateParams: !3, identifier: "bafa31943f8233dbf8d2de6a615f899") -+!26 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "TryFromSliceError", scope: !27, file: !7, align: 8, elements: !3, templateParams: !3, identifier: "2dd7cf8d77337f63be7c7f5feb370b37") -+!27 = !DINamespace(name: "array", scope: !17) -+!28 = !DIGlobalVariableExpression(var: !29, expr: !DIExpression()) -+!29 = distinct !DIGlobalVariable(name: "::{vtable}", scope: null, file: !7, type: !30, isLocal: true, isDefinition: true) -+!30 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "::{vtable_type}", file: !7, size: 256, align: 64, flags: DIFlagArtificial, elements: !3, vtableHolder: !31, templateParams: !3, identifier: "3292395ea0f5a7e3e88f36db52eb440c") -+!31 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "TryFromIntError", scope: !32, file: !7, align: 8, elements: !3, templateParams: !3, identifier: "5b131d57d001578fbf4fb83f2028eb12") -+!32 = !DINamespace(name: "error", scope: !33) -+!33 = !DINamespace(name: "num", scope: !17) -+!34 = !DIGlobalVariableExpression(var: !35, expr: !DIExpression()) -+!35 = distinct !DIGlobalVariable(name: "OUTPUT_CAPTURE_USED", linkageName: "_ZN3std2io5stdio19OUTPUT_CAPTURE_USED17h6bb564f9f9e20f1bE", scope: !36, file: !39, line: 38, type: !40, isLocal: true, isDefinition: true, align: 8) -+!36 = !DINamespace(name: "stdio", scope: !37) -+!37 = !DINamespace(name: "io", scope: !38) -+!38 = !DINamespace(name: "std", scope: null) -+!39 = !DIFile(filename: "library/std/src/io/stdio.rs", directory: "/home/jistone/rust", checksumkind: CSK_MD5, checksum: "6e6a519ce8370e29f07d850a34a413c1") -+!40 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "AtomicBool", scope: !41, file: !7, size: 8, align: 8, elements: !3, templateParams: !3, identifier: "c1cddf0305d4e6a98a8ddd4b6fdb5b91") -+!41 = !DINamespace(name: "atomic", scope: !42) -+!42 = !DINamespace(name: "sync", scope: !17) -+!43 = !DIGlobalVariableExpression(var: !44, expr: !DIExpression()) -+!44 = distinct !DIGlobalVariable(name: "INSTANCE", linkageName: "_ZN3std2io5stdio5stdin8INSTANCE17h225ddf7c6608f4aaE", scope: !45, file: !39, line: 320, type: !46, isLocal: true, isDefinition: true, align: 64) -+!45 = !DINamespace(name: "stdin", scope: !36) -+!46 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "OnceLock>>", scope: !47, file: !7, size: 448, align: 64, elements: !3, templateParams: !3, identifier: "2236c08b0846b8b2f33c235183822718") -+!47 = !DINamespace(name: "once_lock", scope: !48) -+!48 = !DINamespace(name: "sync", scope: !38) -+!49 = !DIGlobalVariableExpression(var: !50, expr: !DIExpression()) -+!50 = distinct !DIGlobalVariable(name: "STDOUT", linkageName: "_ZN3std2io5stdio6STDOUT17hd8472b9eb112f94aE", scope: !36, file: !39, line: 554, type: !51, isLocal: true, isDefinition: true, align: 64) -+!51 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "OnceLock>>>", scope: !47, file: !7, size: 512, align: 64, elements: !3, templateParams: !3, identifier: "31535135376bcf9dc80438cb0beaa95") -+!52 = !DIGlobalVariableExpression(var: !53, expr: !DIExpression()) -+!53 = distinct !DIGlobalVariable(name: "INSTANCE", linkageName: "_ZN3std2io5stdio6stderr8INSTANCE17he81b75fda1609dccE", scope: !54, file: !39, line: 844, type: !55, isLocal: true, isDefinition: true, align: 64) -+!54 = !DINamespace(name: "stderr", scope: !36) -+!55 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "ReentrantMutex>", scope: !56, file: !7, size: 192, align: 64, elements: !3, templateParams: !3, identifier: "5c48123cbde8afbfd832b70e8bb014b") -+!56 = !DINamespace(name: "remutex", scope: !57) -+!57 = !DINamespace(name: "sys_common", scope: !38) -+!58 = !DIGlobalVariableExpression(var: !59, expr: !DIExpression()) -+!59 = distinct !DIGlobalVariable(name: " as core::fmt::Write>::{vtable}", scope: null, file: !7, type: !60, isLocal: true, isDefinition: true) -+!60 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: " as core::fmt::Write>::{vtable_type}", file: !7, size: 384, align: 64, flags: DIFlagArtificial, elements: !3, vtableHolder: !61, templateParams: !3, identifier: "43681bec3eba7b0defb75fd847230ef3") -+!61 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Adapter", scope: !62, file: !7, size: 128, align: 64, elements: !3, templateParams: !3, identifier: "eda3cd8f60f00feb7019a3d90d2413dd") -+!62 = !DINamespace(name: "write_fmt", scope: !63) -+!63 = !DINamespace(name: "Write", scope: !37) -+!64 = !DIGlobalVariableExpression(var: !65, expr: !DIExpression()) -+!65 = distinct !DIGlobalVariable(name: " as core::fmt::Write>::{vtable}", scope: null, file: !7, type: !66, isLocal: true, isDefinition: true) -+!66 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: " as core::fmt::Write>::{vtable_type}", file: !7, size: 384, align: 64, flags: DIFlagArtificial, elements: !3, vtableHolder: !67, templateParams: !3, identifier: "2235adf22355a080446df25ada963d8f") -+!67 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Adapter", scope: !62, file: !7, size: 128, align: 64, elements: !3, templateParams: !3, identifier: "50f418463bae1beffe989359452b170a") -+!68 = !DIGlobalVariableExpression(var: !69, expr: !DIExpression()) -+!69 = distinct !DIGlobalVariable(name: "__KEY", linkageName: "_ZN3std2io5stdio14OUTPUT_CAPTURE7__getit5__KEY17h82ea5b0c4e81236dE", scope: !70, file: !72, line: 331, type: !73, isLocal: true, isDefinition: true, align: 64) -+!70 = !DINamespace(name: "__getit", scope: !71) -+!71 = !DINamespace(name: "OUTPUT_CAPTURE", scope: !36) -+!72 = !DIFile(filename: "library/std/src/thread/local.rs", directory: "/home/jistone/rust", checksumkind: CSK_MD5, checksum: "e3766fd5751a888dc2040f63031e944e") -+!73 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Key>>>>>", scope: !74, file: !7, size: 192, align: 64, elements: !3, templateParams: !3, identifier: "4d1514f685cbd010d7b86d2eef080b6c") -+!74 = !DINamespace(name: "fast", scope: !75) -+!75 = !DINamespace(name: "local", scope: !76) -+!76 = !DINamespace(name: "thread", scope: !38) -+!77 = !DIGlobalVariableExpression(var: !78, expr: !DIExpression()) -+!78 = distinct !DIGlobalVariable(name: "::{vtable}", scope: null, file: !7, type: !79, isLocal: true, isDefinition: true) -+!79 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "::{vtable_type}", file: !7, size: 256, align: 64, flags: DIFlagArtificial, elements: !3, vtableHolder: !80, templateParams: !3, identifier: "1a7c0806435616633a284f48de1194c5") -+!80 = !DIBasicType(name: "i32", size: 32, encoding: DW_ATE_signed) -+!81 = !DIGlobalVariableExpression(var: !82, expr: !DIExpression()) -+!82 = distinct !DIGlobalVariable(name: "::{vtable}", scope: null, file: !7, type: !83, isLocal: true, isDefinition: true) -+!83 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "::{vtable_type}", file: !7, size: 256, align: 64, flags: DIFlagArtificial, elements: !3, vtableHolder: !84, templateParams: !3, identifier: "8e82e7dafb168f2995a6711175975a8") -+!84 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "PathBuf", scope: !85, file: !7, size: 192, align: 64, elements: !3, templateParams: !3, identifier: "85bd755ad2187534379df2cc01ef53a0") -+!85 = !DINamespace(name: "path", scope: !38) -+!86 = !DIGlobalVariableExpression(var: !87, expr: !DIExpression()) -+!87 = distinct !DIGlobalVariable(name: "::{vtable}", scope: null, file: !7, type: !88, isLocal: true, isDefinition: true) -+!88 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "::{vtable_type}", file: !7, size: 256, align: 64, flags: DIFlagArtificial, elements: !3, vtableHolder: !89, templateParams: !3, identifier: "a8f7c32dd1df279746df60c6d46ce35e") -+!89 = !DIBasicType(name: "bool", size: 8, encoding: DW_ATE_boolean) -+!90 = !DIGlobalVariableExpression(var: !91, expr: !DIExpression()) -+!91 = distinct !DIGlobalVariable(name: "STATX_STATE", linkageName: "_ZN3std3sys4unix2fs9try_statx11STATX_STATE17h465ade0d62262837E", scope: !92, file: !96, line: 157, type: !97, isLocal: true, isDefinition: true, align: 8) -+!92 = !DINamespace(name: "try_statx", scope: !93) -+!93 = !DINamespace(name: "fs", scope: !94) -+!94 = !DINamespace(name: "unix", scope: !95) -+!95 = !DINamespace(name: "sys", scope: !38) -+!96 = !DIFile(filename: "library/std/src/sys/unix/fs.rs", directory: "/home/jistone/rust", checksumkind: CSK_MD5, checksum: "594559328c68ee77afe955cd571273ee") -+!97 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "AtomicU8", scope: !41, file: !7, size: 8, align: 8, elements: !3, templateParams: !3, identifier: "dda3b691bea8e1b5292414dd97926af2") -+!98 = !DIGlobalVariableExpression(var: !99, expr: !DIExpression()) -+!99 = distinct !DIGlobalVariable(name: "<&bool as core::fmt::Debug>::{vtable}", scope: null, file: !7, type: !100, isLocal: true, isDefinition: true) -+!100 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "<&bool as core::fmt::Debug>::{vtable_type}", file: !7, size: 256, align: 64, flags: DIFlagArtificial, elements: !3, vtableHolder: !101, templateParams: !3, identifier: "5e8d2c48c9cc79c318e2bd28b03e141a") -+!101 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "&bool", baseType: !89, size: 64, align: 64, dwarfAddressSpace: 0) -+!102 = !DIGlobalVariableExpression(var: !103, expr: !DIExpression()) -+!103 = distinct !DIGlobalVariable(name: "<&i32 as core::fmt::Debug>::{vtable}", scope: null, file: !7, type: !104, isLocal: true, isDefinition: true) -+!104 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "<&i32 as core::fmt::Debug>::{vtable_type}", file: !7, size: 256, align: 64, flags: DIFlagArtificial, elements: !3, vtableHolder: !105, templateParams: !3, identifier: "d4029746615b6a868ffbc67515d99878") -+!105 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "&i32", baseType: !80, size: 64, align: 64, dwarfAddressSpace: 0) -+!106 = !DIGlobalVariableExpression(var: !107, expr: !DIExpression()) -+!107 = distinct !DIGlobalVariable(name: "<&u32 as core::fmt::Debug>::{vtable}", scope: null, file: !7, type: !108, isLocal: true, isDefinition: true) -+!108 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "<&u32 as core::fmt::Debug>::{vtable_type}", file: !7, size: 256, align: 64, flags: DIFlagArtificial, elements: !3, vtableHolder: !109, templateParams: !3, identifier: "178e0e76b9d9178d686381b2d05a7777") -+!109 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "&u32", baseType: !110, size: 64, align: 64, dwarfAddressSpace: 0) -+!110 = !DIBasicType(name: "u32", size: 32, encoding: DW_ATE_unsigned) -+!111 = !DIGlobalVariableExpression(var: !112, expr: !DIExpression()) -+!112 = distinct !DIGlobalVariable(name: "<&core::option::Option as core::fmt::Debug>::{vtable}", scope: null, file: !7, type: !113, isLocal: true, isDefinition: true) -+!113 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "<&core::option::Option as core::fmt::Debug>::{vtable_type}", file: !7, size: 256, align: 64, flags: DIFlagArtificial, elements: !3, vtableHolder: !114, templateParams: !3, identifier: "7ca8386b4d420d719587fa3255329a7a") -+!114 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "&core::option::Option", baseType: !115, size: 64, align: 64, dwarfAddressSpace: 0) -+!115 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Option", scope: !116, file: !7, size: 128, align: 64, elements: !3, templateParams: !3, identifier: "ad8474e495013fa1e3af4a6b53a05f4b") -+!116 = !DINamespace(name: "option", scope: !17) -+!117 = !DIGlobalVariableExpression(var: !118, expr: !DIExpression()) -+!118 = distinct !DIGlobalVariable(name: "HAS_CLONE3", linkageName: "_ZN3std3sys4unix7process13process_inner66_$LT$impl$u20$std..sys..unix..process..process_common..Command$GT$7do_fork10HAS_CLONE317h7d23eb353ae1c9a8E", scope: !119, file: !123, line: 148, type: !40, isLocal: true, isDefinition: true, align: 8) -+!119 = !DINamespace(name: "do_fork", scope: !120) -+!120 = !DINamespace(name: "{impl#0}", scope: !121) -+!121 = !DINamespace(name: "process_inner", scope: !122) -+!122 = !DINamespace(name: "process", scope: !94) -+!123 = !DIFile(filename: "library/std/src/sys/unix/process/process_unix.rs", directory: "/home/jistone/rust", checksumkind: CSK_MD5, checksum: "91761d638041a5dd66c0a64d968debe6") -+!124 = !DIGlobalVariableExpression(var: !125, expr: !DIExpression()) -+!125 = distinct !DIGlobalVariable(name: "::{vtable}", scope: null, file: !7, type: !126, isLocal: true, isDefinition: true) -+!126 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "::{vtable_type}", file: !7, size: 256, align: 64, flags: DIFlagArtificial, elements: !3, vtableHolder: !127, templateParams: !3, identifier: "13903f30d26ee5869ef7a3fc63a2e03d") -+!127 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "NonZeroI32", scope: !128, file: !7, size: 32, align: 32, elements: !3, templateParams: !3, identifier: "e292f11a32f1ce5cf3b26864e4a0f5e5") -+!128 = !DINamespace(name: "nonzero", scope: !33) -+!129 = !DILocalVariable(name: "iterator", arg: 2, scope: !130, file: !131, line: 83, type: !137) -+!130 = distinct !DISubprogram(name: "spec_extend", linkageName: "_ZN132_$LT$alloc..vec..Vec$LT$T$C$A$GT$$u20$as$u20$alloc..vec..spec_extend..SpecExtend$LT$$RF$T$C$core..slice..iter..Iter$LT$T$GT$$GT$$GT$11spec_extend17hb56b69f474ec1e6dE", scope: !132, file: !131, line: 83, type: !135, scopeLine: 83, flags: DIFlagPrototyped, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !1, templateParams: !3, retainedNodes: !3) -+!131 = !DIFile(filename: "library/alloc/src/vec/spec_extend.rs", directory: "/home/jistone/rust", checksumkind: CSK_MD5, checksum: "0614d5dabe9e343254af1b3fa1ec7315") -+!132 = !DINamespace(name: "{impl#4}", scope: !133) -+!133 = !DINamespace(name: "spec_extend", scope: !134) -+!134 = !DINamespace(name: "vec", scope: !11) -+!135 = distinct !DISubroutineType(types: !136) -+!136 = !{null} -+!137 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Iter", scope: !138, file: !7, size: 128, align: 64, elements: !3, templateParams: !3, identifier: "c31ab6f02ccece1f1a6e93425acabaa1") -+!138 = !DINamespace(name: "iter", scope: !139) -+!139 = !DINamespace(name: "slice", scope: !17) -+!140 = !DILocation(line: 0, scope: !130, inlinedAt: !141) -+!141 = distinct !DILocation(line: 2392, column: 9, scope: !142, inlinedAt: !146) -+!142 = distinct !DISubprogram(name: "extend_from_slice", linkageName: "_ZN5alloc3vec16Vec$LT$T$C$A$GT$17extend_from_slice17hbc8d29f2694fd768E", scope: !144, file: !143, line: 2391, type: !145, scopeLine: 2391, flags: DIFlagPrototyped, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !1, templateParams: !3, retainedNodes: !3) -+!143 = !DIFile(filename: "library/alloc/src/vec/mod.rs", directory: "/home/jistone/rust", checksumkind: CSK_MD5, checksum: "0d69d0c0c11b3e47364cf6be0d07c829") -+!144 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Vec", scope: !134, file: !7, size: 192, align: 64, elements: !3, templateParams: !3, identifier: "f970dea4d30c1daf847db520fef9390d") -+!145 = distinct !DISubroutineType(types: !136) -+!146 = distinct !DILocation(line: 330, column: 9, scope: !147, inlinedAt: !154) -+!147 = distinct !DILexicalBlock(scope: !149, file: !148, line: 329, column: 9) -+!148 = !DIFile(filename: "library/std/src/io/buffered/bufreader.rs", directory: "/home/jistone/rust", checksumkind: CSK_MD5, checksum: "5375e06de487f85ee2f6d21c8a84ce7d") -+!149 = distinct !DISubprogram(name: "read_to_end", linkageName: "_ZN82_$LT$std..io..buffered..bufreader..BufReader$LT$R$GT$$u20$as$u20$std..io..Read$GT$11read_to_end17h9f09720ee76e6db9E", scope: !150, file: !148, line: 328, type: !153, scopeLine: 328, flags: DIFlagPrototyped, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !1, templateParams: !3, retainedNodes: !3) -+!150 = !DINamespace(name: "{impl#3}", scope: !151) -+!151 = !DINamespace(name: "bufreader", scope: !152) -+!152 = !DINamespace(name: "buffered", scope: !37) -+!153 = distinct !DISubroutineType(types: !3) -+!154 = distinct !DILocation(line: 464, column: 9, scope: !155, inlinedAt: !158) -+!155 = distinct !DISubprogram(name: "read_to_end", linkageName: "_ZN59_$LT$std..io..stdio..StdinLock$u20$as$u20$std..io..Read$GT$11read_to_end17h38999a681cc6c5b5E", scope: !156, file: !39, line: 463, type: !157, scopeLine: 463, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !1, templateParams: !3, retainedNodes: !3) -+!156 = !DINamespace(name: "{impl#7}", scope: !36) -+!157 = distinct !DISubroutineType(types: !3) -+!158 = distinct !DILocation(line: 430, column: 9, scope: !159) -+!159 = distinct !DISubprogram(name: "read_to_end", linkageName: "_ZN55_$LT$std..io..stdio..Stdin$u20$as$u20$std..io..Read$GT$11read_to_end17haba70a09681d41d3E", scope: !160, file: !39, line: 429, type: !161, scopeLine: 429, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !1, templateParams: !3, retainedNodes: !3) -+!160 = !DINamespace(name: "{impl#5}", scope: !36) -+!161 = !DISubroutineType(types: !3) -diff --git a/src/llvm-project/llvm/test/CodeGen/SPARC/bigreturn.ll b/src/llvm-project/llvm/test/CodeGen/SPARC/bigreturn.ll -new file mode 100644 -index 000000000..25b4eeeca ---- /dev/null -+++ b/src/llvm-project/llvm/test/CodeGen/SPARC/bigreturn.ll -@@ -0,0 +1,254 @@ -+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py -+; RUN: llc < %s -mtriple=sparc -disable-sparc-delay-filler -disable-sparc-leaf-proc | FileCheck --check-prefix=SPARC %s -+; RUN: llc < %s -mtriple=sparc64 -disable-sparc-delay-filler -disable-sparc-leaf-proc | FileCheck --check-prefix=SPARC64 %s -+ -+;; Structs up to six registers in size can be returned in registers. -+;; Note that the maximum return size and member placement is NOT -+;; compatible with the C ABI - see SparcCallingConv.td. -+define { i32, i32 } @ret_i32_pair(i32 %a0, i32 %a1, i32* %p, i32* %q) { -+; SPARC-LABEL: ret_i32_pair: -+; SPARC: .cfi_startproc -+; SPARC-NEXT: ! %bb.0: -+; SPARC-NEXT: save %sp, -96, %sp -+; SPARC-NEXT: .cfi_def_cfa_register %fp -+; SPARC-NEXT: .cfi_window_save -+; SPARC-NEXT: .cfi_register %o7, %i7 -+; SPARC-NEXT: ld [%i2], %i0 -+; SPARC-NEXT: st %g0, [%i2] -+; SPARC-NEXT: ld [%i3], %i1 -+; SPARC-NEXT: restore -+; SPARC-NEXT: retl -+; SPARC-NEXT: nop -+; -+; SPARC64-LABEL: ret_i32_pair: -+; SPARC64: .cfi_startproc -+; SPARC64-NEXT: ! %bb.0: -+; SPARC64-NEXT: save %sp, -128, %sp -+; SPARC64-NEXT: .cfi_def_cfa_register %fp -+; SPARC64-NEXT: .cfi_window_save -+; SPARC64-NEXT: .cfi_register %o7, %i7 -+; SPARC64-NEXT: ld [%i2], %i0 -+; SPARC64-NEXT: st %g0, [%i2] -+; SPARC64-NEXT: ld [%i3], %i1 -+; SPARC64-NEXT: restore -+; SPARC64-NEXT: retl -+; SPARC64-NEXT: nop -+ %r1 = load i32, i32* %p -+ %rv1 = insertvalue { i32, i32 } undef, i32 %r1, 0 -+ store i32 0, i32* %p -+ %r2 = load i32, i32* %q -+ %rv2 = insertvalue { i32, i32 } %rv1, i32 %r2, 1 -+ ret { i32, i32 } %rv2 -+} -+ -+define void @call_ret_i32_pair(i32* %i0) { -+; SPARC-LABEL: call_ret_i32_pair: -+; SPARC: .cfi_startproc -+; SPARC-NEXT: ! %bb.0: -+; SPARC-NEXT: save %sp, -96, %sp -+; SPARC-NEXT: .cfi_def_cfa_register %fp -+; SPARC-NEXT: .cfi_window_save -+; SPARC-NEXT: .cfi_register %o7, %i7 -+; SPARC-NEXT: call ret_i32_pair -+; SPARC-NEXT: nop -+; SPARC-NEXT: st %o0, [%i0] -+; SPARC-NEXT: st %o1, [%i0] -+; SPARC-NEXT: restore -+; SPARC-NEXT: retl -+; SPARC-NEXT: nop -+; -+; SPARC64-LABEL: call_ret_i32_pair: -+; SPARC64: .cfi_startproc -+; SPARC64-NEXT: ! %bb.0: -+; SPARC64-NEXT: save %sp, -176, %sp -+; SPARC64-NEXT: .cfi_def_cfa_register %fp -+; SPARC64-NEXT: .cfi_window_save -+; SPARC64-NEXT: .cfi_register %o7, %i7 -+; SPARC64-NEXT: call ret_i32_pair -+; SPARC64-NEXT: nop -+; SPARC64-NEXT: st %o0, [%i0] -+; SPARC64-NEXT: st %o1, [%i0] -+; SPARC64-NEXT: restore -+; SPARC64-NEXT: retl -+; SPARC64-NEXT: nop -+ %rv = call { i32, i32 } @ret_i32_pair(i32 undef, i32 undef, -+ i32* undef, i32* undef) -+ %e0 = extractvalue { i32, i32 } %rv, 0 -+ store volatile i32 %e0, i32* %i0 -+ %e1 = extractvalue { i32, i32 } %rv, 1 -+ store i32 %e1, i32* %i0 -+ ret void -+} -+ -+;; Functions returning structs more than six registers' worth of space -+;; should be automatically treated as an sret function. -+declare { [16 x i32] } @ret_i32_arr(i32 %input) -+ -+define i32 @call_ret_i32_arr(i32 %0) { -+; SPARC-LABEL: call_ret_i32_arr: -+; SPARC: .cfi_startproc -+; SPARC-NEXT: ! %bb.0: -+; SPARC-NEXT: save %sp, -160, %sp -+; SPARC-NEXT: .cfi_def_cfa_register %fp -+; SPARC-NEXT: .cfi_window_save -+; SPARC-NEXT: .cfi_register %o7, %i7 -+; SPARC-NEXT: add %fp, -64, %i1 -+; SPARC-NEXT: st %i1, [%sp+64] -+; SPARC-NEXT: mov %i0, %o0 -+; SPARC-NEXT: call ret_i32_arr -+; SPARC-NEXT: nop -+; SPARC-NEXT: unimp 64 -+; SPARC-NEXT: ld [%fp+-4], %i0 -+; SPARC-NEXT: restore -+; SPARC-NEXT: retl -+; SPARC-NEXT: nop -+; -+; SPARC64-LABEL: call_ret_i32_arr: -+; SPARC64: .cfi_startproc -+; SPARC64-NEXT: ! %bb.0: -+; SPARC64-NEXT: save %sp, -240, %sp -+; SPARC64-NEXT: .cfi_def_cfa_register %fp -+; SPARC64-NEXT: .cfi_window_save -+; SPARC64-NEXT: .cfi_register %o7, %i7 -+; SPARC64-NEXT: add %fp, 1983, %o0 -+; SPARC64-NEXT: mov %i0, %o1 -+; SPARC64-NEXT: call ret_i32_arr -+; SPARC64-NEXT: nop -+; SPARC64-NEXT: ld [%fp+2043], %i0 -+; SPARC64-NEXT: restore -+; SPARC64-NEXT: retl -+; SPARC64-NEXT: nop -+ %2 = call { [16 x i32] } @ret_i32_arr(i32 %0) -+ %3 = extractvalue { [16 x i32] } %2, 0 -+ %4 = extractvalue [16 x i32] %3, 15 -+ ret i32 %4 -+} -+ -+;; Structs up to six registers in size can be returned in registers. -+;; Note that the maximum return size and member placement is NOT -+;; compatible with the C ABI - see SparcCallingConv.td. -+define { i64, i64 } @ret_i64_pair(i32 %a0, i32 %a1, i64* %p, i64* %q) { -+; SPARC-LABEL: ret_i64_pair: -+; SPARC: .cfi_startproc -+; SPARC-NEXT: ! %bb.0: -+; SPARC-NEXT: save %sp, -96, %sp -+; SPARC-NEXT: .cfi_def_cfa_register %fp -+; SPARC-NEXT: .cfi_window_save -+; SPARC-NEXT: .cfi_register %o7, %i7 -+; SPARC-NEXT: mov %g0, %i4 -+; SPARC-NEXT: ldd [%i2], %i0 -+; SPARC-NEXT: mov %i4, %i5 -+; SPARC-NEXT: std %i4, [%i2] -+; SPARC-NEXT: ldd [%i3], %i2 -+; SPARC-NEXT: restore -+; SPARC-NEXT: retl -+; SPARC-NEXT: nop -+; -+; SPARC64-LABEL: ret_i64_pair: -+; SPARC64: .cfi_startproc -+; SPARC64-NEXT: ! %bb.0: -+; SPARC64-NEXT: save %sp, -128, %sp -+; SPARC64-NEXT: .cfi_def_cfa_register %fp -+; SPARC64-NEXT: .cfi_window_save -+; SPARC64-NEXT: .cfi_register %o7, %i7 -+; SPARC64-NEXT: ldx [%i2], %i0 -+; SPARC64-NEXT: stx %g0, [%i2] -+; SPARC64-NEXT: ldx [%i3], %i1 -+; SPARC64-NEXT: restore -+; SPARC64-NEXT: retl -+; SPARC64-NEXT: nop -+ %r1 = load i64, i64* %p -+ %rv1 = insertvalue { i64, i64 } undef, i64 %r1, 0 -+ store i64 0, i64* %p -+ %r2 = load i64, i64* %q -+ %rv2 = insertvalue { i64, i64 } %rv1, i64 %r2, 1 -+ ret { i64, i64 } %rv2 -+} -+ -+define void @call_ret_i64_pair(i64* %i0) { -+; SPARC-LABEL: call_ret_i64_pair: -+; SPARC: .cfi_startproc -+; SPARC-NEXT: ! %bb.0: -+; SPARC-NEXT: save %sp, -96, %sp -+; SPARC-NEXT: .cfi_def_cfa_register %fp -+; SPARC-NEXT: .cfi_window_save -+; SPARC-NEXT: .cfi_register %o7, %i7 -+; SPARC-NEXT: call ret_i64_pair -+; SPARC-NEXT: nop -+; SPARC-NEXT: ! kill: def $o0 killed $o0 killed $o0_o1 def $o0_o1 -+; SPARC-NEXT: ! kill: def $o2 killed $o2 killed $o2_o3 def $o2_o3 -+; SPARC-NEXT: ! kill: def $o1 killed $o1 killed $o0_o1 def $o0_o1 -+; SPARC-NEXT: std %o0, [%i0] -+; SPARC-NEXT: ! kill: def $o3 killed $o3 killed $o2_o3 def $o2_o3 -+; SPARC-NEXT: std %o2, [%i0] -+; SPARC-NEXT: restore -+; SPARC-NEXT: retl -+; SPARC-NEXT: nop -+; -+; SPARC64-LABEL: call_ret_i64_pair: -+; SPARC64: .cfi_startproc -+; SPARC64-NEXT: ! %bb.0: -+; SPARC64-NEXT: save %sp, -176, %sp -+; SPARC64-NEXT: .cfi_def_cfa_register %fp -+; SPARC64-NEXT: .cfi_window_save -+; SPARC64-NEXT: .cfi_register %o7, %i7 -+; SPARC64-NEXT: call ret_i64_pair -+; SPARC64-NEXT: nop -+; SPARC64-NEXT: stx %o0, [%i0] -+; SPARC64-NEXT: stx %o1, [%i0] -+; SPARC64-NEXT: restore -+; SPARC64-NEXT: retl -+; SPARC64-NEXT: nop -+ %rv = call { i64, i64 } @ret_i64_pair(i32 undef, i32 undef, -+ i64* undef, i64* undef) -+ %e0 = extractvalue { i64, i64 } %rv, 0 -+ store volatile i64 %e0, i64* %i0 -+ %e1 = extractvalue { i64, i64 } %rv, 1 -+ store i64 %e1, i64* %i0 -+ ret void -+} -+ -+;; Functions returning structs more than six registers' worth of space -+;; should be automatically treated as an sret function. -+declare { [16 x i64] } @ret_i64_arr(i64 %input) -+ -+define i64 @call_ret_i64_arr(i64 %0) { -+; SPARC-LABEL: call_ret_i64_arr: -+; SPARC: .cfi_startproc -+; SPARC-NEXT: ! %bb.0: -+; SPARC-NEXT: save %sp, -224, %sp -+; SPARC-NEXT: .cfi_def_cfa_register %fp -+; SPARC-NEXT: .cfi_window_save -+; SPARC-NEXT: .cfi_register %o7, %i7 -+; SPARC-NEXT: add %fp, -128, %i2 -+; SPARC-NEXT: st %i2, [%sp+64] -+; SPARC-NEXT: mov %i0, %o0 -+; SPARC-NEXT: mov %i1, %o1 -+; SPARC-NEXT: call ret_i64_arr -+; SPARC-NEXT: nop -+; SPARC-NEXT: unimp 128 -+; SPARC-NEXT: ldd [%fp+-8], %i0 -+; SPARC-NEXT: restore -+; SPARC-NEXT: retl -+; SPARC-NEXT: nop -+; -+; SPARC64-LABEL: call_ret_i64_arr: -+; SPARC64: .cfi_startproc -+; SPARC64-NEXT: ! %bb.0: -+; SPARC64-NEXT: save %sp, -304, %sp -+; SPARC64-NEXT: .cfi_def_cfa_register %fp -+; SPARC64-NEXT: .cfi_window_save -+; SPARC64-NEXT: .cfi_register %o7, %i7 -+; SPARC64-NEXT: add %fp, 1919, %o0 -+; SPARC64-NEXT: mov %i0, %o1 -+; SPARC64-NEXT: call ret_i64_arr -+; SPARC64-NEXT: nop -+; SPARC64-NEXT: ldx [%fp+2039], %i0 -+; SPARC64-NEXT: restore -+; SPARC64-NEXT: retl -+; SPARC64-NEXT: nop -+ %2 = call { [16 x i64] } @ret_i64_arr(i64 %0) -+ %3 = extractvalue { [16 x i64] } %2, 0 -+ %4 = extractvalue [16 x i64] %3, 15 -+ ret i64 %4 -+} -diff --git a/src/llvm-project/llvm/test/CodeGen/X86/zero-call-used-regs-i386.ll b/src/llvm-project/llvm/test/CodeGen/X86/zero-call-used-regs-i386.ll -new file mode 100644 -index 000000000..33e501ca8 ---- /dev/null -+++ b/src/llvm-project/llvm/test/CodeGen/X86/zero-call-used-regs-i386.ll -@@ -0,0 +1,112 @@ -+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py -+; RUN: llc < %s -mtriple=i386-unknown-linux-gnu -opaque-pointers | FileCheck %s --check-prefix=I386 -+; -+; Make sure we don't zero out %eax when both %ah and %al are used. -+; -+; PR1766: https://github.com/ClangBuiltLinux/linux/issues/1766 -+ -+%struct.maple_subtree_state = type { ptr } -+ -+@mas_data_end_type = dso_local local_unnamed_addr global i32 0, align 4 -+@ma_meta_end_mn_0_0_0_0_0_0 = dso_local local_unnamed_addr global i8 0, align 1 -+@mt_pivots_0 = dso_local local_unnamed_addr global i8 0, align 1 -+@mas_data_end___trans_tmp_2 = dso_local local_unnamed_addr global ptr null, align 4 -+@mt_slots_0 = dso_local local_unnamed_addr global i8 0, align 1 -+ -+define dso_local zeroext i1 @test1(ptr nocapture noundef readonly %0) local_unnamed_addr "zero-call-used-regs"="used-gpr" nounwind { -+; I386-LABEL: test1: -+; I386: # %bb.0: -+; I386-NEXT: pushl %ebx -+; I386-NEXT: subl $24, %esp -+; I386-NEXT: movl {{[0-9]+}}(%esp), %eax -+; I386-NEXT: movl (%eax), %eax -+; I386-NEXT: movzbl (%eax), %ebx -+; I386-NEXT: calll bar -+; I386-NEXT: testb %al, %al -+; I386-NEXT: # implicit-def: $al -+; I386-NEXT: # kill: killed $al -+; I386-NEXT: je .LBB0_6 -+; I386-NEXT: # %bb.1: -+; I386-NEXT: cmpl $0, mas_data_end_type -+; I386-NEXT: je .LBB0_3 -+; I386-NEXT: # %bb.2: -+; I386-NEXT: movzbl ma_meta_end_mn_0_0_0_0_0_0, %eax -+; I386-NEXT: movb %al, {{[-0-9]+}}(%e{{[sb]}}p) # 1-byte Spill -+; I386-NEXT: jmp .LBB0_6 -+; I386-NEXT: .LBB0_3: -+; I386-NEXT: movb mt_pivots_0, %ah -+; I386-NEXT: movb %ah, %al -+; I386-NEXT: decb %al -+; I386-NEXT: movl mas_data_end___trans_tmp_2, %ecx -+; I386-NEXT: movsbl %al, %edx -+; I386-NEXT: cmpl $0, (%ecx,%edx,4) -+; I386-NEXT: je .LBB0_5 -+; I386-NEXT: # %bb.4: -+; I386-NEXT: movb %al, %ah -+; I386-NEXT: .LBB0_5: -+; I386-NEXT: movb %ah, {{[-0-9]+}}(%e{{[sb]}}p) # 1-byte Spill -+; I386-NEXT: .LBB0_6: -+; I386-NEXT: movb mt_slots_0, %bh -+; I386-NEXT: leal {{[0-9]+}}(%esp), %eax -+; I386-NEXT: movl %eax, (%esp) -+; I386-NEXT: calll baz -+; I386-NEXT: subl $4, %esp -+; I386-NEXT: cmpb %bh, %bl -+; I386-NEXT: jae .LBB0_8 -+; I386-NEXT: # %bb.7: -+; I386-NEXT: movsbl {{[-0-9]+}}(%e{{[sb]}}p), %eax # 1-byte Folded Reload -+; I386-NEXT: movl %eax, (%esp) -+; I386-NEXT: calll gaz -+; I386-NEXT: .LBB0_8: -+; I386-NEXT: movb $1, %al -+; I386-NEXT: addl $24, %esp -+; I386-NEXT: popl %ebx -+; I386-NEXT: xorl %ecx, %ecx -+; I386-NEXT: xorl %edx, %edx -+; I386-NEXT: retl -+ %2 = alloca %struct.maple_subtree_state, align 4 -+ %3 = load ptr, ptr %0, align 4 -+ %4 = load i8, ptr %3, align 1 -+ %5 = tail call zeroext i1 @bar() -+ br i1 %5, label %6, label %20 -+ -+6: ; preds = %1 -+ %7 = load i32, ptr @mas_data_end_type, align 4 -+ %8 = icmp eq i32 %7, 0 -+ br i1 %8, label %11, label %9 -+ -+9: ; preds = %6 -+ %10 = load i8, ptr @ma_meta_end_mn_0_0_0_0_0_0, align 1 -+ br label %20 -+ -+11: ; preds = %6 -+ %12 = load i8, ptr @mt_pivots_0, align 1 -+ %13 = add i8 %12, -1 -+ %14 = load ptr, ptr @mas_data_end___trans_tmp_2, align 4 -+ %15 = sext i8 %13 to i32 -+ %16 = getelementptr inbounds [1 x i32], ptr %14, i32 0, i32 %15 -+ %17 = load i32, ptr %16, align 4 -+ %18 = icmp eq i32 %17, 0 -+ %19 = select i1 %18, i8 %12, i8 %13 -+ br label %20 -+ -+20: ; preds = %11, %9, %1 -+ %21 = phi i8 [ undef, %1 ], [ %10, %9 ], [ %19, %11 ] -+ %22 = load i8, ptr @mt_slots_0, align 1 -+ call void @baz(ptr nonnull sret(%struct.maple_subtree_state) align 4 %2) -+ %23 = icmp ult i8 %4, %22 -+ br i1 %23, label %24, label %25 -+ -+24: ; preds = %20 -+ call void @gaz(i8 noundef signext %21) -+ br label %25 -+ -+25: ; preds = %20, %24 -+ ret i1 true -+} -+ -+declare dso_local zeroext i1 @bar(...) local_unnamed_addr -+ -+declare dso_local void @baz(ptr sret(%struct.maple_subtree_state) align 4, ...) local_unnamed_addr -+ -+declare dso_local void @gaz(i8 noundef signext) local_unnamed_addr -diff --git a/src/llvm-project/llvm/test/MC/LoongArch/aligned-nops.s b/src/llvm-project/llvm/test/MC/LoongArch/aligned-nops.s -new file mode 100644 -index 000000000..2ef26ac4b ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/MC/LoongArch/atomic-error.s b/src/llvm-project/llvm/test/MC/LoongArch/atomic-error.s -new file mode 100644 -index 000000000..7e61a5ba5 ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/MC/LoongArch/atomic.s b/src/llvm-project/llvm/test/MC/LoongArch/atomic.s -new file mode 100644 -index 000000000..10a406550 ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/MC/LoongArch/fixups-expr.s b/src/llvm-project/llvm/test/MC/LoongArch/fixups-expr.s -new file mode 100644 -index 000000000..d35fe7e77 ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/MC/LoongArch/invalid.s b/src/llvm-project/llvm/test/MC/LoongArch/invalid.s -new file mode 100644 -index 000000000..e0fc7ce4b ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/MC/LoongArch/lit.local.cfg b/src/llvm-project/llvm/test/MC/LoongArch/lit.local.cfg -index 2b5a4893e..6223fc691 100644 ---- a/src/llvm-project/llvm/test/MC/LoongArch/lit.local.cfg -+++ b/src/llvm-project/llvm/test/MC/LoongArch/lit.local.cfg -@@ -1,2 +1,3 @@ - if not 'LoongArch' in config.root.targets: - config.unsupported = True -+ -diff --git a/src/llvm-project/llvm/test/MC/LoongArch/macro-la.s b/src/llvm-project/llvm/test/MC/LoongArch/macro-la.s -new file mode 100644 -index 000000000..eca76ac69 ---- /dev/null -+++ b/src/llvm-project/llvm/test/MC/LoongArch/macro-la.s -@@ -0,0 +1,168 @@ -+# 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.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/src/llvm-project/llvm/test/MC/LoongArch/macro-li.s b/src/llvm-project/llvm/test/MC/LoongArch/macro-li.s -new file mode 100644 -index 000000000..b1a7c58ba ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/MC/LoongArch/valid_12imm.s b/src/llvm-project/llvm/test/MC/LoongArch/valid_12imm.s -new file mode 100644 -index 000000000..ed44180bf ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/MC/LoongArch/valid_4operands.s b/src/llvm-project/llvm/test/MC/LoongArch/valid_4operands.s -new file mode 100644 -index 000000000..1418bb677 ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/MC/LoongArch/valid_bigimm.s b/src/llvm-project/llvm/test/MC/LoongArch/valid_bigimm.s -new file mode 100644 -index 000000000..d7b3bbb7d ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/MC/LoongArch/valid_branch.s b/src/llvm-project/llvm/test/MC/LoongArch/valid_branch.s -new file mode 100644 -index 000000000..256e70b6d ---- /dev/null -+++ b/src/llvm-project/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 -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/src/llvm-project/llvm/test/MC/LoongArch/valid_float.s b/src/llvm-project/llvm/test/MC/LoongArch/valid_float.s -new file mode 100644 -index 000000000..05ecefdc1 ---- /dev/null -+++ b/src/llvm-project/llvm/test/MC/LoongArch/valid_float.s -@@ -0,0 +1,297 @@ -+# 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: 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: 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/src/llvm-project/llvm/test/MC/LoongArch/valid_integer.s b/src/llvm-project/llvm/test/MC/LoongArch/valid_integer.s -new file mode 100644 -index 000000000..cc78662d5 ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/MC/LoongArch/valid_memory.s b/src/llvm-project/llvm/test/MC/LoongArch/valid_memory.s -new file mode 100644 -index 000000000..30ea88c99 ---- /dev/null -+++ b/src/llvm-project/llvm/test/MC/LoongArch/valid_memory.s -@@ -0,0 +1,405 @@ -+# 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: 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: 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.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.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: 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.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.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/src/llvm-project/llvm/test/MC/LoongArch/valid_priv.s b/src/llvm-project/llvm/test/MC/LoongArch/valid_priv.s -new file mode 100644 -index 000000000..57a252a8d ---- /dev/null -+++ b/src/llvm-project/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/src/llvm-project/llvm/test/Support/unix03-sigpipe-exit.test b/src/llvm-project/llvm/test/Support/unix03-sigpipe-exit.test -deleted file mode 100644 -index 01680841d..000000000 ---- a/src/llvm-project/llvm/test/Support/unix03-sigpipe-exit.test -+++ /dev/null -@@ -1,26 +0,0 @@ --## Test that when writing to a closed stdout, LLVM tools finish with a non-zero --## exit code and an error message on stderr. The test uses llvm-cxxfilt, but --## it's a logic from the default SIGPIPE handler, so it applies to all the tools. --## This is required for UNIX03 conformance. -- --# UNSUPPORTED: system-windows -- --# RUN: not %python %s llvm-cxxfilt 2>&1 | FileCheck %s --# CHECK: error: write on a pipe with no reader -- --import subprocess --import sys -- --with subprocess.Popen([sys.argv[1]], stdout=subprocess.PIPE, stdin=subprocess.PIPE) as process: -- process.stdout.close() -- -- # llvm-cxxfilt with no extra arguments runs interactively and writes input -- # to output. Writing continuously to stdin should trigger SIGPIPE when the -- # subprocess attempts to write out bytes to a closed stdout. -- try: -- while True: -- process.stdin.write("foo\n".encode("utf-8")) -- except BrokenPipeError: -- # Clear stdin, pipe is broken and closing it on cleanup will raise an exception. -- process.stdin = None --sys.exit(process.returncode) -diff --git a/src/llvm-project/llvm/test/Transforms/AtomicExpand/LoongArch/lit.local.cfg b/src/llvm-project/llvm/test/Transforms/AtomicExpand/LoongArch/lit.local.cfg -deleted file mode 100644 -index 31902e060..000000000 ---- a/src/llvm-project/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/src/llvm-project/llvm/test/Transforms/GlobalOpt/inalloca-varargs.ll b/src/llvm-project/llvm/test/Transforms/GlobalOpt/inalloca-varargs.ll -new file mode 100644 -index 000000000..188210782 ---- /dev/null -+++ b/src/llvm-project/llvm/test/Transforms/GlobalOpt/inalloca-varargs.ll -@@ -0,0 +1,38 @@ -+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature -+; RUN: opt -passes=globalopt -S < %s | FileCheck %s -+ -+define i32 @main(ptr %a) { -+; CHECK-LABEL: define {{[^@]+}}@main -+; CHECK-SAME: (ptr [[A:%.*]]) local_unnamed_addr { -+; CHECK-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{ ptr, i32 }>, align 4 -+; CHECK-NEXT: store ptr [[A]], ptr [[ARGMEM]], align 8 -+; CHECK-NEXT: [[G0:%.*]] = getelementptr inbounds <{ ptr, i32 }>, ptr [[ARGMEM]], i32 0, i32 1 -+; CHECK-NEXT: store i32 5, ptr [[G0]], align 4 -+; CHECK-NEXT: [[CALL3:%.*]] = call i32 (ptr, ...) @i(ptr inalloca(ptr) [[ARGMEM]]) -+; CHECK-NEXT: ret i32 [[CALL3]] -+; -+ %argmem = alloca inalloca <{ ptr, i32 }>, align 4 -+ store ptr %a, ptr %argmem, align 8 -+ %g0 = getelementptr inbounds <{ ptr, i32 }>, ptr %argmem, i32 0, i32 1 -+ store i32 5, ptr %g0, align 4 -+ %call3 = call i32 (ptr, ...) @i(ptr inalloca(ptr) %argmem) -+ ret i32 %call3 -+} -+ -+define internal i32 @i(ptr inalloca(ptr) %a, ...) { -+; CHECK-LABEL: define {{[^@]+}}@i -+; CHECK-SAME: (ptr inalloca(ptr) [[A:%.*]], ...) unnamed_addr { -+; CHECK-NEXT: [[AP:%.*]] = alloca ptr, align 4 -+; CHECK-NEXT: call void @llvm.va_start(ptr [[AP]]) -+; CHECK-NEXT: [[ARGP_CUR:%.*]] = load ptr, ptr [[AP]], align 4 -+; CHECK-NEXT: [[L:%.*]] = load i32, ptr [[ARGP_CUR]], align 4 -+; CHECK-NEXT: ret i32 [[L]] -+; -+ %ap = alloca ptr, align 4 -+ call void @llvm.va_start(ptr %ap) -+ %argp.cur = load ptr, ptr %ap, align 4 -+ %l = load i32, ptr %argp.cur, align 4 -+ ret i32 %l -+} -+ -+declare void @llvm.va_start(ptr) -diff --git a/src/llvm-project/llvm/test/Transforms/InstCombine/cast-byval.ll b/src/llvm-project/llvm/test/Transforms/InstCombine/cast-byval.ll -new file mode 100644 -index 000000000..b3e305583 ---- /dev/null -+++ b/src/llvm-project/llvm/test/Transforms/InstCombine/cast-byval.ll -@@ -0,0 +1,31 @@ -+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -+; Check that function calls involving conversion from/to byval aren't transformed. -+; RUN: opt < %s -passes=instcombine -S | FileCheck %s -+ -+%Foo = type { i64 } -+define i64 @foo (ptr byval(%Foo) %foo) { -+; CHECK-LABEL: @foo( -+; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr [[FOO:%.*]], align 4 -+; CHECK-NEXT: ret i64 [[TMP1]] -+; -+ %1 = load i64, ptr %foo, align 4 -+ ret i64 %1 -+} -+ -+define i64 @bar(i64 %0) { -+; CHECK-LABEL: @bar( -+; CHECK-NEXT: [[TMP2:%.*]] = tail call i64 @foo(i64 [[TMP0:%.*]]) -+; CHECK-NEXT: ret i64 [[TMP2]] -+; -+ %2 = tail call i64 @foo(i64 %0) -+ ret i64 %2 -+} -+ -+define i64 @qux(ptr byval(%Foo) %qux) { -+; CHECK-LABEL: @qux( -+; CHECK-NEXT: [[TMP1:%.*]] = tail call i64 @bar(ptr nonnull byval([[FOO:%.*]]) [[QUX:%.*]]) -+; CHECK-NEXT: ret i64 [[TMP1]] -+; -+ %1 = tail call i64 @bar(ptr byval(%Foo) %qux) -+ ret i64 %1 -+} -diff --git a/src/llvm-project/llvm/test/Transforms/LoopLoadElim/versioning-scev-invalidation.ll b/src/llvm-project/llvm/test/Transforms/LoopLoadElim/versioning-scev-invalidation.ll -new file mode 100644 -index 000000000..4b0bc908e ---- /dev/null -+++ b/src/llvm-project/llvm/test/Transforms/LoopLoadElim/versioning-scev-invalidation.ll -@@ -0,0 +1,125 @@ -+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -+; RUN: opt -force-vector-width=4 -force-vector-interleave=1 -passes='loop-vectorize,loop-load-elim' -S %s | FileCheck %s -+ -+@glob.1 = external global [100 x double] -+@glob.2 = external global [100 x double] -+ -+define void @g(ptr %dst.1, ptr %start, i64 %N) { -+; CHECK-LABEL: @g( -+; CHECK-NEXT: loop.1.lver.check: -+; CHECK-NEXT: [[TMP0:%.*]] = shl i64 [[N:%.*]], 3 -+; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[TMP0]], 16 -+; CHECK-NEXT: [[UGLYGEP:%.*]] = getelementptr i8, ptr @glob.2, i64 [[TMP1]] -+; CHECK-NEXT: [[UGLYGEP2:%.*]] = getelementptr i8, ptr [[DST_1:%.*]], i64 8 -+; CHECK-NEXT: [[BOUND0:%.*]] = icmp ult ptr @glob.2, [[UGLYGEP2]] -+; CHECK-NEXT: [[BOUND1:%.*]] = icmp ult ptr [[DST_1]], [[UGLYGEP]] -+; CHECK-NEXT: [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]] -+; CHECK-NEXT: br i1 [[FOUND_CONFLICT]], label [[LOOP_1_PH_LVER_ORIG:%.*]], label [[LOOP_1_PH:%.*]] -+; CHECK: loop.1.ph.lver.orig: -+; CHECK-NEXT: br label [[LOOP_1_LVER_ORIG:%.*]] -+; CHECK: loop.1.lver.orig: -+; CHECK-NEXT: [[IV_LVER_ORIG:%.*]] = phi i64 [ 0, [[LOOP_1_PH_LVER_ORIG]] ], [ [[IV_NEXT_LVER_ORIG:%.*]], [[LOOP_1_LVER_ORIG]] ] -+; CHECK-NEXT: [[PTR_IV_1_LVER_ORIG:%.*]] = phi ptr [ @glob.1, [[LOOP_1_PH_LVER_ORIG]] ], [ [[PTR_IV_1_NEXT_LVER_ORIG:%.*]], [[LOOP_1_LVER_ORIG]] ] -+; CHECK-NEXT: [[GEP_IV_LVER_ORIG:%.*]] = getelementptr inbounds double, ptr @glob.2, i64 [[IV_LVER_ORIG]] -+; CHECK-NEXT: [[L_1_LVER_ORIG:%.*]] = load double, ptr [[GEP_IV_LVER_ORIG]], align 8 -+; CHECK-NEXT: [[GEP_IV_1_LVER_ORIG:%.*]] = getelementptr inbounds double, ptr getelementptr inbounds (double, ptr @glob.2, i64 1), i64 [[IV_LVER_ORIG]] -+; CHECK-NEXT: store double 0.000000e+00, ptr [[GEP_IV_1_LVER_ORIG]], align 8 -+; CHECK-NEXT: store double 0.000000e+00, ptr [[DST_1]], align 8 -+; CHECK-NEXT: [[PTR_IV_1_NEXT_LVER_ORIG]] = getelementptr inbounds double, ptr [[PTR_IV_1_LVER_ORIG]], i64 1 -+; CHECK-NEXT: [[IV_NEXT_LVER_ORIG]] = add nuw nsw i64 [[IV_LVER_ORIG]], 1 -+; CHECK-NEXT: [[EXITCOND_NOT_LVER_ORIG:%.*]] = icmp eq i64 [[IV_LVER_ORIG]], [[N]] -+; CHECK-NEXT: br i1 [[EXITCOND_NOT_LVER_ORIG]], label [[LOOP_2_PH_LOOPEXIT:%.*]], label [[LOOP_1_LVER_ORIG]] -+; CHECK: loop.1.ph: -+; CHECK-NEXT: [[LOAD_INITIAL:%.*]] = load double, ptr @glob.2, align 8 -+; CHECK-NEXT: br label [[LOOP_1:%.*]] -+; CHECK: loop.1: -+; CHECK-NEXT: [[STORE_FORWARDED:%.*]] = phi double [ [[LOAD_INITIAL]], [[LOOP_1_PH]] ], [ 0.000000e+00, [[LOOP_1]] ] -+; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[LOOP_1_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_1]] ] -+; CHECK-NEXT: [[PTR_IV_1:%.*]] = phi ptr [ @glob.1, [[LOOP_1_PH]] ], [ [[PTR_IV_1_NEXT:%.*]], [[LOOP_1]] ] -+; CHECK-NEXT: [[GEP_IV:%.*]] = getelementptr inbounds double, ptr @glob.2, i64 [[IV]] -+; CHECK-NEXT: [[L_1:%.*]] = load double, ptr [[GEP_IV]], align 8 -+; CHECK-NEXT: [[GEP_IV_1:%.*]] = getelementptr inbounds double, ptr getelementptr inbounds (double, ptr @glob.2, i64 1), i64 [[IV]] -+; CHECK-NEXT: store double 0.000000e+00, ptr [[GEP_IV_1]], align 8 -+; CHECK-NEXT: store double 0.000000e+00, ptr [[DST_1]], align 8 -+; CHECK-NEXT: [[PTR_IV_1_NEXT]] = getelementptr inbounds double, ptr [[PTR_IV_1]], i64 1 -+; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 -+; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV]], [[N]] -+; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[LOOP_2_PH_LOOPEXIT3:%.*]], label [[LOOP_1]] -+; CHECK: loop.2.ph.loopexit: -+; CHECK-NEXT: [[LCSSA_PTR_IV_1_PH:%.*]] = phi ptr [ [[PTR_IV_1_LVER_ORIG]], [[LOOP_1_LVER_ORIG]] ] -+; CHECK-NEXT: br label [[LOOP_2_PH:%.*]] -+; CHECK: loop.2.ph.loopexit3: -+; CHECK-NEXT: [[LCSSA_PTR_IV_1_PH4:%.*]] = phi ptr [ [[PTR_IV_1]], [[LOOP_1]] ] -+; CHECK-NEXT: br label [[LOOP_2_PH]] -+; CHECK: loop.2.ph: -+; CHECK-NEXT: [[LCSSA_PTR_IV_1:%.*]] = phi ptr [ [[LCSSA_PTR_IV_1_PH]], [[LOOP_2_PH_LOOPEXIT]] ], [ [[LCSSA_PTR_IV_1_PH4]], [[LOOP_2_PH_LOOPEXIT3]] ] -+; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 4 -+; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] -+; CHECK: vector.ph: -+; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[N]], 4 -+; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[N]], [[N_MOD_VF]] -+; CHECK-NEXT: [[TMP2:%.*]] = mul i64 [[N_VEC]], 8 -+; CHECK-NEXT: [[IND_END:%.*]] = getelementptr i8, ptr [[LCSSA_PTR_IV_1]], i64 [[TMP2]] -+; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] -+; CHECK: vector.body: -+; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] -+; CHECK-NEXT: [[TMP3:%.*]] = add i64 [[INDEX]], 0 -+; CHECK-NEXT: [[TMP4:%.*]] = mul i64 [[TMP3]], 8 -+; CHECK-NEXT: [[NEXT_GEP:%.*]] = getelementptr i8, ptr [[LCSSA_PTR_IV_1]], i64 [[TMP4]] -+; CHECK-NEXT: [[TMP5:%.*]] = getelementptr double, ptr [[NEXT_GEP]], i32 0 -+; CHECK-NEXT: store <4 x double> zeroinitializer, ptr [[TMP5]], align 8 -+; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4 -+; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]] -+; CHECK-NEXT: br i1 [[TMP6]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]] -+; CHECK: middle.block: -+; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[N]], [[N_VEC]] -+; CHECK-NEXT: br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]] -+; CHECK: scalar.ph: -+; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[LOOP_2_PH]] ] -+; CHECK-NEXT: [[BC_RESUME_VAL1:%.*]] = phi ptr [ [[IND_END]], [[MIDDLE_BLOCK]] ], [ [[LCSSA_PTR_IV_1]], [[LOOP_2_PH]] ] -+; CHECK-NEXT: br label [[LOOP_2:%.*]] -+; CHECK: loop.2: -+; CHECK-NEXT: [[IV_2:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_2_NEXT:%.*]], [[LOOP_2]] ] -+; CHECK-NEXT: [[PTR_IV_2:%.*]] = phi ptr [ [[BC_RESUME_VAL1]], [[SCALAR_PH]] ], [ [[PTR_IV_2_NEXT:%.*]], [[LOOP_2]] ] -+; CHECK-NEXT: store double 0.000000e+00, ptr [[PTR_IV_2]], align 8 -+; CHECK-NEXT: [[PTR_IV_2_NEXT]] = getelementptr inbounds double, ptr [[PTR_IV_2]], i64 1 -+; CHECK-NEXT: [[IV_2_NEXT]] = add nuw nsw i64 [[IV_2]], 1 -+; CHECK-NEXT: [[EXITCOND_1_NOT:%.*]] = icmp eq i64 [[IV_2_NEXT]], [[N]] -+; CHECK-NEXT: br i1 [[EXITCOND_1_NOT]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP_2]], !llvm.loop [[LOOP2:![0-9]+]] -+; CHECK: exit.loopexit: -+; CHECK-NEXT: br label [[EXIT]] -+; CHECK: exit: -+; CHECK-NEXT: ret void -+; -+entry: -+ br label %loop.1 -+ -+loop.1: -+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.1 ] -+ %ptr.iv.1 = phi ptr [ @glob.1, %entry ], [ %ptr.iv.1.next, %loop.1 ] -+ %gep.iv = getelementptr inbounds double, ptr @glob.2, i64 %iv -+ %l.1 = load double, ptr %gep.iv, align 8 -+ %gep.iv.1 = getelementptr inbounds double, ptr getelementptr inbounds (double, ptr @glob.2, i64 1), i64 %iv -+ store double 0.000000e+00, ptr %gep.iv.1, align 8 -+ store double 0.000000e+00, ptr %dst.1, align 8 -+ %ptr.iv.1.next = getelementptr inbounds double, ptr %ptr.iv.1, i64 1 -+ %iv.next = add nuw nsw i64 %iv, 1 -+ %exitcond.not = icmp eq i64 %iv, %N -+ br i1 %exitcond.not, label %loop.2.ph, label %loop.1 -+ -+loop.2.ph: -+ %lcssa.ptr.iv.1 = phi ptr [ %ptr.iv.1, %loop.1 ] -+ br label %loop.2 -+ -+loop.2: -+ %iv.2 = phi i64 [ 0, %loop.2.ph ] , [ %iv.2.next, %loop.2 ] -+ %ptr.iv.2 = phi ptr [ %lcssa.ptr.iv.1, %loop.2.ph ], [ %ptr.iv.2.next, %loop.2 ] -+ store double 0.000000e+00, ptr %ptr.iv.2, align 8 -+ %ptr.iv.2.next = getelementptr inbounds double, ptr %ptr.iv.2, i64 1 -+ %iv.2.next = add nuw nsw i64 %iv.2, 1 -+ %exitcond.1.not = icmp eq i64 %iv.2.next, %N -+ br i1 %exitcond.1.not, label %exit, label %loop.2 -+ -+exit: -+ ret void -+} -diff --git a/src/llvm-project/llvm/test/Transforms/LoopVectorize/AArch64/interleave-allocsize-not-equal-typesize.ll b/src/llvm-project/llvm/test/Transforms/LoopVectorize/AArch64/interleave-allocsize-not-equal-typesize.ll -new file mode 100644 -index 000000000..32ca12ee7 ---- /dev/null -+++ b/src/llvm-project/llvm/test/Transforms/LoopVectorize/AArch64/interleave-allocsize-not-equal-typesize.ll -@@ -0,0 +1,141 @@ -+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -+; RUN: opt -passes=loop-vectorize -S %s | FileCheck %s -+ -+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" -+target triple = "aarch64-unknown-linux-gnu" -+ -+; Make sure LV does not crash when analyzing potential interleave groups with -+; accesses where the typesize doesn't match to allocsize. -+define void @pr58722_load_interleave_group(ptr %src, ptr %dst) { -+; CHECK-LABEL: @pr58722_load_interleave_group( -+; CHECK-NEXT: entry: -+; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_MEMCHECK:%.*]] -+; CHECK: vector.memcheck: -+; CHECK-NEXT: [[UGLYGEP:%.*]] = getelementptr i8, ptr [[DST:%.*]], i64 40004 -+; CHECK-NEXT: [[UGLYGEP1:%.*]] = getelementptr i8, ptr [[SRC:%.*]], i64 80007 -+; CHECK-NEXT: [[BOUND0:%.*]] = icmp ult ptr [[DST]], [[UGLYGEP1]] -+; CHECK-NEXT: [[BOUND1:%.*]] = icmp ult ptr [[SRC]], [[UGLYGEP]] -+; CHECK-NEXT: [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]] -+; CHECK-NEXT: br i1 [[FOUND_CONFLICT]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]] -+; CHECK: vector.ph: -+; 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:%.*]] = add i64 [[INDEX]], 1 -+; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[INDEX]], 2 -+; CHECK-NEXT: [[TMP3:%.*]] = add i64 [[INDEX]], 3 -+; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i64, ptr [[SRC]], i64 [[TMP0]] -+; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i64, ptr [[SRC]], i64 [[TMP1]] -+; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i64, ptr [[SRC]], i64 [[TMP2]] -+; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i64, ptr [[SRC]], i64 [[TMP3]] -+; CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP4]], align 4, !alias.scope !0 -+; CHECK-NEXT: [[TMP9:%.*]] = load i32, ptr [[TMP5]], align 4, !alias.scope !0 -+; CHECK-NEXT: [[TMP10:%.*]] = insertelement <2 x i32> poison, i32 [[TMP8]], i32 0 -+; CHECK-NEXT: [[TMP11:%.*]] = insertelement <2 x i32> [[TMP10]], i32 [[TMP9]], i32 1 -+; CHECK-NEXT: [[TMP12:%.*]] = load i32, ptr [[TMP6]], align 4, !alias.scope !0 -+; CHECK-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP7]], align 4, !alias.scope !0 -+; CHECK-NEXT: [[TMP14:%.*]] = insertelement <2 x i32> poison, i32 [[TMP12]], i32 0 -+; CHECK-NEXT: [[TMP15:%.*]] = insertelement <2 x i32> [[TMP14]], i32 [[TMP13]], i32 1 -+; CHECK-NEXT: [[TMP16:%.*]] = getelementptr inbounds i32, ptr [[TMP4]], i64 1 -+; CHECK-NEXT: [[TMP17:%.*]] = getelementptr inbounds i32, ptr [[TMP5]], i64 1 -+; CHECK-NEXT: [[TMP18:%.*]] = getelementptr inbounds i32, ptr [[TMP6]], i64 1 -+; CHECK-NEXT: [[TMP19:%.*]] = getelementptr inbounds i32, ptr [[TMP7]], i64 1 -+; CHECK-NEXT: [[TMP20:%.*]] = load i24, ptr [[TMP16]], align 4, !alias.scope !0 -+; CHECK-NEXT: [[TMP21:%.*]] = load i24, ptr [[TMP17]], align 4, !alias.scope !0 -+; CHECK-NEXT: [[TMP22:%.*]] = insertelement <2 x i24> poison, i24 [[TMP20]], i32 0 -+; CHECK-NEXT: [[TMP23:%.*]] = insertelement <2 x i24> [[TMP22]], i24 [[TMP21]], i32 1 -+; CHECK-NEXT: [[TMP24:%.*]] = load i24, ptr [[TMP18]], align 4, !alias.scope !0 -+; CHECK-NEXT: [[TMP25:%.*]] = load i24, ptr [[TMP19]], align 4, !alias.scope !0 -+; CHECK-NEXT: [[TMP26:%.*]] = insertelement <2 x i24> poison, i24 [[TMP24]], i32 0 -+; CHECK-NEXT: [[TMP27:%.*]] = insertelement <2 x i24> [[TMP26]], i24 [[TMP25]], i32 1 -+; CHECK-NEXT: [[TMP28:%.*]] = zext <2 x i24> [[TMP23]] to <2 x i32> -+; CHECK-NEXT: [[TMP29:%.*]] = zext <2 x i24> [[TMP27]] to <2 x i32> -+; CHECK-NEXT: [[TMP30:%.*]] = add <2 x i32> [[TMP11]], [[TMP28]] -+; CHECK-NEXT: [[TMP31:%.*]] = add <2 x i32> [[TMP15]], [[TMP29]] -+; CHECK-NEXT: [[TMP32:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[TMP0]] -+; CHECK-NEXT: [[TMP33:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[TMP2]] -+; CHECK-NEXT: [[TMP34:%.*]] = getelementptr inbounds i32, ptr [[TMP32]], i32 0 -+; CHECK-NEXT: store <2 x i32> [[TMP30]], ptr [[TMP34]], align 4, !alias.scope !3, !noalias !0 -+; CHECK-NEXT: [[TMP35:%.*]] = getelementptr inbounds i32, ptr [[TMP32]], i32 2 -+; CHECK-NEXT: store <2 x i32> [[TMP31]], ptr [[TMP35]], align 4, !alias.scope !3, !noalias !0 -+; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4 -+; CHECK-NEXT: [[TMP36:%.*]] = icmp eq i64 [[INDEX_NEXT]], 10000 -+; CHECK-NEXT: br i1 [[TMP36]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP5:![0-9]+]] -+; CHECK: middle.block: -+; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 10001, 10000 -+; CHECK-NEXT: br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]] -+; CHECK: scalar.ph: -+; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 10000, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ], [ 0, [[VECTOR_MEMCHECK]] ] -+; CHECK-NEXT: br label [[LOOP:%.*]] -+; CHECK: loop: -+; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] -+; CHECK-NEXT: [[GEP_IV:%.*]] = getelementptr inbounds i64, ptr [[SRC]], i64 [[IV]] -+; CHECK-NEXT: [[V1:%.*]] = load i32, ptr [[GEP_IV]], align 4 -+; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[GEP_IV]], i64 1 -+; CHECK-NEXT: [[V2:%.*]] = load i24, ptr [[GEP]], align 4 -+; CHECK-NEXT: [[V2_EXT:%.*]] = zext i24 [[V2]] to i32 -+; CHECK-NEXT: [[SUM:%.*]] = add i32 [[V1]], [[V2_EXT]] -+; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IV]] -+; CHECK-NEXT: store i32 [[SUM]], ptr [[GEP_DST]], align 4 -+; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 -+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IV]], 10000 -+; CHECK-NEXT: br i1 [[CMP]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP7:![0-9]+]] -+; CHECK: exit: -+; CHECK-NEXT: ret void -+; -+entry: -+ br label %loop -+ -+loop: -+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] -+ %gep.iv = getelementptr inbounds i64, ptr %src, i64 %iv -+ %v1 = load i32, ptr %gep.iv, align 4 -+ %gep = getelementptr inbounds i32, ptr %gep.iv, i64 1 -+ %v2 = load i24, ptr %gep, align 4 -+ %v2.ext = zext i24 %v2 to i32 -+ %sum = add i32 %v1, %v2.ext -+ %gep.dst = getelementptr inbounds i32, ptr %dst, i64 %iv -+ store i32 %sum, ptr %gep.dst -+ %iv.next = add i64 %iv, 1 -+ %cmp = icmp eq i64 %iv, 10000 -+ br i1 %cmp, label %exit, label %loop -+ -+exit: -+ ret void -+} -+ -+define void @pr58722_store_interleave_group(ptr %src, ptr %dst) { -+; CHECK-LABEL: @pr58722_store_interleave_group( -+; CHECK-NEXT: entry: -+; CHECK-NEXT: br label [[LOOP:%.*]] -+; CHECK: loop: -+; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] -+; CHECK-NEXT: [[GEP_IV:%.*]] = getelementptr inbounds i64, ptr [[SRC:%.*]], i32 [[IV]] -+; CHECK-NEXT: store i32 [[IV]], ptr [[GEP_IV]], align 4 -+; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i64, ptr [[GEP_IV]], i64 1 -+; CHECK-NEXT: [[TRUNC_IV:%.*]] = trunc i32 [[IV]] to i24 -+; CHECK-NEXT: store i24 [[TRUNC_IV]], ptr [[GEP]], align 4 -+; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 2 -+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[IV]], 10000 -+; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LOOP]] -+; CHECK: exit: -+; CHECK-NEXT: ret void -+; -+entry: -+ br label %loop -+ -+loop: -+ %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ] -+ %gep.iv = getelementptr inbounds i64, ptr %src, i32 %iv -+ store i32 %iv, ptr %gep.iv -+ %gep = getelementptr inbounds i64, ptr %gep.iv, i64 1 -+ %trunc.iv = trunc i32 %iv to i24 -+ store i24 %trunc.iv, ptr %gep -+ %iv.next = add i32 %iv, 2 -+ %cmp = icmp eq i32 %iv, 10000 -+ br i1 %cmp, label %exit, label %loop -+ -+exit: -+ ret void -+} -diff --git a/src/llvm-project/llvm/test/Transforms/SROA/phi-speculate-different-load-types.ll b/src/llvm-project/llvm/test/Transforms/SROA/phi-speculate-different-load-types.ll -new file mode 100644 -index 000000000..7893da340 ---- /dev/null -+++ b/src/llvm-project/llvm/test/Transforms/SROA/phi-speculate-different-load-types.ll -@@ -0,0 +1,41 @@ -+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -+; RUN: opt -passes=sroa < %s -S | FileCheck %s -+ -+define void @f(i1 %i) { -+; CHECK-LABEL: @f( -+; CHECK-NEXT: [[A1:%.*]] = alloca i64, align 8 -+; CHECK-NEXT: [[A2:%.*]] = alloca i64, align 8 -+; CHECK-NEXT: br i1 [[I:%.*]], label [[BB1:%.*]], label [[BB:%.*]] -+; CHECK: bb: -+; CHECK-NEXT: br label [[BB2:%.*]] -+; CHECK: bb1: -+; CHECK-NEXT: br label [[BB2]] -+; CHECK: bb2: -+; CHECK-NEXT: [[TMP3:%.*]] = phi ptr [ [[A1]], [[BB1]] ], [ [[A2]], [[BB]] ] -+; CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[TMP3]], align 4 -+; CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr [[TMP3]], align 4 -+; CHECK-NEXT: call void @use32(i32 [[TMP5]]) -+; CHECK-NEXT: call void @use64(i64 [[TMP4]]) -+; CHECK-NEXT: ret void -+; -+ %a1 = alloca i64 -+ %a2 = alloca i64 -+ br i1 %i, label %bb1, label %bb -+ -+bb: -+ br label %bb2 -+ -+bb1: -+ br label %bb2 -+ -+bb2: -+ %tmp3 = phi ptr [ %a1, %bb1 ], [ %a2, %bb ] -+ %tmp5 = load i32, ptr %tmp3 -+ %tmp4 = load i64, ptr %tmp3 -+ call void @use32(i32 %tmp5) -+ call void @use64(i64 %tmp4) -+ ret void -+} -+ -+declare void @use32(i32) -+declare void @use64(i64) -diff --git a/src/llvm-project/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_function_name.ll.expected b/src/llvm-project/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_function_name.ll.expected -index 692941b50..306b22ebb 100644 ---- a/src/llvm-project/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_function_name.ll.expected -+++ b/src/llvm-project/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_function_name.ll.expected -@@ -1,13 +1,13 @@ - ; 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 -+; RUN: llc -mtriple=loongarch64-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: jirl $zero, $ra, 0 -+; CHECK-NEXT: ori $r4, $zero, 2 -+; CHECK-NEXT: jr $ra - entry: - ret i32 2 - } -diff --git a/src/llvm-project/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.generated.expected b/src/llvm-project/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.generated.expected -deleted file mode 100644 -index 5d091d735..000000000 ---- a/src/llvm-project/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.generated.expected -+++ /dev/null -@@ -1,148 +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: bnez $zero, .LBB0_2 --; CHECK-NEXT: b .LBB0_1 --; CHECK-NEXT: .LBB0_2: --; CHECK-NEXT: ori $a0, $zero, 1 --; CHECK-NEXT: st.w $a0, $fp, -24 --; CHECK-NEXT: .LBB0_3: --; CHECK-NEXT: ld.w $a0, $fp, -16 --; CHECK-NEXT: bne $a0, $zero, .LBB0_5 --; CHECK-NEXT: b .LBB0_4 --; CHECK-NEXT: .LBB0_5: --; CHECK-NEXT: ori $a0, $zero, 1 --; CHECK-NEXT: st.w $a0, $fp, -24 --; CHECK-NEXT: .LBB0_6: --; 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: jirl $zero, $ra, 0 --; CHECK-NEXT: .LBB0_1: --; 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: b .LBB0_3 --; 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: b .LBB0_6 --; --; 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, x --; CHECK-NEXT: addi.w $a0, $a0, 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: jirl $zero, $ra, 0 -diff --git a/src/llvm-project/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.nogenerated.expected b/src/llvm-project/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.nogenerated.expected -deleted file mode 100644 -index d4edfe5e0..000000000 ---- a/src/llvm-project/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.nogenerated.expected -+++ /dev/null -@@ -1,147 +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: bnez $zero, .LBB0_2 --; CHECK-NEXT: b .LBB0_1 --; CHECK-NEXT: .LBB0_2: --; CHECK-NEXT: ori $a0, $zero, 1 --; CHECK-NEXT: st.w $a0, $fp, -24 --; CHECK-NEXT: .LBB0_3: --; CHECK-NEXT: ld.w $a0, $fp, -16 --; CHECK-NEXT: bne $a0, $zero, .LBB0_5 --; CHECK-NEXT: b .LBB0_4 --; CHECK-NEXT: .LBB0_5: --; CHECK-NEXT: ori $a0, $zero, 1 --; CHECK-NEXT: st.w $a0, $fp, -24 --; CHECK-NEXT: .LBB0_6: --; 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: jirl $zero, $ra, 0 --; CHECK-NEXT: .LBB0_1: --; 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: b .LBB0_3 --; 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: b .LBB0_6 -- %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, x --; CHECK-NEXT: addi.w $a0, $a0, 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: jirl $zero, $ra, 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/src/llvm-project/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/loongarch_generated_funcs.test b/src/llvm-project/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/loongarch_generated_funcs.test -deleted file mode 100644 -index 2209d3036..000000000 ---- a/src/llvm-project/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/src/llvm-project/llvm/test/tools/llvm-readobj/ELF/loongarch-eflags.test b/src/llvm-project/llvm/test/tools/llvm-readobj/ELF/loongarch-eflags.test -deleted file mode 100644 -index b66273640..000000000 ---- a/src/llvm-project/llvm/test/tools/llvm-readobj/ELF/loongarch-eflags.test -+++ /dev/null -@@ -1,64 +0,0 @@ --## Check llvm-readobj is able to decode all possible LoongArch e_flags field values. -- --# RUN: yaml2obj %s -o %t-lp64s -DCLASS=64 -DFLAG=LP64S --# RUN: llvm-readobj -h %t-lp64s | FileCheck --check-prefix=READOBJ-LP64S %s --# RUN: llvm-readelf -h %t-lp64s | FileCheck --check-prefix=READELF-LP64S --match-full-lines %s -- --# RUN: yaml2obj %s -o %t-lp64f -DCLASS=64 -DFLAG=LP64F --# RUN: llvm-readobj -h %t-lp64f | FileCheck --check-prefix=READOBJ-LP64F %s --# RUN: llvm-readelf -h %t-lp64f | FileCheck --check-prefix=READELF-LP64F --match-full-lines %s -- --# RUN: yaml2obj %s -o %t-lp64d -DCLASS=64 -DFLAG=LP64D --# RUN: llvm-readobj -h %t-lp64d | FileCheck --check-prefix=READOBJ-LP64D %s --# RUN: llvm-readelf -h %t-lp64d | FileCheck --check-prefix=READELF-LP64D --match-full-lines %s -- --# RUN: yaml2obj %s -o %t-ilp32s -DCLASS=32 -DFLAG=ILP32S --# RUN: llvm-readobj -h %t-ilp32s | FileCheck --check-prefix=READOBJ-ILP32S %s --# RUN: llvm-readelf -h %t-ilp32s | FileCheck --check-prefix=READELF-ILP32S --match-full-lines %s -- --# RUN: yaml2obj %s -o %t-ilp32f -DCLASS=32 -DFLAG=ILP32F --# RUN: llvm-readobj -h %t-ilp32f | FileCheck --check-prefix=READOBJ-ILP32F %s --# RUN: llvm-readelf -h %t-ilp32f | FileCheck --check-prefix=READELF-ILP32F --match-full-lines %s -- --# RUN: yaml2obj %s -o %t-ilp32d -DCLASS=32 -DFLAG=ILP32D --# RUN: llvm-readobj -h %t-ilp32d | FileCheck --check-prefix=READOBJ-ILP32D %s --# RUN: llvm-readelf -h %t-ilp32d | FileCheck --check-prefix=READELF-ILP32D --match-full-lines %s -- --# READOBJ-LP64S: Flags [ (0x1) --# READOBJ-LP64S-NEXT: EF_LOONGARCH_BASE_ABI_LP64S (0x1) --# READOBJ-LP64S-NEXT: ] -- --# READOBJ-LP64F: Flags [ (0x2) --# READOBJ-LP64F-NEXT: EF_LOONGARCH_BASE_ABI_LP64F (0x2) --# READOBJ-LP64F-NEXT: ] -- --# READOBJ-LP64D: Flags [ (0x3) --# READOBJ-LP64D-NEXT: EF_LOONGARCH_BASE_ABI_LP64D (0x3) --# READOBJ-LP64D-NEXT: ] -- --# READOBJ-ILP32S: Flags [ (0x5) --# READOBJ-ILP32S-NEXT: EF_LOONGARCH_BASE_ABI_ILP32S (0x5) --# READOBJ-ILP32S-NEXT: ] -- --# READOBJ-ILP32F: Flags [ (0x6) --# READOBJ-ILP32F-NEXT: EF_LOONGARCH_BASE_ABI_ILP32F (0x6) --# READOBJ-ILP32F-NEXT: ] -- --# READOBJ-ILP32D: Flags [ (0x7) --# READOBJ-ILP32D-NEXT: EF_LOONGARCH_BASE_ABI_ILP32D (0x7) --# READOBJ-ILP32D-NEXT: ] -- --# READELF-LP64S: Flags: 0x1, LP64, SOFT-FLOAT --# READELF-LP64F: Flags: 0x2, LP64, SINGLE-FLOAT --# READELF-LP64D: Flags: 0x3, LP64, DOUBLE-FLOAT --# READELF-ILP32S: Flags: 0x5, ILP32, SOFT-FLOAT --# READELF-ILP32F: Flags: 0x6, ILP32, SINGLE-FLOAT --# READELF-ILP32D: Flags: 0x7, ILP32, DOUBLE-FLOAT -- ----- !ELF --FileHeader: -- Class: ELFCLASS[[CLASS]] -- Data: ELFDATA2LSB -- Type: ET_EXEC -- Machine: EM_LOONGARCH -- Flags: [ EF_LOONGARCH_BASE_ABI_[[FLAG]] ] -diff --git a/src/llvm-project/llvm/test/tools/obj2yaml/ELF/loongarch-eflags.yaml b/src/llvm-project/llvm/test/tools/obj2yaml/ELF/loongarch-eflags.yaml -deleted file mode 100644 -index e4c4c292e..000000000 ---- a/src/llvm-project/llvm/test/tools/obj2yaml/ELF/loongarch-eflags.yaml -+++ /dev/null -@@ -1,29 +0,0 @@ --## Check obj2yaml is able to decode all possible LoongArch e_flags field values. -- --# RUN: yaml2obj %s -o %t-lp64s -DCLASS=64 -DFLAG=LP64S --# RUN: obj2yaml %t-lp64s | FileCheck -DFLAG=LP64S %s -- --# RUN: yaml2obj %s -o %t-lp64f -DCLASS=64 -DFLAG=LP64F --# RUN: obj2yaml %t-lp64f | FileCheck -DFLAG=LP64F %s -- --# RUN: yaml2obj %s -o %t-lp64d -DCLASS=64 -DFLAG=LP64D --# RUN: obj2yaml %t-lp64d | FileCheck -DFLAG=LP64D %s -- --# RUN: yaml2obj %s -o %t-ilp32s -DCLASS=32 -DFLAG=ILP32S --# RUN: obj2yaml %t-ilp32s | FileCheck -DFLAG=ILP32S %s -- --# RUN: yaml2obj %s -o %t-ilp32f -DCLASS=32 -DFLAG=ILP32F --# RUN: obj2yaml %t-ilp32f | FileCheck -DFLAG=ILP32F %s -- --# RUN: yaml2obj %s -o %t-ilp32d -DCLASS=32 -DFLAG=ILP32D --# RUN: obj2yaml %t-ilp32d | FileCheck -DFLAG=ILP32D %s -- --# CHECK: Flags: [ EF_LOONGARCH_BASE_ABI_[[FLAG]] ] -- ----- !ELF --FileHeader: -- Class: ELFCLASS[[CLASS]] -- Data: ELFDATA2LSB -- Type: ET_EXEC -- Machine: EM_LOONGARCH -- Flags: [ EF_LOONGARCH_BASE_ABI_[[FLAG]] ] -diff --git a/src/llvm-project/llvm/tools/dsymutil/CMakeLists.txt b/src/llvm-project/llvm/tools/dsymutil/CMakeLists.txt -index a255c1c5d..38028cd3d 100644 ---- a/src/llvm-project/llvm/tools/dsymutil/CMakeLists.txt -+++ b/src/llvm-project/llvm/tools/dsymutil/CMakeLists.txt -@@ -40,6 +40,4 @@ if(APPLE) - target_link_libraries(dsymutil PRIVATE "-framework CoreFoundation") - endif(APPLE) - --if(HAVE_CXX_ATOMICS_WITH_LIB OR HAVE_CXX_ATOMICS64_WITH_LIB) -- target_link_libraries(dsymutil PRIVATE atomic) --endif() -+target_link_libraries(dsymutil PRIVATE ${LLVM_ATOMIC_LIB}) -diff --git a/src/llvm-project/llvm/tools/llvm-config/CMakeLists.txt b/src/llvm-project/llvm/tools/llvm-config/CMakeLists.txt -index aa5aa2025..6faee031a 100644 ---- a/src/llvm-project/llvm/tools/llvm-config/CMakeLists.txt -+++ b/src/llvm-project/llvm/tools/llvm-config/CMakeLists.txt -@@ -17,9 +17,14 @@ add_llvm_tool(llvm-config - # Compute the substitution values for various items. - get_property(SUPPORT_SYSTEM_LIBS TARGET LLVMSupport PROPERTY LLVM_SYSTEM_LIBS) - get_property(WINDOWSMANIFEST_SYSTEM_LIBS TARGET LLVMWindowsManifest PROPERTY LLVM_SYSTEM_LIBS) -+ - foreach(l ${SUPPORT_SYSTEM_LIBS} ${WINDOWSMANIFEST_SYSTEM_LIBS}) - if(MSVC) -- set(SYSTEM_LIBS ${SYSTEM_LIBS} "${l}.lib") -+ if(IS_ABSOLUTE ${l}) -+ set(SYSTEM_LIBS ${SYSTEM_LIBS} "${l}") -+ else() -+ set(SYSTEM_LIBS ${SYSTEM_LIBS} "${l}.lib") -+ endif() - else() - if (l MATCHES "^-") - # If it's an option, pass it without changes. -@@ -34,6 +39,7 @@ foreach(l ${SUPPORT_SYSTEM_LIBS} ${WINDOWSMANIFEST_SYSTEM_LIBS}) - endif() - endif() - endforeach() -+ - string(REPLACE ";" " " SYSTEM_LIBS "${SYSTEM_LIBS}") - - # Fetch target specific compile options, e.g. RTTI option -diff --git a/src/llvm-project/llvm/tools/llvm-readobj/ELFDumper.cpp b/src/llvm-project/llvm/tools/llvm-readobj/ELFDumper.cpp -index ba7bae96a..ae2dec5d1 100644 ---- a/src/llvm-project/llvm/tools/llvm-readobj/ELFDumper.cpp -+++ b/src/llvm-project/llvm/tools/llvm-readobj/ELFDumper.cpp -@@ -1648,15 +1648,6 @@ const EnumEntry ElfHeaderAVRFlags[] = { - ENUM_ENT(EF_AVR_LINKRELAX_PREPARED, "relaxable"), - }; - --const EnumEntry ElfHeaderLoongArchFlags[] = { -- ENUM_ENT(EF_LOONGARCH_BASE_ABI_ILP32S, "ILP32, SOFT-FLOAT"), -- ENUM_ENT(EF_LOONGARCH_BASE_ABI_ILP32F, "ILP32, SINGLE-FLOAT"), -- ENUM_ENT(EF_LOONGARCH_BASE_ABI_ILP32D, "ILP32, DOUBLE-FLOAT"), -- ENUM_ENT(EF_LOONGARCH_BASE_ABI_LP64S, "LP64, SOFT-FLOAT"), -- ENUM_ENT(EF_LOONGARCH_BASE_ABI_LP64F, "LP64, SINGLE-FLOAT"), -- ENUM_ENT(EF_LOONGARCH_BASE_ABI_LP64D, "LP64, DOUBLE-FLOAT"), --}; -- - - const EnumEntry ElfSymOtherFlags[] = { - LLVM_READOBJ_ENUM_ENT(ELF, STV_INTERNAL), -@@ -3366,9 +3357,6 @@ template void GNUELFDumper::printFileHeaders() { - else if (e.e_machine == EM_AVR) - ElfFlags = printFlags(e.e_flags, makeArrayRef(ElfHeaderAVRFlags), - unsigned(ELF::EF_AVR_ARCH_MASK)); -- else if (e.e_machine == EM_LOONGARCH) -- ElfFlags = printFlags(e.e_flags, makeArrayRef(ElfHeaderLoongArchFlags), -- unsigned(ELF::EF_LOONGARCH_BASE_ABI_MASK)); - Str = "0x" + utohexstr(e.e_flags); - if (!ElfFlags.empty()) - Str = Str + ", " + ElfFlags; -@@ -6519,9 +6507,6 @@ template void LLVMELFDumper::printFileHeaders() { - else if (E.e_machine == EM_AVR) - W.printFlags("Flags", E.e_flags, makeArrayRef(ElfHeaderAVRFlags), - unsigned(ELF::EF_AVR_ARCH_MASK)); -- else if (E.e_machine == EM_LOONGARCH) -- W.printFlags("Flags", E.e_flags, makeArrayRef(ElfHeaderLoongArchFlags), -- unsigned(ELF::EF_LOONGARCH_BASE_ABI_MASK)); - else - W.printFlags("Flags", E.e_flags); - W.printNumber("HeaderSize", E.e_ehsize); -diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/misc/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/misc/BUILD.gn -index c8506d9ef..7431a507c 100644 ---- a/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/misc/BUILD.gn -+++ b/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/misc/BUILD.gn -@@ -1,7 +1,7 @@ - import("//llvm/utils/gn/build/compiled_action.gni") - - compiled_action("Confusables.inc") { -- tool = "ConfusableTable:make-confusable-table" -+ tool = "ConfusableTable:clang-tidy-confusable-chars-gen" - inputs = [ "ConfusableTable/confusables.txt" ] - outputs = [ "$target_gen_dir/$target_name" ] - args = [ -diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/version.gni b/src/llvm-project/llvm/utils/gn/secondary/llvm/version.gni -index ac79ba5bb..d485a133f 100644 ---- a/src/llvm-project/llvm/utils/gn/secondary/llvm/version.gni -+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/version.gni -@@ -1,4 +1,4 @@ - llvm_version_major = 15 - llvm_version_minor = 0 --llvm_version_patch = 2 -+llvm_version_patch = 7 - llvm_version = "$llvm_version_major.$llvm_version_minor.$llvm_version_patch" -diff --git a/src/llvm-project/llvm/utils/lit/lit/__init__.py b/src/llvm-project/llvm/utils/lit/lit/__init__.py -index 2ee97f578..928d6db8d 100644 ---- a/src/llvm-project/llvm/utils/lit/lit/__init__.py -+++ b/src/llvm-project/llvm/utils/lit/lit/__init__.py -@@ -2,7 +2,7 @@ - - __author__ = 'Daniel Dunbar' - __email__ = 'daniel@minormatter.com' --__versioninfo__ = (15, 0, 2) -+__versioninfo__ = (15, 0, 7) - __version__ = '.'.join(str(v) for v in __versioninfo__) + 'dev' - - __all__ = [] -diff --git a/src/llvm-project/llvm/utils/lit/lit/llvm/config.py b/src/llvm-project/llvm/utils/lit/lit/llvm/config.py -index b65316128..7dae83733 100644 ---- a/src/llvm-project/llvm/utils/lit/lit/llvm/config.py -+++ b/src/llvm-project/llvm/utils/lit/lit/llvm/config.py -@@ -609,7 +609,7 @@ class LLVMConfig(object): - self.with_environment('PATH', paths, append_path=True) - - lib_dir_props = [self.config.name.lower() + '_libs_dir', -- 'lld_libs_dir', 'llvm_libs_dir'] -+ 'lld_libs_dir', 'llvm_shlib_dir', 'llvm_libs_dir'] - lib_paths = [getattr(self.config, pp) for pp in lib_dir_props - if getattr(self.config, pp, None)] - --- -2.41.0 - diff --git a/0006-rust-add-loongarch64-support.patch b/0006-rust-add-loongarch64-support.patch deleted file mode 100644 index 2b91418201ae641c7148c1913ea2ea5498b00ad3..0000000000000000000000000000000000000000 --- a/0006-rust-add-loongarch64-support.patch +++ /dev/null @@ -1,1691 +0,0 @@ -From d81a20d98d9fd47edb762a1716b65d4bfeffae60 Mon Sep 17 00:00:00 2001 -From: WANG Rui -Date: Wed, 26 Apr 2023 14:26:58 +0800 -Subject: [PATCH 6/6] rust: add loongarch64 support - ---- - compiler/rustc_ast_lowering/src/asm.rs | 1 + - .../rustc_codegen_gcc/example/alloc_system.rs | 1 + - compiler/rustc_codegen_gcc/src/asm.rs | 5 + - compiler/rustc_codegen_llvm/src/asm.rs | 17 + - .../rustc_codegen_ssa/src/back/metadata.rs | 6 + - .../rustc_codegen_ssa/src/target_features.rs | 6 + - compiler/rustc_feature/src/active.rs | 1 + - compiler/rustc_hir_analysis/src/collect.rs | 1 + - compiler/rustc_llvm/build.rs | 3 +- - .../rustc_llvm/llvm-wrapper/PassWrapper.cpp | 7 + - compiler/rustc_llvm/src/lib.rs | 8 + - compiler/rustc_span/src/symbol.rs | 1 + - .../rustc_target/src/abi/call/loongarch.rs | 342 ++++++++++++++++++ - compiler/rustc_target/src/abi/call/mod.rs | 2 + - compiler/rustc_target/src/asm/loongarch.rs | 131 +++++++ - compiler/rustc_target/src/asm/mod.rs | 44 +++ - .../src/spec/loongarch64_unknown_linux_gnu.rs | 18 + - compiler/rustc_target/src/spec/mod.rs | 2 + - library/std/src/env.rs | 1 + - library/std/src/os/linux/raw.rs | 1 + - library/std/src/personality/gcc.rs | 3 + - library/std/src/sys/common/alloc.rs | 1 + - library/unwind/src/libunwind.rs | 3 + - src/bootstrap/bootstrap.py | 1 + - src/bootstrap/lib.rs | 2 +- - src/bootstrap/native.rs | 2 +- - src/ci/github-actions/ci.yml | 3 + - src/doc/rustc/src/platform-support.md | 1 + - src/librustdoc/clean/cfg.rs | 1 + - src/test/assembly/asm/loongarch-types.rs | 194 ++++++++++ - .../codegen/abi-main-signature-16bit-c-int.rs | 1 + - src/test/codegen/call-llvm-intrinsics.rs | 1 + - src/test/codegen/global_asm.rs | 1 + - src/test/codegen/global_asm_include.rs | 1 + - src/test/codegen/global_asm_x2.rs | 1 + - .../loongarch-abi/call-llvm-intrinsics.rs | 30 ++ - .../codegen/repr-transparent-aggregates-1.rs | 1 + - .../codegen/repr-transparent-aggregates-2.rs | 1 + - src/test/codegen/repr-transparent.rs | 1 + - .../atomic-lock-free/Makefile | 4 + - src/test/ui/abi/stack-probes-lto.rs | 1 + - src/test/ui/cfg/conditional-compile-arch.rs | 3 + - src/test/ui/check-cfg/compact-values.stderr | 2 +- - src/test/ui/process/nofile-limit.rs | 3 +- - src/test/ui/target-feature/gate.rs | 2 + - .../ui/target-feature/invalid-attribute.rs | 1 + - src/tools/build-manifest/src/main.rs | 2 + - src/tools/clippy/tests/ui/asm_syntax.rs | 1 + - src/tools/compiletest/src/common.rs | 2 +- - 49 files changed, 862 insertions(+), 6 deletions(-) - create mode 100644 compiler/rustc_target/src/abi/call/loongarch.rs - create mode 100644 compiler/rustc_target/src/asm/loongarch.rs - create mode 100644 compiler/rustc_target/src/spec/loongarch64_unknown_linux_gnu.rs - create mode 100644 src/test/assembly/asm/loongarch-types.rs - create mode 100644 src/test/codegen/loongarch-abi/call-llvm-intrinsics.rs - -diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs -index 450cdf246..260a0b24b 100644 ---- a/compiler/rustc_ast_lowering/src/asm.rs -+++ b/compiler/rustc_ast_lowering/src/asm.rs -@@ -44,6 +44,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { - | asm::InlineAsmArch::AArch64 - | asm::InlineAsmArch::RiscV32 - | asm::InlineAsmArch::RiscV64 -+ | asm::InlineAsmArch::LoongArch64 - ); - if !is_stable && !self.tcx.features().asm_experimental_arch { - feature_err( -diff --git a/compiler/rustc_codegen_gcc/example/alloc_system.rs b/compiler/rustc_codegen_gcc/example/alloc_system.rs -index 89661918d..df960c4b8 100644 ---- a/compiler/rustc_codegen_gcc/example/alloc_system.rs -+++ b/compiler/rustc_codegen_gcc/example/alloc_system.rs -@@ -21,6 +21,7 @@ - const MIN_ALIGN: usize = 8; - #[cfg(all(any(target_arch = "x86_64", - target_arch = "aarch64", -+ target_arch = "loongarch64", - target_arch = "mips64", - target_arch = "s390x", - target_arch = "sparc64")))] -diff --git a/compiler/rustc_codegen_gcc/src/asm.rs b/compiler/rustc_codegen_gcc/src/asm.rs -index c346dbd63..58563ac9a 100644 ---- a/compiler/rustc_codegen_gcc/src/asm.rs -+++ b/compiler/rustc_codegen_gcc/src/asm.rs -@@ -582,6 +582,8 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister { - InlineAsmRegClass::Avr(_) => unimplemented!(), - InlineAsmRegClass::Bpf(_) => unimplemented!(), - InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg) => unimplemented!(), -+ InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => unimplemented!(), -+ InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg) => unimplemented!(), - InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg) => unimplemented!(), - InlineAsmRegClass::Mips(MipsInlineAsmRegClass::freg) => unimplemented!(), - InlineAsmRegClass::Msp430(_) => unimplemented!(), -@@ -646,6 +648,8 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl - InlineAsmRegClass::Avr(_) => unimplemented!(), - InlineAsmRegClass::Bpf(_) => unimplemented!(), - InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg) => cx.type_i32(), -+ InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => cx.type_i32(), -+ InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg) => cx.type_f32(), - InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg) => cx.type_i32(), - InlineAsmRegClass::Mips(MipsInlineAsmRegClass::freg) => cx.type_f32(), - InlineAsmRegClass::Msp430(_) => unimplemented!(), -@@ -773,6 +777,7 @@ fn modifier_to_gcc(arch: InlineAsmArch, reg: InlineAsmRegClass, modifier: Option - InlineAsmRegClass::Avr(_) => unimplemented!(), - InlineAsmRegClass::Bpf(_) => unimplemented!(), - InlineAsmRegClass::Hexagon(_) => unimplemented!(), -+ InlineAsmRegClass::LoongArch(_) => unimplemented!(), - InlineAsmRegClass::Mips(_) => unimplemented!(), - InlineAsmRegClass::Msp430(_) => unimplemented!(), - InlineAsmRegClass::Nvptx(_) => unimplemented!(), -diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs -index 017513721..2d380f1c4 100644 ---- a/compiler/rustc_codegen_llvm/src/asm.rs -+++ b/compiler/rustc_codegen_llvm/src/asm.rs -@@ -235,6 +235,18 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { - InlineAsmArch::Msp430 => { - constraints.push("~{sr}".to_string()); - } -+ InlineAsmArch::LoongArch64 => { -+ constraints.extend_from_slice(&[ -+ "~{$fcc0}".to_string(), -+ "~{$fcc1}".to_string(), -+ "~{$fcc2}".to_string(), -+ "~{$fcc3}".to_string(), -+ "~{$fcc4}".to_string(), -+ "~{$fcc5}".to_string(), -+ "~{$fcc6}".to_string(), -+ "~{$fcc7}".to_string(), -+ ]); -+ } - } - } - if !options.contains(InlineAsmOptions::NOMEM) { -@@ -614,6 +626,8 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) -> - InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => { - bug!("LLVM backend does not support SPIR-V") - } -+ InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => "r", -+ InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg) => "f", - InlineAsmRegClass::Err => unreachable!(), - } - .to_string(), -@@ -708,6 +722,7 @@ fn modifier_to_llvm( - InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => { - bug!("LLVM backend does not support SPIR-V") - } -+ InlineAsmRegClass::LoongArch(_) => None, - InlineAsmRegClass::Err => unreachable!(), - } - } -@@ -782,6 +797,8 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &' - InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => { - bug!("LLVM backend does not support SPIR-V") - } -+ InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => cx.type_i32(), -+ InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg) => cx.type_f32(), - InlineAsmRegClass::Err => unreachable!(), - } - } -diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs -index 99ddd1764..ae639d064 100644 ---- a/compiler/rustc_codegen_ssa/src/back/metadata.rs -+++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs -@@ -121,6 +121,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option Architecture::Msp430, - "hexagon" => Architecture::Hexagon, - "bpf" => Architecture::Bpf, -+ "loongarch64" => Architecture::LoongArch64, - // Unsupported architecture. - _ => return None, - }; -@@ -172,6 +173,11 @@ pub(crate) fn create_object_file(sess: &Session) -> Option { -+ // copied from `loongarch64-linux-gnu-gcc foo.c -c` -+ let e_flags = elf::EF_LARCH_ABI; -+ e_flags -+ } - _ => 0, - }; - // adapted from LLVM's `MCELFObjectTargetWriter::getOSABI` -diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs -index 83407ee8f..93d5b79c4 100644 ---- a/compiler/rustc_codegen_ssa/src/target_features.rs -+++ b/compiler/rustc_codegen_ssa/src/target_features.rs -@@ -209,6 +209,10 @@ const HEXAGON_ALLOWED_FEATURES: &[(&str, Option)] = &[ - // tidy-alphabetical-end - ]; - -+const LOONGARCH64_ALLOWED_FEATURES: &[(&str, Option)] = &[ -+ ("fp64", Some(sym::loongarch64_target_feature)), -+]; -+ - const POWERPC_ALLOWED_FEATURES: &[(&str, Option)] = &[ - // tidy-alphabetical-start - ("altivec", Some(sym::powerpc_target_feature)), -@@ -292,6 +296,7 @@ pub fn all_known_features() -> impl Iterator &'static [(&'static str, Opt - "riscv32" | "riscv64" => RISCV_ALLOWED_FEATURES, - "wasm32" | "wasm64" => WASM_ALLOWED_FEATURES, - "bpf" => BPF_ALLOWED_FEATURES, -+ "loongarch64" => LOONGARCH64_ALLOWED_FEATURES, - _ => &[], - } - } -diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs -index 647ccdec7..546a24164 100644 ---- a/compiler/rustc_feature/src/active.rs -+++ b/compiler/rustc_feature/src/active.rs -@@ -254,6 +254,7 @@ declare_features! ( - (active, ermsb_target_feature, "1.49.0", Some(44839), None), - (active, f16c_target_feature, "1.36.0", Some(44839), None), - (active, hexagon_target_feature, "1.27.0", Some(44839), None), -+ (active, loongarch64_target_feature, "1.57.0", Some(44839), None), - (active, mips_target_feature, "1.27.0", Some(44839), None), - (active, movbe_target_feature, "1.34.0", Some(44839), None), - (active, powerpc_target_feature, "1.27.0", Some(44839), None), -diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs -index 346d2e2fc..083f661c8 100644 ---- a/compiler/rustc_hir_analysis/src/collect.rs -+++ b/compiler/rustc_hir_analysis/src/collect.rs -@@ -1538,6 +1538,7 @@ fn from_target_feature( - let allowed = match feature_gate.as_ref().copied() { - Some(sym::arm_target_feature) => rust_features.arm_target_feature, - Some(sym::hexagon_target_feature) => rust_features.hexagon_target_feature, -+ Some(sym::loongarch64_target_feature) => rust_features.loongarch64_target_feature, - Some(sym::powerpc_target_feature) => rust_features.powerpc_target_feature, - Some(sym::mips_target_feature) => rust_features.mips_target_feature, - Some(sym::riscv_target_feature) => rust_features.riscv_target_feature, -diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs -index 28e092c1e..c0c60bc0c 100644 ---- a/compiler/rustc_llvm/build.rs -+++ b/compiler/rustc_llvm/build.rs -@@ -10,6 +10,7 @@ const OPTIONAL_COMPONENTS: &[&str] = &[ - "aarch64", - "amdgpu", - "avr", -+ "loongarch", - "m68k", - "mips", - "powerpc", -@@ -240,7 +241,7 @@ fn main() { - } else if target.contains("windows-gnu") { - println!("cargo:rustc-link-lib=shell32"); - println!("cargo:rustc-link-lib=uuid"); -- } else if target.contains("netbsd") || target.contains("haiku") || target.contains("darwin") { -+ } else if target.contains("netbsd") || target.contains("haiku") || target.contains("darwin") || target.contains("loongarch") { - println!("cargo:rustc-link-lib=z"); - } else if target.starts_with("arm") - || target.starts_with("mips-") -diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp -index 18d37d95a..ac91ee420 100644 ---- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp -+++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp -@@ -166,6 +166,12 @@ extern "C" void LLVMTimeTraceProfilerFinish(const char* FileName) { - #define SUBTARGET_HEXAGON - #endif - -+#ifdef LLVM_COMPONENT_LOONGARCH -+#define SUBTARGET_LOONGARCH SUBTARGET(LoongArch) -+#else -+#define SUBTARGET_LOONGARCH -+#endif -+ - #define GEN_SUBTARGETS \ - SUBTARGET_X86 \ - SUBTARGET_ARM \ -@@ -179,6 +185,7 @@ extern "C" void LLVMTimeTraceProfilerFinish(const char* FileName) { - SUBTARGET_SPARC \ - SUBTARGET_HEXAGON \ - SUBTARGET_RISCV \ -+ SUBTARGET_LOONGARCH \ - - #define SUBTARGET(x) \ - namespace llvm { \ -diff --git a/compiler/rustc_llvm/src/lib.rs b/compiler/rustc_llvm/src/lib.rs -index 8542dcf5b..06351731b 100644 ---- a/compiler/rustc_llvm/src/lib.rs -+++ b/compiler/rustc_llvm/src/lib.rs -@@ -102,6 +102,14 @@ pub fn initialize_available_targets() { - LLVMInitializeM68kAsmPrinter, - LLVMInitializeM68kAsmParser - ); -+ init_target!( -+ llvm_component = "loongarch", -+ LLVMInitializeLoongArchTargetInfo, -+ LLVMInitializeLoongArchTarget, -+ LLVMInitializeLoongArchTargetMC, -+ LLVMInitializeLoongArchAsmPrinter, -+ LLVMInitializeLoongArchAsmParser -+ ); - init_target!( - llvm_component = "mips", - LLVMInitializeMipsTargetInfo, -diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs -index 7f16da52b..b0c040f72 100644 ---- a/compiler/rustc_span/src/symbol.rs -+++ b/compiler/rustc_span/src/symbol.rs -@@ -900,6 +900,7 @@ symbols! { - log_syntax, - logf32, - logf64, -+ loongarch64_target_feature, - loop_break_value, - lt, - macro_at_most_once_rep, -diff --git a/compiler/rustc_target/src/abi/call/loongarch.rs b/compiler/rustc_target/src/abi/call/loongarch.rs -new file mode 100644 -index 000000000..018fe7d15 ---- /dev/null -+++ b/compiler/rustc_target/src/abi/call/loongarch.rs -@@ -0,0 +1,342 @@ -+use crate::abi::call::{ArgAbi, ArgExtension, CastTarget, FnAbi, PassMode, Reg, RegKind, Uniform}; -+use crate::abi::{self, Abi, FieldsShape, HasDataLayout, Size, TyAbiInterface, TyAndLayout}; -+use crate::spec::HasTargetSpec; -+ -+#[derive(Copy, Clone)] -+enum RegPassKind { -+ Float(Reg), -+ Integer(Reg), -+ Unknown, -+} -+ -+#[derive(Copy, Clone)] -+enum FloatConv { -+ FloatPair(Reg, Reg), -+ Float(Reg), -+ MixedPair(Reg, Reg), -+} -+ -+#[derive(Copy, Clone)] -+struct CannotUseFpConv; -+ -+fn is_loongarch_aggregate<'a, Ty>(arg: &ArgAbi<'a, Ty>) -> bool { -+ match arg.layout.abi { -+ Abi::Vector { .. } => true, -+ _ => arg.layout.is_aggregate(), -+ } -+} -+ -+fn should_use_fp_conv_helper<'a, Ty, C>( -+ cx: &C, -+ arg_layout: &TyAndLayout<'a, Ty>, -+ xlen: u64, -+ flen: u64, -+ field1_kind: &mut RegPassKind, -+ field2_kind: &mut RegPassKind, -+) -> Result<(), CannotUseFpConv> -+where -+ Ty: TyAbiInterface<'a, C> + Copy, -+{ -+ match arg_layout.abi { -+ Abi::Scalar(scalar) => match scalar.primitive() { -+ abi::Int(..) | abi::Pointer => { -+ if arg_layout.size.bits() > xlen { -+ return Err(CannotUseFpConv); -+ } -+ match (*field1_kind, *field2_kind) { -+ (RegPassKind::Unknown, _) => { -+ *field1_kind = RegPassKind::Integer(Reg { -+ kind: RegKind::Integer, -+ size: arg_layout.size, -+ }); -+ } -+ (RegPassKind::Float(_), RegPassKind::Unknown) => { -+ *field2_kind = RegPassKind::Integer(Reg { -+ kind: RegKind::Integer, -+ size: arg_layout.size, -+ }); -+ } -+ _ => return Err(CannotUseFpConv), -+ } -+ } -+ abi::F32 | abi::F64 => { -+ if arg_layout.size.bits() > flen { -+ return Err(CannotUseFpConv); -+ } -+ match (*field1_kind, *field2_kind) { -+ (RegPassKind::Unknown, _) => { -+ *field1_kind = -+ RegPassKind::Float(Reg { kind: RegKind::Float, size: arg_layout.size }); -+ } -+ (_, RegPassKind::Unknown) => { -+ *field2_kind = -+ RegPassKind::Float(Reg { kind: RegKind::Float, size: arg_layout.size }); -+ } -+ _ => return Err(CannotUseFpConv), -+ } -+ } -+ }, -+ Abi::Vector { .. } | Abi::Uninhabited => return Err(CannotUseFpConv), -+ Abi::ScalarPair(..) | Abi::Aggregate { .. } => match arg_layout.fields { -+ FieldsShape::Primitive => { -+ unreachable!("aggregates can't have `FieldsShape::Primitive`") -+ } -+ FieldsShape::Union(_) => { -+ if !arg_layout.is_zst() { -+ return Err(CannotUseFpConv); -+ } -+ } -+ FieldsShape::Array { count, .. } => { -+ for _ in 0..count { -+ let elem_layout = arg_layout.field(cx, 0); -+ should_use_fp_conv_helper( -+ cx, -+ &elem_layout, -+ xlen, -+ flen, -+ field1_kind, -+ field2_kind, -+ )?; -+ } -+ } -+ FieldsShape::Arbitrary { .. } => { -+ match arg_layout.variants { -+ abi::Variants::Multiple { .. } => return Err(CannotUseFpConv), -+ abi::Variants::Single { .. } => (), -+ } -+ for i in arg_layout.fields.index_by_increasing_offset() { -+ let field = arg_layout.field(cx, i); -+ should_use_fp_conv_helper(cx, &field, xlen, flen, field1_kind, field2_kind)?; -+ } -+ } -+ }, -+ } -+ Ok(()) -+} -+ -+fn should_use_fp_conv<'a, Ty, C>( -+ cx: &C, -+ arg: &TyAndLayout<'a, Ty>, -+ xlen: u64, -+ flen: u64, -+) -> Option -+where -+ Ty: TyAbiInterface<'a, C> + Copy, -+{ -+ let mut field1_kind = RegPassKind::Unknown; -+ let mut field2_kind = RegPassKind::Unknown; -+ if should_use_fp_conv_helper(cx, arg, xlen, flen, &mut field1_kind, &mut field2_kind).is_err() { -+ return None; -+ } -+ match (field1_kind, field2_kind) { -+ (RegPassKind::Integer(l), RegPassKind::Float(r)) => Some(FloatConv::MixedPair(l, r)), -+ (RegPassKind::Float(l), RegPassKind::Integer(r)) => Some(FloatConv::MixedPair(l, r)), -+ (RegPassKind::Float(l), RegPassKind::Float(r)) => Some(FloatConv::FloatPair(l, r)), -+ (RegPassKind::Float(f), RegPassKind::Unknown) => Some(FloatConv::Float(f)), -+ _ => None, -+ } -+} -+ -+fn classify_ret<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>, xlen: u64, flen: u64) -> bool -+where -+ Ty: TyAbiInterface<'a, C> + Copy, -+{ -+ if let Some(conv) = should_use_fp_conv(cx, &arg.layout, xlen, flen) { -+ match conv { -+ FloatConv::Float(f) => { -+ arg.cast_to(f); -+ } -+ FloatConv::FloatPair(l, r) => { -+ arg.cast_to(CastTarget::pair(l, r)); -+ } -+ FloatConv::MixedPair(l, r) => { -+ arg.cast_to(CastTarget::pair(l, r)); -+ } -+ } -+ return false; -+ } -+ -+ let total = arg.layout.size; -+ -+ // "Scalars wider than 2✕XLEN are passed by reference and are replaced in -+ // the argument list with the address." -+ // "Aggregates larger than 2✕XLEN bits are passed by reference and are -+ // replaced in the argument list with the address, as are C++ aggregates -+ // with nontrivial copy constructors, destructors, or vtables." -+ if total.bits() > 2 * xlen { -+ // We rely on the LLVM backend lowering code to lower passing a scalar larger than 2*XLEN. -+ if is_loongarch_aggregate(arg) { -+ arg.make_indirect(); -+ } -+ return true; -+ } -+ -+ let xlen_reg = match xlen { -+ 32 => Reg::i32(), -+ 64 => Reg::i64(), -+ _ => unreachable!("Unsupported XLEN: {}", xlen), -+ }; -+ if is_loongarch_aggregate(arg) { -+ if total.bits() <= xlen { -+ arg.cast_to(xlen_reg); -+ } else { -+ arg.cast_to(Uniform { unit: xlen_reg, total: Size::from_bits(xlen * 2) }); -+ } -+ return false; -+ } -+ -+ // "When passed in registers, scalars narrower than XLEN bits are widened -+ // according to the sign of their type up to 32 bits, then sign-extended to -+ // XLEN bits." -+ extend_integer_width(arg, xlen); -+ false -+} -+ -+fn classify_arg<'a, Ty, C>( -+ cx: &C, -+ arg: &mut ArgAbi<'a, Ty>, -+ xlen: u64, -+ flen: u64, -+ is_vararg: bool, -+ avail_gprs: &mut u64, -+ avail_fprs: &mut u64, -+) where -+ Ty: TyAbiInterface<'a, C> + Copy, -+{ -+ if !is_vararg { -+ match should_use_fp_conv(cx, &arg.layout, xlen, flen) { -+ Some(FloatConv::Float(f)) if *avail_fprs >= 1 => { -+ *avail_fprs -= 1; -+ arg.cast_to(f); -+ return; -+ } -+ Some(FloatConv::FloatPair(l, r)) if *avail_fprs >= 2 => { -+ *avail_fprs -= 2; -+ arg.cast_to(CastTarget::pair(l, r)); -+ return; -+ } -+ Some(FloatConv::MixedPair(l, r)) if *avail_fprs >= 1 && *avail_gprs >= 1 => { -+ *avail_gprs -= 1; -+ *avail_fprs -= 1; -+ arg.cast_to(CastTarget::pair(l, r)); -+ return; -+ } -+ _ => (), -+ } -+ } -+ -+ let total = arg.layout.size; -+ let align = arg.layout.align.abi.bits(); -+ -+ // "Scalars wider than 2✕XLEN are passed by reference and are replaced in -+ // the argument list with the address." -+ // "Aggregates larger than 2✕XLEN bits are passed by reference and are -+ // replaced in the argument list with the address, as are C++ aggregates -+ // with nontrivial copy constructors, destructors, or vtables." -+ if total.bits() > 2 * xlen { -+ // We rely on the LLVM backend lowering code to lower passing a scalar larger than 2*XLEN. -+ if is_loongarch_aggregate(arg) { -+ arg.make_indirect(); -+ } -+ if *avail_gprs >= 1 { -+ *avail_gprs -= 1; -+ } -+ return; -+ } -+ -+ let double_xlen_reg = match xlen { -+ 32 => Reg::i64(), -+ 64 => Reg::i128(), -+ _ => unreachable!("Unsupported XLEN: {}", xlen), -+ }; -+ -+ let xlen_reg = match xlen { -+ 32 => Reg::i32(), -+ 64 => Reg::i64(), -+ _ => unreachable!("Unsupported XLEN: {}", xlen), -+ }; -+ -+ if total.bits() > xlen { -+ let align_regs = align > xlen; -+ if is_loongarch_aggregate(arg) { -+ arg.cast_to(Uniform { -+ unit: if align_regs { double_xlen_reg } else { xlen_reg }, -+ total: Size::from_bits(xlen * 2), -+ }); -+ } -+ if align_regs && is_vararg { -+ *avail_gprs -= *avail_gprs % 2; -+ } -+ if *avail_gprs >= 2 { -+ *avail_gprs -= 2; -+ } else { -+ *avail_gprs = 0; -+ } -+ return; -+ } else if is_loongarch_aggregate(arg) { -+ arg.cast_to(xlen_reg); -+ if *avail_gprs >= 1 { -+ *avail_gprs -= 1; -+ } -+ return; -+ } -+ -+ // "When passed in registers, scalars narrower than XLEN bits are widened -+ // according to the sign of their type up to 32 bits, then sign-extended to -+ // XLEN bits." -+ if *avail_gprs >= 1 { -+ extend_integer_width(arg, xlen); -+ *avail_gprs -= 1; -+ } -+} -+ -+fn extend_integer_width<'a, Ty>(arg: &mut ArgAbi<'a, Ty>, xlen: u64) { -+ if let Abi::Scalar(scalar) = arg.layout.abi { -+ if let abi::Int(i, _) = scalar.primitive() { -+ // 32-bit integers are always sign-extended -+ if i.size().bits() == 32 && xlen > 32 { -+ if let PassMode::Direct(ref mut attrs) = arg.mode { -+ attrs.ext(ArgExtension::Sext); -+ return; -+ } -+ } -+ } -+ } -+ -+ arg.extend_integer_width_to(xlen); -+} -+ -+pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) -+where -+ Ty: TyAbiInterface<'a, C> + Copy, -+ C: HasDataLayout + HasTargetSpec, -+{ -+ let xlen = cx.data_layout().pointer_size.bits(); -+ let flen = match &cx.target_spec().llvm_abiname[..] { -+ "lp64" => 64, -+ "lp32" | "lpx32" => 32, -+ _ => 0, -+ }; -+ -+ let mut avail_gprs = 8; -+ let mut avail_fprs = 8; -+ -+ if !fn_abi.ret.is_ignore() && classify_ret(cx, &mut fn_abi.ret, xlen, flen) { -+ avail_gprs -= 1; -+ } -+ -+ for (i, arg) in fn_abi.args.iter_mut().enumerate() { -+ if arg.is_ignore() { -+ continue; -+ } -+ classify_arg( -+ cx, -+ arg, -+ xlen, -+ flen, -+ i >= fn_abi.fixed_count as usize, -+ &mut avail_gprs, -+ &mut avail_fprs, -+ ); -+ } -+} -diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs -index 9e5f0e4d1..c5a6f9893 100644 ---- a/compiler/rustc_target/src/abi/call/mod.rs -+++ b/compiler/rustc_target/src/abi/call/mod.rs -@@ -10,6 +10,7 @@ mod arm; - mod avr; - mod bpf; - mod hexagon; -+mod loongarch; - mod m68k; - mod mips; - mod mips64; -@@ -696,6 +697,7 @@ impl<'a, Ty> FnAbi<'a, Ty> { - "amdgpu" => amdgpu::compute_abi_info(cx, self), - "arm" => arm::compute_abi_info(cx, self), - "avr" => avr::compute_abi_info(self), -+ "loongarch64" => loongarch::compute_abi_info(cx, self), - "m68k" => m68k::compute_abi_info(self), - "mips" => mips::compute_abi_info(cx, self), - "mips64" => mips64::compute_abi_info(cx, self), -diff --git a/compiler/rustc_target/src/asm/loongarch.rs b/compiler/rustc_target/src/asm/loongarch.rs -new file mode 100644 -index 000000000..f1b879662 ---- /dev/null -+++ b/compiler/rustc_target/src/asm/loongarch.rs -@@ -0,0 +1,131 @@ -+use super::{InlineAsmArch, InlineAsmType}; -+use rustc_macros::HashStable_Generic; -+use rustc_span::Symbol; -+use std::fmt; -+ -+def_reg_class! { -+ LoongArch LoongArchInlineAsmRegClass { -+ reg, -+ freg, -+ } -+} -+ -+impl LoongArchInlineAsmRegClass { -+ pub fn valid_modifiers(self, _arch: super::InlineAsmArch) -> &'static [char] { -+ &[] -+ } -+ -+ pub fn suggest_class(self, _arch: InlineAsmArch, _ty: InlineAsmType) -> Option { -+ None -+ } -+ -+ pub fn suggest_modifier( -+ self, -+ _arch: InlineAsmArch, -+ _ty: InlineAsmType, -+ ) -> Option<(char, &'static str)> { -+ None -+ } -+ -+ pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> { -+ None -+ } -+ -+ pub fn supported_types( -+ self, -+ arch: InlineAsmArch, -+ ) -> &'static [(InlineAsmType, Option)] { -+ match (self, arch) { -+ (Self::reg, InlineAsmArch::LoongArch64) => types! { _: I8, I16, I32, I64, F32, F64; }, -+ (Self::reg, _) => types! { _: I8, I16, I32, F32; }, -+ (Self::freg, _) => types! { _: F32, F64; }, -+ } -+ } -+} -+ -+// The reserved registers are taken from -+def_regs! { -+ LoongArch LoongArchInlineAsmReg LoongArchInlineAsmRegClass { -+ r1: reg = ["$r1","$ra"], -+ r4: reg = ["$r4","$a0"], -+ r5: reg = ["$r5","$a1"], -+ r6: reg = ["$r6","$a2"], -+ r7: reg = ["$r7","$a3"], -+ r8: reg = ["$r8","$a4"], -+ r9: reg = ["$r9","$a5"], -+ r10: reg = ["$r10","$a6"], -+ r11: reg = ["$r11","$a7"], -+ r12: reg = ["$r12","$t0"], -+ r13: reg = ["$r13","$t1"], -+ r14: reg = ["$r14","$t2"], -+ r15: reg = ["$r15","$t3"], -+ r16: reg = ["$r16","$t4"], -+ r17: reg = ["$r17","$t5"], -+ r18: reg = ["$r18","$t6"], -+ r19: reg = ["$r19","$t7"], -+ r20: reg = ["$r20","$t8"], -+ r23: reg = ["$r23","$s0"], -+ r24: reg = ["$r24","$s1"], -+ r25: reg = ["$r25","$s2"], -+ r26: reg = ["$r26","$s3"], -+ r27: reg = ["$r27","$s4"], -+ r28: reg = ["$r28","$s5"], -+ r29: reg = ["$r29","$s6"], -+ r30: reg = ["$r30","$s7"], -+ f0: freg = ["$f0","$fa0"], -+ f1: freg = ["$f1","$fa1"], -+ f2: freg = ["$f2","$fa2"], -+ f3: freg = ["$f3","$fa3"], -+ f4: freg = ["$f4","$fa4"], -+ f5: freg = ["$f5","$fa5"], -+ f6: freg = ["$f6","$fa6"], -+ f7: freg = ["$f7","$fa7"], -+ f8: freg = ["$f8","$ft0"], -+ f9: freg = ["$f9","$ft1"], -+ f10: freg = ["$f10","$ft2"], -+ f11: freg = ["$f11","$ft3"], -+ f12: freg = ["$f12","$ft4"], -+ f13: freg = ["$f13","$ft5"], -+ f14: freg = ["$f14","$ft6"], -+ f15: freg = ["$f15","$ft7"], -+ f16: freg = ["$f16","$ft8"], -+ f17: freg = ["$f17","$ft9"], -+ f18: freg = ["$f18","$ft10"], -+ f19: freg = ["$f19","$ft11"], -+ f20: freg = ["$f20","$ft12"], -+ f21: freg = ["$f21","$ft13"], -+ f22: freg = ["$f22","$ft14"], -+ f23: freg = ["$f23","$ft15"], -+ f24: freg = ["$f24","$fs0"], -+ f25: freg = ["$f25","$fs1"], -+ f26: freg = ["$f26","$fs2"], -+ f27: freg = ["$f27","$fs3"], -+ f28: freg = ["$f28","$fs4"], -+ f29: freg = ["$f29","$fs5"], -+ f30: freg = ["$f30","$fs6"], -+ f31: freg = ["$f31","$fs7"], -+ #error = ["$r0", "$zero"] => -+ "constant zero cannot be used as an operand for inline asm", -+ #error = ["$r2", "$tp"] => -+ "reserved for TLS", -+ #error = ["$r3", "$sp"] => -+ "the stack pointer cannot be used as an operand for inline asm", -+ #error = ["$r21", "$x"] => -+ "reserved for ABI extension", -+ #error = ["$r22", "$fp"] => -+ "the frame pointer cannot be used as an operand for inline asm", -+ #error = ["$r31", "$s8"] => -+ "r31 is used internally by LLVM and cannot be used as an operand for inline asm", -+ } -+} -+ -+impl LoongArchInlineAsmReg { -+ pub fn emit( -+ self, -+ out: &mut dyn fmt::Write, -+ _arch: InlineAsmArch, -+ _modifier: Option, -+ ) -> fmt::Result { -+ out.write_str(self.name()) -+ } -+} -diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs -index 65d2cd64b..2438ac3e8 100644 ---- a/compiler/rustc_target/src/asm/mod.rs -+++ b/compiler/rustc_target/src/asm/mod.rs -@@ -167,6 +167,7 @@ mod arm; - mod avr; - mod bpf; - mod hexagon; -+mod loongarch; - mod mips; - mod msp430; - mod nvptx; -@@ -182,6 +183,7 @@ pub use arm::{ArmInlineAsmReg, ArmInlineAsmRegClass}; - pub use avr::{AvrInlineAsmReg, AvrInlineAsmRegClass}; - pub use bpf::{BpfInlineAsmReg, BpfInlineAsmRegClass}; - pub use hexagon::{HexagonInlineAsmReg, HexagonInlineAsmRegClass}; -+pub use loongarch::{LoongArchInlineAsmReg, LoongArchInlineAsmRegClass}; - pub use mips::{MipsInlineAsmReg, MipsInlineAsmRegClass}; - pub use msp430::{Msp430InlineAsmReg, Msp430InlineAsmRegClass}; - pub use nvptx::{NvptxInlineAsmReg, NvptxInlineAsmRegClass}; -@@ -213,6 +215,7 @@ pub enum InlineAsmArch { - Bpf, - Avr, - Msp430, -+ LoongArch64, - } - - impl FromStr for InlineAsmArch { -@@ -230,6 +233,7 @@ impl FromStr for InlineAsmArch { - "powerpc" => Ok(Self::PowerPC), - "powerpc64" => Ok(Self::PowerPC64), - "hexagon" => Ok(Self::Hexagon), -+ "loongarch64" => Ok(Self::LoongArch64), - "mips" => Ok(Self::Mips), - "mips64" => Ok(Self::Mips64), - "s390x" => Ok(Self::S390x), -@@ -254,6 +258,7 @@ pub enum InlineAsmReg { - Nvptx(NvptxInlineAsmReg), - PowerPC(PowerPCInlineAsmReg), - Hexagon(HexagonInlineAsmReg), -+ LoongArch(LoongArchInlineAsmReg), - Mips(MipsInlineAsmReg), - S390x(S390xInlineAsmReg), - SpirV(SpirVInlineAsmReg), -@@ -274,6 +279,7 @@ impl InlineAsmReg { - Self::RiscV(r) => r.name(), - Self::PowerPC(r) => r.name(), - Self::Hexagon(r) => r.name(), -+ Self::LoongArch(r) => r.name(), - Self::Mips(r) => r.name(), - Self::S390x(r) => r.name(), - Self::Bpf(r) => r.name(), -@@ -291,6 +297,7 @@ impl InlineAsmReg { - Self::RiscV(r) => InlineAsmRegClass::RiscV(r.reg_class()), - Self::PowerPC(r) => InlineAsmRegClass::PowerPC(r.reg_class()), - Self::Hexagon(r) => InlineAsmRegClass::Hexagon(r.reg_class()), -+ Self::LoongArch(r) => InlineAsmRegClass::LoongArch(r.reg_class()), - Self::Mips(r) => InlineAsmRegClass::Mips(r.reg_class()), - Self::S390x(r) => InlineAsmRegClass::S390x(r.reg_class()), - Self::Bpf(r) => InlineAsmRegClass::Bpf(r.reg_class()), -@@ -316,6 +323,7 @@ impl InlineAsmReg { - Self::PowerPC(PowerPCInlineAsmReg::parse(name)?) - } - InlineAsmArch::Hexagon => Self::Hexagon(HexagonInlineAsmReg::parse(name)?), -+ InlineAsmArch::LoongArch64 => Self::LoongArch(LoongArchInlineAsmReg::parse(name)?), - InlineAsmArch::Mips | InlineAsmArch::Mips64 => { - Self::Mips(MipsInlineAsmReg::parse(name)?) - } -@@ -345,6 +353,7 @@ impl InlineAsmReg { - Self::RiscV(r) => r.validate(arch, reloc_model, target_features, target, is_clobber), - Self::PowerPC(r) => r.validate(arch, reloc_model, target_features, target, is_clobber), - Self::Hexagon(r) => r.validate(arch, reloc_model, target_features, target, is_clobber), -+ Self::LoongArch(r) => r.validate(arch, reloc_model, target_features, target, is_clobber), - Self::Mips(r) => r.validate(arch, reloc_model, target_features, target, is_clobber), - Self::S390x(r) => r.validate(arch, reloc_model, target_features, target, is_clobber), - Self::Bpf(r) => r.validate(arch, reloc_model, target_features, target, is_clobber), -@@ -369,6 +378,7 @@ impl InlineAsmReg { - Self::RiscV(r) => r.emit(out, arch, modifier), - Self::PowerPC(r) => r.emit(out, arch, modifier), - Self::Hexagon(r) => r.emit(out, arch, modifier), -+ Self::LoongArch(r) => r.emit(out, arch, modifier), - Self::Mips(r) => r.emit(out, arch, modifier), - Self::S390x(r) => r.emit(out, arch, modifier), - Self::Bpf(r) => r.emit(out, arch, modifier), -@@ -386,6 +396,7 @@ impl InlineAsmReg { - Self::RiscV(_) => cb(self), - Self::PowerPC(r) => r.overlapping_regs(|r| cb(Self::PowerPC(r))), - Self::Hexagon(r) => r.overlapping_regs(|r| cb(Self::Hexagon(r))), -+ Self::LoongArch(_) => cb(self), - Self::Mips(_) => cb(self), - Self::S390x(_) => cb(self), - Self::Bpf(r) => r.overlapping_regs(|r| cb(Self::Bpf(r))), -@@ -406,6 +417,7 @@ pub enum InlineAsmRegClass { - Nvptx(NvptxInlineAsmRegClass), - PowerPC(PowerPCInlineAsmRegClass), - Hexagon(HexagonInlineAsmRegClass), -+ LoongArch(LoongArchInlineAsmRegClass), - Mips(MipsInlineAsmRegClass), - S390x(S390xInlineAsmRegClass), - SpirV(SpirVInlineAsmRegClass), -@@ -427,6 +439,7 @@ impl InlineAsmRegClass { - Self::Nvptx(r) => r.name(), - Self::PowerPC(r) => r.name(), - Self::Hexagon(r) => r.name(), -+ Self::LoongArch(r) => r.name(), - Self::Mips(r) => r.name(), - Self::S390x(r) => r.name(), - Self::SpirV(r) => r.name(), -@@ -450,6 +463,7 @@ impl InlineAsmRegClass { - Self::Nvptx(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Nvptx), - Self::PowerPC(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::PowerPC), - Self::Hexagon(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Hexagon), -+ Self::LoongArch(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::LoongArch), - Self::Mips(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Mips), - Self::S390x(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::S390x), - Self::SpirV(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::SpirV), -@@ -480,6 +494,7 @@ impl InlineAsmRegClass { - Self::Nvptx(r) => r.suggest_modifier(arch, ty), - Self::PowerPC(r) => r.suggest_modifier(arch, ty), - Self::Hexagon(r) => r.suggest_modifier(arch, ty), -+ Self::LoongArch(r) => r.suggest_modifier(arch, ty), - Self::Mips(r) => r.suggest_modifier(arch, ty), - Self::S390x(r) => r.suggest_modifier(arch, ty), - Self::SpirV(r) => r.suggest_modifier(arch, ty), -@@ -506,6 +521,7 @@ impl InlineAsmRegClass { - Self::Nvptx(r) => r.default_modifier(arch), - Self::PowerPC(r) => r.default_modifier(arch), - Self::Hexagon(r) => r.default_modifier(arch), -+ Self::LoongArch(r) => r.default_modifier(arch), - Self::Mips(r) => r.default_modifier(arch), - Self::S390x(r) => r.default_modifier(arch), - Self::SpirV(r) => r.default_modifier(arch), -@@ -531,6 +547,7 @@ impl InlineAsmRegClass { - Self::Nvptx(r) => r.supported_types(arch), - Self::PowerPC(r) => r.supported_types(arch), - Self::Hexagon(r) => r.supported_types(arch), -+ Self::LoongArch(r) => r.supported_types(arch), - Self::Mips(r) => r.supported_types(arch), - Self::S390x(r) => r.supported_types(arch), - Self::SpirV(r) => r.supported_types(arch), -@@ -557,6 +574,7 @@ impl InlineAsmRegClass { - Self::PowerPC(PowerPCInlineAsmRegClass::parse(name)?) - } - InlineAsmArch::Hexagon => Self::Hexagon(HexagonInlineAsmRegClass::parse(name)?), -+ InlineAsmArch::LoongArch64 => Self::LoongArch(LoongArchInlineAsmRegClass::parse(name)?), - InlineAsmArch::Mips | InlineAsmArch::Mips64 => { - Self::Mips(MipsInlineAsmRegClass::parse(name)?) - } -@@ -582,6 +600,7 @@ impl InlineAsmRegClass { - Self::Nvptx(r) => r.valid_modifiers(arch), - Self::PowerPC(r) => r.valid_modifiers(arch), - Self::Hexagon(r) => r.valid_modifiers(arch), -+ Self::LoongArch(r) => r.valid_modifiers(arch), - Self::Mips(r) => r.valid_modifiers(arch), - Self::S390x(r) => r.valid_modifiers(arch), - Self::SpirV(r) => r.valid_modifiers(arch), -@@ -740,6 +759,11 @@ pub fn allocatable_registers( - hexagon::fill_reg_map(arch, reloc_model, target_features, target, &mut map); - map - } -+ InlineAsmArch::LoongArch64 => { -+ let mut map = loongarch::regclass_map(); -+ loongarch::fill_reg_map(arch, reloc_model, target_features, target, &mut map); -+ map -+ } - InlineAsmArch::Mips | InlineAsmArch::Mips64 => { - let mut map = mips::regclass_map(); - mips::fill_reg_map(arch, reloc_model, target_features, target, &mut map); -@@ -788,6 +812,7 @@ pub enum InlineAsmClobberAbi { - AArch64, - AArch64NoX18, - RiscV, -+ LoongArch, - } - - impl InlineAsmClobberAbi { -@@ -829,6 +854,10 @@ impl InlineAsmClobberAbi { - "C" | "system" | "efiapi" => Ok(InlineAsmClobberAbi::RiscV), - _ => Err(&["C", "system", "efiapi"]), - }, -+ InlineAsmArch::LoongArch64 => match name { -+ "C" | "system" | "efiapi" => Ok(InlineAsmClobberAbi::LoongArch), -+ _ => Err(&["C", "system", "efiapi"]), -+ }, - _ => Err(&[]), - } - } -@@ -971,6 +1000,21 @@ impl InlineAsmClobberAbi { - v24, v25, v26, v27, v28, v29, v30, v31, - } - }, -+ InlineAsmClobberAbi::LoongArch => clobbered_regs! { -+ LoongArch LoongArchInlineAsmReg { -+ // ra -+ r1, -+ // a0-a7 -+ r4, r5, r6, r7, r8, r9, r10, r11, -+ // t0-t8 -+ r12, r13, r14, r15, r16, r17, r18, r19, r20, -+ // fa0-fa7 -+ f0, f1, f2, f3, f4, f5, f6, f7, -+ // ft0-ft15 -+ f8, f9, f10, f11, f12, f13, f14, f15, -+ f16, f17, f18, f19, f20, f21, f22, f23, -+ } -+ }, - } - } - } -diff --git a/compiler/rustc_target/src/spec/loongarch64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/loongarch64_unknown_linux_gnu.rs -new file mode 100644 -index 000000000..4dc785dac ---- /dev/null -+++ b/compiler/rustc_target/src/spec/loongarch64_unknown_linux_gnu.rs -@@ -0,0 +1,18 @@ -+use crate::spec::{Target, TargetOptions}; -+ -+pub fn target() -> Target { -+ Target { -+ llvm_target: "loongarch64-unknown-linux-gnu".into(), -+ pointer_width: 64, -+ data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".into(), -+ arch: "loongarch64".into(), -+ options: TargetOptions { -+ abi: "abilp64".into(), -+ cpu: "la464".into(), -+ max_atomic_width: Some(64), -+ llvm_abiname: "lp64".into(), -+ -+ ..super::linux_gnu_base::opts() -+ }, -+ } -+} -diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs -index 8909cf33a..5f43e4faa 100644 ---- a/compiler/rustc_target/src/spec/mod.rs -+++ b/compiler/rustc_target/src/spec/mod.rs -@@ -1245,6 +1245,8 @@ supported_targets! { - ("x86_64-unknown-none", x86_64_unknown_none), - - ("mips64-openwrt-linux-musl", mips64_openwrt_linux_musl), -+ -+ ("loongarch64-unknown-linux-gnu", loongarch64_unknown_linux_gnu), - } - - /// Cow-Vec-Str: Cow<'static, [Cow<'static, str>]> -diff --git a/library/std/src/env.rs b/library/std/src/env.rs -index 6eb7cbea6..d149d7cda 100644 ---- a/library/std/src/env.rs -+++ b/library/std/src/env.rs -@@ -888,6 +888,7 @@ pub mod consts { - /// - x86_64 - /// - arm - /// - aarch64 -+ /// - loongarch64 - /// - m68k - /// - mips - /// - mips64 -diff --git a/library/std/src/os/linux/raw.rs b/library/std/src/os/linux/raw.rs -index c73791d14..4d0607d19 100644 ---- a/library/std/src/os/linux/raw.rs -+++ b/library/std/src/os/linux/raw.rs -@@ -232,6 +232,7 @@ mod arch { - } - - #[cfg(any( -+ target_arch = "loongarch64", - target_arch = "mips64", - target_arch = "s390x", - target_arch = "sparc64", -diff --git a/library/std/src/personality/gcc.rs b/library/std/src/personality/gcc.rs -index 7f0b0439c..047aa07df 100644 ---- a/library/std/src/personality/gcc.rs -+++ b/library/std/src/personality/gcc.rs -@@ -76,6 +76,9 @@ const UNWIND_DATA_REG: (i32, i32) = (0, 1); // R0, R1 - #[cfg(any(target_arch = "riscv64", target_arch = "riscv32"))] - const UNWIND_DATA_REG: (i32, i32) = (10, 11); // x10, x11 - -+#[cfg(target_arch = "loongarch64")] -+const UNWIND_DATA_REG: (i32, i32) = (4, 5); // A0, A1 -+ - // The following code is based on GCC's C and C++ personality routines. For reference, see: - // https://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/eh_personality.cc - // https://github.com/gcc-mirror/gcc/blob/trunk/libgcc/unwind-c.c -diff --git a/library/std/src/sys/common/alloc.rs b/library/std/src/sys/common/alloc.rs -index e8e7c51cb..3b0c6d4a2 100644 ---- a/library/std/src/sys/common/alloc.rs -+++ b/library/std/src/sys/common/alloc.rs -@@ -24,6 +24,7 @@ pub const MIN_ALIGN: usize = 8; - target_arch = "mips64", - target_arch = "s390x", - target_arch = "sparc64", -+ target_arch = "loongarch64", - target_arch = "riscv64", - target_arch = "wasm64", - )))] -diff --git a/library/unwind/src/libunwind.rs b/library/unwind/src/libunwind.rs -index a5b6193b0..2da4dc286 100644 ---- a/library/unwind/src/libunwind.rs -+++ b/library/unwind/src/libunwind.rs -@@ -69,6 +69,9 @@ pub const unwinder_private_data_size: usize = 20; - #[cfg(all(target_arch = "hexagon", target_os = "linux"))] - pub const unwinder_private_data_size: usize = 35; - -+#[cfg(target_arch = "loongarch64")] -+pub const unwinder_private_data_size: usize = 2; -+ - #[repr(C)] - pub struct _Unwind_Exception { - pub exception_class: _Unwind_Exception_Class, -diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py -index 57128685d..93d53b2a3 100644 ---- a/src/bootstrap/bootstrap.py -+++ b/src/bootstrap/bootstrap.py -@@ -303,6 +303,7 @@ def default_build_triple(verbose): - 'i486': 'i686', - 'i686': 'i686', - 'i786': 'i686', -+ 'loongarch64': 'loongarch64', - 'm68k': 'm68k', - 'powerpc': 'powerpc', - 'powerpc64': 'powerpc64', -diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs -index 7e70e99bb..52cb9dc77 100644 ---- a/src/bootstrap/lib.rs -+++ b/src/bootstrap/lib.rs -@@ -213,7 +213,7 @@ const EXTRA_CHECK_CFGS: &[(Option, &'static str, Option<&[&'static str]>)] - ( - Some(Mode::Std), - "target_arch", -- Some(&["asmjs", "spirv", "nvptx", "nvptx64", "le32", "xtensa"]), -+ Some(&["asmjs", "spirv", "nvptx", "nvptx64", "le32", "xtensa", "loongarch64"]), - ), - /* Extra names used by dependencies */ - // FIXME: Used by rustfmt is their test but is invalid (neither cargo nor bootstrap ever set -diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs -index 2f856c276..7c4da4d23 100644 ---- a/src/bootstrap/native.rs -+++ b/src/bootstrap/native.rs -@@ -357,7 +357,7 @@ impl Step for Llvm { - let llvm_targets = match &builder.config.llvm_targets { - Some(s) => s, - None => { -- "AArch64;ARM;BPF;Hexagon;MSP430;Mips;NVPTX;PowerPC;RISCV;\ -+ "AArch64;ARM;BPF;Hexagon;LoongArch;MSP430;Mips;NVPTX;PowerPC;RISCV;\ - Sparc;SystemZ;WebAssembly;X86" - } - }; -diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml -index 10de2e8d5..b34437f01 100644 ---- a/src/ci/github-actions/ci.yml -+++ b/src/ci/github-actions/ci.yml -@@ -346,6 +346,9 @@ jobs: - - name: dist-i686-linux - <<: *job-linux-xl - -+ - name: dist-loongarch64-linux -+ <<: *job-linux-xl -+ - - name: dist-mips-linux - <<: *job-linux-xl - -diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md -index a36518cc8..3724253a8 100644 ---- a/src/doc/rustc/src/platform-support.md -+++ b/src/doc/rustc/src/platform-support.md -@@ -86,6 +86,7 @@ target | notes - `arm-unknown-linux-gnueabi` | ARMv6 Linux (kernel 3.2, glibc 2.17) - `arm-unknown-linux-gnueabihf` | ARMv6 Linux, hardfloat (kernel 3.2, glibc 2.17) - `armv7-unknown-linux-gnueabihf` | ARMv7 Linux, hardfloat (kernel 3.2, glibc 2.17) -+`loongarch64-unknown-linux-gnu` | LOONGARCH64 Linux (kernel 4.19, glibc 2.28) - `mips-unknown-linux-gnu` | MIPS Linux (kernel 4.4, glibc 2.23) - `mips64-unknown-linux-gnuabi64` | MIPS64 Linux, n64 ABI (kernel 4.4, glibc 2.23) - `mips64el-unknown-linux-gnuabi64` | MIPS64 (LE) Linux, n64 ABI (kernel 4.4, glibc 2.23) -diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs -index f33f5d27d..11f713419 100644 ---- a/src/librustdoc/clean/cfg.rs -+++ b/src/librustdoc/clean/cfg.rs -@@ -515,6 +515,7 @@ impl<'a> fmt::Display for Display<'a> { - "aarch64" => "AArch64", - "arm" => "ARM", - "asmjs" => "JavaScript", -+ "loongarch64" => "LoongArch64", - "m68k" => "M68k", - "mips" => "MIPS", - "mips64" => "MIPS-64", -diff --git a/src/test/assembly/asm/loongarch-types.rs b/src/test/assembly/asm/loongarch-types.rs -new file mode 100644 -index 000000000..9c116f730 ---- /dev/null -+++ b/src/test/assembly/asm/loongarch-types.rs -@@ -0,0 +1,194 @@ -+// min-llvm-version: 10.0.1 -+// assembly-output: emit-asm -+// compile-flags: --target loongarch64-unknown-linux-gnu -+// needs-llvm-components: loongarch -+ -+#![feature(no_core, lang_items, rustc_attrs, asm_sym)] -+#![crate_type = "rlib"] -+#![no_core] -+#![allow(asm_sub_register)] -+ -+#[rustc_builtin_macro] -+macro_rules! asm { -+ () => {}; -+} -+#[rustc_builtin_macro] -+macro_rules! concat { -+ () => {}; -+} -+#[rustc_builtin_macro] -+macro_rules! stringify { -+ () => {}; -+} -+ -+#[lang = "sized"] -+trait Sized {} -+#[lang = "copy"] -+trait Copy {} -+ -+type ptr = *const i32; -+ -+impl Copy for i8 {} -+impl Copy for i16 {} -+impl Copy for i32 {} -+impl Copy for i64 {} -+impl Copy for f32 {} -+impl Copy for f64 {} -+impl Copy for ptr {} -+extern "C" { -+ fn extern_func(); -+ static extern_static: u8; -+} -+ -+// Hack to avoid function merging -+extern "Rust" { -+ fn dont_merge(s: &str); -+} -+ -+// CHECK-LABEL: sym_fn: -+// CHECK: #APP -+// CHECK: la.got $r12, extern_func -+// CHECK: #NO_APP -+#[no_mangle] -+pub unsafe fn sym_fn() { -+ asm!("la.got $r12, {}", sym extern_func); -+} -+ -+// CHECK-LABEL: sym_static: -+// CHECK: #APP -+// CHECK: la.got $r12, extern_static -+// CHECK: #NO_APP -+#[no_mangle] -+pub unsafe fn sym_static() { -+ asm!("la.got $r12, {}", sym extern_static); -+} -+ -+macro_rules! check { ($func:ident, $ty:ty, $class:ident, $mov:literal) => { -+ #[no_mangle] -+ pub unsafe fn $func(x: $ty) -> $ty { -+ dont_merge(stringify!($func)); -+ -+ let y; -+ asm!(concat!($mov," {}, {}"), out($class) y, in($class) x); -+ y -+ } -+};} -+ -+macro_rules! check_reg { ($func:ident, $ty:ty, $reg:tt, $mov:literal) => { -+ #[no_mangle] -+ pub unsafe fn $func(x: $ty) -> $ty { -+ dont_merge(stringify!($func)); -+ -+ let y; -+ asm!(concat!($mov, " ", $reg, ", ", $reg), lateout($reg) y, in($reg) x); -+ y -+ } -+};} -+ -+// CHECK-LABEL: reg_i8: -+// CHECK: #APP -+// CHECK: move $r{{[0-9]+}}, $r{{[0-9]+}} -+// CHECK: #NO_APP -+check!(reg_i8, i8, reg, "move"); -+ -+// CHECK-LABEL: reg_i16: -+// CHECK: #APP -+// CHECK: move $r{{[0-9]+}}, $r{{[0-9]+}} -+// CHECK: #NO_APP -+check!(reg_i16, i16, reg, "move"); -+ -+// CHECK-LABEL: reg_i32: -+// CHECK: #APP -+// CHECK: move $r{{[0-9]+}}, $r{{[0-9]+}} -+// CHECK: #NO_APP -+check!(reg_i32, i32, reg, "move"); -+ -+// CHECK-LABEL: reg_f32: -+// CHECK: #APP -+// CHECK: move $r{{[0-9]+}}, $r{{[0-9]+}} -+// CHECK: #NO_APP -+check!(reg_f32, f32, reg, "move"); -+ -+// CHECK-LABEL: reg_i64: -+// CHECK: #APP -+// CHECK: move $r{{[0-9]+}}, $r{{[0-9]+}} -+// CHECK: #NO_APP -+check!(reg_i64, i64, reg, "move"); -+ -+// CHECK-LABEL: reg_f64: -+// CHECK: #APP -+// CHECK: move $r{{[0-9]+}}, $r{{[0-9]+}} -+// CHECK: #NO_APP -+check!(reg_f64, f64, reg, "move"); -+ -+// CHECK-LABEL: reg_ptr: -+// CHECK: #APP -+// CHECK: move $r{{[0-9]+}}, $r{{[0-9]+}} -+// CHECK: #NO_APP -+check!(reg_ptr, ptr, reg, "move"); -+ -+// CHECK-LABEL: freg_f32: -+// CHECK: #APP -+// CHECK: fmov.s $f{{[0-9]+}}, $f{{[0-9]+}} -+// CHECK: #NO_APP -+check!(freg_f32, f32, freg, "fmov.s"); -+ -+// CHECK-LABEL: freg_f64: -+// CHECK: #APP -+// CHECK: fmov.d $f{{[0-9]+}}, $f{{[0-9]+}} -+// CHECK: #NO_APP -+check!(freg_f64, f64, freg, "fmov.d"); -+ -+// CHECK-LABEL: r4_i8: -+// CHECK: #APP -+// CHECK: move $r4, $r4 -+// CHECK: #NO_APP -+check_reg!(r4_i8, i8, "$r4", "move"); -+ -+// CHECK-LABEL: r4_i16: -+// CHECK: #APP -+// CHECK: move $r4, $r4 -+// CHECK: #NO_APP -+check_reg!(r4_i16, i16, "$r4", "move"); -+ -+// CHECK-LABEL: r4_i32: -+// CHECK: #APP -+// CHECK: move $r4, $r4 -+// CHECK: #NO_APP -+check_reg!(r4_i32, i32, "$r4", "move"); -+ -+// CHECK-LABEL: r4_f32: -+// CHECK: #APP -+// CHECK: move $r4, $r4 -+// CHECK: #NO_APP -+check_reg!(r4_f32, f32, "$r4", "move"); -+ -+// CHECK-LABEL: r4_i64: -+// CHECK: #APP -+// CHECK: move $r4, $r4 -+// CHECK: #NO_APP -+check_reg!(r4_i64, i64, "$r4", "move"); -+ -+// CHECK-LABEL: r4_f64: -+// CHECK: #APP -+// CHECK: move $r4, $r4 -+// CHECK: #NO_APP -+check_reg!(r4_f64, f64, "$r4", "move"); -+ -+// CHECK-LABEL: r4_ptr: -+// CHECK: #APP -+// CHECK: move $r4, $r4 -+// CHECK: #NO_APP -+check_reg!(r4_ptr, ptr, "$r4", "move"); -+ -+// CHECK-LABEL: f0_f32: -+// CHECK: #APP -+// CHECK: fmov.s $f{{[0-9]+}}, $f{{[0-9]+}} -+// CHECK: #NO_APP -+check_reg!(f0_f32, f32, "$f0", "fmov.s"); -+ -+// CHECK-LABEL: f0_f64: -+// CHECK: #APP -+// CHECK: fmov.d $f{{[0-9]+}}, $f{{[0-9]+}} -+// CHECK: #NO_APP -+check_reg!(f0_f64, f64, "$f0", "fmov.d"); -diff --git a/src/test/codegen/abi-main-signature-16bit-c-int.rs b/src/test/codegen/abi-main-signature-16bit-c-int.rs -index 4ed491dfb..1b79aa221 100644 ---- a/src/test/codegen/abi-main-signature-16bit-c-int.rs -+++ b/src/test/codegen/abi-main-signature-16bit-c-int.rs -@@ -6,6 +6,7 @@ - // ignore-arm - // ignore-asmjs - // ignore-hexagon -+// ignore-loongarch64 - // ignore-mips - // ignore-mips64 - // ignore-powerpc -diff --git a/src/test/codegen/call-llvm-intrinsics.rs b/src/test/codegen/call-llvm-intrinsics.rs -index 998099c23..77a11ad9f 100644 ---- a/src/test/codegen/call-llvm-intrinsics.rs -+++ b/src/test/codegen/call-llvm-intrinsics.rs -@@ -1,6 +1,7 @@ - // compile-flags: -C no-prepopulate-passes - - // ignore-riscv64 -+// ignore-loongarch64 - - #![feature(link_llvm_intrinsics)] - #![crate_type = "lib"] -diff --git a/src/test/codegen/global_asm.rs b/src/test/codegen/global_asm.rs -index fab84868f..ab47178b0 100644 ---- a/src/test/codegen/global_asm.rs -+++ b/src/test/codegen/global_asm.rs -@@ -6,6 +6,7 @@ - // ignore-bpfel - // ignore-bpfeb - // ignore-hexagon -+// ignore-loongarch64 - // ignore-mips - // ignore-mips64 - // ignore-msp430 -diff --git a/src/test/codegen/global_asm_include.rs b/src/test/codegen/global_asm_include.rs -index 02ee91645..0eaecfde5 100644 ---- a/src/test/codegen/global_asm_include.rs -+++ b/src/test/codegen/global_asm_include.rs -@@ -6,6 +6,7 @@ - // ignore-bpfel - // ignore-bpfeb - // ignore-hexagon -+// ignore-loongarch64 - // ignore-mips - // ignore-mips64 - // ignore-msp430 -diff --git a/src/test/codegen/global_asm_x2.rs b/src/test/codegen/global_asm_x2.rs -index bdcf0ea84..de2b03336 100644 ---- a/src/test/codegen/global_asm_x2.rs -+++ b/src/test/codegen/global_asm_x2.rs -@@ -6,6 +6,7 @@ - // ignore-bpfel - // ignore-bpfeb - // ignore-hexagon -+// ignore-loongarch64 - // ignore-mips - // ignore-mips64 - // ignore-msp430 -diff --git a/src/test/codegen/loongarch-abi/call-llvm-intrinsics.rs b/src/test/codegen/loongarch-abi/call-llvm-intrinsics.rs -new file mode 100644 -index 000000000..bfc4620d8 ---- /dev/null -+++ b/src/test/codegen/loongarch-abi/call-llvm-intrinsics.rs -@@ -0,0 +1,30 @@ -+// compile-flags: -C no-prepopulate-passes -+ -+// only-loongarch64 -+ -+#![feature(link_llvm_intrinsics)] -+#![crate_type = "lib"] -+ -+struct A; -+ -+impl Drop for A { -+ fn drop(&mut self) { -+ println!("A"); -+ } -+} -+ -+extern "C" { -+ #[link_name = "llvm.sqrt.f32"] -+ fn sqrt(x: f32) -> f32; -+} -+ -+pub fn do_call() { -+ let _a = A; -+ -+ unsafe { -+ // Ensure that we `call` LLVM intrinsics instead of trying to `invoke` them -+ // CHECK: store float 4.000000e+00, ptr %{{.}}, align 4 -+ // CHECK: call float @llvm.sqrt.f32(float %{{.}} -+ sqrt(4.0); -+ } -+} -diff --git a/src/test/codegen/repr-transparent-aggregates-1.rs b/src/test/codegen/repr-transparent-aggregates-1.rs -index 9d18c5f03..97ce1ccbd 100644 ---- a/src/test/codegen/repr-transparent-aggregates-1.rs -+++ b/src/test/codegen/repr-transparent-aggregates-1.rs -@@ -3,6 +3,7 @@ - - // ignore-arm - // ignore-aarch64 -+// ignore-loongarch64 - // ignore-mips - // ignore-mips64 - // ignore-powerpc -diff --git a/src/test/codegen/repr-transparent-aggregates-2.rs b/src/test/codegen/repr-transparent-aggregates-2.rs -index df7e88f08..09ee567cd 100644 ---- a/src/test/codegen/repr-transparent-aggregates-2.rs -+++ b/src/test/codegen/repr-transparent-aggregates-2.rs -@@ -4,6 +4,7 @@ - // ignore-aarch64 - // ignore-emscripten - // ignore-mips64 -+// ignore-loongarch64 - // ignore-powerpc - // ignore-powerpc64 - // ignore-powerpc64le -diff --git a/src/test/codegen/repr-transparent.rs b/src/test/codegen/repr-transparent.rs -index c68ba8460..5d5ebfc4b 100644 ---- a/src/test/codegen/repr-transparent.rs -+++ b/src/test/codegen/repr-transparent.rs -@@ -2,6 +2,7 @@ - - // ignore-riscv64 riscv64 has an i128 type used with test_Vector - // see codegen/riscv-abi for riscv functiona call tests -+// ignore-loongarch64 - - #![crate_type="lib"] - #![feature(repr_simd, transparent_unions)] -diff --git a/src/test/run-make-fulldeps/atomic-lock-free/Makefile b/src/test/run-make-fulldeps/atomic-lock-free/Makefile -index 37e59624a..dcca7f8f7 100644 ---- a/src/test/run-make-fulldeps/atomic-lock-free/Makefile -+++ b/src/test/run-make-fulldeps/atomic-lock-free/Makefile -@@ -25,6 +25,10 @@ ifeq ($(filter aarch64,$(LLVM_COMPONENTS)),aarch64) - $(RUSTC) --target=aarch64-unknown-linux-gnu atomic_lock_free.rs - nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add - endif -+ifeq ($(filter loongarch64,$(LLVM_COMPONENTS)),loongarch64) -+ $(RUSTC) --target=loongarch64-unknown-linux-gnu atomic_lock_free.rs -+ nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add -+endif - ifeq ($(filter mips,$(LLVM_COMPONENTS)),mips) - $(RUSTC) --target=mips-unknown-linux-gnu atomic_lock_free.rs - nm "$(TMPDIR)/libatomic_lock_free.rlib" | $(CGREP) -v __atomic_fetch_add -diff --git a/src/test/ui/abi/stack-probes-lto.rs b/src/test/ui/abi/stack-probes-lto.rs -index 6d934538f..e1b89d950 100644 ---- a/src/test/ui/abi/stack-probes-lto.rs -+++ b/src/test/ui/abi/stack-probes-lto.rs -@@ -1,6 +1,7 @@ - // run-pass - // ignore-arm - // ignore-aarch64 -+// ignore-loongarch64 - // ignore-mips - // ignore-mips64 - // ignore-sparc -diff --git a/src/test/ui/cfg/conditional-compile-arch.rs b/src/test/ui/cfg/conditional-compile-arch.rs -index 7de561df1..34172b8c9 100644 ---- a/src/test/ui/cfg/conditional-compile-arch.rs -+++ b/src/test/ui/cfg/conditional-compile-arch.rs -@@ -13,6 +13,9 @@ pub fn main() { } - #[cfg(target_arch = "aarch64")] - pub fn main() { } - -+#[cfg(target_arch = "loongarch64")] -+pub fn main() { } -+ - #[cfg(target_arch = "mips")] - pub fn main() { } - -diff --git a/src/test/ui/check-cfg/compact-values.stderr b/src/test/ui/check-cfg/compact-values.stderr -index 9864aa385..5ca4d3b3d 100644 ---- a/src/test/ui/check-cfg/compact-values.stderr -+++ b/src/test/ui/check-cfg/compact-values.stderr -@@ -4,7 +4,7 @@ warning: unexpected `cfg` condition value - LL | #[cfg(target(os = "linux", arch = "X"))] - | ^^^^^^^^^^ - | -- = note: expected values for `target_arch` are: aarch64, arm, avr, bpf, hexagon, m68k, mips, mips64, msp430, nvptx64, powerpc, powerpc64, riscv32, riscv64, s390x, sparc, sparc64, wasm32, wasm64, x86, x86_64 -+ = note: expected values for `target_arch` are: aarch64, arm, avr, bpf, hexagon, loongarch64, m68k, mips, mips64, msp430, nvptx64, powerpc, powerpc64, riscv32, riscv64, s390x, sparc, sparc64, wasm32, wasm64, x86, x86_64 - = note: `#[warn(unexpected_cfgs)]` on by default - - warning: 1 warning emitted -diff --git a/src/test/ui/process/nofile-limit.rs b/src/test/ui/process/nofile-limit.rs -index 3ddf8d6ef..79a6be731 100644 ---- a/src/test/ui/process/nofile-limit.rs -+++ b/src/test/ui/process/nofile-limit.rs -@@ -1,7 +1,8 @@ - // Check that statically linked binary executes successfully - // with RLIMIT_NOFILE resource lowered to zero. Regression - // test for issue #96621. --// -+// loongarch64 has no setrlimit -+// ignore-loongarch64 - // run-pass - // dont-check-compiler-stderr - // only-linux -diff --git a/src/test/ui/target-feature/gate.rs b/src/test/ui/target-feature/gate.rs -index 2382c98f8..15d1af6f7 100644 ---- a/src/test/ui/target-feature/gate.rs -+++ b/src/test/ui/target-feature/gate.rs -@@ -2,6 +2,7 @@ - // ignore-aarch64 - // ignore-wasm - // ignore-emscripten -+// ignore-loongarch64 - // ignore-mips - // ignore-mips64 - // ignore-powerpc -@@ -28,6 +29,7 @@ - // gate-test-ermsb_target_feature - // gate-test-bpf_target_feature - // gate-test-aarch64_ver_target_feature -+// gate-test-loongarch64_target_feature - - #[target_feature(enable = "avx512bw")] - //~^ ERROR: currently unstable -diff --git a/src/test/ui/target-feature/invalid-attribute.rs b/src/test/ui/target-feature/invalid-attribute.rs -index ad1b6e96b..040f3a365 100644 ---- a/src/test/ui/target-feature/invalid-attribute.rs -+++ b/src/test/ui/target-feature/invalid-attribute.rs -@@ -2,6 +2,7 @@ - // ignore-aarch64 - // ignore-wasm - // ignore-emscripten -+// ignore-loongarch64 - // ignore-mips - // ignore-mips64 - // ignore-powerpc -diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs -index b0006cb90..0c2b4b1ed 100644 ---- a/src/tools/build-manifest/src/main.rs -+++ b/src/tools/build-manifest/src/main.rs -@@ -28,6 +28,7 @@ static HOSTS: &[&str] = &[ - "i686-pc-windows-gnu", - "i686-pc-windows-msvc", - "i686-unknown-linux-gnu", -+ "loongarch64-unknown-linux-gnu", - "mips-unknown-linux-gnu", - "mips64-unknown-linux-gnuabi64", - "mips64el-unknown-linux-gnuabi64", -@@ -99,6 +100,7 @@ static TARGETS: &[&str] = &[ - "i686-unknown-freebsd", - "i686-unknown-linux-gnu", - "i686-unknown-linux-musl", -+ "loongarch64-unknown-linux-gnu", - "m68k-unknown-linux-gnu", - "mips-unknown-linux-gnu", - "mips-unknown-linux-musl", -diff --git a/src/tools/clippy/tests/ui/asm_syntax.rs b/src/tools/clippy/tests/ui/asm_syntax.rs -index 0220bf333..03748de7b 100644 ---- a/src/tools/clippy/tests/ui/asm_syntax.rs -+++ b/src/tools/clippy/tests/ui/asm_syntax.rs -@@ -1,5 +1,6 @@ - // only-x86_64 - // ignore-aarch64 -+// ignore-loongarch64 - - #[warn(clippy::inline_asm_x86_intel_syntax)] - mod warn_intel { -diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs -index 0260f6848..f4fb9fcdf 100644 ---- a/src/tools/compiletest/src/common.rs -+++ b/src/tools/compiletest/src/common.rs -@@ -430,7 +430,7 @@ impl Config { - pub fn has_asm_support(&self) -> bool { - static ASM_SUPPORTED_ARCHS: &[&str] = &[ - "x86", "x86_64", "arm", "aarch64", "riscv32", -- "riscv64", -+ "riscv64", "loongarch64", - // These targets require an additional asm_experimental_arch feature. - // "nvptx64", "hexagon", "mips", "mips64", "spirv", "wasm32", - ]; --- -2.41.0 - diff --git a/rust.spec b/rust.spec index b09c752fca8145bb4c254dcb547caf08bbfee440..fef55bde20419791d356d2d93f8d2d14ef91b60a 100644 --- a/rust.spec +++ b/rust.spec @@ -134,13 +134,8 @@ Patch100: rustc-1.71.0-disable-libssh2.patch # will try to build it statically -- instead we turn off the feature. Patch101: rustc-1.71.0-disable-http2.patch -#patch for loongarch64 -Patch103: 0001-vendor-cc-add-loongarch64-support.patch -Patch104: 0002-vendor-libc-update-loongarch64-support.patch -Patch105: 0003-vendor-psm-add-loongarch64-support.patch -Patch106: 0004-vendor-object-add-loongarch64-support.patch -Patch107: 0005-llvm-update-loongarch64-support.patch -Patch108: 0006-rust-add-loongarch64-support.patch +Patch102: 0001-asm-Stabilize-loongarch64.patch +Patch103: 0002-rustc-Convert-to-ABI-v0.patch # Get the Rust triple for any arch. %{lua: function rust_triple(arch) @@ -617,12 +612,9 @@ test -f '%{local_rust_root}/bin/rustc' rm -rf vendor/libnghttp2-sys*/ %endif -%patch103 -p1 -%patch104 -p1 -%patch105 -p1 -%patch106 -p1 -%patch107 -p1 -%patch108 -p1 +%patch -P102 -p1 +%patch -P103 -p1 + # Use our explicit python3 first sed -i.try-python -e '/^try python3 /i try "%{__python3}" "$@"' ./configure @@ -1097,9 +1089,8 @@ end} %changelog -* Mon Dec 25 2023 WANG Rui - 1.71.1-1.0.1 +* Thu Dec 28 2023 WANG Rui - 1.71.1-1.0.1 - Add support for loongarch64. -- Fix CVE-2023-38497 (liwei.glw@alibaba-inc.com) * Tue Aug 08 2023 Josh Stone - 1.71.1-1 - Update to 1.71.1.