> From: Fredrik Noring <nor...@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 <nor...@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 > >