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