From da250c714dae8b3a5317cb792650ce8f5893511b Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 28 Oct 2026 15:11:07 +0100 Subject: [PATCH 01/12] fix shift immediate widths This matches LLVM ``` class SRLI_B_DESC : MSA_BIT_SPLAT_DESC_BASE<"srli.b", srl, vsplati8_uimm3, MSA128BOpnd>; class SRLI_H_DESC : MSA_BIT_SPLAT_DESC_BASE<"srli.h", srl, vsplati16_uimm4, MSA128HOpnd>; class SRLI_W_DESC : MSA_BIT_SPLAT_DESC_BASE<"srli.w", srl, vsplati32_uimm5, MSA128WOpnd>; class SRLI_D_DESC : MSA_BIT_SPLAT_DESC_BASE<"srli.d", srl, vsplati64_uimm6, MSA128DOpnd>; ``` I suspect the old code mistakenly matched these variants ``` class SRLRI_B_DESC : MSA_BIT_X_DESC_BASE<"srlri.b", int_mips_srlri_b, uimm3, timmZExt3, MSA128BOpnd>; class SRLRI_H_DESC : MSA_BIT_X_DESC_BASE<"srlri.h", int_mips_srlri_h, uimm4, timmZExt4, MSA128HOpnd>; class SRLRI_W_DESC : MSA_BIT_X_DESC_BASE<"srlri.w", int_mips_srlri_w, uimm5, timmZExt5, MSA128WOpnd>; class SRLRI_D_DESC : MSA_BIT_X_DESC_BASE<"srlri.d", int_mips_srlri_d, uimm6, timmZExt6, MSA128DOpnd>; ``` --- crates/core_arch/src/mips/msa.rs | 64 ++++++++++++++++---------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/crates/core_arch/src/mips/msa.rs b/crates/core_arch/src/mips/msa.rs index 62818aece1..45bcbeda2f 100644 --- a/crates/core_arch/src/mips/msa.rs +++ b/crates/core_arch/src/mips/msa.rs @@ -7855,11 +7855,11 @@ pub unsafe fn __msa_sll_d(a: v2i64, b: v2i64) -> v2i64 { /// #[inline] #[target_feature(enable = "msa")] -#[cfg_attr(test, assert_instr(slli.b, IMM4 = 0b1111))] +#[cfg_attr(test, assert_instr(slli.b, IMM3 = 0b111))] #[unstable(feature = "stdarch_mips", issue = "111198")] -pub unsafe fn __msa_slli_b(a: v16i8) -> v16i8 { - static_assert_uimm_bits!(IMM4, 4); - msa_slli_b(a, IMM4) +pub unsafe fn __msa_slli_b(a: v16i8) -> v16i8 { + static_assert_uimm_bits!(IMM3, 3); + msa_slli_b(a, IMM3) } /// Immediate Shift Left @@ -7870,11 +7870,11 @@ pub unsafe fn __msa_slli_b(a: v16i8) -> v16i8 { /// #[inline] #[target_feature(enable = "msa")] -#[cfg_attr(test, assert_instr(slli.h, IMM3 = 0b111))] +#[cfg_attr(test, assert_instr(slli.h, IMM4 = 0b1111))] #[unstable(feature = "stdarch_mips", issue = "111198")] -pub unsafe fn __msa_slli_h(a: v8i16) -> v8i16 { - static_assert_uimm_bits!(IMM3, 3); - msa_slli_h(a, IMM3) +pub unsafe fn __msa_slli_h(a: v8i16) -> v8i16 { + static_assert_uimm_bits!(IMM4, 4); + msa_slli_h(a, IMM4) } /// Immediate Shift Left @@ -7885,11 +7885,11 @@ pub unsafe fn __msa_slli_h(a: v8i16) -> v8i16 { /// #[inline] #[target_feature(enable = "msa")] -#[cfg_attr(test, assert_instr(slli.w, IMM2 = 0b11))] +#[cfg_attr(test, assert_instr(slli.w, IMM5 = 0b1_1111))] #[unstable(feature = "stdarch_mips", issue = "111198")] -pub unsafe fn __msa_slli_w(a: v4i32) -> v4i32 { - static_assert_uimm_bits!(IMM2, 2); - msa_slli_w(a, IMM2) +pub unsafe fn __msa_slli_w(a: v4i32) -> v4i32 { + static_assert_uimm_bits!(IMM5, 5); + msa_slli_w(a, IMM5) } /// Immediate Shift Left @@ -7900,11 +7900,11 @@ pub unsafe fn __msa_slli_w(a: v4i32) -> v4i32 { /// #[inline] #[target_feature(enable = "msa")] -#[cfg_attr(test, assert_instr(slli.d, IMM1 = 0b1))] +#[cfg_attr(test, assert_instr(slli.d, IMM6 = 0b11_1111))] #[unstable(feature = "stdarch_mips", issue = "111198")] -pub unsafe fn __msa_slli_d(a: v2i64) -> v2i64 { - static_assert_uimm_bits!(IMM1, 1); - msa_slli_d(a, IMM1) +pub unsafe fn __msa_slli_d(a: v2i64) -> v2i64 { + static_assert_uimm_bits!(IMM6, 6); + msa_slli_d(a, IMM6) } /// GPR Element Splat @@ -8339,11 +8339,11 @@ pub unsafe fn __msa_srl_d(a: v2i64, b: v2i64) -> v2i64 { /// #[inline] #[target_feature(enable = "msa")] -#[cfg_attr(test, assert_instr(srli.b, IMM4 = 0b1111))] +#[cfg_attr(test, assert_instr(srli.b, IMM3 = 0b111))] #[unstable(feature = "stdarch_mips", issue = "111198")] -pub unsafe fn __msa_srli_b(a: v16i8) -> v16i8 { - static_assert_uimm_bits!(IMM4, 4); - msa_srli_b(a, IMM4) +pub unsafe fn __msa_srli_b(a: v16i8) -> v16i8 { + static_assert_uimm_bits!(IMM3, 3); + msa_srli_b(a, IMM3) } /// Immediate Shift Right Logical @@ -8354,11 +8354,11 @@ pub unsafe fn __msa_srli_b(a: v16i8) -> v16i8 { /// #[inline] #[target_feature(enable = "msa")] -#[cfg_attr(test, assert_instr(srli.h, IMM3 = 0b111))] +#[cfg_attr(test, assert_instr(srli.h, IMM4 = 0b1111))] #[unstable(feature = "stdarch_mips", issue = "111198")] -pub unsafe fn __msa_srli_h(a: v8i16) -> v8i16 { - static_assert_uimm_bits!(IMM3, 3); - msa_srli_h(a, IMM3) +pub unsafe fn __msa_srli_h(a: v8i16) -> v8i16 { + static_assert_uimm_bits!(IMM4, 4); + msa_srli_h(a, IMM4) } /// Immediate Shift Right Logical @@ -8369,11 +8369,11 @@ pub unsafe fn __msa_srli_h(a: v8i16) -> v8i16 { /// #[inline] #[target_feature(enable = "msa")] -#[cfg_attr(test, assert_instr(srli.w, IMM2 = 0b11))] +#[cfg_attr(test, assert_instr(srli.w, IMM5 = 0b1_1111))] #[unstable(feature = "stdarch_mips", issue = "111198")] -pub unsafe fn __msa_srli_w(a: v4i32) -> v4i32 { - static_assert_uimm_bits!(IMM2, 2); - msa_srli_w(a, IMM2) +pub unsafe fn __msa_srli_w(a: v4i32) -> v4i32 { + static_assert_uimm_bits!(IMM5, 5); + msa_srli_w(a, IMM5) } /// Immediate Shift Right Logical @@ -8384,11 +8384,11 @@ pub unsafe fn __msa_srli_w(a: v4i32) -> v4i32 { /// #[inline] #[target_feature(enable = "msa")] -#[cfg_attr(test, assert_instr(srli.d, IMM1 = 0b1))] +#[cfg_attr(test, assert_instr(srli.d, IMM6 = 0b11_1111))] #[unstable(feature = "stdarch_mips", issue = "111198")] -pub unsafe fn __msa_srli_d(a: v2i64) -> v2i64 { - static_assert_uimm_bits!(IMM1, 1); - msa_srli_d(a, IMM1) +pub unsafe fn __msa_srli_d(a: v2i64) -> v2i64 { + static_assert_uimm_bits!(IMM6, 6); + msa_srli_d(a, IMM6) } /// Vector Shift Right Logical Rounded From 7fffbe9197cf08fc5d812c324999ed8d596ec5c2 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 28 Oct 2026 15:17:04 +0100 Subject: [PATCH 02/12] use better test inputs the all-bits-set input is optimized in a way that defeats the tests, so use a non-trivial input --- crates/core_arch/src/mips/msa.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/core_arch/src/mips/msa.rs b/crates/core_arch/src/mips/msa.rs index 45bcbeda2f..61163fd422 100644 --- a/crates/core_arch/src/mips/msa.rs +++ b/crates/core_arch/src/mips/msa.rs @@ -2248,7 +2248,7 @@ pub unsafe fn __msa_bmnz_v(a: v16u8, b: v16u8, c: v16u8) -> v16u8 { /// #[inline] #[target_feature(enable = "msa")] -#[cfg_attr(test, assert_instr(bmnzi.b, IMM8 = 0b11111111))] +#[cfg_attr(test, assert_instr(bmnzi.b, IMM8 = 0b1011_1111))] #[unstable(feature = "stdarch_mips", issue = "111198")] pub unsafe fn __msa_bmnzi_b(a: v16u8, b: v16u8) -> v16u8 { static_assert_uimm_bits!(IMM8, 8); @@ -2278,7 +2278,7 @@ pub unsafe fn __msa_bmz_v(a: v16u8, b: v16u8, c: v16u8) -> v16u8 { /// #[inline] #[target_feature(enable = "msa")] -#[cfg_attr(test, assert_instr(bmzi.b, IMM8 = 0b11111111))] +#[cfg_attr(test, assert_instr(bmzi.b, IMM8 = 0x5a))] #[unstable(feature = "stdarch_mips", issue = "111198")] pub unsafe fn __msa_bmzi_b(a: v16u8, b: v16u8) -> v16u8 { static_assert_uimm_bits!(IMM8, 8); @@ -7253,7 +7253,7 @@ pub unsafe fn __msa_nor_v(a: v16u8, b: v16u8) -> v16u8 { /// #[inline] #[target_feature(enable = "msa")] -#[cfg_attr(test, assert_instr(nori.b, IMM8 = 0b11111111))] +#[cfg_attr(test, assert_instr(nori.b, IMM8 = 0b1011_1111))] #[unstable(feature = "stdarch_mips", issue = "111198")] pub unsafe fn __msa_nori_b(a: v16u8) -> v16u8 { static_assert_uimm_bits!(IMM8, 8); @@ -7284,7 +7284,7 @@ pub unsafe fn __msa_or_v(a: v16u8, b: v16u8) -> v16u8 { /// #[inline] #[target_feature(enable = "msa")] -#[cfg_attr(test, assert_instr(ori.b, IMM8 = 0b11111111))] +#[cfg_attr(test, assert_instr(ori.b, IMM8 = 0b1011_1111))] #[unstable(feature = "stdarch_mips", issue = "111198")] pub unsafe fn __msa_ori_b(a: v16u8) -> v16u8 { static_assert_uimm_bits!(IMM8, 8); @@ -7740,7 +7740,7 @@ pub unsafe fn __msa_sldi_b(a: v16i8, b: v16i8) -> v16i8 { /// #[inline] #[target_feature(enable = "msa")] -#[cfg_attr(test, assert_instr(sldi.h, IMM3 = 0b111))] +#[cfg_attr(test, assert_instr(sldi.h, IMM3 = 0b101))] #[unstable(feature = "stdarch_mips", issue = "111198")] pub unsafe fn __msa_sldi_h(a: v8i16, b: v8i16) -> v8i16 { static_assert_uimm_bits!(IMM3, 3); From b138ae7dff8c3b9846acb32295f0c5aa6e9657b5 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 28 Oct 2026 15:19:00 +0100 Subject: [PATCH 03/12] use better inputs that don't get folded away --- crates/core_arch/src/mips/msa.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/crates/core_arch/src/mips/msa.rs b/crates/core_arch/src/mips/msa.rs index 61163fd422..0974d82b8c 100644 --- a/crates/core_arch/src/mips/msa.rs +++ b/crates/core_arch/src/mips/msa.rs @@ -2053,7 +2053,7 @@ pub unsafe fn __msa_binsl_d(a: v2u64, b: v2u64, c: v2u64) -> v2u64 { /// #[inline] #[target_feature(enable = "msa")] -#[cfg_attr(test, assert_instr(binsli.b, IMM3 = 0b111))] +#[cfg_attr(test, assert_instr(binsli.b, IMM3 = 0b101))] #[unstable(feature = "stdarch_mips", issue = "111198")] pub unsafe fn __msa_binsli_b(a: v16u8, b: v16u8) -> v16u8 { static_assert_uimm_bits!(IMM3, 3); @@ -2068,7 +2068,7 @@ pub unsafe fn __msa_binsli_b(a: v16u8, b: v16u8) -> v16u8 { /// #[inline] #[target_feature(enable = "msa")] -#[cfg_attr(test, assert_instr(binsli.h, IMM4 = 0b1111))] +#[cfg_attr(test, assert_instr(binsli.h, IMM4 = 0b1011))] #[unstable(feature = "stdarch_mips", issue = "111198")] pub unsafe fn __msa_binsli_h(a: v8u16, b: v8u16) -> v8u16 { static_assert_uimm_bits!(IMM4, 4); @@ -2083,7 +2083,7 @@ pub unsafe fn __msa_binsli_h(a: v8u16, b: v8u16) -> v8u16 { /// #[inline] #[target_feature(enable = "msa")] -#[cfg_attr(test, assert_instr(binsli.w, IMM5 = 0b11111))] +#[cfg_attr(test, assert_instr(binsli.w, IMM5 = 0b10111))] #[unstable(feature = "stdarch_mips", issue = "111198")] pub unsafe fn __msa_binsli_w(a: v4u32, b: v4u32) -> v4u32 { static_assert_uimm_bits!(IMM5, 5); @@ -2098,7 +2098,7 @@ pub unsafe fn __msa_binsli_w(a: v4u32, b: v4u32) -> v4u32 { /// #[inline] #[target_feature(enable = "msa")] -#[cfg_attr(test, assert_instr(binsli.d, IMM6 = 0b111111))] +#[cfg_attr(test, assert_instr(binsli.d, IMM6 = 0b101111))] #[unstable(feature = "stdarch_mips", issue = "111198")] pub unsafe fn __msa_binsli_d(a: v2u64, b: v2u64) -> v2u64 { static_assert_uimm_bits!(IMM6, 6); @@ -2173,7 +2173,7 @@ pub unsafe fn __msa_binsr_d(a: v2u64, b: v2u64, c: v2u64) -> v2u64 { /// #[inline] #[target_feature(enable = "msa")] -#[cfg_attr(test, assert_instr(binsri.b, IMM3 = 0b111))] +#[cfg_attr(test, assert_instr(binsri.b, IMM3 = 0b101))] #[unstable(feature = "stdarch_mips", issue = "111198")] pub unsafe fn __msa_binsri_b(a: v16u8, b: v16u8) -> v16u8 { static_assert_uimm_bits!(IMM3, 3); @@ -2188,7 +2188,7 @@ pub unsafe fn __msa_binsri_b(a: v16u8, b: v16u8) -> v16u8 { /// #[inline] #[target_feature(enable = "msa")] -#[cfg_attr(test, assert_instr(binsri.h, IMM4 = 0b1111))] +#[cfg_attr(test, assert_instr(binsri.h, IMM4 = 0b1011))] #[unstable(feature = "stdarch_mips", issue = "111198")] pub unsafe fn __msa_binsri_h(a: v8u16, b: v8u16) -> v8u16 { static_assert_uimm_bits!(IMM4, 4); @@ -2203,7 +2203,7 @@ pub unsafe fn __msa_binsri_h(a: v8u16, b: v8u16) -> v8u16 { /// #[inline] #[target_feature(enable = "msa")] -#[cfg_attr(test, assert_instr(binsri.w, IMM5 = 0b11111))] +#[cfg_attr(test, assert_instr(binsri.w, IMM5 = 0b10111))] #[unstable(feature = "stdarch_mips", issue = "111198")] pub unsafe fn __msa_binsri_w(a: v4u32, b: v4u32) -> v4u32 { static_assert_uimm_bits!(IMM5, 5); @@ -2218,7 +2218,7 @@ pub unsafe fn __msa_binsri_w(a: v4u32, b: v4u32) -> v4u32 { /// #[inline] #[target_feature(enable = "msa")] -#[cfg_attr(test, assert_instr(binsri.d, IMM6 = 0b111111))] +#[cfg_attr(test, assert_instr(binsri.d, IMM6 = 0b101111))] #[unstable(feature = "stdarch_mips", issue = "111198")] pub unsafe fn __msa_binsri_d(a: v2u64, b: v2u64) -> v2u64 { static_assert_uimm_bits!(IMM6, 6); From 9903c9a27540a958d98fcf935d29d533fa449754 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 28 Oct 2026 15:22:44 +0100 Subject: [PATCH 04/12] use better inputs that don't get folded away note that the immediate is signed, so we actually have 9 bits for the value --- crates/core_arch/src/mips/msa.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/core_arch/src/mips/msa.rs b/crates/core_arch/src/mips/msa.rs index 0974d82b8c..8f1ebb3f54 100644 --- a/crates/core_arch/src/mips/msa.rs +++ b/crates/core_arch/src/mips/msa.rs @@ -5995,7 +5995,7 @@ pub unsafe fn __msa_ldi_b() -> v16i8 { /// #[inline] #[target_feature(enable = "msa")] -#[cfg_attr(test, assert_instr(ldi.h, IMM_S10 = -1))] +#[cfg_attr(test, assert_instr(ldi.h, IMM_S10 = 0b01_00001111))] #[unstable(feature = "stdarch_mips", issue = "111198")] pub unsafe fn __msa_ldi_h() -> v8i16 { static_assert_simm_bits!(IMM_S10, 10); @@ -6010,7 +6010,7 @@ pub unsafe fn __msa_ldi_h() -> v8i16 { /// #[inline] #[target_feature(enable = "msa")] -#[cfg_attr(test, assert_instr(ldi.w, IMM_S10 = -1))] +#[cfg_attr(test, assert_instr(ldi.w, IMM_S10 = 0b01_00001111))] #[unstable(feature = "stdarch_mips", issue = "111198")] pub unsafe fn __msa_ldi_w() -> v4i32 { static_assert_simm_bits!(IMM_S10, 10); @@ -6025,7 +6025,7 @@ pub unsafe fn __msa_ldi_w() -> v4i32 { /// #[inline] #[target_feature(enable = "msa")] -#[cfg_attr(test, assert_instr(ldi.d, IMM_S10 = -1))] +#[cfg_attr(test, assert_instr(ldi.d, IMM_S10 = 0b01_00001111))] #[unstable(feature = "stdarch_mips", issue = "111198")] pub unsafe fn __msa_ldi_d() -> v2i64 { static_assert_simm_bits!(IMM_S10, 10); From 16163e5c347f63e53fa230501caf44691c9387cb Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 28 Oct 2026 15:26:13 +0100 Subject: [PATCH 05/12] fixup docker files at least for me locally a comment can't be on the FROM line --- ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile | 5 +++-- ci/docker/mips64el-unknown-linux-gnuabi64/Dockerfile | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile b/ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile index 8bcd640945..7a7ace498d 100644 --- a/ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile +++ b/ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile @@ -1,4 +1,5 @@ -FROM ubuntu:25.04 # gcc-mips64-linux-gnuabi64 not available in 25.10 +# gcc-mips64-linux-gnuabi64 not available in 25.10 +FROM ubuntu:25.04 RUN apt-get update && apt-get install -y --no-install-recommends \ gcc libc6-dev qemu-user ca-certificates \ @@ -7,4 +8,4 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ ENV CARGO_TARGET_MIPS64_UNKNOWN_LINUX_GNUABI64_LINKER=mips64-linux-gnuabi64-gcc \ CARGO_TARGET_MIPS64_UNKNOWN_LINUX_GNUABI64_RUNNER="qemu-mips64 -L /usr/mips64-linux-gnuabi64" \ - OBJDUMP=mips64-linux-gnuabi64-objdump \ No newline at end of file + OBJDUMP=mips64-linux-gnuabi64-objdump diff --git a/ci/docker/mips64el-unknown-linux-gnuabi64/Dockerfile b/ci/docker/mips64el-unknown-linux-gnuabi64/Dockerfile index 9aa0ce0578..112121a261 100644 --- a/ci/docker/mips64el-unknown-linux-gnuabi64/Dockerfile +++ b/ci/docker/mips64el-unknown-linux-gnuabi64/Dockerfile @@ -1,4 +1,5 @@ -FROM ubuntu:25.04 # gcc-mips64el-linux-gnuabi64 not available in 25.10 +# gcc-mips64el-linux-gnuabi64 not available in 25.10 +FROM ubuntu:25.04 RUN apt-get update && apt-get install -y --no-install-recommends \ gcc libc6-dev qemu-user ca-certificates \ @@ -7,4 +8,4 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ ENV CARGO_TARGET_MIPS64EL_UNKNOWN_LINUX_GNUABI64_LINKER=mips64el-linux-gnuabi64-gcc \ CARGO_TARGET_MIPS64EL_UNKNOWN_LINUX_GNUABI64_RUNNER="qemu-mips64el -L /usr/mips64el-linux-gnuabi64" \ - OBJDUMP=mips64el-linux-gnuabi64-objdump \ No newline at end of file + OBJDUMP=mips64el-linux-gnuabi64-objdump From c3fc38574bd1b6ef0b231ac96d2280c5b5d54cc3 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 28 Oct 2026 15:55:56 +0100 Subject: [PATCH 06/12] loads and stores now always use the `.d` variant --- crates/core_arch/src/mips/msa.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/core_arch/src/mips/msa.rs b/crates/core_arch/src/mips/msa.rs index 8f1ebb3f54..a3da837610 100644 --- a/crates/core_arch/src/mips/msa.rs +++ b/crates/core_arch/src/mips/msa.rs @@ -5917,7 +5917,7 @@ pub unsafe fn __msa_insve_d(a: v2i64, c: v2i64) -> v2i64 { /// #[inline] #[target_feature(enable = "msa")] -#[cfg_attr(test, assert_instr(ld.b, IMM_S10 = -1))] +#[cfg_attr(test, assert_instr(ld.d, IMM_S10 = -1))] #[unstable(feature = "stdarch_mips", issue = "111198")] pub unsafe fn __msa_ld_b(mem_addr: *mut u8) -> v16i8 { static_assert_simm_bits!(IMM_S10, 10); @@ -5932,7 +5932,7 @@ pub unsafe fn __msa_ld_b(mem_addr: *mut u8) -> v16i8 { /// #[inline] #[target_feature(enable = "msa")] -#[cfg_attr(test, assert_instr(ld.h, IMM_S11 = -2))] +#[cfg_attr(test, assert_instr(ld.d, IMM_S11 = -2))] #[unstable(feature = "stdarch_mips", issue = "111198")] pub unsafe fn __msa_ld_h(mem_addr: *mut u8) -> v8i16 { static_assert_simm_bits!(IMM_S11, 11); @@ -5948,7 +5948,7 @@ pub unsafe fn __msa_ld_h(mem_addr: *mut u8) -> v8i16 { /// #[inline] #[target_feature(enable = "msa")] -#[cfg_attr(test, assert_instr(ld.w, IMM_S12 = -4))] +#[cfg_attr(test, assert_instr(ld.d, IMM_S12 = -4))] #[unstable(feature = "stdarch_mips", issue = "111198")] pub unsafe fn __msa_ld_w(mem_addr: *mut u8) -> v4i32 { static_assert_simm_bits!(IMM_S12, 12); @@ -8527,7 +8527,7 @@ pub unsafe fn __msa_srlri_d(a: v2i64) -> v2i64 { /// #[inline] #[target_feature(enable = "msa")] -#[cfg_attr(test, assert_instr(st.b, IMM_S10 = -1))] +#[cfg_attr(test, assert_instr(st.d, IMM_S10 = -1))] #[unstable(feature = "stdarch_mips", issue = "111198")] pub unsafe fn __msa_st_b(a: v16i8, mem_addr: *mut u8) -> () { static_assert_simm_bits!(IMM_S10, 10); @@ -8542,7 +8542,7 @@ pub unsafe fn __msa_st_b(a: v16i8, mem_addr: *mut u8) -> () /// #[inline] #[target_feature(enable = "msa")] -#[cfg_attr(test, assert_instr(st.h, IMM_S11 = -2))] +#[cfg_attr(test, assert_instr(st.d, IMM_S11 = -2))] #[unstable(feature = "stdarch_mips", issue = "111198")] pub unsafe fn __msa_st_h(a: v8i16, mem_addr: *mut u8) -> () { static_assert_simm_bits!(IMM_S11, 11); @@ -8558,7 +8558,7 @@ pub unsafe fn __msa_st_h(a: v8i16, mem_addr: *mut u8) -> () /// #[inline] #[target_feature(enable = "msa")] -#[cfg_attr(test, assert_instr(st.w, IMM_S12 = -4))] +#[cfg_attr(test, assert_instr(st.d, IMM_S12 = -4))] #[unstable(feature = "stdarch_mips", issue = "111198")] pub unsafe fn __msa_st_w(a: v4i32, mem_addr: *mut u8) -> () { static_assert_simm_bits!(IMM_S12, 12); From f0aa4d77cbbd51343dbdbed1d0c25b2f46cad33b Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 28 Oct 2026 15:57:41 +0100 Subject: [PATCH 07/12] `copy_u_d` uses the signed instruction; there is no sign/zero extension so they are equivalent --- crates/core_arch/src/mips/msa.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/core_arch/src/mips/msa.rs b/crates/core_arch/src/mips/msa.rs index a3da837610..422b1fe06c 100644 --- a/crates/core_arch/src/mips/msa.rs +++ b/crates/core_arch/src/mips/msa.rs @@ -3408,7 +3408,7 @@ pub unsafe fn __msa_copy_u_w(a: v4i32) -> u32 { /// #[inline] #[target_feature(enable = "msa")] -#[cfg_attr(test, assert_instr(copy_u.d, IMM1 = 0b1))] +#[cfg_attr(test, assert_instr(copy_s.d, IMM1 = 0b1))] #[unstable(feature = "stdarch_mips", issue = "111198")] pub unsafe fn __msa_copy_u_d(a: v2i64) -> u64 { static_assert_uimm_bits!(IMM1, 1); From da28ba3d2147200fa5fe0030ade802f9ae953bd7 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 28 Oct 2026 16:01:59 +0100 Subject: [PATCH 08/12] clang ends up using the negated variant; fine --- crates/core_arch/src/mips/msa.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/core_arch/src/mips/msa.rs b/crates/core_arch/src/mips/msa.rs index 422b1fe06c..e23ccf3db1 100644 --- a/crates/core_arch/src/mips/msa.rs +++ b/crates/core_arch/src/mips/msa.rs @@ -2264,7 +2264,7 @@ pub unsafe fn __msa_bmnzi_b(a: v16u8, b: v16u8) -> v16u8 { /// #[inline] #[target_feature(enable = "msa")] -#[cfg_attr(test, assert_instr(bmz.v))] +#[cfg_attr(test, assert_instr(bmnz.v))] #[unstable(feature = "stdarch_mips", issue = "111198")] pub unsafe fn __msa_bmz_v(a: v16u8, b: v16u8, c: v16u8) -> v16u8 { msa_bmz_v(a, mem::transmute(b), c) @@ -2278,7 +2278,7 @@ pub unsafe fn __msa_bmz_v(a: v16u8, b: v16u8, c: v16u8) -> v16u8 { /// #[inline] #[target_feature(enable = "msa")] -#[cfg_attr(test, assert_instr(bmzi.b, IMM8 = 0x5a))] +#[cfg_attr(test, assert_instr(bmnzi.b, IMM8 = 0b1011_1111))] #[unstable(feature = "stdarch_mips", issue = "111198")] pub unsafe fn __msa_bmzi_b(a: v16u8, b: v16u8) -> v16u8 { static_assert_uimm_bits!(IMM8, 8); @@ -2475,7 +2475,7 @@ pub unsafe fn __msa_bnz_v(a: v16u8) -> i32 { /// #[inline] #[target_feature(enable = "msa")] -#[cfg_attr(test, assert_instr(bsel.v))] +#[cfg_attr(test, assert_instr(bmnz.v))] #[unstable(feature = "stdarch_mips", issue = "111198")] pub unsafe fn __msa_bsel_v(a: v16u8, b: v16u8, c: v16u8) -> v16u8 { msa_bsel_v(a, mem::transmute(b), c) From e9e6a9ad00ef1af0b50f43becbac0cb4651e3cba Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 28 Oct 2026 16:02:36 +0100 Subject: [PATCH 09/12] clang uses just an `andi.b` for `bclri_b` --- crates/core_arch/src/mips/msa.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/core_arch/src/mips/msa.rs b/crates/core_arch/src/mips/msa.rs index e23ccf3db1..6b6fec834b 100644 --- a/crates/core_arch/src/mips/msa.rs +++ b/crates/core_arch/src/mips/msa.rs @@ -1933,7 +1933,7 @@ pub unsafe fn __msa_bclr_d(a: v2u64, b: v2u64) -> v2u64 { /// #[inline] #[target_feature(enable = "msa")] -#[cfg_attr(test, assert_instr(bclri.b, IMM3 = 0b111))] +#[cfg_attr(test, assert_instr(andi.b, IMM3 = 0b111))] #[unstable(feature = "stdarch_mips", issue = "111198")] pub unsafe fn __msa_bclri_b(a: v16u8) -> v16u8 { static_assert_uimm_bits!(IMM3, 3); From 9792a9a03bd9a69ab6ffa68fd4dba4dec3adef75 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 28 Oct 2026 16:38:31 +0100 Subject: [PATCH 10/12] correct FMA test results --- crates/core_arch/src/mips/msa.rs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/crates/core_arch/src/mips/msa.rs b/crates/core_arch/src/mips/msa.rs index 6b6fec834b..04a14f4710 100644 --- a/crates/core_arch/src/mips/msa.rs +++ b/crates/core_arch/src/mips/msa.rs @@ -13105,14 +13105,15 @@ mod tests { #[simd_test(enable = "msa")] unsafe fn test_msa_fmadd_w() { - #[rustfmt::skip] let a = f32x4::new(1.0, 2.0, 3.0, 4.0); - #[rustfmt::skip] let b = f32x4::new(5.0, 6.0, 7.0, 8.0); - #[rustfmt::skip] let c = f32x4::new(9.0, 10.0, 11.0, 12.0); - #[rustfmt::skip] - let r = f32x4::new(46.0, 62.0, 80.0, 100.0); + let r = f32x4::new( + 1.0 * 5.0 + 9.0, + 2.0 * 6.0 + 10.0, + 3.0 * 7.0 + 11.0, + 4.0 * 8.0 + 12.0, + ); assert_eq!( r, @@ -13126,14 +13127,10 @@ mod tests { #[simd_test(enable = "msa")] unsafe fn test_msa_fmadd_d() { - #[rustfmt::skip] let a = f64x2::new(1.0, 2.0); - #[rustfmt::skip] let b = f64x2::new(3.0, 4.0); - #[rustfmt::skip] let c = f64x2::new(5.0, 6.0); - #[rustfmt::skip] - let r = f64x2::new(16.0, 26.0); + let r = f64x2::new(1.0 * 3.0 + 5.0, 2.0 * 4.0 + 6.0); assert_eq!( r, From 7b864b17cf608f5f329e7347d31f016d95247a98 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 28 Oct 2026 17:11:05 +0100 Subject: [PATCH 11/12] run qemu with a CPU that has +msa --- ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile | 2 +- ci/docker/mips64el-unknown-linux-gnuabi64/Dockerfile | 2 +- ci/run.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile b/ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile index 7a7ace498d..62f3099a35 100644 --- a/ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile +++ b/ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile @@ -7,5 +7,5 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ qemu-system-mips64 qemu-user ENV CARGO_TARGET_MIPS64_UNKNOWN_LINUX_GNUABI64_LINKER=mips64-linux-gnuabi64-gcc \ - CARGO_TARGET_MIPS64_UNKNOWN_LINUX_GNUABI64_RUNNER="qemu-mips64 -L /usr/mips64-linux-gnuabi64" \ + CARGO_TARGET_MIPS64_UNKNOWN_LINUX_GNUABI64_RUNNER="qemu-mips64 -cpu Loongson-3A4000 -L /usr/mips64-linux-gnuabi64" \ OBJDUMP=mips64-linux-gnuabi64-objdump diff --git a/ci/docker/mips64el-unknown-linux-gnuabi64/Dockerfile b/ci/docker/mips64el-unknown-linux-gnuabi64/Dockerfile index 112121a261..bd7f2e7438 100644 --- a/ci/docker/mips64el-unknown-linux-gnuabi64/Dockerfile +++ b/ci/docker/mips64el-unknown-linux-gnuabi64/Dockerfile @@ -7,5 +7,5 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ qemu-system-mips64el ENV CARGO_TARGET_MIPS64EL_UNKNOWN_LINUX_GNUABI64_LINKER=mips64el-linux-gnuabi64-gcc \ - CARGO_TARGET_MIPS64EL_UNKNOWN_LINUX_GNUABI64_RUNNER="qemu-mips64el -L /usr/mips64el-linux-gnuabi64" \ + CARGO_TARGET_MIPS64EL_UNKNOWN_LINUX_GNUABI64_RUNNER="qemu-mips64el -cpu Loongson-3A4000 -L /usr/mips64el-linux-gnuabi64" \ OBJDUMP=mips64el-linux-gnuabi64-objdump diff --git a/ci/run.sh b/ci/run.sh index 8c75df6afb..83b97d139a 100755 --- a/ci/run.sh +++ b/ci/run.sh @@ -113,7 +113,7 @@ case ${TARGET} in # cargo_test # ;; mips64*) - export RUSTFLAGS="${RUSTFLAGS} -C target-feature=+msa" + export RUSTFLAGS="${RUSTFLAGS} -C target-cpu=mips64r5 -C target-feature=+msa" cargo_test ;; s390x*) From e1e61b63a483756e9c695d77ff87be975686f972 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 28 Oct 2026 17:28:06 +0100 Subject: [PATCH 12/12] work around LLVM emitting a different instruction than the intrinsic name suggests our assert_instr checks now match the actual clang output, update stdarch-verify to match --- crates/stdarch-verify/tests/mips.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/crates/stdarch-verify/tests/mips.rs b/crates/stdarch-verify/tests/mips.rs index 18502ae5c7..504f362d2b 100644 --- a/crates/stdarch-verify/tests/mips.rs +++ b/crates/stdarch-verify/tests/mips.rs @@ -286,6 +286,22 @@ fn verify_all_signatures() { assert!(all_valid); } +// Intrinsics for which LLVM does not emit the exact instruction that you'd +// expect based on the intrinsic name, but something equivalent. +static LLVM_SELECTS_SOMETHING_EQUIVALENT: &[(&str, &str)] = &[ + ("__msa_bclri_b", "andi.b"), + ("__msa_bmz_v", "bmnz.v"), + ("__msa_bmzi_b", "bmnzi.b"), + ("__msa_bsel_v", "bmnz.v"), + ("__msa_copy_u_d", "copy_s.d"), + ("__msa_ld_b", "ld.d"), + ("__msa_ld_h", "ld.d"), + ("__msa_ld_w", "ld.d"), + ("__msa_st_b", "st.d"), + ("__msa_st_h", "st.d"), + ("__msa_st_w", "st.d"), +]; + fn matches(rust: &Function, mips: &MsaIntrinsic) -> Result<(), String> { macro_rules! bail { ($($t:tt)*) => (return Err(format!($($t)*))) @@ -358,7 +374,9 @@ fn matches(rust: &Function, mips: &MsaIntrinsic) -> Result<(), String> { // Normalize slightly to get rid of assembler differences let actual = rust.instrs[0].replace('.', "_"); let expected = mips.instruction.replace('.', "_"); - if actual != expected { + if actual != expected + && !LLVM_SELECTS_SOMETHING_EQUIVALENT.contains(&(rust.name, rust.instrs[0])) + { bail!( "wrong instruction: \"{}\" != \"{}\"", rust.instrs[0],