1/*
2 * Copyright (c) 2010 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1.  Redistributions of source code must retain the above copyright
11 *     notice, this list of conditions and the following disclaimer.
12 * 2.  Redistributions in binary form must reproduce the above copyright
13 *     notice, this list of conditions and the following disclaimer in the
14 *     documentation and/or other materials provided with the distribution.
15 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of its
16 *     contributors may be used to endorse or promote products derived from
17 *     this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * Portions of this software have been released under the following terms:
31 *
32 * (c) Copyright 1989-1993 OPEN SOFTWARE FOUNDATION, INC.
33 * (c) Copyright 1989-1993 HEWLETT-PACKARD COMPANY
34 * (c) Copyright 1989-1993 DIGITAL EQUIPMENT CORPORATION
35 *
36 * To anyone who acknowledges that this file is provided "AS IS"
37 * without any express or implied warranty:
38 * permission to use, copy, modify, and distribute this file for any
39 * purpose is hereby granted without fee, provided that the above
40 * copyright notices and this notice appears in all source code copies,
41 * and that none of the names of Open Software Foundation, Inc., Hewlett-
42 * Packard Company or Digital Equipment Corporation be used
43 * in advertising or publicity pertaining to distribution of the software
44 * without specific, written prior permission.  Neither Open Software
45 * Foundation, Inc., Hewlett-Packard Company nor Digital
46 * Equipment Corporation makes any representations about the suitability
47 * of this software for any purpose.
48 *
49 * Copyright (c) 2007, Novell, Inc. All rights reserved.
50 * Redistribution and use in source and binary forms, with or without
51 * modification, are permitted provided that the following conditions
52 * are met:
53 *
54 * 1.  Redistributions of source code must retain the above copyright
55 *     notice, this list of conditions and the following disclaimer.
56 * 2.  Redistributions in binary form must reproduce the above copyright
57 *     notice, this list of conditions and the following disclaimer in the
58 *     documentation and/or other materials provided with the distribution.
59 * 3.  Neither the name of Novell Inc. nor the names of its contributors
60 *     may be used to endorse or promote products derived from this
61 *     this software without specific prior written permission.
62 *
63 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
64 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
65 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
66 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY
67 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
68 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
69 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
70 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
71 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
72 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73 *
74 * @APPLE_LICENSE_HEADER_END@
75 */
76
77/*
78**
79**  NAME:
80**
81**      pkieees.c.h
82**
83**  FACILITY:
84**
85**      IDL Stub Runtime Support
86**
87**  ABSTRACT:
88**
89**      This module contains code to extract information from an
90**      UNPACKED_REAL structure and to create an IEEE single floating number
91**      with those bits.
92**
93**              This module is meant to be used as an include file.
94**
95**  VERSION: DCE 1.0
96**
97*/
98#if HAVE_CONFIG_H
99#include <config.h>
100#endif
101
102/*
103**++
104**  Functional Description:
105**
106**  This module contains code to extract information from an
107**  UNPACKED_REAL structure and to create an IEEE single number
108**  with those bits.
109**
110**  See the header files for a description of the UNPACKED_REAL
111**  structure.
112**
113**  A normalized IEEE single precision floating number looks like:
114**
115**      Sign bit, 8 exp bits (bias 127), 23 fraction bits
116**
117**      1.0 <= fraction < 2.0, MSB implicit
118**
119**  For more details see "Mips R2000 Risc Architecture"
120**  by Gerry Kane, page 6-8 or ANSI/IEEE Std 754-1985.
121**
122**
123**  Implicit parameters:
124**
125**      options: a word of flags, see include files.
126**
127**      output_value: a pointer to the input parameter.
128**
129**      r: an UNPACKED_REAL structure.
130**
131**--
132*/
133
134if (r[U_R_FLAGS] & U_R_UNUSUAL) {
135
136        if (r[U_R_FLAGS] & U_R_ZERO)
137
138                if (r[U_R_FLAGS] & U_R_NEGATIVE)
139                        memcpy(output_value, IEEE_S_NEG_ZERO, 4);
140                else
141                        memcpy(output_value, IEEE_S_POS_ZERO, 4);
142
143        else if (r[U_R_FLAGS] & U_R_INFINITY) {
144
145                if (r[U_R_FLAGS] & U_R_NEGATIVE)
146                        memcpy(output_value, IEEE_S_NEG_INFINITY, 4);
147                else
148                        memcpy(output_value, IEEE_S_POS_INFINITY, 4);
149
150        } else if (r[U_R_FLAGS] & U_R_INVALID) {
151
152                memcpy(output_value, IEEE_S_INVALID, 4);
153                DCETHREAD_RAISE(dcethread_aritherr_e);    /* Invalid value */
154
155        }
156
157} else {
158
159        /* Precision varies if value will be a denorm */
160        /* So, figure out where to round (0 <= i <= 24). */
161
162        round_bit_position = r[U_R_EXP] - ((U_R_BIAS - 126) - 23);
163        if (round_bit_position < 0)
164                round_bit_position = 0;
165        else if (round_bit_position > 24)
166                round_bit_position = 24;
167
168#include "round.c.h"
169
170        if (r[U_R_EXP] < (U_R_BIAS - 125)) {
171
172                /* Denorm or underflow */
173
174                if (r[U_R_EXP] < ((U_R_BIAS - 125) - 23)) {
175
176                        /* Value is too small for a denorm, so underflow */
177
178                        if (r[U_R_FLAGS] & U_R_NEGATIVE)
179                                memcpy(output_value, IEEE_S_NEG_ZERO, 4);
180                        else
181                                memcpy(output_value, IEEE_S_POS_ZERO, 4);
182                        if (options & CVT_C_ERR_UNDERFLOW) {
183                                DCETHREAD_RAISE(dcethread_fltund_e);  /* Underflow */
184                        }
185
186                } else {
187
188                        /* Figure leading zeros for denorm and right-justify fraction */
189
190                        i = 32 - (r[U_R_EXP] - ((U_R_BIAS - 126) - 23));
191                        r[1] >>= i;
192
193                        /* Set sign bit */
194
195                        r[1] |= (r[U_R_FLAGS] << 31);
196
197                        if (options & CVT_C_BIG_ENDIAN) {
198
199                                r[0]  = ((r[1] << 24) | (r[1] >> 24));
200                                r[0] |= ((r[1] << 8) & 0x00FF0000L);
201                                r[0] |= ((r[1] >> 8) & 0x0000FF00L);
202                                memcpy(output_value, r, 4);
203
204                        } else {
205
206                                memcpy(output_value, &r[1], 4);
207
208                        }
209                }
210
211        } else if (r[U_R_EXP] > (U_R_BIAS + 128)) {
212
213                /* Overflow */
214
215                if (options & CVT_C_TRUNCATE) {
216
217                        if (r[U_R_FLAGS] & U_R_NEGATIVE)
218                                memcpy(output_value, IEEE_S_NEG_HUGE, 4);
219                        else
220                                memcpy(output_value, IEEE_S_POS_HUGE, 4);
221
222                } else if ((options & CVT_C_ROUND_TO_POS)
223                                        && (r[U_R_FLAGS] & U_R_NEGATIVE)) {
224
225                                memcpy(output_value, IEEE_S_NEG_HUGE, 4);
226
227                } else if ((options & CVT_C_ROUND_TO_NEG)
228                                        && !(r[U_R_FLAGS] & U_R_NEGATIVE)) {
229
230                                memcpy(output_value, IEEE_S_POS_HUGE, 4);
231
232                } else {
233
234                        if (r[U_R_FLAGS] & U_R_NEGATIVE)
235                                memcpy(output_value, IEEE_S_NEG_INFINITY, 4);
236                        else
237                                memcpy(output_value, IEEE_S_POS_INFINITY, 4);
238
239                }
240
241                DCETHREAD_RAISE(dcethread_fltovf_e);  /* Overflow */
242
243        } else {
244
245                /* Adjust bias of exponent */
246
247                r[U_R_EXP] -= (U_R_BIAS - 126);
248
249                /* Make room for exponent and sign bit */
250
251                r[1] >>= 8;
252
253                /* Clear implicit bit */
254
255                r[1] &= 0x007FFFFFL;
256
257                /* OR in exponent and sign bit */
258
259                r[1] |= (r[U_R_EXP] << 23);
260                r[1] |= (r[U_R_FLAGS] << 31);
261
262#if (NDR_LOCAL_INT_REP == ndr_c_int_big_endian)
263
264                memcpy(output_value, &r[1], 4);
265
266#else
267                if (options & CVT_C_BIG_ENDIAN) {
268
269                        r[0]  = ((r[1] << 24) | (r[1] >> 24));
270                        r[0] |= ((r[1] << 8) & 0x00FF0000L);
271                        r[0] |= ((r[1] >> 8) & 0x0000FF00L);
272                        memcpy(output_value, r, 4);
273
274                } else {
275
276                        memcpy(output_value, &r[1], 4);
277
278                }
279#endif
280        }
281
282}
283