Handle (do not ignore) SwapPixelBytes flag of 15/16
[tangerine.git] / rom / mathieeesingbas / ieeespmul.c
blob7d1d8a7f6445fe61d0457230329128bda99e1e90
1 /*
2 Copyright © 1995-2004, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include "mathieeesingbas_intern.h"
8 /*
9 FUNCTION
10 Multiply two IEEE single precision numbers
11 res = y * z;
13 RESULT
15 Flags:
16 zero : result is zero
17 negative : result is negative
18 overflow : result is out of range
20 NOTES
22 EXAMPLE
24 BUGS
26 SEE ALSO
28 INTERNALS
30 HISTORY
33 AROS_LH2(float, IEEESPMul,
34 AROS_LHA(float, y, D0),
35 AROS_LHA(float, z, D1),
36 struct LibHeader *, MathIeeeSingBasBase, 13, Mathieeesingbas
39 AROS_LIBFUNC_INIT
41 ULONG Mant1H = ((y & 0x00fff000) >> 12 ) | 0x00000800;
42 ULONG Mant2H = ((z & 0x00fff000) >> 12 ) | 0x00000800;
43 ULONG Mant1L = y & 0x00000fff;
44 ULONG Mant2L = z & 0x00000fff;
45 LONG Res;
46 LONG Exponent = ((( y & IEEESPExponent_Mask))
47 + (( z & IEEESPExponent_Mask)) - 0x3f800000 );
49 if (0 == y || 0 == z)
51 SetSR(Zero_Bit, Zero_Bit | Negative_Bit | Overflow_Bit);
52 return ((y & IEEESPSign_Mask) ^ (z & IEEESPSign_Mask) );
55 Res = (Mant1H * Mant2H) << 8;
56 Res += ((Mant1H * Mant2L) >> 4);
57 Res += ((Mant1L * Mant2H) >> 4);
58 Res += ((Mant1L * Mant2L) >> 16);
60 /* Bit 32 is not set */
61 if ((LONG)Res > 0) Res += Res;
62 else Exponent += 0x00800000;
64 /* Correction for precision */
65 if ((char) Res < 0) Res += 0x100;
67 Res >>= 8;
68 Res &= IEEESPMantisse_Mask;
70 Res |= ((y & IEEESPSign_Mask) ^ (z & IEEESPSign_Mask) );
72 if ( Exponent < 0)
74 SetSR(Overflow_Bit, Zero_Bit | Negative_Bit | Overflow_Bit);
75 return (0x7f800000 | (Res & IEEESPSign_Mask) );
78 Res |= Exponent;
80 if ( Res < 0) SetSR(Negative_Bit, Zero_Bit | Negative_Bit | Overflow_Bit);
82 return Res;
84 AROS_LIBFUNC_EXIT