Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
00001 /* 00002 00003 Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved. 00004 00005 This program is free software; you can redistribute it and/or modify it 00006 under the terms of version 2 of the GNU General Public License as 00007 published by the Free Software Foundation. 00008 00009 This program is distributed in the hope that it would be useful, but 00010 WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00012 00013 Further, this software is distributed without any warranty that it is 00014 free of the rightful claim of any third person regarding infringement 00015 or the like. Any license provided herein, whether implied or 00016 otherwise, applies only to this software file. Patent licenses, if 00017 any, provided herein do not apply to combinations of this program with 00018 other software, or any other product whatsoever. 00019 00020 You should have received a copy of the GNU General Public License along 00021 with this program; if not, write the Free Software Foundation, Inc., 59 00022 Temple Place - Suite 330, Boston MA 02111-1307, USA. 00023 00024 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 00025 Mountain View, CA 94043, or: 00026 00027 http://www.sgi.com 00028 00029 For further information regarding this notice, see: 00030 00031 http://oss.sgi.com/projects/GenInfo/NoticeExplan 00032 00033 */ 00034 00035 00036 /* 00037 * Comparison routines 00038 * 00039 * The result of a comparison is to be taken from the status bits 00040 * AR_STAT_ZERO and AR_STAT_NEGATIVE, along with the AR_STAT_OVERFLOW 00041 * error bit and (for IEEE) the AR_STAT_UNDEFINED bit. 00042 */ 00043 00044 #include "arith.internal.h" 00045 00046 00047 /* Low-level interface */ 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 /* Perform comparison by subtraction; a == b implies (a-b) == 0 */ 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 /* one of the operands is a NaN - result is unordered */ 00070 return AR_STAT_UNDEFINED; 00071 } 00072 00073 /* Test for [+-]0 == [+-]0 */ 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 /* Remaining tests use -Infinity < -finite < +finite < +Infinity */ 00080 00081 if (a->sign ^ b->sign) { 00082 /* Signs differ; therefore a<b or a>b */ 00083 return a->sign?AR_STAT_NEGATIVE:AR_STAT_OK; 00084 } 00085 00086 /* Same signs--test exponents next */ 00087 00088 if (a->expo ^ b->expo) { 00089 /* Exponents differ; therefore a<b or a>b */ 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 /* Same sign and exponent--test coefficients */ 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 /* Values are equal */ 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 /* one of the operands is a NaN - result is unordered */ 00122 return AR_STAT_UNDEFINED; 00123 } 00124 00125 /* Test for [+-]0 == [+-]0 */ 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 /* Remaining tests use -Infinity < -finite < +finite < +Infinity */ 00132 00133 if (a->sign ^ b->sign) { 00134 /* Signs differ; therefore a<b or a>b */ 00135 return a->sign?AR_STAT_NEGATIVE:AR_STAT_OK; 00136 } 00137 00138 /* Same signs--test exponents next */ 00139 00140 if (a->expo ^ b->expo) { 00141 /* Exponents differ; therefore a<b or a>b */ 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 /* Same sign and exponent--test coefficients */ 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 /* Values are equal */ 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 /* one of the operands is a NaN - result is unordered */ 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 * Use native arithmetic for MIPS. 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 * One of the operands is a NaN - result 00220 * is unordered. 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 /* one of the operands is a NaN - result is unordered */ 00236 return AR_STAT_UNDEFINED; 00237 } 00238 00239 /* Test for [+-]0 == [+-]0 */ 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 /* Remaining tests use -Infinity < -finite < +finite < +Infinity */ 00246 00247 if (a->sign ^ b->sign) { 00248 /* Signs differ; therefore a<b or a>b */ 00249 return a->sign?AR_STAT_NEGATIVE:AR_STAT_OK; 00250 } 00251 00252 /* Same signs--test exponents next */ 00253 00254 if (a->expo ^ b->expo) { 00255 /* Exponents differ; therefore a<b or a>b */ 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 /* Same sign and exponent--test coefficients */ 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 /* Values are equal */ 00308 00309 return AR_STAT_ZERO; 00310 } 00311 #endif 00312 00313 /* Integer comparison */ 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 /* subtractflags == SZVC bits */ 00326 00327 /* Signed comparisons */ 00328 if (AR_SIGNEDNESS (*opnd1type) == AR_SIGNED) { 00329 if ((subtractflags ^ (subtractflags >> 2)) & 0x2) 00330 return AR_Compare_LT; /* sign != overflow */ 00331 if (subtractflags & 0x4) 00332 return AR_Compare_EQ; /* zero flag set */ 00333 return AR_Compare_GT; 00334 } 00335 00336 /* Unsigned comparisons */ 00337 if (subtractflags & 0x1) 00338 return AR_Compare_LT; /* carry bit set */ 00339 if (subtractflags & 0x4) 00340 return AR_Compare_EQ; /* zero bit set */ 00341 return (AR_Compare_GT); 00342 } 00343 00344 00345 /* Floating-point comparison */ 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 /* Complex comparison */ 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 /* General dispatch routine for comparison. */ 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 $";