xref: /csrg-svn/usr.bin/f77/pass1.tahoe/intr.c (revision 43212)
1*43212Sbostic /*
2*43212Sbostic  * Copyright (c) 1980 Regents of the University of California.
3*43212Sbostic  * All rights reserved.  The Berkeley software License Agreement
4*43212Sbostic  * specifies the terms and conditions for redistribution.
5*43212Sbostic  */
6*43212Sbostic 
7*43212Sbostic #ifndef lint
8*43212Sbostic static char sccsid[] = "@(#)intr.c	5.1 (Berkeley) 6/7/85";
9*43212Sbostic #endif not lint
10*43212Sbostic 
11*43212Sbostic /*
12*43212Sbostic  * intr.c
13*43212Sbostic  *
14*43212Sbostic  * Routines for handling intrinsic functions, f77 compiler pass 1, 4.2 BSD.
15*43212Sbostic  *
16*43212Sbostic  * University of Utah CS Dept modification history:
17*43212Sbostic  *
18*43212Sbostic  * $Log:	intr.c,v $
19*43212Sbostic  * Revision 1.4  85/02/22  00:54:59  donn
20*43212Sbostic  * Mark intrinsic functions as having storage class STGINTR.  builtin()
21*43212Sbostic  * always returns STGEXT nodes.  Notice that the reference to the function
22*43212Sbostic  * in the external symbol table still uses STGEXT...  I hope this is right.
23*43212Sbostic  *
24*43212Sbostic  * Revision 1.3  85/01/15  21:05:40  donn
25*43212Sbostic  * Changes to distinguish explicit from implicit conversions with intrconv().
26*43212Sbostic  *
27*43212Sbostic  * Revision 1.2  84/12/15  01:02:33  donn
28*43212Sbostic  * Added a case for an integer*4 result from len() in inline().  Previously
29*43212Sbostic  * only -i2 provoked len() inline, sigh.
30*43212Sbostic  *
31*43212Sbostic  */
32*43212Sbostic 
33*43212Sbostic #include "defs.h"
34*43212Sbostic 
35*43212Sbostic extern ftnint intcon[14];
36*43212Sbostic extern double realcon[6];
37*43212Sbostic 
38*43212Sbostic union
39*43212Sbostic 	{
40*43212Sbostic 	int ijunk;
41*43212Sbostic 	struct Intrpacked bits;
42*43212Sbostic 	} packed;
43*43212Sbostic 
44*43212Sbostic struct Intrbits
45*43212Sbostic 	{
46*43212Sbostic 	int intrgroup /* :3 */;
47*43212Sbostic 	int intrstuff /* result type or number of generics */;
48*43212Sbostic 	int intrno /* :7 */;
49*43212Sbostic 	};
50*43212Sbostic 
51*43212Sbostic LOCAL struct Intrblock
52*43212Sbostic 	{
53*43212Sbostic 	char intrfname[VL];
54*43212Sbostic 	struct Intrbits intrval;
55*43212Sbostic 	} intrtab[ ] =
56*43212Sbostic {
57*43212Sbostic "int", 		{ INTRCONV, TYLONG },
58*43212Sbostic "real", 	{ INTRCONV, TYREAL },
59*43212Sbostic "dble", 	{ INTRCONV, TYDREAL },
60*43212Sbostic "dreal",	{ INTRCONV, TYDREAL },
61*43212Sbostic "cmplx", 	{ INTRCONV, TYCOMPLEX },
62*43212Sbostic "dcmplx", 	{ INTRCONV, TYDCOMPLEX },
63*43212Sbostic "ifix", 	{ INTRCONV, TYLONG },
64*43212Sbostic "idint", 	{ INTRCONV, TYLONG },
65*43212Sbostic "float", 	{ INTRCONV, TYREAL },
66*43212Sbostic "dfloat",	{ INTRCONV, TYDREAL },
67*43212Sbostic "sngl", 	{ INTRCONV, TYREAL },
68*43212Sbostic "ichar", 	{ INTRCONV, TYLONG },
69*43212Sbostic "iachar", 	{ INTRCONV, TYLONG },
70*43212Sbostic "char", 	{ INTRCONV, TYCHAR },
71*43212Sbostic "achar", 	{ INTRCONV, TYCHAR },
72*43212Sbostic 
73*43212Sbostic "max", 		{ INTRMAX, TYUNKNOWN },
74*43212Sbostic "max0", 	{ INTRMAX, TYLONG },
75*43212Sbostic "amax0", 	{ INTRMAX, TYREAL },
76*43212Sbostic "max1", 	{ INTRMAX, TYLONG },
77*43212Sbostic "amax1", 	{ INTRMAX, TYREAL },
78*43212Sbostic "dmax1", 	{ INTRMAX, TYDREAL },
79*43212Sbostic 
80*43212Sbostic "and",		{ INTRBOOL, TYUNKNOWN, OPBITAND },
81*43212Sbostic "or",		{ INTRBOOL, TYUNKNOWN, OPBITOR },
82*43212Sbostic "xor",		{ INTRBOOL, TYUNKNOWN, OPBITXOR },
83*43212Sbostic "not",		{ INTRBOOL, TYUNKNOWN, OPBITNOT },
84*43212Sbostic "lshift",	{ INTRBOOL, TYUNKNOWN, OPLSHIFT },
85*43212Sbostic "rshift",	{ INTRBOOL, TYUNKNOWN, OPRSHIFT },
86*43212Sbostic 
87*43212Sbostic "min", 		{ INTRMIN, TYUNKNOWN },
88*43212Sbostic "min0", 	{ INTRMIN, TYLONG },
89*43212Sbostic "amin0", 	{ INTRMIN, TYREAL },
90*43212Sbostic "min1", 	{ INTRMIN, TYLONG },
91*43212Sbostic "amin1", 	{ INTRMIN, TYREAL },
92*43212Sbostic "dmin1", 	{ INTRMIN, TYDREAL },
93*43212Sbostic 
94*43212Sbostic "aint", 	{ INTRGEN, 2, 0 },
95*43212Sbostic "dint", 	{ INTRSPEC, TYDREAL, 1 },
96*43212Sbostic 
97*43212Sbostic "anint", 	{ INTRGEN, 2, 2 },
98*43212Sbostic "dnint", 	{ INTRSPEC, TYDREAL, 3 },
99*43212Sbostic 
100*43212Sbostic "nint", 	{ INTRGEN, 4, 4 },
101*43212Sbostic "idnint", 	{ INTRGEN, 2, 6 },
102*43212Sbostic 
103*43212Sbostic "abs", 		{ INTRGEN, 6, 8 },
104*43212Sbostic "iabs", 	{ INTRGEN, 2, 9 },
105*43212Sbostic "dabs", 	{ INTRSPEC, TYDREAL, 11 },
106*43212Sbostic "cabs", 	{ INTRSPEC, TYREAL, 12 },
107*43212Sbostic "zabs", 	{ INTRSPEC, TYDREAL, 13 },
108*43212Sbostic "cdabs",	{ INTRSPEC, TYDREAL, 13 },
109*43212Sbostic 
110*43212Sbostic "mod", 		{ INTRGEN, 4, 14 },
111*43212Sbostic "amod", 	{ INTRSPEC, TYREAL, 16 },
112*43212Sbostic "dmod", 	{ INTRSPEC, TYDREAL, 17 },
113*43212Sbostic 
114*43212Sbostic "sign", 	{ INTRGEN, 4, 18 },
115*43212Sbostic "isign", 	{ INTRGEN, 2, 19 },
116*43212Sbostic "dsign", 	{ INTRSPEC, TYDREAL, 21 },
117*43212Sbostic 
118*43212Sbostic "dim", 		{ INTRGEN, 4, 22 },
119*43212Sbostic "idim", 	{ INTRGEN, 2, 23 },
120*43212Sbostic "ddim", 	{ INTRSPEC, TYDREAL, 25 },
121*43212Sbostic 
122*43212Sbostic "dprod", 	{ INTRSPEC, TYDREAL, 26 },
123*43212Sbostic 
124*43212Sbostic "len", 		{ INTRSPEC, TYLONG, 27 },
125*43212Sbostic "index", 	{ INTRSPEC, TYLONG, 29 },
126*43212Sbostic 
127*43212Sbostic "imag", 	{ INTRGEN, 2, 31 },
128*43212Sbostic "aimag", 	{ INTRSPEC, TYREAL, 31 },
129*43212Sbostic "dimag", 	{ INTRSPEC, TYDREAL, 32 },
130*43212Sbostic 
131*43212Sbostic "conjg", 	{ INTRGEN, 2, 33 },
132*43212Sbostic "dconjg", 	{ INTRSPEC, TYDCOMPLEX, 34 },
133*43212Sbostic 
134*43212Sbostic "sqrt", 	{ INTRGEN, 4, 35 },
135*43212Sbostic "dsqrt", 	{ INTRSPEC, TYDREAL, 36 },
136*43212Sbostic "csqrt", 	{ INTRSPEC, TYCOMPLEX, 37 },
137*43212Sbostic "zsqrt", 	{ INTRSPEC, TYDCOMPLEX, 38 },
138*43212Sbostic "cdsqrt",	{ INTRSPEC, TYDCOMPLEX, 38 },
139*43212Sbostic 
140*43212Sbostic "exp", 		{ INTRGEN, 4, 39 },
141*43212Sbostic "dexp", 	{ INTRSPEC, TYDREAL, 40 },
142*43212Sbostic "cexp", 	{ INTRSPEC, TYCOMPLEX, 41 },
143*43212Sbostic "zexp", 	{ INTRSPEC, TYDCOMPLEX, 42 },
144*43212Sbostic "cdexp",	{ INTRSPEC, TYDCOMPLEX, 42 },
145*43212Sbostic 
146*43212Sbostic "log", 		{ INTRGEN, 4, 43 },
147*43212Sbostic "alog", 	{ INTRSPEC, TYREAL, 43 },
148*43212Sbostic "dlog", 	{ INTRSPEC, TYDREAL, 44 },
149*43212Sbostic "clog", 	{ INTRSPEC, TYCOMPLEX, 45 },
150*43212Sbostic "zlog", 	{ INTRSPEC, TYDCOMPLEX, 46 },
151*43212Sbostic "cdlog",	{ INTRSPEC, TYDCOMPLEX, 46 },
152*43212Sbostic 
153*43212Sbostic "log10", 	{ INTRGEN, 2, 47 },
154*43212Sbostic "alog10", 	{ INTRSPEC, TYREAL, 47 },
155*43212Sbostic "dlog10", 	{ INTRSPEC, TYDREAL, 48 },
156*43212Sbostic 
157*43212Sbostic "sin", 		{ INTRGEN, 4, 49 },
158*43212Sbostic "dsin", 	{ INTRSPEC, TYDREAL, 50 },
159*43212Sbostic "csin", 	{ INTRSPEC, TYCOMPLEX, 51 },
160*43212Sbostic "zsin", 	{ INTRSPEC, TYDCOMPLEX, 52 },
161*43212Sbostic "cdsin",	{ INTRSPEC, TYDCOMPLEX, 52 },
162*43212Sbostic 
163*43212Sbostic "cos", 		{ INTRGEN, 4, 53 },
164*43212Sbostic "dcos", 	{ INTRSPEC, TYDREAL, 54 },
165*43212Sbostic "ccos", 	{ INTRSPEC, TYCOMPLEX, 55 },
166*43212Sbostic "zcos", 	{ INTRSPEC, TYDCOMPLEX, 56 },
167*43212Sbostic "cdcos",	{ INTRSPEC, TYDCOMPLEX, 56 },
168*43212Sbostic 
169*43212Sbostic "tan", 		{ INTRGEN, 2, 57 },
170*43212Sbostic "dtan", 	{ INTRSPEC, TYDREAL, 58 },
171*43212Sbostic 
172*43212Sbostic "asin", 	{ INTRGEN, 2, 59 },
173*43212Sbostic "dasin", 	{ INTRSPEC, TYDREAL, 60 },
174*43212Sbostic 
175*43212Sbostic "acos", 	{ INTRGEN, 2, 61 },
176*43212Sbostic "dacos", 	{ INTRSPEC, TYDREAL, 62 },
177*43212Sbostic 
178*43212Sbostic "atan", 	{ INTRGEN, 2, 63 },
179*43212Sbostic "datan", 	{ INTRSPEC, TYDREAL, 64 },
180*43212Sbostic 
181*43212Sbostic "atan2", 	{ INTRGEN, 2, 65 },
182*43212Sbostic "datan2", 	{ INTRSPEC, TYDREAL, 66 },
183*43212Sbostic 
184*43212Sbostic "sinh", 	{ INTRGEN, 2, 67 },
185*43212Sbostic "dsinh", 	{ INTRSPEC, TYDREAL, 68 },
186*43212Sbostic 
187*43212Sbostic "cosh", 	{ INTRGEN, 2, 69 },
188*43212Sbostic "dcosh", 	{ INTRSPEC, TYDREAL, 70 },
189*43212Sbostic 
190*43212Sbostic "tanh", 	{ INTRGEN, 2, 71 },
191*43212Sbostic "dtanh", 	{ INTRSPEC, TYDREAL, 72 },
192*43212Sbostic 
193*43212Sbostic "lge",		{ INTRSPEC, TYLOGICAL, 73},
194*43212Sbostic "lgt",		{ INTRSPEC, TYLOGICAL, 75},
195*43212Sbostic "lle",		{ INTRSPEC, TYLOGICAL, 77},
196*43212Sbostic "llt",		{ INTRSPEC, TYLOGICAL, 79},
197*43212Sbostic 
198*43212Sbostic "epbase",	{ INTRCNST, 4, 0 },
199*43212Sbostic "epprec",	{ INTRCNST, 4, 4 },
200*43212Sbostic "epemin",	{ INTRCNST, 2, 8 },
201*43212Sbostic "epemax",	{ INTRCNST, 2, 10 },
202*43212Sbostic "eptiny",	{ INTRCNST, 2, 12 },
203*43212Sbostic "ephuge",	{ INTRCNST, 4, 14 },
204*43212Sbostic "epmrsp",	{ INTRCNST, 2, 18 },
205*43212Sbostic 
206*43212Sbostic "fpexpn",	{ INTRGEN, 4, 81 },
207*43212Sbostic "fpabsp",	{ INTRGEN, 2, 85 },
208*43212Sbostic "fprrsp",	{ INTRGEN, 2, 87 },
209*43212Sbostic "fpfrac",	{ INTRGEN, 2, 89 },
210*43212Sbostic "fpmake",	{ INTRGEN, 2, 91 },
211*43212Sbostic "fpscal",	{ INTRGEN, 2, 93 },
212*43212Sbostic 
213*43212Sbostic "" };
214*43212Sbostic 
215*43212Sbostic 
216*43212Sbostic LOCAL struct Specblock
217*43212Sbostic 	{
218*43212Sbostic 	char atype;
219*43212Sbostic 	char rtype;
220*43212Sbostic 	char nargs;
221*43212Sbostic 	char spxname[XL];
222*43212Sbostic 	char othername;	/* index into callbyvalue table */
223*43212Sbostic 	} spectab[ ] =
224*43212Sbostic {
225*43212Sbostic 	{ TYREAL,TYREAL,1,"r_int" },
226*43212Sbostic 	{ TYDREAL,TYDREAL,1,"d_int" },
227*43212Sbostic 
228*43212Sbostic 	{ TYREAL,TYREAL,1,"r_nint" },
229*43212Sbostic 	{ TYDREAL,TYDREAL,1,"d_nint" },
230*43212Sbostic 
231*43212Sbostic 	{ TYREAL,TYSHORT,1,"h_nint" },
232*43212Sbostic 	{ TYREAL,TYLONG,1,"i_nint" },
233*43212Sbostic 
234*43212Sbostic 	{ TYDREAL,TYSHORT,1,"h_dnnt" },
235*43212Sbostic 	{ TYDREAL,TYLONG,1,"i_dnnt" },
236*43212Sbostic 
237*43212Sbostic 	{ TYREAL,TYREAL,1,"r_abs" },
238*43212Sbostic 	{ TYSHORT,TYSHORT,1,"h_abs" },
239*43212Sbostic 	{ TYLONG,TYLONG,1,"i_abs" },
240*43212Sbostic 	{ TYDREAL,TYDREAL,1,"d_abs" },
241*43212Sbostic 	{ TYCOMPLEX,TYREAL,1,"c_abs" },
242*43212Sbostic 	{ TYDCOMPLEX,TYDREAL,1,"z_abs" },
243*43212Sbostic 
244*43212Sbostic 	{ TYSHORT,TYSHORT,2,"h_mod" },
245*43212Sbostic 	{ TYLONG,TYLONG,2,"i_mod" },
246*43212Sbostic 	{ TYREAL,TYREAL,2,"r_mod" },
247*43212Sbostic 	{ TYDREAL,TYDREAL,2,"d_mod" },
248*43212Sbostic 
249*43212Sbostic 	{ TYREAL,TYREAL,2,"r_sign" },
250*43212Sbostic 	{ TYSHORT,TYSHORT,2,"h_sign" },
251*43212Sbostic 	{ TYLONG,TYLONG,2,"i_sign" },
252*43212Sbostic 	{ TYDREAL,TYDREAL,2,"d_sign" },
253*43212Sbostic 
254*43212Sbostic 	{ TYREAL,TYREAL,2,"r_dim" },
255*43212Sbostic 	{ TYSHORT,TYSHORT,2,"h_dim" },
256*43212Sbostic 	{ TYLONG,TYLONG,2,"i_dim" },
257*43212Sbostic 	{ TYDREAL,TYDREAL,2,"d_dim" },
258*43212Sbostic 
259*43212Sbostic 	{ TYREAL,TYDREAL,2,"d_prod" },
260*43212Sbostic 
261*43212Sbostic 	{ TYCHAR,TYSHORT,1,"h_len" },
262*43212Sbostic 	{ TYCHAR,TYLONG,1,"i_len" },
263*43212Sbostic 
264*43212Sbostic 	{ TYCHAR,TYSHORT,2,"h_indx" },
265*43212Sbostic 	{ TYCHAR,TYLONG,2,"i_indx" },
266*43212Sbostic 
267*43212Sbostic 	{ TYCOMPLEX,TYREAL,1,"r_imag" },
268*43212Sbostic 	{ TYDCOMPLEX,TYDREAL,1,"d_imag" },
269*43212Sbostic 	{ TYCOMPLEX,TYCOMPLEX,1,"r_cnjg" },
270*43212Sbostic 	{ TYDCOMPLEX,TYDCOMPLEX,1,"d_cnjg" },
271*43212Sbostic 
272*43212Sbostic 	{ TYREAL,TYREAL,1,"r_sqrt", 14 },
273*43212Sbostic 	{ TYDREAL,TYDREAL,1,"d_sqrt", 1 },
274*43212Sbostic 	{ TYCOMPLEX,TYCOMPLEX,1,"c_sqrt" },
275*43212Sbostic 	{ TYDCOMPLEX,TYDCOMPLEX,1,"z_sqrt" },
276*43212Sbostic 
277*43212Sbostic 	{ TYREAL,TYREAL,1,"r_exp", 15 },
278*43212Sbostic 	{ TYDREAL,TYDREAL,1,"d_exp", 2 },
279*43212Sbostic 	{ TYCOMPLEX,TYCOMPLEX,1,"c_exp" },
280*43212Sbostic 	{ TYDCOMPLEX,TYDCOMPLEX,1,"z_exp" },
281*43212Sbostic 
282*43212Sbostic 	{ TYREAL,TYREAL,1,"r_log", 16 },
283*43212Sbostic 	{ TYDREAL,TYDREAL,1,"d_log", 3 },
284*43212Sbostic 	{ TYCOMPLEX,TYCOMPLEX,1,"c_log" },
285*43212Sbostic 	{ TYDCOMPLEX,TYDCOMPLEX,1,"z_log" },
286*43212Sbostic 
287*43212Sbostic 	{ TYREAL,TYREAL,1,"r_lg10" },
288*43212Sbostic 	{ TYDREAL,TYDREAL,1,"d_lg10" },
289*43212Sbostic 
290*43212Sbostic 	{ TYREAL,TYREAL,1,"r_sin", 17 },
291*43212Sbostic 	{ TYDREAL,TYDREAL,1,"d_sin", 4 },
292*43212Sbostic 	{ TYCOMPLEX,TYCOMPLEX,1,"c_sin" },
293*43212Sbostic 	{ TYDCOMPLEX,TYDCOMPLEX,1,"z_sin" },
294*43212Sbostic 
295*43212Sbostic 	{ TYREAL,TYREAL,1,"r_cos", 18 },
296*43212Sbostic 	{ TYDREAL,TYDREAL,1,"d_cos", 5 },
297*43212Sbostic 	{ TYCOMPLEX,TYCOMPLEX,1,"c_cos" },
298*43212Sbostic 	{ TYDCOMPLEX,TYDCOMPLEX,1,"z_cos" },
299*43212Sbostic 
300*43212Sbostic 	{ TYREAL,TYREAL,1,"r_tan" },
301*43212Sbostic 	{ TYDREAL,TYDREAL,1,"d_tan", 6 },
302*43212Sbostic 
303*43212Sbostic 	{ TYREAL,TYREAL,1,"r_asin" },
304*43212Sbostic 	{ TYDREAL,TYDREAL,1,"d_asin", 7 },
305*43212Sbostic 
306*43212Sbostic 	{ TYREAL,TYREAL,1,"r_acos" },
307*43212Sbostic 	{ TYDREAL,TYDREAL,1,"d_acos", 8 },
308*43212Sbostic 
309*43212Sbostic 	{ TYREAL,TYREAL,1,"r_atan", 19 },
310*43212Sbostic 	{ TYDREAL,TYDREAL,1,"d_atan", 9 },
311*43212Sbostic 
312*43212Sbostic 	{ TYREAL,TYREAL,2,"r_atn2" },
313*43212Sbostic 	{ TYDREAL,TYDREAL,2,"d_atn2", 10 },
314*43212Sbostic 
315*43212Sbostic 	{ TYREAL,TYREAL,1,"r_sinh" },
316*43212Sbostic 	{ TYDREAL,TYDREAL,1,"d_sinh", 11 },
317*43212Sbostic 
318*43212Sbostic 	{ TYREAL,TYREAL,1,"r_cosh" },
319*43212Sbostic 	{ TYDREAL,TYDREAL,1,"d_cosh", 12 },
320*43212Sbostic 
321*43212Sbostic 	{ TYREAL,TYREAL,1,"r_tanh" },
322*43212Sbostic 	{ TYDREAL,TYDREAL,1,"d_tanh", 13 },
323*43212Sbostic 
324*43212Sbostic 	{ TYCHAR,TYLOGICAL,2,"hl_ge" },
325*43212Sbostic 	{ TYCHAR,TYLOGICAL,2,"l_ge" },
326*43212Sbostic 
327*43212Sbostic 	{ TYCHAR,TYLOGICAL,2,"hl_gt" },
328*43212Sbostic 	{ TYCHAR,TYLOGICAL,2,"l_gt" },
329*43212Sbostic 
330*43212Sbostic 	{ TYCHAR,TYLOGICAL,2,"hl_le" },
331*43212Sbostic 	{ TYCHAR,TYLOGICAL,2,"l_le" },
332*43212Sbostic 
333*43212Sbostic 	{ TYCHAR,TYLOGICAL,2,"hl_lt" },
334*43212Sbostic 	{ TYCHAR,TYLOGICAL,2,"l_lt" },
335*43212Sbostic 
336*43212Sbostic 	{ TYREAL,TYSHORT,1,"hr_expn" },
337*43212Sbostic 	{ TYREAL,TYLONG,1,"ir_expn" },
338*43212Sbostic 	{ TYDREAL,TYSHORT,1,"hd_expn" },
339*43212Sbostic 	{ TYDREAL,TYLONG,1,"id_expn" },
340*43212Sbostic 
341*43212Sbostic 	{ TYREAL,TYREAL,1,"r_absp" },
342*43212Sbostic 	{ TYDREAL,TYDREAL,1,"d_absp" },
343*43212Sbostic 
344*43212Sbostic 	{ TYREAL,TYDREAL,1,"r_rrsp" },
345*43212Sbostic 	{ TYDREAL,TYDREAL,1,"d_rrsp" },
346*43212Sbostic 
347*43212Sbostic 	{ TYREAL,TYREAL,1,"r_frac" },
348*43212Sbostic 	{ TYDREAL,TYDREAL,1,"d_frac" },
349*43212Sbostic 
350*43212Sbostic 	{ TYREAL,TYREAL,2,"r_make" },
351*43212Sbostic 	{ TYDREAL,TYDREAL,2,"d_make" },
352*43212Sbostic 
353*43212Sbostic 	{ TYREAL,TYREAL,2,"r_scal" },
354*43212Sbostic 	{ TYDREAL,TYDREAL,2,"d_scal" }
355*43212Sbostic } ;
356*43212Sbostic 
357*43212Sbostic LOCAL struct Incstblock
358*43212Sbostic 	{
359*43212Sbostic 	char atype;
360*43212Sbostic 	char rtype;
361*43212Sbostic 	char constno;
362*43212Sbostic 	} consttab[ ] =
363*43212Sbostic {
364*43212Sbostic 	{ TYSHORT, TYLONG, 0 },
365*43212Sbostic 	{ TYLONG, TYLONG, 1 },
366*43212Sbostic 	{ TYREAL, TYLONG, 2 },
367*43212Sbostic 	{ TYDREAL, TYLONG, 3 },
368*43212Sbostic 
369*43212Sbostic 	{ TYSHORT, TYLONG, 4 },
370*43212Sbostic 	{ TYLONG, TYLONG, 5 },
371*43212Sbostic 	{ TYREAL, TYLONG, 6 },
372*43212Sbostic 	{ TYDREAL, TYLONG, 7 },
373*43212Sbostic 
374*43212Sbostic 	{ TYREAL, TYLONG, 8 },
375*43212Sbostic 	{ TYDREAL, TYLONG, 9 },
376*43212Sbostic 
377*43212Sbostic 	{ TYREAL, TYLONG, 10 },
378*43212Sbostic 	{ TYDREAL, TYLONG, 11 },
379*43212Sbostic 
380*43212Sbostic 	{ TYREAL, TYREAL, 0 },
381*43212Sbostic 	{ TYDREAL, TYDREAL, 1 },
382*43212Sbostic 
383*43212Sbostic 	{ TYSHORT, TYLONG, 12 },
384*43212Sbostic 	{ TYLONG, TYLONG, 13 },
385*43212Sbostic 	{ TYREAL, TYREAL, 2 },
386*43212Sbostic 	{ TYDREAL, TYDREAL, 3 },
387*43212Sbostic 
388*43212Sbostic 	{ TYREAL, TYREAL, 4 },
389*43212Sbostic 	{ TYDREAL, TYDREAL, 5 }
390*43212Sbostic };
391*43212Sbostic 
392*43212Sbostic /* For each machine, two arrays must be initialized.
393*43212Sbostic intcon contains
394*43212Sbostic 	radix for short int
395*43212Sbostic 	radix for long int
396*43212Sbostic 	radix for single precision
397*43212Sbostic 	radix for double precision
398*43212Sbostic 	precision for short int
399*43212Sbostic 	precision for long int
400*43212Sbostic 	precision for single precision
401*43212Sbostic 	precision for double precision
402*43212Sbostic 	emin for single precision
403*43212Sbostic 	emin for double precision
404*43212Sbostic 	emax for single precision
405*43212Sbostic 	emax for double prcision
406*43212Sbostic 	largest short int
407*43212Sbostic 	largest long int
408*43212Sbostic 
409*43212Sbostic realcon contains
410*43212Sbostic 	tiny for single precision
411*43212Sbostic 	tiny for double precision
412*43212Sbostic 	huge for single precision
413*43212Sbostic 	huge for double precision
414*43212Sbostic 	mrsp (epsilon) for single precision
415*43212Sbostic 	mrsp (epsilon) for double precision
416*43212Sbostic 
417*43212Sbostic the realcons should probably be filled in in binary if TARGET==HERE
418*43212Sbostic */
419*43212Sbostic 
420*43212Sbostic char callbyvalue[ ][XL] =
421*43212Sbostic 	{
422*43212Sbostic 	"sqrt",
423*43212Sbostic 	"exp",
424*43212Sbostic 	"log",
425*43212Sbostic 	"sin",
426*43212Sbostic 	"cos",
427*43212Sbostic 	"tan",
428*43212Sbostic 	"asin",
429*43212Sbostic 	"acos",
430*43212Sbostic 	"atan",
431*43212Sbostic 	"atan2",
432*43212Sbostic 	"sinh",
433*43212Sbostic 	"cosh",
434*43212Sbostic 	"tanh",
435*43212Sbostic 	/* function opcodes */
436*43212Sbostic 	"@sqrt",
437*43212Sbostic 	"@exp",
438*43212Sbostic 	"@log",
439*43212Sbostic 	"@sin",
440*43212Sbostic 	"@cos",
441*43212Sbostic 	"@atan"
442*43212Sbostic 	};
443*43212Sbostic 
444*43212Sbostic expptr intrcall(np, argsp, nargs)
445*43212Sbostic Namep np;
446*43212Sbostic struct Listblock *argsp;
447*43212Sbostic int nargs;
448*43212Sbostic {
449*43212Sbostic int i, rettype;
450*43212Sbostic Addrp ap;
451*43212Sbostic register struct Specblock *sp;
452*43212Sbostic register struct Chain *cp;
453*43212Sbostic expptr inline(), mkcxcon(), mkrealcon();
454*43212Sbostic register struct Incstblock *cstp;
455*43212Sbostic expptr q, ep;
456*43212Sbostic int mtype;
457*43212Sbostic int op;
458*43212Sbostic int f1field, f2field, f3field;
459*43212Sbostic 
460*43212Sbostic packed.ijunk = np->vardesc.varno;
461*43212Sbostic f1field = packed.bits.f1;
462*43212Sbostic f2field = packed.bits.f2;
463*43212Sbostic f3field = packed.bits.f3;
464*43212Sbostic if(nargs == 0)
465*43212Sbostic 	goto badnargs;
466*43212Sbostic 
467*43212Sbostic mtype = 0;
468*43212Sbostic for(cp = argsp->listp ; cp ; cp = cp->nextp)
469*43212Sbostic 	{
470*43212Sbostic /* TEMPORARY */ ep = (expptr) (cp->datap);
471*43212Sbostic /* TEMPORARY */	if( ISCONST(ep) && ep->headblock.vtype==TYSHORT )
472*43212Sbostic /* TEMPORARY */		cp->datap = (tagptr) mkconv(tyint, ep);
473*43212Sbostic 	mtype = maxtype(mtype, ep->headblock.vtype);
474*43212Sbostic 	}
475*43212Sbostic 
476*43212Sbostic switch(f1field)
477*43212Sbostic 	{
478*43212Sbostic 	case INTRBOOL:
479*43212Sbostic 		op = f3field;
480*43212Sbostic 		if( ! ONEOF(mtype, MSKINT|MSKLOGICAL) )
481*43212Sbostic 			goto badtype;
482*43212Sbostic 		if(op == OPBITNOT)
483*43212Sbostic 			{
484*43212Sbostic 			if(nargs != 1)
485*43212Sbostic 				goto badnargs;
486*43212Sbostic 			q = mkexpr(OPBITNOT, argsp->listp->datap, ENULL);
487*43212Sbostic 			}
488*43212Sbostic 		else
489*43212Sbostic 			{
490*43212Sbostic 			if(nargs != 2)
491*43212Sbostic 				goto badnargs;
492*43212Sbostic 			q = mkexpr(op, argsp->listp->datap,
493*43212Sbostic 				argsp->listp->nextp->datap);
494*43212Sbostic 			}
495*43212Sbostic 		frchain( &(argsp->listp) );
496*43212Sbostic 		free( (charptr) argsp);
497*43212Sbostic 		return(q);
498*43212Sbostic 
499*43212Sbostic 	case INTRCONV:
500*43212Sbostic 		if (nargs == 1)
501*43212Sbostic 			{
502*43212Sbostic 			if(argsp->listp->datap->headblock.vtype == TYERROR)
503*43212Sbostic 				{
504*43212Sbostic 				free( (charptr) argsp->listp->datap);
505*43212Sbostic 				frchain( &(argsp->listp) );
506*43212Sbostic 				free( (charptr) argsp);
507*43212Sbostic 				return( errnode() );
508*43212Sbostic 				}
509*43212Sbostic 			}
510*43212Sbostic 		else if (nargs == 2)
511*43212Sbostic 			{
512*43212Sbostic 			if(argsp->listp->nextp->datap->headblock.vtype ==
513*43212Sbostic 				TYERROR ||
514*43212Sbostic 				argsp->listp->datap->headblock.vtype == TYERROR)
515*43212Sbostic 				{
516*43212Sbostic 				free( (charptr) argsp->listp->nextp->datap);
517*43212Sbostic 				free( (charptr) argsp->listp->datap);
518*43212Sbostic 				frchain( &(argsp->listp) );
519*43212Sbostic 				free( (charptr) argsp);
520*43212Sbostic 				return( errnode() );
521*43212Sbostic 				}
522*43212Sbostic 			}
523*43212Sbostic 		rettype = f2field;
524*43212Sbostic 		if(rettype == TYLONG)
525*43212Sbostic 			rettype = tyint;
526*43212Sbostic 		if( ISCOMPLEX(rettype) && nargs==2)
527*43212Sbostic 			{
528*43212Sbostic 			expptr qr, qi;
529*43212Sbostic 			qr = (expptr) (argsp->listp->datap);
530*43212Sbostic 			qi = (expptr) (argsp->listp->nextp->datap);
531*43212Sbostic 			if(ISCONST(qr) && ISCONST(qi))
532*43212Sbostic 				q = mkcxcon(qr,qi);
533*43212Sbostic 			else	q = mkexpr(OPCONV,intrconv(rettype-2,qr),
534*43212Sbostic 					intrconv(rettype-2,qi));
535*43212Sbostic 			}
536*43212Sbostic 		else if(nargs == 1)
537*43212Sbostic 			q = intrconv(rettype, argsp->listp->datap);
538*43212Sbostic 		else goto badnargs;
539*43212Sbostic 
540*43212Sbostic 		q->headblock.vtype = rettype;
541*43212Sbostic 		frchain(&(argsp->listp));
542*43212Sbostic 		free( (charptr) argsp);
543*43212Sbostic 		return(q);
544*43212Sbostic 
545*43212Sbostic 
546*43212Sbostic 	case INTRCNST:
547*43212Sbostic 		cstp = consttab + f3field;
548*43212Sbostic 		for(i=0 ; i<f2field ; ++i)
549*43212Sbostic 			if(cstp->atype == mtype)
550*43212Sbostic 				goto foundconst;
551*43212Sbostic 			else
552*43212Sbostic 				++cstp;
553*43212Sbostic 		goto badtype;
554*43212Sbostic 
555*43212Sbostic 	foundconst:
556*43212Sbostic 		switch(cstp->rtype)
557*43212Sbostic 			{
558*43212Sbostic 			case TYLONG:
559*43212Sbostic 				return(mkintcon(intcon[cstp->constno]));
560*43212Sbostic 
561*43212Sbostic 			case TYREAL:
562*43212Sbostic 			case TYDREAL:
563*43212Sbostic 				return(mkrealcon(cstp->rtype,
564*43212Sbostic 					realcon[cstp->constno]) );
565*43212Sbostic 
566*43212Sbostic 			default:
567*43212Sbostic 				fatal("impossible intrinsic constant");
568*43212Sbostic 			}
569*43212Sbostic 
570*43212Sbostic 	case INTRGEN:
571*43212Sbostic 		sp = spectab + f3field;
572*43212Sbostic 		if(no66flag)
573*43212Sbostic 			if(sp->atype == mtype)
574*43212Sbostic 				goto specfunct;
575*43212Sbostic 			else err66("generic function");
576*43212Sbostic 
577*43212Sbostic 		for(i=0; i<f2field ; ++i)
578*43212Sbostic 			if(sp->atype == mtype)
579*43212Sbostic 				goto specfunct;
580*43212Sbostic 			else
581*43212Sbostic 				++sp;
582*43212Sbostic 		goto badtype;
583*43212Sbostic 
584*43212Sbostic 	case INTRSPEC:
585*43212Sbostic 		sp = spectab + f3field;
586*43212Sbostic 	specfunct:
587*43212Sbostic 		if(tyint==TYLONG && ONEOF(sp->rtype,M(TYSHORT)|M(TYLOGICAL))
588*43212Sbostic 			&& (sp+1)->atype==sp->atype)
589*43212Sbostic 				++sp;
590*43212Sbostic 
591*43212Sbostic 		if(nargs != sp->nargs)
592*43212Sbostic 			goto badnargs;
593*43212Sbostic 		if(mtype != sp->atype)
594*43212Sbostic 			goto badtype;
595*43212Sbostic 		fixargs(YES, argsp);
596*43212Sbostic 		if(q = inline(sp-spectab, mtype, argsp->listp))
597*43212Sbostic 			{
598*43212Sbostic 			frchain( &(argsp->listp) );
599*43212Sbostic 			free( (charptr) argsp);
600*43212Sbostic 			}
601*43212Sbostic 		else if(sp->othername)
602*43212Sbostic 			{
603*43212Sbostic 			ap = builtin(sp->rtype,
604*43212Sbostic 				varstr(XL, callbyvalue[sp->othername-1]) );
605*43212Sbostic 			ap->vstg = STGINTR;
606*43212Sbostic 			q = fixexpr( mkexpr(OPCCALL, ap, argsp) );
607*43212Sbostic 			}
608*43212Sbostic 		else
609*43212Sbostic 			{
610*43212Sbostic 			ap = builtin(sp->rtype, varstr(XL, sp->spxname) );
611*43212Sbostic 			ap->vstg = STGINTR;
612*43212Sbostic 			q = fixexpr( mkexpr(OPCALL, ap, argsp) );
613*43212Sbostic 			}
614*43212Sbostic 		return(q);
615*43212Sbostic 
616*43212Sbostic 	case INTRMIN:
617*43212Sbostic 	case INTRMAX:
618*43212Sbostic 		if(nargs < 2)
619*43212Sbostic 			goto badnargs;
620*43212Sbostic 		if( ! ONEOF(mtype, MSKINT|MSKREAL) )
621*43212Sbostic 			goto badtype;
622*43212Sbostic 		argsp->vtype = mtype;
623*43212Sbostic 		q = mkexpr( (f1field==INTRMIN ? OPMIN : OPMAX), argsp, ENULL);
624*43212Sbostic 
625*43212Sbostic 		q->headblock.vtype = mtype;
626*43212Sbostic 		rettype = f2field;
627*43212Sbostic 		if(rettype == TYLONG)
628*43212Sbostic 			rettype = tyint;
629*43212Sbostic 		else if(rettype == TYUNKNOWN)
630*43212Sbostic 			rettype = mtype;
631*43212Sbostic 		return( intrconv(rettype, q) );
632*43212Sbostic 
633*43212Sbostic 	default:
634*43212Sbostic 		fatali("intrcall: bad intrgroup %d", f1field);
635*43212Sbostic 	}
636*43212Sbostic badnargs:
637*43212Sbostic 	errstr("bad number of arguments to intrinsic %s",
638*43212Sbostic 		varstr(VL,np->varname) );
639*43212Sbostic 	goto bad;
640*43212Sbostic 
641*43212Sbostic badtype:
642*43212Sbostic 	errstr("bad argument type to intrinsic %s", varstr(VL, np->varname) );
643*43212Sbostic 
644*43212Sbostic bad:
645*43212Sbostic 	return( errnode() );
646*43212Sbostic }
647*43212Sbostic 
648*43212Sbostic 
649*43212Sbostic 
650*43212Sbostic 
651*43212Sbostic intrfunct(s)
652*43212Sbostic char s[VL];
653*43212Sbostic {
654*43212Sbostic register struct Intrblock *p;
655*43212Sbostic char nm[VL];
656*43212Sbostic register int i;
657*43212Sbostic 
658*43212Sbostic for(i = 0 ; i<VL ; ++s)
659*43212Sbostic 	nm[i++] = (*s==' ' ? '\0' : *s);
660*43212Sbostic 
661*43212Sbostic for(p = intrtab; p->intrval.intrgroup!=INTREND ; ++p)
662*43212Sbostic 	{
663*43212Sbostic 	if( eqn(VL, nm, p->intrfname) )
664*43212Sbostic 		{
665*43212Sbostic 		packed.bits.f1 = p->intrval.intrgroup;
666*43212Sbostic 		packed.bits.f2 = p->intrval.intrstuff;
667*43212Sbostic 		packed.bits.f3 = p->intrval.intrno;
668*43212Sbostic 		return(packed.ijunk);
669*43212Sbostic 		}
670*43212Sbostic 	}
671*43212Sbostic 
672*43212Sbostic return(0);
673*43212Sbostic }
674*43212Sbostic 
675*43212Sbostic 
676*43212Sbostic 
677*43212Sbostic 
678*43212Sbostic 
679*43212Sbostic Addrp intraddr(np)
680*43212Sbostic Namep np;
681*43212Sbostic {
682*43212Sbostic Addrp q;
683*43212Sbostic register struct Specblock *sp;
684*43212Sbostic int f3field;
685*43212Sbostic 
686*43212Sbostic if(np->vclass!=CLPROC || np->vprocclass!=PINTRINSIC)
687*43212Sbostic 	fatalstr("intraddr: %s is not intrinsic", varstr(VL,np->varname));
688*43212Sbostic packed.ijunk = np->vardesc.varno;
689*43212Sbostic f3field = packed.bits.f3;
690*43212Sbostic 
691*43212Sbostic switch(packed.bits.f1)
692*43212Sbostic 	{
693*43212Sbostic 	case INTRGEN:
694*43212Sbostic 		/* imag, log, and log10 arent specific functions */
695*43212Sbostic 		if(f3field==31 || f3field==43 || f3field==47)
696*43212Sbostic 			goto bad;
697*43212Sbostic 
698*43212Sbostic 	case INTRSPEC:
699*43212Sbostic 		sp = spectab + f3field;
700*43212Sbostic 		if(tyint==TYLONG && sp->rtype==TYSHORT)
701*43212Sbostic 			++sp;
702*43212Sbostic 		q = builtin(sp->rtype, varstr(XL,sp->spxname) );
703*43212Sbostic 		q->vstg = STGINTR;
704*43212Sbostic 		return(q);
705*43212Sbostic 
706*43212Sbostic 	case INTRCONV:
707*43212Sbostic 	case INTRMIN:
708*43212Sbostic 	case INTRMAX:
709*43212Sbostic 	case INTRBOOL:
710*43212Sbostic 	case INTRCNST:
711*43212Sbostic 	bad:
712*43212Sbostic 		errstr("cannot pass %s as actual",
713*43212Sbostic 			varstr(VL,np->varname));
714*43212Sbostic 		return( (Addrp) errnode() );
715*43212Sbostic 	}
716*43212Sbostic fatali("intraddr: impossible f1=%d\n", (int) packed.bits.f1);
717*43212Sbostic /* NOTREACHED */
718*43212Sbostic }
719*43212Sbostic 
720*43212Sbostic 
721*43212Sbostic 
722*43212Sbostic 
723*43212Sbostic 
724*43212Sbostic expptr inline(fno, type, args)
725*43212Sbostic int fno;
726*43212Sbostic int type;
727*43212Sbostic struct Chain *args;
728*43212Sbostic {
729*43212Sbostic register expptr q, t, t1;
730*43212Sbostic 
731*43212Sbostic switch(fno)
732*43212Sbostic 	{
733*43212Sbostic 	case 8:	/* real abs */
734*43212Sbostic 	case 9:	/* short int abs */
735*43212Sbostic 	case 10:	/* long int abs */
736*43212Sbostic 	case 11:	/* double precision abs */
737*43212Sbostic 		if( addressable(q = (expptr) (args->datap)) )
738*43212Sbostic 			{
739*43212Sbostic 			t = q;
740*43212Sbostic 			q = NULL;
741*43212Sbostic 			}
742*43212Sbostic 		else
743*43212Sbostic 			t = (expptr) mktemp(type,PNULL);
744*43212Sbostic 		t1 = mkexpr(OPQUEST,
745*43212Sbostic 			mkexpr(OPLE, intrconv(type,ICON(0)), cpexpr(t)),
746*43212Sbostic 			mkexpr(OPCOLON, cpexpr(t),
747*43212Sbostic 				mkexpr(OPNEG, cpexpr(t), ENULL) ));
748*43212Sbostic 		if(q)
749*43212Sbostic 			t1 = mkexpr(OPCOMMA, mkexpr(OPASSIGN, cpexpr(t),q), t1);
750*43212Sbostic 		frexpr(t);
751*43212Sbostic 		return(t1);
752*43212Sbostic 
753*43212Sbostic 	case 26:	/* dprod */
754*43212Sbostic 		q = mkexpr(OPSTAR, intrconv(TYDREAL,args->datap), args->nextp->datap);
755*43212Sbostic 		return(q);
756*43212Sbostic 
757*43212Sbostic 	case 27:	/* len of character string */
758*43212Sbostic 	case 28:
759*43212Sbostic 		q = (expptr) cpexpr(args->datap->headblock.vleng);
760*43212Sbostic 		frexpr(args->datap);
761*43212Sbostic 		return(q);
762*43212Sbostic 
763*43212Sbostic 	case 14:	/* half-integer mod */
764*43212Sbostic 	case 15:	/* mod */
765*43212Sbostic 		return( mkexpr(OPMOD, (expptr) (args->datap),
766*43212Sbostic 			(expptr) (args->nextp->datap) ));
767*43212Sbostic 	}
768*43212Sbostic return(NULL);
769*43212Sbostic }
770