blob: f9de69a04e88d85fc707231e5eb8641384cc1b08 [file] [log] [blame]
Anton Blanchardef1313d2013-10-14 21:03:58 +11001/*
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 */
Daniel Axtens8fe08882016-04-26 23:49:09 +100020
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__)
Anton Blanchardef1313d2013-10-14 21:03:58 +110026#include <altivec.h>
Daniel Axtens8fe08882016-04-26 23:49:09 +100027#else
28#define vec_xor(a, b) a ^ b
29#define vector __attribute__((vector_size(16)))
30#endif
Anton Blanchardef1313d2013-10-14 21:03:58 +110031
32#include <linux/preempt.h>
33#include <linux/export.h>
34#include <linux/sched.h>
35#include <asm/switch_to.h>
36
37typedef vector signed char unative_t;
38
39#define DEFINE(V) \
40 unative_t *V = (unative_t *)V##_in; \
41 unative_t V##_0, V##_1, V##_2, V##_3
42
43#define LOAD(V) \
44 do { \
45 V##_0 = V[0]; \
46 V##_1 = V[1]; \
47 V##_2 = V[2]; \
48 V##_3 = V[3]; \
49 } while (0)
50
51#define STORE(V) \
52 do { \
53 V[0] = V##_0; \
54 V[1] = V##_1; \
55 V[2] = V##_2; \
56 V[3] = V##_3; \
57 } while (0)
58
59#define XOR(V1, V2) \
60 do { \
61 V1##_0 = vec_xor(V1##_0, V2##_0); \
62 V1##_1 = vec_xor(V1##_1, V2##_1); \
63 V1##_2 = vec_xor(V1##_2, V2##_2); \
64 V1##_3 = vec_xor(V1##_3, V2##_3); \
65 } while (0)
66
67void xor_altivec_2(unsigned long bytes, unsigned long *v1_in,
68 unsigned long *v2_in)
69{
70 DEFINE(v1);
71 DEFINE(v2);
72 unsigned long lines = bytes / (sizeof(unative_t)) / 4;
73
74 preempt_disable();
75 enable_kernel_altivec();
76
77 do {
78 LOAD(v1);
79 LOAD(v2);
80 XOR(v1, v2);
81 STORE(v1);
82
83 v1 += 4;
84 v2 += 4;
85 } while (--lines > 0);
86
Anton Blancharddc4fbba2015-10-29 11:44:05 +110087 disable_kernel_altivec();
Anton Blanchardef1313d2013-10-14 21:03:58 +110088 preempt_enable();
89}
90EXPORT_SYMBOL(xor_altivec_2);
91
92void xor_altivec_3(unsigned long bytes, unsigned long *v1_in,
93 unsigned long *v2_in, unsigned long *v3_in)
94{
95 DEFINE(v1);
96 DEFINE(v2);
97 DEFINE(v3);
98 unsigned long lines = bytes / (sizeof(unative_t)) / 4;
99
100 preempt_disable();
101 enable_kernel_altivec();
102
103 do {
104 LOAD(v1);
105 LOAD(v2);
106 LOAD(v3);
107 XOR(v1, v2);
108 XOR(v1, v3);
109 STORE(v1);
110
111 v1 += 4;
112 v2 += 4;
113 v3 += 4;
114 } while (--lines > 0);
115
Anton Blancharddc4fbba2015-10-29 11:44:05 +1100116 disable_kernel_altivec();
Anton Blanchardef1313d2013-10-14 21:03:58 +1100117 preempt_enable();
118}
119EXPORT_SYMBOL(xor_altivec_3);
120
121void xor_altivec_4(unsigned long bytes, unsigned long *v1_in,
122 unsigned long *v2_in, unsigned long *v3_in,
123 unsigned long *v4_in)
124{
125 DEFINE(v1);
126 DEFINE(v2);
127 DEFINE(v3);
128 DEFINE(v4);
129 unsigned long lines = bytes / (sizeof(unative_t)) / 4;
130
131 preempt_disable();
132 enable_kernel_altivec();
133
134 do {
135 LOAD(v1);
136 LOAD(v2);
137 LOAD(v3);
138 LOAD(v4);
139 XOR(v1, v2);
140 XOR(v3, v4);
141 XOR(v1, v3);
142 STORE(v1);
143
144 v1 += 4;
145 v2 += 4;
146 v3 += 4;
147 v4 += 4;
148 } while (--lines > 0);
149
Anton Blancharddc4fbba2015-10-29 11:44:05 +1100150 disable_kernel_altivec();
Anton Blanchardef1313d2013-10-14 21:03:58 +1100151 preempt_enable();
152}
153EXPORT_SYMBOL(xor_altivec_4);
154
155void xor_altivec_5(unsigned long bytes, unsigned long *v1_in,
156 unsigned long *v2_in, unsigned long *v3_in,
157 unsigned long *v4_in, unsigned long *v5_in)
158{
159 DEFINE(v1);
160 DEFINE(v2);
161 DEFINE(v3);
162 DEFINE(v4);
163 DEFINE(v5);
164 unsigned long lines = bytes / (sizeof(unative_t)) / 4;
165
166 preempt_disable();
167 enable_kernel_altivec();
168
169 do {
170 LOAD(v1);
171 LOAD(v2);
172 LOAD(v3);
173 LOAD(v4);
174 LOAD(v5);
175 XOR(v1, v2);
176 XOR(v3, v4);
177 XOR(v1, v5);
178 XOR(v1, v3);
179 STORE(v1);
180
181 v1 += 4;
182 v2 += 4;
183 v3 += 4;
184 v4 += 4;
185 v5 += 4;
186 } while (--lines > 0);
187
Anton Blancharddc4fbba2015-10-29 11:44:05 +1100188 disable_kernel_altivec();
Anton Blanchardef1313d2013-10-14 21:03:58 +1100189 preempt_enable();
190}
191EXPORT_SYMBOL(xor_altivec_5);