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