xref: /linux/lib/raid/xor/powerpc/xor_vmx.c (revision 440d6635b20037bc9ad46b20817d7b61cef0fc1b)
13f276cecSChristoph Hellwig // SPDX-License-Identifier: GPL-2.0-or-later
23f276cecSChristoph Hellwig /*
33f276cecSChristoph Hellwig  *
43f276cecSChristoph Hellwig  * Copyright (C) IBM Corporation, 2012
53f276cecSChristoph Hellwig  *
63f276cecSChristoph Hellwig  * Author: Anton Blanchard <anton@au.ibm.com>
73f276cecSChristoph Hellwig  */
83f276cecSChristoph Hellwig 
93f276cecSChristoph Hellwig /*
103f276cecSChristoph Hellwig  * Sparse (as at v0.5.0) gets very, very confused by this file.
113f276cecSChristoph Hellwig  * Make it a bit simpler for it.
123f276cecSChristoph Hellwig  */
13*80dcf0a7SChristoph Hellwig #include "xor_impl.h"
143f276cecSChristoph Hellwig #if !defined(__CHECKER__)
153f276cecSChristoph Hellwig #include <altivec.h>
163f276cecSChristoph Hellwig #else
173f276cecSChristoph Hellwig #define vec_xor(a, b) a ^ b
183f276cecSChristoph Hellwig #define vector __attribute__((vector_size(16)))
193f276cecSChristoph Hellwig #endif
203f276cecSChristoph Hellwig 
213f276cecSChristoph Hellwig #include "xor_vmx.h"
223f276cecSChristoph Hellwig 
233f276cecSChristoph Hellwig typedef vector signed char unative_t;
243f276cecSChristoph Hellwig 
253f276cecSChristoph Hellwig #define DEFINE(V)				\
263f276cecSChristoph Hellwig 	unative_t *V = (unative_t *)V##_in;	\
273f276cecSChristoph Hellwig 	unative_t V##_0, V##_1, V##_2, V##_3
283f276cecSChristoph Hellwig 
293f276cecSChristoph Hellwig #define LOAD(V)			\
303f276cecSChristoph Hellwig 	do {			\
313f276cecSChristoph Hellwig 		V##_0 = V[0];	\
323f276cecSChristoph Hellwig 		V##_1 = V[1];	\
333f276cecSChristoph Hellwig 		V##_2 = V[2];	\
343f276cecSChristoph Hellwig 		V##_3 = V[3];	\
353f276cecSChristoph Hellwig 	} while (0)
363f276cecSChristoph Hellwig 
373f276cecSChristoph Hellwig #define STORE(V)		\
383f276cecSChristoph Hellwig 	do {			\
393f276cecSChristoph Hellwig 		V[0] = V##_0;	\
403f276cecSChristoph Hellwig 		V[1] = V##_1;	\
413f276cecSChristoph Hellwig 		V[2] = V##_2;	\
423f276cecSChristoph Hellwig 		V[3] = V##_3;	\
433f276cecSChristoph Hellwig 	} while (0)
443f276cecSChristoph Hellwig 
453f276cecSChristoph Hellwig #define XOR(V1, V2)					\
463f276cecSChristoph Hellwig 	do {						\
473f276cecSChristoph Hellwig 		V1##_0 = vec_xor(V1##_0, V2##_0);	\
483f276cecSChristoph Hellwig 		V1##_1 = vec_xor(V1##_1, V2##_1);	\
493f276cecSChristoph Hellwig 		V1##_2 = vec_xor(V1##_2, V2##_2);	\
503f276cecSChristoph Hellwig 		V1##_3 = vec_xor(V1##_3, V2##_3);	\
513f276cecSChristoph Hellwig 	} while (0)
523f276cecSChristoph Hellwig 
53*80dcf0a7SChristoph Hellwig static void __xor_altivec_2(unsigned long bytes,
543f276cecSChristoph Hellwig 		unsigned long * __restrict v1_in,
553f276cecSChristoph Hellwig 		const unsigned long * __restrict v2_in)
563f276cecSChristoph Hellwig {
573f276cecSChristoph Hellwig 	DEFINE(v1);
583f276cecSChristoph Hellwig 	DEFINE(v2);
593f276cecSChristoph Hellwig 	unsigned long lines = bytes / (sizeof(unative_t)) / 4;
603f276cecSChristoph Hellwig 
613f276cecSChristoph Hellwig 	do {
623f276cecSChristoph Hellwig 		LOAD(v1);
633f276cecSChristoph Hellwig 		LOAD(v2);
643f276cecSChristoph Hellwig 		XOR(v1, v2);
653f276cecSChristoph Hellwig 		STORE(v1);
663f276cecSChristoph Hellwig 
673f276cecSChristoph Hellwig 		v1 += 4;
683f276cecSChristoph Hellwig 		v2 += 4;
693f276cecSChristoph Hellwig 	} while (--lines > 0);
703f276cecSChristoph Hellwig }
713f276cecSChristoph Hellwig 
72*80dcf0a7SChristoph Hellwig static void __xor_altivec_3(unsigned long bytes,
733f276cecSChristoph Hellwig 		unsigned long * __restrict v1_in,
743f276cecSChristoph Hellwig 		const unsigned long * __restrict v2_in,
753f276cecSChristoph Hellwig 		const unsigned long * __restrict v3_in)
763f276cecSChristoph Hellwig {
773f276cecSChristoph Hellwig 	DEFINE(v1);
783f276cecSChristoph Hellwig 	DEFINE(v2);
793f276cecSChristoph Hellwig 	DEFINE(v3);
803f276cecSChristoph Hellwig 	unsigned long lines = bytes / (sizeof(unative_t)) / 4;
813f276cecSChristoph Hellwig 
823f276cecSChristoph Hellwig 	do {
833f276cecSChristoph Hellwig 		LOAD(v1);
843f276cecSChristoph Hellwig 		LOAD(v2);
853f276cecSChristoph Hellwig 		LOAD(v3);
863f276cecSChristoph Hellwig 		XOR(v1, v2);
873f276cecSChristoph Hellwig 		XOR(v1, v3);
883f276cecSChristoph Hellwig 		STORE(v1);
893f276cecSChristoph Hellwig 
903f276cecSChristoph Hellwig 		v1 += 4;
913f276cecSChristoph Hellwig 		v2 += 4;
923f276cecSChristoph Hellwig 		v3 += 4;
933f276cecSChristoph Hellwig 	} while (--lines > 0);
943f276cecSChristoph Hellwig }
953f276cecSChristoph Hellwig 
96*80dcf0a7SChristoph Hellwig static void __xor_altivec_4(unsigned long bytes,
973f276cecSChristoph Hellwig 		unsigned long * __restrict v1_in,
983f276cecSChristoph Hellwig 		const unsigned long * __restrict v2_in,
993f276cecSChristoph Hellwig 		const unsigned long * __restrict v3_in,
1003f276cecSChristoph Hellwig 		const unsigned long * __restrict v4_in)
1013f276cecSChristoph Hellwig {
1023f276cecSChristoph Hellwig 	DEFINE(v1);
1033f276cecSChristoph Hellwig 	DEFINE(v2);
1043f276cecSChristoph Hellwig 	DEFINE(v3);
1053f276cecSChristoph Hellwig 	DEFINE(v4);
1063f276cecSChristoph Hellwig 	unsigned long lines = bytes / (sizeof(unative_t)) / 4;
1073f276cecSChristoph Hellwig 
1083f276cecSChristoph Hellwig 	do {
1093f276cecSChristoph Hellwig 		LOAD(v1);
1103f276cecSChristoph Hellwig 		LOAD(v2);
1113f276cecSChristoph Hellwig 		LOAD(v3);
1123f276cecSChristoph Hellwig 		LOAD(v4);
1133f276cecSChristoph Hellwig 		XOR(v1, v2);
1143f276cecSChristoph Hellwig 		XOR(v3, v4);
1153f276cecSChristoph Hellwig 		XOR(v1, v3);
1163f276cecSChristoph Hellwig 		STORE(v1);
1173f276cecSChristoph Hellwig 
1183f276cecSChristoph Hellwig 		v1 += 4;
1193f276cecSChristoph Hellwig 		v2 += 4;
1203f276cecSChristoph Hellwig 		v3 += 4;
1213f276cecSChristoph Hellwig 		v4 += 4;
1223f276cecSChristoph Hellwig 	} while (--lines > 0);
1233f276cecSChristoph Hellwig }
1243f276cecSChristoph Hellwig 
125*80dcf0a7SChristoph Hellwig static void __xor_altivec_5(unsigned long bytes,
1263f276cecSChristoph Hellwig 		unsigned long * __restrict v1_in,
1273f276cecSChristoph Hellwig 		const unsigned long * __restrict v2_in,
1283f276cecSChristoph Hellwig 		const unsigned long * __restrict v3_in,
1293f276cecSChristoph Hellwig 		const unsigned long * __restrict v4_in,
1303f276cecSChristoph Hellwig 		const unsigned long * __restrict v5_in)
1313f276cecSChristoph Hellwig {
1323f276cecSChristoph Hellwig 	DEFINE(v1);
1333f276cecSChristoph Hellwig 	DEFINE(v2);
1343f276cecSChristoph Hellwig 	DEFINE(v3);
1353f276cecSChristoph Hellwig 	DEFINE(v4);
1363f276cecSChristoph Hellwig 	DEFINE(v5);
1373f276cecSChristoph Hellwig 	unsigned long lines = bytes / (sizeof(unative_t)) / 4;
1383f276cecSChristoph Hellwig 
1393f276cecSChristoph Hellwig 	do {
1403f276cecSChristoph Hellwig 		LOAD(v1);
1413f276cecSChristoph Hellwig 		LOAD(v2);
1423f276cecSChristoph Hellwig 		LOAD(v3);
1433f276cecSChristoph Hellwig 		LOAD(v4);
1443f276cecSChristoph Hellwig 		LOAD(v5);
1453f276cecSChristoph Hellwig 		XOR(v1, v2);
1463f276cecSChristoph Hellwig 		XOR(v3, v4);
1473f276cecSChristoph Hellwig 		XOR(v1, v5);
1483f276cecSChristoph Hellwig 		XOR(v1, v3);
1493f276cecSChristoph Hellwig 		STORE(v1);
1503f276cecSChristoph Hellwig 
1513f276cecSChristoph Hellwig 		v1 += 4;
1523f276cecSChristoph Hellwig 		v2 += 4;
1533f276cecSChristoph Hellwig 		v3 += 4;
1543f276cecSChristoph Hellwig 		v4 += 4;
1553f276cecSChristoph Hellwig 		v5 += 4;
1563f276cecSChristoph Hellwig 	} while (--lines > 0);
1573f276cecSChristoph Hellwig }
158*80dcf0a7SChristoph Hellwig 
159*80dcf0a7SChristoph Hellwig __DO_XOR_BLOCKS(altivec_inner, __xor_altivec_2, __xor_altivec_3,
160*80dcf0a7SChristoph Hellwig 		__xor_altivec_4, __xor_altivec_5);
161