xref: /linux/arch/powerpc/lib/xor_vmx.c (revision 8c749ce93ee69e789e46b3be98de9e0cbfcf8ed8)
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 #include <altivec.h>
21 
22 #include <linux/preempt.h>
23 #include <linux/export.h>
24 #include <linux/sched.h>
25 #include <asm/switch_to.h>
26 
27 typedef vector signed char unative_t;
28 
29 #define DEFINE(V)				\
30 	unative_t *V = (unative_t *)V##_in;	\
31 	unative_t V##_0, V##_1, V##_2, V##_3
32 
33 #define LOAD(V)			\
34 	do {			\
35 		V##_0 = V[0];	\
36 		V##_1 = V[1];	\
37 		V##_2 = V[2];	\
38 		V##_3 = V[3];	\
39 	} while (0)
40 
41 #define STORE(V)		\
42 	do {			\
43 		V[0] = V##_0;	\
44 		V[1] = V##_1;	\
45 		V[2] = V##_2;	\
46 		V[3] = V##_3;	\
47 	} while (0)
48 
49 #define XOR(V1, V2)					\
50 	do {						\
51 		V1##_0 = vec_xor(V1##_0, V2##_0);	\
52 		V1##_1 = vec_xor(V1##_1, V2##_1);	\
53 		V1##_2 = vec_xor(V1##_2, V2##_2);	\
54 		V1##_3 = vec_xor(V1##_3, V2##_3);	\
55 	} while (0)
56 
57 void xor_altivec_2(unsigned long bytes, unsigned long *v1_in,
58 		   unsigned long *v2_in)
59 {
60 	DEFINE(v1);
61 	DEFINE(v2);
62 	unsigned long lines = bytes / (sizeof(unative_t)) / 4;
63 
64 	preempt_disable();
65 	enable_kernel_altivec();
66 
67 	do {
68 		LOAD(v1);
69 		LOAD(v2);
70 		XOR(v1, v2);
71 		STORE(v1);
72 
73 		v1 += 4;
74 		v2 += 4;
75 	} while (--lines > 0);
76 
77 	disable_kernel_altivec();
78 	preempt_enable();
79 }
80 EXPORT_SYMBOL(xor_altivec_2);
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 	preempt_disable();
91 	enable_kernel_altivec();
92 
93 	do {
94 		LOAD(v1);
95 		LOAD(v2);
96 		LOAD(v3);
97 		XOR(v1, v2);
98 		XOR(v1, v3);
99 		STORE(v1);
100 
101 		v1 += 4;
102 		v2 += 4;
103 		v3 += 4;
104 	} while (--lines > 0);
105 
106 	disable_kernel_altivec();
107 	preempt_enable();
108 }
109 EXPORT_SYMBOL(xor_altivec_3);
110 
111 void xor_altivec_4(unsigned long bytes, unsigned long *v1_in,
112 		   unsigned long *v2_in, unsigned long *v3_in,
113 		   unsigned long *v4_in)
114 {
115 	DEFINE(v1);
116 	DEFINE(v2);
117 	DEFINE(v3);
118 	DEFINE(v4);
119 	unsigned long lines = bytes / (sizeof(unative_t)) / 4;
120 
121 	preempt_disable();
122 	enable_kernel_altivec();
123 
124 	do {
125 		LOAD(v1);
126 		LOAD(v2);
127 		LOAD(v3);
128 		LOAD(v4);
129 		XOR(v1, v2);
130 		XOR(v3, v4);
131 		XOR(v1, v3);
132 		STORE(v1);
133 
134 		v1 += 4;
135 		v2 += 4;
136 		v3 += 4;
137 		v4 += 4;
138 	} while (--lines > 0);
139 
140 	disable_kernel_altivec();
141 	preempt_enable();
142 }
143 EXPORT_SYMBOL(xor_altivec_4);
144 
145 void xor_altivec_5(unsigned long bytes, unsigned long *v1_in,
146 		   unsigned long *v2_in, unsigned long *v3_in,
147 		   unsigned long *v4_in, unsigned long *v5_in)
148 {
149 	DEFINE(v1);
150 	DEFINE(v2);
151 	DEFINE(v3);
152 	DEFINE(v4);
153 	DEFINE(v5);
154 	unsigned long lines = bytes / (sizeof(unative_t)) / 4;
155 
156 	preempt_disable();
157 	enable_kernel_altivec();
158 
159 	do {
160 		LOAD(v1);
161 		LOAD(v2);
162 		LOAD(v3);
163 		LOAD(v4);
164 		LOAD(v5);
165 		XOR(v1, v2);
166 		XOR(v3, v4);
167 		XOR(v1, v5);
168 		XOR(v1, v3);
169 		STORE(v1);
170 
171 		v1 += 4;
172 		v2 += 4;
173 		v3 += 4;
174 		v4 += 4;
175 		v5 += 4;
176 	} while (--lines > 0);
177 
178 	disable_kernel_altivec();
179 	preempt_enable();
180 }
181 EXPORT_SYMBOL(xor_altivec_5);
182