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**      pkibml.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 IBM long 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 IBM long floating number
108**  with those bits.
109**
110**  See the header files for a description of the UNPACKED_REAL
111**  structure.
112**
113**  A normalized IBM long floating number looks like:
114**
115**      [0]: Sign bit, 7 exp bits (bias 64), 24 fraction bits
116**      [1]: 32 low order fraction bits
117**
118**      0.0625 <= fraction < 1.0, from 0 to 3 leading zeros
119**      to compensate for the hexadecimal exponent.
120**
121**
122**  Implicit parameters:
123**
124**      options: a word of flags, see include files.
125**
126**      output_value: a pointer to the input parameter.
127**
128**      r: an UNPACKED_REAL structure.
129**
130**      i: temporary integer variable
131**
132**      j: temporary integer variable
133**
134**--
135*/
136
137if (r[U_R_FLAGS] & U_R_UNUSUAL) {
138
139        if (r[U_R_FLAGS] & U_R_ZERO)
140
141                if (r[U_R_FLAGS] & U_R_NEGATIVE)
142                        memcpy(output_value, IBM_L_NEG_ZERO, 8);
143                else
144                        memcpy(output_value, IBM_L_POS_ZERO, 8);
145
146        else if (r[U_R_FLAGS] & U_R_INFINITY) {
147
148                if (r[U_R_FLAGS] & U_R_NEGATIVE)
149                        memcpy(output_value, IBM_L_NEG_INFINITY, 8);
150                else
151                        memcpy(output_value, IBM_L_POS_INFINITY, 8);
152
153        } else if (r[U_R_FLAGS] & U_R_INVALID) {
154
155                memcpy(output_value, IBM_L_INVALID, 8);
156                DCETHREAD_RAISE(dcethread_aritherr_e);    /* Invalid value */
157
158        }
159
160} else {
161
162        /* Precision varies because binary exp must be multiple of 4 */
163        /* (since we must convert it to a hexadecimal exponent). */
164        /* So, figure out where to round (53 <= i <= 56). */
165
166        i = (r[U_R_EXP] & 0x00000003L);
167        if (i)
168                round_bit_position = i + 52;
169        else
170                round_bit_position = 56;
171
172#include "round.c.h"
173
174        if (r[U_R_EXP] < (U_R_BIAS - 255)) {
175
176                /* Underflow */
177
178                if (r[U_R_FLAGS] & U_R_NEGATIVE)
179                        memcpy(output_value, IBM_L_NEG_ZERO, 8);
180                else
181                        memcpy(output_value, IBM_L_POS_ZERO, 8);
182                if (options & CVT_C_ERR_UNDERFLOW) {
183                        DCETHREAD_RAISE(dcethread_fltund_e);  /* Underflow */
184                }
185
186        } else if (r[U_R_EXP] > (U_R_BIAS + 252)) {
187
188                /* Overflow */
189
190                if (options & CVT_C_TRUNCATE) {
191
192                        if (r[U_R_FLAGS] & U_R_NEGATIVE)
193                                memcpy(output_value, IBM_L_NEG_HUGE, 8);
194                        else
195                                memcpy(output_value, IBM_L_POS_HUGE, 8);
196
197                } else if ((options & CVT_C_ROUND_TO_POS)
198                                        && (r[U_R_FLAGS] & U_R_NEGATIVE)) {
199
200                                memcpy(output_value, IBM_L_NEG_HUGE, 8);
201
202                } else if ((options & CVT_C_ROUND_TO_NEG)
203                                        && !(r[U_R_FLAGS] & U_R_NEGATIVE)) {
204
205                                memcpy(output_value, IBM_L_POS_HUGE, 8);
206
207                } else {
208
209                        if (r[U_R_FLAGS] & U_R_NEGATIVE)
210                                memcpy(output_value, IBM_L_NEG_INFINITY, 8);
211                        else
212                                memcpy(output_value, IBM_L_POS_INFINITY, 8);
213
214                }
215
216                DCETHREAD_RAISE(dcethread_fltovf_e);  /* Overflow */
217
218        } else {
219
220                /* Figure leading zeros (i) and biased exponent (j) */
221
222                i = (r[U_R_EXP] & 0x00000003L);
223                j = ((int)(r[U_R_EXP] - U_R_BIAS) / 4) + 64;
224
225                if (i) {
226                        if (r[U_R_EXP] > U_R_BIAS)
227                                j += 1;
228                        i = 12 - i;
229                } else {
230                        i = 8;
231                }
232
233                /* Make room for exponent and sign bit */
234
235                r[2] >>= i;
236                r[2] |= (r[1] << (32 - i));
237                r[1] >>= i;
238
239                /* OR in exponent and sign bit */
240
241                r[1] |= (j << 24);
242                r[1] |= (r[U_R_FLAGS] << 31);
243
244#if (NDR_LOCAL_INT_REP == ndr_c_int_big_endian)
245
246                memcpy(output_value, &r[1], 8);
247
248#else
249                /* Shuffle bytes to big endian format */
250
251                r[0]  = ((r[1] << 24) | (r[1] >> 24));
252                r[0] |= ((r[1] << 8) & 0x00FF0000L);
253                r[0] |= ((r[1] >> 8) & 0x0000FF00L);
254                r[1]  = ((r[2] << 24) | (r[2] >> 24));
255                r[1] |= ((r[2] << 8) & 0x00FF0000L);
256                r[1] |= ((r[2] >> 8) & 0x0000FF00L);
257
258                memcpy(output_value, r, 8);
259#endif
260        }
261
262}
263