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