1 #include "l.h" 2 3 long OFFSET; 4 /* 5 long BADOFFSET = -1; 6 7 if(OFFSET <= BADOFFSET && OFFSET+4 > BADOFFSET)\ 8 abort();\ 9 OFFSET += 4;\ 10 11 if(OFFSET == BADOFFSET)\ 12 abort();\ 13 OFFSET++;\ 14 */ 15 16 void 17 cput(int c) 18 { 19 cbp[0] = c; 20 cbp++; 21 cbc--; 22 if(cbc <= 0) 23 cflush(); 24 } 25 26 void 27 bput(long l) 28 { 29 cbp[0] = l>>24; 30 cbp[1] = l>>16; 31 cbp[2] = l>>8; 32 cbp[3] = l; 33 cbp += 4; 34 cbc -= 4; 35 if(cbc <= 0) 36 cflush(); 37 } 38 39 void 40 lput(long l) 41 { 42 43 cbp[0] = l; 44 cbp[1] = l>>8; 45 cbp[2] = l>>16; 46 cbp[3] = l>>24; 47 cbp += 4; 48 cbc -= 4; 49 if(cbc <= 0) 50 cflush(); 51 } 52 53 long 54 entryvalue(void) 55 { 56 char *a; 57 Sym *s; 58 59 a = INITENTRY; 60 if(*a >= '0' && *a <= '9') 61 return atolwhex(a); 62 s = lookup(a, 0); 63 if(s->type == 0) 64 return INITTEXT; 65 if(s->type != STEXT && s->type != SLEAF) 66 diag("entry not text: %s", s->name); 67 return s->value; 68 } 69 70 void 71 asmb(void) 72 { 73 Prog *p; 74 long t; 75 Optab *o; 76 77 if(debug['v']) 78 Bprint(&bso, "%5.2f asm\n", cputime()); 79 Bflush(&bso); 80 OFFSET = HEADR; 81 seek(cout, OFFSET, 0); 82 pc = INITTEXT; 83 for(p = firstp; p != P; p = p->link) { 84 if(p->as == ATEXT) { 85 curtext = p; 86 autosize = p->to.offset + 8; 87 } 88 if(p->pc != pc) { 89 diag("phase error %lux sb %lux\n", 90 p->pc, pc); 91 if(!debug['a']) 92 prasm(curp); 93 pc = p->pc; 94 } 95 curp = p; 96 o = oplook(p); /* could probably avoid this call */ 97 if(asmout(p, o, 0)) { 98 p = p->link; 99 pc += 4; 100 } 101 pc += o->size; 102 } 103 if(debug['a']) 104 Bprint(&bso, "\n"); 105 Bflush(&bso); 106 cflush(); 107 108 curtext = P; 109 switch(HEADTYPE) { 110 case 0: 111 case 4: 112 OFFSET = rnd(HEADR+textsize, 4096); 113 seek(cout, OFFSET, 0); 114 break; 115 case 1: 116 case 2: 117 case 3: 118 case 5: 119 case 6: 120 OFFSET = HEADR+textsize; 121 seek(cout, OFFSET, 0); 122 break; 123 } 124 for(t = 0; t < datsize; t += sizeof(buf)-100) { 125 if(datsize-t > sizeof(buf)-100) 126 datblk(t, sizeof(buf)-100); 127 else 128 datblk(t, datsize-t); 129 } 130 131 symsize = 0; 132 lcsize = 0; 133 if(!debug['s']) { 134 if(debug['v']) 135 Bprint(&bso, "%5.2f sym\n", cputime()); 136 Bflush(&bso); 137 switch(HEADTYPE) { 138 case 0: 139 case 4: 140 OFFSET = rnd(HEADR+textsize, 4096)+datsize; 141 seek(cout, OFFSET, 0); 142 break; 143 case 3: 144 case 2: 145 case 1: 146 case 5: 147 case 6: 148 OFFSET = HEADR+textsize+datsize; 149 seek(cout, OFFSET, 0); 150 break; 151 } 152 if(!debug['s']) 153 asmsym(); 154 if(debug['v']) 155 Bprint(&bso, "%5.2f pc\n", cputime()); 156 Bflush(&bso); 157 if(!debug['s']) 158 asmlc(); 159 cflush(); 160 } 161 162 if(debug['v']) 163 Bprint(&bso, "%5.2f header\n", cputime()); 164 Bflush(&bso); 165 OFFSET = 0; 166 seek(cout, OFFSET, 0); 167 switch(HEADTYPE) { 168 case 0: 169 bput(0x160L<<16); /* magic and sections */ 170 bput(0L); /* time and date */ 171 bput(rnd(HEADR+textsize, 4096)+datsize); 172 bput(symsize); /* nsyms */ 173 bput((0x38L<<16)|7L); /* size of optional hdr and flags */ 174 bput((0413<<16)|0437L); /* magic and version */ 175 bput(rnd(HEADR+textsize, 4096)); /* sizes */ 176 bput(datsize); 177 bput(bsssize); 178 bput(entryvalue()); /* va of entry */ 179 bput(INITTEXT-HEADR); /* va of base of text */ 180 bput(INITDAT); /* va of base of data */ 181 bput(INITDAT+datsize); /* va of base of bss */ 182 bput(~0L); /* gp reg mask */ 183 bput(0L); 184 bput(0L); 185 bput(0L); 186 bput(0L); 187 bput(~0L); /* gp value ?? */ 188 break; 189 case 1: 190 bput(0x160L<<16); /* magic and sections */ 191 bput(0L); /* time and date */ 192 bput(HEADR+textsize+datsize); 193 bput(symsize); /* nsyms */ 194 bput((0x38L<<16)|7L); /* size of optional hdr and flags */ 195 196 bput((0407<<16)|0437L); /* magic and version */ 197 bput(textsize); /* sizes */ 198 bput(datsize); 199 bput(bsssize); 200 bput(entryvalue()); /* va of entry */ 201 bput(INITTEXT); /* va of base of text */ 202 bput(INITDAT); /* va of base of data */ 203 bput(INITDAT+datsize); /* va of base of bss */ 204 bput(~0L); /* gp reg mask */ 205 bput(lcsize); 206 bput(0L); 207 bput(0L); 208 bput(0L); 209 bput(~0L); /* gp value ?? */ 210 bput(0L); /* complete mystery */ 211 break; 212 case 2: 213 t = 22; 214 bput(((((4*t)+0)*t)+7)); /* magic */ 215 bput(textsize); /* sizes */ 216 bput(datsize); 217 bput(bsssize); 218 bput(symsize); /* nsyms */ 219 bput(entryvalue()); /* va of entry */ 220 bput(0L); 221 bput(lcsize); 222 break; 223 case 3: 224 bput((0x160L<<16)|3L); /* magic and sections */ 225 bput(time(0)); /* time and date */ 226 bput(HEADR+textsize+datsize); 227 bput(symsize); /* nsyms */ 228 bput((0x38L<<16)|7L); /* size of optional hdr and flags */ 229 230 bput((0407<<16)|0437L); /* magic and version */ 231 bput(textsize); /* sizes */ 232 bput(datsize); 233 bput(bsssize); 234 bput(entryvalue()); /* va of entry */ 235 bput(INITTEXT); /* va of base of text */ 236 bput(INITDAT); /* va of base of data */ 237 bput(INITDAT+datsize); /* va of base of bss */ 238 bput(~0L); /* gp reg mask */ 239 bput(lcsize); 240 bput(0L); 241 bput(0L); 242 bput(0L); 243 bput(~0L); /* gp value ?? */ 244 245 strnput(".text", 8); /* text segment */ 246 bput(INITTEXT); /* address */ 247 bput(INITTEXT); 248 bput(textsize); 249 bput(HEADR); 250 bput(0L); 251 bput(HEADR+textsize+datsize+symsize); 252 bput(lcsize); /* line number size */ 253 bput(0x20L); /* flags */ 254 255 strnput(".data", 8); /* data segment */ 256 bput(INITDAT); /* address */ 257 bput(INITDAT); 258 bput(datsize); 259 bput(HEADR+textsize); 260 bput(0L); 261 bput(0L); 262 bput(0L); 263 bput(0x40L); /* flags */ 264 265 strnput(".bss", 8); /* bss segment */ 266 bput(INITDAT+datsize); /* address */ 267 bput(INITDAT+datsize); 268 bput(bsssize); 269 bput(0L); 270 bput(0L); 271 bput(0L); 272 bput(0L); 273 bput(0x80L); /* flags */ 274 break; 275 case 4: 276 277 bput((0x160L<<16)|3L); /* magic and sections */ 278 bput(time(0)); /* time and date */ 279 bput(rnd(HEADR+textsize, 4096)+datsize); 280 bput(symsize); /* nsyms */ 281 bput((0x38L<<16)|7L); /* size of optional hdr and flags */ 282 283 bput((0413<<16)|01012L); /* magic and version */ 284 bput(textsize); /* sizes */ 285 bput(datsize); 286 bput(bsssize); 287 bput(entryvalue()); /* va of entry */ 288 bput(INITTEXT); /* va of base of text */ 289 bput(INITDAT); /* va of base of data */ 290 bput(INITDAT+datsize); /* va of base of bss */ 291 bput(~0L); /* gp reg mask */ 292 bput(lcsize); 293 bput(0L); 294 bput(0L); 295 bput(0L); 296 bput(~0L); /* gp value ?? */ 297 298 strnput(".text", 8); /* text segment */ 299 bput(INITTEXT); /* address */ 300 bput(INITTEXT); 301 bput(textsize); 302 bput(HEADR); 303 bput(0L); 304 bput(HEADR+textsize+datsize+symsize); 305 bput(lcsize); /* line number size */ 306 bput(0x20L); /* flags */ 307 308 strnput(".data", 8); /* data segment */ 309 bput(INITDAT); /* address */ 310 bput(INITDAT); 311 bput(datsize); 312 bput(rnd(HEADR+textsize, 4096)); /* sizes */ 313 bput(0L); 314 bput(0L); 315 bput(0L); 316 bput(0x40L); /* flags */ 317 318 strnput(".bss", 8); /* bss segment */ 319 bput(INITDAT+datsize); /* address */ 320 bput(INITDAT+datsize); 321 bput(bsssize); 322 bput(0L); 323 bput(0L); 324 bput(0L); 325 bput(0L); 326 bput(0x80L); /* flags */ 327 break; 328 case 5: 329 strnput("\177ELF", 4); /* e_ident */ 330 cput(1); /* class = 32 bit */ 331 cput(2); /* data = MSB */ 332 cput(1); /* version = CURRENT */ 333 strnput("", 9); 334 bput((2L<<16)|8L); /* type = EXEC; machine = MIPS */ 335 bput(1L); /* version = CURRENT */ 336 bput(entryvalue()); /* entry vaddr */ 337 bput(52L); /* offset to first phdr */ 338 bput(0L); /* offset to first shdr */ 339 bput(0L); /* flags = MIPS */ 340 bput((52L<<16)|32L); /* Ehdr & Phdr sizes*/ 341 bput((3L<<16)|0L); /* # Phdrs & Shdr size */ 342 bput((0L<<16)|0L); /* # Shdrs & shdr string size */ 343 344 bput(1L); /* text - type = PT_LOAD */ 345 bput(0L); /* file offset */ 346 bput(INITTEXT-HEADR); /* vaddr */ 347 bput(INITTEXT-HEADR); /* paddr */ 348 bput(HEADR+textsize); /* file size */ 349 bput(HEADR+textsize); /* memory size */ 350 bput(0x05L); /* protections = RX */ 351 bput(0x10000L); /* alignment code?? */ 352 353 bput(1L); /* data - type = PT_LOAD */ 354 bput(HEADR+textsize); /* file offset */ 355 bput(INITDAT); /* vaddr */ 356 bput(INITDAT); /* paddr */ 357 bput(datsize); /* file size */ 358 bput(datsize+bsssize); /* memory size */ 359 bput(0x06L); /* protections = RW */ 360 bput(0x10000L); /* alignment code?? */ 361 362 bput(0L); /* data - type = PT_NULL */ 363 bput(HEADR+textsize+datsize); /* file offset */ 364 bput(0L); 365 bput(0L); 366 bput(symsize); /* symbol table size */ 367 bput(lcsize); /* line number size */ 368 bput(0x04L); /* protections = R */ 369 bput(0x04L); /* alignment code?? */ 370 break; 371 case 6: 372 t = 22; 373 bput(((((4*t)+0)*t)+7)); /* magic */ 374 bput(textsize); /* sizes */ 375 bput(datsize); 376 bput(bsssize); 377 bput(symsize); /* nsyms */ 378 bput(entryvalue()); /* va of entry */ 379 bput(0L); 380 bput(lcsize); 381 break; 382 } 383 cflush(); 384 } 385 386 void 387 strnput(char *s, int n) 388 { 389 for(; *s; s++){ 390 cput(*s); 391 n--; 392 } 393 for(; n > 0; n--) 394 cput(0); 395 } 396 397 void 398 cflush(void) 399 { 400 int n; 401 402 n = sizeof(buf.cbuf) - cbc; 403 if(n) 404 write(cout, buf.cbuf, n); 405 cbp = (uchar*)buf.cbuf; 406 cbc = sizeof(buf.cbuf); 407 } 408 409 void 410 nopstat(char *f, Count *c) 411 { 412 if(c->outof) 413 Bprint(&bso, "%s delay %ld/%ld (%.2f)\n", f, 414 c->outof - c->count, c->outof, 415 (double)(c->outof - c->count)/c->outof); 416 } 417 418 void 419 asmsym(void) 420 { 421 Prog *p; 422 Auto *a; 423 Sym *s; 424 int h; 425 426 s = lookup("etext", 0); 427 if(s->type == STEXT) 428 putsymb(s->name, 'T', s->value, s->version); 429 430 for(h=0; h<NHASH; h++) 431 for(s=hash[h]; s!=S; s=s->link) 432 switch(s->type) { 433 case SCONST: 434 putsymb(s->name, 'D', s->value, s->version); 435 continue; 436 437 case SDATA: 438 putsymb(s->name, 'D', s->value+INITDAT, s->version); 439 continue; 440 441 case SBSS: 442 putsymb(s->name, 'B', s->value+INITDAT, s->version); 443 continue; 444 445 case SFILE: 446 putsymb(s->name, 'f', s->value, s->version); 447 continue; 448 } 449 450 for(p=textp; p!=P; p=p->cond) { 451 s = p->from.sym; 452 if(s->type != STEXT && s->type != SLEAF) 453 continue; 454 455 /* filenames first */ 456 for(a=p->to.autom; a; a=a->link) 457 if(a->type == D_FILE) 458 putsymb(a->asym->name, 'z', a->aoffset, 0); 459 else 460 if(a->type == D_FILE1) 461 putsymb(a->asym->name, 'Z', a->aoffset, 0); 462 463 if(s->type == STEXT) 464 putsymb(s->name, 'T', s->value, s->version); 465 else 466 putsymb(s->name, 'L', s->value, s->version); 467 468 /* frame, auto and param after */ 469 putsymb(".frame", 'm', p->to.offset+8, 0); 470 for(a=p->to.autom; a; a=a->link) 471 if(a->type == D_AUTO) 472 putsymb(a->asym->name, 'a', -a->aoffset, 0); 473 else 474 if(a->type == D_PARAM) 475 putsymb(a->asym->name, 'p', a->aoffset, 0); 476 } 477 if(debug['v'] || debug['n']) 478 Bprint(&bso, "symsize = %lud\n", symsize); 479 Bflush(&bso); 480 } 481 482 void 483 putsymb(char *s, int t, long v, int ver) 484 { 485 int i, f; 486 487 if(t == 'f') 488 s++; 489 bput(v); 490 if(ver) 491 t += 'a' - 'A'; 492 cput(t+0x80); /* 0x80 is variable length */ 493 494 if(t == 'Z' || t == 'z') { 495 cput(s[0]); 496 for(i=1; s[i] != 0 || s[i+1] != 0; i += 2) { 497 cput(s[i]); 498 cput(s[i+1]); 499 } 500 cput(0); 501 cput(0); 502 i++; 503 } 504 else { 505 for(i=0; s[i]; i++) 506 cput(s[i]); 507 cput(0); 508 } 509 symsize += 4 + 1 + i + 1; 510 511 if(debug['n']) { 512 if(t == 'z' || t == 'Z') { 513 Bprint(&bso, "%c %.8lux ", t, v); 514 for(i=1; s[i] != 0 || s[i+1] != 0; i+=2) { 515 f = ((s[i]&0xff) << 8) | (s[i+1]&0xff); 516 Bprint(&bso, "/%x", f); 517 } 518 Bprint(&bso, "\n"); 519 return; 520 } 521 if(ver) 522 Bprint(&bso, "%c %.8lux %s<%d>\n", t, v, s, ver); 523 else 524 Bprint(&bso, "%c %.8lux %s\n", t, v, s); 525 } 526 } 527 528 #define MINLC 4 529 void 530 asmlc(void) 531 { 532 long oldpc, oldlc; 533 Prog *p; 534 long v, s; 535 536 oldpc = INITTEXT; 537 oldlc = 0; 538 for(p = firstp; p != P; p = p->link) { 539 if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) { 540 if(p->as == ATEXT) 541 curtext = p; 542 if(debug['L']) 543 Bprint(&bso, "%6lux %P\n", 544 p->pc, p); 545 continue; 546 } 547 if(debug['L']) 548 Bprint(&bso, "\t\t%6ld", lcsize); 549 v = (p->pc - oldpc) / MINLC; 550 while(v) { 551 s = 127; 552 if(v < 127) 553 s = v; 554 cput(s+128); /* 129-255 +pc */ 555 if(debug['L']) 556 Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128); 557 v -= s; 558 lcsize++; 559 } 560 s = p->line - oldlc; 561 oldlc = p->line; 562 oldpc = p->pc + MINLC; 563 if(s > 64 || s < -64) { 564 cput(0); /* 0 vv +lc */ 565 cput(s>>24); 566 cput(s>>16); 567 cput(s>>8); 568 cput(s); 569 if(debug['L']) { 570 if(s > 0) 571 Bprint(&bso, " lc+%ld(%d,%ld)\n", 572 s, 0, s); 573 else 574 Bprint(&bso, " lc%ld(%d,%ld)\n", 575 s, 0, s); 576 Bprint(&bso, "%6lux %P\n", 577 p->pc, p); 578 } 579 lcsize += 5; 580 continue; 581 } 582 if(s > 0) { 583 cput(0+s); /* 1-64 +lc */ 584 if(debug['L']) { 585 Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s); 586 Bprint(&bso, "%6lux %P\n", 587 p->pc, p); 588 } 589 } else { 590 cput(64-s); /* 65-128 -lc */ 591 if(debug['L']) { 592 Bprint(&bso, " lc%ld(%ld)\n", s, 64-s); 593 Bprint(&bso, "%6lux %P\n", 594 p->pc, p); 595 } 596 } 597 lcsize++; 598 } 599 while(lcsize & 1) { 600 s = 129; 601 cput(s); 602 lcsize++; 603 } 604 if(debug['v'] || debug['L']) 605 Bprint(&bso, "lcsize = %ld\n", lcsize); 606 Bflush(&bso); 607 } 608 609 void 610 datblk(long s, long n) 611 { 612 Prog *p; 613 char *cast; 614 long l, fl, j, d; 615 int i, c; 616 617 memset(buf.dbuf, 0, n+100); 618 for(p = datap; p != P; p = p->link) { 619 curp = p; 620 l = p->from.sym->value + p->from.offset - s; 621 c = p->reg; 622 i = 0; 623 if(l < 0) { 624 if(l+c <= 0) 625 continue; 626 while(l < 0) { 627 l++; 628 i++; 629 } 630 } 631 if(l >= n) 632 continue; 633 if(p->as != AINIT && p->as != ADYNT) { 634 for(j=l+(c-i)-1; j>=l; j--) 635 if(buf.dbuf[j]) { 636 print("%P\n", p); 637 diag("multiple initialization\n"); 638 break; 639 } 640 } 641 switch(p->to.type) { 642 default: 643 diag("unknown mode in initialization\n%P\n", p); 644 break; 645 646 case D_VCONST: 647 cast = (char*)p->to.ieee; 648 for(; i<c; i++) { 649 buf.dbuf[l] = cast[fnuxi8[i]]; 650 l++; 651 } 652 break; 653 654 case D_FCONST: 655 switch(c) { 656 default: 657 case 4: 658 fl = ieeedtof(p->to.ieee); 659 cast = (char*)&fl; 660 for(; i<c; i++) { 661 buf.dbuf[l] = cast[fnuxi4[i]]; 662 l++; 663 } 664 break; 665 case 8: 666 cast = (char*)p->to.ieee; 667 for(; i<c; i++) { 668 buf.dbuf[l] = cast[fnuxi8[i]]; 669 l++; 670 } 671 break; 672 } 673 break; 674 675 case D_SCONST: 676 for(; i<c; i++) { 677 buf.dbuf[l] = p->to.sval[i]; 678 l++; 679 } 680 break; 681 682 case D_CONST: 683 d = p->to.offset; 684 if(p->to.sym) { 685 if(p->to.sym->type == STEXT || 686 p->to.sym->type == SLEAF) 687 d += p->to.sym->value; 688 if(p->to.sym->type == SDATA) 689 d += p->to.sym->value + INITDAT; 690 if(p->to.sym->type == SBSS) 691 d += p->to.sym->value + INITDAT; 692 } 693 cast = (char*)&d; 694 switch(c) { 695 default: 696 diag("bad nuxi %d %d\n%P\n", c, i, curp); 697 break; 698 case 1: 699 for(; i<c; i++) { 700 buf.dbuf[l] = cast[inuxi1[i]]; 701 l++; 702 } 703 break; 704 case 2: 705 for(; i<c; i++) { 706 buf.dbuf[l] = cast[inuxi2[i]]; 707 l++; 708 } 709 break; 710 case 4: 711 for(; i<c; i++) { 712 buf.dbuf[l] = cast[inuxi4[i]]; 713 l++; 714 } 715 break; 716 } 717 break; 718 } 719 } 720 write(cout, buf.dbuf, n); 721 } 722 723 #define OP_RRR(op,r1,r2,r3)\ 724 (op|(((r1)&31L)<<16)|(((r2)&31L)<<21)|(((r3)&31L)<<11)) 725 #define OP_IRR(op,i,r2,r3)\ 726 (op|((i)&0xffffL)|(((r2)&31L)<<21)|(((r3)&31L)<<16)) 727 #define OP_SRR(op,s,r2,r3)\ 728 (op|(((s)&31L)<<6)|(((r2)&31L)<<16)|(((r3)&31L)<<11)) 729 #define OP_FRRR(op,r1,r2,r3)\ 730 (op|(((r1)&31L)<<16)|(((r2)&31L)<<11)|(((r3)&31L)<<6)) 731 #define OP_JMP(op,i)\ 732 ((op)|((i)&0x3ffffffL)) 733 734 #define OP(x,y)\ 735 (((x)<<3)|((y)<<0)) 736 #define SP(x,y)\ 737 (((x)<<29)|((y)<<26)) 738 #define BCOND(x,y)\ 739 (((x)<<19)|((y)<<16)) 740 #define MMU(x,y)\ 741 (SP(2,0)|(16<<21)|((x)<<3)|((y)<<0)) 742 #define FPF(x,y)\ 743 (SP(2,1)|(16<<21)|((x)<<3)|((y)<<0)) 744 #define FPD(x,y)\ 745 (SP(2,1)|(17<<21)|((x)<<3)|((y)<<0)) 746 #define FPW(x,y)\ 747 (SP(2,1)|(20<<21)|((x)<<3)|((y)<<0)) 748 #define FPV(x,y)\ 749 (SP(2,1)|(21<<21)|((x)<<3)|((y)<<0)) 750 751 int 752 asmout(Prog *p, Optab *o, int aflag) 753 { 754 long o1, o2, o3, o4, o5, o6, o7, v; 755 Prog *ct; 756 int r, a; 757 758 o1 = 0; 759 o2 = 0; 760 o3 = 0; 761 o4 = 0; 762 o5 = 0; 763 o6 = 0; 764 o7 = 0; 765 switch(o->type) { 766 default: 767 diag("unknown type %d\n", o->type); 768 if(!debug['a']) 769 prasm(p); 770 break; 771 772 case 0: /* pseudo ops */ 773 if(aflag) { 774 if(p->link) { 775 if(p->as == ATEXT) { 776 ct = curtext; 777 o2 = autosize; 778 curtext = p; 779 autosize = p->to.offset + 8; 780 o1 = asmout(p->link, oplook(p->link), aflag); 781 curtext = ct; 782 autosize = o2; 783 } else 784 o1 = asmout(p->link, oplook(p->link), aflag); 785 } 786 return o1; 787 } 788 break; 789 790 case 1: /* mov[v] r1,r2 ==> OR r1,r0,r2 */ 791 o1 = OP_RRR(oprrr(AOR), p->from.reg, REGZERO, p->to.reg); 792 break; 793 794 case 2: /* add/sub r1,[r2],r3 */ 795 r = p->reg; 796 if(r == NREG) 797 r = p->to.reg; 798 o1 = OP_RRR(oprrr(p->as), p->from.reg, r, p->to.reg); 799 break; 800 801 case 3: /* mov $soreg, r ==> or/add $i,o,r */ 802 v = regoff(&p->from); 803 r = p->from.reg; 804 if(r == NREG) 805 r = o->param; 806 a = AADDU; 807 if(o->a1 == C_ANDCON) 808 a = AOR; 809 o1 = OP_IRR(opirr(a), v, r, p->to.reg); 810 break; 811 812 case 4: /* add $scon,[r1],r2 */ 813 v = regoff(&p->from); 814 r = p->reg; 815 if(r == NREG) 816 r = p->to.reg; 817 o1 = OP_IRR(opirr(p->as), v, r, p->to.reg); 818 break; 819 820 case 5: /* syscall */ 821 if(aflag) 822 return 0; 823 o1 = oprrr(p->as); 824 break; 825 826 case 6: /* beq r1,[r2],sbra */ 827 if(aflag) 828 return 0; 829 if(!debug['Y'] && p->link && p->cond && isnop(p->link)) { 830 nop.branch.count--; 831 nop.branch.outof--; 832 nop.jump.outof++; 833 o2 = asmout(p->cond, oplook(p->cond), 1); 834 if(o2) { 835 if(p->cond == P) 836 v = -4 >> 2; 837 else 838 v = (p->cond->pc+4 - pc-4) >> 2; 839 if(((v << 16) >> 16) != v) 840 diag("short branch too far: %d\n%P\n", v, p); 841 o1 = OP_IRR(opirr(p->as+ALAST), v, p->from.reg, p->reg); 842 if(debug['a']) 843 Bprint(&bso, " %.8lux: %.8lux %.8lux%P\n", 844 p->pc, o1, o2, p); 845 lput(o1); 846 lput(o2); 847 return 1; 848 } 849 } 850 if(p->cond == P) 851 v = -4 >> 2; 852 else 853 v = (p->cond->pc - pc-4) >> 2; 854 if(((v << 16) >> 16) != v) 855 diag("short branch too far: %d\n%P\n", v, p); 856 o1 = OP_IRR(opirr(p->as), v, p->from.reg, p->reg); 857 break; 858 859 case 7: /* mov r, soreg ==> sw o(r) */ 860 r = p->to.reg; 861 if(r == NREG) 862 r = o->param; 863 v = regoff(&p->to); 864 o1 = OP_IRR(opirr(p->as), v, r, p->from.reg); 865 break; 866 867 case 8: /* mov soreg, r ==> lw o(r) */ 868 r = p->from.reg; 869 if(r == NREG) 870 r = o->param; 871 v = regoff(&p->from); 872 o1 = OP_IRR(opirr(p->as+ALAST), v, r, p->to.reg); 873 break; 874 875 case 9: /* asl r1,[r2],r3 */ 876 r = p->reg; 877 if(r == NREG) 878 r = p->to.reg; 879 o1 = OP_RRR(oprrr(p->as), r, p->from.reg, p->to.reg); 880 break; 881 882 case 10: /* add $con,[r1],r2 ==> mov $con,t; add t,[r1],r2 */ 883 v = regoff(&p->from); 884 r = AOR; 885 if(v < 0) 886 r = AADDU; 887 o1 = OP_IRR(opirr(r), v, 0, REGTMP); 888 r = p->reg; 889 if(r == NREG) 890 r = p->to.reg; 891 o2 = OP_RRR(oprrr(p->as), REGTMP, r, p->to.reg); 892 break; 893 894 case 11: /* jmp lbra */ 895 if(aflag) 896 return 0; 897 if(p->cond == P) 898 v = p->pc >> 2; 899 else 900 v = p->cond->pc >> 2; 901 o1 = OP_JMP(opirr(p->as), v); 902 if(!debug['Y'] && p->link && p->cond && isnop(p->link)) { 903 nop.branch.count--; 904 nop.branch.outof--; 905 nop.jump.outof++; 906 o2 = asmout(p->cond, oplook(p->cond), 1); 907 if(o2) { 908 o1 += 1; 909 if(debug['a']) 910 Bprint(&bso, " %.8lux: %.8lux %.8lux%P\n", 911 p->pc, o1, o2, p); 912 lput(o1); 913 lput(o2); 914 return 1; 915 } 916 } 917 break; 918 919 case 12: /* movbs r,r */ 920 v = 16; 921 if(p->as == AMOVB) 922 v = 24; 923 o1 = OP_SRR(opirr(ASLL), v, p->from.reg, p->to.reg); 924 o2 = OP_SRR(opirr(ASRA), v, p->to.reg, p->to.reg); 925 break; 926 927 case 13: /* movbu r,r */ 928 if(p->as == AMOVBU) 929 o1 = OP_IRR(opirr(AAND), 0xffL, p->from.reg, p->to.reg); 930 else 931 o1 = OP_IRR(opirr(AAND), 0xffffL, p->from.reg, p->to.reg); 932 break; 933 934 case 14: /* movwu r,r */ 935 v = 32-32; 936 o1 = OP_SRR(opirr(ASLLV+ALAST), v, p->from.reg, p->to.reg); 937 o2 = OP_SRR(opirr(ASRLV+ALAST), v, p->to.reg, p->to.reg); 938 break; 939 940 case 16: /* sll $c,[r1],r2 */ 941 v = regoff(&p->from); 942 r = p->reg; 943 if(r == NREG) 944 r = p->to.reg; 945 if(v >= 32) 946 o1 = OP_SRR(opirr(p->as+ALAST), v-32, r, p->to.reg); 947 else 948 o1 = OP_SRR(opirr(p->as), v, r, p->to.reg); 949 break; 950 951 case 18: /* jmp [r1],0(r2) */ 952 if(aflag) 953 return 0; 954 r = p->reg; 955 if(r == NREG) 956 r = o->param; 957 o1 = OP_RRR(oprrr(p->as), 0, p->to.reg, r); 958 break; 959 960 case 19: /* mov $lcon,r ==> lu+or */ 961 v = regoff(&p->from); 962 o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, p->to.reg); 963 o2 = OP_IRR(opirr(AOR), v, p->to.reg, p->to.reg); 964 break; 965 966 case 20: /* mov lohi,r */ 967 r = OP(2,0); /* mfhi */ 968 if(p->from.type == D_LO) 969 r = OP(2,2); /* mflo */ 970 o1 = OP_RRR(r, REGZERO, REGZERO, p->to.reg); 971 break; 972 973 case 21: /* mov r,lohi */ 974 r = OP(2,1); /* mthi */ 975 if(p->to.type == D_LO) 976 r = OP(2,3); /* mtlo */ 977 o1 = OP_RRR(r, REGZERO, p->from.reg, REGZERO); 978 break; 979 980 case 22: /* mul r1,r2 */ 981 o1 = OP_RRR(oprrr(p->as), p->from.reg, p->reg, REGZERO); 982 break; 983 984 case 23: /* add $lcon,r1,r2 ==> lu+or+add */ 985 v = regoff(&p->from); 986 if(p->to.reg == REGTMP || p->reg == REGTMP) 987 diag("cant synthesize large constant\n%P\n", p); 988 o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP); 989 o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP); 990 r = p->reg; 991 if(r == NREG) 992 r = p->to.reg; 993 o3 = OP_RRR(oprrr(p->as), REGTMP, r, p->to.reg); 994 break; 995 996 case 24: /* mov $ucon,,r ==> lu r */ 997 v = regoff(&p->from); 998 o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, p->to.reg); 999 break; 1000 1001 case 25: /* add/and $ucon,[r1],r2 ==> lu $con,t; add t,[r1],r2 */ 1002 v = regoff(&p->from); 1003 o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP); 1004 r = p->reg; 1005 if(r == NREG) 1006 r = p->to.reg; 1007 o2 = OP_RRR(oprrr(p->as), REGTMP, r, p->to.reg); 1008 break; 1009 1010 case 26: /* mov $lsext/auto/oreg,,r2 ==> lu+or+add */ 1011 v = regoff(&p->from); 1012 if(p->to.reg == REGTMP) 1013 diag("cant synthesize large constant\n%P\n", p); 1014 o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP); 1015 o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP); 1016 r = p->from.reg; 1017 if(r == NREG) 1018 r = o->param; 1019 o3 = OP_RRR(oprrr(AADDU), REGTMP, r, p->to.reg); 1020 break; 1021 1022 case 27: /* mov [sl]ext/auto/oreg,fr ==> lwc1 o(r) */ 1023 r = p->from.reg; 1024 if(r == NREG) 1025 r = o->param; 1026 v = regoff(&p->from); 1027 if(p->as == AMOVD) 1028 o4 = opirr(AMOVD+ALAST); 1029 else 1030 o4 = opirr(AMOVF+ALAST); 1031 switch(o->size) { 1032 case 16: 1033 o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP); 1034 o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP); 1035 o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP); 1036 o4 = OP_IRR(o4, 0, REGTMP, p->to.reg); 1037 break; 1038 case 4: 1039 o1 = OP_IRR(o4, v, r, p->to.reg); 1040 break; 1041 } 1042 break; 1043 1044 case 28: /* mov fr,[sl]ext/auto/oreg ==> swc1 o(r) */ 1045 r = p->to.reg; 1046 if(r == NREG) 1047 r = o->param; 1048 v = regoff(&p->to); 1049 if(p->as == AMOVD) 1050 o4 = opirr(AMOVD); 1051 else 1052 o4 = opirr(AMOVF); 1053 switch(o->size) { 1054 case 16: 1055 if(r == REGTMP) 1056 diag("cant synthesize large constant\n%P\n", p); 1057 o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP); 1058 o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP); 1059 o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP); 1060 o4 = OP_IRR(o4, 0, REGTMP, p->from.reg); 1061 break; 1062 case 4: 1063 o1 = OP_IRR(o4, v, r, p->from.reg); 1064 break; 1065 } 1066 break; 1067 1068 case 30: /* movw r,fr */ 1069 r = SP(2,1)|(4<<21); /* mtc1 */ 1070 o1 = OP_RRR(r, p->from.reg, 0, p->to.reg); 1071 break; 1072 1073 case 31: /* movw fr,r */ 1074 r = SP(2,1)|(0<<21); /* mfc1 */ 1075 o1 = OP_RRR(r, p->to.reg, 0, p->from.reg); 1076 break; 1077 1078 case 32: /* fadd fr1,[fr2],fr3 */ 1079 r = p->reg; 1080 if(r == NREG) 1081 o1 = OP_FRRR(oprrr(p->as), p->from.reg, p->to.reg, p->to.reg); 1082 else 1083 o1 = OP_FRRR(oprrr(p->as), p->from.reg, r, p->to.reg); 1084 break; 1085 1086 case 33: /* fabs fr1,fr3 */ 1087 o1 = OP_FRRR(oprrr(p->as), 0, p->from.reg, p->to.reg); 1088 break; 1089 1090 case 34: /* mov $con,fr ==> or/add $i,r,r2 */ 1091 v = regoff(&p->from); 1092 r = AADDU; 1093 if(o->a1 == C_ANDCON) 1094 r = AOR; 1095 o1 = OP_IRR(opirr(r), v, 0, REGTMP); 1096 o2 = OP_RRR(SP(2,1)|(4<<21), REGTMP, 0, p->to.reg); /* mtc1 */ 1097 break; 1098 1099 case 35: /* mov r,lext/luto/oreg ==> sw o(r) */ 1100 /* 1101 * the lowbits of the constant cannot 1102 * be moved into the offset of the load 1103 * because the mips 4000 in 64-bit mode 1104 * does a 64-bit add and it will screw up. 1105 */ 1106 v = regoff(&p->to); 1107 r = p->to.reg; 1108 if(r == NREG) 1109 r = o->param; 1110 if(r == REGTMP) 1111 diag("cant synthesize large constant\n%P\n", p); 1112 o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP); 1113 o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP); 1114 o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP); 1115 o4 = OP_IRR(opirr(p->as), 0, REGTMP, p->from.reg); 1116 break; 1117 1118 case 36: /* mov lext/lauto/lreg,r ==> lw o(r30) */ 1119 v = regoff(&p->from); 1120 r = p->from.reg; 1121 if(r == NREG) 1122 r = o->param; 1123 if(r == REGTMP) 1124 diag("cant synthesize large constant\n%P\n", p); 1125 o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP); 1126 o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP); 1127 o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP); 1128 o4 = OP_IRR(opirr(p->as+ALAST), 0, REGTMP, p->to.reg); 1129 break; 1130 1131 case 37: /* movw r,mr */ 1132 r = SP(2,0)|(4<<21); /* mtc0 */ 1133 if(p->as == AMOVV) 1134 r = SP(2,0)|(5<<21); /* dmtc0 */ 1135 o1 = OP_RRR(r, p->from.reg, 0, p->to.reg); 1136 break; 1137 1138 case 38: /* movw mr,r */ 1139 r = SP(2,0)|(0<<21); /* mfc0 */ 1140 if(p->as == AMOVV) 1141 r = SP(2,0)|(1<<21); /* dmfc0 */ 1142 o1 = OP_RRR(r, p->to.reg, 0, p->from.reg); 1143 break; 1144 1145 case 39: /* rfe ==> jmp+rfe */ 1146 if(aflag) 1147 return 0; 1148 o1 = OP_RRR(oprrr(AJMP), 0, p->to.reg, REGZERO); 1149 o2 = oprrr(p->as); 1150 break; 1151 1152 case 40: /* word */ 1153 if(aflag) 1154 return 0; 1155 o1 = regoff(&p->to); 1156 break; 1157 1158 case 41: /* movw r,fcr */ 1159 o1 = OP_RRR(SP(2,1)|(2<<21), REGZERO, 0, p->to.reg); /* mfcc1 */ 1160 o2 = OP_RRR(SP(2,1)|(6<<21), p->from.reg, 0, p->to.reg);/* mtcc1 */ 1161 break; 1162 1163 case 42: /* movw fcr,r */ 1164 o1 = OP_RRR(SP(2,1)|(2<<21), p->to.reg, 0, p->from.reg);/* mfcc1 */ 1165 break; 1166 1167 case 47: /* movv r,fr */ 1168 r = SP(2,1)|(5<<21); /* dmtc1 */ 1169 o1 = OP_RRR(r, p->from.reg, 0, p->to.reg); 1170 break; 1171 1172 case 48: /* movv fr,r */ 1173 r = SP(2,1)|(1<<21); /* dmfc1 */ 1174 o1 = OP_RRR(r, p->to.reg, 0, p->from.reg); 1175 break; 1176 } 1177 if(aflag) 1178 return o1; 1179 v = p->pc; 1180 switch(o->size) { 1181 default: 1182 if(debug['a']) 1183 Bprint(&bso, " %.8lux:\t\t%P\n", v, p); 1184 break; 1185 case 4: 1186 if(debug['a']) 1187 Bprint(&bso, " %.8lux: %.8lux\t%P\n", v, o1, p); 1188 lput(o1); 1189 break; 1190 case 8: 1191 if(debug['a']) 1192 Bprint(&bso, " %.8lux: %.8lux %.8lux%P\n", v, o1, o2, p); 1193 lput(o1); 1194 lput(o2); 1195 break; 1196 case 12: 1197 if(debug['a']) 1198 Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux%P\n", v, o1, o2, o3, p); 1199 lput(o1); 1200 lput(o2); 1201 lput(o3); 1202 break; 1203 case 16: 1204 if(debug['a']) 1205 Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux%P\n", 1206 v, o1, o2, o3, o4, p); 1207 lput(o1); 1208 lput(o2); 1209 lput(o3); 1210 lput(o4); 1211 break; 1212 case 20: 1213 if(debug['a']) 1214 Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %.8lux%P\n", 1215 v, o1, o2, o3, o4, o5, p); 1216 lput(o1); 1217 lput(o2); 1218 lput(o3); 1219 lput(o4); 1220 lput(o5); 1221 break; 1222 1223 case 28: 1224 if(debug['a']) 1225 Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %.8lux %.8lux %.8lux%P\n", 1226 v, o1, o2, o3, o4, o5, o6, o7, p); 1227 lput(o1); 1228 lput(o2); 1229 lput(o3); 1230 lput(o4); 1231 lput(o5); 1232 lput(o6); 1233 lput(o7); 1234 break; 1235 } 1236 return 0; 1237 } 1238 1239 int 1240 isnop(Prog *p) 1241 { 1242 if(p->as != ANOR) 1243 return 0; 1244 if(p->reg != REGZERO && p->reg != NREG) 1245 return 0; 1246 if(p->from.type != D_REG || p->from.reg != REGZERO) 1247 return 0; 1248 if(p->to.type != D_REG || p->to.reg != REGZERO) 1249 return 0; 1250 return 1; 1251 } 1252 1253 long 1254 oprrr(int a) 1255 { 1256 switch(a) { 1257 case AADD: return OP(4,0); 1258 case AADDU: return OP(4,1); 1259 case ASGT: return OP(5,2); 1260 case ASGTU: return OP(5,3); 1261 case AAND: return OP(4,4); 1262 case AOR: return OP(4,5); 1263 case AXOR: return OP(4,6); 1264 case ASUB: return OP(4,2); 1265 case ASUBU: return OP(4,3); 1266 case ANOR: return OP(4,7); 1267 case ASLL: return OP(0,4); 1268 case ASRL: return OP(0,6); 1269 case ASRA: return OP(0,7); 1270 1271 case ASLLV: return OP(2,4); 1272 case ASRLV: return OP(2,6); 1273 case ASRAV: return OP(2,7); 1274 1275 case AADDV: return OP(5,4); 1276 case AADDVU: return OP(5,5); 1277 case ASUBV: return OP(5,6); 1278 case ASUBVU: return OP(5,7); 1279 case AREM: 1280 case ADIV: return OP(3,2); 1281 case AREMU: 1282 case ADIVU: return OP(3,3); 1283 case AMUL: return OP(3,0); 1284 case AMULU: return OP(3,1); 1285 1286 case AREMV: 1287 case ADIVV: return OP(3,6); 1288 case AREMVU: 1289 case ADIVVU: return OP(3,7); 1290 case AMULV: return OP(3,4); 1291 case AMULVU: return OP(3,5); 1292 1293 case AJMP: return OP(1,0); 1294 case AJAL: return OP(1,1); 1295 1296 case ABREAK: return OP(1,5); 1297 case ASYSCALL: return OP(1,4); 1298 case ATLBP: return MMU(1,0); 1299 case ATLBR: return MMU(0,1); 1300 case ATLBWI: return MMU(0,2); 1301 case ATLBWR: return MMU(0,6); 1302 case ARFE: return MMU(2,0); 1303 1304 case ADIVF: return FPF(0,3); 1305 case ADIVD: return FPD(0,3); 1306 case AMULF: return FPF(0,2); 1307 case AMULD: return FPD(0,2); 1308 case ASUBF: return FPF(0,1); 1309 case ASUBD: return FPD(0,1); 1310 case AADDF: return FPF(0,0); 1311 case AADDD: return FPD(0,0); 1312 1313 case ATRUNCFV: return FPF(1,1); 1314 case ATRUNCDV: return FPD(1,1); 1315 case ATRUNCFW: return FPF(1,5); 1316 case ATRUNCDW: return FPD(1,5); 1317 case AMOVFV: return FPF(4,5); 1318 case AMOVDV: return FPD(4,5); 1319 case AMOVVF: return FPV(4,0); 1320 case AMOVVD: return FPV(4,1); 1321 1322 case AMOVFW: return FPF(4,4); 1323 case AMOVDW: return FPD(4,4); 1324 case AMOVWF: return FPW(4,0); 1325 case AMOVDF: return FPD(4,0); 1326 case AMOVWD: return FPW(4,1); 1327 case AMOVFD: return FPF(4,1); 1328 case AABSF: return FPF(0,5); 1329 case AABSD: return FPD(0,5); 1330 case AMOVF: return FPF(0,6); 1331 case AMOVD: return FPD(0,6); 1332 case ANEGF: return FPF(0,7); 1333 case ANEGD: return FPD(0,7); 1334 1335 case ACMPEQF: return FPF(6,2); 1336 case ACMPEQD: return FPD(6,2); 1337 case ACMPGTF: return FPF(7,4); 1338 case ACMPGTD: return FPD(7,4); 1339 case ACMPGEF: return FPF(7,6); 1340 case ACMPGED: return FPD(7,6); 1341 } 1342 if(a >= ALAST) 1343 diag("bad rrr %A+ALAST", a-ALAST); 1344 else 1345 diag("bad rrr %A", a); 1346 return 0; 1347 } 1348 1349 long 1350 opirr(int a) 1351 { 1352 switch(a) { 1353 case AADD: return SP(1,0); 1354 case AADDU: return SP(1,1); 1355 case ASGT: return SP(1,2); 1356 case ASGTU: return SP(1,3); 1357 case AAND: return SP(1,4); 1358 case AOR: return SP(1,5); 1359 case AXOR: return SP(1,6); 1360 case ALAST: return SP(1,7); /* lui */ 1361 case ASLL: return OP(0,0); 1362 case ASRL: return OP(0,2); 1363 case ASRA: return OP(0,3); 1364 1365 case AADDV: return SP(3,0); 1366 case AADDVU: return SP(3,1); 1367 1368 case AJMP: return SP(0,2); 1369 case AJAL: return SP(0,3); 1370 case ABEQ: return SP(0,4); 1371 case ABEQ+ALAST: return SP(2,4); /* likely */ 1372 case ABNE: return SP(0,5); 1373 case ABNE+ALAST: return SP(2,5); /* likely */ 1374 1375 case ABGEZ: return SP(0,1)|BCOND(0,1); 1376 case ABGEZ+ALAST: return SP(0,1)|BCOND(0,3); /* likely */ 1377 case ABGEZAL: return SP(0,1)|BCOND(2,1); 1378 case ABGEZAL+ALAST: return SP(0,1)|BCOND(2,3); /* likely */ 1379 case ABGTZ: return SP(0,7); 1380 case ABGTZ+ALAST: return SP(2,7); /* likely */ 1381 case ABLEZ: return SP(0,6); 1382 case ABLEZ+ALAST: return SP(2,6); /* likely */ 1383 case ABLTZ: return SP(0,1)|BCOND(0,0); 1384 case ABLTZ+ALAST: return SP(0,1)|BCOND(0,2); /* likely */ 1385 case ABLTZAL: return SP(0,1)|BCOND(2,0); 1386 case ABLTZAL+ALAST: return SP(0,1)|BCOND(2,2); /* likely */ 1387 1388 case ABFPT: return SP(2,1)|(257<<16); 1389 case ABFPT+ALAST: return SP(2,1)|(259<<16); /* likely */ 1390 case ABFPF: return SP(2,1)|(256<<16); 1391 case ABFPF+ALAST: return SP(2,1)|(258<<16); /* likely */ 1392 1393 case AMOVB: 1394 case AMOVBU: return SP(5,0); 1395 case AMOVH: 1396 case AMOVHU: return SP(5,1); 1397 case AMOVW: return SP(5,3); 1398 case AMOVV: return SP(7,7); 1399 case AMOVF: return SP(7,1); 1400 case AMOVD: return SP(7,5); 1401 case AMOVWL: return SP(5,2); 1402 case AMOVWR: return SP(5,6); 1403 case AMOVVL: return SP(5,4); 1404 case AMOVVR: return SP(5,5); 1405 1406 case ABREAK: return SP(5,7); 1407 1408 case AMOVWL+ALAST: return SP(4,2); 1409 case AMOVWR+ALAST: return SP(4,6); 1410 case AMOVVL+ALAST: return SP(3,2); 1411 case AMOVVR+ALAST: return SP(3,3); 1412 case AMOVB+ALAST: return SP(4,0); 1413 case AMOVBU+ALAST: return SP(4,4); 1414 case AMOVH+ALAST: return SP(4,1); 1415 case AMOVHU+ALAST: return SP(4,5); 1416 case AMOVW+ALAST: return SP(4,3); 1417 case AMOVV+ALAST: return SP(6,7); 1418 case AMOVF+ALAST: return SP(6,1); 1419 case AMOVD+ALAST: return SP(6,5); 1420 1421 case ASLLV: return OP(7,0); 1422 case ASRLV: return OP(7,2); 1423 case ASRAV: return OP(7,3); 1424 case ASLLV+ALAST: return OP(7,4); 1425 case ASRLV+ALAST: return OP(7,6); 1426 case ASRAV+ALAST: return OP(7,7); 1427 } 1428 if(a >= ALAST) 1429 diag("bad irr %A+ALAST", a-ALAST); 1430 else 1431 diag("bad irr %A", a); 1432 return 0; 1433 } 1434