1  /* { dg-do run } */
       2  /* { dg-options "-O2 -msha" } */
       3  /* { dg-require-effective-target sha } */
       4  
       5  #include "sha-check.h"
       6  #include "m128-check.h"
       7  #include <x86intrin.h>
       8  #include <immintrin.h>
       9  
      10  static int
      11  f0 (int b, int c, int d)
      12  {
      13    return (b & c) ^ (~b & d);
      14  }
      15  
      16  static int
      17  f1 (int b, int c, int d)
      18  {
      19    return b ^ c ^ d;
      20  }
      21  
      22  static int
      23  f2 (int b, int c, int d)
      24  {
      25    return (b & c) ^ (b & d) ^ (c & d);
      26  }
      27  
      28  int (*f_arr[4])(int, int, int) = { f0, f1, f2, f1 };
      29  const int k_arr[4] = { 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6 };
      30  
      31  
      32  static void
      33  compute_sha1rnds4 (int *src1, int *src2, int imm, int *res)
      34  {
      35    int k = k_arr[imm];
      36    int (*f)(int, int, int) = f_arr[imm];
      37  
      38    int w[4] = { src2[3], src2[2], src2[1], src2[0] };
      39    int a[5], b[5], c[5], d[5], e[5];
      40  
      41    a[0] = src1[3];
      42    b[0] = src1[2];
      43    c[0] = src1[1];
      44    d[0] = src1[0];
      45    e[0] = 0;
      46  
      47    int i;
      48    for (i = 0; i <= 3; i++)
      49      {
      50        a[i+1] = f(b[i], c[i], d[i]) + __rold (a[i], 5) + w[i] + e[i] + k;
      51        b[i+1] = a[i];
      52        c[i+1] = __rold (b[i], 30);
      53        d[i+1] = c[i];
      54        e[i+1] = d[i];
      55      }
      56  
      57    res[0] = d[4];
      58    res[1] = c[4];
      59    res[2] = b[4];
      60    res[3] = a[4];
      61  }
      62  
      63  
      64  static void
      65  sha_test (void)
      66  {
      67    int imm;
      68    union128i_d s1, s2, res;
      69    int res_ref[4];
      70  
      71    s1.x = _mm_set_epi32 (111, 222, 333, 444);
      72    s2.x = _mm_set_epi32 (555, 666, 777, 888);
      73  
      74    res.x = _mm_sha1rnds4_epu32 (s1.x, s2.x, 0);
      75    compute_sha1rnds4 (s1.a, s2.a, 0, res_ref);
      76    if (check_union128i_d (res, res_ref))
      77      abort ();
      78  
      79    res.x = _mm_sha1rnds4_epu32 (s1.x, s2.x, 1);
      80    compute_sha1rnds4 (s1.a, s2.a, 1, res_ref);
      81    if (check_union128i_d (res, res_ref))
      82      abort ();
      83  
      84    res.x = _mm_sha1rnds4_epu32 (s1.x, s2.x, 2);
      85    compute_sha1rnds4 (s1.a, s2.a, 2, res_ref);
      86    if (check_union128i_d (res, res_ref))
      87      abort ();
      88  
      89    res.x = _mm_sha1rnds4_epu32 (s1.x, s2.x, 3);
      90    compute_sha1rnds4 (s1.a, s2.a, 3, res_ref);
      91    if (check_union128i_d (res, res_ref))
      92      abort ();
      93  }