1756Speter /* Copyright (c) 1979 Regents of the University of California */ 2756Speter 3*7951Speter static char sccsid[] = "@(#)lab.c 1.13 08/29/82"; 4756Speter 5756Speter #include "whoami.h" 6756Speter #include "0.h" 7756Speter #include "tree.h" 8756Speter #include "opcode.h" 9756Speter #include "objfmt.h" 10756Speter #ifdef PC 11756Speter # include "pc.h" 12756Speter # include "pcops.h" 13756Speter #endif PC 14756Speter 15756Speter /* 16756Speter * Label enters the definitions 17756Speter * of the label declaration part 18756Speter * into the namelist. 19756Speter */ 20756Speter label(r, l) 21756Speter int *r, l; 22756Speter { 23*7951Speter static bool label_order = FALSE; 24*7951Speter static bool label_seen = FALSE; 253366Speter #ifdef PC 263366Speter char extname[ BUFSIZ ]; 273366Speter #endif PC 28756Speter #ifndef PI0 29756Speter register *ll; 30756Speter register struct nl *p, *lp; 31756Speter 32756Speter lp = NIL; 33756Speter #else 34756Speter send(REVLAB, r); 35756Speter #endif 36756Speter if ( ! progseen ) { 37756Speter level1(); 38756Speter } 39756Speter line = l; 40756Speter #ifndef PI1 41835Speter if (parts[ cbn ] & (CPRT|TPRT|VPRT|RPRT)){ 42835Speter if ( opt( 's' ) ) { 43756Speter standard(); 44*7951Speter error("Label declarations should precede const, type, var and routine declarations"); 45835Speter } else { 46*7951Speter if ( !label_order ) { 47*7951Speter label_order = TRUE; 48*7951Speter warning(); 49*7951Speter error("Label declarations should precede const, type, var and routine declarations"); 50*7951Speter } 51835Speter } 52756Speter } 53835Speter if (parts[ cbn ] & LPRT) { 54835Speter if ( opt( 's' ) ) { 55756Speter standard(); 56*7951Speter error("All labels should be declared in one label part"); 57835Speter } else { 58*7951Speter if ( !label_seen ) { 59*7951Speter label_seen = TRUE; 60*7951Speter warning(); 61*7951Speter error("All labels should be declared in one label part"); 62*7951Speter } 63835Speter } 64756Speter } 65835Speter parts[ cbn ] |= LPRT; 66756Speter #endif 67756Speter #ifndef PI0 68756Speter for (ll = r; ll != NIL; ll = ll[2]) { 69756Speter l = getlab(); 70756Speter p = enter(defnl(ll[1], LABEL, 0, l)); 71756Speter /* 72756Speter * Get the label for the eventual target 73756Speter */ 74756Speter p->value[1] = getlab(); 75756Speter p->chain = lp; 76756Speter p->nl_flags |= (NFORWD|NMOD); 77756Speter p->value[NL_GOLEV] = NOTYET; 787919Smckusick p->value[NL_ENTLOC] = l; 79756Speter lp = p; 80756Speter # ifdef OBJ 81756Speter /* 82756Speter * This operator is between 83756Speter * the bodies of two procedures 84756Speter * and provides a target for 85756Speter * gotos for this label via TRA. 86756Speter */ 87756Speter putlab(l); 883074Smckusic /* put(2, O_GOTO | cbn<<8+INDX, (long)p->value[1]); */ 893074Smckusic put(2, O_GOTO | cbn<<8, (long)p->value[1]); 90756Speter # endif OBJ 91756Speter # ifdef PC 92756Speter /* 93756Speter * labels have to be .globl otherwise /lib/c2 may 94756Speter * throw them away if they aren't used in the function 95756Speter * which defines them. 96756Speter */ 974880Speter extlabname( extname , p -> symbol , cbn ); 983366Speter putprintf( " .globl %s" , 0 , extname ); 993366Speter if ( cbn == 1 ) { 1003366Speter stabglabel( extname , line ); 101756Speter } 102756Speter # endif PC 103756Speter } 104756Speter gotos[cbn] = lp; 105756Speter # ifdef PTREE 106756Speter { 107756Speter pPointer Labels = LabelDCopy( r ); 108756Speter 109756Speter pDEF( PorFHeader[ nesting ] ).PorFLabels = Labels; 110756Speter } 111756Speter # endif PTREE 112756Speter #endif 113756Speter } 114756Speter 115756Speter #ifndef PI0 116756Speter /* 117756Speter * Gotoop is called when 118756Speter * we get a statement "goto label" 119756Speter * and generates the needed tra. 120756Speter */ 121756Speter gotoop(s) 122756Speter char *s; 123756Speter { 124756Speter register struct nl *p; 1253366Speter #ifdef PC 1263366Speter char extname[ BUFSIZ ]; 1273366Speter #endif PC 128756Speter 129756Speter gocnt++; 130756Speter p = lookup(s); 131756Speter if (p == NIL) 132756Speter return (NIL); 133756Speter # ifdef OBJ 1347919Smckusick put(2, O_TRA4, (long)p->value[NL_ENTLOC]); 135756Speter # endif OBJ 136756Speter # ifdef PC 137756Speter if ( cbn != bn ) { 138756Speter /* 139756Speter * call goto to unwind the stack to the destination level 140756Speter */ 141756Speter putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR ) 142756Speter , "_GOTO" ); 1433827Speter putLV( DISPLAYNAME , 0 , bn * sizeof( struct dispsave ) , 1443827Speter NGLOBAL , P2PTR | P2INT ); 145756Speter putop( P2CALL , P2INT ); 146756Speter putdot( filename , line ); 147756Speter } 1484880Speter extlabname( extname , p -> symbol , bn ); 1497449Speter /* 1507449Speter * this is a jmp because it's a jump to a global 1517449Speter * and the assembler doesn't change jbr's into jmp's 1527449Speter * if the destination is a global symbol. 1537449Speter */ 1547449Speter putprintf( " jmp %s" , 0 , extname ); 155756Speter # endif PC 156756Speter if (bn == cbn) 157756Speter if (p->nl_flags & NFORWD) { 158756Speter if (p->value[NL_GOLEV] == NOTYET) { 159756Speter p->value[NL_GOLEV] = level; 160756Speter p->value[NL_GOLINE] = line; 161756Speter } 162756Speter } else 163756Speter if (p->value[NL_GOLEV] == DEAD) { 164756Speter recovered(); 165756Speter error("Goto %s is into a structured statement", p->symbol); 166756Speter } 167756Speter } 168756Speter 169756Speter /* 170756Speter * Labeled is called when a label 171756Speter * definition is encountered, and 172756Speter * marks that it has been found and 173756Speter * patches the associated GOTO generated 174756Speter * by gotoop. 175756Speter */ 176756Speter labeled(s) 177756Speter char *s; 178756Speter { 179756Speter register struct nl *p; 1803366Speter #ifdef PC 1813366Speter char extname[ BUFSIZ ]; 1823366Speter #endif PC 183756Speter 184756Speter p = lookup(s); 185756Speter if (p == NIL) 186756Speter return (NIL); 187756Speter if (bn != cbn) { 188756Speter error("Label %s not defined in correct block", s); 189756Speter return; 190756Speter } 191756Speter if ((p->nl_flags & NFORWD) == 0) { 192756Speter error("Label %s redefined", s); 193756Speter return; 194756Speter } 195756Speter p->nl_flags &= ~NFORWD; 196756Speter # ifdef OBJ 1977919Smckusick patch4(p->value[NL_ENTLOC]); 198756Speter # endif OBJ 199756Speter # ifdef PC 2004880Speter extlabname( extname , p -> symbol , bn ); 2013366Speter putprintf( "%s:" , 0 , extname ); 202756Speter # endif PC 203756Speter if (p->value[NL_GOLEV] != NOTYET) 204756Speter if (p->value[NL_GOLEV] < level) { 205756Speter recovered(); 206756Speter error("Goto %s from line %d is into a structured statement", s, p->value[NL_GOLINE]); 207756Speter } 208756Speter p->value[NL_GOLEV] = level; 209756Speter } 210756Speter #endif 2114880Speter 2124880Speter #ifdef PC 2134880Speter /* 2144880Speter * construct the long name of a label based on it's static nesting. 2154880Speter * into a caller-supplied buffer (that should be about BUFSIZ big). 2164880Speter */ 2174880Speter extlabname( buffer , name , level ) 2184880Speter char buffer[]; 2194880Speter char *name; 2204880Speter int level; 2214880Speter { 2224880Speter char *starthere; 2234880Speter int i; 2244880Speter 2254880Speter starthere = &buffer[0]; 2264880Speter for ( i = 1 ; i < level ; i++ ) { 2274880Speter sprintf( starthere , EXTFORMAT , enclosing[ i ] ); 2284880Speter starthere += strlen( enclosing[ i ] ) + 1; 2294880Speter } 2304880Speter sprintf( starthere , EXTFORMAT , "" ); 2314880Speter starthere += 1; 2324880Speter sprintf( starthere , LABELFORMAT , name ); 2334880Speter starthere += strlen( name ) + 1; 2344880Speter if ( starthere >= &buffer[ BUFSIZ ] ) { 2354880Speter panic( "extlabname" ); 2364880Speter } 2374880Speter } 2384880Speter #endif PC 239