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
32 /* The following should be coded as inline expansion templates. */
33
34 /*
35 * Multiplies two normal or subnormal doubles, returns result and exceptions.
36 */
37 double
__mul_set(double x,double y,int * pe)38 __mul_set(double x, double y, int *pe) {
39 extern void _putsw(), _getsw();
40 int sw;
41 double z;
42
43 _putsw(0);
44 z = x * y;
45 _getsw(&sw);
46 if ((sw & 0x3f) == 0) {
47 *pe = 0;
48 } else {
49 /* Result may not be exact. */
50 *pe = 1;
51 }
52 return (z);
53 }
54
55 /*
56 * Divides two normal or subnormal doubles x/y, returns result and exceptions.
57 */
58 double
__div_set(double x,double y,int * pe)59 __div_set(double x, double y, int *pe) {
60 extern void _putsw(), _getsw();
61 int sw;
62 double z;
63
64 _putsw(0);
65 z = x / y;
66 _getsw(&sw);
67 if ((sw & 0x3f) == 0) {
68 *pe = 0;
69 } else {
70 *pe = 1;
71 }
72 return (z);
73 }
74
75 double
__dabs(double * d)76 __dabs(double *d)
77 {
78 /* should use hardware fabs instruction */
79 return ((*d < 0.0) ? -*d : *d);
80 }
81
82 /*
83 * Returns IEEE mode/status and
84 * sets up standard environment for base conversion.
85 */
86 void
__get_ieee_flags(__ieee_flags_type * b)87 __get_ieee_flags(__ieee_flags_type *b) {
88 extern void _getcw(), _getsw(), _putcw();
89 int cw;
90
91 _getcw(&cw);
92 b->mode = cw;
93 _getsw(&b->status);
94 /*
95 * set CW to...
96 * RC (bits 10:11) 0 == round to nearest even
97 * PC (bits 8:9) 2 == round to double
98 * EM (bits 0:5) 0x3f == all exception trapping masked off
99 */
100 cw = (cw & ~0xf3f) | 0x23f;
101 _putcw(cw);
102 }
103
104 /*
105 * Restores previous IEEE mode/status
106 */
107 void
__set_ieee_flags(__ieee_flags_type * b)108 __set_ieee_flags(__ieee_flags_type *b) {
109 extern void _putcw(), _putsw();
110
111 _putcw(b->mode);
112 _putsw(b->status);
113 }
114