Merge tag 'topic/drm-misc-2016-02-08' of git://anongit.freedesktop.org/drm-intel...
[cascardo/linux.git] / arch / powerpc / lib / xor_vmx.c
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);