2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
6 #include "mathieeedoubbas_intern.h"
8 /*****************************************************************************
12 AROS_LHQUAD2(double, IEEEDPAdd
,
15 AROS_LHAQUAD(double, y
, D0
, D1
),
16 AROS_LHAQUAD(double, z
, D2
, D3
),
19 struct MathIeeeDoubBasBase
*, MathIeeeDoubBasBase
, 11, MathIeeeDoubBas
)
22 Calculate the sum of two IEEE double precision numbers.
33 negative : result is negative
34 overflow : result is too large or too small for IEEE DP format
46 *****************************************************************************/
56 QUAD
* Qy
= (QUAD
*)&y
;
57 QUAD
* Qz
= (QUAD
*)&z
;
58 double * DRes
= (double *)&Res
;
60 SetSR(0, Zero_Bit
| Overflow_Bit
| Negative_Bit
);
62 AND64C(Qtmp1
, *Qy
, IEEEDPExponent_Mask_Hi
, IEEEDPExponent_Mask_Lo
);
63 AND64C(Qtmp2
, *Qz
, IEEEDPExponent_Mask_Hi
, IEEEDPExponent_Mask_Lo
);
64 SHRU32(Ltmp1
, Qtmp1
, 52);
65 SHRU32(Ltmp2
, Qtmp2
, 52);
66 Shift
= Ltmp1
- Ltmp2
;
70 is_neqC(*Qy
, 0x0, 0x0)
71 && is_neqC(*Qy
, IEEEDPSign_Mask_Hi
, IEEEDPSign_Mask_Lo
)
74 AND64C(Mant1
, *Qy
, IEEEDPMantisse_Mask_Hi
, IEEEDPMantisse_Mask_Lo
);
75 OR64QC(Mant1
, 0x00100000, 0x00000000);
79 Set_Value64C(Mant1
, 0x0, 0x0);
84 is_neqC(*Qz
, 0x0, 0x0)
85 && is_neqC(*Qz
, IEEEDPSign_Mask_Hi
, IEEEDPSign_Mask_Lo
)
88 /* Mant2 = (*Qz & IEEESPMantisse_Mask) | 0x00800000; */
89 AND64C(Mant2
, *Qz
, IEEEDPMantisse_Mask_Hi
, IEEEDPMantisse_Mask_Lo
);
90 OR64QC(Mant2
, 0x00100000, 0x00000000);
94 Set_Value64C(Mant2
, 0x0, 0x0);
99 SHRU64(Mant2
, Mant2
, Shift
);
100 AND64C(Exponent
, *Qy
, IEEEDPExponent_Mask_Hi
, IEEEDPExponent_Mask_Lo
);
104 SHRU64(Mant1
, Mant1
, (-Shift
));
105 AND64C(Exponent
, *Qz
, IEEEDPExponent_Mask_Hi
, IEEEDPExponent_Mask_Lo
);
108 // sign(fnum1) == sign(fnum2)
111 AND64C(Qtmp1
, *Qz
, IEEEDPSign_Mask_Hi
, IEEEDPSign_Mask_Lo
);
112 AND64C(Qtmp2
, *Qy
, IEEEDPSign_Mask_Hi
, IEEEDPSign_Mask_Lo
);
113 if ( is_eq(Qtmp1
, Qtmp2
))
115 AND64C(Res
, *Qy
, IEEEDPSign_Mask_Hi
, IEEEDPSign_Mask_Lo
);
116 ADD64Q(Mant1
, Mant2
);
117 AND64C(Qtmp1
, Mant1
, 0x00200000, 0x0);
118 if ( is_neqC(Qtmp1
, 0x0, 0x0))
120 ADD64QC(Exponent
, 0x00100000, 0x0);
121 SHRU64(Mant1
, Mant1
, 1);
123 AND64QC(Mant1
, IEEEDPMantisse_Mask_Hi
, IEEEDPMantisse_Mask_Lo
);
125 // second case: sign(fnum1) != sign(fnum2)
129 //printf("Exponent: %x\n",Exponent);
130 if ( is_lessSC(*Qy
, 0x0, 0x0))
132 SUB64(Mant1
, Mant2
, Mant1
);
136 SUB64(Mant1
, Mant1
, Mant2
);
139 //if the result is below zero
140 if ( is_lessSC(Mant1
, 0x0, 0x0))
142 Set_Value64C(Res
, IEEEDPSign_Mask_Hi
, IEEEDPSign_Mask_Lo
);
144 SetSR(Negative_Bit
, Zero_Bit
| Negative_Bit
| Overflow_Bit
);
148 Set_Value64C(Res
, 0x0, 0x0);
151 if (is_eqC(Mant1
, 0x0, 0x0))
153 union { QUAD i
; double d
; } tmp
;
154 SetSR(Zero_Bit
, Zero_Bit
| Negative_Bit
| Overflow_Bit
);
155 Set_Value64C(Res
, 0x0, 0x0);
161 /* normalize the mantisse */
162 AND64C(Qtmp1
, Mant1
, 0x00100000, 0x0);
163 while ( is_eqC(Qtmp1
, 0x0, 0x0))
165 SHL64(Mant1
, Mant1
, 1); //one bit to the left.
166 SUB64QC(Exponent
, 0x00100000, 0x0);
167 AND64C(Qtmp1
, Mant1
, 0x00100000, 0x0);
169 AND64QC(Mant1
, IEEEDPMantisse_Mask_Hi
, IEEEDPMantisse_Mask_Lo
);
174 if ( is_lessSC(Exponent
, 0x0, 0x0))
176 SetSR(Overflow_Bit
, Zero_Bit
| Overflow_Bit
); //do not change Negative_Bit!
180 (IEEEDPMantisse_Mask_Hi
| IEEEDPExponent_Mask_Hi
),
181 (IEEEDPMantisse_Mask_Lo
| IEEEDPExponent_Mask_Lo
)
185 OR64Q(Res
, Exponent
);