548 |
RETURN(); |
RETURN(); |
549 |
} |
} |
550 |
|
|
551 |
PPC_OP(addo) |
void do_addo (void); |
552 |
|
void op_addo (void) |
553 |
{ |
{ |
554 |
T2 = T0; |
do_addo(); |
|
T0 += T1; |
|
|
if ((T2 ^ T1 ^ (-1)) & (T2 ^ T0) & (1 << 31)) { |
|
|
xer_so = 1; |
|
|
xer_ov = 1; |
|
|
} else { |
|
|
xer_ov = 0; |
|
|
} |
|
555 |
RETURN(); |
RETURN(); |
556 |
} |
} |
557 |
|
|
568 |
RETURN(); |
RETURN(); |
569 |
} |
} |
570 |
|
|
571 |
PPC_OP(addco) |
void do_addco (void); |
572 |
|
void op_addco (void) |
573 |
{ |
{ |
574 |
T2 = T0; |
do_addco(); |
|
T0 += T1; |
|
|
if (T0 < T2) { |
|
|
xer_ca = 1; |
|
|
} else { |
|
|
xer_ca = 0; |
|
|
} |
|
|
if ((T2 ^ T1 ^ (-1)) & (T2 ^ T0) & (1 << 31)) { |
|
|
xer_so = 1; |
|
|
xer_ov = 1; |
|
|
} else { |
|
|
xer_ov = 0; |
|
|
} |
|
575 |
RETURN(); |
RETURN(); |
576 |
} |
} |
577 |
|
|
578 |
/* add extended */ |
/* add extended */ |
579 |
/* candidate for helper (too long) */ |
void do_adde (void); |
580 |
PPC_OP(adde) |
void op_adde (void) |
581 |
{ |
{ |
582 |
T2 = T0; |
do_adde(); |
|
T0 += T1 + xer_ca; |
|
|
if (T0 < T2 || (xer_ca == 1 && T0 == T2)) { |
|
|
xer_ca = 1; |
|
|
} else { |
|
|
xer_ca = 0; |
|
|
} |
|
|
RETURN(); |
|
583 |
} |
} |
584 |
|
|
585 |
|
void do_addeo (void); |
586 |
PPC_OP(addeo) |
PPC_OP(addeo) |
587 |
{ |
{ |
588 |
T2 = T0; |
do_addeo(); |
|
T0 += T1 + xer_ca; |
|
|
if (T0 < T2 || (xer_ca == 1 && T0 == T2)) { |
|
|
xer_ca = 1; |
|
|
} else { |
|
|
xer_ca = 0; |
|
|
} |
|
|
if ((T2 ^ T1 ^ (-1)) & (T2 ^ T0) & (1 << 31)) { |
|
|
xer_so = 1; |
|
|
xer_ov = 1; |
|
|
} else { |
|
|
xer_ov = 0; |
|
|
} |
|
589 |
RETURN(); |
RETURN(); |
590 |
} |
} |
591 |
|
|
619 |
RETURN(); |
RETURN(); |
620 |
} |
} |
621 |
|
|
622 |
PPC_OP(addmeo) |
void do_addmeo (void); |
623 |
|
void op_addmeo (void) |
624 |
{ |
{ |
625 |
T1 = T0; |
do_addmeo(); |
|
T0 += xer_ca + (-1); |
|
|
if (T1 & (T1 ^ T0) & (1 << 31)) { |
|
|
xer_so = 1; |
|
|
xer_ov = 1; |
|
|
} else { |
|
|
xer_ov = 0; |
|
|
} |
|
|
if (T1 != 0) |
|
|
xer_ca = 1; |
|
626 |
RETURN(); |
RETURN(); |
627 |
} |
} |
628 |
|
|
639 |
RETURN(); |
RETURN(); |
640 |
} |
} |
641 |
|
|
642 |
PPC_OP(addzeo) |
void do_addzeo (void); |
643 |
|
void op_addzeo (void) |
644 |
{ |
{ |
645 |
T1 = T0; |
do_addzeo(); |
|
T0 += xer_ca; |
|
|
if ((T1 ^ (-1)) & (T1 ^ T0) & (1 << 31)) { |
|
|
xer_so = 1; |
|
|
xer_ov = 1; |
|
|
} else { |
|
|
xer_ov = 0; |
|
|
} |
|
|
if (T0 < T1) { |
|
|
xer_ca = 1; |
|
|
} else { |
|
|
xer_ca = 0; |
|
|
} |
|
646 |
RETURN(); |
RETURN(); |
647 |
} |
} |
648 |
|
|
649 |
/* divide word */ |
/* divide word */ |
|
/* candidate for helper (too long) */ |
|
650 |
PPC_OP(divw) |
PPC_OP(divw) |
651 |
{ |
{ |
652 |
if ((Ts0 == INT32_MIN && Ts1 == -1) || Ts1 == 0) { |
if ((Ts0 == INT32_MIN && Ts1 == -1) || Ts1 == 0) { |
657 |
RETURN(); |
RETURN(); |
658 |
} |
} |
659 |
|
|
660 |
PPC_OP(divwo) |
void do_divwo (void); |
661 |
|
void op_divwo (void) |
662 |
{ |
{ |
663 |
if ((Ts0 == INT32_MIN && Ts1 == -1) || Ts1 == 0) { |
do_divwo(); |
|
xer_so = 1; |
|
|
xer_ov = 1; |
|
|
T0 = (-1) * (T0 >> 31); |
|
|
} else { |
|
|
xer_ov = 0; |
|
|
T0 = (Ts0 / Ts1); |
|
|
} |
|
664 |
RETURN(); |
RETURN(); |
665 |
} |
} |
666 |
|
|
675 |
RETURN(); |
RETURN(); |
676 |
} |
} |
677 |
|
|
678 |
PPC_OP(divwuo) |
void do_divwuo (void); |
679 |
|
void op_divwuo (void) |
680 |
{ |
{ |
681 |
if (T1 == 0) { |
do_divwuo(); |
|
xer_so = 1; |
|
|
xer_ov = 1; |
|
|
T0 = 0; |
|
|
} else { |
|
|
xer_ov = 0; |
|
|
T0 /= T1; |
|
|
} |
|
682 |
RETURN(); |
RETURN(); |
683 |
} |
} |
684 |
|
|
710 |
RETURN(); |
RETURN(); |
711 |
} |
} |
712 |
|
|
713 |
PPC_OP(mullwo) |
void do_mullwo (void); |
714 |
|
void op_mullwo (void) |
715 |
{ |
{ |
716 |
int64_t res = (int64_t)Ts0 * (int64_t)Ts1; |
do_mullwo(); |
|
|
|
|
if ((int32_t)res != res) { |
|
|
xer_ov = 1; |
|
|
xer_so = 1; |
|
|
} else { |
|
|
xer_ov = 0; |
|
|
} |
|
|
T0 = (int32_t)res; |
|
717 |
RETURN(); |
RETURN(); |
718 |
} |
} |
719 |
|
|
726 |
RETURN(); |
RETURN(); |
727 |
} |
} |
728 |
|
|
729 |
PPC_OP(nego) |
void do_nego (void); |
730 |
|
void op_nego (void) |
731 |
{ |
{ |
732 |
if (T0 == 0x80000000) { |
do_nego(); |
|
xer_ov = 1; |
|
|
xer_so = 1; |
|
|
} else { |
|
|
xer_ov = 0; |
|
|
T0 = -Ts0; |
|
|
} |
|
733 |
RETURN(); |
RETURN(); |
734 |
} |
} |
735 |
|
|
740 |
RETURN(); |
RETURN(); |
741 |
} |
} |
742 |
|
|
743 |
PPC_OP(subfo) |
void do_subfo (void); |
744 |
|
void op_subfo (void) |
745 |
{ |
{ |
746 |
T2 = T0; |
do_subfo(); |
|
T0 = T1 - T0; |
|
|
if (((~T2) ^ T1 ^ (-1)) & ((~T2) ^ T0) & (1 << 31)) { |
|
|
xer_so = 1; |
|
|
xer_ov = 1; |
|
|
} else { |
|
|
xer_ov = 0; |
|
|
} |
|
747 |
RETURN(); |
RETURN(); |
748 |
} |
} |
749 |
|
|
759 |
RETURN(); |
RETURN(); |
760 |
} |
} |
761 |
|
|
762 |
PPC_OP(subfco) |
void do_subfco (void); |
763 |
|
void op_subfco (void) |
764 |
{ |
{ |
765 |
T2 = T0; |
do_subfco(); |
|
T0 = T1 - T0; |
|
|
if (T0 <= T1) { |
|
|
xer_ca = 1; |
|
|
} else { |
|
|
xer_ca = 0; |
|
|
} |
|
|
if (((~T2) ^ T1 ^ (-1)) & ((~T2) ^ T0) & (1 << 31)) { |
|
|
xer_so = 1; |
|
|
xer_ov = 1; |
|
|
} else { |
|
|
xer_ov = 0; |
|
|
} |
|
766 |
RETURN(); |
RETURN(); |
767 |
} |
} |
768 |
|
|
769 |
/* substract from extended */ |
/* substract from extended */ |
770 |
/* candidate for helper (too long) */ |
void do_subfe (void); |
771 |
PPC_OP(subfe) |
void op_subfe (void) |
772 |
{ |
{ |
773 |
T0 = T1 + ~T0 + xer_ca; |
do_subfe(); |
|
if (T0 < T1 || (xer_ca == 1 && T0 == T1)) { |
|
|
xer_ca = 1; |
|
|
} else { |
|
|
xer_ca = 0; |
|
|
} |
|
774 |
RETURN(); |
RETURN(); |
775 |
} |
} |
776 |
|
|
777 |
|
void do_subfeo (void); |
778 |
PPC_OP(subfeo) |
PPC_OP(subfeo) |
779 |
{ |
{ |
780 |
T2 = T0; |
do_subfeo(); |
|
T0 = T1 + ~T0 + xer_ca; |
|
|
if ((~T2 ^ T1 ^ (-1)) & (~T2 ^ T0) & (1 << 31)) { |
|
|
xer_so = 1; |
|
|
xer_ov = 1; |
|
|
} else { |
|
|
xer_ov = 0; |
|
|
} |
|
|
if (T0 < T1 || (xer_ca == 1 && T0 == T1)) { |
|
|
xer_ca = 1; |
|
|
} else { |
|
|
xer_ca = 0; |
|
|
} |
|
781 |
RETURN(); |
RETURN(); |
782 |
} |
} |
783 |
|
|
803 |
RETURN(); |
RETURN(); |
804 |
} |
} |
805 |
|
|
806 |
PPC_OP(subfmeo) |
void do_subfmeo (void); |
807 |
|
void op_subfmeo (void) |
808 |
{ |
{ |
809 |
T1 = T0; |
do_subfmeo(); |
|
T0 = ~T0 + xer_ca - 1; |
|
|
if (~T1 & (~T1 ^ T0) & (1 << 31)) { |
|
|
xer_so = 1; |
|
|
xer_ov = 1; |
|
|
} else { |
|
|
xer_ov = 0; |
|
|
} |
|
|
if (T1 != -1) |
|
|
xer_ca = 1; |
|
810 |
RETURN(); |
RETURN(); |
811 |
} |
} |
812 |
|
|
823 |
RETURN(); |
RETURN(); |
824 |
} |
} |
825 |
|
|
826 |
PPC_OP(subfzeo) |
void do_subfzeo (void); |
827 |
|
void op_subfzeo (void) |
828 |
{ |
{ |
829 |
T1 = T0; |
do_subfzeo(); |
|
T0 = ~T0 + xer_ca; |
|
|
if ((~T1 ^ (-1)) & ((~T1) ^ T0) & (1 << 31)) { |
|
|
xer_ov = 1; |
|
|
xer_so = 1; |
|
|
} else { |
|
|
xer_ov = 0; |
|
|
} |
|
|
if (T0 < ~T1) { |
|
|
xer_ca = 1; |
|
|
} else { |
|
|
xer_ca = 0; |
|
|
} |
|
830 |
RETURN(); |
RETURN(); |
831 |
} |
} |
832 |
|
|
1043 |
} |
} |
1044 |
|
|
1045 |
/* shift right algebraic word */ |
/* shift right algebraic word */ |
1046 |
PPC_OP(sraw) |
void op_sraw (void) |
1047 |
{ |
{ |
1048 |
do_sraw(); |
do_sraw(); |
1049 |
RETURN(); |
RETURN(); |
1096 |
} |
} |
1097 |
|
|
1098 |
/* fdiv - fdiv. */ |
/* fdiv - fdiv. */ |
|
void do_fdiv (void); |
|
1099 |
PPC_OP(fdiv) |
PPC_OP(fdiv) |
1100 |
{ |
{ |
1101 |
do_fdiv(); |
FT0 = float64_div(FT0, FT1, &env->fp_status); |
1102 |
RETURN(); |
RETURN(); |
1103 |
} |
} |
1104 |
|
|
1199 |
|
|
1200 |
/*** Floating-point move ***/ |
/*** Floating-point move ***/ |
1201 |
/* fabs */ |
/* fabs */ |
|
void do_fabs (void); |
|
1202 |
PPC_OP(fabs) |
PPC_OP(fabs) |
1203 |
{ |
{ |
1204 |
do_fabs(); |
FT0 = float64_abs(FT0); |
1205 |
RETURN(); |
RETURN(); |
1206 |
} |
} |
1207 |
|
|
1208 |
/* fnabs */ |
/* fnabs */ |
|
void do_fnabs (void); |
|
1209 |
PPC_OP(fnabs) |
PPC_OP(fnabs) |
1210 |
{ |
{ |
1211 |
do_fnabs(); |
FT0 = float64_abs(FT0); |
1212 |
|
FT0 = float64_chs(FT0); |
1213 |
RETURN(); |
RETURN(); |
1214 |
} |
} |
1215 |
|
|
1216 |
/* fneg */ |
/* fneg */ |
1217 |
PPC_OP(fneg) |
PPC_OP(fneg) |
1218 |
{ |
{ |
1219 |
FT0 = -FT0; |
FT0 = float64_chs(FT0); |
1220 |
RETURN(); |
RETURN(); |
1221 |
} |
} |
1222 |
|
|
1234 |
/* Special op to check and maybe clear reservation */ |
/* Special op to check and maybe clear reservation */ |
1235 |
PPC_OP(check_reservation) |
PPC_OP(check_reservation) |
1236 |
{ |
{ |
1237 |
do_check_reservation(); |
if ((uint32_t)env->reserve == (uint32_t)(T0 & ~0x00000003)) |
1238 |
|
env->reserve = -1; |
1239 |
RETURN(); |
RETURN(); |
1240 |
} |
} |
1241 |
|
|
1242 |
/* Return from interrupt */ |
/* Return from interrupt */ |
1243 |
PPC_OP(rfi) |
void do_rfi (void); |
1244 |
|
void op_rfi (void) |
1245 |
{ |
{ |
1246 |
env->nip = env->spr[SPR_SRR0] & ~0x00000003; |
do_rfi(); |
|
T0 = env->spr[SPR_SRR1] & ~0xFFFF0000UL; |
|
|
do_store_msr(env, T0); |
|
|
env->interrupt_request |= CPU_INTERRUPT_EXITTB; |
|
1247 |
RETURN(); |
RETURN(); |
1248 |
} |
} |
1249 |
|
|
1250 |
/* Trap word */ |
/* Trap word */ |
1251 |
PPC_OP(tw) |
void do_tw (uint32_t cmp, int flags); |
1252 |
|
void op_tw (void) |
1253 |
{ |
{ |
1254 |
if ((Ts0 < Ts1 && (PARAM(1) & 0x10)) || |
do_tw(T1, PARAM(1)); |
|
(Ts0 > Ts1 && (PARAM(1) & 0x08)) || |
|
|
(Ts0 == Ts1 && (PARAM(1) & 0x04)) || |
|
|
(T0 < T1 && (PARAM(1) & 0x02)) || |
|
|
(T0 > T1 && (PARAM(1) & 0x01))) |
|
|
do_raise_exception_err(EXCP_PROGRAM, EXCP_TRAP); |
|
1255 |
RETURN(); |
RETURN(); |
1256 |
} |
} |
1257 |
|
|
1258 |
PPC_OP(twi) |
void op_twi (void) |
1259 |
{ |
{ |
1260 |
if ((Ts0 < SPARAM(1) && (PARAM(2) & 0x10)) || |
do_tw(PARAM(1), PARAM(2)); |
|
(Ts0 > SPARAM(1) && (PARAM(2) & 0x08)) || |
|
|
(Ts0 == SPARAM(1) && (PARAM(2) & 0x04)) || |
|
|
(T0 < (uint32_t)SPARAM(1) && (PARAM(2) & 0x02)) || |
|
|
(T0 > (uint32_t)SPARAM(1) && (PARAM(2) & 0x01))) |
|
|
do_raise_exception_err(EXCP_PROGRAM, EXCP_TRAP); |
|
1261 |
RETURN(); |
RETURN(); |
1262 |
} |
} |
1263 |
|
|