xref: /kernel/linux/linux-6.6/arch/s390/lib/xor.c (revision 62306a36)
162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Optimized xor_block operation for RAID4/5
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright IBM Corp. 2016
662306a36Sopenharmony_ci * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/types.h>
1062306a36Sopenharmony_ci#include <linux/export.h>
1162306a36Sopenharmony_ci#include <linux/raid/xor.h>
1262306a36Sopenharmony_ci#include <asm/xor.h>
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_cistatic void xor_xc_2(unsigned long bytes, unsigned long * __restrict p1,
1562306a36Sopenharmony_ci		     const unsigned long * __restrict p2)
1662306a36Sopenharmony_ci{
1762306a36Sopenharmony_ci	asm volatile(
1862306a36Sopenharmony_ci		"	larl	1,2f\n"
1962306a36Sopenharmony_ci		"	aghi	%0,-1\n"
2062306a36Sopenharmony_ci		"	jm	3f\n"
2162306a36Sopenharmony_ci		"	srlg	0,%0,8\n"
2262306a36Sopenharmony_ci		"	ltgr	0,0\n"
2362306a36Sopenharmony_ci		"	jz	1f\n"
2462306a36Sopenharmony_ci		"0:	xc	0(256,%1),0(%2)\n"
2562306a36Sopenharmony_ci		"	la	%1,256(%1)\n"
2662306a36Sopenharmony_ci		"	la	%2,256(%2)\n"
2762306a36Sopenharmony_ci		"	brctg	0,0b\n"
2862306a36Sopenharmony_ci		"1:	ex	%0,0(1)\n"
2962306a36Sopenharmony_ci		"	j	3f\n"
3062306a36Sopenharmony_ci		"2:	xc	0(1,%1),0(%2)\n"
3162306a36Sopenharmony_ci		"3:\n"
3262306a36Sopenharmony_ci		: : "d" (bytes), "a" (p1), "a" (p2)
3362306a36Sopenharmony_ci		: "0", "1", "cc", "memory");
3462306a36Sopenharmony_ci}
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_cistatic void xor_xc_3(unsigned long bytes, unsigned long * __restrict p1,
3762306a36Sopenharmony_ci		     const unsigned long * __restrict p2,
3862306a36Sopenharmony_ci		     const unsigned long * __restrict p3)
3962306a36Sopenharmony_ci{
4062306a36Sopenharmony_ci	asm volatile(
4162306a36Sopenharmony_ci		"	larl	1,2f\n"
4262306a36Sopenharmony_ci		"	aghi	%0,-1\n"
4362306a36Sopenharmony_ci		"	jm	3f\n"
4462306a36Sopenharmony_ci		"	srlg	0,%0,8\n"
4562306a36Sopenharmony_ci		"	ltgr	0,0\n"
4662306a36Sopenharmony_ci		"	jz	1f\n"
4762306a36Sopenharmony_ci		"0:	xc	0(256,%1),0(%2)\n"
4862306a36Sopenharmony_ci		"	xc	0(256,%1),0(%3)\n"
4962306a36Sopenharmony_ci		"	la	%1,256(%1)\n"
5062306a36Sopenharmony_ci		"	la	%2,256(%2)\n"
5162306a36Sopenharmony_ci		"	la	%3,256(%3)\n"
5262306a36Sopenharmony_ci		"	brctg	0,0b\n"
5362306a36Sopenharmony_ci		"1:	ex	%0,0(1)\n"
5462306a36Sopenharmony_ci		"	ex	%0,6(1)\n"
5562306a36Sopenharmony_ci		"	j	3f\n"
5662306a36Sopenharmony_ci		"2:	xc	0(1,%1),0(%2)\n"
5762306a36Sopenharmony_ci		"	xc	0(1,%1),0(%3)\n"
5862306a36Sopenharmony_ci		"3:\n"
5962306a36Sopenharmony_ci		: "+d" (bytes), "+a" (p1), "+a" (p2), "+a" (p3)
6062306a36Sopenharmony_ci		: : "0", "1", "cc", "memory");
6162306a36Sopenharmony_ci}
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_cistatic void xor_xc_4(unsigned long bytes, unsigned long * __restrict p1,
6462306a36Sopenharmony_ci		     const unsigned long * __restrict p2,
6562306a36Sopenharmony_ci		     const unsigned long * __restrict p3,
6662306a36Sopenharmony_ci		     const unsigned long * __restrict p4)
6762306a36Sopenharmony_ci{
6862306a36Sopenharmony_ci	asm volatile(
6962306a36Sopenharmony_ci		"	larl	1,2f\n"
7062306a36Sopenharmony_ci		"	aghi	%0,-1\n"
7162306a36Sopenharmony_ci		"	jm	3f\n"
7262306a36Sopenharmony_ci		"	srlg	0,%0,8\n"
7362306a36Sopenharmony_ci		"	ltgr	0,0\n"
7462306a36Sopenharmony_ci		"	jz	1f\n"
7562306a36Sopenharmony_ci		"0:	xc	0(256,%1),0(%2)\n"
7662306a36Sopenharmony_ci		"	xc	0(256,%1),0(%3)\n"
7762306a36Sopenharmony_ci		"	xc	0(256,%1),0(%4)\n"
7862306a36Sopenharmony_ci		"	la	%1,256(%1)\n"
7962306a36Sopenharmony_ci		"	la	%2,256(%2)\n"
8062306a36Sopenharmony_ci		"	la	%3,256(%3)\n"
8162306a36Sopenharmony_ci		"	la	%4,256(%4)\n"
8262306a36Sopenharmony_ci		"	brctg	0,0b\n"
8362306a36Sopenharmony_ci		"1:	ex	%0,0(1)\n"
8462306a36Sopenharmony_ci		"	ex	%0,6(1)\n"
8562306a36Sopenharmony_ci		"	ex	%0,12(1)\n"
8662306a36Sopenharmony_ci		"	j	3f\n"
8762306a36Sopenharmony_ci		"2:	xc	0(1,%1),0(%2)\n"
8862306a36Sopenharmony_ci		"	xc	0(1,%1),0(%3)\n"
8962306a36Sopenharmony_ci		"	xc	0(1,%1),0(%4)\n"
9062306a36Sopenharmony_ci		"3:\n"
9162306a36Sopenharmony_ci		: "+d" (bytes), "+a" (p1), "+a" (p2), "+a" (p3), "+a" (p4)
9262306a36Sopenharmony_ci		: : "0", "1", "cc", "memory");
9362306a36Sopenharmony_ci}
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_cistatic void xor_xc_5(unsigned long bytes, unsigned long * __restrict p1,
9662306a36Sopenharmony_ci		     const unsigned long * __restrict p2,
9762306a36Sopenharmony_ci		     const unsigned long * __restrict p3,
9862306a36Sopenharmony_ci		     const unsigned long * __restrict p4,
9962306a36Sopenharmony_ci		     const unsigned long * __restrict p5)
10062306a36Sopenharmony_ci{
10162306a36Sopenharmony_ci	asm volatile(
10262306a36Sopenharmony_ci		"	larl	1,2f\n"
10362306a36Sopenharmony_ci		"	aghi	%0,-1\n"
10462306a36Sopenharmony_ci		"	jm	3f\n"
10562306a36Sopenharmony_ci		"	srlg	0,%0,8\n"
10662306a36Sopenharmony_ci		"	ltgr	0,0\n"
10762306a36Sopenharmony_ci		"	jz	1f\n"
10862306a36Sopenharmony_ci		"0:	xc	0(256,%1),0(%2)\n"
10962306a36Sopenharmony_ci		"	xc	0(256,%1),0(%3)\n"
11062306a36Sopenharmony_ci		"	xc	0(256,%1),0(%4)\n"
11162306a36Sopenharmony_ci		"	xc	0(256,%1),0(%5)\n"
11262306a36Sopenharmony_ci		"	la	%1,256(%1)\n"
11362306a36Sopenharmony_ci		"	la	%2,256(%2)\n"
11462306a36Sopenharmony_ci		"	la	%3,256(%3)\n"
11562306a36Sopenharmony_ci		"	la	%4,256(%4)\n"
11662306a36Sopenharmony_ci		"	la	%5,256(%5)\n"
11762306a36Sopenharmony_ci		"	brctg	0,0b\n"
11862306a36Sopenharmony_ci		"1:	ex	%0,0(1)\n"
11962306a36Sopenharmony_ci		"	ex	%0,6(1)\n"
12062306a36Sopenharmony_ci		"	ex	%0,12(1)\n"
12162306a36Sopenharmony_ci		"	ex	%0,18(1)\n"
12262306a36Sopenharmony_ci		"	j	3f\n"
12362306a36Sopenharmony_ci		"2:	xc	0(1,%1),0(%2)\n"
12462306a36Sopenharmony_ci		"	xc	0(1,%1),0(%3)\n"
12562306a36Sopenharmony_ci		"	xc	0(1,%1),0(%4)\n"
12662306a36Sopenharmony_ci		"	xc	0(1,%1),0(%5)\n"
12762306a36Sopenharmony_ci		"3:\n"
12862306a36Sopenharmony_ci		: "+d" (bytes), "+a" (p1), "+a" (p2), "+a" (p3), "+a" (p4),
12962306a36Sopenharmony_ci		  "+a" (p5)
13062306a36Sopenharmony_ci		: : "0", "1", "cc", "memory");
13162306a36Sopenharmony_ci}
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_cistruct xor_block_template xor_block_xc = {
13462306a36Sopenharmony_ci	.name = "xc",
13562306a36Sopenharmony_ci	.do_2 = xor_xc_2,
13662306a36Sopenharmony_ci	.do_3 = xor_xc_3,
13762306a36Sopenharmony_ci	.do_4 = xor_xc_4,
13862306a36Sopenharmony_ci	.do_5 = xor_xc_5,
13962306a36Sopenharmony_ci};
14062306a36Sopenharmony_ciEXPORT_SYMBOL(xor_block_xc);
141