github.com/rohankumardubey/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/cmd/5l/span.c (about) 1 // Inferno utils/5l/span.c 2 // http://code.google.com/p/inferno-os/source/browse/utils/5l/span.c 3 // 4 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. 5 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) 6 // Portions Copyright © 1997-1999 Vita Nuova Limited 7 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) 8 // Portions Copyright © 2004,2006 Bruce Ellis 9 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) 10 // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others 11 // Portions Copyright © 2009 The Go Authors. All rights reserved. 12 // 13 // Permission is hereby granted, free of charge, to any person obtaining a copy 14 // of this software and associated documentation files (the "Software"), to deal 15 // in the Software without restriction, including without limitation the rights 16 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 // copies of the Software, and to permit persons to whom the Software is 18 // furnished to do so, subject to the following conditions: 19 // 20 // The above copyright notice and this permission notice shall be included in 21 // all copies or substantial portions of the Software. 22 // 23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 29 // THE SOFTWARE. 30 31 // Instruction layout. 32 33 #include "l.h" 34 #include "../ld/lib.h" 35 36 static struct { 37 uint32 start; 38 uint32 size; 39 uint32 extra; 40 } pool; 41 42 int checkpool(Prog*, int); 43 int flushpool(Prog*, int, int); 44 45 int 46 isbranch(Prog *p) 47 { 48 int as = p->as; 49 return (as >= ABEQ && as <= ABLE) || as == AB || as == ABL || as == ABX; 50 } 51 52 static int 53 scan(Prog *op, Prog *p, int c) 54 { 55 Prog *q; 56 57 for(q = op->link; q != p && q != P; q = q->link){ 58 q->pc = c; 59 c += oplook(q)->size; 60 nocache(q); 61 } 62 return c; 63 } 64 65 /* size of a case statement including jump table */ 66 static int32 67 casesz(Prog *p) 68 { 69 int jt = 0; 70 int32 n = 0; 71 Optab *o; 72 73 for( ; p != P; p = p->link){ 74 if(p->as == ABCASE) 75 jt = 1; 76 else if(jt) 77 break; 78 o = oplook(p); 79 n += o->size; 80 } 81 return n; 82 } 83 84 void 85 span(void) 86 { 87 Prog *p, *op; 88 Optab *o; 89 int m, bflag, i, v; 90 int32 c, otxt, out[6]; 91 Section *sect; 92 uchar *bp; 93 Sym *sub, *gmsym; 94 95 if(debug['v']) 96 Bprint(&bso, "%5.2f span\n", cputime()); 97 Bflush(&bso); 98 99 sect = addsection(&segtext, ".text", 05); 100 lookup("text", 0)->sect = sect; 101 lookup("etext", 0)->sect = sect; 102 103 bflag = 0; 104 c = INITTEXT; 105 otxt = c; 106 for(cursym = textp; cursym != nil; cursym = cursym->next) { 107 cursym->sect = sect; 108 p = cursym->text; 109 if(p == P || p->link == P) { // handle external functions and ELF section symbols 110 if(cursym->type & SSUB) 111 continue; 112 if(cursym->align != 0) 113 c = rnd(c, cursym->align); 114 cursym->value = 0; 115 for(sub = cursym; sub != S; sub = sub->sub) { 116 sub->value += c; 117 for(p = sub->text; p != P; p = p->link) 118 p->pc += sub->value; 119 } 120 c += cursym->size; 121 continue; 122 } 123 p->pc = c; 124 cursym->value = c; 125 126 autosize = p->to.offset + 4; 127 if(p->from.sym != S) 128 p->from.sym->value = c; 129 /* need passes to resolve branches */ 130 if(c-otxt >= 1L<<17) 131 bflag = 1; 132 otxt = c; 133 134 for(op = p, p = p->link; p != P; op = p, p = p->link) { 135 curp = p; 136 p->pc = c; 137 o = oplook(p); 138 m = o->size; 139 // must check literal pool here in case p generates many instructions 140 if(blitrl){ 141 if(checkpool(op, p->as == ACASE ? casesz(p) : m)) 142 c = p->pc = scan(op, p, c); 143 } 144 if(m == 0 && (p->as != AFUNCDATA && p->as != APCDATA)) { 145 diag("zero-width instruction\n%P", p); 146 continue; 147 } 148 switch(o->flag & (LFROM|LTO|LPOOL)) { 149 case LFROM: 150 addpool(p, &p->from); 151 break; 152 case LTO: 153 addpool(p, &p->to); 154 break; 155 case LPOOL: 156 if ((p->scond&C_SCOND) == 14) 157 flushpool(p, 0, 0); 158 break; 159 } 160 if(p->as==AMOVW && p->to.type==D_REG && p->to.reg==REGPC && (p->scond&C_SCOND) == 14) 161 flushpool(p, 0, 0); 162 c += m; 163 } 164 if(blitrl){ 165 if(checkpool(op, 0)) 166 c = scan(op, P, c); 167 } 168 cursym->size = c - cursym->value; 169 } 170 171 /* 172 * if any procedure is large enough to 173 * generate a large SBRA branch, then 174 * generate extra passes putting branches 175 * around jmps to fix. this is rare. 176 */ 177 while(bflag) { 178 if(debug['v']) 179 Bprint(&bso, "%5.2f span1\n", cputime()); 180 bflag = 0; 181 c = INITTEXT; 182 for(cursym = textp; cursym != nil; cursym = cursym->next) { 183 if(!cursym->text || !cursym->text->link) 184 continue; 185 cursym->value = c; 186 for(p = cursym->text; p != P; p = p->link) { 187 curp = p; 188 p->pc = c; 189 o = oplook(p); 190 /* very large branches 191 if(o->type == 6 && p->cond) { 192 otxt = p->cond->pc - c; 193 if(otxt < 0) 194 otxt = -otxt; 195 if(otxt >= (1L<<17) - 10) { 196 q = prg(); 197 q->link = p->link; 198 p->link = q; 199 q->as = AB; 200 q->to.type = D_BRANCH; 201 q->cond = p->cond; 202 p->cond = q; 203 q = prg(); 204 q->link = p->link; 205 p->link = q; 206 q->as = AB; 207 q->to.type = D_BRANCH; 208 q->cond = q->link->link; 209 bflag = 1; 210 } 211 } 212 */ 213 m = o->size; 214 if(m == 0 && (p->as != AFUNCDATA && p->as != APCDATA)) { 215 if(p->as == ATEXT) { 216 autosize = p->to.offset + 4; 217 if(p->from.sym != S) 218 p->from.sym->value = c; 219 continue; 220 } 221 diag("zero-width instruction\n%P", p); 222 continue; 223 } 224 c += m; 225 } 226 cursym->size = c - cursym->value; 227 } 228 } 229 230 c = rnd(c, 8); 231 232 /* 233 * lay out the code. all the pc-relative code references, 234 * even cross-function, are resolved now; 235 * only data references need to be relocated. 236 * with more work we could leave cross-function 237 * code references to be relocated too, and then 238 * perhaps we'd be able to parallelize the span loop above. 239 */ 240 gmsym = S; 241 if(linkmode == LinkExternal) 242 gmsym = lookup("runtime.tlsgm", 0); 243 for(cursym = textp; cursym != nil; cursym = cursym->next) { 244 p = cursym->text; 245 if(p == P || p->link == P) 246 continue; 247 autosize = p->to.offset + 4; 248 symgrow(cursym, cursym->size); 249 250 bp = cursym->p; 251 for(p = p->link; p != P; p = p->link) { 252 pc = p->pc; 253 curp = p; 254 o = oplook(p); 255 asmout(p, o, out, gmsym); 256 for(i=0; i<o->size/4; i++) { 257 v = out[i]; 258 *bp++ = v; 259 *bp++ = v>>8; 260 *bp++ = v>>16; 261 *bp++ = v>>24; 262 } 263 } 264 } 265 sect->vaddr = INITTEXT; 266 sect->len = c - INITTEXT; 267 } 268 269 /* 270 * when the first reference to the literal pool threatens 271 * to go out of range of a 12-bit PC-relative offset, 272 * drop the pool now, and branch round it. 273 * this happens only in extended basic blocks that exceed 4k. 274 */ 275 int 276 checkpool(Prog *p, int sz) 277 { 278 if(pool.size >= 0xffc || immaddr((p->pc+sz+4)+4+pool.size - pool.start+8) == 0) 279 return flushpool(p, 1, 0); 280 else if(p->link == P) 281 return flushpool(p, 2, 0); 282 return 0; 283 } 284 285 int 286 flushpool(Prog *p, int skip, int force) 287 { 288 Prog *q; 289 290 if(blitrl) { 291 if(skip){ 292 if(0 && skip==1)print("note: flush literal pool at %ux: len=%ud ref=%ux\n", p->pc+4, pool.size, pool.start); 293 q = prg(); 294 q->as = AB; 295 q->to.type = D_BRANCH; 296 q->cond = p->link; 297 q->link = blitrl; 298 q->line = p->line; 299 blitrl = q; 300 } 301 else if(!force && (p->pc+pool.size-pool.start < 2048)) 302 return 0; 303 elitrl->link = p->link; 304 p->link = blitrl; 305 // BUG(minux): how to correctly handle line number for constant pool entries? 306 // for now, we set line number to the last instruction preceding them at least 307 // this won't bloat the .debug_line tables 308 while(blitrl) { 309 blitrl->line = p->line; 310 blitrl = blitrl->link; 311 } 312 blitrl = 0; /* BUG: should refer back to values until out-of-range */ 313 elitrl = 0; 314 pool.size = 0; 315 pool.start = 0; 316 pool.extra = 0; 317 return 1; 318 } 319 return 0; 320 } 321 322 void 323 addpool(Prog *p, Adr *a) 324 { 325 Prog *q, t; 326 int c; 327 328 c = aclass(a); 329 330 t = zprg; 331 t.as = AWORD; 332 333 switch(c) { 334 default: 335 t.to = *a; 336 if(flag_shared && t.to.sym != S) 337 t.pcrel = p; 338 break; 339 340 case C_SROREG: 341 case C_LOREG: 342 case C_ROREG: 343 case C_FOREG: 344 case C_SOREG: 345 case C_HOREG: 346 case C_FAUTO: 347 case C_SAUTO: 348 case C_LAUTO: 349 case C_LACON: 350 t.to.type = D_CONST; 351 t.to.offset = instoffset; 352 break; 353 } 354 355 if(t.pcrel == P) { 356 for(q = blitrl; q != P; q = q->link) /* could hash on t.t0.offset */ 357 if(q->pcrel == P && memcmp(&q->to, &t.to, sizeof(t.to)) == 0) { 358 p->cond = q; 359 return; 360 } 361 } 362 363 q = prg(); 364 *q = t; 365 q->pc = pool.size; 366 367 if(blitrl == P) { 368 blitrl = q; 369 pool.start = p->pc; 370 q->align = 4; 371 } else 372 elitrl->link = q; 373 elitrl = q; 374 pool.size += 4; 375 376 p->cond = q; 377 } 378 379 void 380 xdefine(char *p, int t, int32 v) 381 { 382 Sym *s; 383 384 s = lookup(p, 0); 385 s->type = t; 386 s->value = v; 387 s->reachable = 1; 388 s->special = 1; 389 } 390 391 int32 392 regoff(Adr *a) 393 { 394 395 instoffset = 0; 396 aclass(a); 397 return instoffset; 398 } 399 400 int32 401 immrot(uint32 v) 402 { 403 int i; 404 405 for(i=0; i<16; i++) { 406 if((v & ~0xff) == 0) 407 return (i<<8) | v | (1<<25); 408 v = (v<<2) | (v>>30); 409 } 410 return 0; 411 } 412 413 int32 414 immaddr(int32 v) 415 { 416 if(v >= 0 && v <= 0xfff) 417 return (v & 0xfff) | 418 (1<<24) | /* pre indexing */ 419 (1<<23); /* pre indexing, up */ 420 if(v >= -0xfff && v < 0) 421 return (-v & 0xfff) | 422 (1<<24); /* pre indexing */ 423 return 0; 424 } 425 426 int 427 immfloat(int32 v) 428 { 429 return (v & 0xC03) == 0; /* offset will fit in floating-point load/store */ 430 } 431 432 int 433 immhalf(int32 v) 434 { 435 if(v >= 0 && v <= 0xff) 436 return v| 437 (1<<24)| /* pre indexing */ 438 (1<<23); /* pre indexing, up */ 439 if(v >= -0xff && v < 0) 440 return (-v & 0xff)| 441 (1<<24); /* pre indexing */ 442 return 0; 443 } 444 445 int32 446 symaddr(Sym *s) 447 { 448 if(!s->reachable) 449 diag("unreachable symbol in symaddr - %s", s->name); 450 return s->value; 451 } 452 453 int 454 aclass(Adr *a) 455 { 456 Sym *s; 457 int t; 458 459 switch(a->type) { 460 case D_NONE: 461 return C_NONE; 462 463 case D_REG: 464 return C_REG; 465 466 case D_REGREG: 467 return C_REGREG; 468 469 case D_REGREG2: 470 return C_REGREG2; 471 472 case D_SHIFT: 473 return C_SHIFT; 474 475 case D_FREG: 476 return C_FREG; 477 478 case D_FPCR: 479 return C_FCR; 480 481 case D_OREG: 482 switch(a->name) { 483 case D_EXTERN: 484 case D_STATIC: 485 if(a->sym == 0 || a->sym->name == 0) { 486 print("null sym external\n"); 487 print("%D\n", a); 488 return C_GOK; 489 } 490 instoffset = 0; // s.b. unused but just in case 491 return C_ADDR; 492 493 case D_AUTO: 494 instoffset = autosize + a->offset; 495 t = immaddr(instoffset); 496 if(t){ 497 if(immhalf(instoffset)) 498 return immfloat(t) ? C_HFAUTO : C_HAUTO; 499 if(immfloat(t)) 500 return C_FAUTO; 501 return C_SAUTO; 502 } 503 return C_LAUTO; 504 505 case D_PARAM: 506 instoffset = autosize + a->offset + 4L; 507 t = immaddr(instoffset); 508 if(t){ 509 if(immhalf(instoffset)) 510 return immfloat(t) ? C_HFAUTO : C_HAUTO; 511 if(immfloat(t)) 512 return C_FAUTO; 513 return C_SAUTO; 514 } 515 return C_LAUTO; 516 case D_NONE: 517 instoffset = a->offset; 518 t = immaddr(instoffset); 519 if(t) { 520 if(immhalf(instoffset)) /* n.b. that it will also satisfy immrot */ 521 return immfloat(t) ? C_HFOREG : C_HOREG; 522 if(immfloat(t)) 523 return C_FOREG; /* n.b. that it will also satisfy immrot */ 524 t = immrot(instoffset); 525 if(t) 526 return C_SROREG; 527 if(immhalf(instoffset)) 528 return C_HOREG; 529 return C_SOREG; 530 } 531 t = immrot(instoffset); 532 if(t) 533 return C_ROREG; 534 return C_LOREG; 535 } 536 return C_GOK; 537 538 case D_PSR: 539 return C_PSR; 540 541 case D_OCONST: 542 switch(a->name) { 543 case D_EXTERN: 544 case D_STATIC: 545 instoffset = 0; // s.b. unused but just in case 546 return C_ADDR; 547 } 548 return C_GOK; 549 550 case D_FCONST: 551 if(chipzero(&a->ieee) >= 0) 552 return C_ZFCON; 553 if(chipfloat(&a->ieee) >= 0) 554 return C_SFCON; 555 return C_LFCON; 556 557 case D_CONST: 558 case D_CONST2: 559 switch(a->name) { 560 561 case D_NONE: 562 instoffset = a->offset; 563 if(a->reg != NREG) 564 goto aconsize; 565 566 t = immrot(instoffset); 567 if(t) 568 return C_RCON; 569 t = immrot(~instoffset); 570 if(t) 571 return C_NCON; 572 return C_LCON; 573 574 case D_EXTERN: 575 case D_STATIC: 576 s = a->sym; 577 if(s == S) 578 break; 579 instoffset = 0; // s.b. unused but just in case 580 return C_LCONADDR; 581 582 case D_AUTO: 583 instoffset = autosize + a->offset; 584 goto aconsize; 585 586 case D_PARAM: 587 instoffset = autosize + a->offset + 4L; 588 aconsize: 589 t = immrot(instoffset); 590 if(t) 591 return C_RACON; 592 return C_LACON; 593 } 594 return C_GOK; 595 596 case D_BRANCH: 597 return C_SBRA; 598 } 599 return C_GOK; 600 } 601 602 Optab* 603 oplook(Prog *p) 604 { 605 int a1, a2, a3, r; 606 char *c1, *c3; 607 Optab *o, *e; 608 609 a1 = p->optab; 610 if(a1) 611 return optab+(a1-1); 612 a1 = p->from.class; 613 if(a1 == 0) { 614 a1 = aclass(&p->from) + 1; 615 p->from.class = a1; 616 } 617 a1--; 618 a3 = p->to.class; 619 if(a3 == 0) { 620 a3 = aclass(&p->to) + 1; 621 p->to.class = a3; 622 } 623 a3--; 624 a2 = C_NONE; 625 if(p->reg != NREG) 626 a2 = C_REG; 627 r = p->as; 628 o = oprange[r].start; 629 if(o == 0) { 630 a1 = opcross[repop[r]][a1][a2][a3]; 631 if(a1) { 632 p->optab = a1+1; 633 return optab+a1; 634 } 635 o = oprange[r].stop; /* just generate an error */ 636 } 637 if(debug['O']) { 638 print("oplook %A %O %O %O\n", 639 (int)p->as, a1, a2, a3); 640 print(" %d %d\n", p->from.type, p->to.type); 641 } 642 e = oprange[r].stop; 643 c1 = xcmp[a1]; 644 c3 = xcmp[a3]; 645 for(; o<e; o++) 646 if(o->a2 == a2) 647 if(c1[o->a1]) 648 if(c3[o->a3]) { 649 p->optab = (o-optab)+1; 650 return o; 651 } 652 diag("illegal combination %A %O %O %O, %d %d", 653 p->as, a1, a2, a3, p->from.type, p->to.type); 654 prasm(p); 655 if(o == 0) 656 o = optab; 657 return o; 658 } 659 660 int 661 cmp(int a, int b) 662 { 663 664 if(a == b) 665 return 1; 666 switch(a) { 667 case C_LCON: 668 if(b == C_RCON || b == C_NCON) 669 return 1; 670 break; 671 case C_LACON: 672 if(b == C_RACON) 673 return 1; 674 break; 675 case C_LFCON: 676 if(b == C_ZFCON || b == C_SFCON) 677 return 1; 678 break; 679 680 case C_HFAUTO: 681 return b == C_HAUTO || b == C_FAUTO; 682 case C_FAUTO: 683 case C_HAUTO: 684 return b == C_HFAUTO; 685 case C_SAUTO: 686 return cmp(C_HFAUTO, b); 687 case C_LAUTO: 688 return cmp(C_SAUTO, b); 689 690 case C_HFOREG: 691 return b == C_HOREG || b == C_FOREG; 692 case C_FOREG: 693 case C_HOREG: 694 return b == C_HFOREG; 695 case C_SROREG: 696 return cmp(C_SOREG, b) || cmp(C_ROREG, b); 697 case C_SOREG: 698 case C_ROREG: 699 return b == C_SROREG || cmp(C_HFOREG, b); 700 case C_LOREG: 701 return cmp(C_SROREG, b); 702 703 case C_LBRA: 704 if(b == C_SBRA) 705 return 1; 706 break; 707 708 case C_HREG: 709 return cmp(C_SP, b) || cmp(C_PC, b); 710 711 } 712 return 0; 713 } 714 715 int 716 ocmp(const void *a1, const void *a2) 717 { 718 Optab *p1, *p2; 719 int n; 720 721 p1 = (Optab*)a1; 722 p2 = (Optab*)a2; 723 n = p1->as - p2->as; 724 if(n) 725 return n; 726 n = p1->a1 - p2->a1; 727 if(n) 728 return n; 729 n = p1->a2 - p2->a2; 730 if(n) 731 return n; 732 n = p1->a3 - p2->a3; 733 if(n) 734 return n; 735 return 0; 736 } 737 738 void 739 buildop(void) 740 { 741 int i, n, r; 742 743 for(i=0; i<C_GOK; i++) 744 for(n=0; n<C_GOK; n++) 745 xcmp[i][n] = cmp(n, i); 746 for(n=0; optab[n].as != AXXX; n++) { 747 if((optab[n].flag & LPCREL) != 0) { 748 if(flag_shared) 749 optab[n].size += optab[n].pcrelsiz; 750 else 751 optab[n].flag &= ~LPCREL; 752 } 753 } 754 qsort(optab, n, sizeof(optab[0]), ocmp); 755 for(i=0; i<n; i++) { 756 r = optab[i].as; 757 oprange[r].start = optab+i; 758 while(optab[i].as == r) 759 i++; 760 oprange[r].stop = optab+i; 761 i--; 762 763 switch(r) 764 { 765 default: 766 diag("unknown op in build: %A", r); 767 errorexit(); 768 case AADD: 769 oprange[AAND] = oprange[r]; 770 oprange[AEOR] = oprange[r]; 771 oprange[ASUB] = oprange[r]; 772 oprange[ARSB] = oprange[r]; 773 oprange[AADC] = oprange[r]; 774 oprange[ASBC] = oprange[r]; 775 oprange[ARSC] = oprange[r]; 776 oprange[AORR] = oprange[r]; 777 oprange[ABIC] = oprange[r]; 778 break; 779 case ACMP: 780 oprange[ATEQ] = oprange[r]; 781 oprange[ACMN] = oprange[r]; 782 break; 783 case AMVN: 784 break; 785 case ABEQ: 786 oprange[ABNE] = oprange[r]; 787 oprange[ABCS] = oprange[r]; 788 oprange[ABHS] = oprange[r]; 789 oprange[ABCC] = oprange[r]; 790 oprange[ABLO] = oprange[r]; 791 oprange[ABMI] = oprange[r]; 792 oprange[ABPL] = oprange[r]; 793 oprange[ABVS] = oprange[r]; 794 oprange[ABVC] = oprange[r]; 795 oprange[ABHI] = oprange[r]; 796 oprange[ABLS] = oprange[r]; 797 oprange[ABGE] = oprange[r]; 798 oprange[ABLT] = oprange[r]; 799 oprange[ABGT] = oprange[r]; 800 oprange[ABLE] = oprange[r]; 801 break; 802 case ASLL: 803 oprange[ASRL] = oprange[r]; 804 oprange[ASRA] = oprange[r]; 805 break; 806 case AMUL: 807 oprange[AMULU] = oprange[r]; 808 break; 809 case ADIV: 810 oprange[AMOD] = oprange[r]; 811 oprange[AMODU] = oprange[r]; 812 oprange[ADIVU] = oprange[r]; 813 break; 814 case AMOVW: 815 case AMOVB: 816 case AMOVBS: 817 case AMOVBU: 818 case AMOVH: 819 case AMOVHS: 820 case AMOVHU: 821 break; 822 case ASWPW: 823 oprange[ASWPBU] = oprange[r]; 824 break; 825 case AB: 826 case ABL: 827 case ABX: 828 case ABXRET: 829 case ASWI: 830 case AWORD: 831 case AMOVM: 832 case ARFE: 833 case ATEXT: 834 case AUSEFIELD: 835 case ACASE: 836 case ABCASE: 837 case ATYPE: 838 break; 839 case AADDF: 840 oprange[AADDD] = oprange[r]; 841 oprange[ASUBF] = oprange[r]; 842 oprange[ASUBD] = oprange[r]; 843 oprange[AMULF] = oprange[r]; 844 oprange[AMULD] = oprange[r]; 845 oprange[ADIVF] = oprange[r]; 846 oprange[ADIVD] = oprange[r]; 847 oprange[ASQRTF] = oprange[r]; 848 oprange[ASQRTD] = oprange[r]; 849 oprange[AMOVFD] = oprange[r]; 850 oprange[AMOVDF] = oprange[r]; 851 oprange[AABSF] = oprange[r]; 852 oprange[AABSD] = oprange[r]; 853 break; 854 855 case ACMPF: 856 oprange[ACMPD] = oprange[r]; 857 break; 858 859 case AMOVF: 860 oprange[AMOVD] = oprange[r]; 861 break; 862 863 case AMOVFW: 864 oprange[AMOVDW] = oprange[r]; 865 break; 866 867 case AMOVWF: 868 oprange[AMOVWD] = oprange[r]; 869 break; 870 871 case AMULL: 872 oprange[AMULAL] = oprange[r]; 873 oprange[AMULLU] = oprange[r]; 874 oprange[AMULALU] = oprange[r]; 875 break; 876 877 case AMULWT: 878 oprange[AMULWB] = oprange[r]; 879 break; 880 881 case AMULAWT: 882 oprange[AMULAWB] = oprange[r]; 883 break; 884 885 case AMULA: 886 case ALDREX: 887 case ASTREX: 888 case ALDREXD: 889 case ASTREXD: 890 case ATST: 891 case APLD: 892 case AUNDEF: 893 case ACLZ: 894 case AFUNCDATA: 895 case APCDATA: 896 break; 897 } 898 } 899 } 900 901 /* 902 void 903 buildrep(int x, int as) 904 { 905 Opcross *p; 906 Optab *e, *s, *o; 907 int a1, a2, a3, n; 908 909 if(C_NONE != 0 || C_REG != 1 || C_GOK >= 32 || x >= nelem(opcross)) { 910 diag("assumptions fail in buildrep"); 911 errorexit(); 912 } 913 repop[as] = x; 914 p = (opcross + x); 915 s = oprange[as].start; 916 e = oprange[as].stop; 917 for(o=e-1; o>=s; o--) { 918 n = o-optab; 919 for(a2=0; a2<2; a2++) { 920 if(a2) { 921 if(o->a2 == C_NONE) 922 continue; 923 } else 924 if(o->a2 != C_NONE) 925 continue; 926 for(a1=0; a1<32; a1++) { 927 if(!xcmp[a1][o->a1]) 928 continue; 929 for(a3=0; a3<32; a3++) 930 if(xcmp[a3][o->a3]) 931 (*p)[a1][a2][a3] = n; 932 } 933 } 934 } 935 oprange[as].start = 0; 936 } 937 */