xref: /onnv-gate/usr/src/lib/libc/amd64/fp/_base_il.c (revision 6812:febeba71273d)
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 "lint.h"
30 #include "base_conversion.h"
31 #include <sys/isa_defs.h>
32 
33 #define	CSR_DEFAULT 0x1f80
34 
35 /* The following should be coded as inline expansion templates.	 */
36 
37 /*
38  * Multiplies two normal or subnormal doubles, returns result and exceptions.
39  */
40 double
__mul_set(double x,double y,int * pe)41 __mul_set(double x, double y, int *pe) {
42 	extern void _putmxcsr(), _getmxcsr();
43 	int csr;
44 	double z;
45 
46 	_putmxcsr(CSR_DEFAULT);
47 	z = x * y;
48 	_getmxcsr(&csr);
49 	if ((csr & 0x3f) == 0) {
50 		*pe = 0;
51 	} else {
52 		/* Result may not be exact. */
53 		*pe = 1;
54 	}
55 	return (z);
56 }
57 
58 /*
59  * Divides two normal or subnormal doubles x/y, returns result and exceptions.
60  */
61 double
__div_set(double x,double y,int * pe)62 __div_set(double x, double y, int *pe) {
63 	extern void _putmxcsr(), _getmxcsr();
64 	int csr;
65 	double z;
66 
67 	_putmxcsr(CSR_DEFAULT);
68 	z = x / y;
69 	_getmxcsr(&csr);
70 	if ((csr & 0x3f) == 0) {
71 		*pe = 0;
72 	} else {
73 		*pe = 1;
74 	}
75 	return (z);
76 }
77 
78 double
__dabs(double * d)79 __dabs(double *d)
80 {
81 	/* should use hardware fabs instruction */
82 	return ((*d < 0.0) ? -*d : *d);
83 }
84 
85 /*
86  * Returns IEEE mode/status and
87  * sets up standard environment for base conversion.
88  */
89 void
__get_ieee_flags(__ieee_flags_type * b)90 __get_ieee_flags(__ieee_flags_type *b) {
91 	extern void _getmxcsr(), _putmxcsr();
92 
93 	_getmxcsr(&b->status);
94 
95 	/* round-to-nearest, all exceptions masked, gradual underflow */
96 	_putmxcsr(CSR_DEFAULT);
97 }
98 
99 /*
100  * Restores previous IEEE mode/status
101  */
102 void
__set_ieee_flags(__ieee_flags_type * b)103 __set_ieee_flags(__ieee_flags_type *b) {
104 	extern void _putmxcsr();
105 
106 	_putmxcsr(b->status);
107 }
108