1 #include <arm_neon.h>
2 #include "arm-neon-ref.h"
3 #include "compute-ref-data.h"
4 #include <math.h>
5 
6 /* Expected results for vcvt.  */
7 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
8 VECT_VAR_DECL(expected_s, hfloat, 16, 4) [] =
9 { 0xcc00, 0xcb80, 0xcb00, 0xca80 };
10 VECT_VAR_DECL(expected_u, hfloat, 16, 4) [] =
11 { 0x7c00, 0x7c00, 0x7c00, 0x7c00, };
12 VECT_VAR_DECL(expected_s, hfloat, 16, 8) [] =
13 { 0xcc00, 0xcb80, 0xcb00, 0xca80,
14   0xca00, 0xc980, 0xc900, 0xc880 };
15 VECT_VAR_DECL(expected_u, hfloat, 16, 8) [] =
16 { 0x7c00, 0x7c00, 0x7c00, 0x7c00,
17   0x7c00, 0x7c00, 0x7c00, 0x7c00, };
18 #endif
19 VECT_VAR_DECL(expected_s,hfloat,32,2) [] = { 0xc1800000, 0xc1700000 };
20 VECT_VAR_DECL(expected_u,hfloat,32,2) [] = { 0x4f800000, 0x4f800000 };
21 VECT_VAR_DECL(expected_s,hfloat,32,4) [] = { 0xc1800000, 0xc1700000,
22 					     0xc1600000, 0xc1500000 };
23 VECT_VAR_DECL(expected_u,hfloat,32,4) [] = { 0x4f800000, 0x4f800000,
24 					     0x4f800000, 0x4f800000 };
25 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
26 VECT_VAR_DECL(expected, int, 16, 4) [] = { 0xfff1, 0x5, 0xfff1, 0x5 };
27 VECT_VAR_DECL(expected, uint, 16, 4) [] = { 0x0, 0x5, 0x0, 0x5 };
28 VECT_VAR_DECL(expected, int, 16, 8) [] = { 0x0, 0x0, 0xf, 0xfff1,
29 					   0x0, 0x0, 0xf, 0xfff1 };
30 VECT_VAR_DECL(expected, uint, 16, 8) [] = { 0x0, 0x0, 0xf, 0x0,
31 					    0x0, 0x0, 0xf, 0x0 };
32 #endif
33 VECT_VAR_DECL(expected,int,32,2) [] = { 0xfffffff1, 0x5 };
34 VECT_VAR_DECL(expected,uint,32,2) [] = { 0x0, 0x5 };
35 VECT_VAR_DECL(expected,int,32,4) [] = { 0x0, 0x0, 0xf, 0xfffffff1 };
36 VECT_VAR_DECL(expected,uint,32,4) [] = { 0x0, 0x0, 0xf, 0x0 };
37 
38 /* Expected results for vcvt_n.  */
39 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
40 VECT_VAR_DECL(expected_vcvt_n_s, hfloat, 16, 4) [] = { 0xc400, 0xc380,
41 						       0xc300, 0xc280 };
42 VECT_VAR_DECL(expected_vcvt_n_u, hfloat, 16, 4) [] = { 0x6000, 0x6000,
43 						       0x6000, 0x6000 };
44 VECT_VAR_DECL(expected_vcvt_n_s, hfloat, 16, 8) [] = { 0xb000, 0xaf80,
45 						       0xaf00, 0xae80,
46 						       0xae00, 0xad80,
47 						       0xad00, 0xac80 };
48 VECT_VAR_DECL(expected_vcvt_n_u, hfloat, 16, 8) [] = { 0x4c00, 0x4c00,
49 						       0x4c00, 0x4c00,
50 						       0x4c00, 0x4c00,
51 						       0x4c00, 0x4c00 };
52 #endif
53 VECT_VAR_DECL(expected_vcvt_n_s,hfloat,32,2) [] = { 0xc0800000, 0xc0700000 };
54 VECT_VAR_DECL(expected_vcvt_n_u,hfloat,32,2) [] = { 0x4c000000, 0x4c000000 };
55 VECT_VAR_DECL(expected_vcvt_n_s,hfloat,32,4) [] = { 0xb2800000, 0xb2700000,
56 						  0xb2600000, 0xb2500000 };
57 VECT_VAR_DECL(expected_vcvt_n_u,hfloat,32,4) [] = { 0x49800000, 0x49800000,
58 						  0x49800000, 0x49800000 };
59 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
60 VECT_VAR_DECL(expected_vcvt_n, int, 16, 4) [] = { 0xffc3, 0x15,
61 						  0xffc3, 0x15 };
62 VECT_VAR_DECL(expected_vcvt_n, uint, 16, 4) [] = { 0x0, 0x2a6, 0x0, 0x2a6 };
63 VECT_VAR_DECL(expected_vcvt_n, int, 16, 8) [] = { 0x0, 0x0, 0x78f, 0xf871,
64 						  0x0, 0x0, 0x78f, 0xf871 };
65 VECT_VAR_DECL(expected_vcvt_n, uint, 16, 8) [] = { 0x0, 0x0, 0xf1e0, 0x0,
66 						   0x0, 0x0, 0xf1e0, 0x0 };
67 #endif
68 VECT_VAR_DECL(expected_vcvt_n,int,32,2) [] = { 0xff0b3333, 0x54cccd };
69 VECT_VAR_DECL(expected_vcvt_n,uint,32,2) [] = { 0x0, 0x15 };
70 VECT_VAR_DECL(expected_vcvt_n,int,32,4) [] = { 0x0, 0x0, 0x1e3d7, 0xfffe1c29 };
71 VECT_VAR_DECL(expected_vcvt_n,uint,32,4) [] = { 0x0, 0x0, 0x1e, 0x0 };
72 
73 /* Expected results for vcvt with rounding.  */
74 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
75 VECT_VAR_DECL(expected_rounding, int, 16, 4) [] = { 0xa, 0xa, 0xa, 0xa };
76 VECT_VAR_DECL(expected_rounding, uint, 16, 4) [] = { 0xa, 0xa, 0xa, 0xa };
77 VECT_VAR_DECL(expected_rounding, int, 16, 8) [] = { 0x7d, 0x7d, 0x7d, 0x7d,
78 						    0x7d, 0x7d, 0x7d, 0x7d };
79 VECT_VAR_DECL(expected_rounding, uint, 16, 8) [] = { 0x7d, 0x7d, 0x7d, 0x7d,
80 						     0x7d, 0x7d, 0x7d, 0x7d };
81 #endif
82 VECT_VAR_DECL(expected_rounding,int,32,2) [] = { 0xa, 0xa };
83 VECT_VAR_DECL(expected_rounding,uint,32,2) [] = { 0xa, 0xa };
84 VECT_VAR_DECL(expected_rounding,int,32,4) [] = { 0x7d, 0x7d, 0x7d, 0x7d };
85 VECT_VAR_DECL(expected_rounding,uint,32,4) [] = { 0x7d, 0x7d, 0x7d, 0x7d };
86 
87 /* Expected results for vcvt_n with rounding.  */
88 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
89 VECT_VAR_DECL(expected_vcvt_n_rounding, int, 16, 4) [] =
90 { 0x533, 0x533, 0x533, 0x533 };
91 VECT_VAR_DECL(expected_vcvt_n_rounding, uint, 16, 4) [] =
92 { 0x533, 0x533, 0x533, 0x533 };
93 VECT_VAR_DECL(expected_vcvt_n_rounding, int, 16, 8) [] =
94 { 0x7fff, 0x7fff, 0x7fff, 0x7fff,
95   0x7fff, 0x7fff, 0x7fff, 0x7fff };
96 VECT_VAR_DECL(expected_vcvt_n_rounding, uint, 16, 8) [] =
97 { 0xffff, 0xffff, 0xffff, 0xffff,
98   0xffff, 0xffff, 0xffff, 0xffff };
99 #endif
100 VECT_VAR_DECL(expected_vcvt_n_rounding,int,32,2) [] = { 0xa66666, 0xa66666 };
101 VECT_VAR_DECL(expected_vcvt_n_rounding,uint,32,2) [] = { 0xa66666, 0xa66666 };
102 VECT_VAR_DECL(expected_vcvt_n_rounding,int,32,4) [] = { 0xfbccc, 0xfbccc,
103 					       0xfbccc, 0xfbccc };
104 VECT_VAR_DECL(expected_vcvt_n_rounding,uint,32,4) [] = { 0xfbccc, 0xfbccc,
105 						0xfbccc, 0xfbccc };
106 
107 /* Expected results for vcvt_n with saturation.  */
108 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
109 VECT_VAR_DECL(expected_vcvt_n_saturation, int, 16, 4) [] =
110 { 0x533, 0x533, 0x533, 0x533 };
111 VECT_VAR_DECL(expected_vcvt_n_saturation, int, 16, 8) [] =
112 { 0x7fff, 0x7fff, 0x7fff, 0x7fff,
113   0x7fff, 0x7fff, 0x7fff, 0x7fff };
114 #endif
115 VECT_VAR_DECL(expected_vcvt_n_saturation,int,32,2) [] =
116 { 0x7fffffff, 0x7fffffff };
117 VECT_VAR_DECL(expected_vcvt_n_saturation,int,32,4) [] =
118 { 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff };
119 
120 #define TEST_MSG "VCVT/VCVTQ"
exec_vcvt(void)121 void exec_vcvt (void)
122 {
123   int i;
124 
125   /* Basic test: y=vcvt(x), then store the result.  */
126 #define TEST_VCVT(Q, T1, T2, W, N, TS1, TS2, EXP)		\
127   VECT_VAR(vector_res, T1, W, N) =				\
128     vcvt##Q##_##T2##W##_##TS2##W(VECT_VAR(vector, TS1, W, N));	\
129   vst1##Q##_##T2##W(VECT_VAR(result, T1, W, N),			\
130 		    VECT_VAR(vector_res, T1, W, N));		\
131   CHECK(TEST_MSG, T1, W, N, PRIx##W, EXP, TEST_MSG2);
132 
133 #define TEST_VCVT_FP(Q, T1, T2, W, N, TS1, TS2, EXP)		\
134   VECT_VAR(vector_res, T1, W, N) =				\
135     vcvt##Q##_##T2##W##_##TS2##W(VECT_VAR(vector, TS1, W, N));	\
136   vst1##Q##_##T2##W(VECT_VAR(result, T1, W, N),			\
137 		    VECT_VAR(vector_res, T1, W, N));		\
138   CHECK_FP(TEST_MSG, T1, W, N, PRIx##W, EXP, TEST_MSG2);
139 
140 #define TEST_VCVT_N(Q, T1, T2, W, N, TS1, TS2, V, EXP)			\
141   VECT_VAR(vector_res, T1, W, N) =					\
142     vcvt##Q##_n_##T2##W##_##TS2##W(VECT_VAR(vector, TS1, W, N), V);	\
143   vst1##Q##_##T2##W(VECT_VAR(result, T1, W, N),				\
144 		    VECT_VAR(vector_res, T1, W, N));			\
145   CHECK(TEST_MSG, T1, W, N, PRIx##W, EXP, TEST_MSG2);
146 
147 #define TEST_VCVT_N_FP(Q, T1, T2, W, N, TS1, TS2, V, EXP)		\
148   VECT_VAR(vector_res, T1, W, N) =					\
149     vcvt##Q##_n_##T2##W##_##TS2##W(VECT_VAR(vector, TS1, W, N), V);	\
150   vst1##Q##_##T2##W(VECT_VAR(result, T1, W, N),				\
151 		    VECT_VAR(vector_res, T1, W, N));			\
152   CHECK_FP(TEST_MSG, T1, W, N, PRIx##W, EXP, TEST_MSG2);
153 
154   DECL_VARIABLE_ALL_VARIANTS(vector);
155   DECL_VARIABLE_ALL_VARIANTS(vector_res);
156 
157   clean_results ();
158 
159   /* Initialize input "vector" from "buffer".  */
160   TEST_MACRO_ALL_VARIANTS_2_5(VLOAD, vector, buffer);
161 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
162   VLOAD(vector, buffer, , float, f, 16, 4);
163   VLOAD(vector, buffer, q, float, f, 16, 8);
164 #endif
165   VLOAD(vector, buffer, , float, f, 32, 2);
166   VLOAD(vector, buffer, q, float, f, 32, 4);
167 
168   /* Make sure some elements have a fractional part, to exercise
169      integer conversions.  */
170 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
171   VSET_LANE(vector, , float, f, 16, 4, 0, -15.3f);
172   VSET_LANE(vector, , float, f, 16, 4, 1, 5.3f);
173   VSET_LANE(vector, , float, f, 16, 4, 2, -15.3f);
174   VSET_LANE(vector, , float, f, 16, 4, 3, 5.3f);
175   VSET_LANE(vector, q, float, f, 16, 8, 4, -15.3f);
176   VSET_LANE(vector, q, float, f, 16, 8, 5, 5.3f);
177   VSET_LANE(vector, q, float, f, 16, 8, 6, -15.3f);
178   VSET_LANE(vector, q, float, f, 16, 8, 7, 5.3f);
179 #endif
180 
181   VSET_LANE(vector, , float, f, 32, 2, 0, -15.3f);
182   VSET_LANE(vector, , float, f, 32, 2, 1, 5.3f);
183   VSET_LANE(vector, q, float, f, 32, 4, 2, -15.3f);
184   VSET_LANE(vector, q, float, f, 32, 4, 3, 5.3f);
185 
186   /* The same result buffers are used multiple times, so we check them
187      before overwriting them.  */
188 #define TEST_MSG2 ""
189 
190 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
191   /* vcvt_f16_xx.  */
192   TEST_VCVT_FP(, float, f, 16, 4, int, s, expected_s);
193   TEST_VCVT_FP(, float, f, 16, 4, uint, u, expected_u);
194 #endif
195   /* vcvt_f32_xx.  */
196   TEST_VCVT_FP(, float, f, 32, 2, int, s, expected_s);
197   TEST_VCVT_FP(, float, f, 32, 2, uint, u, expected_u);
198 
199 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
200   /* vcvtq_f16_xx.  */
201   TEST_VCVT_FP(q, float, f, 16, 8, int, s, expected_s);
202   TEST_VCVT_FP(q, float, f, 16, 8, uint, u, expected_u);
203 #endif
204   /* vcvtq_f32_xx.  */
205   TEST_VCVT_FP(q, float, f, 32, 4, int, s, expected_s);
206   TEST_VCVT_FP(q, float, f, 32, 4, uint, u, expected_u);
207 
208 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
209   /* vcvt_xx_f16.  */
210   TEST_VCVT(, int, s, 16, 4, float, f, expected);
211   TEST_VCVT(, uint, u, 16, 4, float, f, expected);
212 #endif
213   /* vcvt_xx_f32.  */
214   TEST_VCVT(, int, s, 32, 2, float, f, expected);
215   TEST_VCVT(, uint, u, 32, 2, float, f, expected);
216 
217 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
218   VSET_LANE(vector, q, float, f, 16, 8, 0, 0.0f);
219   VSET_LANE(vector, q, float, f, 16, 8, 1, -0.0f);
220   VSET_LANE(vector, q, float, f, 16, 8, 2, 15.12f);
221   VSET_LANE(vector, q, float, f, 16, 8, 3, -15.12f);
222   VSET_LANE(vector, q, float, f, 16, 8, 4, 0.0f);
223   VSET_LANE(vector, q, float, f, 16, 8, 5, -0.0f);
224   VSET_LANE(vector, q, float, f, 16, 8, 6, 15.12f);
225   VSET_LANE(vector, q, float, f, 16, 8, 7, -15.12f);
226 #endif
227 
228   VSET_LANE(vector, q, float, f, 32, 4, 0, 0.0f);
229   VSET_LANE(vector, q, float, f, 32, 4, 1, -0.0f);
230   VSET_LANE(vector, q, float, f, 32, 4, 2, 15.12f);
231   VSET_LANE(vector, q, float, f, 32, 4, 3, -15.12f);
232 
233 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
234   /* vcvtq_xx_f16.  */
235   TEST_VCVT(q, int, s, 16, 8, float, f, expected);
236   TEST_VCVT(q, uint, u, 16, 8, float, f, expected);
237 #endif
238 
239   /* vcvtq_xx_f32.  */
240   TEST_VCVT(q, int, s, 32, 4, float, f, expected);
241   TEST_VCVT(q, uint, u, 32, 4, float, f, expected);
242 
243   /* The same result buffers are used multiple times, so we check them
244      before overwriting them.  */
245 #undef TEST_MSG
246 #define TEST_MSG "VCVT_N/VCVTQ_N"
247 
248 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
249   /* vcvt_n_f16_xx.  */
250   TEST_VCVT_N_FP(, float, f, 16, 4, int, s, 2, expected_vcvt_n_s);
251   TEST_VCVT_N_FP(, float, f, 16, 4, uint, u, 7, expected_vcvt_n_u);
252 #endif
253   /* vcvt_n_f32_xx.  */
254   TEST_VCVT_N_FP(, float, f, 32, 2, int, s, 2, expected_vcvt_n_s);
255   TEST_VCVT_N_FP(, float, f, 32, 2, uint, u, 7, expected_vcvt_n_u);
256 
257 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
258   /* vcvtq_n_f16_xx.  */
259   TEST_VCVT_N_FP(q, float, f, 16, 8, int, s, 7, expected_vcvt_n_s);
260   TEST_VCVT_N_FP(q, float, f, 16, 8, uint, u, 12, expected_vcvt_n_u);
261 #endif
262   /* vcvtq_n_f32_xx.  */
263   TEST_VCVT_N_FP(q, float, f, 32, 4, int, s, 30, expected_vcvt_n_s);
264   TEST_VCVT_N_FP(q, float, f, 32, 4, uint, u, 12, expected_vcvt_n_u);
265 
266 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
267   /* vcvt_n_xx_f16.  */
268   TEST_VCVT_N(, int, s, 16, 4, float, f, 2, expected_vcvt_n);
269   TEST_VCVT_N(, uint, u, 16, 4, float, f, 7, expected_vcvt_n);
270 #endif
271   /* vcvt_n_xx_f32.  */
272   TEST_VCVT_N(, int, s, 32, 2, float, f, 20, expected_vcvt_n);
273   TEST_VCVT_N(, uint, u, 32, 2, float, f, 2, expected_vcvt_n);
274 
275 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
276   /* vcvtq_n_xx_f16.  */
277   TEST_VCVT_N(q, int, s, 16, 8, float, f, 7, expected_vcvt_n);
278   TEST_VCVT_N(q, uint, u, 16, 8, float, f, 12, expected_vcvt_n);
279 #endif
280   /* vcvtq_n_xx_f32.  */
281   TEST_VCVT_N(q, int, s, 32, 4, float, f, 13, expected_vcvt_n);
282   TEST_VCVT_N(q, uint, u, 32, 4, float, f, 1, expected_vcvt_n);
283 
284   /* Check rounding.  */
285 #undef TEST_MSG
286 #define TEST_MSG "VCVT/VCVTQ"
287 #undef TEST_MSG2
288 #define TEST_MSG2 "(check rounding)"
289 
290 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
291   VDUP(vector, , float, f, 16, 4, 10.4f);
292   VDUP(vector, q, float, f, 16, 8, 125.9f);
293 #endif
294   VDUP(vector, , float, f, 32, 2, 10.4f);
295   VDUP(vector, q, float, f, 32, 4, 125.9f);
296 
297 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
298   /* vcvt_xx_f16.  */
299   TEST_VCVT(, int, s, 16, 4, float, f, expected_rounding);
300   TEST_VCVT(, uint, u, 16, 4, float, f, expected_rounding);
301 #endif
302   /* vcvt_xx_f32.  */
303   TEST_VCVT(, int, s, 32, 2, float, f, expected_rounding);
304   TEST_VCVT(, uint, u, 32, 2, float, f, expected_rounding);
305 
306 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
307   /* vcvtq_xx_f16.  */
308   TEST_VCVT(q, int, s, 16, 8, float, f, expected_rounding);
309   TEST_VCVT(q, uint, u, 16, 8, float, f, expected_rounding);
310 #endif
311   /* vcvtq_xx_f32.  */
312   TEST_VCVT(q, int, s, 32, 4, float, f, expected_rounding);
313   TEST_VCVT(q, uint, u, 32, 4, float, f, expected_rounding);
314 
315 #undef TEST_MSG
316 #define TEST_MSG "VCVT_N/VCVTQ_N"
317 
318 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
319   /* vcvt_n_xx_f16.  */
320   TEST_VCVT_N(, int, s, 16, 4, float, f, 7, expected_vcvt_n_rounding);
321   TEST_VCVT_N(, uint, u, 16, 4, float, f, 7, expected_vcvt_n_rounding);
322 #endif
323   /* vcvt_n_xx_f32.  */
324   TEST_VCVT_N(, int, s, 32, 2, float, f, 20, expected_vcvt_n_rounding);
325   TEST_VCVT_N(, uint, u, 32, 2, float, f, 20, expected_vcvt_n_rounding);
326 
327 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
328   /* vcvtq_n_xx_f16.  */
329   TEST_VCVT_N(q, int, s, 16, 8, float, f, 13, expected_vcvt_n_rounding);
330   TEST_VCVT_N(q, uint, u, 16, 8, float, f, 13, expected_vcvt_n_rounding);
331 #endif
332   /* vcvtq_n_xx_f32.  */
333   TEST_VCVT_N(q, int, s, 32, 4, float, f, 13, expected_vcvt_n_rounding);
334   TEST_VCVT_N(q, uint, u, 32, 4, float, f, 13, expected_vcvt_n_rounding);
335 
336 #undef TEST_MSG
337 #define TEST_MSG "VCVT_N/VCVTQ_N"
338 #undef TEST_MSG2
339 #define TEST_MSG2 "(check saturation)"
340 
341 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
342   /* vcvt_n_xx_f16.  */
343   TEST_VCVT_N(, int, s, 16, 4, float, f, 7, expected_vcvt_n_saturation);
344 #endif
345   /* vcvt_n_xx_f32.  */
346   TEST_VCVT_N(, int, s, 32, 2, float, f, 31, expected_vcvt_n_saturation);
347 
348 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
349   /* vcvtq_n_xx_f16.  */
350   TEST_VCVT_N(q, int, s, 16, 8, float, f, 13, expected_vcvt_n_saturation);
351 #endif
352   /* vcvtq_n_xx_f32.  */
353   TEST_VCVT_N(q, int, s, 32, 4, float, f, 31, expected_vcvt_n_saturation);
354 }
355 
main(void)356 int main (void)
357 {
358   exec_vcvt ();
359   return 0;
360 }
361