Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0-or-later 2 : // Copyright (C) 2013 Andrea Mazzoleni 3 : 4 : #ifndef __RAID_GF_H 5 : #define __RAID_GF_H 6 : 7 : /* 8 : * Galois field operations. 9 : * 10 : * Basic range checks are implemented using BUG_ON(). 11 : */ 12 : 13 : /* 14 : * GF a*b. 15 : */ 16 : static __always_inline uint8_t mul(uint8_t a, uint8_t b) 17 : { 18 27229406 : return gfmul[a][b]; 19 : } 20 : 21 : /* 22 : * GF 1/a. 23 : * Not defined for a == 0. 24 : */ 25 : static __always_inline uint8_t inv(uint8_t v) 26 : { 27 749006 : BUG_ON(v == 0); /* division by zero */ 28 : 29 749006 : return gfinv[v]; 30 : } 31 : 32 : /* 33 : * GF 2^a. 34 : */ 35 : static __always_inline uint8_t pow2(int v) 36 : { 37 396 : BUG_ON(v < 0 || v > 254); /* invalid exponent */ 38 : 39 396 : return gfexp[v]; 40 : } 41 : 42 : /* 43 : * Gets the multiplication table for a specified value. 44 : */ 45 : static __always_inline const uint8_t *table(uint8_t v) 46 : { 47 407378 : return gfmul[v]; 48 : } 49 : 50 : /* 51 : * Gets the generator matrix coefficient for parity 'p' and disk 'd'. 52 : */ 53 : static __always_inline uint8_t A(int p, int d) 54 : { 55 3033010 : return gfgen[p][d]; 56 : } 57 : 58 : /* 59 : * Dereference as uint8_t 60 : */ 61 : #define v_8(p) (*(uint8_t *)&(p)) 62 : 63 : /* 64 : * Dereference as uint32_t 65 : */ 66 : #define v_32(p) (*(uint32_t *)&(p)) 67 : 68 : /* 69 : * Dereference as uint64_t 70 : */ 71 : #define v_64(p) (*(uint64_t *)&(p)) 72 : 73 : /* 74 : * Multiply each byte of a uint32 by 2 in the GF(2^8). 75 : */ 76 : static __always_inline uint32_t x2_32(uint32_t v) 77 : { 78 36247360 : uint32_t mask = v & 0x80808080U; 79 : 80 36247360 : mask = (mask << 1) - (mask >> 7); 81 36247360 : v = (v << 1) & 0xfefefefeU; 82 36247360 : v ^= mask & 0x1d1d1d1dU; 83 36247360 : return v; 84 : } 85 : 86 : /* 87 : * Multiply each byte of a uint64 by 2 in the GF(2^8). 88 : */ 89 : static __always_inline uint64_t x2_64(uint64_t v) 90 : { 91 33262496 : uint64_t mask = v & 0x8080808080808080ULL; 92 : 93 33262496 : mask = (mask << 1) - (mask >> 7); 94 33262496 : v = (v << 1) & 0xfefefefefefefefeULL; 95 33262496 : v ^= mask & 0x1d1d1d1d1d1d1d1dULL; 96 33262496 : return v; 97 : } 98 : 99 : /* 100 : * Divide each byte of a uint32 by 2 in the GF(2^8). 101 : */ 102 : static __always_inline uint32_t d2_32(uint32_t v) 103 : { 104 14223296 : uint32_t mask = v & 0x01010101U; 105 : 106 14223296 : mask = (mask << 8) - mask; 107 14223296 : v = (v >> 1) & 0x7f7f7f7fU; 108 14223296 : v ^= mask & 0x8e8e8e8eU; 109 14223296 : return v; 110 : } 111 : 112 : /* 113 : * Divide each byte of a uint64 by 2 in the GF(2^8). 114 : */ 115 : static __always_inline uint64_t d2_64(uint64_t v) 116 : { 117 12846048 : uint64_t mask = v & 0x0101010101010101ULL; 118 : 119 12846048 : mask = (mask << 8) - mask; 120 12846048 : v = (v >> 1) & 0x7f7f7f7f7f7f7f7fULL; 121 12846048 : v ^= mask & 0x8e8e8e8e8e8e8e8eULL; 122 12846048 : return v; 123 : } 124 : 125 : #endif 126 :