1703c08d9STaylor Simpson /*
21a442c09STaylor Simpson * Copyright(c) 2020-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
3703c08d9STaylor Simpson *
4703c08d9STaylor Simpson * This program is free software; you can redistribute it and/or modify
5703c08d9STaylor Simpson * it under the terms of the GNU General Public License as published by
6703c08d9STaylor Simpson * the Free Software Foundation; either version 2 of the License, or
7703c08d9STaylor Simpson * (at your option) any later version.
8703c08d9STaylor Simpson *
9703c08d9STaylor Simpson * This program is distributed in the hope that it will be useful,
10703c08d9STaylor Simpson * but WITHOUT ANY WARRANTY; without even the implied warranty of
11703c08d9STaylor Simpson * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12703c08d9STaylor Simpson * GNU General Public License for more details.
13703c08d9STaylor Simpson *
14703c08d9STaylor Simpson * You should have received a copy of the GNU General Public License
15703c08d9STaylor Simpson * along with this program; if not, see <http://www.gnu.org/licenses/>.
16703c08d9STaylor Simpson */
17703c08d9STaylor Simpson
18703c08d9STaylor Simpson /*
19703c08d9STaylor Simpson * This test checks various FP operations performed on Hexagon
20703c08d9STaylor Simpson */
21703c08d9STaylor Simpson
22703c08d9STaylor Simpson #include <stdio.h>
230d57cd61STaylor Simpson #include <stdint.h>
24163e5fa3STaylor Simpson #include <float.h>
25703c08d9STaylor Simpson
26703c08d9STaylor Simpson int err;
27703c08d9STaylor Simpson
280d57cd61STaylor Simpson #include "hex_test.h"
29703c08d9STaylor Simpson
check_fpstatus_bit(uint32_t usr,uint32_t expect,uint32_t flag,const char * name)300d57cd61STaylor Simpson static void check_fpstatus_bit(uint32_t usr, uint32_t expect, uint32_t flag,
310d57cd61STaylor Simpson const char *name)
32703c08d9STaylor Simpson {
330d57cd61STaylor Simpson uint32_t bit = 1 << flag;
34703c08d9STaylor Simpson if ((usr & bit) != (expect & bit)) {
350d57cd61STaylor Simpson printf("ERROR %s: usr = %d, expect = %d\n", name,
36703c08d9STaylor Simpson (usr >> flag) & 1, (expect >> flag) & 1);
37703c08d9STaylor Simpson err++;
38703c08d9STaylor Simpson }
39703c08d9STaylor Simpson }
40703c08d9STaylor Simpson
check_fpstatus(uint32_t usr,uint32_t expect)410d57cd61STaylor Simpson static void check_fpstatus(uint32_t usr, uint32_t expect)
42703c08d9STaylor Simpson {
430d57cd61STaylor Simpson check_fpstatus_bit(usr, expect, USR_FPINVF_BIT, "Invalid");
440d57cd61STaylor Simpson check_fpstatus_bit(usr, expect, USR_FPDBZF_BIT, "Div by zero");
450d57cd61STaylor Simpson check_fpstatus_bit(usr, expect, USR_FPOVFF_BIT, "Overflow");
460d57cd61STaylor Simpson check_fpstatus_bit(usr, expect, USR_FPUNFF_BIT, "Underflow");
470d57cd61STaylor Simpson check_fpstatus_bit(usr, expect, USR_FPINPF_BIT, "Inexact");
48703c08d9STaylor Simpson }
49703c08d9STaylor Simpson
check_compare_exception(void)50703c08d9STaylor Simpson static void check_compare_exception(void)
51703c08d9STaylor Simpson {
520d57cd61STaylor Simpson uint32_t cmp;
530d57cd61STaylor Simpson uint32_t usr;
54703c08d9STaylor Simpson
55*6c67d98cSMichael Tokarev /* Check that FP compares are quiet (don't raise any exceptions) */
56703c08d9STaylor Simpson asm (CLEAR_FPSTATUS
57703c08d9STaylor Simpson "p0 = sfcmp.eq(%2, %3)\n\t"
58703c08d9STaylor Simpson "%0 = p0\n\t"
59703c08d9STaylor Simpson "%1 = usr\n\t"
600d57cd61STaylor Simpson : "=r"(cmp), "=r"(usr) : "r"(SF_QNaN), "r"(SF_any)
61703c08d9STaylor Simpson : "r2", "p0", "usr");
62703c08d9STaylor Simpson check32(cmp, 0);
63703c08d9STaylor Simpson check_fpstatus(usr, 0);
64703c08d9STaylor Simpson
65703c08d9STaylor Simpson asm (CLEAR_FPSTATUS
66703c08d9STaylor Simpson "p0 = sfcmp.gt(%2, %3)\n\t"
67703c08d9STaylor Simpson "%0 = p0\n\t"
68703c08d9STaylor Simpson "%1 = usr\n\t"
690d57cd61STaylor Simpson : "=r"(cmp), "=r"(usr) : "r"(SF_QNaN), "r"(SF_any)
70703c08d9STaylor Simpson : "r2", "p0", "usr");
71703c08d9STaylor Simpson check32(cmp, 0);
72703c08d9STaylor Simpson check_fpstatus(usr, 0);
73703c08d9STaylor Simpson
74703c08d9STaylor Simpson asm (CLEAR_FPSTATUS
75703c08d9STaylor Simpson "p0 = sfcmp.ge(%2, %3)\n\t"
76703c08d9STaylor Simpson "%0 = p0\n\t"
77703c08d9STaylor Simpson "%1 = usr\n\t"
780d57cd61STaylor Simpson : "=r"(cmp), "=r"(usr) : "r"(SF_QNaN), "r"(SF_any)
79703c08d9STaylor Simpson : "r2", "p0", "usr");
80703c08d9STaylor Simpson check32(cmp, 0);
81703c08d9STaylor Simpson check_fpstatus(usr, 0);
82703c08d9STaylor Simpson
83703c08d9STaylor Simpson asm (CLEAR_FPSTATUS
84703c08d9STaylor Simpson "p0 = dfcmp.eq(%2, %3)\n\t"
85703c08d9STaylor Simpson "%0 = p0\n\t"
86703c08d9STaylor Simpson "%1 = usr\n\t"
870d57cd61STaylor Simpson : "=r"(cmp), "=r"(usr) : "r"(DF_QNaN), "r"(DF_any)
88703c08d9STaylor Simpson : "r2", "p0", "usr");
89703c08d9STaylor Simpson check32(cmp, 0);
90703c08d9STaylor Simpson check_fpstatus(usr, 0);
91703c08d9STaylor Simpson
92703c08d9STaylor Simpson asm (CLEAR_FPSTATUS
93703c08d9STaylor Simpson "p0 = dfcmp.gt(%2, %3)\n\t"
94703c08d9STaylor Simpson "%0 = p0\n\t"
95703c08d9STaylor Simpson "%1 = usr\n\t"
960d57cd61STaylor Simpson : "=r"(cmp), "=r"(usr) : "r"(DF_QNaN), "r"(DF_any)
97703c08d9STaylor Simpson : "r2", "p0", "usr");
98703c08d9STaylor Simpson check32(cmp, 0);
99703c08d9STaylor Simpson check_fpstatus(usr, 0);
100703c08d9STaylor Simpson
101703c08d9STaylor Simpson asm (CLEAR_FPSTATUS
102703c08d9STaylor Simpson "p0 = dfcmp.ge(%2, %3)\n\t"
103703c08d9STaylor Simpson "%0 = p0\n\t"
104703c08d9STaylor Simpson "%1 = usr\n\t"
1050d57cd61STaylor Simpson : "=r"(cmp), "=r"(usr) : "r"(DF_QNaN), "r"(DF_any)
106703c08d9STaylor Simpson : "r2", "p0", "usr");
107703c08d9STaylor Simpson check32(cmp, 0);
108703c08d9STaylor Simpson check_fpstatus(usr, 0);
109703c08d9STaylor Simpson }
110703c08d9STaylor Simpson
check_sfminmax(void)111703c08d9STaylor Simpson static void check_sfminmax(void)
112703c08d9STaylor Simpson {
1130d57cd61STaylor Simpson uint32_t minmax;
1140d57cd61STaylor Simpson uint32_t usr;
115703c08d9STaylor Simpson
116703c08d9STaylor Simpson /*
117703c08d9STaylor Simpson * Execute sfmin/sfmax instructions with one operand as NaN
118703c08d9STaylor Simpson * Check that
119703c08d9STaylor Simpson * Result is the other operand
120703c08d9STaylor Simpson * Invalid bit in USR is not set
121703c08d9STaylor Simpson */
122703c08d9STaylor Simpson asm (CLEAR_FPSTATUS
123703c08d9STaylor Simpson "%0 = sfmin(%2, %3)\n\t"
124703c08d9STaylor Simpson "%1 = usr\n\t"
1250d57cd61STaylor Simpson : "=r"(minmax), "=r"(usr) : "r"(SF_QNaN), "r"(SF_any)
126703c08d9STaylor Simpson : "r2", "usr");
1270d57cd61STaylor Simpson check32(minmax, SF_any);
128703c08d9STaylor Simpson check_fpstatus(usr, 0);
129703c08d9STaylor Simpson
130703c08d9STaylor Simpson asm (CLEAR_FPSTATUS
131703c08d9STaylor Simpson "%0 = sfmax(%2, %3)\n\t"
132703c08d9STaylor Simpson "%1 = usr\n\t"
1330d57cd61STaylor Simpson : "=r"(minmax), "=r"(usr) : "r"(SF_QNaN), "r"(SF_any)
134703c08d9STaylor Simpson : "r2", "usr");
1350d57cd61STaylor Simpson check32(minmax, SF_any);
136703c08d9STaylor Simpson check_fpstatus(usr, 0);
137703c08d9STaylor Simpson
138703c08d9STaylor Simpson /*
139703c08d9STaylor Simpson * Execute sfmin/sfmax instructions with both operands NaN
140703c08d9STaylor Simpson * Check that
1410d57cd61STaylor Simpson * Result is SF_HEX_NaN
142703c08d9STaylor Simpson * Invalid bit in USR is set
143703c08d9STaylor Simpson */
144703c08d9STaylor Simpson asm (CLEAR_FPSTATUS
145703c08d9STaylor Simpson "%0 = sfmin(%2, %3)\n\t"
146703c08d9STaylor Simpson "%1 = usr\n\t"
1470d57cd61STaylor Simpson : "=r"(minmax), "=r"(usr) : "r"(SF_QNaN), "r"(SF_QNaN)
148703c08d9STaylor Simpson : "r2", "usr");
1490d57cd61STaylor Simpson check32(minmax, SF_HEX_NaN);
150703c08d9STaylor Simpson check_fpstatus(usr, 0);
151703c08d9STaylor Simpson
152703c08d9STaylor Simpson asm (CLEAR_FPSTATUS
153703c08d9STaylor Simpson "%0 = sfmax(%2, %3)\n\t"
154703c08d9STaylor Simpson "%1 = usr\n\t"
1550d57cd61STaylor Simpson : "=r"(minmax), "=r"(usr) : "r"(SF_QNaN), "r"(SF_QNaN)
156703c08d9STaylor Simpson : "r2", "usr");
1570d57cd61STaylor Simpson check32(minmax, SF_HEX_NaN);
158703c08d9STaylor Simpson check_fpstatus(usr, 0);
159703c08d9STaylor Simpson }
160703c08d9STaylor Simpson
check_dfminmax(void)161703c08d9STaylor Simpson static void check_dfminmax(void)
162703c08d9STaylor Simpson {
1630d57cd61STaylor Simpson uint64_t minmax;
1640d57cd61STaylor Simpson uint32_t usr;
165703c08d9STaylor Simpson
166703c08d9STaylor Simpson /*
167d76dd816STaylor Simpson * Execute dfmin/dfmax instructions with one operand as SNaN
168703c08d9STaylor Simpson * Check that
169703c08d9STaylor Simpson * Result is the other operand
170703c08d9STaylor Simpson * Invalid bit in USR is set
171703c08d9STaylor Simpson */
172703c08d9STaylor Simpson asm (CLEAR_FPSTATUS
173703c08d9STaylor Simpson "%0 = dfmin(%2, %3)\n\t"
174703c08d9STaylor Simpson "%1 = usr\n\t"
1750d57cd61STaylor Simpson : "=r"(minmax), "=r"(usr) : "r"(DF_SNaN), "r"(DF_any)
176703c08d9STaylor Simpson : "r2", "usr");
1770d57cd61STaylor Simpson check64(minmax, DF_any);
1780d57cd61STaylor Simpson check_fpstatus(usr, USR_FPINVF);
179703c08d9STaylor Simpson
180703c08d9STaylor Simpson asm (CLEAR_FPSTATUS
181703c08d9STaylor Simpson "%0 = dfmax(%2, %3)\n\t"
182703c08d9STaylor Simpson "%1 = usr\n\t"
1830d57cd61STaylor Simpson : "=r"(minmax), "=r"(usr) : "r"(DF_SNaN), "r"(DF_any)
184703c08d9STaylor Simpson : "r2", "usr");
1850d57cd61STaylor Simpson check64(minmax, DF_any);
1860d57cd61STaylor Simpson check_fpstatus(usr, USR_FPINVF);
187703c08d9STaylor Simpson
188703c08d9STaylor Simpson /*
189d76dd816STaylor Simpson * Execute dfmin/dfmax instructions with one operand as QNaN
190d76dd816STaylor Simpson * Check that
191d76dd816STaylor Simpson * Result is the other operand
192d76dd816STaylor Simpson * No bit in USR is set
193d76dd816STaylor Simpson */
194d76dd816STaylor Simpson asm (CLEAR_FPSTATUS
195d76dd816STaylor Simpson "%0 = dfmin(%2, %3)\n\t"
196d76dd816STaylor Simpson "%1 = usr\n\t"
1970d57cd61STaylor Simpson : "=r"(minmax), "=r"(usr) : "r"(DF_QNaN), "r"(DF_any)
198d76dd816STaylor Simpson : "r2", "usr");
1990d57cd61STaylor Simpson check64(minmax, DF_any);
200d76dd816STaylor Simpson check_fpstatus(usr, 0);
201d76dd816STaylor Simpson
202d76dd816STaylor Simpson asm (CLEAR_FPSTATUS
203d76dd816STaylor Simpson "%0 = dfmax(%2, %3)\n\t"
204d76dd816STaylor Simpson "%1 = usr\n\t"
2050d57cd61STaylor Simpson : "=r"(minmax), "=r"(usr) : "r"(DF_QNaN), "r"(DF_any)
206d76dd816STaylor Simpson : "r2", "usr");
2070d57cd61STaylor Simpson check64(minmax, DF_any);
208d76dd816STaylor Simpson check_fpstatus(usr, 0);
209d76dd816STaylor Simpson
210d76dd816STaylor Simpson /*
211d76dd816STaylor Simpson * Execute dfmin/dfmax instructions with both operands SNaN
212703c08d9STaylor Simpson * Check that
2130d57cd61STaylor Simpson * Result is DF_HEX_NaN
214703c08d9STaylor Simpson * Invalid bit in USR is set
215703c08d9STaylor Simpson */
216703c08d9STaylor Simpson asm (CLEAR_FPSTATUS
217703c08d9STaylor Simpson "%0 = dfmin(%2, %3)\n\t"
218703c08d9STaylor Simpson "%1 = usr\n\t"
219d76dd816STaylor Simpson : "=r"(minmax), "=r"(usr) : "r"(DF_SNaN), "r"(DF_SNaN)
220703c08d9STaylor Simpson : "r2", "usr");
2210d57cd61STaylor Simpson check64(minmax, DF_HEX_NaN);
2220d57cd61STaylor Simpson check_fpstatus(usr, USR_FPINVF);
223703c08d9STaylor Simpson
224703c08d9STaylor Simpson asm (CLEAR_FPSTATUS
225703c08d9STaylor Simpson "%0 = dfmax(%2, %3)\n\t"
226703c08d9STaylor Simpson "%1 = usr\n\t"
227d76dd816STaylor Simpson : "=r"(minmax), "=r"(usr) : "r"(DF_SNaN), "r"(DF_SNaN)
228703c08d9STaylor Simpson : "r2", "usr");
2290d57cd61STaylor Simpson check64(minmax, DF_HEX_NaN);
2300d57cd61STaylor Simpson check_fpstatus(usr, USR_FPINVF);
231d76dd816STaylor Simpson
232d76dd816STaylor Simpson /*
233d76dd816STaylor Simpson * Execute dfmin/dfmax instructions with both operands QNaN
234d76dd816STaylor Simpson * Check that
2350d57cd61STaylor Simpson * Result is DF_HEX_NaN
236d76dd816STaylor Simpson * No bit in USR is set
237d76dd816STaylor Simpson */
238d76dd816STaylor Simpson asm (CLEAR_FPSTATUS
239d76dd816STaylor Simpson "%0 = dfmin(%2, %3)\n\t"
240d76dd816STaylor Simpson "%1 = usr\n\t"
241d76dd816STaylor Simpson : "=r"(minmax), "=r"(usr) : "r"(DF_QNaN), "r"(DF_QNaN)
242d76dd816STaylor Simpson : "r2", "usr");
2430d57cd61STaylor Simpson check64(minmax, DF_HEX_NaN);
244d76dd816STaylor Simpson check_fpstatus(usr, 0);
245d76dd816STaylor Simpson
246d76dd816STaylor Simpson asm (CLEAR_FPSTATUS
247d76dd816STaylor Simpson "%0 = dfmax(%2, %3)\n\t"
248d76dd816STaylor Simpson "%1 = usr\n\t"
249d76dd816STaylor Simpson : "=r"(minmax), "=r"(usr) : "r"(DF_QNaN), "r"(DF_QNaN)
250d76dd816STaylor Simpson : "r2", "usr");
2510d57cd61STaylor Simpson check64(minmax, DF_HEX_NaN);
252d76dd816STaylor Simpson check_fpstatus(usr, 0);
253703c08d9STaylor Simpson }
254703c08d9STaylor Simpson
check_sfrecipa(void)25577ccf444STaylor Simpson static void check_sfrecipa(void)
256d934c16dSTaylor Simpson {
2570d57cd61STaylor Simpson uint32_t result;
2580d57cd61STaylor Simpson uint32_t usr;
2590d57cd61STaylor Simpson uint32_t pred;
260d934c16dSTaylor Simpson
261d934c16dSTaylor Simpson /*
262d934c16dSTaylor Simpson * Check that sfrecipa doesn't set status bits when
263d934c16dSTaylor Simpson * a NaN with bit 22 non-zero is passed
264d934c16dSTaylor Simpson */
265d934c16dSTaylor Simpson asm (CLEAR_FPSTATUS
266d934c16dSTaylor Simpson "%0,p0 = sfrecipa(%2, %3)\n\t"
267d934c16dSTaylor Simpson "%1 = usr\n\t"
2680d57cd61STaylor Simpson : "=r"(result), "=r"(usr) : "r"(SF_QNaN), "r"(SF_any)
269d934c16dSTaylor Simpson : "r2", "p0", "usr");
2700d57cd61STaylor Simpson check32(result, SF_HEX_NaN);
271d934c16dSTaylor Simpson check_fpstatus(usr, 0);
272d934c16dSTaylor Simpson
273d934c16dSTaylor Simpson asm (CLEAR_FPSTATUS
274d934c16dSTaylor Simpson "%0,p0 = sfrecipa(%2, %3)\n\t"
275d934c16dSTaylor Simpson "%1 = usr\n\t"
2760d57cd61STaylor Simpson : "=r"(result), "=r"(usr) : "r"(SF_any), "r"(SF_QNaN)
277d934c16dSTaylor Simpson : "r2", "p0", "usr");
2780d57cd61STaylor Simpson check32(result, SF_HEX_NaN);
279d934c16dSTaylor Simpson check_fpstatus(usr, 0);
280d934c16dSTaylor Simpson
281d934c16dSTaylor Simpson asm (CLEAR_FPSTATUS
282d934c16dSTaylor Simpson "%0,p0 = sfrecipa(%2, %2)\n\t"
283d934c16dSTaylor Simpson "%1 = usr\n\t"
2840d57cd61STaylor Simpson : "=r"(result), "=r"(usr) : "r"(SF_QNaN)
285d934c16dSTaylor Simpson : "r2", "p0", "usr");
2860d57cd61STaylor Simpson check32(result, SF_HEX_NaN);
287d934c16dSTaylor Simpson check_fpstatus(usr, 0);
288d934c16dSTaylor Simpson
289d934c16dSTaylor Simpson /*
290d934c16dSTaylor Simpson * Check that sfrecipa doesn't set status bits when
291d934c16dSTaylor Simpson * a NaN with bit 22 zero is passed
292d934c16dSTaylor Simpson */
293d934c16dSTaylor Simpson asm (CLEAR_FPSTATUS
294d934c16dSTaylor Simpson "%0,p0 = sfrecipa(%2, %3)\n\t"
295d934c16dSTaylor Simpson "%1 = usr\n\t"
2960d57cd61STaylor Simpson : "=r"(result), "=r"(usr) : "r"(SF_QNaN_special), "r"(SF_any)
297d934c16dSTaylor Simpson : "r2", "p0", "usr");
2980d57cd61STaylor Simpson check32(result, SF_HEX_NaN);
2990d57cd61STaylor Simpson check_fpstatus(usr, USR_FPINVF);
300d934c16dSTaylor Simpson
301d934c16dSTaylor Simpson asm (CLEAR_FPSTATUS
302d934c16dSTaylor Simpson "%0,p0 = sfrecipa(%2, %3)\n\t"
303d934c16dSTaylor Simpson "%1 = usr\n\t"
3040d57cd61STaylor Simpson : "=r"(result), "=r"(usr) : "r"(SF_any), "r"(SF_QNaN_special)
305d934c16dSTaylor Simpson : "r2", "p0", "usr");
3060d57cd61STaylor Simpson check32(result, SF_HEX_NaN);
3070d57cd61STaylor Simpson check_fpstatus(usr, USR_FPINVF);
308d934c16dSTaylor Simpson
309d934c16dSTaylor Simpson asm (CLEAR_FPSTATUS
310d934c16dSTaylor Simpson "%0,p0 = sfrecipa(%2, %2)\n\t"
311d934c16dSTaylor Simpson "%1 = usr\n\t"
3120d57cd61STaylor Simpson : "=r"(result), "=r"(usr) : "r"(SF_QNaN_special)
313d934c16dSTaylor Simpson : "r2", "p0", "usr");
3140d57cd61STaylor Simpson check32(result, SF_HEX_NaN);
3150d57cd61STaylor Simpson check_fpstatus(usr, USR_FPINVF);
316d934c16dSTaylor Simpson
317d934c16dSTaylor Simpson /*
318d934c16dSTaylor Simpson * Check that sfrecipa properly sets divid-by-zero
319d934c16dSTaylor Simpson */
320d934c16dSTaylor Simpson asm (CLEAR_FPSTATUS
321d934c16dSTaylor Simpson "%0,p0 = sfrecipa(%2, %3)\n\t"
322d934c16dSTaylor Simpson "%1 = usr\n\t"
323d934c16dSTaylor Simpson : "=r"(result), "=r"(usr) : "r"(0x885dc960), "r"(0x80000000)
324d934c16dSTaylor Simpson : "r2", "p0", "usr");
325d934c16dSTaylor Simpson check32(result, 0x3f800000);
3260d57cd61STaylor Simpson check_fpstatus(usr, USR_FPDBZF);
327d934c16dSTaylor Simpson
328d934c16dSTaylor Simpson asm (CLEAR_FPSTATUS
329d934c16dSTaylor Simpson "%0,p0 = sfrecipa(%2, %3)\n\t"
330d934c16dSTaylor Simpson "%1 = usr\n\t"
3310d57cd61STaylor Simpson : "=r"(result), "=r"(usr) : "r"(0x7f800000), "r"(SF_zero)
332d934c16dSTaylor Simpson : "r2", "p0", "usr");
333d934c16dSTaylor Simpson check32(result, 0x3f800000);
334d934c16dSTaylor Simpson check_fpstatus(usr, 0);
33577ccf444STaylor Simpson
33677ccf444STaylor Simpson /*
33777ccf444STaylor Simpson * Check that sfrecipa properly handles denorm
33877ccf444STaylor Simpson */
33977ccf444STaylor Simpson asm (CLEAR_FPSTATUS
34077ccf444STaylor Simpson "%0,p0 = sfrecipa(%2, %3)\n\t"
34177ccf444STaylor Simpson "%1 = p0\n\t"
34277ccf444STaylor Simpson : "=r"(result), "=r"(pred) : "r"(SF_denorm), "r"(SF_random)
34377ccf444STaylor Simpson : "p0", "usr");
34477ccf444STaylor Simpson check32(result, 0x6a920001);
34577ccf444STaylor Simpson check32(pred, 0x80);
346d934c16dSTaylor Simpson }
347d934c16dSTaylor Simpson
check_canonical_NaN(void)348703c08d9STaylor Simpson static void check_canonical_NaN(void)
349703c08d9STaylor Simpson {
3500d57cd61STaylor Simpson uint32_t sf_result;
3510d57cd61STaylor Simpson uint64_t df_result;
3520d57cd61STaylor Simpson uint32_t usr;
353703c08d9STaylor Simpson
3540d57cd61STaylor Simpson /* Check that each FP instruction properly returns SF_HEX_NaN/DF_HEX_NaN */
355703c08d9STaylor Simpson asm(CLEAR_FPSTATUS
356703c08d9STaylor Simpson "%0 = sfadd(%2, %3)\n\t"
357703c08d9STaylor Simpson "%1 = usr\n\t"
3580d57cd61STaylor Simpson : "=r"(sf_result), "=r"(usr) : "r"(SF_QNaN), "r"(SF_any)
359703c08d9STaylor Simpson : "r2", "usr");
3600d57cd61STaylor Simpson check32(sf_result, SF_HEX_NaN);
361703c08d9STaylor Simpson check_fpstatus(usr, 0);
362703c08d9STaylor Simpson
363703c08d9STaylor Simpson asm(CLEAR_FPSTATUS
364703c08d9STaylor Simpson "%0 = sfsub(%2, %3)\n\t"
365703c08d9STaylor Simpson "%1 = usr\n\t"
3660d57cd61STaylor Simpson : "=r"(sf_result), "=r"(usr) : "r"(SF_QNaN), "r"(SF_any)
367703c08d9STaylor Simpson : "r2", "usr");
3680d57cd61STaylor Simpson check32(sf_result, SF_HEX_NaN);
369703c08d9STaylor Simpson check_fpstatus(usr, 0);
370703c08d9STaylor Simpson
371703c08d9STaylor Simpson asm(CLEAR_FPSTATUS
372703c08d9STaylor Simpson "%0 = sfmpy(%2, %3)\n\t"
373703c08d9STaylor Simpson "%1 = usr\n\t"
3740d57cd61STaylor Simpson : "=r"(sf_result), "=r"(usr) : "r"(SF_QNaN), "r"(SF_any)
375703c08d9STaylor Simpson : "r2", "usr");
3760d57cd61STaylor Simpson check32(sf_result, SF_HEX_NaN);
377703c08d9STaylor Simpson check_fpstatus(usr, 0);
378703c08d9STaylor Simpson
3790d57cd61STaylor Simpson sf_result = SF_zero;
380703c08d9STaylor Simpson asm(CLEAR_FPSTATUS
381703c08d9STaylor Simpson "%0 += sfmpy(%2, %3)\n\t"
382703c08d9STaylor Simpson "%1 = usr\n\t"
3830d57cd61STaylor Simpson : "+r"(sf_result), "=r"(usr) : "r"(SF_QNaN), "r"(SF_any)
384703c08d9STaylor Simpson : "r2", "usr");
3850d57cd61STaylor Simpson check32(sf_result, SF_HEX_NaN);
386703c08d9STaylor Simpson check_fpstatus(usr, 0);
387703c08d9STaylor Simpson
3880d57cd61STaylor Simpson sf_result = SF_zero;
389703c08d9STaylor Simpson asm(CLEAR_FPSTATUS
390703c08d9STaylor Simpson "p0 = !cmp.eq(r0, r0)\n\t"
391703c08d9STaylor Simpson "%0 += sfmpy(%2, %3, p0):scale\n\t"
392703c08d9STaylor Simpson "%1 = usr\n\t"
3930d57cd61STaylor Simpson : "+r"(sf_result), "=r"(usr) : "r"(SF_QNaN), "r"(SF_any)
394703c08d9STaylor Simpson : "r2", "usr", "p0");
3950d57cd61STaylor Simpson check32(sf_result, SF_HEX_NaN);
396703c08d9STaylor Simpson check_fpstatus(usr, 0);
397703c08d9STaylor Simpson
3980d57cd61STaylor Simpson sf_result = SF_zero;
399703c08d9STaylor Simpson asm(CLEAR_FPSTATUS
400703c08d9STaylor Simpson "%0 -= sfmpy(%2, %3)\n\t"
401703c08d9STaylor Simpson "%1 = usr\n\t"
4020d57cd61STaylor Simpson : "+r"(sf_result), "=r"(usr) : "r"(SF_QNaN), "r"(SF_any)
403703c08d9STaylor Simpson : "r2", "usr");
4040d57cd61STaylor Simpson check32(sf_result, SF_HEX_NaN);
405703c08d9STaylor Simpson check_fpstatus(usr, 0);
406703c08d9STaylor Simpson
4070d57cd61STaylor Simpson sf_result = SF_zero;
408703c08d9STaylor Simpson asm(CLEAR_FPSTATUS
409703c08d9STaylor Simpson "%0 += sfmpy(%2, %3):lib\n\t"
410703c08d9STaylor Simpson "%1 = usr\n\t"
4110d57cd61STaylor Simpson : "+r"(sf_result), "=r"(usr) : "r"(SF_QNaN), "r"(SF_any)
412703c08d9STaylor Simpson : "r2", "usr");
4130d57cd61STaylor Simpson check32(sf_result, SF_HEX_NaN);
414703c08d9STaylor Simpson check_fpstatus(usr, 0);
415703c08d9STaylor Simpson
4160d57cd61STaylor Simpson sf_result = SF_zero;
417703c08d9STaylor Simpson asm(CLEAR_FPSTATUS
418703c08d9STaylor Simpson "%0 -= sfmpy(%2, %3):lib\n\t"
419703c08d9STaylor Simpson "%1 = usr\n\t"
4200d57cd61STaylor Simpson : "+r"(sf_result), "=r"(usr) : "r"(SF_QNaN), "r"(SF_any)
421703c08d9STaylor Simpson : "r2", "usr");
4220d57cd61STaylor Simpson check32(sf_result, SF_HEX_NaN);
423703c08d9STaylor Simpson check_fpstatus(usr, 0);
424703c08d9STaylor Simpson
425703c08d9STaylor Simpson asm(CLEAR_FPSTATUS
426703c08d9STaylor Simpson "%0 = convert_df2sf(%2)\n\t"
427703c08d9STaylor Simpson "%1 = usr\n\t"
428d76dd816STaylor Simpson : "=r"(sf_result), "=r"(usr) : "r"(DF_QNaN)
429703c08d9STaylor Simpson : "r2", "usr");
4300d57cd61STaylor Simpson check32(sf_result, SF_HEX_NaN);
431703c08d9STaylor Simpson check_fpstatus(usr, 0);
432703c08d9STaylor Simpson
433703c08d9STaylor Simpson asm(CLEAR_FPSTATUS
434703c08d9STaylor Simpson "%0 = dfadd(%2, %3)\n\t"
435703c08d9STaylor Simpson "%1 = usr\n\t"
4360d57cd61STaylor Simpson : "=r"(df_result), "=r"(usr) : "r"(DF_QNaN), "r"(DF_any)
437703c08d9STaylor Simpson : "r2", "usr");
4380d57cd61STaylor Simpson check64(df_result, DF_HEX_NaN);
439703c08d9STaylor Simpson check_fpstatus(usr, 0);
440703c08d9STaylor Simpson
441703c08d9STaylor Simpson asm(CLEAR_FPSTATUS
442703c08d9STaylor Simpson "%0 = dfsub(%2, %3)\n\t"
443703c08d9STaylor Simpson "%1 = usr\n\t"
4440d57cd61STaylor Simpson : "=r"(df_result), "=r"(usr) : "r"(DF_QNaN), "r"(DF_any)
445703c08d9STaylor Simpson : "r2", "usr");
4460d57cd61STaylor Simpson check64(df_result, DF_HEX_NaN);
447703c08d9STaylor Simpson check_fpstatus(usr, 0);
448703c08d9STaylor Simpson
449703c08d9STaylor Simpson asm(CLEAR_FPSTATUS
450703c08d9STaylor Simpson "%0 = convert_sf2df(%2)\n\t"
451703c08d9STaylor Simpson "%1 = usr\n\t"
4520d57cd61STaylor Simpson : "=r"(df_result), "=r"(usr) : "r"(SF_QNaN)
453703c08d9STaylor Simpson : "r2", "usr");
4540d57cd61STaylor Simpson check64(df_result, DF_HEX_NaN);
455703c08d9STaylor Simpson check_fpstatus(usr, 0);
456703c08d9STaylor Simpson }
457703c08d9STaylor Simpson
check_invsqrta(void)458dd8705bdSTaylor Simpson static void check_invsqrta(void)
459dd8705bdSTaylor Simpson {
4600d57cd61STaylor Simpson uint32_t result;
4610d57cd61STaylor Simpson uint32_t predval;
462dd8705bdSTaylor Simpson
463dd8705bdSTaylor Simpson asm volatile("%0,p0 = sfinvsqrta(%2)\n\t"
464dd8705bdSTaylor Simpson "%1 = p0\n\t"
465dd8705bdSTaylor Simpson : "+r"(result), "=r"(predval)
466dd8705bdSTaylor Simpson : "r"(0x7f800000)
467dd8705bdSTaylor Simpson : "p0");
468dd8705bdSTaylor Simpson check32(result, 0xff800000);
469dd8705bdSTaylor Simpson check32(predval, 0x0);
470dd8705bdSTaylor Simpson }
471dd8705bdSTaylor Simpson
check_sffixupn(void)47277ccf444STaylor Simpson static void check_sffixupn(void)
47377ccf444STaylor Simpson {
4740d57cd61STaylor Simpson uint32_t result;
47577ccf444STaylor Simpson
47677ccf444STaylor Simpson /* Check that sffixupn properly deals with denorm */
47777ccf444STaylor Simpson asm volatile("%0 = sffixupn(%1, %2)\n\t"
47877ccf444STaylor Simpson : "=r"(result)
47977ccf444STaylor Simpson : "r"(SF_random), "r"(SF_denorm));
48077ccf444STaylor Simpson check32(result, 0x246001d6);
48177ccf444STaylor Simpson }
48277ccf444STaylor Simpson
check_sffixupd(void)48377ccf444STaylor Simpson static void check_sffixupd(void)
48477ccf444STaylor Simpson {
4850d57cd61STaylor Simpson uint32_t result;
48677ccf444STaylor Simpson
48777ccf444STaylor Simpson /* Check that sffixupd properly deals with denorm */
48877ccf444STaylor Simpson asm volatile("%0 = sffixupd(%1, %2)\n\t"
48977ccf444STaylor Simpson : "=r"(result)
49077ccf444STaylor Simpson : "r"(SF_denorm), "r"(SF_random));
49177ccf444STaylor Simpson check32(result, 0x146001d6);
49277ccf444STaylor Simpson }
49377ccf444STaylor Simpson
check_sffms(void)4941a442c09STaylor Simpson static void check_sffms(void)
4951a442c09STaylor Simpson {
4960d57cd61STaylor Simpson uint32_t result;
4971a442c09STaylor Simpson
4981a442c09STaylor Simpson /* Check that sffms properly deals with -0 */
4990d57cd61STaylor Simpson result = SF_zero_neg;
5001a442c09STaylor Simpson asm ("%0 -= sfmpy(%1 , %2)\n\t"
5011a442c09STaylor Simpson : "+r"(result)
5020d57cd61STaylor Simpson : "r"(SF_zero), "r"(SF_zero)
5031a442c09STaylor Simpson : "r12", "r8");
5040d57cd61STaylor Simpson check32(result, SF_zero_neg);
5051a442c09STaylor Simpson
5060d57cd61STaylor Simpson result = SF_zero;
5071a442c09STaylor Simpson asm ("%0 -= sfmpy(%1 , %2)\n\t"
5081a442c09STaylor Simpson : "+r"(result)
5090d57cd61STaylor Simpson : "r"(SF_zero_neg), "r"(SF_zero)
5101a442c09STaylor Simpson : "r12", "r8");
5110d57cd61STaylor Simpson check32(result, SF_zero);
5121a442c09STaylor Simpson
5130d57cd61STaylor Simpson result = SF_zero;
5141a442c09STaylor Simpson asm ("%0 -= sfmpy(%1 , %2)\n\t"
5151a442c09STaylor Simpson : "+r"(result)
5160d57cd61STaylor Simpson : "r"(SF_zero), "r"(SF_zero_neg)
5171a442c09STaylor Simpson : "r12", "r8");
5180d57cd61STaylor Simpson check32(result, SF_zero);
5191a442c09STaylor Simpson }
5201a442c09STaylor Simpson
check_float2int_convs()521b3f37abdSTaylor Simpson static void check_float2int_convs()
522b3f37abdSTaylor Simpson {
5230d57cd61STaylor Simpson uint32_t res32;
5240d57cd61STaylor Simpson uint64_t res64;
5250d57cd61STaylor Simpson uint32_t usr;
526b3f37abdSTaylor Simpson
527b3f37abdSTaylor Simpson /*
528b3f37abdSTaylor Simpson * Check that the various forms of float-to-unsigned
529b3f37abdSTaylor Simpson * check sign before rounding
530b3f37abdSTaylor Simpson */
531b3f37abdSTaylor Simpson asm(CLEAR_FPSTATUS
532b3f37abdSTaylor Simpson "%0 = convert_sf2uw(%2)\n\t"
533b3f37abdSTaylor Simpson "%1 = usr\n\t"
534b3f37abdSTaylor Simpson : "=r"(res32), "=r"(usr) : "r"(SF_small_neg)
535b3f37abdSTaylor Simpson : "r2", "usr");
536b3f37abdSTaylor Simpson check32(res32, 0);
5370d57cd61STaylor Simpson check_fpstatus(usr, USR_FPINVF);
538b3f37abdSTaylor Simpson
539b3f37abdSTaylor Simpson asm(CLEAR_FPSTATUS
540b3f37abdSTaylor Simpson "%0 = convert_sf2uw(%2):chop\n\t"
541b3f37abdSTaylor Simpson "%1 = usr\n\t"
542b3f37abdSTaylor Simpson : "=r"(res32), "=r"(usr) : "r"(SF_small_neg)
543b3f37abdSTaylor Simpson : "r2", "usr");
544b3f37abdSTaylor Simpson check32(res32, 0);
5450d57cd61STaylor Simpson check_fpstatus(usr, USR_FPINVF);
546b3f37abdSTaylor Simpson
547b3f37abdSTaylor Simpson asm(CLEAR_FPSTATUS
548b3f37abdSTaylor Simpson "%0 = convert_sf2ud(%2)\n\t"
549b3f37abdSTaylor Simpson "%1 = usr\n\t"
550b3f37abdSTaylor Simpson : "=r"(res64), "=r"(usr) : "r"(SF_small_neg)
551b3f37abdSTaylor Simpson : "r2", "usr");
552b3f37abdSTaylor Simpson check64(res64, 0);
5530d57cd61STaylor Simpson check_fpstatus(usr, USR_FPINVF);
554b3f37abdSTaylor Simpson
555b3f37abdSTaylor Simpson asm(CLEAR_FPSTATUS
556b3f37abdSTaylor Simpson "%0 = convert_sf2ud(%2):chop\n\t"
557b3f37abdSTaylor Simpson "%1 = usr\n\t"
558b3f37abdSTaylor Simpson : "=r"(res64), "=r"(usr) : "r"(SF_small_neg)
559b3f37abdSTaylor Simpson : "r2", "usr");
560b3f37abdSTaylor Simpson check64(res64, 0);
5610d57cd61STaylor Simpson check_fpstatus(usr, USR_FPINVF);
562b3f37abdSTaylor Simpson
563b3f37abdSTaylor Simpson asm(CLEAR_FPSTATUS
564b3f37abdSTaylor Simpson "%0 = convert_df2uw(%2)\n\t"
565b3f37abdSTaylor Simpson "%1 = usr\n\t"
566b3f37abdSTaylor Simpson : "=r"(res32), "=r"(usr) : "r"(DF_small_neg)
567b3f37abdSTaylor Simpson : "r2", "usr");
568b3f37abdSTaylor Simpson check32(res32, 0);
5690d57cd61STaylor Simpson check_fpstatus(usr, USR_FPINVF);
570b3f37abdSTaylor Simpson
571b3f37abdSTaylor Simpson asm(CLEAR_FPSTATUS
572b3f37abdSTaylor Simpson "%0 = convert_df2uw(%2):chop\n\t"
573b3f37abdSTaylor Simpson "%1 = usr\n\t"
574b3f37abdSTaylor Simpson : "=r"(res32), "=r"(usr) : "r"(DF_small_neg)
575b3f37abdSTaylor Simpson : "r2", "usr");
576b3f37abdSTaylor Simpson check32(res32, 0);
5770d57cd61STaylor Simpson check_fpstatus(usr, USR_FPINVF);
578b3f37abdSTaylor Simpson
579b3f37abdSTaylor Simpson asm(CLEAR_FPSTATUS
580b3f37abdSTaylor Simpson "%0 = convert_df2ud(%2)\n\t"
581b3f37abdSTaylor Simpson "%1 = usr\n\t"
582b3f37abdSTaylor Simpson : "=r"(res64), "=r"(usr) : "r"(DF_small_neg)
583b3f37abdSTaylor Simpson : "r2", "usr");
584b3f37abdSTaylor Simpson check64(res64, 0);
5850d57cd61STaylor Simpson check_fpstatus(usr, USR_FPINVF);
586b3f37abdSTaylor Simpson
587b3f37abdSTaylor Simpson asm(CLEAR_FPSTATUS
588b3f37abdSTaylor Simpson "%0 = convert_df2ud(%2):chop\n\t"
589b3f37abdSTaylor Simpson "%1 = usr\n\t"
590b3f37abdSTaylor Simpson : "=r"(res64), "=r"(usr) : "r"(DF_small_neg)
591b3f37abdSTaylor Simpson : "r2", "usr");
592b3f37abdSTaylor Simpson check64(res64, 0);
5930d57cd61STaylor Simpson check_fpstatus(usr, USR_FPINVF);
594b3f37abdSTaylor Simpson
595b3f37abdSTaylor Simpson /*
596b3f37abdSTaylor Simpson * Check that the various forms of float-to-signed return -1 for NaN
597b3f37abdSTaylor Simpson */
598b3f37abdSTaylor Simpson asm(CLEAR_FPSTATUS
599b3f37abdSTaylor Simpson "%0 = convert_sf2w(%2)\n\t"
600b3f37abdSTaylor Simpson "%1 = usr\n\t"
6010d57cd61STaylor Simpson : "=r"(res32), "=r"(usr) : "r"(SF_QNaN)
602b3f37abdSTaylor Simpson : "r2", "usr");
603b3f37abdSTaylor Simpson check32(res32, -1);
6040d57cd61STaylor Simpson check_fpstatus(usr, USR_FPINVF);
605b3f37abdSTaylor Simpson
606b3f37abdSTaylor Simpson asm(CLEAR_FPSTATUS
607b3f37abdSTaylor Simpson "%0 = convert_sf2w(%2):chop\n\t"
608b3f37abdSTaylor Simpson "%1 = usr\n\t"
6090d57cd61STaylor Simpson : "=r"(res32), "=r"(usr) : "r"(SF_QNaN)
610b3f37abdSTaylor Simpson : "r2", "usr");
611b3f37abdSTaylor Simpson check32(res32, -1);
6120d57cd61STaylor Simpson check_fpstatus(usr, USR_FPINVF);
613b3f37abdSTaylor Simpson
614b3f37abdSTaylor Simpson asm(CLEAR_FPSTATUS
615b3f37abdSTaylor Simpson "%0 = convert_sf2d(%2)\n\t"
616b3f37abdSTaylor Simpson "%1 = usr\n\t"
6170d57cd61STaylor Simpson : "=r"(res64), "=r"(usr) : "r"(SF_QNaN)
618b3f37abdSTaylor Simpson : "r2", "usr");
619b3f37abdSTaylor Simpson check64(res64, -1);
6200d57cd61STaylor Simpson check_fpstatus(usr, USR_FPINVF);
621b3f37abdSTaylor Simpson
622b3f37abdSTaylor Simpson asm(CLEAR_FPSTATUS
623b3f37abdSTaylor Simpson "%0 = convert_sf2d(%2):chop\n\t"
624b3f37abdSTaylor Simpson "%1 = usr\n\t"
6250d57cd61STaylor Simpson : "=r"(res64), "=r"(usr) : "r"(SF_QNaN)
626b3f37abdSTaylor Simpson : "r2", "usr");
627b3f37abdSTaylor Simpson check64(res64, -1);
6280d57cd61STaylor Simpson check_fpstatus(usr, USR_FPINVF);
629b3f37abdSTaylor Simpson
630b3f37abdSTaylor Simpson asm(CLEAR_FPSTATUS
631b3f37abdSTaylor Simpson "%0 = convert_df2w(%2)\n\t"
632b3f37abdSTaylor Simpson "%1 = usr\n\t"
633d76dd816STaylor Simpson : "=r"(res32), "=r"(usr) : "r"(DF_QNaN)
634b3f37abdSTaylor Simpson : "r2", "usr");
635b3f37abdSTaylor Simpson check32(res32, -1);
6360d57cd61STaylor Simpson check_fpstatus(usr, USR_FPINVF);
637b3f37abdSTaylor Simpson
638b3f37abdSTaylor Simpson asm(CLEAR_FPSTATUS
639b3f37abdSTaylor Simpson "%0 = convert_df2w(%2):chop\n\t"
640b3f37abdSTaylor Simpson "%1 = usr\n\t"
641d76dd816STaylor Simpson : "=r"(res32), "=r"(usr) : "r"(DF_QNaN)
642b3f37abdSTaylor Simpson : "r2", "usr");
643b3f37abdSTaylor Simpson check32(res32, -1);
6440d57cd61STaylor Simpson check_fpstatus(usr, USR_FPINVF);
645b3f37abdSTaylor Simpson
646b3f37abdSTaylor Simpson asm(CLEAR_FPSTATUS
647b3f37abdSTaylor Simpson "%0 = convert_df2d(%2)\n\t"
648b3f37abdSTaylor Simpson "%1 = usr\n\t"
649d76dd816STaylor Simpson : "=r"(res64), "=r"(usr) : "r"(DF_QNaN)
650b3f37abdSTaylor Simpson : "r2", "usr");
651b3f37abdSTaylor Simpson check64(res64, -1);
6520d57cd61STaylor Simpson check_fpstatus(usr, USR_FPINVF);
653b3f37abdSTaylor Simpson
654b3f37abdSTaylor Simpson asm(CLEAR_FPSTATUS
655b3f37abdSTaylor Simpson "%0 = convert_df2d(%2):chop\n\t"
656b3f37abdSTaylor Simpson "%1 = usr\n\t"
657d76dd816STaylor Simpson : "=r"(res64), "=r"(usr) : "r"(DF_QNaN)
658b3f37abdSTaylor Simpson : "r2", "usr");
659b3f37abdSTaylor Simpson check64(res64, -1);
6600d57cd61STaylor Simpson check_fpstatus(usr, USR_FPINVF);
661b3f37abdSTaylor Simpson }
662b3f37abdSTaylor Simpson
check_float_consts(void)663163e5fa3STaylor Simpson static void check_float_consts(void)
664163e5fa3STaylor Simpson {
6650d57cd61STaylor Simpson uint32_t res32;
6660d57cd61STaylor Simpson uint64_t res64;
667163e5fa3STaylor Simpson
668163e5fa3STaylor Simpson asm("%0 = sfmake(#%1):neg\n\t" : "=r"(res32) : "i"(0xf));
669163e5fa3STaylor Simpson check32(res32, 0xbc9e0000);
670163e5fa3STaylor Simpson
671163e5fa3STaylor Simpson asm("%0 = sfmake(#%1):pos\n\t" : "=r"(res32) : "i"(0xf));
672163e5fa3STaylor Simpson check32(res32, 0x3c9e0000);
673163e5fa3STaylor Simpson
674163e5fa3STaylor Simpson asm("%0 = dfmake(#%1):neg\n\t" : "=r"(res64) : "i"(0xf));
675163e5fa3STaylor Simpson check64(res64, 0xbf93c00000000000ULL);
676163e5fa3STaylor Simpson
677163e5fa3STaylor Simpson asm("%0 = dfmake(#%1):pos\n\t" : "=r"(res64) : "i"(0xf));
678163e5fa3STaylor Simpson check64(res64, 0x3f93c00000000000ULL);
679163e5fa3STaylor Simpson }
680163e5fa3STaylor Simpson
dfmpyll(double x,double y)6810d57cd61STaylor Simpson static inline uint64_t dfmpyll(double x, double y)
682163e5fa3STaylor Simpson {
6830d57cd61STaylor Simpson uint64_t res64;
684163e5fa3STaylor Simpson asm("%0 = dfmpyll(%1, %2)" : "=r"(res64) : "r"(x), "r"(y));
685163e5fa3STaylor Simpson return res64;
686163e5fa3STaylor Simpson }
687163e5fa3STaylor Simpson
dfmpylh(double acc,double x,double y)6880d57cd61STaylor Simpson static inline uint64_t dfmpylh(double acc, double x, double y)
689163e5fa3STaylor Simpson {
6900d57cd61STaylor Simpson uint64_t res64 = *(uint64_t *)&acc;
691163e5fa3STaylor Simpson asm("%0 += dfmpylh(%1, %2)" : "+r"(res64) : "r"(x), "r"(y));
692163e5fa3STaylor Simpson return res64;
693163e5fa3STaylor Simpson }
694163e5fa3STaylor Simpson
check_dfmpyxx(void)695163e5fa3STaylor Simpson static void check_dfmpyxx(void)
696163e5fa3STaylor Simpson {
6970d57cd61STaylor Simpson uint64_t res64;
698163e5fa3STaylor Simpson
699163e5fa3STaylor Simpson res64 = dfmpyll(DBL_MIN, DBL_MIN);
700163e5fa3STaylor Simpson check64(res64, 0ULL);
701163e5fa3STaylor Simpson res64 = dfmpyll(-1.0, DBL_MIN);
702163e5fa3STaylor Simpson check64(res64, 0ULL);
703163e5fa3STaylor Simpson res64 = dfmpyll(DBL_MAX, DBL_MAX);
704163e5fa3STaylor Simpson check64(res64, 0x1fffffffdULL);
705163e5fa3STaylor Simpson
706163e5fa3STaylor Simpson res64 = dfmpylh(DBL_MIN, DBL_MIN, DBL_MIN);
707163e5fa3STaylor Simpson check64(res64, 0x10000000000000ULL);
708163e5fa3STaylor Simpson res64 = dfmpylh(-1.0, DBL_MAX, DBL_MIN);
709163e5fa3STaylor Simpson check64(res64, 0xc00fffffffe00000ULL);
710163e5fa3STaylor Simpson res64 = dfmpylh(DBL_MAX, 0.0, -1.0);
711163e5fa3STaylor Simpson check64(res64, 0x7fefffffffffffffULL);
712163e5fa3STaylor Simpson }
713163e5fa3STaylor Simpson
main()714703c08d9STaylor Simpson int main()
715703c08d9STaylor Simpson {
716703c08d9STaylor Simpson check_compare_exception();
717703c08d9STaylor Simpson check_sfminmax();
718703c08d9STaylor Simpson check_dfminmax();
71977ccf444STaylor Simpson check_sfrecipa();
720703c08d9STaylor Simpson check_canonical_NaN();
721dd8705bdSTaylor Simpson check_invsqrta();
72277ccf444STaylor Simpson check_sffixupn();
72377ccf444STaylor Simpson check_sffixupd();
7241a442c09STaylor Simpson check_sffms();
725b3f37abdSTaylor Simpson check_float2int_convs();
726163e5fa3STaylor Simpson check_float_consts();
727163e5fa3STaylor Simpson check_dfmpyxx();
728703c08d9STaylor Simpson
729703c08d9STaylor Simpson puts(err ? "FAIL" : "PASS");
730703c08d9STaylor Simpson return err ? 1 : 0;
731703c08d9STaylor Simpson }
732