00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "defs.h"
00025 #include "names.h"
00026
00027 union
00028 {
00029 int ijunk;
00030 struct Intrpacked bits;
00031 } packed;
00032
00033 struct Intrbits
00034 {
00035 char intrgroup ;
00036 char intrstuff ;
00037 char intrno ;
00038 char dblcmplx;
00039 char dblintrno;
00040 char extflag;
00041 };
00042
00043
00044
00045 LOCAL struct Intrblock
00046 {
00047 char intrfname[8];
00048 struct Intrbits intrval;
00049 } intrtab[ ] =
00050 {
00051 "int", { INTRCONV, TYLONG },
00052 "real", { INTRCONV, TYREAL, 1 },
00053
00054 "dble", { INTRCONV, TYDREAL },
00055 "dreal", { INTRCONV, TYDREAL, 0, 0, 0, 1 },
00056 "cmplx", { INTRCONV, TYCOMPLEX },
00057 "dcmplx", { INTRCONV, TYDCOMPLEX, 0, 1 },
00058 "ifix", { INTRCONV, TYLONG },
00059 "idint", { INTRCONV, TYLONG },
00060 "float", { INTRCONV, TYREAL },
00061 "dfloat", { INTRCONV, TYDREAL },
00062 "sngl", { INTRCONV, TYREAL },
00063 "ichar", { INTRCONV, TYLONG },
00064 "iachar", { INTRCONV, TYLONG },
00065 "char", { INTRCONV, TYCHAR },
00066 "achar", { INTRCONV, TYCHAR },
00067
00068
00069
00070
00071
00072 "max", { INTRMAX, TYUNKNOWN },
00073 "max0", { INTRMAX, TYLONG },
00074 "amax0", { INTRMAX, TYREAL },
00075 "max1", { INTRMAX, TYLONG },
00076 "amax1", { INTRMAX, TYREAL },
00077 "dmax1", { INTRMAX, TYDREAL },
00078
00079 "and", { INTRBOOL, TYUNKNOWN, OPBITAND },
00080 "or", { INTRBOOL, TYUNKNOWN, OPBITOR },
00081 "xor", { INTRBOOL, TYUNKNOWN, OPBITXOR },
00082 "not", { INTRBOOL, TYUNKNOWN, OPBITNOT },
00083 "lshift", { INTRBOOL, TYUNKNOWN, OPLSHIFT },
00084 "rshift", { INTRBOOL, TYUNKNOWN, OPRSHIFT },
00085
00086 "min", { INTRMIN, TYUNKNOWN },
00087 "min0", { INTRMIN, TYLONG },
00088 "amin0", { INTRMIN, TYREAL },
00089 "min1", { INTRMIN, TYLONG },
00090 "amin1", { INTRMIN, TYREAL },
00091 "dmin1", { INTRMIN, TYDREAL },
00092
00093 "aint", { INTRGEN, 2, 0 },
00094 "dint", { INTRSPEC, TYDREAL, 1 },
00095
00096 "anint", { INTRGEN, 2, 2 },
00097 "dnint", { INTRSPEC, TYDREAL, 3 },
00098
00099 "nint", { INTRGEN, 4, 4 },
00100 "idnint", { INTRGEN, 2, 6 },
00101
00102 "abs", { INTRGEN, 6, 8 },
00103 "iabs", { INTRGEN, 2, 9 },
00104 "dabs", { INTRSPEC, TYDREAL, 11 },
00105 "cabs", { INTRSPEC, TYREAL, 12, 0, 13 },
00106 "zabs", { INTRSPEC, TYDREAL, 13, 1 },
00107
00108 "mod", { INTRGEN, 4, 14 },
00109 "amod", { INTRSPEC, TYREAL, 16, 0, 17 },
00110 "dmod", { INTRSPEC, TYDREAL, 17 },
00111
00112 "sign", { INTRGEN, 4, 18 },
00113 "isign", { INTRGEN, 2, 19 },
00114 "dsign", { INTRSPEC, TYDREAL, 21 },
00115
00116 "dim", { INTRGEN, 4, 22 },
00117 "idim", { INTRGEN, 2, 23 },
00118 "ddim", { INTRSPEC, TYDREAL, 25 },
00119
00120 "dprod", { INTRSPEC, TYDREAL, 26 },
00121
00122 "len", { INTRSPEC, TYLONG, 27 },
00123 "index", { INTRSPEC, TYLONG, 29 },
00124
00125 "imag", { INTRGEN, 2, 31 },
00126 "aimag", { INTRSPEC, TYREAL, 31, 0, 32 },
00127 "dimag", { INTRSPEC, TYDREAL, 32 },
00128
00129 "conjg", { INTRGEN, 2, 33 },
00130 "dconjg", { INTRSPEC, TYDCOMPLEX, 34, 1 },
00131
00132 "sqrt", { INTRGEN, 4, 35 },
00133 "dsqrt", { INTRSPEC, TYDREAL, 36 },
00134 "csqrt", { INTRSPEC, TYCOMPLEX, 37, 0, 38 },
00135 "zsqrt", { INTRSPEC, TYDCOMPLEX, 38, 1 },
00136
00137 "exp", { INTRGEN, 4, 39 },
00138 "dexp", { INTRSPEC, TYDREAL, 40 },
00139 "cexp", { INTRSPEC, TYCOMPLEX, 41, 0, 42 },
00140 "zexp", { INTRSPEC, TYDCOMPLEX, 42, 1 },
00141
00142 "log", { INTRGEN, 4, 43 },
00143 "alog", { INTRSPEC, TYREAL, 43, 0, 44 },
00144 "dlog", { INTRSPEC, TYDREAL, 44 },
00145 "clog", { INTRSPEC, TYCOMPLEX, 45, 0, 46 },
00146 "zlog", { INTRSPEC, TYDCOMPLEX, 46, 1 },
00147
00148 "log10", { INTRGEN, 2, 47 },
00149 "alog10", { INTRSPEC, TYREAL, 47, 0, 48 },
00150 "dlog10", { INTRSPEC, TYDREAL, 48 },
00151
00152 "sin", { INTRGEN, 4, 49 },
00153 "dsin", { INTRSPEC, TYDREAL, 50 },
00154 "csin", { INTRSPEC, TYCOMPLEX, 51, 0, 52 },
00155 "zsin", { INTRSPEC, TYDCOMPLEX, 52, 1 },
00156
00157 "cos", { INTRGEN, 4, 53 },
00158 "dcos", { INTRSPEC, TYDREAL, 54 },
00159 "ccos", { INTRSPEC, TYCOMPLEX, 55, 0, 56 },
00160 "zcos", { INTRSPEC, TYDCOMPLEX, 56, 1 },
00161
00162 "tan", { INTRGEN, 2, 57 },
00163 "dtan", { INTRSPEC, TYDREAL, 58 },
00164
00165 "asin", { INTRGEN, 2, 59 },
00166 "dasin", { INTRSPEC, TYDREAL, 60 },
00167
00168 "acos", { INTRGEN, 2, 61 },
00169 "dacos", { INTRSPEC, TYDREAL, 62 },
00170
00171 "atan", { INTRGEN, 2, 63 },
00172 "datan", { INTRSPEC, TYDREAL, 64 },
00173
00174 "atan2", { INTRGEN, 2, 65 },
00175 "datan2", { INTRSPEC, TYDREAL, 66 },
00176
00177 "sinh", { INTRGEN, 2, 67 },
00178 "dsinh", { INTRSPEC, TYDREAL, 68 },
00179
00180 "cosh", { INTRGEN, 2, 69 },
00181 "dcosh", { INTRSPEC, TYDREAL, 70 },
00182
00183 "tanh", { INTRGEN, 2, 71 },
00184 "dtanh", { INTRSPEC, TYDREAL, 72 },
00185
00186 "lge", { INTRSPEC, TYLOGICAL, 73},
00187 "lgt", { INTRSPEC, TYLOGICAL, 75},
00188 "lle", { INTRSPEC, TYLOGICAL, 77},
00189 "llt", { INTRSPEC, TYLOGICAL, 79},
00190
00191 #if 0
00192 "epbase", { INTRCNST, 4, 0 },
00193 "epprec", { INTRCNST, 4, 4 },
00194 "epemin", { INTRCNST, 2, 8 },
00195 "epemax", { INTRCNST, 2, 10 },
00196 "eptiny", { INTRCNST, 2, 12 },
00197 "ephuge", { INTRCNST, 4, 14 },
00198 "epmrsp", { INTRCNST, 2, 18 },
00199 #endif
00200
00201 "fpexpn", { INTRGEN, 4, 81 },
00202 "fpabsp", { INTRGEN, 2, 85 },
00203 "fprrsp", { INTRGEN, 2, 87 },
00204 "fpfrac", { INTRGEN, 2, 89 },
00205 "fpmake", { INTRGEN, 2, 91 },
00206 "fpscal", { INTRGEN, 2, 93 },
00207
00208 "cdabs", { INTRSPEC, TYDREAL, 13, 1, 0, 1 },
00209 "cdsqrt", { INTRSPEC, TYDCOMPLEX, 38, 1, 0, 1 },
00210 "cdexp", { INTRSPEC, TYDCOMPLEX, 42, 1, 0, 1 },
00211 "cdlog", { INTRSPEC, TYDCOMPLEX, 46, 1, 0, 1 },
00212 "cdsin", { INTRSPEC, TYDCOMPLEX, 52, 1, 0, 1 },
00213 "cdcos", { INTRSPEC, TYDCOMPLEX, 56, 1, 0, 1 },
00214
00215 "iand", { INTRBOOL, TYUNKNOWN, OPBITAND, 0, 0, 2 },
00216 "ior", { INTRBOOL, TYUNKNOWN, OPBITOR, 0, 0, 2 },
00217 "ieor", { INTRBOOL, TYUNKNOWN, OPBITXOR, 0, 0, 2 },
00218
00219 "btest", { INTRBGEN, TYLOGICAL, OPBITTEST,0, 0, 2 },
00220 "ibclr", { INTRBGEN, TYUNKNOWN, OPBITCLR, 0, 0, 2 },
00221 "ibset", { INTRBGEN, TYUNKNOWN, OPBITSET, 0, 0, 2 },
00222 "ibits", { INTRBGEN, TYUNKNOWN, OPBITBITS,0, 0, 2 },
00223 "ishft", { INTRBGEN, TYUNKNOWN, OPBITSH, 0, 0, 2 },
00224 "ishftc", { INTRBGEN, TYUNKNOWN, OPBITSHC, 0, 0, 2 },
00225
00226 "" };
00227
00228
00229 LOCAL struct Specblock
00230 {
00231 char atype;
00232
00233 char rtype;
00234 char nargs;
00235 char spxname[8];
00236 char othername;
00237 } spectab[ ] =
00238 {
00239 { TYREAL,TYREAL,1,"r_int" },
00240 { TYDREAL,TYDREAL,1,"d_int" },
00241
00242 { TYREAL,TYREAL,1,"r_nint" },
00243 { TYDREAL,TYDREAL,1,"d_nint" },
00244
00245 { TYREAL,TYSHORT,1,"h_nint" },
00246 { TYREAL,TYLONG,1,"i_nint" },
00247
00248 { TYDREAL,TYSHORT,1,"h_dnnt" },
00249 { TYDREAL,TYLONG,1,"i_dnnt" },
00250
00251 { TYREAL,TYREAL,1,"r_abs" },
00252 { TYSHORT,TYSHORT,1,"h_abs" },
00253 { TYLONG,TYLONG,1,"i_abs" },
00254 { TYDREAL,TYDREAL,1,"d_abs" },
00255 { TYCOMPLEX,TYREAL,1,"c_abs" },
00256 { TYDCOMPLEX,TYDREAL,1,"z_abs" },
00257
00258 { TYSHORT,TYSHORT,2,"h_mod" },
00259 { TYLONG,TYLONG,2,"i_mod" },
00260 { TYREAL,TYREAL,2,"r_mod" },
00261 { TYDREAL,TYDREAL,2,"d_mod" },
00262
00263 { TYREAL,TYREAL,2,"r_sign" },
00264 { TYSHORT,TYSHORT,2,"h_sign" },
00265 { TYLONG,TYLONG,2,"i_sign" },
00266 { TYDREAL,TYDREAL,2,"d_sign" },
00267
00268 { TYREAL,TYREAL,2,"r_dim" },
00269 { TYSHORT,TYSHORT,2,"h_dim" },
00270 { TYLONG,TYLONG,2,"i_dim" },
00271 { TYDREAL,TYDREAL,2,"d_dim" },
00272
00273 { TYREAL,TYDREAL,2,"d_prod" },
00274
00275 { TYCHAR,TYSHORT,1,"h_len" },
00276 { TYCHAR,TYLONG,1,"i_len" },
00277
00278 { TYCHAR,TYSHORT,2,"h_indx" },
00279 { TYCHAR,TYLONG,2,"i_indx" },
00280
00281 { TYCOMPLEX,TYREAL,1,"r_imag" },
00282 { TYDCOMPLEX,TYDREAL,1,"d_imag" },
00283 { TYCOMPLEX,TYCOMPLEX,1,"r_cnjg" },
00284 { TYDCOMPLEX,TYDCOMPLEX,1,"d_cnjg" },
00285
00286 { TYREAL,TYREAL,1,"r_sqrt", 1 },
00287 { TYDREAL,TYDREAL,1,"d_sqrt", 1 },
00288 { TYCOMPLEX,TYCOMPLEX,1,"c_sqrt" },
00289 { TYDCOMPLEX,TYDCOMPLEX,1,"z_sqrt" },
00290
00291 { TYREAL,TYREAL,1,"r_exp", 2 },
00292 { TYDREAL,TYDREAL,1,"d_exp", 2 },
00293 { TYCOMPLEX,TYCOMPLEX,1,"c_exp" },
00294 { TYDCOMPLEX,TYDCOMPLEX,1,"z_exp" },
00295
00296 { TYREAL,TYREAL,1,"r_log", 3 },
00297 { TYDREAL,TYDREAL,1,"d_log", 3 },
00298 { TYCOMPLEX,TYCOMPLEX,1,"c_log" },
00299 { TYDCOMPLEX,TYDCOMPLEX,1,"z_log" },
00300
00301 { TYREAL,TYREAL,1,"r_lg10" },
00302 { TYDREAL,TYDREAL,1,"d_lg10" },
00303
00304 { TYREAL,TYREAL,1,"r_sin", 4 },
00305 { TYDREAL,TYDREAL,1,"d_sin", 4 },
00306 { TYCOMPLEX,TYCOMPLEX,1,"c_sin" },
00307 { TYDCOMPLEX,TYDCOMPLEX,1,"z_sin" },
00308
00309 { TYREAL,TYREAL,1,"r_cos", 5 },
00310 { TYDREAL,TYDREAL,1,"d_cos", 5 },
00311 { TYCOMPLEX,TYCOMPLEX,1,"c_cos" },
00312 { TYDCOMPLEX,TYDCOMPLEX,1,"z_cos" },
00313
00314 { TYREAL,TYREAL,1,"r_tan", 6 },
00315 { TYDREAL,TYDREAL,1,"d_tan", 6 },
00316
00317 { TYREAL,TYREAL,1,"r_asin", 7 },
00318 { TYDREAL,TYDREAL,1,"d_asin", 7 },
00319
00320 { TYREAL,TYREAL,1,"r_acos", 8 },
00321 { TYDREAL,TYDREAL,1,"d_acos", 8 },
00322
00323 { TYREAL,TYREAL,1,"r_atan", 9 },
00324 { TYDREAL,TYDREAL,1,"d_atan", 9 },
00325
00326 { TYREAL,TYREAL,2,"r_atn2", 10 },
00327 { TYDREAL,TYDREAL,2,"d_atn2", 10 },
00328
00329 { TYREAL,TYREAL,1,"r_sinh", 11 },
00330 { TYDREAL,TYDREAL,1,"d_sinh", 11 },
00331
00332 { TYREAL,TYREAL,1,"r_cosh", 12 },
00333 { TYDREAL,TYDREAL,1,"d_cosh", 12 },
00334
00335 { TYREAL,TYREAL,1,"r_tanh", 13 },
00336 { TYDREAL,TYDREAL,1,"d_tanh", 13 },
00337
00338 { TYCHAR,TYLOGICAL,2,"hl_ge" },
00339 { TYCHAR,TYLOGICAL,2,"l_ge" },
00340
00341 { TYCHAR,TYLOGICAL,2,"hl_gt" },
00342 { TYCHAR,TYLOGICAL,2,"l_gt" },
00343
00344 { TYCHAR,TYLOGICAL,2,"hl_le" },
00345 { TYCHAR,TYLOGICAL,2,"l_le" },
00346
00347 { TYCHAR,TYLOGICAL,2,"hl_lt" },
00348 { TYCHAR,TYLOGICAL,2,"l_lt" },
00349
00350 { TYREAL,TYSHORT,1,"hr_expn" },
00351 { TYREAL,TYLONG,1,"ir_expn" },
00352 { TYDREAL,TYSHORT,1,"hd_expn" },
00353 { TYDREAL,TYLONG,1,"id_expn" },
00354
00355 { TYREAL,TYREAL,1,"r_absp" },
00356 { TYDREAL,TYDREAL,1,"d_absp" },
00357
00358 { TYREAL,TYDREAL,1,"r_rrsp" },
00359 { TYDREAL,TYDREAL,1,"d_rrsp" },
00360
00361 { TYREAL,TYREAL,1,"r_frac" },
00362 { TYDREAL,TYDREAL,1,"d_frac" },
00363
00364 { TYREAL,TYREAL,2,"r_make" },
00365 { TYDREAL,TYDREAL,2,"d_make" },
00366
00367 { TYREAL,TYREAL,2,"r_scal" },
00368 { TYDREAL,TYDREAL,2,"d_scal" },
00369
00370 { 0 }
00371 } ;
00372
00373 #if 0
00374 LOCAL struct Incstblock
00375 {
00376 char atype;
00377 char rtype;
00378 char constno;
00379 } consttab[ ] =
00380 {
00381 { TYSHORT, TYLONG, 0 },
00382 { TYLONG, TYLONG, 1 },
00383 { TYREAL, TYLONG, 2 },
00384 { TYDREAL, TYLONG, 3 },
00385
00386 { TYSHORT, TYLONG, 4 },
00387 { TYLONG, TYLONG, 5 },
00388 { TYREAL, TYLONG, 6 },
00389 { TYDREAL, TYLONG, 7 },
00390
00391 { TYREAL, TYLONG, 8 },
00392 { TYDREAL, TYLONG, 9 },
00393
00394 { TYREAL, TYLONG, 10 },
00395 { TYDREAL, TYLONG, 11 },
00396
00397 { TYREAL, TYREAL, 0 },
00398 { TYDREAL, TYDREAL, 1 },
00399
00400 { TYSHORT, TYLONG, 12 },
00401 { TYLONG, TYLONG, 13 },
00402 { TYREAL, TYREAL, 2 },
00403 { TYDREAL, TYDREAL, 3 },
00404
00405 { TYREAL, TYREAL, 4 },
00406 { TYDREAL, TYDREAL, 5 }
00407 };
00408 #endif
00409
00410 char *callbyvalue[ ] =
00411 {0,
00412 "sqrt",
00413 "exp",
00414 "log",
00415 "sin",
00416 "cos",
00417 "tan",
00418 "asin",
00419 "acos",
00420 "atan",
00421 "atan2",
00422 "sinh",
00423 "cosh",
00424 "tanh"
00425 };
00426
00427 void
00428 r8fix(Void)
00429 {
00430 register struct Intrblock *I;
00431 register struct Specblock *S;
00432
00433 for(I = intrtab; I->intrfname[0]; I++)
00434 if (I->intrval.intrgroup != INTRGEN)
00435 switch(I->intrval.intrstuff) {
00436 case TYREAL:
00437 I->intrval.intrstuff = TYDREAL;
00438 I->intrval.intrno = I->intrval.dblintrno;
00439 break;
00440 case TYCOMPLEX:
00441 I->intrval.intrstuff = TYDCOMPLEX;
00442 I->intrval.intrno = I->intrval.dblintrno;
00443 I->intrval.dblcmplx = 1;
00444 }
00445
00446 for(S = spectab; S->atype; S++)
00447 switch(S->atype) {
00448 case TYCOMPLEX:
00449 S->atype = TYDCOMPLEX;
00450 if (S->rtype == TYREAL)
00451 S->rtype = TYDREAL;
00452 else if (S->rtype == TYCOMPLEX)
00453 S->rtype = TYDCOMPLEX;
00454 switch(S->spxname[0]) {
00455 case 'r':
00456 S->spxname[0] = 'd';
00457 break;
00458 case 'c':
00459 S->spxname[0] = 'z';
00460 break;
00461 default:
00462 Fatal("r8fix bug");
00463 }
00464 break;
00465 case TYREAL:
00466 S->atype = TYDREAL;
00467 switch(S->rtype) {
00468 case TYREAL:
00469 S->rtype = TYDREAL;
00470 if (S->spxname[0] != 'r')
00471 Fatal("r8fix bug");
00472 S->spxname[0] = 'd';
00473 case TYDREAL:
00474 break;
00475
00476 case TYSHORT:
00477 if (!strcmp(S->spxname, "hr_expn"))
00478 S->spxname[1] = 'd';
00479 else if (!strcmp(S->spxname, "h_nint"))
00480 strcpy(S->spxname, "h_dnnt");
00481 else Fatal("r8fix bug");
00482 break;
00483
00484 case TYLONG:
00485 if (!strcmp(S->spxname, "ir_expn"))
00486 S->spxname[1] = 'd';
00487 else if (!strcmp(S->spxname, "i_nint"))
00488 strcpy(S->spxname, "i_dnnt");
00489 else Fatal("r8fix bug");
00490 break;
00491
00492 default:
00493 Fatal("r8fix bug");
00494 }
00495 }
00496 }
00497
00498 static expptr
00499 #ifdef KR_headers
00500 foldminmax(ismin, argsp) int ismin; struct Listblock *argsp;
00501 #else
00502 foldminmax(int ismin, struct Listblock *argsp)
00503 #endif
00504 {
00505 #ifndef NO_LONG_LONG
00506 Llong cq, cq1;
00507 #endif
00508 Constp h;
00509 double cd, cd1;
00510 ftnint ci;
00511 int mtype;
00512 struct Chain *cp, *cpx;
00513
00514 mtype = argsp->vtype;
00515 cp = cpx = argsp->listp;
00516 h = &((expptr)cp->datap)->constblock;
00517 #ifndef NO_LONG_LONG
00518 if (mtype == TYQUAD) {
00519 cq = h->vtype == TYQUAD ? h->Const.cq : h->Const.ci;
00520 while(cp = cp->nextp) {
00521 h = &((expptr)cp->datap)->constblock;
00522 cq1 = h->vtype == TYQUAD ? h->Const.cq : h->Const.ci;
00523 if (ismin) {
00524 if (cq > cq1) {
00525 cq = cq1;
00526 cpx = cp;
00527 }
00528 }
00529 else {
00530 if (cq < cq1) {
00531 cq = cq1;
00532 cpx = cp;
00533 }
00534 }
00535 }
00536 }
00537 else
00538 #endif
00539 if (ISINT(mtype)) {
00540 ci = h->Const.ci;
00541 if (ismin)
00542 while(cp = cp->nextp) {
00543 h = &((expptr)cp->datap)->constblock;
00544 if (ci > h->Const.ci) {
00545 ci = h->Const.ci;
00546 cpx = cp;
00547 }
00548 }
00549 else
00550 while(cp = cp->nextp) {
00551 h = &((expptr)cp->datap)->constblock;
00552 if (ci < h->Const.ci) {
00553 ci = h->Const.ci;
00554 cpx = cp;
00555 }
00556 }
00557 }
00558 else {
00559 if (ISREAL(h->vtype))
00560 cd = h->vstg ? atof(h->Const.cds[0]) : h->Const.cd[0];
00561 #ifndef NO_LONG_LONG
00562 else if (h->vtype == TYQUAD)
00563 cd = (double)(h->Const.cq);
00564 #endif
00565 else
00566 cd = h->Const.ci;
00567 while(cp = cp->nextp) {
00568 h = &((expptr)cp->datap)->constblock;
00569 if (ISREAL(h->vtype))
00570 cd1 = h->vstg ? atof(h->Const.cds[0])
00571 : h->Const.cd[0];
00572 #ifndef NO_LONG_LONG
00573 else if (h->vtype == TYQUAD)
00574 cd1 = (double)(h->Const.cq);
00575 #endif
00576 else
00577 cd1 = h->Const.ci;
00578 if (ismin) {
00579 if (cd > cd1) {
00580 cd = cd1;
00581 cpx = cp;
00582 }
00583 }
00584 else {
00585 if (cd < cd1) {
00586 cd = cd1;
00587 cpx = cp;
00588 }
00589 }
00590 }
00591 }
00592 h = &((expptr)cpx->datap)->constblock;
00593 cpx->datap = 0;
00594 frexpr((tagptr)argsp);
00595 if (h->vtype != mtype)
00596 return mkconv(mtype, (expptr)h);
00597 return (expptr)h;
00598 }
00599
00600
00601 expptr
00602 #ifdef KR_headers
00603 intrcall(np, argsp, nargs)
00604 Namep np;
00605 struct Listblock *argsp;
00606 int nargs;
00607 #else
00608 intrcall(Namep np, struct Listblock *argsp, int nargs)
00609 #endif
00610 {
00611 int i, rettype;
00612 ftnint k;
00613 Addrp ap;
00614 register struct Specblock *sp;
00615 register struct Chain *cp;
00616 expptr q, ep;
00617 int constargs, mtype, op;
00618 int f1field, f2field, f3field;
00619 char *s;
00620 static char bit_bits[] = "?bit_bits",
00621 bit_shift[] = "?bit_shift",
00622 bit_cshift[] = "?bit_cshift";
00623 static char *bitop[3] = { bit_bits, bit_shift, bit_cshift };
00624 static int t_pref[2] = { 'l', 'q' };
00625
00626 packed.ijunk = np->vardesc.varno;
00627 f1field = packed.bits.f1;
00628 f2field = packed.bits.f2;
00629 f3field = packed.bits.f3;
00630 if(nargs == 0)
00631 goto badnargs;
00632
00633 mtype = 0;
00634 constargs = 1;
00635 for(cp = argsp->listp ; cp ; cp = cp->nextp)
00636 {
00637 ep = (expptr)cp->datap;
00638 if (!ISCONST(ep))
00639 constargs = 0;
00640 else if( ep->headblock.vtype==TYSHORT )
00641 cp->datap = (char *) mkconv(tyint, ep);
00642 mtype = maxtype(mtype, ep->headblock.vtype);
00643 }
00644
00645 switch(f1field)
00646 {
00647 case INTRBGEN:
00648 op = f3field;
00649 if( ! ONEOF(mtype, MSKINT) )
00650 goto badtype;
00651 if (op < OPBITBITS) {
00652 if(nargs != 2)
00653 goto badnargs;
00654 if (op != OPBITTEST) {
00655 #ifdef TYQUAD
00656 if (mtype == TYQUAD)
00657 op += 2;
00658 #endif
00659 goto intrbool2;
00660 }
00661 q = mkexpr(op, (expptr)argsp->listp->datap,
00662 (expptr)argsp->listp->nextp->datap);
00663 q->exprblock.vtype = TYLOGICAL;
00664 goto intrbool2a;
00665 }
00666 if (nargs != 2 && (nargs != 3 || op == OPBITSH))
00667 goto badnargs;
00668 cp = argsp->listp;
00669 ep = (expptr)cp->datap;
00670 if (ep->headblock.vtype < TYLONG)
00671 cp->datap = (char *)mkconv(TYLONG, ep);
00672 while(cp->nextp) {
00673 cp = cp->nextp;
00674 ep = (expptr)cp->datap;
00675 if (ep->headblock.vtype != TYLONG)
00676 cp->datap = (char *)mkconv(TYLONG, ep);
00677 }
00678 if (op == OPBITSH) {
00679 ep = (expptr)argsp->listp->nextp->datap;
00680 if (ISCONST(ep)) {
00681 if ((k = ep->constblock.Const.ci) < 0) {
00682 q = (expptr)argsp->listp->datap;
00683 if (ISCONST(q)) {
00684 ep->constblock.Const.ci = -k;
00685 op = OPRSHIFT;
00686 goto intrbool2;
00687 }
00688 }
00689 else {
00690 op = OPLSHIFT;
00691 goto intrbool2;
00692 }
00693 }
00694 }
00695 else if (nargs == 2) {
00696 if (op == OPBITBITS)
00697 goto badnargs;
00698 cp->nextp = mkchain((char*)ICON(-1), 0);
00699 }
00700 ep = (expptr)argsp->listp->datap;
00701 i = ep->headblock.vtype;
00702 s = bitop[op - OPBITBITS];
00703 *s = t_pref[i - TYLONG];
00704 ap = builtin(i, s, 1);
00705 return fixexpr((Exprp)
00706 mkexpr(OPCCALL, (expptr)ap, (expptr)argsp) );
00707
00708 case INTRBOOL:
00709 op = f3field;
00710 if( ! ONEOF(mtype, MSKINT|MSKLOGICAL) )
00711 goto badtype;
00712 if(op == OPBITNOT)
00713 {
00714 if(nargs != 1)
00715 goto badnargs;
00716 q = mkexpr(OPBITNOT, (expptr)argsp->listp->datap, ENULL);
00717 }
00718 else
00719 {
00720 if(nargs != 2)
00721 goto badnargs;
00722 intrbool2:
00723 q = mkexpr(op, (expptr)argsp->listp->datap,
00724 (expptr)argsp->listp->nextp->datap);
00725 }
00726 intrbool2a:
00727 frchain( &(argsp->listp) );
00728 free( (charptr) argsp);
00729 return(q);
00730
00731 case INTRCONV:
00732 rettype = f2field;
00733 switch(rettype) {
00734 case TYLONG:
00735 rettype = tyint;
00736 break;
00737 case TYLOGICAL:
00738 rettype = tylog;
00739 }
00740 if( ISCOMPLEX(rettype) && nargs==2)
00741 {
00742 expptr qr, qi;
00743 qr = (expptr) argsp->listp->datap;
00744 qi = (expptr) argsp->listp->nextp->datap;
00745 if (qr->headblock.vtype == TYDREAL
00746 || qi->headblock.vtype == TYDREAL)
00747 rettype = TYDCOMPLEX;
00748 if(ISCONST(qr) && ISCONST(qi))
00749 q = mkcxcon(qr,qi);
00750 else q = mkexpr(OPCONV,mkconv(rettype-2,qr),
00751 mkconv(rettype-2,qi));
00752 }
00753 else if(nargs == 1) {
00754 if (f3field && ((Exprp)argsp->listp->datap)->vtype
00755 == TYDCOMPLEX)
00756 rettype = TYDREAL;
00757 q = mkconv(rettype+100, (expptr)argsp->listp->datap);
00758 if (q->tag == TADDR)
00759 q->addrblock.parenused = 1;
00760 }
00761 else goto badnargs;
00762
00763 q->headblock.vtype = rettype;
00764 frchain(&(argsp->listp));
00765 free( (charptr) argsp);
00766 return(q);
00767
00768
00769 #if 0
00770 case INTRCNST:
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798 { register struct Incstblock *cstp;
00799 extern ftnint intcon[14];
00800 extern double realcon[6];
00801
00802 cstp = consttab + f3field;
00803 for(i=0 ; i<f2field ; ++i)
00804 if(cstp->atype == mtype)
00805 goto foundconst;
00806 else
00807 ++cstp;
00808 goto badtype;
00809
00810 foundconst:
00811 switch(cstp->rtype)
00812 {
00813 case TYLONG:
00814 return(mkintcon(intcon[cstp->constno]));
00815
00816 case TYREAL:
00817 case TYDREAL:
00818 return(mkrealcon(cstp->rtype,
00819 realcon[cstp->constno]) );
00820
00821 default:
00822 Fatal("impossible intrinsic constant");
00823 }
00824 }
00825 #endif
00826
00827 case INTRGEN:
00828 sp = spectab + f3field;
00829 if(no66flag)
00830 if(sp->atype == mtype)
00831 goto specfunct;
00832 else err66("generic function");
00833
00834 for(i=0; i<f2field ; ++i)
00835 if(sp->atype == mtype)
00836 goto specfunct;
00837 else
00838 ++sp;
00839 warn1 ("bad argument type to intrinsic %s", np->fvarname);
00840
00841
00842
00843
00844
00845
00846
00847 sp = spectab + f3field;
00848 mtype = sp -> atype;
00849 goto specfunct;
00850
00851 case INTRSPEC:
00852 sp = spectab + f3field;
00853 specfunct:
00854 if(tyint==TYLONG && ONEOF(sp->rtype,M(TYSHORT)|M(TYLOGICAL))
00855 && (sp+1)->atype==sp->atype)
00856 ++sp;
00857
00858 if(nargs != sp->nargs)
00859 goto badnargs;
00860 if(mtype != sp->atype)
00861 goto badtype;
00862
00863
00864
00865
00866 fixargs (NO, argsp);
00867 cast_args (mtype, argsp -> listp);
00868
00869 if(q = Inline((int)(sp-spectab), mtype, argsp->listp))
00870 {
00871 frchain( &(argsp->listp) );
00872 free( (charptr) argsp);
00873 } else {
00874
00875 if(sp->othername) {
00876
00877
00878 ap = builtin(sp->rtype,
00879 callbyvalue[sp->othername], 1);
00880 q = fixexpr((Exprp)
00881 mkexpr(OPCCALL, (expptr)ap, (expptr)argsp) );
00882 } else {
00883 fixargs(YES, argsp);
00884 ap = builtin(sp->rtype, sp->spxname, 0);
00885 q = fixexpr((Exprp)
00886 mkexpr(OPCALL, (expptr)ap, (expptr)argsp) );
00887 }
00888 }
00889 return(q);
00890
00891 case INTRMIN:
00892 case INTRMAX:
00893 if(nargs < 2)
00894 goto badnargs;
00895 if( ! ONEOF(mtype, MSKINT|MSKREAL) )
00896 goto badtype;
00897 argsp->vtype = mtype;
00898 if (constargs)
00899 q = foldminmax(f1field==INTRMIN, argsp);
00900 else
00901 q = mkexpr(f1field==INTRMIN ? OPMIN : OPMAX,
00902 (expptr)argsp, ENULL);
00903
00904 q->headblock.vtype = mtype;
00905 rettype = f2field;
00906 if(rettype == TYLONG)
00907 rettype = tyint;
00908 else if(rettype == TYUNKNOWN)
00909 rettype = mtype;
00910 return( mkconv(rettype, q) );
00911
00912 default:
00913 fatali("intrcall: bad intrgroup %d", f1field);
00914 }
00915 badnargs:
00916 errstr("bad number of arguments to intrinsic %s", np->fvarname);
00917 goto bad;
00918
00919 badtype:
00920 errstr("bad argument type to intrinsic %s", np->fvarname);
00921
00922 bad:
00923 return( errnode() );
00924 }
00925
00926
00927
00928 int
00929 #ifdef KR_headers
00930 intrfunct(s)
00931 char *s;
00932 #else
00933 intrfunct(char *s)
00934 #endif
00935 {
00936 register struct Intrblock *p;
00937 int i;
00938 extern int intr_omit;
00939
00940 for(p = intrtab; p->intrval.intrgroup!=INTREND ; ++p)
00941 {
00942 if( !strcmp(s, p->intrfname) )
00943 {
00944 if (i = p->intrval.extflag) {
00945 if (i & intr_omit)
00946 return 0;
00947 if (noextflag)
00948 errext(s);
00949 }
00950 packed.bits.f1 = p->intrval.intrgroup;
00951 packed.bits.f2 = p->intrval.intrstuff;
00952 packed.bits.f3 = p->intrval.intrno;
00953 packed.bits.f4 = p->intrval.dblcmplx;
00954 return(packed.ijunk);
00955 }
00956 }
00957
00958 return(0);
00959 }
00960
00961
00962
00963
00964
00965 Addrp
00966 #ifdef KR_headers
00967 intraddr(np)
00968 Namep np;
00969 #else
00970 intraddr(Namep np)
00971 #endif
00972 {
00973 Addrp q;
00974 register struct Specblock *sp;
00975 int f3field;
00976
00977 if(np->vclass!=CLPROC || np->vprocclass!=PINTRINSIC)
00978 fatalstr("intraddr: %s is not intrinsic", np->fvarname);
00979 packed.ijunk = np->vardesc.varno;
00980 f3field = packed.bits.f3;
00981
00982 switch(packed.bits.f1)
00983 {
00984 case INTRGEN:
00985
00986 if(f3field==31 || f3field==43 || f3field==47)
00987 goto bad;
00988
00989 case INTRSPEC:
00990 sp = spectab + f3field;
00991 if (tyint == TYLONG
00992 && (sp->rtype == TYSHORT || sp->rtype == TYLOGICAL))
00993 ++sp;
00994 q = builtin(sp->rtype, sp->spxname,
00995 sp->othername ? 1 : 0);
00996 return(q);
00997
00998 case INTRCONV:
00999 case INTRMIN:
01000 case INTRMAX:
01001 case INTRBOOL:
01002 case INTRCNST:
01003 case INTRBGEN:
01004 bad:
01005 errstr("cannot pass %s as actual", np->fvarname);
01006 return((Addrp)errnode());
01007 }
01008 fatali("intraddr: impossible f1=%d\n", (int) packed.bits.f1);
01009 return 0;
01010 }
01011
01012
01013
01014 void
01015 #ifdef KR_headers
01016 cast_args(maxtype, args)
01017 int maxtype;
01018 chainp args;
01019 #else
01020 cast_args(int maxtype, chainp args)
01021 #endif
01022 {
01023 for (; args; args = args -> nextp) {
01024 expptr e = (expptr) args->datap;
01025 if (e -> headblock.vtype != maxtype)
01026 if (e -> tag == TCONST)
01027 args->datap = (char *) mkconv(maxtype, e);
01028 else {
01029 Addrp temp = mktmp(maxtype, ENULL);
01030
01031 puteq(cpexpr((expptr)temp), e);
01032 args->datap = (char *)temp;
01033 }
01034 }
01035 }
01036
01037
01038
01039 expptr
01040 #ifdef KR_headers
01041 Inline(fno, type, args)
01042 int fno;
01043 int type;
01044 struct Chain *args;
01045 #else
01046 Inline(int fno, int type, struct Chain *args)
01047 #endif
01048 {
01049 register expptr q, t, t1;
01050
01051 switch(fno)
01052 {
01053 case 8:
01054 case 9:
01055 case 10:
01056 case 11:
01057 if( addressable(q = (expptr) args->datap) )
01058 {
01059 t = q;
01060 q = NULL;
01061 }
01062 else
01063 t = (expptr) mktmp(type,ENULL);
01064 t1 = mkexpr(type == TYREAL && forcedouble ? OPDABS : OPABS,
01065 cpexpr(t), ENULL);
01066 if(q)
01067 t1 = mkexpr(OPCOMMA, mkexpr(OPASSIGN, cpexpr(t),q), t1);
01068 frexpr(t);
01069 return(t1);
01070
01071 case 26:
01072 q = mkexpr(OPSTAR, mkconv(TYDREAL,(expptr)args->datap),
01073 (expptr)args->nextp->datap);
01074 return(q);
01075
01076 case 27:
01077 q = (expptr) cpexpr(((tagptr)args->datap)->headblock.vleng);
01078 frexpr((expptr)args->datap);
01079 return mkconv(tyioint, q);
01080
01081 case 14:
01082 case 15:
01083 return mkexpr(OPMOD, (expptr) args->datap,
01084 (expptr) args->nextp->datap);
01085 }
01086 return(NULL);
01087 }