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 VECT_VAR_DECL(expected_s,hfloat,32,2) [] = { 0xc1800000, 0xc1700000 };
8 VECT_VAR_DECL(expected_u,hfloat,32,2) [] = { 0x4f800000, 0x4f800000 };
9 VECT_VAR_DECL(expected_s,hfloat,32,4) [] = { 0xc1800000, 0xc1700000,
10 					   0xc1600000, 0xc1500000 };
11 VECT_VAR_DECL(expected_u,hfloat,32,4) [] = { 0x4f800000, 0x4f800000,
12 					   0x4f800000, 0x4f800000 };
13 VECT_VAR_DECL(expected,int,32,2) [] = { 0xfffffff1, 0x5 };
14 VECT_VAR_DECL(expected,uint,32,2) [] = { 0x0, 0x5 };
15 VECT_VAR_DECL(expected,int,32,4) [] = { 0x0, 0x0, 0xf, 0xfffffff1 };
16 VECT_VAR_DECL(expected,uint,32,4) [] = { 0x0, 0x0, 0xf, 0x0 };
17 
18 /* Expected results for vcvt_n.  */
19 VECT_VAR_DECL(expected_vcvt_n_s,hfloat,32,2) [] = { 0xc0800000, 0xc0700000 };
20 VECT_VAR_DECL(expected_vcvt_n_u,hfloat,32,2) [] = { 0x4c000000, 0x4c000000 };
21 VECT_VAR_DECL(expected_vcvt_n_s,hfloat,32,4) [] = { 0xb2800000, 0xb2700000,
22 						  0xb2600000, 0xb2500000 };
23 VECT_VAR_DECL(expected_vcvt_n_u,hfloat,32,4) [] = { 0x49800000, 0x49800000,
24 						  0x49800000, 0x49800000 };
25 VECT_VAR_DECL(expected_vcvt_n,int,32,2) [] = { 0xff0b3333, 0x54cccd };
26 VECT_VAR_DECL(expected_vcvt_n,uint,32,2) [] = { 0x0, 0x15 };
27 VECT_VAR_DECL(expected_vcvt_n,int,32,4) [] = { 0x0, 0x0, 0x1e3d7, 0xfffe1c29 };
28 VECT_VAR_DECL(expected_vcvt_n,uint,32,4) [] = { 0x0, 0x0, 0x1e, 0x0 };
29 
30 /* Expected results for vcvt with rounding.  */
31 VECT_VAR_DECL(expected_rounding,int,32,2) [] = { 0xa, 0xa };
32 VECT_VAR_DECL(expected_rounding,uint,32,2) [] = { 0xa, 0xa };
33 VECT_VAR_DECL(expected_rounding,int,32,4) [] = { 0x7d, 0x7d, 0x7d, 0x7d };
34 VECT_VAR_DECL(expected_rounding,uint,32,4) [] = { 0x7d, 0x7d, 0x7d, 0x7d };
35 
36 /* Expected results for vcvt_n with rounding.  */
37 VECT_VAR_DECL(expected_vcvt_n_rounding,int,32,2) [] = { 0xa66666, 0xa66666 };
38 VECT_VAR_DECL(expected_vcvt_n_rounding,uint,32,2) [] = { 0xa66666, 0xa66666 };
39 VECT_VAR_DECL(expected_vcvt_n_rounding,int,32,4) [] = { 0xfbccc, 0xfbccc,
40 					       0xfbccc, 0xfbccc };
41 VECT_VAR_DECL(expected_vcvt_n_rounding,uint,32,4) [] = { 0xfbccc, 0xfbccc,
42 						0xfbccc, 0xfbccc };
43 
44 /* Expected results for vcvt_n with saturation.  */
45 VECT_VAR_DECL(expected_vcvt_n_saturation,int,32,2) [] = { 0x7fffffff,
46 							  0x7fffffff };
47 VECT_VAR_DECL(expected_vcvt_n_saturation,int,32,4) [] = { 0x7fffffff,
48 							  0x7fffffff,
49 					       0x7fffffff, 0x7fffffff };
50 
51 #define TEST_MSG "VCVT/VCVTQ"
exec_vcvt(void)52 void exec_vcvt (void)
53 {
54   int i;
55 
56   /* Basic test: y=vcvt(x), then store the result.  */
57 #define TEST_VCVT(Q, T1, T2, W, N, TS1, TS2, EXP)		\
58   VECT_VAR(vector_res, T1, W, N) =				\
59     vcvt##Q##_##T2##W##_##TS2##W(VECT_VAR(vector, TS1, W, N));	\
60   vst1##Q##_##T2##W(VECT_VAR(result, T1, W, N),			\
61 		    VECT_VAR(vector_res, T1, W, N));		\
62   CHECK(TEST_MSG, T1, W, N, PRIx##W, EXP, TEST_MSG2);
63 
64 #define TEST_VCVT_FP(Q, T1, T2, W, N, TS1, TS2, EXP)		\
65   VECT_VAR(vector_res, T1, W, N) =				\
66     vcvt##Q##_##T2##W##_##TS2##W(VECT_VAR(vector, TS1, W, N));	\
67   vst1##Q##_##T2##W(VECT_VAR(result, T1, W, N),			\
68 		    VECT_VAR(vector_res, T1, W, N));		\
69   CHECK_FP(TEST_MSG, T1, W, N, PRIx##W, EXP, TEST_MSG2);
70 
71 #define TEST_VCVT_N(Q, T1, T2, W, N, TS1, TS2, V, EXP)			\
72   VECT_VAR(vector_res, T1, W, N) =					\
73     vcvt##Q##_n_##T2##W##_##TS2##W(VECT_VAR(vector, TS1, W, N), V);	\
74   vst1##Q##_##T2##W(VECT_VAR(result, T1, W, N),				\
75 		    VECT_VAR(vector_res, T1, W, N));			\
76   CHECK(TEST_MSG, T1, W, N, PRIx##W, EXP, TEST_MSG2);
77 
78 #define TEST_VCVT_N_FP(Q, T1, T2, W, N, TS1, TS2, V, EXP)		\
79   VECT_VAR(vector_res, T1, W, N) =					\
80     vcvt##Q##_n_##T2##W##_##TS2##W(VECT_VAR(vector, TS1, W, N), V);	\
81   vst1##Q##_##T2##W(VECT_VAR(result, T1, W, N),				\
82 		    VECT_VAR(vector_res, T1, W, N));			\
83   CHECK_FP(TEST_MSG, T1, W, N, PRIx##W, EXP, TEST_MSG2);
84 
85   DECL_VARIABLE_ALL_VARIANTS(vector);
86   DECL_VARIABLE_ALL_VARIANTS(vector_res);
87 
88   clean_results ();
89 
90   /* Initialize input "vector" from "buffer".  */
91   TEST_MACRO_ALL_VARIANTS_2_5(VLOAD, vector, buffer);
92   VLOAD(vector, buffer, , float, f, 32, 2);
93   VLOAD(vector, buffer, q, float, f, 32, 4);
94 
95   /* Make sure some elements have a fractional part, to exercise
96      integer conversions.  */
97   VSET_LANE(vector, , float, f, 32, 2, 0, -15.3f);
98   VSET_LANE(vector, , float, f, 32, 2, 1, 5.3f);
99   VSET_LANE(vector, q, float, f, 32, 4, 2, -15.3f);
100   VSET_LANE(vector, q, float, f, 32, 4, 3, 5.3f);
101 
102   /* The same result buffers are used multiple times, so we check them
103      before overwriting them.  */
104 #define TEST_MSG2 ""
105 
106   /* vcvt_f32_xx.  */
107   TEST_VCVT_FP(, float, f, 32, 2, int, s, expected_s);
108   TEST_VCVT_FP(, float, f, 32, 2, uint, u, expected_u);
109 
110   /* vcvtq_f32_xx.  */
111   TEST_VCVT_FP(q, float, f, 32, 4, int, s, expected_s);
112   TEST_VCVT_FP(q, float, f, 32, 4, uint, u, expected_u);
113 
114   /* vcvt_xx_f32.  */
115   TEST_VCVT(, int, s, 32, 2, float, f, expected);
116   TEST_VCVT(, uint, u, 32, 2, float, f, expected);
117 
118   VSET_LANE(vector, q, float, f, 32, 4, 0, 0.0f);
119   VSET_LANE(vector, q, float, f, 32, 4, 1, -0.0f);
120   VSET_LANE(vector, q, float, f, 32, 4, 2, 15.12f);
121   VSET_LANE(vector, q, float, f, 32, 4, 3, -15.12f);
122 
123   /* vcvtq_xx_f32.  */
124   TEST_VCVT(q, int, s, 32, 4, float, f, expected);
125   TEST_VCVT(q, uint, u, 32, 4, float, f, expected);
126 
127   /* The same result buffers are used multiple times, so we check them
128      before overwriting them.  */
129 #undef TEST_MSG
130 #define TEST_MSG "VCVT_N/VCVTQ_N"
131 
132   /* vcvt_n_f32_xx.  */
133   TEST_VCVT_N_FP(, float, f, 32, 2, int, s, 2, expected_vcvt_n_s);
134   TEST_VCVT_N_FP(, float, f, 32, 2, uint, u, 7, expected_vcvt_n_u);
135 
136   /* vcvtq_n_f32_xx.  */
137   TEST_VCVT_N_FP(q, float, f, 32, 4, int, s, 30, expected_vcvt_n_s);
138   TEST_VCVT_N_FP(q, float, f, 32, 4, uint, u, 12, expected_vcvt_n_u);
139 
140   /* vcvt_n_xx_f32.  */
141   TEST_VCVT_N(, int, s, 32, 2, float, f, 20, expected_vcvt_n);
142   TEST_VCVT_N(, uint, u, 32, 2, float, f, 2, expected_vcvt_n);
143 
144   /* vcvtq_n_xx_f32.  */
145   TEST_VCVT_N(q, int, s, 32, 4, float, f, 13, expected_vcvt_n);
146   TEST_VCVT_N(q, uint, u, 32, 4, float, f, 1, expected_vcvt_n);
147 
148   /* Check rounding.  */
149 #undef TEST_MSG
150 #define TEST_MSG "VCVT/VCVTQ"
151 #undef TEST_MSG2
152 #define TEST_MSG2 "(check rounding)"
153   VDUP(vector, , float, f, 32, 2, 10.4f);
154   VDUP(vector, q, float, f, 32, 4, 125.9f);
155   /* vcvt_xx_f32.  */
156   TEST_VCVT(, int, s, 32, 2, float, f, expected_rounding);
157   TEST_VCVT(, uint, u, 32, 2, float, f, expected_rounding);
158   /* vcvtq_xx_f32.  */
159   TEST_VCVT(q, int, s, 32, 4, float, f, expected_rounding);
160   TEST_VCVT(q, uint, u, 32, 4, float, f, expected_rounding);
161 
162 #undef TEST_MSG
163 #define TEST_MSG "VCVT_N/VCVTQ_N"
164   /* vcvt_n_xx_f32.  */
165   TEST_VCVT_N(, int, s, 32, 2, float, f, 20, expected_vcvt_n_rounding);
166   TEST_VCVT_N(, uint, u, 32, 2, float, f, 20, expected_vcvt_n_rounding);
167   /* vcvtq_n_xx_f32.  */
168   TEST_VCVT_N(q, int, s, 32, 4, float, f, 13, expected_vcvt_n_rounding);
169   TEST_VCVT_N(q, uint, u, 32, 4, float, f, 13, expected_vcvt_n_rounding);
170 
171 #undef TEST_MSG
172 #define TEST_MSG "VCVT_N/VCVTQ_N"
173 #undef TEST_MSG2
174 #define TEST_MSG2 "(check saturation)"
175   /* vcvt_n_xx_f32.  */
176   TEST_VCVT_N(, int, s, 32, 2, float, f, 31, expected_vcvt_n_saturation);
177   /* vcvtq_n_xx_f32.  */
178   TEST_VCVT_N(q, int, s, 32, 4, float, f, 31, expected_vcvt_n_saturation);
179 }
180 
main(void)181 int main (void)
182 {
183   exec_vcvt ();
184   return 0;
185 }
186