1 /* Copyright (c) 1979 Regents of the University of California */ 2 3 static char sccsid[] = "@(#)lab.c 1.4 09/04/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 if (cbn == 1) { 84 /* 85 * stab the label for separate compilation. 86 * make label number = label name. 87 */ 88 stabglabel( p -> symbol , line ); 89 p -> value[1] = atol( p -> symbol ); 90 putprintf( " .globl " , 1 ); 91 putprintf( PREFIXFORMAT , 0 , PLABELPREFIX 92 , p -> value[1] ); 93 } else { 94 putprintf( " .globl " , 1 ); 95 putprintf( PREFIXFORMAT , 0 , GLABELPREFIX 96 , p -> value[1] ); 97 } 98 # endif PC 99 } 100 gotos[cbn] = lp; 101 # ifdef PTREE 102 { 103 pPointer Labels = LabelDCopy( r ); 104 105 pDEF( PorFHeader[ nesting ] ).PorFLabels = Labels; 106 } 107 # endif PTREE 108 #endif 109 } 110 111 #ifndef PI0 112 /* 113 * Gotoop is called when 114 * we get a statement "goto label" 115 * and generates the needed tra. 116 */ 117 gotoop(s) 118 char *s; 119 { 120 register struct nl *p; 121 122 gocnt++; 123 p = lookup(s); 124 if (p == NIL) 125 return (NIL); 126 # ifdef OBJ 127 put2(O_TRA4, p->entloc); 128 # endif OBJ 129 # ifdef PC 130 if ( cbn != bn ) { 131 /* 132 * call goto to unwind the stack to the destination level 133 */ 134 putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR ) 135 , "_GOTO" ); 136 putLV( DISPLAYNAME , 0 , bn * sizeof( struct dispsave ) 137 , P2PTR | P2INT ); 138 putop( P2CALL , P2INT ); 139 putdot( filename , line ); 140 } 141 if ( bn <= 1 ) { 142 printjbr( PLABELPREFIX , p -> value[1] ); 143 } else { 144 printjbr( GLABELPREFIX , p -> value[1] ); 145 } 146 # endif PC 147 if (bn == cbn) 148 if (p->nl_flags & NFORWD) { 149 if (p->value[NL_GOLEV] == NOTYET) { 150 p->value[NL_GOLEV] = level; 151 p->value[NL_GOLINE] = line; 152 } 153 } else 154 if (p->value[NL_GOLEV] == DEAD) { 155 recovered(); 156 error("Goto %s is into a structured statement", p->symbol); 157 } 158 } 159 160 /* 161 * Labeled is called when a label 162 * definition is encountered, and 163 * marks that it has been found and 164 * patches the associated GOTO generated 165 * by gotoop. 166 */ 167 labeled(s) 168 char *s; 169 { 170 register struct nl *p; 171 172 p = lookup(s); 173 if (p == NIL) 174 return (NIL); 175 if (bn != cbn) { 176 error("Label %s not defined in correct block", s); 177 return; 178 } 179 if ((p->nl_flags & NFORWD) == 0) { 180 error("Label %s redefined", s); 181 return; 182 } 183 p->nl_flags &= ~NFORWD; 184 # ifdef OBJ 185 patch4(p->entloc); 186 # endif OBJ 187 # ifdef PC 188 if ( bn <= 1 ) { 189 putprintf( PREFIXFORMAT , 1 , PLABELPREFIX , p -> value[1] ); 190 } else { 191 putprintf( PREFIXFORMAT , 1 , GLABELPREFIX , p -> value[1] ); 192 } 193 putprintf( ":" , 0 ); 194 # endif PC 195 if (p->value[NL_GOLEV] != NOTYET) 196 if (p->value[NL_GOLEV] < level) { 197 recovered(); 198 error("Goto %s from line %d is into a structured statement", s, p->value[NL_GOLINE]); 199 } 200 p->value[NL_GOLEV] = level; 201 } 202 #endif 203