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