1*47955Sbostic /*-
2*47955Sbostic * Copyright (c) 1980 The Regents of the University of California.
3*47955Sbostic * All rights reserved.
4*47955Sbostic *
5*47955Sbostic * %sccs.include.proprietary.c%
622834Smckusick */
722834Smckusick
822834Smckusick #ifndef lint
9*47955Sbostic static char sccsid[] = "@(#)intr.c 5.4 (Berkeley) 04/12/91";
10*47955Sbostic #endif /* not lint */
1122834Smckusick
1222834Smckusick /*
1322834Smckusick * intr.c
1422834Smckusick *
1522834Smckusick * Routines for handling intrinsic functions, f77 compiler pass 1, 4.2 BSD.
1622834Smckusick *
1722834Smckusick * University of Utah CS Dept modification history:
1822834Smckusick *
1922834Smckusick * $Log: intr.c,v $
2024480Sdonn * Revision 5.2 85/08/10 04:39:23 donn
2124480Sdonn * Various changes from Jerry Berkman. We now call the new builtin log10()
2224480Sdonn * instead of the f77 library emulations; we figure out that builtins will
2324480Sdonn * return type double instead of type float; we get rid of lots of
2424480Sdonn * undocumented material; we ifdef 66 code and handle -r8/double flag.
2524480Sdonn *
2624480Sdonn * Revision 5.1 85/08/10 03:47:37 donn
2724480Sdonn * 4.3 alpha
2824480Sdonn *
2922834Smckusick * Revision 1.4 85/02/22 00:54:59 donn
3022834Smckusick * Mark intrinsic functions as having storage class STGINTR. builtin()
3122834Smckusick * always returns STGEXT nodes. Notice that the reference to the function
3222834Smckusick * in the external symbol table still uses STGEXT... I hope this is right.
3322834Smckusick *
3422834Smckusick * Revision 1.3 85/01/15 21:05:40 donn
3522834Smckusick * Changes to distinguish explicit from implicit conversions with intrconv().
3622834Smckusick *
3722834Smckusick * Revision 1.2 84/12/15 01:02:33 donn
3847880Ssklower * Added a case for an integer*4 result from len() in Inline(). Previously
3922834Smckusick * only -i2 provoked len() inline, sigh.
4022834Smckusick *
4122834Smckusick */
4222834Smckusick
4322834Smckusick #include "defs.h"
4422834Smckusick
4522834Smckusick extern ftnint intcon[14];
4622834Smckusick extern double realcon[6];
4722834Smckusick
4822834Smckusick union
4922834Smckusick {
5022834Smckusick int ijunk;
5122834Smckusick struct Intrpacked bits;
5222834Smckusick } packed;
5322834Smckusick
5422834Smckusick struct Intrbits
5522834Smckusick {
5622834Smckusick int intrgroup /* :3 */;
5724480Sdonn int intrstuff /* result type or number of specifics */;
5822834Smckusick int intrno /* :7 */;
5922834Smckusick };
6022834Smckusick
6122834Smckusick LOCAL struct Intrblock
6222834Smckusick {
6322834Smckusick char intrfname[VL];
6422834Smckusick struct Intrbits intrval;
6522834Smckusick } intrtab[ ] =
6622834Smckusick {
6722834Smckusick "int", { INTRCONV, TYLONG },
6822834Smckusick "real", { INTRCONV, TYREAL },
6922834Smckusick "dble", { INTRCONV, TYDREAL },
7022834Smckusick "dreal", { INTRCONV, TYDREAL },
7122834Smckusick "cmplx", { INTRCONV, TYCOMPLEX },
7222834Smckusick "dcmplx", { INTRCONV, TYDCOMPLEX },
7322834Smckusick "ifix", { INTRCONV, TYLONG },
7422834Smckusick "idint", { INTRCONV, TYLONG },
7522834Smckusick "float", { INTRCONV, TYREAL },
7622834Smckusick "dfloat", { INTRCONV, TYDREAL },
7722834Smckusick "sngl", { INTRCONV, TYREAL },
7822834Smckusick "ichar", { INTRCONV, TYLONG },
7922834Smckusick "char", { INTRCONV, TYCHAR },
8022834Smckusick
8122834Smckusick "max", { INTRMAX, TYUNKNOWN },
8222834Smckusick "max0", { INTRMAX, TYLONG },
8322834Smckusick "amax0", { INTRMAX, TYREAL },
8422834Smckusick "max1", { INTRMAX, TYLONG },
8522834Smckusick "amax1", { INTRMAX, TYREAL },
8622834Smckusick "dmax1", { INTRMAX, TYDREAL },
8722834Smckusick
8822834Smckusick "and", { INTRBOOL, TYUNKNOWN, OPBITAND },
8922834Smckusick "or", { INTRBOOL, TYUNKNOWN, OPBITOR },
9022834Smckusick "xor", { INTRBOOL, TYUNKNOWN, OPBITXOR },
9122834Smckusick "not", { INTRBOOL, TYUNKNOWN, OPBITNOT },
9222834Smckusick "lshift", { INTRBOOL, TYUNKNOWN, OPLSHIFT },
9322834Smckusick "rshift", { INTRBOOL, TYUNKNOWN, OPRSHIFT },
9422834Smckusick
9522834Smckusick "min", { INTRMIN, TYUNKNOWN },
9622834Smckusick "min0", { INTRMIN, TYLONG },
9722834Smckusick "amin0", { INTRMIN, TYREAL },
9822834Smckusick "min1", { INTRMIN, TYLONG },
9922834Smckusick "amin1", { INTRMIN, TYREAL },
10022834Smckusick "dmin1", { INTRMIN, TYDREAL },
10122834Smckusick
10222834Smckusick "aint", { INTRGEN, 2, 0 },
10322834Smckusick "dint", { INTRSPEC, TYDREAL, 1 },
10422834Smckusick
10522834Smckusick "anint", { INTRGEN, 2, 2 },
10622834Smckusick "dnint", { INTRSPEC, TYDREAL, 3 },
10722834Smckusick
10822834Smckusick "nint", { INTRGEN, 4, 4 },
10922834Smckusick "idnint", { INTRGEN, 2, 6 },
11022834Smckusick
11122834Smckusick "abs", { INTRGEN, 6, 8 },
11222834Smckusick "iabs", { INTRGEN, 2, 9 },
11322834Smckusick "dabs", { INTRSPEC, TYDREAL, 11 },
11422834Smckusick "cabs", { INTRSPEC, TYREAL, 12 },
11522834Smckusick "zabs", { INTRSPEC, TYDREAL, 13 },
11622834Smckusick "cdabs", { INTRSPEC, TYDREAL, 13 },
11722834Smckusick
11822834Smckusick "mod", { INTRGEN, 4, 14 },
11922834Smckusick "amod", { INTRSPEC, TYREAL, 16 },
12022834Smckusick "dmod", { INTRSPEC, TYDREAL, 17 },
12122834Smckusick
12222834Smckusick "sign", { INTRGEN, 4, 18 },
12322834Smckusick "isign", { INTRGEN, 2, 19 },
12422834Smckusick "dsign", { INTRSPEC, TYDREAL, 21 },
12522834Smckusick
12622834Smckusick "dim", { INTRGEN, 4, 22 },
12722834Smckusick "idim", { INTRGEN, 2, 23 },
12822834Smckusick "ddim", { INTRSPEC, TYDREAL, 25 },
12922834Smckusick
13022834Smckusick "dprod", { INTRSPEC, TYDREAL, 26 },
13122834Smckusick
13222834Smckusick "len", { INTRSPEC, TYLONG, 27 },
13322834Smckusick "index", { INTRSPEC, TYLONG, 29 },
13422834Smckusick
13522834Smckusick "imag", { INTRGEN, 2, 31 },
13622834Smckusick "aimag", { INTRSPEC, TYREAL, 31 },
13722834Smckusick "dimag", { INTRSPEC, TYDREAL, 32 },
13822834Smckusick
13922834Smckusick "conjg", { INTRGEN, 2, 33 },
14022834Smckusick "dconjg", { INTRSPEC, TYDCOMPLEX, 34 },
14122834Smckusick
14222834Smckusick "sqrt", { INTRGEN, 4, 35 },
14322834Smckusick "dsqrt", { INTRSPEC, TYDREAL, 36 },
14422834Smckusick "csqrt", { INTRSPEC, TYCOMPLEX, 37 },
14522834Smckusick "zsqrt", { INTRSPEC, TYDCOMPLEX, 38 },
14622834Smckusick "cdsqrt", { INTRSPEC, TYDCOMPLEX, 38 },
14722834Smckusick
14822834Smckusick "exp", { INTRGEN, 4, 39 },
14922834Smckusick "dexp", { INTRSPEC, TYDREAL, 40 },
15022834Smckusick "cexp", { INTRSPEC, TYCOMPLEX, 41 },
15122834Smckusick "zexp", { INTRSPEC, TYDCOMPLEX, 42 },
15222834Smckusick "cdexp", { INTRSPEC, TYDCOMPLEX, 42 },
15322834Smckusick
15422834Smckusick "log", { INTRGEN, 4, 43 },
15522834Smckusick "alog", { INTRSPEC, TYREAL, 43 },
15622834Smckusick "dlog", { INTRSPEC, TYDREAL, 44 },
15722834Smckusick "clog", { INTRSPEC, TYCOMPLEX, 45 },
15822834Smckusick "zlog", { INTRSPEC, TYDCOMPLEX, 46 },
15922834Smckusick "cdlog", { INTRSPEC, TYDCOMPLEX, 46 },
16022834Smckusick
16122834Smckusick "log10", { INTRGEN, 2, 47 },
16222834Smckusick "alog10", { INTRSPEC, TYREAL, 47 },
16322834Smckusick "dlog10", { INTRSPEC, TYDREAL, 48 },
16422834Smckusick
16522834Smckusick "sin", { INTRGEN, 4, 49 },
16622834Smckusick "dsin", { INTRSPEC, TYDREAL, 50 },
16722834Smckusick "csin", { INTRSPEC, TYCOMPLEX, 51 },
16822834Smckusick "zsin", { INTRSPEC, TYDCOMPLEX, 52 },
16922834Smckusick "cdsin", { INTRSPEC, TYDCOMPLEX, 52 },
17022834Smckusick
17122834Smckusick "cos", { INTRGEN, 4, 53 },
17222834Smckusick "dcos", { INTRSPEC, TYDREAL, 54 },
17322834Smckusick "ccos", { INTRSPEC, TYCOMPLEX, 55 },
17422834Smckusick "zcos", { INTRSPEC, TYDCOMPLEX, 56 },
17522834Smckusick "cdcos", { INTRSPEC, TYDCOMPLEX, 56 },
17622834Smckusick
17722834Smckusick "tan", { INTRGEN, 2, 57 },
17822834Smckusick "dtan", { INTRSPEC, TYDREAL, 58 },
17922834Smckusick
18022834Smckusick "asin", { INTRGEN, 2, 59 },
18122834Smckusick "dasin", { INTRSPEC, TYDREAL, 60 },
18222834Smckusick
18322834Smckusick "acos", { INTRGEN, 2, 61 },
18422834Smckusick "dacos", { INTRSPEC, TYDREAL, 62 },
18522834Smckusick
18622834Smckusick "atan", { INTRGEN, 2, 63 },
18722834Smckusick "datan", { INTRSPEC, TYDREAL, 64 },
18822834Smckusick
18922834Smckusick "atan2", { INTRGEN, 2, 65 },
19022834Smckusick "datan2", { INTRSPEC, TYDREAL, 66 },
19122834Smckusick
19222834Smckusick "sinh", { INTRGEN, 2, 67 },
19322834Smckusick "dsinh", { INTRSPEC, TYDREAL, 68 },
19422834Smckusick
19522834Smckusick "cosh", { INTRGEN, 2, 69 },
19622834Smckusick "dcosh", { INTRSPEC, TYDREAL, 70 },
19722834Smckusick
19822834Smckusick "tanh", { INTRGEN, 2, 71 },
19922834Smckusick "dtanh", { INTRSPEC, TYDREAL, 72 },
20022834Smckusick
20122834Smckusick "lge", { INTRSPEC, TYLOGICAL, 73},
20222834Smckusick "lgt", { INTRSPEC, TYLOGICAL, 75},
20322834Smckusick "lle", { INTRSPEC, TYLOGICAL, 77},
20422834Smckusick "llt", { INTRSPEC, TYLOGICAL, 79},
20522834Smckusick
20624480Sdonn "", { INTREND, 0, 0} };
20722834Smckusick
20822834Smckusick
20922834Smckusick LOCAL struct Specblock
21022834Smckusick {
21122834Smckusick char atype;
21222834Smckusick char rtype;
21322834Smckusick char nargs;
21422834Smckusick char spxname[XL];
21522834Smckusick char othername; /* index into callbyvalue table */
21622834Smckusick } spectab[ ] =
21722834Smckusick {
21822834Smckusick { TYREAL,TYREAL,1,"r_int" },
21922834Smckusick { TYDREAL,TYDREAL,1,"d_int" },
22022834Smckusick
22122834Smckusick { TYREAL,TYREAL,1,"r_nint" },
22222834Smckusick { TYDREAL,TYDREAL,1,"d_nint" },
22322834Smckusick
22422834Smckusick { TYREAL,TYSHORT,1,"h_nint" },
22522834Smckusick { TYREAL,TYLONG,1,"i_nint" },
22622834Smckusick
22722834Smckusick { TYDREAL,TYSHORT,1,"h_dnnt" },
22822834Smckusick { TYDREAL,TYLONG,1,"i_dnnt" },
22922834Smckusick
23022834Smckusick { TYREAL,TYREAL,1,"r_abs" },
23122834Smckusick { TYSHORT,TYSHORT,1,"h_abs" },
23222834Smckusick { TYLONG,TYLONG,1,"i_abs" },
23322834Smckusick { TYDREAL,TYDREAL,1,"d_abs" },
23422834Smckusick { TYCOMPLEX,TYREAL,1,"c_abs" },
23522834Smckusick { TYDCOMPLEX,TYDREAL,1,"z_abs" },
23622834Smckusick
23722834Smckusick { TYSHORT,TYSHORT,2,"h_mod" },
23822834Smckusick { TYLONG,TYLONG,2,"i_mod" },
23922834Smckusick { TYREAL,TYREAL,2,"r_mod" },
24022834Smckusick { TYDREAL,TYDREAL,2,"d_mod" },
24122834Smckusick
24222834Smckusick { TYREAL,TYREAL,2,"r_sign" },
24322834Smckusick { TYSHORT,TYSHORT,2,"h_sign" },
24422834Smckusick { TYLONG,TYLONG,2,"i_sign" },
24522834Smckusick { TYDREAL,TYDREAL,2,"d_sign" },
24622834Smckusick
24722834Smckusick { TYREAL,TYREAL,2,"r_dim" },
24822834Smckusick { TYSHORT,TYSHORT,2,"h_dim" },
24922834Smckusick { TYLONG,TYLONG,2,"i_dim" },
25022834Smckusick { TYDREAL,TYDREAL,2,"d_dim" },
25122834Smckusick
25222834Smckusick { TYREAL,TYDREAL,2,"d_prod" },
25322834Smckusick
25422834Smckusick { TYCHAR,TYSHORT,1,"h_len" },
25522834Smckusick { TYCHAR,TYLONG,1,"i_len" },
25622834Smckusick
25722834Smckusick { TYCHAR,TYSHORT,2,"h_indx" },
25822834Smckusick { TYCHAR,TYLONG,2,"i_indx" },
25922834Smckusick
26022834Smckusick { TYCOMPLEX,TYREAL,1,"r_imag" },
26122834Smckusick { TYDCOMPLEX,TYDREAL,1,"d_imag" },
26222834Smckusick { TYCOMPLEX,TYCOMPLEX,1,"r_cnjg" },
26322834Smckusick { TYDCOMPLEX,TYDCOMPLEX,1,"d_cnjg" },
26422834Smckusick
26522834Smckusick { TYREAL,TYREAL,1,"r_sqrt", 1 },
26622834Smckusick { TYDREAL,TYDREAL,1,"d_sqrt", 1 },
26722834Smckusick { TYCOMPLEX,TYCOMPLEX,1,"c_sqrt" },
26822834Smckusick { TYDCOMPLEX,TYDCOMPLEX,1,"z_sqrt" },
26922834Smckusick
27022834Smckusick { TYREAL,TYREAL,1,"r_exp", 2 },
27122834Smckusick { TYDREAL,TYDREAL,1,"d_exp", 2 },
27222834Smckusick { TYCOMPLEX,TYCOMPLEX,1,"c_exp" },
27322834Smckusick { TYDCOMPLEX,TYDCOMPLEX,1,"z_exp" },
27422834Smckusick
27522834Smckusick { TYREAL,TYREAL,1,"r_log", 3 },
27622834Smckusick { TYDREAL,TYDREAL,1,"d_log", 3 },
27722834Smckusick { TYCOMPLEX,TYCOMPLEX,1,"c_log" },
27822834Smckusick { TYDCOMPLEX,TYDCOMPLEX,1,"z_log" },
27922834Smckusick
28024480Sdonn { TYREAL,TYREAL,1,"r_lg10", 14 },
28124480Sdonn { TYDREAL,TYDREAL,1,"d_lg10", 14 },
28222834Smckusick
28322834Smckusick { TYREAL,TYREAL,1,"r_sin", 4 },
28422834Smckusick { TYDREAL,TYDREAL,1,"d_sin", 4 },
28522834Smckusick { TYCOMPLEX,TYCOMPLEX,1,"c_sin" },
28622834Smckusick { TYDCOMPLEX,TYDCOMPLEX,1,"z_sin" },
28722834Smckusick
28822834Smckusick { TYREAL,TYREAL,1,"r_cos", 5 },
28922834Smckusick { TYDREAL,TYDREAL,1,"d_cos", 5 },
29022834Smckusick { TYCOMPLEX,TYCOMPLEX,1,"c_cos" },
29122834Smckusick { TYDCOMPLEX,TYDCOMPLEX,1,"z_cos" },
29222834Smckusick
29322834Smckusick { TYREAL,TYREAL,1,"r_tan", 6 },
29422834Smckusick { TYDREAL,TYDREAL,1,"d_tan", 6 },
29522834Smckusick
29622834Smckusick { TYREAL,TYREAL,1,"r_asin", 7 },
29722834Smckusick { TYDREAL,TYDREAL,1,"d_asin", 7 },
29822834Smckusick
29922834Smckusick { TYREAL,TYREAL,1,"r_acos", 8 },
30022834Smckusick { TYDREAL,TYDREAL,1,"d_acos", 8 },
30122834Smckusick
30222834Smckusick { TYREAL,TYREAL,1,"r_atan", 9 },
30322834Smckusick { TYDREAL,TYDREAL,1,"d_atan", 9 },
30422834Smckusick
30522834Smckusick { TYREAL,TYREAL,2,"r_atn2", 10 },
30622834Smckusick { TYDREAL,TYDREAL,2,"d_atn2", 10 },
30722834Smckusick
30822834Smckusick { TYREAL,TYREAL,1,"r_sinh", 11 },
30922834Smckusick { TYDREAL,TYDREAL,1,"d_sinh", 11 },
31022834Smckusick
31122834Smckusick { TYREAL,TYREAL,1,"r_cosh", 12 },
31222834Smckusick { TYDREAL,TYDREAL,1,"d_cosh", 12 },
31322834Smckusick
31422834Smckusick { TYREAL,TYREAL,1,"r_tanh", 13 },
31522834Smckusick { TYDREAL,TYDREAL,1,"d_tanh", 13 },
31622834Smckusick
31722834Smckusick { TYCHAR,TYLOGICAL,2,"hl_ge" },
31822834Smckusick { TYCHAR,TYLOGICAL,2,"l_ge" },
31922834Smckusick
32022834Smckusick { TYCHAR,TYLOGICAL,2,"hl_gt" },
32122834Smckusick { TYCHAR,TYLOGICAL,2,"l_gt" },
32222834Smckusick
32322834Smckusick { TYCHAR,TYLOGICAL,2,"hl_le" },
32422834Smckusick { TYCHAR,TYLOGICAL,2,"l_le" },
32522834Smckusick
32622834Smckusick { TYCHAR,TYLOGICAL,2,"hl_lt" },
32722834Smckusick { TYCHAR,TYLOGICAL,2,"l_lt" },
32822834Smckusick
32924480Sdonn { TYDREAL,TYDREAL,2,"d_dprod"} /* dprod() with dblflag */
33022834Smckusick } ;
33122834Smckusick
33222834Smckusick char callbyvalue[ ][XL] =
33322834Smckusick {
33422834Smckusick "sqrt",
33522834Smckusick "exp",
33622834Smckusick "log",
33722834Smckusick "sin",
33822834Smckusick "cos",
33922834Smckusick "tan",
34022834Smckusick "asin",
34122834Smckusick "acos",
34222834Smckusick "atan",
34322834Smckusick "atan2",
34422834Smckusick "sinh",
34522834Smckusick "cosh",
34624480Sdonn "tanh",
34724480Sdonn "log10"
34822834Smckusick };
34922834Smckusick
intrcall(np,argsp,nargs)35022834Smckusick expptr intrcall(np, argsp, nargs)
35122834Smckusick Namep np;
35222834Smckusick struct Listblock *argsp;
35322834Smckusick int nargs;
35422834Smckusick {
35522834Smckusick int i, rettype;
35622834Smckusick Addrp ap;
35722834Smckusick register struct Specblock *sp;
35822834Smckusick register struct Chain *cp;
35947880Ssklower expptr Inline(), mkcxcon(), mkrealcon();
36022834Smckusick expptr q, ep;
36122834Smckusick int mtype;
36222834Smckusick int op;
36322834Smckusick int f1field, f2field, f3field;
36422834Smckusick
36522834Smckusick packed.ijunk = np->vardesc.varno;
36622834Smckusick f1field = packed.bits.f1;
36722834Smckusick f2field = packed.bits.f2;
36822834Smckusick f3field = packed.bits.f3;
36922834Smckusick if(nargs == 0)
37022834Smckusick goto badnargs;
37122834Smckusick
37222834Smckusick mtype = 0;
37322834Smckusick for(cp = argsp->listp ; cp ; cp = cp->nextp)
37422834Smckusick {
37522834Smckusick /* TEMPORARY */ ep = (expptr) (cp->datap);
37622834Smckusick /* TEMPORARY */ if( ISCONST(ep) && ep->headblock.vtype==TYSHORT )
37722834Smckusick /* TEMPORARY */ cp->datap = (tagptr) mkconv(tyint, ep);
37822834Smckusick mtype = maxtype(mtype, ep->headblock.vtype);
37922834Smckusick }
38022834Smckusick
38122834Smckusick switch(f1field)
38222834Smckusick {
38322834Smckusick case INTRBOOL:
38422834Smckusick op = f3field;
38522834Smckusick if( ! ONEOF(mtype, MSKINT|MSKLOGICAL) )
38622834Smckusick goto badtype;
38722834Smckusick if(op == OPBITNOT)
38822834Smckusick {
38922834Smckusick if(nargs != 1)
39022834Smckusick goto badnargs;
39122834Smckusick q = mkexpr(OPBITNOT, argsp->listp->datap, ENULL);
39222834Smckusick }
39322834Smckusick else
39422834Smckusick {
39522834Smckusick if(nargs != 2)
39622834Smckusick goto badnargs;
39722834Smckusick q = mkexpr(op, argsp->listp->datap,
39822834Smckusick argsp->listp->nextp->datap);
39922834Smckusick }
40022834Smckusick frchain( &(argsp->listp) );
40122834Smckusick free( (charptr) argsp);
40222834Smckusick return(q);
40322834Smckusick
40422834Smckusick case INTRCONV:
40522834Smckusick if (nargs == 1)
40622834Smckusick {
40722834Smckusick if(argsp->listp->datap->headblock.vtype == TYERROR)
40822834Smckusick {
40922834Smckusick free( (charptr) argsp->listp->datap);
41022834Smckusick frchain( &(argsp->listp) );
41122834Smckusick free( (charptr) argsp);
41222834Smckusick return( errnode() );
41322834Smckusick }
41422834Smckusick }
41522834Smckusick else if (nargs == 2)
41622834Smckusick {
41722834Smckusick if(argsp->listp->nextp->datap->headblock.vtype ==
41822834Smckusick TYERROR ||
41922834Smckusick argsp->listp->datap->headblock.vtype == TYERROR)
42022834Smckusick {
42122834Smckusick free( (charptr) argsp->listp->nextp->datap);
42222834Smckusick free( (charptr) argsp->listp->datap);
42322834Smckusick frchain( &(argsp->listp) );
42422834Smckusick free( (charptr) argsp);
42522834Smckusick return( errnode() );
42622834Smckusick }
42722834Smckusick }
42822834Smckusick rettype = f2field;
42922834Smckusick if( ISCOMPLEX(rettype) && nargs==2)
43022834Smckusick {
43122834Smckusick expptr qr, qi;
43224480Sdonn if(dblflag) rettype = TYDCOMPLEX;
43322834Smckusick qr = (expptr) (argsp->listp->datap);
43422834Smckusick qi = (expptr) (argsp->listp->nextp->datap);
43522834Smckusick if(ISCONST(qr) && ISCONST(qi))
43622834Smckusick q = mkcxcon(qr,qi);
43722834Smckusick else q = mkexpr(OPCONV,intrconv(rettype-2,qr),
43822834Smckusick intrconv(rettype-2,qi));
43922834Smckusick }
44022834Smckusick else if(nargs == 1)
44124480Sdonn {
44224480Sdonn if(rettype == TYLONG) rettype = tyint;
44324480Sdonn else if( dblflag )
44424480Sdonn {
44524480Sdonn if ( rettype == TYREAL )
44624480Sdonn rettype = TYDREAL;
44724480Sdonn else if( rettype == TYCOMPLEX )
44824480Sdonn rettype = TYDCOMPLEX;
44924480Sdonn }
45022834Smckusick q = intrconv(rettype, argsp->listp->datap);
45124480Sdonn }
45222834Smckusick else goto badnargs;
45322834Smckusick
45422834Smckusick q->headblock.vtype = rettype;
45522834Smckusick frchain(&(argsp->listp));
45622834Smckusick free( (charptr) argsp);
45722834Smckusick return(q);
45822834Smckusick
45922834Smckusick case INTRGEN:
46022834Smckusick sp = spectab + f3field;
46124480Sdonn #ifdef ONLY66
46222834Smckusick if(no66flag)
46322834Smckusick if(sp->atype == mtype)
46422834Smckusick goto specfunct;
46522834Smckusick else err66("generic function");
46624480Sdonn #endif
46722834Smckusick
46822834Smckusick for(i=0; i<f2field ; ++i)
46922834Smckusick if(sp->atype == mtype)
47022834Smckusick goto specfunct;
47122834Smckusick else
47222834Smckusick ++sp;
47322834Smckusick goto badtype;
47422834Smckusick
47522834Smckusick case INTRSPEC:
47622834Smckusick sp = spectab + f3field;
47724480Sdonn if( dblflag )
47824480Sdonn {
47924480Sdonn /* convert specific complex functions to double complex:
48024480Sdonn * cabs,csqrt,cexp,clog,csin,ccos, aimag
48124480Sdonn * and convert real specifics to double:
48224480Sdonn * amod,alog,alog10
48324480Sdonn * (sqrt,cos,sin,... o.k. since go through INTRGEN)
48424480Sdonn */
48524480Sdonn if( (sp->atype==TYCOMPLEX && (sp+1)->atype==TYDCOMPLEX)
48624480Sdonn ||(sp->atype==TYREAL && (sp+1)->atype==TYDREAL))
48724480Sdonn sp++;
48824480Sdonn }
48922834Smckusick specfunct:
49022834Smckusick if(tyint==TYLONG && ONEOF(sp->rtype,M(TYSHORT)|M(TYLOGICAL))
49122834Smckusick && (sp+1)->atype==sp->atype)
49222834Smckusick ++sp;
49322834Smckusick
49422834Smckusick if(nargs != sp->nargs)
49522834Smckusick goto badnargs;
49624480Sdonn if(mtype != sp->atype
49724480Sdonn && (!dblflag || f3field != 26 || mtype != TYDREAL ) )
49824480Sdonn goto badtype;
49922834Smckusick fixargs(YES, argsp);
50047880Ssklower if(q = Inline(sp-spectab, mtype, argsp->listp))
50122834Smckusick {
50222834Smckusick frchain( &(argsp->listp) );
50322834Smckusick free( (charptr) argsp);
50422834Smckusick }
50522834Smckusick else if(sp->othername)
50622834Smckusick {
50724480Sdonn ap = builtin(TYDREAL,
50822834Smckusick varstr(XL, callbyvalue[sp->othername-1]) );
50922834Smckusick ap->vstg = STGINTR;
51022834Smckusick q = fixexpr( mkexpr(OPCCALL, ap, argsp) );
51124480Sdonn if( sp->rtype != TYDREAL )
51224480Sdonn q = mkconv( sp->rtype, q );
51322834Smckusick }
51422834Smckusick else
51522834Smckusick {
51622834Smckusick ap = builtin(sp->rtype, varstr(XL, sp->spxname) );
51722834Smckusick ap->vstg = STGINTR;
51822834Smckusick q = fixexpr( mkexpr(OPCALL, ap, argsp) );
51922834Smckusick }
52022834Smckusick return(q);
52122834Smckusick
52222834Smckusick case INTRMIN:
52322834Smckusick case INTRMAX:
52422834Smckusick if(nargs < 2)
52522834Smckusick goto badnargs;
52622834Smckusick if( ! ONEOF(mtype, MSKINT|MSKREAL) )
52722834Smckusick goto badtype;
52822834Smckusick argsp->vtype = mtype;
52922834Smckusick q = mkexpr( (f1field==INTRMIN ? OPMIN : OPMAX), argsp, ENULL);
53022834Smckusick
53122834Smckusick q->headblock.vtype = mtype;
53222834Smckusick rettype = f2field;
53322834Smckusick if(rettype == TYLONG)
53422834Smckusick rettype = tyint;
53522834Smckusick else if(rettype == TYUNKNOWN)
53622834Smckusick rettype = mtype;
53724480Sdonn else if( dblflag && rettype == TYREAL )
53824480Sdonn rettype = TYDREAL;
53922834Smckusick return( intrconv(rettype, q) );
54022834Smckusick
54122834Smckusick default:
54222834Smckusick fatali("intrcall: bad intrgroup %d", f1field);
54322834Smckusick }
54422834Smckusick badnargs:
54522834Smckusick errstr("bad number of arguments to intrinsic %s",
54622834Smckusick varstr(VL,np->varname) );
54722834Smckusick goto bad;
54822834Smckusick
54922834Smckusick badtype:
55022834Smckusick errstr("bad argument type to intrinsic %s", varstr(VL, np->varname) );
55122834Smckusick
55222834Smckusick bad:
55322834Smckusick return( errnode() );
55422834Smckusick }
55522834Smckusick
55622834Smckusick
55722834Smckusick
55822834Smckusick
intrfunct(s)55922834Smckusick intrfunct(s)
56022834Smckusick char s[VL];
56122834Smckusick {
56222834Smckusick register struct Intrblock *p;
56322834Smckusick char nm[VL];
56422834Smckusick register int i;
56522834Smckusick
56622834Smckusick for(i = 0 ; i<VL ; ++s)
56722834Smckusick nm[i++] = (*s==' ' ? '\0' : *s);
56822834Smckusick
56922834Smckusick for(p = intrtab; p->intrval.intrgroup!=INTREND ; ++p)
57022834Smckusick {
57122834Smckusick if( eqn(VL, nm, p->intrfname) )
57222834Smckusick {
57322834Smckusick packed.bits.f1 = p->intrval.intrgroup;
57422834Smckusick packed.bits.f2 = p->intrval.intrstuff;
57522834Smckusick packed.bits.f3 = p->intrval.intrno;
57622834Smckusick return(packed.ijunk);
57722834Smckusick }
57822834Smckusick }
57922834Smckusick
58022834Smckusick return(0);
58122834Smckusick }
58222834Smckusick
58322834Smckusick
58422834Smckusick
58522834Smckusick
58622834Smckusick
intraddr(np)58722834Smckusick Addrp intraddr(np)
58822834Smckusick Namep np;
58922834Smckusick {
59022834Smckusick Addrp q;
59122834Smckusick register struct Specblock *sp;
59222834Smckusick int f3field;
59322834Smckusick
59422834Smckusick if(np->vclass!=CLPROC || np->vprocclass!=PINTRINSIC)
59522834Smckusick fatalstr("intraddr: %s is not intrinsic", varstr(VL,np->varname));
59622834Smckusick packed.ijunk = np->vardesc.varno;
59722834Smckusick f3field = packed.bits.f3;
59822834Smckusick
59922834Smckusick switch(packed.bits.f1)
60022834Smckusick {
60122834Smckusick case INTRGEN:
60222834Smckusick /* imag, log, and log10 arent specific functions */
60322834Smckusick if(f3field==31 || f3field==43 || f3field==47)
60422834Smckusick goto bad;
60522834Smckusick
60622834Smckusick case INTRSPEC:
60722834Smckusick sp = spectab + f3field;
60824480Sdonn if( dblflag )
60924480Sdonn {
61024480Sdonn if((sp->atype==TYCOMPLEX && (sp+1)->atype==TYDCOMPLEX)
61124480Sdonn ||(sp->atype==TYREAL && (sp+1)->atype==TYDREAL))
61224480Sdonn sp++;
61324480Sdonn else if( f3field==4 )
61424480Sdonn sp += 2; /* h_nint -> h_dnnt */
61524480Sdonn else if( f3field==8 || f3field==18 || f3field==22)
61624480Sdonn sp += 3; /* r_{abs,sign,dim} ->d_... */
61724480Sdonn else if( f3field==26 )
61824480Sdonn sp = spectab + 81; /* dprod */
61924480Sdonn
62024480Sdonn }
62122834Smckusick if(tyint==TYLONG && sp->rtype==TYSHORT)
62222834Smckusick ++sp;
62322834Smckusick q = builtin(sp->rtype, varstr(XL,sp->spxname) );
62422834Smckusick q->vstg = STGINTR;
62522834Smckusick return(q);
62622834Smckusick
62722834Smckusick case INTRCONV:
62822834Smckusick case INTRMIN:
62922834Smckusick case INTRMAX:
63022834Smckusick case INTRBOOL:
63122834Smckusick bad:
63222834Smckusick errstr("cannot pass %s as actual",
63322834Smckusick varstr(VL,np->varname));
63422834Smckusick return( (Addrp) errnode() );
63522834Smckusick }
63622834Smckusick fatali("intraddr: impossible f1=%d\n", (int) packed.bits.f1);
63722834Smckusick /* NOTREACHED */
63822834Smckusick }
63922834Smckusick
64022834Smckusick
64122834Smckusick
64222834Smckusick
64322834Smckusick
Inline(fno,type,args)64447880Ssklower expptr Inline(fno, type, args)
64522834Smckusick int fno;
64622834Smckusick int type;
64722834Smckusick struct Chain *args;
64822834Smckusick {
64922834Smckusick register expptr q, t, t1;
65022834Smckusick
65122834Smckusick switch(fno)
65222834Smckusick {
65322834Smckusick case 8: /* real abs */
65422834Smckusick case 9: /* short int abs */
65522834Smckusick case 10: /* long int abs */
65622834Smckusick case 11: /* double precision abs */
65722834Smckusick if( addressable(q = (expptr) (args->datap)) )
65822834Smckusick {
65922834Smckusick t = q;
66022834Smckusick q = NULL;
66122834Smckusick }
66222834Smckusick else
66322834Smckusick t = (expptr) mktemp(type,PNULL);
66422834Smckusick t1 = mkexpr(OPQUEST,
66522834Smckusick mkexpr(OPLE, intrconv(type,ICON(0)), cpexpr(t)),
66622834Smckusick mkexpr(OPCOLON, cpexpr(t),
66722834Smckusick mkexpr(OPNEG, cpexpr(t), ENULL) ));
66822834Smckusick if(q)
66922834Smckusick t1 = mkexpr(OPCOMMA, mkexpr(OPASSIGN, cpexpr(t),q), t1);
67022834Smckusick frexpr(t);
67122834Smckusick return(t1);
67222834Smckusick
67322834Smckusick case 26: /* dprod */
67422834Smckusick q = mkexpr(OPSTAR, intrconv(TYDREAL,args->datap), args->nextp->datap);
67522834Smckusick return(q);
67622834Smckusick
67722834Smckusick case 27: /* len of character string */
67822834Smckusick case 28:
67922834Smckusick q = (expptr) cpexpr(args->datap->headblock.vleng);
68022834Smckusick frexpr(args->datap);
68122834Smckusick return(q);
68222834Smckusick
68322834Smckusick case 14: /* half-integer mod */
68422834Smckusick case 15: /* mod */
68522834Smckusick return( mkexpr(OPMOD, (expptr) (args->datap),
68622834Smckusick (expptr) (args->nextp->datap) ));
68722834Smckusick }
68822834Smckusick return(NULL);
68922834Smckusick }
690