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
10static int
11f0 (int b, int c, int d)
12{
13  return (b & c) ^ (~b & d);
14}
15
16static int
17f1 (int b, int c, int d)
18{
19  return b ^ c ^ d;
20}
21
22static int
23f2 (int b, int c, int d)
24{
25  return (b & c) ^ (b & d) ^ (c & d);
26}
27
28int (*f_arr[4])(int, int, int) = { f0, f1, f2, f1 };
29const int k_arr[4] = { 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6 };
30
31
32static void
33compute_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
64static void
65sha_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}
94