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: minmaxdim.c *
25* *
26* Contains: C99 fmin, fmax, fdim, and fma *
27* *
28* Copyright � 2001 Apple Computer, Inc. All rights reserved. *
29* *
30* Written by Stephen C. Peters, started in November 2001. *
31* *
32* A MathLib v5 file. *
33* *
34* Change History (most recent first): *
35* *
36* 21 Nov 01 scp First created. *
37* *
38* W A R N I N G: *
39* These routines require a 64-bit double precision IEEE-754 model. *
40* They are written for PowerPC only and are expecting the compiler *
41* to generate the correct sequence of multiply-add fused instructions. *
42* *
43* These routines are not intended for 32-bit Intel architectures. *
44* *
45* A version of gcc higher than 932 is required. *
46* *
47* GCC compiler options: *
48* optimization level 3 (-O3) *
49* -fschedule-insns -finline-functions -funroll-all-loops *
50* *
51*******************************************************************************/
52
53#include "fp_private.h"
54#include "math.h"
55
56#if defined(BUILDING_FOR_CARBONCORE_LEGACY)
57
58double fdim ( double x, double y )
59{
60 if (unlikely((x != x) || (y != y)))
61 return ( x + y );
62 else if (x > y)
63 return ( x - y );
64 else
65 return 0.0;
66}
67
68//
69// N.B. max/min (-0, 0) allows implementation dependent result
70//
71#define __fmax(x, y) \
72({ \
73 double __value, __argx = (x), __argy = (y); \
74 asm volatile ( \
75 "fcmpu cr0,%1,%2 ; /* Compare unordered */ \n \
76 blt cr0, 0f ; /* Order discerned? Then we have our answer */ \n \
77 bnu+ cr0, 1f ; /* Opposite order discerned? Then we have our answer */ \n \
78 fcmpu cr1,%2,%2 ; /* x, y or both are NAN. Is y NAN? */ \n \
79 bun- cr1, 1f ; /* If so, x is our answer */ \n \
80 0: fmr %0, %2; /* Else y is our answer */ \n \
81 b 2f \n \
82 1: fmr %0,%1; \n \
83 2: \n \
84 ": "=f"(__value) : "f" (__argx), "f" (__argy)); \
85 __value; \
86})
87
88#if 0
89//
90// N.B. max/min (-0, 0) allows implementation dependent result
91//
92double fmax ( double x, double y )
93{
94 if (x != x)
95 return y;
96 else if (y != y)
97 return x;
98 else if (x < y)
99 return y;
100 else
101 return x;
102}
103#else
104double fmax ( double x, double y )
105{
106 return __fmax( x, y );
107}
108#endif
109
110#define __fmin(x, y) \
111({ \
112 double __value, __argx = (x), __argy = (y); \
113 asm volatile ( \
114 "fcmpu cr0,%1,%2 ; /* Compare unordered */ \n \
115 bgt cr0, 0f ; /* Order discerned? Then we have our answer */ \n \
116 bnu+ cr0, 1f ; /* Opposite order discerned? Then we have our answer */ \n \
117 fcmpu cr1,%2,%2 ; /* x, y or both are NAN. Is y NAN? */ \n \
118 bun- cr1, 1f ; /* If so, x is our answer */ \n \
119 0: fmr %0, %2; /* Else y is our answer */ \n \
120 b 2f \n \
121 1: fmr %0,%1; \n \
122 2: \n \
123 ": "=f"(__value) : "f" (__argx), "f" (__argy)); \
124 __value; \
125})
126
127#if 0
128double fmin ( double x, double y )
129{
130 if (x != x)
131 return y;
132 else if (y != y)
133 return x;
134 else if (x > y)
135 return y;
136 else
137 return x;
138}
139#else
140double fmin ( double x, double y )
141{
142 return __fmin( x, y );
143}
144#endif
145
146#else /* !BUILDING_FOR_CARBONCORE_LEGACY */
147
148float fdimf ( float x, float y )
149{
150 if (unlikely((x != x) || (y != y)))
151 return ( x + y );
152 else if (x > y)
153 return ( x - y );
154 else
155 return 0.0f;
156}
157
158
159#define __fmaxf(x, y) \
160({ \
161 float __value, __argx = (x), __argy = (y); \
162 asm volatile ( \
163 "fcmpu cr0,%1,%2 ; /* Compare unordered */ \n \
164 blt cr0, 0f ; /* Order discerned? Then we have our answer */ \n \
165 bnu+ cr0, 1f ; /* Opposite order discerned? Then we have our answer */ \n \
166 fcmpu cr1,%2,%2 ; /* x, y or both are NAN. Is y NAN? */ \n \
167 bun- cr1, 1f ; /* If so, x is our answer */ \n \
168 0: fmr %0, %2; /* Else y is our answer */ \n \
169 b 2f \n \
170 1: fmr %0,%1; \n \
171 2: \n \
172 ": "=f"(__value) : "f" (__argx), "f" (__argy)); \
173 __value; \
174})
175
176#if 0
177float fmaxf ( float x, float y )
178{
179 if (x != x)
180 return y;
181 else if (y != y)
182 return x;
183 else if (x < y)
184 return y;
185 else
186 return x;
187}
188#else
189float fmaxf ( float x, float y )
190{
191 return __fmaxf( x, y );
192}
193#endif
194
195#define __fminf(x, y) \
196({ \
197 float __value, __argx = (x), __argy = (y); \
198 asm volatile ( \
199 "fcmpu cr0,%1,%2 ; /* Compare unordered */ \n \
200 bgt cr0, 0f ; /* Order discerned? Then we have our answer */ \n \
201 bnu+ cr0, 1f ; /* Opposite order discerned? Then we have our answer */ \n \
202 fcmpu cr1,%2,%2 ; /* x, y or both are NAN. Is y NAN? */ \n \
203 bun- cr1, 1f ; /* If so, x is our answer */ \n \
204 0: fmr %0, %2; /* Else y is our answer */ \n \
205 b 2f \n \
206 1: fmr %0,%1; \n \
207 2: \n \
208 ": "=f"(__value) : "f" (__argx), "f" (__argy)); \
209 __value; \
210})
211
212#if 0
213float fminf ( float x, float y )
214{
215 if (x != x)
216 return y;
217 else if (y != y)
218 return x;
219 else if (x > y)
220 return y;
221 else
222 return x;
223}
224#else
225float fminf ( float x, float y )
226{
227 return __fminf( x, y );
228}
229#endif
230
231double fma ( double x, double y, double z )
232{
233 return __FMADD(x, y, z);
234}
235
236float fmaf ( float x, float y, float z )
237{
238 return __FMADDS(x, y, z);
239}
240#endif /* !BUILDING_FOR_CARBONCORE_LEGACY */