xref: /onnv-gate/usr/src/cmd/fps/fptest/fpu_if64.s (revision 7186:e728311aafb0)
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#pragma ident	"%Z%%M%	%I%	%E% SMI"
28
29#include<sys/asm_linkage.h>
30
31/*
32 * -----------------------------------------------------------------------
33 *	File: fpu-if64.s
34 * -----------------------------------------------------------------------
35 */
36
37/*
38 * --------------------------------------------------------------------------
39 * Name:	Get the Floating point Status Register
40 * Function:	return a copy of the FSR to caller
41 * Calling:	none
42 * Returns:	i0 = fsr contents
43 * Convention:	fsr_value = get_fsr() **
44 * --------------------------------------------------------------------------
45 */
46
47#ifdef __lint
48
49unsigned long
50get_fsr()
51{
52	return (0);
53}
54
55#else
56
57.section        ".data"
58.align          8
59.Lgfsr:
60        .skip   8
61
62ENTRY_NP(get_fsr)
63	save	%sp, -SA(MINFRAME), %sp	! save the registers & stack frame
64	setn	.Lgfsr,%l6,%l0 	! .. set the address of the result holder
65	stx	%fsr, [%l0]	! .. set the contents of the FSR register
66	ldx	[%l0], %i0	! .. return the fsr to caller
67	ret			! Delayed return (get user ret addr)
68	restore			! .. restore the frame window
69SET_SIZE(get_fsr)
70
71#endif
72
73/*
74 * --------------------------------------------------------------------------
75 * Name:	Set Floating point Status Register
76 * Function:	Set the FSR
77 * Calling:	i0 = value to write to fsr
78 * Returns:	none
79 * Convention:	set_fsr(get_fsr() ** || <userVal>) **
80 *              Please note that the user is expected to OR the new value
81 *              with the current FSR content and pass the result to
82 *              set_fsr().
83 * --------------------------------------------------------------------------
84 */
85
86#ifdef __lint
87
88/*ARGSUSED*/
89void
90set_fsr(unsigned long arg1)
91{
92}
93
94#else
95
96.section        ".data"
97.align          8
98.Lsfsr:
99        .skip   8
100
101ENTRY_NP(set_fsr)
102	save	%sp, -SA(MINFRAME), %sp	! save the registers & stack frame
103	setn	.Lsfsr,%l6,%l0 	! .. set the address of the result holder
104	stx	%i0, [%l0]	! .. save the value in memory
105	ldx	[%l0], %fsr	! .. get the contents of the FSR register
106	ret			! Delayed return (get user ret addr)
107	restore			! .. restore the frame window
108SET_SIZE(set_fsr)
109
110#endif
111
112/*
113 * --------------------------------------------------------------------------
114 * Name:	Get the Graphics Status Register
115 * Function:	return a copy of the GSR to caller
116 * Calling:	none
117 * Returns:	i0 = gsr contents
118 * Convention:	gsr_value = get_gsr() **
119 * --------------------------------------------------------------------------
120 */
121
122#ifdef __lint
123
124uint64_t
125get_gsr()
126{
127	return (0);
128}
129
130#else
131
132ENTRY_NP(get_gsr)
133	save	%sp, -SA(MINFRAME), %sp	! save the registers & stack frame
134	rd      %gsr, %i0
135	ret			! Delayed return (get user ret addr)
136	restore			! .. restore the frame window
137SET_SIZE(get_gsr)
138
139#endif
140
141/*
142 * -------------------------------------------------------------------------
143 * Name:	Set Graphics Status Register
144 * Function:	Set the GSR
145 * Calling:	i0 = value to write to gsr
146 * Returns:	none
147 * Convention:	set_gsr(get_gsr() || <userVal>)
148 *              Please note that the user is expected to OR the new value
149 *              with the current GSR content and pass the result to
150 *              set_gsr().
151 * --------------------------------------------------------------------------
152 */
153
154#ifdef __lint
155
156/*ARGSUSED*/
157void
158set_gsr(uint64_t arg1)
159{
160}
161
162#else
163
164ENTRY_NP(set_gsr)
165	save	%sp, -SA(MINFRAME), %sp	! save the registers & stack frame
166	wr      %i0, %g0, %gsr
167	ret			! Delayed return (get user ret addr)
168	restore			! .. restore the frame window
169SET_SIZE(set_gsr)
170
171#endif
172
173/*
174 * -----------------------------------------------------------------------
175 *			Data Conversion Functions			 *
176 * -----------------------------------------------------------------------
177 */
178
179/*
180 * --------------------------------------------------------------------------
181 * Name:	Integer to Float (Single)
182 * Function:	Convert an integer value to a single precision floating point
183 * 		value
184 * Calling:	in0 = value to convert
185 * Returns:	in0 = converted value
186 * Convention:	Real = int_float_s(Int) **
187 * --------------------------------------------------------------------------
188 */
189
190#ifdef __lint
191
192/*ARGSUSED*/
193unsigned long
194int_float_s(int arg1)
195{
196	return (0);
197}
198
199#else
200
201.section        ".data"
202.align          4
203.Lfls:
204        .word   0
205.Lfls1:
206        .word   0
207
208ENTRY_NP(int_float_s)
209	save	%sp, -SA(MINFRAME), %sp	! save the registers, stack
210	setn	.Lfls1,%l6,%o5	! .. set the address of the result holder
211	setn	.Lfls,%l6,%o4	! .. set address of temp. mem reg
212	st	%i0, [%o4]	! .. put the passed value into memory
213	ld	[%o4], %f0	! .. get the value from memory into FPU register
214	fitos   %f0, %f2	! .. get the integer into float into fpu r1
215	st	%f2, [%o5]	! .. store into the location
216	ld	[%o5], %i0	! .. put the value for return
217	ret			! Delayed return (get user ret addr)
218	restore			! .. restore the frame window
219SET_SIZE(int_float_s)
220
221#endif
222
223/*
224 * --------------------------------------------------------------------------
225 * Name:	Integer to Float (double)
226 * Function:	Convert an integer value to a double precision floating point
227 * 		value
228 * Calling:	in0 = value to convert
229 * Returns:	in0 = converted value
230 * Convention:	Real = int_float_d(Int) **
231 * --------------------------------------------------------------------------
232 */
233
234#ifdef __lint
235
236/*ARGSUSED*/
237unsigned long
238int_float_d(int arg1)
239{
240	return (0);
241}
242
243#else
244
245.section        ".data"
246.align  4
247.Lfld:
248        .word   0
249
250        .align  8
251
252.Lfld1:
253        .skip   8
254
255ENTRY_NP(int_float_d)
256	save	%sp, -SA(MINFRAME), %sp	! save the registers, stack
257	setn	.Lfld1,%l6,%o5	! .. get the address of temp2
258	setn	.Lfld,%l6,%o4	! .. get the address of temp
259	st	%i0, [%o4]	! .. get the user value
260	ld	[%o4], %f0	! .. into the float register
261	fitod   %f0, %f2	! .... have the fpu perform the operation
262	std	%f2, [%o5]	! .. save the result
263	ldx	[%o5], %i0	! .. and return it to caller
264	ret			! Delayed return (get user ret addr)
265	restore			! .. restore the frame window
266SET_SIZE(int_float_d)
267
268#endif
269
270/*
271 * --------------------------------------------------------------------------
272 * Name:	float to integer (single)
273 * Function:	Convert a real value to an integer
274 * Calling:	in0 = Value
275 * Returns:	in0 = Value
276 * Convention:	Int = float_int_s(real) **
277 * --------------------------------------------------------------------------
278 */
279
280#ifdef __lint
281
282/*ARGSUSED*/
283unsigned long
284float_int_s(unsigned long arg1)
285{
286	return (0);
287}
288
289#else
290
291.section        ".data"
292.align  4
293.Lflnts:
294        .word   0
295.Lflnts1:
296        .word   0
297
298ENTRY_NP(float_int_s)
299	save	%sp, -SA(MINFRAME), %sp	! save the registers, stack
300	setn	.Lflnts1,%l6,%o5	! .. get the address of temp2
301	setn	.Lflnts,%l6,%o4	! .... and temp
302	st	%i0, [%o4]	! .. get the users value
303	ld	[%o4], %f0	! .. into the float register
304	fstoi   %f0, %f2	! .... have the fpu perform the operation
305	st	%f2, [%o5]	! .. save the result
306	ld	[%o5], %i0	! .. and return it to the user
307	ret			! Delayed return (get user ret addr)
308	restore			! .. restore the frame window
309SET_SIZE(float_int_s)
310
311#endif
312
313/*
314 * --------------------------------------------------------------------------
315 * Name:	Float to Integer conversion (double)
316 * Function:	Convert a real value to an integer
317 * Calling:	in0 = value
318 * Returns:	in0 = value
319 * Convention:	Int = float_int_d(real) **
320 * --------------------------------------------------------------------------
321 */
322
323#ifdef __lint
324
325/*ARGSUSED*/
326unsigned long
327float_int_d(uint64_t arg1)
328{
329	return (0);
330}
331
332#else
333
334.section        ".data"
335.align  8
336.Lflntd:
337        .skip   8
338.Lflntd1:
339        .skip   4
340
341ENTRY_NP(float_int_d)
342	save	%sp, -SA(MINFRAME), %sp	! save the registers, stack
343	setn	.Lflntd1,%l6,%o5 	! .. get the address of temp2
344	setn	.Lflntd,%l6,%o4 	! .. and temp
345	stx     %i0, [%o4] 	! .. get the callers value
346	ldd     [%o4], %f0 	! .. into the float register
347	fdtoi   %f0, %f2 	! .... have the fpu perform the operation
348	st      %f2, [%o5] 	! .. save the result
349	ld      [%o5], %i0 	! .... and return it to caller
350	ret 			! Delayed return (get user ret addr)
351	restore 		! .. restore the frame window
352SET_SIZE(float_int_d)
353
354#endif
355
356/*
357 * --------------------------------------------------------------------------
358 * Name:	Convert Single to double precision
359 * Function:	<as the name says>
360 * Calling:	in0 = value
361 * Returns:	in0 = result
362 * Convention:	result = convert_sp_dp(value) **
363 * --------------------------------------------------------------------------
364 */
365
366#ifdef __lint
367
368/*ARGSUSED*/
369uint64_t
370convert_sp_dp(unsigned long arg1)
371{
372	return (0);
373}
374
375#else
376
377.section        ".data"
378.align  8
379.Lspdp:
380        .skip   8
381.Lspdp1:
382        .skip   4
383
384ENTRY_NP(convert_sp_dp)
385	save	%sp, -SA(MINFRAME), %sp	! save the registers, stack
386	setn	.Lspdp1,%l6,%l0	! .. get the address of temp2
387	setn	.Lspdp,%l6,%l1	! .. get the address of temp
388	st	%i0, [%l0]	! .. get the callers value
389	ld	[%l0], %f0	! .. into the float register
390	fstod   %f0, %f2	! .... have the fpu perform the operation
391	std	%f2, [%l1]	! .. save the result
392	ldx	[%l1], %i0	! .... and return it to the caller
393	ret			! Delayed return (get user ret addr)
394	restore			! .. restore the frame window
395SET_SIZE(convert_sp_dp)
396
397#endif
398
399/*
400 * --------------------------------------------------------------------------
401 * Name:	Convert Double to Single precision
402 * Function:	..
403 * Calling:	in0 = double precision value
404 * Returns:	in0 = result
405 * Convention:	result = convert_dp_sp(value) **
406 * --------------------------------------------------------------------------
407 */
408
409#ifdef __lint
410
411/*ARGSUSED*/
412unsigned long
413convert_dp_sp(uint64_t arg1)
414{
415	return (0);
416}
417
418#else
419
420.section        ".data"
421.align  4
422.Ldpsp:
423        .skip   4
424
425        .align  8
426
427.Ldpsp1:
428        .skip   8
429
430ENTRY_NP(convert_dp_sp)
431	save	%sp, -SA(MINFRAME), %sp	! save the registers, stack
432	setn	.Ldpsp1,%l6,%l0	! .. get the address of temp2
433	setn	.Ldpsp,%l6,%l1	! .. and temp
434	stx	%i0, [%l0]	! .. get the users value
435	ldd	[%l0], %f0	! .. move it to a float register
436	fdtos	%f0, %f2	! .... have the fpu perform the operation
437	st	%f2, [%l1]	! .. save the result
438	ld	[%l1], %i0	! .... and return it to the caller
439	ret			! Delayed return (get user ret addr)
440	restore			! .. restore the frame window
441SET_SIZE(convert_dp_sp)
442
443#endif
444
445/*
446 * --------------------------------------------------------------------------
447 * Name:	Negate a value (Single-precision)
448 * Function:	Compliments the Sign bit
449 * Calling:	in0 = number to cross her
450 * Returns:	in0 = result
451 * Convention:	result = negate_value_sp(value) **
452 * --------------------------------------------------------------------------
453 */
454
455#ifdef __lint
456
457/*ARGSUSED*/
458unsigned long
459negate_value_sp(unsigned long arg1)
460{
461	return (0);
462}
463
464#else
465
466.section        ".data"
467.align  8
468.Lneg:
469        .skip   8
470.Lneg1:
471        .skip   8
472
473ENTRY_NP(negate_value_sp)
474	save	%sp, -SA(MINFRAME), %sp	! save the registers, stack
475	setn	.Lneg1,%l6,%l0	! .. get the address of .Lneg
476	setn	.Lneg,%l6,%l1	! .. and of .Lneg1
477	st	%i0, [%l0]	! .. get the callers value
478	ld	[%l0], %f0	! .. into the float register
479	fnegs   %f0, %f2	! .... have the fpu perform the operation
480	st	%f2, [%l1]	! .. save the result
481	ld	[%l1], %i0 	! .... and return it to the caller
482	ret 			! Delayed return (get user ret addr)
483	restore 		! .. restore the frame window
484SET_SIZE(negate_value_sp)
485
486#endif
487
488/*
489 * --------------------------------------------------------------------------
490 * Name:	Negate a value (Double-precision)
491 * Function:	Compliments the Sign bit
492 * Calling:	in0 = number to cross her
493 * Returns:	in0 = result
494 * Convention:	result = negate_value_dp(value) **
495 * --------------------------------------------------------------------------
496 */
497
498#ifdef __lint
499
500/*ARGSUSED*/
501uint64_t
502negate_value_dp(uint64_t arg1)
503{
504	return (0);
505}
506
507#else
508
509.section        ".data"
510.align  8
511.Lneg2:
512        .skip   8
513.Lneg3:
514        .skip   8
515
516ENTRY_NP(negate_value_dp)
517	save	%sp, -SA(MINFRAME), %sp	! save the registers, stack
518	setn	.Lneg3,%l6,%l0	! .. get the address of .Lneg
519	setn	.Lneg1,%l6,%l1	! .. and of .Lneg1
520	stx	%i0, [%l0]	! .. get the callers value
521	ldd	[%l0], %f0	! .. into the float register
522	fnegd   %f0, %f2	! .... have the fpu perform the operation
523	std	%f2, [%l1]	! .. save the result
524	ldx	[%l1], %i0 	! .... and return it to the caller
525	ret 			! Delayed return (get user ret addr)
526	restore 		! .. restore the frame window
527SET_SIZE(negate_value_dp)
528
529#endif
530
531/*
532 * --------------------------------------------------------------------------
533 * Name:	Absolute Value (Single-precision)
534 * Function:	Convert a SP value to its absolute value (clears sign bit)
535 * Calling:	in0 = value
536 * Returns:	in0 = result
537 * Convention:	result = absolute_value_sp(value) **
538 * --------------------------------------------------------------------------
539 */
540
541#ifdef __lint
542
543/*ARGSUSED*/
544unsigned long
545absolute_value_sp(unsigned long arg1)
546{
547	return (0);
548}
549
550#else
551
552.section        ".data"
553.align  8
554.Labs:
555        .skip   8
556.Labs1:
557        .skip   8
558
559ENTRY_NP(absolute_value_sp)
560	save	%sp, -SA(MINFRAME), %sp	! save the registers, stack
561	setn	.Labs1,%l6,%l0 	! .. get the address of temp2
562	setn	.Labs,%l6,%l1 	! .. and temp
563	st	%i0, [%l0] 	! .. get the users value
564	ld	[%l0], %f0 	! .. into a float register
565	fabss	%f0, %f2 	! .... have the fpu perform the operation
566	st	%f2, [%l1] 	! .. save the result
567	ld	[%l1], %i0  	! .... and return it to caller
568	ret  			! Delayed return (get user ret addr)
569	restore			! .. restore the frame window
570SET_SIZE(absolute_value_sp)
571
572#endif
573
574/*
575 * --------------------------------------------------------------------------
576 * Name:	Absolute Value (Double-precision)
577 * Function:	Convert a DP value to its absolute value (clears sign bit)
578 * Calling:	in0 = value
579 * Returns:	in0 = result
580 * Convention:	result = absolute_value_dp(value) **
581 * --------------------------------------------------------------------------
582 */
583
584#ifdef __lint
585
586/*ARGSUSED*/
587uint64_t
588absolute_value_dp(uint64_t arg1)
589{
590	return (0);
591}
592
593#else
594
595.section        ".data"
596.align  8
597.Labs2:
598        .skip   8
599.Labs3:
600        .skip   8
601
602ENTRY_NP(absolute_value_dp)
603	save	%sp, -SA(MINFRAME), %sp	! save the registers, stack
604	setn	.Labs3,%l6,%l0 	! .. get the address of temp2
605	setn	.Labs2,%l6,%l1 	! .. and temp
606	stx	%i0, [%l0] 	! .. get the users value
607	ldd	[%l0], %f0 	! .. into a float register
608	fabsd	%f0, %f2 	! .... have the fpu perform the operation
609	std	%f2, [%l1] 	! .. save the result
610	ldx	[%l1], %i0  	! .... and return it to caller
611	ret  			! Delayed return (get user ret addr)
612	restore			! .. restore the frame window
613SET_SIZE(absolute_value_dp)
614
615#endif
616
617/*
618 * -----------------------------------------------------------------------
619 *				Arithmetic Functions			 *
620 * -----------------------------------------------------------------------
621 */
622
623/*
624 * --------------------------------------------------------------------------
625 * Name:	Single-precision square-root
626 * Function:	Calculate the square-root of a Single precision value
627 * Calling:	in0 = value
628 * Returns:	in0 = result
629 * Convention:	result = sqrt_sp(value) **
630 * --------------------------------------------------------------------------
631 */
632
633#ifdef __lint
634
635/*ARGSUSED*/
636uint64_t
637sqrt_sp(unsigned long arg1)
638{
639	return (0);
640}
641
642#else
643
644.section        ".data"
645.align  4
646.Lsqsp:
647        .skip   4
648.Lsqsp1:
649        .skip   4
650
651ENTRY_NP(sqrt_sp)
652	save	%sp, -SA(MINFRAME), %sp	! save the registers, stack
653	setn	.Lsqsp1,%l6,%l0	! .. get the address of temp2
654	setn	.Lsqsp,%l6,%l1	! .. and temp
655	st	%i0, [%l0]	! .. get the callers value
656	ld	[%l0], %f0	! .. into the float register
657	fsqrts  %f0, %f2	! .... have the fpu perform the operation
658	st	%f2, [%l1]	! .. save the result
659	ld	[%l1], %i0	! .... and return it to caller
660	ret			! Delayed return (get user ret addr)
661	restore			! .. restore the frame window
662SET_SIZE(sqrt_sp)
663
664#endif
665
666/*
667 * --------------------------------------------------------------------------
668 * Name:	Double-precision square-root
669 * Function:	Calculate the square-root of a double precision value
670 * Calling:	in0 = value
671 * Returns:	in0 = result
672 * Convention:	result = sqrt_dp(value) **
673 * --------------------------------------------------------------------------
674 */
675
676#ifdef __lint
677
678/*ARGSUSED*/
679uint64_t
680sqrt_dp(uint64_t arg1)
681{
682	return (0);
683}
684
685#else
686
687.section        ".data"
688.align  8
689.Lsqdp:
690        .skip   8
691.Lsqdp1:
692        .skip   8
693
694ENTRY_NP(sqrt_dp)
695	save	%sp, -SA(MINFRAME), %sp	! save the registers, stack
696	setn	.Lsqdp1,%l6,%l0 	! .. get the address of temp2
697	setn	.Lsqdp,%l6,%l1 	! .. and temp
698	stx		%i0, [%l0] 	! .. get the callers value
699	ldd		[%l0], %f0 	! .. into a float register
700	fsqrtd  %f0, %f2	! .... have the fpu perform the operation
701	std		%f2, [%l1] 	! .. save the result
702	ldx		[%l1], %i0 	! .... and return it to the caller
703	ret 			! Delayed return (get user ret addr)
704	restore			! .. restore the frame window
705SET_SIZE(sqrt_dp)
706
707#endif
708
709/*
710 * --------------------------------------------------------------------------
711 * Name:	Add single precision
712 * Function:	Add two values
713 * Calling:	in0 = value1,  in1 = value2
714 * Returns:	in0 = result
715 * Convention:	result = add_sp(value1,value2);
716 * --------------------------------------------------------------------------
717 */
718
719#ifdef __lint
720
721/*ARGSUSED*/
722unsigned long
723add_sp(unsigned long arg1, unsigned long arg2)
724{
725	return (0);
726}
727
728#else
729
730.section        ".data"
731.align  4
732.Laddsp:
733        .skip   4
734.Laddsp1:
735        .skip   4
736.Laddsp2:
737        .skip   4
738
739ENTRY_NP(add_sp)
740	save	%sp, -SA(MINFRAME), %sp	! save the registers, stack
741	setn	.Laddsp2,%l6,%l0  	! .. get the address of temp2
742	setn	.Laddsp1,%l6,%l1	! .. and temp1
743	setn	.Laddsp,%l6,%l2	! .. and temp
744	st	%i0, [%l0]	! .. get the users value1
745	st	%i1, [%l1]	! .. and value2
746	ld	[%l0], %f0	! .. into the float registers
747	ld	[%l1], %f2	! ......
748	fadds   %f0, %f2, %f4	! .... have the fpu perform the operation
749	st	%f4, [%l2]	! .. save the result
750	ld	[%l2], %i0	! .... and return it to caller
751	ret			! Delayed return (get user ret addr)
752	restore			! .. restore the frame window
753SET_SIZE(add_sp)
754
755#endif
756
757/*
758 * --------------------------------------------------------------------------
759 * Name:	Add double precision
760 * Function:	Add two 64 bit values
761 * Calling:	in0 = value1, in1 = value2
762 * Returns:	in0.1 = result
763 * Convention:	result = add_dp(value1,value2);
764 * --------------------------------------------------------------------------
765 */
766
767#ifdef __lint
768
769/*ARGSUSED*/
770uint64_t
771add_dp(uint64_t arg1, uint64_t arg2)
772{
773	return (0);
774}
775
776#else
777
778.section        ".data"
779.align  8
780.Ladddp:
781        .skip   8
782.Ladddp1:
783        .skip   8
784.Ladddp2:
785        .skip   8
786
787ENTRY_NP(add_dp)
788	save	%sp, -SA(MINFRAME), %sp	! save the registers, stack
789	setn	.Ladddp2,%l6,%l0   	! .. get the address of temp2
790	setn	.Ladddp1,%l6,%l1 	! .. and temp1
791	setn	.Ladddp,%l6,%l2 	! .. and temp
792	stx	%i0, [%l0] 	! .. get the user value1
793	stx	%i1, [%l1]	! .. get the user value2
794	ldd	[%l0], %f0 	! .. set them in float registers
795	ldd	[%l1], %f2	! .... both values
796	faddd	%f0, %f2, %f4	! .... have the fpu perform the operation
797	std	%f4, [%l2] 	! .. save the result
798	ldx	[%l2], %i0 	! .... and return it to the caller
799	ret 			! Delayed return (get user ret addr)
800	restore 		! .. restore the frame window
801SET_SIZE(add_dp)
802
803#endif
804
805/*
806 * --------------------------------------------------------------------------
807 * Name:		Subtract Single Precision
808 * Function:	Subtract two single precision values from each other
809 * Calling:	in0 = Value1, in1 = value2
810 * Returns:	in0 = result
811 * Convention:	result = sub_sp(value1, value2);
812 * --------------------------------------------------------------------------
813 */
814
815#ifdef __lint
816
817/*ARGSUSED*/
818unsigned long
819sub_sp(unsigned long arg1, unsigned long arg2)
820{
821	return (0);
822}
823
824#else
825
826.section        ".data"
827.align  4
828.Lsbsp:
829        .skip   4
830.Lsbsp1:
831        .skip   4
832.Lsbsp2:
833        .skip   4
834
835ENTRY_NP(sub_sp)
836	save	%sp, -SA(MINFRAME), %sp	! save the registers, stack
837	setn	.Lsbsp2,%l6,%l0   	! set the address of the result holder
838	setn	.Lsbsp1,%l6,%l1 	! .. get the address of temp1 (holder)
839	setn	.Lsbsp,%l6,%l2 	! .. get the address of temp
840	st	%i0, [%l0] 	! .. save the value in memory
841	st	%i1, [%l1] 	! .. save the value in memory
842	ld	[%l0], %f0 	! .. load the fpu register
843	ld	[%l1], %f2 	! .. load the fpu register
844	fsubs	%f0, %f2, %f4 	! .... have the fpu perform the operation
845	st	%f4, [%l2] 	! .. save the result
846	ld	[%l2], %i0 	! .. return the result to the caller
847	ret 			! Delayed return (get user ret addr)
848	restore 		! .. restore the frame window
849SET_SIZE(sub_sp)
850
851#endif
852
853/*
854 * --------------------------------------------------------------------------
855 * Name:	Subtract Double Precision
856 * Function:	Subtract two double precision values
857 * Calling:	in0 = Value1, in1 = Value2
858 * Returns:	in0 = Result
859 * Convention:	Result = sub_dp(Value1,Value2);
860 * --------------------------------------------------------------------------
861 */
862
863#ifdef __lint
864
865/*ARGSUSED*/
866uint64_t
867sub_dp(uint64_t arg1, uint64_t arg2)
868{
869	return (0);
870}
871
872#else
873
874.section        ".data"
875.align  8
876.Lsbdp:
877        .skip   8
878.Lsbdp1:
879        .skip   8
880.Lsbdp2:
881        .skip   8
882
883ENTRY_NP(sub_dp)
884	save	%sp, -SA(MINFRAME), %sp	! save the registers, stack
885	setn	.Lsbdp2,%l6,%l0    	! set the address of the result holder
886	setn	.Lsbdp1,%l6,%l1  	! .. get the address of temp1 (holder)
887	setn	.Lsbdp,%l6,%l2  	! .. get the address of temp
888	stx	%i0, [%l0]  	! .. save the value in memory
889	stx	%i1, [%l1] 	! .. save the value in memory
890	ldd	[%l0], %f0  	! .. load the fpu register
891	ldd	[%l1], %f2 	! .. load the fpu register
892	fsubd	%f0, %f2, %f4 	! .... have the fpu perform the operation
893	std	%f4, [%l2]  	! .. save the result
894	ldx	[%l2], %i0  	! .. return the result to the caller
895	ret  			! Delayed return (get user ret addr)
896	restore			! .. restore the frame window
897SET_SIZE(sub_dp)
898
899#endif
900
901/*
902 * --------------------------------------------------------------------------
903 * Name:	Multiply Single Precision
904 * Function:	Multiply two single precision values
905 * Calling:	in0 = Value1, in1 = value2
906 * Returns:	in0 = Result
907 * Convention:	Result = mult_sp(Value1,Value2);
908 * --------------------------------------------------------------------------
909 */
910
911#ifdef __lint
912
913/*ARGSUSED*/
914unsigned
915long mult_sp(unsigned long arg1, unsigned long arg2)
916{
917	return (0);
918}
919
920#else
921
922.section        ".data"
923.align  4
924.Lmlsp:
925        .skip   4
926.Lmlsp1:
927        .skip   4
928.Lmlsp2:
929        .skip   4
930
931ENTRY_NP(mult_sp)
932	save	%sp, -SA(MINFRAME), %sp	! save the registers, stack
933	setn	.Lmlsp2,%l6,%l0	! .. get the address of temp2
934	setn	.Lmlsp1,%l6,%l1	! .. and temp1
935	setn	.Lmlsp,%l6,%l2	! .. and temp
936	st	%i0, [%l0]	! .. Get the callers value1 into temp2
937	st	%i1, [%l1]	! .. Get the callers value2 into temp1
938	ld	[%l0], %f0	! .. then load Value1
939	ld	[%l1], %f2	! .. and Value2
940	fmuls   %f0, %f2, %f4	! .... have the fpu perform the operation
941	st	%f4, [%l2]	! .. save the result
942	ld	[%l2], %i0	! .... and return it to the caller
943	ret			! Delayed return (get user ret addr)
944	restore			! .. restore the frame window
945SET_SIZE(mult_sp)
946
947#endif
948
949/*
950 * --------------------------------------------------------------------------
951 * Name:		Multiply Double Precision
952 * Function:	Multiply two values and return the result
953 * Calling:	i0 = value1, i1 = value2
954 * Returns:	i0 = result
955 * Convention:	result = mul_dp(value1, value2);
956 * --------------------------------------------------------------------------
957 */
958
959#ifdef __lint
960
961/*ARGSUSED*/
962uint64_t
963mult_dp(uint64_t arg1, uint64_t arg2)
964{
965	return (0);
966}
967
968#else
969
970.section        ".data"
971.align  8
972.Lmldp:
973        .skip   8
974.Lmldp1:
975        .skip   8
976.Lmldp2:
977        .skip   8
978
979ENTRY_NP(mult_dp)
980	save	%sp, -SA(MINFRAME), %sp	! save the registers, stack
981	setn	.Lmldp2,%l6,%l0     	! set the address of the result holder
982	setn	.Lmldp1,%l6,%l1     	! .. get the address of temp1 (holder)
983	setn	.Lmldp,%l6,%l2	! .. get the address of temp
984	stx		%i0, [%l0]	! .. save the value in memory
985	stx		%i1, [%l1]	! .. save the value in memory
986	ldd		[%l0], %f0	! .. load the fpu register
987	ldd		[%l1], %f2	! .. load the fpu register
988	fmuld   %f0, %f2, %f4  	! .... have the fpu perform the operation
989	std		%f4, [%l2]	! .. save the result
990	ldx		[%l2], %i0	! .. return the result to the caller
991	ret    			! Delayed return (get user ret addr)
992	restore			! .. restore the frame window
993SET_SIZE(mult_dp)
994
995#endif
996
997/*
998 * --------------------------------------------------------------------------
999 * Name:		Divide Single Precision
1000 * Function:	Divide two value and return the result
1001 * Calling:	i0 = value1, i1 = value2
1002 * Returns:	i0 = result
1003 * Convention:	result = div_sp(value1, value2);
1004 * --------------------------------------------------------------------------
1005 */
1006
1007#ifdef __lint
1008
1009/*ARGSUSED*/
1010unsigned long
1011div_sp(unsigned long arg1, unsigned long arg2)
1012{
1013	return (0);
1014}
1015
1016#else
1017
1018.section        ".data"
1019.align  4
1020.Ldvsp:
1021        .word   0
1022.Ldvsp1:
1023        .word   0
1024.Ldvsp2:
1025        .word   0
1026
1027ENTRY_NP(div_sp)
1028	save	%sp, -SA(MINFRAME), %sp	! save the registers, stack
1029	setn	.Ldvsp2,%l6,%l0	! .. get the address of temp2
1030	setn	.Ldvsp1,%l6,%l1     	! .. get the address of temp1 (holder)
1031	setn	.Ldvsp,%l6,%l2	! .. get the address of temp
1032	st	%i0, [%l0]	! .. save the value in memory
1033	st	%i1, [%l1]	! .. save the value in memory
1034	ld	[%l0], %f0     	! .. load the fpu register
1035	ld	[%l1], %f2     	! .. load the fpu register
1036
1037	fdivs   %f0, %f2, %f4  	! .... have the fpu perform the operation
1038	st	%f4, [%l2]	! .. save the result
1039	ld	[%l2], %i0	! .. return the result to the caller
1040
1041	ret    			! Delayed return (get user ret addr)
1042	restore			! .. restore the frame window
1043SET_SIZE(div_sp)
1044
1045#endif
1046
1047/*
1048 * --------------------------------------------------------------------------
1049 * Name:	Divide Double Precision
1050 * Function:	Divide two value and return the result
1051 * Calling:	i0 = value1, i1 = value2
1052 * Returns:	i0 = result
1053 * Convention:	result = div_dp(value1, value2);
1054 * --------------------------------------------------------------------------
1055 */
1056
1057#ifdef __lint
1058
1059/*ARGSUSED*/
1060uint64_t
1061div_dp(uint64_t arg1, uint64_t arg2)
1062{
1063	return (0);
1064}
1065
1066#else
1067
1068.section        ".data"
1069.align  8
1070.Ldvdp:
1071        .skip   8
1072.Ldvdp1:
1073        .skip   8
1074.Ldvdp2:
1075        .skip   8
1076
1077ENTRY_NP(div_dp)
1078	save	%sp, -SA(MINFRAME), %sp	! save the registers, stack
1079	setn	.Ldvdp2,%l6,%l0     	! .. get the address of temp2
1080	setn	.Ldvdp1,%l6,%l1     	! .. get the address of temp1 (holder)
1081	setn	.Ldvdp,%l6,%l2	! .. get the address of temp
1082	stx	%i0, [%l0]	! .. save the value in memory
1083	stx	%i1, [%l1]	! .. save the value in memory
1084	ldd	[%l0], %f0     	! .. load the fpu register
1085	ldd	[%l1], %f2     	! .. load the fpu register
1086	fdivd   %f0, %f2, %f4  	! .... have the fpu perform the operation
1087	std	%f4, [%l2]	! .. save the result
1088	ldx	[%l2], %i0	! .. return the result to the caller
1089	ret    			! Delayed return (get user ret addr)
1090	restore			! .. restore the frame window
1091SET_SIZE(div_dp)
1092
1093#endif
1094
1095/*
1096 * -----------------------------------------------------------------------
1097 *			Data Comparison Functions
1098 * -----------------------------------------------------------------------
1099 */
1100
1101/*
1102 * --------------------------------------------------------------------------
1103 * Name:		Compare Single and Exception if Unordered
1104 * Function:	Compare two values and return the FSR flags
1105 * Warning:
1106 * Calling:	i0 = value1, i2 = value2
1107 * Returns:	i0 = flags
1108 * Convention:	flagsresult  = cmp_s_ex(value1, value2);
1109 * --------------------------------------------------------------------------
1110 */
1111
1112#ifdef __lint
1113
1114/*ARGSUSED*/
1115unsigned long
1116cmp_s_ex(unsigned long arg1, unsigned long arg2)
1117{
1118	return (0);
1119}
1120
1121#else
1122
1123.section        ".data"
1124.align  8
1125.Lcpsx:
1126        .skip   8
1127.Lcpsx1:
1128        .skip   4
1129.Lcpsx2:
1130        .skip   4
1131
1132ENTRY_NP(cmp_s_ex)
1133	save	%sp, -SA(MINFRAME), %sp	! save the registers, stack
1134	setn	.Lcpsx2,%l6,%l0	! .. get the address of temp2
1135	setn	.Lcpsx1,%l6,%l1	! .. get the address of temp
1136	setn	.Lcpsx,%l6,%l2	! .. get the address of temp
1137	st	%i0, [%l0]	! .. save the value in memory
1138	st	%i1, [%l1]	! .. save the value in memory
1139	ld	[%l0], %f0	! .. load the fpu register
1140	ld	[%l1], %f2	! .. load the fpu register
1141	fcmpes  %f0, %f2	! .... have the fpu perform the operation
1142	nop			! .. delay
1143	stx	%fsr, [%l2]	! .. get the contents of the FSR register
1144	ldx	[%l2], %i0	! .. return the result to the caller
1145	ret			! Delayed return (get user ret addr)
1146	restore			! .. restore the frame window
1147SET_SIZE(cmp_s_ex)
1148
1149#endif
1150
1151/*
1152 * --------------------------------------------------------------------------
1153 * Name:	Compare Double and Exception if Unordered
1154 * Function:	Compare two values and return the FSR flags
1155 * Warning:
1156 * Calling:	i0 = value1, i2 = value2
1157 * Returns:	i0 = flags
1158 * Convention:	flagsresult  = cmp_d_ex(value1, value2);
1159 * --------------------------------------------------------------------------
1160 */
1161
1162#ifdef __lint
1163
1164/*ARGSUSED*/
1165unsigned long
1166cmp_d_ex(unsigned long arg1, unsigned long arg2)
1167{
1168	return (0);
1169}
1170
1171#else
1172
1173.section        ".data"
1174.align  8
1175.Lcpdx:
1176        .skip   8
1177.Lcpdx1:
1178        .skip   8
1179.Lcpdx2:
1180        .skip   8
1181
1182ENTRY_NP(cmp_d_ex)
1183	save	%sp, -SA(MINFRAME), %sp	! save the registers, stack
1184	setn	.Lcpdx2,%l6,%l0     	! .. get the address of temp2
1185	setn	.Lcpdx1,%l6,%l1     	! .. get the address of temp1 (holder)
1186	setn	.Lcpdx,%l6,%l2  	! .. get the address of temp
1187	stx		%i0, [%l0]	! .. save the value in memory
1188	stx		%i1, [%l1]	! .. save the value in memory
1189	ldd		[%l0], %f0     	! .. load the fpu register
1190	ldd		[%l1], %f2	! .. load the fpu register
1191	fcmped  %f0, %f2	! .... have the FPU do it
1192	nop			! .. delay
1193	stx	%fsr, [%l2]	! .. get the contents of the FSR register
1194	ldx	[%l2], %i0	! .. return the result to the caller
1195	ret			! Delayed return (get user ret addr)
1196	restore			! .. restore the frame window
1197SET_SIZE(cmp_d_ex)
1198
1199#endif
1200
1201/*
1202 * --------------------------------------------------------------------------
1203 * Name:	Float to long conversion (single)
1204 * Function:	Convert a real single-precision value to a long
1205 * Calling:	in0 = value
1206 * Returns:	in0 = value
1207 * Convention:	long = float_long_s(real) **
1208 * --------------------------------------------------------------------------
1209 */
1210#ifdef __lint
1211
1212/*ARGSUSED*/
1213uint64_t
1214float_long_s(unsigned long arg1)
1215{
1216	return (0);
1217}
1218
1219#else
1220
1221.data
1222.align  4
1223
1224.Lfllngs:
1225	.skip   4
1226
1227.align  8
1228
1229.Lfllngs1:
1230	.skip   8
1231
1232ENTRY_NP(float_long_s)
1233    save    %sp, -SA(MINFRAME), %sp
1234    setn    .Lfllngs1,%l6,%o5    ! .. get the address of temp2
1235    setn    .Lfllngs,%l6,%o4     ! .. and temp
1236
1237    st      %i0, [%o4]  ! .. get the callers value
1238    ld      [%o4], %f0  ! .. into the float register
1239    fstox   %f0, %f2    ! .... have the fpu perform the operation
1240    std     %f2, [%o5]  ! .. save the result
1241    ldx     [%o5], %i0  ! .... and return it to caller
1242
1243    ret
1244    restore
1245SET_SIZE(float_long_s)
1246
1247#endif
1248
1249/*
1250 * --------------------------------------------------------------------------
1251 * Name:	Float to long conversion (double)
1252 * Function:	Convert a real value to a long
1253 * Calling:	in0 = value
1254 * Returns:	in0 = value
1255 * Convention:	long = float_long_d(real) **
1256 * --------------------------------------------------------------------------
1257 */
1258
1259#ifdef __lint
1260
1261/*ARGSUSED*/
1262uint64_t
1263float_long_d(uint64_t arg1)
1264{
1265	return (0);
1266}
1267
1268#else
1269
1270        .data
1271        .align  8
1272
1273.Lfllngd:
1274    .skip   8
1275.Lfllngd1:
1276    .skip   8
1277
1278ENTRY_NP(float_long_d)
1279    save    %sp, -SA(MINFRAME), %sp
1280    setn    .Lfllngd1,%l6,%o5    ! .. get the address of temp2
1281    setn    .Lfllngd,%l6,%o4     ! .. and temp
1282
1283    stx     %i0, [%o4]  ! .. get the callers value
1284    ldd     [%o4], %f0  ! .. into the float register
1285    fdtox   %f0, %f2    ! .... have the fpu perform the operation
1286    std     %f2, [%o5]  ! .. save the result
1287    ldx     [%o5], %i0  ! .... and return it to caller
1288
1289    ret
1290    restore
1291SET_SIZE(float_long_d)
1292
1293#endif
1294
1295/*
1296 * --------------------------------------------------------------------------
1297 * Name:	Long to Float (Single)
1298 * Function:	Convert an integer value to a single precision floating point
1299 *		value
1300 * Calling:	in0 = value to convert
1301 * Returns:	in0 = converted value
1302 * Convention:	Real = long_float_s(Int) **
1303 * --------------------------------------------------------------------------
1304 */
1305
1306#ifdef __lint
1307
1308/*ARGSUSED*/
1309unsigned long
1310long_float_s(uint64_t arg1)
1311{
1312	return (0);
1313}
1314
1315#else
1316
1317        .data
1318        .align  8
1319
1320.Llngfls:
1321        .skip   8
1322.Llngfls1:
1323        .skip   4
1324
1325ENTRY_NP(long_float_s)
1326	save	%sp, -SA(MINFRAME), %sp	! save the registers, stack
1327	setn	.Llngfls1,%l6,%o5	! .. set the address of the result holder
1328	setn	.Llngfls,%l6,%o4	! .. set address of temp. mem reg
1329	stx	%i0, [%o4]	! .. put the passed value into memory
1330	ldd	[%o4], %f0	! .. get the value from memory into FPU register
1331	fxtos   %f0, %f2	! .. get the integer into float into fpu r1
1332	st	%f2, [%o5]	! .. store into the location
1333	ld	[%o5], %i0	! .. put the value for return
1334	ret			! Delayed return (get user ret addr)
1335	restore			! .. restore the frame window
1336SET_SIZE(long_float_s)
1337
1338#endif
1339
1340/*
1341 * --------------------------------------------------------------------------
1342 * Name:		Long to Float (double)
1343 * Function:	Convert an integer value to a double precision floating point
1344 * 		value
1345 * Calling:	in0 = value to convert
1346 * Returns:	in0 = converted value
1347 * Convention:	Real = long_float_d(Int) **
1348 * ---------------------------------------------------------------------------
1349 */
1350
1351#ifdef __lint
1352
1353/*ARGSUSED*/
1354uint64_t
1355long_float_d(uint64_t arg1)
1356{
1357	return (0);
1358}
1359
1360#else
1361        .data
1362        .align  8
1363.Llngfld:
1364        .skip   8
1365.Llngfld1:
1366        .skip   8
1367
1368ENTRY_NP(long_float_d)
1369	save	%sp, -SA(MINFRAME), %sp	! save the registers, stack
1370	setn	.Llngfld1,%l6,%o5	! .. get the address of temp2
1371	setn	.Llngfld,%l6,%o4	! .. get the address of temp
1372	stx	%i0, [%o4]	! .. get the user value
1373	ldd	[%o4], %f0	! .. into the float register
1374	fxtod   %f0, %f2	! .... have the fpu perform the operation
1375	std	%f2, [%o5]	! .. save the result
1376	ldx	[%o5], %i0	! .. and return it to caller
1377	ret			! Delayed return (get user ret addr)
1378	restore			! .. restore the frame window
1379SET_SIZE(long_float_d)
1380
1381#endif
1382