1*756Speter /* Copyright (c) 1979 Regents of the University of California */ 2*756Speter 3*756Speter static char sccsid[] = "@(#)lab.c 1.1 08/27/80"; 4*756Speter 5*756Speter #include "whoami.h" 6*756Speter #include "0.h" 7*756Speter #include "tree.h" 8*756Speter #include "opcode.h" 9*756Speter #include "objfmt.h" 10*756Speter #ifdef PC 11*756Speter # include "pc.h" 12*756Speter # include "pcops.h" 13*756Speter #endif PC 14*756Speter 15*756Speter /* 16*756Speter * Label enters the definitions 17*756Speter * of the label declaration part 18*756Speter * into the namelist. 19*756Speter */ 20*756Speter label(r, l) 21*756Speter int *r, l; 22*756Speter { 23*756Speter #ifndef PI0 24*756Speter register *ll; 25*756Speter register struct nl *p, *lp; 26*756Speter 27*756Speter lp = NIL; 28*756Speter #else 29*756Speter send(REVLAB, r); 30*756Speter #endif 31*756Speter if ( ! progseen ) { 32*756Speter level1(); 33*756Speter } 34*756Speter line = l; 35*756Speter #ifndef PI1 36*756Speter #ifdef PC 37*756Speter if (opt('s')) { 38*756Speter if (parts & (CPRT|TPRT|VPRT)){ 39*756Speter standard(); 40*756Speter error("Label declarations must precede const, type and var declarations"); 41*756Speter } 42*756Speter if (parts & LPRT) { 43*756Speter standard(); 44*756Speter error("All labels must be declared in one label part"); 45*756Speter } 46*756Speter } 47*756Speter #endif PC 48*756Speter #ifdef OBJ 49*756Speter if (parts & (CPRT|TPRT|VPRT)) 50*756Speter error("Label declarations must precede const, type and var declarations"); 51*756Speter if (parts & LPRT) 52*756Speter error("All labels must be declared in one label part"); 53*756Speter #endif OBJ 54*756Speter parts |= LPRT; 55*756Speter #endif 56*756Speter #ifndef PI0 57*756Speter for (ll = r; ll != NIL; ll = ll[2]) { 58*756Speter l = getlab(); 59*756Speter p = enter(defnl(ll[1], LABEL, 0, l)); 60*756Speter /* 61*756Speter * Get the label for the eventual target 62*756Speter */ 63*756Speter p->value[1] = getlab(); 64*756Speter p->chain = lp; 65*756Speter p->nl_flags |= (NFORWD|NMOD); 66*756Speter p->value[NL_GOLEV] = NOTYET; 67*756Speter p->entloc = l; 68*756Speter lp = p; 69*756Speter # ifdef OBJ 70*756Speter /* 71*756Speter * This operator is between 72*756Speter * the bodies of two procedures 73*756Speter * and provides a target for 74*756Speter * gotos for this label via TRA. 75*756Speter */ 76*756Speter putlab(l); 77*756Speter put2(O_GOTO | cbn<<8+INDX, p->value[1]); 78*756Speter # endif OBJ 79*756Speter # ifdef PC 80*756Speter /* 81*756Speter * labels have to be .globl otherwise /lib/c2 may 82*756Speter * throw them away if they aren't used in the function 83*756Speter * which defines them. 84*756Speter */ 85*756Speter if (cbn == 1) { 86*756Speter /* 87*756Speter * stab the label for separate compilation. 88*756Speter * make label number = label name. 89*756Speter */ 90*756Speter p -> value[1] = atol( p -> symbol ); 91*756Speter stabglab( p -> value[1] ); 92*756Speter putprintf( " .globl " , 1 ); 93*756Speter putprintf( PREFIXFORMAT , 0 , PLABELPREFIX 94*756Speter , p -> value[1] ); 95*756Speter } else { 96*756Speter putprintf( " .globl " , 1 ); 97*756Speter putprintf( PREFIXFORMAT , 0 , GLABELPREFIX 98*756Speter , p -> value[1] ); 99*756Speter } 100*756Speter # endif PC 101*756Speter } 102*756Speter gotos[cbn] = lp; 103*756Speter # ifdef PTREE 104*756Speter { 105*756Speter pPointer Labels = LabelDCopy( r ); 106*756Speter 107*756Speter pDEF( PorFHeader[ nesting ] ).PorFLabels = Labels; 108*756Speter } 109*756Speter # endif PTREE 110*756Speter #endif 111*756Speter } 112*756Speter 113*756Speter #ifndef PI0 114*756Speter /* 115*756Speter * Gotoop is called when 116*756Speter * we get a statement "goto label" 117*756Speter * and generates the needed tra. 118*756Speter */ 119*756Speter gotoop(s) 120*756Speter char *s; 121*756Speter { 122*756Speter register struct nl *p; 123*756Speter 124*756Speter gocnt++; 125*756Speter p = lookup(s); 126*756Speter if (p == NIL) 127*756Speter return (NIL); 128*756Speter # ifdef OBJ 129*756Speter put2(O_TRA4, p->entloc); 130*756Speter # endif OBJ 131*756Speter # ifdef PC 132*756Speter if ( cbn != bn ) { 133*756Speter /* 134*756Speter * call goto to unwind the stack to the destination level 135*756Speter */ 136*756Speter putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR ) 137*756Speter , "_GOTO" ); 138*756Speter putLV( DISPLAYNAME , 0 , bn * sizeof( struct dispsave ) 139*756Speter , P2PTR | P2INT ); 140*756Speter putop( P2CALL , P2INT ); 141*756Speter putdot( filename , line ); 142*756Speter } 143*756Speter if ( bn <= 1 ) { 144*756Speter printjbr( PLABELPREFIX , p -> value[1] ); 145*756Speter } else { 146*756Speter printjbr( GLABELPREFIX , p -> value[1] ); 147*756Speter } 148*756Speter # endif PC 149*756Speter if (bn == cbn) 150*756Speter if (p->nl_flags & NFORWD) { 151*756Speter if (p->value[NL_GOLEV] == NOTYET) { 152*756Speter p->value[NL_GOLEV] = level; 153*756Speter p->value[NL_GOLINE] = line; 154*756Speter } 155*756Speter } else 156*756Speter if (p->value[NL_GOLEV] == DEAD) { 157*756Speter recovered(); 158*756Speter error("Goto %s is into a structured statement", p->symbol); 159*756Speter } 160*756Speter } 161*756Speter 162*756Speter /* 163*756Speter * Labeled is called when a label 164*756Speter * definition is encountered, and 165*756Speter * marks that it has been found and 166*756Speter * patches the associated GOTO generated 167*756Speter * by gotoop. 168*756Speter */ 169*756Speter labeled(s) 170*756Speter char *s; 171*756Speter { 172*756Speter register struct nl *p; 173*756Speter 174*756Speter p = lookup(s); 175*756Speter if (p == NIL) 176*756Speter return (NIL); 177*756Speter if (bn != cbn) { 178*756Speter error("Label %s not defined in correct block", s); 179*756Speter return; 180*756Speter } 181*756Speter if ((p->nl_flags & NFORWD) == 0) { 182*756Speter error("Label %s redefined", s); 183*756Speter return; 184*756Speter } 185*756Speter p->nl_flags &= ~NFORWD; 186*756Speter # ifdef OBJ 187*756Speter patch4(p->entloc); 188*756Speter # endif OBJ 189*756Speter # ifdef PC 190*756Speter if ( bn <= 1 ) { 191*756Speter putprintf( PREFIXFORMAT , 1 , PLABELPREFIX , p -> value[1] ); 192*756Speter } else { 193*756Speter putprintf( PREFIXFORMAT , 1 , GLABELPREFIX , p -> value[1] ); 194*756Speter } 195*756Speter putprintf( ":" , 0 ); 196*756Speter # endif PC 197*756Speter if (p->value[NL_GOLEV] != NOTYET) 198*756Speter if (p->value[NL_GOLEV] < level) { 199*756Speter recovered(); 200*756Speter error("Goto %s from line %d is into a structured statement", s, p->value[NL_GOLINE]); 201*756Speter } 202*756Speter p->value[NL_GOLEV] = level; 203*756Speter } 204*756Speter #endif 205