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