1 /*
2
3 Copyright (c) 2009, 2010, 2011, 2012 STMicroelectronics
4 Written by Christophe Lyon
5
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 THE SOFTWARE.
23
24 */
25
26 #if defined(__arm__) || defined(__aarch64__)
27 #include <arm_neon.h>
28 #else
29 #include "stm-arm-neon.h"
30 #endif
31
32 #include "stm-arm-neon-ref.h"
33
34 #define INSN vqrshl
35 #define TEST_MSG "VQRSHL/VQRSHLQ"
36
37 #define FNNAME1(NAME) void exec_ ## NAME (void)
38 #define FNNAME(NAME) FNNAME1(NAME)
39
FNNAME(INSN)40 FNNAME (INSN)
41 {
42 /* Basic test: v3=vqrshl(v1,v2), then store the result. */
43 #define TEST_VQRSHL2(INSN, T3, Q, T1, T2, W, N) \
44 Set_Neon_Cumulative_Sat(0, VECT_VAR(vector_res, T1, W, N)); \
45 VECT_VAR(vector_res, T1, W, N) = \
46 INSN##Q##_##T2##W(VECT_VAR(vector, T1, W, N), \
47 VECT_VAR(vector_shift, T3, W, N)); \
48 vst1##Q##_##T2##W(VECT_VAR(result, T1, W, N), \
49 VECT_VAR(vector_res, T1, W, N)); \
50 dump_neon_cumulative_sat(TEST_MSG, xSTR(INSN##Q##_##T2##W), \
51 xSTR(T1), W, N)
52
53 /* Two auxliary macros are necessary to expand INSN */
54 #define TEST_VQRSHL1(INSN, T3, Q, T1, T2, W, N) \
55 TEST_VQRSHL2(INSN, T3, Q, T1, T2, W, N)
56
57 #define TEST_VQRSHL(T3, Q, T1, T2, W, N) \
58 TEST_VQRSHL1(INSN, T3, Q, T1, T2, W, N)
59
60
61 /* With ARM RVCT, we need to declare variables before any executable
62 statement */
63 DECL_VARIABLE_ALL_VARIANTS(vector);
64 DECL_VARIABLE_ALL_VARIANTS(vector_res);
65
66 DECL_VARIABLE_SIGNED_VARIANTS(vector_shift);
67
68 clean_results ();
69
70 /* Fill input vector with 0, to check saturation on limits */
71 VDUP(vector, , int, s, 8, 8, 0);
72 VDUP(vector, , int, s, 16, 4, 0);
73 VDUP(vector, , int, s, 32, 2, 0);
74 VDUP(vector, , int, s, 64, 1, 0);
75 VDUP(vector, , uint, u, 8, 8, 0);
76 VDUP(vector, , uint, u, 16, 4, 0);
77 VDUP(vector, , uint, u, 32, 2, 0);
78 VDUP(vector, , uint, u, 64, 1, 0);
79 VDUP(vector, q, int, s, 8, 16, 0);
80 VDUP(vector, q, int, s, 16, 8, 0);
81 VDUP(vector, q, int, s, 32, 4, 0);
82 VDUP(vector, q, int, s, 64, 2, 0);
83 VDUP(vector, q, uint, u, 8, 16, 0);
84 VDUP(vector, q, uint, u, 16, 8, 0);
85 VDUP(vector, q, uint, u, 32, 4, 0);
86 VDUP(vector, q, uint, u, 64, 2, 0);
87
88 /* Choose init value arbitrarily, will be used as shift amount */
89 /* Use values equal or one-less-than the type width to check
90 behaviour on limits */
91 VDUP(vector_shift, , int, s, 8, 8, 7);
92 VDUP(vector_shift, , int, s, 16, 4, 15);
93 VDUP(vector_shift, , int, s, 32, 2, 31);
94 VDUP(vector_shift, , int, s, 64, 1, 63);
95 VDUP(vector_shift, q, int, s, 8, 16, 8);
96 VDUP(vector_shift, q, int, s, 16, 8, 16);
97 VDUP(vector_shift, q, int, s, 32, 4, 32);
98 VDUP(vector_shift, q, int, s, 64, 2, 64);
99
100 fprintf(ref_file, "\n%s cumulative saturation output:\n",
101 TEST_MSG " (with input = 0)");
102 TEST_MACRO_ALL_VARIANTS_1_5(TEST_VQRSHL, int);
103 dump_results_hex2 (TEST_MSG, " (with input = 0)");
104
105 /* Use negative shift amounts */
106 VDUP(vector_shift, , int, s, 8, 8, -1);
107 VDUP(vector_shift, , int, s, 16, 4, -2);
108 VDUP(vector_shift, , int, s, 32, 2, -3);
109 VDUP(vector_shift, , int, s, 64, 1, -4);
110 VDUP(vector_shift, q, int, s, 8, 16, -7);
111 VDUP(vector_shift, q, int, s, 16, 8, -11);
112 VDUP(vector_shift, q, int, s, 32, 4, -13);
113 VDUP(vector_shift, q, int, s, 64, 2, -20);
114
115 fprintf(ref_file, "\n%s cumulative saturation output:\n",
116 TEST_MSG " (input 0 and negative shift amount)");
117 TEST_MACRO_ALL_VARIANTS_1_5(TEST_VQRSHL, int);
118 dump_results_hex2 (TEST_MSG, " (input 0 and negative shift amount)");
119
120 /* Test again, with predefined input values */
121 TEST_MACRO_ALL_VARIANTS_2_5(VLOAD, vector, buffer);
122
123 /* Choose init value arbitrarily, will be used as shift amount */
124 VDUP(vector_shift, , int, s, 8, 8, 1);
125 VDUP(vector_shift, , int, s, 16, 4, 3);
126 VDUP(vector_shift, , int, s, 32, 2, 8);
127 VDUP(vector_shift, , int, s, 64, 1, 3);
128 VDUP(vector_shift, q, int, s, 8, 16, 10);
129 VDUP(vector_shift, q, int, s, 16, 8, 12);
130 VDUP(vector_shift, q, int, s, 32, 4, 31);
131 VDUP(vector_shift, q, int, s, 64, 2, 63);
132
133 fprintf(ref_file, "\n%s cumulative saturation output:\n", TEST_MSG);
134 TEST_MACRO_ALL_VARIANTS_1_5(TEST_VQRSHL, int);
135 dump_results_hex (TEST_MSG);
136
137 /* Use negative shift amounts */
138 VDUP(vector_shift, , int, s, 8, 8, -2);
139 VDUP(vector_shift, , int, s, 16, 4, -2);
140 VDUP(vector_shift, , int, s, 32, 2, -3);
141 VDUP(vector_shift, , int, s, 64, 1, -4);
142 VDUP(vector_shift, q, int, s, 8, 16, -7);
143 VDUP(vector_shift, q, int, s, 16, 8, -11);
144 VDUP(vector_shift, q, int, s, 32, 4, -13);
145 VDUP(vector_shift, q, int, s, 64, 2, -20);
146
147 fprintf(ref_file, "\n%s cumulative saturation output:\n",
148 TEST_MSG " (negative shift amount)");
149 TEST_MACRO_ALL_VARIANTS_1_5(TEST_VQRSHL, int);
150 dump_results_hex2 (TEST_MSG, " (negative shift amount)");
151
152
153 /* Fill input vector with max value, to check saturation on limits */
154 VDUP(vector, , int, s, 8, 8, 0x7F);
155 VDUP(vector, , int, s, 16, 4, 0x7FFF);
156 VDUP(vector, , int, s, 32, 2, 0x7FFFFFFF);
157 VDUP(vector, , int, s, 64, 1, 0x7FFFFFFFFFFFFFFFLL);
158 VDUP(vector, , uint, u, 8, 8, 0xFF);
159 VDUP(vector, , uint, u, 16, 4, 0xFFFF);
160 VDUP(vector, , uint, u, 32, 2, 0xFFFFFFFF);
161 VDUP(vector, , uint, u, 64, 1, 0xFFFFFFFFFFFFFFFFULL);
162 VDUP(vector, q, int, s, 8, 16, 0x7F);
163 VDUP(vector, q, int, s, 16, 8, 0x7FFF);
164 VDUP(vector, q, int, s, 32, 4, 0x7FFFFFFF);
165 VDUP(vector, q, int, s, 64, 2, 0x7FFFFFFFFFFFFFFFLL);
166 VDUP(vector, q, uint, u, 8, 16, 0xFF);
167 VDUP(vector, q, uint, u, 16, 8, 0xFFFF);
168 VDUP(vector, q, uint, u, 32, 4, 0xFFFFFFFF);
169 VDUP(vector, q, uint, u, 64, 2, 0xFFFFFFFFFFFFFFFFULL);
170
171 /* Use -1 shift amount to check cumulative saturation with round_const */
172 VDUP(vector_shift, , int, s, 8, 8, -1);
173 VDUP(vector_shift, , int, s, 16, 4, -1);
174 VDUP(vector_shift, , int, s, 32, 2, -1);
175 VDUP(vector_shift, , int, s, 64, 1, -1);
176 VDUP(vector_shift, q, int, s, 8, 16, -1);
177 VDUP(vector_shift, q, int, s, 16, 8, -1);
178 VDUP(vector_shift, q, int, s, 32, 4, -1);
179 VDUP(vector_shift, q, int, s, 64, 2, -1);
180
181 fprintf(ref_file, "\n%s cumulative saturation output:\n",
182 TEST_MSG " (checking cumulative saturation: shift by -1)");
183 TEST_MACRO_ALL_VARIANTS_1_5(TEST_VQRSHL, int);
184 dump_results_hex2 (TEST_MSG,
185 " (checking cumulative saturation: shift by -1)");
186
187
188 /* Use -3 shift amount to check cumulative saturation with round_const */
189 VDUP(vector_shift, , int, s, 8, 8, -3);
190 VDUP(vector_shift, , int, s, 16, 4, -3);
191 VDUP(vector_shift, , int, s, 32, 2, -3);
192 VDUP(vector_shift, , int, s, 64, 1, -3);
193 VDUP(vector_shift, q, int, s, 8, 16, -3);
194 VDUP(vector_shift, q, int, s, 16, 8, -3);
195 VDUP(vector_shift, q, int, s, 32, 4, -3);
196 VDUP(vector_shift, q, int, s, 64, 2, -3);
197
198 fprintf(ref_file, "\n%s cumulative saturation output:\n",
199 TEST_MSG " (checking cumulative saturation: shift by -3)");
200 TEST_MACRO_ALL_VARIANTS_1_5(TEST_VQRSHL, int);
201 dump_results_hex2 (TEST_MSG,
202 " (checking cumulative saturation: shift by -3)");
203
204
205 /* Use large shift amount */
206 VDUP(vector_shift, , int, s, 8, 8, 10);
207 VDUP(vector_shift, , int, s, 16, 4, 20);
208 VDUP(vector_shift, , int, s, 32, 2, 40);
209 VDUP(vector_shift, , int, s, 64, 1, 70);
210 VDUP(vector_shift, q, int, s, 8, 16, 10);
211 VDUP(vector_shift, q, int, s, 16, 8, 20);
212 VDUP(vector_shift, q, int, s, 32, 4, 40);
213 VDUP(vector_shift, q, int, s, 64, 2, 70);
214
215 fprintf(ref_file, "\n%s cumulative saturation output:\n",
216 TEST_MSG " (checking cumulative saturation: large shift amount)");
217 TEST_MACRO_ALL_VARIANTS_1_5(TEST_VQRSHL, int);
218 dump_results_hex2 (TEST_MSG,
219 " (checking cumulative saturation: large shift amount)");
220
221
222 /* Fill input vector with negative values, to check saturation on limits */
223 VDUP(vector, , int, s, 8, 8, 0x80);
224 VDUP(vector, , int, s, 16, 4, 0x8000);
225 VDUP(vector, , int, s, 32, 2, 0x80000000);
226 VDUP(vector, , int, s, 64, 1, 0x8000000000000000LL);
227 VDUP(vector, q, int, s, 8, 16, 0x80);
228 VDUP(vector, q, int, s, 16, 8, 0x8000);
229 VDUP(vector, q, int, s, 32, 4, 0x80000000);
230 VDUP(vector, q, int, s, 64, 2, 0x8000000000000000LL);
231
232 /* Use large shift amount */
233 VDUP(vector_shift, , int, s, 8, 8, 10);
234 VDUP(vector_shift, , int, s, 16, 4, 20);
235 VDUP(vector_shift, , int, s, 32, 2, 40);
236 VDUP(vector_shift, , int, s, 64, 1, 70);
237 VDUP(vector_shift, q, int, s, 8, 16, 10);
238 VDUP(vector_shift, q, int, s, 16, 8, 20);
239 VDUP(vector_shift, q, int, s, 32, 4, 40);
240 VDUP(vector_shift, q, int, s, 64, 2, 70);
241
242 fprintf(ref_file, "\n%s cumulative saturation output:\n",
243 TEST_MSG " (checking cumulative saturation: large shift amount with negative input)");
244 TEST_MACRO_ALL_VARIANTS_1_5(TEST_VQRSHL, int);
245 dump_results_hex2 (TEST_MSG,
246 " (checking cumulative saturation: large shift amount with negative input)");
247
248
249 /* Fill input vector with negative and positive values, to check
250 * saturation on limits */
251 VDUP(vector, , int, s, 8, 8, 0x7F);
252 VDUP(vector, , int, s, 16, 4, 0x7FFF);
253 VDUP(vector, , int, s, 32, 2, 0x7FFFFFFF);
254 VDUP(vector, , int, s, 64, 1, 0x7FFFFFFFFFFFFFFFLL);
255 VDUP(vector, q, int, s, 8, 16, 0x80);
256 VDUP(vector, q, int, s, 16, 8, 0x8000);
257 VDUP(vector, q, int, s, 32, 4, 0x80000000);
258 VDUP(vector, q, int, s, 64, 2, 0x8000000000000000LL);
259
260 /* Use large negative shift amount */
261 VDUP(vector_shift, , int, s, 8, 8, -10);
262 VDUP(vector_shift, , int, s, 16, 4, -20);
263 VDUP(vector_shift, , int, s, 32, 2, -40);
264 VDUP(vector_shift, , int, s, 64, 1, -70);
265 VDUP(vector_shift, q, int, s, 8, 16, -10);
266 VDUP(vector_shift, q, int, s, 16, 8, -20);
267 VDUP(vector_shift, q, int, s, 32, 4, -40);
268 VDUP(vector_shift, q, int, s, 64, 2, -70);
269
270 fprintf(ref_file, "\n%s cumulative saturation output:\n",
271 TEST_MSG " (checking cumulative saturation: large negative shift amount)");
272 TEST_MACRO_ALL_VARIANTS_1_5(TEST_VQRSHL, int);
273 dump_results_hex2 (TEST_MSG,
274 " (checking cumulative saturation: large negative shift amount)");
275
276
277 /* Fill input vector with 0, to check saturation in case of large
278 * shift amount */
279 VDUP(vector, , int, s, 8, 8, 0);
280 VDUP(vector, , int, s, 16, 4, 0);
281 VDUP(vector, , int, s, 32, 2, 0);
282 VDUP(vector, , int, s, 64, 1, 0);
283 VDUP(vector, q, int, s, 8, 16, 0);
284 VDUP(vector, q, int, s, 16, 8, 0);
285 VDUP(vector, q, int, s, 32, 4, 0);
286 VDUP(vector, q, int, s, 64, 2, 0);
287
288 /* Use large shift amount */
289 VDUP(vector_shift, , int, s, 8, 8, -10);
290 VDUP(vector_shift, , int, s, 16, 4, -20);
291 VDUP(vector_shift, , int, s, 32, 2, -40);
292 VDUP(vector_shift, , int, s, 64, 1, -70);
293 VDUP(vector_shift, q, int, s, 8, 16, -10);
294 VDUP(vector_shift, q, int, s, 16, 8, -20);
295 VDUP(vector_shift, q, int, s, 32, 4, -40);
296 VDUP(vector_shift, q, int, s, 64, 2, -70);
297
298 fprintf(ref_file, "\n%s cumulative saturation output:\n",
299 TEST_MSG " (checking cumulative saturation: large shift amount with 0 input)");
300 TEST_MACRO_ALL_VARIANTS_1_5(TEST_VQRSHL, int);
301 dump_results_hex2 (TEST_MSG,
302 " (checking cumulative saturation: large shift amount with 0 input)");
303 }
304