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 with positive input.  */
7 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
8 VECT_VAR_DECL(expected, hfloat, 16, 4) [] = { 0xd70c, 0xd70c, 0xd70c, 0xd70c };
9 VECT_VAR_DECL(expected, hfloat, 16, 8) [] = { 0xcedc, 0xcedc, 0xcedc, 0xcedc,
10 					      0xcedc, 0xcedc, 0xcedc, 0xcedc };
11 #endif
12 VECT_VAR_DECL(expected,hfloat,32,2) [] = { 0xc2e19eb7, 0xc2e19eb7 };
13 VECT_VAR_DECL(expected,hfloat,32,4) [] = { 0xc1db851f, 0xc1db851f,
14 					   0xc1db851f, 0xc1db851f };
15 
16 /* Expected results with FP special values (NaN).  */
17 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
18 VECT_VAR_DECL(expected_fp1, hfloat, 16, 4) [] = { 0x7e00, 0x7e00,
19 						  0x7e00, 0x7e00 };
20 VECT_VAR_DECL(expected_fp1, hfloat, 16, 8) [] = { 0x7e00, 0x7e00,
21 						  0x7e00, 0x7e00,
22 						  0x7e00, 0x7e00,
23 						  0x7e00, 0x7e00 };
24 #endif
25 VECT_VAR_DECL(expected_fp1,hfloat,32,2) [] = { 0x7fc00000, 0x7fc00000 };
26 VECT_VAR_DECL(expected_fp1,hfloat,32,4) [] = { 0x7fc00000, 0x7fc00000,
27 					       0x7fc00000, 0x7fc00000 };
28 
29 /* Expected results with FP special values (infinity, 0) and normal
30    values.  */
31 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
32 VECT_VAR_DECL(expected_fp2, hfloat, 16, 4) [] = { 0xfc00, 0xfc00,
33 						  0xfc00, 0xfc00 };
34 VECT_VAR_DECL(expected_fp2, hfloat, 16, 8) [] = { 0x4000, 0x4000,
35 						  0x4000, 0x4000,
36 						  0x4000, 0x4000,
37 						  0x4000, 0x4000 };
38 #endif
39 VECT_VAR_DECL(expected_fp2,hfloat,32,2) [] = { 0xff800000, 0xff800000 };
40 VECT_VAR_DECL(expected_fp2,hfloat,32,4) [] = { 0x40000000, 0x40000000,
41 					       0x40000000, 0x40000000 };
42 
43 /* Expected results with FP special values (infinity, 0).  */
44 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
45 VECT_VAR_DECL(expected_fp3, hfloat, 16, 4) [] = { 0x4000, 0x4000,
46 						  0x4000, 0x4000 };
47 VECT_VAR_DECL(expected_fp3, hfloat, 16, 8) [] = { 0x4000, 0x4000,
48 						  0x4000, 0x4000,
49 						  0x4000, 0x4000,
50 						  0x4000, 0x4000 };
51 #endif
52 VECT_VAR_DECL(expected_fp3,hfloat,32,2) [] = { 0x40000000, 0x40000000 };
53 VECT_VAR_DECL(expected_fp3,hfloat,32,4) [] = { 0x40000000, 0x40000000,
54 					       0x40000000, 0x40000000 };
55 
56 #define TEST_MSG "VRECPS/VRECPSQ"
exec_vrecps(void)57 void exec_vrecps(void)
58 {
59   int i;
60 
61   /* Basic test: y=vrecps(x), then store the result.  */
62 #define TEST_VRECPS(Q, T1, T2, W, N)			\
63   VECT_VAR(vector_res, T1, W, N) =			\
64     vrecps##Q##_##T2##W(VECT_VAR(vector, T1, W, N),	\
65 			VECT_VAR(vector2, T1, W, N));	\
66   vst1##Q##_##T2##W(VECT_VAR(result, T1, W, N),		\
67 		    VECT_VAR(vector_res, T1, W, N))
68 
69   /* No need for integer variants.  */
70 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
71   DECL_VARIABLE(vector, float, 16, 4);
72   DECL_VARIABLE(vector, float, 16, 8);
73 #endif
74   DECL_VARIABLE(vector, float, 32, 2);
75   DECL_VARIABLE(vector, float, 32, 4);
76 
77 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
78   DECL_VARIABLE(vector2, float, 16, 4);
79   DECL_VARIABLE(vector2, float, 16, 8);
80 #endif
81   DECL_VARIABLE(vector2, float, 32, 2);
82   DECL_VARIABLE(vector2, float, 32, 4);
83 
84 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
85   DECL_VARIABLE(vector_res, float, 16, 4);
86   DECL_VARIABLE(vector_res, float, 16, 8);
87 #endif
88   DECL_VARIABLE(vector_res, float, 32, 2);
89   DECL_VARIABLE(vector_res, float, 32, 4);
90 
91   clean_results ();
92 
93   /* Choose init value arbitrarily.  */
94 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
95   VDUP(vector, , float, f, 16, 4, 12.9f);
96   VDUP(vector, q, float, f, 16, 8, 9.2f);
97 #endif
98   VDUP(vector, , float, f, 32, 2, 12.9f);
99   VDUP(vector, q, float, f, 32, 4, 9.2f);
100 
101 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
102   VDUP(vector2, , float, f, 16, 4, 8.9f);
103   VDUP(vector2, q, float, f, 16, 8, 3.2f);
104 #endif
105   VDUP(vector2, , float, f, 32, 2, 8.9f);
106   VDUP(vector2, q, float, f, 32, 4, 3.2f);
107 
108   /* Apply the operator.  */
109 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
110   TEST_VRECPS(, float, f, 16, 4);
111   TEST_VRECPS(q, float, f, 16, 8);
112 #endif
113   TEST_VRECPS(, float, f, 32, 2);
114   TEST_VRECPS(q, float, f, 32, 4);
115 
116 #define CMT " (positive input)"
117 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
118   CHECK_FP(TEST_MSG, float, 16, 4, PRIx16, expected, CMT);
119   CHECK_FP(TEST_MSG, float, 16, 8, PRIx16, expected, CMT);
120 #endif
121   CHECK_FP(TEST_MSG, float, 32, 2, PRIx32, expected, CMT);
122   CHECK_FP(TEST_MSG, float, 32, 4, PRIx32, expected, CMT);
123 
124 
125   /* Test FP variants with special input values (NaN).  */
126 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
127   VDUP(vector, , float, f, 16, 4, NAN);
128   VDUP(vector2, q, float, f, 16, 8, NAN);
129 #endif
130   VDUP(vector, , float, f, 32, 2, NAN);
131   VDUP(vector2, q, float, f, 32, 4, NAN);
132 
133   /* Apply the operator.  */
134 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
135   TEST_VRECPS(, float, f, 16, 4);
136   TEST_VRECPS(q, float, f, 16, 8);
137 #endif
138   TEST_VRECPS(, float, f, 32, 2);
139   TEST_VRECPS(q, float, f, 32, 4);
140 
141 #undef CMT
142 #define CMT " FP special (NaN)"
143 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
144   CHECK_FP(TEST_MSG, float, 16, 4, PRIx16, expected_fp1, CMT);
145   CHECK_FP(TEST_MSG, float, 16, 8, PRIx16, expected_fp1, CMT);
146 #endif
147   CHECK_FP(TEST_MSG, float, 32, 2, PRIx32, expected_fp1, CMT);
148   CHECK_FP(TEST_MSG, float, 32, 4, PRIx32, expected_fp1, CMT);
149 
150 
151   /* Test FP variants with special input values (infinity, 0).  */
152 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
153   VDUP(vector, , float, f, 16, 4, HUGE_VALF);
154   VDUP(vector, q, float, f, 16, 8, 0.0f);
155   VDUP(vector2, q, float, f, 16, 8, 3.2f); /* Restore a normal value.  */
156 #endif
157   VDUP(vector, , float, f, 32, 2, HUGE_VALF);
158   VDUP(vector, q, float, f, 32, 4, 0.0f);
159   VDUP(vector2, q, float, f, 32, 4, 3.2f); /* Restore a normal value.  */
160 
161 
162   /* Apply the operator.  */
163 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
164   TEST_VRECPS(, float, f, 16, 4);
165   TEST_VRECPS(q, float, f, 16, 8);
166 #endif
167   TEST_VRECPS(, float, f, 32, 2);
168   TEST_VRECPS(q, float, f, 32, 4);
169 
170 #undef CMT
171 #define CMT " FP special (infinity, 0) and normal value"
172 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
173   CHECK_FP(TEST_MSG, float, 16, 4, PRIx16, expected_fp2, CMT);
174   CHECK_FP(TEST_MSG, float, 16, 8, PRIx16, expected_fp2, CMT);
175 #endif
176   CHECK_FP(TEST_MSG, float, 32, 2, PRIx32, expected_fp2, CMT);
177   CHECK_FP(TEST_MSG, float, 32, 4, PRIx32, expected_fp2, CMT);
178 
179 
180   /* Test FP variants with only special input values (infinity, 0).  */
181 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
182   VDUP(vector, , float, f, 16, 4, HUGE_VALF);
183   VDUP(vector, q, float, f, 16, 8, 0.0f);
184   VDUP(vector2, , float, f, 16, 4, 0.0f);
185   VDUP(vector2, q, float, f, 16, 8, HUGE_VALF);
186 #endif
187   VDUP(vector, , float, f, 32, 2, HUGE_VALF);
188   VDUP(vector, q, float, f, 32, 4, 0.0f);
189   VDUP(vector2, , float, f, 32, 2, 0.0f);
190   VDUP(vector2, q, float, f, 32, 4, HUGE_VALF);
191 
192 
193   /* Apply the operator */
194 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
195   TEST_VRECPS(, float, f, 16, 4);
196   TEST_VRECPS(q, float, f, 16, 8);
197 #endif
198   TEST_VRECPS(, float, f, 32, 2);
199   TEST_VRECPS(q, float, f, 32, 4);
200 
201 #undef CMT
202 #define CMT " FP special (infinity, 0)"
203 #if defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)
204   CHECK_FP(TEST_MSG, float, 16, 4, PRIx16, expected_fp3, CMT);
205   CHECK_FP(TEST_MSG, float, 16, 8, PRIx16, expected_fp3, CMT);
206 #endif
207   CHECK_FP(TEST_MSG, float, 32, 2, PRIx32, expected_fp3, CMT);
208   CHECK_FP(TEST_MSG, float, 32, 4, PRIx32, expected_fp3, CMT);
209 }
210 
main(void)211 int main (void)
212 {
213   exec_vrecps ();
214   return 0;
215 }
216