122834Smckusick /* 222834Smckusick * Copyright (c) 1980 Regents of the University of California. 322834Smckusick * All rights reserved. The Berkeley software License Agreement 422834Smckusick * specifies the terms and conditions for redistribution. 522834Smckusick */ 622834Smckusick 722834Smckusick #ifndef lint 8*47880Ssklower static char sccsid[] = "@(#)intr.c 5.3 (Berkeley) 04/11/91"; 922834Smckusick #endif not lint 1022834Smckusick 1122834Smckusick /* 1222834Smckusick * intr.c 1322834Smckusick * 1422834Smckusick * Routines for handling intrinsic functions, f77 compiler pass 1, 4.2 BSD. 1522834Smckusick * 1622834Smckusick * University of Utah CS Dept modification history: 1722834Smckusick * 1822834Smckusick * $Log: intr.c,v $ 1924480Sdonn * Revision 5.2 85/08/10 04:39:23 donn 2024480Sdonn * Various changes from Jerry Berkman. We now call the new builtin log10() 2124480Sdonn * instead of the f77 library emulations; we figure out that builtins will 2224480Sdonn * return type double instead of type float; we get rid of lots of 2324480Sdonn * undocumented material; we ifdef 66 code and handle -r8/double flag. 2424480Sdonn * 2524480Sdonn * Revision 5.1 85/08/10 03:47:37 donn 2624480Sdonn * 4.3 alpha 2724480Sdonn * 2822834Smckusick * Revision 1.4 85/02/22 00:54:59 donn 2922834Smckusick * Mark intrinsic functions as having storage class STGINTR. builtin() 3022834Smckusick * always returns STGEXT nodes. Notice that the reference to the function 3122834Smckusick * in the external symbol table still uses STGEXT... I hope this is right. 3222834Smckusick * 3322834Smckusick * Revision 1.3 85/01/15 21:05:40 donn 3422834Smckusick * Changes to distinguish explicit from implicit conversions with intrconv(). 3522834Smckusick * 3622834Smckusick * Revision 1.2 84/12/15 01:02:33 donn 37*47880Ssklower * Added a case for an integer*4 result from len() in Inline(). Previously 3822834Smckusick * only -i2 provoked len() inline, sigh. 3922834Smckusick * 4022834Smckusick */ 4122834Smckusick 4222834Smckusick #include "defs.h" 4322834Smckusick 4422834Smckusick extern ftnint intcon[14]; 4522834Smckusick extern double realcon[6]; 4622834Smckusick 4722834Smckusick union 4822834Smckusick { 4922834Smckusick int ijunk; 5022834Smckusick struct Intrpacked bits; 5122834Smckusick } packed; 5222834Smckusick 5322834Smckusick struct Intrbits 5422834Smckusick { 5522834Smckusick int intrgroup /* :3 */; 5624480Sdonn int intrstuff /* result type or number of specifics */; 5722834Smckusick int intrno /* :7 */; 5822834Smckusick }; 5922834Smckusick 6022834Smckusick LOCAL struct Intrblock 6122834Smckusick { 6222834Smckusick char intrfname[VL]; 6322834Smckusick struct Intrbits intrval; 6422834Smckusick } intrtab[ ] = 6522834Smckusick { 6622834Smckusick "int", { INTRCONV, TYLONG }, 6722834Smckusick "real", { INTRCONV, TYREAL }, 6822834Smckusick "dble", { INTRCONV, TYDREAL }, 6922834Smckusick "dreal", { INTRCONV, TYDREAL }, 7022834Smckusick "cmplx", { INTRCONV, TYCOMPLEX }, 7122834Smckusick "dcmplx", { INTRCONV, TYDCOMPLEX }, 7222834Smckusick "ifix", { INTRCONV, TYLONG }, 7322834Smckusick "idint", { INTRCONV, TYLONG }, 7422834Smckusick "float", { INTRCONV, TYREAL }, 7522834Smckusick "dfloat", { INTRCONV, TYDREAL }, 7622834Smckusick "sngl", { INTRCONV, TYREAL }, 7722834Smckusick "ichar", { INTRCONV, TYLONG }, 7822834Smckusick "char", { INTRCONV, TYCHAR }, 7922834Smckusick 8022834Smckusick "max", { INTRMAX, TYUNKNOWN }, 8122834Smckusick "max0", { INTRMAX, TYLONG }, 8222834Smckusick "amax0", { INTRMAX, TYREAL }, 8322834Smckusick "max1", { INTRMAX, TYLONG }, 8422834Smckusick "amax1", { INTRMAX, TYREAL }, 8522834Smckusick "dmax1", { INTRMAX, TYDREAL }, 8622834Smckusick 8722834Smckusick "and", { INTRBOOL, TYUNKNOWN, OPBITAND }, 8822834Smckusick "or", { INTRBOOL, TYUNKNOWN, OPBITOR }, 8922834Smckusick "xor", { INTRBOOL, TYUNKNOWN, OPBITXOR }, 9022834Smckusick "not", { INTRBOOL, TYUNKNOWN, OPBITNOT }, 9122834Smckusick "lshift", { INTRBOOL, TYUNKNOWN, OPLSHIFT }, 9222834Smckusick "rshift", { INTRBOOL, TYUNKNOWN, OPRSHIFT }, 9322834Smckusick 9422834Smckusick "min", { INTRMIN, TYUNKNOWN }, 9522834Smckusick "min0", { INTRMIN, TYLONG }, 9622834Smckusick "amin0", { INTRMIN, TYREAL }, 9722834Smckusick "min1", { INTRMIN, TYLONG }, 9822834Smckusick "amin1", { INTRMIN, TYREAL }, 9922834Smckusick "dmin1", { INTRMIN, TYDREAL }, 10022834Smckusick 10122834Smckusick "aint", { INTRGEN, 2, 0 }, 10222834Smckusick "dint", { INTRSPEC, TYDREAL, 1 }, 10322834Smckusick 10422834Smckusick "anint", { INTRGEN, 2, 2 }, 10522834Smckusick "dnint", { INTRSPEC, TYDREAL, 3 }, 10622834Smckusick 10722834Smckusick "nint", { INTRGEN, 4, 4 }, 10822834Smckusick "idnint", { INTRGEN, 2, 6 }, 10922834Smckusick 11022834Smckusick "abs", { INTRGEN, 6, 8 }, 11122834Smckusick "iabs", { INTRGEN, 2, 9 }, 11222834Smckusick "dabs", { INTRSPEC, TYDREAL, 11 }, 11322834Smckusick "cabs", { INTRSPEC, TYREAL, 12 }, 11422834Smckusick "zabs", { INTRSPEC, TYDREAL, 13 }, 11522834Smckusick "cdabs", { INTRSPEC, TYDREAL, 13 }, 11622834Smckusick 11722834Smckusick "mod", { INTRGEN, 4, 14 }, 11822834Smckusick "amod", { INTRSPEC, TYREAL, 16 }, 11922834Smckusick "dmod", { INTRSPEC, TYDREAL, 17 }, 12022834Smckusick 12122834Smckusick "sign", { INTRGEN, 4, 18 }, 12222834Smckusick "isign", { INTRGEN, 2, 19 }, 12322834Smckusick "dsign", { INTRSPEC, TYDREAL, 21 }, 12422834Smckusick 12522834Smckusick "dim", { INTRGEN, 4, 22 }, 12622834Smckusick "idim", { INTRGEN, 2, 23 }, 12722834Smckusick "ddim", { INTRSPEC, TYDREAL, 25 }, 12822834Smckusick 12922834Smckusick "dprod", { INTRSPEC, TYDREAL, 26 }, 13022834Smckusick 13122834Smckusick "len", { INTRSPEC, TYLONG, 27 }, 13222834Smckusick "index", { INTRSPEC, TYLONG, 29 }, 13322834Smckusick 13422834Smckusick "imag", { INTRGEN, 2, 31 }, 13522834Smckusick "aimag", { INTRSPEC, TYREAL, 31 }, 13622834Smckusick "dimag", { INTRSPEC, TYDREAL, 32 }, 13722834Smckusick 13822834Smckusick "conjg", { INTRGEN, 2, 33 }, 13922834Smckusick "dconjg", { INTRSPEC, TYDCOMPLEX, 34 }, 14022834Smckusick 14122834Smckusick "sqrt", { INTRGEN, 4, 35 }, 14222834Smckusick "dsqrt", { INTRSPEC, TYDREAL, 36 }, 14322834Smckusick "csqrt", { INTRSPEC, TYCOMPLEX, 37 }, 14422834Smckusick "zsqrt", { INTRSPEC, TYDCOMPLEX, 38 }, 14522834Smckusick "cdsqrt", { INTRSPEC, TYDCOMPLEX, 38 }, 14622834Smckusick 14722834Smckusick "exp", { INTRGEN, 4, 39 }, 14822834Smckusick "dexp", { INTRSPEC, TYDREAL, 40 }, 14922834Smckusick "cexp", { INTRSPEC, TYCOMPLEX, 41 }, 15022834Smckusick "zexp", { INTRSPEC, TYDCOMPLEX, 42 }, 15122834Smckusick "cdexp", { INTRSPEC, TYDCOMPLEX, 42 }, 15222834Smckusick 15322834Smckusick "log", { INTRGEN, 4, 43 }, 15422834Smckusick "alog", { INTRSPEC, TYREAL, 43 }, 15522834Smckusick "dlog", { INTRSPEC, TYDREAL, 44 }, 15622834Smckusick "clog", { INTRSPEC, TYCOMPLEX, 45 }, 15722834Smckusick "zlog", { INTRSPEC, TYDCOMPLEX, 46 }, 15822834Smckusick "cdlog", { INTRSPEC, TYDCOMPLEX, 46 }, 15922834Smckusick 16022834Smckusick "log10", { INTRGEN, 2, 47 }, 16122834Smckusick "alog10", { INTRSPEC, TYREAL, 47 }, 16222834Smckusick "dlog10", { INTRSPEC, TYDREAL, 48 }, 16322834Smckusick 16422834Smckusick "sin", { INTRGEN, 4, 49 }, 16522834Smckusick "dsin", { INTRSPEC, TYDREAL, 50 }, 16622834Smckusick "csin", { INTRSPEC, TYCOMPLEX, 51 }, 16722834Smckusick "zsin", { INTRSPEC, TYDCOMPLEX, 52 }, 16822834Smckusick "cdsin", { INTRSPEC, TYDCOMPLEX, 52 }, 16922834Smckusick 17022834Smckusick "cos", { INTRGEN, 4, 53 }, 17122834Smckusick "dcos", { INTRSPEC, TYDREAL, 54 }, 17222834Smckusick "ccos", { INTRSPEC, TYCOMPLEX, 55 }, 17322834Smckusick "zcos", { INTRSPEC, TYDCOMPLEX, 56 }, 17422834Smckusick "cdcos", { INTRSPEC, TYDCOMPLEX, 56 }, 17522834Smckusick 17622834Smckusick "tan", { INTRGEN, 2, 57 }, 17722834Smckusick "dtan", { INTRSPEC, TYDREAL, 58 }, 17822834Smckusick 17922834Smckusick "asin", { INTRGEN, 2, 59 }, 18022834Smckusick "dasin", { INTRSPEC, TYDREAL, 60 }, 18122834Smckusick 18222834Smckusick "acos", { INTRGEN, 2, 61 }, 18322834Smckusick "dacos", { INTRSPEC, TYDREAL, 62 }, 18422834Smckusick 18522834Smckusick "atan", { INTRGEN, 2, 63 }, 18622834Smckusick "datan", { INTRSPEC, TYDREAL, 64 }, 18722834Smckusick 18822834Smckusick "atan2", { INTRGEN, 2, 65 }, 18922834Smckusick "datan2", { INTRSPEC, TYDREAL, 66 }, 19022834Smckusick 19122834Smckusick "sinh", { INTRGEN, 2, 67 }, 19222834Smckusick "dsinh", { INTRSPEC, TYDREAL, 68 }, 19322834Smckusick 19422834Smckusick "cosh", { INTRGEN, 2, 69 }, 19522834Smckusick "dcosh", { INTRSPEC, TYDREAL, 70 }, 19622834Smckusick 19722834Smckusick "tanh", { INTRGEN, 2, 71 }, 19822834Smckusick "dtanh", { INTRSPEC, TYDREAL, 72 }, 19922834Smckusick 20022834Smckusick "lge", { INTRSPEC, TYLOGICAL, 73}, 20122834Smckusick "lgt", { INTRSPEC, TYLOGICAL, 75}, 20222834Smckusick "lle", { INTRSPEC, TYLOGICAL, 77}, 20322834Smckusick "llt", { INTRSPEC, TYLOGICAL, 79}, 20422834Smckusick 20524480Sdonn "", { INTREND, 0, 0} }; 20622834Smckusick 20722834Smckusick 20822834Smckusick LOCAL struct Specblock 20922834Smckusick { 21022834Smckusick char atype; 21122834Smckusick char rtype; 21222834Smckusick char nargs; 21322834Smckusick char spxname[XL]; 21422834Smckusick char othername; /* index into callbyvalue table */ 21522834Smckusick } spectab[ ] = 21622834Smckusick { 21722834Smckusick { TYREAL,TYREAL,1,"r_int" }, 21822834Smckusick { TYDREAL,TYDREAL,1,"d_int" }, 21922834Smckusick 22022834Smckusick { TYREAL,TYREAL,1,"r_nint" }, 22122834Smckusick { TYDREAL,TYDREAL,1,"d_nint" }, 22222834Smckusick 22322834Smckusick { TYREAL,TYSHORT,1,"h_nint" }, 22422834Smckusick { TYREAL,TYLONG,1,"i_nint" }, 22522834Smckusick 22622834Smckusick { TYDREAL,TYSHORT,1,"h_dnnt" }, 22722834Smckusick { TYDREAL,TYLONG,1,"i_dnnt" }, 22822834Smckusick 22922834Smckusick { TYREAL,TYREAL,1,"r_abs" }, 23022834Smckusick { TYSHORT,TYSHORT,1,"h_abs" }, 23122834Smckusick { TYLONG,TYLONG,1,"i_abs" }, 23222834Smckusick { TYDREAL,TYDREAL,1,"d_abs" }, 23322834Smckusick { TYCOMPLEX,TYREAL,1,"c_abs" }, 23422834Smckusick { TYDCOMPLEX,TYDREAL,1,"z_abs" }, 23522834Smckusick 23622834Smckusick { TYSHORT,TYSHORT,2,"h_mod" }, 23722834Smckusick { TYLONG,TYLONG,2,"i_mod" }, 23822834Smckusick { TYREAL,TYREAL,2,"r_mod" }, 23922834Smckusick { TYDREAL,TYDREAL,2,"d_mod" }, 24022834Smckusick 24122834Smckusick { TYREAL,TYREAL,2,"r_sign" }, 24222834Smckusick { TYSHORT,TYSHORT,2,"h_sign" }, 24322834Smckusick { TYLONG,TYLONG,2,"i_sign" }, 24422834Smckusick { TYDREAL,TYDREAL,2,"d_sign" }, 24522834Smckusick 24622834Smckusick { TYREAL,TYREAL,2,"r_dim" }, 24722834Smckusick { TYSHORT,TYSHORT,2,"h_dim" }, 24822834Smckusick { TYLONG,TYLONG,2,"i_dim" }, 24922834Smckusick { TYDREAL,TYDREAL,2,"d_dim" }, 25022834Smckusick 25122834Smckusick { TYREAL,TYDREAL,2,"d_prod" }, 25222834Smckusick 25322834Smckusick { TYCHAR,TYSHORT,1,"h_len" }, 25422834Smckusick { TYCHAR,TYLONG,1,"i_len" }, 25522834Smckusick 25622834Smckusick { TYCHAR,TYSHORT,2,"h_indx" }, 25722834Smckusick { TYCHAR,TYLONG,2,"i_indx" }, 25822834Smckusick 25922834Smckusick { TYCOMPLEX,TYREAL,1,"r_imag" }, 26022834Smckusick { TYDCOMPLEX,TYDREAL,1,"d_imag" }, 26122834Smckusick { TYCOMPLEX,TYCOMPLEX,1,"r_cnjg" }, 26222834Smckusick { TYDCOMPLEX,TYDCOMPLEX,1,"d_cnjg" }, 26322834Smckusick 26422834Smckusick { TYREAL,TYREAL,1,"r_sqrt", 1 }, 26522834Smckusick { TYDREAL,TYDREAL,1,"d_sqrt", 1 }, 26622834Smckusick { TYCOMPLEX,TYCOMPLEX,1,"c_sqrt" }, 26722834Smckusick { TYDCOMPLEX,TYDCOMPLEX,1,"z_sqrt" }, 26822834Smckusick 26922834Smckusick { TYREAL,TYREAL,1,"r_exp", 2 }, 27022834Smckusick { TYDREAL,TYDREAL,1,"d_exp", 2 }, 27122834Smckusick { TYCOMPLEX,TYCOMPLEX,1,"c_exp" }, 27222834Smckusick { TYDCOMPLEX,TYDCOMPLEX,1,"z_exp" }, 27322834Smckusick 27422834Smckusick { TYREAL,TYREAL,1,"r_log", 3 }, 27522834Smckusick { TYDREAL,TYDREAL,1,"d_log", 3 }, 27622834Smckusick { TYCOMPLEX,TYCOMPLEX,1,"c_log" }, 27722834Smckusick { TYDCOMPLEX,TYDCOMPLEX,1,"z_log" }, 27822834Smckusick 27924480Sdonn { TYREAL,TYREAL,1,"r_lg10", 14 }, 28024480Sdonn { TYDREAL,TYDREAL,1,"d_lg10", 14 }, 28122834Smckusick 28222834Smckusick { TYREAL,TYREAL,1,"r_sin", 4 }, 28322834Smckusick { TYDREAL,TYDREAL,1,"d_sin", 4 }, 28422834Smckusick { TYCOMPLEX,TYCOMPLEX,1,"c_sin" }, 28522834Smckusick { TYDCOMPLEX,TYDCOMPLEX,1,"z_sin" }, 28622834Smckusick 28722834Smckusick { TYREAL,TYREAL,1,"r_cos", 5 }, 28822834Smckusick { TYDREAL,TYDREAL,1,"d_cos", 5 }, 28922834Smckusick { TYCOMPLEX,TYCOMPLEX,1,"c_cos" }, 29022834Smckusick { TYDCOMPLEX,TYDCOMPLEX,1,"z_cos" }, 29122834Smckusick 29222834Smckusick { TYREAL,TYREAL,1,"r_tan", 6 }, 29322834Smckusick { TYDREAL,TYDREAL,1,"d_tan", 6 }, 29422834Smckusick 29522834Smckusick { TYREAL,TYREAL,1,"r_asin", 7 }, 29622834Smckusick { TYDREAL,TYDREAL,1,"d_asin", 7 }, 29722834Smckusick 29822834Smckusick { TYREAL,TYREAL,1,"r_acos", 8 }, 29922834Smckusick { TYDREAL,TYDREAL,1,"d_acos", 8 }, 30022834Smckusick 30122834Smckusick { TYREAL,TYREAL,1,"r_atan", 9 }, 30222834Smckusick { TYDREAL,TYDREAL,1,"d_atan", 9 }, 30322834Smckusick 30422834Smckusick { TYREAL,TYREAL,2,"r_atn2", 10 }, 30522834Smckusick { TYDREAL,TYDREAL,2,"d_atn2", 10 }, 30622834Smckusick 30722834Smckusick { TYREAL,TYREAL,1,"r_sinh", 11 }, 30822834Smckusick { TYDREAL,TYDREAL,1,"d_sinh", 11 }, 30922834Smckusick 31022834Smckusick { TYREAL,TYREAL,1,"r_cosh", 12 }, 31122834Smckusick { TYDREAL,TYDREAL,1,"d_cosh", 12 }, 31222834Smckusick 31322834Smckusick { TYREAL,TYREAL,1,"r_tanh", 13 }, 31422834Smckusick { TYDREAL,TYDREAL,1,"d_tanh", 13 }, 31522834Smckusick 31622834Smckusick { TYCHAR,TYLOGICAL,2,"hl_ge" }, 31722834Smckusick { TYCHAR,TYLOGICAL,2,"l_ge" }, 31822834Smckusick 31922834Smckusick { TYCHAR,TYLOGICAL,2,"hl_gt" }, 32022834Smckusick { TYCHAR,TYLOGICAL,2,"l_gt" }, 32122834Smckusick 32222834Smckusick { TYCHAR,TYLOGICAL,2,"hl_le" }, 32322834Smckusick { TYCHAR,TYLOGICAL,2,"l_le" }, 32422834Smckusick 32522834Smckusick { TYCHAR,TYLOGICAL,2,"hl_lt" }, 32622834Smckusick { TYCHAR,TYLOGICAL,2,"l_lt" }, 32722834Smckusick 32824480Sdonn { TYDREAL,TYDREAL,2,"d_dprod"} /* dprod() with dblflag */ 32922834Smckusick } ; 33022834Smckusick 33122834Smckusick char callbyvalue[ ][XL] = 33222834Smckusick { 33322834Smckusick "sqrt", 33422834Smckusick "exp", 33522834Smckusick "log", 33622834Smckusick "sin", 33722834Smckusick "cos", 33822834Smckusick "tan", 33922834Smckusick "asin", 34022834Smckusick "acos", 34122834Smckusick "atan", 34222834Smckusick "atan2", 34322834Smckusick "sinh", 34422834Smckusick "cosh", 34524480Sdonn "tanh", 34624480Sdonn "log10" 34722834Smckusick }; 34822834Smckusick 34922834Smckusick expptr intrcall(np, argsp, nargs) 35022834Smckusick Namep np; 35122834Smckusick struct Listblock *argsp; 35222834Smckusick int nargs; 35322834Smckusick { 35422834Smckusick int i, rettype; 35522834Smckusick Addrp ap; 35622834Smckusick register struct Specblock *sp; 35722834Smckusick register struct Chain *cp; 358*47880Ssklower expptr Inline(), mkcxcon(), mkrealcon(); 35922834Smckusick expptr q, ep; 36022834Smckusick int mtype; 36122834Smckusick int op; 36222834Smckusick int f1field, f2field, f3field; 36322834Smckusick 36422834Smckusick packed.ijunk = np->vardesc.varno; 36522834Smckusick f1field = packed.bits.f1; 36622834Smckusick f2field = packed.bits.f2; 36722834Smckusick f3field = packed.bits.f3; 36822834Smckusick if(nargs == 0) 36922834Smckusick goto badnargs; 37022834Smckusick 37122834Smckusick mtype = 0; 37222834Smckusick for(cp = argsp->listp ; cp ; cp = cp->nextp) 37322834Smckusick { 37422834Smckusick /* TEMPORARY */ ep = (expptr) (cp->datap); 37522834Smckusick /* TEMPORARY */ if( ISCONST(ep) && ep->headblock.vtype==TYSHORT ) 37622834Smckusick /* TEMPORARY */ cp->datap = (tagptr) mkconv(tyint, ep); 37722834Smckusick mtype = maxtype(mtype, ep->headblock.vtype); 37822834Smckusick } 37922834Smckusick 38022834Smckusick switch(f1field) 38122834Smckusick { 38222834Smckusick case INTRBOOL: 38322834Smckusick op = f3field; 38422834Smckusick if( ! ONEOF(mtype, MSKINT|MSKLOGICAL) ) 38522834Smckusick goto badtype; 38622834Smckusick if(op == OPBITNOT) 38722834Smckusick { 38822834Smckusick if(nargs != 1) 38922834Smckusick goto badnargs; 39022834Smckusick q = mkexpr(OPBITNOT, argsp->listp->datap, ENULL); 39122834Smckusick } 39222834Smckusick else 39322834Smckusick { 39422834Smckusick if(nargs != 2) 39522834Smckusick goto badnargs; 39622834Smckusick q = mkexpr(op, argsp->listp->datap, 39722834Smckusick argsp->listp->nextp->datap); 39822834Smckusick } 39922834Smckusick frchain( &(argsp->listp) ); 40022834Smckusick free( (charptr) argsp); 40122834Smckusick return(q); 40222834Smckusick 40322834Smckusick case INTRCONV: 40422834Smckusick if (nargs == 1) 40522834Smckusick { 40622834Smckusick if(argsp->listp->datap->headblock.vtype == TYERROR) 40722834Smckusick { 40822834Smckusick free( (charptr) argsp->listp->datap); 40922834Smckusick frchain( &(argsp->listp) ); 41022834Smckusick free( (charptr) argsp); 41122834Smckusick return( errnode() ); 41222834Smckusick } 41322834Smckusick } 41422834Smckusick else if (nargs == 2) 41522834Smckusick { 41622834Smckusick if(argsp->listp->nextp->datap->headblock.vtype == 41722834Smckusick TYERROR || 41822834Smckusick argsp->listp->datap->headblock.vtype == TYERROR) 41922834Smckusick { 42022834Smckusick free( (charptr) argsp->listp->nextp->datap); 42122834Smckusick free( (charptr) argsp->listp->datap); 42222834Smckusick frchain( &(argsp->listp) ); 42322834Smckusick free( (charptr) argsp); 42422834Smckusick return( errnode() ); 42522834Smckusick } 42622834Smckusick } 42722834Smckusick rettype = f2field; 42822834Smckusick if( ISCOMPLEX(rettype) && nargs==2) 42922834Smckusick { 43022834Smckusick expptr qr, qi; 43124480Sdonn if(dblflag) rettype = TYDCOMPLEX; 43222834Smckusick qr = (expptr) (argsp->listp->datap); 43322834Smckusick qi = (expptr) (argsp->listp->nextp->datap); 43422834Smckusick if(ISCONST(qr) && ISCONST(qi)) 43522834Smckusick q = mkcxcon(qr,qi); 43622834Smckusick else q = mkexpr(OPCONV,intrconv(rettype-2,qr), 43722834Smckusick intrconv(rettype-2,qi)); 43822834Smckusick } 43922834Smckusick else if(nargs == 1) 44024480Sdonn { 44124480Sdonn if(rettype == TYLONG) rettype = tyint; 44224480Sdonn else if( dblflag ) 44324480Sdonn { 44424480Sdonn if ( rettype == TYREAL ) 44524480Sdonn rettype = TYDREAL; 44624480Sdonn else if( rettype == TYCOMPLEX ) 44724480Sdonn rettype = TYDCOMPLEX; 44824480Sdonn } 44922834Smckusick q = intrconv(rettype, argsp->listp->datap); 45024480Sdonn } 45122834Smckusick else goto badnargs; 45222834Smckusick 45322834Smckusick q->headblock.vtype = rettype; 45422834Smckusick frchain(&(argsp->listp)); 45522834Smckusick free( (charptr) argsp); 45622834Smckusick return(q); 45722834Smckusick 45822834Smckusick case INTRGEN: 45922834Smckusick sp = spectab + f3field; 46024480Sdonn #ifdef ONLY66 46122834Smckusick if(no66flag) 46222834Smckusick if(sp->atype == mtype) 46322834Smckusick goto specfunct; 46422834Smckusick else err66("generic function"); 46524480Sdonn #endif 46622834Smckusick 46722834Smckusick for(i=0; i<f2field ; ++i) 46822834Smckusick if(sp->atype == mtype) 46922834Smckusick goto specfunct; 47022834Smckusick else 47122834Smckusick ++sp; 47222834Smckusick goto badtype; 47322834Smckusick 47422834Smckusick case INTRSPEC: 47522834Smckusick sp = spectab + f3field; 47624480Sdonn if( dblflag ) 47724480Sdonn { 47824480Sdonn /* convert specific complex functions to double complex: 47924480Sdonn * cabs,csqrt,cexp,clog,csin,ccos, aimag 48024480Sdonn * and convert real specifics to double: 48124480Sdonn * amod,alog,alog10 48224480Sdonn * (sqrt,cos,sin,... o.k. since go through INTRGEN) 48324480Sdonn */ 48424480Sdonn if( (sp->atype==TYCOMPLEX && (sp+1)->atype==TYDCOMPLEX) 48524480Sdonn ||(sp->atype==TYREAL && (sp+1)->atype==TYDREAL)) 48624480Sdonn sp++; 48724480Sdonn } 48822834Smckusick specfunct: 48922834Smckusick if(tyint==TYLONG && ONEOF(sp->rtype,M(TYSHORT)|M(TYLOGICAL)) 49022834Smckusick && (sp+1)->atype==sp->atype) 49122834Smckusick ++sp; 49222834Smckusick 49322834Smckusick if(nargs != sp->nargs) 49422834Smckusick goto badnargs; 49524480Sdonn if(mtype != sp->atype 49624480Sdonn && (!dblflag || f3field != 26 || mtype != TYDREAL ) ) 49724480Sdonn goto badtype; 49822834Smckusick fixargs(YES, argsp); 499*47880Ssklower if(q = Inline(sp-spectab, mtype, argsp->listp)) 50022834Smckusick { 50122834Smckusick frchain( &(argsp->listp) ); 50222834Smckusick free( (charptr) argsp); 50322834Smckusick } 50422834Smckusick else if(sp->othername) 50522834Smckusick { 50624480Sdonn ap = builtin(TYDREAL, 50722834Smckusick varstr(XL, callbyvalue[sp->othername-1]) ); 50822834Smckusick ap->vstg = STGINTR; 50922834Smckusick q = fixexpr( mkexpr(OPCCALL, ap, argsp) ); 51024480Sdonn if( sp->rtype != TYDREAL ) 51124480Sdonn q = mkconv( sp->rtype, q ); 51222834Smckusick } 51322834Smckusick else 51422834Smckusick { 51522834Smckusick ap = builtin(sp->rtype, varstr(XL, sp->spxname) ); 51622834Smckusick ap->vstg = STGINTR; 51722834Smckusick q = fixexpr( mkexpr(OPCALL, ap, argsp) ); 51822834Smckusick } 51922834Smckusick return(q); 52022834Smckusick 52122834Smckusick case INTRMIN: 52222834Smckusick case INTRMAX: 52322834Smckusick if(nargs < 2) 52422834Smckusick goto badnargs; 52522834Smckusick if( ! ONEOF(mtype, MSKINT|MSKREAL) ) 52622834Smckusick goto badtype; 52722834Smckusick argsp->vtype = mtype; 52822834Smckusick q = mkexpr( (f1field==INTRMIN ? OPMIN : OPMAX), argsp, ENULL); 52922834Smckusick 53022834Smckusick q->headblock.vtype = mtype; 53122834Smckusick rettype = f2field; 53222834Smckusick if(rettype == TYLONG) 53322834Smckusick rettype = tyint; 53422834Smckusick else if(rettype == TYUNKNOWN) 53522834Smckusick rettype = mtype; 53624480Sdonn else if( dblflag && rettype == TYREAL ) 53724480Sdonn rettype = TYDREAL; 53822834Smckusick return( intrconv(rettype, q) ); 53922834Smckusick 54022834Smckusick default: 54122834Smckusick fatali("intrcall: bad intrgroup %d", f1field); 54222834Smckusick } 54322834Smckusick badnargs: 54422834Smckusick errstr("bad number of arguments to intrinsic %s", 54522834Smckusick varstr(VL,np->varname) ); 54622834Smckusick goto bad; 54722834Smckusick 54822834Smckusick badtype: 54922834Smckusick errstr("bad argument type to intrinsic %s", varstr(VL, np->varname) ); 55022834Smckusick 55122834Smckusick bad: 55222834Smckusick return( errnode() ); 55322834Smckusick } 55422834Smckusick 55522834Smckusick 55622834Smckusick 55722834Smckusick 55822834Smckusick intrfunct(s) 55922834Smckusick char s[VL]; 56022834Smckusick { 56122834Smckusick register struct Intrblock *p; 56222834Smckusick char nm[VL]; 56322834Smckusick register int i; 56422834Smckusick 56522834Smckusick for(i = 0 ; i<VL ; ++s) 56622834Smckusick nm[i++] = (*s==' ' ? '\0' : *s); 56722834Smckusick 56822834Smckusick for(p = intrtab; p->intrval.intrgroup!=INTREND ; ++p) 56922834Smckusick { 57022834Smckusick if( eqn(VL, nm, p->intrfname) ) 57122834Smckusick { 57222834Smckusick packed.bits.f1 = p->intrval.intrgroup; 57322834Smckusick packed.bits.f2 = p->intrval.intrstuff; 57422834Smckusick packed.bits.f3 = p->intrval.intrno; 57522834Smckusick return(packed.ijunk); 57622834Smckusick } 57722834Smckusick } 57822834Smckusick 57922834Smckusick return(0); 58022834Smckusick } 58122834Smckusick 58222834Smckusick 58322834Smckusick 58422834Smckusick 58522834Smckusick 58622834Smckusick Addrp intraddr(np) 58722834Smckusick Namep np; 58822834Smckusick { 58922834Smckusick Addrp q; 59022834Smckusick register struct Specblock *sp; 59122834Smckusick int f3field; 59222834Smckusick 59322834Smckusick if(np->vclass!=CLPROC || np->vprocclass!=PINTRINSIC) 59422834Smckusick fatalstr("intraddr: %s is not intrinsic", varstr(VL,np->varname)); 59522834Smckusick packed.ijunk = np->vardesc.varno; 59622834Smckusick f3field = packed.bits.f3; 59722834Smckusick 59822834Smckusick switch(packed.bits.f1) 59922834Smckusick { 60022834Smckusick case INTRGEN: 60122834Smckusick /* imag, log, and log10 arent specific functions */ 60222834Smckusick if(f3field==31 || f3field==43 || f3field==47) 60322834Smckusick goto bad; 60422834Smckusick 60522834Smckusick case INTRSPEC: 60622834Smckusick sp = spectab + f3field; 60724480Sdonn if( dblflag ) 60824480Sdonn { 60924480Sdonn if((sp->atype==TYCOMPLEX && (sp+1)->atype==TYDCOMPLEX) 61024480Sdonn ||(sp->atype==TYREAL && (sp+1)->atype==TYDREAL)) 61124480Sdonn sp++; 61224480Sdonn else if( f3field==4 ) 61324480Sdonn sp += 2; /* h_nint -> h_dnnt */ 61424480Sdonn else if( f3field==8 || f3field==18 || f3field==22) 61524480Sdonn sp += 3; /* r_{abs,sign,dim} ->d_... */ 61624480Sdonn else if( f3field==26 ) 61724480Sdonn sp = spectab + 81; /* dprod */ 61824480Sdonn 61924480Sdonn } 62022834Smckusick if(tyint==TYLONG && sp->rtype==TYSHORT) 62122834Smckusick ++sp; 62222834Smckusick q = builtin(sp->rtype, varstr(XL,sp->spxname) ); 62322834Smckusick q->vstg = STGINTR; 62422834Smckusick return(q); 62522834Smckusick 62622834Smckusick case INTRCONV: 62722834Smckusick case INTRMIN: 62822834Smckusick case INTRMAX: 62922834Smckusick case INTRBOOL: 63022834Smckusick bad: 63122834Smckusick errstr("cannot pass %s as actual", 63222834Smckusick varstr(VL,np->varname)); 63322834Smckusick return( (Addrp) errnode() ); 63422834Smckusick } 63522834Smckusick fatali("intraddr: impossible f1=%d\n", (int) packed.bits.f1); 63622834Smckusick /* NOTREACHED */ 63722834Smckusick } 63822834Smckusick 63922834Smckusick 64022834Smckusick 64122834Smckusick 64222834Smckusick 643*47880Ssklower expptr Inline(fno, type, args) 64422834Smckusick int fno; 64522834Smckusick int type; 64622834Smckusick struct Chain *args; 64722834Smckusick { 64822834Smckusick register expptr q, t, t1; 64922834Smckusick 65022834Smckusick switch(fno) 65122834Smckusick { 65222834Smckusick case 8: /* real abs */ 65322834Smckusick case 9: /* short int abs */ 65422834Smckusick case 10: /* long int abs */ 65522834Smckusick case 11: /* double precision abs */ 65622834Smckusick if( addressable(q = (expptr) (args->datap)) ) 65722834Smckusick { 65822834Smckusick t = q; 65922834Smckusick q = NULL; 66022834Smckusick } 66122834Smckusick else 66222834Smckusick t = (expptr) mktemp(type,PNULL); 66322834Smckusick t1 = mkexpr(OPQUEST, 66422834Smckusick mkexpr(OPLE, intrconv(type,ICON(0)), cpexpr(t)), 66522834Smckusick mkexpr(OPCOLON, cpexpr(t), 66622834Smckusick mkexpr(OPNEG, cpexpr(t), ENULL) )); 66722834Smckusick if(q) 66822834Smckusick t1 = mkexpr(OPCOMMA, mkexpr(OPASSIGN, cpexpr(t),q), t1); 66922834Smckusick frexpr(t); 67022834Smckusick return(t1); 67122834Smckusick 67222834Smckusick case 26: /* dprod */ 67322834Smckusick q = mkexpr(OPSTAR, intrconv(TYDREAL,args->datap), args->nextp->datap); 67422834Smckusick return(q); 67522834Smckusick 67622834Smckusick case 27: /* len of character string */ 67722834Smckusick case 28: 67822834Smckusick q = (expptr) cpexpr(args->datap->headblock.vleng); 67922834Smckusick frexpr(args->datap); 68022834Smckusick return(q); 68122834Smckusick 68222834Smckusick case 14: /* half-integer mod */ 68322834Smckusick case 15: /* mod */ 68422834Smckusick return( mkexpr(OPMOD, (expptr) (args->datap), 68522834Smckusick (expptr) (args->nextp->datap) )); 68622834Smckusick } 68722834Smckusick return(NULL); 68822834Smckusick } 689