home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************
- Copyright 1990 by AT&T Bell Laboratories and Bellcore.
-
- Permission to use, copy, modify, and distribute this software
- and its documentation for any purpose and without fee is hereby
- granted, provided that the above copyright notice appear in all
- copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the names of AT&T Bell Laboratories or
- Bellcore or any of their entities not be used in advertising or
- publicity pertaining to distribution of the software without
- specific, written prior permission.
-
- AT&T and Bellcore disclaim all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall AT&T or Bellcore be liable for
- any special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
- ****************************************************************/
-
- #include "defs.h"
- #include "names.h"
-
- void cast_args ();
-
- union
- {
- int ijunk;
- struct Intrpacked bits;
- } packed;
-
- struct Intrbits
- {
- char intrgroup /* :3 */;
- char intrstuff /* result type or number of generics */;
- char intrno /* :7 */;
- char dblcmplx;
- char dblintrno; /* for -r8 */
- };
-
- /* List of all intrinsic functions. */
-
- LOCAL struct Intrblock
- {
- char intrfname[8];
- struct Intrbits intrval;
- } intrtab[ ] =
- {
- "int", { INTRCONV, TYLONG },
- "real", { INTRCONV, TYREAL, 1 },
- /* 1 ==> real(TYDCOMPLEX) yields TYDREAL */
- "dble", { INTRCONV, TYDREAL },
- "cmplx", { INTRCONV, TYCOMPLEX },
- "dcmplx", { INTRCONV, TYDCOMPLEX, 0, 1 },
- "ifix", { INTRCONV, TYLONG },
- "idint", { INTRCONV, TYLONG },
- "float", { INTRCONV, TYREAL },
- "dfloat", { INTRCONV, TYDREAL },
- "sngl", { INTRCONV, TYREAL },
- "ichar", { INTRCONV, TYLONG },
- "iachar", { INTRCONV, TYLONG },
- "char", { INTRCONV, TYCHAR },
- "achar", { INTRCONV, TYCHAR },
-
- /* any MAX or MIN can be used with any types; the compiler will cast them
- correctly. So rules against bad syntax in these expressions are not
- enforced */
-
- "max", { INTRMAX, TYUNKNOWN },
- "max0", { INTRMAX, TYLONG },
- "amax0", { INTRMAX, TYREAL },
- "max1", { INTRMAX, TYLONG },
- "amax1", { INTRMAX, TYREAL },
- "dmax1", { INTRMAX, TYDREAL },
-
- "and", { INTRBOOL, TYUNKNOWN, OPBITAND },
- "or", { INTRBOOL, TYUNKNOWN, OPBITOR },
- "xor", { INTRBOOL, TYUNKNOWN, OPBITXOR },
- "not", { INTRBOOL, TYUNKNOWN, OPBITNOT },
- "lshift", { INTRBOOL, TYUNKNOWN, OPLSHIFT },
- "rshift", { INTRBOOL, TYUNKNOWN, OPRSHIFT },
-
- "min", { INTRMIN, TYUNKNOWN },
- "min0", { INTRMIN, TYLONG },
- "amin0", { INTRMIN, TYREAL },
- "min1", { INTRMIN, TYLONG },
- "amin1", { INTRMIN, TYREAL },
- "dmin1", { INTRMIN, TYDREAL },
-
- "aint", { INTRGEN, 2, 0 },
- "dint", { INTRSPEC, TYDREAL, 1 },
-
- "anint", { INTRGEN, 2, 2 },
- "dnint", { INTRSPEC, TYDREAL, 3 },
-
- "nint", { INTRGEN, 4, 4 },
- "idnint", { INTRGEN, 2, 6 },
-
- "abs", { INTRGEN, 6, 8 },
- "iabs", { INTRGEN, 2, 9 },
- "dabs", { INTRSPEC, TYDREAL, 11 },
- "cabs", { INTRSPEC, TYREAL, 12, 0, 13 },
- "zabs", { INTRSPEC, TYDREAL, 13, 1 },
-
- "mod", { INTRGEN, 4, 14 },
- "amod", { INTRSPEC, TYREAL, 16, 0, 17 },
- "dmod", { INTRSPEC, TYDREAL, 17 },
-
- "sign", { INTRGEN, 4, 18 },
- "isign", { INTRGEN, 2, 19 },
- "dsign", { INTRSPEC, TYDREAL, 21 },
-
- "dim", { INTRGEN, 4, 22 },
- "idim", { INTRGEN, 2, 23 },
- "ddim", { INTRSPEC, TYDREAL, 25 },
-
- "dprod", { INTRSPEC, TYDREAL, 26 },
-
- "len", { INTRSPEC, TYLONG, 27 },
- "index", { INTRSPEC, TYLONG, 29 },
-
- "imag", { INTRGEN, 2, 31 },
- "aimag", { INTRSPEC, TYREAL, 31, 0, 32 },
- "dimag", { INTRSPEC, TYDREAL, 32 },
-
- "conjg", { INTRGEN, 2, 33 },
- "dconjg", { INTRSPEC, TYDCOMPLEX, 34, 1 },
-
- "sqrt", { INTRGEN, 4, 35 },
- "dsqrt", { INTRSPEC, TYDREAL, 36 },
- "csqrt", { INTRSPEC, TYCOMPLEX, 37, 0, 38 },
- "zsqrt", { INTRSPEC, TYDCOMPLEX, 38, 1 },
-
- "exp", { INTRGEN, 4, 39 },
- "dexp", { INTRSPEC, TYDREAL, 40 },
- "cexp", { INTRSPEC, TYCOMPLEX, 41, 0, 42 },
- "zexp", { INTRSPEC, TYDCOMPLEX, 42, 1 },
-
- "log", { INTRGEN, 4, 43 },
- "alog", { INTRSPEC, TYREAL, 43, 0, 44 },
- "dlog", { INTRSPEC, TYDREAL, 44 },
- "clog", { INTRSPEC, TYCOMPLEX, 45, 0, 46 },
- "zlog", { INTRSPEC, TYDCOMPLEX, 46, 1 },
-
- "log10", { INTRGEN, 2, 47 },
- "alog10", { INTRSPEC, TYREAL, 47, 0, 48 },
- "dlog10", { INTRSPEC, TYDREAL, 48 },
-
- "sin", { INTRGEN, 4, 49 },
- "dsin", { INTRSPEC, TYDREAL, 50 },
- "csin", { INTRSPEC, TYCOMPLEX, 51, 0, 52 },
- "zsin", { INTRSPEC, TYDCOMPLEX, 52, 1 },
-
- "cos", { INTRGEN, 4, 53 },
- "dcos", { INTRSPEC, TYDREAL, 54 },
- "ccos", { INTRSPEC, TYCOMPLEX, 55, 0, 56 },
- "zcos", { INTRSPEC, TYDCOMPLEX, 56, 1 },
-
- "tan", { INTRGEN, 2, 57 },
- "dtan", { INTRSPEC, TYDREAL, 58 },
-
- "asin", { INTRGEN, 2, 59 },
- "dasin", { INTRSPEC, TYDREAL, 60 },
-
- "acos", { INTRGEN, 2, 61 },
- "dacos", { INTRSPEC, TYDREAL, 62 },
-
- "atan", { INTRGEN, 2, 63 },
- "datan", { INTRSPEC, TYDREAL, 64 },
-
- "atan2", { INTRGEN, 2, 65 },
- "datan2", { INTRSPEC, TYDREAL, 66 },
-
- "sinh", { INTRGEN, 2, 67 },
- "dsinh", { INTRSPEC, TYDREAL, 68 },
-
- "cosh", { INTRGEN, 2, 69 },
- "dcosh", { INTRSPEC, TYDREAL, 70 },
-
- "tanh", { INTRGEN, 2, 71 },
- "dtanh", { INTRSPEC, TYDREAL, 72 },
-
- "lge", { INTRSPEC, TYLOGICAL, 73},
- "lgt", { INTRSPEC, TYLOGICAL, 75},
- "lle", { INTRSPEC, TYLOGICAL, 77},
- "llt", { INTRSPEC, TYLOGICAL, 79},
-
- #if 0
- "epbase", { INTRCNST, 4, 0 },
- "epprec", { INTRCNST, 4, 4 },
- "epemin", { INTRCNST, 2, 8 },
- "epemax", { INTRCNST, 2, 10 },
- "eptiny", { INTRCNST, 2, 12 },
- "ephuge", { INTRCNST, 4, 14 },
- "epmrsp", { INTRCNST, 2, 18 },
- #endif
-
- "fpexpn", { INTRGEN, 4, 81 },
- "fpabsp", { INTRGEN, 2, 85 },
- "fprrsp", { INTRGEN, 2, 87 },
- "fpfrac", { INTRGEN, 2, 89 },
- "fpmake", { INTRGEN, 2, 91 },
- "fpscal", { INTRGEN, 2, 93 },
-
- "" };
-
-
- LOCAL struct Specblock
- {
- char atype; /* Argument type; every arg must have
- this type */
- char rtype; /* Result type */
- char nargs; /* Number of arguments */
- char spxname[8]; /* Name of the function in Fortran */
- char othername; /* index into callbyvalue table */
- } spectab[ ] =
- {
- { TYREAL,TYREAL,1,"r_int" },
- { TYDREAL,TYDREAL,1,"d_int" },
-
- { TYREAL,TYREAL,1,"r_nint" },
- { TYDREAL,TYDREAL,1,"d_nint" },
-
- { TYREAL,TYSHORT,1,"h_nint" },
- { TYREAL,TYLONG,1,"i_nint" },
-
- { TYDREAL,TYSHORT,1,"h_dnnt" },
- { TYDREAL,TYLONG,1,"i_dnnt" },
-
- { TYREAL,TYREAL,1,"r_abs" },
- { TYSHORT,TYSHORT,1,"h_abs" },
- { TYLONG,TYLONG,1,"i_abs" },
- { TYDREAL,TYDREAL,1,"d_abs" },
- { TYCOMPLEX,TYREAL,1,"c_abs" },
- { TYDCOMPLEX,TYDREAL,1,"z_abs" },
-
- { TYSHORT,TYSHORT,2,"h_mod" },
- { TYLONG,TYLONG,2,"i_mod" },
- { TYREAL,TYREAL,2,"r_mod" },
- { TYDREAL,TYDREAL,2,"d_mod" },
-
- { TYREAL,TYREAL,2,"r_sign" },
- { TYSHORT,TYSHORT,2,"h_sign" },
- { TYLONG,TYLONG,2,"i_sign" },
- { TYDREAL,TYDREAL,2,"d_sign" },
-
- { TYREAL,TYREAL,2,"r_dim" },
- { TYSHORT,TYSHORT,2,"h_dim" },
- { TYLONG,TYLONG,2,"i_dim" },
- { TYDREAL,TYDREAL,2,"d_dim" },
-
- { TYREAL,TYDREAL,2,"d_prod" },
-
- { TYCHAR,TYSHORT,1,"h_len" },
- { TYCHAR,TYLONG,1,"i_len" },
-
- { TYCHAR,TYSHORT,2,"h_indx" },
- { TYCHAR,TYLONG,2,"i_indx" },
-
- { TYCOMPLEX,TYREAL,1,"r_imag" },
- { TYDCOMPLEX,TYDREAL,1,"d_imag" },
- { TYCOMPLEX,TYCOMPLEX,1,"r_cnjg" },
- { TYDCOMPLEX,TYDCOMPLEX,1,"d_cnjg" },
-
- { TYREAL,TYREAL,1,"r_sqrt", 1 },
- { TYDREAL,TYDREAL,1,"d_sqrt", 1 },
- { TYCOMPLEX,TYCOMPLEX,1,"c_sqrt" },
- { TYDCOMPLEX,TYDCOMPLEX,1,"z_sqrt" },
-
- { TYREAL,TYREAL,1,"r_exp", 2 },
- { TYDREAL,TYDREAL,1,"d_exp", 2 },
- { TYCOMPLEX,TYCOMPLEX,1,"c_exp" },
- { TYDCOMPLEX,TYDCOMPLEX,1,"z_exp" },
-
- { TYREAL,TYREAL,1,"r_log", 3 },
- { TYDREAL,TYDREAL,1,"d_log", 3 },
- { TYCOMPLEX,TYCOMPLEX,1,"c_log" },
- { TYDCOMPLEX,TYDCOMPLEX,1,"z_log" },
-
- { TYREAL,TYREAL,1,"r_lg10" },
- { TYDREAL,TYDREAL,1,"d_lg10" },
-
- { TYREAL,TYREAL,1,"r_sin", 4 },
- { TYDREAL,TYDREAL,1,"d_sin", 4 },
- { TYCOMPLEX,TYCOMPLEX,1,"c_sin" },
- { TYDCOMPLEX,TYDCOMPLEX,1,"z_sin" },
-
- { TYREAL,TYREAL,1,"r_cos", 5 },
- { TYDREAL,TYDREAL,1,"d_cos", 5 },
- { TYCOMPLEX,TYCOMPLEX,1,"c_cos" },
- { TYDCOMPLEX,TYDCOMPLEX,1,"z_cos" },
-
- { TYREAL,TYREAL,1,"r_tan", 6 },
- { TYDREAL,TYDREAL,1,"d_tan", 6 },
-
- { TYREAL,TYREAL,1,"r_asin", 7 },
- { TYDREAL,TYDREAL,1,"d_asin", 7 },
-
- { TYREAL,TYREAL,1,"r_acos", 8 },
- { TYDREAL,TYDREAL,1,"d_acos", 8 },
-
- { TYREAL,TYREAL,1,"r_atan", 9 },
- { TYDREAL,TYDREAL,1,"d_atan", 9 },
-
- { TYREAL,TYREAL,2,"r_atn2", 10 },
- { TYDREAL,TYDREAL,2,"d_atn2", 10 },
-
- { TYREAL,TYREAL,1,"r_sinh", 11 },
- { TYDREAL,TYDREAL,1,"d_sinh", 11 },
-
- { TYREAL,TYREAL,1,"r_cosh", 12 },
- { TYDREAL,TYDREAL,1,"d_cosh", 12 },
-
- { TYREAL,TYREAL,1,"r_tanh", 13 },
- { TYDREAL,TYDREAL,1,"d_tanh", 13 },
-
- { TYCHAR,TYLOGICAL,2,"hl_ge" },
- { TYCHAR,TYLOGICAL,2,"l_ge" },
-
- { TYCHAR,TYLOGICAL,2,"hl_gt" },
- { TYCHAR,TYLOGICAL,2,"l_gt" },
-
- { TYCHAR,TYLOGICAL,2,"hl_le" },
- { TYCHAR,TYLOGICAL,2,"l_le" },
-
- { TYCHAR,TYLOGICAL,2,"hl_lt" },
- { TYCHAR,TYLOGICAL,2,"l_lt" },
-
- { TYREAL,TYSHORT,1,"hr_expn" },
- { TYREAL,TYLONG,1,"ir_expn" },
- { TYDREAL,TYSHORT,1,"hd_expn" },
- { TYDREAL,TYLONG,1,"id_expn" },
-
- { TYREAL,TYREAL,1,"r_absp" },
- { TYDREAL,TYDREAL,1,"d_absp" },
-
- { TYREAL,TYDREAL,1,"r_rrsp" },
- { TYDREAL,TYDREAL,1,"d_rrsp" },
-
- { TYREAL,TYREAL,1,"r_frac" },
- { TYDREAL,TYDREAL,1,"d_frac" },
-
- { TYREAL,TYREAL,2,"r_make" },
- { TYDREAL,TYDREAL,2,"d_make" },
-
- { TYREAL,TYREAL,2,"r_scal" },
- { TYDREAL,TYDREAL,2,"d_scal" },
- { 0 }
- } ;
-
- #if 0
- LOCAL struct Incstblock
- {
- char atype;
- char rtype;
- char constno;
- } consttab[ ] =
- {
- { TYSHORT, TYLONG, 0 },
- { TYLONG, TYLONG, 1 },
- { TYREAL, TYLONG, 2 },
- { TYDREAL, TYLONG, 3 },
-
- { TYSHORT, TYLONG, 4 },
- { TYLONG, TYLONG, 5 },
- { TYREAL, TYLONG, 6 },
- { TYDREAL, TYLONG, 7 },
-
- { TYREAL, TYLONG, 8 },
- { TYDREAL, TYLONG, 9 },
-
- { TYREAL, TYLONG, 10 },
- { TYDREAL, TYLONG, 11 },
-
- { TYREAL, TYREAL, 0 },
- { TYDREAL, TYDREAL, 1 },
-
- { TYSHORT, TYLONG, 12 },
- { TYLONG, TYLONG, 13 },
- { TYREAL, TYREAL, 2 },
- { TYDREAL, TYDREAL, 3 },
-
- { TYREAL, TYREAL, 4 },
- { TYDREAL, TYDREAL, 5 }
- };
- #endif
-
- char *callbyvalue[ ] =
- {0,
- "sqrt",
- "exp",
- "log",
- "sin",
- "cos",
- "tan",
- "asin",
- "acos",
- "atan",
- "atan2",
- "sinh",
- "cosh",
- "tanh"
- };
-
- void
- r8fix() /* adjust tables for -r8 */
- {
- register struct Intrblock *I;
- register struct Specblock *S;
-
- for(I = intrtab; I->intrfname[0]; I++)
- if (I->intrval.intrgroup != INTRGEN)
- switch(I->intrval.intrstuff) {
- case TYREAL:
- I->intrval.intrstuff = TYDREAL;
- I->intrval.intrno = I->intrval.dblintrno;
- break;
- case TYCOMPLEX:
- I->intrval.intrstuff = TYDCOMPLEX;
- I->intrval.intrno = I->intrval.dblintrno;
- I->intrval.dblcmplx = 1;
- }
-
- for(S = spectab; S->atype; S++)
- switch(S->atype) {
- case TYCOMPLEX:
- S->atype = TYDCOMPLEX;
- if (S->rtype == TYREAL)
- S->rtype = TYDREAL;
- else if (S->rtype == TYCOMPLEX)
- S->rtype = TYDCOMPLEX;
- switch(S->spxname[0]) {
- case 'r':
- S->spxname[0] = 'd';
- break;
- case 'c':
- S->spxname[0] = 'z';
- break;
- default:
- Fatal("r8fix bug");
- }
- break;
- case TYREAL:
- S->atype = TYDREAL;
- switch(S->rtype) {
- case TYREAL:
- S->rtype = TYDREAL;
- if (S->spxname[0] != 'r')
- Fatal("r8fix bug");
- S->spxname[0] = 'd';
- case TYDREAL: /* d_prod */
- break;
-
- case TYSHORT:
- if (!strcmp(S->spxname, "hr_expn"))
- S->spxname[1] = 'd';
- else if (!strcmp(S->spxname, "h_nint"))
- strcpy(S->spxname, "h_dnnt");
- else Fatal("r8fix bug");
- break;
-
- case TYLONG:
- if (!strcmp(S->spxname, "ir_expn"))
- S->spxname[1] = 'd';
- else if (!strcmp(S->spxname, "i_nint"))
- strcpy(S->spxname, "i_dnnt");
- else Fatal("r8fix bug");
- break;
-
- default:
- Fatal("r8fix bug");
- }
- }
- }
-
- expptr intrcall(np, argsp, nargs)
- Namep np;
- struct Listblock *argsp;
- int nargs;
- {
- int i, rettype;
- Addrp ap;
- register struct Specblock *sp;
- register struct Chain *cp;
- expptr Inline(), mkcxcon(), mkrealcon();
- expptr q, ep;
- int mtype;
- int op;
- int f1field, f2field, f3field;
-
- packed.ijunk = np->vardesc.varno;
- f1field = packed.bits.f1;
- f2field = packed.bits.f2;
- f3field = packed.bits.f3;
- if(nargs == 0)
- goto badnargs;
-
- mtype = 0;
- for(cp = argsp->listp ; cp ; cp = cp->nextp)
- {
- ep = (expptr)cp->datap;
- if( ISCONST(ep) && ep->headblock.vtype==TYSHORT )
- cp->datap = (char *) mkconv(tyint, ep);
- mtype = maxtype(mtype, ep->headblock.vtype);
- }
-
- switch(f1field)
- {
- case INTRBOOL:
- op = f3field;
- if( ! ONEOF(mtype, MSKINT|MSKLOGICAL) )
- goto badtype;
- if(op == OPBITNOT)
- {
- if(nargs != 1)
- goto badnargs;
- q = mkexpr(OPBITNOT, (expptr)argsp->listp->datap, ENULL);
- }
- else
- {
- if(nargs != 2)
- goto badnargs;
- q = mkexpr(op, (expptr)argsp->listp->datap,
- (expptr)argsp->listp->nextp->datap);
- }
- frchain( &(argsp->listp) );
- free( (charptr) argsp);
- return(q);
-
- case INTRCONV:
- rettype = f2field;
- if(rettype == TYLONG)
- rettype = tyint;
- if( ISCOMPLEX(rettype) && nargs==2)
- {
- expptr qr, qi;
- qr = (expptr) argsp->listp->datap;
- qi = (expptr) argsp->listp->nextp->datap;
- if(ISCONST(qr) && ISCONST(qi))
- q = mkcxcon(qr,qi);
- else q = mkexpr(OPCONV,mkconv(rettype-2,qr),
- mkconv(rettype-2,qi));
- }
- else if(nargs == 1) {
- if (f3field && ((Exprp)argsp->listp->datap)->vtype
- == TYDCOMPLEX)
- rettype = TYDREAL;
- q = mkconv(rettype, (expptr)argsp->listp->datap);
- }
- else goto badnargs;
-
- q->headblock.vtype = rettype;
- frchain(&(argsp->listp));
- free( (charptr) argsp);
- return(q);
-
-
- #if 0
- case INTRCNST:
-
- /* Machine-dependent f77 stuff that f2c omits:
-
- intcon contains
- radix for short int
- radix for long int
- radix for single precision
- radix for double precision
- precision for short int
- precision for long int
- precision for single precision
- precision for double precision
- emin for single precision
- emin for double precision
- emax for single precision
- emax for double prcision
- largest short int
- largest long int
-
- realcon contains
- tiny for single precision
- tiny for double precision
- huge for single precision
- huge for double precision
- mrsp (epsilon) for single precision
- mrsp (epsilon) for double precision
- */
- { register struct Incstblock *cstp;
- extern ftnint intcon[14];
- extern double realcon[6];
-
- cstp = consttab + f3field;
- for(i=0 ; i<f2field ; ++i)
- if(cstp->atype == mtype)
- goto foundconst;
- else
- ++cstp;
- goto badtype;
-
- foundconst:
- switch(cstp->rtype)
- {
- case TYLONG:
- return(mkintcon(intcon[cstp->constno]));
-
- case TYREAL:
- case TYDREAL:
- return(mkrealcon(cstp->rtype,
- realcon[cstp->constno]) );
-
- default:
- Fatal("impossible intrinsic constant");
- }
- }
- #endif
-
- case INTRGEN:
- sp = spectab + f3field;
- if(no66flag)
- if(sp->atype == mtype)
- goto specfunct;
- else err66("generic function");
-
- for(i=0; i<f2field ; ++i)
- if(sp->atype == mtype)
- goto specfunct;
- else
- ++sp;
- warn1 ("bad argument type to intrinsic %s", np->fvarname);
-
- /* Made this a warning rather than an error so things like "log (5) ==>
- log (5.0)" can be accommodated. When none of these cases matches, the
- argument is cast up to the first type in the spectab list; this first
- type is assumed to be the "smallest" type, e.g. REAL before DREAL
- before COMPLEX, before DCOMPLEX */
-
- sp = spectab + f3field;
- mtype = sp -> atype;
- goto specfunct;
-
- case INTRSPEC:
- sp = spectab + f3field;
- specfunct:
- if(tyint==TYLONG && ONEOF(sp->rtype,M(TYSHORT)|M(TYLOGICAL))
- && (sp+1)->atype==sp->atype)
- ++sp;
-
- if(nargs != sp->nargs)
- goto badnargs;
- if(mtype != sp->atype)
- goto badtype;
-
- /* NOTE!! I moved fixargs (YES) into the ELSE branch so that constants in
- the inline expression wouldn't get put into the constant table */
-
- fixargs (NO, argsp);
- cast_args (mtype, argsp -> listp);
-
- if(q = Inline((int)(sp-spectab), mtype, argsp->listp))
- {
- frchain( &(argsp->listp) );
- free( (charptr) argsp);
- } else {
-
- if(sp->othername) {
- /* C library routines that return double... */
- /* sp->rtype might be TYREAL */
- ap = builtin(sp->rtype,
- callbyvalue[sp->othername], 1);
- q = fixexpr((Exprp)
- mkexpr(OPCCALL, (expptr)ap, (expptr)argsp) );
- } else {
- fixargs(YES, argsp);
- ap = builtin(sp->rtype, sp->spxname, 0);
- q = fixexpr((Exprp)
- mkexpr(OPCALL, (expptr)ap, (expptr)argsp) );
- } /* else */
- } /* else */
- return(q);
-
- case INTRMIN:
- case INTRMAX:
- if(nargs < 2)
- goto badnargs;
- if( ! ONEOF(mtype, MSKINT|MSKREAL) )
- goto badtype;
- argsp->vtype = mtype;
- q = mkexpr( (f1field==INTRMIN ? OPMIN : OPMAX), (expptr)argsp, ENULL);
-
- q->headblock.vtype = mtype;
- rettype = f2field;
- if(rettype == TYLONG)
- rettype = tyint;
- else if(rettype == TYUNKNOWN)
- rettype = mtype;
- return( mkconv(rettype, q) );
-
- default:
- fatali("intrcall: bad intrgroup %d", f1field);
- }
- badnargs:
- errstr("bad number of arguments to intrinsic %s", np->fvarname);
- goto bad;
-
- badtype:
- errstr("bad argument type to intrinsic %s", np->fvarname);
-
- bad:
- return( errnode() );
- }
-
-
-
-
- intrfunct(s)
- char *s;
- {
- register struct Intrblock *p;
-
- for(p = intrtab; p->intrval.intrgroup!=INTREND ; ++p)
- {
- if( !strcmp(s, p->intrfname) )
- {
- packed.bits.f1 = p->intrval.intrgroup;
- packed.bits.f2 = p->intrval.intrstuff;
- packed.bits.f3 = p->intrval.intrno;
- packed.bits.f4 = p->intrval.dblcmplx;
- return(packed.ijunk);
- }
- }
-
- return(0);
- }
-
-
-
-
-
- Addrp intraddr(np)
- Namep np;
- {
- Addrp q;
- register struct Specblock *sp;
- int f3field;
-
- if(np->vclass!=CLPROC || np->vprocclass!=PINTRINSIC)
- fatalstr("intraddr: %s is not intrinsic", np->fvarname);
- packed.ijunk = np->vardesc.varno;
- f3field = packed.bits.f3;
-
- switch(packed.bits.f1)
- {
- case INTRGEN:
- /* imag, log, and log10 arent specific functions */
- if(f3field==31 || f3field==43 || f3field==47)
- goto bad;
-
- case INTRSPEC:
- sp = spectab + f3field;
- if(tyint==TYLONG && sp->rtype==TYSHORT)
- ++sp;
- q = builtin(sp->rtype, sp->spxname,
- sp->othername ? 1 : 0);
- return(q);
-
- case INTRCONV:
- case INTRMIN:
- case INTRMAX:
- case INTRBOOL:
- case INTRCNST:
- bad:
- errstr("cannot pass %s as actual", np->fvarname);
- return((Addrp)errnode());
- }
- fatali("intraddr: impossible f1=%d\n", (int) packed.bits.f1);
- /* NOT REACHED */ return 0;
- }
-
-
-
- void cast_args (maxtype, args)
- int maxtype;
- chainp args;
- {
- for (; args; args = args -> nextp) {
- expptr e = (expptr) args->datap;
- if (e -> headblock.vtype != maxtype)
- if (e -> tag == TCONST)
- args->datap = (char *) mkconv(maxtype, e);
- else {
- Addrp temp = mktmp(maxtype, ENULL);
-
- puteq(cpexpr((expptr)temp), e);
- args->datap = (char *)temp;
- } /* else */
- } /* for */
- } /* cast_args */
-
-
-
- expptr Inline(fno, type, args)
- int fno;
- int type;
- struct Chain *args;
- {
- register expptr q, t, t1;
-
- switch(fno)
- {
- case 8: /* real abs */
- case 9: /* short int abs */
- case 10: /* long int abs */
- case 11: /* double precision abs */
- if( addressable(q = (expptr) args->datap) )
- {
- t = q;
- q = NULL;
- }
- else
- t = (expptr) mktmp(type,ENULL);
- t1 = mkexpr(type == TYREAL && forcedouble ? OPDABS : OPABS,
- cpexpr(t), ENULL);
- if(q)
- t1 = mkexpr(OPCOMMA, mkexpr(OPASSIGN, cpexpr(t),q), t1);
- frexpr(t);
- return(t1);
-
- case 26: /* dprod */
- q = mkexpr(OPSTAR, mkconv(TYDREAL,(expptr)args->datap),
- (expptr)args->nextp->datap);
- return(q);
-
- case 27: /* len of character string */
- q = (expptr) cpexpr(((tagptr)args->datap)->headblock.vleng);
- frexpr((expptr)args->datap);
- return(q);
-
- case 14: /* half-integer mod */
- case 15: /* mod */
- return mkexpr(OPMOD, (expptr) args->datap,
- (expptr) args->nextp->datap);
- }
- return(NULL);
- }
-