1 #include "l.h" 2 3 void 4 dodata(void) 5 { 6 int i; 7 Sym *s; 8 Prog *p; 9 long t, u; 10 11 if(debug['v']) 12 Bprint(&bso, "%5.2f dodata\n", cputime()); 13 Bflush(&bso); 14 for(p = datap; p != P; p = p->link) { 15 s = p->from.sym; 16 if(s->type == SBSS) 17 s->type = SDATA; 18 if(s->type != SDATA) 19 diag("initialize non-data (%d): %s\n%P\n", 20 s->type, s->name, p); 21 t = p->from.offset + p->width; 22 if(t > s->value) 23 diag("initialize bounds (%ld): %s\n%P\n", 24 s->value, s->name, p); 25 } 26 27 /* allocate small guys */ 28 datsize = 0; 29 for(i=0; i<NHASH; i++) 30 for(s = hash[i]; s != S; s = s->link) { 31 if(s->type != SDATA) 32 if(s->type != SBSS) 33 continue; 34 t = s->value; 35 if(t == 0) { 36 diag("%s: no size\n", s->name); 37 t = 1; 38 } 39 t = rnd(t, 4);; 40 s->value = t; 41 if(t > MINSIZ) 42 continue; 43 s->value = datsize; 44 datsize += t; 45 s->type = SDATA1; 46 } 47 48 /* allocate the rest of the data */ 49 for(i=0; i<NHASH; i++) 50 for(s = hash[i]; s != S; s = s->link) { 51 if(s->type != SDATA) { 52 if(s->type == SDATA1) 53 s->type = SDATA; 54 continue; 55 } 56 t = s->value; 57 s->value = datsize; 58 datsize += t; 59 } 60 61 if(debug['j']) { 62 /* 63 * pad data with bss that fits up to next 64 * 8k boundary, then push data to 8k 65 */ 66 u = rnd(datsize, 8192); 67 u -= datsize; 68 for(i=0; i<NHASH; i++) 69 for(s = hash[i]; s != S; s = s->link) { 70 if(s->type != SBSS) 71 continue; 72 t = s->value; 73 if(t > u) 74 continue; 75 u -= t; 76 s->value = datsize; 77 s->type = SDATA; 78 datsize += t; 79 } 80 datsize += u; 81 } 82 83 /* now the bss */ 84 bsssize = 0; 85 for(i=0; i<NHASH; i++) 86 for(s = hash[i]; s != S; s = s->link) { 87 if(s->type != SBSS) 88 continue; 89 t = s->value; 90 s->value = bsssize + datsize; 91 bsssize += t; 92 } 93 94 symSB = lookup("setSB", 0); 95 xdefine("setSB", SDATA, 0L); 96 xdefine("bdata", SDATA, 0L); 97 xdefine("edata", SDATA, datsize); 98 xdefine("end", SBSS, datsize+bsssize); 99 xdefine("etext", STEXT, 0L); 100 } 101 102 Prog* 103 brchain(Prog *p) 104 { 105 int i; 106 107 for(i=0; i<20; i++) { 108 if(p == P || p->as != AB) 109 return p; 110 p = p->cond; 111 } 112 return P; 113 } 114 115 void 116 follow(void) 117 { 118 119 if(debug['v']) 120 Bprint(&bso, "%5.2f follow\n", cputime()); 121 Bflush(&bso); 122 firstp = prg(); 123 lastp = firstp; 124 xfol(textp); 125 firstp = firstp->link; 126 lastp->link = P; 127 } 128 129 void 130 xfol(Prog *p) 131 { 132 Prog *q; 133 int i; 134 enum as a; 135 136 loop: 137 if(p == P) 138 return; 139 if(p->as == ATEXT) 140 curtext = p; 141 if(p->as == AB) 142 if((q = p->cond) != P) { 143 p->mark = 1; 144 p = q; 145 if(p->mark == 0) 146 goto loop; 147 } 148 if(p->mark) { 149 /* copy up to 4 instructions to avoid branch */ 150 for(i=0,q=p; i<4; i++,q=q->link) { 151 if(q == P) 152 break; 153 if(q == lastp) 154 break; 155 a = q->as; 156 if(a == ANOP) { 157 i--; 158 continue; 159 } 160 if(a == AB || a == ARTS) 161 break; 162 if(q->cond == P || q->cond->mark) 163 continue; 164 if(a == ABAL) 165 continue; 166 for(;;) { 167 if(p->as == ANOP) { 168 p = p->link; 169 continue; 170 } 171 q = copyp(p); 172 p = p->link; 173 q->mark = 1; 174 lastp->link = q; 175 lastp = q; 176 if(q->as != a || q->cond == P || q->cond->mark) 177 continue; 178 q->as = relinv(q->as); 179 p = q->cond; 180 q->cond = q->link; 181 q->link = p; 182 xfol(q->link); 183 p = q->link; 184 if(p->mark) 185 return; 186 goto loop; 187 } 188 } /* */ 189 q = prg(); 190 q->as = AB; 191 q->line = p->line; 192 q->to.type = D_BRANCH; 193 q->to.offset = p->pc; 194 q->cond = p; 195 p = q; 196 } 197 p->mark = 1; 198 lastp->link = p; 199 lastp = p; 200 a = p->as; 201 if(a == AB || a == ARTS) 202 return; 203 if(p->cond != P) 204 if(a != ABAL) { 205 q = brchain(p->link); 206 if(q != P && q->mark) { 207 p->as = relinv(a); 208 p->link = p->cond; 209 p->cond = q; 210 } 211 xfol(p->link); 212 q = brchain(p->cond); 213 if(q->mark) { 214 p->cond = q; 215 return; 216 } 217 p = q; 218 goto loop; 219 } 220 p = p->link; 221 goto loop; 222 } 223 224 int 225 relinv(int a) 226 { 227 switch(a) { 228 case ABE: return ABNE; 229 case ABNE: return ABE; 230 case ABLE: return ABG; 231 case ABL: return ABGE; 232 case ABGE: return ABL; 233 case ABG: return ABLE; 234 case ABBS: return ABBC; 235 case ABBC: return ABBS; 236 case ABO: return ABNO; 237 case ABNO: return ABO; 238 } 239 diag("unknown relation: %s in %s\n", anames[a], TNAME); 240 return a; 241 } 242 243 void 244 doinit(void) 245 { 246 Sym *s; 247 Prog *p; 248 int x; 249 250 for(p = datap; p != P; p = p->link) { 251 x = p->to.type; 252 if(x != D_EXTERN && x != D_STATIC) 253 continue; 254 s = p->to.sym; 255 if(s->type == 0 || s->type == SXREF) 256 diag("undefined %s initializer of %s\n", 257 s->name, p->from.sym->name); 258 p->to.offset += s->value; 259 p->to.type = D_CONST; 260 if(s->type == SDATA || s->type == SBSS) 261 p->to.offset += INITDAT; 262 } 263 } 264 265 void 266 patch(void) 267 { 268 long c; 269 Prog *p, *q; 270 Sym *s; 271 long vexit; 272 273 if(debug['v']) 274 Bprint(&bso, "%5.2f mkfwd\n", cputime()); 275 Bflush(&bso); 276 mkfwd(); 277 if(debug['v']) 278 Bprint(&bso, "%5.2f patch\n", cputime()); 279 Bflush(&bso); 280 s = lookup("exit", 0); 281 vexit = s->value; 282 for(p = firstp; p != P; p = p->link) { 283 if(p->as == ATEXT) 284 curtext = p; 285 if(p->as == ABAL || p->as == ARTS) { 286 s = p->to.sym; 287 if(s) { 288 if(s->type != STEXT && s->type != SLEAF) { 289 diag("undefined: %s in %s\n", s->name, TNAME); 290 s->type = STEXT; 291 s->value = vexit; 292 } 293 p->to.offset = s->value; 294 p->to.type = D_BRANCH; 295 } 296 } 297 if(p->to.type != D_BRANCH) 298 continue; 299 c = p->to.offset; 300 for(q = firstp; q != P;) { 301 if(q->forwd != P) 302 if(c >= q->forwd->pc) { 303 q = q->forwd; 304 continue; 305 } 306 if(c == q->pc) 307 break; 308 q = q->link; 309 } 310 if(q == P) { 311 diag("branch out of range in %s\n%P\n", TNAME, p); 312 p->to.type = D_NONE; 313 } 314 p->cond = q; 315 } 316 317 for(p = firstp; p != P; p = p->link) { 318 if(p->as == ATEXT) 319 curtext = p; 320 p->mark = 0; /* initialization for follow */ 321 if(p->cond != P) { 322 p->cond = brloop(p->cond); 323 if(p->cond != P) 324 if(p->to.type == D_BRANCH) 325 p->to.offset = p->cond->pc; 326 } 327 } 328 } 329 330 #define LOG 5 331 void 332 mkfwd(void) 333 { 334 Prog *p; 335 int i; 336 long dwn[LOG], cnt[LOG]; 337 Prog *lst[LOG]; 338 339 for(i=0; i<LOG; i++) { 340 if(i == 0) 341 cnt[i] = 1; else 342 cnt[i] = LOG * cnt[i-1]; 343 dwn[i] = 1; 344 lst[i] = P; 345 } 346 i = 0; 347 for(p = firstp; p != P; p = p->link) { 348 if(p->as == ATEXT) 349 curtext = p; 350 i--; 351 if(i < 0) 352 i = LOG-1; 353 p->forwd = P; 354 dwn[i]--; 355 if(dwn[i] <= 0) { 356 dwn[i] = cnt[i]; 357 if(lst[i] != P) 358 lst[i]->forwd = p; 359 lst[i] = p; 360 } 361 } 362 } 363 364 Prog* 365 brloop(Prog *p) 366 { 367 int c; 368 Prog *q; 369 370 c = 0; 371 for(q = p; q != P; q = q->cond) { 372 if(q->as != AB) 373 break; 374 c++; 375 if(c >= 100) 376 return P; 377 } 378 return q; 379 } 380 381 long 382 atolwhex(char *s) 383 { 384 long n; 385 int f; 386 387 n = 0; 388 f = 0; 389 while(*s == ' ' || *s == '\t') 390 s++; 391 if(*s == '-' || *s == '+') { 392 if(*s++ == '-') 393 f = 1; 394 while(*s == ' ' || *s == '\t') 395 s++; 396 } 397 if(s[0]=='0' && s[1]){ 398 if(s[1]=='x' || s[1]=='X'){ 399 s += 2; 400 for(;;){ 401 if(*s >= '0' && *s <= '9') 402 n = n*16 + *s++ - '0'; 403 else if(*s >= 'a' && *s <= 'f') 404 n = n*16 + *s++ - 'a' + 10; 405 else if(*s >= 'A' && *s <= 'F') 406 n = n*16 + *s++ - 'A' + 10; 407 else 408 break; 409 } 410 } else 411 while(*s >= '0' && *s <= '7') 412 n = n*8 + *s++ - '0'; 413 } else 414 while(*s >= '0' && *s <= '9') 415 n = n*10 + *s++ - '0'; 416 if(f) 417 n = -n; 418 return n; 419 } 420 421 void 422 undef(void) 423 { 424 int i; 425 Sym *s; 426 427 for(i=0; i<NHASH; i++) 428 for(s = hash[i]; s != S; s = s->link) 429 if(s->type == SXREF) 430 diag("%s: not defined\n", s->name); 431 } 432