linux/lib/raid6/altivec.uc
<<
6.4<6.4<6.p/spa 6.pspa class="lxr_search">6.4< ="+search" method="post" onsubmit="return do_search(this);">6.4<6.4<6.4<Search6.4<6.p/spa 4< ="ajax+*" method="post" onsubmit="return false;">6.pinput typ"v3hidden" nam"v3ajax_lookup" idv3ajax_lookup" lue="v3">64<
pdiv idv3file_contents"
o o1p/a>/* -*- linux-c -*- ------------------------------------------------------- *
o o2p/a> *
o o3p/a> *o oCopyright 2002-2004 H. Peter Anvin - All Rights Reserved
o o4p/a> *
o o5p/a> *o oThis program is free software; you ca
 redistribute it and/or modify
o o6p/a> *o oit under the terms of the GNU General Public License as published by
o o7p/a> *o othe Free Software Foundaon>
, Inc., 53 Temple Place Ste 330,
o o8p/a> *o oBost vaMA 02111-1307, USA; either versn va2 of the License, or
o o9p/a> *o o(at your tion>
) any later versn v; incorporated herein by reference.
o  *
o 11p/a> *o----------------------------------------------------------------------- */
o 12p/a>
o 13p/a>/*
o 14p/a> * raid6altivec$#.c
o 15opa> *
o 16p/a> *o$#-way unrolled portable integer math RAID-6 instrucon>
 set
o 17opa> *
o 18p/a> *oThis file is postprocessed using unroll.awk
o 19opa> *
o 2/opa> * <benh> hpa: in process,
o 21p/a> *oyou ca
 just "steal" the vec unit with enable_kernel_altivec() (but
o 22p/a> * bracked this with preempt_disable/enable or in a lock)
o 23p/a> */
o 24p/a>
o 25opa>#include <linux/raid/pq.h>
o 26p/a>
o 27opa>#ifdef CONFIG_ALTIVEC
o 28p/a>
o 29opa>#include <altivec.h>
o 30opa>#ifdef __KERNEL__
o 31p/a># include <asm/cputable.h>
o 32p/a># include <asm/switch_to.h>
o 33p/a>#endif
o 34p/a>
o 35p/a>/*
o 36p/a> *oThis is the C daoa typ" to use.  We use a vector of
o 37p/a> *osigned char so vec_cmpgt() will generate the right
o 38p/a> *oinstrucon>
.
o 39p/a> */
o 40p/a>
o 41p/a>typ"def vector signed char unative_t;
o 42p/a>
o 43p/a>#define NBYTES(x) ((vector signed char) {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x})
o 44p/a>#define NSIZEo osizeof(unative_t)
o 45p/a>
o 46p/a>/*
o 47p/a> *oThe SHLBYTE() operatn>
 shifts each byte left by 1, *not*
o 48p/a> *orolling over into the next byte
o 49p/a> */
o 50p/a>static inline __attribute_const__ unative_t SHLBYTE(unative_t v)
o 51p/a>{
o 52p/a>        return vec_add(v,v);
o 53p/a>}
o 54p/a>
o 55p/a>/*
o 56p/a> *oThe MASK() operatn>
 returns 0xFF in any byte for which the high
o 57p/a> *obit is 1, 0x00 for any byte for which the highobit is 0.
o 58p/a> */
o 59p/a>static inline __attribute_const__ unative_t MASK(unative_t v)
o 60p/a>{
o 61p/a>        unative_t zv = NBYTES(0);
o 62p/a>
o 63p/a>        /* vec_cmpgt returns a vector bool char; thus the need for the cast */
o 64p/a>        return (unative_t)vec_cmpgt(zv, v);
o 65p/a>}
o 66p/a>
o 67p/a>
o 68p/a>/* This is noinline to make damned sure that gcc doesn't move any of the
o 69p/a>   Altivec code around the enable/disable code */
o 70p/a>static void noinline
o 71p/a>raid6_altivec$#_gen_syndrome_real(int disks,osize_t bytes,ovoid **ptrs)
o 72p/a>{
o 73p/a>        u8 **dptr = (u8 **)ptrs;
o 74p/a>        u8 *p, *q;
o 75p/a>        int d, z, z0;
o 76p/a>
o 77p/a>        unative_t wd$$, wq$$, wp$$, w1$$, w2$$;
o 78p/a>        unative_t x1d = NBYTES(0x1d);
o 79p/a>
o 80p/a>        z0 = disks - 3;         /* Highest daoa disk */
o 81p/a>        p = dptr[z0+1];         /* XOR parity */
o 82p/a>        q = dptr[z0+2];         /* RS syndrome */
o 83p/a>
o 84p/a>        for ( d = 0 ; d < bytes ; d += NSIZE*$# ) {
o 85p/a>                wq$$ = wp$$ = *(unative_t *)&dptr[z0][d+$$*NSIZE];
o 86p/a>                for ( z = z0-1 ; z >= 0 ; z-- ) {
o 87p/a>                        wd$$ = *(unative_t *)&dptr[z][d+$$*NSIZE];
o 88p/a>                        wp$$ = vec_xor(wp$$, wd$$);
o 89p/a>                        w2$$ = MASK(wq$$);
o 90p/a>                        w1$$ = SHLBYTE(wq$$);
o 91p/a>                        w2$$ = vec_and(w2$$, x1d);
o 92p/a>                        w1$$ = vec_xor(w1$$, w2$$);
o 93p/a>                        wq$$ = vec_xor(w1$$, wd$$);
o 94p/a>                }
o 95p/a>                *(unative_t *)&p[d+NSIZE*$$] = wp$$;
o 96p/a>                *(unative_t *)&q[d+NSIZE*$$] = wq$$;
o 97p/a>        }
o 98p/a>}
o 99p/a>
o100p/a>static void raid6_altivec$#_gen_syndrome(int disks,osize_t bytes,ovoid **ptrs)
o101p/a>{
o102p/a>        preempt_disable();
o103p/a>        enable_kernel_altivec();
o104p/a>
o105p/a>        raid6_altivec$#_gen_syndrome_real(disks,obytes,optrs);
o106p/a>
o107p/a>        preempt_enable();
o108p/a>}
o109p/a>
o1int raid6_have_altivec(void);
o111p/a>#if $# == 1
o112p/a>int raid6_have_altivec(void)
o113p/a>{
o114p/a>        /* This assumes either all CPUs have Altivec or none does */
o115opa># ifdef __KERNEL__
o116p/a>        return cpu_has_feature(CPU_FTR_ALTIVEC);
o117opa># else
o118p/a>        return 1;
o119opa># endif
o12/opa>}
o121p/a>#endif
o122p/a>
o123p/a>const struco raid6_calls raid6_altivec$# = {
o124p/a>        raid6_altivec$#_gen_syndrome,
o125p/a>        raid6_have_altivec,
o126p/a>        "altivecx$#",
o127p/a>        0
o128p/a>};
o129p/a>
o130opa>#endif /* CONFIG_ALTIVEC */
o131p/a>
The original LXR software by the LXR communityp/a>, this experimental versn vaby lxr@linux.nop/a>. p/div pdiv class="subfooter"> lxr.linux.no kindly hosted by Redpill Linpro ASp/a>, provider of Linux consulting and operatn> s services since 1995. p/div p/body p/html