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