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
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
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
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.
|
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
38 __mul_set(double x, double y, int *pe) {
39 extern void _putsw(), _getsw();
40 int sw;
41 volatile double z;
42
43 _putsw(0);
44 /*
45 * NOTE: By declaring 'z' volatile above, we intend for the
46 * compiler to not move this after the _getmxcsr() call, whose results
47 * are only useful if they immediately follow the multiply.
48 *
49 * From the C11 spec:
50 *
51 * 134 - A volatile declaration may be used to describe an
52 * object corresponding to a memory-mapped input/output port
53 * or an object accessed by an asynchronously interrupting
54 * function. Actions on objects so declared shall by an
55 * implementation or reordered except as permitted by the
56 * rules for evaluating expressions."
57 */
58 z = x * y;
59 _getsw(&sw);
60 if ((sw & 0x3f) == 0) {
61 *pe = 0;
62 } else {
63 /* Result may not be exact. */
64 *pe = 1;
65 }
66 return (z);
67 }
68
69 /*
70 * Divides two normal or subnormal doubles x/y, returns result and exceptions.
71 */
72 double
73 __div_set(double x, double y, int *pe) {
74 extern void _putsw(), _getsw();
75 int sw;
76 volatile double z;
77
78 _putsw(0);
79 /* NOTE: See __mul_set() above, same principle applies here. */
80 z = x / y;
81 _getsw(&sw);
82 if ((sw & 0x3f) == 0) {
83 *pe = 0;
84 } else {
85 *pe = 1;
86 }
87 return (z);
88 }
89
90 double
91 __dabs(double *d)
92 {
93 /* should use hardware fabs instruction */
94 return ((*d < 0.0) ? -*d : *d);
95 }
96
97 /*
98 * Returns IEEE mode/status and
99 * sets up standard environment for base conversion.
|