00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include "arith.internal.h"
00041
00042
00043 int
00044 ar_cfadd64 (AR_CRAY_64 *x,
00045 const AR_CRAY_64 *a,
00046 const AR_CRAY_64 *b) {
00047
00048 int res = AR_STAT_OK, a_expo = a->expo, b_expo = b->expo;
00049 unsigned int carry, shift, inexact;
00050 AR_CRAY_64 y;
00051
00052
00053 if (b_expo > a_expo)
00054 y = *a, *x = *b;
00055 else
00056 y = *b, *x = *a;
00057
00058
00059 if (x->expo < AR_CRAY_MIN_EXPO) {
00060 ZEROCRAY64 (*x);
00061 return AR_STAT_UNDERFLOW | AR_STAT_ZERO;
00062 }
00063
00064
00065
00066
00067 inexact = 0;
00068 shift = x->expo - y.expo;
00069 if (shift > AR_CRAY64_COEFF_BITS)
00070 ZEROCRAY64 (y);
00071 else {
00072 for (; shift; shift--) {
00073 inexact |= y.coeff2 & 1;
00074 SHRIGHTCRAY64 (y);
00075 y.expo++;
00076 }
00077 }
00078
00079
00080
00081
00082 if (x->sign != y.sign)
00083 NOTCRAY64 (*x);
00084
00085
00086 carry = 0;
00087 ADDCRAY64 (*x, carry, *x, y);
00088
00089
00090
00091
00092 if (x->sign != y.sign)
00093 if (carry) {
00094 x->sign ^= 1;
00095 carry = 1;
00096 INCCRAY64 (*x, carry);
00097 carry = 0;
00098 } else
00099 NOTCRAY64 (*x);
00100
00101 if (carry) {
00102 SHRIGHTCRAY64 (*x);
00103 x->coeff0 |= 1 << (AR_CRAY_C0_BITS - 1);
00104 x->expo++;
00105 }
00106
00107
00108 if (!(x->coeff0 | x->coeff1 | x->coeff2)) {
00109 x->sign = x->expo = 0;
00110 return AR_STAT_ZERO;
00111 }
00112
00113
00114 while (!(x->coeff0 >> (AR_CRAY_C0_BITS - 1))) {
00115 x->expo--;
00116 SHLEFTCRAY64 (*x);
00117 }
00118
00119
00120 if (x->expo > AR_CRAY_MAX_EXPO ||
00121 a_expo > AR_CRAY_MAX_EXPO ||
00122 b_expo > AR_CRAY_MAX_EXPO) {
00123 x->sign = 0;
00124 x->expo = AR_CRAY_MAX_EXPO + 1;
00125 res |= AR_STAT_OVERFLOW;
00126 }
00127
00128 if (inexact)
00129 res |= AR_STAT_INEXACT;
00130 if (x->sign)
00131 res |= AR_STAT_NEGATIVE;
00132
00133 return res;
00134 }
00135
00136
00137 int
00138 ar_cfsub64 (AR_CRAY_64 *x,
00139 const AR_CRAY_64 *a,
00140 const AR_CRAY_64 *b) {
00141
00142 AR_CRAY_64 nb = *b;
00143
00144 nb.sign ^= 1;
00145 return ar_cfadd64 (x, a, &nb);
00146 }
00147
00148
00149 int
00150 ar_cfadd128 (AR_CRAY_128 *x,
00151 const AR_CRAY_128 *a,
00152 const AR_CRAY_128 *b) {
00153
00154 int res = AR_STAT_OK, x_expo;
00155 long carry, shift, inexact;
00156 AR_CRAY_128 y;
00157
00158 x->zero = 0;
00159
00160
00161
00162
00163 if (b->expo > a->expo ||
00164 b->expo == a->expo &&
00165 (b->coeff0 > a->coeff0 ||
00166 b->coeff0 == a->coeff0 &&
00167 (b->coeff1 > a->coeff1 ||
00168 b->coeff1 == a->coeff1 &&
00169 (b->coeff2 > a->coeff2 ||
00170 b->coeff2 == a->coeff2 &&
00171 (b->coeff3 > a->coeff3 ||
00172 b->coeff3 == a->coeff3 &&
00173 (b->coeff4 > a->coeff4 ||
00174 b->coeff4 == a->coeff4 &&
00175 b->coeff5 > a->coeff5))))))
00176 y = *a, *x = *b;
00177 else
00178 y = *b, *x = *a;
00179
00180 if ((x_expo = x->expo) > AR_CRAY_MAX_EXPO) {
00181 ZEROCRAY128 (*x);
00182 x->expo = AR_CRAY_MAX_EXPO + 1;
00183 x->coeff0 = 1 << (AR_CRAY_C0_BITS - 1);
00184 return AR_STAT_OVERFLOW;
00185 }
00186
00187
00188 inexact = 0;
00189 shift = x_expo - y.expo;
00190 if (shift > AR_CRAY128_COEFF_BITS)
00191 ZEROCRAY128 (y);
00192 else
00193 for (; shift; shift--) {
00194 inexact |= y.coeff5 & 1;
00195 SHRIGHTCRAY128 (y);
00196 y.expo++;
00197 }
00198
00199
00200 if (x->sign != y.sign) {
00201 NOTCRAY128 (y);
00202 carry = 1;
00203 } else
00204 carry = 0;
00205
00206
00207 ADDCRAY128 (*x, carry, *x, y);
00208
00209
00210 if (x->sign != y.sign)
00211 carry--;
00212
00213 if (carry < 0) {
00214
00215
00216
00217
00218 x_expo += 16;
00219 x->coeff0 = x->coeff1 = x->coeff2 =
00220 x->coeff3 = x->coeff4 = x->coeff5 = 0;
00221
00222 } else if (carry > 0) {
00223
00224
00225 if (carry > 0) {
00226 SHRIGHTCRAY128 (*x);
00227 x->coeff0 |= 1 << (AR_CRAY_C0_BITS - 1);
00228 x_expo++;
00229 }
00230
00231 } else if (x->coeff0 | x->coeff1 | x->coeff2 |
00232 x->coeff3 | x->coeff4 | x->coeff5) {
00233
00234
00235 while (!(x->coeff0 >> (AR_CRAY_C0_BITS - 1))) {
00236 x_expo--;
00237 SHLEFTCRAY128 (*x);
00238 }
00239
00240 } else if (x_expo >= AR_CRAY_MIN_EXPO && x_expo <= AR_CRAY_MAX_EXPO) {
00241
00242
00243 x->sign = 0;
00244 x_expo = 0;
00245 res |= AR_STAT_ZERO;
00246 }
00247
00248
00249
00250
00251 if (x_expo > AR_CRAY_MAX_EXPO) {
00252 ZEROCRAY128 (*x);
00253 x->expo = AR_CRAY_MAX_EXPO + 1;
00254 x->coeff0 = 1 << (AR_CRAY_C0_BITS - 1);
00255 res |= AR_STAT_OVERFLOW;
00256 } else if (x_expo < AR_CRAY_MIN_EXPO) {
00257 ZEROCRAY128 (*x);
00258 res |= AR_STAT_UNDERFLOW | AR_STAT_ZERO;
00259 } else
00260 x->expo = x_expo;
00261
00262 if (inexact)
00263 res |= AR_STAT_INEXACT;
00264 if (x->sign)
00265 res |= AR_STAT_NEGATIVE;
00266
00267 return res;
00268 }
00269
00270
00271 int
00272 ar_cfsub128 (AR_CRAY_128 *x,
00273 const AR_CRAY_128 *a,
00274 const AR_CRAY_128 *b) {
00275
00276 AR_CRAY_128 nb = *b;
00277
00278 nb.sign ^= 1;
00279 return ar_cfadd128 (x, a, &nb);
00280 }
00281
00282
00283 static char USMID [] = "\n%Z%%M% %I% %G% %U%\n";
00284 static char rcsid [] = "$Id: cray_fadd.c,v 1.1.1.1 2005/10/21 19:00:00 marcel Exp $";