1 #include <u.h> 2 #include <libc.h> 3 #include <bio.h> 4 #include <mach.h> 5 #define Extern extern 6 #include "sparc.h" 7 8 void add(ulong); 9 void and(ulong); 10 void or(ulong); 11 void xor(ulong); 12 void sub(ulong); 13 void andn(ulong); 14 void xnor(ulong); 15 void subcc(ulong); 16 void sll(ulong); 17 void srl(ulong); 18 void sra(ulong); 19 void jmpl(ulong); 20 void andcc(ulong); 21 void xorcc(ulong); 22 void andncc(ulong); 23 void wry(ulong); 24 void rdy(ulong); 25 void mulscc(ulong); 26 void fcmp(ulong); 27 void farith(ulong); 28 void addcc(ulong); 29 void addx(ulong); 30 void addxcc(ulong); 31 void orcc(ulong); 32 void orncc(ulong); 33 void xnorcc(ulong); 34 void orn(ulong); 35 36 Inst op2[] = { 37 { add, "add", Iarith }, 38 { and, "and", Iarith }, 39 { or, "or", Iarith }, 40 { xor, "xor", Iarith }, 41 { sub, "sub", Iarith }, 42 { andn, "andn", Iarith }, 43 { orn, "orn", Inop }, 44 { xnor, "xnor", Iarith }, 45 { addx, "addx", Iarith }, 46 { undef, "" }, 47 { undef, "" }, 48 { undef, "" }, 49 { undef, "" }, 50 { undef, "" }, 51 { undef, "" }, 52 { undef, "" }, 53 { addcc, "addcc", Iarith }, 54 { andcc, "andcc", Iarith }, 55 { orcc, "orcc", Iarith }, 56 { xorcc, "xorcc", Iarith }, 57 { subcc, "subcc", Iarith }, 58 { andncc, "andncc",Iarith }, 59 { orncc, "orncc", Iarith }, 60 { xnorcc, "xnorcc",Iarith }, 61 { addxcc, "addxcc",Iarith }, 62 { undef, "" }, 63 { undef, "" }, 64 { undef, "" }, 65 { undef, "" }, 66 { undef, "" }, 67 { undef, "" }, 68 { undef, "" }, 69 { undef, "" }, 70 { undef, "" }, 71 { undef, "" }, 72 { undef, "" }, 73 { mulscc, "mulscc", Iarith }, 74 { sll, "sll", Iarith }, 75 { srl, "srl", Iarith }, 76 { sra, "sra", Iarith }, 77 { rdy, "rdy", Ireg }, 78 { undef, "" }, 79 { undef, "" }, 80 { undef, "" }, 81 { undef, "" }, 82 { undef, "" }, 83 { undef, "" }, 84 { undef, "" }, 85 { wry, "wry", Ireg }, 86 { undef, "" }, 87 { undef, "" }, 88 { undef, "" }, 89 { farith, "farith", Ifloat }, 90 { fcmp, "fcmp", Ifloat }, 91 { undef, "" }, 92 { undef, "" }, 93 { jmpl, "jmpl", Ibranch }, 94 { undef, "" }, 95 { ta, "ta", Isyscall }, 96 { undef, "" }, 97 { undef, "" }, 98 { undef, "" }, 99 { undef, "" }, 100 { undef, "" }, 101 { 0 } 102 }; 103 104 void st(ulong); 105 void stb(ulong); 106 void sth(ulong); 107 void ld(ulong); 108 void ldub(ulong); 109 void ldsb(ulong); 110 void lduh(ulong); 111 void stf(ulong); 112 void ldf(ulong); 113 void ldsh(ulong); 114 void std(ulong); 115 void ldd(ulong); 116 void ldstub(ulong); 117 void swap(ulong); 118 void lddf(ulong); 119 void stdf(ulong); 120 121 Inst op3[] = { 122 { ld, "ld", Iload }, 123 { ldub, "ldub", Iload }, 124 { lduh, "lduh", Iload }, 125 { ldd, "ldd", Iload }, 126 { st, "st", Istore }, 127 { stb, "stb", Istore }, 128 { sth, "sth", Istore }, 129 { std, "std", Istore }, 130 { undef, "" }, 131 { ldsb, "ldsb", Iload }, 132 { ldsh, "ldsh", Iload }, 133 { undef, "" }, 134 { undef, "" }, 135 { ldstub, "ldstub", Iload }, 136 { undef, "" }, 137 { swap, "swap", Iload }, 138 { undef, "" }, 139 { undef, "" }, 140 { undef, "" }, 141 { undef, "" }, 142 { undef, "" }, 143 { undef, "" }, 144 { undef, "" }, 145 { undef, "" }, 146 { undef, "" }, 147 { undef, "" }, 148 { undef, "" }, 149 { undef, "" }, 150 { undef, "" }, 151 { undef, "" }, 152 { undef, "" }, 153 { undef, "" }, 154 { ldf, "ldf", Ifloat }, 155 { undef, "" }, 156 { undef, "" }, 157 { lddf, "lddf", Ifloat }, 158 { stf, "stf", Ifloat }, 159 { undef, "" }, 160 { undef, "" }, 161 { stdf, "stdf", Ifloat }, 162 { undef, "" }, 163 { undef, "" }, 164 { undef, "" }, 165 { undef, "" }, 166 { undef, "" }, 167 { undef, "" }, 168 { undef, "" }, 169 { undef, "" }, 170 { undef, "" }, 171 { undef, "" }, 172 { undef, "" }, 173 { undef, "" }, 174 { undef, "" }, 175 { undef, "" }, 176 { undef, "" }, 177 { undef, "" }, 178 { undef, "" }, 179 { undef, "" }, 180 { undef, "" }, 181 { undef, "" }, 182 { undef, "" }, 183 { undef, "" }, 184 { undef, "" }, 185 { undef, "" }, 186 { 0 } 187 }; 188 189 void sethi(ulong); 190 void bicc(ulong); 191 void fbcc(ulong); 192 void call(ulong); 193 194 Inst op0[] = { 195 { undef, "" }, 196 { undef, "" }, 197 { bicc, "bicc", Ibranch }, 198 { undef, "" }, 199 { sethi, "sethi",Iarith }, 200 { undef, "" }, 201 { fbcc, "fbcc", Ibranch }, 202 { undef, "" }, 203 /* This is a fake and connot be reached by op0 decode */ 204 { call, "call", Ibranch }, 205 { 0 } 206 }; 207 208 void call(ulong); 209 210 void 211 run(void) 212 { 213 do { 214 reg.r[0] = 0; 215 reg.ir = ifetch(reg.pc); 216 switch(reg.ir>>30) { 217 case 0: 218 ci = &op0[(reg.ir>>22)&0x07]; 219 ci->count++; 220 (*ci->func)(reg.ir); 221 break; 222 case 1: 223 ci = &op0[8]; 224 ci->count++; 225 call(reg.ir); 226 break; 227 case 2: 228 ci = &op2[(reg.ir>>19)&0x3f]; 229 ci->count++; 230 (*ci->func)(reg.ir); 231 break; 232 case 3: 233 ci = &op3[(reg.ir>>19)&0x3f]; 234 ci->count++; 235 (*ci->func)(reg.ir); 236 break; 237 } 238 reg.pc += 4; 239 if(bplist) 240 brkchk(reg.pc, Instruction); 241 }while(--count); 242 } 243 244 void 245 ilock(int rd) 246 { 247 ulong ir; 248 249 ir = getmem_4(reg.pc+4); 250 switch(ir>>30) { 251 case 0: 252 case 1: 253 break; 254 case 2: 255 if(((ir>>20)&0x1f) == 0x1a) /* floating point */ 256 break; 257 case 3: 258 if(rd == ((ir>>14)&0x1f)) { 259 loadlock++; 260 break; 261 } 262 if(ir&IMMBIT) 263 break; 264 if(rd == (ir&0x1f)) 265 loadlock++; 266 break; 267 } 268 } 269 270 void 271 delay(ulong npc) 272 { 273 ulong opc; 274 275 reg.r[0] = 0; 276 if(reg.ir != NOP) 277 ci->useddelay++; 278 switch(reg.ir>>30) { 279 case 0: 280 ci = &op0[(reg.ir>>22)&0x07]; 281 ci->count++; 282 (*ci->func)(reg.ir); 283 break; 284 case 1: 285 ci = &op0[8]; 286 ci->count++; 287 call(reg.ir); 288 break; 289 case 2: 290 ci = &op2[(reg.ir>>19)&0x3f]; 291 ci->count++; 292 opc = reg.pc; 293 reg.pc = npc-4; 294 (*ci->func)(reg.ir); 295 reg.pc = opc; 296 break; 297 case 3: 298 ci = &op3[(reg.ir>>19)&0x3f]; 299 ci->count++; 300 opc = reg.pc; 301 reg.pc = npc-4; 302 (*ci->func)(reg.ir); 303 reg.pc = opc; 304 break; 305 } 306 } 307 308 void 309 undef(ulong ir) 310 { 311 /* Bprint(bioout, "op=%d op2=%d op3=%d\n", ir>>30, (ir>>21)&0x7, (ir>>19)&0x3f); */ 312 Bprint(bioout, "illegal_instruction IR #%.8lux\n", ir); 313 longjmp(errjmp, 0); 314 } 315 316 void 317 sub(ulong ir) 318 { 319 long v; 320 int rd, rs1, rs2; 321 322 getrop23(ir); 323 if(ir&IMMBIT) { 324 ximm(v, ir); 325 if(trace) 326 itrace("sub\tr%d,#0x%x,r%d", rs1, v, rd); 327 } 328 else { 329 v = reg.r[rs2]; 330 if(trace) 331 itrace("sub\tr%d,r%d,r%d", rs1, rs2, rd); 332 } 333 reg.r[rd] = reg.r[rs1] - v; 334 } 335 336 void 337 sll(ulong ir) 338 { 339 long v; 340 int rd, rs1, rs2; 341 342 getrop23(ir); 343 if(ir&IMMBIT) { 344 ximm(v, ir); 345 if(trace) 346 itrace("sll\tr%d,#0x%x,r%d", rs1, v, rd); 347 } 348 else { 349 v = reg.r[rs2]&0x1F; 350 if(trace) 351 itrace("sll\tr%d,r%d,r%d", rs1, rs2, rd); 352 } 353 reg.r[rd] = reg.r[rs1] << v; 354 } 355 356 void 357 srl(ulong ir) 358 { 359 long v; 360 int rd, rs1, rs2; 361 362 getrop23(ir); 363 if(ir&IMMBIT) { 364 ximm(v, ir); 365 if(trace) 366 itrace("srl\tr%d,#0x%x,r%d", rs1, v, rd); 367 } 368 else { 369 v = reg.r[rs2]; 370 if(trace) 371 itrace("srl\tr%d,r%d,r%d", rs1, rs2, rd); 372 } 373 reg.r[rd] = (ulong)reg.r[rs1] >> v; 374 } 375 376 void 377 sra(ulong ir) 378 { 379 long v; 380 int rd, rs1, rs2; 381 382 getrop23(ir); 383 if(ir&IMMBIT) { 384 ximm(v, ir); 385 if(trace) 386 itrace("sra\tr%d,#0x%x,r%d", rs1, v, rd); 387 } 388 else { 389 v = reg.r[rs2]; 390 if(trace) 391 itrace("sra\tr%d,r%d,r%d", rs1, rs2, rd); 392 } 393 if(reg.r[rs1]&SIGNBIT) 394 reg.r[rd] = reg.r[rs1]>>v | ~((1<<(32-v))-1); 395 else 396 reg.r[rd] = reg.r[rs1]>>v; 397 } 398 399 void 400 subcc(ulong ir) 401 { 402 long v; 403 int b31rs1, b31op2, b31res, r, rd, rs1, rs2; 404 405 getrop23(ir); 406 if(ir&IMMBIT) { 407 ximm(v, ir); 408 if(trace) 409 itrace("subcc\tr%d,#0x%x,r%d", rs1, v, rd); 410 } 411 else { 412 v = reg.r[rs2]; 413 if(trace) 414 itrace("subcc\tr%d,r%d,r%d", rs1, rs2, rd); 415 } 416 r = reg.r[rs1] - v; 417 reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v); 418 if(r == 0) 419 reg.psr |= PSR_z; 420 if(r < 0) 421 reg.psr |= PSR_n; 422 423 b31rs1 = reg.r[rs1]>>31; 424 b31op2 = v>>31; 425 b31res = r>>31; 426 427 if((b31rs1 & ~b31op2 & ~b31res)|(~b31rs1 & b31op2 & b31res)) 428 reg.psr |= PSR_v; 429 430 if((~b31rs1 & b31op2)|(b31res & (~b31rs1|b31op2))) 431 reg.psr |= PSR_c; 432 433 reg.r[rd] = r; 434 435 } 436 437 void 438 add(ulong ir) 439 { 440 long v; 441 int rd, rs1, rs2; 442 443 getrop23(ir); 444 if(ir&IMMBIT) { 445 ximm(v, ir); 446 if(trace) 447 itrace("add\tr%d,#0x%x,r%d", rs1, v, rd); 448 } 449 else { 450 v = reg.r[rs2]; 451 if(trace) 452 itrace("add\tr%d,r%d,r%d", rs1, rs2, rd); 453 } 454 reg.r[rd] = reg.r[rs1] + v; 455 } 456 457 void 458 addcc(ulong ir) 459 { 460 long v, r; 461 int rd, rs1, rs2, b31rs1, b31op2, b31r; 462 463 getrop23(ir); 464 if(ir&IMMBIT) { 465 ximm(v, ir); 466 if(trace) 467 itrace("addcc\tr%d,#0x%x,r%d", rs1, v, rd); 468 } 469 else { 470 v = reg.r[rs2]; 471 if(trace) 472 itrace("addcc\tr%d,r%d,r%d", rs1, rs2, rd); 473 } 474 r = reg.r[rs1] + v; 475 reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v); 476 if(r == 0) 477 reg.psr |= PSR_z; 478 if(r < 0) 479 reg.psr |= PSR_n; 480 481 b31rs1 = reg.r[rs1]>>31; 482 b31op2 = v>>31; 483 b31r = r>>31; 484 if((b31rs1 & b31op2 & ~b31r)|(~b31rs1 & ~b31op2 & b31r)) 485 reg.psr |= PSR_v; 486 if((b31rs1 & b31op2) | (~b31r & (b31rs1 | b31op2))) 487 reg.psr |= PSR_c; 488 489 reg.r[rd] = r; 490 } 491 492 void 493 addx(ulong ir) 494 { 495 long v; 496 int rd, rs1, rs2; 497 498 getrop23(ir); 499 if(ir&IMMBIT) { 500 ximm(v, ir); 501 if(trace) 502 itrace("addx\tr%d,#0x%x,r%d", rs1, v, rd); 503 } 504 else { 505 v = reg.r[rs2]; 506 if(trace) 507 itrace("addx\tr%d,r%d,r%d", rs1, rs2, rd); 508 } 509 if(reg.psr&PSR_c) 510 v++; 511 reg.r[rd] = reg.r[rs1] + v; 512 } 513 514 void 515 addxcc(ulong ir) 516 { 517 long r, v; 518 int rd, rs1, rs2, b31rs1, b31op2, b31r; 519 520 getrop23(ir); 521 if(ir&IMMBIT) { 522 ximm(v, ir); 523 if(trace) 524 itrace("addxcc\tr%d,#0x%x,r%d", rs1, v, rd); 525 } 526 else { 527 v = reg.r[rs2]; 528 if(trace) 529 itrace("addxcc\tr%d,r%d,r%d", rs1, rs2, rd); 530 } 531 if(reg.psr&PSR_c) 532 v++; 533 534 r = reg.r[rs1] + v; 535 reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v); 536 if(r == 0) 537 reg.psr |= PSR_z; 538 if(r < 0) 539 reg.psr |= PSR_n; 540 541 b31rs1 = reg.r[rs1]>>31; 542 b31op2 = v>>31; 543 b31r = r>>31; 544 if((b31rs1 & b31op2 & ~b31r)|(~b31rs1 & ~b31op2 & b31r)) 545 reg.psr |= PSR_v; 546 if((b31rs1 & b31op2) | (~b31r & (b31rs1 | b31op2))) 547 reg.psr |= PSR_c; 548 549 reg.r[rd] = r; 550 } 551 552 void 553 wry(ulong ir) 554 { 555 long v; 556 int rd, rs1, rs2; 557 558 getrop23(ir); 559 if(rd != 0) 560 undef(ir); 561 if(ir&IMMBIT) { 562 ximm(v, ir); 563 if(trace) 564 itrace("wry\tr%d,#0x%x,Y", rs1, v); 565 } 566 else { 567 v = reg.r[rs2]; 568 if(trace) 569 itrace("wry\tr%d,r%d,Y", rs1, rs2); 570 } 571 reg.Y = reg.r[rs1] + v; 572 } 573 574 void 575 rdy(ulong ir) 576 { 577 int rd, rs1, rs2; 578 579 getrop23(ir); 580 USED(rs2); 581 if(rs1 != 0) 582 undef(ir); 583 584 if(trace) 585 itrace("rdy\tY,r%d", rd); 586 587 reg.r[rd] = reg.Y; 588 } 589 590 void 591 and(ulong ir) 592 { 593 long v; 594 int rd, rs1, rs2; 595 596 getrop23(ir); 597 if(ir&IMMBIT) { 598 ximm(v, ir); 599 if(trace) 600 itrace("and\tr%d,#0x%x,r%d", rs1, v, rd); 601 } 602 else { 603 v = reg.r[rs2]; 604 if(trace) 605 itrace("and\tr%d,r%d,r%d", rs1, rs2, rd); 606 } 607 reg.r[rd] = reg.r[rs1] & v; 608 } 609 610 void 611 andcc(ulong ir) 612 { 613 long v, r; 614 int rd, rs1, rs2; 615 616 getrop23(ir); 617 if(ir&IMMBIT) { 618 ximm(v, ir); 619 if(trace) 620 itrace("andcc\tr%d,#0x%x,r%d", rs1, v, rd); 621 } 622 else { 623 v = reg.r[rs2]; 624 if(trace) 625 itrace("andcc\tr%d,r%d,r%d", rs1, rs2, rd); 626 } 627 r = reg.r[rs1] & v; 628 reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v); 629 if(r == 0) 630 reg.psr |= PSR_z; 631 if(r < 0) 632 reg.psr |= PSR_n; 633 634 reg.r[rd] = r; 635 } 636 637 void 638 orcc(ulong ir) 639 { 640 long v, r; 641 int rd, rs1, rs2; 642 643 getrop23(ir); 644 if(ir&IMMBIT) { 645 ximm(v, ir); 646 if(trace) 647 itrace("orcc\tr%d,#0x%x,r%d", rs1, v, rd); 648 } 649 else { 650 v = reg.r[rs2]; 651 if(trace) 652 itrace("orcc\tr%d,r%d,r%d", rs1, rs2, rd); 653 } 654 r = reg.r[rs1] | v; 655 reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v); 656 if(r == 0) 657 reg.psr |= PSR_z; 658 if(r < 0) 659 reg.psr |= PSR_n; 660 661 reg.r[rd] = r; 662 } 663 664 void 665 mulscc(ulong ir) 666 { 667 int b, n, v, rd, rs1, rs2; 668 long o1, o2, r, b31o1, b31o2, b31r; 669 670 getrop23(ir); 671 if(ir&IMMBIT) { 672 ximm(o2, ir); 673 if(trace) 674 itrace("mulscc\tr%d,#0x%x,r%d", rs1, o2, rd); 675 } 676 else { 677 o2 = reg.r[rs2]; 678 if(trace) 679 itrace("mulscc\tr%d,r%d,r%d", rs1, rs2, rd); 680 } 681 o1 = reg.r[rs1]>>1; 682 n = reg.psr&PSR_n ? 1 : 0; 683 v = reg.psr&PSR_v ? 1 : 0; 684 685 o1 |= (n ^ v)<<31; 686 if((reg.Y&1) == 0) 687 o2 = 0; 688 689 r = o1 + o2; 690 reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v); 691 if(r == 0) 692 reg.psr |= PSR_z; 693 if(r < 0) 694 reg.psr |= PSR_n; 695 696 b31o1 = o1>>31; 697 b31o2 = o2>>31; 698 b31r = r>>31; 699 if((b31o1 & b31o2 & ~b31r) | (~b31o1 & ~b31o2 & b31r)) 700 reg.psr |= PSR_v; 701 if((b31o1 & b31o2) | (~b31r & (b31o1 | b31o2))) 702 reg.psr |= PSR_c; 703 704 b = reg.r[rs1]&1; 705 reg.Y = (reg.Y>>1)|(b<<31); 706 reg.r[rd] = r; 707 } 708 709 void 710 or(ulong ir) 711 { 712 long v; 713 int rd, rs1, rs2; 714 715 getrop23(ir); 716 if(ir&IMMBIT) { 717 ximm(v, ir); 718 if(trace) 719 itrace("or\tr%d,#0x%x,r%d", rs1, v, rd); 720 } 721 else { 722 v = reg.r[rs2]; 723 if(trace) 724 itrace("or\tr%d,r%d,r%d", rs1, rs2, rd); 725 } 726 reg.r[rd] = reg.r[rs1] | v; 727 } 728 729 void 730 xor(ulong ir) 731 { 732 long v; 733 int rd, rs1, rs2; 734 735 getrop23(ir); 736 if(ir&IMMBIT) { 737 ximm(v, ir); 738 if(trace) 739 itrace("xor\tr%d,#0x%x,r%d", rs1, v, rd); 740 } 741 else { 742 v = reg.r[rs2]; 743 if(trace) 744 itrace("xor\tr%d,r%d,r%d", rs1, rs2, rd); 745 } 746 reg.r[rd] = reg.r[rs1] ^ v; 747 } 748 749 void 750 xorcc(ulong ir) 751 { 752 long v, r; 753 int rd, rs1, rs2; 754 755 getrop23(ir); 756 if(ir&IMMBIT) { 757 ximm(v, ir); 758 if(trace) 759 itrace("xorcc\tr%d,#0x%x,r%d", rs1, v, rd); 760 } 761 else { 762 v = reg.r[rs2]; 763 if(trace) 764 itrace("xorcc\tr%d,r%d,r%d", rs1, rs2, rd); 765 } 766 r = reg.r[rs1] ^ v; 767 reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v); 768 if(r == 0) 769 reg.psr |= PSR_z; 770 if(r < 0) 771 reg.psr |= PSR_n; 772 773 reg.r[rd] = r; 774 } 775 776 void 777 andn(ulong ir) 778 { 779 long v; 780 int rd, rs1, rs2; 781 782 getrop23(ir); 783 if(ir&IMMBIT) { 784 ximm(v, ir); 785 if(trace) 786 itrace("andn\tr%d,#0x%x,r%d", rs1, v, rd); 787 } 788 else { 789 v = reg.r[rs2]; 790 if(trace) 791 itrace("andn\tr%d,r%d,r%d", rs1, rs2, rd); 792 } 793 reg.r[rd] = reg.r[rs1] & ~v; 794 } 795 796 void 797 andncc(ulong ir) 798 { 799 long v, r; 800 int rd, rs1, rs2; 801 802 getrop23(ir); 803 if(ir&IMMBIT) { 804 ximm(v, ir); 805 if(trace) 806 itrace("andncc\tr%d,#0x%x,r%d", rs1, v, rd); 807 } 808 else { 809 v = reg.r[rs2]; 810 if(trace) 811 itrace("andncc\tr%d,r%d,r%d", rs1, rs2, rd); 812 } 813 r = reg.r[rs1] & ~v; 814 reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v); 815 if(r == 0) 816 reg.psr |= PSR_z; 817 if(r < 0) 818 reg.psr |= PSR_n; 819 820 reg.r[rd] = r; 821 } 822 823 void 824 orn(ulong ir) 825 { 826 long v; 827 int rd, rs1, rs2; 828 829 getrop23(ir); 830 if(rd == 0 && rs1 == 0) /* ken used orn r0,r0,r0 as nop */ 831 nopcount++; 832 833 if(ir&IMMBIT) { 834 ximm(v, ir); 835 if(trace) 836 itrace("orn\tr%d,#0x%x,r%d", rs1, v, rd); 837 } 838 else { 839 v = reg.r[rs2]; 840 if(trace) 841 itrace("orn\tr%d,r%d,r%d", rs1, rs2, rd); 842 } 843 reg.r[rd] = reg.r[rs1] | ~v; 844 } 845 846 void 847 orncc(ulong ir) 848 { 849 long r, v; 850 int rd, rs1, rs2; 851 852 getrop23(ir); 853 if(ir&IMMBIT) { 854 ximm(v, ir); 855 if(trace) 856 itrace("orncc\tr%d,#0x%x,r%d", rs1, v, rd); 857 } 858 else { 859 v = reg.r[rs2]; 860 if(trace) 861 itrace("orncc\tr%d,r%d,r%d", rs1, rs2, rd); 862 } 863 r = reg.r[rs1] | ~v; 864 reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v); 865 if(r == 0) 866 reg.psr |= PSR_z; 867 if(r < 0) 868 reg.psr |= PSR_n; 869 870 reg.r[rd] = r; 871 } 872 873 void 874 xnor(ulong ir) 875 { 876 long v; 877 int rd, rs1, rs2; 878 879 getrop23(ir); 880 if(ir&IMMBIT) { 881 ximm(v, ir); 882 if(trace) 883 itrace("xnor\tr%d,#0x%x,r%d", rs1, v, rd); 884 } 885 else { 886 v = reg.r[rs2]; 887 if(trace) 888 itrace("xnor\tr%d,r%d,r%d", rs1, rs2, rd); 889 } 890 reg.r[rd] = reg.r[rs1] ^ ~v; 891 } 892 893 void 894 xnorcc(ulong ir) 895 { 896 long v, r; 897 int rd, rs1, rs2; 898 899 getrop23(ir); 900 if(ir&IMMBIT) { 901 ximm(v, ir); 902 if(trace) 903 itrace("xnorcc\tr%d,#0x%x,r%d", rs1, v, rd); 904 } 905 else { 906 v = reg.r[rs2]; 907 if(trace) 908 itrace("xnorcc\tr%d,r%d,r%d", rs1, rs2, rd); 909 } 910 r = reg.r[rs1] ^ ~v; 911 reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v); 912 if(r == 0) 913 reg.psr |= PSR_z; 914 if(r < 0) 915 reg.psr |= PSR_n; 916 917 reg.r[rd] = r; 918 } 919 920 void 921 st(ulong ir) 922 { 923 ulong ea; 924 int rd, rs1, rs2; 925 926 getrop23(ir); 927 if(ir&IMMBIT) { 928 ximm(ea, ir); 929 if(trace) 930 itrace("st\tr%d,0x%lux(r%d) %lux=%lux", 931 rd, ea, rs1, ea+reg.r[rs1], reg.r[rd]); 932 ea += reg.r[rs1]; 933 } 934 else { 935 ea = reg.r[rs1] + reg.r[rs2]; 936 if(trace) 937 itrace("st\tr%d,[r%d+r%d] %lux=%lux", 938 rd, rs1, rs2, ea, reg.r[rd]); 939 } 940 941 putmem_w(ea, reg.r[rd]); 942 } 943 944 void 945 std(ulong ir) 946 { 947 ulong ea; 948 int rd, rs1, rs2; 949 950 getrop23(ir); 951 if(ir&IMMBIT) { 952 ximm(ea, ir); 953 if(trace) 954 itrace("std\tr%d,0x%lux(r%d) %lux=%lux", 955 rd, ea, rs1, ea+reg.r[rs1], reg.r[rd]); 956 ea += reg.r[rs1]; 957 } 958 else { 959 ea = reg.r[rs1] + reg.r[rs2]; 960 if(trace) 961 itrace("std\tr%d,[r%d+r%d] %lux=%lux", 962 rd, rs1, rs2, ea, reg.r[rd]); 963 } 964 965 putmem_w(ea, reg.r[rd]); 966 putmem_w(ea+4, reg.r[rd+1]); 967 } 968 969 void 970 stb(ulong ir) 971 { 972 ulong ea; 973 int rd, rs1, rs2; 974 975 getrop23(ir); 976 if(ir&IMMBIT) { 977 ximm(ea, ir); 978 if(trace) 979 itrace("stb\tr%d,0x%lux(r%d) %lux=%lux", 980 rd, ea, rs1, ea+reg.r[rs1], reg.r[rd]&0xff); 981 ea += reg.r[rs1]; 982 } 983 else { 984 ea = reg.r[rs1] + reg.r[rs2]; 985 if(trace) 986 itrace("stb\tr%d,[r%d+r%d] %lux=%lux", 987 rd, rs1, rs2, ea, reg.r[rd]&0xff); 988 } 989 990 putmem_b(ea, reg.r[rd]); 991 } 992 993 void 994 sth(ulong ir) 995 { 996 ulong ea; 997 int rd, rs1, rs2; 998 999 getrop23(ir); 1000 if(ir&IMMBIT) { 1001 ximm(ea, ir); 1002 if(trace) 1003 itrace("sth\tr%d,0x%lux(r%d) %lux=%lux", 1004 rd, ea, rs1, ea+reg.r[rs1], reg.r[rd]&0xffff); 1005 ea += reg.r[rs1]; 1006 } 1007 else { 1008 ea = reg.r[rs1] + reg.r[rs2]; 1009 if(trace) 1010 itrace("sth\tr%d,[r%d+r%d] %lux=%lux", 1011 rd, rs1, rs2, ea, reg.r[rd]&0xffff); 1012 } 1013 1014 putmem_h(ea, reg.r[rd]); 1015 } 1016 1017 void 1018 ld(ulong ir) 1019 { 1020 ulong ea; 1021 int rd, rs1, rs2; 1022 1023 getrop23(ir); 1024 if(ir&IMMBIT) { 1025 ximm(ea, ir); 1026 if(trace) 1027 itrace("ld\tr%d,0x%lux(r%d) ea=%lux",rd, ea, rs1, ea+reg.r[rs1]); 1028 ea += reg.r[rs1]; 1029 } 1030 else { 1031 ea = reg.r[rs1] + reg.r[rs2]; 1032 if(trace) 1033 itrace("ld\tr%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea); 1034 } 1035 1036 reg.r[rd] = getmem_w(ea); 1037 ilock(rd); 1038 } 1039 1040 void 1041 swap(ulong ir) 1042 { 1043 ulong t, ea; 1044 int rd, rs1, rs2; 1045 1046 getrop23(ir); 1047 if(ir&IMMBIT) { 1048 ximm(ea, ir); 1049 if(trace) 1050 itrace("swap\tr%d,0x%lux(r%d) ea=%lux", 1051 rd, ea, rs1, ea+reg.r[rs1]); 1052 ea += reg.r[rs1]; 1053 } 1054 else { 1055 ea = reg.r[rs1] + reg.r[rs2]; 1056 if(trace) 1057 itrace("swap\tr%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea); 1058 } 1059 1060 t = reg.r[rd]; 1061 reg.r[rd] = getmem_w(ea); 1062 putmem_w(ea, t); 1063 } 1064 1065 void 1066 ldd(ulong ir) 1067 { 1068 ulong ea; 1069 int rd, rs1, rs2; 1070 1071 getrop23(ir); 1072 if(ir&IMMBIT) { 1073 ximm(ea, ir); 1074 if(trace) 1075 itrace("ldd\tr%d,0x%lux(r%d) ea=%lux",rd, ea, rs1, ea+reg.r[rs1]); 1076 ea += reg.r[rs1]; 1077 } 1078 else { 1079 ea = reg.r[rs1] + reg.r[rs2]; 1080 if(trace) 1081 itrace("ldd\tr%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea); 1082 } 1083 1084 reg.r[rd] = getmem_w(ea); 1085 reg.r[rd+1] = getmem_w(ea+4); 1086 } 1087 1088 void 1089 ldub(ulong ir) 1090 { 1091 ulong ea; 1092 int rd, rs1, rs2; 1093 1094 getrop23(ir); 1095 if(ir&IMMBIT) { 1096 ximm(ea, ir); 1097 if(trace) 1098 itrace("ldub\tr%d,0x%lux(r%d) ea=%lux", 1099 rd, ea, rs1, ea+reg.r[rs1]); 1100 ea += reg.r[rs1]; 1101 } 1102 else { 1103 ea = reg.r[rs1] + reg.r[rs2]; 1104 if(trace) 1105 itrace("ldub\tr%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea); 1106 } 1107 1108 reg.r[rd] = getmem_b(ea) & 0xff; 1109 ilock(rd); 1110 } 1111 1112 void 1113 ldstub(ulong ir) 1114 { 1115 ulong ea; 1116 int rd, rs1, rs2; 1117 1118 getrop23(ir); 1119 if(ir&IMMBIT) { 1120 ximm(ea, ir); 1121 if(trace) 1122 itrace("ldstub\tr%d,0x%lux(r%d) ea=%lux", 1123 rd, ea, rs1, ea+reg.r[rs1]); 1124 ea += reg.r[rs1]; 1125 } 1126 else { 1127 ea = reg.r[rs1] + reg.r[rs2]; 1128 if(trace) 1129 itrace("ldstub\tr%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea); 1130 } 1131 1132 reg.r[rd] = getmem_b(ea) & 0xff; 1133 putmem_b(ea, 0xff); 1134 } 1135 1136 void 1137 ldsb(ulong ir) 1138 { 1139 ulong ea; 1140 int rd, rs1, rs2; 1141 1142 getrop23(ir); 1143 if(ir&IMMBIT) { 1144 ximm(ea, ir); 1145 if(trace) 1146 itrace("ldsb\tr%d,0x%lux(r%d) ea=%lux", 1147 rd, ea, rs1, ea+reg.r[rs1]); 1148 ea += reg.r[rs1]; 1149 } 1150 else { 1151 ea = reg.r[rs1] + reg.r[rs2]; 1152 if(trace) 1153 itrace("ldsb\tr%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea); 1154 } 1155 1156 reg.r[rd] = (schar)getmem_b(ea); 1157 ilock(rd); 1158 } 1159 1160 void 1161 lduh(ulong ir) 1162 { 1163 ulong ea; 1164 int rd, rs1, rs2; 1165 1166 getrop23(ir); 1167 if(ir&IMMBIT) { 1168 ximm(ea, ir); 1169 if(trace) 1170 itrace("lduh\tr%d,0x%lux(r%d) ea=%lux", 1171 rd, ea, rs1, ea+reg.r[rs1]); 1172 ea += reg.r[rs1]; 1173 } 1174 else { 1175 ea = reg.r[rs1] + reg.r[rs2]; 1176 if(trace) 1177 itrace("lduh\tr%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea); 1178 } 1179 1180 reg.r[rd] = getmem_h(ea) & 0xffff; 1181 ilock(rd); 1182 } 1183 1184 void 1185 ldsh(ulong ir) 1186 { 1187 ulong ea; 1188 int rd, rs1, rs2; 1189 1190 getrop23(ir); 1191 if(ir&IMMBIT) { 1192 ximm(ea, ir); 1193 if(trace) 1194 itrace("ldsh\tr%d,0x%lux(r%d) ea=%lux", 1195 rd, ea, rs1, ea+reg.r[rs1]); 1196 ea += reg.r[rs1]; 1197 } 1198 else { 1199 ea = reg.r[rs1] + reg.r[rs2]; 1200 if(trace) 1201 itrace("ldsh\tr%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea); 1202 } 1203 1204 reg.r[rd] = (short)getmem_h(ea); 1205 ilock(rd); 1206 } 1207 1208 void 1209 sethi(ulong ir) 1210 { 1211 int rd; 1212 ulong v; 1213 1214 rd = (ir>>25)&0x1f; 1215 v = (ir&0x3FFFFF)<<10; 1216 1217 if(rd == 0) 1218 nopcount++; 1219 1220 if(trace) 1221 itrace("sethi\t0x%lux,r%d", v, rd); 1222 1223 reg.r[rd] = v; 1224 } 1225 1226 void 1227 call(ulong ir) 1228 { 1229 Symbol s; 1230 ulong npc; 1231 1232 npc = (ir<<2) + reg.pc; 1233 if(trace) 1234 itrace("call\t%lux", npc); 1235 1236 ci->taken++; 1237 reg.r[15] = reg.pc; 1238 reg.ir = ifetch(reg.pc+4); 1239 delay(npc); 1240 1241 if(calltree) { 1242 findsym(npc, CTEXT, &s); 1243 Bprint(bioout, "%8lux %s(", reg.pc, s.name); 1244 printparams(&s, reg.r[1]); 1245 Bprint(bioout, "from "); 1246 printsource(reg.pc); 1247 Bputc(bioout, '\n'); 1248 } 1249 npc -= 4; 1250 reg.pc = npc; 1251 } 1252 1253 void 1254 jmpl(ulong ir) 1255 { 1256 ulong ea, o; 1257 Symbol s; 1258 int rd, rs1, rs2; 1259 1260 getrop23(ir); 1261 if(ir&IMMBIT) { 1262 ximm(ea, ir); 1263 o = ea; 1264 if(trace) 1265 itrace("jmpl\t0x%lux(r%d),r%d", ea, rs1, rd); 1266 1267 ea += reg.r[rs1]; 1268 if(calltree && rd == 0 && o == 8) { 1269 findsym(ea-4, CTEXT, &s); 1270 Bprint(bioout, "%8lux return to %lux %s r7=%lux\n", 1271 reg.pc, ea-4, s.name, reg.r[7]); 1272 } 1273 } 1274 else { 1275 ea = reg.r[rs1] + reg.r[rs2]; 1276 if(trace) 1277 itrace("jmpl\t[r%d+r%d],r%d", rs1, rs2, rd); 1278 } 1279 1280 ci->taken++; 1281 reg.r[rd] = reg.pc; 1282 reg.ir = ifetch(reg.pc+4); 1283 delay(ea); 1284 reg.pc = ea-4; 1285 } 1286 1287 void 1288 bicc(ulong ir) 1289 { 1290 char *op; 1291 ulong npc, anul, ba; 1292 int takeit, z, v, n, c; 1293 1294 SET(op, takeit); 1295 ba = 0; 1296 switch((ir>>25)&0x0F) { 1297 case 0: 1298 op = "bn"; 1299 takeit = 0; 1300 break; 1301 case 1: 1302 op = "be"; 1303 takeit = reg.psr&PSR_z; 1304 break; 1305 case 2: 1306 op = "ble"; 1307 z = reg.psr&PSR_z ? 1 : 0; 1308 v = reg.psr&PSR_v ? 1 : 0; 1309 n = reg.psr&PSR_n ? 1 : 0; 1310 takeit = z | (n ^ v); 1311 break; 1312 case 3: 1313 op = "bl"; 1314 v = reg.psr&PSR_v ? 1 : 0; 1315 n = reg.psr&PSR_n ? 1 : 0; 1316 takeit = n ^ v; 1317 break; 1318 case 4: 1319 op = "bleu"; 1320 z = reg.psr&PSR_z ? 1 : 0; 1321 c = reg.psr&PSR_c ? 1 : 0; 1322 takeit = c | z; 1323 break; 1324 case 5: 1325 op = "bcs"; 1326 takeit = reg.psr&PSR_c; 1327 break; 1328 case 6: 1329 op = "bneg"; 1330 takeit = reg.psr&PSR_n; 1331 break; 1332 case 7: 1333 op = "bvs"; 1334 takeit = reg.psr&PSR_v; 1335 break; 1336 case 8: 1337 op = "ba"; 1338 ba = 1; 1339 takeit = 1; 1340 break; 1341 case 9: 1342 op = "bne"; 1343 takeit = !(reg.psr&PSR_z); 1344 break; 1345 case 10: 1346 op = "bg"; 1347 z = reg.psr&PSR_z ? 1 : 0; 1348 v = reg.psr&PSR_v ? 1 : 0; 1349 n = reg.psr&PSR_n ? 1 : 0; 1350 takeit = !(z | (n ^ v)); 1351 break; 1352 case 11: 1353 op = "bge"; 1354 v = reg.psr&PSR_v ? 1 : 0; 1355 n = reg.psr&PSR_n ? 1 : 0; 1356 takeit = !(n ^ v); 1357 break; 1358 case 12: 1359 op = "bgu"; 1360 z = reg.psr&PSR_z ? 1 : 0; 1361 c = reg.psr&PSR_c ? 1 : 0; 1362 takeit = !(c | z); 1363 break; 1364 case 13: 1365 op = "bcc"; 1366 takeit = !(reg.psr&PSR_c); 1367 break; 1368 case 14: 1369 op = "bpos"; 1370 takeit = !(reg.psr&PSR_n); 1371 break; 1372 case 15: 1373 op = "bvc"; 1374 takeit = !(reg.psr&PSR_v); 1375 break; 1376 } 1377 1378 npc = ir & 0x3FFFFF; 1379 if(npc & (1<<21)) 1380 npc |= ~((1<<22)-1); 1381 npc = (npc<<2) + reg.pc; 1382 1383 anul = ir&ANUL; 1384 if(trace) { 1385 if(anul) 1386 itrace("%s,a\t%lux", op, npc); 1387 else 1388 itrace("%s\t%lux", op, npc); 1389 } 1390 1391 if(takeit == 0) { 1392 reg.pc += 4; 1393 if(anul == 0) { 1394 reg.ir = ifetch(reg.pc); 1395 delay(reg.pc+4); 1396 } 1397 else 1398 anulled++; 1399 return; 1400 } 1401 1402 ci->taken++; 1403 if(ba && anul) { 1404 anulled++; 1405 reg.pc = npc-4; 1406 return; 1407 } 1408 reg.ir = ifetch(reg.pc+4); 1409 delay(npc); 1410 reg.pc = npc-4; 1411 } 1412