VirtualBox

source: vbox/trunk/src/libs/softfloat-3e/source/s_mulAddF128M.c@ 94552

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

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

  • 屬性 svn:eol-style 設為 native
檔案大小: 14.6 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, 2016 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 "specialize.h"
42#include "softfloat.h"
43
44void
45 softfloat_mulAddF128M(
46 const uint32_t *aWPtr,
47 const uint32_t *bWPtr,
48 const uint32_t *cWPtr,
49 uint32_t *zWPtr,
50 uint_fast8_t op
51 )
52{
53 uint32_t uiA96;
54 int32_t expA;
55 uint32_t uiB96;
56 int32_t expB;
57 uint32_t uiC96;
58 bool signC;
59 int32_t expC;
60 bool signProd, prodIsInfinite;
61 uint32_t *ptr, uiZ96, sigA[4];
62 uint_fast8_t shiftDist;
63 uint32_t sigX[5];
64 int32_t expProd;
65 uint32_t sigProd[8], wordSig;
66 bool doSub;
67 uint_fast8_t
68 (*addCarryMRoutinePtr)(
69 uint_fast8_t,
70 const uint32_t *,
71 const uint32_t *,
72 uint_fast8_t,
73 uint32_t *
74 );
75 int32_t expDiff;
76 bool signZ;
77 int32_t expZ;
78 uint32_t *extSigPtr;
79 uint_fast8_t carry;
80 void (*roundPackRoutinePtr)( bool, int32_t, uint32_t *, uint32_t * );
81
82 /*------------------------------------------------------------------------
83 *------------------------------------------------------------------------*/
84 uiA96 = aWPtr[indexWordHi( 4 )];
85 expA = expF128UI96( uiA96 );
86 uiB96 = bWPtr[indexWordHi( 4 )];
87 expB = expF128UI96( uiB96 );
88 uiC96 = cWPtr[indexWordHi( 4 )];
89 signC = signF128UI96( uiC96 ) ^ (op == softfloat_mulAdd_subC);
90 expC = expF128UI96( uiC96 );
91 signProd =
92 signF128UI96( uiA96 ) ^ signF128UI96( uiB96 )
93 ^ (op == softfloat_mulAdd_subProd);
94 /*------------------------------------------------------------------------
95 *------------------------------------------------------------------------*/
96 prodIsInfinite = false;
97 if ( (expA == 0x7FFF) || (expB == 0x7FFF) ) {
98 if ( softfloat_tryPropagateNaNF128M( aWPtr, bWPtr, zWPtr ) ) {
99 goto propagateNaN_ZC;
100 }
101 ptr = (uint32_t *) aWPtr;
102 if ( ! (uint32_t) (uiA96<<1) ) goto possibleInvalidProd;
103 if ( ! (uint32_t) (uiB96<<1) ) {
104 ptr = (uint32_t *) bWPtr;
105 possibleInvalidProd:
106 if (
107 ! (ptr[indexWord( 4, 2 )] | ptr[indexWord( 4, 1 )]
108 | ptr[indexWord( 4, 0 )])
109 ) {
110 goto invalid;
111 }
112 }
113 prodIsInfinite = true;
114 }
115 if ( expC == 0x7FFF ) {
116 if (
117 fracF128UI96( uiC96 )
118 || (cWPtr[indexWord( 4, 2 )] | cWPtr[indexWord( 4, 1 )]
119 | cWPtr[indexWord( 4, 0 )])
120 ) {
121 zWPtr[indexWordHi( 4 )] = 0;
122 goto propagateNaN_ZC;
123 }
124 if ( prodIsInfinite && (signProd != signC) ) goto invalid;
125 goto copyC;
126 }
127 if ( prodIsInfinite ) {
128 uiZ96 = packToF128UI96( signProd, 0x7FFF, 0 );
129 goto uiZ;
130 }
131 /*------------------------------------------------------------------------
132 *------------------------------------------------------------------------*/
133 if ( expA ) {
134 sigA[indexWordHi( 4 )] = fracF128UI96( uiA96 ) | 0x00010000;
135 sigA[indexWord( 4, 2 )] = aWPtr[indexWord( 4, 2 )];
136 sigA[indexWord( 4, 1 )] = aWPtr[indexWord( 4, 1 )];
137 sigA[indexWord( 4, 0 )] = aWPtr[indexWord( 4, 0 )];
138 } else {
139 expA = softfloat_shiftNormSigF128M( aWPtr, 0, sigA );
140 if ( expA == -128 ) goto zeroProd;
141 }
142 if ( expB ) {
143 sigX[indexWordHi( 4 )] = fracF128UI96( uiB96 ) | 0x00010000;
144 sigX[indexWord( 4, 2 )] = bWPtr[indexWord( 4, 2 )];
145 sigX[indexWord( 4, 1 )] = bWPtr[indexWord( 4, 1 )];
146 sigX[indexWord( 4, 0 )] = bWPtr[indexWord( 4, 0 )];
147 } else {
148 expB = softfloat_shiftNormSigF128M( bWPtr, 0, sigX );
149 if ( expB == -128 ) goto zeroProd;
150 }
151 /*------------------------------------------------------------------------
152 *------------------------------------------------------------------------*/
153 expProd = expA + expB - 0x3FF0;
154 softfloat_mul128MTo256M( sigA, sigX, sigProd );
155 /*------------------------------------------------------------------------
156 *------------------------------------------------------------------------*/
157 wordSig = fracF128UI96( uiC96 );
158 if ( expC ) {
159 --expC;
160 wordSig |= 0x00010000;
161 }
162 sigX[indexWordHi( 5 )] = wordSig;
163 sigX[indexWord( 5, 3 )] = cWPtr[indexWord( 4, 2 )];
164 sigX[indexWord( 5, 2 )] = cWPtr[indexWord( 4, 1 )];
165 sigX[indexWord( 5, 1 )] = cWPtr[indexWord( 4, 0 )];
166 /*------------------------------------------------------------------------
167 *------------------------------------------------------------------------*/
168 doSub = (signProd != signC);
169 addCarryMRoutinePtr =
170 doSub ? softfloat_addComplCarryM : softfloat_addCarryM;
171 expDiff = expProd - expC;
172 if ( expDiff <= 0 ) {
173 /*--------------------------------------------------------------------
174 *--------------------------------------------------------------------*/
175 signZ = signC;
176 expZ = expC;
177 if (
178 sigProd[indexWord( 8, 2 )]
179 || (sigProd[indexWord( 8, 1 )] | sigProd[indexWord( 8, 0 )])
180 ) {
181 sigProd[indexWord( 8, 3 )] |= 1;
182 }
183 extSigPtr = &sigProd[indexMultiwordHi( 8, 5 )];
184 if ( expDiff ) {
185 softfloat_shiftRightJam160M( extSigPtr, -expDiff, extSigPtr );
186 }
187 carry = 0;
188 if ( doSub ) {
189 wordSig = extSigPtr[indexWordLo( 5 )];
190 extSigPtr[indexWordLo( 5 )] = -wordSig;
191 carry = ! wordSig;
192 }
193 (*addCarryMRoutinePtr)(
194 4,
195 &sigX[indexMultiwordHi( 5, 4 )],
196 extSigPtr + indexMultiwordHi( 5, 4 ),
197 carry,
198 extSigPtr + indexMultiwordHi( 5, 4 )
199 );
200 wordSig = extSigPtr[indexWordHi( 5 )];
201 if ( ! expZ ) {
202 if ( wordSig & 0x80000000 ) {
203 signZ = ! signZ;
204 softfloat_negX160M( extSigPtr );
205 wordSig = extSigPtr[indexWordHi( 5 )];
206 }
207 goto checkCancellation;
208 }
209 if ( wordSig < 0x00010000 ) {
210 --expZ;
211 softfloat_add160M( extSigPtr, extSigPtr, extSigPtr );
212 goto roundPack;
213 }
214 goto extSigReady_noCancellation;
215 } else {
216 /*--------------------------------------------------------------------
217 *--------------------------------------------------------------------*/
218 signZ = signProd;
219 expZ = expProd;
220 sigX[indexWordLo( 5 )] = 0;
221 expDiff -= 128;
222 if ( 0 <= expDiff ) {
223 /*----------------------------------------------------------------
224 *----------------------------------------------------------------*/
225 if ( expDiff ) softfloat_shiftRightJam160M( sigX, expDiff, sigX );
226 wordSig = sigX[indexWordLo( 5 )];
227 carry = 0;
228 if ( doSub ) {
229 carry = ! wordSig;
230 wordSig = -wordSig;
231 }
232 carry =
233 (*addCarryMRoutinePtr)(
234 4,
235 &sigProd[indexMultiwordLo( 8, 4 )],
236 &sigX[indexMultiwordHi( 5, 4 )],
237 carry,
238 &sigProd[indexMultiwordLo( 8, 4 )]
239 );
240 sigProd[indexWord( 8, 2 )] |= wordSig;
241 ptr = &sigProd[indexWord( 8, 4 )];
242 } else {
243 /*----------------------------------------------------------------
244 *----------------------------------------------------------------*/
245 shiftDist = expDiff & 31;
246 if ( shiftDist ) {
247 softfloat_shortShiftRight160M( sigX, shiftDist, sigX );
248 }
249 expDiff >>= 5;
250 extSigPtr =
251 &sigProd[indexMultiwordLo( 8, 5 )] - wordIncr
252 + expDiff * -wordIncr;
253 carry =
254 (*addCarryMRoutinePtr)( 5, extSigPtr, sigX, doSub, extSigPtr );
255 if ( expDiff == -4 ) {
256 /*------------------------------------------------------------
257 *------------------------------------------------------------*/
258 wordSig = sigProd[indexWordHi( 8 )];
259 if ( wordSig & 0x80000000 ) {
260 signZ = ! signZ;
261 softfloat_negX256M( sigProd );
262 wordSig = sigProd[indexWordHi( 8 )];
263 }
264 /*------------------------------------------------------------
265 *------------------------------------------------------------*/
266 if ( wordSig ) goto expProdBigger_noWordShift;
267 wordSig = sigProd[indexWord( 8, 6 )];
268 if ( 0x00040000 <= wordSig ) goto expProdBigger_noWordShift;
269 expZ -= 32;
270 extSigPtr = &sigProd[indexMultiwordHi( 8, 5 )] - wordIncr;
271 for (;;) {
272 if ( wordSig ) break;
273 wordSig = extSigPtr[indexWord( 5, 3 )];
274 if ( 0x00040000 <= wordSig ) break;
275 expZ -= 32;
276 extSigPtr -= wordIncr;
277 if ( extSigPtr == &sigProd[indexMultiwordLo( 8, 5 )] ) {
278 goto checkCancellation;
279 }
280 }
281 /*------------------------------------------------------------
282 *------------------------------------------------------------*/
283 ptr = extSigPtr + indexWordLo( 5 );
284 do {
285 ptr -= wordIncr;
286 if ( *ptr ) {
287 extSigPtr[indexWordLo( 5 )] |= 1;
288 break;
289 }
290 } while ( ptr != &sigProd[indexWordLo( 8 )] );
291 wordSig = extSigPtr[indexWordHi( 5 )];
292 goto extSigReady;
293 }
294 ptr = extSigPtr + indexWordHi( 5 ) + wordIncr;
295 }
296 /*--------------------------------------------------------------------
297 *--------------------------------------------------------------------*/
298 if ( carry != doSub ) {
299 if ( doSub ) {
300 do {
301 wordSig = *ptr;
302 *ptr = wordSig - 1;
303 ptr += wordIncr;
304 } while ( ! wordSig );
305 } else {
306 do {
307 wordSig = *ptr + 1;
308 *ptr = wordSig;
309 ptr += wordIncr;
310 } while ( ! wordSig );
311 }
312 }
313 /*--------------------------------------------------------------------
314 *--------------------------------------------------------------------*/
315 expProdBigger_noWordShift:
316 if (
317 sigProd[indexWord( 8, 2 )]
318 || (sigProd[indexWord( 8, 1 )] | sigProd[indexWord( 8, 0 )])
319 ) {
320 sigProd[indexWord( 8, 3 )] |= 1;
321 }
322 extSigPtr = &sigProd[indexMultiwordHi( 8, 5 )];
323 wordSig = extSigPtr[indexWordHi( 5 )];
324 }
325 extSigReady:
326 roundPackRoutinePtr = softfloat_normRoundPackMToF128M;
327 if ( wordSig < 0x00010000 ) goto doRoundPack;
328 extSigReady_noCancellation:
329 if ( 0x00020000 <= wordSig ) {
330 ++expZ;
331 softfloat_shortShiftRightJam160M( extSigPtr, 1, extSigPtr );
332 }
333 roundPack:
334 roundPackRoutinePtr = softfloat_roundPackMToF128M;
335 doRoundPack:
336 (*roundPackRoutinePtr)( signZ, expZ, extSigPtr, zWPtr );
337 return;
338 /*------------------------------------------------------------------------
339 *------------------------------------------------------------------------*/
340 invalid:
341 softfloat_invalidF128M( zWPtr );
342 propagateNaN_ZC:
343 softfloat_propagateNaNF128M( zWPtr, cWPtr, zWPtr );
344 return;
345 /*------------------------------------------------------------------------
346 *------------------------------------------------------------------------*/
347 zeroProd:
348 if (
349 ! (uint32_t) (uiC96<<1) && (signProd != signC)
350 && ! cWPtr[indexWord( 4, 2 )]
351 && ! (cWPtr[indexWord( 4, 1 )] | cWPtr[indexWord( 4, 0 )])
352 ) {
353 goto completeCancellation;
354 }
355 copyC:
356 zWPtr[indexWordHi( 4 )] = uiC96;
357 zWPtr[indexWord( 4, 2 )] = cWPtr[indexWord( 4, 2 )];
358 zWPtr[indexWord( 4, 1 )] = cWPtr[indexWord( 4, 1 )];
359 zWPtr[indexWord( 4, 0 )] = cWPtr[indexWord( 4, 0 )];
360 return;
361 /*------------------------------------------------------------------------
362 *------------------------------------------------------------------------*/
363 checkCancellation:
364 if (
365 wordSig
366 || (extSigPtr[indexWord( 5, 3 )] | extSigPtr[indexWord( 5, 2 )])
367 || (extSigPtr[indexWord( 5, 1 )] | extSigPtr[indexWord( 5, 0 )])
368 ) {
369 goto extSigReady;
370 }
371 completeCancellation:
372 uiZ96 =
373 packToF128UI96(
374 (softfloat_roundingMode == softfloat_round_min), 0, 0 );
375 uiZ:
376 zWPtr[indexWordHi( 4 )] = uiZ96;
377 zWPtr[indexWord( 4, 2 )] = 0;
378 zWPtr[indexWord( 4, 1 )] = 0;
379 zWPtr[indexWord( 4, 0 )] = 0;
380
381}
382
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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