1#!/bin/bash
2
3# ULP error check script.
4#
5# Copyright (c) 2019-2022, Arm Limited.
6# SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception
7
8#set -x
9set -eu
10
11# cd to bin directory.
12cd "${0%/*}"
13
14rmodes='n u d z'
15#rmodes=n
16flags="${ULPFLAGS:--q}"
17emu="$@"
18
19FAIL=0
20PASS=0
21
22t() {
23	[ $r = "n" ] && Lt=$L || Lt=$Ldir
24	$emu ./ulp -r $r -e $Lt $flags "$@" && PASS=$((PASS+1)) || FAIL=$((FAIL+1))
25}
26
27check() {
28	$emu ./ulp -f -q "$@" >/dev/null
29}
30
31Ldir=0.5
32for r in $rmodes
33do
34L=0.01
35t exp  0 0xffff000000000000 10000
36t exp  0x1p-6     0x1p6     40000
37t exp -0x1p-6    -0x1p6     40000
38t exp  633.3      733.3     10000
39t exp -633.3     -777.3     10000
40
41L=0.01
42t exp2  0 0xffff000000000000 10000
43t exp2  0x1p-6     0x1p6     40000
44t exp2 -0x1p-6    -0x1p6     40000
45t exp2  633.3      733.3     10000
46t exp2 -633.3     -777.3     10000
47
48L=0.02
49t log  0 0xffff000000000000 10000
50t log  0x1p-4    0x1p4      40000
51t log  0         inf        40000
52
53L=0.05
54t log2  0 0xffff000000000000 10000
55t log2  0x1p-4    0x1p4      40000
56t log2  0         inf        40000
57
58L=0.05
59t pow  0.5  2.0  x  0  inf 20000
60t pow -0.5 -2.0  x  0  inf 20000
61t pow  0.5  2.0  x -0 -inf 20000
62t pow -0.5 -2.0  x -0 -inf 20000
63t pow  0.5  2.0  x  0x1p-10  0x1p10  40000
64t pow  0.5  2.0  x -0x1p-10 -0x1p10  40000
65t pow  0    inf  x    0.5      2.0   80000
66t pow  0    inf  x   -0.5     -2.0   80000
67t pow  0x1.fp-1   0x1.08p0  x  0x1p8 0x1p17  80000
68t pow  0x1.fp-1   0x1.08p0  x -0x1p8 -0x1p17 80000
69t pow  0         0x1p-1000  x  0 1.0 50000
70t pow  0x1p1000        inf  x  0 1.0 50000
71t pow  0x1.ffffffffffff0p-1  0x1.0000000000008p0 x 0x1p60 0x1p68 50000
72t pow  0x1.ffffffffff000p-1  0x1p0 x 0x1p50 0x1p52 50000
73t pow -0x1.ffffffffff000p-1 -0x1p0 x 0x1p50 0x1p52 50000
74
75L=1.0
76Ldir=0.9
77t erf  0 0xffff000000000000 10000
78t erf  0x1p-1022  0x1p-26   40000
79t erf  -0x1p-1022 -0x1p-26  40000
80t erf  0x1p-26    0x1p3     40000
81t erf  -0x1p-26  -0x1p3     40000
82t erf  0         inf        40000
83Ldir=0.5
84
85L=0.01
86t expf  0    0xffff0000    10000
87t expf  0x1p-14   0x1p8    50000
88t expf -0x1p-14  -0x1p8    50000
89
90L=0.01
91t exp2f  0    0xffff0000   10000
92t exp2f  0x1p-14   0x1p8   50000
93t exp2f -0x1p-14  -0x1p8   50000
94
95L=0.32
96t logf  0    0xffff0000    10000
97t logf  0x1p-4    0x1p4    50000
98t logf  0         inf      50000
99
100L=0.26
101t log2f  0    0xffff0000   10000
102t log2f  0x1p-4    0x1p4   50000
103t log2f  0         inf     50000
104
105L=0.06
106t sinf  0    0xffff0000    10000
107t sinf  0x1p-14  0x1p54    50000
108t sinf -0x1p-14 -0x1p54    50000
109
110L=0.06
111t cosf  0    0xffff0000    10000
112t cosf  0x1p-14  0x1p54    50000
113t cosf -0x1p-14 -0x1p54    50000
114
115L=0.06
116t sincosf_sinf  0    0xffff0000    10000
117t sincosf_sinf  0x1p-14  0x1p54    50000
118t sincosf_sinf -0x1p-14 -0x1p54    50000
119
120L=0.06
121t sincosf_cosf  0    0xffff0000    10000
122t sincosf_cosf  0x1p-14  0x1p54    50000
123t sincosf_cosf -0x1p-14 -0x1p54    50000
124
125L=0.4
126t powf  0x1p-1   0x1p1  x  0x1p-7 0x1p7   50000
127t powf  0x1p-1   0x1p1  x -0x1p-7 -0x1p7  50000
128t powf  0x1p-70 0x1p70  x  0x1p-1 0x1p1   50000
129t powf  0x1p-70 0x1p70  x  -0x1p-1 -0x1p1 50000
130t powf  0x1.ep-1 0x1.1p0 x  0x1p8 0x1p14  50000
131t powf  0x1.ep-1 0x1.1p0 x -0x1p8 -0x1p14 50000
132
133L=0.6
134Ldir=0.9
135t erff  0      0xffff0000 10000
136t erff  0x1p-127  0x1p-26 40000
137t erff -0x1p-127 -0x1p-26 40000
138t erff  0x1p-26   0x1p3   40000
139t erff -0x1p-26  -0x1p3   40000
140t erff  0         inf     40000
141Ldir=0.5
142
143done
144
145# vector functions
146Ldir=0.5
147r='n'
148flags="${ULPFLAGS:--q}"
149runs=
150check __s_exp 1 && runs=1
151runv=
152check __v_exp 1 && runv=1
153runvn=
154check __vn_exp 1 && runvn=1
155
156range_exp='
157  0 0xffff000000000000 10000
158  0x1p-6     0x1p6     400000
159 -0x1p-6    -0x1p6     400000
160  633.3      733.3     10000
161 -633.3     -777.3     10000
162'
163
164range_log='
165  0 0xffff000000000000 10000
166  0x1p-4     0x1p4     400000
167  0          inf       400000
168'
169
170range_pow='
171 0x1p-1   0x1p1  x  0x1p-10 0x1p10   50000
172 0x1p-1   0x1p1  x -0x1p-10 -0x1p10  50000
173 0x1p-500 0x1p500  x  0x1p-1 0x1p1   50000
174 0x1p-500 0x1p500  x  -0x1p-1 -0x1p1 50000
175 0x1.ep-1 0x1.1p0 x  0x1p8 0x1p16    50000
176 0x1.ep-1 0x1.1p0 x -0x1p8 -0x1p16   50000
177'
178
179range_sin='
180  0 0xffff000000000000 10000
181  0x1p-4     0x1p4     400000
182 -0x1p-23    0x1p23    400000
183'
184range_cos="$range_sin"
185
186range_expf='
187  0    0xffff0000    10000
188  0x1p-14   0x1p8    500000
189 -0x1p-14  -0x1p8    500000
190'
191
192range_expf_1u="$range_expf"
193range_exp2f="$range_expf"
194range_exp2f_1u="$range_expf"
195
196range_logf='
197 0    0xffff0000    10000
198 0x1p-4    0x1p4    500000
199'
200
201range_sinf='
202 0    0xffff0000    10000
203 0x1p-4    0x1p4    300000
204-0x1p-9   -0x1p9    300000
205'
206range_cosf="$range_sinf"
207
208range_powf='
209 0x1p-1   0x1p1  x  0x1p-7 0x1p7   50000
210 0x1p-1   0x1p1  x -0x1p-7 -0x1p7  50000
211 0x1p-70 0x1p70  x  0x1p-1 0x1p1   50000
212 0x1p-70 0x1p70  x  -0x1p-1 -0x1p1 50000
213 0x1.ep-1 0x1.1p0 x  0x1p8 0x1p14  50000
214 0x1.ep-1 0x1.1p0 x -0x1p8 -0x1p14 50000
215'
216
217# error limits
218L_exp=1.9
219L_log=1.2
220L_pow=0.05
221L_sin=3.0
222L_cos=3.0
223L_expf=1.49
224L_expf_1u=0.4
225L_exp2f=1.49
226L_exp2f_1u=0.4
227L_logf=2.9
228L_sinf=1.4
229L_cosf=1.4
230L_powf=2.1
231
232while read G F R D
233do
234	[ "$R" = 1 ] || continue
235	case "$G" in \#*) continue ;; esac
236	eval range="\${range_$G}"
237	eval L="\${L_$G}"
238	while read X
239	do
240		[ -n "$X" ] || continue
241		case "$X" in \#*) continue ;; esac
242		disable_fenv=""
243		if [ -z "$WANT_SIMD_EXCEPT" ] || [ $WANT_SIMD_EXCEPT -eq 0 ]; then
244			# If library was built with SIMD exceptions
245			# disabled, disable fenv checking in ulp
246			# tool. Otherwise, fenv checking may still be
247			# disabled by adding -f to the end of the run
248			# line.
249			disable_fenv="-f"
250		fi
251		t $D $disable_fenv $F $X
252	done << EOF
253$range
254EOF
255done << EOF
256# group symbol run
257exp  __s_exp       $runs
258exp  __v_exp       $runv
259exp  __vn_exp      $runvn
260exp  _ZGVnN2v_exp  $runvn
261
262log  __s_log       $runs
263log  __v_log       $runv
264log  __vn_log      $runvn
265log  _ZGVnN2v_log  $runvn
266
267pow __s_pow       $runs         -f
268pow __v_pow       $runv         -f
269pow __vn_pow      $runvn        -f
270pow _ZGVnN2vv_pow $runvn        -f
271
272sin __s_sin       $runs
273sin __v_sin       $runv
274sin __vn_sin      $runvn
275sin _ZGVnN2v_sin  $runvn
276
277cos __s_cos       $runs
278cos __v_cos       $runv
279cos __vn_cos      $runvn
280cos _ZGVnN2v_cos  $runvn
281
282expf __s_expf      $runs
283expf __v_expf      $runv
284expf __vn_expf     $runvn
285expf _ZGVnN4v_expf $runvn
286
287expf_1u __s_expf_1u   $runs     -f
288expf_1u __v_expf_1u   $runv     -f
289expf_1u __vn_expf_1u  $runvn    -f
290
291exp2f __s_exp2f      $runs
292exp2f __v_exp2f      $runv
293exp2f __vn_exp2f     $runvn
294exp2f _ZGVnN4v_exp2f $runvn
295
296exp2f_1u __s_exp2f_1u  $runs    -f
297exp2f_1u __v_exp2f_1u  $runv    -f
298exp2f_1u __vn_exp2f_1u $runvn   -f
299
300logf __s_logf      $runs
301logf __v_logf      $runv
302logf __vn_logf     $runvn
303logf _ZGVnN4v_logf $runvn
304
305sinf __s_sinf      $runs
306sinf __v_sinf      $runv
307sinf __vn_sinf     $runvn
308sinf _ZGVnN4v_sinf $runvn
309
310cosf __s_cosf      $runs
311cosf __v_cosf      $runv
312cosf __vn_cosf     $runvn
313cosf _ZGVnN4v_cosf $runvn
314
315powf __s_powf       $runs       -f
316powf __v_powf       $runv       -f
317powf __vn_powf      $runvn      -f
318powf _ZGVnN4vv_powf $runvn      -f
319EOF
320
321[ 0 -eq $FAIL ] || {
322	echo "FAILED $FAIL PASSED $PASS"
323	exit 1
324}
325