1 /* Copyright (c) 1979 Regents of the University of California */ 2 3 static char sccsid[] = "@(#)lab.c 1.7 03/08/81"; 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 /* put(2, O_GOTO | cbn<<8+INDX, (long)p->value[1]); */ 76 put(2, O_GOTO | cbn<<8, (long)p->value[1]); 77 # endif OBJ 78 # ifdef PC 79 /* 80 * labels have to be .globl otherwise /lib/c2 may 81 * throw them away if they aren't used in the function 82 * which defines them. 83 */ 84 { 85 char extname[ BUFSIZ ]; 86 char *starthere; 87 int i; 88 89 starthere = &extname[0]; 90 for ( i = 1 ; i < cbn ; i++ ) { 91 sprintf( starthere , EXTFORMAT , enclosing[ i ] ); 92 starthere += strlen( enclosing[ i ] ) + 1; 93 } 94 sprintf( starthere , EXTFORMAT , p -> symbol ); 95 starthere += strlen( p -> symbol ) + 1; 96 if ( starthere >= &extname[ BUFSIZ ] ) { 97 panic( "lab decl namelength" ); 98 } 99 putprintf( " .globl " , 1 ); 100 putprintf( NAMEFORMAT , 0 , extname ); 101 if ( cbn == 1 ) { 102 stabglabel( extname , line ); 103 } 104 } 105 # endif PC 106 } 107 gotos[cbn] = lp; 108 # ifdef PTREE 109 { 110 pPointer Labels = LabelDCopy( r ); 111 112 pDEF( PorFHeader[ nesting ] ).PorFLabels = Labels; 113 } 114 # endif PTREE 115 #endif 116 } 117 118 #ifndef PI0 119 /* 120 * Gotoop is called when 121 * we get a statement "goto label" 122 * and generates the needed tra. 123 */ 124 gotoop(s) 125 char *s; 126 { 127 register struct nl *p; 128 129 gocnt++; 130 p = lookup(s); 131 if (p == NIL) 132 return (NIL); 133 # ifdef OBJ 134 put(2, O_TRA4, (long)p->entloc); 135 # endif OBJ 136 # ifdef PC 137 if ( cbn != bn ) { 138 /* 139 * call goto to unwind the stack to the destination level 140 */ 141 putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR ) 142 , "_GOTO" ); 143 putLV( DISPLAYNAME , 0 , bn * sizeof( struct dispsave ) 144 , P2PTR | P2INT ); 145 putop( P2CALL , P2INT ); 146 putdot( filename , line ); 147 } 148 { 149 char extname[ BUFSIZ ]; 150 char *starthere; 151 int i; 152 153 starthere = &extname[0]; 154 for ( i = 1 ; i < bn ; i++ ) { 155 sprintf( starthere , EXTFORMAT , enclosing[ i ] ); 156 starthere += strlen( enclosing[ i ] ) + 1; 157 } 158 sprintf( starthere , EXTFORMAT , p -> symbol ); 159 starthere += strlen( p -> symbol ) + 1; 160 if ( starthere >= &extname[ BUFSIZ ] ) { 161 panic( "goto namelength" ); 162 } 163 putprintf( " jbr " , 1 ); 164 putprintf( NAMEFORMAT , 0 , extname ); 165 } 166 # endif PC 167 if (bn == cbn) 168 if (p->nl_flags & NFORWD) { 169 if (p->value[NL_GOLEV] == NOTYET) { 170 p->value[NL_GOLEV] = level; 171 p->value[NL_GOLINE] = line; 172 } 173 } else 174 if (p->value[NL_GOLEV] == DEAD) { 175 recovered(); 176 error("Goto %s is into a structured statement", p->symbol); 177 } 178 } 179 180 /* 181 * Labeled is called when a label 182 * definition is encountered, and 183 * marks that it has been found and 184 * patches the associated GOTO generated 185 * by gotoop. 186 */ 187 labeled(s) 188 char *s; 189 { 190 register struct nl *p; 191 192 p = lookup(s); 193 if (p == NIL) 194 return (NIL); 195 if (bn != cbn) { 196 error("Label %s not defined in correct block", s); 197 return; 198 } 199 if ((p->nl_flags & NFORWD) == 0) { 200 error("Label %s redefined", s); 201 return; 202 } 203 p->nl_flags &= ~NFORWD; 204 # ifdef OBJ 205 patch4(p->entloc); 206 # endif OBJ 207 # ifdef PC 208 { 209 char extname[ BUFSIZ ]; 210 char *starthere; 211 int i; 212 213 starthere = &extname[0]; 214 for ( i = 1 ; i < bn ; i++ ) { 215 sprintf( starthere , EXTFORMAT , enclosing[ i ] ); 216 starthere += strlen( enclosing[ i ] ) + 1; 217 } 218 sprintf( starthere , EXTFORMAT , p -> symbol ); 219 starthere += strlen( p -> symbol ) + 1; 220 if ( starthere >= &extname[ BUFSIZ ] ) { 221 panic( "labeled namelength" ); 222 } 223 putprintf( NAMEFORMAT , 1 , extname ); 224 putprintf( ":" , 0 ); 225 } 226 # endif PC 227 if (p->value[NL_GOLEV] != NOTYET) 228 if (p->value[NL_GOLEV] < level) { 229 recovered(); 230 error("Goto %s from line %d is into a structured statement", s, p->value[NL_GOLINE]); 231 } 232 p->value[NL_GOLEV] = level; 233 } 234 #endif 235