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) [] = { 0xfff5, 0xfff6, 0xfff7, 0xfff7 };
13 VECT_VAR_DECL(expected,int,32,2) [] = { 0x0, 0x0 };
14 VECT_VAR_DECL(expected,int,16,8) [] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
15 VECT_VAR_DECL(expected,int,32,4) [] = { 0x0, 0x0, 0x0, 0x0 };
16
17 /* Expected values of cumulative_saturation flag when multiplication
18 saturates. */
19 int VECT_VAR(expected_cumulative_sat_mul,int,16,4) = 1;
20 int VECT_VAR(expected_cumulative_sat_mul,int,32,2) = 1;
21 int VECT_VAR(expected_cumulative_sat_mul,int,16,8) = 1;
22 int VECT_VAR(expected_cumulative_sat_mul,int,32,4) = 1;
23
24 /* Expected results when multiplication saturates. */
25 VECT_VAR_DECL(expected_mul,int,16,4) [] = { 0x7fff, 0x7fff, 0x7fff, 0x7fff };
26 VECT_VAR_DECL(expected_mul,int,32,2) [] = { 0x7fffffff, 0x7fffffff };
27 VECT_VAR_DECL(expected_mul,int,16,8) [] = { 0x7fff, 0x7fff, 0x7fff, 0x7fff,
28 0x7fff, 0x7fff, 0x7fff, 0x7fff };
29 VECT_VAR_DECL(expected_mul,int,32,4) [] = { 0x7fffffff, 0x7fffffff,
30 0x7fffffff, 0x7fffffff };
31
32 /* Expected values of cumulative_saturation flag when rounding
33 should not cause saturation. */
34 int VECT_VAR(expected_cumulative_sat_round,int,16,4) = 0;
35 int VECT_VAR(expected_cumulative_sat_round,int,32,2) = 0;
36 int VECT_VAR(expected_cumulative_sat_round,int,16,8) = 0;
37 int VECT_VAR(expected_cumulative_sat_round,int,32,4) = 0;
38
39 /* Expected results when rounding should not cause saturation. */
40 VECT_VAR_DECL(expected_round,int,16,4) [] = { 0x7fff, 0x7fff, 0x7fff, 0x7fff };
41 VECT_VAR_DECL(expected_round,int,32,2) [] = { 0x7fffffff, 0x7fffffff };
42 VECT_VAR_DECL(expected_round,int,16,8) [] = { 0x7fff, 0x7fff, 0x7fff, 0x7fff,
43 0x7fff, 0x7fff, 0x7fff, 0x7fff };
44 VECT_VAR_DECL(expected_round,int,32,4) [] = { 0x7fffffff, 0x7fffffff,
45 0x7fffffff, 0x7fffffff };
46
47 #define INSN vqrdmulh
48 #define TEST_MSG "VQRDMULH"
49
50 #define FNNAME1(NAME) void exec_ ## NAME (void)
51 #define FNNAME(NAME) FNNAME1(NAME)
52
FNNAME(INSN)53 FNNAME (INSN)
54 {
55 /* vector_res = vqrdmulh(vector,vector2), then store the result. */
56 #define TEST_VQRDMULH2(INSN, Q, T1, T2, W, N, EXPECTED_CUMULATIVE_SAT, CMT) \
57 Set_Neon_Cumulative_Sat(0, VECT_VAR(vector_res, T1, W, N)); \
58 VECT_VAR(vector_res, T1, W, N) = \
59 INSN##Q##_##T2##W(VECT_VAR(vector, T1, W, N), \
60 VECT_VAR(vector2, T1, W, N)); \
61 vst1##Q##_##T2##W(VECT_VAR(result, T1, W, N), \
62 VECT_VAR(vector_res, T1, W, N)); \
63 CHECK_CUMULATIVE_SAT(TEST_MSG, T1, W, N, EXPECTED_CUMULATIVE_SAT, CMT)
64
65 /* Two auxliary macros are necessary to expand INSN */
66 #define TEST_VQRDMULH1(INSN, Q, T1, T2, W, N, EXPECTED_CUMULATIVE_SAT, CMT) \
67 TEST_VQRDMULH2(INSN, Q, T1, T2, W, N, EXPECTED_CUMULATIVE_SAT, CMT)
68
69 #define TEST_VQRDMULH(Q, T1, T2, W, N, EXPECTED_CUMULATIVE_SAT, CMT) \
70 TEST_VQRDMULH1(INSN, Q, T1, T2, W, N, EXPECTED_CUMULATIVE_SAT, CMT)
71
72
73 DECL_VARIABLE(vector, int, 16, 4);
74 DECL_VARIABLE(vector, int, 32, 2);
75 DECL_VARIABLE(vector, int, 16, 8);
76 DECL_VARIABLE(vector, int, 32, 4);
77
78 DECL_VARIABLE(vector_res, int, 16, 4);
79 DECL_VARIABLE(vector_res, int, 32, 2);
80 DECL_VARIABLE(vector_res, int, 16, 8);
81 DECL_VARIABLE(vector_res, int, 32, 4);
82
83 DECL_VARIABLE(vector2, int, 16, 4);
84 DECL_VARIABLE(vector2, int, 32, 2);
85 DECL_VARIABLE(vector2, int, 16, 8);
86 DECL_VARIABLE(vector2, int, 32, 4);
87
88 clean_results ();
89
90 VLOAD(vector, buffer, , int, s, 16, 4);
91 VLOAD(vector, buffer, , int, s, 32, 2);
92 VLOAD(vector, buffer, q, int, s, 16, 8);
93 VLOAD(vector, buffer, q, int, s, 32, 4);
94
95 /* Initialize vector2. */
96 VDUP(vector2, , int, s, 16, 4, 0x5555);
97 VDUP(vector2, , int, s, 32, 2, 0xBB);
98 VDUP(vector2, q, int, s, 16, 8, 0x33);
99 VDUP(vector2, q, int, s, 32, 4, 0x22);
100
101 #define CMT ""
102 TEST_VQRDMULH(, int, s, 16, 4, expected_cumulative_sat, CMT);
103 TEST_VQRDMULH(, int, s, 32, 2, expected_cumulative_sat, CMT);
104 TEST_VQRDMULH(q, int, s, 16, 8, expected_cumulative_sat, CMT);
105 TEST_VQRDMULH(q, int, s, 32, 4, expected_cumulative_sat, CMT);
106
107 CHECK(TEST_MSG, int, 16, 4, PRIx16, expected, CMT);
108 CHECK(TEST_MSG, int, 32, 2, PRIx32, expected, CMT);
109 CHECK(TEST_MSG, int, 16, 8, PRIx16, expected, CMT);
110 CHECK(TEST_MSG, int, 32, 4, PRIx32, expected, CMT);
111
112 /* Now use input values such that the multiplication causes
113 saturation. */
114 #define TEST_MSG_MUL " (check mul cumulative saturation)"
115 VDUP(vector, , int, s, 16, 4, 0x8000);
116 VDUP(vector, , int, s, 32, 2, 0x80000000);
117 VDUP(vector, q, int, s, 16, 8, 0x8000);
118 VDUP(vector, q, int, s, 32, 4, 0x80000000);
119 VDUP(vector2, , int, s, 16, 4, 0x8000);
120 VDUP(vector2, , int, s, 32, 2, 0x80000000);
121 VDUP(vector2, q, int, s, 16, 8, 0x8000);
122 VDUP(vector2, q, int, s, 32, 4, 0x80000000);
123
124 TEST_VQRDMULH(, int, s, 16, 4, expected_cumulative_sat_mul, TEST_MSG_MUL);
125 TEST_VQRDMULH(, int, s, 32, 2, expected_cumulative_sat_mul, TEST_MSG_MUL);
126 TEST_VQRDMULH(q, int, s, 16, 8, expected_cumulative_sat_mul, TEST_MSG_MUL);
127 TEST_VQRDMULH(q, int, s, 32, 4, expected_cumulative_sat_mul, TEST_MSG_MUL);
128
129 CHECK(TEST_MSG, int, 16, 4, PRIx16, expected_mul, TEST_MSG_MUL);
130 CHECK(TEST_MSG, int, 32, 2, PRIx32, expected_mul, TEST_MSG_MUL);
131 CHECK(TEST_MSG, int, 16, 8, PRIx16, expected_mul, TEST_MSG_MUL);
132 CHECK(TEST_MSG, int, 32, 4, PRIx32, expected_mul, TEST_MSG_MUL);
133
134 /* Use input values where rounding produces a result equal to the
135 saturation value, but does not set the saturation flag. */
136 #define TEST_MSG_ROUND " (check rounding)"
137 VDUP(vector, , int, s, 16, 4, 0x8000);
138 VDUP(vector, , int, s, 32, 2, 0x80000000);
139 VDUP(vector, q, int, s, 16, 8, 0x8000);
140 VDUP(vector, q, int, s, 32, 4, 0x80000000);
141 VDUP(vector2, , int, s, 16, 4, 0x8001);
142 VDUP(vector2, , int, s, 32, 2, 0x80000001);
143 VDUP(vector2, q, int, s, 16, 8, 0x8001);
144 VDUP(vector2, q, int, s, 32, 4, 0x80000001);
145
146 TEST_VQRDMULH(, int, s, 16, 4, expected_cumulative_sat_round, TEST_MSG_ROUND);
147 TEST_VQRDMULH(, int, s, 32, 2, expected_cumulative_sat_round, TEST_MSG_ROUND);
148 TEST_VQRDMULH(q, int, s, 16, 8, expected_cumulative_sat_round, TEST_MSG_ROUND);
149 TEST_VQRDMULH(q, int, s, 32, 4, expected_cumulative_sat_round, TEST_MSG_ROUND);
150
151 CHECK(TEST_MSG, int, 16, 4, PRIx16, expected_round, TEST_MSG_ROUND);
152 CHECK(TEST_MSG, int, 32, 2, PRIx32, expected_round, TEST_MSG_ROUND);
153 CHECK(TEST_MSG, int, 16, 8, PRIx16, expected_round, TEST_MSG_ROUND);
154 CHECK(TEST_MSG, int, 32, 4, PRIx32, expected_round, TEST_MSG_ROUND);
155 }
156
main(void)157 int main (void)
158 {
159 exec_vqrdmulh ();
160 return 0;
161 }
162