1 #include "l.h" 2 #define r0iszero 1 3 4 void 5 span(void) 6 { 7 Prog *p; 8 Sym *setext; 9 Optab *o; 10 int m; 11 long c; 12 13 if(debug['v']) 14 Bprint(&bso, "%5.2f span\n", cputime()); 15 Bflush(&bso); 16 c = INITTEXT; 17 for(p = firstp; p != P; p = p->link) { 18 p->pc = c; 19 o = oplook(p); 20 m = o->size; 21 if(m == 0) { 22 if(p->as == ATEXT) { 23 curtext = p; 24 autosize = p->to.offset + 4; 25 if(p->from3.type == D_CONST) { 26 if(p->from3.offset & 3) 27 diag("illegal origin\n%P", p); 28 if(c > p->from3.offset) 29 diag("passed origin (#%lux)\n%P", c, p); 30 else 31 c = p->from3.offset; 32 p->pc = c; 33 } 34 if(p->from.sym != S) 35 p->from.sym->value = c; 36 continue; 37 } 38 if(p->as != ANOP) 39 diag("zero-width instruction\n%P", p); 40 continue; 41 } 42 c += m; 43 } 44 c = rnd(c, 4); 45 46 setext = lookup("etext", 0); 47 if(setext != S) { 48 setext->value = c; 49 textsize = c - INITTEXT; 50 } 51 if(INITRND) 52 INITDAT = rnd(c, INITRND); 53 if(debug['v']) 54 Bprint(&bso, "tsize = %lux\n", textsize); 55 Bflush(&bso); 56 } 57 58 void 59 xdefine(char *p, int t, long v) 60 { 61 Sym *s; 62 63 s = lookup(p, 0); 64 if(s->type == 0 || s->type == SXREF) { 65 s->type = t; 66 s->value = v; 67 } 68 } 69 70 long 71 regoff(Adr *a) 72 { 73 74 instoffset = 0; 75 aclass(a); 76 return instoffset; 77 } 78 79 int 80 aclass(Adr *a) 81 { 82 Sym *s; 83 int t; 84 85 switch(a->type) { 86 case D_NONE: 87 return C_NONE; 88 89 case D_REG: 90 return C_REG; 91 92 case D_FREG: 93 return C_FREG; 94 95 case D_CREG: 96 return C_CREG; 97 98 case D_SPR: 99 if(a->offset == D_LR) 100 return C_LR; 101 if(a->offset == D_XER) 102 return C_XER; 103 if(a->offset == D_CTR) 104 return C_CTR; 105 return C_SPR; 106 107 case D_DCR: 108 return C_SPR; 109 110 case D_SREG: 111 return C_SREG; 112 113 case D_FPSCR: 114 return C_FPSCR; 115 116 case D_MSR: 117 return C_MSR; 118 119 case D_OREG: 120 switch(a->name) { 121 case D_EXTERN: 122 case D_STATIC: 123 if(a->sym == S) 124 break; 125 t = a->sym->type; 126 if(t == 0 || t == SXREF) { 127 diag("undefined external: %s in %s", 128 a->sym->name, TNAME); 129 a->sym->type = SDATA; 130 } 131 if(dlm){ 132 instoffset = a->sym->value + a->offset; 133 switch(a->sym->type){ 134 case STEXT: 135 case SLEAF: 136 case SCONST: 137 case SUNDEF: 138 break; 139 default: 140 instoffset += INITDAT; 141 } 142 return C_ADDR; 143 } 144 instoffset = a->sym->value + a->offset - BIG; 145 if(instoffset >= -BIG && instoffset < BIG) 146 return C_SEXT; 147 return C_LEXT; 148 case D_AUTO: 149 instoffset = autosize + a->offset; 150 if(instoffset >= -BIG && instoffset < BIG) 151 return C_SAUTO; 152 return C_LAUTO; 153 154 case D_PARAM: 155 instoffset = autosize + a->offset + 4L; 156 if(instoffset >= -BIG && instoffset < BIG) 157 return C_SAUTO; 158 return C_LAUTO; 159 case D_NONE: 160 instoffset = a->offset; 161 if(instoffset == 0) 162 return C_ZOREG; 163 if(instoffset >= -BIG && instoffset < BIG) 164 return C_SOREG; 165 return C_LOREG; 166 } 167 return C_GOK; 168 169 case D_OPT: 170 instoffset = a->offset & 31L; 171 if(a->name == D_NONE) 172 return C_SCON; 173 return C_GOK; 174 175 case D_CONST: 176 switch(a->name) { 177 178 case D_NONE: 179 instoffset = a->offset; 180 consize: 181 if(instoffset >= 0) { 182 if(r0iszero && instoffset == 0) 183 return C_ZCON; 184 if(instoffset <= 0x7fff) 185 return C_SCON; 186 if(instoffset <= 0xffff) 187 return C_ANDCON; 188 if((instoffset & 0xffff) == 0) 189 return C_UCON; 190 return C_LCON; 191 } 192 if(instoffset >= -0x8000) 193 return C_ADDCON; 194 if((instoffset & 0xffff) == 0) 195 return C_UCON; 196 return C_LCON; 197 198 case D_EXTERN: 199 case D_STATIC: 200 s = a->sym; 201 if(s == S) 202 break; 203 t = s->type; 204 if(t == 0 || t == SXREF) { 205 diag("undefined external: %s in %s", 206 s->name, TNAME); 207 s->type = SDATA; 208 } 209 if(s->type == STEXT || s->type == SLEAF || s->type == SUNDEF) { 210 instoffset = s->value + a->offset; 211 return C_LCON; 212 } 213 if(s->type == SCONST) { 214 instoffset = s->value + a->offset; 215 if(dlm) 216 return C_LCON; 217 goto consize; 218 } 219 if(!dlm){ 220 instoffset = s->value + a->offset - BIG; 221 if(instoffset >= -BIG && instoffset < BIG && instoffset != 0) 222 return C_SECON; 223 } 224 instoffset = s->value + a->offset + INITDAT; 225 if(dlm) 226 return C_LCON; 227 /* not sure why this barfs */ 228 return C_LCON; 229 /* 230 if(instoffset == 0) 231 return C_ZCON; 232 if(instoffset >= -0x8000 && instoffset <= 0xffff) 233 return C_SCON; 234 if((instoffset & 0xffff) == 0) 235 return C_UCON; 236 return C_LCON; 237 */ 238 239 case D_AUTO: 240 instoffset = autosize + a->offset; 241 if(instoffset >= -BIG && instoffset < BIG) 242 return C_SACON; 243 return C_LACON; 244 245 case D_PARAM: 246 instoffset = autosize + a->offset + 4L; 247 if(instoffset >= -BIG && instoffset < BIG) 248 return C_SACON; 249 return C_LACON; 250 } 251 return C_GOK; 252 253 case D_BRANCH: 254 return C_SBRA; 255 } 256 return C_GOK; 257 } 258 259 Optab* 260 oplook(Prog *p) 261 { 262 int a1, a2, a3, a4, r; 263 char *c1, *c3, *c4; 264 Optab *o, *e; 265 266 a1 = p->optab; 267 if(a1) 268 return optab+(a1-1); 269 a1 = p->from.class; 270 if(a1 == 0) { 271 a1 = aclass(&p->from) + 1; 272 p->from.class = a1; 273 } 274 a1--; 275 a3 = p->from3.class; 276 if(a3 == 0) { 277 a3 = aclass(&p->from3) + 1; 278 p->from3.class = a3; 279 } 280 a3--; 281 a4 = p->to.class; 282 if(a4 == 0) { 283 a4 = aclass(&p->to) + 1; 284 p->to.class = a4; 285 } 286 a4--; 287 a2 = C_NONE; 288 if(p->reg != NREG) 289 a2 = C_REG; 290 r = p->as; 291 o = oprange[r].start; 292 if(o == 0) 293 o = oprange[r].stop; /* just generate an error */ 294 e = oprange[r].stop; 295 c1 = xcmp[a1]; 296 c3 = xcmp[a3]; 297 c4 = xcmp[a4]; 298 for(; o<e; o++) 299 if(o->a2 == a2) 300 if(c1[o->a1]) 301 if(c3[o->a3]) 302 if(c4[o->a4]) { 303 p->optab = (o-optab)+1; 304 return o; 305 } 306 diag("illegal combination %A %R %R %R %R", 307 p->as, a1, a2, a3, a4); 308 if(1||!debug['a']) 309 prasm(p); 310 if(o == 0) 311 errorexit(); 312 return o; 313 } 314 315 int 316 cmp(int a, int b) 317 { 318 319 if(a == b) 320 return 1; 321 switch(a) { 322 case C_LCON: 323 if(b == C_ZCON || b == C_SCON || b == C_UCON || b == C_ADDCON || b == C_ANDCON) 324 return 1; 325 break; 326 case C_ADDCON: 327 if(b == C_ZCON || b == C_SCON) 328 return 1; 329 break; 330 case C_ANDCON: 331 if(b == C_ZCON || b == C_SCON) 332 return 1; 333 break; 334 case C_SPR: 335 if(b == C_LR || b == C_XER || b == C_CTR) 336 return 1; 337 break; 338 case C_UCON: 339 if(b == C_ZCON) 340 return 1; 341 break; 342 case C_SCON: 343 if(b == C_ZCON) 344 return 1; 345 break; 346 case C_LACON: 347 if(b == C_SACON) 348 return 1; 349 break; 350 case C_LBRA: 351 if(b == C_SBRA) 352 return 1; 353 break; 354 case C_LEXT: 355 if(b == C_SEXT) 356 return 1; 357 break; 358 case C_LAUTO: 359 if(b == C_SAUTO) 360 return 1; 361 break; 362 case C_REG: 363 if(r0iszero && b == C_ZCON) 364 return 1; 365 break; 366 case C_LOREG: 367 if(b == C_ZOREG || b == C_SOREG) 368 return 1; 369 break; 370 case C_SOREG: 371 if(b == C_ZOREG) 372 return 1; 373 break; 374 375 case C_ANY: 376 return 1; 377 } 378 return 0; 379 } 380 381 int 382 ocmp(void *a1, void *a2) 383 { 384 Optab *p1, *p2; 385 int n; 386 387 p1 = a1; 388 p2 = a2; 389 n = p1->as - p2->as; 390 if(n) 391 return n; 392 n = p1->a1 - p2->a1; 393 if(n) 394 return n; 395 n = p1->a2 - p2->a2; 396 if(n) 397 return n; 398 n = p1->a3 - p2->a3; 399 if(n) 400 return n; 401 n = p1->a4 - p2->a4; 402 if(n) 403 return n; 404 return 0; 405 } 406 407 void 408 buildop(void) 409 { 410 int i, n, r; 411 412 for(i=0; i<C_NCLASS; i++) 413 for(n=0; n<C_NCLASS; n++) 414 xcmp[i][n] = cmp(n, i); 415 for(n=0; optab[n].as != AXXX; n++) 416 ; 417 qsort(optab, n, sizeof(optab[0]), ocmp); 418 for(i=0; i<n; i++) { 419 r = optab[i].as; 420 oprange[r].start = optab+i; 421 while(optab[i].as == r) 422 i++; 423 oprange[r].stop = optab+i; 424 i--; 425 426 switch(r) 427 { 428 default: 429 diag("unknown op in build: %A", r); 430 errorexit(); 431 case ADCBF: /* unary indexed: op (b+a); op (b) */ 432 oprange[ADCBI] = oprange[r]; 433 oprange[ADCBST] = oprange[r]; 434 oprange[ADCBT] = oprange[r]; 435 oprange[ADCBTST] = oprange[r]; 436 oprange[ADCBZ] = oprange[r]; 437 oprange[AICBI] = oprange[r]; 438 break; 439 case AECOWX: /* indexed store: op s,(b+a); op s,(b) */ 440 oprange[ASTWCCC] = oprange[r]; 441 break; 442 case AREM: /* macro */ 443 oprange[AREMCC] = oprange[r]; 444 oprange[AREMV] = oprange[r]; 445 oprange[AREMVCC] = oprange[r]; 446 oprange[AREMU] = oprange[r]; 447 oprange[AREMUCC] = oprange[r]; 448 oprange[AREMUV] = oprange[r]; 449 oprange[AREMUVCC] = oprange[r]; 450 break; 451 case ADIVW: /* op Rb[,Ra],Rd */ 452 oprange[AMULHW] = oprange[r]; 453 oprange[AMULHWCC] = oprange[r]; 454 oprange[AMULHWU] = oprange[r]; 455 oprange[AMULHWUCC] = oprange[r]; 456 oprange[AMULLWCC] = oprange[r]; 457 oprange[AMULLWVCC] = oprange[r]; 458 oprange[AMULLWV] = oprange[r]; 459 oprange[ADIVWCC] = oprange[r]; 460 oprange[ADIVWV] = oprange[r]; 461 oprange[ADIVWVCC] = oprange[r]; 462 oprange[ADIVWU] = oprange[r]; 463 oprange[ADIVWUCC] = oprange[r]; 464 oprange[ADIVWUV] = oprange[r]; 465 oprange[ADIVWUVCC] = oprange[r]; 466 oprange[AADDCC] = oprange[r]; 467 oprange[AADDCV] = oprange[r]; 468 oprange[AADDCVCC] = oprange[r]; 469 oprange[AADDV] = oprange[r]; 470 oprange[AADDVCC] = oprange[r]; 471 oprange[AADDE] = oprange[r]; 472 oprange[AADDECC] = oprange[r]; 473 oprange[AADDEV] = oprange[r]; 474 oprange[AADDEVCC] = oprange[r]; 475 oprange[ACRAND] = oprange[r]; 476 oprange[ACRANDN] = oprange[r]; 477 oprange[ACREQV] = oprange[r]; 478 oprange[ACRNAND] = oprange[r]; 479 oprange[ACRNOR] = oprange[r]; 480 oprange[ACROR] = oprange[r]; 481 oprange[ACRORN] = oprange[r]; 482 oprange[ACRXOR] = oprange[r]; 483 oprange[AMULCHW] = oprange[r]; 484 oprange[AMULCHWCC] = oprange[r]; 485 oprange[AMULCHWU] = oprange[r]; 486 oprange[AMULCHWUCC] = oprange[r]; 487 oprange[AMULHHW] = oprange[r]; 488 oprange[AMULHHWCC] = oprange[r]; 489 oprange[AMULHHWU] = oprange[r]; 490 oprange[AMULHHWUCC] = oprange[r]; 491 oprange[AMULLHW] = oprange[r]; 492 oprange[AMULLHWCC] = oprange[r]; 493 oprange[AMULLHWU] = oprange[r]; 494 oprange[AMULLHWUCC] = oprange[r]; 495 break; 496 case AMACCHW: /* strictly 3 registers */ 497 oprange[AMACCHWCC] = oprange[r]; 498 oprange[AMACCHWS] = oprange[r]; 499 oprange[AMACCHWSCC] = oprange[r]; 500 oprange[AMACCHWSU] = oprange[r]; 501 oprange[AMACCHWSUCC] = oprange[r]; 502 oprange[AMACCHWSUV] = oprange[r]; 503 oprange[AMACCHWSUVCC] = oprange[r]; 504 oprange[AMACCHWSV] = oprange[r]; 505 oprange[AMACCHWSVCC] = oprange[r]; 506 oprange[AMACCHWU] = oprange[r]; 507 oprange[AMACCHWUCC] = oprange[r]; 508 oprange[AMACCHWUV] = oprange[r]; 509 oprange[AMACCHWUVCC] = oprange[r]; 510 oprange[AMACCHWV] = oprange[r]; 511 oprange[AMACCHWVCC] = oprange[r]; 512 oprange[AMACHHW] = oprange[r]; 513 oprange[AMACHHWCC] = oprange[r]; 514 oprange[AMACHHWS] = oprange[r]; 515 oprange[AMACHHWSCC] = oprange[r]; 516 oprange[AMACHHWSU] = oprange[r]; 517 oprange[AMACHHWSUCC] = oprange[r]; 518 oprange[AMACHHWSUV] = oprange[r]; 519 oprange[AMACHHWSUVCC] = oprange[r]; 520 oprange[AMACHHWSV] = oprange[r]; 521 oprange[AMACHHWSVCC] = oprange[r]; 522 oprange[AMACHHWU] = oprange[r]; 523 oprange[AMACHHWUCC] = oprange[r]; 524 oprange[AMACHHWUV] = oprange[r]; 525 oprange[AMACHHWUVCC] = oprange[r]; 526 oprange[AMACHHWV] = oprange[r]; 527 oprange[AMACHHWVCC] = oprange[r]; 528 oprange[AMACLHW] = oprange[r]; 529 oprange[AMACLHWCC] = oprange[r]; 530 oprange[AMACLHWS] = oprange[r]; 531 oprange[AMACLHWSCC] = oprange[r]; 532 oprange[AMACLHWSU] = oprange[r]; 533 oprange[AMACLHWSUCC] = oprange[r]; 534 oprange[AMACLHWSUV] = oprange[r]; 535 oprange[AMACLHWSUVCC] = oprange[r]; 536 oprange[AMACLHWSV] = oprange[r]; 537 oprange[AMACLHWSVCC] = oprange[r]; 538 oprange[AMACLHWU] = oprange[r]; 539 oprange[AMACLHWUCC] = oprange[r]; 540 oprange[AMACLHWUV] = oprange[r]; 541 oprange[AMACLHWUVCC] = oprange[r]; 542 oprange[AMACLHWV] = oprange[r]; 543 oprange[AMACLHWVCC] = oprange[r]; 544 oprange[ANMACCHW] = oprange[r]; 545 oprange[ANMACCHWCC] = oprange[r]; 546 oprange[ANMACCHWS] = oprange[r]; 547 oprange[ANMACCHWSCC] = oprange[r]; 548 oprange[ANMACCHWSV] = oprange[r]; 549 oprange[ANMACCHWSVCC] = oprange[r]; 550 oprange[ANMACCHWV] = oprange[r]; 551 oprange[ANMACCHWVCC] = oprange[r]; 552 oprange[ANMACHHW] = oprange[r]; 553 oprange[ANMACHHWCC] = oprange[r]; 554 oprange[ANMACHHWS] = oprange[r]; 555 oprange[ANMACHHWSCC] = oprange[r]; 556 oprange[ANMACHHWSV] = oprange[r]; 557 oprange[ANMACHHWSVCC] = oprange[r]; 558 oprange[ANMACHHWV] = oprange[r]; 559 oprange[ANMACHHWVCC] = oprange[r]; 560 oprange[ANMACLHW] = oprange[r]; 561 oprange[ANMACLHWCC] = oprange[r]; 562 oprange[ANMACLHWS] = oprange[r]; 563 oprange[ANMACLHWSCC] = oprange[r]; 564 oprange[ANMACLHWSV] = oprange[r]; 565 oprange[ANMACLHWSVCC] = oprange[r]; 566 oprange[ANMACLHWV] = oprange[r]; 567 oprange[ANMACLHWVCC] = oprange[r]; 568 break; 569 /* floating point move *//* 570 oprange[AFMR] = oprange[r]; 571 oprange[AFMRCC] = oprange[r]; 572 */ 573 /**/ 574 case AMOVBZ: /* lbz, stz, rlwm(r/r), lhz, lha, stz, and x variants */ 575 oprange[AMOVH] = oprange[r]; 576 oprange[AMOVHZ] = oprange[r]; 577 break; 578 case AMOVBZU: /* lbz[x]u, stb[x]u, lhz[x]u, lha[x]u, sth[u]x */ 579 oprange[AMOVHU] = oprange[r]; 580 oprange[AMOVHZU] = oprange[r]; 581 oprange[AMOVWU] = oprange[r]; 582 oprange[AMOVMW] = oprange[r]; 583 break; 584 case AAND: /* logical op Rb,Rs,Ra; no literal */ 585 oprange[AANDN] = oprange[r]; 586 oprange[AANDNCC] = oprange[r]; 587 oprange[AEQV] = oprange[r]; 588 oprange[AEQVCC] = oprange[r]; 589 oprange[ANAND] = oprange[r]; 590 oprange[ANANDCC] = oprange[r]; 591 oprange[ANOR] = oprange[r]; 592 oprange[ANORCC] = oprange[r]; 593 oprange[AORCC] = oprange[r]; 594 oprange[AORN] = oprange[r]; 595 oprange[AORNCC] = oprange[r]; 596 oprange[AXORCC] = oprange[r]; 597 break; 598 case AADDME: /* op Ra, Rd */ 599 oprange[AADDMECC] = oprange[r]; 600 oprange[AADDMEV] = oprange[r]; 601 oprange[AADDMEVCC] = oprange[r]; 602 oprange[AADDZE] = oprange[r]; 603 oprange[AADDZECC] = oprange[r]; 604 oprange[AADDZEV] = oprange[r]; 605 oprange[AADDZEVCC] = oprange[r]; 606 oprange[ASUBME] = oprange[r]; 607 oprange[ASUBMECC] = oprange[r]; 608 oprange[ASUBMEV] = oprange[r]; 609 oprange[ASUBMEVCC] = oprange[r]; 610 oprange[ASUBZE] = oprange[r]; 611 oprange[ASUBZECC] = oprange[r]; 612 oprange[ASUBZEV] = oprange[r]; 613 oprange[ASUBZEVCC] = oprange[r]; 614 break; 615 case AADDC: 616 oprange[AADDCCC] = oprange[r]; 617 break; 618 case ABEQ: 619 oprange[ABGE] = oprange[r]; 620 oprange[ABGT] = oprange[r]; 621 oprange[ABLE] = oprange[r]; 622 oprange[ABLT] = oprange[r]; 623 oprange[ABNE] = oprange[r]; 624 oprange[ABVC] = oprange[r]; 625 oprange[ABVS] = oprange[r]; 626 break; 627 case ABR: 628 oprange[ABL] = oprange[r]; 629 break; 630 case ABC: 631 oprange[ABCL] = oprange[r]; 632 break; 633 case AEXTSB: /* op Rs, Ra */ 634 oprange[AEXTSBCC] = oprange[r]; 635 oprange[AEXTSH] = oprange[r]; 636 oprange[AEXTSHCC] = oprange[r]; 637 oprange[ACNTLZW] = oprange[r]; 638 oprange[ACNTLZWCC] = oprange[r]; 639 break; 640 case AFABS: /* fop [s,]d */ 641 oprange[AFABSCC] = oprange[r]; 642 oprange[AFNABS] = oprange[r]; 643 oprange[AFNABSCC] = oprange[r]; 644 oprange[AFNEG] = oprange[r]; 645 oprange[AFNEGCC] = oprange[r]; 646 oprange[AFRSP] = oprange[r]; 647 oprange[AFRSPCC] = oprange[r]; 648 oprange[AFCTIW] = oprange[r]; 649 oprange[AFCTIWCC] = oprange[r]; 650 oprange[AFCTIWZ] = oprange[r]; 651 oprange[AFCTIWZCC] = oprange[r]; 652 break; 653 case AFADD: 654 oprange[AFADDS] = oprange[r]; 655 oprange[AFADDCC] = oprange[r]; 656 oprange[AFADDSCC] = oprange[r]; 657 oprange[AFDIV] = oprange[r]; 658 oprange[AFDIVS] = oprange[r]; 659 oprange[AFDIVCC] = oprange[r]; 660 oprange[AFDIVSCC] = oprange[r]; 661 oprange[AFSUB] = oprange[r]; 662 oprange[AFSUBS] = oprange[r]; 663 oprange[AFSUBCC] = oprange[r]; 664 oprange[AFSUBSCC] = oprange[r]; 665 break; 666 case AFMADD: 667 oprange[AFMADDCC] = oprange[r]; 668 oprange[AFMADDS] = oprange[r]; 669 oprange[AFMADDSCC] = oprange[r]; 670 oprange[AFMSUB] = oprange[r]; 671 oprange[AFMSUBCC] = oprange[r]; 672 oprange[AFMSUBS] = oprange[r]; 673 oprange[AFMSUBSCC] = oprange[r]; 674 oprange[AFNMADD] = oprange[r]; 675 oprange[AFNMADDCC] = oprange[r]; 676 oprange[AFNMADDS] = oprange[r]; 677 oprange[AFNMADDSCC] = oprange[r]; 678 oprange[AFNMSUB] = oprange[r]; 679 oprange[AFNMSUBCC] = oprange[r]; 680 oprange[AFNMSUBS] = oprange[r]; 681 oprange[AFNMSUBSCC] = oprange[r]; 682 break; 683 case AFMUL: 684 oprange[AFMULS] = oprange[r]; 685 oprange[AFMULCC] = oprange[r]; 686 oprange[AFMULSCC] = oprange[r]; 687 break; 688 case AFCMPO: 689 oprange[AFCMPU] = oprange[r]; 690 break; 691 case AMTFSB0: 692 oprange[AMTFSB0CC] = oprange[r]; 693 oprange[AMTFSB1] = oprange[r]; 694 oprange[AMTFSB1CC] = oprange[r]; 695 break; 696 case ANEG: /* op [Ra,] Rd */ 697 oprange[ANEGCC] = oprange[r]; 698 oprange[ANEGV] = oprange[r]; 699 oprange[ANEGVCC] = oprange[r]; 700 break; 701 case AOR: /* or/xor Rb,Rs,Ra; ori/xori $uimm,Rs,Ra; oris/xoris $uimm,Rs,Ra */ 702 oprange[AXOR] = oprange[r]; 703 break; 704 case ASLW: 705 oprange[ASLWCC] = oprange[r]; 706 oprange[ASRW] = oprange[r]; 707 oprange[ASRWCC] = oprange[r]; 708 break; 709 case ASRAW: /* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */ 710 oprange[ASRAWCC] = oprange[r]; 711 break; 712 case ASUB: /* SUB Ra,Rb,Rd => subf Rd,ra,rb */ 713 oprange[ASUB] = oprange[r]; 714 oprange[ASUBCC] = oprange[r]; 715 oprange[ASUBV] = oprange[r]; 716 oprange[ASUBVCC] = oprange[r]; 717 oprange[ASUBCCC] = oprange[r]; 718 oprange[ASUBCV] = oprange[r]; 719 oprange[ASUBCVCC] = oprange[r]; 720 oprange[ASUBE] = oprange[r]; 721 oprange[ASUBECC] = oprange[r]; 722 oprange[ASUBEV] = oprange[r]; 723 oprange[ASUBEVCC] = oprange[r]; 724 break; 725 case ASYNC: 726 oprange[AISYNC] = oprange[r]; 727 break; 728 case ARLWMI: 729 oprange[ARLWMICC] = oprange[r]; 730 oprange[ARLWNM] = oprange[r]; 731 oprange[ARLWNMCC] = oprange[r]; 732 break; 733 case AFMOVD: 734 oprange[AFMOVDCC] = oprange[r]; 735 oprange[AFMOVDU] = oprange[r]; 736 oprange[AFMOVS] = oprange[r]; 737 oprange[AFMOVSU] = oprange[r]; 738 break; 739 case AECIWX: 740 oprange[ALWAR] = oprange[r]; 741 break; 742 case ASYSCALL: /* just the op; flow of control */ 743 oprange[ARFI] = oprange[r]; 744 oprange[ARFCI] = oprange[r]; 745 break; 746 case AMOVHBR: 747 oprange[AMOVWBR] = oprange[r]; 748 break; 749 case AADD: 750 case AANDCC: /* and. Rb,Rs,Ra; andi. $uimm,Rs,Ra; andis. $uimm,Rs,Ra */ 751 case ACMP: 752 case ACMPU: 753 case AEIEIO: 754 case ALSW: 755 case AMOVB: /* macro: move byte with sign extension */ 756 case AMOVBU: /* macro: move byte with sign extension & update */ 757 case AMOVW: 758 case AMOVFL: 759 case AMULLW: /* op $s[,r2],r3; op r1[,r2],r3; no cc/v */ 760 case ASUBC: /* op r1,$s,r3; op r1[,r2],r3 */ 761 case ASTSW: 762 case ATLBIE: 763 case ATW: 764 case AWORD: 765 case ANOP: 766 case ATEXT: 767 break; 768 } 769 } 770 } 771 772 enum{ 773 ABSD = 0, 774 ABSU = 1, 775 RELD = 2, 776 RELU = 3, 777 }; 778 779 int modemap[8] = { 0, 1, -1, 2, 3, 4, 5, 6}; 780 781 typedef struct Reloc Reloc; 782 783 struct Reloc 784 { 785 int n; 786 int t; 787 uchar *m; 788 ulong *a; 789 }; 790 791 Reloc rels; 792 793 static void 794 grow(Reloc *r) 795 { 796 int t; 797 uchar *m, *nm; 798 ulong *a, *na; 799 800 t = r->t; 801 r->t += 64; 802 m = r->m; 803 a = r->a; 804 r->m = nm = malloc(r->t*sizeof(uchar)); 805 r->a = na = malloc(r->t*sizeof(ulong)); 806 memmove(nm, m, t*sizeof(uchar)); 807 memmove(na, a, t*sizeof(ulong)); 808 free(m); 809 free(a); 810 } 811 812 void 813 dynreloc(Sym *s, long v, int abs, int split, int sext) 814 { 815 int i, k, n; 816 uchar *m; 817 ulong *a; 818 Reloc *r; 819 820 if(v&3) 821 diag("bad relocation address"); 822 v >>= 2; 823 if(s->type == SUNDEF) 824 k = abs ? ABSU : RELU; 825 else 826 k = abs ? ABSD : RELD; 827 if(split) 828 k += 4; 829 if(sext) 830 k += 2; 831 /* Bprint(&bso, "R %s a=%ld(%lx) %d\n", s->name, a, a, k); */ 832 k = modemap[k]; 833 r = &rels; 834 n = r->n; 835 if(n >= r->t) 836 grow(r); 837 m = r->m; 838 a = r->a; 839 for(i = n; i > 0; i--){ 840 if(v < a[i-1]){ /* happens occasionally for data */ 841 m[i] = m[i-1]; 842 a[i] = a[i-1]; 843 } 844 else 845 break; 846 } 847 m[i] = k; 848 a[i] = v; 849 r->n++; 850 } 851 852 static int 853 sput(char *s) 854 { 855 char *p; 856 857 p = s; 858 while(*s) 859 cput(*s++); 860 cput(0); 861 return s-p+1; 862 } 863 864 void 865 asmdyn() 866 { 867 int i, n, t, c; 868 Sym *s; 869 ulong la, ra, *a; 870 vlong off; 871 uchar *m; 872 Reloc *r; 873 874 cflush(); 875 off = seek(cout, 0, 1); 876 lput(0); 877 t = 0; 878 lput(imports); 879 t += 4; 880 for(i = 0; i < NHASH; i++) 881 for(s = hash[i]; s != S; s = s->link) 882 if(s->type == SUNDEF){ 883 lput(s->sig); 884 t += 4; 885 t += sput(s->name); 886 } 887 888 la = 0; 889 r = &rels; 890 n = r->n; 891 m = r->m; 892 a = r->a; 893 lput(n); 894 t += 4; 895 for(i = 0; i < n; i++){ 896 ra = *a-la; 897 if(*a < la) 898 diag("bad relocation order"); 899 if(ra < 256) 900 c = 0; 901 else if(ra < 65536) 902 c = 1; 903 else 904 c = 2; 905 cput((c<<6)|*m++); 906 t++; 907 if(c == 0){ 908 cput(ra); 909 t++; 910 } 911 else if(c == 1){ 912 wput(ra); 913 t += 2; 914 } 915 else{ 916 lput(ra); 917 t += 4; 918 } 919 la = *a++; 920 } 921 922 cflush(); 923 seek(cout, off, 0); 924 lput(t); 925 926 if(debug['v']){ 927 Bprint(&bso, "import table entries = %d\n", imports); 928 Bprint(&bso, "export table entries = %d\n", exports); 929 } 930 } 931