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