Commit 8d3012efed for qemu.org
commit 8d3012efedd09aaf65b9032132a52e4d3e88a536
Author: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Date: Thu Oct 29 11:18:19 2026 +0100
tests/tcg/mipsel: Test MIPS32R6 LSA
Test LSA opcode.
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
Message-ID: <20261030182546.2508-11-philmd@oss.qualcomm.com>
diff --git a/tests/tcg/mips/include/wrappers_mips32r6.h b/tests/tcg/mips/include/wrappers_mips32r6.h
index cbff8450b6..63b4496b31 100644
--- a/tests/tcg/mips/include/wrappers_mips32r6.h
+++ b/tests/tcg/mips/include/wrappers_mips32r6.h
@@ -48,6 +48,28 @@ DO_MIPS32R6__RD__RS_RT(SLLV, sllv)
DO_MIPS32R6__RD__RS_RT(SRLV, srlv)
DO_MIPS32R6__RD__RS_RT(SRAV, srav)
+/* LSA rd, rs, rt, sa: rd = (rs << sa) + rt, with sa in 1..4. */
+#define DO_MIPS32R6__LSA(suffix, sa) \
+static inline void do_mips32r6_##suffix(const uint32_t *input1, \
+ const uint32_t *input2, \
+ uint32_t *output) \
+{ \
+ __asm__ volatile ( \
+ "lw $t1, 0(%0)\n\t" \
+ "lw $t2, 0(%1)\n\t" \
+ "lsa $t0, $t1, $t2, " #sa "\n\t" \
+ "sw $t0, 0(%2)\n\t" \
+ : \
+ : "r" (input1), "r" (input2), "r" (output) \
+ : "t0", "t1", "t2", "memory" \
+ ); \
+}
+
+DO_MIPS32R6__LSA(LSA1, 1)
+DO_MIPS32R6__LSA(LSA2, 2)
+DO_MIPS32R6__LSA(LSA3, 3)
+DO_MIPS32R6__LSA(LSA4, 4)
+
DO_MIPS32R6__RD__RS_RT(MUL, mul)
DO_MIPS32R6__RD__RS_RT(MUH, muh)
DO_MIPS32R6__RD__RS_RT(MULU, mulu)
diff --git a/tests/tcg/mipsel/test_mips32r6_shift.c b/tests/tcg/mipsel/test_mips32r6_shift.c
index 2f25e2a6bf..c1233f0ad8 100644
--- a/tests/tcg/mipsel/test_mips32r6_shift.c
+++ b/tests/tcg/mipsel/test_mips32r6_shift.c
@@ -24,6 +24,12 @@ static uint32_t ref_srav(uint32_t a, uint32_t b)
return (uint32_t)((int32_t)a >> (b & 31));
}
+/* LSA: shift rs left by 1..4, then add rt. */
+static uint32_t ref_lsa1(uint32_t a, uint32_t b) { return (a << 1) + b; }
+static uint32_t ref_lsa2(uint32_t a, uint32_t b) { return (a << 2) + b; }
+static uint32_t ref_lsa3(uint32_t a, uint32_t b) { return (a << 3) + b; }
+static uint32_t ref_lsa4(uint32_t a, uint32_t b) { return (a << 4) + b; }
+
static int check_one(const char *name, binary_op_32 op, ref_op_32 ref,
uint32_t a, uint32_t b)
{
@@ -69,6 +75,10 @@ int main(void)
run("SLLV", do_mips32r6_SLLV, ref_sllv);
run("SRLV", do_mips32r6_SRLV, ref_srlv);
run("SRAV", do_mips32r6_SRAV, ref_srav);
+ run("LSA1", do_mips32r6_LSA1, ref_lsa1);
+ run("LSA2", do_mips32r6_LSA2, ref_lsa2);
+ run("LSA3", do_mips32r6_LSA3, ref_lsa3);
+ run("LSA4", do_mips32r6_LSA4, ref_lsa4);
return tap_done();
}