1*3191Smckusick /* Copyright (c) 1979 Regents of the University of California */ 2*3191Smckusick 3*3191Smckusick static char sccsid[] = "@(#)fhdr.c 1.1 03/11/81"; 4*3191Smckusick 5*3191Smckusick #include "whoami.h" 6*3191Smckusick #include "0.h" 7*3191Smckusick #include "tree.h" 8*3191Smckusick #include "opcode.h" 9*3191Smckusick #include "objfmt.h" 10*3191Smckusick #include "align.h" 11*3191Smckusick 12*3191Smckusick /* 13*3191Smckusick * this array keeps the pxp counters associated with 14*3191Smckusick * functions and procedures, so that they can be output 15*3191Smckusick * when their bodies are encountered 16*3191Smckusick */ 17*3191Smckusick int bodycnts[ DSPLYSZ ]; 18*3191Smckusick 19*3191Smckusick #ifdef PC 20*3191Smckusick # include "pc.h" 21*3191Smckusick # include "pcops.h" 22*3191Smckusick #endif PC 23*3191Smckusick 24*3191Smckusick #ifdef OBJ 25*3191Smckusick int cntpatch; 26*3191Smckusick int nfppatch; 27*3191Smckusick #endif OBJ 28*3191Smckusick 29*3191Smckusick /* 30*3191Smckusick * Funchdr inserts 31*3191Smckusick * declaration of a the 32*3191Smckusick * prog/proc/func into the 33*3191Smckusick * namelist. It also handles 34*3191Smckusick * the arguments and puts out 35*3191Smckusick * a transfer which defines 36*3191Smckusick * the entry point of a procedure. 37*3191Smckusick */ 38*3191Smckusick 39*3191Smckusick struct nl * 40*3191Smckusick funchdr(r) 41*3191Smckusick int *r; 42*3191Smckusick { 43*3191Smckusick register struct nl *p; 44*3191Smckusick register *il, **rl; 45*3191Smckusick int *rll; 46*3191Smckusick struct nl *cp, *dp, *sp; 47*3191Smckusick int w, s, o, *pp; 48*3191Smckusick 49*3191Smckusick if (inpflist(r[2])) { 50*3191Smckusick opush('l'); 51*3191Smckusick yyretrieve(); /* kludge */ 52*3191Smckusick } 53*3191Smckusick pfcnt++; 54*3191Smckusick parts[ cbn ] |= RPRT; 55*3191Smckusick line = r[1]; 56*3191Smckusick if (r[3] == NIL && (p=lookup1(r[2])) != NIL && bn == cbn) { 57*3191Smckusick /* 58*3191Smckusick * Symbol already defined 59*3191Smckusick * in this block. it is either 60*3191Smckusick * a redeclared symbol (error) 61*3191Smckusick * a forward declaration, 62*3191Smckusick * or an external declaration. 63*3191Smckusick */ 64*3191Smckusick if ((p->class == FUNC || p->class == PROC) && (p->nl_flags & NFORWD) != 0) { 65*3191Smckusick /* 66*3191Smckusick * Grammar doesnt forbid 67*3191Smckusick * types on a resolution 68*3191Smckusick * of a forward function 69*3191Smckusick * declaration. 70*3191Smckusick */ 71*3191Smckusick if (p->class == FUNC && r[4]) 72*3191Smckusick error("Function type should be given only in forward declaration"); 73*3191Smckusick /* 74*3191Smckusick * get another counter for the actual 75*3191Smckusick */ 76*3191Smckusick if ( monflg ) { 77*3191Smckusick bodycnts[ cbn ] = getcnt(); 78*3191Smckusick } 79*3191Smckusick # ifdef PC 80*3191Smckusick enclosing[ cbn ] = p -> symbol; 81*3191Smckusick # endif PC 82*3191Smckusick # ifdef PTREE 83*3191Smckusick /* 84*3191Smckusick * mark this proc/func as forward 85*3191Smckusick * in the pTree. 86*3191Smckusick */ 87*3191Smckusick pDEF( p -> inTree ).PorFForward = TRUE; 88*3191Smckusick # endif PTREE 89*3191Smckusick return (p); 90*3191Smckusick } 91*3191Smckusick } 92*3191Smckusick 93*3191Smckusick /* if a routine segment is being compiled, 94*3191Smckusick * do level one processing. 95*3191Smckusick */ 96*3191Smckusick 97*3191Smckusick if ((r[0] != T_PROG) && (!progseen)) 98*3191Smckusick level1(); 99*3191Smckusick 100*3191Smckusick 101*3191Smckusick /* 102*3191Smckusick * Declare the prog/proc/func 103*3191Smckusick */ 104*3191Smckusick switch (r[0]) { 105*3191Smckusick case T_PROG: 106*3191Smckusick progseen = TRUE; 107*3191Smckusick if (opt('z')) 108*3191Smckusick monflg = TRUE; 109*3191Smckusick program = p = defnl(r[2], PROG, 0, 0); 110*3191Smckusick p->value[3] = r[1]; 111*3191Smckusick break; 112*3191Smckusick case T_PDEC: 113*3191Smckusick if (r[4] != NIL) 114*3191Smckusick error("Procedures do not have types, only functions do"); 115*3191Smckusick p = enter(defnl(r[2], PROC, 0, 0)); 116*3191Smckusick p->nl_flags |= NMOD; 117*3191Smckusick # ifdef PC 118*3191Smckusick enclosing[ cbn ] = r[2]; 119*3191Smckusick # endif PC 120*3191Smckusick break; 121*3191Smckusick case T_FDEC: 122*3191Smckusick il = r[4]; 123*3191Smckusick if (il == NIL) 124*3191Smckusick error("Function type must be specified"); 125*3191Smckusick else if (il[0] != T_TYID) { 126*3191Smckusick il = NIL; 127*3191Smckusick error("Function type can be specified only by using a type identifier"); 128*3191Smckusick } else 129*3191Smckusick il = gtype(il); 130*3191Smckusick p = enter(defnl(r[2], FUNC, il, NIL)); 131*3191Smckusick p->nl_flags |= NMOD; 132*3191Smckusick /* 133*3191Smckusick * An arbitrary restriction 134*3191Smckusick */ 135*3191Smckusick switch (o = classify(p->type)) { 136*3191Smckusick case TFILE: 137*3191Smckusick case TARY: 138*3191Smckusick case TREC: 139*3191Smckusick case TSET: 140*3191Smckusick case TSTR: 141*3191Smckusick warning(); 142*3191Smckusick if (opt('s')) { 143*3191Smckusick standard(); 144*3191Smckusick } 145*3191Smckusick error("Functions should not return %ss", clnames[o]); 146*3191Smckusick } 147*3191Smckusick # ifdef PC 148*3191Smckusick enclosing[ cbn ] = r[2]; 149*3191Smckusick # endif PC 150*3191Smckusick break; 151*3191Smckusick default: 152*3191Smckusick panic("funchdr"); 153*3191Smckusick } 154*3191Smckusick if (r[0] != T_PROG) { 155*3191Smckusick /* 156*3191Smckusick * Mark this proc/func as 157*3191Smckusick * being forward declared 158*3191Smckusick */ 159*3191Smckusick p->nl_flags |= NFORWD; 160*3191Smckusick /* 161*3191Smckusick * Enter the parameters 162*3191Smckusick * in the next block for 163*3191Smckusick * the time being 164*3191Smckusick */ 165*3191Smckusick if (++cbn >= DSPLYSZ) { 166*3191Smckusick error("Procedure/function nesting too deep"); 167*3191Smckusick pexit(ERRS); 168*3191Smckusick } 169*3191Smckusick /* 170*3191Smckusick * For functions, the function variable 171*3191Smckusick */ 172*3191Smckusick if (p->class == FUNC) { 173*3191Smckusick # ifdef OBJ 174*3191Smckusick cp = defnl(r[2], FVAR, p->type, 0); 175*3191Smckusick # endif OBJ 176*3191Smckusick # ifdef PC 177*3191Smckusick /* 178*3191Smckusick * fvars used to be allocated and deallocated 179*3191Smckusick * by the caller right before the arguments. 180*3191Smckusick * the offset of the fvar was kept in 181*3191Smckusick * value[NL_OFFS] of function (very wierd, 182*3191Smckusick * but see asgnop). 183*3191Smckusick * now, they are locals to the function 184*3191Smckusick * with the offset kept in the fvar. 185*3191Smckusick */ 186*3191Smckusick 187*3191Smckusick cp = defnl(r[2], FVAR, p->type, 188*3191Smckusick -(roundup((int)(DPOFF1+lwidth(p->type)), 189*3191Smckusick (long)align(p->type)))); 190*3191Smckusick # endif PC 191*3191Smckusick cp->chain = p; 192*3191Smckusick p->ptr[NL_FVAR] = cp; 193*3191Smckusick } 194*3191Smckusick /* 195*3191Smckusick * Enter the parameters 196*3191Smckusick * and compute total size 197*3191Smckusick */ 198*3191Smckusick cp = sp = p; 199*3191Smckusick 200*3191Smckusick # ifdef OBJ 201*3191Smckusick o = 0; 202*3191Smckusick # endif OBJ 203*3191Smckusick # ifdef PC 204*3191Smckusick /* 205*3191Smckusick * parameters used to be allocated backwards, 206*3191Smckusick * then fixed. for pc, they are allocated correctly. 207*3191Smckusick * also, they are aligned. 208*3191Smckusick */ 209*3191Smckusick o = DPOFF2; 210*3191Smckusick # endif PC 211*3191Smckusick for (rl = r[3]; rl != NIL; rl = rl[2]) { 212*3191Smckusick p = NIL; 213*3191Smckusick if (rl[1] == NIL) 214*3191Smckusick continue; 215*3191Smckusick /* 216*3191Smckusick * Parametric procedures 217*3191Smckusick * don't have types !?! 218*3191Smckusick */ 219*3191Smckusick if (rl[1][0] != T_PPROC) { 220*3191Smckusick rll = rl[1][2]; 221*3191Smckusick if (rll[0] != T_TYID) { 222*3191Smckusick error("Types for arguments can be specified only by using type identifiers"); 223*3191Smckusick p = NIL; 224*3191Smckusick } else 225*3191Smckusick p = gtype(rll); 226*3191Smckusick } 227*3191Smckusick for (il = rl[1][1]; il != NIL; il = il[2]) { 228*3191Smckusick switch (rl[1][0]) { 229*3191Smckusick default: 230*3191Smckusick panic("funchdr2"); 231*3191Smckusick case T_PVAL: 232*3191Smckusick if (p != NIL) { 233*3191Smckusick if (p->class == FILET) 234*3191Smckusick error("Files cannot be passed by value"); 235*3191Smckusick else if (p->nl_flags & NFILES) 236*3191Smckusick error("Files cannot be a component of %ss passed by value", 237*3191Smckusick nameof(p)); 238*3191Smckusick } 239*3191Smckusick # ifdef OBJ 240*3191Smckusick w = width(p); 241*3191Smckusick o -= even(w); 242*3191Smckusick # ifdef DEC11 243*3191Smckusick dp = defnl(il[1], VAR, p, o); 244*3191Smckusick # else 245*3191Smckusick dp = defnl(il[1], VAR, p, 246*3191Smckusick (w < 2) ? o + 1 : o); 247*3191Smckusick # endif DEC11 248*3191Smckusick # endif OBJ 249*3191Smckusick # ifdef PC 250*3191Smckusick dp = defnl( il[1] , VAR , p 251*3191Smckusick , o = roundup( o , (long)A_STACK ) ); 252*3191Smckusick o += width( p ); 253*3191Smckusick # endif PC 254*3191Smckusick dp->nl_flags |= NMOD; 255*3191Smckusick break; 256*3191Smckusick case T_PVAR: 257*3191Smckusick # ifdef OBJ 258*3191Smckusick dp = defnl(il[1], REF, p, o -= sizeof ( int * ) ); 259*3191Smckusick # endif OBJ 260*3191Smckusick # ifdef PC 261*3191Smckusick dp = defnl( il[1] , REF , p 262*3191Smckusick , o = roundup( o , (long)A_STACK ) ); 263*3191Smckusick o += sizeof(char *); 264*3191Smckusick # endif PC 265*3191Smckusick break; 266*3191Smckusick case T_PFUNC: 267*3191Smckusick # ifdef OBJ 268*3191Smckusick dp = defnl(il[1], FFUNC, p, o -= sizeof ( int * ) ); 269*3191Smckusick # endif OBJ 270*3191Smckusick # ifdef PC 271*3191Smckusick dp = defnl( il[1] , FFUNC , p 272*3191Smckusick , o = roundup( o , (long)A_STACK ) ); 273*3191Smckusick o += sizeof(char *); 274*3191Smckusick # endif PC 275*3191Smckusick dp -> nl_flags |= NMOD; 276*3191Smckusick break; 277*3191Smckusick case T_PPROC: 278*3191Smckusick # ifdef OBJ 279*3191Smckusick dp = defnl(il[1], FPROC, p, o -= sizeof ( int * ) ); 280*3191Smckusick # endif OBJ 281*3191Smckusick # ifdef PC 282*3191Smckusick dp = defnl( il[1] , FPROC , p 283*3191Smckusick , o = roundup( o , (long)A_STACK ) ); 284*3191Smckusick o += sizeof(char *); 285*3191Smckusick # endif PC 286*3191Smckusick dp -> nl_flags |= NMOD; 287*3191Smckusick break; 288*3191Smckusick } 289*3191Smckusick if (dp != NIL) { 290*3191Smckusick cp->chain = dp; 291*3191Smckusick cp = dp; 292*3191Smckusick } 293*3191Smckusick } 294*3191Smckusick } 295*3191Smckusick cbn--; 296*3191Smckusick p = sp; 297*3191Smckusick # ifdef OBJ 298*3191Smckusick p->value[NL_OFFS] = -o+DPOFF2; 299*3191Smckusick /* 300*3191Smckusick * Correct the naivete (naievity) 301*3191Smckusick * of our above code to 302*3191Smckusick * calculate offsets 303*3191Smckusick */ 304*3191Smckusick for (il = p->chain; il != NIL; il = il->chain) 305*3191Smckusick il->value[NL_OFFS] += p->value[NL_OFFS]; 306*3191Smckusick # endif OBJ 307*3191Smckusick # ifdef PC 308*3191Smckusick p -> value[ NL_OFFS ] = roundup( o , (long)A_STACK ); 309*3191Smckusick # endif PC 310*3191Smckusick } else { 311*3191Smckusick /* 312*3191Smckusick * The wonderful 313*3191Smckusick * program statement! 314*3191Smckusick */ 315*3191Smckusick # ifdef OBJ 316*3191Smckusick if (monflg) { 317*3191Smckusick put(1, O_PXPBUF); 318*3191Smckusick cntpatch = put(2, O_CASE4, (long)0); 319*3191Smckusick nfppatch = put(2, O_CASE4, (long)0); 320*3191Smckusick } 321*3191Smckusick # endif OBJ 322*3191Smckusick cp = p; 323*3191Smckusick for (rl = r[3]; rl; rl = rl[2]) { 324*3191Smckusick if (rl[1] == NIL) 325*3191Smckusick continue; 326*3191Smckusick dp = defnl(rl[1], VAR, 0, 0); 327*3191Smckusick cp->chain = dp; 328*3191Smckusick cp = dp; 329*3191Smckusick } 330*3191Smckusick } 331*3191Smckusick /* 332*3191Smckusick * Define a branch at 333*3191Smckusick * the "entry point" of 334*3191Smckusick * the prog/proc/func. 335*3191Smckusick */ 336*3191Smckusick p->entloc = getlab(); 337*3191Smckusick if (monflg) { 338*3191Smckusick bodycnts[ cbn ] = getcnt(); 339*3191Smckusick p->value[ NL_CNTR ] = 0; 340*3191Smckusick } 341*3191Smckusick # ifdef OBJ 342*3191Smckusick put(2, O_TRA4, (long)p->entloc); 343*3191Smckusick # endif OBJ 344*3191Smckusick # ifdef PTREE 345*3191Smckusick { 346*3191Smckusick pPointer PF = tCopy( r ); 347*3191Smckusick 348*3191Smckusick pSeize( PorFHeader[ nesting ] ); 349*3191Smckusick if ( r[0] != T_PROG ) { 350*3191Smckusick pPointer *PFs; 351*3191Smckusick 352*3191Smckusick PFs = &( pDEF( PorFHeader[ nesting ] ).PorFPFs ); 353*3191Smckusick *PFs = ListAppend( *PFs , PF ); 354*3191Smckusick } else { 355*3191Smckusick pDEF( PorFHeader[ nesting ] ).GlobProg = PF; 356*3191Smckusick } 357*3191Smckusick pRelease( PorFHeader[ nesting ] ); 358*3191Smckusick } 359*3191Smckusick # endif PTREE 360*3191Smckusick return (p); 361*3191Smckusick } 362