1*47951Sbostic /*-
2*47951Sbostic * Copyright (c) 1980 The Regents of the University of California.
3*47951Sbostic * All rights reserved.
4*47951Sbostic *
5*47951Sbostic * %sccs.include.proprietary.c%
643212Sbostic */
743212Sbostic
843212Sbostic #ifndef lint
9*47951Sbostic static char sccsid[] = "@(#)intr.c 5.3 (Berkeley) 04/12/91";
10*47951Sbostic #endif /* not lint */
1143212Sbostic
1243212Sbostic /*
1343212Sbostic * intr.c
1443212Sbostic *
1543212Sbostic * Routines for handling intrinsic functions, f77 compiler pass 1, 4.2 BSD.
1643212Sbostic *
1743212Sbostic * University of Utah CS Dept modification history:
1843212Sbostic *
1943212Sbostic * $Log: intr.c,v $
2043212Sbostic * Revision 1.4 85/02/22 00:54:59 donn
2143212Sbostic * Mark intrinsic functions as having storage class STGINTR. builtin()
2243212Sbostic * always returns STGEXT nodes. Notice that the reference to the function
2343212Sbostic * in the external symbol table still uses STGEXT... I hope this is right.
2443212Sbostic *
2543212Sbostic * Revision 1.3 85/01/15 21:05:40 donn
2643212Sbostic * Changes to distinguish explicit from implicit conversions with intrconv().
2743212Sbostic *
2843212Sbostic * Revision 1.2 84/12/15 01:02:33 donn
2946304Sbostic * Added a case for an integer*4 result from len() in inlne(). Previously
3043212Sbostic * only -i2 provoked len() inline, sigh.
3143212Sbostic *
3243212Sbostic */
3343212Sbostic
3443212Sbostic #include "defs.h"
3543212Sbostic
3643212Sbostic extern ftnint intcon[14];
3743212Sbostic extern double realcon[6];
3843212Sbostic
3943212Sbostic union
4043212Sbostic {
4143212Sbostic int ijunk;
4243212Sbostic struct Intrpacked bits;
4343212Sbostic } packed;
4443212Sbostic
4543212Sbostic struct Intrbits
4643212Sbostic {
4743212Sbostic int intrgroup /* :3 */;
4843212Sbostic int intrstuff /* result type or number of generics */;
4943212Sbostic int intrno /* :7 */;
5043212Sbostic };
5143212Sbostic
5243212Sbostic LOCAL struct Intrblock
5343212Sbostic {
5443212Sbostic char intrfname[VL];
5543212Sbostic struct Intrbits intrval;
5643212Sbostic } intrtab[ ] =
5743212Sbostic {
5843212Sbostic "int", { INTRCONV, TYLONG },
5943212Sbostic "real", { INTRCONV, TYREAL },
6043212Sbostic "dble", { INTRCONV, TYDREAL },
6143212Sbostic "dreal", { INTRCONV, TYDREAL },
6243212Sbostic "cmplx", { INTRCONV, TYCOMPLEX },
6343212Sbostic "dcmplx", { INTRCONV, TYDCOMPLEX },
6443212Sbostic "ifix", { INTRCONV, TYLONG },
6543212Sbostic "idint", { INTRCONV, TYLONG },
6643212Sbostic "float", { INTRCONV, TYREAL },
6743212Sbostic "dfloat", { INTRCONV, TYDREAL },
6843212Sbostic "sngl", { INTRCONV, TYREAL },
6943212Sbostic "ichar", { INTRCONV, TYLONG },
7043212Sbostic "iachar", { INTRCONV, TYLONG },
7143212Sbostic "char", { INTRCONV, TYCHAR },
7243212Sbostic "achar", { INTRCONV, TYCHAR },
7343212Sbostic
7443212Sbostic "max", { INTRMAX, TYUNKNOWN },
7543212Sbostic "max0", { INTRMAX, TYLONG },
7643212Sbostic "amax0", { INTRMAX, TYREAL },
7743212Sbostic "max1", { INTRMAX, TYLONG },
7843212Sbostic "amax1", { INTRMAX, TYREAL },
7943212Sbostic "dmax1", { INTRMAX, TYDREAL },
8043212Sbostic
8143212Sbostic "and", { INTRBOOL, TYUNKNOWN, OPBITAND },
8243212Sbostic "or", { INTRBOOL, TYUNKNOWN, OPBITOR },
8343212Sbostic "xor", { INTRBOOL, TYUNKNOWN, OPBITXOR },
8443212Sbostic "not", { INTRBOOL, TYUNKNOWN, OPBITNOT },
8543212Sbostic "lshift", { INTRBOOL, TYUNKNOWN, OPLSHIFT },
8643212Sbostic "rshift", { INTRBOOL, TYUNKNOWN, OPRSHIFT },
8743212Sbostic
8843212Sbostic "min", { INTRMIN, TYUNKNOWN },
8943212Sbostic "min0", { INTRMIN, TYLONG },
9043212Sbostic "amin0", { INTRMIN, TYREAL },
9143212Sbostic "min1", { INTRMIN, TYLONG },
9243212Sbostic "amin1", { INTRMIN, TYREAL },
9343212Sbostic "dmin1", { INTRMIN, TYDREAL },
9443212Sbostic
9543212Sbostic "aint", { INTRGEN, 2, 0 },
9643212Sbostic "dint", { INTRSPEC, TYDREAL, 1 },
9743212Sbostic
9843212Sbostic "anint", { INTRGEN, 2, 2 },
9943212Sbostic "dnint", { INTRSPEC, TYDREAL, 3 },
10043212Sbostic
10143212Sbostic "nint", { INTRGEN, 4, 4 },
10243212Sbostic "idnint", { INTRGEN, 2, 6 },
10343212Sbostic
10443212Sbostic "abs", { INTRGEN, 6, 8 },
10543212Sbostic "iabs", { INTRGEN, 2, 9 },
10643212Sbostic "dabs", { INTRSPEC, TYDREAL, 11 },
10743212Sbostic "cabs", { INTRSPEC, TYREAL, 12 },
10843212Sbostic "zabs", { INTRSPEC, TYDREAL, 13 },
10943212Sbostic "cdabs", { INTRSPEC, TYDREAL, 13 },
11043212Sbostic
11143212Sbostic "mod", { INTRGEN, 4, 14 },
11243212Sbostic "amod", { INTRSPEC, TYREAL, 16 },
11343212Sbostic "dmod", { INTRSPEC, TYDREAL, 17 },
11443212Sbostic
11543212Sbostic "sign", { INTRGEN, 4, 18 },
11643212Sbostic "isign", { INTRGEN, 2, 19 },
11743212Sbostic "dsign", { INTRSPEC, TYDREAL, 21 },
11843212Sbostic
11943212Sbostic "dim", { INTRGEN, 4, 22 },
12043212Sbostic "idim", { INTRGEN, 2, 23 },
12143212Sbostic "ddim", { INTRSPEC, TYDREAL, 25 },
12243212Sbostic
12343212Sbostic "dprod", { INTRSPEC, TYDREAL, 26 },
12443212Sbostic
12543212Sbostic "len", { INTRSPEC, TYLONG, 27 },
12643212Sbostic "index", { INTRSPEC, TYLONG, 29 },
12743212Sbostic
12843212Sbostic "imag", { INTRGEN, 2, 31 },
12943212Sbostic "aimag", { INTRSPEC, TYREAL, 31 },
13043212Sbostic "dimag", { INTRSPEC, TYDREAL, 32 },
13143212Sbostic
13243212Sbostic "conjg", { INTRGEN, 2, 33 },
13343212Sbostic "dconjg", { INTRSPEC, TYDCOMPLEX, 34 },
13443212Sbostic
13543212Sbostic "sqrt", { INTRGEN, 4, 35 },
13643212Sbostic "dsqrt", { INTRSPEC, TYDREAL, 36 },
13743212Sbostic "csqrt", { INTRSPEC, TYCOMPLEX, 37 },
13843212Sbostic "zsqrt", { INTRSPEC, TYDCOMPLEX, 38 },
13943212Sbostic "cdsqrt", { INTRSPEC, TYDCOMPLEX, 38 },
14043212Sbostic
14143212Sbostic "exp", { INTRGEN, 4, 39 },
14243212Sbostic "dexp", { INTRSPEC, TYDREAL, 40 },
14343212Sbostic "cexp", { INTRSPEC, TYCOMPLEX, 41 },
14443212Sbostic "zexp", { INTRSPEC, TYDCOMPLEX, 42 },
14543212Sbostic "cdexp", { INTRSPEC, TYDCOMPLEX, 42 },
14643212Sbostic
14743212Sbostic "log", { INTRGEN, 4, 43 },
14843212Sbostic "alog", { INTRSPEC, TYREAL, 43 },
14943212Sbostic "dlog", { INTRSPEC, TYDREAL, 44 },
15043212Sbostic "clog", { INTRSPEC, TYCOMPLEX, 45 },
15143212Sbostic "zlog", { INTRSPEC, TYDCOMPLEX, 46 },
15243212Sbostic "cdlog", { INTRSPEC, TYDCOMPLEX, 46 },
15343212Sbostic
15443212Sbostic "log10", { INTRGEN, 2, 47 },
15543212Sbostic "alog10", { INTRSPEC, TYREAL, 47 },
15643212Sbostic "dlog10", { INTRSPEC, TYDREAL, 48 },
15743212Sbostic
15843212Sbostic "sin", { INTRGEN, 4, 49 },
15943212Sbostic "dsin", { INTRSPEC, TYDREAL, 50 },
16043212Sbostic "csin", { INTRSPEC, TYCOMPLEX, 51 },
16143212Sbostic "zsin", { INTRSPEC, TYDCOMPLEX, 52 },
16243212Sbostic "cdsin", { INTRSPEC, TYDCOMPLEX, 52 },
16343212Sbostic
16443212Sbostic "cos", { INTRGEN, 4, 53 },
16543212Sbostic "dcos", { INTRSPEC, TYDREAL, 54 },
16643212Sbostic "ccos", { INTRSPEC, TYCOMPLEX, 55 },
16743212Sbostic "zcos", { INTRSPEC, TYDCOMPLEX, 56 },
16843212Sbostic "cdcos", { INTRSPEC, TYDCOMPLEX, 56 },
16943212Sbostic
17043212Sbostic "tan", { INTRGEN, 2, 57 },
17143212Sbostic "dtan", { INTRSPEC, TYDREAL, 58 },
17243212Sbostic
17343212Sbostic "asin", { INTRGEN, 2, 59 },
17443212Sbostic "dasin", { INTRSPEC, TYDREAL, 60 },
17543212Sbostic
17643212Sbostic "acos", { INTRGEN, 2, 61 },
17743212Sbostic "dacos", { INTRSPEC, TYDREAL, 62 },
17843212Sbostic
17943212Sbostic "atan", { INTRGEN, 2, 63 },
18043212Sbostic "datan", { INTRSPEC, TYDREAL, 64 },
18143212Sbostic
18243212Sbostic "atan2", { INTRGEN, 2, 65 },
18343212Sbostic "datan2", { INTRSPEC, TYDREAL, 66 },
18443212Sbostic
18543212Sbostic "sinh", { INTRGEN, 2, 67 },
18643212Sbostic "dsinh", { INTRSPEC, TYDREAL, 68 },
18743212Sbostic
18843212Sbostic "cosh", { INTRGEN, 2, 69 },
18943212Sbostic "dcosh", { INTRSPEC, TYDREAL, 70 },
19043212Sbostic
19143212Sbostic "tanh", { INTRGEN, 2, 71 },
19243212Sbostic "dtanh", { INTRSPEC, TYDREAL, 72 },
19343212Sbostic
19443212Sbostic "lge", { INTRSPEC, TYLOGICAL, 73},
19543212Sbostic "lgt", { INTRSPEC, TYLOGICAL, 75},
19643212Sbostic "lle", { INTRSPEC, TYLOGICAL, 77},
19743212Sbostic "llt", { INTRSPEC, TYLOGICAL, 79},
19843212Sbostic
19943212Sbostic "epbase", { INTRCNST, 4, 0 },
20043212Sbostic "epprec", { INTRCNST, 4, 4 },
20143212Sbostic "epemin", { INTRCNST, 2, 8 },
20243212Sbostic "epemax", { INTRCNST, 2, 10 },
20343212Sbostic "eptiny", { INTRCNST, 2, 12 },
20443212Sbostic "ephuge", { INTRCNST, 4, 14 },
20543212Sbostic "epmrsp", { INTRCNST, 2, 18 },
20643212Sbostic
20743212Sbostic "fpexpn", { INTRGEN, 4, 81 },
20843212Sbostic "fpabsp", { INTRGEN, 2, 85 },
20943212Sbostic "fprrsp", { INTRGEN, 2, 87 },
21043212Sbostic "fpfrac", { INTRGEN, 2, 89 },
21143212Sbostic "fpmake", { INTRGEN, 2, 91 },
21243212Sbostic "fpscal", { INTRGEN, 2, 93 },
21343212Sbostic
21443212Sbostic "" };
21543212Sbostic
21643212Sbostic
21743212Sbostic LOCAL struct Specblock
21843212Sbostic {
21943212Sbostic char atype;
22043212Sbostic char rtype;
22143212Sbostic char nargs;
22243212Sbostic char spxname[XL];
22343212Sbostic char othername; /* index into callbyvalue table */
22443212Sbostic } spectab[ ] =
22543212Sbostic {
22643212Sbostic { TYREAL,TYREAL,1,"r_int" },
22743212Sbostic { TYDREAL,TYDREAL,1,"d_int" },
22843212Sbostic
22943212Sbostic { TYREAL,TYREAL,1,"r_nint" },
23043212Sbostic { TYDREAL,TYDREAL,1,"d_nint" },
23143212Sbostic
23243212Sbostic { TYREAL,TYSHORT,1,"h_nint" },
23343212Sbostic { TYREAL,TYLONG,1,"i_nint" },
23443212Sbostic
23543212Sbostic { TYDREAL,TYSHORT,1,"h_dnnt" },
23643212Sbostic { TYDREAL,TYLONG,1,"i_dnnt" },
23743212Sbostic
23843212Sbostic { TYREAL,TYREAL,1,"r_abs" },
23943212Sbostic { TYSHORT,TYSHORT,1,"h_abs" },
24043212Sbostic { TYLONG,TYLONG,1,"i_abs" },
24143212Sbostic { TYDREAL,TYDREAL,1,"d_abs" },
24243212Sbostic { TYCOMPLEX,TYREAL,1,"c_abs" },
24343212Sbostic { TYDCOMPLEX,TYDREAL,1,"z_abs" },
24443212Sbostic
24543212Sbostic { TYSHORT,TYSHORT,2,"h_mod" },
24643212Sbostic { TYLONG,TYLONG,2,"i_mod" },
24743212Sbostic { TYREAL,TYREAL,2,"r_mod" },
24843212Sbostic { TYDREAL,TYDREAL,2,"d_mod" },
24943212Sbostic
25043212Sbostic { TYREAL,TYREAL,2,"r_sign" },
25143212Sbostic { TYSHORT,TYSHORT,2,"h_sign" },
25243212Sbostic { TYLONG,TYLONG,2,"i_sign" },
25343212Sbostic { TYDREAL,TYDREAL,2,"d_sign" },
25443212Sbostic
25543212Sbostic { TYREAL,TYREAL,2,"r_dim" },
25643212Sbostic { TYSHORT,TYSHORT,2,"h_dim" },
25743212Sbostic { TYLONG,TYLONG,2,"i_dim" },
25843212Sbostic { TYDREAL,TYDREAL,2,"d_dim" },
25943212Sbostic
26043212Sbostic { TYREAL,TYDREAL,2,"d_prod" },
26143212Sbostic
26243212Sbostic { TYCHAR,TYSHORT,1,"h_len" },
26343212Sbostic { TYCHAR,TYLONG,1,"i_len" },
26443212Sbostic
26543212Sbostic { TYCHAR,TYSHORT,2,"h_indx" },
26643212Sbostic { TYCHAR,TYLONG,2,"i_indx" },
26743212Sbostic
26843212Sbostic { TYCOMPLEX,TYREAL,1,"r_imag" },
26943212Sbostic { TYDCOMPLEX,TYDREAL,1,"d_imag" },
27043212Sbostic { TYCOMPLEX,TYCOMPLEX,1,"r_cnjg" },
27143212Sbostic { TYDCOMPLEX,TYDCOMPLEX,1,"d_cnjg" },
27243212Sbostic
27343212Sbostic { TYREAL,TYREAL,1,"r_sqrt", 14 },
27443212Sbostic { TYDREAL,TYDREAL,1,"d_sqrt", 1 },
27543212Sbostic { TYCOMPLEX,TYCOMPLEX,1,"c_sqrt" },
27643212Sbostic { TYDCOMPLEX,TYDCOMPLEX,1,"z_sqrt" },
27743212Sbostic
27843212Sbostic { TYREAL,TYREAL,1,"r_exp", 15 },
27943212Sbostic { TYDREAL,TYDREAL,1,"d_exp", 2 },
28043212Sbostic { TYCOMPLEX,TYCOMPLEX,1,"c_exp" },
28143212Sbostic { TYDCOMPLEX,TYDCOMPLEX,1,"z_exp" },
28243212Sbostic
28343212Sbostic { TYREAL,TYREAL,1,"r_log", 16 },
28443212Sbostic { TYDREAL,TYDREAL,1,"d_log", 3 },
28543212Sbostic { TYCOMPLEX,TYCOMPLEX,1,"c_log" },
28643212Sbostic { TYDCOMPLEX,TYDCOMPLEX,1,"z_log" },
28743212Sbostic
28843212Sbostic { TYREAL,TYREAL,1,"r_lg10" },
28943212Sbostic { TYDREAL,TYDREAL,1,"d_lg10" },
29043212Sbostic
29143212Sbostic { TYREAL,TYREAL,1,"r_sin", 17 },
29243212Sbostic { TYDREAL,TYDREAL,1,"d_sin", 4 },
29343212Sbostic { TYCOMPLEX,TYCOMPLEX,1,"c_sin" },
29443212Sbostic { TYDCOMPLEX,TYDCOMPLEX,1,"z_sin" },
29543212Sbostic
29643212Sbostic { TYREAL,TYREAL,1,"r_cos", 18 },
29743212Sbostic { TYDREAL,TYDREAL,1,"d_cos", 5 },
29843212Sbostic { TYCOMPLEX,TYCOMPLEX,1,"c_cos" },
29943212Sbostic { TYDCOMPLEX,TYDCOMPLEX,1,"z_cos" },
30043212Sbostic
30143212Sbostic { TYREAL,TYREAL,1,"r_tan" },
30243212Sbostic { TYDREAL,TYDREAL,1,"d_tan", 6 },
30343212Sbostic
30443212Sbostic { TYREAL,TYREAL,1,"r_asin" },
30543212Sbostic { TYDREAL,TYDREAL,1,"d_asin", 7 },
30643212Sbostic
30743212Sbostic { TYREAL,TYREAL,1,"r_acos" },
30843212Sbostic { TYDREAL,TYDREAL,1,"d_acos", 8 },
30943212Sbostic
31043212Sbostic { TYREAL,TYREAL,1,"r_atan", 19 },
31143212Sbostic { TYDREAL,TYDREAL,1,"d_atan", 9 },
31243212Sbostic
31343212Sbostic { TYREAL,TYREAL,2,"r_atn2" },
31443212Sbostic { TYDREAL,TYDREAL,2,"d_atn2", 10 },
31543212Sbostic
31643212Sbostic { TYREAL,TYREAL,1,"r_sinh" },
31743212Sbostic { TYDREAL,TYDREAL,1,"d_sinh", 11 },
31843212Sbostic
31943212Sbostic { TYREAL,TYREAL,1,"r_cosh" },
32043212Sbostic { TYDREAL,TYDREAL,1,"d_cosh", 12 },
32143212Sbostic
32243212Sbostic { TYREAL,TYREAL,1,"r_tanh" },
32343212Sbostic { TYDREAL,TYDREAL,1,"d_tanh", 13 },
32443212Sbostic
32543212Sbostic { TYCHAR,TYLOGICAL,2,"hl_ge" },
32643212Sbostic { TYCHAR,TYLOGICAL,2,"l_ge" },
32743212Sbostic
32843212Sbostic { TYCHAR,TYLOGICAL,2,"hl_gt" },
32943212Sbostic { TYCHAR,TYLOGICAL,2,"l_gt" },
33043212Sbostic
33143212Sbostic { TYCHAR,TYLOGICAL,2,"hl_le" },
33243212Sbostic { TYCHAR,TYLOGICAL,2,"l_le" },
33343212Sbostic
33443212Sbostic { TYCHAR,TYLOGICAL,2,"hl_lt" },
33543212Sbostic { TYCHAR,TYLOGICAL,2,"l_lt" },
33643212Sbostic
33743212Sbostic { TYREAL,TYSHORT,1,"hr_expn" },
33843212Sbostic { TYREAL,TYLONG,1,"ir_expn" },
33943212Sbostic { TYDREAL,TYSHORT,1,"hd_expn" },
34043212Sbostic { TYDREAL,TYLONG,1,"id_expn" },
34143212Sbostic
34243212Sbostic { TYREAL,TYREAL,1,"r_absp" },
34343212Sbostic { TYDREAL,TYDREAL,1,"d_absp" },
34443212Sbostic
34543212Sbostic { TYREAL,TYDREAL,1,"r_rrsp" },
34643212Sbostic { TYDREAL,TYDREAL,1,"d_rrsp" },
34743212Sbostic
34843212Sbostic { TYREAL,TYREAL,1,"r_frac" },
34943212Sbostic { TYDREAL,TYDREAL,1,"d_frac" },
35043212Sbostic
35143212Sbostic { TYREAL,TYREAL,2,"r_make" },
35243212Sbostic { TYDREAL,TYDREAL,2,"d_make" },
35343212Sbostic
35443212Sbostic { TYREAL,TYREAL,2,"r_scal" },
35543212Sbostic { TYDREAL,TYDREAL,2,"d_scal" }
35643212Sbostic } ;
35743212Sbostic
35843212Sbostic LOCAL struct Incstblock
35943212Sbostic {
36043212Sbostic char atype;
36143212Sbostic char rtype;
36243212Sbostic char constno;
36343212Sbostic } consttab[ ] =
36443212Sbostic {
36543212Sbostic { TYSHORT, TYLONG, 0 },
36643212Sbostic { TYLONG, TYLONG, 1 },
36743212Sbostic { TYREAL, TYLONG, 2 },
36843212Sbostic { TYDREAL, TYLONG, 3 },
36943212Sbostic
37043212Sbostic { TYSHORT, TYLONG, 4 },
37143212Sbostic { TYLONG, TYLONG, 5 },
37243212Sbostic { TYREAL, TYLONG, 6 },
37343212Sbostic { TYDREAL, TYLONG, 7 },
37443212Sbostic
37543212Sbostic { TYREAL, TYLONG, 8 },
37643212Sbostic { TYDREAL, TYLONG, 9 },
37743212Sbostic
37843212Sbostic { TYREAL, TYLONG, 10 },
37943212Sbostic { TYDREAL, TYLONG, 11 },
38043212Sbostic
38143212Sbostic { TYREAL, TYREAL, 0 },
38243212Sbostic { TYDREAL, TYDREAL, 1 },
38343212Sbostic
38443212Sbostic { TYSHORT, TYLONG, 12 },
38543212Sbostic { TYLONG, TYLONG, 13 },
38643212Sbostic { TYREAL, TYREAL, 2 },
38743212Sbostic { TYDREAL, TYDREAL, 3 },
38843212Sbostic
38943212Sbostic { TYREAL, TYREAL, 4 },
39043212Sbostic { TYDREAL, TYDREAL, 5 }
39143212Sbostic };
39243212Sbostic
39343212Sbostic /* For each machine, two arrays must be initialized.
39443212Sbostic intcon contains
39543212Sbostic radix for short int
39643212Sbostic radix for long int
39743212Sbostic radix for single precision
39843212Sbostic radix for double precision
39943212Sbostic precision for short int
40043212Sbostic precision for long int
40143212Sbostic precision for single precision
40243212Sbostic precision for double precision
40343212Sbostic emin for single precision
40443212Sbostic emin for double precision
40543212Sbostic emax for single precision
40643212Sbostic emax for double prcision
40743212Sbostic largest short int
40843212Sbostic largest long int
40943212Sbostic
41043212Sbostic realcon contains
41143212Sbostic tiny for single precision
41243212Sbostic tiny for double precision
41343212Sbostic huge for single precision
41443212Sbostic huge for double precision
41543212Sbostic mrsp (epsilon) for single precision
41643212Sbostic mrsp (epsilon) for double precision
41743212Sbostic
41843212Sbostic the realcons should probably be filled in in binary if TARGET==HERE
41943212Sbostic */
42043212Sbostic
42143212Sbostic char callbyvalue[ ][XL] =
42243212Sbostic {
42343212Sbostic "sqrt",
42443212Sbostic "exp",
42543212Sbostic "log",
42643212Sbostic "sin",
42743212Sbostic "cos",
42843212Sbostic "tan",
42943212Sbostic "asin",
43043212Sbostic "acos",
43143212Sbostic "atan",
43243212Sbostic "atan2",
43343212Sbostic "sinh",
43443212Sbostic "cosh",
43543212Sbostic "tanh",
43643212Sbostic /* function opcodes */
43743212Sbostic "@sqrt",
43843212Sbostic "@exp",
43943212Sbostic "@log",
44043212Sbostic "@sin",
44143212Sbostic "@cos",
44243212Sbostic "@atan"
44343212Sbostic };
44443212Sbostic
intrcall(np,argsp,nargs)44543212Sbostic expptr intrcall(np, argsp, nargs)
44643212Sbostic Namep np;
44743212Sbostic struct Listblock *argsp;
44843212Sbostic int nargs;
44943212Sbostic {
45043212Sbostic int i, rettype;
45143212Sbostic Addrp ap;
45243212Sbostic register struct Specblock *sp;
45343212Sbostic register struct Chain *cp;
45446304Sbostic expptr inlne(), mkcxcon(), mkrealcon();
45543212Sbostic register struct Incstblock *cstp;
45643212Sbostic expptr q, ep;
45743212Sbostic int mtype;
45843212Sbostic int op;
45943212Sbostic int f1field, f2field, f3field;
46043212Sbostic
46143212Sbostic packed.ijunk = np->vardesc.varno;
46243212Sbostic f1field = packed.bits.f1;
46343212Sbostic f2field = packed.bits.f2;
46443212Sbostic f3field = packed.bits.f3;
46543212Sbostic if(nargs == 0)
46643212Sbostic goto badnargs;
46743212Sbostic
46843212Sbostic mtype = 0;
46943212Sbostic for(cp = argsp->listp ; cp ; cp = cp->nextp)
47043212Sbostic {
47143212Sbostic /* TEMPORARY */ ep = (expptr) (cp->datap);
47243212Sbostic /* TEMPORARY */ if( ISCONST(ep) && ep->headblock.vtype==TYSHORT )
47343212Sbostic /* TEMPORARY */ cp->datap = (tagptr) mkconv(tyint, ep);
47443212Sbostic mtype = maxtype(mtype, ep->headblock.vtype);
47543212Sbostic }
47643212Sbostic
47743212Sbostic switch(f1field)
47843212Sbostic {
47943212Sbostic case INTRBOOL:
48043212Sbostic op = f3field;
48143212Sbostic if( ! ONEOF(mtype, MSKINT|MSKLOGICAL) )
48243212Sbostic goto badtype;
48343212Sbostic if(op == OPBITNOT)
48443212Sbostic {
48543212Sbostic if(nargs != 1)
48643212Sbostic goto badnargs;
48743212Sbostic q = mkexpr(OPBITNOT, argsp->listp->datap, ENULL);
48843212Sbostic }
48943212Sbostic else
49043212Sbostic {
49143212Sbostic if(nargs != 2)
49243212Sbostic goto badnargs;
49343212Sbostic q = mkexpr(op, argsp->listp->datap,
49443212Sbostic argsp->listp->nextp->datap);
49543212Sbostic }
49643212Sbostic frchain( &(argsp->listp) );
49743212Sbostic free( (charptr) argsp);
49843212Sbostic return(q);
49943212Sbostic
50043212Sbostic case INTRCONV:
50143212Sbostic if (nargs == 1)
50243212Sbostic {
50343212Sbostic if(argsp->listp->datap->headblock.vtype == TYERROR)
50443212Sbostic {
50543212Sbostic free( (charptr) argsp->listp->datap);
50643212Sbostic frchain( &(argsp->listp) );
50743212Sbostic free( (charptr) argsp);
50843212Sbostic return( errnode() );
50943212Sbostic }
51043212Sbostic }
51143212Sbostic else if (nargs == 2)
51243212Sbostic {
51343212Sbostic if(argsp->listp->nextp->datap->headblock.vtype ==
51443212Sbostic TYERROR ||
51543212Sbostic argsp->listp->datap->headblock.vtype == TYERROR)
51643212Sbostic {
51743212Sbostic free( (charptr) argsp->listp->nextp->datap);
51843212Sbostic free( (charptr) argsp->listp->datap);
51943212Sbostic frchain( &(argsp->listp) );
52043212Sbostic free( (charptr) argsp);
52143212Sbostic return( errnode() );
52243212Sbostic }
52343212Sbostic }
52443212Sbostic rettype = f2field;
52543212Sbostic if(rettype == TYLONG)
52643212Sbostic rettype = tyint;
52743212Sbostic if( ISCOMPLEX(rettype) && nargs==2)
52843212Sbostic {
52943212Sbostic expptr qr, qi;
53043212Sbostic qr = (expptr) (argsp->listp->datap);
53143212Sbostic qi = (expptr) (argsp->listp->nextp->datap);
53243212Sbostic if(ISCONST(qr) && ISCONST(qi))
53343212Sbostic q = mkcxcon(qr,qi);
53443212Sbostic else q = mkexpr(OPCONV,intrconv(rettype-2,qr),
53543212Sbostic intrconv(rettype-2,qi));
53643212Sbostic }
53743212Sbostic else if(nargs == 1)
53843212Sbostic q = intrconv(rettype, argsp->listp->datap);
53943212Sbostic else goto badnargs;
54043212Sbostic
54143212Sbostic q->headblock.vtype = rettype;
54243212Sbostic frchain(&(argsp->listp));
54343212Sbostic free( (charptr) argsp);
54443212Sbostic return(q);
54543212Sbostic
54643212Sbostic
54743212Sbostic case INTRCNST:
54843212Sbostic cstp = consttab + f3field;
54943212Sbostic for(i=0 ; i<f2field ; ++i)
55043212Sbostic if(cstp->atype == mtype)
55143212Sbostic goto foundconst;
55243212Sbostic else
55343212Sbostic ++cstp;
55443212Sbostic goto badtype;
55543212Sbostic
55643212Sbostic foundconst:
55743212Sbostic switch(cstp->rtype)
55843212Sbostic {
55943212Sbostic case TYLONG:
56043212Sbostic return(mkintcon(intcon[cstp->constno]));
56143212Sbostic
56243212Sbostic case TYREAL:
56343212Sbostic case TYDREAL:
56443212Sbostic return(mkrealcon(cstp->rtype,
56543212Sbostic realcon[cstp->constno]) );
56643212Sbostic
56743212Sbostic default:
56843212Sbostic fatal("impossible intrinsic constant");
56943212Sbostic }
57043212Sbostic
57143212Sbostic case INTRGEN:
57243212Sbostic sp = spectab + f3field;
57343212Sbostic if(no66flag)
57443212Sbostic if(sp->atype == mtype)
57543212Sbostic goto specfunct;
57643212Sbostic else err66("generic function");
57743212Sbostic
57843212Sbostic for(i=0; i<f2field ; ++i)
57943212Sbostic if(sp->atype == mtype)
58043212Sbostic goto specfunct;
58143212Sbostic else
58243212Sbostic ++sp;
58343212Sbostic goto badtype;
58443212Sbostic
58543212Sbostic case INTRSPEC:
58643212Sbostic sp = spectab + f3field;
58743212Sbostic specfunct:
58843212Sbostic if(tyint==TYLONG && ONEOF(sp->rtype,M(TYSHORT)|M(TYLOGICAL))
58943212Sbostic && (sp+1)->atype==sp->atype)
59043212Sbostic ++sp;
59143212Sbostic
59243212Sbostic if(nargs != sp->nargs)
59343212Sbostic goto badnargs;
59443212Sbostic if(mtype != sp->atype)
59543212Sbostic goto badtype;
59643212Sbostic fixargs(YES, argsp);
59746304Sbostic if(q = inlne(sp-spectab, mtype, argsp->listp))
59843212Sbostic {
59943212Sbostic frchain( &(argsp->listp) );
60043212Sbostic free( (charptr) argsp);
60143212Sbostic }
60243212Sbostic else if(sp->othername)
60343212Sbostic {
60443212Sbostic ap = builtin(sp->rtype,
60543212Sbostic varstr(XL, callbyvalue[sp->othername-1]) );
60643212Sbostic ap->vstg = STGINTR;
60743212Sbostic q = fixexpr( mkexpr(OPCCALL, ap, argsp) );
60843212Sbostic }
60943212Sbostic else
61043212Sbostic {
61143212Sbostic ap = builtin(sp->rtype, varstr(XL, sp->spxname) );
61243212Sbostic ap->vstg = STGINTR;
61343212Sbostic q = fixexpr( mkexpr(OPCALL, ap, argsp) );
61443212Sbostic }
61543212Sbostic return(q);
61643212Sbostic
61743212Sbostic case INTRMIN:
61843212Sbostic case INTRMAX:
61943212Sbostic if(nargs < 2)
62043212Sbostic goto badnargs;
62143212Sbostic if( ! ONEOF(mtype, MSKINT|MSKREAL) )
62243212Sbostic goto badtype;
62343212Sbostic argsp->vtype = mtype;
62443212Sbostic q = mkexpr( (f1field==INTRMIN ? OPMIN : OPMAX), argsp, ENULL);
62543212Sbostic
62643212Sbostic q->headblock.vtype = mtype;
62743212Sbostic rettype = f2field;
62843212Sbostic if(rettype == TYLONG)
62943212Sbostic rettype = tyint;
63043212Sbostic else if(rettype == TYUNKNOWN)
63143212Sbostic rettype = mtype;
63243212Sbostic return( intrconv(rettype, q) );
63343212Sbostic
63443212Sbostic default:
63543212Sbostic fatali("intrcall: bad intrgroup %d", f1field);
63643212Sbostic }
63743212Sbostic badnargs:
63843212Sbostic errstr("bad number of arguments to intrinsic %s",
63943212Sbostic varstr(VL,np->varname) );
64043212Sbostic goto bad;
64143212Sbostic
64243212Sbostic badtype:
64343212Sbostic errstr("bad argument type to intrinsic %s", varstr(VL, np->varname) );
64443212Sbostic
64543212Sbostic bad:
64643212Sbostic return( errnode() );
64743212Sbostic }
64843212Sbostic
64943212Sbostic
65043212Sbostic
65143212Sbostic
intrfunct(s)65243212Sbostic intrfunct(s)
65343212Sbostic char s[VL];
65443212Sbostic {
65543212Sbostic register struct Intrblock *p;
65643212Sbostic char nm[VL];
65743212Sbostic register int i;
65843212Sbostic
65943212Sbostic for(i = 0 ; i<VL ; ++s)
66043212Sbostic nm[i++] = (*s==' ' ? '\0' : *s);
66143212Sbostic
66243212Sbostic for(p = intrtab; p->intrval.intrgroup!=INTREND ; ++p)
66343212Sbostic {
66443212Sbostic if( eqn(VL, nm, p->intrfname) )
66543212Sbostic {
66643212Sbostic packed.bits.f1 = p->intrval.intrgroup;
66743212Sbostic packed.bits.f2 = p->intrval.intrstuff;
66843212Sbostic packed.bits.f3 = p->intrval.intrno;
66943212Sbostic return(packed.ijunk);
67043212Sbostic }
67143212Sbostic }
67243212Sbostic
67343212Sbostic return(0);
67443212Sbostic }
67543212Sbostic
67643212Sbostic
67743212Sbostic
67843212Sbostic
67943212Sbostic
intraddr(np)68043212Sbostic Addrp intraddr(np)
68143212Sbostic Namep np;
68243212Sbostic {
68343212Sbostic Addrp q;
68443212Sbostic register struct Specblock *sp;
68543212Sbostic int f3field;
68643212Sbostic
68743212Sbostic if(np->vclass!=CLPROC || np->vprocclass!=PINTRINSIC)
68843212Sbostic fatalstr("intraddr: %s is not intrinsic", varstr(VL,np->varname));
68943212Sbostic packed.ijunk = np->vardesc.varno;
69043212Sbostic f3field = packed.bits.f3;
69143212Sbostic
69243212Sbostic switch(packed.bits.f1)
69343212Sbostic {
69443212Sbostic case INTRGEN:
69543212Sbostic /* imag, log, and log10 arent specific functions */
69643212Sbostic if(f3field==31 || f3field==43 || f3field==47)
69743212Sbostic goto bad;
69843212Sbostic
69943212Sbostic case INTRSPEC:
70043212Sbostic sp = spectab + f3field;
70143212Sbostic if(tyint==TYLONG && sp->rtype==TYSHORT)
70243212Sbostic ++sp;
70343212Sbostic q = builtin(sp->rtype, varstr(XL,sp->spxname) );
70443212Sbostic q->vstg = STGINTR;
70543212Sbostic return(q);
70643212Sbostic
70743212Sbostic case INTRCONV:
70843212Sbostic case INTRMIN:
70943212Sbostic case INTRMAX:
71043212Sbostic case INTRBOOL:
71143212Sbostic case INTRCNST:
71243212Sbostic bad:
71343212Sbostic errstr("cannot pass %s as actual",
71443212Sbostic varstr(VL,np->varname));
71543212Sbostic return( (Addrp) errnode() );
71643212Sbostic }
71743212Sbostic fatali("intraddr: impossible f1=%d\n", (int) packed.bits.f1);
71843212Sbostic /* NOTREACHED */
71943212Sbostic }
72043212Sbostic
72143212Sbostic
72243212Sbostic
72343212Sbostic
72443212Sbostic
inlne(fno,type,args)72546304Sbostic expptr inlne(fno, type, args)
72643212Sbostic int fno;
72743212Sbostic int type;
72843212Sbostic struct Chain *args;
72943212Sbostic {
73043212Sbostic register expptr q, t, t1;
73143212Sbostic
73243212Sbostic switch(fno)
73343212Sbostic {
73443212Sbostic case 8: /* real abs */
73543212Sbostic case 9: /* short int abs */
73643212Sbostic case 10: /* long int abs */
73743212Sbostic case 11: /* double precision abs */
73843212Sbostic if( addressable(q = (expptr) (args->datap)) )
73943212Sbostic {
74043212Sbostic t = q;
74143212Sbostic q = NULL;
74243212Sbostic }
74343212Sbostic else
74443212Sbostic t = (expptr) mktemp(type,PNULL);
74543212Sbostic t1 = mkexpr(OPQUEST,
74643212Sbostic mkexpr(OPLE, intrconv(type,ICON(0)), cpexpr(t)),
74743212Sbostic mkexpr(OPCOLON, cpexpr(t),
74843212Sbostic mkexpr(OPNEG, cpexpr(t), ENULL) ));
74943212Sbostic if(q)
75043212Sbostic t1 = mkexpr(OPCOMMA, mkexpr(OPASSIGN, cpexpr(t),q), t1);
75143212Sbostic frexpr(t);
75243212Sbostic return(t1);
75343212Sbostic
75443212Sbostic case 26: /* dprod */
75543212Sbostic q = mkexpr(OPSTAR, intrconv(TYDREAL,args->datap), args->nextp->datap);
75643212Sbostic return(q);
75743212Sbostic
75843212Sbostic case 27: /* len of character string */
75943212Sbostic case 28:
76043212Sbostic q = (expptr) cpexpr(args->datap->headblock.vleng);
76143212Sbostic frexpr(args->datap);
76243212Sbostic return(q);
76343212Sbostic
76443212Sbostic case 14: /* half-integer mod */
76543212Sbostic case 15: /* mod */
76643212Sbostic return( mkexpr(OPMOD, (expptr) (args->datap),
76743212Sbostic (expptr) (args->nextp->datap) ));
76843212Sbostic }
76943212Sbostic return(NULL);
77043212Sbostic }
771