added concrete implementations of putc(), getc(), getchar() and gets()
[tangerine.git] / workbench / libs / mathieeedoubbas / ieeedpadd.c
blobf41befb1a5c4ceeeb914d286de14f34ea46cc68f
1 /*
2 Copyright © 1995-2003, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include "mathieeedoubbas_intern.h"
8 /*
9 FUNCTION
10 Calculate the sum of two IEEE double precision numbers
12 RESULT
13 sum of y and z
15 Flags:
16 zero : result is zero
17 negative : result is negative
18 overflow : result is too large or too small for ffp format
20 NOTES
22 EXAMPLE
24 BUGS
26 SEE ALSO
28 INTERNALS
30 HISTORY
33 AROS_LHQUAD2(double, IEEEDPAdd,
34 AROS_LHAQUAD(double, y, D0, D1),
35 AROS_LHAQUAD(double, z, D2, D3),
36 struct MathIeeeDoubBasBase *, MathIeeeDoubBasBase, 11, MathIeeeDoubBas
39 AROS_LIBFUNC_INIT
41 QUAD Res;
42 QUAD Mant1, Mant2;
43 QUAD Qtmp1, Qtmp2;
44 LONG Shift;
45 QUAD Exponent;
46 LONG Ltmp1, Ltmp2;
47 QUAD * Qy = (QUAD *)&y;
48 QUAD * Qz = (QUAD *)&z;
49 double * DRes = (double *)&Res;
51 SetSR(0, Zero_Bit | Overflow_Bit | Negative_Bit );
53 AND64C(Qtmp1, *Qy, IEEEDPExponent_Mask_Hi, IEEEDPExponent_Mask_Lo);
54 AND64C(Qtmp2, *Qz, IEEEDPExponent_Mask_Hi, IEEEDPExponent_Mask_Lo);
55 SHRU32(Ltmp1, Qtmp1, 52);
56 SHRU32(Ltmp2, Qtmp2, 52);
57 Shift = Ltmp1 - Ltmp2;
61 is_neqC(*Qy, 0x0, 0x0)
62 && is_neqC(*Qy, IEEEDPSign_Mask_Hi, IEEEDPSign_Mask_Lo)
65 AND64C(Mant1, *Qy, IEEEDPMantisse_Mask_Hi, IEEEDPMantisse_Mask_Lo);
66 OR64QC(Mant1, 0x00100000, 0x00000000);
68 else
70 Set_Value64C(Mant1, 0x0, 0x0);
75 is_neqC(*Qz, 0x0, 0x0)
76 && is_neqC(*Qz, IEEEDPSign_Mask_Hi, IEEEDPSign_Mask_Lo)
79 /* Mant2 = (*Qz & IEEESPMantisse_Mask) | 0x00800000; */
80 AND64C(Mant2, *Qz, IEEEDPMantisse_Mask_Hi, IEEEDPMantisse_Mask_Lo);
81 OR64QC(Mant2, 0x00100000, 0x00000000);
83 else
85 Set_Value64C(Mant2, 0x0, 0x0);
88 if (Shift > 0)
90 SHRU64(Mant2, Mant2, Shift);
91 AND64C(Exponent, *Qy, IEEEDPExponent_Mask_Hi, IEEEDPExponent_Mask_Lo);
93 else
95 SHRU64(Mant1, Mant1, (-Shift));
96 AND64C(Exponent, *Qz, IEEEDPExponent_Mask_Hi, IEEEDPExponent_Mask_Lo);
99 // sign(fnum1) == sign(fnum2)
100 // simple addition
101 // 0.25 <= res < 1
102 AND64C(Qtmp1, *Qz, IEEEDPSign_Mask_Hi, IEEEDPSign_Mask_Lo);
103 AND64C(Qtmp2, *Qy, IEEEDPSign_Mask_Hi, IEEEDPSign_Mask_Lo);
104 if ( is_eq(Qtmp1, Qtmp2))
106 AND64C(Res, *Qy, IEEEDPSign_Mask_Hi, IEEEDPSign_Mask_Lo);
107 ADD64Q(Mant1, Mant2);
108 AND64C(Qtmp1, Mant1, 0x00200000, 0x0);
109 if ( is_neqC(Qtmp1, 0x0, 0x0))
111 ADD64QC(Exponent, 0x00100000, 0x0);
112 SHRU64(Mant1, Mant1, 1);
114 AND64QC(Mant1, IEEEDPMantisse_Mask_Hi, IEEEDPMantisse_Mask_Lo);
116 // second case: sign(fnum1) != sign(fnum2)
117 // -1 <= res < 1
118 else
120 //printf("Exponent: %x\n",Exponent);
121 if ( is_lessSC(*Qy, 0x0, 0x0))
123 SUB64(Mant1, Mant2, Mant1);
125 else // fnum2 < 0
127 SUB64(Mant1, Mant1, Mant2);
130 //if the result is below zero
131 if ( is_lessSC(Mant1, 0x0, 0x0))
133 Set_Value64C(Res, IEEEDPSign_Mask_Hi, IEEEDPSign_Mask_Lo);
134 NEG64(Mant1);
135 SetSR(Negative_Bit, Zero_Bit | Negative_Bit | Overflow_Bit);
137 else
139 Set_Value64C(Res, 0x0, 0x0);
142 if (is_eqC(Mant1, 0x0, 0x0))
144 SetSR(Zero_Bit, Zero_Bit | Negative_Bit | Overflow_Bit);
145 Set_Value64C(Res, 0x0, 0x0);
146 return *(double *)&Res;
148 else
150 /* normalize the mantisse */
151 AND64C(Qtmp1, Mant1, 0x00100000, 0x0);
152 while ( is_eqC(Qtmp1, 0x0, 0x0))
154 SHL64(Mant1, Mant1, 1); //one bit to the left.
155 SUB64QC(Exponent, 0x00100000, 0x0);
156 AND64C(Qtmp1, Mant1, 0x00100000, 0x0);
158 AND64QC(Mant1, IEEEDPMantisse_Mask_Hi, IEEEDPMantisse_Mask_Lo);
159 } /* else */
161 } /* else */
163 if ( is_lessSC(Exponent, 0x0, 0x0))
165 SetSR(Overflow_Bit, Zero_Bit | Overflow_Bit); //do not change Negative_Bit!
166 OR64QC
168 Res,
169 (IEEEDPMantisse_Mask_Hi | IEEEDPExponent_Mask_Hi),
170 (IEEEDPMantisse_Mask_Lo | IEEEDPExponent_Mask_Lo)
173 OR64Q(Res, Mant1);
174 OR64Q(Res, Exponent);
176 return *DRes;
178 AROS_LIBFUNC_EXIT