2235e745dc4d4dd7a4ed7773376f424980b098cd
[gcc.git] / gcc / testsuite / gcc.target / aarch64 / advsimd-intrinsics / vqrdmulh_lane.c
1 #include <arm_neon.h>
2 #include "arm-neon-ref.h"
3 #include "compute-ref-data.h"
4
5 /* Expected values of cumulative_saturation flag. */
6 int VECT_VAR(expected_cumulative_sat,int,16,4) = 0;
7 int VECT_VAR(expected_cumulative_sat,int,32,2) = 0;
8 int VECT_VAR(expected_cumulative_sat,int,16,8) = 0;
9 int VECT_VAR(expected_cumulative_sat,int,32,4) = 0;
10
11 /* Expected results. */
12 VECT_VAR_DECL(expected,int,16,4) [] = { 0x0, 0x0, 0x0, 0x0 };
13 VECT_VAR_DECL(expected,int,32,2) [] = { 0x0, 0x0 };
14 VECT_VAR_DECL(expected,int,16,8) [] = { 0x0, 0x0, 0x0, 0x0,
15 0x0, 0x0, 0x0, 0x0 };
16 VECT_VAR_DECL(expected,int,32,4) [] = { 0x0, 0x0, 0x0, 0x0 };
17
18 /* Expected values of cumulative_saturation flag when multiplication
19 saturates. */
20 int VECT_VAR(expected_cumulative_sat_mul,int,16,4) = 1;
21 int VECT_VAR(expected_cumulative_sat_mul,int,32,2) = 1;
22 int VECT_VAR(expected_cumulative_sat_mul,int,16,8) = 1;
23 int VECT_VAR(expected_cumulative_sat_mul,int,32,4) = 1;
24
25 /* Expected results when multiplication saturates. */
26 VECT_VAR_DECL(expected_mul,int,16,4) [] = { 0x7fff, 0x7fff, 0x7fff, 0x7fff };
27 VECT_VAR_DECL(expected_mul,int,32,2) [] = { 0x7fffffff, 0x7fffffff };
28 VECT_VAR_DECL(expected_mul,int,16,8) [] = { 0x7fff, 0x7fff, 0x7fff, 0x7fff,
29 0x7fff, 0x7fff, 0x7fff, 0x7fff };
30 VECT_VAR_DECL(expected_mul,int,32,4) [] = { 0x7fffffff, 0x7fffffff,
31 0x7fffffff, 0x7fffffff };
32
33 /* Expected values of cumulative_saturation flag when rounding
34 should not cause saturation. */
35 int VECT_VAR(expected_cumulative_sat_round,int,16,4) = 0;
36 int VECT_VAR(expected_cumulative_sat_round,int,32,2) = 0;
37 int VECT_VAR(expected_cumulative_sat_round,int,16,8) = 0;
38 int VECT_VAR(expected_cumulative_sat_round,int,32,4) = 0;
39
40 /* Expected results when rounding should not cause saturation. */
41 VECT_VAR_DECL(expected_round,int,16,4) [] = { 0x7fff, 0x7fff, 0x7fff, 0x7fff };
42 VECT_VAR_DECL(expected_round,int,32,2) [] = { 0x7fffffff, 0x7fffffff };
43 VECT_VAR_DECL(expected_round,int,16,8) [] = { 0x7fff, 0x7fff, 0x7fff, 0x7fff,
44 0x7fff, 0x7fff, 0x7fff, 0x7fff };
45 VECT_VAR_DECL(expected_round,int,32,4) [] = { 0x7fffffff, 0x7fffffff,
46 0x7fffffff, 0x7fffffff };
47
48 #define INSN vqrdmulh
49 #define TEST_MSG "VQRDMULH_LANE"
50
51 #define FNNAME1(NAME) void exec_ ## NAME ## _lane (void)
52 #define FNNAME(NAME) FNNAME1(NAME)
53
54 FNNAME (INSN)
55 {
56 /* vector_res = vqrdmulh_lane(vector,vector2,lane), then store the result. */
57 #define TEST_VQRDMULH_LANE2(INSN, Q, T1, T2, W, N, N2, L, EXPECTED_CUMULATIVE_SAT, CMT) \
58 Set_Neon_Cumulative_Sat(0, VECT_VAR(vector_res, T1, W, N)); \
59 VECT_VAR(vector_res, T1, W, N) = \
60 INSN##Q##_lane_##T2##W(VECT_VAR(vector, T1, W, N), \
61 VECT_VAR(vector2, T1, W, N2), \
62 L); \
63 vst1##Q##_##T2##W(VECT_VAR(result, T1, W, N), \
64 VECT_VAR(vector_res, T1, W, N)); \
65 CHECK_CUMULATIVE_SAT(TEST_MSG, T1, W, N, EXPECTED_CUMULATIVE_SAT, CMT)
66
67 /* Two auxliary macros are necessary to expand INSN */
68 #define TEST_VQRDMULH_LANE1(INSN, Q, T1, T2, W, N, N2, L, EXPECTED_CUMULATIVE_SAT, CMT) \
69 TEST_VQRDMULH_LANE2(INSN, Q, T1, T2, W, N, N2, L, EXPECTED_CUMULATIVE_SAT, CMT)
70
71 #define TEST_VQRDMULH_LANE(Q, T1, T2, W, N, N2, L, EXPECTED_CUMULATIVE_SAT, CMT) \
72 TEST_VQRDMULH_LANE1(INSN, Q, T1, T2, W, N, N2, L, EXPECTED_CUMULATIVE_SAT, CMT)
73
74
75 DECL_VARIABLE(vector, int, 16, 4);
76 DECL_VARIABLE(vector, int, 32, 2);
77 DECL_VARIABLE(vector, int, 16, 8);
78 DECL_VARIABLE(vector, int, 32, 4);
79
80 DECL_VARIABLE(vector_res, int, 16, 4);
81 DECL_VARIABLE(vector_res, int, 32, 2);
82 DECL_VARIABLE(vector_res, int, 16, 8);
83 DECL_VARIABLE(vector_res, int, 32, 4);
84
85 /* vector2: vqrdmulh_lane and vqrdmulhq_lane have a 2nd argument with
86 the same number of elements, so we need only one variable of each
87 type. */
88 DECL_VARIABLE(vector2, int, 16, 4);
89 DECL_VARIABLE(vector2, int, 32, 2);
90
91 clean_results ();
92
93 VLOAD(vector, buffer, , int, s, 16, 4);
94 VLOAD(vector, buffer, , int, s, 32, 2);
95
96 VLOAD(vector, buffer, q, int, s, 16, 8);
97 VLOAD(vector, buffer, q, int, s, 32, 4);
98
99 /* Initialize vector2. */
100 VDUP(vector2, , int, s, 16, 4, 0x55);
101 VDUP(vector2, , int, s, 32, 2, 0xBB);
102
103 /* Choose lane arbitrarily. */
104 #define CMT ""
105 TEST_VQRDMULH_LANE(, int, s, 16, 4, 4, 2, expected_cumulative_sat, CMT);
106 TEST_VQRDMULH_LANE(, int, s, 32, 2, 2, 1, expected_cumulative_sat, CMT);
107 TEST_VQRDMULH_LANE(q, int, s, 16, 8, 4, 3, expected_cumulative_sat, CMT);
108 TEST_VQRDMULH_LANE(q, int, s, 32, 4, 2, 0, expected_cumulative_sat, CMT);
109
110 CHECK(TEST_MSG, int, 16, 4, PRIx16, expected, CMT);
111 CHECK(TEST_MSG, int, 32, 2, PRIx32, expected, CMT);
112 CHECK(TEST_MSG, int, 16, 8, PRIx16, expected, CMT);
113 CHECK(TEST_MSG, int, 32, 4, PRIx32, expected, CMT);
114
115 /* Now use input values such that the multiplication causes
116 saturation. */
117 #define TEST_MSG_MUL " (check mul cumulative saturation)"
118 VDUP(vector, , int, s, 16, 4, 0x8000);
119 VDUP(vector, , int, s, 32, 2, 0x80000000);
120 VDUP(vector, q, int, s, 16, 8, 0x8000);
121 VDUP(vector, q, int, s, 32, 4, 0x80000000);
122 VDUP(vector2, , int, s, 16, 4, 0x8000);
123 VDUP(vector2, , int, s, 32, 2, 0x80000000);
124
125 TEST_VQRDMULH_LANE(, int, s, 16, 4, 4, 2, expected_cumulative_sat_mul,
126 TEST_MSG_MUL);
127 TEST_VQRDMULH_LANE(, int, s, 32, 2, 2, 1, expected_cumulative_sat_mul,
128 TEST_MSG_MUL);
129 TEST_VQRDMULH_LANE(q, int, s, 16, 8, 4, 3, expected_cumulative_sat_mul,
130 TEST_MSG_MUL);
131 TEST_VQRDMULH_LANE(q, int, s, 32, 4, 2, 0, expected_cumulative_sat_mul,
132 TEST_MSG_MUL);
133
134 CHECK(TEST_MSG, int, 16, 4, PRIx16, expected_mul, TEST_MSG_MUL);
135 CHECK(TEST_MSG, int, 32, 2, PRIx32, expected_mul, TEST_MSG_MUL);
136 CHECK(TEST_MSG, int, 16, 8, PRIx16, expected_mul, TEST_MSG_MUL);
137 CHECK(TEST_MSG, int, 32, 4, PRIx32, expected_mul, TEST_MSG_MUL);
138
139 VDUP(vector, , int, s, 16, 4, 0x8000);
140 VDUP(vector, , int, s, 32, 2, 0x80000000);
141 VDUP(vector, q, int, s, 16, 8, 0x8000);
142 VDUP(vector, q, int, s, 32, 4, 0x80000000);
143 VDUP(vector2, , int, s, 16, 4, 0x8001);
144 VDUP(vector2, , int, s, 32, 2, 0x80000001);
145
146 /* Use input values where rounding produces a result equal to the
147 saturation value, but does not set the saturation flag. */
148 #define TEST_MSG_ROUND " (check rounding)"
149 TEST_VQRDMULH_LANE(, int, s, 16, 4, 4, 2, expected_cumulative_sat_round,
150 TEST_MSG_ROUND);
151 TEST_VQRDMULH_LANE(, int, s, 32, 2, 2, 1, expected_cumulative_sat_round,
152 TEST_MSG_ROUND);
153 TEST_VQRDMULH_LANE(q, int, s, 16, 8, 4, 3, expected_cumulative_sat_round,
154 TEST_MSG_ROUND);
155 TEST_VQRDMULH_LANE(q, int, s, 32, 4, 2, 0, expected_cumulative_sat_round,
156 TEST_MSG_ROUND);
157
158 CHECK(TEST_MSG, int, 16, 4, PRIx16, expected_round, TEST_MSG_ROUND);
159 CHECK(TEST_MSG, int, 32, 2, PRIx32, expected_round, TEST_MSG_ROUND);
160 CHECK(TEST_MSG, int, 16, 8, PRIx16, expected_round, TEST_MSG_ROUND);
161 CHECK(TEST_MSG, int, 32, 4, PRIx32, expected_round, TEST_MSG_ROUND);
162 }
163
164 int main (void)
165 {
166 exec_vqrdmulh_lane ();
167 return 0;
168 }
169