1207151Smarius/*-
2207151Smarius * Copyright (c) 2010 by Peter Jeremy <peterjeremy@acm.org>
3207151Smarius * All rights reserved.
4207151Smarius *
5207151Smarius * Redistribution and use in source and binary forms, with or without
6207151Smarius * modification, are permitted provided that the following conditions
7207151Smarius * are met:
8207151Smarius * 1. Redistributions of source code must retain the above copyright
9207151Smarius *    notice, this list of conditions and the following disclaimer.
10207151Smarius * 2. Redistributions in binary form must reproduce the above copyright
11207151Smarius *    notice, this list of conditions and the following disclaimer in the
12207151Smarius *    documentation and/or other materials provided with the distribution.
13207151Smarius *
14207151Smarius * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15207151Smarius * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16207151Smarius * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17207151Smarius * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
18207151Smarius * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19207151Smarius * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20207151Smarius * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21207151Smarius * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22207151Smarius * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
23207151Smarius * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24207151Smarius */
25207151Smarius
26207151Smarius#include <sys/cdefs.h>
27207151Smarius__FBSDID("$FreeBSD$");
28207151Smarius
29207151Smarius#include <sys/param.h>
30207151Smarius
31207151Smarius#include <math.h>
32207151Smarius#include <stdio.h>
33207151Smarius#include <stdlib.h>
34207151Smarius
35207151Smarius#include "__sparc_utrap_private.h"
36207151Smarius#include "fpu_extern.h"
37207151Smarius#include "fpu_reg.h"
38207151Smarius
39207151Smariusstatic u_long	ireg[32];
40207151Smarius
41207151Smariusvoid
42207151Smarius__utrap_panic(const char *msg)
43207151Smarius{
44207151Smarius
45207151Smarius	fprintf(stderr, "panic: %s\n", msg);
46207151Smarius	exit(1);
47207151Smarius}
48207151Smarius
49207151Smariusvoid __utrap_write(const char *msg)
50207151Smarius{
51207151Smarius
52207151Smarius	fprintf(stderr, "%s", msg);
53207151Smarius}
54207151Smarius
55207151Smariusu_long
56207151Smarius__emul_fetch_reg(struct utrapframe *uf, int reg)
57207151Smarius{
58207151Smarius
59207151Smarius	return (ireg[reg]);
60207151Smarius}
61207151Smarius
62207151Smariustypedef unsigned char int8;
63207151Smariustypedef unsigned int int32;
64207151Smariustypedef unsigned long int64;
65207151Smariustypedef unsigned int float32;
66207151Smariustypedef unsigned long float64;
67207151Smariustypedef struct {
68207151Smarius	unsigned long high, low;
69207151Smarius} float128;
70207151Smariustypedef unsigned long flag;
71207151Smarius
72207151Smariusstruct utrapframe utf;
73207151Smarius
74207151Smariusu_int32_t __fpreg[64];
75207151Smarius
76207151Smariusstatic __inline float128
77207151Smarius__fpu_getreg128(int r)
78207151Smarius{
79207151Smarius	float128 v;
80207151Smarius
81207151Smarius	v.high = ((u_int64_t)__fpreg[r] << 32 | (u_int64_t)__fpreg[r + 1]);
82207151Smarius	v.low = ((u_int64_t)__fpreg[r + 2] << 32 | (u_int64_t)__fpreg[r + 3]);
83207151Smarius	return (v);
84207151Smarius}
85207151Smarius
86207151Smariusstatic __inline void
87207151Smarius__fpu_setreg128(int r, float128 v)
88207151Smarius{
89207151Smarius
90207151Smarius	__fpreg[r] = (u_int32_t)(v.high >> 32);
91207151Smarius	__fpreg[r + 1] = (u_int32_t)v.high;
92207151Smarius	__fpreg[r + 2] = (u_int32_t)(v.low >> 32);
93207151Smarius	__fpreg[r + 3] = (u_int32_t)v.low;
94207151Smarius}
95207151Smarius
96207151Smarius/*
97207151Smarius-------------------------------------------------------------------------------
98207151SmariusClears the system's IEC/IEEE floating-point exception flags.  Returns the
99207151Smariusprevious value of the flags.
100207151Smarius-------------------------------------------------------------------------------
101207151Smarius*/
102207151Smarius#include <fenv.h>
103207151Smarius#include <ieeefp.h>
104207151Smarius
105207151Smariusint8 syst_float_flags_clear(void)
106207151Smarius{
107207151Smarius	int32 flags;
108207151Smarius
109207151Smarius	flags = (utf.uf_fsr & FE_ALL_EXCEPT) >> 5;
110207151Smarius	utf.uf_fsr &= ~(u_long)FE_ALL_EXCEPT;
111207151Smarius	return (flags);
112207151Smarius}
113207151Smarius
114207151Smariusstatic void
115207151Smariusemul_trap(const u_int *insn, u_long mask)
116207151Smarius{
117207151Smarius	u_int32_t savreg[64];
118207151Smarius	int i;
119207151Smarius
120207151Smarius	for (i = 0; i < 64; i++)
121207151Smarius	    savreg[i] = __fpreg[i];
122207151Smarius
123207151Smarius	utf.uf_fsr = (utf.uf_fsr & ~FSR_FTT_MASK) |
124207151Smarius		(FSR_FTT_UNFIN << FSR_FTT_SHIFT);
125207151Smarius	utf.uf_pc = (u_long)insn;
126207151Smarius	if (__fpu_exception(&utf) == 0)
127207151Smarius	    __asm("stx %%fsr,%0" : "=m" (utf.uf_fsr));
128207151Smarius
129207151Smarius	for (i = 0; i < 64; i++) {
130207151Smarius		if (!(mask & (1UL << i)) && savreg[i] != __fpreg[i]) {
131207151Smarius			fprintf(stderr, "### %2d %08x != %08x\n",
132207151Smarius			    i, savreg[i], __fpreg[i]);
133207151Smarius		}
134207151Smarius	}
135207151Smarius}
136207151Smarius
137207151Smariusextern u_int insn_int32_to_float32;
138207151Smariusextern u_int insn_int32_to_float64;
139207151Smariusextern u_int insn_int32_to_float128;
140207151Smariusextern u_int insn_int64_to_float32;
141207151Smariusextern u_int insn_int64_to_float64;
142207151Smariusextern u_int insn_int64_to_float128;
143207151Smariusextern u_int insn_float32_to_int32_round_to_zero;
144207151Smariusextern u_int insn_float32_to_int64_round_to_zero;
145207151Smariusextern u_int insn_float32_to_float64;
146207151Smariusextern u_int insn_float32_to_float128;
147207151Smariusextern u_int insn_float32_add;
148207151Smariusextern u_int insn_float32_sub;
149207151Smariusextern u_int insn_float32_mul;
150207151Smariusextern u_int insn_float32_div;
151207151Smariusextern u_int insn_float32_sqrt;
152207151Smariusextern u_int insn_float32_cmp;
153207151Smariusextern u_int insn_float32_cmpe;
154207151Smariusextern u_int insn_float64_to_int32_round_to_zero;
155207151Smariusextern u_int insn_float64_to_int64_round_to_zero;
156207151Smariusextern u_int insn_float64_to_float32;
157207151Smariusextern u_int insn_float64_to_float128;
158207151Smariusextern u_int insn_float64_add;
159207151Smariusextern u_int insn_float64_sub;
160207151Smariusextern u_int insn_float64_mul;
161207151Smariusextern u_int insn_float64_div;
162207151Smariusextern u_int insn_float64_sqrt;
163207151Smariusextern u_int insn_float64_cmp;
164207151Smariusextern u_int insn_float64_cmpe;
165207151Smariusextern u_int insn_float128_to_int32_round_to_zero;
166207151Smariusextern u_int insn_float128_to_int64_round_to_zero;
167207151Smariusextern u_int insn_float128_to_float32;
168207151Smariusextern u_int insn_float128_to_float64;
169207151Smariusextern u_int insn_float128_add;
170207151Smariusextern u_int insn_float128_sub;
171207151Smariusextern u_int insn_float128_mul;
172207151Smariusextern u_int insn_float128_div;
173207151Smariusextern u_int insn_float128_sqrt;
174207151Smariusextern u_int insn_float128_cmp;
175207151Smariusextern u_int insn_float128_cmpe;
176207151Smarius
177207151Smariusfloat32
178207151Smariussyst_int32_to_float32(int32 a)
179207151Smarius{
180207151Smarius
181207151Smarius	__fpu_setreg(0, a);
182207151Smarius	emul_trap(&insn_int32_to_float32, 0x1UL);
183207151Smarius	return (__fpu_getreg(0));
184207151Smarius}
185207151Smarius
186207151Smariusfloat64
187207151Smariussyst_int32_to_float64(int32 a)
188207151Smarius{
189207151Smarius
190207151Smarius	__fpu_setreg(0, a);
191207151Smarius	emul_trap(&insn_int32_to_float64, 0x3UL);
192207151Smarius	return (__fpu_getreg64(0));
193207151Smarius}
194207151Smarius
195207151Smariusfloat128
196207151Smariussyst_int32_to_float128(int32 a)
197207151Smarius{
198207151Smarius
199207151Smarius	__fpu_setreg(0, a);
200207151Smarius	emul_trap(&insn_int32_to_float128, 0xfUL);
201207151Smarius	return (__fpu_getreg128(0));
202207151Smarius}
203207151Smarius
204207151Smariusfloat32
205207151Smariussyst_int64_to_float32(int64 a)
206207151Smarius{
207207151Smarius
208207151Smarius	__fpu_setreg64(0, a);
209207151Smarius	emul_trap(&insn_int64_to_float32, 0x1UL);
210207151Smarius	return (__fpu_getreg(0));
211207151Smarius}
212207151Smarius
213207151Smariusfloat64
214207151Smariussyst_int64_to_float64(int64 a)
215207151Smarius{
216207151Smarius
217207151Smarius	__fpu_setreg64(0, a);
218207151Smarius	emul_trap(&insn_int64_to_float64, 0x3UL);
219207151Smarius	return (__fpu_getreg64(0));
220207151Smarius}
221207151Smarius
222207151Smarius
223207151Smariusfloat128
224207151Smariussyst_int64_to_float128(int64 a)
225207151Smarius{
226207151Smarius
227207151Smarius	__fpu_setreg64(0, a);
228207151Smarius	emul_trap(&insn_int64_to_float128, 0xfUL);
229207151Smarius	return (__fpu_getreg128(0));
230207151Smarius}
231207151Smarius
232207151Smariusint32
233207151Smariussyst_float32_to_int32_round_to_zero(float32 a)
234207151Smarius{
235207151Smarius
236207151Smarius	__fpu_setreg(0, a);
237207151Smarius	emul_trap(&insn_float32_to_int32_round_to_zero, 0x1UL);
238207151Smarius	return (__fpu_getreg(0));
239207151Smarius}
240207151Smarius
241207151Smariusint64
242207151Smariussyst_float32_to_int64_round_to_zero(float32 a)
243207151Smarius{
244207151Smarius
245207151Smarius	__fpu_setreg(0, a);
246207151Smarius	emul_trap(&insn_float32_to_int64_round_to_zero, 0x3UL);
247207151Smarius	return (__fpu_getreg64(0));
248207151Smarius}
249207151Smarius
250207151Smariusfloat64
251207151Smariussyst_float32_to_float64(float32 a)
252207151Smarius{
253207151Smarius
254207151Smarius	__fpu_setreg(0, a);
255207151Smarius	emul_trap(&insn_float32_to_float64, 0x3UL);
256207151Smarius	return (__fpu_getreg64(0));
257207151Smarius}
258207151Smarius
259207151Smariusfloat128
260207151Smariussyst_float32_to_float128(float32 a)
261207151Smarius{
262207151Smarius
263207151Smarius	__fpu_setreg(0, a);
264207151Smarius	emul_trap(&insn_float32_to_float128, 0xfUL);
265207151Smarius	return (__fpu_getreg128(0));
266207151Smarius}
267207151Smarius
268207151Smariusfloat32
269207151Smariussyst_float32_add(float32 a, float32 b)
270207151Smarius{
271207151Smarius
272207151Smarius	__fpu_setreg(0, a);
273207151Smarius	__fpu_setreg(1, b);
274207151Smarius	emul_trap(&insn_float32_add, 0x1UL);
275207151Smarius	return (__fpu_getreg(0));
276207151Smarius}
277207151Smarius
278207151Smariusfloat32
279207151Smariussyst_float32_sub(float32 a, float32 b)
280207151Smarius{
281207151Smarius
282207151Smarius	__fpu_setreg(0, a);
283207151Smarius	__fpu_setreg(1, b);
284207151Smarius	emul_trap(&insn_float32_sub, 0x1UL);
285207151Smarius	return (__fpu_getreg(0));
286207151Smarius}
287207151Smarius
288207151Smariusfloat32
289207151Smariussyst_float32_mul(float32 a, float32 b)
290207151Smarius{
291207151Smarius
292207151Smarius	__fpu_setreg(0, a);
293207151Smarius	__fpu_setreg(1, b);
294207151Smarius	emul_trap(&insn_float32_mul, 0x1UL);
295207151Smarius	return (__fpu_getreg(0));
296207151Smarius}
297207151Smarius
298207151Smariusfloat32
299207151Smariussyst_float32_div(float32 a, float32 b)
300207151Smarius{
301207151Smarius
302207151Smarius	__fpu_setreg(0, a);
303207151Smarius	__fpu_setreg(1, b);
304207151Smarius	emul_trap(&insn_float32_div, 0x1UL);
305207151Smarius	return (__fpu_getreg(0));
306207151Smarius}
307207151Smarius
308207151Smariusfloat32
309207151Smariussyst_float32_sqrt(float32 a)
310207151Smarius{
311207151Smarius
312207151Smarius	__fpu_setreg(0, a);
313207151Smarius	emul_trap(&insn_float32_sqrt, 0x1UL);
314207151Smarius	return (__fpu_getreg(0));
315207151Smarius}
316207151Smarius
317207151Smariusflag syst_float32_eq(float32 a, float32 b)
318207151Smarius{
319207151Smarius	u_long r;
320207151Smarius
321207151Smarius	__fpu_setreg(0, a);
322207151Smarius	__fpu_setreg(1, b);
323207151Smarius	emul_trap(&insn_float32_cmp, 0x0UL);
324207151Smarius	__asm __volatile("mov 0,%0; move %%fcc0,1,%0" : "=r" (r));
325207151Smarius	return (r);
326207151Smarius}
327207151Smarius
328207151Smariusflag syst_float32_le(float32 a, float32 b)
329207151Smarius{
330207151Smarius	u_long r;
331207151Smarius
332207151Smarius	__fpu_setreg(0, a);
333207151Smarius	__fpu_setreg(1, b);
334207151Smarius	emul_trap(&insn_float32_cmpe, 0x0UL);
335207151Smarius	__asm __volatile("mov 0,%0; movle %%fcc0,1,%0" : "=r" (r));
336207151Smarius	return (r);
337207151Smarius}
338207151Smarius
339207151Smariusflag syst_float32_lt(float32 a, float32 b)
340207151Smarius{
341207151Smarius	u_long r;
342207151Smarius
343207151Smarius	__fpu_setreg(0, a);
344207151Smarius	__fpu_setreg(1, b);
345207151Smarius	emul_trap(&insn_float32_cmpe, 0x0UL);
346207151Smarius	__asm __volatile("mov 0,%0; movl %%fcc0,1,%0" : "=r" (r));
347207151Smarius	return (r);
348207151Smarius}
349207151Smarius
350207151Smariusflag syst_float32_eq_signaling(float32 a, float32 b)
351207151Smarius{
352207151Smarius	u_long r;
353207151Smarius
354207151Smarius	__fpu_setreg(0, a);
355207151Smarius	__fpu_setreg(1, b);
356207151Smarius	emul_trap(&insn_float32_cmpe, 0x0UL);
357207151Smarius	__asm __volatile("mov 0,%0; move %%fcc0,1,%0" : "=r" (r));
358207151Smarius	return (r);
359207151Smarius}
360207151Smarius
361207151Smariusflag syst_float32_le_quiet(float32 a, float32 b)
362207151Smarius{
363207151Smarius	u_long r;
364207151Smarius
365207151Smarius	__fpu_setreg(0, a);
366207151Smarius	__fpu_setreg(1, b);
367207151Smarius	emul_trap(&insn_float32_cmp, 0x0UL);
368207151Smarius	__asm __volatile("mov 0,%0; movle %%fcc0,1,%0" : "=r" (r));
369207151Smarius	return (r);
370207151Smarius}
371207151Smarius
372207151Smariusflag syst_float32_lt_quiet(float32 a, float32 b)
373207151Smarius{
374207151Smarius	u_long r;
375207151Smarius
376207151Smarius	__fpu_setreg(0, a);
377207151Smarius	__fpu_setreg(1, b);
378207151Smarius	emul_trap(&insn_float32_cmp, 0x0UL);
379207151Smarius	__asm __volatile("mov 0,%0; movl %%fcc0,1,%0" : "=r" (r));
380207151Smarius	return (r);
381207151Smarius}
382207151Smarius
383207151Smariusint32
384207151Smariussyst_float64_to_int32_round_to_zero(float64 a)
385207151Smarius{
386207151Smarius
387207151Smarius	__fpu_setreg64(0, a);
388207151Smarius	emul_trap(&insn_float64_to_int32_round_to_zero, 0x1UL);
389207151Smarius	return (__fpu_getreg(0));
390207151Smarius}
391207151Smarius
392207151Smariusint64
393207151Smariussyst_float64_to_int64_round_to_zero(float64 a)
394207151Smarius{
395207151Smarius
396207151Smarius	__fpu_setreg64(0, a);
397207151Smarius	emul_trap(&insn_float64_to_int64_round_to_zero, 0x3UL);
398207151Smarius	return (__fpu_getreg64(0));
399207151Smarius}
400207151Smarius
401207151Smariusfloat32
402207151Smariussyst_float64_to_float32(float64 a)
403207151Smarius{
404207151Smarius
405207151Smarius	__fpu_setreg64(0, a);
406207151Smarius	emul_trap(&insn_float64_to_float32, 0x1UL);
407207151Smarius	return (__fpu_getreg(0));
408207151Smarius}
409207151Smarius
410207151Smariusfloat128
411207151Smariussyst_float64_to_float128(float64 a)
412207151Smarius{
413207151Smarius
414207151Smarius	__fpu_setreg64(0, a);
415207151Smarius	emul_trap(&insn_float64_to_float128, 0xfUL);
416207151Smarius	return (__fpu_getreg128(0));
417207151Smarius}
418207151Smarius
419207151Smariusfloat64
420207151Smariussyst_float64_add(float64 a, float64 b)
421207151Smarius{
422207151Smarius
423207151Smarius	__fpu_setreg64(0, a);
424207151Smarius	__fpu_setreg64(2, b);
425207151Smarius	emul_trap(&insn_float64_add, 0x3UL);
426207151Smarius	return (__fpu_getreg64(0));
427207151Smarius}
428207151Smarius
429207151Smariusfloat64
430207151Smariussyst_float64_sub(float64 a, float64 b)
431207151Smarius{
432207151Smarius
433207151Smarius	__fpu_setreg64(0, a);
434207151Smarius	__fpu_setreg64(2, b);
435207151Smarius	emul_trap(&insn_float64_sub, 0x3UL);
436207151Smarius	return (__fpu_getreg64(0));
437207151Smarius}
438207151Smarius
439207151Smariusfloat64
440207151Smariussyst_float64_mul(float64 a, float64 b)
441207151Smarius{
442207151Smarius
443207151Smarius	__fpu_setreg64(0, a);
444207151Smarius	__fpu_setreg64(2, b);
445207151Smarius	emul_trap(&insn_float64_mul, 0x3UL);
446207151Smarius	return (__fpu_getreg64(0));
447207151Smarius}
448207151Smarius
449207151Smariusfloat64
450207151Smariussyst_float64_div(float64 a, float64 b)
451207151Smarius{
452207151Smarius
453207151Smarius	__fpu_setreg64(0, a);
454207151Smarius	__fpu_setreg64(2, b);
455207151Smarius	emul_trap(&insn_float64_div, 0x3UL);
456207151Smarius	return (__fpu_getreg64(0));
457207151Smarius}
458207151Smarius
459207151Smariusfloat64
460207151Smariussyst_float64_sqrt(float64 a)
461207151Smarius{
462207151Smarius
463207151Smarius	__fpu_setreg64(0, a);
464207151Smarius	emul_trap(&insn_float64_sqrt, 0x3UL);
465207151Smarius	return (__fpu_getreg64(0));
466207151Smarius}
467207151Smarius
468207151Smariusflag syst_float64_eq(float64 a, float64 b)
469207151Smarius{
470207151Smarius	u_long r;
471207151Smarius
472207151Smarius	__fpu_setreg64(0, a);
473207151Smarius	__fpu_setreg64(2, b);
474207151Smarius	emul_trap(&insn_float64_cmp, 0x0UL);
475207151Smarius	__asm __volatile("mov 0,%0; move %%fcc0,1,%0" : "=r" (r));
476207151Smarius	return (r);
477207151Smarius}
478207151Smarius
479207151Smariusflag syst_float64_le(float64 a, float64 b)
480207151Smarius{
481207151Smarius	u_long r;
482207151Smarius
483207151Smarius	__fpu_setreg64(0, a);
484207151Smarius	__fpu_setreg64(2, b);
485207151Smarius	emul_trap(&insn_float64_cmpe, 0x0UL);
486207151Smarius	__asm __volatile("mov 0,%0; movle %%fcc0,1,%0" : "=r" (r));
487207151Smarius	return (r);
488207151Smarius}
489207151Smarius
490207151Smariusflag syst_float64_lt(float64 a, float64 b)
491207151Smarius{
492207151Smarius	u_long r;
493207151Smarius
494207151Smarius	__fpu_setreg64(0, a);
495207151Smarius	__fpu_setreg64(2, b);
496207151Smarius	emul_trap(&insn_float64_cmpe, 0x0UL);
497207151Smarius	__asm __volatile("mov 0,%0; movl %%fcc0,1,%0" : "=r" (r));
498207151Smarius	return (r);
499207151Smarius}
500207151Smarius
501207151Smariusflag syst_float64_eq_signaling(float64 a, float64 b)
502207151Smarius{
503207151Smarius	u_long r;
504207151Smarius
505207151Smarius	__fpu_setreg64(0, a);
506207151Smarius	__fpu_setreg64(2, b);
507207151Smarius	emul_trap(&insn_float64_cmpe, 0x0UL);
508207151Smarius	__asm __volatile("mov 0,%0; move %%fcc0,1,%0" : "=r" (r));
509207151Smarius	return (r);
510207151Smarius}
511207151Smarius
512207151Smariusflag syst_float64_le_quiet(float64 a, float64 b)
513207151Smarius{
514207151Smarius	u_long r;
515207151Smarius
516207151Smarius	__fpu_setreg64(0, a);
517207151Smarius	__fpu_setreg64(2, b);
518207151Smarius	emul_trap(&insn_float64_cmp, 0x0UL);
519207151Smarius	__asm __volatile("mov 0,%0; movle %%fcc0,1,%0" : "=r" (r));
520207151Smarius	return (r);
521207151Smarius}
522207151Smarius
523207151Smariusflag syst_float64_lt_quiet(float64 a, float64 b)
524207151Smarius{
525207151Smarius	u_long r;
526207151Smarius
527207151Smarius	__fpu_setreg64(0, a);
528207151Smarius	__fpu_setreg64(2, b);
529207151Smarius	emul_trap(&insn_float64_cmp, 0x0UL);
530207151Smarius	__asm __volatile("mov 0,%0; movl %%fcc0,1,%0" : "=r" (r));
531207151Smarius	return (r);
532207151Smarius}
533207151Smarius
534207151Smariusint32
535207151Smariussyst_float128_to_int32_round_to_zero(float128 a)
536207151Smarius{
537207151Smarius
538207151Smarius	__fpu_setreg128(0, a);
539207151Smarius	emul_trap(&insn_float128_to_int32_round_to_zero, 0x1UL);
540207151Smarius	return (__fpu_getreg(0));
541207151Smarius}
542207151Smarius
543207151Smariusint64
544207151Smariussyst_float128_to_int64_round_to_zero(float128 a)
545207151Smarius{
546207151Smarius
547207151Smarius	__fpu_setreg128(0, a);
548207151Smarius	emul_trap(&insn_float128_to_int64_round_to_zero, 0x3UL);
549207151Smarius	return (__fpu_getreg64(0));
550207151Smarius}
551207151Smarius
552207151Smariusfloat32
553207151Smariussyst_float128_to_float32(float128 a)
554207151Smarius{
555207151Smarius
556207151Smarius	__fpu_setreg128(0, a);
557207151Smarius	emul_trap(&insn_float128_to_float32, 0x1UL);
558207151Smarius	return (__fpu_getreg(0));
559207151Smarius}
560207151Smarius
561207151Smariusfloat64
562207151Smariussyst_float128_to_float64(float128 a)
563207151Smarius{
564207151Smarius
565207151Smarius	__fpu_setreg128(0, a);
566207151Smarius	emul_trap(&insn_float128_to_float64, 0x3UL);
567207151Smarius	return (__fpu_getreg64(0));
568207151Smarius}
569207151Smarius
570207151Smariusfloat128
571207151Smariussyst_float128_add(float128 a, float128 b)
572207151Smarius{
573207151Smarius
574207151Smarius	__fpu_setreg128(0, a);
575207151Smarius	__fpu_setreg128(4, b);
576207151Smarius	emul_trap(&insn_float128_add, 0xfUL);
577207151Smarius	return (__fpu_getreg128(0));
578207151Smarius}
579207151Smarius
580207151Smariusfloat128
581207151Smariussyst_float128_sub(float128 a, float128 b)
582207151Smarius{
583207151Smarius
584207151Smarius	__fpu_setreg128(0, a);
585207151Smarius	__fpu_setreg128(4, b);
586207151Smarius	emul_trap(&insn_float128_sub, 0xfUL);
587207151Smarius	return (__fpu_getreg128(0));
588207151Smarius}
589207151Smarius
590207151Smariusfloat128
591207151Smariussyst_float128_mul(float128 a, float128 b)
592207151Smarius{
593207151Smarius
594207151Smarius	__fpu_setreg128(0, a);
595207151Smarius	__fpu_setreg128(4, b);
596207151Smarius	emul_trap(&insn_float128_mul, 0xfUL);
597207151Smarius	return (__fpu_getreg128(0));
598207151Smarius}
599207151Smarius
600207151Smariusfloat128
601207151Smariussyst_float128_div(float128 a, float128 b)
602207151Smarius{
603207151Smarius
604207151Smarius	__fpu_setreg128(0, a);
605207151Smarius	__fpu_setreg128(4, b);
606207151Smarius	emul_trap(&insn_float128_div, 0xfUL);
607207151Smarius	return (__fpu_getreg128(0));
608207151Smarius}
609207151Smarius
610207151Smariusfloat128
611207151Smariussyst_float128_sqrt(float128 a)
612207151Smarius{
613207151Smarius
614207151Smarius	__fpu_setreg128(0, a);
615207151Smarius	emul_trap(&insn_float128_sqrt, 0xfUL);
616207151Smarius	return (__fpu_getreg128(0));
617207151Smarius}
618207151Smarius
619207151Smariusflag syst_float128_eq(float128 a, float128 b)
620207151Smarius{
621207151Smarius	u_long r;
622207151Smarius
623207151Smarius	__fpu_setreg128(0, a);
624207151Smarius	__fpu_setreg128(4, b);
625207151Smarius	emul_trap(&insn_float128_cmp, 0x0UL);
626207151Smarius	__asm __volatile("mov 0,%0; move %%fcc0,1,%0" : "=r" (r));
627207151Smarius	return (r);
628207151Smarius}
629207151Smarius
630207151Smariusflag syst_float128_le(float128 a, float128 b)
631207151Smarius{
632207151Smarius	u_long r;
633207151Smarius
634207151Smarius	__fpu_setreg128(0, a);
635207151Smarius	__fpu_setreg128(4, b);
636207151Smarius	emul_trap(&insn_float128_cmpe, 0x0UL);
637207151Smarius	__asm __volatile("mov 0,%0; movle %%fcc0,1,%0" : "=r" (r));
638207151Smarius	return (r);
639207151Smarius}
640207151Smarius
641207151Smariusflag syst_float128_lt(float128 a, float128 b)
642207151Smarius{
643207151Smarius	u_long r;
644207151Smarius
645207151Smarius	__fpu_setreg128(0, a);
646207151Smarius	__fpu_setreg128(4, b);
647207151Smarius	emul_trap(&insn_float128_cmpe, 0x0UL);
648207151Smarius	__asm __volatile("mov 0,%0; movl %%fcc0,1,%0" : "=r" (r));
649207151Smarius	return (r);
650207151Smarius}
651207151Smarius
652207151Smariusflag syst_float128_eq_signaling(float128 a, float128 b)
653207151Smarius{
654207151Smarius	u_long r;
655207151Smarius
656207151Smarius	__fpu_setreg128(0, a);
657207151Smarius	__fpu_setreg128(4, b);
658207151Smarius	emul_trap(&insn_float128_cmpe, 0x0UL);
659207151Smarius	__asm __volatile("mov 0,%0; move %%fcc0,1,%0" : "=r" (r));
660207151Smarius	return (r);
661207151Smarius}
662207151Smarius
663207151Smariusflag syst_float128_le_quiet(float128 a, float128 b)
664207151Smarius{
665207151Smarius	u_long r;
666207151Smarius
667207151Smarius	__fpu_setreg128(0, a);
668207151Smarius	__fpu_setreg128(4, b);
669207151Smarius	emul_trap(&insn_float128_cmp, 0x0UL);
670207151Smarius	__asm __volatile("mov 0,%0; movle %%fcc0,1,%0" : "=r" (r));
671207151Smarius	return (r);
672207151Smarius}
673207151Smarius
674207151Smariusflag syst_float128_lt_quiet(float128 a, float128 b)
675207151Smarius{
676207151Smarius	u_long r;
677207151Smarius
678207151Smarius	__fpu_setreg128(0, a);
679207151Smarius	__fpu_setreg128(4, b);
680207151Smarius	emul_trap(&insn_float128_cmp, 0x0UL);
681207151Smarius	__asm __volatile("mov 0,%0; movl %%fcc0,1,%0" : "=r" (r));
682207151Smarius	return (r);
683207151Smarius}
684207151Smarius
685207151Smarius
686207151Smarius/*
687207151Smarius-------------------------------------------------------------------------------
688207151SmariusSets the system's IEC/IEEE floating-point rounding mode.
689207151Smarius-------------------------------------------------------------------------------
690207151Smarius*/
691207151Smariusvoid syst_float_set_rounding_mode(int8 roundingMode)
692207151Smarius{
693207151Smarius
694207151Smarius	utf.uf_fsr &= ~FSR_RD_MASK;
695207151Smarius	utf.uf_fsr |= FSR_RD((unsigned int)roundingMode & 0x03);
696207151Smarius}
697207151Smarius
698207151Smarius/*
699207151Smarius-------------------------------------------------------------------------------
700207151SmariusDoes nothing.
701207151Smarius-------------------------------------------------------------------------------
702207151Smarius*/
703207151Smariusvoid syst_float_set_rounding_precision(int8 precision)
704207151Smarius{
705207151Smarius
706207151Smarius}
707