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
00041
00042
00043
00044 #include "arith.internal.h"
00045
00046
00047
00048 static int
00049 ar_cfcmp64 (const AR_CRAY_64 *a, const AR_CRAY_64 *b, int roundmode) {
00050
00051 AR_CRAY_64 diff;
00052
00053
00054 return ar_cfsub64 (&diff, a, b);
00055 }
00056
00057
00058 static int
00059 ar_cfcmp128 (const AR_CRAY_128 *a, const AR_CRAY_128 *b) {
00060 AR_CRAY_128 diff;
00061 return ar_cfsub128 (&diff, a, b);
00062 }
00063
00064
00065 static int
00066 ar_ifcmp32 (const AR_IEEE_32 *a, const AR_IEEE_32 *b) {
00067
00068 if (IS_IEEE32_NaN(a) || IS_IEEE32_NaN(b)) {
00069
00070 return AR_STAT_UNDEFINED;
00071 }
00072
00073
00074
00075 if (a->expo == 0 && !IS_IEEE32_NZ_COEFF(a) &&
00076 b->expo == 0 && !IS_IEEE32_NZ_COEFF(b))
00077 return AR_STAT_ZERO;
00078
00079
00080
00081 if (a->sign ^ b->sign) {
00082
00083 return a->sign?AR_STAT_NEGATIVE:AR_STAT_OK;
00084 }
00085
00086
00087
00088 if (a->expo ^ b->expo) {
00089
00090 if(a->expo < b->expo)
00091 return a->sign?AR_STAT_OK:AR_STAT_NEGATIVE;
00092 else
00093 return a->sign?AR_STAT_NEGATIVE:AR_STAT_OK;
00094 }
00095
00096
00097
00098 if (a->coeff0 ^ b->coeff0) {
00099 if(a->coeff0 < b->coeff0)
00100 return a->sign?AR_STAT_OK:AR_STAT_NEGATIVE;
00101 else
00102 return a->sign?AR_STAT_NEGATIVE:AR_STAT_OK;
00103 }
00104 if (a->coeff1 ^ b->coeff1) {
00105 if(a->coeff1 < b->coeff1)
00106 return a->sign?AR_STAT_OK:AR_STAT_NEGATIVE;
00107 else
00108 return a->sign?AR_STAT_NEGATIVE:AR_STAT_OK;
00109 }
00110
00111
00112
00113 return AR_STAT_ZERO;
00114 }
00115
00116
00117 int
00118 ar_ifcmp64 (const AR_IEEE_64 *a, const AR_IEEE_64 *b) {
00119
00120 if (IS_IEEE64_NaN(a) || IS_IEEE64_NaN(b)) {
00121
00122 return AR_STAT_UNDEFINED;
00123 }
00124
00125
00126
00127 if (a->expo == 0 && !IS_IEEE64_NZ_COEFF(a) &&
00128 b->expo == 0 && !IS_IEEE64_NZ_COEFF(b))
00129 return AR_STAT_ZERO;
00130
00131
00132
00133 if (a->sign ^ b->sign) {
00134
00135 return a->sign?AR_STAT_NEGATIVE:AR_STAT_OK;
00136 }
00137
00138
00139
00140 if (a->expo ^ b->expo) {
00141
00142 if(a->expo < b->expo)
00143 return a->sign?AR_STAT_OK:AR_STAT_NEGATIVE;
00144 else
00145 return a->sign?AR_STAT_NEGATIVE:AR_STAT_OK;
00146 }
00147
00148
00149
00150 if (a->coeff0 ^ b->coeff0) {
00151 if(a->coeff0 < b->coeff0)
00152 return a->sign?AR_STAT_OK:AR_STAT_NEGATIVE;
00153 else
00154 return a->sign?AR_STAT_NEGATIVE:AR_STAT_OK;
00155 }
00156 if (a->coeff1 ^ b->coeff1) {
00157 if(a->coeff1 < b->coeff1)
00158 return a->sign?AR_STAT_OK:AR_STAT_NEGATIVE;
00159 else
00160 return a->sign?AR_STAT_NEGATIVE:AR_STAT_OK;
00161 }
00162 if (a->coeff2 ^ b->coeff2) {
00163 if(a->coeff2 < b->coeff2)
00164 return a->sign?AR_STAT_OK:AR_STAT_NEGATIVE;
00165 else
00166 return a->sign?AR_STAT_NEGATIVE:AR_STAT_OK;
00167 }
00168 if (a->coeff3 ^ b->coeff3) {
00169 if(a->coeff3 < b->coeff3)
00170 return a->sign?AR_STAT_OK:AR_STAT_NEGATIVE;
00171 else
00172 return a->sign?AR_STAT_NEGATIVE:AR_STAT_OK;
00173 }
00174
00175
00176
00177 return AR_STAT_ZERO;
00178 }
00179
00180
00181 #ifdef __mips
00182 static int
00183 ar_ifcmp128 (const AR_IEEE_128 *a, const AR_IEEE_128 *b)
00184 {
00185 long double o1,o2;
00186 o1 = *(long double *) a;
00187 o2 = *(long double *) b;
00188
00189 if (IS_MIPS128_NaN((AR_MIPS_128 *)a) || IS_MIPS128_NaN((AR_MIPS_128 *)b)) {
00190
00191 return AR_STAT_UNDEFINED;
00192 }
00193
00194 if (o1 == o2) {
00195 return AR_STAT_ZERO;
00196 } else if (o1 < o2) {
00197 return AR_STAT_NEGATIVE;
00198 } else {
00199 return AR_STAT_OK;
00200 }
00201 }
00202
00203 #else
00204
00205 static int
00206 ar_ifcmp128 (const AR_IEEE_128 *a, const AR_IEEE_128 *b) {
00207
00208
00209
00210
00211 if (HOST_IS_MIPS) {
00212 long double o1,o2;
00213 o1 = *(long double *) a;
00214 o2 = *(long double *) b;
00215
00216 if (IS_MIPS128_NaN((AR_MIPS_128 *)a) ||
00217 IS_MIPS128_NaN((AR_MIPS_128 *)b)) {
00218
00219
00220
00221
00222 return AR_STAT_UNDEFINED;
00223 }
00224
00225 if (o1 == o2) {
00226 return AR_STAT_ZERO;
00227 } else if (o1 < o2) {
00228 return AR_STAT_NEGATIVE;
00229 } else {
00230 return AR_STAT_OK;
00231 }
00232 }
00233
00234 if (IS_IEEE128_NaN(a) || IS_IEEE128_NaN(b)) {
00235
00236 return AR_STAT_UNDEFINED;
00237 }
00238
00239
00240
00241 if (a->expo == 0 && !IS_IEEE128_NZ_COEFF(a) &&
00242 b->expo == 0 && !IS_IEEE128_NZ_COEFF(b))
00243 return AR_STAT_ZERO;
00244
00245
00246
00247 if (a->sign ^ b->sign) {
00248
00249 return a->sign?AR_STAT_NEGATIVE:AR_STAT_OK;
00250 }
00251
00252
00253
00254 if (a->expo ^ b->expo) {
00255
00256 if(a->expo < b->expo)
00257 return a->sign?AR_STAT_OK:AR_STAT_NEGATIVE;
00258 else
00259 return a->sign?AR_STAT_NEGATIVE:AR_STAT_OK;
00260 }
00261
00262
00263
00264 if (a->coeff0 ^ b->coeff0) {
00265 if(a->coeff0 < b->coeff0)
00266 return a->sign?AR_STAT_OK:AR_STAT_NEGATIVE;
00267 else
00268 return a->sign?AR_STAT_NEGATIVE:AR_STAT_OK;
00269 }
00270 if (a->coeff1 ^ b->coeff1) {
00271 if(a->coeff1 < b->coeff1)
00272 return a->sign?AR_STAT_OK:AR_STAT_NEGATIVE;
00273 else
00274 return a->sign?AR_STAT_NEGATIVE:AR_STAT_OK;
00275 }
00276 if (a->coeff2 ^ b->coeff2) {
00277 if(a->coeff2 < b->coeff2)
00278 return a->sign?AR_STAT_OK:AR_STAT_NEGATIVE;
00279 else
00280 return a->sign?AR_STAT_NEGATIVE:AR_STAT_OK;
00281 }
00282 if (a->coeff3 ^ b->coeff3) {
00283 if(a->coeff3 < b->coeff3)
00284 return a->sign?AR_STAT_OK:AR_STAT_NEGATIVE;
00285 else
00286 return a->sign?AR_STAT_NEGATIVE:AR_STAT_OK;
00287 }
00288 if (a->coeff4 ^ b->coeff4) {
00289 if(a->coeff4 < b->coeff4)
00290 return a->sign?AR_STAT_OK:AR_STAT_NEGATIVE;
00291 else
00292 return a->sign?AR_STAT_NEGATIVE:AR_STAT_OK;
00293 }
00294 if (a->coeff5 ^ b->coeff5) {
00295 if(a->coeff5 < b->coeff5)
00296 return a->sign?AR_STAT_OK:AR_STAT_NEGATIVE;
00297 else
00298 return a->sign?AR_STAT_NEGATIVE:AR_STAT_OK;
00299 }
00300 if (a->coeff6 ^ b->coeff6) {
00301 if(a->coeff6 < b->coeff6)
00302 return a->sign?AR_STAT_OK:AR_STAT_NEGATIVE;
00303 else
00304 return a->sign?AR_STAT_NEGATIVE:AR_STAT_OK;
00305 }
00306
00307
00308
00309 return AR_STAT_ZERO;
00310 }
00311 #endif
00312
00313
00314 static
00315 AR_COMPARE_TYPE
00316 ar_compare_integer (const ar_data *opnd1, const AR_TYPE *opnd1type,
00317 const ar_data *opnd2, const AR_TYPE *opnd2type) {
00318
00319 ar_data temp;
00320 int subtractflags;
00321
00322 ar_subtract_integer (&temp, opnd1type, &subtractflags,
00323 opnd1, opnd1type, opnd2, opnd2type);
00324
00325
00326
00327
00328 if (AR_SIGNEDNESS (*opnd1type) == AR_SIGNED) {
00329 if ((subtractflags ^ (subtractflags >> 2)) & 0x2)
00330 return AR_Compare_LT;
00331 if (subtractflags & 0x4)
00332 return AR_Compare_EQ;
00333 return AR_Compare_GT;
00334 }
00335
00336
00337 if (subtractflags & 0x1)
00338 return AR_Compare_LT;
00339 if (subtractflags & 0x4)
00340 return AR_Compare_EQ;
00341 return (AR_Compare_GT);
00342 }
00343
00344
00345
00346 static
00347 AR_COMPARE_TYPE
00348 ar_compare_float (const ar_data *opnd1, const AR_TYPE *opnd1type,
00349 const ar_data *opnd2, const AR_TYPE *opnd2type) {
00350
00351 ar_data re1, im1, re2, im2;
00352 AR_TYPE reimtype1, reimtype2;
00353 int status, restat, imstat;
00354 AR_COMPARE_TYPE recomp, imcomp;
00355
00356 if (AR_FLOAT_IS_COMPLEX (*opnd1type) == AR_FLOAT_SIMPLE) {
00357
00358 switch (*opnd1type) {
00359 case AR_Float_Cray1_64:
00360 case AR_Float_Cray1_64_F:
00361 status = ar_cfcmp64 (&opnd1->ar_f64, &opnd2->ar_f64,
00362 ROUND_MODE (*opnd1type));
00363 break;
00364 case AR_Float_Cray1_128:
00365 status = ar_cfcmp128 (&opnd1->ar_f128, &opnd2->ar_f128);
00366 break;
00367 case AR_Float_IEEE_NR_32:
00368 case AR_Float_IEEE_ZE_32:
00369 case AR_Float_IEEE_UP_32:
00370 case AR_Float_IEEE_DN_32:
00371 status = ar_ifcmp32 (&opnd1->ar_ieee32, &opnd2->ar_ieee32);
00372 break;
00373 case AR_Float_IEEE_NR_64:
00374 case AR_Float_IEEE_ZE_64:
00375 case AR_Float_IEEE_UP_64:
00376 case AR_Float_IEEE_DN_64:
00377 status = ar_ifcmp64 (&opnd1->ar_ieee64, &opnd2->ar_ieee64);
00378 break;
00379 case AR_Float_IEEE_NR_128:
00380 case AR_Float_IEEE_ZE_128:
00381 case AR_Float_IEEE_UP_128:
00382 case AR_Float_IEEE_DN_128:
00383 status = ar_ifcmp128(&opnd1->ar_ieee128, &opnd2->ar_ieee128);
00384 break;
00385 default:
00386 return AR_Compare_Invalid;
00387 }
00388
00389 if (status & AR_STAT_UNDEFINED)
00390 return AR_Compare_Unord;
00391 if (status & AR_STAT_ZERO)
00392 return AR_Compare_EQ;
00393 if (status & AR_STAT_NEGATIVE)
00394 return AR_Compare_LT;
00395 return AR_Compare_GT;
00396
00397 }
00398
00399
00400 status = ar_decompose_complex (&re1, &im1, &reimtype1,
00401 opnd1, opnd1type);
00402 status |= ar_decompose_complex (&re2, &im2, &reimtype2,
00403 opnd2, opnd2type);
00404 if (status & (AR_STAT_INVALID_TYPE))
00405 return AR_Compare_Invalid;
00406 recomp = ar_compare_float (&re1, &reimtype1, &re2, &reimtype2);
00407 imcomp = ar_compare_float (&im1, &reimtype1, &im2, &reimtype2);
00408 if (recomp == AR_Compare_Invalid || imcomp == AR_Compare_Invalid)
00409 return AR_Compare_Invalid;
00410 if (recomp == AR_Compare_Unord || imcomp == AR_Compare_Unord)
00411 return AR_Compare_Unord;
00412 if (recomp == AR_Compare_EQ && imcomp == AR_Compare_EQ)
00413 return AR_Compare_EQ;
00414 return AR_Compare_NE;
00415 }
00416
00417
00418
00419 AR_COMPARE_TYPE
00420 AR_compare
00421 (const AR_DATA *op1, const AR_TYPE *opnd1type,
00422 const AR_DATA *op2, const AR_TYPE *opnd2type) {
00423
00424 ar_data* opnd1 = (ar_data*)op1;
00425 ar_data* opnd2 = (ar_data*)op2;
00426
00427 ar_data temp1, temp2;
00428 AR_TYPE sint64_artype = AR_Int_64_S;
00429 AR_TYPE shifttype = AR_Int_64_U;
00430
00431 if (*opnd1type != *opnd2type)
00432 return AR_Compare_Invalid;
00433
00434 if (AR_CLASS (*opnd1type) == AR_CLASS_POINTER) {
00435
00436 if (AR_POINTER_FORMAT (*opnd1type) == AR_POINTER_FCTN) {
00437 if (opnd1->ar_i64.part1 == opnd2->ar_i64.part1 &&
00438 opnd1->ar_i64.part2 == opnd2->ar_i64.part2 &&
00439 opnd1->ar_i64.part3 == opnd2->ar_i64.part3 &&
00440 opnd1->ar_i64.part4 == opnd2->ar_i64.part4)
00441 return AR_Compare_EQ;
00442 else
00443 return AR_Compare_NE;
00444 }
00445
00446 if (AR_POINTER_FORMAT (*opnd1type) == AR_POINTER_CHAR) {
00447 ar_dblshift (&temp1, &shifttype, opnd1, opnd1, 128-3);
00448 ar_dblshift (&temp2, &shifttype, opnd2, opnd2, 128-3);
00449 } else {
00450 temp1 = *opnd1;
00451 temp2 = *opnd2;
00452 }
00453
00454 return ar_compare_integer (&temp1, &sint64_artype,
00455 &temp2, &sint64_artype);
00456 }
00457
00458 if (AR_CLASS (*opnd1type) == AR_CLASS_INT) {
00459 if (AR_INT_SIZE (*opnd1type) != AR_INT_SIZE_8 &&
00460 AR_INT_SIZE (*opnd1type) != AR_INT_SIZE_16 &&
00461 AR_INT_SIZE (*opnd1type) != AR_INT_SIZE_32 &&
00462 AR_INT_SIZE (*opnd1type) != AR_INT_SIZE_46 &&
00463 AR_INT_SIZE (*opnd1type) != AR_INT_SIZE_64)
00464 return AR_Compare_Invalid;
00465 return ar_compare_integer (opnd1, opnd1type, opnd2, opnd2type);
00466 }
00467
00468 if (AR_CLASS (*opnd1type) == AR_CLASS_FLOAT)
00469 return ar_compare_float (opnd1, opnd1type, opnd2, opnd2type);
00470
00471 return AR_Compare_Invalid;
00472 }
00473
00474
00475 static char USMID [] = "\n%Z%%M% %I% %G% %U%\n";
00476 static char rcsid [] = "$Id: compare.c,v 1.1.1.1 2002-05-22 20:06:18 dsystem Exp $";