this repo has no description
1/*
2 * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22/*******************************************************************************
23* *
24* File copysign.c, *
25* Function copysign for PowerPC based machines. *
26* *
27* Copyright � 1991-2001 Apple Computer, Inc. All rights reserved. *
28* *
29* Written by A. Sazegari, started on June 1991. *
30* Modified and ported by Robert A. Murley (ram) for Mac OS X. *
31* *
32* A MathLib v4 file. *
33* *
34* August 26 1991: no CFront Version 1.1d17 warnings. *
35* September 06 1991: passes the test suite with invalid raised on *
36* signaling nans. sane rom code behaves the same. *
37* September 24 1992: took the �#include support.h� out. *
38* Dcember 02 1992: PowerPC port. *
39* July 20 1994: __FABS added *
40* July 21 1994: deleted unnecessary functions: neg, COPYSIGNnew, *
41* and SIGNNUMnew. *
42* April 11 2001: first port to os x using gcc. *
43* removed fabs and deffered to gcc for direct *
44* instruction generation. *
45* August 28 2001: replaced DblInHex typedef with hexdouble. *
46* added #ifdef __ppc__. *
47* September 09 2001: added more comments. *
48* September 10 2001: added macros to detect PowerPC and correct compiler. *
49* October 08 2001: removed <CoreServices/CoreServices.h>. *
50* changed compiler errors to warnings. *
51* November 06 2001: commented out warning about Intel architectures. *
52* *
53* W A R N I N G: *
54* These routines require a 64-bit double precision IEEE-754 model. *
55* They are written for PowerPC only and are expecting the compiler *
56* to generate the correct sequence of multiply-add fused instructions. *
57* *
58* These routines are not intended for 32-bit Intel architectures. *
59* *
60* A version of gcc higher than 932 is required. *
61* *
62* GCC compiler options: *
63* optimization level 3 (-O3) *
64* -fschedule-insns -finline-functions -funroll-all-loops *
65* *
66*******************************************************************************/
67
68#include "fp_private.h"
69#include "math.h"
70
71/*******************************************************************************
72* Function copysign. *
73* Produces a value with the magnitude of its first argument and sign of *
74* its second argument. NOTE: the order of the arguments matches the *
75* recommendation of the IEEE-754 floating-point standard, which is the *
76* opposite from SANE's copysign function. *
77*******************************************************************************/
78
79static inline double __copysign_MEM ( double x, double y )
80{
81 hexdouble hx, hy;
82 register uint32_t GPR_7f, GPR_80, GPR_x, GPR_y;
83 register double result;
84
85/*******************************************************************************
86* No need to flush NaNs out. *
87*******************************************************************************/
88
89 hx.d = x; hy.d = y;
90 GPR_7f = 0x7fffffff; GPR_80 = 0x80000000;
91 __NOOP;
92 __NOOP;
93 __NOOP; // gaurantees next instruction is in different issue group, so allows store-fwd.
94
95 GPR_x = hx.i.hi;
96 GPR_x &= GPR_7f;
97 GPR_y = hy.i.hi;
98 GPR_x |= GPR_y & GPR_80;
99 hx.i.hi = GPR_x;
100 __NOOP;
101 __NOOP;
102 __NOOP;
103
104 result = hx.d;
105 return result;
106}
107
108double copysign ( double x, double y )
109{
110 double pos_x, neg_x;
111 double pos_y, neg_y, t;
112
113 pos_x = __fabs(x);
114 neg_x = __fnabs(x);
115 pos_y = __fabs(y);
116 neg_y = __fnabs(y);
117
118 if (unlikely(pos_y == neg_y))
119 return __copysign_MEM(x, y);
120
121 if (unlikely(y != y))
122 return __copysign_MEM(x, y);
123
124 t = __fsel(y, pos_x, neg_x);
125 return t;
126}
127
128static inline float __copysignf_MEM ( float x, float y )
129{
130 hexsingle hx, hy;
131 register uint32_t GPR_7f, GPR_80, GPR_x, GPR_y;
132 register float result;
133
134/*******************************************************************************
135* No need to flush NaNs out. *
136*******************************************************************************/
137
138 hx.fval = x; hy.fval = y;
139 GPR_7f = 0x7fffffff; GPR_80 = 0x80000000;
140 __NOOP;
141 __NOOP;
142 __NOOP; // gaurantees next instruction is in different issue group, so allows store-fwd.
143
144 GPR_x = hx.lval;
145 GPR_x &= GPR_7f;
146 GPR_y = hy.lval;
147 GPR_x |= GPR_y & GPR_80;
148 hx.lval = GPR_x;
149 __NOOP;
150 __NOOP;
151 __NOOP;
152
153 result = hx.fval;
154 return result;
155}
156
157float copysignf ( float x, float y )
158{
159 double pos_x, neg_x;
160 double pos_y, neg_y;
161 float t;
162
163 pos_x = __fabs(x);
164 neg_x = __fnabs(x);
165 pos_y = __fabs(y);
166 neg_y = __fnabs(y);
167
168 if (unlikely(pos_y == neg_y))
169 return __copysignf_MEM(x, y);
170
171 if (unlikely(y != y))
172 return __copysignf_MEM(x, y);
173
174 t = __fsels(y, pos_x, neg_x);
175 return t;
176}