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