xref: /linux/arch/powerpc/lib/xor_vmx.c (revision ca55b2fef3a9373fcfc30f82fd26bc7fccbda732)
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 	preempt_enable();
78 }
79 EXPORT_SYMBOL(xor_altivec_2);
80 
81 void xor_altivec_3(unsigned long bytes, unsigned long *v1_in,
82 		   unsigned long *v2_in, unsigned long *v3_in)
83 {
84 	DEFINE(v1);
85 	DEFINE(v2);
86 	DEFINE(v3);
87 	unsigned long lines = bytes / (sizeof(unative_t)) / 4;
88 
89 	preempt_disable();
90 	enable_kernel_altivec();
91 
92 	do {
93 		LOAD(v1);
94 		LOAD(v2);
95 		LOAD(v3);
96 		XOR(v1, v2);
97 		XOR(v1, v3);
98 		STORE(v1);
99 
100 		v1 += 4;
101 		v2 += 4;
102 		v3 += 4;
103 	} while (--lines > 0);
104 
105 	preempt_enable();
106 }
107 EXPORT_SYMBOL(xor_altivec_3);
108 
109 void xor_altivec_4(unsigned long bytes, unsigned long *v1_in,
110 		   unsigned long *v2_in, unsigned long *v3_in,
111 		   unsigned long *v4_in)
112 {
113 	DEFINE(v1);
114 	DEFINE(v2);
115 	DEFINE(v3);
116 	DEFINE(v4);
117 	unsigned long lines = bytes / (sizeof(unative_t)) / 4;
118 
119 	preempt_disable();
120 	enable_kernel_altivec();
121 
122 	do {
123 		LOAD(v1);
124 		LOAD(v2);
125 		LOAD(v3);
126 		LOAD(v4);
127 		XOR(v1, v2);
128 		XOR(v3, v4);
129 		XOR(v1, v3);
130 		STORE(v1);
131 
132 		v1 += 4;
133 		v2 += 4;
134 		v3 += 4;
135 		v4 += 4;
136 	} while (--lines > 0);
137 
138 	preempt_enable();
139 }
140 EXPORT_SYMBOL(xor_altivec_4);
141 
142 void xor_altivec_5(unsigned long bytes, unsigned long *v1_in,
143 		   unsigned long *v2_in, unsigned long *v3_in,
144 		   unsigned long *v4_in, unsigned long *v5_in)
145 {
146 	DEFINE(v1);
147 	DEFINE(v2);
148 	DEFINE(v3);
149 	DEFINE(v4);
150 	DEFINE(v5);
151 	unsigned long lines = bytes / (sizeof(unative_t)) / 4;
152 
153 	preempt_disable();
154 	enable_kernel_altivec();
155 
156 	do {
157 		LOAD(v1);
158 		LOAD(v2);
159 		LOAD(v3);
160 		LOAD(v4);
161 		LOAD(v5);
162 		XOR(v1, v2);
163 		XOR(v3, v4);
164 		XOR(v1, v5);
165 		XOR(v1, v3);
166 		STORE(v1);
167 
168 		v1 += 4;
169 		v2 += 4;
170 		v3 += 4;
171 		v4 += 4;
172 		v5 += 4;
173 	} while (--lines > 0);
174 
175 	preempt_enable();
176 }
177 EXPORT_SYMBOL(xor_altivec_5);
178