revert between 56095 -> 55830 in arch
[AROS.git] / workbench / libs / mathieeesingbas / ieeespmul.c
blob52afb197d7ec2e17da2a87ab244b350d014799c3
1 /*
2 Copyright © 1995-2004, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include "mathieeesingbas_intern.h"
8 /*****************************************************************************
10 NAME */
12 AROS_LH2(float, IEEESPMul,
14 /* SYNOPSIS */
15 AROS_LHA(float, y, D0),
16 AROS_LHA(float, z, D1),
18 /* LOCATION */
19 struct LibHeader *, MathIeeeSingBasBase, 13, Mathieeesingbas)
21 /* FUNCTION
22 Multiply two IEEE single precision numbers
23 res = y * z;
25 INPUTS
27 RESULT
28 Flags:
29 zero : result is zero
30 negative : result is negative
31 overflow : result is out of range
33 BUGS
35 INTERNALS
37 *****************************************************************************/
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