root/arch/s390/crypto/crc32le-vx.S

/* [<][>][^][v][top][bottom][index][help] */
   1 /* SPDX-License-Identifier: GPL-2.0 */
   2 /*
   3  * Hardware-accelerated CRC-32 variants for Linux on z Systems
   4  *
   5  * Use the z/Architecture Vector Extension Facility to accelerate the
   6  * computing of bitreflected CRC-32 checksums for IEEE 802.3 Ethernet
   7  * and Castagnoli.
   8  *
   9  * This CRC-32 implementation algorithm is bitreflected and processes
  10  * the least-significant bit first (Little-Endian).
  11  *
  12  * Copyright IBM Corp. 2015
  13  * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
  14  */
  15 
  16 #include <linux/linkage.h>
  17 #include <asm/nospec-insn.h>
  18 #include <asm/vx-insn.h>
  19 
  20 /* Vector register range containing CRC-32 constants */
  21 #define CONST_PERM_LE2BE        %v9
  22 #define CONST_R2R1              %v10
  23 #define CONST_R4R3              %v11
  24 #define CONST_R5                %v12
  25 #define CONST_RU_POLY           %v13
  26 #define CONST_CRC_POLY          %v14
  27 
  28 .data
  29 .align 8
  30 
  31 /*
  32  * The CRC-32 constant block contains reduction constants to fold and
  33  * process particular chunks of the input data stream in parallel.
  34  *
  35  * For the CRC-32 variants, the constants are precomputed according to
  36  * these definitions:
  37  *
  38  *      R1 = [(x4*128+32 mod P'(x) << 32)]' << 1
  39  *      R2 = [(x4*128-32 mod P'(x) << 32)]' << 1
  40  *      R3 = [(x128+32 mod P'(x) << 32)]'   << 1
  41  *      R4 = [(x128-32 mod P'(x) << 32)]'   << 1
  42  *      R5 = [(x64 mod P'(x) << 32)]'       << 1
  43  *      R6 = [(x32 mod P'(x) << 32)]'       << 1
  44  *
  45  *      The bitreflected Barret reduction constant, u', is defined as
  46  *      the bit reversal of floor(x**64 / P(x)).
  47  *
  48  *      where P(x) is the polynomial in the normal domain and the P'(x) is the
  49  *      polynomial in the reversed (bitreflected) domain.
  50  *
  51  * CRC-32 (IEEE 802.3 Ethernet, ...) polynomials:
  52  *
  53  *      P(x)  = 0x04C11DB7
  54  *      P'(x) = 0xEDB88320
  55  *
  56  * CRC-32C (Castagnoli) polynomials:
  57  *
  58  *      P(x)  = 0x1EDC6F41
  59  *      P'(x) = 0x82F63B78
  60  */
  61 
  62 .Lconstants_CRC_32_LE:
  63         .octa           0x0F0E0D0C0B0A09080706050403020100      # BE->LE mask
  64         .quad           0x1c6e41596, 0x154442bd4                # R2, R1
  65         .quad           0x0ccaa009e, 0x1751997d0                # R4, R3
  66         .octa           0x163cd6124                             # R5
  67         .octa           0x1F7011641                             # u'
  68         .octa           0x1DB710641                             # P'(x) << 1
  69 
  70 .Lconstants_CRC_32C_LE:
  71         .octa           0x0F0E0D0C0B0A09080706050403020100      # BE->LE mask
  72         .quad           0x09e4addf8, 0x740eef02                 # R2, R1
  73         .quad           0x14cd00bd6, 0xf20c0dfe                 # R4, R3
  74         .octa           0x0dd45aab8                             # R5
  75         .octa           0x0dea713f1                             # u'
  76         .octa           0x105ec76f0                             # P'(x) << 1
  77 
  78 .previous
  79 
  80         GEN_BR_THUNK %r14
  81 
  82 .text
  83 
  84 /*
  85  * The CRC-32 functions use these calling conventions:
  86  *
  87  * Parameters:
  88  *
  89  *      %r2:    Initial CRC value, typically ~0; and final CRC (return) value.
  90  *      %r3:    Input buffer pointer, performance might be improved if the
  91  *              buffer is on a doubleword boundary.
  92  *      %r4:    Length of the buffer, must be 64 bytes or greater.
  93  *
  94  * Register usage:
  95  *
  96  *      %r5:    CRC-32 constant pool base pointer.
  97  *      V0:     Initial CRC value and intermediate constants and results.
  98  *      V1..V4: Data for CRC computation.
  99  *      V5..V8: Next data chunks that are fetched from the input buffer.
 100  *      V9:     Constant for BE->LE conversion and shift operations
 101  *
 102  *      V10..V14: CRC-32 constants.
 103  */
 104 
 105 ENTRY(crc32_le_vgfm_16)
 106         larl    %r5,.Lconstants_CRC_32_LE
 107         j       crc32_le_vgfm_generic
 108 ENDPROC(crc32_le_vgfm_16)
 109 
 110 ENTRY(crc32c_le_vgfm_16)
 111         larl    %r5,.Lconstants_CRC_32C_LE
 112         j       crc32_le_vgfm_generic
 113 ENDPROC(crc32c_le_vgfm_16)
 114 
 115 ENTRY(crc32_le_vgfm_generic)
 116         /* Load CRC-32 constants */
 117         VLM     CONST_PERM_LE2BE,CONST_CRC_POLY,0,%r5
 118 
 119         /*
 120          * Load the initial CRC value.
 121          *
 122          * The CRC value is loaded into the rightmost word of the
 123          * vector register and is later XORed with the LSB portion
 124          * of the loaded input data.
 125          */
 126         VZERO   %v0                     /* Clear V0 */
 127         VLVGF   %v0,%r2,3               /* Load CRC into rightmost word */
 128 
 129         /* Load a 64-byte data chunk and XOR with CRC */
 130         VLM     %v1,%v4,0,%r3           /* 64-bytes into V1..V4 */
 131         VPERM   %v1,%v1,%v1,CONST_PERM_LE2BE
 132         VPERM   %v2,%v2,%v2,CONST_PERM_LE2BE
 133         VPERM   %v3,%v3,%v3,CONST_PERM_LE2BE
 134         VPERM   %v4,%v4,%v4,CONST_PERM_LE2BE
 135 
 136         VX      %v1,%v0,%v1             /* V1 ^= CRC */
 137         aghi    %r3,64                  /* BUF = BUF + 64 */
 138         aghi    %r4,-64                 /* LEN = LEN - 64 */
 139 
 140         cghi    %r4,64
 141         jl      .Lless_than_64bytes
 142 
 143 .Lfold_64bytes_loop:
 144         /* Load the next 64-byte data chunk into V5 to V8 */
 145         VLM     %v5,%v8,0,%r3
 146         VPERM   %v5,%v5,%v5,CONST_PERM_LE2BE
 147         VPERM   %v6,%v6,%v6,CONST_PERM_LE2BE
 148         VPERM   %v7,%v7,%v7,CONST_PERM_LE2BE
 149         VPERM   %v8,%v8,%v8,CONST_PERM_LE2BE
 150 
 151         /*
 152          * Perform a GF(2) multiplication of the doublewords in V1 with
 153          * the R1 and R2 reduction constants in V0.  The intermediate result
 154          * is then folded (accumulated) with the next data chunk in V5 and
 155          * stored in V1. Repeat this step for the register contents
 156          * in V2, V3, and V4 respectively.
 157          */
 158         VGFMAG  %v1,CONST_R2R1,%v1,%v5
 159         VGFMAG  %v2,CONST_R2R1,%v2,%v6
 160         VGFMAG  %v3,CONST_R2R1,%v3,%v7
 161         VGFMAG  %v4,CONST_R2R1,%v4,%v8
 162 
 163         aghi    %r3,64                  /* BUF = BUF + 64 */
 164         aghi    %r4,-64                 /* LEN = LEN - 64 */
 165 
 166         cghi    %r4,64
 167         jnl     .Lfold_64bytes_loop
 168 
 169 .Lless_than_64bytes:
 170         /*
 171          * Fold V1 to V4 into a single 128-bit value in V1.  Multiply V1 with R3
 172          * and R4 and accumulating the next 128-bit chunk until a single 128-bit
 173          * value remains.
 174          */
 175         VGFMAG  %v1,CONST_R4R3,%v1,%v2
 176         VGFMAG  %v1,CONST_R4R3,%v1,%v3
 177         VGFMAG  %v1,CONST_R4R3,%v1,%v4
 178 
 179         cghi    %r4,16
 180         jl      .Lfinal_fold
 181 
 182 .Lfold_16bytes_loop:
 183 
 184         VL      %v2,0,,%r3              /* Load next data chunk */
 185         VPERM   %v2,%v2,%v2,CONST_PERM_LE2BE
 186         VGFMAG  %v1,CONST_R4R3,%v1,%v2  /* Fold next data chunk */
 187 
 188         aghi    %r3,16
 189         aghi    %r4,-16
 190 
 191         cghi    %r4,16
 192         jnl     .Lfold_16bytes_loop
 193 
 194 .Lfinal_fold:
 195         /*
 196          * Set up a vector register for byte shifts.  The shift value must
 197          * be loaded in bits 1-4 in byte element 7 of a vector register.
 198          * Shift by 8 bytes: 0x40
 199          * Shift by 4 bytes: 0x20
 200          */
 201         VLEIB   %v9,0x40,7
 202 
 203         /*
 204          * Prepare V0 for the next GF(2) multiplication: shift V0 by 8 bytes
 205          * to move R4 into the rightmost doubleword and set the leftmost
 206          * doubleword to 0x1.
 207          */
 208         VSRLB   %v0,CONST_R4R3,%v9
 209         VLEIG   %v0,1,0
 210 
 211         /*
 212          * Compute GF(2) product of V1 and V0.  The rightmost doubleword
 213          * of V1 is multiplied with R4.  The leftmost doubleword of V1 is
 214          * multiplied by 0x1 and is then XORed with rightmost product.
 215          * Implicitly, the intermediate leftmost product becomes padded
 216          */
 217         VGFMG   %v1,%v0,%v1
 218 
 219         /*
 220          * Now do the final 32-bit fold by multiplying the rightmost word
 221          * in V1 with R5 and XOR the result with the remaining bits in V1.
 222          *
 223          * To achieve this by a single VGFMAG, right shift V1 by a word
 224          * and store the result in V2 which is then accumulated.  Use the
 225          * vector unpack instruction to load the rightmost half of the
 226          * doubleword into the rightmost doubleword element of V1; the other
 227          * half is loaded in the leftmost doubleword.
 228          * The vector register with CONST_R5 contains the R5 constant in the
 229          * rightmost doubleword and the leftmost doubleword is zero to ignore
 230          * the leftmost product of V1.
 231          */
 232         VLEIB   %v9,0x20,7                /* Shift by words */
 233         VSRLB   %v2,%v1,%v9               /* Store remaining bits in V2 */
 234         VUPLLF  %v1,%v1                   /* Split rightmost doubleword */
 235         VGFMAG  %v1,CONST_R5,%v1,%v2      /* V1 = (V1 * R5) XOR V2 */
 236 
 237         /*
 238          * Apply a Barret reduction to compute the final 32-bit CRC value.
 239          *
 240          * The input values to the Barret reduction are the degree-63 polynomial
 241          * in V1 (R(x)), degree-32 generator polynomial, and the reduction
 242          * constant u.  The Barret reduction result is the CRC value of R(x) mod
 243          * P(x).
 244          *
 245          * The Barret reduction algorithm is defined as:
 246          *
 247          *    1. T1(x) = floor( R(x) / x^32 ) GF2MUL u
 248          *    2. T2(x) = floor( T1(x) / x^32 ) GF2MUL P(x)
 249          *    3. C(x)  = R(x) XOR T2(x) mod x^32
 250          *
 251          *  Note: The leftmost doubleword of vector register containing
 252          *  CONST_RU_POLY is zero and, thus, the intermediate GF(2) product
 253          *  is zero and does not contribute to the final result.
 254          */
 255 
 256         /* T1(x) = floor( R(x) / x^32 ) GF2MUL u */
 257         VUPLLF  %v2,%v1
 258         VGFMG   %v2,CONST_RU_POLY,%v2
 259 
 260         /*
 261          * Compute the GF(2) product of the CRC polynomial with T1(x) in
 262          * V2 and XOR the intermediate result, T2(x), with the value in V1.
 263          * The final result is stored in word element 2 of V2.
 264          */
 265         VUPLLF  %v2,%v2
 266         VGFMAG  %v2,CONST_CRC_POLY,%v2,%v1
 267 
 268 .Ldone:
 269         VLGVF   %r2,%v2,2
 270         BR_EX   %r14
 271 ENDPROC(crc32_le_vgfm_generic)
 272 
 273 .previous

/* [<][>][^][v][top][bottom][index][help] */