VirtualBox

source: vbox/trunk/src/libs/softfloat-3e/source/s_roundPackMToExtF80M.c@ 94480

最後變更 在這個檔案從94480是 94480,由 vboxsync 提交於 3 年 前

libs/softfloat-3e: Copied from vendor branch (SoftFloat-3e.zip, md5: 7dac954ea4aed0697cbfee800ba4f492). bugref:9898

  • 屬性 svn:eol-style 設為 native
檔案大小: 9.9 KB
 
1
2/*============================================================================
3
4This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
5Package, Release 3e, by John R. Hauser.
6
7Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of
8California. All rights reserved.
9
10Redistribution and use in source and binary forms, with or without
11modification, are permitted provided that the following conditions are met:
12
13 1. Redistributions of source code must retain the above copyright notice,
14 this list of conditions, and the following disclaimer.
15
16 2. Redistributions in binary form must reproduce the above copyright notice,
17 this list of conditions, and the following disclaimer in the documentation
18 and/or other materials provided with the distribution.
19
20 3. Neither the name of the University nor the names of its contributors may
21 be used to endorse or promote products derived from this software without
22 specific prior written permission.
23
24THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
25EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
27DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
28DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
35=============================================================================*/
36
37#include <stdbool.h>
38#include <stdint.h>
39#include "platform.h"
40#include "internals.h"
41#include "softfloat.h"
42
43void
44 softfloat_roundPackMToExtF80M(
45 bool sign,
46 int32_t exp,
47 uint32_t *extSigPtr,
48 uint_fast8_t roundingPrecision,
49 struct extFloat80M *zSPtr
50 )
51{
52 uint_fast8_t roundingMode;
53 bool roundNearEven;
54 uint64_t sig, roundIncrement, roundMask, roundBits;
55 bool isTiny;
56 uint32_t sigExtra;
57 bool doIncrement;
58
59 /*------------------------------------------------------------------------
60 *------------------------------------------------------------------------*/
61 roundingMode = softfloat_roundingMode;
62 roundNearEven = (roundingMode == softfloat_round_near_even);
63 sig =
64 (uint64_t) extSigPtr[indexWord( 3, 2 )]<<32
65 | extSigPtr[indexWord( 3, 1 )];
66 if ( roundingPrecision == 80 ) goto precision80;
67 if ( roundingPrecision == 64 ) {
68 roundIncrement = UINT64_C( 0x0000000000000400 );
69 roundMask = UINT64_C( 0x00000000000007FF );
70 } else if ( roundingPrecision == 32 ) {
71 roundIncrement = UINT64_C( 0x0000008000000000 );
72 roundMask = UINT64_C( 0x000000FFFFFFFFFF );
73 } else {
74 goto precision80;
75 }
76 /*------------------------------------------------------------------------
77 *------------------------------------------------------------------------*/
78 if ( extSigPtr[indexWordLo( 3 )] ) sig |= 1;
79 if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) {
80 roundIncrement =
81 (roundingMode
82 == (sign ? softfloat_round_min : softfloat_round_max))
83 ? roundMask
84 : 0;
85 }
86 roundBits = sig & roundMask;
87 /*------------------------------------------------------------------------
88 *------------------------------------------------------------------------*/
89 if ( 0x7FFD <= (uint32_t) (exp - 1) ) {
90 if ( exp <= 0 ) {
91 /*----------------------------------------------------------------
92 *----------------------------------------------------------------*/
93 isTiny =
94 (softfloat_detectTininess
95 == softfloat_tininess_beforeRounding)
96 || (exp < 0)
97 || (sig <= (uint64_t) (sig + roundIncrement));
98 sig = softfloat_shiftRightJam64( sig, 1 - exp );
99 roundBits = sig & roundMask;
100 if ( roundBits ) {
101 if ( isTiny ) softfloat_raiseFlags( softfloat_flag_underflow );
102 softfloat_exceptionFlags |= softfloat_flag_inexact;
103#ifdef SOFTFLOAT_ROUND_ODD
104 if ( roundingMode == softfloat_round_odd ) {
105 sig |= roundMask + 1;
106 }
107#endif
108 }
109 sig += roundIncrement;
110 exp = ((sig & UINT64_C( 0x8000000000000000 )) != 0);
111 roundIncrement = roundMask + 1;
112 if ( roundNearEven && (roundBits<<1 == roundIncrement) ) {
113 roundMask |= roundIncrement;
114 }
115 sig &= ~roundMask;
116 goto packReturn;
117 }
118 if (
119 (0x7FFE < exp)
120 || ((exp == 0x7FFE) && ((uint64_t) (sig + roundIncrement) < sig))
121 ) {
122 goto overflow;
123 }
124 }
125 /*------------------------------------------------------------------------
126 *------------------------------------------------------------------------*/
127 if ( roundBits ) {
128 softfloat_exceptionFlags |= softfloat_flag_inexact;
129#ifdef SOFTFLOAT_ROUND_ODD
130 if ( roundingMode == softfloat_round_odd ) {
131 sig = (sig & ~roundMask) | (roundMask + 1);
132 goto packReturn;
133 }
134#endif
135 }
136 sig += roundIncrement;
137 if ( sig < roundIncrement ) {
138 ++exp;
139 sig = UINT64_C( 0x8000000000000000 );
140 }
141 roundIncrement = roundMask + 1;
142 if ( roundNearEven && (roundBits<<1 == roundIncrement) ) {
143 roundMask |= roundIncrement;
144 }
145 sig &= ~roundMask;
146 goto packReturn;
147 /*------------------------------------------------------------------------
148 *------------------------------------------------------------------------*/
149 precision80:
150 sigExtra = extSigPtr[indexWordLo( 3 )];
151 doIncrement = (0x80000000 <= sigExtra);
152 if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) {
153 doIncrement =
154 (roundingMode
155 == (sign ? softfloat_round_min : softfloat_round_max))
156 && sigExtra;
157 }
158 /*------------------------------------------------------------------------
159 *------------------------------------------------------------------------*/
160 if ( 0x7FFD <= (uint32_t) (exp - 1) ) {
161 if ( exp <= 0 ) {
162 /*----------------------------------------------------------------
163 *----------------------------------------------------------------*/
164 isTiny =
165 (softfloat_detectTininess
166 == softfloat_tininess_beforeRounding)
167 || (exp < 0)
168 || ! doIncrement
169 || (sig < UINT64_C( 0xFFFFFFFFFFFFFFFF ));
170 softfloat_shiftRightJam96M( extSigPtr, 1 - exp, extSigPtr );
171 exp = 0;
172 sig =
173 (uint64_t) extSigPtr[indexWord( 3, 2 )]<<32
174 | extSigPtr[indexWord( 3, 1 )];
175 sigExtra = extSigPtr[indexWordLo( 3 )];
176 if ( sigExtra ) {
177 if ( isTiny ) softfloat_raiseFlags( softfloat_flag_underflow );
178 softfloat_exceptionFlags |= softfloat_flag_inexact;
179#ifdef SOFTFLOAT_ROUND_ODD
180 if ( roundingMode == softfloat_round_odd ) {
181 sig |= 1;
182 goto packReturn;
183 }
184#endif
185 }
186 doIncrement = (0x80000000 <= sigExtra);
187 if (
188 ! roundNearEven
189 && (roundingMode != softfloat_round_near_maxMag)
190 ) {
191 doIncrement =
192 (roundingMode
193 == (sign ? softfloat_round_min : softfloat_round_max))
194 && sigExtra;
195 }
196 if ( doIncrement ) {
197 ++sig;
198 sig &= ~(uint64_t) (! (sigExtra & 0x7FFFFFFF) & roundNearEven);
199 exp = ((sig & UINT64_C( 0x8000000000000000 )) != 0);
200 }
201 goto packReturn;
202 }
203 if (
204 (0x7FFE < exp)
205 || ((exp == 0x7FFE) && (sig == UINT64_C( 0xFFFFFFFFFFFFFFFF ))
206 && doIncrement)
207 ) {
208 /*----------------------------------------------------------------
209 *----------------------------------------------------------------*/
210 roundMask = 0;
211 overflow:
212 softfloat_raiseFlags(
213 softfloat_flag_overflow | softfloat_flag_inexact );
214 if (
215 roundNearEven
216 || (roundingMode == softfloat_round_near_maxMag)
217 || (roundingMode
218 == (sign ? softfloat_round_min : softfloat_round_max))
219 ) {
220 exp = 0x7FFF;
221 sig = UINT64_C( 0x8000000000000000 );
222 } else {
223 exp = 0x7FFE;
224 sig = ~roundMask;
225 }
226 goto packReturn;
227 }
228 }
229 /*------------------------------------------------------------------------
230 *------------------------------------------------------------------------*/
231 if ( sigExtra ) {
232 softfloat_exceptionFlags |= softfloat_flag_inexact;
233#ifdef SOFTFLOAT_ROUND_ODD
234 if ( roundingMode == softfloat_round_odd ) {
235 sig |= 1;
236 goto packReturn;
237 }
238#endif
239 }
240 if ( doIncrement ) {
241 ++sig;
242 if ( ! sig ) {
243 ++exp;
244 sig = UINT64_C( 0x8000000000000000 );
245 } else {
246 sig &= ~(uint64_t) (! (sigExtra & 0x7FFFFFFF) & roundNearEven);
247 }
248 }
249 /*------------------------------------------------------------------------
250 *------------------------------------------------------------------------*/
251 packReturn:
252 zSPtr->signExp = packToExtF80UI64( sign, exp );
253 zSPtr->signif = sig;
254
255}
256
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette