xref: /linux/lib/raid/xor/loongarch/xor_template.c (revision 440d6635b20037bc9ad46b20817d7b61cef0fc1b)
1*033bee3eSChristoph Hellwig // SPDX-License-Identifier: GPL-2.0-or-later
2*033bee3eSChristoph Hellwig /*
3*033bee3eSChristoph Hellwig  * Copyright (C) 2023 WANG Xuerui <git@xen0n.name>
4*033bee3eSChristoph Hellwig  *
5*033bee3eSChristoph Hellwig  * Template for XOR operations, instantiated in xor_simd.c.
6*033bee3eSChristoph Hellwig  *
7*033bee3eSChristoph Hellwig  * Expected preprocessor definitions:
8*033bee3eSChristoph Hellwig  *
9*033bee3eSChristoph Hellwig  * - LINE_WIDTH
10*033bee3eSChristoph Hellwig  * - XOR_FUNC_NAME(nr)
11*033bee3eSChristoph Hellwig  * - LD_INOUT_LINE(buf)
12*033bee3eSChristoph Hellwig  * - LD_AND_XOR_LINE(buf)
13*033bee3eSChristoph Hellwig  * - ST_LINE(buf)
14*033bee3eSChristoph Hellwig  */
15*033bee3eSChristoph Hellwig 
16*033bee3eSChristoph Hellwig void XOR_FUNC_NAME(2)(unsigned long bytes,
17*033bee3eSChristoph Hellwig 		      unsigned long * __restrict v1,
18*033bee3eSChristoph Hellwig 		      const unsigned long * __restrict v2)
19*033bee3eSChristoph Hellwig {
20*033bee3eSChristoph Hellwig 	unsigned long lines = bytes / LINE_WIDTH;
21*033bee3eSChristoph Hellwig 
22*033bee3eSChristoph Hellwig 	do {
23*033bee3eSChristoph Hellwig 		__asm__ __volatile__ (
24*033bee3eSChristoph Hellwig 			LD_INOUT_LINE(v1)
25*033bee3eSChristoph Hellwig 			LD_AND_XOR_LINE(v2)
26*033bee3eSChristoph Hellwig 			ST_LINE(v1)
27*033bee3eSChristoph Hellwig 		: : [v1] "r"(v1), [v2] "r"(v2) : "memory"
28*033bee3eSChristoph Hellwig 		);
29*033bee3eSChristoph Hellwig 
30*033bee3eSChristoph Hellwig 		v1 += LINE_WIDTH / sizeof(unsigned long);
31*033bee3eSChristoph Hellwig 		v2 += LINE_WIDTH / sizeof(unsigned long);
32*033bee3eSChristoph Hellwig 	} while (--lines > 0);
33*033bee3eSChristoph Hellwig }
34*033bee3eSChristoph Hellwig 
35*033bee3eSChristoph Hellwig void XOR_FUNC_NAME(3)(unsigned long bytes,
36*033bee3eSChristoph Hellwig 		      unsigned long * __restrict v1,
37*033bee3eSChristoph Hellwig 		      const unsigned long * __restrict v2,
38*033bee3eSChristoph Hellwig 		      const unsigned long * __restrict v3)
39*033bee3eSChristoph Hellwig {
40*033bee3eSChristoph Hellwig 	unsigned long lines = bytes / LINE_WIDTH;
41*033bee3eSChristoph Hellwig 
42*033bee3eSChristoph Hellwig 	do {
43*033bee3eSChristoph Hellwig 		__asm__ __volatile__ (
44*033bee3eSChristoph Hellwig 			LD_INOUT_LINE(v1)
45*033bee3eSChristoph Hellwig 			LD_AND_XOR_LINE(v2)
46*033bee3eSChristoph Hellwig 			LD_AND_XOR_LINE(v3)
47*033bee3eSChristoph Hellwig 			ST_LINE(v1)
48*033bee3eSChristoph Hellwig 		: : [v1] "r"(v1), [v2] "r"(v2), [v3] "r"(v3) : "memory"
49*033bee3eSChristoph Hellwig 		);
50*033bee3eSChristoph Hellwig 
51*033bee3eSChristoph Hellwig 		v1 += LINE_WIDTH / sizeof(unsigned long);
52*033bee3eSChristoph Hellwig 		v2 += LINE_WIDTH / sizeof(unsigned long);
53*033bee3eSChristoph Hellwig 		v3 += LINE_WIDTH / sizeof(unsigned long);
54*033bee3eSChristoph Hellwig 	} while (--lines > 0);
55*033bee3eSChristoph Hellwig }
56*033bee3eSChristoph Hellwig 
57*033bee3eSChristoph Hellwig void XOR_FUNC_NAME(4)(unsigned long bytes,
58*033bee3eSChristoph Hellwig 		      unsigned long * __restrict v1,
59*033bee3eSChristoph Hellwig 		      const unsigned long * __restrict v2,
60*033bee3eSChristoph Hellwig 		      const unsigned long * __restrict v3,
61*033bee3eSChristoph Hellwig 		      const unsigned long * __restrict v4)
62*033bee3eSChristoph Hellwig {
63*033bee3eSChristoph Hellwig 	unsigned long lines = bytes / LINE_WIDTH;
64*033bee3eSChristoph Hellwig 
65*033bee3eSChristoph Hellwig 	do {
66*033bee3eSChristoph Hellwig 		__asm__ __volatile__ (
67*033bee3eSChristoph Hellwig 			LD_INOUT_LINE(v1)
68*033bee3eSChristoph Hellwig 			LD_AND_XOR_LINE(v2)
69*033bee3eSChristoph Hellwig 			LD_AND_XOR_LINE(v3)
70*033bee3eSChristoph Hellwig 			LD_AND_XOR_LINE(v4)
71*033bee3eSChristoph Hellwig 			ST_LINE(v1)
72*033bee3eSChristoph Hellwig 		: : [v1] "r"(v1), [v2] "r"(v2), [v3] "r"(v3), [v4] "r"(v4)
73*033bee3eSChristoph Hellwig 		: "memory"
74*033bee3eSChristoph Hellwig 		);
75*033bee3eSChristoph Hellwig 
76*033bee3eSChristoph Hellwig 		v1 += LINE_WIDTH / sizeof(unsigned long);
77*033bee3eSChristoph Hellwig 		v2 += LINE_WIDTH / sizeof(unsigned long);
78*033bee3eSChristoph Hellwig 		v3 += LINE_WIDTH / sizeof(unsigned long);
79*033bee3eSChristoph Hellwig 		v4 += LINE_WIDTH / sizeof(unsigned long);
80*033bee3eSChristoph Hellwig 	} while (--lines > 0);
81*033bee3eSChristoph Hellwig }
82*033bee3eSChristoph Hellwig 
83*033bee3eSChristoph Hellwig void XOR_FUNC_NAME(5)(unsigned long bytes,
84*033bee3eSChristoph Hellwig 		      unsigned long * __restrict v1,
85*033bee3eSChristoph Hellwig 		      const unsigned long * __restrict v2,
86*033bee3eSChristoph Hellwig 		      const unsigned long * __restrict v3,
87*033bee3eSChristoph Hellwig 		      const unsigned long * __restrict v4,
88*033bee3eSChristoph Hellwig 		      const unsigned long * __restrict v5)
89*033bee3eSChristoph Hellwig {
90*033bee3eSChristoph Hellwig 	unsigned long lines = bytes / LINE_WIDTH;
91*033bee3eSChristoph Hellwig 
92*033bee3eSChristoph Hellwig 	do {
93*033bee3eSChristoph Hellwig 		__asm__ __volatile__ (
94*033bee3eSChristoph Hellwig 			LD_INOUT_LINE(v1)
95*033bee3eSChristoph Hellwig 			LD_AND_XOR_LINE(v2)
96*033bee3eSChristoph Hellwig 			LD_AND_XOR_LINE(v3)
97*033bee3eSChristoph Hellwig 			LD_AND_XOR_LINE(v4)
98*033bee3eSChristoph Hellwig 			LD_AND_XOR_LINE(v5)
99*033bee3eSChristoph Hellwig 			ST_LINE(v1)
100*033bee3eSChristoph Hellwig 		: : [v1] "r"(v1), [v2] "r"(v2), [v3] "r"(v3), [v4] "r"(v4),
101*033bee3eSChristoph Hellwig 		    [v5] "r"(v5) : "memory"
102*033bee3eSChristoph Hellwig 		);
103*033bee3eSChristoph Hellwig 
104*033bee3eSChristoph Hellwig 		v1 += LINE_WIDTH / sizeof(unsigned long);
105*033bee3eSChristoph Hellwig 		v2 += LINE_WIDTH / sizeof(unsigned long);
106*033bee3eSChristoph Hellwig 		v3 += LINE_WIDTH / sizeof(unsigned long);
107*033bee3eSChristoph Hellwig 		v4 += LINE_WIDTH / sizeof(unsigned long);
108*033bee3eSChristoph Hellwig 		v5 += LINE_WIDTH / sizeof(unsigned long);
109*033bee3eSChristoph Hellwig 	} while (--lines > 0);
110*033bee3eSChristoph Hellwig }
111