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 /* Simulate library intrinsics if this module is loaded */ 00037 00038 #include <stdio.h> 00039 00040 #include "arith.internal.h" 00041 #include "int64.h" 00042 00043 #define MAX_DOPE_VECTOR_WORDS 32 00044 00045 #define CRAY_FLOAT_64 (UNROUNDED_TYPE(AR_Float_Cray1_64)) 00046 #define CRAY_FLOAT_128 (UNROUNDED_TYPE(AR_Float_Cray1_128)) 00047 #define CRAY_COMPLEX_64 (UNROUNDED_TYPE(AR_Complex_Cray1_64)) 00048 #define CRAY_COMPLEX_128 (UNROUNDED_TYPE(AR_Complex_Cray1_128)) 00049 00050 #define IEEE_FLOAT_32 (UNROUNDED_TYPE(AR_Float_IEEE_NR_32)) 00051 #define IEEE_FLOAT_64 (UNROUNDED_TYPE(AR_Float_IEEE_NR_64)) 00052 #define IEEE_FLOAT_128 (UNROUNDED_TYPE(AR_Float_IEEE_NR_128)) 00053 #define IEEE_COMPLEX_32 (UNROUNDED_TYPE(AR_Complex_IEEE_NR_32)) 00054 #define IEEE_COMPLEX_64 (UNROUNDED_TYPE(AR_Complex_IEEE_NR_64)) 00055 #define IEEE_COMPLEX_128 (UNROUNDED_TYPE(AR_Complex_IEEE_NR_128)) 00056 00057 /* Declarations of simulation support functions */ 00058 00059 extern int ar_ext_address(AR_INT_64 *intaddr, const void *extaddr, int nwords); 00060 00061 extern int ar_pass_arg_address(const ar_data *arg, const AR_TYPE *argtype); 00062 00063 extern int ar_pass_ext_address(AR_INT_64 *intaddr, const void *extaddr, int nwords); 00064 00065 extern int ar_pass_fcd_address(const char *str, long lenstr); 00066 00067 extern int ar_pass_arg_value(const ar_data *arg, const AR_TYPE *argtype); 00068 00069 extern int ar_put_real_address(AR_INT_64 *intaddr); 00070 00071 extern int ar_get_function_value(ar_data *result, const AR_TYPE *resulttype); 00072 00073 extern int ar_sim(char* function_name); 00074 00075 00076 /* Fortran character index */ 00077 int 00078 ar_index (ar_data *result, const AR_TYPE *resulttype, 00079 const char *str1, long len1, const char *str2, long len2, long backward) 00080 { 00081 int status; 00082 AR_TYPE type = AR_Logical; 00083 00084 status = ar_clear_sim_state(*resulttype); 00085 status |= ar_pass_fcd_address(str1, len1); 00086 status |= ar_pass_fcd_address(str2, len2); 00087 if(backward) 00088 status |= ar_pass_arg_address((ar_data*)&AR_const_true, &type); 00089 else 00090 status |= ar_pass_arg_address((ar_data*)&AR_const_false, &type); 00091 if(IS_ERROR_STATUS(status)) 00092 return status; 00093 00094 switch (*resulttype) { 00095 00096 case AR_Int_32_S: 00097 status = ar_sim("indexi"); 00098 break; 00099 00100 case AR_Int_46_S: 00101 case AR_Int_64_S: 00102 status = ar_sim("index"); 00103 break; 00104 00105 default: 00106 return AR_STAT_INVALID_TYPE; 00107 } 00108 00109 status &= AR_ERROR_STATUS; 00110 if(status) 00111 return status; 00112 00113 return ar_get_function_value(result, resulttype); 00114 } 00115 00116 00117 /* Fortran character scan */ 00118 int 00119 ar_scan (ar_data *result, const AR_TYPE *resulttype, 00120 const char *str1, long len1, const char *str2, long len2, long backward) 00121 { 00122 int status; 00123 AR_TYPE type = AR_Logical; 00124 00125 status = ar_clear_sim_state(*resulttype); 00126 status |= ar_pass_fcd_address(str1, len1); 00127 status |= ar_pass_fcd_address(str2, len2); 00128 if(backward) 00129 status |= ar_pass_arg_address((ar_data*)&AR_const_true, &type); 00130 else 00131 status |= ar_pass_arg_address((ar_data*)&AR_const_false, &type); 00132 if(IS_ERROR_STATUS(status)) 00133 return status; 00134 00135 switch (*resulttype) { 00136 00137 case AR_Int_32_S: 00138 status = ar_sim("scani"); 00139 break; 00140 00141 case AR_Int_46_S: 00142 case AR_Int_64_S: 00143 status = ar_sim("scan"); 00144 break; 00145 00146 default: 00147 return AR_STAT_INVALID_TYPE; 00148 } 00149 00150 status &= AR_ERROR_STATUS; 00151 if(status) 00152 return status; 00153 00154 return ar_get_function_value(result, resulttype); 00155 } 00156 00157 00158 /* Fortran character verify */ 00159 int 00160 ar_verify (ar_data *result, const AR_TYPE *resulttype, 00161 const char *str1, long len1, const char *str2, long len2, long backward) 00162 { 00163 int status; 00164 AR_TYPE type = AR_Logical; 00165 00166 status = ar_clear_sim_state(*resulttype); 00167 status |= ar_pass_fcd_address(str1, len1); 00168 status |= ar_pass_fcd_address(str2, len2); 00169 if(backward) 00170 status |= ar_pass_arg_address((ar_data*)&AR_const_true, &type); 00171 else 00172 status |= ar_pass_arg_address((ar_data*)&AR_const_false, &type); 00173 if(IS_ERROR_STATUS(status)) 00174 return status; 00175 00176 switch (*resulttype) { 00177 00178 case AR_Int_32_S: 00179 status = ar_sim("verifyi"); 00180 break; 00181 00182 case AR_Int_46_S: 00183 case AR_Int_64_S: 00184 status = ar_sim("verify"); 00185 break; 00186 00187 default: 00188 return AR_STAT_INVALID_TYPE; 00189 } 00190 00191 status &= AR_ERROR_STATUS; 00192 if(status) 00193 return status; 00194 00195 return ar_get_function_value(result, resulttype); 00196 } 00197 00198 00199 /* Fortran-90 reshape */ 00200 int 00201 ar_reshape (void *result, const void *source, const void *shape, 00202 const void *pad, const void *order) 00203 { 00204 int status; 00205 00206 char* addr; 00207 00208 long long resfcd1; 00209 long long srcfcd1; 00210 long long shpfcd1; 00211 00212 AR_INT_64 extaddr; 00213 00214 /* Grab the 1st word which is always the 1st word of an fcd */ 00215 memcpy((char*)&resfcd1, (char*)result, 8); 00216 memcpy((char*)&srcfcd1, (char*)source, 8); 00217 memcpy((char*)&shpfcd1, (char*)shape, 8); 00218 00219 if(srcfcd1 == 0 || shpfcd1 == 0) 00220 return AR_STAT_UNDEFINED; 00221 00222 status = ar_clear_sim_state(AR_Int_64_S); 00223 00224 /* If result baseaddr is not NULL, replace it with an ext addr desc */ 00225 if(resfcd1 != 0) { 00226 memcpy((char*)&addr, (char*)&resfcd1 + sizeof(long long) - 00227 sizeof(char*), sizeof(char*)); 00228 ar_ext_address(&extaddr, (const void*)addr, 0x7ffffff); 00229 if(extaddr.part2) 00230 memcpy((char*)result, (char*)&extaddr, 8); 00231 else 00232 memcpy((char*)result+4, (char*)(&extaddr)+4, 4); 00233 } 00234 status |= ar_pass_ext_address(NULL, (const void*)result, MAX_DOPE_VECTOR_WORDS); 00235 00236 /* Replace baseaddr in source dope vector with an ext addr descriptor */ 00237 memcpy((char*)&addr, (char*)&srcfcd1 + sizeof(long long) - 00238 sizeof(char*), sizeof(char*)); 00239 ar_ext_address(&extaddr, (const void*)addr, 0x7ffffff); 00240 if(extaddr.part2) 00241 memcpy((char*)source, (char*)&extaddr, 8); 00242 else 00243 memcpy((char*)source+4, (char*)(&extaddr)+4, 4); 00244 status |= ar_pass_ext_address(NULL, source, MAX_DOPE_VECTOR_WORDS); 00245 00246 /* Replace baseaddr in shape dope vector with an ext addr descriptor */ 00247 memcpy((char*)&addr, (char*)&shpfcd1 + sizeof(long long) - 00248 sizeof(char*), sizeof(char*)); 00249 ar_ext_address(&extaddr, (const void*)addr, 0x7ffffff); 00250 if(extaddr.part2) 00251 memcpy((char*)shape, (char*)&extaddr, 8); 00252 else 00253 memcpy((char*)shape+4, (char*)(&extaddr)+4, 4); 00254 status |= ar_pass_ext_address(NULL, shape, MAX_DOPE_VECTOR_WORDS); 00255 00256 /* Replace baseaddr in pad dope vector with an ext addr descriptor */ 00257 if(pad != NULL) { 00258 memcpy((char*)&addr, (char*)pad + sizeof(long long) - 00259 sizeof(char*), sizeof(char*)); 00260 ar_ext_address(&extaddr, (const void*)addr, 0x7ffffff); 00261 if(extaddr.part2) 00262 memcpy((char*)pad, (char*)&extaddr, 8); 00263 else 00264 memcpy((char*)pad+4, (char*)(&extaddr)+4, 4); 00265 } 00266 status |= ar_pass_ext_address(NULL, pad, MAX_DOPE_VECTOR_WORDS); 00267 00268 /* Replace baseaddr in order dope vector with an ext addr descriptor */ 00269 if(order != NULL) { 00270 memcpy((char*)&addr, (char*)order + sizeof(long long) - 00271 sizeof(char*), sizeof(char*)); 00272 ar_ext_address(&extaddr, (const void*)addr, 0x7ffffff); 00273 if(extaddr.part2) 00274 memcpy((char*)order, (char*)&extaddr, 8); 00275 else 00276 memcpy((char*)order+4, (char*)(&extaddr)+4, 4); 00277 } 00278 status |= ar_pass_ext_address(NULL, order, MAX_DOPE_VECTOR_WORDS); 00279 00280 if(IS_ERROR_STATUS(status)) 00281 return status; 00282 00283 status = ar_sim("reshape"); 00284 00285 /* Restore baseaddr fields in dope vectors */ 00286 memcpy((char*)source, (char*)&srcfcd1, 8); 00287 memcpy((char*)shape, (char*)&shpfcd1, 8); 00288 00289 if(IS_ERROR_STATUS(status)) 00290 return status; 00291 00292 return ar_put_real_address((AR_INT_64*)result); 00293 } 00294 00295 00296 /* Fortran-90 transfer */ 00297 int 00298 ar_transfer (void *result, const void *source, const void *mold, long *size) 00299 { 00300 int status; 00301 00302 char* addr; 00303 00304 long long resfcd1; 00305 long long srcfcd1; 00306 long long mldfcd1; 00307 00308 AR_INT_64 extaddr; 00309 AR_INT_64 length; 00310 00311 AR_TYPE inttype = AR_Int_64_S; 00312 00313 /* Grab the 1st word which is always the 1st word of an fcd */ 00314 memcpy((char*)&resfcd1, (char*)result, 8); 00315 memcpy((char*)&srcfcd1, (char*)source, 8); 00316 memcpy((char*)&mldfcd1, (char*)mold, 8); 00317 00318 if(srcfcd1 == 0 || mldfcd1 == 0) 00319 return AR_STAT_UNDEFINED; 00320 00321 status = ar_clear_sim_state(AR_Int_64_S); 00322 00323 /* If result baseaddr is not NULL, replace it with an ext addr desc */ 00324 if(resfcd1 != 0) { 00325 memcpy((char*)&addr, (char*)&resfcd1 + sizeof(long long) - 00326 sizeof(char*), sizeof(char*)); 00327 ar_ext_address(&extaddr, (const void*)addr, 0x7ffffff); 00328 if(extaddr.part2) 00329 memcpy((char*)result, (char*)&extaddr, 8); 00330 else 00331 memcpy((char*)result+4, (char*)(&extaddr)+4, 4); 00332 } 00333 status |= ar_pass_ext_address(NULL, (const void*)result, MAX_DOPE_VECTOR_WORDS); 00334 00335 /* Replace baseaddr in source dope vector with an ext addr descriptor */ 00336 memcpy((char*)&addr, (char*)&srcfcd1 + sizeof(long long) - 00337 sizeof(char*), sizeof(char*)); 00338 ar_ext_address(&extaddr, (const void*)addr, 0x7ffffff); 00339 if(extaddr.part2) 00340 memcpy((char*)source, (char*)&extaddr, 8); 00341 else 00342 memcpy((char*)source+4, (char*)(&extaddr)+4, 4); 00343 status |= ar_pass_ext_address(NULL, source, MAX_DOPE_VECTOR_WORDS); 00344 00345 /* Replace baseaddr in mold dope vector with an ext addr descriptor */ 00346 memcpy((char*)&addr, (char*)&mldfcd1 + sizeof(long long) - 00347 sizeof(char*), sizeof(char*)); 00348 ar_ext_address(&extaddr, (const void*)addr, 0x7ffffff); 00349 if(extaddr.part2) 00350 memcpy((char*)mold, (char*)&extaddr, 8); 00351 else 00352 memcpy((char*)mold+4, (char*)(&extaddr)+4, 4); 00353 status |= ar_pass_ext_address(NULL, mold, MAX_DOPE_VECTOR_WORDS); 00354 00355 if(size != NULL) { 00356 length.part1 = length.part2 = 0; 00357 length.part3 = *size>>16; 00358 length.part4 = *size & 0xffff; 00359 status |= ar_pass_arg_address((ar_data*)&length, &inttype); 00360 } 00361 else 00362 status |= ar_pass_arg_address((ar_data*)size, &inttype); 00363 00364 if(IS_ERROR_STATUS(status)) 00365 return status; 00366 00367 status = ar_sim("transfer"); 00368 00369 /* Restore baseaddr fields in dope vectors */ 00370 memcpy((char*)source, (char*)&srcfcd1, 8); 00371 memcpy((char*)mold, (char*)&mldfcd1, 8); 00372 00373 if(IS_ERROR_STATUS(status)) 00374 return status; 00375 00376 return ar_put_real_address((AR_INT_64*)result); 00377 } 00378 00379 00380 /* Fortran-90 modulo */ 00381 int 00382 ar_modulo (ar_data *result, const AR_TYPE *resulttype, 00383 const ar_data *opnd1, const AR_TYPE *opnd1type, 00384 const ar_data *opnd2, const AR_TYPE *opnd2type) { 00385 00386 int status; 00387 00388 status = ar_clear_sim_state(*resulttype); 00389 status |= ar_pass_arg_address(opnd1, opnd1type); 00390 status |= ar_pass_arg_address(opnd2, opnd2type); 00391 if(IS_ERROR_STATUS(status)) 00392 return status; 00393 00394 switch (UNROUNDED_TYPE(*resulttype)) { 00395 00396 case IEEE_FLOAT_32: 00397 status = ar_sim("modulof"); 00398 break; 00399 00400 case CRAY_FLOAT_64: 00401 case IEEE_FLOAT_64: 00402 status = ar_sim("modulos"); 00403 break; 00404 00405 case CRAY_FLOAT_128: 00406 case IEEE_FLOAT_128: 00407 status = ar_sim("modulod"); 00408 break; 00409 00410 default: 00411 switch (*resulttype) { 00412 00413 case AR_Int_32_S: 00414 case AR_Int_46_S: 00415 status = ar_sim("moduloi"); 00416 break; 00417 00418 case AR_Int_64_S: 00419 status = ar_sim("moduloj"); 00420 break; 00421 00422 default: 00423 return AR_STAT_INVALID_TYPE; 00424 } 00425 00426 } 00427 00428 status &= AR_ERROR_STATUS; 00429 if(status) 00430 return status; 00431 00432 return ar_get_function_value(result, resulttype); 00433 } 00434 00435 00436 /* Fortran-90 selected_real_kind */ 00437 int 00438 ar_selected_real_kind (ar_data *result, const AR_TYPE *resulttype, 00439 const ar_data *opnd1, const AR_TYPE *opnd1type, 00440 const ar_data *opnd2, const AR_TYPE *opnd2type) { 00441 00442 int status; 00443 00444 status = ar_clear_sim_state(*resulttype); 00445 status |= ar_pass_arg_address(opnd1, opnd1type); 00446 status |= ar_pass_arg_address(opnd2, opnd2type); 00447 if(IS_ERROR_STATUS(status)) 00448 return status; 00449 00450 switch (*resulttype) { 00451 00452 case AR_Int_32_S: 00453 status = ar_sim("selreali"); 00454 break; 00455 00456 case AR_Int_46_S: 00457 case AR_Int_64_S: 00458 status = ar_sim("selrealk"); 00459 break; 00460 00461 default: 00462 return AR_STAT_INVALID_TYPE; 00463 } 00464 00465 status &= AR_ERROR_STATUS; 00466 if(status) 00467 return status; 00468 00469 return ar_get_function_value(result, resulttype); 00470 } 00471 00472 00473 /* Square root */ 00474 int 00475 ar_sqrt (ar_data *result, const AR_TYPE *resulttype, 00476 const ar_data *opnd, const AR_TYPE *opndtype) { 00477 00478 int status; 00479 00480 status = ar_clear_sim_state(*resulttype); 00481 status |= ar_pass_arg_value(opnd, opndtype); 00482 if(IS_ERROR_STATUS(status)) 00483 return status; 00484 00485 switch (UNROUNDED_TYPE(*resulttype)) { 00486 00487 case IEEE_FLOAT_32: 00488 status = ar_sim("hsqrt"); 00489 break; 00490 00491 case CRAY_FLOAT_64: 00492 case IEEE_FLOAT_64: 00493 status = ar_sim("sqrt"); 00494 break; 00495 00496 case CRAY_FLOAT_128: 00497 case IEEE_FLOAT_128: 00498 status = ar_sim("dsqrt"); 00499 break; 00500 00501 case CRAY_COMPLEX_64: 00502 case IEEE_COMPLEX_32: 00503 case IEEE_COMPLEX_64: 00504 status = ar_sim("csqrt"); 00505 break; 00506 00507 case CRAY_COMPLEX_128: 00508 case IEEE_COMPLEX_128: 00509 status = ar_sim("cdsqrt"); 00510 break; 00511 00512 default: 00513 return AR_STAT_INVALID_TYPE; 00514 } 00515 00516 status &= AR_ERROR_STATUS; 00517 if(status) 00518 return status; 00519 00520 return ar_get_function_value(result, resulttype); 00521 } 00522 00523 00524 /* Natural (base "e") logarithm */ 00525 int 00526 ar_log (ar_data *result, const AR_TYPE *resulttype, 00527 const ar_data *opnd, const AR_TYPE *opndtype) { 00528 00529 int status; 00530 00531 status = ar_clear_sim_state(*resulttype); 00532 status |= ar_pass_arg_value(opnd, opndtype); 00533 if(IS_ERROR_STATUS(status)) 00534 return status; 00535 00536 switch (UNROUNDED_TYPE(*resulttype)) { 00537 00538 case IEEE_FLOAT_32: 00539 status = ar_sim("hlog"); 00540 break; 00541 00542 case CRAY_FLOAT_64: 00543 case IEEE_FLOAT_64: 00544 status = ar_sim("alog"); 00545 break; 00546 00547 case CRAY_FLOAT_128: 00548 case IEEE_FLOAT_128: 00549 status = ar_sim("dlog"); 00550 break; 00551 00552 case CRAY_COMPLEX_64: 00553 case IEEE_COMPLEX_32: 00554 case IEEE_COMPLEX_64: 00555 status = ar_sim("clog"); 00556 break; 00557 00558 case CRAY_COMPLEX_128: 00559 case IEEE_COMPLEX_128: 00560 status = ar_sim("cdlog"); 00561 break; 00562 00563 default: 00564 return AR_STAT_INVALID_TYPE; 00565 } 00566 00567 status &= AR_ERROR_STATUS; 00568 if(status) 00569 return status; 00570 00571 return ar_get_function_value(result, resulttype); 00572 } 00573 00574 00575 /* Exponential ("e" ** x) function */ 00576 int 00577 ar_exp (ar_data *result, const AR_TYPE *resulttype, 00578 const ar_data *opnd, const AR_TYPE *opndtype) { 00579 00580 int status; 00581 00582 status = ar_clear_sim_state(*resulttype); 00583 status |= ar_pass_arg_value(opnd, opndtype); 00584 if(IS_ERROR_STATUS(status)) 00585 return status; 00586 00587 switch (UNROUNDED_TYPE(*resulttype)) { 00588 00589 case IEEE_FLOAT_32: 00590 status = ar_sim("hexp"); 00591 break; 00592 00593 case CRAY_FLOAT_64: 00594 case IEEE_FLOAT_64: 00595 status = ar_sim("exp"); 00596 break; 00597 00598 case CRAY_FLOAT_128: 00599 case IEEE_FLOAT_128: 00600 status = ar_sim("dexp"); 00601 break; 00602 00603 case CRAY_COMPLEX_64: 00604 case IEEE_COMPLEX_32: 00605 case IEEE_COMPLEX_64: 00606 status = ar_sim("cexp"); 00607 break; 00608 00609 case CRAY_COMPLEX_128: 00610 case IEEE_COMPLEX_128: 00611 status = ar_sim("cdexp"); 00612 break; 00613 00614 default: 00615 return AR_STAT_INVALID_TYPE; 00616 } 00617 00618 status &= AR_ERROR_STATUS; 00619 if(status) 00620 return status; 00621 00622 return ar_get_function_value(result, resulttype); 00623 } 00624 00625 00626 /* Complex absolute value */ 00627 int 00628 ar_cabs (ar_data *result, const AR_TYPE *resulttype, 00629 const ar_data *opnd, const AR_TYPE *opndtype) { 00630 00631 int status; 00632 00633 status = ar_clear_sim_state(*resulttype); 00634 status |= ar_pass_arg_value(opnd, opndtype); 00635 if(IS_ERROR_STATUS(status)) 00636 return status; 00637 00638 switch (UNROUNDED_TYPE(*resulttype)) { 00639 00640 case CRAY_FLOAT_64: 00641 case IEEE_FLOAT_32: 00642 case IEEE_FLOAT_64: 00643 status = ar_sim("cabs"); 00644 break; 00645 00646 case CRAY_FLOAT_128: 00647 case IEEE_FLOAT_128: 00648 status = ar_sim("cdabs"); 00649 break; 00650 00651 default: 00652 return AR_STAT_INVALID_TYPE; 00653 } 00654 00655 status &= AR_ERROR_STATUS; 00656 if(status) 00657 return status; 00658 00659 return ar_get_function_value(result, resulttype); 00660 } 00661 00662 00663 /* Exponentiation */ 00664 int 00665 ar_power(ar_data *result, const AR_TYPE *resulttype, 00666 const ar_data *base, const AR_TYPE *basetype, 00667 const ar_data *power, const AR_TYPE *powertype) 00668 { 00669 int status; 00670 ar_data temp; 00671 AR_TYPE btype, ptype; 00672 00673 /* Prepare for power function simulation by converting 00674 * base and power operand types to values supported by 00675 * the simulated power functions. 00676 */ 00677 00678 if(AR_CLASS(*basetype) == AR_CLASS_INT) 00679 00680 btype = ptype = *powertype; 00681 00682 else if(AR_CLASS(*powertype) == AR_CLASS_INT || 00683 (AR_FLOAT_SIZE(*powertype) <= AR_FLOAT_64 && 00684 AR_FLOAT_IS_COMPLEX(*powertype) != AR_FLOAT_COMPLEX)) { 00685 00686 /* base**I or base**R power functions */ 00687 00688 btype = *basetype; 00689 ptype = *powertype; 00690 } 00691 00692 /* Otherwise, process arg types to simulate power function with 00693 * base type == power type using the greatest precision and/or 00694 * generality required. 00695 */ 00696 00697 else { 00698 00699 /* Convert to base type == power type using the greatest 00700 * precision and/or generality required. 00701 */ 00702 00703 if(AR_FLOAT_SIZE(*basetype) > AR_FLOAT_SIZE(*powertype)) 00704 btype = (AR_TYPE) (*basetype | AR_FLOAT_IS_COMPLEX(*powertype)); 00705 else 00706 btype = (AR_TYPE) (*powertype | AR_FLOAT_IS_COMPLEX(*basetype)); 00707 00708 ptype = btype; 00709 } 00710 00711 /* 00712 * Verify that the resulttype matches the simulated function's 00713 * return type given by the expanded base type. 00714 */ 00715 00716 if(*resulttype != btype) 00717 return AR_STAT_INVALID_TYPE; 00718 00719 /* 00720 * Setup the operands to the power function converting to the 00721 * correct (expanded) type if necessary. 00722 */ 00723 00724 status = ar_clear_sim_state(*resulttype); 00725 if(*basetype != btype) { 00726 status |= AR_convert((AR_DATA*)&temp, &btype, (AR_DATA*)base, basetype); 00727 if(ptype == btype && 00728 AR_FLOAT_SIZE(btype) == AR_FLOAT_128 && 00729 AR_FLOAT_IS_COMPLEX(btype) == AR_FLOAT_COMPLEX) 00730 status |= ar_pass_arg_address(&temp, &btype); 00731 else 00732 status |= ar_pass_arg_value(&temp, &btype); 00733 } 00734 else 00735 if(ptype == btype && 00736 AR_FLOAT_SIZE(btype) == AR_FLOAT_128 && 00737 AR_FLOAT_IS_COMPLEX(btype) == AR_FLOAT_COMPLEX) 00738 status |= ar_pass_arg_address(base, basetype); 00739 else 00740 status |= ar_pass_arg_value(base, basetype); 00741 00742 if(*powertype != ptype) { 00743 status = AR_convert((AR_DATA*)&temp, &ptype, (AR_DATA*)power, powertype); 00744 if(ptype == btype && 00745 AR_FLOAT_SIZE(btype) == AR_FLOAT_128 && 00746 AR_FLOAT_IS_COMPLEX(btype) == AR_FLOAT_COMPLEX) 00747 status |= ar_pass_arg_address(&temp, &ptype); 00748 else 00749 status |= ar_pass_arg_value(&temp, &ptype); 00750 } 00751 else 00752 if(ptype == btype && 00753 AR_FLOAT_SIZE(btype) == AR_FLOAT_128 && 00754 AR_FLOAT_IS_COMPLEX(btype) == AR_FLOAT_COMPLEX) 00755 status |= ar_pass_arg_address(power, powertype); 00756 else 00757 status |= ar_pass_arg_value(power, powertype); 00758 00759 if(IS_ERROR_STATUS(status)) 00760 return status; 00761 00762 /* 00763 * Call (simulate) the correct power function determined by 00764 * the (expanded) base and power types. 00765 */ 00766 00767 switch (UNROUNDED_TYPE(btype)) { 00768 00769 case CRAY_FLOAT_64: 00770 case IEEE_FLOAT_32: 00771 case IEEE_FLOAT_64: 00772 if(AR_CLASS(ptype) == AR_CLASS_INT) 00773 status = ar_sim("rtoi"); 00774 else 00775 status = ar_sim("rtor"); 00776 break; 00777 00778 case CRAY_FLOAT_128: 00779 case IEEE_FLOAT_128: 00780 if(AR_CLASS(ptype) == AR_CLASS_INT) 00781 status = ar_sim("dtoi"); 00782 else if(AR_FLOAT_SIZE(ptype) <= AR_FLOAT_64) 00783 status = ar_sim("dtor"); 00784 else 00785 status = ar_sim("dtod"); 00786 break; 00787 00788 case CRAY_COMPLEX_64: 00789 case IEEE_COMPLEX_32: 00790 case IEEE_COMPLEX_64: 00791 if(AR_CLASS(ptype) == AR_CLASS_INT) 00792 status = ar_sim("ctoi"); 00793 else if(AR_FLOAT_IS_COMPLEX(ptype) != AR_FLOAT_COMPLEX) 00794 status = ar_sim("ctor"); 00795 else 00796 status = ar_sim("ctoc"); 00797 break; 00798 00799 case CRAY_COMPLEX_128: 00800 case IEEE_COMPLEX_128: 00801 if(AR_CLASS(ptype) == AR_CLASS_INT) 00802 status = ar_sim("cdtoi"); 00803 else 00804 status = ar_sim("cdtocd"); 00805 break; 00806 00807 default: 00808 switch (btype) { 00809 00810 case AR_Int_32_S: 00811 case AR_Int_46_S: 00812 case AR_Int_64_S: 00813 status = ar_sim("itoi"); 00814 break; 00815 00816 default: 00817 return AR_STAT_INVALID_TYPE; 00818 } 00819 } 00820 00821 status &= AR_ERROR_STATUS; 00822 if(status) 00823 return status; 00824 00825 return ar_get_function_value(result, resulttype); 00826 } 00827 00828 00829 /* Input conversion precision mode flags */ 00830 00831 #define MODESP 000 /* Single-precision (64-bit) flag */ 00832 #define MODEDP 004 /* Double-precision (128-bit) flag */ 00833 #define MODEHP 020 /* Half-precision (32-bit) flag */ 00834 00835 /* Input conversion exit values */ 00836 00837 #define EX_REAL64 3 /* 64-bit real */ 00838 #define EX_REAL128 4 /* 128-bit real */ 00839 #define EX_REAL32 5 /* 32-bit real */ 00840 #define EX_ILLCHAR -1 /* invalid character */ 00841 #define EX_EXPUFLO -3 /* floating-point underflow */ 00842 #define EX_EXPOFLO -4 /* floating-point overflow */ 00843 #define EX_NULLFLD -5 /* null field (no digits) */ 00844 00845 /* string -> floating point */ 00846 int 00847 ar_convert_str_to_float (ar_data *result, const AR_TYPE *resulttype, 00848 const char *str) 00849 { 00850 int status; 00851 00852 int i; 00853 00854 long w, d, p; 00855 00856 AR_INT_64 fw; 00857 AR_INT_64 lcap1; 00858 AR_INT_64 mode; 00859 AR_INT_64 stat; 00860 AR_INT_64 xd; 00861 AR_INT_64 xp; 00862 00863 long ichars[64]; 00864 AR_INT_64 unpacked_chars[64]; 00865 00866 extern int ar_unpack_float_str(); 00867 00868 /* Unpack char string into integer array 1 character per word */ 00869 00870 status = ar_unpack_float_str(ichars, 64, &w, &d, &p, str); 00871 if (IS_ERROR_STATUS(status)) 00872 return status; 00873 00874 if(status == AR_STAT_ZERO) { 00875 ZERO64(result[0].ar_i64); 00876 if(AR_FLOAT_SIZE(*resulttype) == AR_FLOAT_128) 00877 result[0].ar_i128.part5 = result[0].ar_i128.part6 = 00878 result[0].ar_i128.part7 = result[0].ar_i128.part8 = 0; 00879 return AR_STAT_ZERO; 00880 } 00881 00882 /* Set up 64-bit arguments for the simulated call */ 00883 00884 ZERO64(fw); 00885 fw.part4 = w; 00886 ZERO64(xd); 00887 xd.part4 = d; 00888 xp.part4 = p; 00889 if(p < 0) 00890 xp.part1 = xp.part2 = xp.part3 = 0xffff; 00891 else 00892 xp.part1 = xp.part2 = xp.part3 = 0; 00893 00894 /* Define the floating point mode of the numeric result */ 00895 00896 ZERO64(mode); 00897 if(UNROUNDED_TYPE(*resulttype) == IEEE_FLOAT_32) 00898 mode.part4 = MODEHP; /* = 32-bit */ 00899 else if(AR_FLOAT_SIZE(*resulttype) == AR_FLOAT_64) 00900 mode.part4 = MODESP; /* = 64-bit */ 00901 else if(AR_FLOAT_SIZE(*resulttype) == AR_FLOAT_128) 00902 mode.part4 = MODEDP; /* = 128-bit */ 00903 else 00904 return AR_STAT_INVALID_TYPE; 00905 00906 for(i=0; i<w; i++) { 00907 ZERO64(unpacked_chars[i]); 00908 unpacked_chars[i].part4 = ichars[i]; 00909 } 00910 00911 /* Define (call-by-address) argument list to: 00912 * 00913 * defgu2sd(fca, &fw, &lcap1, &mode, &result, &status, &d, &p) 00914 * 00915 */ 00916 00917 status = ar_clear_sim_state(*resulttype); 00918 status |= ar_pass_ext_address(&lcap1,(const void*)unpacked_chars, 64); 00919 status |= ar_pass_ext_address(NULL, (const void*)&fw, 1); 00920 status |= ar_pass_ext_address(NULL, (const void*)&lcap1, 1); 00921 status |= ar_pass_ext_address(NULL, (const void*)&mode, 1); 00922 status |= ar_pass_ext_address(NULL, (const void*)result, 4); 00923 status |= ar_pass_ext_address(NULL, (const void*)&stat, 1); 00924 status |= ar_pass_ext_address(NULL, (const void*)&xd, 1); 00925 status |= ar_pass_ext_address(NULL, (const void*)&xp, 1); 00926 00927 /* Store the unpacked last character address + 1 (into lcap1) 00928 * Note that lcap1.part4 was returned with shift count to convert 00929 * a 64-bit word offset/index into a address quantity. 00930 */ 00931 00932 lcap1.part4 = w<<lcap1.part4; 00933 00934 if (IS_ERROR_STATUS(status)) 00935 return status; 00936 00937 00938 /* 00939 * Solaris porting 00940 * The ported mfef90 causes "illegal instruction" error when running on Fortran 00941 * files containing floating-point number assignment. This error happens during 00942 * the following ar_sim("defgu2sd") call. 00943 */ 00944 /* Simulate low-level input conversion routine, defgu2sd */ 00945 status = ar_sim("defgu2sd"); 00946 if(IS_ERROR_STATUS(status)) 00947 return status; 00948 00949 /* 00950 * Process results returned by defgu2sd. Note that defgu2sd has 00951 * already stored the converted number into result. 00952 */ 00953 00954 memcpy(&status, (char*)(&stat)+8-sizeof(int), sizeof(int)); 00955 switch (status) { 00956 case EX_REAL32: 00957 result[0].ar_i64.part3 = result[0].ar_i64.part1; 00958 result[0].ar_i64.part4 = result[0].ar_i64.part2; 00959 result[0].ar_i64.part1 = result[0].ar_i64.part2 = 0; 00960 case EX_REAL64: 00961 case EX_REAL128: 00962 status = AR_status((AR_DATA*)result, resulttype); 00963 break; 00964 00965 case EX_EXPUFLO: 00966 ZERO64(result[0].ar_i64); 00967 if(AR_FLOAT_SIZE(*resulttype) == AR_FLOAT_128) 00968 result[0].ar_i128.part5 = result[0].ar_i128.part6 = 00969 result[0].ar_i128.part7 = result[0].ar_i128.part8 = 0; 00970 status = AR_STAT_UNDERFLOW|AR_STAT_ZERO; 00971 break; 00972 00973 case EX_EXPOFLO: 00974 status = AR_STAT_OVERFLOW; 00975 break; 00976 00977 default: 00978 status = AR_STAT_UNDEFINED; 00979 break; 00980 } 00981 00982 return status; 00983 } 00984 00985 00986 /* "Normal" complex division algorithm */ 00987 int 00988 ar_divide_complex (ar_data *result, const AR_TYPE *resulttype, 00989 const ar_data *opnd1, const AR_TYPE *opnd1type, 00990 const ar_data *opnd2, const AR_TYPE *opnd2type) 00991 { 00992 00993 /* Assume types all match (see logic in AR_divide) */ 00994 00995 AR_DATA a, b, c, d, ac, bd, bc, ad, cc, dd, acbd, bcad, ccdd, re, im; 00996 AR_TYPE reimtype1, reimtype2, temptype; 00997 int status, restat, imstat; 00998 00999 status = ar_decompose_complex ((ar_data*)&a, (ar_data*)&b, &reimtype1, 01000 opnd1, opnd1type); 01001 status |= ar_decompose_complex ((ar_data*)&c, (ar_data*)&d, &reimtype2, 01002 opnd2, opnd2type); 01003 01004 /* PDGCS requests that a different sequence be used when the 01005 * imaginary part of the denominator is zero. A meeting of 01006 * managers on 11/30/93 decided in favor of this expediency. 01007 * Note that we do NOT apply special-case processing when 01008 * the real part of the denominator is zero. 01009 */ 01010 01011 imstat = AR_status (&d, &reimtype2); 01012 if (imstat & AR_STAT_ZERO) { 01013 01014 /* zero imaginary part, use short sequence */ 01015 restat = AR_divide (&re, &reimtype1, 01016 &a, &reimtype1, &c, &reimtype2); 01017 imstat = AR_divide (&im, &reimtype1, 01018 &b, &reimtype1, &c, &reimtype2); 01019 01020 } else { 01021 01022 /* 01023 * general sequence: 01024 * 01025 * a + bi (a + bi)(c - di) (ac + bd) (bc - ad)i 01026 * ------ = ---------------- = --------- + ---------- 01027 * c + di (c + di)(c - di) c*c + d*d c*c + d*d 01028 */ 01029 01030 status |= AR_multiply (&ac, &reimtype1, 01031 &a, &reimtype1, &c, &reimtype2); 01032 status |= AR_multiply (&bd, &reimtype1, &b, 01033 &reimtype1, &d, &reimtype2); 01034 status |= AR_multiply (&bc, &reimtype1, 01035 &b, &reimtype1, &c, &reimtype2); 01036 status |= AR_multiply (&ad, &reimtype1, 01037 &a, &reimtype1, &d, &reimtype2); 01038 status |= AR_multiply (&cc, &reimtype2, 01039 &c, &reimtype2, &c, &reimtype2); 01040 status |= AR_multiply (&dd, &reimtype2, 01041 &d, &reimtype2, &d, &reimtype2); 01042 status |= AR_add (&acbd, &reimtype1, 01043 &ac, &reimtype1, &bd, &reimtype1); 01044 status |= AR_subtract (&bcad, &reimtype1, 01045 &bc, &reimtype1, &ad, &reimtype1); 01046 status |= AR_add (&ccdd, &reimtype1, 01047 &cc, &reimtype1, &dd, &reimtype1); 01048 01049 restat = AR_divide (&re, &reimtype1, 01050 &acbd, &reimtype1, &ccdd, &reimtype1); 01051 imstat = AR_divide (&im, &reimtype1, 01052 &bcad, &reimtype1, &ccdd, &reimtype1); 01053 } 01054 01055 status |= ar_compose_complex (result, &temptype, 01056 (ar_data*)&re, (ar_data*)&im, &reimtype1); 01057 status |= restat | imstat; 01058 status &= ~(AR_STAT_ZERO | AR_STAT_NEGATIVE); 01059 status |= restat & imstat & AR_STAT_ZERO; 01060 return status; 01061 } 01062 01063 01064 #if defined(__sparc__) || defined(__mips) 01065 char *strnstrn(char *str1, long n1, char *str2, long n2) 01066 { 01067 int i = 0; 01068 int imax = n1-n2; 01069 01070 while(i <= imax) { 01071 if(str1[i] == str2[0] && 01072 strncmp(&str1[i], str2, n2) == 0) 01073 return &str1[i]; 01074 i++; 01075 } 01076 01077 return NULL; 01078 } 01079 #endif 01080 01081 static char USMID [] = "\n%Z%%M% %I% %G% %U%\n";