xref: /kvm-unit-tests/s390x/vector.c (revision 0c259cf369540df8fed7e64d63998f92574966b9)
1fa624cc2SJanosch Frank /* SPDX-License-Identifier: GPL-2.0-only */
243868475SJanosch Frank /*
343868475SJanosch Frank  * Tests vector instruction support
443868475SJanosch Frank  *
543868475SJanosch Frank  * Copyright 2018 IBM Corp.
643868475SJanosch Frank  *
743868475SJanosch Frank  * Authors:
8*b81a2cd4SJanosch Frank  *    Janosch Frank <frankja@linux.ibm.com>
943868475SJanosch Frank  */
1043868475SJanosch Frank #include <libcflat.h>
1143868475SJanosch Frank #include <asm/page.h>
1243868475SJanosch Frank #include <asm/facility.h>
1343868475SJanosch Frank #include <asm/interrupt.h>
1443868475SJanosch Frank #include <asm-generic/barrier.h>
1543868475SJanosch Frank 
1643868475SJanosch Frank static uint8_t pagebuf[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
1743868475SJanosch Frank 
1843868475SJanosch Frank /* Fills all vector registers with data from addr */
vlm_all(unsigned long * addr)1943868475SJanosch Frank static inline void vlm_all(unsigned long *addr)
2043868475SJanosch Frank {
2143868475SJanosch Frank 	asm volatile(" .machine z13\n"
2243868475SJanosch Frank 		     " vlm 0, 15, %[a]\n"
2343868475SJanosch Frank 		     : : [a]  "Q" (*addr)
2443868475SJanosch Frank 		     :	"v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8",
2543868475SJanosch Frank 			"v9", "v10", "v11", "v12", "v13", "v14", "v15");
2643868475SJanosch Frank 	asm volatile(" .machine z13\n"
2743868475SJanosch Frank 		     " vlm 16, 31, %[a]\n"
2843868475SJanosch Frank 		     : : [a]  "Q" (*(addr+256/8))
2943868475SJanosch Frank 		     :	"v16", "v17", "v18", "v19", "v20", "v21", "v22",
3043868475SJanosch Frank 			"v23", "v24", "v25", "v26", "v27", "v28", "v29",
3143868475SJanosch Frank 			"v30", "v31");
3243868475SJanosch Frank }
3343868475SJanosch Frank 
test_add(void)3443868475SJanosch Frank static void test_add(void)
3543868475SJanosch Frank {
3643868475SJanosch Frank 	static struct prm {
3743868475SJanosch Frank 		__uint128_t a,b,c;
3843868475SJanosch Frank 	} prm __attribute__((aligned(16)));
3943868475SJanosch Frank 
4043868475SJanosch Frank 	prm.a = prm.b = prm.c = 21;
4143868475SJanosch Frank 
4243868475SJanosch Frank 	asm volatile(" .machine z13\n"
4343868475SJanosch Frank 		     " vl 0, %[v1]\n"
4443868475SJanosch Frank 		     " vl 1, %[v2]\n"
4543868475SJanosch Frank 		     " va 2, 0, 1, 4\n"
4643868475SJanosch Frank 		     " vst 2, %[v3]\n"
4743868475SJanosch Frank 		     : [v3]  "=Q" (prm.c)
4843868475SJanosch Frank 		     : [v1]  "Q" (prm.a), [v2]  "Q" (prm.b)
4943868475SJanosch Frank 		     : "v0", "v1", "v2", "memory");
50a299895bSThomas Huth 	report(prm.c == 42, "adding 21");
5143868475SJanosch Frank }
5243868475SJanosch Frank 
5343868475SJanosch Frank /* z14 vector extension test */
test_ext1_nand(void)5443868475SJanosch Frank static void test_ext1_nand(void)
5543868475SJanosch Frank {
567231778dSJanosch Frank 	bool has_vext = test_facility(135);
5743868475SJanosch Frank 	static struct prm {
5843868475SJanosch Frank 		__uint128_t a,b,c;
5943868475SJanosch Frank 	} prm __attribute__((aligned(16)));
6043868475SJanosch Frank 
6190016cc5SThomas Huth 	if (!has_vext) {
6290016cc5SThomas Huth 		report_skip("Vector extensions 1 is not available");
6343868475SJanosch Frank 		return;
6490016cc5SThomas Huth 	}
6543868475SJanosch Frank 
6643868475SJanosch Frank 	memset(&prm, 0xff, sizeof(prm));
6743868475SJanosch Frank 
6843868475SJanosch Frank 	asm volatile(" .machine z13\n"
6943868475SJanosch Frank 		     " vl 0, %[v1]\n"
7043868475SJanosch Frank 		     " vl 1, %[v2]\n"
7143868475SJanosch Frank 		     " .byte 0xe7, 0x20, 0x10, 0x00, 0x00, 0x6e\n" /* vnn */
7243868475SJanosch Frank 		     " vst 2, %[v3]\n"
7343868475SJanosch Frank 		     : [v3]  "=Q" (prm.c)
7443868475SJanosch Frank 		     : [v1]  "Q" (prm.a), [v2]  "Q" (prm.b)
7543868475SJanosch Frank 		     : "v0", "v1", "v2", "memory");
76a299895bSThomas Huth 	report(!prm.c, "nand ff");
7743868475SJanosch Frank }
7843868475SJanosch Frank 
7943868475SJanosch Frank /* z14 bcd extension test */
test_bcd_add(void)8043868475SJanosch Frank static void test_bcd_add(void)
8143868475SJanosch Frank {
827231778dSJanosch Frank 	bool has_bcd = test_facility(134);
8343868475SJanosch Frank 	static struct prm {
8443868475SJanosch Frank 		__uint128_t a,b,c;
8543868475SJanosch Frank 	} prm __attribute__((aligned(16)));
8643868475SJanosch Frank 
8790016cc5SThomas Huth 	if (!has_bcd) {
8890016cc5SThomas Huth 		report_skip("Vector BCD extensions is not available");
8943868475SJanosch Frank 		return;
9090016cc5SThomas Huth 	}
9143868475SJanosch Frank 
9243868475SJanosch Frank 	prm.c = 0;
9343868475SJanosch Frank 	prm.a = prm.b = 0b001000011100;
9443868475SJanosch Frank 
9543868475SJanosch Frank 	asm volatile(" .machine z13\n"
9643868475SJanosch Frank 		     " vl 0, %[v1]\n"
9743868475SJanosch Frank 		     " vl 1, %[v2]\n"
9843868475SJanosch Frank 		     " .byte 0xe6, 0x20, 0x10, 0x01, 0x00, 0x71\n" /* vap */
9943868475SJanosch Frank 		     " vst 2, %[v3]\n"
10043868475SJanosch Frank 		     : [v3]  "=Q" (prm.c)
10143868475SJanosch Frank 		     : [v1]  "Q" (prm.a), [v2]  "Q" (prm.b)
10243868475SJanosch Frank 		     : "v0", "v1", "v2", "memory");
103a299895bSThomas Huth 	report(prm.c == 0x42c, "bcd add 21");
10443868475SJanosch Frank }
10543868475SJanosch Frank 
init(void)10643868475SJanosch Frank static void init(void)
10743868475SJanosch Frank {
10843868475SJanosch Frank 	/* Enable vector instructions */
1091b2c0437SClaudio Imbrenda 	ctl_set_bit(0, CTL0_VECTOR);
11043868475SJanosch Frank 
11143868475SJanosch Frank 	/* Preset vector registers to 0xff */
11243868475SJanosch Frank 	memset(pagebuf, 0xff, PAGE_SIZE);
11343868475SJanosch Frank 	vlm_all((u64*)pagebuf);
11443868475SJanosch Frank }
11543868475SJanosch Frank 
main(void)11643868475SJanosch Frank int main(void)
11743868475SJanosch Frank {
11843868475SJanosch Frank 	bool has_vregs = test_facility(129);
11943868475SJanosch Frank 
12043868475SJanosch Frank 	report_prefix_push("vector");
12190016cc5SThomas Huth 	if (!has_vregs) {
12290016cc5SThomas Huth 		report_skip("Basic vector facility is not available");
12343868475SJanosch Frank 		goto done;
12490016cc5SThomas Huth 	}
12543868475SJanosch Frank 
12643868475SJanosch Frank 	init();
12743868475SJanosch Frank 	test_add();
12843868475SJanosch Frank 	test_ext1_nand();
12943868475SJanosch Frank 	test_bcd_add();
13043868475SJanosch Frank 
13143868475SJanosch Frank done:
13243868475SJanosch Frank 	report_prefix_pop();
13343868475SJanosch Frank 	return report_summary();
13443868475SJanosch Frank }
135