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