1 /* { dg-do run { target { fixed_point } } } */
2 /* { dg-options "-std=gnu99" } */
4 /* Check basic arithmetic ops for ARM fixed-point/saturating operation support.
5 Not target-independent since we make various assumptions about precision and
6 magnitudes of various types. */
13 #define TEST(TYPE, OP, NAME, SUFFIX) \
14 TYPE NAME##SUFFIX (TYPE A, TYPE B) \
19 #define VARIANTS(TYPE, OP, NAME) \
20 TEST (short TYPE, OP, NAME, _short); \
21 TEST (TYPE, OP, NAME, _regular); \
22 TEST (long TYPE, OP, NAME, _long); \
23 TEST (_Sat short TYPE, OP, NAME, _sat_short); \
24 TEST (_Sat TYPE, OP, NAME, _sat_regular); \
25 TEST (_Sat long TYPE, OP, NAME, _sat_long); \
26 TEST (unsigned short TYPE, OP, NAME, _uns_short); \
27 TEST (unsigned TYPE, OP, NAME, _uns_regular); \
28 TEST (unsigned long TYPE, OP, NAME, _uns_long); \
29 TEST (unsigned _Sat short TYPE, OP, NAME, _uns_sat_short); \
30 TEST (unsigned _Sat TYPE, OP, NAME, _uns_sat_regular); \
31 TEST (unsigned _Sat long TYPE, OP, NAME, _uns_sat_long)
33 VARIANTS (_Fract
, +, plus_fract
);
34 VARIANTS (_Accum
, +, plus_accum
);
35 VARIANTS (_Fract
, -, minus_fract
);
36 VARIANTS (_Accum
, -, minus_accum
);
37 VARIANTS (_Fract
, *, mult_fract
);
38 VARIANTS (_Accum
, *, mult_accum
);
39 VARIANTS (_Accum
, /, div_accum
);
41 /* Inputs for signed add, multiply fractional tests. */
42 short _Fract sf_a
= 0.9hr
;
43 short _Fract sf_b
= -0.8hr
;
46 long _Fract lf_a
= 0.9lr
;
47 long _Fract lf_b
= -0.8lr
;
49 /* Inputs for signed subtract fractional tests. */
50 short _Fract sf_c
= 0.7hr
;
51 short _Fract sf_d
= 0.9hr
;
54 long _Fract lf_c
= 0.7lr
;
55 long _Fract lf_d
= 0.9lr
;
57 /* Inputs for unsigned add, subtract, multiply fractional tests. */
58 unsigned short _Fract usf_a
= 0.4uhr
;
59 unsigned short _Fract usf_b
= 0.3uhr
;
60 unsigned _Fract uf_a
= 0.4ur
;
61 unsigned _Fract uf_b
= 0.3ur
;
62 unsigned long _Fract ulf_a
= 0.4ulr
;
63 unsigned long _Fract ulf_b
= 0.3ulr
;
65 /* Inputs for saturating signed add tests. */
66 short _Sat _Fract sf_e
= 0.8hr
;
67 short _Sat _Fract sf_f
= 0.8hr
;
68 _Sat _Fract f_e
= 0.8r
;
69 _Sat _Fract f_f
= 0.8r
;
70 long _Sat _Fract lf_e
= 0.8r
;
71 long _Sat _Fract lf_f
= 0.8r
;
73 short _Sat _Fract sf_g
= -0.8hr
;
74 short _Sat _Fract sf_h
= -0.8hr
;
75 _Sat _Fract f_g
= -0.8r
;
76 _Sat _Fract f_h
= -0.8r
;
77 long _Sat _Fract lf_g
= -0.8r
;
78 long _Sat _Fract lf_h
= -0.8r
;
80 /* Inputs for saturating unsigned subtract tests. */
81 unsigned short _Sat _Fract usf_c
= 0.3uhr
;
82 unsigned short _Sat _Fract usf_d
= 0.4uhr
;
83 unsigned _Sat _Fract uf_c
= 0.3ur
;
84 unsigned _Sat _Fract uf_d
= 0.4ur
;
85 unsigned long _Sat _Fract ulf_c
= 0.3ulr
;
86 unsigned long _Sat _Fract ulf_d
= 0.4ulr
;
88 /* Inputs for signed accumulator tests. */
90 short _Accum sa_a
= 1.25hk
;
91 short _Accum sa_b
= -1.5hk
;
94 long _Accum la_a
= 1000.25lk
;
95 long _Accum la_b
= -1000.5lk
;
97 /* Inputs for unsigned accumulator tests. */
99 unsigned short _Accum usa_a
= 2.5uhk
;
100 unsigned short _Accum usa_b
= 1.75uhk
;
101 unsigned _Accum ua_a
= 255.5uk
;
102 unsigned _Accum ua_b
= 170.25uk
;
103 unsigned long _Accum ula_a
= 1550.5ulk
;
104 unsigned long _Accum ula_b
= 999.5ulk
;
106 /* Inputs for signed saturating accumulator tests. */
108 short _Sat _Accum sa_c
= 240.0hk
;
109 short _Sat _Accum sa_d
= 250.0hk
;
110 short _Sat _Accum sa_e
= -240.0hk
;
111 short _Sat _Accum sa_f
= -250.0hk
;
112 short _Sat _Accum sa_g
= 0.5hk
;
114 _Sat _Accum a_c
= 65000.0k
;
115 _Sat _Accum a_d
= 20000.0k
;
116 _Sat _Accum a_e
= -65000.0k
;
117 _Sat _Accum a_f
= -20000.0k
;
118 _Sat _Accum a_g
= 0.5k
;
120 long _Sat _Accum la_c
= 3472883712.0lk
;
121 long _Sat _Accum la_d
= 3456106496.0lk
;
122 long _Sat _Accum la_e
= -3472883712.0lk
;
123 long _Sat _Accum la_f
= -3456106496.0lk
;
124 long _Sat _Accum la_g
= 0.5lk
;
126 /* Inputs for unsigned saturating accumulator tests. */
128 unsigned short _Sat _Accum usa_c
= 250.0uhk
;
129 unsigned short _Sat _Accum usa_d
= 240.0uhk
;
130 unsigned short _Sat _Accum usa_e
= 0.5uhk
;
132 unsigned _Sat _Accum ua_c
= 65000.0uk
;
133 unsigned _Sat _Accum ua_d
= 20000.0uk
;
134 unsigned _Sat _Accum ua_e
= 0.5uk
;
136 unsigned long _Sat _Accum ula_c
= 3472883712.0ulk
;
137 unsigned long _Sat _Accum ula_d
= 3456106496.0ulk
;
138 unsigned long _Sat _Accum ula_e
= 0.5ulk
;
140 #define CHECK(FN, EXP) do { \
141 if (fabs ((float) (FN) - (EXP)) > 0.05) \
143 fprintf (stderr, "result for " #FN " (as float): %f\n", (double) (FN));\
148 #define CHECK_EXACT(FN, EXP) do { \
151 fprintf (stderr, "result for " #FN " (as float): %f, should be %f\n", \
152 (double) (FN), (double) (EXP)); \
158 main (int argc
, char *argv
[])
160 /* Fract/fract operations, non-saturating. */
162 CHECK (plus_fract_short (sf_a
, sf_b
), 0.1);
163 CHECK (plus_fract_regular (f_a
, f_b
), 0.1);
164 CHECK (plus_fract_long (lf_a
, lf_b
), 0.1);
166 CHECK (plus_fract_uns_short (usf_a
, usf_b
), 0.7);
167 CHECK (plus_fract_uns_regular (uf_a
, uf_b
), 0.7);
168 CHECK (plus_fract_uns_long (ulf_a
, ulf_b
), 0.7);
170 CHECK (minus_fract_short (sf_c
, sf_d
), -0.2);
171 CHECK (minus_fract_regular (f_c
, f_d
), -0.2);
172 CHECK (minus_fract_long (lf_c
, lf_d
), -0.2);
174 CHECK (minus_fract_uns_short (usf_a
, usf_b
), 0.1);
175 CHECK (minus_fract_uns_regular (uf_a
, uf_b
), 0.1);
176 CHECK (minus_fract_uns_long (ulf_a
, ulf_b
), 0.1);
178 CHECK (mult_fract_short (sf_a
, sf_b
), -0.72);
179 CHECK (mult_fract_regular (f_a
, f_b
), -0.72);
180 CHECK (mult_fract_long (lf_a
, lf_b
), -0.72);
182 CHECK (mult_fract_uns_short (usf_a
, usf_b
), 0.12);
183 CHECK (mult_fract_uns_regular (uf_a
, uf_b
), 0.12);
184 CHECK (mult_fract_uns_long (ulf_a
, ulf_b
), 0.12);
186 /* Fract/fract operations, saturating. */
188 CHECK (plus_fract_sat_short (sf_e
, sf_f
), 1.0);
189 CHECK (plus_fract_sat_regular (f_e
, f_f
), 1.0);
190 CHECK (plus_fract_sat_long (lf_e
, lf_f
), 1.0);
192 CHECK (plus_fract_sat_short (sf_g
, sf_h
), -1.0);
193 CHECK (plus_fract_sat_regular (f_g
, f_h
), -1.0);
194 CHECK (plus_fract_sat_long (lf_g
, lf_h
), -1.0);
196 CHECK (plus_fract_uns_sat_short (sf_e
, sf_f
), 1.0);
197 CHECK (plus_fract_uns_sat_regular (f_e
, f_f
), 1.0);
198 CHECK (plus_fract_uns_sat_long (lf_e
, lf_f
), 1.0);
200 CHECK (plus_fract_sat_short (sf_a
, sf_b
), 0.1);
201 CHECK (plus_fract_sat_regular (f_a
, f_b
), 0.1);
202 CHECK (plus_fract_sat_long (lf_a
, lf_b
), 0.1);
204 CHECK (plus_fract_uns_sat_short (usf_a
, usf_b
), 0.7);
205 CHECK (plus_fract_uns_sat_regular (uf_a
, uf_b
), 0.7);
206 CHECK (plus_fract_uns_sat_long (ulf_a
, ulf_b
), 0.7);
208 CHECK (minus_fract_uns_sat_short (usf_c
, usf_d
), 0.0);
209 CHECK (minus_fract_uns_sat_regular (uf_c
, uf_d
), 0.0);
210 CHECK (minus_fract_uns_sat_short (ulf_c
, ulf_d
), 0.0);
212 CHECK (minus_fract_sat_short (sf_c
, sf_d
), -0.2);
213 CHECK (minus_fract_sat_regular (f_c
, f_d
), -0.2);
214 CHECK (minus_fract_sat_long (lf_c
, lf_d
), -0.2);
216 /* Accum/accum operations, non-saturating. */
218 CHECK (plus_accum_short (sa_a
, sa_b
), -0.25);
219 CHECK (plus_accum_regular (a_a
, a_b
), -0.25);
220 CHECK (plus_accum_long (la_a
, la_b
), -0.25);
222 CHECK (minus_accum_short (sa_a
, sa_b
), 2.75);
223 CHECK (minus_accum_regular (a_a
, a_b
), 200.75);
224 CHECK (minus_accum_long (la_a
, la_b
), 2000.75);
226 CHECK (mult_accum_short (sa_a
, sa_b
), -1.875);
227 CHECK (mult_accum_regular (a_a
, a_b
), -10075.125);
228 CHECK (mult_accum_long (la_a
, la_b
), -1000750.125);
230 CHECK (div_accum_short (sa_a
, sa_b
), -1.25/1.5);
231 CHECK (div_accum_regular (a_a
, a_b
), -100.25/100.5);
232 CHECK (div_accum_long (la_a
, la_b
), -1000.25/1000.5);
234 /* Unsigned accum/accum operations, non-saturating. */
236 CHECK (plus_accum_uns_short (usa_a
, usa_b
), 4.25);
237 CHECK (plus_accum_uns_regular (ua_a
, ua_b
), 425.75);
238 CHECK (plus_accum_uns_long (ula_a
, ula_b
), 2550.0);
240 CHECK (minus_accum_uns_short (usa_a
, usa_b
), 0.75);
241 CHECK (minus_accum_uns_regular (ua_a
, ua_b
), 85.25);
242 CHECK (minus_accum_uns_long (ula_a
, ula_b
), 551.0);
244 CHECK (mult_accum_uns_short (usa_a
, usa_b
), 4.375);
245 CHECK (mult_accum_uns_regular (ua_a
, ua_b
), 43498.875);
246 CHECK (mult_accum_uns_long (ula_a
, ula_b
), 1549724.75);
248 CHECK (div_accum_uns_short (usa_a
, usa_b
), 2.5/1.75);
249 CHECK (div_accum_uns_regular (ua_a
, ua_b
), 255.5/170.25);
250 CHECK (div_accum_uns_long (ula_a
, ula_b
), 1550.5/999.5);
252 /* Signed accum/accum operations, saturating. */
254 CHECK_EXACT (plus_accum_sat_short (sa_c
, sa_d
), SACCUM_MAX
);
255 CHECK_EXACT (plus_accum_sat_short (sa_e
, sa_f
), SACCUM_MIN
);
256 CHECK_EXACT (plus_accum_sat_regular (a_c
, a_d
), ACCUM_MAX
);
257 CHECK_EXACT (plus_accum_sat_regular (a_e
, a_f
), ACCUM_MIN
);
258 CHECK_EXACT (plus_accum_sat_long (la_c
, la_d
), LACCUM_MAX
);
259 CHECK_EXACT (plus_accum_sat_long (la_e
, la_f
), LACCUM_MIN
);
261 CHECK_EXACT (minus_accum_sat_short (sa_e
, sa_d
), SACCUM_MIN
);
262 CHECK_EXACT (minus_accum_sat_short (sa_c
, sa_f
), SACCUM_MAX
);
263 CHECK_EXACT (minus_accum_sat_regular (a_e
, a_d
), ACCUM_MIN
);
264 CHECK_EXACT (minus_accum_sat_regular (a_c
, a_f
), ACCUM_MAX
);
265 CHECK_EXACT (minus_accum_sat_long (la_e
, la_d
), LACCUM_MIN
);
266 CHECK_EXACT (minus_accum_sat_long (la_c
, la_f
), LACCUM_MAX
);
268 CHECK_EXACT (mult_accum_sat_short (sa_c
, sa_d
), SACCUM_MAX
);
269 CHECK_EXACT (mult_accum_sat_short (sa_c
, sa_e
), SACCUM_MIN
);
270 CHECK_EXACT (mult_accum_sat_regular (a_c
, a_d
), ACCUM_MAX
);
271 CHECK_EXACT (mult_accum_sat_regular (a_c
, a_e
), ACCUM_MIN
);
272 CHECK_EXACT (mult_accum_sat_long (la_c
, la_d
), LACCUM_MAX
);
273 CHECK_EXACT (mult_accum_sat_long (la_c
, la_e
), LACCUM_MIN
);
275 CHECK_EXACT (div_accum_sat_short (sa_d
, sa_g
), SACCUM_MAX
);
276 CHECK_EXACT (div_accum_sat_short (sa_e
, sa_g
), SACCUM_MIN
);
277 CHECK_EXACT (div_accum_sat_regular (a_c
, a_g
), ACCUM_MAX
);
278 CHECK_EXACT (div_accum_sat_regular (a_e
, a_g
), ACCUM_MIN
);
279 CHECK_EXACT (div_accum_sat_long (la_d
, la_g
), LACCUM_MAX
);
280 CHECK_EXACT (div_accum_sat_long (la_e
, la_g
), LACCUM_MIN
);
282 /* Unsigned accum/accum operations, saturating. */
284 CHECK_EXACT (plus_accum_uns_sat_short (usa_c
, usa_d
), USACCUM_MAX
);
285 CHECK_EXACT (plus_accum_uns_sat_regular (ua_c
, ua_d
), UACCUM_MAX
);
286 CHECK_EXACT (plus_accum_uns_sat_long (ula_c
, ula_d
), ULACCUM_MAX
);
288 CHECK_EXACT (minus_accum_uns_sat_short (usa_d
, usa_c
), 0uhk
);
289 CHECK_EXACT (minus_accum_uns_sat_regular (ua_d
, ua_c
), 0uk
);
290 CHECK_EXACT (minus_accum_uns_sat_long (ula_d
, ula_c
), 0ulk
);
292 CHECK_EXACT (mult_accum_uns_sat_short (usa_c
, usa_d
), USACCUM_MAX
);
293 CHECK_EXACT (mult_accum_uns_sat_regular (ua_c
, ua_d
), UACCUM_MAX
);
294 CHECK_EXACT (mult_accum_uns_sat_long (ula_c
, ula_d
), ULACCUM_MAX
);
296 CHECK_EXACT (div_accum_uns_sat_short (usa_c
, usa_e
), USACCUM_MAX
);
297 CHECK_EXACT (div_accum_uns_sat_regular (ua_c
, ua_e
), UACCUM_MAX
);
298 CHECK_EXACT (div_accum_uns_sat_long (ula_c
, ula_e
), ULACCUM_MAX
);