xref: /openbmc/linux/arch/powerpc/lib/xor_vmx.c (revision a44d924c)
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 2 of the License, or
5  * (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15  *
16  * Copyright (C) IBM Corporation, 2012
17  *
18  * Author: Anton Blanchard <anton@au.ibm.com>
19  */
20 
21 /*
22  * Sparse (as at v0.5.0) gets very, very confused by this file.
23  * Make it a bit simpler for it.
24  */
25 #if !defined(__CHECKER__)
26 #include <altivec.h>
27 #else
28 #define vec_xor(a, b) a ^ b
29 #define vector __attribute__((vector_size(16)))
30 #endif
31 
32 #include "xor_vmx.h"
33 
34 typedef vector signed char unative_t;
35 
36 #define DEFINE(V)				\
37 	unative_t *V = (unative_t *)V##_in;	\
38 	unative_t V##_0, V##_1, V##_2, V##_3
39 
40 #define LOAD(V)			\
41 	do {			\
42 		V##_0 = V[0];	\
43 		V##_1 = V[1];	\
44 		V##_2 = V[2];	\
45 		V##_3 = V[3];	\
46 	} while (0)
47 
48 #define STORE(V)		\
49 	do {			\
50 		V[0] = V##_0;	\
51 		V[1] = V##_1;	\
52 		V[2] = V##_2;	\
53 		V[3] = V##_3;	\
54 	} while (0)
55 
56 #define XOR(V1, V2)					\
57 	do {						\
58 		V1##_0 = vec_xor(V1##_0, V2##_0);	\
59 		V1##_1 = vec_xor(V1##_1, V2##_1);	\
60 		V1##_2 = vec_xor(V1##_2, V2##_2);	\
61 		V1##_3 = vec_xor(V1##_3, V2##_3);	\
62 	} while (0)
63 
64 void __xor_altivec_2(unsigned long bytes, unsigned long *v1_in,
65 		     unsigned long *v2_in)
66 {
67 	DEFINE(v1);
68 	DEFINE(v2);
69 	unsigned long lines = bytes / (sizeof(unative_t)) / 4;
70 
71 	do {
72 		LOAD(v1);
73 		LOAD(v2);
74 		XOR(v1, v2);
75 		STORE(v1);
76 
77 		v1 += 4;
78 		v2 += 4;
79 	} while (--lines > 0);
80 }
81 
82 void __xor_altivec_3(unsigned long bytes, unsigned long *v1_in,
83 		     unsigned long *v2_in, unsigned long *v3_in)
84 {
85 	DEFINE(v1);
86 	DEFINE(v2);
87 	DEFINE(v3);
88 	unsigned long lines = bytes / (sizeof(unative_t)) / 4;
89 
90 	do {
91 		LOAD(v1);
92 		LOAD(v2);
93 		LOAD(v3);
94 		XOR(v1, v2);
95 		XOR(v1, v3);
96 		STORE(v1);
97 
98 		v1 += 4;
99 		v2 += 4;
100 		v3 += 4;
101 	} while (--lines > 0);
102 }
103 
104 void __xor_altivec_4(unsigned long bytes, unsigned long *v1_in,
105 		     unsigned long *v2_in, unsigned long *v3_in,
106 		     unsigned long *v4_in)
107 {
108 	DEFINE(v1);
109 	DEFINE(v2);
110 	DEFINE(v3);
111 	DEFINE(v4);
112 	unsigned long lines = bytes / (sizeof(unative_t)) / 4;
113 
114 	do {
115 		LOAD(v1);
116 		LOAD(v2);
117 		LOAD(v3);
118 		LOAD(v4);
119 		XOR(v1, v2);
120 		XOR(v3, v4);
121 		XOR(v1, v3);
122 		STORE(v1);
123 
124 		v1 += 4;
125 		v2 += 4;
126 		v3 += 4;
127 		v4 += 4;
128 	} while (--lines > 0);
129 }
130 
131 void __xor_altivec_5(unsigned long bytes, unsigned long *v1_in,
132 		     unsigned long *v2_in, unsigned long *v3_in,
133 		     unsigned long *v4_in, unsigned long *v5_in)
134 {
135 	DEFINE(v1);
136 	DEFINE(v2);
137 	DEFINE(v3);
138 	DEFINE(v4);
139 	DEFINE(v5);
140 	unsigned long lines = bytes / (sizeof(unative_t)) / 4;
141 
142 	do {
143 		LOAD(v1);
144 		LOAD(v2);
145 		LOAD(v3);
146 		LOAD(v4);
147 		LOAD(v5);
148 		XOR(v1, v2);
149 		XOR(v3, v4);
150 		XOR(v1, v5);
151 		XOR(v1, v3);
152 		STORE(v1);
153 
154 		v1 += 4;
155 		v2 += 4;
156 		v3 += 4;
157 		v4 += 4;
158 		v5 += 4;
159 	} while (--lines > 0);
160 }
161