xref: /kvm-unit-tests/s390x/vector.c (revision 43868475663e4fddcf9ec9e2c63f30aa80c87395)
1*43868475SJanosch Frank /*
2*43868475SJanosch Frank  * Tests vector instruction support
3*43868475SJanosch Frank  *
4*43868475SJanosch Frank  * Copyright 2018 IBM Corp.
5*43868475SJanosch Frank  *
6*43868475SJanosch Frank  * Authors:
7*43868475SJanosch Frank  *    Janosch Frank <frankja@de.ibm.com>
8*43868475SJanosch Frank  *
9*43868475SJanosch Frank  * This code is free software; you can redistribute it and/or modify it
10*43868475SJanosch Frank  * under the terms of the GNU Library General Public License version 2.
11*43868475SJanosch Frank  */
12*43868475SJanosch Frank #include <libcflat.h>
13*43868475SJanosch Frank #include <asm/page.h>
14*43868475SJanosch Frank #include <asm/facility.h>
15*43868475SJanosch Frank #include <asm/interrupt.h>
16*43868475SJanosch Frank #include <asm-generic/barrier.h>
17*43868475SJanosch Frank 
18*43868475SJanosch Frank static uint8_t pagebuf[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
19*43868475SJanosch Frank 
20*43868475SJanosch Frank /* Fills all vector registers with data from addr */
21*43868475SJanosch Frank static inline void vlm_all(unsigned long *addr)
22*43868475SJanosch Frank {
23*43868475SJanosch Frank 	asm volatile(" .machine z13\n"
24*43868475SJanosch Frank 		     " vlm 0, 15, %[a]\n"
25*43868475SJanosch Frank 		     : : [a]  "Q" (*addr)
26*43868475SJanosch Frank 		     :	"v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8",
27*43868475SJanosch Frank 			"v9", "v10", "v11", "v12", "v13", "v14", "v15");
28*43868475SJanosch Frank 	asm volatile(" .machine z13\n"
29*43868475SJanosch Frank 		     " vlm 16, 31, %[a]\n"
30*43868475SJanosch Frank 		     : : [a]  "Q" (*(addr+256/8))
31*43868475SJanosch Frank 		     :	"v16", "v17", "v18", "v19", "v20", "v21", "v22",
32*43868475SJanosch Frank 			"v23", "v24", "v25", "v26", "v27", "v28", "v29",
33*43868475SJanosch Frank 			"v30", "v31");
34*43868475SJanosch Frank }
35*43868475SJanosch Frank 
36*43868475SJanosch Frank static void test_add(void)
37*43868475SJanosch Frank {
38*43868475SJanosch Frank 	static struct prm {
39*43868475SJanosch Frank 		__uint128_t a,b,c;
40*43868475SJanosch Frank 	} prm __attribute__((aligned(16)));
41*43868475SJanosch Frank 
42*43868475SJanosch Frank 	prm.a = prm.b = prm.c = 21;
43*43868475SJanosch Frank 
44*43868475SJanosch Frank 	asm volatile(" .machine z13\n"
45*43868475SJanosch Frank 		     " vl 0, %[v1]\n"
46*43868475SJanosch Frank 		     " vl 1, %[v2]\n"
47*43868475SJanosch Frank 		     " va 2, 0, 1, 4\n"
48*43868475SJanosch Frank 		     " vst 2, %[v3]\n"
49*43868475SJanosch Frank 		     : [v3]  "=Q" (prm.c)
50*43868475SJanosch Frank 		     : [v1]  "Q" (prm.a), [v2]  "Q" (prm.b)
51*43868475SJanosch Frank 		     : "v0", "v1", "v2", "memory");
52*43868475SJanosch Frank 	report("adding 21", prm.c == 42);
53*43868475SJanosch Frank }
54*43868475SJanosch Frank 
55*43868475SJanosch Frank /* z14 vector extension test */
56*43868475SJanosch Frank static void test_ext1_nand(void)
57*43868475SJanosch Frank {
58*43868475SJanosch Frank 	bool has_vext = test_facility(134);
59*43868475SJanosch Frank 	static struct prm {
60*43868475SJanosch Frank 		__uint128_t a,b,c;
61*43868475SJanosch Frank 	} prm __attribute__((aligned(16)));
62*43868475SJanosch Frank 
63*43868475SJanosch Frank 	report_xfail("Vector extensions 1 available", !has_vext, has_vext);
64*43868475SJanosch Frank 	if (!has_vext)
65*43868475SJanosch Frank 		return;
66*43868475SJanosch Frank 
67*43868475SJanosch Frank 	memset(&prm, 0xff, sizeof(prm));
68*43868475SJanosch Frank 
69*43868475SJanosch Frank 	asm volatile(" .machine z13\n"
70*43868475SJanosch Frank 		     " vl 0, %[v1]\n"
71*43868475SJanosch Frank 		     " vl 1, %[v2]\n"
72*43868475SJanosch Frank 		     " .byte 0xe7, 0x20, 0x10, 0x00, 0x00, 0x6e\n" /* vnn */
73*43868475SJanosch Frank 		     " vst 2, %[v3]\n"
74*43868475SJanosch Frank 		     : [v3]  "=Q" (prm.c)
75*43868475SJanosch Frank 		     : [v1]  "Q" (prm.a), [v2]  "Q" (prm.b)
76*43868475SJanosch Frank 		     : "v0", "v1", "v2", "memory");
77*43868475SJanosch Frank 	report("nand ff", !prm.c);
78*43868475SJanosch Frank }
79*43868475SJanosch Frank 
80*43868475SJanosch Frank /* z14 bcd extension test */
81*43868475SJanosch Frank static void test_bcd_add(void)
82*43868475SJanosch Frank {
83*43868475SJanosch Frank 	bool has_bcd = test_facility(135);
84*43868475SJanosch Frank 	static struct prm {
85*43868475SJanosch Frank 		__uint128_t a,b,c;
86*43868475SJanosch Frank 	} prm __attribute__((aligned(16)));
87*43868475SJanosch Frank 
88*43868475SJanosch Frank 	report_xfail("Vector BCD extensions available", !has_bcd, has_bcd);
89*43868475SJanosch Frank 	if (!has_bcd)
90*43868475SJanosch Frank 		return;
91*43868475SJanosch Frank 
92*43868475SJanosch Frank 	prm.c = 0;
93*43868475SJanosch Frank 	prm.a = prm.b = 0b001000011100;
94*43868475SJanosch Frank 
95*43868475SJanosch Frank 	asm volatile(" .machine z13\n"
96*43868475SJanosch Frank 		     " vl 0, %[v1]\n"
97*43868475SJanosch Frank 		     " vl 1, %[v2]\n"
98*43868475SJanosch Frank 		     " .byte 0xe6, 0x20, 0x10, 0x01, 0x00, 0x71\n" /* vap */
99*43868475SJanosch Frank 		     " vst 2, %[v3]\n"
100*43868475SJanosch Frank 		     : [v3]  "=Q" (prm.c)
101*43868475SJanosch Frank 		     : [v1]  "Q" (prm.a), [v2]  "Q" (prm.b)
102*43868475SJanosch Frank 		     : "v0", "v1", "v2", "memory");
103*43868475SJanosch Frank 	report("bcd add 21", prm.c == 0x42c);
104*43868475SJanosch Frank }
105*43868475SJanosch Frank 
106*43868475SJanosch Frank static void init(void)
107*43868475SJanosch Frank {
108*43868475SJanosch Frank 	/* Enable vector instructions */
109*43868475SJanosch Frank 	ctl_set_bit(0, 17);
110*43868475SJanosch Frank 
111*43868475SJanosch Frank 	/* Preset vector registers to 0xff */
112*43868475SJanosch Frank 	memset(pagebuf, 0xff, PAGE_SIZE);
113*43868475SJanosch Frank 	vlm_all((u64*)pagebuf);
114*43868475SJanosch Frank }
115*43868475SJanosch Frank 
116*43868475SJanosch Frank int main(void)
117*43868475SJanosch Frank {
118*43868475SJanosch Frank 	bool has_vregs = test_facility(129);
119*43868475SJanosch Frank 
120*43868475SJanosch Frank 	report_prefix_push("vector");
121*43868475SJanosch Frank 	report_xfail("Basic vector facility available", !has_vregs, has_vregs);
122*43868475SJanosch Frank 	if (!has_vregs)
123*43868475SJanosch Frank 		goto done;
124*43868475SJanosch Frank 
125*43868475SJanosch Frank 	init();
126*43868475SJanosch Frank 	test_add();
127*43868475SJanosch Frank 	test_ext1_nand();
128*43868475SJanosch Frank 	test_bcd_add();
129*43868475SJanosch Frank 
130*43868475SJanosch Frank done:
131*43868475SJanosch Frank 	report_prefix_pop();
132*43868475SJanosch Frank 	return report_summary();
133*43868475SJanosch Frank }
134