linux/lib/raid6/tilegx.uc
<<
>>
Prefs
   1/* -*- linux-c -*- ------------------------------------------------------- *
   2 *
   3 *   Copyright 2002 H. Peter Anvin - All Rights Reserved
   4 *   Copyright 2012 Tilera Corporation - All Rights Reserved
   5 *
   6 *   This program is free software; you can redistribute it and/or modify
   7 *   it under the terms of the GNU General Public License as published by
   8 *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
   9 *   Boston MA 02111-1307, USA; either version 2 of the License, or
  10 *   (at your option) any later version; incorporated herein by reference.
  11 *
  12 * ----------------------------------------------------------------------- */
  13
  14/*
  15 * tilegx$#.c
  16 *
  17 * $#-way unrolled TILE-Gx SIMD for RAID-6 math.
  18 *
  19 * This file is postprocessed using unroll.awk.
  20 *
  21 */
  22
  23#include <linux/raid/pq.h>
  24
  25/* Create 8 byte copies of constant byte */
  26# define NBYTES(x) (__insn_v1addi(0, x))
  27# define NSIZE  8
  28
  29/*
  30 * The SHLBYTE() operation shifts each byte left by 1, *not*
  31 * rolling over into the next byte
  32 */
  33static inline __attribute_const__ u64 SHLBYTE(u64 v)
  34{
  35        /* Vector One Byte Shift Left Immediate. */
  36        return __insn_v1shli(v, 1);
  37}
  38
  39/*
  40 * The MASK() operation returns 0xFF in any byte for which the high
  41 * bit is 1, 0x00 for any byte for which the high bit is 0.
  42 */
  43static inline __attribute_const__ u64 MASK(u64 v)
  44{
  45        /* Vector One Byte Shift Right Signed Immediate. */
  46        return __insn_v1shrsi(v, 7);
  47}
  48
  49
  50void raid6_tilegx$#_gen_syndrome(int disks, size_t bytes, void **ptrs)
  51{
  52        u8 **dptr = (u8 **)ptrs;
  53        u64 *p, *q;
  54        int d, z, z0;
  55
  56        u64 wd$$, wq$$, wp$$, w1$$, w2$$;
  57        u64 x1d = NBYTES(0x1d);
  58        u64 * z0ptr;
  59
  60        z0 = disks - 3;                 /* Highest data disk */
  61        p = (u64 *)dptr[z0+1];  /* XOR parity */
  62        q = (u64 *)dptr[z0+2];  /* RS syndrome */
  63
  64        z0ptr = (u64 *)&dptr[z0][0];
  65        for ( d = 0 ; d < bytes ; d += NSIZE*$# ) {
  66                wq$$ = wp$$ = *z0ptr++;
  67                for ( z = z0-1 ; z >= 0 ; z-- ) {
  68                        wd$$ = *(u64 *)&dptr[z][d+$$*NSIZE];
  69                        wp$$ = wp$$ ^ wd$$;
  70                        w2$$ = MASK(wq$$);
  71                        w1$$ = SHLBYTE(wq$$);
  72                        w2$$ = w2$$ & x1d;
  73                        w1$$ = w1$$ ^ w2$$;
  74                        wq$$ = w1$$ ^ wd$$;
  75                }
  76                *p++ = wp$$;
  77                *q++ = wq$$;
  78        }
  79}
  80
  81const struct raid6_calls raid6_tilegx$# = {
  82        raid6_tilegx$#_gen_syndrome,
  83        NULL,                   /* XOR not yet implemented */
  84        NULL,
  85        "tilegx$#",
  86        0
  87};
  88