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 (%lld): %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, 139 s->version, p->from.offset); 140 } else { 141 if(p->from.name != D_NONE) 142 continue; 143 if(p->from.reg != NREG) 144 continue; 145 v = p->from.offset; 146 if(v >= -0x7fff && v <= 0xffff) 147 continue; 148 if(!(v & 0xffff)) 149 continue; 150 /* size should be 9 max */ 151 sprint(literal, "$%lux", v); 152 } 153 s = lookup(literal, 0); 154 if(s->type == 0) { 155 s->type = SDATA; 156 s->value = orig1+orig; 157 orig += 4; 158 p1 = prg(); 159 p1->line = p->line; 160 p1->as = ADATA; 161 p1->from.type = D_OREG; 162 p1->from.sym = s; 163 p1->from.name = D_EXTERN; 164 p1->reg = 4; 165 p1->to = p->from; 166 p1->link = datap; 167 datap = p1; 168 } 169 if(s->type != SDATA) 170 diag("literal not data: %s", s->name); 171 p->from.type = D_OREG; 172 p->from.sym = s; 173 p->from.name = D_EXTERN; 174 p->from.offset = 0; 175 nocache(p); 176 continue; 177 } 178 while(orig & 7) 179 orig++; 180 /* 181 * pass 5 182 * re-adjust offsets 183 */ 184 for(i=0; i<NHASH; i++) 185 for(s = hash[i]; s != S; s = s->link) { 186 t = s->type; 187 if(t == SBSS) { 188 s->value += orig; 189 continue; 190 } 191 if(t == SDATA1) { 192 s->type = SDATA; 193 s->value += orig; 194 continue; 195 } 196 } 197 datsize += orig; 198 xdefine("setR30", SDATA, 0L+BIG); 199 xdefine("bdata", SDATA, 0L); 200 xdefine("edata", SDATA, datsize); 201 xdefine("end", SBSS, datsize+bsssize); 202 xdefine("etext", STEXT, 0L); 203 } 204 205 void 206 undef(void) 207 { 208 int i; 209 Sym *s; 210 211 for(i=0; i<NHASH; i++) 212 for(s = hash[i]; s != S; s = s->link) 213 if(s->type == SXREF) 214 diag("%s: not defined", s->name); 215 } 216 217 void 218 follow(void) 219 { 220 if(debug['v']) 221 Bprint(&bso, "%5.2f follow\n", cputime()); 222 Bflush(&bso); 223 224 firstp = prg(); 225 lastp = firstp; 226 xfol(textp); 227 228 firstp = firstp->link; 229 lastp->link = P; 230 } 231 232 void 233 xfol(Prog *p) 234 { 235 Prog *q, *r; 236 int a, i; 237 238 loop: 239 if(p == P) 240 return; 241 a = p->as; 242 if(a == ATEXT) 243 curtext = p; 244 if(a == AJMP) { 245 q = p->cond; 246 if((p->mark&NOSCHED) || q && (q->mark&NOSCHED)){ 247 p->mark |= FOLL; 248 lastp->link = p; 249 lastp = p; 250 p = p->link; 251 xfol(p); 252 p = q; 253 if(p && !(p->mark & FOLL)) 254 goto loop; 255 return; 256 } 257 if(q != P) { 258 p->mark |= FOLL; 259 p = q; 260 if(!(p->mark & FOLL)) 261 goto loop; 262 } 263 } 264 if(p->mark & FOLL) { 265 for(i=0,q=p; i<4; i++,q=q->link) { 266 if(q == lastp || (q->mark&NOSCHED)) 267 break; 268 a = q->as; 269 if(a == ANOP) { 270 i--; 271 continue; 272 } 273 if(a == AJMP || a == ARET || a == ARFE) 274 goto copy; 275 if(!q->cond || (q->cond->mark&FOLL)) 276 continue; 277 if(a != ABEQ && a != ABNE) 278 continue; 279 copy: 280 for(;;) { 281 r = prg(); 282 *r = *p; 283 if(!(r->mark&FOLL)) 284 print("cant happen 1\n"); 285 r->mark |= FOLL; 286 if(p != q) { 287 p = p->link; 288 lastp->link = r; 289 lastp = r; 290 continue; 291 } 292 lastp->link = r; 293 lastp = r; 294 if(a == AJMP || a == ARET || a == ARFE) 295 return; 296 r->as = ABNE; 297 if(a == ABNE) 298 r->as = ABEQ; 299 r->cond = p->link; 300 r->link = p->cond; 301 if(!(r->link->mark&FOLL)) 302 xfol(r->link); 303 if(!(r->cond->mark&FOLL)) 304 print("cant happen 2\n"); 305 return; 306 } 307 } 308 a = AJMP; 309 q = prg(); 310 q->as = a; 311 q->line = p->line; 312 q->to.type = D_BRANCH; 313 q->to.offset = p->pc; 314 q->cond = p; 315 p = q; 316 } 317 p->mark |= FOLL; 318 lastp->link = p; 319 lastp = p; 320 if(a == AJMP || a == ARET || a == ARFE){ 321 if(p->mark & NOSCHED){ 322 p = p->link; 323 goto loop; 324 } 325 return; 326 } 327 if(p->cond != P) 328 if(a != AJAL && p->link != P) { 329 xfol(p->link); 330 p = p->cond; 331 if(p == P || (p->mark&FOLL)) 332 return; 333 goto loop; 334 } 335 p = p->link; 336 goto loop; 337 } 338 339 void 340 patch(void) 341 { 342 vlong c, vexit; 343 Prog *p, *q; 344 Sym *s; 345 int a; 346 347 if(debug['v']) 348 Bprint(&bso, "%5.2f patch\n", cputime()); 349 Bflush(&bso); 350 mkfwd(); 351 s = lookup("exit", 0); 352 vexit = s->value; 353 for(p = firstp; p != P; p = p->link) { 354 a = p->as; 355 if(a == ATEXT) 356 curtext = p; 357 if((a == AJAL || a == AJMP || a == ARET) && 358 p->to.type != D_BRANCH && p->to.sym != S) { 359 s = p->to.sym; 360 if(s->type != STEXT) { 361 diag("undefined: %s\n%P", s->name, p); 362 s->type = STEXT; 363 s->value = vexit; 364 } 365 p->to.offset = s->value; 366 p->to.type = D_BRANCH; 367 } 368 if(p->to.type != D_BRANCH) 369 continue; 370 c = p->to.offset; 371 for(q = firstp; q != P;) { 372 if(q->forwd != P) 373 if(c >= q->forwd->pc) { 374 q = q->forwd; 375 continue; 376 } 377 if(c == q->pc) 378 break; 379 q = q->link; 380 } 381 if(q == P) { 382 diag("branch out of range %lld\n%P", c, p); 383 p->to.type = D_NONE; 384 } 385 p->cond = q; 386 } 387 388 for(p = firstp; p != P; p = p->link) { 389 if(p->as == ATEXT) 390 curtext = p; 391 if(p->cond != P) { 392 p->cond = brloop(p->cond); 393 if(p->cond != P) 394 if(p->to.type == D_BRANCH) 395 p->to.offset = p->cond->pc; 396 } 397 } 398 } 399 400 #define LOG 5 401 void 402 mkfwd(void) 403 { 404 Prog *p; 405 long dwn[LOG], cnt[LOG], i; 406 Prog *lst[LOG]; 407 408 for(i=0; i<LOG; i++) { 409 if(i == 0) 410 cnt[i] = 1; else 411 cnt[i] = LOG * cnt[i-1]; 412 dwn[i] = 1; 413 lst[i] = P; 414 } 415 i = 0; 416 for(p = firstp; p != P; p = p->link) { 417 if(p->as == ATEXT) 418 curtext = p; 419 i--; 420 if(i < 0) 421 i = LOG-1; 422 p->forwd = P; 423 dwn[i]--; 424 if(dwn[i] <= 0) { 425 dwn[i] = cnt[i]; 426 if(lst[i] != P) 427 lst[i]->forwd = p; 428 lst[i] = p; 429 } 430 } 431 } 432 433 Prog* 434 brloop(Prog *p) 435 { 436 Prog *q; 437 int c; 438 439 for(c=0; p!=P;) { 440 if(p->as != AJMP || (p->mark&NOSCHED)) 441 return p; 442 q = p->cond; 443 if(q <= p) { 444 c++; 445 if(q == p || c > 5000) 446 break; 447 } 448 p = q; 449 } 450 return P; 451 } 452 453 vlong 454 atolwhex(char *s) 455 { 456 vlong n; 457 int f; 458 459 n = 0; 460 f = 0; 461 while(*s == ' ' || *s == '\t') 462 s++; 463 if(*s == '-' || *s == '+') { 464 if(*s++ == '-') 465 f = 1; 466 while(*s == ' ' || *s == '\t') 467 s++; 468 } 469 if(s[0]=='0' && s[1]){ 470 if(s[1]=='x' || s[1]=='X'){ 471 s += 2; 472 for(;;){ 473 if(*s >= '0' && *s <= '9') 474 n = n*16 + *s++ - '0'; 475 else if(*s >= 'a' && *s <= 'f') 476 n = n*16 + *s++ - 'a' + 10; 477 else if(*s >= 'A' && *s <= 'F') 478 n = n*16 + *s++ - 'A' + 10; 479 else 480 break; 481 } 482 } else 483 while(*s >= '0' && *s <= '7') 484 n = n*8 + *s++ - '0'; 485 } else 486 while(*s >= '0' && *s <= '9') 487 n = n*10 + *s++ - '0'; 488 if(f) 489 n = -n; 490 return n; 491 } 492 493 vlong 494 rnd(vlong v, long r) 495 { 496 long c; 497 498 if(r <= 0) 499 return v; 500 v += r - 1; 501 c = v % r; 502 if(c < 0) 503 c += r; 504 v -= c; 505 return v; 506 } 507