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 .
*
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - * /
/ *
* raid6int$ # . c
*
* $ # - 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$$ ;
}
}
const struct raid6 _calls raid6 _intx$ # = {
raid6 _int$ # _gen _syndrome ,
NULL , /* always valid */
"int" NSTRING "x$#" ,
0
} ;
# endif