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