xref: /openbmc/linux/arch/s390/lib/xor.c (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
22cfc5f9cSMartin Schwidefsky /*
32cfc5f9cSMartin Schwidefsky  * Optimized xor_block operation for RAID4/5
42cfc5f9cSMartin Schwidefsky  *
52cfc5f9cSMartin Schwidefsky  * Copyright IBM Corp. 2016
62cfc5f9cSMartin Schwidefsky  * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
72cfc5f9cSMartin Schwidefsky  */
82cfc5f9cSMartin Schwidefsky 
92cfc5f9cSMartin Schwidefsky #include <linux/types.h>
10d3217967SPaul Gortmaker #include <linux/export.h>
112cfc5f9cSMartin Schwidefsky #include <linux/raid/xor.h>
12d25220d2SVasily Gorbik #include <asm/xor.h>
132cfc5f9cSMartin Schwidefsky 
xor_xc_2(unsigned long bytes,unsigned long * __restrict p1,const unsigned long * __restrict p2)14*297565aaSArd Biesheuvel static void xor_xc_2(unsigned long bytes, unsigned long * __restrict p1,
15*297565aaSArd Biesheuvel 		     const unsigned long * __restrict p2)
162cfc5f9cSMartin Schwidefsky {
172cfc5f9cSMartin Schwidefsky 	asm volatile(
182cfc5f9cSMartin Schwidefsky 		"	larl	1,2f\n"
192cfc5f9cSMartin Schwidefsky 		"	aghi	%0,-1\n"
202cfc5f9cSMartin Schwidefsky 		"	jm	3f\n"
212cfc5f9cSMartin Schwidefsky 		"	srlg	0,%0,8\n"
222cfc5f9cSMartin Schwidefsky 		"	ltgr	0,0\n"
232cfc5f9cSMartin Schwidefsky 		"	jz	1f\n"
242cfc5f9cSMartin Schwidefsky 		"0:	xc	0(256,%1),0(%2)\n"
252cfc5f9cSMartin Schwidefsky 		"	la	%1,256(%1)\n"
262cfc5f9cSMartin Schwidefsky 		"	la	%2,256(%2)\n"
272cfc5f9cSMartin Schwidefsky 		"	brctg	0,0b\n"
282cfc5f9cSMartin Schwidefsky 		"1:	ex	%0,0(1)\n"
292cfc5f9cSMartin Schwidefsky 		"	j	3f\n"
302cfc5f9cSMartin Schwidefsky 		"2:	xc	0(1,%1),0(%2)\n"
312cfc5f9cSMartin Schwidefsky 		"3:\n"
322cfc5f9cSMartin Schwidefsky 		: : "d" (bytes), "a" (p1), "a" (p2)
332cfc5f9cSMartin Schwidefsky 		: "0", "1", "cc", "memory");
342cfc5f9cSMartin Schwidefsky }
352cfc5f9cSMartin Schwidefsky 
xor_xc_3(unsigned long bytes,unsigned long * __restrict p1,const unsigned long * __restrict p2,const unsigned long * __restrict p3)36*297565aaSArd Biesheuvel static void xor_xc_3(unsigned long bytes, unsigned long * __restrict p1,
37*297565aaSArd Biesheuvel 		     const unsigned long * __restrict p2,
38*297565aaSArd Biesheuvel 		     const unsigned long * __restrict p3)
392cfc5f9cSMartin Schwidefsky {
402cfc5f9cSMartin Schwidefsky 	asm volatile(
412cfc5f9cSMartin Schwidefsky 		"	larl	1,2f\n"
422cfc5f9cSMartin Schwidefsky 		"	aghi	%0,-1\n"
432cfc5f9cSMartin Schwidefsky 		"	jm	3f\n"
442cfc5f9cSMartin Schwidefsky 		"	srlg	0,%0,8\n"
452cfc5f9cSMartin Schwidefsky 		"	ltgr	0,0\n"
462cfc5f9cSMartin Schwidefsky 		"	jz	1f\n"
472cfc5f9cSMartin Schwidefsky 		"0:	xc	0(256,%1),0(%2)\n"
482cfc5f9cSMartin Schwidefsky 		"	xc	0(256,%1),0(%3)\n"
492cfc5f9cSMartin Schwidefsky 		"	la	%1,256(%1)\n"
502cfc5f9cSMartin Schwidefsky 		"	la	%2,256(%2)\n"
512cfc5f9cSMartin Schwidefsky 		"	la	%3,256(%3)\n"
522cfc5f9cSMartin Schwidefsky 		"	brctg	0,0b\n"
532cfc5f9cSMartin Schwidefsky 		"1:	ex	%0,0(1)\n"
542cfc5f9cSMartin Schwidefsky 		"	ex	%0,6(1)\n"
552cfc5f9cSMartin Schwidefsky 		"	j	3f\n"
562cfc5f9cSMartin Schwidefsky 		"2:	xc	0(1,%1),0(%2)\n"
572cfc5f9cSMartin Schwidefsky 		"	xc	0(1,%1),0(%3)\n"
582cfc5f9cSMartin Schwidefsky 		"3:\n"
592cfc5f9cSMartin Schwidefsky 		: "+d" (bytes), "+a" (p1), "+a" (p2), "+a" (p3)
602cfc5f9cSMartin Schwidefsky 		: : "0", "1", "cc", "memory");
612cfc5f9cSMartin Schwidefsky }
622cfc5f9cSMartin Schwidefsky 
xor_xc_4(unsigned long bytes,unsigned long * __restrict p1,const unsigned long * __restrict p2,const unsigned long * __restrict p3,const unsigned long * __restrict p4)63*297565aaSArd Biesheuvel static void xor_xc_4(unsigned long bytes, unsigned long * __restrict p1,
64*297565aaSArd Biesheuvel 		     const unsigned long * __restrict p2,
65*297565aaSArd Biesheuvel 		     const unsigned long * __restrict p3,
66*297565aaSArd Biesheuvel 		     const unsigned long * __restrict p4)
672cfc5f9cSMartin Schwidefsky {
682cfc5f9cSMartin Schwidefsky 	asm volatile(
692cfc5f9cSMartin Schwidefsky 		"	larl	1,2f\n"
702cfc5f9cSMartin Schwidefsky 		"	aghi	%0,-1\n"
712cfc5f9cSMartin Schwidefsky 		"	jm	3f\n"
722cfc5f9cSMartin Schwidefsky 		"	srlg	0,%0,8\n"
732cfc5f9cSMartin Schwidefsky 		"	ltgr	0,0\n"
742cfc5f9cSMartin Schwidefsky 		"	jz	1f\n"
752cfc5f9cSMartin Schwidefsky 		"0:	xc	0(256,%1),0(%2)\n"
762cfc5f9cSMartin Schwidefsky 		"	xc	0(256,%1),0(%3)\n"
772cfc5f9cSMartin Schwidefsky 		"	xc	0(256,%1),0(%4)\n"
782cfc5f9cSMartin Schwidefsky 		"	la	%1,256(%1)\n"
792cfc5f9cSMartin Schwidefsky 		"	la	%2,256(%2)\n"
802cfc5f9cSMartin Schwidefsky 		"	la	%3,256(%3)\n"
812cfc5f9cSMartin Schwidefsky 		"	la	%4,256(%4)\n"
822cfc5f9cSMartin Schwidefsky 		"	brctg	0,0b\n"
832cfc5f9cSMartin Schwidefsky 		"1:	ex	%0,0(1)\n"
842cfc5f9cSMartin Schwidefsky 		"	ex	%0,6(1)\n"
852cfc5f9cSMartin Schwidefsky 		"	ex	%0,12(1)\n"
862cfc5f9cSMartin Schwidefsky 		"	j	3f\n"
872cfc5f9cSMartin Schwidefsky 		"2:	xc	0(1,%1),0(%2)\n"
882cfc5f9cSMartin Schwidefsky 		"	xc	0(1,%1),0(%3)\n"
892cfc5f9cSMartin Schwidefsky 		"	xc	0(1,%1),0(%4)\n"
902cfc5f9cSMartin Schwidefsky 		"3:\n"
912cfc5f9cSMartin Schwidefsky 		: "+d" (bytes), "+a" (p1), "+a" (p2), "+a" (p3), "+a" (p4)
922cfc5f9cSMartin Schwidefsky 		: : "0", "1", "cc", "memory");
932cfc5f9cSMartin Schwidefsky }
942cfc5f9cSMartin Schwidefsky 
xor_xc_5(unsigned long bytes,unsigned long * __restrict p1,const unsigned long * __restrict p2,const unsigned long * __restrict p3,const unsigned long * __restrict p4,const unsigned long * __restrict p5)95*297565aaSArd Biesheuvel static void xor_xc_5(unsigned long bytes, unsigned long * __restrict p1,
96*297565aaSArd Biesheuvel 		     const unsigned long * __restrict p2,
97*297565aaSArd Biesheuvel 		     const unsigned long * __restrict p3,
98*297565aaSArd Biesheuvel 		     const unsigned long * __restrict p4,
99*297565aaSArd Biesheuvel 		     const unsigned long * __restrict p5)
1002cfc5f9cSMartin Schwidefsky {
1012cfc5f9cSMartin Schwidefsky 	asm volatile(
1022cfc5f9cSMartin Schwidefsky 		"	larl	1,2f\n"
1032cfc5f9cSMartin Schwidefsky 		"	aghi	%0,-1\n"
1042cfc5f9cSMartin Schwidefsky 		"	jm	3f\n"
1052cfc5f9cSMartin Schwidefsky 		"	srlg	0,%0,8\n"
1062cfc5f9cSMartin Schwidefsky 		"	ltgr	0,0\n"
1072cfc5f9cSMartin Schwidefsky 		"	jz	1f\n"
1082cfc5f9cSMartin Schwidefsky 		"0:	xc	0(256,%1),0(%2)\n"
1092cfc5f9cSMartin Schwidefsky 		"	xc	0(256,%1),0(%3)\n"
1102cfc5f9cSMartin Schwidefsky 		"	xc	0(256,%1),0(%4)\n"
1112cfc5f9cSMartin Schwidefsky 		"	xc	0(256,%1),0(%5)\n"
1122cfc5f9cSMartin Schwidefsky 		"	la	%1,256(%1)\n"
1132cfc5f9cSMartin Schwidefsky 		"	la	%2,256(%2)\n"
1142cfc5f9cSMartin Schwidefsky 		"	la	%3,256(%3)\n"
1152cfc5f9cSMartin Schwidefsky 		"	la	%4,256(%4)\n"
1162cfc5f9cSMartin Schwidefsky 		"	la	%5,256(%5)\n"
1172cfc5f9cSMartin Schwidefsky 		"	brctg	0,0b\n"
1182cfc5f9cSMartin Schwidefsky 		"1:	ex	%0,0(1)\n"
1192cfc5f9cSMartin Schwidefsky 		"	ex	%0,6(1)\n"
1202cfc5f9cSMartin Schwidefsky 		"	ex	%0,12(1)\n"
1212cfc5f9cSMartin Schwidefsky 		"	ex	%0,18(1)\n"
1222cfc5f9cSMartin Schwidefsky 		"	j	3f\n"
1232cfc5f9cSMartin Schwidefsky 		"2:	xc	0(1,%1),0(%2)\n"
1242cfc5f9cSMartin Schwidefsky 		"	xc	0(1,%1),0(%3)\n"
1252cfc5f9cSMartin Schwidefsky 		"	xc	0(1,%1),0(%4)\n"
1262cfc5f9cSMartin Schwidefsky 		"	xc	0(1,%1),0(%5)\n"
1272cfc5f9cSMartin Schwidefsky 		"3:\n"
1282cfc5f9cSMartin Schwidefsky 		: "+d" (bytes), "+a" (p1), "+a" (p2), "+a" (p3), "+a" (p4),
1297e86f967SHeiko Carstens 		  "+a" (p5)
1302cfc5f9cSMartin Schwidefsky 		: : "0", "1", "cc", "memory");
1312cfc5f9cSMartin Schwidefsky }
1322cfc5f9cSMartin Schwidefsky 
1332cfc5f9cSMartin Schwidefsky struct xor_block_template xor_block_xc = {
1342cfc5f9cSMartin Schwidefsky 	.name = "xc",
1352cfc5f9cSMartin Schwidefsky 	.do_2 = xor_xc_2,
1362cfc5f9cSMartin Schwidefsky 	.do_3 = xor_xc_3,
1372cfc5f9cSMartin Schwidefsky 	.do_4 = xor_xc_4,
1382cfc5f9cSMartin Schwidefsky 	.do_5 = xor_xc_5,
1392cfc5f9cSMartin Schwidefsky };
1402cfc5f9cSMartin Schwidefsky EXPORT_SYMBOL(xor_block_xc);
141