1 #include "l.h" 2 3 void 4 dodata(void) 5 { 6 int i, t; 7 Sym *s; 8 Prog *p, *p1; 9 long orig, orig1, v; 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(p->as == ADYNT || p->as == AINIT) 17 s->value = dtype; 18 if(s->type == SBSS) 19 s->type = SDATA; 20 if(s->type != SDATA) 21 diag("initialize non-data (%d): %s\n%P", 22 s->type, s->name, p); 23 v = p->from.offset + p->reg; 24 if(v > s->value) 25 diag("initialize bounds (%ld): %s\n%P", 26 s->value, s->name, p); 27 } 28 29 if(debug['t']) { 30 /* 31 * pull out string constants 32 */ 33 for(p = datap; p != P; p = p->link) { 34 s = p->from.sym; 35 if(p->to.type == D_SCONST) 36 s->type = SSTRING; 37 } 38 } 39 40 /* 41 * pass 1 42 * assign 'small' variables to data segment 43 * (rational is that data segment is more easily 44 * addressed through offset on R30) 45 */ 46 orig = 0; 47 for(i=0; i<NHASH; i++) 48 for(s = hash[i]; s != S; s = s->link) { 49 t = s->type; 50 if(t != SDATA && t != SBSS) 51 continue; 52 v = s->value; 53 if(v == 0) { 54 diag("%s: no size", s->name); 55 v = 1; 56 } 57 while(v & 3) 58 v++; 59 s->value = v; 60 if(v > MINSIZ) 61 continue; 62 s->value = orig; 63 orig += v; 64 s->type = SDATA1; 65 } 66 orig1 = orig; 67 68 /* 69 * pass 2 70 * assign 'data' variables to data segment 71 */ 72 for(i=0; i<NHASH; i++) 73 for(s = hash[i]; s != S; s = s->link) { 74 t = s->type; 75 if(t != SDATA) { 76 if(t == SDATA1) 77 s->type = SDATA; 78 continue; 79 } 80 v = s->value; 81 s->value = orig; 82 orig += v; 83 s->type = SDATA1; 84 } 85 86 while(orig & 7) 87 orig++; 88 datsize = orig; 89 90 /* 91 * pass 3 92 * everything else to bss segment 93 */ 94 for(i=0; i<NHASH; i++) 95 for(s = hash[i]; s != S; s = s->link) { 96 if(s->type != SBSS) 97 continue; 98 v = s->value; 99 s->value = orig; 100 orig += v; 101 } 102 while(orig & 7) 103 orig++; 104 bsssize = orig-datsize; 105 106 /* 107 * pass 4 108 * add literals to all large values. 109 * at this time: 110 * small data is allocated DATA 111 * large data is allocated DATA1 112 * large bss is allocated BSS 113 * the new literals are loaded between 114 * small data and large data. 115 */ 116 orig = 0; 117 for(p = firstp; p != P; p = p->link) { 118 if(p->as != AMOVW) 119 continue; 120 if(p->from.type != D_CONST) 121 continue; 122 if(s = p->from.sym) { 123 t = s->type; 124 if(t != SDATA && t != SDATA1 && t != SBSS) 125 continue; 126 t = p->from.name; 127 if(t != D_EXTERN && t != D_STATIC) 128 continue; 129 v = s->value + p->from.offset; 130 if(v >= 0 && v <= 0xffff) 131 continue; 132 if(!strcmp(s->name, "setR30")) 133 continue; 134 /* size should be 19 max */ 135 if(strlen(s->name) >= 10) /* has loader address */ 136 sprint(literal, "$%p.%lux", s, p->from.offset); 137 else 138 sprint(literal, "$%s.%d.%lux", s->name, s->version, p->from.offset); 139 } else { 140 if(p->from.name != D_NONE) 141 continue; 142 if(p->from.reg != NREG) 143 continue; 144 v = p->from.offset; 145 if(v >= -0x7fff && v <= 0xffff) 146 continue; 147 if(!(v & 0xffff)) 148 continue; 149 /* size should be 9 max */ 150 sprint(literal, "$%lux", v); 151 } 152 s = lookup(literal, 0); 153 if(s->type == 0) { 154 s->type = SDATA; 155 s->value = orig1+orig; 156 orig += 4; 157 p1 = prg(); 158 p1->line = p->line; 159 p1->as = ADATA; 160 p1->from.type = D_OREG; 161 p1->from.sym = s; 162 p1->from.name = D_EXTERN; 163 p1->reg = 4; 164 p1->to = p->from; 165 p1->link = datap; 166 datap = p1; 167 } 168 if(s->type != SDATA) 169 diag("literal not data: %s", s->name); 170 p->from.type = D_OREG; 171 p->from.sym = s; 172 p->from.name = D_EXTERN; 173 p->from.offset = 0; 174 nocache(p); 175 continue; 176 } 177 while(orig & 7) 178 orig++; 179 /* 180 * pass 5 181 * re-adjust offsets 182 */ 183 for(i=0; i<NHASH; i++) 184 for(s = hash[i]; s != S; s = s->link) { 185 t = s->type; 186 if(t == SBSS) { 187 s->value += orig; 188 continue; 189 } 190 if(t == SDATA1) { 191 s->type = SDATA; 192 s->value += orig; 193 continue; 194 } 195 } 196 datsize += orig; 197 xdefine("setR30", SDATA, 0L+BIG); 198 xdefine("bdata", SDATA, 0L); 199 xdefine("edata", SDATA, datsize); 200 xdefine("end", SBSS, datsize+bsssize); 201 xdefine("etext", STEXT, 0L); 202 } 203 204 void 205 undef(void) 206 { 207 int i; 208 Sym *s; 209 210 for(i=0; i<NHASH; i++) 211 for(s = hash[i]; s != S; s = s->link) 212 if(s->type == SXREF) 213 diag("%s: not defined", s->name); 214 } 215 216 void 217 follow(void) 218 { 219 if(debug['v']) 220 Bprint(&bso, "%5.2f follow\n", cputime()); 221 Bflush(&bso); 222 223 firstp = prg(); 224 lastp = firstp; 225 xfol(textp); 226 227 firstp = firstp->link; 228 lastp->link = P; 229 } 230 231 void 232 xfol(Prog *p) 233 { 234 Prog *q, *r; 235 int a, i; 236 237 loop: 238 if(p == P) 239 return; 240 a = p->as; 241 if(a == ATEXT) 242 curtext = p; 243 if(a == AJMP) { 244 q = p->cond; 245 if((p->mark&NOSCHED) || q && (q->mark&NOSCHED)){ 246 p->mark |= FOLL; 247 lastp->link = p; 248 lastp = p; 249 p = p->link; 250 xfol(p); 251 p = q; 252 if(p && !(p->mark & FOLL)) 253 goto loop; 254 return; 255 } 256 if(q != P) { 257 p->mark |= FOLL; 258 p = q; 259 if(!(p->mark & FOLL)) 260 goto loop; 261 } 262 } 263 if(p->mark & FOLL) { 264 for(i=0,q=p; i<4; i++,q=q->link) { 265 if(q == lastp || (q->mark&NOSCHED)) 266 break; 267 a = q->as; 268 if(a == ANOP) { 269 i--; 270 continue; 271 } 272 if(a == AJMP || a == ARET || a == ARFE) 273 goto copy; 274 if(!q->cond || (q->cond->mark&FOLL)) 275 continue; 276 if(a != ABEQ && a != ABNE) 277 continue; 278 copy: 279 for(;;) { 280 r = prg(); 281 *r = *p; 282 if(!(r->mark&FOLL)) 283 print("cant happen 1\n"); 284 r->mark |= FOLL; 285 if(p != q) { 286 p = p->link; 287 lastp->link = r; 288 lastp = r; 289 continue; 290 } 291 lastp->link = r; 292 lastp = r; 293 if(a == AJMP || a == ARET || a == ARFE) 294 return; 295 r->as = ABNE; 296 if(a == ABNE) 297 r->as = ABEQ; 298 r->cond = p->link; 299 r->link = p->cond; 300 if(!(r->link->mark&FOLL)) 301 xfol(r->link); 302 if(!(r->cond->mark&FOLL)) 303 print("cant happen 2\n"); 304 return; 305 } 306 } 307 a = AJMP; 308 q = prg(); 309 q->as = a; 310 q->line = p->line; 311 q->to.type = D_BRANCH; 312 q->to.offset = p->pc; 313 q->cond = p; 314 p = q; 315 } 316 p->mark |= FOLL; 317 lastp->link = p; 318 lastp = p; 319 if(a == AJMP || a == ARET || a == ARFE){ 320 if(p->mark & NOSCHED){ 321 p = p->link; 322 goto loop; 323 } 324 return; 325 } 326 if(p->cond != P) 327 if(a != AJAL && p->link != P) { 328 xfol(p->link); 329 p = p->cond; 330 if(p == P || (p->mark&FOLL)) 331 return; 332 goto loop; 333 } 334 p = p->link; 335 goto loop; 336 } 337 338 void 339 patch(void) 340 { 341 long c, vexit; 342 Prog *p, *q; 343 Sym *s; 344 int a; 345 346 if(debug['v']) 347 Bprint(&bso, "%5.2f patch\n", cputime()); 348 Bflush(&bso); 349 mkfwd(); 350 s = lookup("exit", 0); 351 vexit = s->value; 352 for(p = firstp; p != P; p = p->link) { 353 a = p->as; 354 if(a == ATEXT) 355 curtext = p; 356 if((a == AJAL || a == AJMP || a == ARET) && 357 p->to.type != D_BRANCH && p->to.sym != S) { 358 s = p->to.sym; 359 if(s->type != STEXT) { 360 diag("undefined: %s\n%P", s->name, p); 361 s->type = STEXT; 362 s->value = vexit; 363 } 364 p->to.offset = s->value; 365 p->to.type = D_BRANCH; 366 } 367 if(p->to.type != D_BRANCH) 368 continue; 369 c = p->to.offset; 370 for(q = firstp; q != P;) { 371 if(q->forwd != P) 372 if(c >= q->forwd->pc) { 373 q = q->forwd; 374 continue; 375 } 376 if(c == q->pc) 377 break; 378 q = q->link; 379 } 380 if(q == P) { 381 diag("branch out of range %ld\n%P", c, p); 382 p->to.type = D_NONE; 383 } 384 p->cond = q; 385 } 386 387 for(p = firstp; p != P; p = p->link) { 388 if(p->as == ATEXT) 389 curtext = p; 390 if(p->cond != P) { 391 p->cond = brloop(p->cond); 392 if(p->cond != P) 393 if(p->to.type == D_BRANCH) 394 p->to.offset = p->cond->pc; 395 } 396 } 397 } 398 399 #define LOG 5 400 void 401 mkfwd(void) 402 { 403 Prog *p; 404 long dwn[LOG], cnt[LOG], i; 405 Prog *lst[LOG]; 406 407 for(i=0; i<LOG; i++) { 408 if(i == 0) 409 cnt[i] = 1; else 410 cnt[i] = LOG * cnt[i-1]; 411 dwn[i] = 1; 412 lst[i] = P; 413 } 414 i = 0; 415 for(p = firstp; p != P; p = p->link) { 416 if(p->as == ATEXT) 417 curtext = p; 418 i--; 419 if(i < 0) 420 i = LOG-1; 421 p->forwd = P; 422 dwn[i]--; 423 if(dwn[i] <= 0) { 424 dwn[i] = cnt[i]; 425 if(lst[i] != P) 426 lst[i]->forwd = p; 427 lst[i] = p; 428 } 429 } 430 } 431 432 Prog* 433 brloop(Prog *p) 434 { 435 Prog *q; 436 int c; 437 438 for(c=0; p!=P;) { 439 if(p->as != AJMP || (p->mark&NOSCHED)) 440 return p; 441 q = p->cond; 442 if(q <= p) { 443 c++; 444 if(q == p || c > 5000) 445 break; 446 } 447 p = q; 448 } 449 return P; 450 } 451 452 long 453 atolwhex(char *s) 454 { 455 long n; 456 int f; 457 458 n = 0; 459 f = 0; 460 while(*s == ' ' || *s == '\t') 461 s++; 462 if(*s == '-' || *s == '+') { 463 if(*s++ == '-') 464 f = 1; 465 while(*s == ' ' || *s == '\t') 466 s++; 467 } 468 if(s[0]=='0' && s[1]){ 469 if(s[1]=='x' || s[1]=='X'){ 470 s += 2; 471 for(;;){ 472 if(*s >= '0' && *s <= '9') 473 n = n*16 + *s++ - '0'; 474 else if(*s >= 'a' && *s <= 'f') 475 n = n*16 + *s++ - 'a' + 10; 476 else if(*s >= 'A' && *s <= 'F') 477 n = n*16 + *s++ - 'A' + 10; 478 else 479 break; 480 } 481 } else 482 while(*s >= '0' && *s <= '7') 483 n = n*8 + *s++ - '0'; 484 } else 485 while(*s >= '0' && *s <= '9') 486 n = n*10 + *s++ - '0'; 487 if(f) 488 n = -n; 489 return n; 490 } 491 492 long 493 rnd(long v, long r) 494 { 495 long c; 496 497 if(r <= 0) 498 return v; 499 v += r - 1; 500 c = v % r; 501 if(c < 0) 502 c += r; 503 v -= c; 504 return v; 505 } 506