diff mbox series

[8/9] tests/tcg/mips: Test R5900 multimedia instruction LQ

Message ID e1efe4eff36a4069bbf8411a09d01acd387fb49d.1547403692.git.noring@nocrew.org
State New
Headers show
Series target/mips: Limited support for R5900 multimedia instructions | expand

Commit Message

Fredrik Noring Jan. 13, 2019, 7:08 p.m. UTC
Signed-off-by: Fredrik Noring <noring@nocrew.org>
---
 tests/tcg/mips/mipsn32r5900/Makefile |   3 +-
 tests/tcg/mips/mipsn32r5900/lq.c     | 111 +++++++++++++++++++++++++++
 2 files changed, 113 insertions(+), 1 deletion(-)
 create mode 100644 tests/tcg/mips/mipsn32r5900/lq.c

Comments

Aleksandar Markovic Jan. 15, 2019, 9:56 p.m. UTC | #1
> From: Fredrik Noring <noring@nocrew.org>
> Sent: Sunday, January 13, 2019 8:08 PM
> To: Aleksandar Markovic; Aurelien Jarno; Philippe Mathieu-Daudé
> Cc: Jürgen Urban; Maciej W. Rozycki; qemu-devel@nongnu.org
> Subject: [PATCH 8/9] tests/tcg/mips: Test R5900 multimedia instruction LQ
> 
> Signed-off-by: Fredrik Noring <noring@nocrew.org>
> ---

The commit message is missing. I will deal with the rest of this patch once LQ
implementation patch is accepted.

>  tests/tcg/mips/mipsn32r5900/Makefile |   3 +-
>  tests/tcg/mips/mipsn32r5900/lq.c     | 111 +++++++++++++++++++++++++++
>  2 files changed, 113 insertions(+), 1 deletion(-)
>  create mode 100644 tests/tcg/mips/mipsn32r5900/lq.c
> 
> diff --git a/tests/tcg/mips/mipsn32r5900/Makefile b/tests/tcg/mips/mipsn32r5900/Makefile
> index f4887678ae..cb3ef9d26a 100644
> --- a/tests/tcg/mips/mipsn32r5900/Makefile
> +++ b/tests/tcg/mips/mipsn32r5900/Makefile
> @@ -8,7 +8,8 @@ SIM_FLAGS=-cpu R5900
>  CC      = $(CROSS)gcc
>  CFLAGS  = -Wall -mabi=n32 -march=r5900 -static
> 
> -TESTCASES = pcpyuld.tst
> +TESTCASES = lq.tst
> +TESTCASES += pcpyuld.tst
> 
>  all: $(TESTCASES)
> 
> diff --git a/tests/tcg/mips/mipsn32r5900/lq.c b/tests/tcg/mips/mipsn32r5900/lq.c
> new file mode 100644
> index 0000000000..5a16b12450
> --- /dev/null
> +++ b/tests/tcg/mips/mipsn32r5900/lq.c
> @@ -0,0 +1,111 @@
> +/*
> + * Test LQ.
> + */
> +
> +#include <stdio.h>
> +#include <inttypes.h>
> +#include <assert.h>
> +
> +/* 128-bit multimedia register */
> +struct mmr { uint64_t hi, lo; } __attribute__((aligned(16)));
> +
> +#define LQ(base, offset) \
> +    ({ \
> +        uint64_t hi, lo; \
> +    \
> +        __asm__ __volatile__ ( \
> +            "    pcpyld  %1, %1, %1\n" \
> +            "    lq %1, %3(%2)\n" \
> +            "    pcpyud  %0, %1, %1\n" \
> +            : "=r" (hi), "=r" (lo) \
> +            : "r" (base), "i" (offset)); \
> +    \
> +        (struct mmr) { .hi = hi, .lo = lo }; \
> +    })
> +
> +static uint64_t ld_reference(const void *base, int16_t offset)
> +{
> +    const uint8_t *p = base;
> +    uint64_t r = 0;
> +    int i;
> +
> +    for (i = 0; i < 8; i++) {
> +        r |= (uint64_t)p[offset + i] << (8 * i);
> +    }
> +
> +    return r;
> +}
> +
> +static struct mmr lq_reference(const void *base, int16_t offset)
> +{
> +    /*
> +     * The least significant four bits of the effective address are
> +     * masked to zero, effectively creating an aligned address. No
> +     * address exceptions due to alignment are possible.
> +     */
> +    const uint8_t *b = base;
> +    const uint8_t *o = &b[offset];
> +    const void *a = (const void*)((unsigned long)o & ~0xFUL);
> +
> +    return (struct mmr) {
> +        .hi = ld_reference(a, 8),
> +        .lo = ld_reference(a, 0)
> +    };
> +}
> +
> +static void assert_equal_mmr(struct mmr a, struct mmr b)
> +{
> +    assert(a.hi == b.hi);
> +    assert(a.lo == b.lo);
> +}
> +
> +#define VERIFY_LQ(base, offset) \
> +    assert_equal_mmr(LQ(base, offset), lq_reference(base, offset))
> +
> +int main()
> +{
> +    static const char data[] __attribute__((aligned(16)))=
> +        "0123456789abcdef"
> +        "ghijklmnopqrstuv"
> +        "wxyzABCDEFGHIJKL"
> +        "MNOPQRSTUVWXYZ.,";
> +    int i;
> +
> +    for (i = 16; i < 48; i++) {
> +        VERIFY_LQ(&data[i], -16);
> +        VERIFY_LQ(&data[i], -15);
> +        VERIFY_LQ(&data[i], -14);
> +        VERIFY_LQ(&data[i], -13);
> +        VERIFY_LQ(&data[i], -12);
> +        VERIFY_LQ(&data[i], -11);
> +        VERIFY_LQ(&data[i], -10);
> +        VERIFY_LQ(&data[i], -9);
> +        VERIFY_LQ(&data[i], -8);
> +        VERIFY_LQ(&data[i], -7);
> +        VERIFY_LQ(&data[i], -6);
> +        VERIFY_LQ(&data[i], -5);
> +        VERIFY_LQ(&data[i], -4);
> +        VERIFY_LQ(&data[i], -3);
> +        VERIFY_LQ(&data[i], -2);
> +        VERIFY_LQ(&data[i], -1);
> +        VERIFY_LQ(&data[i],  0);
> +        VERIFY_LQ(&data[i],  1);
> +        VERIFY_LQ(&data[i],  2);
> +        VERIFY_LQ(&data[i],  3);
> +        VERIFY_LQ(&data[i],  4);
> +        VERIFY_LQ(&data[i],  5);
> +        VERIFY_LQ(&data[i],  6);
> +        VERIFY_LQ(&data[i],  7);
> +        VERIFY_LQ(&data[i],  8);
> +        VERIFY_LQ(&data[i],  9);
> +        VERIFY_LQ(&data[i],  10);
> +        VERIFY_LQ(&data[i],  11);
> +        VERIFY_LQ(&data[i],  12);
> +        VERIFY_LQ(&data[i],  13);
> +        VERIFY_LQ(&data[i],  14);
> +        VERIFY_LQ(&data[i],  15);
> +        VERIFY_LQ(&data[i],  16);
> +    }
> +
> +    return 0;
> +}
> --
> 2.19.2
> 
>
diff mbox series

Patch

diff --git a/tests/tcg/mips/mipsn32r5900/Makefile b/tests/tcg/mips/mipsn32r5900/Makefile
index f4887678ae..cb3ef9d26a 100644
--- a/tests/tcg/mips/mipsn32r5900/Makefile
+++ b/tests/tcg/mips/mipsn32r5900/Makefile
@@ -8,7 +8,8 @@  SIM_FLAGS=-cpu R5900
 CC      = $(CROSS)gcc
 CFLAGS  = -Wall -mabi=n32 -march=r5900 -static
 
-TESTCASES = pcpyuld.tst
+TESTCASES = lq.tst
+TESTCASES += pcpyuld.tst
 
 all: $(TESTCASES)
 
diff --git a/tests/tcg/mips/mipsn32r5900/lq.c b/tests/tcg/mips/mipsn32r5900/lq.c
new file mode 100644
index 0000000000..5a16b12450
--- /dev/null
+++ b/tests/tcg/mips/mipsn32r5900/lq.c
@@ -0,0 +1,111 @@ 
+/*
+ * Test LQ.
+ */
+
+#include <stdio.h>
+#include <inttypes.h>
+#include <assert.h>
+
+/* 128-bit multimedia register */
+struct mmr { uint64_t hi, lo; } __attribute__((aligned(16)));
+
+#define LQ(base, offset) \
+    ({ \
+        uint64_t hi, lo; \
+    \
+        __asm__ __volatile__ ( \
+            "    pcpyld  %1, %1, %1\n" \
+            "    lq %1, %3(%2)\n" \
+            "    pcpyud  %0, %1, %1\n" \
+            : "=r" (hi), "=r" (lo) \
+            : "r" (base), "i" (offset)); \
+    \
+        (struct mmr) { .hi = hi, .lo = lo }; \
+    })
+
+static uint64_t ld_reference(const void *base, int16_t offset)
+{
+    const uint8_t *p = base;
+    uint64_t r = 0;
+    int i;
+
+    for (i = 0; i < 8; i++) {
+        r |= (uint64_t)p[offset + i] << (8 * i);
+    }
+
+    return r;
+}
+
+static struct mmr lq_reference(const void *base, int16_t offset)
+{
+    /*
+     * The least significant four bits of the effective address are
+     * masked to zero, effectively creating an aligned address. No
+     * address exceptions due to alignment are possible.
+     */
+    const uint8_t *b = base;
+    const uint8_t *o = &b[offset];
+    const void *a = (const void*)((unsigned long)o & ~0xFUL);
+
+    return (struct mmr) {
+        .hi = ld_reference(a, 8),
+        .lo = ld_reference(a, 0)
+    };
+}
+
+static void assert_equal_mmr(struct mmr a, struct mmr b)
+{
+    assert(a.hi == b.hi);
+    assert(a.lo == b.lo);
+}
+
+#define VERIFY_LQ(base, offset) \
+    assert_equal_mmr(LQ(base, offset), lq_reference(base, offset))
+
+int main()
+{
+    static const char data[] __attribute__((aligned(16)))=
+        "0123456789abcdef"
+        "ghijklmnopqrstuv"
+        "wxyzABCDEFGHIJKL"
+        "MNOPQRSTUVWXYZ.,";
+    int i;
+
+    for (i = 16; i < 48; i++) {
+        VERIFY_LQ(&data[i], -16);
+        VERIFY_LQ(&data[i], -15);
+        VERIFY_LQ(&data[i], -14);
+        VERIFY_LQ(&data[i], -13);
+        VERIFY_LQ(&data[i], -12);
+        VERIFY_LQ(&data[i], -11);
+        VERIFY_LQ(&data[i], -10);
+        VERIFY_LQ(&data[i], -9);
+        VERIFY_LQ(&data[i], -8);
+        VERIFY_LQ(&data[i], -7);
+        VERIFY_LQ(&data[i], -6);
+        VERIFY_LQ(&data[i], -5);
+        VERIFY_LQ(&data[i], -4);
+        VERIFY_LQ(&data[i], -3);
+        VERIFY_LQ(&data[i], -2);
+        VERIFY_LQ(&data[i], -1);
+        VERIFY_LQ(&data[i],  0);
+        VERIFY_LQ(&data[i],  1);
+        VERIFY_LQ(&data[i],  2);
+        VERIFY_LQ(&data[i],  3);
+        VERIFY_LQ(&data[i],  4);
+        VERIFY_LQ(&data[i],  5);
+        VERIFY_LQ(&data[i],  6);
+        VERIFY_LQ(&data[i],  7);
+        VERIFY_LQ(&data[i],  8);
+        VERIFY_LQ(&data[i],  9);
+        VERIFY_LQ(&data[i],  10);
+        VERIFY_LQ(&data[i],  11);
+        VERIFY_LQ(&data[i],  12);
+        VERIFY_LQ(&data[i],  13);
+        VERIFY_LQ(&data[i],  14);
+        VERIFY_LQ(&data[i],  15);
+        VERIFY_LQ(&data[i],  16);
+    }
+
+    return 0;
+}