740 |
GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER) |
GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER) |
741 |
{ |
{ |
742 |
gen_op_load_gpr_T0(rS(ctx->opcode)); |
gen_op_load_gpr_T0(rS(ctx->opcode)); |
743 |
|
if (SH(ctx->opcode) != 0) |
744 |
gen_op_srawi(SH(ctx->opcode), MASK(32 - SH(ctx->opcode), 31)); |
gen_op_srawi(SH(ctx->opcode), MASK(32 - SH(ctx->opcode), 31)); |
745 |
if (Rc(ctx->opcode) != 0) |
if (Rc(ctx->opcode) != 0) |
746 |
gen_op_set_Rc0(); |
gen_op_set_Rc0(); |
750 |
__GEN_LOGICAL2(srw, 0x18, 0x10); |
__GEN_LOGICAL2(srw, 0x18, 0x10); |
751 |
|
|
752 |
/*** Floating-Point arithmetic ***/ |
/*** Floating-Point arithmetic ***/ |
753 |
#define _GEN_FLOAT_ACB(name, op1, op2) \ |
#define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat) \ |
754 |
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, PPC_FLOAT) \ |
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, PPC_FLOAT) \ |
755 |
{ \ |
{ \ |
756 |
if (!ctx->fpu_enabled) { \ |
if (!ctx->fpu_enabled) { \ |
761 |
gen_op_load_fpr_FT0(rA(ctx->opcode)); \ |
gen_op_load_fpr_FT0(rA(ctx->opcode)); \ |
762 |
gen_op_load_fpr_FT1(rC(ctx->opcode)); \ |
gen_op_load_fpr_FT1(rC(ctx->opcode)); \ |
763 |
gen_op_load_fpr_FT2(rB(ctx->opcode)); \ |
gen_op_load_fpr_FT2(rB(ctx->opcode)); \ |
764 |
gen_op_f##name(); \ |
gen_op_f##op(); \ |
765 |
|
if (isfloat) { \ |
766 |
|
gen_op_frsp(); \ |
767 |
|
} \ |
768 |
gen_op_store_FT0_fpr(rD(ctx->opcode)); \ |
gen_op_store_FT0_fpr(rD(ctx->opcode)); \ |
769 |
if (Rc(ctx->opcode)) \ |
if (Rc(ctx->opcode)) \ |
770 |
gen_op_set_Rc1(); \ |
gen_op_set_Rc1(); \ |
771 |
} |
} |
772 |
|
|
773 |
#define GEN_FLOAT_ACB(name, op2) \ |
#define GEN_FLOAT_ACB(name, op2) \ |
774 |
_GEN_FLOAT_ACB(name, 0x3F, op2); \ |
_GEN_FLOAT_ACB(name, name, 0x3F, op2, 0); \ |
775 |
_GEN_FLOAT_ACB(name##s, 0x3B, op2); |
_GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1); |
776 |
|
|
777 |
#define _GEN_FLOAT_AB(name, op1, op2, inval) \ |
#define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat) \ |
778 |
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT) \ |
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT) \ |
779 |
{ \ |
{ \ |
780 |
if (!ctx->fpu_enabled) { \ |
if (!ctx->fpu_enabled) { \ |
784 |
gen_op_reset_scrfx(); \ |
gen_op_reset_scrfx(); \ |
785 |
gen_op_load_fpr_FT0(rA(ctx->opcode)); \ |
gen_op_load_fpr_FT0(rA(ctx->opcode)); \ |
786 |
gen_op_load_fpr_FT1(rB(ctx->opcode)); \ |
gen_op_load_fpr_FT1(rB(ctx->opcode)); \ |
787 |
gen_op_f##name(); \ |
gen_op_f##op(); \ |
788 |
|
if (isfloat) { \ |
789 |
|
gen_op_frsp(); \ |
790 |
|
} \ |
791 |
gen_op_store_FT0_fpr(rD(ctx->opcode)); \ |
gen_op_store_FT0_fpr(rD(ctx->opcode)); \ |
792 |
if (Rc(ctx->opcode)) \ |
if (Rc(ctx->opcode)) \ |
793 |
gen_op_set_Rc1(); \ |
gen_op_set_Rc1(); \ |
794 |
} |
} |
795 |
#define GEN_FLOAT_AB(name, op2, inval) \ |
#define GEN_FLOAT_AB(name, op2, inval) \ |
796 |
_GEN_FLOAT_AB(name, 0x3F, op2, inval); \ |
_GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0); \ |
797 |
_GEN_FLOAT_AB(name##s, 0x3B, op2, inval); |
_GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1); |
798 |
|
|
799 |
#define _GEN_FLOAT_AC(name, op1, op2, inval) \ |
#define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat) \ |
800 |
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT) \ |
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT) \ |
801 |
{ \ |
{ \ |
802 |
if (!ctx->fpu_enabled) { \ |
if (!ctx->fpu_enabled) { \ |
806 |
gen_op_reset_scrfx(); \ |
gen_op_reset_scrfx(); \ |
807 |
gen_op_load_fpr_FT0(rA(ctx->opcode)); \ |
gen_op_load_fpr_FT0(rA(ctx->opcode)); \ |
808 |
gen_op_load_fpr_FT1(rC(ctx->opcode)); \ |
gen_op_load_fpr_FT1(rC(ctx->opcode)); \ |
809 |
gen_op_f##name(); \ |
gen_op_f##op(); \ |
810 |
|
if (isfloat) { \ |
811 |
|
gen_op_frsp(); \ |
812 |
|
} \ |
813 |
gen_op_store_FT0_fpr(rD(ctx->opcode)); \ |
gen_op_store_FT0_fpr(rD(ctx->opcode)); \ |
814 |
if (Rc(ctx->opcode)) \ |
if (Rc(ctx->opcode)) \ |
815 |
gen_op_set_Rc1(); \ |
gen_op_set_Rc1(); \ |
816 |
} |
} |
817 |
#define GEN_FLOAT_AC(name, op2, inval) \ |
#define GEN_FLOAT_AC(name, op2, inval) \ |
818 |
_GEN_FLOAT_AC(name, 0x3F, op2, inval); \ |
_GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0); \ |
819 |
_GEN_FLOAT_AC(name##s, 0x3B, op2, inval); |
_GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1); |
820 |
|
|
821 |
#define GEN_FLOAT_B(name, op2, op3) \ |
#define GEN_FLOAT_B(name, op2, op3) \ |
822 |
GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, PPC_FLOAT) \ |
GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, PPC_FLOAT) \ |
833 |
gen_op_set_Rc1(); \ |
gen_op_set_Rc1(); \ |
834 |
} |
} |
835 |
|
|
836 |
#define GEN_FLOAT_BS(name, op2) \ |
#define GEN_FLOAT_BS(name, op1, op2) \ |
837 |
GEN_HANDLER(f##name, 0x3F, op2, 0xFF, 0x001F07C0, PPC_FLOAT) \ |
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, PPC_FLOAT) \ |
838 |
{ \ |
{ \ |
839 |
if (!ctx->fpu_enabled) { \ |
if (!ctx->fpu_enabled) { \ |
840 |
RET_EXCP(ctx, EXCP_NO_FP, 0); \ |
RET_EXCP(ctx, EXCP_NO_FP, 0); \ |
850 |
|
|
851 |
/* fadd - fadds */ |
/* fadd - fadds */ |
852 |
GEN_FLOAT_AB(add, 0x15, 0x000007C0); |
GEN_FLOAT_AB(add, 0x15, 0x000007C0); |
853 |
/* fdiv */ |
/* fdiv - fdivs */ |
854 |
GEN_FLOAT_AB(div, 0x12, 0x000007C0); |
GEN_FLOAT_AB(div, 0x12, 0x000007C0); |
855 |
/* fmul */ |
/* fmul - fmuls */ |
856 |
GEN_FLOAT_AC(mul, 0x19, 0x0000F800); |
GEN_FLOAT_AC(mul, 0x19, 0x0000F800); |
857 |
|
|
858 |
/* fres */ |
/* fres */ |
859 |
GEN_FLOAT_BS(res, 0x18); |
GEN_FLOAT_BS(res, 0x3B, 0x18); |
860 |
|
|
861 |
/* frsqrte */ |
/* frsqrte */ |
862 |
GEN_FLOAT_BS(rsqrte, 0x1A); |
GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A); |
863 |
|
|
864 |
/* fsel */ |
/* fsel */ |
865 |
_GEN_FLOAT_ACB(sel, 0x3F, 0x17); |
_GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0); |
866 |
/* fsub */ |
/* fsub - fsubs */ |
867 |
GEN_FLOAT_AB(sub, 0x14, 0x000007C0); |
GEN_FLOAT_AB(sub, 0x14, 0x000007C0); |
868 |
/* Optional: */ |
/* Optional: */ |
869 |
/* fsqrt */ |
/* fsqrt */ |
870 |
GEN_FLOAT_BS(sqrt, 0x16); |
GEN_FLOAT_BS(sqrt, 0x3F, 0x16); |
871 |
|
|
872 |
GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_OPT) |
GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_OPT) |
873 |
{ |
{ |
877 |
} |
} |
878 |
gen_op_reset_scrfx(); |
gen_op_reset_scrfx(); |
879 |
gen_op_load_fpr_FT0(rB(ctx->opcode)); |
gen_op_load_fpr_FT0(rB(ctx->opcode)); |
880 |
gen_op_fsqrts(); |
gen_op_fsqrt(); |
881 |
|
gen_op_frsp(); |
882 |
gen_op_store_FT0_fpr(rD(ctx->opcode)); |
gen_op_store_FT0_fpr(rD(ctx->opcode)); |
883 |
if (Rc(ctx->opcode)) |
if (Rc(ctx->opcode)) |
884 |
gen_op_set_Rc1(); |
gen_op_set_Rc1(); |
885 |
} |
} |
886 |
|
|
887 |
/*** Floating-Point multiply-and-add ***/ |
/*** Floating-Point multiply-and-add ***/ |
888 |
/* fmadd */ |
/* fmadd - fmadds */ |
889 |
GEN_FLOAT_ACB(madd, 0x1D); |
GEN_FLOAT_ACB(madd, 0x1D); |
890 |
/* fmsub */ |
/* fmsub - fmsubs */ |
891 |
GEN_FLOAT_ACB(msub, 0x1C); |
GEN_FLOAT_ACB(msub, 0x1C); |
892 |
/* fnmadd */ |
/* fnmadd - fnmadds */ |
893 |
GEN_FLOAT_ACB(nmadd, 0x1F); |
GEN_FLOAT_ACB(nmadd, 0x1F); |
894 |
/* fnmsub */ |
/* fnmsub - fnmsubs */ |
895 |
GEN_FLOAT_ACB(nmsub, 0x1E); |
GEN_FLOAT_ACB(nmsub, 0x1E); |
896 |
|
|
897 |
/*** Floating-Point round & convert ***/ |
/*** Floating-Point round & convert ***/ |
1437 |
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) \ |
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) \ |
1438 |
{ \ |
{ \ |
1439 |
uint32_t simm = SIMM(ctx->opcode); \ |
uint32_t simm = SIMM(ctx->opcode); \ |
1440 |
|
if (!ctx->fpu_enabled) { \ |
1441 |
|
RET_EXCP(ctx, EXCP_NO_FP, 0); \ |
1442 |
|
return; \ |
1443 |
|
} \ |
1444 |
if (rA(ctx->opcode) == 0) { \ |
if (rA(ctx->opcode) == 0) { \ |
1445 |
gen_op_set_T0(simm); \ |
gen_op_set_T0(simm); \ |
1446 |
} else { \ |
} else { \ |
1456 |
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) \ |
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) \ |
1457 |
{ \ |
{ \ |
1458 |
uint32_t simm = SIMM(ctx->opcode); \ |
uint32_t simm = SIMM(ctx->opcode); \ |
1459 |
|
if (!ctx->fpu_enabled) { \ |
1460 |
|
RET_EXCP(ctx, EXCP_NO_FP, 0); \ |
1461 |
|
return; \ |
1462 |
|
} \ |
1463 |
if (rA(ctx->opcode) == 0 || \ |
if (rA(ctx->opcode) == 0 || \ |
1464 |
rA(ctx->opcode) == rD(ctx->opcode)) { \ |
rA(ctx->opcode) == rD(ctx->opcode)) { \ |
1465 |
RET_INVAL(ctx); \ |
RET_INVAL(ctx); \ |
1476 |
#define GEN_LDUXF(width, opc) \ |
#define GEN_LDUXF(width, opc) \ |
1477 |
GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_INTEGER) \ |
GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_INTEGER) \ |
1478 |
{ \ |
{ \ |
1479 |
|
if (!ctx->fpu_enabled) { \ |
1480 |
|
RET_EXCP(ctx, EXCP_NO_FP, 0); \ |
1481 |
|
return; \ |
1482 |
|
} \ |
1483 |
if (rA(ctx->opcode) == 0 || \ |
if (rA(ctx->opcode) == 0 || \ |
1484 |
rA(ctx->opcode) == rD(ctx->opcode)) { \ |
rA(ctx->opcode) == rD(ctx->opcode)) { \ |
1485 |
RET_INVAL(ctx); \ |
RET_INVAL(ctx); \ |
1496 |
#define GEN_LDXF(width, opc2, opc3) \ |
#define GEN_LDXF(width, opc2, opc3) \ |
1497 |
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_INTEGER) \ |
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_INTEGER) \ |
1498 |
{ \ |
{ \ |
1499 |
|
if (!ctx->fpu_enabled) { \ |
1500 |
|
RET_EXCP(ctx, EXCP_NO_FP, 0); \ |
1501 |
|
return; \ |
1502 |
|
} \ |
1503 |
if (rA(ctx->opcode) == 0) { \ |
if (rA(ctx->opcode) == 0) { \ |
1504 |
gen_op_load_gpr_T0(rB(ctx->opcode)); \ |
gen_op_load_gpr_T0(rB(ctx->opcode)); \ |
1505 |
} else { \ |
} else { \ |
1528 |
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) \ |
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) \ |
1529 |
{ \ |
{ \ |
1530 |
uint32_t simm = SIMM(ctx->opcode); \ |
uint32_t simm = SIMM(ctx->opcode); \ |
1531 |
|
if (!ctx->fpu_enabled) { \ |
1532 |
|
RET_EXCP(ctx, EXCP_NO_FP, 0); \ |
1533 |
|
return; \ |
1534 |
|
} \ |
1535 |
if (rA(ctx->opcode) == 0) { \ |
if (rA(ctx->opcode) == 0) { \ |
1536 |
gen_op_set_T0(simm); \ |
gen_op_set_T0(simm); \ |
1537 |
} else { \ |
} else { \ |
1547 |
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) \ |
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) \ |
1548 |
{ \ |
{ \ |
1549 |
uint32_t simm = SIMM(ctx->opcode); \ |
uint32_t simm = SIMM(ctx->opcode); \ |
1550 |
|
if (!ctx->fpu_enabled) { \ |
1551 |
|
RET_EXCP(ctx, EXCP_NO_FP, 0); \ |
1552 |
|
return; \ |
1553 |
|
} \ |
1554 |
if (rA(ctx->opcode) == 0) { \ |
if (rA(ctx->opcode) == 0) { \ |
1555 |
RET_INVAL(ctx); \ |
RET_INVAL(ctx); \ |
1556 |
return; \ |
return; \ |
1566 |
#define GEN_STUXF(width, opc) \ |
#define GEN_STUXF(width, opc) \ |
1567 |
GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_INTEGER) \ |
GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_INTEGER) \ |
1568 |
{ \ |
{ \ |
1569 |
|
if (!ctx->fpu_enabled) { \ |
1570 |
|
RET_EXCP(ctx, EXCP_NO_FP, 0); \ |
1571 |
|
return; \ |
1572 |
|
} \ |
1573 |
if (rA(ctx->opcode) == 0) { \ |
if (rA(ctx->opcode) == 0) { \ |
1574 |
RET_INVAL(ctx); \ |
RET_INVAL(ctx); \ |
1575 |
return; \ |
return; \ |
1585 |
#define GEN_STXF(width, opc2, opc3) \ |
#define GEN_STXF(width, opc2, opc3) \ |
1586 |
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_INTEGER) \ |
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_INTEGER) \ |
1587 |
{ \ |
{ \ |
1588 |
|
if (!ctx->fpu_enabled) { \ |
1589 |
|
RET_EXCP(ctx, EXCP_NO_FP, 0); \ |
1590 |
|
return; \ |
1591 |
|
} \ |
1592 |
if (rA(ctx->opcode) == 0) { \ |
if (rA(ctx->opcode) == 0) { \ |
1593 |
gen_op_load_gpr_T0(rB(ctx->opcode)); \ |
gen_op_load_gpr_T0(rB(ctx->opcode)); \ |
1594 |
} else { \ |
} else { \ |