1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Get values of vector registers as soon as the program starts to test if
4  * is properly cleaning the values before starting a new program. Vector
5  * registers are caller saved, so no function calls may happen before reading
6  * the values. To further ensure consistency, this file is compiled without
7  * libc and without auto-vectorization.
8  *
9  * To be "clean" all values must be either all ones or all zeroes.
10  */
11 
12 #define __stringify_1(x...)	#x
13 #define __stringify(x...)	__stringify_1(x)
14 
main(int argc,char ** argv)15 int main(int argc, char **argv)
16 {
17 	char prev_value = 0, value;
18 	unsigned long vl;
19 	int first = 1;
20 
21 	if (argc > 2 && strcmp(argv[2], "x"))
22 		asm volatile (
23 			// 0 | zimm[10:0] | rs1 | 1 1 1 | rd |1010111| vsetvli
24 			// vsetvli	t4, x0, e8, m1, d1
25 			".4byte		0b00000000000000000111111011010111\n\t"
26 			"mv		%[vl], t4\n\t"
27 			: [vl] "=r" (vl) : : "t4"
28 		);
29 	else
30 		asm volatile (
31 			".option push\n\t"
32 			".option arch, +v\n\t"
33 			"vsetvli	%[vl], x0, e8, m1, ta, ma\n\t"
34 			".option pop\n\t"
35 			: [vl] "=r" (vl)
36 		);
37 
38 #define CHECK_VECTOR_REGISTER(register) ({					\
39 	for (int i = 0; i < vl; i++) {						\
40 		asm volatile (							\
41 			".option push\n\t"					\
42 			".option arch, +v\n\t"					\
43 			"vmv.x.s %0, " __stringify(register) "\n\t"		\
44 			"vsrl.vi " __stringify(register) ", " __stringify(register) ", 8\n\t" \
45 			".option pop\n\t"					\
46 			: "=r" (value));					\
47 		if (first) {							\
48 			first = 0;						\
49 		} else if (value != prev_value || !(value == 0x00 || value == 0xff)) { \
50 			printf("Register " __stringify(register)		\
51 				" values not clean! value: %u\n", value);	\
52 			exit(-1);						\
53 		}								\
54 		prev_value = value;						\
55 	}									\
56 })
57 
58 	CHECK_VECTOR_REGISTER(v0);
59 	CHECK_VECTOR_REGISTER(v1);
60 	CHECK_VECTOR_REGISTER(v2);
61 	CHECK_VECTOR_REGISTER(v3);
62 	CHECK_VECTOR_REGISTER(v4);
63 	CHECK_VECTOR_REGISTER(v5);
64 	CHECK_VECTOR_REGISTER(v6);
65 	CHECK_VECTOR_REGISTER(v7);
66 	CHECK_VECTOR_REGISTER(v8);
67 	CHECK_VECTOR_REGISTER(v9);
68 	CHECK_VECTOR_REGISTER(v10);
69 	CHECK_VECTOR_REGISTER(v11);
70 	CHECK_VECTOR_REGISTER(v12);
71 	CHECK_VECTOR_REGISTER(v13);
72 	CHECK_VECTOR_REGISTER(v14);
73 	CHECK_VECTOR_REGISTER(v15);
74 	CHECK_VECTOR_REGISTER(v16);
75 	CHECK_VECTOR_REGISTER(v17);
76 	CHECK_VECTOR_REGISTER(v18);
77 	CHECK_VECTOR_REGISTER(v19);
78 	CHECK_VECTOR_REGISTER(v20);
79 	CHECK_VECTOR_REGISTER(v21);
80 	CHECK_VECTOR_REGISTER(v22);
81 	CHECK_VECTOR_REGISTER(v23);
82 	CHECK_VECTOR_REGISTER(v24);
83 	CHECK_VECTOR_REGISTER(v25);
84 	CHECK_VECTOR_REGISTER(v26);
85 	CHECK_VECTOR_REGISTER(v27);
86 	CHECK_VECTOR_REGISTER(v28);
87 	CHECK_VECTOR_REGISTER(v29);
88 	CHECK_VECTOR_REGISTER(v30);
89 	CHECK_VECTOR_REGISTER(v31);
90 
91 #undef CHECK_VECTOR_REGISTER
92 
93 	return 0;
94 }
95