On 13.03.2018 13:01, Janosch Frank wrote: > Short test of the vector, vector enhancement 1 and vector bcd > facility. > > Signed-off-by: Janosch Frank <frankja@xxxxxxxxxxxxxxxxxx> > --- > s390x/Makefile | 1 + > s390x/unittests.cfg | 3 ++ > s390x/vector.c | 136 ++++++++++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 140 insertions(+) > create mode 100644 s390x/vector.c > > diff --git a/s390x/Makefile b/s390x/Makefile > index d33e1d8..628f653 100644 > --- a/s390x/Makefile > +++ b/s390x/Makefile > @@ -8,6 +8,7 @@ tests += $(TEST_DIR)/diag10.elf > tests += $(TEST_DIR)/pfmf.elf > tests += $(TEST_DIR)/cmm.elf > tests += $(TEST_DIR)/gs.elf > +tests += $(TEST_DIR)/vector.elf > > all: directories test_cases > > diff --git a/s390x/unittests.cfg b/s390x/unittests.cfg > index 7f10d6b..97a16f5 100644 > --- a/s390x/unittests.cfg > +++ b/s390x/unittests.cfg > @@ -53,3 +53,6 @@ file = cmm.elf > > [gs] > file = gs.elf > + > +[vector] > +file = vector.elf > diff --git a/s390x/vector.c b/s390x/vector.c > new file mode 100644 > index 0000000..a9de1bd > --- /dev/null > +++ b/s390x/vector.c > @@ -0,0 +1,136 @@ > +/* > + * Tests vector instruction support > + * > + * Copyright 2017 IBM Corp. > + * > + * Authors: > + * Janosch Frank <frankja@xxxxxxxxxx> > + * > + * This code is free software; you can redistribute it and/or modify it > + * under the terms of the GNU Library General Public License version 2. > + */ > +#include <libcflat.h> > +#include <asm/page.h> > +#include <asm/facility.h> > +#include <asm/interrupt.h> > +#include <asm-generic/barrier.h> > + > +static uint8_t pagebuf[PAGE_SIZE * 2] __attribute__((aligned(PAGE_SIZE * 2))); > + > +static inline void vstm(unsigned long *addr) > +{ > + asm volatile(" .machine z13\n" > + " vstm 0, 15, %[a]\n" > + : [a] "=Q" (*addr) > + : : "memory"); > + asm volatile(" .machine z13\n" > + " vstm 16, 31, %[a]\n" > + : [a] "=Q" (*(addr+256/8)) > + : : "memory"); > +} This inline function is apparently unused and thus could be removed. > +static inline void vlm(unsigned long *addr) > +{ > + asm volatile(" .machine z13\n" > + " vlm 0, 15, %[a]\n" > + : : [a] "Q" (*addr) : ); > + asm volatile(" .machine z13\n" > + " vlm 16, 31, %[a]\n" > + : : [a] "Q" (*(addr+256/8)) : ); > +} > + > +static void test_add(void) > +{ > + static struct prm { > + __uint128_t a,b,c; > + } prm __attribute__((aligned(16))); > + > + prm.a = prm.b = 21; > + > + asm volatile(" .machine z13\n" > + " vl 0, %[v1]\n" > + " vl 1, %[v2]\n" > + " va 2, 0, 1, 4\n" > + " vst 2, %[v3]\n" > + : [v3] "=Q" (prm.c) > + : [v1] "Q" (prm.a), [v2] "Q" (prm.b) > + : "memory"); Is it possible to specify the vector registers in the clobber list? ... just in case the compiler also wants to use them on its own ... > + report("adding 21", prm.c == 42); > +} > + > +/* z14 vector extension test */ > +static void test_ext1_nand(void) > +{ > + static struct prm { > + __uint128_t a,b,c; > + } prm __attribute__((aligned(16))); > + > + > + if (!test_facility(134)) > + return; > + > + memset(&prm.a, 0xff, 16); > + prm.b = prm.a; > + > + asm volatile(" .machine z13\n" > + " vl 0, %[v1]\n" > + " vl 1, %[v2]\n" > + " .byte 0xe7, 0x20, 0x10, 0x00, 0x00, 0x6e\n" Please add a comment at the end of the line with the mnemonic of this instruction ("vnn"). > + " vst 2, %[v3]\n" > + : [v3] "=Q" (prm.c) > + : [v1] "Q" (prm.a), [v2] "Q" (prm.b) > + : "memory"); > + report("nand ff", !prm.c); > +} > + > +/* z14 bcd extension test */ > +static void test_bcd_add(void) > +{ > + static struct prm { > + __uint128_t a,b,c; > + } prm __attribute__((aligned(16))); > + > + if (!test_facility(135)) > + return; > + > + memset(&prm.a, 0x00, 16); > + prm.b = prm.a; > + prm.a = prm.b = 0b001000011100; > + > + asm volatile(" .machine z13\n" > + " vl 0, %[v1]\n" > + " vl 1, %[v2]\n" > + " .byte 0xe6, 0x20, 0x10, 0x01, 0x00, 0x71\n" /* vap */ (off-topic: SIMD instructions for BCD arithmetics? WTF? Who needs such stuff in the 21st century??) > + " vst 2, %[v3]\n" > + : [v3] "=Q" (prm.c) > + : [v1] "Q" (prm.a), [v2] "Q" (prm.b) > + : "memory"); > + report("bcd add 21", prm.c == 0x42c); > +} > + > +static void init(void) > +{ > + /* Enable vector instructions */ > + ctl_set_bit(0, 17); > +} > + > +int main(void) > +{ > + unsigned long *addr = (u64*)pagebuf; > + > + addr += PAGE_SIZE/8; addr seems to be unused here? > + if (!test_facility(129)) { > + printf("basic vector facility not available"); > + return 0; > + } > + > + report_prefix_push("vector"); > + memset(pagebuf, 0xff, PAGE_SIZE); Maybe move that memset into the init() function? > + init(); > + vlm((u64*)pagebuf); > + test_add(); > + test_ext1_nand(); > + test_bcd_add(); > + report_prefix_pop(); > + return report_summary(); > +} > Thomas PS: In case you've got some spare cycles, here's an idea for a future test: Check whether the contents of all vector registers are preserved correctly during migration. See run_migration in scripts/arch-run.bash and powerpc/sprs.c for an example how this can be done automatically with kvm-unit-tests.