// SPDX-License-Identifier: GPL-2.0-or-later
/*
* RAID-6 syndrome calculation using RISC-V vector instructions
*
* Copyright 2024 Institute of Software, CAS.
* Author: Chunyan Zhang <zhangchunyan@iscas.ac.cn>
*
* Based on neon.uc:
* Copyright 2002-2004 H. Peter Anvin
*/
#include "rvv.h"
#ifdef __riscv_vector
#error "This code must be built without compiler support for vector"
#endif
static void raid6_rvv1_gen_syndrome_real(int disks, unsigned long bytes, void **ptrs)
{
u8 **dptr = (u8 **)ptrs;
u8 *p, *q;
unsigned long vl, d, nsize;
int z, z0;
z0 = disks - 3; /* Highest data disk */
p = dptr[z0 + 1]; /* XOR parity */
q = dptr[z0 + 2]; /* RS syndrome */
asm volatile (".option push\n"
".option arch,+v\n"
"vsetvli %0, x0, e8, m1, ta, ma\n"
".option pop\n"
: "=&r" (vl)
);
nsize = vl;
/* v0:wp0, v1:wq0, v2:wd0/w20, v3:w10 */
for (d = 0; d < bytes; d += nsize * 1) {
/* wq$$ = wp$$ = *(unative_t *)&dptr[z0][d+$$*NSIZE]; */
asm volatile (".option push\n"
".option arch,+v\n"
"vle8.v v0, (%[wp0])\n"
"vmv.v.v v1, v0\n"
".option pop\n"
: :
[wp0]"r"(&dptr[z0][d + 0 * nsize])
);
for (z = z0 - 1 ; z >= 0 ; z--) {
/*
* w2$$ = MASK(wq$$);
* w1$$ = SHLBYTE(wq$$);
* w2$$ &= NBYTES(0x1d);
* w1$$ ^= w2$$;
* wd$$ = *(unative_t *)&dptr[z][d+$$*NSIZE];
* wq$$ = w1$$ ^ wd$$;
* wp$$ ^= wd$$;
*/
asm volatile (".option push\n"
".option arch,+v\n"
"vsra.vi v2, v1, 7\n"
"vsll.vi v3, v1, 1\n"
"vand.vx v2, v2, %[x1d]\n"
"vxor.vv v3, v3, v2\n"
"vle8.v v2, (%[wd0])\n"
"vxor.vv v1, v3, v2\n"
"vxor.vv v0, v0, v2\n"
".option pop\n"
: :
[wd0]"r"(&dptr[z][d + 0 * nsize]),
[x1d]"r"(0x1d)
);
}
/*
* *(unative_t *)&p[d+NSIZE*$$] = wp$$;
* *(unative_t *)&q[d+NSIZE*$$] = wq$$;
*/
asm volatile (".option push\n"
".option arch,+v\n"
"vse8.v v0, (%[wp0])\n"
"vse8.v v1, (%[wq0])\n"
".option pop\n"
: :
[wp0]"r"(&p[d + nsize * 0]),
[wq0]"r"(&q[d + nsize * 0])
);
}
}
static void raid6_rvv1_xor_syndrome_real(int disks, int start, int stop,
unsigned long bytes, void **ptrs)
{
u8 **dptr