Revision c570fd16 target-mips/op.c
b/target-mips/op.c | ||
---|---|---|
140 | 140 |
#include "op_template.c" |
141 | 141 |
#undef REG |
142 | 142 |
|
143 |
#define TN T0 |
|
144 |
#include "op_template.c" |
|
145 |
#undef TN |
|
146 |
#define TN T1 |
|
147 |
#include "op_template.c" |
|
148 |
#undef TN |
|
149 |
#define TN T2 |
|
143 |
#define TN |
|
150 | 144 |
#include "op_template.c" |
151 | 145 |
#undef TN |
152 | 146 |
|
... | ... | |
334 | 328 |
/* Arithmetic */ |
335 | 329 |
void op_add (void) |
336 | 330 |
{ |
337 |
T0 += T1;
|
|
331 |
T0 = SIGN_EXTEND32((int32_t)T0 + (int32_t)T1);
|
|
338 | 332 |
RETURN(); |
339 | 333 |
} |
340 | 334 |
|
... | ... | |
342 | 336 |
{ |
343 | 337 |
target_ulong tmp; |
344 | 338 |
|
345 |
tmp = T0; |
|
346 |
T0 += T1;
|
|
339 |
tmp = (int32_t)T0;
|
|
340 |
T0 = (int32_t)T0 + (int32_t)T1;
|
|
347 | 341 |
if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 31) { |
348 |
/* operands of same sign, result different sign */ |
|
342 |
/* operands of same sign, result different sign */
|
|
349 | 343 |
CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW); |
350 | 344 |
} |
345 |
T0 = SIGN_EXTEND32(T0); |
|
351 | 346 |
RETURN(); |
352 | 347 |
} |
353 | 348 |
|
354 | 349 |
void op_sub (void) |
355 | 350 |
{ |
356 |
T0 -= T1;
|
|
351 |
T0 = SIGN_EXTEND32((int32_t)T0 - (int32_t)T1);
|
|
357 | 352 |
RETURN(); |
358 | 353 |
} |
359 | 354 |
|
... | ... | |
361 | 356 |
{ |
362 | 357 |
target_ulong tmp; |
363 | 358 |
|
364 |
tmp = T0; |
|
359 |
tmp = (int32_t)T0;
|
|
365 | 360 |
T0 = (int32_t)T0 - (int32_t)T1; |
366 | 361 |
if (((tmp ^ T1) & (tmp ^ T0)) >> 31) { |
367 |
/* operands of different sign, first operand and result different sign */ |
|
362 |
/* operands of different sign, first operand and result different sign */
|
|
368 | 363 |
CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW); |
369 | 364 |
} |
365 |
T0 = SIGN_EXTEND32(T0); |
|
370 | 366 |
RETURN(); |
371 | 367 |
} |
372 | 368 |
|
373 | 369 |
void op_mul (void) |
374 | 370 |
{ |
375 |
T0 = (int32_t)T0 * (int32_t)T1;
|
|
371 |
T0 = SIGN_EXTEND32((int32_t)T0 * (int32_t)T1);
|
|
376 | 372 |
RETURN(); |
377 | 373 |
} |
378 | 374 |
|
379 | 375 |
void op_div (void) |
380 | 376 |
{ |
381 | 377 |
if (T1 != 0) { |
382 |
env->LO = (int32_t)T0 / (int32_t)T1;
|
|
383 |
env->HI = (int32_t)T0 % (int32_t)T1;
|
|
378 |
env->LO = SIGN_EXTEND32((int32_t)T0 / (int32_t)T1);
|
|
379 |
env->HI = SIGN_EXTEND32((int32_t)T0 % (int32_t)T1);
|
|
384 | 380 |
} |
385 | 381 |
RETURN(); |
386 | 382 |
} |
... | ... | |
388 | 384 |
void op_divu (void) |
389 | 385 |
{ |
390 | 386 |
if (T1 != 0) { |
387 |
env->LO = SIGN_EXTEND32((uint32_t)T0 / (uint32_t)T1); |
|
388 |
env->HI = SIGN_EXTEND32((uint32_t)T0 % (uint32_t)T1); |
|
389 |
} |
|
390 |
RETURN(); |
|
391 |
} |
|
392 |
|
|
393 |
#ifdef MIPS_HAS_MIPS64 |
|
394 |
/* Arithmetic */ |
|
395 |
void op_dadd (void) |
|
396 |
{ |
|
397 |
T0 += T1; |
|
398 |
RETURN(); |
|
399 |
} |
|
400 |
|
|
401 |
void op_daddo (void) |
|
402 |
{ |
|
403 |
target_long tmp; |
|
404 |
|
|
405 |
tmp = T0; |
|
406 |
T0 += T1; |
|
407 |
if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 63) { |
|
408 |
/* operands of same sign, result different sign */ |
|
409 |
CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW); |
|
410 |
} |
|
411 |
RETURN(); |
|
412 |
} |
|
413 |
|
|
414 |
void op_dsub (void) |
|
415 |
{ |
|
416 |
T0 -= T1; |
|
417 |
RETURN(); |
|
418 |
} |
|
419 |
|
|
420 |
void op_dsubo (void) |
|
421 |
{ |
|
422 |
target_long tmp; |
|
423 |
|
|
424 |
tmp = T0; |
|
425 |
T0 = (int64_t)T0 - (int64_t)T1; |
|
426 |
if (((tmp ^ T1) & (tmp ^ T0)) >> 63) { |
|
427 |
/* operands of different sign, first operand and result different sign */ |
|
428 |
CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW); |
|
429 |
} |
|
430 |
RETURN(); |
|
431 |
} |
|
432 |
|
|
433 |
void op_dmul (void) |
|
434 |
{ |
|
435 |
T0 = (int64_t)T0 * (int64_t)T1; |
|
436 |
RETURN(); |
|
437 |
} |
|
438 |
|
|
439 |
#if TARGET_LONG_BITS > HOST_LONG_BITS |
|
440 |
/* Those might call libgcc functions. */ |
|
441 |
void op_ddiv (void) |
|
442 |
{ |
|
443 |
do_ddiv(); |
|
444 |
RETURN(); |
|
445 |
} |
|
446 |
|
|
447 |
void op_ddivu (void) |
|
448 |
{ |
|
449 |
do_ddivu(); |
|
450 |
RETURN(); |
|
451 |
} |
|
452 |
#else |
|
453 |
void op_ddiv (void) |
|
454 |
{ |
|
455 |
if (T1 != 0) { |
|
456 |
env->LO = (int64_t)T0 / (int64_t)T1; |
|
457 |
env->HI = (int64_t)T0 % (int64_t)T1; |
|
458 |
} |
|
459 |
RETURN(); |
|
460 |
} |
|
461 |
|
|
462 |
void op_ddivu (void) |
|
463 |
{ |
|
464 |
if (T1 != 0) { |
|
391 | 465 |
env->LO = T0 / T1; |
392 | 466 |
env->HI = T0 % T1; |
393 | 467 |
} |
394 | 468 |
RETURN(); |
395 | 469 |
} |
470 |
#endif |
|
471 |
#endif /* MIPS_HAS_MIPS64 */ |
|
396 | 472 |
|
397 | 473 |
/* Logical */ |
398 | 474 |
void op_and (void) |
... | ... | |
421 | 497 |
|
422 | 498 |
void op_sll (void) |
423 | 499 |
{ |
424 |
T0 = T0 << T1;
|
|
500 |
T0 = SIGN_EXTEND32((uint32_t)T0 << (uint32_t)T1);
|
|
425 | 501 |
RETURN(); |
426 | 502 |
} |
427 | 503 |
|
428 | 504 |
void op_sra (void) |
429 | 505 |
{ |
430 |
T0 = (int32_t)T0 >> T1;
|
|
506 |
T0 = SIGN_EXTEND32((int32_t)T0 >> (uint32_t)T1);
|
|
431 | 507 |
RETURN(); |
432 | 508 |
} |
433 | 509 |
|
434 | 510 |
void op_srl (void) |
435 | 511 |
{ |
436 |
T0 = T0 >> T1;
|
|
512 |
T0 = SIGN_EXTEND32((uint32_t)T0 >> (uint32_t)T1);
|
|
437 | 513 |
RETURN(); |
438 | 514 |
} |
439 | 515 |
|
... | ... | |
442 | 518 |
target_ulong tmp; |
443 | 519 |
|
444 | 520 |
if (T1) { |
445 |
tmp = T0 << (0x20 - T1);
|
|
446 |
T0 = (T0 >> T1) | tmp;
|
|
521 |
tmp = SIGN_EXTEND32((uint32_t)T0 << (0x20 - (uint32_t)T1));
|
|
522 |
T0 = SIGN_EXTEND32((uint32_t)T0 >> (uint32_t)T1) | tmp;
|
|
447 | 523 |
} else |
448 | 524 |
T0 = T1; |
449 | 525 |
RETURN(); |
... | ... | |
451 | 527 |
|
452 | 528 |
void op_sllv (void) |
453 | 529 |
{ |
454 |
T0 = T1 << (T0 & 0x1F);
|
|
530 |
T0 = SIGN_EXTEND32((uint32_t)T1 << ((uint32_t)T0 & 0x1F));
|
|
455 | 531 |
RETURN(); |
456 | 532 |
} |
457 | 533 |
|
458 | 534 |
void op_srav (void) |
459 | 535 |
{ |
460 |
T0 = (int32_t)T1 >> (T0 & 0x1F);
|
|
536 |
T0 = SIGN_EXTEND32((int32_t)T1 >> (T0 & 0x1F));
|
|
461 | 537 |
RETURN(); |
462 | 538 |
} |
463 | 539 |
|
464 | 540 |
void op_srlv (void) |
465 | 541 |
{ |
466 |
T0 = T1 >> (T0 & 0x1F);
|
|
542 |
T0 = SIGN_EXTEND32((uint32_t)T1 >> (T0 & 0x1F));
|
|
467 | 543 |
RETURN(); |
468 | 544 |
} |
469 | 545 |
|
... | ... | |
473 | 549 |
|
474 | 550 |
T0 &= 0x1F; |
475 | 551 |
if (T0) { |
476 |
tmp = T1 << (0x20 - T0);
|
|
477 |
T0 = (T1 >> T0) | tmp;
|
|
552 |
tmp = SIGN_EXTEND32((uint32_t)T1 << (0x20 - T0));
|
|
553 |
T0 = SIGN_EXTEND32((uint32_t)T1 >> T0) | tmp;
|
|
478 | 554 |
} else |
479 | 555 |
T0 = T1; |
480 | 556 |
RETURN(); |
... | ... | |
484 | 560 |
{ |
485 | 561 |
int n; |
486 | 562 |
|
487 |
if (T0 == (target_ulong)-1) {
|
|
563 |
if (T0 == ~((target_ulong)0)) {
|
|
488 | 564 |
T0 = 32; |
489 | 565 |
} else { |
490 | 566 |
for (n = 0; n < 32; n++) { |
... | ... | |
514 | 590 |
RETURN(); |
515 | 591 |
} |
516 | 592 |
|
517 |
/* 64 bits arithmetic */ |
|
518 |
#if (HOST_LONG_BITS == 64) |
|
519 |
static inline uint64_t get_HILO (void) |
|
593 |
#ifdef MIPS_HAS_MIPS64 |
|
594 |
|
|
595 |
#if TARGET_LONG_BITS > HOST_LONG_BITS |
|
596 |
/* Those might call libgcc functions. */ |
|
597 |
void op_dsll (void) |
|
520 | 598 |
{ |
521 |
return ((uint64_t)env->HI << 32) | (uint64_t)env->LO; |
|
599 |
CALL_FROM_TB0(do_dsll); |
|
600 |
RETURN(); |
|
522 | 601 |
} |
523 | 602 |
|
524 |
static inline void set_HILO (uint64_t HILO)
|
|
603 |
void op_dsll32 (void)
|
|
525 | 604 |
{ |
526 |
env->LO = HILO & 0xFFFFFFFF;
|
|
527 |
env->HI = HILO >> 32;
|
|
605 |
CALL_FROM_TB0(do_dsll32);
|
|
606 |
RETURN();
|
|
528 | 607 |
} |
529 | 608 |
|
530 |
void op_mult (void)
|
|
609 |
void op_dsra (void)
|
|
531 | 610 |
{ |
532 |
set_HILO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
|
|
611 |
CALL_FROM_TB0(do_dsra);
|
|
533 | 612 |
RETURN(); |
534 | 613 |
} |
535 | 614 |
|
536 |
void op_multu (void)
|
|
615 |
void op_dsra32 (void)
|
|
537 | 616 |
{ |
538 |
set_HILO((uint64_t)T0 * (uint64_t)T1);
|
|
617 |
CALL_FROM_TB0(do_dsra32);
|
|
539 | 618 |
RETURN(); |
540 | 619 |
} |
541 | 620 |
|
542 |
void op_madd (void)
|
|
621 |
void op_dsrl (void)
|
|
543 | 622 |
{ |
544 |
int64_t tmp; |
|
623 |
CALL_FROM_TB0(do_dsrl); |
|
624 |
RETURN(); |
|
625 |
} |
|
545 | 626 |
|
546 |
tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1); |
|
547 |
set_HILO((int64_t)get_HILO() + tmp); |
|
627 |
void op_dsrl32 (void) |
|
628 |
{ |
|
629 |
CALL_FROM_TB0(do_dsrl32); |
|
548 | 630 |
RETURN(); |
549 | 631 |
} |
550 | 632 |
|
551 |
void op_maddu (void)
|
|
633 |
void op_drotr (void)
|
|
552 | 634 |
{ |
553 |
uint64_t tmp; |
|
635 |
CALL_FROM_TB0(do_drotr); |
|
636 |
RETURN(); |
|
637 |
} |
|
554 | 638 |
|
555 |
tmp = ((uint64_t)T0 * (uint64_t)T1); |
|
556 |
set_HILO(get_HILO() + tmp); |
|
639 |
void op_drotr32 (void) |
|
640 |
{ |
|
641 |
CALL_FROM_TB0(do_drotr32); |
|
557 | 642 |
RETURN(); |
558 | 643 |
} |
559 | 644 |
|
560 |
void op_msub (void)
|
|
645 |
void op_dsllv (void)
|
|
561 | 646 |
{ |
562 |
int64_t tmp; |
|
647 |
CALL_FROM_TB0(do_dsllv); |
|
648 |
RETURN(); |
|
649 |
} |
|
563 | 650 |
|
564 |
tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1); |
|
565 |
set_HILO((int64_t)get_HILO() - tmp); |
|
651 |
void op_dsrav (void) |
|
652 |
{ |
|
653 |
CALL_FROM_TB0(do_dsrav); |
|
566 | 654 |
RETURN(); |
567 | 655 |
} |
568 | 656 |
|
569 |
void op_msubu (void)
|
|
657 |
void op_dsrlv (void)
|
|
570 | 658 |
{ |
571 |
uint64_t tmp; |
|
659 |
CALL_FROM_TB0(do_dsrlv); |
|
660 |
RETURN(); |
|
661 |
} |
|
572 | 662 |
|
573 |
tmp = ((uint64_t)T0 * (uint64_t)T1); |
|
574 |
set_HILO(get_HILO() - tmp); |
|
663 |
void op_drotrv (void) |
|
664 |
{ |
|
665 |
CALL_FROM_TB0(do_drotrv); |
|
575 | 666 |
RETURN(); |
576 | 667 |
} |
577 |
#else |
|
668 |
|
|
669 |
#else /* TARGET_LONG_BITS > HOST_LONG_BITS */ |
|
670 |
|
|
671 |
void op_dsll (void) |
|
672 |
{ |
|
673 |
T0 = T0 << T1; |
|
674 |
RETURN(); |
|
675 |
} |
|
676 |
|
|
677 |
void op_dsll32 (void) |
|
678 |
{ |
|
679 |
T0 = T0 << (T1 + 32); |
|
680 |
RETURN(); |
|
681 |
} |
|
682 |
|
|
683 |
void op_dsra (void) |
|
684 |
{ |
|
685 |
T0 = (int64_t)T0 >> T1; |
|
686 |
RETURN(); |
|
687 |
} |
|
688 |
|
|
689 |
void op_dsra32 (void) |
|
690 |
{ |
|
691 |
T0 = (int64_t)T0 >> (T1 + 32); |
|
692 |
RETURN(); |
|
693 |
} |
|
694 |
|
|
695 |
void op_dsrl (void) |
|
696 |
{ |
|
697 |
T0 = T0 >> T1; |
|
698 |
RETURN(); |
|
699 |
} |
|
700 |
|
|
701 |
void op_dsrl32 (void) |
|
702 |
{ |
|
703 |
T0 = T0 >> (T1 + 32); |
|
704 |
RETURN(); |
|
705 |
} |
|
706 |
|
|
707 |
void op_drotr (void) |
|
708 |
{ |
|
709 |
target_ulong tmp; |
|
710 |
|
|
711 |
if (T1) { |
|
712 |
tmp = T0 << (0x40 - T1); |
|
713 |
T0 = (T0 >> T1) | tmp; |
|
714 |
} else |
|
715 |
T0 = T1; |
|
716 |
RETURN(); |
|
717 |
} |
|
718 |
|
|
719 |
void op_drotr32 (void) |
|
720 |
{ |
|
721 |
target_ulong tmp; |
|
722 |
|
|
723 |
if (T1) { |
|
724 |
tmp = T0 << (0x40 - (32 + T1)); |
|
725 |
T0 = (T0 >> (32 + T1)) | tmp; |
|
726 |
} else |
|
727 |
T0 = T1; |
|
728 |
RETURN(); |
|
729 |
} |
|
730 |
|
|
731 |
void op_dsllv (void) |
|
732 |
{ |
|
733 |
T0 = T1 << (T0 & 0x3F); |
|
734 |
RETURN(); |
|
735 |
} |
|
736 |
|
|
737 |
void op_dsrav (void) |
|
738 |
{ |
|
739 |
T0 = (int64_t)T1 >> (T0 & 0x3F); |
|
740 |
RETURN(); |
|
741 |
} |
|
742 |
|
|
743 |
void op_dsrlv (void) |
|
744 |
{ |
|
745 |
T0 = T1 >> (T0 & 0x3F); |
|
746 |
RETURN(); |
|
747 |
} |
|
748 |
|
|
749 |
void op_drotrv (void) |
|
750 |
{ |
|
751 |
target_ulong tmp; |
|
752 |
|
|
753 |
T0 &= 0x3F; |
|
754 |
if (T0) { |
|
755 |
tmp = T1 << (0x40 - T0); |
|
756 |
T0 = (T1 >> T0) | tmp; |
|
757 |
} else |
|
758 |
T0 = T1; |
|
759 |
RETURN(); |
|
760 |
} |
|
761 |
#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */ |
|
762 |
|
|
763 |
void op_dclo (void) |
|
764 |
{ |
|
765 |
int n; |
|
766 |
|
|
767 |
if (T0 == ~((target_ulong)0)) { |
|
768 |
T0 = 64; |
|
769 |
} else { |
|
770 |
for (n = 0; n < 64; n++) { |
|
771 |
if (!(T0 & (1ULL << 63))) |
|
772 |
break; |
|
773 |
T0 = T0 << 1; |
|
774 |
} |
|
775 |
T0 = n; |
|
776 |
} |
|
777 |
RETURN(); |
|
778 |
} |
|
779 |
|
|
780 |
void op_dclz (void) |
|
781 |
{ |
|
782 |
int n; |
|
783 |
|
|
784 |
if (T0 == 0) { |
|
785 |
T0 = 64; |
|
786 |
} else { |
|
787 |
for (n = 0; n < 64; n++) { |
|
788 |
if (T0 & (1ULL << 63)) |
|
789 |
break; |
|
790 |
T0 = T0 << 1; |
|
791 |
} |
|
792 |
T0 = n; |
|
793 |
} |
|
794 |
RETURN(); |
|
795 |
} |
|
796 |
#endif |
|
797 |
|
|
798 |
/* 64 bits arithmetic */ |
|
799 |
#if TARGET_LONG_BITS > HOST_LONG_BITS |
|
578 | 800 |
void op_mult (void) |
579 | 801 |
{ |
580 | 802 |
CALL_FROM_TB0(do_mult); |
... | ... | |
610 | 832 |
CALL_FROM_TB0(do_msubu); |
611 | 833 |
RETURN(); |
612 | 834 |
} |
835 |
|
|
836 |
#else /* TARGET_LONG_BITS > HOST_LONG_BITS */ |
|
837 |
|
|
838 |
static inline uint64_t get_HILO (void) |
|
839 |
{ |
|
840 |
return ((uint64_t)env->HI << 32) | ((uint64_t)(uint32_t)env->LO); |
|
841 |
} |
|
842 |
|
|
843 |
static inline void set_HILO (uint64_t HILO) |
|
844 |
{ |
|
845 |
env->LO = SIGN_EXTEND32(HILO & 0xFFFFFFFF); |
|
846 |
env->HI = SIGN_EXTEND32(HILO >> 32); |
|
847 |
} |
|
848 |
|
|
849 |
void op_mult (void) |
|
850 |
{ |
|
851 |
set_HILO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1); |
|
852 |
RETURN(); |
|
853 |
} |
|
854 |
|
|
855 |
void op_multu (void) |
|
856 |
{ |
|
857 |
set_HILO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1); |
|
858 |
RETURN(); |
|
859 |
} |
|
860 |
|
|
861 |
void op_madd (void) |
|
862 |
{ |
|
863 |
int64_t tmp; |
|
864 |
|
|
865 |
tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1); |
|
866 |
set_HILO((int64_t)get_HILO() + tmp); |
|
867 |
RETURN(); |
|
868 |
} |
|
869 |
|
|
870 |
void op_maddu (void) |
|
871 |
{ |
|
872 |
uint64_t tmp; |
|
873 |
|
|
874 |
tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1); |
|
875 |
set_HILO(get_HILO() + tmp); |
|
876 |
RETURN(); |
|
877 |
} |
|
878 |
|
|
879 |
void op_msub (void) |
|
880 |
{ |
|
881 |
int64_t tmp; |
|
882 |
|
|
883 |
tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1); |
|
884 |
set_HILO((int64_t)get_HILO() - tmp); |
|
885 |
RETURN(); |
|
886 |
} |
|
887 |
|
|
888 |
void op_msubu (void) |
|
889 |
{ |
|
890 |
uint64_t tmp; |
|
891 |
|
|
892 |
tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1); |
|
893 |
set_HILO(get_HILO() - tmp); |
|
894 |
RETURN(); |
|
895 |
} |
|
896 |
#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */ |
|
897 |
|
|
898 |
#ifdef MIPS_HAS_MIPS64 |
|
899 |
void op_dmult (void) |
|
900 |
{ |
|
901 |
CALL_FROM_TB0(do_dmult); |
|
902 |
RETURN(); |
|
903 |
} |
|
904 |
|
|
905 |
void op_dmultu (void) |
|
906 |
{ |
|
907 |
CALL_FROM_TB0(do_dmultu); |
|
908 |
RETURN(); |
|
909 |
} |
|
613 | 910 |
#endif |
614 | 911 |
|
615 | 912 |
/* Conditional moves */ |
... | ... | |
735 | 1032 |
/* CP0 functions */ |
736 | 1033 |
void op_mfc0_index (void) |
737 | 1034 |
{ |
738 |
T0 = env->CP0_index;
|
|
1035 |
T0 = SIGN_EXTEND32(env->CP0_index);
|
|
739 | 1036 |
RETURN(); |
740 | 1037 |
} |
741 | 1038 |
|
... | ... | |
765 | 1062 |
|
766 | 1063 |
void op_mfc0_pagemask (void) |
767 | 1064 |
{ |
768 |
T0 = env->CP0_PageMask;
|
|
1065 |
T0 = SIGN_EXTEND32(env->CP0_PageMask);
|
|
769 | 1066 |
RETURN(); |
770 | 1067 |
} |
771 | 1068 |
|
772 | 1069 |
void op_mfc0_pagegrain (void) |
773 | 1070 |
{ |
774 |
T0 = env->CP0_PageGrain;
|
|
1071 |
T0 = SIGN_EXTEND32(env->CP0_PageGrain);
|
|
775 | 1072 |
RETURN(); |
776 | 1073 |
} |
777 | 1074 |
|
778 | 1075 |
void op_mfc0_wired (void) |
779 | 1076 |
{ |
780 |
T0 = env->CP0_Wired;
|
|
1077 |
T0 = SIGN_EXTEND32(env->CP0_Wired);
|
|
781 | 1078 |
RETURN(); |
782 | 1079 |
} |
783 | 1080 |
|
784 | 1081 |
void op_mfc0_hwrena (void) |
785 | 1082 |
{ |
786 |
T0 = env->CP0_HWREna;
|
|
1083 |
T0 = SIGN_EXTEND32(env->CP0_HWREna);
|
|
787 | 1084 |
RETURN(); |
788 | 1085 |
} |
789 | 1086 |
|
... | ... | |
807 | 1104 |
|
808 | 1105 |
void op_mfc0_compare (void) |
809 | 1106 |
{ |
810 |
T0 = env->CP0_Compare;
|
|
1107 |
T0 = SIGN_EXTEND32(env->CP0_Compare);
|
|
811 | 1108 |
RETURN(); |
812 | 1109 |
} |
813 | 1110 |
|
814 | 1111 |
void op_mfc0_status (void) |
815 | 1112 |
{ |
816 |
T0 = env->CP0_Status;
|
|
1113 |
T0 = SIGN_EXTEND32(env->CP0_Status);
|
|
817 | 1114 |
if (env->hflags & MIPS_HFLAG_UM) |
818 | 1115 |
T0 |= (1 << CP0St_UM); |
819 | 1116 |
if (env->hflags & MIPS_HFLAG_ERL) |
... | ... | |
825 | 1122 |
|
826 | 1123 |
void op_mfc0_intctl (void) |
827 | 1124 |
{ |
828 |
T0 = env->CP0_IntCtl;
|
|
1125 |
T0 = SIGN_EXTEND32(env->CP0_IntCtl);
|
|
829 | 1126 |
RETURN(); |
830 | 1127 |
} |
831 | 1128 |
|
832 | 1129 |
void op_mfc0_srsctl (void) |
833 | 1130 |
{ |
834 |
T0 = env->CP0_SRSCtl;
|
|
1131 |
T0 = SIGN_EXTEND32(env->CP0_SRSCtl);
|
|
835 | 1132 |
RETURN(); |
836 | 1133 |
} |
837 | 1134 |
|
838 | 1135 |
void op_mfc0_cause (void) |
839 | 1136 |
{ |
840 |
T0 = env->CP0_Cause;
|
|
1137 |
T0 = SIGN_EXTEND32(env->CP0_Cause);
|
|
841 | 1138 |
RETURN(); |
842 | 1139 |
} |
843 | 1140 |
|
... | ... | |
849 | 1146 |
|
850 | 1147 |
void op_mfc0_prid (void) |
851 | 1148 |
{ |
852 |
T0 = env->CP0_PRid;
|
|
1149 |
T0 = SIGN_EXTEND32(env->CP0_PRid);
|
|
853 | 1150 |
RETURN(); |
854 | 1151 |
} |
855 | 1152 |
|
... | ... | |
861 | 1158 |
|
862 | 1159 |
void op_mfc0_config0 (void) |
863 | 1160 |
{ |
864 |
T0 = env->CP0_Config0;
|
|
1161 |
T0 = SIGN_EXTEND32(env->CP0_Config0);
|
|
865 | 1162 |
RETURN(); |
866 | 1163 |
} |
867 | 1164 |
|
868 | 1165 |
void op_mfc0_config1 (void) |
869 | 1166 |
{ |
870 |
T0 = env->CP0_Config1;
|
|
1167 |
T0 = SIGN_EXTEND32(env->CP0_Config1);
|
|
871 | 1168 |
RETURN(); |
872 | 1169 |
} |
873 | 1170 |
|
874 | 1171 |
void op_mfc0_config2 (void) |
875 | 1172 |
{ |
876 |
T0 = env->CP0_Config2;
|
|
1173 |
T0 = SIGN_EXTEND32(env->CP0_Config2);
|
|
877 | 1174 |
RETURN(); |
878 | 1175 |
} |
879 | 1176 |
|
880 | 1177 |
void op_mfc0_config3 (void) |
881 | 1178 |
{ |
882 |
T0 = env->CP0_Config3;
|
|
1179 |
T0 = SIGN_EXTEND32(env->CP0_Config3);
|
|
883 | 1180 |
RETURN(); |
884 | 1181 |
} |
885 | 1182 |
|
... | ... | |
891 | 1188 |
|
892 | 1189 |
void op_mfc0_watchlo0 (void) |
893 | 1190 |
{ |
894 |
T0 = env->CP0_WatchLo;
|
|
1191 |
T0 = SIGN_EXTEND32(env->CP0_WatchLo);
|
|
895 | 1192 |
RETURN(); |
896 | 1193 |
} |
897 | 1194 |
|
898 | 1195 |
void op_mfc0_watchhi0 (void) |
899 | 1196 |
{ |
900 |
T0 = env->CP0_WatchHi;
|
|
1197 |
T0 = SIGN_EXTEND32(env->CP0_WatchHi);
|
|
901 | 1198 |
RETURN(); |
902 | 1199 |
} |
903 | 1200 |
|
... | ... | |
915 | 1212 |
|
916 | 1213 |
void op_mfc0_debug (void) |
917 | 1214 |
{ |
918 |
T0 = env->CP0_Debug;
|
|
1215 |
T0 = SIGN_EXTEND32(env->CP0_Debug);
|
|
919 | 1216 |
if (env->hflags & MIPS_HFLAG_DM) |
920 | 1217 |
T0 |= 1 << CP0DB_DM; |
921 | 1218 |
RETURN(); |
... | ... | |
929 | 1226 |
|
930 | 1227 |
void op_mfc0_performance0 (void) |
931 | 1228 |
{ |
932 |
T0 = env->CP0_Performance0;
|
|
1229 |
T0 = SIGN_EXTEND32(env->CP0_Performance0);
|
|
933 | 1230 |
RETURN(); |
934 | 1231 |
} |
935 | 1232 |
|
936 | 1233 |
void op_mfc0_taglo (void) |
937 | 1234 |
{ |
938 |
T0 = env->CP0_TagLo;
|
|
1235 |
T0 = SIGN_EXTEND32(env->CP0_TagLo);
|
|
939 | 1236 |
RETURN(); |
940 | 1237 |
} |
941 | 1238 |
|
942 | 1239 |
void op_mfc0_datalo (void) |
943 | 1240 |
{ |
944 |
T0 = env->CP0_DataLo;
|
|
1241 |
T0 = SIGN_EXTEND32(env->CP0_DataLo);
|
|
945 | 1242 |
RETURN(); |
946 | 1243 |
} |
947 | 1244 |
|
948 | 1245 |
void op_mfc0_taghi (void) |
949 | 1246 |
{ |
950 |
T0 = env->CP0_TagHi;
|
|
1247 |
T0 = SIGN_EXTEND32(env->CP0_TagHi);
|
|
951 | 1248 |
RETURN(); |
952 | 1249 |
} |
953 | 1250 |
|
954 | 1251 |
void op_mfc0_datahi (void) |
955 | 1252 |
{ |
956 |
T0 = env->CP0_DataHi;
|
|
1253 |
T0 = SIGN_EXTEND32(env->CP0_DataHi);
|
|
957 | 1254 |
RETURN(); |
958 | 1255 |
} |
959 | 1256 |
|
... | ... | |
965 | 1262 |
|
966 | 1263 |
void op_mfc0_desave (void) |
967 | 1264 |
{ |
968 |
T0 = env->CP0_DESAVE;
|
|
1265 |
T0 = SIGN_EXTEND32(env->CP0_DESAVE);
|
|
969 | 1266 |
RETURN(); |
970 | 1267 |
} |
971 | 1268 |
|
... | ... | |
979 | 1276 |
{ |
980 | 1277 |
/* Large physaddr not implemented */ |
981 | 1278 |
/* 1k pages not implemented */ |
982 |
env->CP0_EntryLo0 = T0 & 0x3FFFFFFFUL;
|
|
1279 |
env->CP0_EntryLo0 = T0 & SIGN_EXTEND32(0x3FFFFFFFUL);
|
|
983 | 1280 |
RETURN(); |
984 | 1281 |
} |
985 | 1282 |
|
... | ... | |
987 | 1284 |
{ |
988 | 1285 |
/* Large physaddr not implemented */ |
989 | 1286 |
/* 1k pages not implemented */ |
990 |
env->CP0_EntryLo1 = T0 & 0x3FFFFFFFUL;
|
|
1287 |
env->CP0_EntryLo1 = T0 & SIGN_EXTEND32(0x3FFFFFFFUL);
|
|
991 | 1288 |
RETURN(); |
992 | 1289 |
} |
993 | 1290 |
|
... | ... | |
1037 | 1334 |
|
1038 | 1335 |
/* 1k pages not implemented */ |
1039 | 1336 |
/* Ignore MIPS64 TLB for now */ |
1040 |
val = T0 & 0xFFFFE0FF;
|
|
1337 |
val = T0 & SIGN_EXTEND32(0xFFFFE0FF);
|
|
1041 | 1338 |
old = env->CP0_EntryHi; |
1042 | 1339 |
env->CP0_EntryHi = val; |
1043 | 1340 |
/* If the ASID changes, flush qemu's TLB. */ |
... | ... | |
1056 | 1353 |
{ |
1057 | 1354 |
uint32_t val, old, mask; |
1058 | 1355 |
|
1059 |
val = T0 & 0xFA78FF01;
|
|
1356 |
val = T0 & SIGN_EXTEND32(0xFA78FF01);
|
|
1060 | 1357 |
old = env->CP0_Status; |
1061 | 1358 |
if (T0 & (1 << CP0St_UM)) |
1062 | 1359 |
env->hflags |= MIPS_HFLAG_UM; |
... | ... | |
1107 | 1404 |
{ |
1108 | 1405 |
uint32_t val, old; |
1109 | 1406 |
|
1110 |
val = (env->CP0_Cause & 0xB000F87C) | (T0 & 0x000C00300);
|
|
1407 |
val = (env->CP0_Cause & 0xB000F87C) | (T0 & 0x00C00300); |
|
1111 | 1408 |
old = env->CP0_Cause; |
1112 | 1409 |
env->CP0_Cause = val; |
1113 | 1410 |
#if 0 |
... | ... | |
1134 | 1431 |
{ |
1135 | 1432 |
/* vectored interrupts not implemented */ |
1136 | 1433 |
/* Multi-CPU not implemented */ |
1137 |
env->CP0_EBase = 0x80000000 | (T0 & 0x3FFFF000);
|
|
1434 |
env->CP0_EBase = SIGN_EXTEND32(0x80000000) | (T0 & 0x3FFFF000);
|
|
1138 | 1435 |
RETURN(); |
1139 | 1436 |
} |
1140 | 1437 |
|
... | ... | |
1204 | 1501 |
|
1205 | 1502 |
void op_mtc0_taglo (void) |
1206 | 1503 |
{ |
1207 |
env->CP0_TagLo = T0 & 0xFFFFFCF6;
|
|
1504 |
env->CP0_TagLo = T0 & SIGN_EXTEND32(0xFFFFFCF6);
|
|
1208 | 1505 |
RETURN(); |
1209 | 1506 |
} |
1210 | 1507 |
|
... | ... | |
1787 | 2084 |
unsigned int pos = PARAM1; |
1788 | 2085 |
unsigned int size = PARAM2; |
1789 | 2086 |
|
1790 |
T0 = (T1 >> pos) & ((1 << size) - 1); |
|
2087 |
T0 = ((uint32_t)T1 >> pos) & ((1 << size) - 1);
|
|
1791 | 2088 |
RETURN(); |
1792 | 2089 |
} |
1793 | 2090 |
|
... | ... | |
1797 | 2094 |
unsigned int size = PARAM2; |
1798 | 2095 |
target_ulong mask = ((1 << size) - 1) << pos; |
1799 | 2096 |
|
1800 |
T0 = (T2 & ~mask) | ((T1 << pos) & mask); |
|
2097 |
T0 = (T2 & ~mask) | (((uint32_t)T1 << pos) & mask);
|
|
1801 | 2098 |
RETURN(); |
1802 | 2099 |
} |
1803 | 2100 |
|
... | ... | |
1807 | 2104 |
RETURN(); |
1808 | 2105 |
} |
1809 | 2106 |
|
2107 |
#ifdef MIPS_HAS_MIPS64 |
|
2108 |
void op_dext(void) |
|
2109 |
{ |
|
2110 |
unsigned int pos = PARAM1; |
|
2111 |
unsigned int size = PARAM2; |
|
2112 |
|
|
2113 |
T0 = (T1 >> pos) & ((1 << size) - 1); |
|
2114 |
RETURN(); |
|
2115 |
} |
|
2116 |
|
|
2117 |
void op_dins(void) |
|
2118 |
{ |
|
2119 |
unsigned int pos = PARAM1; |
|
2120 |
unsigned int size = PARAM2; |
|
2121 |
target_ulong mask = ((1 << size) - 1) << pos; |
|
2122 |
|
|
2123 |
T0 = (T2 & ~mask) | ((T1 << pos) & mask); |
|
2124 |
RETURN(); |
|
2125 |
} |
|
2126 |
|
|
1810 | 2127 |
void op_dsbh(void) |
1811 | 2128 |
{ |
1812 | 2129 |
T0 = ((T1 << 8) & ~0x00FF00FF00FF00FFULL) | ((T1 >> 8) & 0x00FF00FF00FF00FFULL); |
... | ... | |
1818 | 2135 |
T0 = ((T1 << 16) & ~0x0000FFFF0000FFFFULL) | ((T1 >> 16) & 0x0000FFFF0000FFFFULL); |
1819 | 2136 |
RETURN(); |
1820 | 2137 |
} |
2138 |
#endif |
|
1821 | 2139 |
|
1822 | 2140 |
void op_seb(void) |
1823 | 2141 |
{ |
Also available in: Unified diff