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


Reply via email to