2 Copyright © 1995-2003, The AROS Development Team. All rights reserved.
6 #include "mathieeedoubbas_intern.h"
10 Calculate the sum of two IEEE double precision numbers
17 negative : result is negative
18 overflow : result is too large or too small for ffp format
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
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);
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);
85 Set_Value64C(Mant2
, 0x0, 0x0);
90 SHRU64(Mant2
, Mant2
, Shift
);
91 AND64C(Exponent
, *Qy
, IEEEDPExponent_Mask_Hi
, IEEEDPExponent_Mask_Lo
);
95 SHRU64(Mant1
, Mant1
, (-Shift
));
96 AND64C(Exponent
, *Qz
, IEEEDPExponent_Mask_Hi
, IEEEDPExponent_Mask_Lo
);
99 // sign(fnum1) == sign(fnum2)
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)
120 //printf("Exponent: %x\n",Exponent);
121 if ( is_lessSC(*Qy
, 0x0, 0x0))
123 SUB64(Mant1
, Mant2
, Mant1
);
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
);
135 SetSR(Negative_Bit
, Zero_Bit
| Negative_Bit
| Overflow_Bit
);
139 Set_Value64C(Res
, 0x0, 0x0);
142 if (is_eqC(Mant1
, 0x0, 0x0))
144 union { QUAD i
; double d
; } tmp
;
145 SetSR(Zero_Bit
, Zero_Bit
| Negative_Bit
| Overflow_Bit
);
146 Set_Value64C(Res
, 0x0, 0x0);
152 /* normalize the mantisse */
153 AND64C(Qtmp1
, Mant1
, 0x00100000, 0x0);
154 while ( is_eqC(Qtmp1
, 0x0, 0x0))
156 SHL64(Mant1
, Mant1
, 1); //one bit to the left.
157 SUB64QC(Exponent
, 0x00100000, 0x0);
158 AND64C(Qtmp1
, Mant1
, 0x00100000, 0x0);
160 AND64QC(Mant1
, IEEEDPMantisse_Mask_Hi
, IEEEDPMantisse_Mask_Lo
);
165 if ( is_lessSC(Exponent
, 0x0, 0x0))
167 SetSR(Overflow_Bit
, Zero_Bit
| Overflow_Bit
); //do not change Negative_Bit!
171 (IEEEDPMantisse_Mask_Hi
| IEEEDPExponent_Mask_Hi
),
172 (IEEEDPMantisse_Mask_Lo
| IEEEDPExponent_Mask_Lo
)
176 OR64Q(Res
, Exponent
);