1 #include <u.h> 2 #include <libc.h> 3 #include <bio.h> 4 #include <mach.h> 5 #define Extern extern 6 #include "power.h" 7 8 void add(ulong); 9 void addc(ulong); 10 void adde(ulong); 11 void addme(ulong); 12 void addze(ulong); 13 void and(ulong); 14 void andc(ulong); 15 void cmp(ulong); 16 void cmpl(ulong); 17 void cntlzw(ulong); 18 void dcbf(ulong); 19 void dcbi(ulong); 20 void dcbst(ulong); 21 void dcbt(ulong); 22 void dcbtst(ulong); 23 void dcbz(ulong); 24 void divw(ulong); 25 void divwu(ulong); 26 void eciwx(ulong); 27 void ecowx(ulong); 28 void eieio(ulong); 29 void eqv(ulong); 30 void extsb(ulong); 31 void extsh(ulong); 32 void icbi(ulong); 33 void lbzx(ulong); 34 void lfdx(ulong); 35 void lfsx(ulong); 36 void lhax(ulong); 37 void lhbrx(ulong); 38 void lhzx(ulong); 39 void lswi(ulong); 40 void lswx(ulong); 41 void lwarx(ulong); 42 void lwbrx(ulong); 43 void lwzx(ulong); 44 void mcrxr(ulong); 45 void mfcr(ulong); 46 void mfmsr(ulong); 47 void mfpmr(ulong); 48 void mfspr(ulong); 49 void mfsr(ulong); 50 void mfsrin(ulong); 51 void mftb(ulong); 52 void mftbu(ulong); 53 void mspr(ulong); 54 void mtcrf(ulong); 55 void mtmsr(ulong); 56 void mtpmr(ulong); 57 void mtspr(ulong); 58 void mtsr(ulong); 59 void mtsrin(ulong); 60 void mttb(ulong); 61 void mttbu(ulong); 62 void mulhw(ulong); 63 void mulhwu(ulong); 64 void mullw(ulong); 65 void nand(ulong); 66 void neg(ulong); 67 void nor(ulong); 68 void or(ulong); 69 void orc(ulong); 70 void slbia(ulong); 71 void slbia(ulong); 72 void slw(ulong); 73 void sraw(ulong); 74 void srawi(ulong); 75 void srw(ulong); 76 void stbx(ulong); 77 void stfdx(ulong); 78 void stfiwx(ulong); 79 void stfsx(ulong); 80 void sthbrx(ulong); 81 void sthx(ulong); 82 void stswi(ulong); 83 void stswx(ulong); 84 void stwbrx(ulong); 85 void stwcx(ulong); 86 void stwx(ulong); 87 void subf(ulong); 88 void subfc(ulong); 89 void subfe(ulong); 90 void subfme(ulong); 91 void subfze(ulong); 92 void sync(ulong); 93 void tlbie(ulong); 94 void tw(ulong); 95 void xor(ulong); 96 97 Inst op31[] = { 98 [0] {cmp, "cmp", Iarith}, 99 [4] {tw, "tw", Iarith}, 100 [8] {subfc, "subfc", Iarith}, 101 [10] {addc, "addc", Iarith}, 102 [11] {mulhwu, "mulhwu", Iarith}, 103 [19] {mfcr, "mfcr", Iarith}, 104 [20] {lwarx, "lwarx", Iload}, 105 [23] {lwzx, "lwzx", Iload}, 106 [24] {slw, "slw", Ilog}, 107 [26] {cntlzw, "cntlzw", Ilog}, 108 [28] {and, "and", Ilog}, 109 [32] {cmpl, "cmpl", Iarith}, 110 [40] {subf, "subf", Iarith}, 111 [54] {dcbst, "dcbst", Icontrol}, 112 [55] {lwzx, "lwzux", Iload}, 113 [60] {andc, "andc", Ilog}, 114 [75] {mulhw, "mulhw", Iarith}, 115 [83] {0, "mfmsr", Icontrol}, 116 [86] {dcbf, "dcbf", Icontrol}, 117 [87] {lbzx, "lbzx", Iload}, 118 [104] {neg, "neg", Iarith}, 119 [115] {0, "mfpmr", Iarith}, 120 [119] {lbzx, "lbzux", Iload}, 121 [124] {nor, "nor", Iarith}, 122 [136] {subfe, "subfe", Iarith}, 123 [138] {adde, "adde", Iarith}, 124 [144] {mtcrf, "mtcrf", Ireg}, 125 [146] {0, "mtmsr", Icontrol}, 126 [150] {stwcx, "stwcx.", Istore}, 127 [151] {stwx, "stwx", Istore}, 128 [178] {0, "mtpmr", Icontrol}, 129 [183] {stwx, "stwux", Istore}, 130 [200] {subfze, "subfze", Iarith}, 131 [202] {addze, "addze", Iarith}, 132 [210] {0, "mtsr", Ireg}, 133 [215] {stbx, "stbx", Istore}, 134 [232] {subfme, "subfme", Iarith}, 135 [234] {addme, "addme", Iarith}, 136 [235] {mullw, "mullw", Iarith}, 137 [242] {0, "mtsrin", Ireg}, 138 [246] {dcbtst, "dcbtst", Icontrol}, 139 [247] {stbx, "stbux", Istore}, 140 [266] {add, "add", Iarith}, 141 [275] {0, "mftb", Icontrol}, 142 [278] {dcbt, "dcbt", Icontrol}, 143 [279] {lhzx, "lhzx", Iload}, 144 [284] {eqv, "eqv", Ilog}, 145 [306] {0, "tlbie", Icontrol}, 146 [307] {0, "mftbu", Icontrol}, 147 [310] {0, "eciwx", Icontrol}, 148 [311] {lhzx, "lhzux", Iload}, 149 [316] {xor, "xor", Ilog}, 150 [339] {mspr, "mfspr", Ireg}, 151 [343] {lhax, "lhax", Iload}, 152 [375] {lhax, "lhaux", Iload}, 153 [403] {0, "mttb", Icontrol}, 154 [407] {sthx, "sthx", Istore}, 155 [412] {orc, "orc", Ilog}, 156 [434] {0, "slbia", Iarith}, 157 [435] {0, "mttbu", Icontrol}, 158 [438] {0, "ecowx", Icontrol}, 159 [439] {sthx, "sthux", Istore}, 160 [444] {or, "or", Ilog}, 161 [459] {divwu, "divwu", Iarith}, 162 [467] {mspr, "mtspr", Ireg}, 163 [470] {0, "dcbi", Icontrol}, 164 [476] {nand, "nand", Ilog}, 165 [491] {divw, "divw", Iarith}, 166 [498] {0, "slbia", Icontrol}, 167 [512] {mcrxr, "mcrxr", Ireg}, 168 [533] {lswx, "lswx", Iload}, 169 [534] {lwbrx, "lwbrx", Iload}, 170 [535] {lfsx, "lfsx", Ifloat}, 171 [536] {srw, "srw", Ilog}, 172 [567] {lfsx, "lfsux", Ifloat}, 173 [595] {0, "mfsr", Iarith}, 174 [597] {lswi, "lswi", Iarith}, 175 [598] {sync, "sync", Iarith}, 176 [599] {lfdx, "lfdx", Ifloat}, 177 [631] {lfdx, "lfdux", Ifloat}, 178 [659] {0, "mfsrin", Ireg}, 179 [661] {stswx, "stswx", Istore}, 180 [662] {stwbrx, "stwbrx", Istore}, 181 [663] {stfsx, "stfsx", Istore}, 182 [695] {stfsx, "stfsux", Istore}, 183 [725] {stswi, "stswi", Istore}, 184 [727] {stfdx, "stfdx", Istore}, 185 [759] {stfdx, "stfdux", Istore}, 186 [790] {lhbrx, "lhbrx", Iload}, 187 [792] {sraw, "sraw", Ilog}, 188 [824] {srawi, "srawi", Ilog}, 189 [854] {0, "eieio", Icontrol}, 190 [918] {sthbrx, "sthbrx", Istore}, 191 [922] {extsh, "extsh", Iarith}, 192 [954] {extsb, "extsb", Iarith}, 193 [982] {icbi, "icbi", Icontrol}, 194 [983] {unimp, "stfiwx", Istore}, 195 [1014] {dcbz, "dcbz", Icontrol}, 196 }; 197 198 Inset ops31 = {op31, nelem(op31)}; 199 200 void 201 mspr(ulong ir) 202 { 203 int rd, ra, rb; 204 ulong *d; 205 char *n; 206 char buf[20]; 207 208 getarrr(ir); 209 switch((rb<<5) | ra) { 210 case 0: 211 undef(ir); /* was mq */ 212 return; 213 case 1: 214 d = ®.xer; n = "xer"; 215 break; 216 case 268: 217 case 284: 218 d = ®.tbl; n = "tbl"; 219 break; 220 case 269: 221 case 285: 222 d = ®.tbu; n = "tbu"; 223 break; 224 case 22: 225 d = ®.dec; n = "dec"; 226 break; 227 case 8: 228 d = ®.lr; n = "lr"; 229 break; 230 case 9: 231 d = ®.ctr; n = "ctr"; 232 break; 233 default: 234 d = 0; sprint(n = buf, "spr%d", rd); 235 break; 236 } 237 if(getxo(ir) == 339) { 238 if(trace) 239 itrace("%s\tr%d,%s", ci->name, rd, n); 240 reg.r[rd] = *d; 241 } else { 242 if(trace) 243 itrace("%s\t%s,r%d", ci->name, n, rd); 244 *d = reg.r[rd]; 245 } 246 } 247 248 static void 249 setcr(int d, long r) 250 { 251 int c; 252 253 c = 0; 254 if(reg.xer & XER_SO) 255 c |= 1; 256 if(r == 0) 257 c |= 2; 258 else if(r > 0) 259 c |= 4; 260 else 261 c |= 8; 262 reg.cr = (reg.cr & ~mkCR(d, 0xF)) | mkCR(d, c); 263 } 264 265 void 266 addi(ulong ir) 267 { 268 int rd, ra; 269 long imm; 270 271 getairr(ir); 272 if(trace) { 273 if(ra) 274 itrace("%s\tr%d,r%d,$0x%lux", ci->name, rd, ra, imm); 275 else 276 itrace("li\tr%d,$0x%lux", rd, imm); 277 } 278 if(ra) 279 imm += reg.r[ra]; 280 reg.r[rd] = imm; 281 } 282 283 void 284 addis(ulong ir) 285 { 286 int rd, ra; 287 long imm; 288 289 getairr(ir); 290 if(trace) { 291 if(ra) 292 itrace("%s\tr%d,r%d,$0x%lux", ci->name, rd, ra, imm); 293 else 294 itrace("lis\tr%d,$0x%lux", rd, imm); 295 } 296 imm <<= 16; 297 if(ra) 298 imm += reg.r[ra]; 299 reg.r[rd] = imm; 300 } 301 302 void 303 and(ulong ir) 304 { 305 int rs, ra, rb; 306 307 getlrrr(ir); 308 reg.r[ra] = reg.r[rs] & reg.r[rb]; 309 if(trace) 310 itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb); 311 if(ir & 1) 312 setcr(0, reg.r[ra]); 313 } 314 315 void 316 andc(ulong ir) 317 { 318 int rs, ra, rb; 319 320 getlrrr(ir); 321 reg.r[ra] = reg.r[rs] & ~reg.r[rb]; 322 if(trace) 323 itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb); 324 if(ir & 1) 325 setcr(0, reg.r[ra]); 326 } 327 328 void 329 andicc(ulong ir) 330 { 331 int rs, ra; 332 ulong imm; 333 334 getlirr(ir); 335 reg.r[ra] = reg.r[rs] & imm; 336 if(trace) 337 itrace("%s\tr%d,r%d,$0x%lx", ci->name, ra, rs, imm); 338 setcr(0, reg.r[ra]); 339 } 340 341 void 342 andiscc(ulong ir) 343 { 344 int rs, ra; 345 ulong imm; 346 347 getlirr(ir); 348 reg.r[ra] = reg.r[rs] & (imm<<16); 349 if(trace) 350 itrace("%s\tr%d,r%d,$0x%lx", ci->name, ra, rs, imm); 351 setcr(0, reg.r[ra]); 352 } 353 354 void 355 cmpli(ulong ir) 356 { 357 int rd, ra; 358 ulong c; 359 ulong imm, v; 360 361 getairr(ir); 362 imm &= 0xFFFF; 363 if(rd & 3) 364 undef(ir); 365 rd >>= 2; 366 v = reg.r[ra]; 367 c = 0; 368 if(reg.xer & XER_SO) 369 c |= CRSO; 370 if(v < imm) 371 c |= CRLT; 372 else if(v == imm) 373 c |= CREQ; 374 else 375 c |= CRGT; 376 c >>= 28; 377 reg.cr = (reg.cr & ~mkCR(rd, 0xF)) | mkCR(rd, c); 378 if(trace) 379 itrace("%s\tcrf%d,r%d,0x%lux [cr=#%x]", ci->name, rd, ra, imm, c); 380 } 381 382 void 383 cmp(ulong ir) 384 { 385 int rd, ra, rb; 386 ulong c; 387 long va, vb; 388 389 getarrr(ir); 390 if(rd & 3) 391 undef(ir); 392 rd >>= 2; 393 c = 0; 394 if(reg.xer & XER_SO) 395 c |= CRSO; 396 va = reg.r[ra]; 397 vb = reg.r[rb]; 398 if(va < vb) 399 c |= CRLT; 400 else if(va == vb) 401 c |= CREQ; 402 else 403 c |= CRGT; 404 c >>= 28; 405 reg.cr = (reg.cr & ~mkCR(rd, 0xF)) | mkCR(rd, c); 406 if(trace) 407 itrace("%s\tcrf%d,r%d,r%d [cr=#%x]", ci->name, rd, ra, rb, c); 408 } 409 410 void 411 cmpi(ulong ir) 412 { 413 int rd, ra; 414 ulong c; 415 long imm, v; 416 417 getairr(ir); 418 if(rd & 3) 419 undef(ir); 420 rd >>= 2; 421 v = reg.r[ra]; 422 c = 0; 423 if(reg.xer & XER_SO) 424 c |= CRSO; 425 if(v < imm) 426 c |= CRLT; 427 else if(v == imm) 428 c |= CREQ; 429 else 430 c |= CRGT; 431 c >>= 28; 432 reg.cr = (reg.cr & ~mkCR(rd, 0xF)) | mkCR(rd, c); 433 if(trace) 434 itrace("%s\tcrf%d,r%d,0x%lux [cr=#%x]", ci->name, rd, ra, imm, c); 435 } 436 437 void 438 cmpl(ulong ir) 439 { 440 int rd, ra, rb; 441 ulong c; 442 ulong va, vb; 443 444 getarrr(ir); 445 if(rd & 3) 446 undef(ir); 447 rd >>= 2; 448 c = 0; 449 if(reg.xer & XER_SO) 450 c |= CRSO; 451 va = reg.r[ra]; 452 vb = reg.r[rb]; 453 if(va < vb) 454 c |= CRLT; 455 else if(va == vb) 456 c |= CREQ; 457 else 458 c |= CRGT; 459 c >>= 28; 460 reg.cr = (reg.cr & ~mkCR(rd, 0xF)) | mkCR(rd, c); 461 if(trace) 462 itrace("%s\tcrf%d,r%d,r%d [cr=#%x]", ci->name, rd, ra, rb, c); 463 } 464 465 void 466 cntlzw(ulong ir) 467 { 468 int rs, ra, rb, n; 469 470 getlrrr(ir); 471 if(rb) 472 undef(ir); 473 for(n=0; n<32 && (reg.r[rs] & (1L<<(31-n))) == 0; n++) 474 ; 475 reg.r[ra] = n; 476 if(trace) 477 itrace("%s%s\tr%d,r%d", ci->name, ir&1?".":"", ra, rs); 478 if(ir & 1) 479 setcr(0, reg.r[ra]); 480 } 481 482 void 483 eqv(ulong ir) 484 { 485 int rs, ra, rb; 486 487 getlrrr(ir); 488 reg.r[ra] = ~(reg.r[rs] ^ reg.r[rb]); 489 if(trace) 490 itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb); 491 if(ir & 1) 492 setcr(0, reg.r[ra]); 493 } 494 495 void 496 extsb(ulong ir) 497 { 498 int rs, ra, rb; 499 500 getlrrr(ir); 501 if(rb) 502 undef(ir); 503 reg.r[ra] = (schar)reg.r[rs]; 504 if(trace) 505 itrace("%s%s\tr%d,r%d", ci->name, ir&1?".":"", ra, rs); 506 if(ir & 1) 507 setcr(0, reg.r[ra]); 508 } 509 510 void 511 extsh(ulong ir) 512 { 513 int rs, ra, rb; 514 515 getlrrr(ir); 516 if(rb) 517 undef(ir); 518 reg.r[ra] = (short)reg.r[rs]; 519 if(trace) 520 itrace("%s%s\tr%d,r%d", ci->name, ir&1?".":"", ra, rs); 521 if(ir & 1) 522 setcr(0, reg.r[ra]); 523 } 524 525 void 526 add(ulong ir) 527 { 528 int rd, ra, rb; 529 uvlong r; 530 531 getarrr(ir); 532 r = (uvlong)(ulong)reg.r[ra] + reg.r[rb]; 533 if(ir & OE) { 534 reg.xer &= ~XER_OV; 535 if(r >> 16) 536 reg.xer |= XER_SO | XER_OV; 537 } 538 reg.r[rd] = (ulong)r; 539 if(ir & Rc) 540 setcr(0, reg.r[rd]); 541 if(trace) 542 itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra, rb); 543 } 544 545 void 546 addc(ulong ir) 547 { 548 int rd, ra, rb; 549 ulong v; 550 uvlong r; 551 552 getarrr(ir); 553 r = (uvlong)(ulong)reg.r[ra] + reg.r[rb]; 554 v = r>>32; 555 reg.xer &= ~XER_CA; 556 if(v) 557 reg.xer |= XER_CA; 558 if(ir & OE) { 559 reg.xer &= ~XER_OV; 560 if(v>>1) 561 reg.xer |= XER_SO | XER_OV; 562 } 563 reg.r[rd] = (ulong)r; 564 if(ir & Rc) 565 setcr(0, reg.r[rd]); 566 if(trace) 567 itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra, rb); 568 } 569 570 void 571 adde(ulong ir) 572 { 573 int rd, ra, rb; 574 ulong v; 575 uvlong r; 576 577 getarrr(ir); 578 r = (uvlong)(ulong)reg.r[ra] + reg.r[rb] + (reg.xer&XER_CA)!=0; 579 v = r>>32; 580 reg.xer &= ~XER_CA; 581 if(v) 582 reg.xer |= XER_CA; 583 if(ir & OE) { 584 reg.xer &= ~XER_OV; 585 if(v>>1) 586 reg.xer |= XER_SO | XER_OV; 587 } 588 reg.r[rd] = (ulong)r; 589 if(ir & Rc) 590 setcr(0, reg.r[rd]); 591 if(trace) 592 itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra, rb); 593 } 594 595 void 596 addic(ulong ir) 597 { 598 int rd, ra; 599 long imm; 600 ulong v; 601 uvlong r; 602 603 getairr(ir); 604 r = (uvlong)(ulong)reg.r[ra] + imm; 605 v = r>>32; 606 reg.xer &= ~XER_CA; 607 if(v) 608 reg.xer |= XER_CA; 609 reg.r[rd] = (ulong)r; 610 if(trace) 611 itrace("%s\tr%d,r%d,$%ld", ci->name, rd, ra, imm); 612 } 613 614 void 615 addiccc(ulong ir) 616 { 617 int rd, ra; 618 long imm; 619 ulong v; 620 uvlong r; 621 622 getairr(ir); 623 r = (uvlong)(ulong)reg.r[ra] + imm; 624 v = r>>32; 625 reg.xer &= ~XER_CA; 626 if(v) 627 reg.xer |= XER_CA; 628 reg.r[rd] = (ulong)r; 629 setcr(0, reg.r[rd]); 630 if(trace) 631 itrace("%s\tr%d,r%d,$%ld", ci->name, rd, ra, imm); 632 } 633 634 void 635 addme(ulong ir) 636 { 637 int rd, ra, rb; 638 ulong v; 639 uvlong r; 640 641 getarrr(ir); 642 if(rb) 643 undef(ir); 644 r = (uvlong)(ulong)reg.r[ra] + 0xFFFFFFFF + (reg.xer&XER_CA)!=0; 645 v = r>>32; 646 reg.xer &= ~XER_CA; 647 if(v) 648 reg.xer |= XER_CA; 649 if(ir & OE) { 650 reg.xer &= ~XER_OV; 651 if(v>>1) 652 reg.xer |= XER_SO | XER_OV; 653 } 654 reg.r[rd] = (ulong)r; 655 if(ir & Rc) 656 setcr(0, reg.r[rd]); 657 if(trace) 658 itrace("%s%s%s\tr%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra); 659 } 660 661 void 662 addze(ulong ir) 663 { 664 int rd, ra, rb; 665 ulong v; 666 uvlong r; 667 668 getarrr(ir); 669 if(rb) 670 undef(ir); 671 r = (uvlong)(ulong)reg.r[ra] + (reg.xer&XER_CA)!=0; 672 v = r>>32; 673 reg.xer &= ~XER_CA; 674 if(v) 675 reg.xer |= XER_CA; 676 if(ir & OE) { 677 reg.xer &= ~XER_OV; 678 if(v>>1) 679 reg.xer |= XER_SO | XER_OV; 680 } 681 reg.r[rd] = (ulong)r; 682 if(ir & Rc) 683 setcr(0, reg.r[rd]); 684 if(trace) 685 itrace("%s%s%s\tr%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra); 686 } 687 688 void 689 divw(ulong ir) 690 { 691 int rd, ra, rb; 692 693 getarrr(ir); 694 if(reg.r[rb] != 0 && ((ulong)reg.r[ra] != 0x80000000 || reg.r[rb] != -1)) 695 reg.r[rd] = reg.r[ra]/reg.r[rb]; 696 else if(ir & OE) 697 reg.xer |= XER_SO | XER_OV; 698 if(ir & Rc) 699 setcr(0, reg.r[rd]); 700 if(trace) 701 itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra, rb); 702 } 703 704 void 705 divwu(ulong ir) 706 { 707 int rd, ra, rb; 708 709 getarrr(ir); 710 if(reg.r[rb] != 0) 711 reg.r[rd] = (ulong)reg.r[ra]/(ulong)reg.r[rb]; 712 else if(ir & OE) 713 reg.xer |= XER_SO | XER_OV; 714 if(ir & Rc) 715 setcr(0, reg.r[rd]); 716 if(trace) 717 itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra, rb); 718 } 719 720 void 721 mcrxr(ulong ir) 722 { 723 int rd, ra, rb; 724 725 getarrr(ir); 726 if(rd & 3 || ra != 0 || rb != 0 || ir & Rc) 727 undef(ir); 728 rd >>= 2; 729 reg.cr = (reg.cr & ~mkCR(rd, 0xF)) | mkCR(rd, reg.xer>>28); 730 reg.xer &= ~(0xF<<28); 731 } 732 733 void 734 mtcrf(ulong ir) 735 { 736 int rs, crm, i; 737 ulong m; 738 739 if(ir & ((1<<20)|(1<<11)|Rc)) 740 undef(ir); 741 rs = (ir>>21)&0x1F; 742 crm = (ir>>12)&0xFF; 743 m = 0; 744 for(i = 0x80; i; i >>= 1) { 745 m <<= 4; 746 if(crm & i) 747 m |= 0xF; 748 } 749 reg.cr = (reg.cr & ~m) | (reg.r[rs] & m); 750 } 751 752 void 753 mfcr(ulong ir) 754 { 755 int rd, ra, rb; 756 757 getarrr(ir); 758 if(ra != 0 || rb != 0 || ir & Rc) 759 undef(ir); 760 reg.r[rd] = reg.cr; 761 } 762 763 void 764 mulhw(ulong ir) 765 { 766 int rd, ra, rb; 767 768 getarrr(ir); 769 reg.r[rd] = ((vlong)(long)reg.r[ra]*(long)reg.r[rb])>>32; 770 if(ir & Rc) 771 setcr(0, reg.r[rd]); 772 if(trace) 773 itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&Rc?".":"", rd, ra, rb); 774 /* BUG: doesn't set OV */ 775 } 776 777 void 778 mulhwu(ulong ir) 779 { 780 int rd, ra, rb; 781 782 getarrr(ir); 783 reg.r[rd] = ((uvlong)(ulong)reg.r[ra]*(ulong)reg.r[rb])>>32; 784 if(ir & Rc) 785 setcr(0, reg.r[rd]); /* not sure whether CR setting is signed or unsigned */ 786 if(trace) 787 itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&Rc?".":"", rd, ra, rb); 788 /* BUG: doesn't set OV */ 789 } 790 791 void 792 mullw(ulong ir) 793 { 794 int rd, ra, rb; 795 796 getarrr(ir); 797 reg.r[rd] = (uvlong)(ulong)reg.r[ra]*(ulong)reg.r[rb]; 798 if(ir & Rc) 799 setcr(0, reg.r[rd]); 800 if(trace) 801 itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&Rc?".":"", rd, ra, rb); 802 /* BUG: doesn't set OV */ 803 } 804 805 void 806 mulli(ulong ir) 807 { 808 int rd, ra; 809 long imm; 810 811 getairr(ir); 812 reg.r[rd] = (uvlong)(ulong)reg.r[ra]*(ulong)imm; 813 if(trace) 814 itrace("%s\tr%d,r%d,$%ld", ci->name, rd, ra, imm); 815 } 816 817 void 818 nand(ulong ir) 819 { 820 int rs, ra, rb; 821 822 getlrrr(ir); 823 reg.r[ra] = ~(reg.r[rs] & reg.r[rb]); 824 if(ir & Rc) 825 setcr(0, reg.r[ra]); 826 if(trace) 827 itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb); 828 } 829 830 void 831 neg(ulong ir) 832 { 833 int rd, ra, rb; 834 835 getarrr(ir); 836 if(rb) 837 undef(ir); 838 if(ir & OE) 839 reg.xer &= ~XER_OV; 840 if((ulong)reg.r[ra] == 0x80000000) { 841 if(ir & OE) 842 reg.xer |= XER_SO | XER_OV; 843 reg.r[rd] = reg.r[ra]; 844 } else 845 reg.r[rd] = -reg.r[ra]; 846 if(ir & Rc) 847 setcr(0, reg.r[rd]); 848 } 849 850 void 851 nor(ulong ir) 852 { 853 int rs, ra, rb; 854 855 getlrrr(ir); 856 reg.r[ra] = ~(reg.r[rs] | reg.r[rb]); 857 if(ir & Rc) 858 setcr(0, reg.r[ra]); 859 if(trace) 860 itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb); 861 } 862 863 void 864 or(ulong ir) 865 { 866 int rs, ra, rb; 867 868 getlrrr(ir); 869 reg.r[ra] = reg.r[rs] | reg.r[rb]; 870 if(ir & Rc) 871 setcr(0, reg.r[ra]); 872 if(trace) { 873 if(rs == rb) 874 itrace("mr%s\tr%d,r%d", ir&1?".":"", ra, rs); 875 else 876 itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb); 877 } 878 } 879 880 void 881 orc(ulong ir) 882 { 883 int rs, ra, rb; 884 885 getlrrr(ir); 886 reg.r[ra] = reg.r[rs] | ~reg.r[rb]; 887 if(ir & Rc) 888 setcr(0, reg.r[ra]); 889 if(trace) 890 itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb); 891 } 892 893 void 894 ori(ulong ir) 895 { 896 int rs, ra; 897 ulong imm; 898 899 getlirr(ir); 900 reg.r[ra] = reg.r[rs] | imm; 901 if(trace) 902 itrace("%s\tr%d,r%d,$0x%lx", ci->name, ra, rs, imm); 903 } 904 905 void 906 oris(ulong ir) 907 { 908 int rs, ra; 909 ulong imm; 910 911 getlirr(ir); 912 reg.r[ra] = reg.r[rs] | (imm<<16); 913 if(trace) 914 itrace("%s\tr%d,r%d,$0x%lx", ci->name, ra, rs, imm); 915 } 916 917 static ulong 918 mkmask(int mb, int me) 919 { 920 int i; 921 ulong v; 922 923 if(mb > me) 924 return mkmask(0, me) | mkmask(mb, 31); 925 v = 0; 926 for(i=mb; i<=me; i++) 927 v |= 1L << (31-i); /* don't need a loop, but i'm lazy */ 928 return v; 929 } 930 931 static ulong 932 rotl(ulong v, int sh) 933 { 934 if(sh == 0) 935 return v; 936 return (v<<sh) | (v>>(32-sh)); 937 } 938 939 void 940 rlwimi(ulong ir) 941 { 942 int rs, ra, rb, sh; 943 ulong m; 944 945 getlrrr(ir); 946 sh = rb; 947 m = mkmask((ir>>6)&0x1F, (ir>>1)&0x1F); 948 reg.r[ra] = (reg.r[ra] & ~m) | (rotl(reg.r[rs], sh) & m); 949 if(trace) 950 itrace("%s\tr%d,r%d,%d,#%lux", ci->name, ra, rs, sh, m); 951 if(ir & 1) 952 setcr(0, reg.r[ra]); 953 } 954 955 void 956 rlwinm(ulong ir) 957 { 958 int rs, ra, rb, sh; 959 ulong m; 960 961 getlrrr(ir); 962 sh = rb; 963 m = mkmask((ir>>6)&0x1F, (ir>>1)&0x1F); 964 reg.r[ra] = rotl(reg.r[rs], sh) & m; 965 if(trace) 966 itrace("%s%s\tr%d,r%d,%d,#%lux", ci->name, ir&Rc?".":"", ra, rs, sh, m); 967 if(ir & Rc) 968 setcr(0, reg.r[ra]); 969 } 970 971 void 972 rlwnm(ulong ir) 973 { 974 int rs, ra, rb, sh; 975 ulong m; 976 977 getlrrr(ir); 978 sh = reg.r[rb] & 0x1F; 979 m = mkmask((ir>>6)&0x1F, (ir>>1)&0x1F); 980 reg.r[ra] = rotl(reg.r[rs], sh) & m; 981 if(trace) 982 itrace("%s\tr%d,r%d,r%d,#%lux", ci->name, ra, rs, rb, m); 983 if(ir & 1) 984 setcr(0, reg.r[ra]); 985 } 986 987 void 988 slw(ulong ir) 989 { 990 int rs, ra, rb; 991 long v; 992 993 getlrrr(ir); 994 v = reg.r[rb]; 995 if((v & 0x20) == 0) { 996 v &= 0x1F; 997 reg.r[ra] = (ulong)reg.r[rs] << v; 998 } else 999 reg.r[ra] = 0; 1000 if(ir & Rc) 1001 setcr(0, reg.r[ra]); 1002 if(trace) 1003 itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb); 1004 } 1005 1006 void 1007 sraw(ulong ir) 1008 { 1009 int rs, ra, rb; 1010 long v; 1011 1012 getlrrr(ir); 1013 v = reg.r[rb]; 1014 if((v & 0x20) == 0) { 1015 v &= 0x1F; 1016 if(reg.r[rs]&SIGNBIT && v) 1017 reg.r[ra] = reg.r[rs]>>v | ~((1<<(32-v))-1); 1018 else 1019 reg.r[ra] = reg.r[rs]>>v; 1020 } else 1021 reg.r[ra] = reg.r[rs]&SIGNBIT? ~0: 0; 1022 if(ir & Rc) 1023 setcr(0, reg.r[ra]); 1024 if(trace) 1025 itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb); 1026 } 1027 1028 void 1029 srawi(ulong ir) 1030 { 1031 int rs, ra, rb; 1032 long v; 1033 1034 getlrrr(ir); 1035 v = rb; 1036 if((v & 0x20) == 0) { 1037 v &= 0x1F; 1038 if(reg.r[rs]&SIGNBIT && v) 1039 reg.r[ra] = reg.r[rs]>>v | ~((1<<(32-v))-1); 1040 else 1041 reg.r[ra] = reg.r[rs]>>v; 1042 } else 1043 reg.r[ra] = reg.r[rs]&SIGNBIT? ~0: 0; 1044 if(ir & Rc) 1045 setcr(0, reg.r[ra]); 1046 if(trace) 1047 itrace("%s%s\tr%d,r%d,$%d", ci->name, ir&1?".":"", ra, rs, v); 1048 } 1049 1050 void 1051 srw(ulong ir) 1052 { 1053 int rs, ra, rb; 1054 long v; 1055 1056 getlrrr(ir); 1057 v = reg.r[rb]; 1058 if((v & 0x20) == 0) 1059 reg.r[ra] = (ulong)reg.r[rs] >> (v&0x1F); 1060 else 1061 reg.r[ra] = 0; 1062 if(ir & Rc) 1063 setcr(0, reg.r[ra]); 1064 if(trace) 1065 itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb); 1066 } 1067 1068 void 1069 subf(ulong ir) 1070 { 1071 int rd, ra, rb; 1072 uvlong r; 1073 1074 getarrr(ir); 1075 r = (uvlong)((ulong)~reg.r[ra]) + reg.r[rb] + 1; 1076 if(ir & OE) { 1077 reg.xer &= ~XER_OV; 1078 if(r >> 16) 1079 reg.xer |= XER_SO | XER_OV; 1080 } 1081 reg.r[rd] = (ulong)r; 1082 if(ir & Rc) 1083 setcr(0, reg.r[rd]); 1084 if(trace) 1085 itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra, rb); 1086 } 1087 1088 void 1089 subfc(ulong ir) 1090 { 1091 int rd, ra, rb; 1092 ulong v; 1093 uvlong r; 1094 1095 getarrr(ir); 1096 r = (uvlong)((ulong)~reg.r[ra]) + reg.r[rb] + 1; 1097 v = r>>32; 1098 reg.xer &= ~XER_CA; 1099 if(v) 1100 reg.xer |= XER_CA; 1101 if(ir & OE) { 1102 reg.xer &= ~XER_OV; 1103 if(v>>1) 1104 reg.xer |= XER_SO | XER_OV; 1105 } 1106 reg.r[rd] = (ulong)r; 1107 if(ir & Rc) 1108 setcr(0, reg.r[rd]); 1109 if(trace) 1110 itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra, rb); 1111 } 1112 1113 void 1114 subfe(ulong ir) 1115 { 1116 int rd, ra, rb; 1117 ulong v; 1118 uvlong r; 1119 1120 getarrr(ir); 1121 r = (uvlong)((ulong)~reg.r[ra]) + reg.r[rb] + (reg.xer&XER_CA)!=0; 1122 v = r>>32; 1123 reg.xer &= ~XER_CA; 1124 if(v) 1125 reg.xer |= XER_CA; 1126 if(ir & OE) { 1127 reg.xer &= ~XER_OV; 1128 if(v>>1) 1129 reg.xer |= XER_SO | XER_OV; 1130 } 1131 reg.r[rd] = (ulong)r; 1132 if(ir & Rc) 1133 setcr(0, reg.r[rd]); 1134 if(trace) 1135 itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra, rb); 1136 } 1137 1138 void 1139 subfic(ulong ir) 1140 { 1141 int rd, ra; 1142 long imm; 1143 ulong v; 1144 uvlong r; 1145 1146 getairr(ir); 1147 r = (uvlong)((ulong)~reg.r[ra]) + imm + 1; 1148 v = r>>32; 1149 reg.xer &= ~XER_CA; 1150 if(v) 1151 reg.xer |= XER_CA; 1152 reg.r[rd] = (ulong)r; 1153 if(trace) 1154 itrace("%s\tr%d,r%d,$%ld", ci->name, rd, ra, imm); 1155 } 1156 1157 void 1158 subfme(ulong ir) 1159 { 1160 int rd, ra, rb; 1161 ulong v; 1162 uvlong r; 1163 1164 getarrr(ir); 1165 if(rb) 1166 undef(ir); 1167 r = (uvlong)((ulong)~reg.r[ra]) + 0xFFFFFFFF + (reg.xer&XER_CA)!=0; 1168 v = r>>32; 1169 reg.xer &= ~XER_CA; 1170 if(v) 1171 reg.xer |= XER_CA; 1172 if(ir & OE) { 1173 reg.xer &= ~XER_OV; 1174 if(v>>1) 1175 reg.xer |= XER_SO | XER_OV; 1176 } 1177 reg.r[rd] = (ulong)r; 1178 if(ir & Rc) 1179 setcr(0, reg.r[rd]); 1180 if(trace) 1181 itrace("%s%s%s\tr%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra); 1182 } 1183 1184 void 1185 subfze(ulong ir) 1186 { 1187 int rd, ra, rb; 1188 ulong v; 1189 uvlong r; 1190 1191 getarrr(ir); 1192 if(rb) 1193 undef(ir); 1194 r = (uvlong)((ulong)~reg.r[ra]) + (reg.xer&XER_CA)!=0; 1195 v = r>>32; 1196 reg.xer &= ~XER_CA; 1197 if(v) 1198 reg.xer |= XER_CA; 1199 if(ir & OE) { 1200 reg.xer &= ~XER_OV; 1201 if(v>>1) 1202 reg.xer |= XER_SO | XER_OV; 1203 } 1204 reg.r[rd] = (ulong)r; 1205 if(ir & Rc) 1206 setcr(0, reg.r[rd]); 1207 if(trace) 1208 itrace("%s%s%s\tr%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra); 1209 } 1210 1211 void 1212 xor(ulong ir) 1213 { 1214 int rs, ra, rb; 1215 1216 getlrrr(ir); 1217 reg.r[ra] = reg.r[rs] ^ reg.r[rb]; 1218 if(trace) 1219 itrace("%s\tr%d,r%d,r%d", ci->name, ra, rs, rb); 1220 } 1221 1222 void 1223 xori(ulong ir) 1224 { 1225 int rs, ra; 1226 ulong imm; 1227 1228 getlirr(ir); 1229 reg.r[ra] = reg.r[rs] ^ imm; 1230 if(trace) 1231 itrace("%s\tr%d,r%d,$0x%lx", ci->name, ra, rs, imm); 1232 } 1233 1234 void 1235 xoris(ulong ir) 1236 { 1237 int rs, ra; 1238 ulong imm; 1239 1240 getlirr(ir); 1241 reg.r[ra] = reg.r[rs] ^ (imm<<16); 1242 if(trace) 1243 itrace("%s\tr%d,r%d,$0x%lx", ci->name, ra, rs, imm); 1244 } 1245 1246 void 1247 lwz(ulong ir) 1248 { 1249 ulong ea; 1250 int ra, rd, upd; 1251 long imm; 1252 1253 getairr(ir); 1254 ea = imm; 1255 upd = (ir&(1L<<26))!=0; 1256 if(ra) { 1257 ea += reg.r[ra]; 1258 if(upd) 1259 reg.r[ra] = ea; 1260 } else { 1261 if(upd) 1262 undef(ir); 1263 } 1264 if(trace) 1265 itrace("%s\tr%d,%ld(r%d) ea=%lux", ci->name, rd, imm, ra, ea); 1266 1267 reg.r[rd] = getmem_w(ea); 1268 } 1269 1270 void 1271 lwzx(ulong ir) 1272 { 1273 ulong ea; 1274 int rb, ra, rd, upd; 1275 1276 getarrr(ir); 1277 ea = reg.r[rb]; 1278 upd = getxo(ir)==55; 1279 if(ra) { 1280 ea += reg.r[ra]; 1281 if(upd) 1282 reg.r[ra] = ea; 1283 if(trace) 1284 itrace("%s\tr%d,(r%d+r%d) ea=%lux", ci->name, rd, ra, rb, ea); 1285 } else { 1286 if(upd) 1287 undef(ir); 1288 if(trace) 1289 itrace("%s\tr%d,(r%d) ea=%lux", ci->name, rd, rb, ea); 1290 } 1291 1292 reg.r[rd] = getmem_w(ea); 1293 } 1294 1295 void 1296 lwarx(ulong ir) 1297 { 1298 lwzx(ir); 1299 } 1300 1301 void 1302 lbz(ulong ir) 1303 { 1304 ulong ea; 1305 int ra, rd, upd; 1306 long imm; 1307 1308 getairr(ir); 1309 ea = imm; 1310 upd = (ir&(1L<<26))!=0; 1311 if(ra) { 1312 ea += reg.r[ra]; 1313 if(upd) 1314 reg.r[ra] = ea; 1315 } else { 1316 if(upd) 1317 undef(ir); 1318 } 1319 if(trace) 1320 itrace("%s\tr%d,%ld(r%d) ea=%lux", ci->name, rd, imm, ra, ea); 1321 1322 reg.r[rd] = getmem_b(ea); 1323 } 1324 1325 void 1326 lbzx(ulong ir) 1327 { 1328 ulong ea; 1329 int rb, ra, rd, upd; 1330 1331 getarrr(ir); 1332 ea = reg.r[rb]; 1333 upd = getxo(ir)==119; 1334 if(ra) { 1335 ea += reg.r[ra]; 1336 if(upd) 1337 reg.r[ra] = ea; 1338 if(trace) 1339 itrace("%s\tr%d,(r%d+r%d) ea=%lux", ci->name, rd, ra, rb, ea); 1340 } else { 1341 if(upd) 1342 undef(ir); 1343 if(trace) 1344 itrace("%s\tr%d,(r%d) ea=%lux", ci->name, rd, rb, ea); 1345 } 1346 1347 reg.r[rd] = getmem_b(ea); 1348 } 1349 1350 void 1351 stw(ulong ir) 1352 { 1353 ulong ea; 1354 int ra, rd, upd; 1355 long imm; 1356 1357 getairr(ir); 1358 ea = imm; 1359 upd = (ir&(1L<<26))!=0; 1360 if(ra) { 1361 ea += reg.r[ra]; 1362 if(upd) 1363 reg.r[ra] = ea; 1364 } else { 1365 if(upd) 1366 undef(ir); 1367 } 1368 if(trace) 1369 itrace("%s\tr%d,%ld(r%d) #%lux=#%lux (%ld)", 1370 ci->name, rd, imm, ra, ea, reg.r[rd], reg.r[rd]); 1371 putmem_w(ea, reg.r[rd]); 1372 1373 } 1374 1375 void 1376 stwx(ulong ir) 1377 { 1378 ulong ea; 1379 int ra, rd, upd, rb; 1380 1381 getarrr(ir); 1382 ea = reg.r[rb]; 1383 upd = getxo(ir)==183; 1384 if(ra) { 1385 ea += reg.r[ra]; 1386 if(upd) 1387 reg.r[ra] = ea; 1388 if(trace) 1389 itrace("%s\tr%d,(r%d+r%d) #%lux=#%lux (%ld)", 1390 ci->name, rd, ra, rb, ea, reg.r[rd], reg.r[rd]); 1391 } else { 1392 if(upd) 1393 undef(ir); 1394 if(trace) 1395 itrace("%s\tr%d,(r%d) #%lux=#%lux (%ld)", 1396 ci->name, rd, rb, ea, reg.r[rd], reg.r[rd]); 1397 } 1398 putmem_w(ea, reg.r[rd]); 1399 1400 } 1401 1402 void 1403 stwcx(ulong ir) 1404 { 1405 ulong ea; 1406 int ra, rd, rb; 1407 1408 if((ir & Rc) == 0) 1409 undef(ir); 1410 getarrr(ir); 1411 ea = reg.r[rb]; 1412 if(ra) { 1413 ea += reg.r[ra]; 1414 if(trace) 1415 itrace("%s\tr%d,(r%d+r%d) #%lux=#%lux (%ld)", 1416 ci->name, rd, ra, rb, ea, reg.r[rd], reg.r[rd]); 1417 } else { 1418 if(trace) 1419 itrace("%s\tr%d,(r%d) #%lux=#%lux (%ld)", 1420 ci->name, rd, rb, ea, reg.r[rd], reg.r[rd]); 1421 } 1422 putmem_w(ea, reg.r[rd]); /* assume a reservation exists; store succeeded */ 1423 setcr(0, 0); 1424 1425 } 1426 1427 void 1428 stb(ulong ir) 1429 { 1430 ulong ea; 1431 int ra, rd, upd, v; 1432 long imm; 1433 1434 getairr(ir); 1435 ea = imm; 1436 upd = (ir&(1L<<26))!=0; 1437 if(ra) { 1438 ea += reg.r[ra]; 1439 if(upd) 1440 reg.r[ra] = ea; 1441 } else { 1442 if(upd) 1443 undef(ir); 1444 } 1445 v = reg.r[rd] & 0xFF; 1446 if(trace) 1447 itrace("%s\tr%d,%ld(r%d) #%lux=#%lux (%ld)", 1448 ci->name, rd, imm, ra, ea, v, v); 1449 putmem_b(ea, v); 1450 } 1451 1452 void 1453 stbx(ulong ir) 1454 { 1455 ulong ea; 1456 int ra, rd, upd, rb, v; 1457 1458 getarrr(ir); 1459 ea = reg.r[rb]; 1460 upd = getxo(ir)==247; 1461 v = reg.r[rd] & 0xFF; 1462 if(ra) { 1463 ea += reg.r[ra]; 1464 if(upd) 1465 reg.r[ra] = ea; 1466 if(trace) 1467 itrace("%s\tr%d,(r%d+r%d) #%lux=#%lux (%ld)", 1468 ci->name, rd, ra, rb, ea, v, v); 1469 } else { 1470 if(upd) 1471 undef(ir); 1472 if(trace) 1473 itrace("%s\tr%d,(r%d) #%lux=#%lux (%ld)", 1474 ci->name, rd, rb, ea, v, v); 1475 } 1476 putmem_b(ea, v); 1477 1478 } 1479 1480 void 1481 lhz(ulong ir) 1482 { 1483 ulong ea; 1484 int imm, ra, rd, upd; 1485 1486 getairr(ir); 1487 ea = imm; 1488 upd = (ir&(1L<<26))!=0; 1489 if(ra) { 1490 ea += reg.r[ra]; 1491 if(upd) 1492 reg.r[ra] = ea; 1493 } else { 1494 if(upd) 1495 undef(ir); 1496 } 1497 if(trace) 1498 itrace("%s\tr%d,%ld(r%d) ea=%lux", ci->name, rd, imm, ra, ea); 1499 1500 reg.r[rd] = getmem_h(ea); 1501 } 1502 1503 void 1504 lhzx(ulong ir) 1505 { 1506 ulong ea; 1507 int rb, ra, rd, upd; 1508 1509 getarrr(ir); 1510 ea = reg.r[rb]; 1511 upd = getxo(ir)==311; 1512 if(ra) { 1513 ea += reg.r[ra]; 1514 if(upd) 1515 reg.r[ra] = ea; 1516 if(trace) 1517 itrace("%s\tr%d,(r%d+r%d) ea=%lux", ci->name, rd, ra, rb, ea); 1518 } else { 1519 if(upd) 1520 undef(ir); 1521 if(trace) 1522 itrace("%s\tr%d,(r%d) ea=%lux", ci->name, rd, rb, ea); 1523 } 1524 1525 reg.r[rd] = getmem_h(ea); 1526 } 1527 1528 void 1529 lha(ulong ir) 1530 { 1531 ulong ea; 1532 int imm, ra, rd, upd; 1533 1534 getairr(ir); 1535 ea = imm; 1536 upd = (ir&(1L<<26))!=0; 1537 if(ra) { 1538 ea += reg.r[ra]; 1539 if(upd) 1540 reg.r[ra] = ea; 1541 } else { 1542 if(upd) 1543 undef(ir); 1544 } 1545 if(trace) 1546 itrace("%s\tr%d,%ld(r%d) ea=%lux", ci->name, rd, imm, ra, ea); 1547 1548 reg.r[rd] = (short)getmem_h(ea); 1549 } 1550 1551 void 1552 lhax(ulong ir) 1553 { 1554 ulong ea; 1555 int rb, ra, rd, upd; 1556 1557 getarrr(ir); 1558 ea = reg.r[rb]; 1559 upd = getxo(ir)==311; 1560 if(ra) { 1561 ea += reg.r[ra]; 1562 if(upd) 1563 reg.r[ra] = ea; 1564 if(trace) 1565 itrace("%s\tr%d,(r%d+r%d) ea=%lux", ci->name, rd, ra, rb, ea); 1566 } else { 1567 if(upd) 1568 undef(ir); 1569 if(trace) 1570 itrace("%s\tr%d,(r%d) ea=%lux", ci->name, rd, rb, ea); 1571 } 1572 1573 reg.r[rd] = (short)getmem_h(ea); 1574 } 1575 1576 void 1577 lhbrx(ulong ir) 1578 { 1579 ulong ea; 1580 int rb, ra, rd; 1581 ulong v; 1582 1583 getarrr(ir); 1584 ea = reg.r[rb]; 1585 if(ra) { 1586 ea += reg.r[ra]; 1587 if(trace) 1588 itrace("%s\tr%d,(r%d+r%d) ea=%lux", ci->name, rd, ra, rb, ea); 1589 } else { 1590 if(trace) 1591 itrace("%s\tr%d,(r%d) ea=%lux", ci->name, rd, rb, ea); 1592 } 1593 v = getmem_h(ea); 1594 1595 reg.r[rd] = ((v&0xFF)<<8)|(v&0xFF); 1596 } 1597 1598 void 1599 sth(ulong ir) 1600 { 1601 ulong ea; 1602 int imm, ra, rd, upd, v; 1603 1604 getairr(ir); 1605 ea = imm; 1606 upd = (ir&(1L<<26))!=0; 1607 if(ra) { 1608 ea += reg.r[ra]; 1609 if(upd) 1610 reg.r[ra] = ea; 1611 } else { 1612 if(upd) 1613 undef(ir); 1614 } 1615 v = reg.r[rd] & 0xFFFF; 1616 if(trace) 1617 itrace("%s\tr%d,%ld(r%d) #%lux=#%lux (%ld)", 1618 ci->name, rd, imm, ra, ea, v, v); 1619 putmem_h(ea, v); 1620 1621 } 1622 1623 void 1624 sthx(ulong ir) 1625 { 1626 ulong ea; 1627 int ra, rd, upd, rb, v; 1628 1629 getarrr(ir); 1630 ea = reg.r[rb]; 1631 upd = getxo(ir)==247; 1632 v = reg.r[rd] & 0xFFFF; 1633 if(ra) { 1634 ea += reg.r[ra]; 1635 if(upd) 1636 reg.r[ra] = ea; 1637 if(trace) 1638 itrace("%s\tr%d,(r%d+r%d) #%lux=#%lux (%ld)", 1639 ci->name, rd, ra, rb, ea, v, v); 1640 } else { 1641 if(upd) 1642 undef(ir); 1643 if(trace) 1644 itrace("%s\tr%d,(r%d) #%lux=#%lux (%ld)", 1645 ci->name, rd, rb, ea, v, v); 1646 } 1647 putmem_h(ea, v); 1648 } 1649 1650 void 1651 sthbrx(ulong ir) 1652 { 1653 ulong ea; 1654 int ra, rd, rb; 1655 ulong v; 1656 1657 getarrr(ir); 1658 ea = reg.r[rb]; 1659 v = reg.r[rd]; 1660 v = ((v&0xFF)<<8)|(v&0xFF); 1661 if(ra) { 1662 ea += reg.r[ra]; 1663 if(trace) 1664 itrace("%s\tr%d,(r%d+r%d) #%lux=#%lux (%ld)", 1665 ci->name, rd, ra, rb, ea, v, v); 1666 } else { 1667 if(trace) 1668 itrace("%s\tr%d,(r%d) #%lux=#%lux (%ld)", 1669 ci->name, rd, rb, ea, v, v); 1670 } 1671 putmem_h(ea, v); 1672 } 1673 1674 void 1675 lwbrx(ulong ir) 1676 { 1677 ulong ea; 1678 int rb, ra, rd, i; 1679 ulong v; 1680 1681 getarrr(ir); 1682 if(ir & Rc) 1683 undef(ir); 1684 ea = reg.r[rb]; 1685 if(ra) { 1686 ea += reg.r[ra]; 1687 if(trace) 1688 itrace("%s\tr%d,(r%d+r%d) ea=%lux", ci->name, rd, ra, rb, ea); 1689 } else { 1690 if(trace) 1691 itrace("%s\tr%d,(r%d) ea=%lux", ci->name, rd, rb, ea); 1692 } 1693 v = 0; 1694 for(i = 0; i < 4; i++) 1695 v = v>>8 | getmem_b(ea++); /* assume unaligned load is allowed */ 1696 reg.r[rd] = v; 1697 } 1698 1699 void 1700 stwbrx(ulong ir) 1701 { 1702 ulong ea; 1703 int rb, ra, rd, i; 1704 ulong v; 1705 1706 getarrr(ir); 1707 if(ir & Rc) 1708 undef(ir); 1709 ea = reg.r[rb]; 1710 if(ra) { 1711 ea += reg.r[ra]; 1712 if(trace) 1713 itrace("%s\tr%d,(r%d+r%d) ea=%lux", ci->name, rd, ra, rb, ea); 1714 } else { 1715 if(trace) 1716 itrace("%s\tr%d,(r%d) ea=%lux", ci->name, rd, rb, ea); 1717 } 1718 v = 0; 1719 for(i = 0; i < 4; i++) { 1720 putmem_b(ea++, v & 0xFF); /* assume unaligned store is allowed */ 1721 v >>= 8; 1722 } 1723 } 1724 1725 void 1726 lswi(ulong ir) 1727 { 1728 ulong ea; 1729 int rb, ra, rd, n, i, r, b; 1730 1731 getarrr(ir); 1732 if(ir & Rc) 1733 undef(ir); 1734 n = rb; 1735 if(n == 0) 1736 n = 32; 1737 ea = 0; 1738 if(ra) { 1739 ea += reg.r[ra]; 1740 if(trace) 1741 itrace("%s\tr%d,(r%d),%d ea=%lux", ci->name, rd, ra, n, ea); 1742 } else { 1743 if(trace) 1744 itrace("%s\tr%d,(0),%d ea=0", ci->name, rd, n); 1745 } 1746 i = -1; 1747 r = rd-1; 1748 while(--n >= 0) { 1749 if(i < 0) { 1750 r = (r+1)&0x1F; 1751 if(ra == 0 || r != ra) 1752 reg.r[r] = 0; 1753 i = 24; 1754 } 1755 b = getmem_b(ea++); 1756 if(ra == 0 || r != ra) 1757 reg.r[r] = (reg.r[r] & ~(0xFF<<i)) | (b << i); 1758 i -= 8; 1759 } 1760 } 1761 1762 void 1763 lswx(ulong ir) 1764 { 1765 ulong ea; 1766 int rb, ra, rd, n, i, r, b; 1767 1768 getarrr(ir); 1769 if(ir & Rc) 1770 undef(ir); 1771 n = reg.xer & 0x7F; 1772 ea = reg.r[rb]; 1773 if(ra) { 1774 ea += reg.r[ra]; 1775 if(trace) 1776 itrace("%s\tr%d,(r%d+r%d) ea=%lux n=%d", ci->name, rd, ra, rb, ea, n); 1777 } else { 1778 if(trace) 1779 itrace("%s\tr%d,(r%d) ea=%lux n=%d", ci->name, rd, rb, ea, n); 1780 } 1781 i = -1; 1782 r = rd-1; 1783 while(--n >= 0) { 1784 if(i < 0) { 1785 r = (r+1)&0x1F; 1786 if((ra == 0 || r != ra) && r != rb) 1787 reg.r[r] = 0; 1788 i = 24; 1789 } 1790 b = getmem_b(ea++); 1791 if((ra == 0 || r != ra) && r != rb) 1792 reg.r[r] = (reg.r[r] & ~(0xFF<<i)) | (b << i); 1793 i -= 8; 1794 } 1795 } 1796 1797 void 1798 stswx(ulong ir) 1799 { 1800 ulong ea; 1801 int rb, ra, rd, n, i, r; 1802 1803 getarrr(ir); 1804 if(ir & Rc) 1805 undef(ir); 1806 n = reg.xer & 0x7F; 1807 ea = reg.r[rb]; 1808 if(ra) { 1809 ea += reg.r[ra]; 1810 if(trace) 1811 itrace("%s\tr%d,(r%d+r%d) ea=%lux n=%d", ci->name, rd, ra, rb, ea, n); 1812 } else { 1813 if(trace) 1814 itrace("%s\tr%d,(r%d) ea=%lux n=%d", ci->name, rd, rb, ea, n); 1815 } 1816 i = -1; 1817 r = rd-1; 1818 while(--n >= 0) { 1819 if(i < 0) { 1820 r = (r+1)&0x1F; 1821 i = 24; 1822 } 1823 putmem_b(ea++, (reg.r[r]>>i)&0xFF); 1824 i -= 8; 1825 } 1826 } 1827 1828 void 1829 stswi(ulong ir) 1830 { 1831 ulong ea; 1832 int rb, ra, rd, n, i, r; 1833 1834 getarrr(ir); 1835 if(ir & Rc) 1836 undef(ir); 1837 n = rb; 1838 if(n == 0) 1839 n = 32; 1840 ea = 0; 1841 if(ra) { 1842 ea += reg.r[ra]; 1843 if(trace) 1844 itrace("%s\tr%d,(r%d),%d ea=%lux", ci->name, rd, ra, n, ea); 1845 } else { 1846 if(trace) 1847 itrace("%s\tr%d,(0),%d ea=0", ci->name, rd, n); 1848 } 1849 i = -1; 1850 r = rd-1; 1851 while(--n >= 0) { 1852 if(i < 0) { 1853 r = (r+1)&0x1F; 1854 i = 24; 1855 } 1856 putmem_b(ea++, (reg.r[r]>>i)&0xFF); 1857 i -= 8; 1858 } 1859 } 1860 1861 void 1862 lmw(ulong ir) 1863 { 1864 ulong ea; 1865 int ra, rd, r; 1866 long imm; 1867 1868 getairr(ir); 1869 ea = imm; 1870 if(ra) 1871 ea += reg.r[ra]; 1872 if(trace) 1873 itrace("%s\tr%d,%ld(r%d) ea=%lux", ci->name, rd, imm, ra, ea); 1874 1875 for(r = rd; r <= 31; r++) { 1876 if(r != 0 && r != rd) 1877 reg.r[rd] = getmem_w(ea); 1878 ea += 4; 1879 } 1880 } 1881 1882 void 1883 stmw(ulong ir) 1884 { 1885 ulong ea; 1886 int ra, rd, r; 1887 long imm; 1888 1889 getairr(ir); 1890 ea = imm; 1891 if(ra) 1892 ea += reg.r[ra]; 1893 if(trace) 1894 itrace("%s\tr%d,%ld(r%d) ea=%lux", ci->name, rd, imm, ra, ea); 1895 1896 for(r = rd; r <= 31; r++) { 1897 putmem_w(ea, reg.r[rd]); 1898 ea += 4; 1899 } 1900 } 1901 1902 void 1903 twi(ulong ir) 1904 { 1905 int rd, ra; 1906 long a, imm; 1907 1908 getairr(ir); 1909 a = reg.r[ra]; 1910 if(trace) 1911 itrace("twi\t#%.2x,r%d,$0x%lux (%ld)", rd, ra, imm, imm); 1912 if(a < imm && rd&0x10 || 1913 a > imm && rd&0x08 || 1914 a == imm && rd&0x04 || 1915 (ulong)a < imm && rd&0x02 || 1916 (ulong)a > imm && rd&0x01) { 1917 Bprint(bioout, "program_exception (trap type)\n"); 1918 longjmp(errjmp, 0); 1919 } 1920 } 1921 1922 void 1923 tw(ulong ir) 1924 { 1925 int rd, ra, rb; 1926 long a, b; 1927 1928 getarrr(ir); 1929 a = reg.r[ra]; 1930 b = reg.r[rb]; 1931 if(trace) 1932 itrace("tw\t#%.2x,r%d,r%d", rd, ra, rb); 1933 if(a < b && rd&0x10 || 1934 a > b && rd&0x08 || 1935 a == b && rd&0x04 || 1936 (ulong)a < b && rd&0x02 || 1937 (ulong)a > b && rd&0x01) { 1938 Bprint(bioout, "program_exception (trap type)\n"); 1939 longjmp(errjmp, 0); 1940 } 1941 } 1942 1943 void 1944 sync(ulong ir) 1945 { 1946 USED(ir); 1947 if(trace) 1948 itrace("sync"); 1949 } 1950 1951 void 1952 icbi(ulong ir) 1953 { 1954 int rd, ra, rb; 1955 1956 if(ir & Rc) 1957 undef(ir); 1958 getarrr(ir); 1959 USED(rd); 1960 if(trace) 1961 itrace("%s\tr%d,r%d", ci->name, ra, rb); 1962 } 1963 1964 void 1965 dcbf(ulong ir) 1966 { 1967 int rd, ra, rb; 1968 1969 if(ir & Rc) 1970 undef(ir); 1971 getarrr(ir); 1972 USED(rd); 1973 if(trace) 1974 itrace("%s\tr%d,r%d", ci->name, ra, rb); 1975 } 1976 1977 void 1978 dcbst(ulong ir) 1979 { 1980 int rd, ra, rb; 1981 1982 if(ir & Rc) 1983 undef(ir); 1984 getarrr(ir); 1985 USED(rd); 1986 if(trace) 1987 itrace("%s\tr%d,r%d", ci->name, ra, rb); 1988 } 1989 1990 void 1991 dcbt(ulong ir) 1992 { 1993 int rd, ra, rb; 1994 1995 if(ir & Rc) 1996 undef(ir); 1997 getarrr(ir); 1998 USED(rd); 1999 if(trace) 2000 itrace("%s\tr%d,r%d", ci->name, ra, rb); 2001 } 2002 2003 void 2004 dcbtst(ulong ir) 2005 { 2006 int rd, ra, rb; 2007 2008 if(ir & Rc) 2009 undef(ir); 2010 getarrr(ir); 2011 USED(rd); 2012 if(trace) 2013 itrace("%s\tr%d,r%d", ci->name, ra, rb); 2014 } 2015 2016 void 2017 dcbz(ulong ir) 2018 { 2019 int rd, ra, rb; 2020 2021 if(ir & Rc) 2022 undef(ir); 2023 getarrr(ir); 2024 USED(rd); 2025 if(trace) 2026 itrace("%s\tr%d,r%d", ci->name, ra, rb); 2027 } 2028