2005-04-17 02:20:36 +04:00
/ * - * - l i n u x - c - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
*
* Copyright 2002 - 2004 H . Peter Anvin - All Rights Reserved
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , Inc . , 53 Temple Place Ste 330 ,
2009-03-31 07:57:37 +04:00
* Boston MA 02111 - 1307 , USA ; either version 2 of the License , or
2005-04-17 02:20:36 +04:00
* ( at your option ) any later version ; incorporated herein by reference .
*
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - * /
/ *
2011-10-18 00:29:08 +04:00
* int$ # . c
2005-04-17 02:20:36 +04:00
*
* $ # - way unrolled portable integer math RAID - 6 instruction set
*
2009-10-16 09:25:19 +04:00
* This file is postprocessed using unroll . awk
2005-04-17 02:20:36 +04:00
* /
2009-03-31 08:09:39 +04:00
# include < linux / raid / pq . h >
2005-04-17 02:20:36 +04:00
/ *
* This is the C data type to use
* /
/* Change this from BITS_PER_LONG if there is something better... */
# if BITS _PER _LONG == 64
# define NBYTES ( x ) ( ( x ) * 0x0101010101010101 UL )
# define NSIZE 8
# define NSHIFT 3
# define NSTRING "64"
typedef u64 unative _t ;
# else
# define NBYTES ( x ) ( ( x ) * 0x01010101 U )
# define NSIZE 4
# define NSHIFT 2
# define NSTRING "32"
typedef u32 unative _t ;
# endif
/ *
* IA - 64 wants insane amounts of unrolling . On other architectures that
* is just a waste of space .
* /
# if ( $ # <= 8 ) || defined ( _ _ia64 _ _ )
/ *
* These sub - operations are separate inlines since they can sometimes be
* specially optimized using architecture - specific hacks .
* /
/ *
* The SHLBYTE ( ) operation shifts each byte left by 1 , * not *
* rolling over into the next byte
* /
static inline _ _attribute _const _ _ unative _t SHLBYTE ( unative _t v )
{
unative _t vv ;
vv = ( v << 1 ) & NBYTES ( 0xfe ) ;
return vv ;
}
/ *
* The MASK ( ) operation returns 0xFF in any byte for which the high
* bit is 1 , 0x00 for any byte for which the high bit is 0.
* /
static inline _ _attribute _const _ _ unative _t MASK ( unative _t v )
{
unative _t vv ;
vv = v & NBYTES ( 0x80 ) ;
vv = ( vv << 1 ) - ( vv >> 7 ) ; /* Overflow on the top bit is OK */
return vv ;
}
static void raid6 _int$ # _gen _syndrome ( int disks , size _t bytes , void * * ptrs )
{
u8 * * dptr = ( u8 * * ) ptrs ;
u8 * p , * q ;
int d , z , z0 ;
unative _t wd$$ , wq$$ , wp$$ , w1$$ , w2$$ ;
z0 = disks - 3 ; /* Highest data disk */
p = dptr [ z0 + 1 ] ; /* XOR parity */
q = dptr [ z0 + 2 ] ; /* RS syndrome */
for ( d = 0 ; d < bytes ; d += NSIZE * $ # ) {
wq$$ = wp$$ = * ( unative _t * ) & dptr [ z0 ] [ d + $$ * NSIZE ] ;
for ( z = z0 - 1 ; z >= 0 ; z -- ) {
wd$$ = * ( unative _t * ) & dptr [ z ] [ d + $$ * NSIZE ] ;
wp$$ ^= wd$$ ;
w2$$ = MASK ( wq$$ ) ;
w1$$ = SHLBYTE ( wq$$ ) ;
w2$$ &= NBYTES ( 0x1d ) ;
w1$$ ^= w2$$ ;
wq$$ = w1$$ ^ wd$$ ;
}
* ( unative _t * ) & p [ d + NSIZE * $$ ] = wp$$ ;
* ( unative _t * ) & q [ d + NSIZE * $$ ] = wq$$ ;
}
}
2014-12-15 04:57:04 +03:00
static void raid6 _int$ # _xor _syndrome ( int disks , int start , int stop ,
size _t bytes , void * * ptrs )
{
u8 * * dptr = ( u8 * * ) ptrs ;
u8 * p , * q ;
int d , z , z0 ;
unative _t wd$$ , wq$$ , wp$$ , w1$$ , w2$$ ;
z0 = stop ; /* P/Q right side optimization */
p = dptr [ disks - 2 ] ; /* XOR parity */
q = dptr [ disks - 1 ] ; /* RS syndrome */
for ( d = 0 ; d < bytes ; d += NSIZE * $ # ) {
/* P/Q data pages */
wq$$ = wp$$ = * ( unative _t * ) & dptr [ z0 ] [ d + $$ * NSIZE ] ;
for ( z = z0 - 1 ; z >= start ; z -- ) {
wd$$ = * ( unative _t * ) & dptr [ z ] [ d + $$ * NSIZE ] ;
wp$$ ^= wd$$ ;
w2$$ = MASK ( wq$$ ) ;
w1$$ = SHLBYTE ( wq$$ ) ;
w2$$ &= NBYTES ( 0x1d ) ;
w1$$ ^= w2$$ ;
wq$$ = w1$$ ^ wd$$ ;
}
/* P/Q left side optimization */
for ( z = start - 1 ; z >= 0 ; z -- ) {
w2$$ = MASK ( wq$$ ) ;
w1$$ = SHLBYTE ( wq$$ ) ;
w2$$ &= NBYTES ( 0x1d ) ;
wq$$ = w1$$ ^ w2$$ ;
}
* ( unative _t * ) & p [ d + NSIZE * $$ ] ^= wp$$ ;
* ( unative _t * ) & q [ d + NSIZE * $$ ] ^= wq$$ ;
}
}
2005-04-17 02:20:36 +04:00
const struct raid6 _calls raid6 _intx$ # = {
raid6 _int$ # _gen _syndrome ,
2014-12-15 04:57:04 +03:00
raid6 _int$ # _xor _syndrome ,
2014-12-15 04:57:04 +03:00
NULL , /* always valid */
2005-04-17 02:20:36 +04:00
"int" NSTRING "x$#" ,
0
} ;
# endif