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