1 #include "l.h" 2 3 void 4 span(void) 5 { 6 Prog *p; 7 Sym *setext; 8 Optab *o; 9 int m; 10 long c; 11 12 if(debug['v']) 13 Bprint(&bso, "%5.2f span\n", cputime()); 14 Bflush(&bso); 15 c = INITTEXT; 16 for(p = firstp; p != P; p = p->link) { 17 p->pc = c; 18 o = oplook(p); 19 m = o->size; 20 if(m == 0) { 21 if(p->as == ATEXT) { 22 curtext = p; 23 autosize = p->to.offset + 4; 24 if(p->from3.type == D_CONST) { 25 if(p->from3.offset & 3) 26 diag("illegal origin\n%P", p); 27 if(c > p->from3.offset) 28 diag("passed origin (#%lux)\n%P", c, p); 29 else 30 c = p->from3.offset; 31 p->pc = c; 32 } 33 if(p->from.sym != S) 34 p->from.sym->value = c; 35 continue; 36 } 37 if(p->as != ANOP) 38 diag("zero-width instruction\n%P", p); 39 continue; 40 } 41 c += m; 42 } 43 c = rnd(c, 4); 44 45 setext = lookup("etext", 0); 46 if(setext != S) { 47 setext->value = c; 48 textsize = c - INITTEXT; 49 } 50 if(INITRND) 51 INITDAT = rnd(c, INITRND); 52 if(debug['v']) 53 Bprint(&bso, "tsize = %lux\n", textsize); 54 Bflush(&bso); 55 } 56 57 void 58 xdefine(char *p, int t, long v) 59 { 60 Sym *s; 61 62 s = lookup(p, 0); 63 if(s->type == 0 || s->type == SXREF) { 64 s->type = t; 65 s->value = v; 66 } 67 } 68 69 long 70 regoff(Adr *a) 71 { 72 73 offset = 0; 74 aclass(a); 75 return offset; 76 } 77 78 int 79 aclass(Adr *a) 80 { 81 Sym *s; 82 int t; 83 84 switch(a->type) { 85 case D_NONE: 86 return C_NONE; 87 88 case D_REG: 89 return C_REG; 90 91 case D_FREG: 92 return C_FREG; 93 94 case D_CREG: 95 return C_CREG; 96 97 case D_SPR: 98 if(a->offset == D_LR) 99 return C_LR; 100 if(a->offset == D_XER) 101 return C_XER; 102 if(a->offset == D_CTR) 103 return C_CTR; 104 return C_SPR; 105 106 case D_SREG: 107 return C_SREG; 108 109 case D_FPSCR: 110 return C_FPSCR; 111 112 case D_MSR: 113 return C_MSR; 114 115 case D_OREG: 116 switch(a->name) { 117 case D_EXTERN: 118 case D_STATIC: 119 if(a->sym == S) 120 break; 121 t = a->sym->type; 122 if(t == 0 || t == SXREF) { 123 diag("undefined external: %s in %s", 124 a->sym->name, TNAME); 125 a->sym->type = SDATA; 126 } 127 offset = a->sym->value + a->offset - BIG; 128 if(offset >= -BIG && offset < BIG) 129 return C_SEXT; 130 return C_LEXT; 131 case D_AUTO: 132 offset = autosize + a->offset; 133 if(offset >= -BIG && offset < BIG) 134 return C_SAUTO; 135 return C_LAUTO; 136 137 case D_PARAM: 138 offset = autosize + a->offset + 4L; 139 if(offset >= -BIG && offset < BIG) 140 return C_SAUTO; 141 return C_LAUTO; 142 case D_NONE: 143 offset = a->offset; 144 if(offset == 0) 145 return C_ZOREG; 146 if(offset >= -BIG && offset < BIG) 147 return C_SOREG; 148 return C_LOREG; 149 } 150 return C_GOK; 151 152 case D_OPT: 153 offset = a->offset & 31L; 154 if(a->name == D_NONE) 155 return C_SCON; 156 return C_GOK; 157 158 case D_CONST: 159 switch(a->name) { 160 161 case D_NONE: 162 offset = a->offset; 163 consize: 164 if(offset >= 0) { 165 if(offset <= 0x7fff) 166 return C_SCON; 167 if(offset <= 0xffff) 168 return C_ANDCON; 169 if((offset & 0xffff) == 0) 170 return C_UCON; 171 return C_LCON; 172 } 173 if(offset >= -0x8000) 174 return C_ADDCON; 175 if((offset & 0xffff) == 0) 176 return C_UCON; 177 return C_LCON; 178 179 case D_EXTERN: 180 case D_STATIC: 181 s = a->sym; 182 if(s == S) 183 break; 184 t = s->type; 185 if(t == 0 || t == SXREF) { 186 diag("undefined external: %s in %s", 187 s->name, TNAME); 188 s->type = SDATA; 189 } 190 if(s->type == STEXT || s->type == SLEAF) { 191 offset = s->value + a->offset; 192 return C_LCON; 193 } 194 if(s->type == SCONST) { 195 offset = s->value + a->offset; 196 goto consize; 197 } 198 offset = s->value + a->offset - BIG; 199 if(offset >= -BIG && offset < BIG && offset != 0) 200 return C_SECON; 201 offset = s->value + a->offset + INITDAT; 202 /* not sure why this barfs */ 203 return C_LCON; 204 if(offset == 0) 205 return C_ZCON; 206 if(offset >= -0x8000 && offset <= 0xffff) 207 return C_SCON; 208 if((offset & 0xffff) == 0) 209 return C_UCON; 210 return C_LCON; 211 212 case D_AUTO: 213 offset = autosize + a->offset; 214 if(offset >= -BIG && offset < BIG) 215 return C_SACON; 216 return C_LACON; 217 218 case D_PARAM: 219 offset = autosize + a->offset + 4L; 220 if(offset >= -BIG && offset < BIG) 221 return C_SACON; 222 return C_LACON; 223 } 224 return C_GOK; 225 226 case D_BRANCH: 227 return C_SBRA; 228 } 229 return C_GOK; 230 } 231 232 Optab* 233 oplook(Prog *p) 234 { 235 int a1, a2, a3, a4, r; 236 char *c1, *c3, *c4; 237 Optab *o, *e; 238 239 a1 = p->optab; 240 if(a1) 241 return optab+(a1-1); 242 a1 = p->from.class; 243 if(a1 == 0) { 244 a1 = aclass(&p->from) + 1; 245 p->from.class = a1; 246 } 247 a1--; 248 a3 = p->from3.class; 249 if(a3 == 0) { 250 a3 = aclass(&p->from3) + 1; 251 p->from3.class = a3; 252 } 253 a3--; 254 a4 = p->to.class; 255 if(a4 == 0) { 256 a4 = aclass(&p->to) + 1; 257 p->to.class = a4; 258 } 259 a4--; 260 a2 = C_NONE; 261 if(p->reg != NREG) 262 a2 = C_REG; 263 r = p->as; 264 o = oprange[r].start; 265 if(o == 0) 266 o = oprange[r].stop; /* just generate an error */ 267 e = oprange[r].stop; 268 c1 = xcmp[a1]; 269 c3 = xcmp[a3]; 270 c4 = xcmp[a4]; 271 for(; o<e; o++) 272 if(o->a2 == a2) 273 if(c1[o->a1]) 274 if(c3[o->a3]) 275 if(c4[o->a4]) { 276 p->optab = (o-optab)+1; 277 return o; 278 } 279 diag("illegal combination %A %R %R %R %R", 280 p->as, a1, a2, a3, a4); 281 if(1||!debug['a']) 282 prasm(p); 283 if(o == 0) 284 errorexit(); 285 return o; 286 } 287 288 int 289 cmp(int a, int b) 290 { 291 292 if(a == b) 293 return 1; 294 switch(a) { 295 case C_LCON: 296 if(b == C_ZCON || b == C_SCON || b == C_UCON || b == C_ADDCON || b == C_ANDCON) 297 return 1; 298 break; 299 case C_ADDCON: 300 if(b == C_ZCON || b == C_SCON) 301 return 1; 302 break; 303 case C_ANDCON: 304 if(b == C_ZCON || b == C_SCON) 305 return 1; 306 break; 307 case C_SPR: 308 if(b == C_LR || b == C_XER || b == C_CTR) 309 return 1; 310 break; 311 case C_UCON: 312 if(b == C_ZCON) 313 return 1; 314 break; 315 case C_SCON: 316 if(b == C_ZCON) 317 return 1; 318 break; 319 case C_LACON: 320 if(b == C_SACON) 321 return 1; 322 break; 323 case C_LBRA: 324 if(b == C_SBRA) 325 return 1; 326 break; 327 case C_LEXT: 328 if(b == C_SEXT) 329 return 1; 330 break; 331 case C_LAUTO: 332 if(b == C_SAUTO) 333 return 1; 334 break; 335 case C_REG: 336 if(b == C_ZCON) 337 return 1; 338 break; 339 case C_LOREG: 340 if(b == C_ZOREG || b == C_SOREG) 341 return 1; 342 break; 343 case C_SOREG: 344 if(b == C_ZOREG) 345 return 1; 346 break; 347 348 case C_ANY: 349 return 1; 350 } 351 return 0; 352 } 353 354 int 355 ocmp(void *a1, void *a2) 356 { 357 Optab *p1, *p2; 358 int n; 359 360 p1 = a1; 361 p2 = a2; 362 n = p1->as - p2->as; 363 if(n) 364 return n; 365 n = p1->a1 - p2->a1; 366 if(n) 367 return n; 368 n = p1->a2 - p2->a2; 369 if(n) 370 return n; 371 n = p1->a3 - p2->a3; 372 if(n) 373 return n; 374 n = p1->a4 - p2->a4; 375 if(n) 376 return n; 377 return 0; 378 } 379 380 void 381 buildop(void) 382 { 383 int i, n, r; 384 385 for(i=0; i<C_NCLASS; i++) 386 for(n=0; n<C_NCLASS; n++) 387 xcmp[i][n] = cmp(n, i); 388 for(n=0; optab[n].as != AXXX; n++) 389 ; 390 qsort(optab, n, sizeof(optab[0]), ocmp); 391 for(i=0; i<n; i++) { 392 r = optab[i].as; 393 oprange[r].start = optab+i; 394 while(optab[i].as == r) 395 i++; 396 oprange[r].stop = optab+i; 397 i--; 398 399 switch(r) 400 { 401 default: 402 diag("unknown op in build: %A", r); 403 errorexit(); 404 case ADCBF: /* unary indexed: op (b+a); op (b) */ 405 oprange[ADCBI] = oprange[r]; 406 oprange[ADCBST] = oprange[r]; 407 oprange[ADCBT] = oprange[r]; 408 oprange[ADCBTST] = oprange[r]; 409 oprange[ADCBZ] = oprange[r]; 410 oprange[AICBI] = oprange[r]; 411 break; 412 case AECOWX: /* indexed store: op s,(b+a); op s,(b) */ 413 oprange[ASTWCCC] = oprange[r]; 414 break; 415 case AREM: /* macro */ 416 oprange[AREMCC] = oprange[r]; 417 oprange[AREMV] = oprange[r]; 418 oprange[AREMVCC] = oprange[r]; 419 oprange[AREMU] = oprange[r]; 420 oprange[AREMUCC] = oprange[r]; 421 oprange[AREMUV] = oprange[r]; 422 oprange[AREMUVCC] = oprange[r]; 423 break; 424 case ADIVW: /* op Rb[,Ra],Rd */ 425 oprange[AMULHW] = oprange[r]; 426 oprange[AMULHWCC] = oprange[r]; 427 oprange[AMULHWU] = oprange[r]; 428 oprange[AMULHWUCC] = oprange[r]; 429 oprange[AMULLWCC] = oprange[r]; 430 oprange[AMULLWVCC] = oprange[r]; 431 oprange[AMULLWV] = oprange[r]; 432 oprange[ADIVWCC] = oprange[r]; 433 oprange[ADIVWV] = oprange[r]; 434 oprange[ADIVWVCC] = oprange[r]; 435 oprange[ADIVWU] = oprange[r]; 436 oprange[ADIVWUCC] = oprange[r]; 437 oprange[ADIVWUV] = oprange[r]; 438 oprange[ADIVWUVCC] = oprange[r]; 439 oprange[AADDCC] = oprange[r]; 440 oprange[AADDCV] = oprange[r]; 441 oprange[AADDCVCC] = oprange[r]; 442 oprange[AADDV] = oprange[r]; 443 oprange[AADDVCC] = oprange[r]; 444 oprange[AADDE] = oprange[r]; 445 oprange[AADDECC] = oprange[r]; 446 oprange[AADDEV] = oprange[r]; 447 oprange[AADDEVCC] = oprange[r]; 448 oprange[ACRAND] = oprange[r]; 449 oprange[ACRANDN] = oprange[r]; 450 oprange[ACREQV] = oprange[r]; 451 oprange[ACRNAND] = oprange[r]; 452 oprange[ACRNOR] = oprange[r]; 453 oprange[ACROR] = oprange[r]; 454 oprange[ACRORN] = oprange[r]; 455 oprange[ACRXOR] = oprange[r]; 456 break; 457 /* floating point move *//* 458 oprange[AFMR] = oprange[r]; 459 oprange[AFMRCC] = oprange[r]; 460 */ 461 /**/ 462 case AMOVBZ: /* lbz, stz, rlwm(r/r), lhz, lha, stz, and x variants */ 463 oprange[AMOVH] = oprange[r]; 464 oprange[AMOVHZ] = oprange[r]; 465 break; 466 case AMOVBZU: /* lbz[x]u, stb[x]u, lhz[x]u, lha[x]u, sth[u]x */ 467 oprange[AMOVHU] = oprange[r]; 468 oprange[AMOVHZU] = oprange[r]; 469 oprange[AMOVWU] = oprange[r]; 470 oprange[AMOVMW] = oprange[r]; 471 break; 472 case AAND: /* logical op Rb,Rs,Ra; no literal */ 473 oprange[AANDN] = oprange[r]; 474 oprange[AANDNCC] = oprange[r]; 475 oprange[AEQV] = oprange[r]; 476 oprange[AEQVCC] = oprange[r]; 477 oprange[ANAND] = oprange[r]; 478 oprange[ANANDCC] = oprange[r]; 479 oprange[ANOR] = oprange[r]; 480 oprange[ANORCC] = oprange[r]; 481 oprange[AORCC] = oprange[r]; 482 oprange[AORN] = oprange[r]; 483 oprange[AORNCC] = oprange[r]; 484 oprange[AXORCC] = oprange[r]; 485 break; 486 case AADDME: /* op Ra, Rd */ 487 oprange[AADDMECC] = oprange[r]; 488 oprange[AADDMEV] = oprange[r]; 489 oprange[AADDMEVCC] = oprange[r]; 490 oprange[AADDZE] = oprange[r]; 491 oprange[AADDZECC] = oprange[r]; 492 oprange[AADDZEV] = oprange[r]; 493 oprange[AADDZEVCC] = oprange[r]; 494 oprange[ASUBME] = oprange[r]; 495 oprange[ASUBMECC] = oprange[r]; 496 oprange[ASUBMEV] = oprange[r]; 497 oprange[ASUBMEVCC] = oprange[r]; 498 oprange[ASUBZE] = oprange[r]; 499 oprange[ASUBZECC] = oprange[r]; 500 oprange[ASUBZEV] = oprange[r]; 501 oprange[ASUBZEVCC] = oprange[r]; 502 break; 503 case AADDC: 504 oprange[AADDCCC] = oprange[r]; 505 break; 506 case ABEQ: 507 oprange[ABGE] = oprange[r]; 508 oprange[ABGT] = oprange[r]; 509 oprange[ABLE] = oprange[r]; 510 oprange[ABLT] = oprange[r]; 511 oprange[ABNE] = oprange[r]; 512 oprange[ABVC] = oprange[r]; 513 oprange[ABVS] = oprange[r]; 514 break; 515 case ABR: 516 oprange[ABL] = oprange[r]; 517 break; 518 case ABC: 519 oprange[ABCL] = oprange[r]; 520 break; 521 case AEXTSB: /* op Rs, Ra */ 522 oprange[AEXTSBCC] = oprange[r]; 523 oprange[AEXTSH] = oprange[r]; 524 oprange[AEXTSHCC] = oprange[r]; 525 oprange[ACNTLZW] = oprange[r]; 526 oprange[ACNTLZWCC] = oprange[r]; 527 break; 528 case AFABS: /* fop [s,]d */ 529 oprange[AFABSCC] = oprange[r]; 530 oprange[AFNABS] = oprange[r]; 531 oprange[AFNABSCC] = oprange[r]; 532 oprange[AFNEG] = oprange[r]; 533 oprange[AFNEGCC] = oprange[r]; 534 oprange[AFRSP] = oprange[r]; 535 oprange[AFRSPCC] = oprange[r]; 536 oprange[AFCTIW] = oprange[r]; 537 oprange[AFCTIWCC] = oprange[r]; 538 oprange[AFCTIWZ] = oprange[r]; 539 oprange[AFCTIWZCC] = oprange[r]; 540 break; 541 case AFADD: 542 oprange[AFADDS] = oprange[r]; 543 oprange[AFADDCC] = oprange[r]; 544 oprange[AFADDSCC] = oprange[r]; 545 oprange[AFDIV] = oprange[r]; 546 oprange[AFDIVS] = oprange[r]; 547 oprange[AFDIVCC] = oprange[r]; 548 oprange[AFDIVSCC] = oprange[r]; 549 oprange[AFSUB] = oprange[r]; 550 oprange[AFSUBS] = oprange[r]; 551 oprange[AFSUBCC] = oprange[r]; 552 oprange[AFSUBSCC] = oprange[r]; 553 break; 554 case AFMADD: 555 oprange[AFMADDCC] = oprange[r]; 556 oprange[AFMADDS] = oprange[r]; 557 oprange[AFMADDSCC] = oprange[r]; 558 oprange[AFMSUB] = oprange[r]; 559 oprange[AFMSUBCC] = oprange[r]; 560 oprange[AFMSUBS] = oprange[r]; 561 oprange[AFMSUBSCC] = oprange[r]; 562 oprange[AFNMADD] = oprange[r]; 563 oprange[AFNMADDCC] = oprange[r]; 564 oprange[AFNMADDS] = oprange[r]; 565 oprange[AFNMADDSCC] = oprange[r]; 566 oprange[AFNMSUB] = oprange[r]; 567 oprange[AFNMSUBCC] = oprange[r]; 568 oprange[AFNMSUBS] = oprange[r]; 569 oprange[AFNMSUBSCC] = oprange[r]; 570 break; 571 case AFMUL: 572 oprange[AFMULS] = oprange[r]; 573 oprange[AFMULCC] = oprange[r]; 574 oprange[AFMULSCC] = oprange[r]; 575 break; 576 case AFCMPO: 577 oprange[AFCMPU] = oprange[r]; 578 break; 579 case AMTFSB0: 580 oprange[AMTFSB0CC] = oprange[r]; 581 oprange[AMTFSB1] = oprange[r]; 582 oprange[AMTFSB1CC] = oprange[r]; 583 break; 584 case ANEG: /* op [Ra,] Rd */ 585 oprange[ANEGCC] = oprange[r]; 586 oprange[ANEGV] = oprange[r]; 587 oprange[ANEGVCC] = oprange[r]; 588 break; 589 case AOR: /* or/xor Rb,Rs,Ra; ori/xori $uimm,Rs,Ra; oris/xoris $uimm,Rs,Ra */ 590 oprange[AXOR] = oprange[r]; 591 break; 592 case ASLW: 593 oprange[ASLWCC] = oprange[r]; 594 oprange[ASRW] = oprange[r]; 595 oprange[ASRWCC] = oprange[r]; 596 break; 597 case ASRAW: /* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */ 598 oprange[ASRAWCC] = oprange[r]; 599 break; 600 case ASUB: /* SUB Ra,Rb,Rd => subf Rd,ra,rb */ 601 oprange[ASUB] = oprange[r]; 602 oprange[ASUBCC] = oprange[r]; 603 oprange[ASUBV] = oprange[r]; 604 oprange[ASUBVCC] = oprange[r]; 605 oprange[ASUBCCC] = oprange[r]; 606 oprange[ASUBCV] = oprange[r]; 607 oprange[ASUBCVCC] = oprange[r]; 608 oprange[ASUBE] = oprange[r]; 609 oprange[ASUBECC] = oprange[r]; 610 oprange[ASUBEV] = oprange[r]; 611 oprange[ASUBEVCC] = oprange[r]; 612 break; 613 case ASYNC: 614 oprange[AISYNC] = oprange[r]; 615 break; 616 case ARLWMI: 617 oprange[ARLWMICC] = oprange[r]; 618 oprange[ARLWNM] = oprange[r]; 619 oprange[ARLWNMCC] = oprange[r]; 620 break; 621 case AFMOVD: 622 oprange[AFMOVDCC] = oprange[r]; 623 oprange[AFMOVDU] = oprange[r]; 624 oprange[AFMOVS] = oprange[r]; 625 oprange[AFMOVSU] = oprange[r]; 626 break; 627 case AECIWX: 628 oprange[ALWAR] = oprange[r]; 629 break; 630 case ASYSCALL: /* just the op; flow of control */ 631 oprange[ARFI] = oprange[r]; 632 break; 633 case AMOVHBR: 634 oprange[AMOVWBR] = oprange[r]; 635 break; 636 case AADD: 637 case AANDCC: /* and. Rb,Rs,Ra; andi. $uimm,Rs,Ra; andis. $uimm,Rs,Ra */ 638 case ACMP: 639 case ACMPU: 640 case AEIEIO: 641 case ALSW: 642 case AMOVB: /* macro: move byte with sign extension */ 643 case AMOVBU: /* macro: move byte with sign extension & update */ 644 case AMOVW: 645 case AMOVFL: 646 case AMULLW: /* op $s[,r2],r3; op r1[,r2],r3; no cc/v */ 647 case ASUBC: /* op r1,$s,r3; op r1[,r2],r3 */ 648 case ASTSW: 649 case ATLBIE: 650 case ATW: 651 case AWORD: 652 case ANOP: 653 case ATEXT: 654 break; 655 } 656 } 657 } 658