Test LSA opcode.
Signed-off-by: Philippe Mathieu-Daudé <[email protected]>
---
tests/tcg/mips/include/wrappers_mips32r6.h | 22 ++++++++++++++++++++++
tests/tcg/mipsel/test_mips32r6_shift.c | 12 +++++++++++-
2 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/tests/tcg/mips/include/wrappers_mips32r6.h
b/tests/tcg/mips/include/wrappers_mips32r6.h
index cbff8450b656..63b4496b3188 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 c4389b5d232a..7b419ef05f28 100644
--- a/tests/tcg/mipsel/test_mips32r6_shift.c
+++ b/tests/tcg/mipsel/test_mips32r6_shift.c
@@ -21,6 +21,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)
{
@@ -65,10 +71,14 @@ int main(void)
{
int ret = 0;
- printf("TAP version 14\n1..3\n");
+ printf("TAP version 14\n1..7\n");
ret |= run("SLLV", do_mips32r6_SLLV, ref_sllv);
ret |= run("SRLV", do_mips32r6_SRLV, ref_srlv);
ret |= run("SRAV", do_mips32r6_SRAV, ref_srav);
+ ret |= run("LSA1", do_mips32r6_LSA1, ref_lsa1);
+ ret |= run("LSA2", do_mips32r6_LSA2, ref_lsa2);
+ ret |= run("LSA3", do_mips32r6_LSA3, ref_lsa3);
+ ret |= run("LSA4", do_mips32r6_LSA4, ref_lsa4);
return ret ? 1 : 0;
}
--
2.55.0