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