Message ID | e1efe4eff36a4069bbf8411a09d01acd387fb49d.1547403692.git.noring@nocrew.org |
---|---|
State | New |
Headers | show |
Series | target/mips: Limited support for R5900 multimedia instructions | expand |
> 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 --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; +}
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