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