diff --git a/cpu/ppc/poweropcodes.cpp b/cpu/ppc/poweropcodes.cpp
index 731b563..44b2135 100644
--- a/cpu/ppc/poweropcodes.cpp
+++ b/cpu/ppc/poweropcodes.cpp
@@ -24,58 +24,38 @@ along with this program. If not, see .
#include "ppcemu.h"
#include "ppcmmu.h"
+#include
#include
#include
#include
+#include
#include
#include
+// Affects the XER register's SO and OV Bits
+
+inline void power_setsoov(uint32_t a, uint32_t b, uint32_t d) {
+ if ((a ^ b) & (a ^ d) & 0x80000000UL) {
+ ppc_state.spr[SPR::XER] |= 0xC0000000UL;
+ } else {
+ ppc_state.spr[SPR::XER] &= 0xBFFFFFFFUL;
+ }
+}
+
void power_abs() {
ppc_grab_regsda();
if (ppc_result_a == 0x80000000) {
ppc_result_d = ppc_result_a;
+ if (oe_flag)
+ ppc_state.spr[SPR::XER] |= 0x40000000;
} else {
ppc_result_d = ppc_result_a & 0x7FFFFFFF;
}
- ppc_store_result_regd();
-}
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_d);
-void power_absdot() {
- ppc_grab_regsda();
- if (ppc_result_a == 0x80000000) {
- ppc_result_d = ppc_result_a;
-
- } else {
- ppc_result_d = ppc_result_a & 0x7FFFFFFF;
- }
- ppc_changecrf0(ppc_result_d);
- ppc_store_result_regd();
-}
-
-void power_abso() {
- ppc_grab_regsda();
- if (ppc_result_a == 0x80000000) {
- ppc_result_d = ppc_result_a;
- ppc_state.spr[SPR::XER] |= 0x40000000;
-
- } else {
- ppc_result_d = ppc_result_a & 0x7FFFFFFF;
- }
- ppc_store_result_regd();
-}
-
-void power_absodot() {
- ppc_grab_regsda();
- if (ppc_result_a == 0x80000000) {
- ppc_result_d = ppc_result_a;
- ppc_state.spr[SPR::XER] |= 0x40000000;
-
- } else {
- ppc_result_d = ppc_result_a & 0x7FFFFFFF;
- }
- ppc_changecrf0(ppc_result_d);
ppc_store_result_regd();
}
@@ -91,22 +71,12 @@ void power_clcs() {
default:
ppc_result_d = 0;
}
- ppc_store_result_regd();
-}
-void power_clcsdot() {
- switch (reg_a) {
- case 12:
- case 13:
- case 14:
- case 15:
- ppc_result_d = 65535;
- break;
- default:
- ppc_result_d = 0;
+ if (rc_flag) {
+ ppc_changecrf0(ppc_result_d);
+ printf("Does RC do anything here? (TODO) \n");
}
- ppc_changecrf0(ppc_result_d);
- printf("Does RC do anything here? (TODO) \n");
+
ppc_store_result_regd();
}
@@ -114,46 +84,28 @@ void power_div() {
ppc_grab_regsdab();
ppc_result_d = (ppc_result_a | ppc_state.spr[SPR::MQ]) / ppc_result_b;
ppc_state.spr[SPR::MQ] = (ppc_result_a | ppc_state.spr[SPR::MQ]) % ppc_result_b;
+
+ if (oe_flag)
+ power_setsoov(ppc_result_b, ppc_result_a, ppc_result_d);
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_d);
+
ppc_store_result_regd();
}
-void power_divdot() {
- ppc_result_d = (ppc_result_a | ppc_state.spr[SPR::MQ]) / ppc_result_b;
- ppc_state.spr[SPR::MQ] = (ppc_result_a | ppc_state.spr[SPR::MQ]) % ppc_result_b;
-}
-
-void power_divo() {
- ppc_result_d = (ppc_result_a | ppc_state.spr[SPR::MQ]) / ppc_result_b;
- ppc_state.spr[SPR::MQ] = (ppc_result_a | ppc_state.spr[SPR::MQ]) % ppc_result_b;
-}
-
-void power_divodot() {
- ppc_result_d = (ppc_result_a | ppc_state.spr[SPR::MQ]) / ppc_result_b;
- ppc_state.spr[SPR::MQ] = (ppc_result_a | ppc_state.spr[SPR::MQ]) % ppc_result_b;
-}
-
void power_divs() {
ppc_grab_regsdab();
ppc_result_d = ppc_result_a / ppc_result_b;
ppc_state.spr[SPR::MQ] = (ppc_result_a % ppc_result_b);
+
+ if (oe_flag)
+ power_setsoov(ppc_result_b, ppc_result_a, ppc_result_d);
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_d);
+
ppc_store_result_regd();
}
-void power_divsdot() {
- ppc_result_d = ppc_result_a / ppc_result_b;
- ppc_state.spr[SPR::MQ] = (ppc_result_a % ppc_result_b);
-}
-
-void power_divso() {
- ppc_result_d = ppc_result_a / ppc_result_b;
- ppc_state.spr[SPR::MQ] = (ppc_result_a % ppc_result_b);
-}
-
-void power_divsodot() {
- ppc_result_d = ppc_result_a / ppc_result_b;
- ppc_state.spr[SPR::MQ] = (ppc_result_a % ppc_result_b);
-}
-
void power_doz() {
ppc_grab_regsdab();
if (((int32_t)ppc_result_a) > ((int32_t)ppc_result_b)) {
@@ -161,36 +113,13 @@ void power_doz() {
} else {
ppc_result_d = ~ppc_result_a + ppc_result_b + 1;
}
+
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_d);
+
ppc_store_result_rega();
}
-void power_dozdot() {
- ppc_grab_regsdab();
- if (((int32_t)ppc_result_a) > ((int32_t)ppc_result_b)) {
- ppc_result_d = 0;
- } else {
- ppc_result_d = ~ppc_result_a + ppc_result_b + 1;
- }
- ppc_changecrf0(ppc_result_d);
- ppc_store_result_rega();
-}
-
-void power_dozo() {
- if (((int32_t)ppc_result_a) > ((int32_t)ppc_result_b)) {
- ppc_result_d = 0;
- } else {
- ppc_result_d = ~ppc_result_a + ppc_result_b + 1;
- }
-}
-
-void power_dozodot() {
- if (((int32_t)ppc_result_a) > ((int32_t)ppc_result_b)) {
- ppc_result_d = 0;
- } else {
- ppc_result_d = ~ppc_result_a + ppc_result_b + 1;
- }
-}
-
void power_dozi() {
ppc_grab_regsdab();
if (((int32_t)ppc_result_a) > simm) {
@@ -254,11 +183,12 @@ void power_lscbx() {
}
} while (bytes_to_load > 0);
ppc_state.spr[SPR::XER] = (ppc_state.spr[SPR::XER] & 0xFFFFFF80) | bytes_copied;
- ppc_store_result_regd();
-}
-void power_lscbxdot() {
- printf("OOPS! Placeholder!!! \n");
+
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_d);
+
+ ppc_store_result_regd();
}
void power_maskg() {
@@ -281,29 +211,10 @@ void power_maskg() {
}
ppc_result_a = insert_mask;
- ppc_store_result_rega();
-}
-void power_maskgdot() {
- ppc_grab_regssab();
- uint32_t mask_start = ppc_result_d & 31;
- uint32_t mask_end = ppc_result_b & 31;
- uint32_t insert_mask = 0;
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_d);
- if (mask_start < (mask_end + 1)) {
- for (uint32_t i = mask_start; i < mask_end; i++) {
- insert_mask |= (0x80000000 >> i);
- }
- } else if (mask_start == (mask_end + 1)) {
- insert_mask = 0xFFFFFFFF;
- } else {
- insert_mask = 0xFFFFFFFF;
- for (uint32_t i = (mask_end + 1); i < (mask_start - 1); i++) {
- insert_mask &= (~(0x80000000 >> i));
- }
- }
-
- ppc_result_a = insert_mask;
ppc_store_result_rega();
}
@@ -320,23 +231,10 @@ void power_maskir() {
} while (insert_rot > 0);
ppc_result_a = (ppc_result_d & ppc_result_b);
- ppc_store_result_rega();
-}
-void power_maskirdot() {
- ppc_grab_regssab();
- uint32_t mask_insert = ppc_result_a;
- uint32_t insert_rot = 0x80000000;
- do {
- if (ppc_result_b & insert_rot) {
- mask_insert &= ~insert_rot;
- mask_insert |= (ppc_result_d & insert_rot);
- }
- insert_rot = insert_rot >> 1;
- } while (insert_rot > 0);
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_a);
- ppc_result_a = (ppc_result_d & ppc_result_b);
- ppc_changecrf0(ppc_result_a);
ppc_store_result_rega();
}
@@ -347,54 +245,23 @@ void power_mul() {
product = ((uint64_t)ppc_result_a) * ((uint64_t)ppc_result_b);
ppc_result_d = ((uint32_t)(product >> 32));
ppc_state.spr[SPR::MQ] = ((uint32_t)(product));
+
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_d);
+
ppc_store_result_regd();
}
-void power_muldot() {
- ppc_grab_regsdab();
- uint64_t product;
-
- product = ((uint64_t)ppc_result_a) * ((uint64_t)ppc_result_b);
- ppc_result_d = ((uint32_t)(product >> 32));
- ppc_state.spr[SPR::MQ] = ((uint32_t)(product));
- ppc_changecrf0(ppc_result_d);
- ppc_store_result_regd();
-}
-
-void power_mulo() {
- uint64_t product;
-
- product = ((uint64_t)ppc_result_a) * ((uint64_t)ppc_result_b);
- ppc_result_d = ((uint32_t)(product >> 32));
- ppc_state.spr[SPR::MQ] = ((uint32_t)(product));
-}
-
-void power_mulodot() {
- uint64_t product;
-
- product = ((uint64_t)ppc_result_a) * ((uint64_t)ppc_result_b);
- ppc_result_d = ((uint32_t)(product >> 32));
- ppc_state.spr[SPR::MQ] = ((uint32_t)(product));
-}
-
void power_nabs() {
ppc_grab_regsda();
ppc_result_d = (0x80000000 | ppc_result_a);
+
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_d);
+
ppc_store_result_regd();
}
-void power_nabsdot() {
- ppc_result_d = (0x80000000 | ppc_result_a);
-}
-
-void power_nabso() {
- ppc_result_d = (0x80000000 | ppc_result_a);
-}
-
-void power_nabsodot() {
- ppc_result_d = (0x80000000 | ppc_result_a);
-}
-
void power_rlmi() {
ppc_grab_regssab();
unsigned rot_mb = (ppc_cur_instruction >> 6) & 31;
@@ -422,22 +289,16 @@ void power_rlmi() {
void power_rrib() {
ppc_grab_regssab();
- if (ppc_result_d & 0x80000000) {
- ppc_result_a |= (0x80000000 >> ppc_result_b);
- } else {
- ppc_result_a &= ~(0x80000000 >> ppc_result_b);
- }
- ppc_store_result_rega();
-}
-void power_rribdot() {
- ppc_grab_regssab();
if (ppc_result_d & 0x80000000) {
ppc_result_a |= (0x80000000 >> ppc_result_b);
} else {
ppc_result_a &= ~(0x80000000 >> ppc_result_b);
}
- ppc_changecrf0(ppc_result_a);
+
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_a);
+
ppc_store_result_rega();
}
@@ -451,20 +312,10 @@ void power_sle() {
uint32_t insert_final = ((ppc_result_d << rot_amt) | (ppc_result_d >> (32 - rot_amt)));
ppc_state.spr[SPR::MQ] = insert_final & insert_mask;
ppc_result_a = insert_final & insert_mask;
- ppc_store_result_rega();
-}
-void power_sledot() {
- ppc_grab_regssa();
- uint32_t insert_mask = 0;
- uint32_t rot_amt = ppc_result_b & 31;
- for (uint32_t i = 31; i > rot_amt; i--) {
- insert_mask |= (1 << i);
- }
- uint32_t insert_final = ((ppc_result_d << rot_amt) | (ppc_result_d >> (32 - rot_amt)));
- ppc_state.spr[SPR::MQ] = insert_final & insert_mask;
- ppc_result_a = insert_final & insert_mask;
- ppc_changecrf0(ppc_result_a);
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_a);
+
ppc_store_result_rega();
}
@@ -487,29 +338,10 @@ void power_sleq() {
ppc_result_a = insert_end;
ppc_state.spr[SPR::MQ] = insert_start;
- ppc_store_result_rega();
-}
-void power_sleqdot() {
- ppc_grab_regssa();
- uint32_t insert_mask = 0;
- uint32_t rot_amt = ppc_result_b & 31;
- for (uint32_t i = 31; i > rot_amt; i--) {
- insert_mask |= (1 << i);
- }
- uint32_t insert_start = ((ppc_result_d << rot_amt) | (ppc_result_d >> (rot_amt - 31)));
- uint32_t insert_end = ppc_state.spr[SPR::MQ];
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_a);
- for (int i = 0; i < 32; i++) {
- if (insert_mask & (1 << i)) {
- insert_end &= ~(1 << i);
- insert_end |= (insert_start & (1 << i));
- }
- }
-
- ppc_result_a = insert_end;
- ppc_state.spr[SPR::MQ] = insert_start;
- ppc_changecrf0(ppc_result_a);
ppc_store_result_rega();
}
@@ -532,29 +364,10 @@ void power_sliq() {
ppc_result_a = insert_end & insert_mask;
ppc_state.spr[SPR::MQ] = insert_start;
- ppc_store_result_rega();
-}
-void power_sliqdot() {
- ppc_grab_regssa();
- uint32_t insert_mask = 0;
- unsigned rot_sh = (ppc_cur_instruction >> 11) & 31;
- for (uint32_t i = 31; i > rot_sh; i--) {
- insert_mask |= (1 << i);
- }
- uint32_t insert_start = ((ppc_result_d << rot_sh) | (ppc_result_d >> (rot_sh - 31)));
- uint32_t insert_end = ppc_state.spr[SPR::MQ];
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_a);
- for (int i = 0; i < 32; i++) {
- if (insert_mask & (1 << i)) {
- insert_end &= ~(1 << i);
- insert_end |= (insert_start & (1 << i));
- }
- }
-
- ppc_result_a = insert_end & insert_mask;
- ppc_state.spr[SPR::MQ] = insert_start;
- ppc_changecrf0(ppc_result_a);
ppc_store_result_rega();
}
@@ -577,29 +390,10 @@ void power_slliq() {
ppc_result_a = insert_end;
ppc_state.spr[SPR::MQ] = insert_start;
- ppc_store_result_rega();
-}
-void power_slliqdot() {
- ppc_grab_regssa();
- uint32_t insert_mask = 0;
- unsigned rot_sh = (ppc_cur_instruction >> 11) & 31;
- for (uint32_t i = 31; i > rot_sh; i--) {
- insert_mask |= (1 << i);
- }
- uint32_t insert_start = ((ppc_result_d << rot_sh) | (ppc_result_d >> (32 - rot_sh)));
- uint32_t insert_end = ppc_state.spr[SPR::MQ];
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_a);
- for (int i = 0; i < 32; i++) {
- if (insert_mask & (1 << i)) {
- insert_end &= ~(1 << i);
- insert_end |= (insert_start & (1 << i));
- }
- }
-
- ppc_result_a = insert_end;
- ppc_state.spr[SPR::MQ] = insert_start;
- ppc_changecrf0(ppc_result_a);
ppc_store_result_rega();
}
@@ -607,34 +401,18 @@ void power_sllq() {
LOG_F(WARNING, "OOPS! Placeholder for sllq!!! \n");
}
-void power_sllqdot() {
- LOG_F(WARNING, "OOPS! Placeholder for sllq.!!! \n");
-}
-
void power_slq() {
LOG_F(WARNING, "OOPS! Placeholder for slq!!! \n");
}
-void power_slqdot() {
- LOG_F(WARNING, "OOPS! Placeholder for slq.!!! \n");
-}
-
void power_sraiq() {
LOG_F(WARNING, "OOPS! Placeholder for sraiq!!! \n");
}
-void power_sraiqdot() {
- LOG_F(WARNING, "OOPS! Placeholder for sraiq.!!! \n");
-}
-
void power_sraq() {
LOG_F(WARNING, "OOPS! Placeholder for sraq!!! \n");
}
-void power_sraqdot() {
- LOG_F(WARNING, "OOPS! Placeholder for sraq.!!! \n");
-}
-
void power_sre() {
ppc_grab_regssa();
uint32_t insert_mask = 0;
@@ -645,20 +423,8 @@ void power_sre() {
uint32_t insert_final = ((ppc_result_d >> rot_amt) | (ppc_result_d << (32 - rot_amt)));
ppc_state.spr[SPR::MQ] = insert_final & insert_mask;
ppc_result_a = insert_final;
- ppc_store_result_rega();
-}
-
-void power_sredot() {
- ppc_grab_regssa();
- uint32_t insert_mask = 0;
- uint32_t rot_amt = ppc_result_b & 31;
- for (uint32_t i = 31; i > rot_amt; i--) {
- insert_mask |= (1 << i);
- }
- uint32_t insert_final = ((ppc_result_d >> rot_amt) | (ppc_result_d << (32 - rot_amt)));
- ppc_state.spr[SPR::MQ] = insert_final & insert_mask;
- ppc_result_a = insert_final;
- ppc_changecrf0(ppc_result_a);
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_a);
ppc_store_result_rega();
}
@@ -666,10 +432,6 @@ void power_srea() {
LOG_F(WARNING, "OOPS! Placeholder for srea!!! \n");
}
-void power_sreadot() {
- LOG_F(WARNING, "OOPS! Placeholder for srea.!!! \n");
-}
-
void power_sreq() {
ppc_grab_regssa();
uint32_t insert_mask = 0;
@@ -689,29 +451,10 @@ void power_sreq() {
ppc_result_a = insert_end;
ppc_state.spr[SPR::MQ] = insert_start;
- ppc_store_result_rega();
-}
-void power_sreqdot() {
- ppc_grab_regssa();
- uint32_t insert_mask = 0;
- unsigned rot_sh = ppc_result_b & 31;
- for (uint32_t i = 31; i > rot_sh; i--) {
- insert_mask |= (1 << i);
- }
- uint32_t insert_start = ((ppc_result_d >> rot_sh) | (ppc_result_d << (32 - rot_sh)));
- uint32_t insert_end = ppc_state.spr[SPR::MQ];
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_a);
- for (int i = 0; i < 32; i++) {
- if (insert_mask & (1 << i)) {
- insert_end &= ~(1 << i);
- insert_end |= (insert_start & (1 << i));
- }
- }
-
- ppc_result_a = insert_end;
- ppc_state.spr[SPR::MQ] = insert_start;
- ppc_changecrf0(ppc_result_a);
ppc_store_result_rega();
}
@@ -734,29 +477,10 @@ void power_sriq() {
ppc_result_a = insert_end;
ppc_state.spr[SPR::MQ] = insert_start;
- ppc_store_result_rega();
-}
-void power_sriqdot() {
- ppc_grab_regssa();
- uint32_t insert_mask = 0;
- unsigned rot_sh = (ppc_cur_instruction >> 11) & 31;
- for (uint32_t i = 31; i > rot_sh; i--) {
- insert_mask |= (1 << i);
- }
- uint32_t insert_start = ((ppc_result_d >> rot_sh) | (ppc_result_d << (32 - rot_sh)));
- uint32_t insert_end = ppc_state.spr[SPR::MQ];
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_a);
- for (int i = 0; i < 32; i++) {
- if (insert_mask & (1 << i)) {
- insert_end &= ~(1 << i);
- insert_end |= (insert_start & (1 << i));
- }
- }
-
- ppc_result_a = insert_end;
- ppc_state.spr[SPR::MQ] = insert_start;
- ppc_changecrf0(ppc_result_a);
ppc_store_result_rega();
}
@@ -764,22 +488,10 @@ void power_srliq() {
LOG_F(WARNING, "OOPS! Placeholder for slriq!!! \n");
}
-void power_srliqdot() {
- LOG_F(WARNING, "OOPS! Placeholder for slriq.!!! \n");
-}
-
void power_srlq() {
LOG_F(WARNING, "OOPS! Placeholder for slrq!!! \n");
}
-void power_srlqdot() {
- LOG_F(WARNING, "OOPS! Placeholder for slrq.!!! \n");
-}
-
void power_srq() {
LOG_F(WARNING, "OOPS! Placeholder for srq!!! \n");
-}
-
-void power_srqdot() {
- LOG_F(WARNING, "OOPS! Placeholder for srq.!!! \n");
-}
+}
\ No newline at end of file
diff --git a/cpu/ppc/ppcemu.h b/cpu/ppc/ppcemu.h
index 54f595d..64de5bd 100644
--- a/cpu/ppc/ppcemu.h
+++ b/cpu/ppc/ppcemu.h
@@ -226,10 +226,12 @@ extern bool grab_return;
extern bool power_on;
extern bool is_601; // For PowerPC 601 Emulation
-extern bool is_gekko; // For GameCube Emulation
extern bool is_altivec; // For Altivec Emulation
extern bool is_64bit; // For PowerPC G5 Emulation
+extern bool rc_flag; // Record flag
+extern bool oe_flag; // Overflow flag
+
// Important Addressing Integers
extern uint32_t ppc_cur_instruction;
extern uint32_t ppc_effective_address;
@@ -245,6 +247,11 @@ extern void ppc_cpu_init(MemCtrlBase* mem_ctrl, uint32_t proc_version);
extern void ppc_mmu_init();
void ppc_illegalop();
+void ppc_illegalsubop19();
+void ppc_illegalsubop31();
+void ppc_illegalsubop59();
+void ppc_illegalsubop63();
+
void ppc_opcode4();
void ppc_opcode16();
void ppc_opcode18();
@@ -253,6 +260,8 @@ void ppc_opcode31();
void ppc_opcode59();
void ppc_opcode63();
+void initialize_ppc_opcode_tables();
+
extern bool ppc_confirm_inf_nan(uint64_t input_a, uint64_t input_b, bool is_single, uint32_t op);
extern double fp_return_double(uint32_t reg);
extern uint64_t fp_return_uint64(uint32_t reg);
@@ -286,8 +295,6 @@ extern void ppc_store_dfpresult(bool int_rep);
void ppc_changecrf0(uint32_t set_result);
void ppc_fp_changecrf1();
-void ppc_tbr_update();
-
/* Exception handlers. */
[[noreturn]] void ppc_exception_handler(Except_Type exception_type, uint32_t srr1_bits);
[[noreturn]] void dbg_exception_handler(Except_Type exception_type, uint32_t srr1_bits);
@@ -311,33 +318,15 @@ extern void ppc_crxor();
extern void ppc_isync();
extern void ppc_add();
-extern void ppc_adddot();
-extern void ppc_addo();
-extern void ppc_addodot();
extern void ppc_addc();
-extern void ppc_addcdot();
-extern void ppc_addco();
-extern void ppc_addcodot();
extern void ppc_adde();
-extern void ppc_addedot();
-extern void ppc_addeo();
-extern void ppc_addeodot();
extern void ppc_addme();
-extern void ppc_addmedot();
-extern void ppc_addmeo();
-extern void ppc_addmeodot();
extern void ppc_addze();
-extern void ppc_addzedot();
-extern void ppc_addzeo();
-extern void ppc_addzeodot();
extern void ppc_and();
-extern void ppc_anddot();
extern void ppc_andc();
-extern void ppc_andcdot();
extern void ppc_cmp();
extern void ppc_cmpl();
extern void ppc_cntlzw();
-extern void ppc_cntlzwdot();
extern void ppc_dcbf();
extern void ppc_dcbi();
extern void ppc_dcbst();
@@ -345,20 +334,11 @@ extern void ppc_dcbt();
extern void ppc_dcbtst();
extern void ppc_dcbz();
extern void ppc_divw();
-extern void ppc_divwdot();
-extern void ppc_divwo();
-extern void ppc_divwodot();
extern void ppc_divwu();
-extern void ppc_divwudot();
-extern void ppc_divwuo();
-extern void ppc_divwuodot();
extern void ppc_eieio();
extern void ppc_eqv();
-extern void ppc_eqvdot();
extern void ppc_extsb();
-extern void ppc_extsbdot();
extern void ppc_extsh();
-extern void ppc_extshdot();
extern void ppc_icbi();
extern void ppc_mftb();
extern void ppc_lhzux();
@@ -375,33 +355,17 @@ extern void ppc_lwzx();
extern void ppc_mcrxr();
extern void ppc_mfcr();
extern void ppc_mulhwu();
-extern void ppc_mulhwudot();
extern void ppc_mulhw();
-extern void ppc_mulhwdot();
extern void ppc_mullw();
-extern void ppc_mullwdot();
-extern void ppc_mullwo();
-extern void ppc_mullwodot();
extern void ppc_nand();
-extern void ppc_nanddot();
extern void ppc_neg();
-extern void ppc_negdot();
-extern void ppc_nego();
-extern void ppc_negodot();
extern void ppc_nor();
-extern void ppc_nordot();
extern void ppc_or();
-extern void ppc_ordot();
extern void ppc_orc();
-extern void ppc_orcdot();
extern void ppc_slw();
-extern void ppc_slwdot();
extern void ppc_srw();
-extern void ppc_srwdot();
extern void ppc_sraw();
-extern void ppc_srawdot();
extern void ppc_srawi();
-extern void ppc_srawidot();
extern void ppc_stbx();
extern void ppc_stbux();
extern void ppc_stfiwx();
@@ -413,25 +377,10 @@ extern void ppc_stwcx();
extern void ppc_stwux();
extern void ppc_stwbrx();
extern void ppc_subf();
-extern void ppc_subfdot();
-extern void ppc_subfo();
-extern void ppc_subfodot();
extern void ppc_subfc();
-extern void ppc_subfcdot();
-extern void ppc_subfco();
-extern void ppc_subfcodot();
extern void ppc_subfe();
-extern void ppc_subfedot();
-extern void ppc_subfeo();
-extern void ppc_subfeodot();
extern void ppc_subfme();
-extern void ppc_subfmedot();
-extern void ppc_subfmeo();
-extern void ppc_subfmeodot();
extern void ppc_subfze();
-extern void ppc_subfzedot();
-extern void ppc_subfzeo();
-extern void ppc_subfzeodot();
extern void ppc_sync();
extern void ppc_tlbia();
extern void ppc_tlbie();
@@ -440,7 +389,6 @@ extern void ppc_tlbld();
extern void ppc_tlbsync();
extern void ppc_tw();
extern void ppc_xor();
-extern void ppc_xordot();
extern void ppc_lswi();
extern void ppc_lswx();
@@ -561,105 +509,38 @@ extern void ppc_frsp();
extern void ppc_fctiw();
extern void ppc_fctiwz();
-extern void ppc_fadddot();
-extern void ppc_fsubdot();
-extern void ppc_fmultdot();
-extern void ppc_fdivdot();
-extern void ppc_fmadddot();
-extern void ppc_fmsubdot();
-extern void ppc_fnmadddot();
-extern void ppc_fnmsubdot();
-extern void ppc_fabsdot();
-extern void ppc_fnabsdot();
-extern void ppc_fnegdot();
-extern void ppc_fseldot();
-extern void ppc_fsqrtdot();
-extern void ppc_frsqrtedot();
-extern void ppc_frspdot();
-extern void ppc_fctiwdot();
-extern void ppc_fctiwzdot();
-
-extern void ppc_fresdot();
-extern void ppc_faddsdot();
-extern void ppc_fsubsdot();
-extern void ppc_fmultsdot();
-extern void ppc_fdivsdot();
-extern void ppc_fmaddsdot();
-extern void ppc_fmsubsdot();
-extern void ppc_fnmaddsdot();
-extern void ppc_fnmsubsdot();
-extern void ppc_fsqrtsdot();
-
extern void ppc_fcmpo();
extern void ppc_fcmpu();
// Power-specific instructions
extern void power_abs();
-extern void power_absdot();
-extern void power_abso();
-extern void power_absodot();
extern void power_clcs();
-extern void power_clcsdot();
extern void power_div();
-extern void power_divdot();
-extern void power_divo();
-extern void power_divodot();
extern void power_divs();
-extern void power_divsdot();
-extern void power_divso();
-extern void power_divsodot();
extern void power_doz();
-extern void power_dozdot();
-extern void power_dozo();
-extern void power_dozodot();
extern void power_dozi();
extern void power_lscbx();
-extern void power_lscbxdot();
extern void power_maskg();
-extern void power_maskgdot();
extern void power_maskir();
-extern void power_maskirdot();
extern void power_mul();
-extern void power_muldot();
-extern void power_mulo();
-extern void power_mulodot();
extern void power_nabs();
-extern void power_nabsdot();
-extern void power_nabso();
-extern void power_nabsodot();
extern void power_rlmi();
extern void power_rrib();
-extern void power_rribdot();
extern void power_sle();
-extern void power_sledot();
extern void power_sleq();
-extern void power_sleqdot();
extern void power_sliq();
-extern void power_sliqdot();
extern void power_slliq();
-extern void power_slliqdot();
extern void power_sllq();
-extern void power_sllqdot();
extern void power_slq();
-extern void power_slqdot();
extern void power_sraiq();
-extern void power_sraiqdot();
extern void power_sraq();
-extern void power_sraqdot();
extern void power_sre();
-extern void power_sredot();
extern void power_srea();
-extern void power_sreadot();
extern void power_sreq();
-extern void power_sreqdot();
extern void power_sriq();
-extern void power_sriqdot();
extern void power_srliq();
-extern void power_srliqdot();
extern void power_srlq();
-extern void power_srlqdot();
extern void power_srq();
-extern void power_srqdot();
// Gekko instructions
extern void ppc_psq_l();
diff --git a/cpu/ppc/ppcexec.cpp b/cpu/ppc/ppcexec.cpp
index 066ccfc..582d202 100644
--- a/cpu/ppc/ppcexec.cpp
+++ b/cpu/ppc/ppcexec.cpp
@@ -42,6 +42,9 @@ bool power_on = 1;
SetPRS ppc_state;
+bool rc_flag = 0; // Record flag
+bool oe_flag = 0; // Overflow flag
+
bool grab_exception;
bool grab_return;
bool grab_breakpoint;
@@ -86,327 +89,12 @@ static PPCOpcode SubOpcode16Grabber[] = {ppc_bc, ppc_bcl, ppc_bca, ppc_bcla};
static PPCOpcode SubOpcode18Grabber[] = {ppc_b, ppc_bl, ppc_ba, ppc_bla};
-/** General conditional register instructions decoding table. */
-static std::unordered_map SubOpcode19Grabber = {
- {32, &ppc_bclr},
- {33, &ppc_bclrl},
- {66, &ppc_crnor},
- {100, &ppc_rfi},
- {258, &ppc_crandc},
- {300, &ppc_isync},
- {386, &ppc_crxor},
- {450, &ppc_crnand},
- {514, &ppc_crand},
- {578, &ppc_creqv},
- {834, &ppc_crorc},
- {898, &ppc_cror},
- {1056, &ppc_bcctr},
- {1057, &ppc_bcctrl}};
+/** Instructions decoding tables for integer,
+ single floating-point, and double-floating point ops respectively */
-/** General integer instructions decoding table. */
-static std::unordered_map SubOpcode31Grabber = {
- {0, &ppc_cmp}, {8, &ppc_tw},
- {16, &ppc_subfc}, {17, &ppc_subfcdot},
- {20, &ppc_addc}, {21, &ppc_addcdot},
- {22, &ppc_mulhwu}, {23, &ppc_mulhwudot},
- {38, &ppc_mfcr}, {40, &ppc_lwarx},
- {46, &ppc_lwzx}, {48, &ppc_slw},
- {49, &ppc_slwdot}, {52, &ppc_cntlzw},
- {53, &ppc_cntlzwdot}, {56, &ppc_and},
- {57, &ppc_anddot}, {58, &power_maskg},
- {59, &power_maskgdot}, {64, &ppc_cmpl},
- {80, &ppc_subf}, {81, &ppc_subfdot},
- {108, &ppc_dcbst}, {110, &ppc_lwzux},
- {120, &ppc_andc}, {121, &ppc_andcdot},
- {150, &ppc_mulhw}, {151, &ppc_mulhwdot},
- {166, &ppc_mfmsr}, {172, &ppc_dcbf},
- {174, &ppc_lbzx}, {208, &ppc_neg},
- {209, &ppc_negdot}, {214, &power_mul},
- {215, &power_muldot}, {238, &ppc_lbzux},
- {248, &ppc_nor}, {249, &ppc_nordot},
- {272, &ppc_subfe}, {273, &ppc_subfedot},
- {276, &ppc_adde}, {277, &ppc_addedot},
- {288, &ppc_mtcrf}, {292, &ppc_mtmsr},
- {301, &ppc_stwcx}, {302, &ppc_stwx},
- {304, &power_slq}, {305, &power_slqdot},
- {306, &power_sle}, {307, &power_sledot},
- {366, &ppc_stwux}, {368, &power_sliq},
- {400, &ppc_subfze}, {401, &ppc_subfzedot},
- {404, &ppc_addze}, {405, &ppc_addzedot},
- {420, &ppc_mtsr}, {430, &ppc_stbx},
- {432, &power_sllq}, {433, &power_sllqdot},
- {434, &power_sleq}, {436, &power_sleqdot},
- {464, &ppc_subfme}, {465, &ppc_subfmedot},
- {468, &ppc_addme}, {469, &ppc_addmedot},
- {470, &ppc_mullw}, {471, &ppc_mullwdot},
- {484, &ppc_mtsrin}, {492, &ppc_dcbtst},
- {494, &ppc_stbux}, {496, &power_slliq},
- {497, &power_slliqdot}, {528, &power_doz},
- {529, &power_dozdot}, {532, &ppc_add},
- {533, &ppc_adddot}, {554, &power_lscbx},
- {555, &power_lscbxdot}, {556, &ppc_dcbt},
- {558, &ppc_lhzx}, {568, &ppc_eqv},
- {569, &ppc_eqvdot}, {612, &ppc_tlbie},
- {622, &ppc_lhzux}, {632, &ppc_xor},
- {633, &ppc_xordot}, {662, &power_div},
- {663, &power_divdot}, {678, &ppc_mfspr},
- {686, &ppc_lhax}, {720, &power_abs},
- {721, &power_absdot}, {726, &power_divs},
- {727, &power_divsdot}, {740, &ppc_tlbia},
- {742, &ppc_mftb}, {750, &ppc_lhaux},
- {814, &ppc_sthx}, {824, &ppc_orc},
- {825, &ppc_orcdot}, {878, &ppc_sthx},
- {888, &ppc_or}, {889, &ppc_ordot},
- {918, &ppc_divwu}, {919, &ppc_divwudot},
- {934, &ppc_mtspr}, {940, &ppc_dcbi},
- {952, &ppc_nand}, {953, &ppc_nanddot},
- {976, &power_nabs}, {977, &power_nabsdot},
- {982, &ppc_divw}, {983, &ppc_divwdot},
- {1024, &ppc_mcrxr}, {1040, &ppc_subfco},
- {1041, &ppc_subfcodot}, {1044, &ppc_addco},
- {1045, &ppc_addcodot}, {1062, &power_clcs},
- {1063, &power_clcsdot}, {1066, &ppc_lswx},
- {1068, &ppc_lwbrx}, {1070, &ppc_lfsx},
- {1072, &ppc_srw}, {1073, &ppc_srwdot},
- {1074, &power_rrib}, {1075, &power_rribdot},
- {1082, &power_maskir}, {1083, &power_maskirdot},
- {1104, &ppc_subfo}, {1105, &ppc_subfodot},
- {1132, &ppc_tlbsync}, {1134, &ppc_lfsux},
- {1190, &ppc_mfsr}, {1194, &ppc_lswi},
- {1196, &ppc_sync}, {1198, &ppc_lfdx},
- {1232, &ppc_nego}, {1233, &ppc_negodot},
- {1238, &power_mulo}, {1239, &power_mulodot},
- {1262, &ppc_lfdux}, {1296, &ppc_subfeo},
- {1297, &ppc_subfeodot}, {1300, &ppc_addeo},
- {1301, &ppc_addeodot}, {1318, &ppc_mfsrin},
- {1322, &ppc_stswx}, {1324, &ppc_stwbrx},
- {1326, &ppc_stfsx}, {1328, &power_srq},
- {1329, &power_srqdot}, {1330, &power_sre},
- {1331, &power_sredot}, {1390, &ppc_stfsux},
- {1392, &power_sriq}, {1393, &power_sriqdot},
- {1424, &ppc_subfzeo}, {1425, &ppc_subfzeodot},
- {1428, &ppc_addzeo}, {1429, &ppc_addzeodot},
- {1450, &ppc_stswi}, {1454, &ppc_stfdx},
- {1456, &power_srlq}, {1457, &power_srlqdot},
- {1458, &power_sreq}, {1459, &power_sreqdot},
- {1488, &ppc_subfmeo}, {1489, &ppc_subfmeodot},
- {1492, &ppc_addmeo}, {1493, &ppc_addmeodot},
- {1494, &ppc_mullwo}, {1495, &ppc_mullwodot},
- {1518, &ppc_stfdux}, {1520, &power_srliq},
- {1521, &power_srliqdot}, {1552, &power_dozo},
- {1553, &power_dozodot}, {1556, &ppc_addo},
- {1557, &ppc_addodot}, {1580, &ppc_lhbrx},
- {1584, &ppc_sraw}, {1585, &ppc_srawdot},
- {1648, &ppc_srawi}, {1649, &ppc_srawidot},
- {1686, &power_divo}, {1687, &power_divodot},
- {1708, &ppc_eieio}, {1744, &power_abso},
- {1745, &power_absodot}, {1750, &power_divso},
- {1751, &power_divsodot}, {1836, &ppc_sthbrx},
- {1840, &power_sraq}, {1841, &power_sraqdot},
- {1842, &power_srea}, {1843, &power_sreadot},
- {1844, &ppc_extsh}, {1845, &ppc_extshdot},
- {1904, &power_sraiq}, {1905, &power_sraiqdot},
- {1908, &ppc_extsb}, {1909, &ppc_extsbdot},
- {1942, &ppc_divwuo}, {1943, &ppc_divwuodot},
- {1956, &ppc_tlbld}, {1964, &ppc_icbi},
- {1966, &ppc_stfiwx}, {2000, &power_nabso},
- {2001, &power_nabsodot}, {2006, &ppc_divwo},
- {2007, &ppc_divwodot}, {2020, &ppc_tlbli},
- {2028, &ppc_dcbz}};
-
-/** Single-precision floating-point instructions decoding table. */
-static std::unordered_map SubOpcode59Grabber = {
- {36, &ppc_fdivs}, {37, &ppc_fdivsdot}, {40, &ppc_fsubs}, {41, &ppc_fsubsdot},
- {42, &ppc_fadds}, {43, &ppc_faddsdot}, {44, &ppc_fsqrts}, {45, &ppc_fsqrtsdot},
- {48, &ppc_fres}, {49, &ppc_fresdot}, {50, &ppc_fmults}, {51, &ppc_fmultsdot},
- {56, &ppc_fmsubs}, {57, &ppc_fmsubsdot}, {58, &ppc_fmadds}, {59, &ppc_fmaddsdot},
- {60, &ppc_fnmsubs}, {61, &ppc_fnmsubsdot}, {62, &ppc_fnmadds}, {63, &ppc_fnmaddsdot},
- {114, &ppc_fmults}, {115, &ppc_fmultsdot}, {120, &ppc_fmsubs}, {121, &ppc_fmsubsdot},
- {122, &ppc_fmadds}, {123, &ppc_fmadds}, {124, &ppc_fnmsubs}, {125, &ppc_fnmsubsdot},
- {126, &ppc_fnmadds}, {127, &ppc_fnmaddsdot}, {178, &ppc_fmults}, {179, &ppc_fmultsdot},
- {184, &ppc_fmsubs}, {185, &ppc_fmsubsdot}, {186, &ppc_fmadds}, {187, &ppc_fmaddsdot},
- {188, &ppc_fnmsubs}, {189, &ppc_fnmsubsdot}, {190, &ppc_fnmadds}, {191, &ppc_fnmaddsdot},
- {242, &ppc_fmults}, {243, &ppc_fmultsdot}, {248, &ppc_fmsubs}, {249, &ppc_fmsubsdot},
- {250, &ppc_fmadds}, {251, &ppc_fmaddsdot}, {252, &ppc_fnmsubs}, {253, &ppc_fnmsubsdot},
- {254, &ppc_fnmadds}, {255, &ppc_fnmaddsdot}, {306, &ppc_fmults}, {307, &ppc_fmultsdot},
- {312, &ppc_fmsubs}, {313, &ppc_fmsubsdot}, {314, &ppc_fmadds}, {315, &ppc_fmaddsdot},
- {316, &ppc_fnmsubs}, {317, &ppc_fnmsubsdot}, {318, &ppc_fnmadds}, {319, &ppc_fnmaddsdot},
- {370, &ppc_fmults}, {371, &ppc_fmultsdot}, {376, &ppc_fmsubs}, {377, &ppc_fmsubsdot},
- {378, &ppc_fmadds}, {379, &ppc_fmaddsdot}, {380, &ppc_fnmsubs}, {381, &ppc_fnmsubsdot},
- {382, &ppc_fnmadds}, {383, &ppc_fnmaddsdot}, {434, &ppc_fmults}, {435, &ppc_fmultsdot},
- {440, &ppc_fmsubs}, {441, &ppc_fmsubsdot}, {442, &ppc_fmadds}, {443, &ppc_fmaddsdot},
- {444, &ppc_fnmsubs}, {445, &ppc_fnmsubsdot}, {446, &ppc_fnmadds}, {447, &ppc_fnmaddsdot},
- {498, &ppc_fmults}, {499, &ppc_fmultsdot}, {504, &ppc_fmsubs}, {505, &ppc_fmsubsdot},
- {506, &ppc_fmadds}, {507, &ppc_fmaddsdot}, {508, &ppc_fnmsubs}, {509, &ppc_fnmsubsdot},
- {510, &ppc_fnmadds}, {511, &ppc_fnmaddsdot}, {562, &ppc_fmults}, {563, &ppc_fmultsdot},
- {568, &ppc_fmsubs}, {569, &ppc_fmsubsdot}, {570, &ppc_fmadds}, {571, &ppc_fmaddsdot},
- {572, &ppc_fnmsubs}, {573, &ppc_fnmsubsdot}, {574, &ppc_fnmadds}, {575, &ppc_fnmaddsdot},
- {626, &ppc_fmults}, {627, &ppc_fmultsdot}, {632, &ppc_fmsubs}, {633, &ppc_fmsubsdot},
- {634, &ppc_fmadds}, {635, &ppc_fmaddsdot}, {636, &ppc_fnmsubs}, {637, &ppc_fnmsubsdot},
- {638, &ppc_fnmadds}, {639, &ppc_fnmaddsdot}, {690, &ppc_fmults}, {691, &ppc_fmultsdot},
- {696, &ppc_fmsubs}, {697, &ppc_fmsubsdot}, {698, &ppc_fmadds}, {699, &ppc_fmaddsdot},
- {700, &ppc_fnmsubs}, {701, &ppc_fnmsubsdot}, {702, &ppc_fnmadds}, {703, &ppc_fnmaddsdot},
- {754, &ppc_fmults}, {755, &ppc_fmultsdot}, {760, &ppc_fmsubs}, {761, &ppc_fmsubsdot},
- {762, &ppc_fmadds}, {763, &ppc_fmaddsdot}, {764, &ppc_fnmsubs}, {765, &ppc_fnmsubsdot},
- {766, &ppc_fnmadds}, {767, &ppc_fnmaddsdot}, {818, &ppc_fmults}, {819, &ppc_fmultsdot},
- {824, &ppc_fmsubs}, {825, &ppc_fmsubsdot}, {826, &ppc_fmadds}, {827, &ppc_fmaddsdot},
- {828, &ppc_fnmsubs}, {829, &ppc_fnmsubsdot}, {830, &ppc_fnmadds}, {831, &ppc_fnmaddsdot},
- {882, &ppc_fmults}, {883, &ppc_fmultsdot}, {888, &ppc_fmsubs}, {889, &ppc_fmsubsdot},
- {890, &ppc_fmadds}, {891, &ppc_fmaddsdot}, {892, &ppc_fnmsubs}, {893, &ppc_fnmsubsdot},
- {894, &ppc_fnmadds}, {895, &ppc_fnmaddsdot}, {946, &ppc_fmults}, {947, &ppc_fmultsdot},
- {952, &ppc_fmsubs}, {953, &ppc_fmsubsdot}, {954, &ppc_fmadds}, {955, &ppc_fmaddsdot},
- {957, &ppc_fnmsubs}, {958, &ppc_fnmsubsdot}, {958, &ppc_fnmadds}, {959, &ppc_fnmaddsdot},
- {1010, &ppc_fmults}, {1011, &ppc_fmultsdot}, {1016, &ppc_fmsubs}, {1017, &ppc_fmsubsdot},
- {1018, &ppc_fmadds}, {1019, &ppc_fmaddsdot}, {1020, &ppc_fnmsubs}, {1021, &ppc_fnmsubsdot},
- {1022, &ppc_fnmadds}, {1023, &ppc_fnmaddsdot}, {1074, &ppc_fmults}, {1075, &ppc_fmultsdot},
- {1080, &ppc_fmsubs}, {1081, &ppc_fmsubsdot}, {1082, &ppc_fmadds}, {1083, &ppc_fmaddsdot},
- {1084, &ppc_fnmsubs}, {1085, &ppc_fnmsubsdot}, {1086, &ppc_fnmadds}, {1087, &ppc_fnmaddsdot},
- {1138, &ppc_fmults}, {1139, &ppc_fmultsdot}, {1144, &ppc_fmsubs}, {1145, &ppc_fmsubsdot},
- {1146, &ppc_fmadds}, {1147, &ppc_fmaddsdot}, {1148, &ppc_fnmsubs}, {1149, &ppc_fnmsubsdot},
- {1150, &ppc_fnmadds}, {1151, &ppc_fnmaddsdot}, {1202, &ppc_fmults}, {1203, &ppc_fmultsdot},
- {1208, &ppc_fmsubs}, {1209, &ppc_fmsubsdot}, {1210, &ppc_fmadds}, {1211, &ppc_fmaddsdot},
- {1212, &ppc_fnmsubs}, {1213, &ppc_fnmsubsdot}, {1214, &ppc_fnmadds}, {1215, &ppc_fnmaddsdot},
- {1266, &ppc_fmults}, {1267, &ppc_fmultsdot}, {1272, &ppc_fmsubs}, {1273, &ppc_fmsubsdot},
- {1274, &ppc_fmadds}, {1275, &ppc_fmaddsdot}, {1276, &ppc_fnmsubs}, {1277, &ppc_fnmsubsdot},
- {1278, &ppc_fnmadds}, {1279, &ppc_fnmaddsdot}, {1330, &ppc_fmults}, {1331, &ppc_fmultsdot},
- {1336, &ppc_fmsubs}, {1337, &ppc_fmsubsdot}, {1338, &ppc_fmadds}, {1339, &ppc_fmaddsdot},
- {1340, &ppc_fnmsubs}, {1341, &ppc_fnmsubsdot}, {1342, &ppc_fnmadds}, {1343, &ppc_fnmaddsdot},
- {1394, &ppc_fmults}, {1395, &ppc_fmultsdot}, {1400, &ppc_fmsubs}, {1401, &ppc_fmsubsdot},
- {1402, &ppc_fmadds}, {1403, &ppc_fmaddsdot}, {1404, &ppc_fnmsubs}, {1405, &ppc_fnmsubsdot},
- {1406, &ppc_fnmadds}, {1407, &ppc_fnmaddsdot}, {1458, &ppc_fmults}, {1459, &ppc_fmultsdot},
- {1464, &ppc_fmsubs}, {1465, &ppc_fmsubsdot}, {1466, &ppc_fmadds}, {1467, &ppc_fmaddsdot},
- {1468, &ppc_fnmsubs}, {1469, &ppc_fnmsubsdot}, {1470, &ppc_fnmadds}, {1471, &ppc_fnmaddsdot},
- {1522, &ppc_fmults}, {1523, &ppc_fmultsdot}, {1528, &ppc_fmsubs}, {1529, &ppc_fmsubsdot},
- {1530, &ppc_fmadds}, {1531, &ppc_fmaddsdot}, {1532, &ppc_fnmsubs}, {1533, &ppc_fnmsubsdot},
- {1534, &ppc_fnmadds}, {1535, &ppc_fnmaddsdot}, {1586, &ppc_fmults}, {1587, &ppc_fmultsdot},
- {1592, &ppc_fmsubs}, {1593, &ppc_fmsubsdot}, {1594, &ppc_fmadds}, {1595, &ppc_fmaddsdot},
- {1596, &ppc_fnmsubs}, {1597, &ppc_fnmsubsdot}, {1598, &ppc_fnmadds}, {1599, &ppc_fnmaddsdot},
- {1650, &ppc_fmults}, {1651, &ppc_fmultsdot}, {1656, &ppc_fmsubs}, {1657, &ppc_fmsubsdot},
- {1658, &ppc_fmadds}, {1659, &ppc_fmaddsdot}, {1660, &ppc_fnmsubs}, {1661, &ppc_fnmsubsdot},
- {1662, &ppc_fnmadds}, {1663, &ppc_fnmaddsdot}, {1714, &ppc_fmults}, {1715, &ppc_fmultsdot},
- {1720, &ppc_fmsubs}, {1721, &ppc_fmsubsdot}, {1722, &ppc_fmadds}, {1723, &ppc_fmaddsdot},
- {1724, &ppc_fnmsubs}, {1725, &ppc_fnmsubsdot}, {1726, &ppc_fnmadds}, {1727, &ppc_fnmaddsdot},
- {1778, &ppc_fmults}, {1779, &ppc_fmultsdot}, {1784, &ppc_fmsubs}, {1785, &ppc_fmsubsdot},
- {1786, &ppc_fmadds}, {1787, &ppc_fmaddsdot}, {1788, &ppc_fnmsubs}, {1789, &ppc_fnmsubsdot},
- {1790, &ppc_fnmadds}, {1791, &ppc_fnmaddsdot}, {1842, &ppc_fmults}, {1843, &ppc_fmultsdot},
- {1848, &ppc_fmsubs}, {1849, &ppc_fmsubsdot}, {1850, &ppc_fmadds}, {1851, &ppc_fmaddsdot},
- {1852, &ppc_fnmsubs}, {1853, &ppc_fnmsubsdot}, {1854, &ppc_fnmadds}, {1855, &ppc_fnmaddsdot},
- {1906, &ppc_fmults}, {1907, &ppc_fmultsdot}, {1912, &ppc_fmsubs}, {1913, &ppc_fmsubsdot},
- {1914, &ppc_fmadds}, {1915, &ppc_fmaddsdot}, {1916, &ppc_fnmsubs}, {1917, &ppc_fnmsubsdot},
- {1918, &ppc_fnmadds}, {1919, &ppc_fnmaddsdot}, {1970, &ppc_fmults}, {1971, &ppc_fmultsdot},
- {1976, &ppc_fmsubs}, {1977, &ppc_fmsubsdot}, {1978, &ppc_fmadds}, {1979, &ppc_fmaddsdot},
- {1980, &ppc_fnmsubs}, {1981, &ppc_fnmsubsdot}, {1982, &ppc_fnmadds}, {1983, &ppc_fnmaddsdot},
- {2034, &ppc_fmults}, {2035, &ppc_fmultsdot}, {2040, &ppc_fmsubs}, {2041, &ppc_fmsubsdot},
- {2042, &ppc_fmadds}, {2043, &ppc_fmaddsdot}, {2044, &ppc_fnmsubs}, {2045, &ppc_fnmsubsdot},
- {2046, &ppc_fnmadds}, {2047, &ppc_fnmaddsdot}};
-
-/** Double-precision floating-point instructions decoding table. */
-static std::unordered_map SubOpcode63Grabber = {
- {0, &ppc_fcmpu}, {24, &ppc_frsp}, {25, &ppc_frspdot}, {28, &ppc_fctiw},
- {29, &ppc_fctiwdot}, {30, &ppc_fctiwz}, {31, &ppc_fctiwzdot}, {36, &ppc_fdiv},
- {37, &ppc_fdivdot}, {40, &ppc_fsub}, {41, &ppc_fsubdot}, {42, &ppc_fadd},
- {43, &ppc_fadddot}, {44, &ppc_fsqrt}, {45, &ppc_fsqrtdot}, {46, &ppc_fsel},
- {47, &ppc_fseldot}, {50, &ppc_fmult}, {51, &ppc_fmultdot}, {52, &ppc_frsqrte},
- {53, &ppc_frsqrtedot}, {56, &ppc_fmsub}, {57, &ppc_fmsubdot}, {58, &ppc_fmadd},
- {59, &ppc_fmadddot}, {60, &ppc_fnmsub}, {61, &ppc_fnmsubdot}, {62, &ppc_fnmadd},
- {63, &ppc_fnmadddot}, {64, &ppc_fcmpo}, {76, &ppc_mtfsb1}, {77, &ppc_mtfsb1dot},
- {80, &ppc_fneg}, {81, &ppc_fnegdot}, {110, &ppc_fsel}, {111, &ppc_fseldot},
- {114, &ppc_fmult}, {115, &ppc_fmultdot}, {120, &ppc_fmsub}, {121, &ppc_fmsubdot},
- {122, &ppc_fmadd}, {123, &ppc_fmadd}, {124, &ppc_fnmsub}, {125, &ppc_fnmsubdot},
- {126, &ppc_fnmadd}, {127, &ppc_fnmadddot}, {128, &ppc_mcrfs}, {140, &ppc_mtfsb0},
- {141, &ppc_mtfsb0dot}, {144, &ppc_fmr}, {174, &ppc_fsel}, {175, &ppc_fseldot},
- {178, &ppc_fmult}, {179, &ppc_fmultdot}, {184, &ppc_fmsub}, {185, &ppc_fmsubdot},
- {186, &ppc_fmadd}, {187, &ppc_fmadddot}, {188, &ppc_fnmsub}, {189, &ppc_fnmsubdot},
- {190, &ppc_fnmadd}, {191, &ppc_fnmadddot}, {238, &ppc_fsel}, {239, &ppc_fseldot},
- {242, &ppc_fmult}, {243, &ppc_fmultdot}, {248, &ppc_fmsub}, {249, &ppc_fmsubdot},
- {250, &ppc_fmadd}, {251, &ppc_fmadddot}, {252, &ppc_fnmsub}, {253, &ppc_fnmsubdot},
- {254, &ppc_fnmadd}, {255, &ppc_fnmadddot}, {268, &ppc_mtfsfi}, {272, &ppc_fnabs},
- {273, &ppc_fnabsdot}, {302, &ppc_fsel}, {303, &ppc_fseldot}, {306, &ppc_fmult},
- {307, &ppc_fmultdot}, {312, &ppc_fmsub}, {313, &ppc_fmsubdot}, {314, &ppc_fmadd},
- {315, &ppc_fmadddot}, {316, &ppc_fnmsub}, {317, &ppc_fnmsubdot}, {318, &ppc_fnmadd},
- {319, &ppc_fnmadddot}, {366, &ppc_fsel}, {367, &ppc_fseldot}, {370, &ppc_fmult},
- {371, &ppc_fmultdot}, {376, &ppc_fmsub}, {377, &ppc_fmsubdot}, {378, &ppc_fmadd},
- {379, &ppc_fmadddot}, {380, &ppc_fnmsub}, {381, &ppc_fnmsubdot}, {382, &ppc_fnmadd},
- {383, &ppc_fnmadddot}, {430, &ppc_fsel}, {431, &ppc_fseldot}, {434, &ppc_fmult},
- {435, &ppc_fmultdot}, {440, &ppc_fmsub}, {441, &ppc_fmsubdot}, {442, &ppc_fmadd},
- {443, &ppc_fmadddot}, {444, &ppc_fnmsub}, {445, &ppc_fnmsubdot}, {446, &ppc_fnmadd},
- {447, &ppc_fnmadddot}, {494, &ppc_fsel}, {495, &ppc_fseldot}, {498, &ppc_fmult},
- {499, &ppc_fmultdot}, {504, &ppc_fmsub}, {505, &ppc_fmsubdot}, {506, &ppc_fmadd},
- {507, &ppc_fmadddot}, {508, &ppc_fnmsub}, {509, &ppc_fnmsubdot}, {510, &ppc_fnmadd},
- {511, &ppc_fnmadddot}, {528, &ppc_fabs}, {529, &ppc_fabsdot}, {536, &ppc_mtfsfidot},
- {558, &ppc_fsel}, {559, &ppc_fseldot}, {562, &ppc_fmult}, {563, &ppc_fmultdot},
- {568, &ppc_fmsub}, {569, &ppc_fmsubdot}, {570, &ppc_fmadd}, {571, &ppc_fmadddot},
- {572, &ppc_fnmsub}, {573, &ppc_fnmsubdot}, {574, &ppc_fnmadd}, {575, &ppc_fnmadddot},
- {622, &ppc_fsel}, {623, &ppc_fseldot}, {626, &ppc_fmult}, {627, &ppc_fmultdot},
- {632, &ppc_fmsub}, {633, &ppc_fmsubdot}, {634, &ppc_fmadd}, {635, &ppc_fmadddot},
- {636, &ppc_fnmsub}, {637, &ppc_fnmsubdot}, {638, &ppc_fnmadd}, {639, &ppc_fnmadddot},
- {686, &ppc_fsel}, {687, &ppc_fseldot}, {690, &ppc_fmult}, {691, &ppc_fmultdot},
- {696, &ppc_fmsub}, {697, &ppc_fmsubdot}, {698, &ppc_fmadd}, {699, &ppc_fmadddot},
- {700, &ppc_fnmsub}, {701, &ppc_fnmsubdot}, {702, &ppc_fnmadd}, {703, &ppc_fnmadddot},
- {750, &ppc_fsel}, {751, &ppc_fseldot}, {754, &ppc_fmult}, {755, &ppc_fmultdot},
- {760, &ppc_fmsub}, {761, &ppc_fmsubdot}, {762, &ppc_fmadd}, {763, &ppc_fmadddot},
- {764, &ppc_fnmsub}, {765, &ppc_fnmsubdot}, {766, &ppc_fnmadd}, {767, &ppc_fnmadddot},
- {814, &ppc_fsel}, {815, &ppc_fseldot}, {818, &ppc_fmult}, {819, &ppc_fmultdot},
- {824, &ppc_fmsub}, {825, &ppc_fmsubdot}, {826, &ppc_fmadd}, {827, &ppc_fmadddot},
- {828, &ppc_fnmsub}, {829, &ppc_fnmsubdot}, {830, &ppc_fnmadd}, {831, &ppc_fnmadddot},
- {878, &ppc_fsel}, {879, &ppc_fseldot}, {882, &ppc_fmult}, {883, &ppc_fmultdot},
- {888, &ppc_fmsub}, {889, &ppc_fmsubdot}, {890, &ppc_fmadd}, {891, &ppc_fmadddot},
- {892, &ppc_fnmsub}, {893, &ppc_fnmsubdot}, {894, &ppc_fnmadd}, {895, &ppc_fnmadddot},
- {942, &ppc_fsel}, {943, &ppc_fseldot}, {946, &ppc_fmult}, {947, &ppc_fmultdot},
- {952, &ppc_fmsub}, {953, &ppc_fmsubdot}, {954, &ppc_fmadd}, {955, &ppc_fmadddot},
- {957, &ppc_fnmsub}, {958, &ppc_fnmsubdot}, {958, &ppc_fnmadd}, {959, &ppc_fnmadddot},
- {1006, &ppc_fsel}, {1007, &ppc_fseldot}, {1010, &ppc_fmult}, {1011, &ppc_fmultdot},
- {1016, &ppc_fmsub}, {1017, &ppc_fmsubdot}, {1018, &ppc_fmadd}, {1019, &ppc_fmadddot},
- {1020, &ppc_fnmsub}, {1021, &ppc_fnmsubdot}, {1022, &ppc_fnmadd}, {1023, &ppc_fnmadddot},
- {1070, &ppc_fsel}, {1071, &ppc_fseldot}, {1074, &ppc_fmult}, {1075, &ppc_fmultdot},
- {1080, &ppc_fmsub}, {1081, &ppc_fmsubdot}, {1082, &ppc_fmadd}, {1083, &ppc_fmadddot},
- {1084, &ppc_fnmsub}, {1085, &ppc_fnmsubdot}, {1086, &ppc_fnmadd}, {1087, &ppc_fnmadddot},
- {1134, &ppc_fsel}, {1135, &ppc_fseldot}, {1138, &ppc_fmult}, {1139, &ppc_fmultdot},
- {1144, &ppc_fmsub}, {1145, &ppc_fmsubdot}, {1146, &ppc_fmadd}, {1147, &ppc_fmadddot},
- {1148, &ppc_fnmsub}, {1149, &ppc_fnmsubdot}, {1150, &ppc_fnmadd}, {1151, &ppc_fnmadddot},
- {1166, &ppc_mffs}, {1167, &ppc_mffsdot}, {1198, &ppc_fsel}, {1199, &ppc_fseldot},
- {1202, &ppc_fmult}, {1203, &ppc_fmultdot}, {1208, &ppc_fmsub}, {1209, &ppc_fmsubdot},
- {1210, &ppc_fmadd}, {1211, &ppc_fmadddot}, {1212, &ppc_fnmsub}, {1213, &ppc_fnmsubdot},
- {1214, &ppc_fnmadd}, {1215, &ppc_fnmadddot}, {1262, &ppc_fsel}, {1263, &ppc_fseldot},
- {1266, &ppc_fmult}, {1267, &ppc_fmultdot}, {1272, &ppc_fmsub}, {1273, &ppc_fmsubdot},
- {1274, &ppc_fmadd}, {1275, &ppc_fmadddot}, {1276, &ppc_fnmsub}, {1277, &ppc_fnmsubdot},
- {1278, &ppc_fnmadd}, {1279, &ppc_fnmadddot}, {1326, &ppc_fsel}, {1327, &ppc_fseldot},
- {1330, &ppc_fmult}, {1331, &ppc_fmultdot}, {1336, &ppc_fmsub}, {1337, &ppc_fmsubdot},
- {1338, &ppc_fmadd}, {1339, &ppc_fmadddot}, {1340, &ppc_fnmsub}, {1341, &ppc_fnmsubdot},
- {1342, &ppc_fnmadd}, {1343, &ppc_fnmadddot}, {1390, &ppc_fsel}, {1391, &ppc_fseldot},
- {1394, &ppc_fmult}, {1395, &ppc_fmultdot}, {1400, &ppc_fmsub}, {1401, &ppc_fmsubdot},
- {1402, &ppc_fmadd}, {1403, &ppc_fmadddot}, {1404, &ppc_fnmsub}, {1405, &ppc_fnmsubdot},
- {1406, &ppc_fnmadd}, {1407, &ppc_fnmadddot}, {1422, &ppc_mtfsf}, {1423, &ppc_mtfsfdot},
- {1454, &ppc_fsel}, {1455, &ppc_fseldot}, {1458, &ppc_fmult}, {1459, &ppc_fmultdot},
- {1464, &ppc_fmsub}, {1465, &ppc_fmsubdot}, {1466, &ppc_fmadd}, {1467, &ppc_fmadddot},
- {1468, &ppc_fnmsub}, {1469, &ppc_fnmsubdot}, {1470, &ppc_fnmadd}, {1471, &ppc_fnmadddot},
- {1518, &ppc_fsel}, {1519, &ppc_fseldot}, {1522, &ppc_fmult}, {1523, &ppc_fmultdot},
- {1528, &ppc_fmsub}, {1529, &ppc_fmsubdot}, {1530, &ppc_fmadd}, {1531, &ppc_fmadddot},
- {1532, &ppc_fnmsub}, {1533, &ppc_fnmsubdot}, {1534, &ppc_fnmadd}, {1535, &ppc_fnmadddot},
- {1582, &ppc_fsel}, {1583, &ppc_fseldot}, {1586, &ppc_fmult}, {1587, &ppc_fmultdot},
- {1592, &ppc_fmsub}, {1593, &ppc_fmsubdot}, {1594, &ppc_fmadd}, {1595, &ppc_fmadddot},
- {1596, &ppc_fnmsub}, {1597, &ppc_fnmsubdot}, {1598, &ppc_fnmadd}, {1599, &ppc_fnmadddot},
- {1646, &ppc_fsel}, {1647, &ppc_fseldot}, {1650, &ppc_fmult}, {1651, &ppc_fmultdot},
- {1656, &ppc_fmsub}, {1657, &ppc_fmsubdot}, {1658, &ppc_fmadd}, {1659, &ppc_fmadddot},
- {1660, &ppc_fnmsub}, {1661, &ppc_fnmsubdot}, {1662, &ppc_fnmadd}, {1663, &ppc_fnmadddot},
- {1710, &ppc_fsel}, {1711, &ppc_fseldot}, {1714, &ppc_fmult}, {1715, &ppc_fmultdot},
- {1720, &ppc_fmsub}, {1721, &ppc_fmsubdot}, {1722, &ppc_fmadd}, {1723, &ppc_fmadddot},
- {1724, &ppc_fnmsub}, {1725, &ppc_fnmsubdot}, {1726, &ppc_fnmadd}, {1727, &ppc_fnmadddot},
- {1774, &ppc_fsel}, {1775, &ppc_fseldot}, {1778, &ppc_fmult}, {1779, &ppc_fmultdot},
- {1784, &ppc_fmsub}, {1785, &ppc_fmsubdot}, {1786, &ppc_fmadd}, {1787, &ppc_fmadddot},
- {1788, &ppc_fnmsub}, {1789, &ppc_fnmsubdot}, {1790, &ppc_fnmadd}, {1791, &ppc_fnmadddot},
- {1838, &ppc_fsel}, {1839, &ppc_fseldot}, {1842, &ppc_fmult}, {1843, &ppc_fmultdot},
- {1848, &ppc_fmsub}, {1849, &ppc_fmsubdot}, {1850, &ppc_fmadd}, {1851, &ppc_fmadddot},
- {1852, &ppc_fnmsub}, {1853, &ppc_fnmsubdot}, {1854, &ppc_fnmadd}, {1855, &ppc_fnmadddot},
- {1902, &ppc_fsel}, {1903, &ppc_fseldot}, {1906, &ppc_fmult}, {1907, &ppc_fmultdot},
- {1912, &ppc_fmsub}, {1913, &ppc_fmsubdot}, {1914, &ppc_fmadd}, {1915, &ppc_fmadddot},
- {1916, &ppc_fnmsub}, {1917, &ppc_fnmsubdot}, {1918, &ppc_fnmadd}, {1919, &ppc_fnmadddot},
- {1966, &ppc_fsel}, {1967, &ppc_fseldot}, {1970, &ppc_fmult}, {1971, &ppc_fmultdot},
- {1976, &ppc_fmsub}, {1977, &ppc_fmsubdot}, {1978, &ppc_fmadd}, {1979, &ppc_fmadddot},
- {1980, &ppc_fnmsub}, {1981, &ppc_fnmsubdot}, {1982, &ppc_fnmadd}, {1983, &ppc_fnmadddot},
- {2030, &ppc_fsel}, {2031, &ppc_fseldot}, {2034, &ppc_fmult}, {2035, &ppc_fmultdot},
- {2040, &ppc_fmsub}, {2041, &ppc_fmsubdot}, {2042, &ppc_fmadd}, {2043, &ppc_fmadddot},
- {2044, &ppc_fnmsub}, {2045, &ppc_fnmsubdot}, {2046, &ppc_fnmadd}, {2047, &ppc_fnmadddot}};
+PPCOpcode SubOpcode31Grabber[1024] = {ppc_illegalsubop19};
+PPCOpcode SubOpcode59Grabber[1024] = {ppc_illegalsubop19};
+PPCOpcode SubOpcode63Grabber[1024] = {ppc_illegalsubop19};
#define UPDATE_TBR_DEC \
@@ -427,6 +115,34 @@ void ppc_illegalop() {
exit(-1);
}
+void ppc_illegalsubop19() {
+ uint16_t illegal_subcode = ppc_cur_instruction & 0x7FF;
+ uint32_t grab_it = (uint32_t)illegal_subcode;
+ LOG_F(ERROR, "Illegal subopcode for 19 reported: %d Report this! \n", grab_it);
+ exit(-1);
+}
+
+void ppc_illegalsubop31() {
+ uint16_t illegal_subcode = ppc_cur_instruction & 0x7FF;
+ uint32_t grab_it = (uint32_t)illegal_subcode;
+ LOG_F(ERROR, "Illegal subopcode for 31 reported: %d Report this! \n", grab_it);
+ exit(-1);
+}
+
+void ppc_illegalsubop59() {
+ uint16_t illegal_subcode = ppc_cur_instruction & 0x7FF;
+ uint32_t grab_it = (uint32_t)illegal_subcode;
+ LOG_F(ERROR, "Illegal subopcode for 59 reported: %d Report this! \n", grab_it);
+ exit(-1);
+}
+
+void ppc_illegalsubop63() {
+ uint16_t illegal_subcode = ppc_cur_instruction & 0x7FF;
+ uint32_t grab_it = (uint32_t)illegal_subcode;
+ LOG_F(ERROR, "Illegal subopcode for 63 reported: %d Report this! \n", grab_it);
+ exit(-1);
+}
+
void ppc_opcode4() {
LOG_F(INFO, "Reading from Opcode 4 table \n");
uint8_t subop_grab = ppc_cur_instruction & 3;
@@ -445,67 +161,92 @@ void ppc_opcode18() {
}
void ppc_opcode19() {
- uint16_t subop_grab = ppc_cur_instruction & 2047;
+ uint16_t subop_grab = ppc_cur_instruction & 0x7FF;
+
#ifdef EXHAUSTIVE_DEBUG
uint32_t regrab = (uint32_t)subop_grab;
LOG_F(INFO, "Executing Opcode 19 table subopcode entry \n", regrab);
- if (SubOpcode19Grabber.count(subop_grab) == 1) {
- SubOpcode19Grabber[subop_grab]();
- } else {
- LOG_F(ERROR, "ILLEGAL SUBOPCODE: %d \n", subop_grab);
- ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x80000);
- }
-#else
- SubOpcode19Grabber[subop_grab]();
#endif // EXHAUSTIVE_DEBUG
+
+ if (subop_grab == 32) {
+ ppc_bclr();
+ } else if (subop_grab == 33) {
+ ppc_bclrl();
+ } else if (subop_grab == 1056) {
+ ppc_bcctr();
+ } else if (subop_grab == 1057) {
+ ppc_bcctrl();
+
+ } else {
+ switch (subop_grab) {
+ case 66:
+ ppc_crnor();
+ break;
+ case 100:
+ ppc_rfi();
+ break;
+ case 258:
+ ppc_crandc();
+ break;
+ case 300:
+ ppc_isync();
+ break;
+ case 386:
+ ppc_crxor();
+ break;
+ case 450:
+ ppc_crnand();
+ break;
+ case 514:
+ ppc_crand();
+ break;
+ case 578:
+ ppc_creqv();
+ break;
+ case 834:
+ ppc_crorc();
+ break;
+ case 898:
+ ppc_cror();
+ break;
+ default: // Illegal opcode - should never happen
+ ppc_illegalsubop19();
+ }
+ }
}
void ppc_opcode31() {
- uint16_t subop_grab = ppc_cur_instruction & 2047;
-#ifdef EXHAUSTIVE_DEBUG
- uint32_t regrab = (uint32_t)subop_grab;
- LOG_F(INFO, "Executing Opcode 31 table subopcode entry \n", regrab);
- if (SubOpcode31Grabber.count(subop_grab) == 1) {
- SubOpcode31Grabber[subop_grab]();
- } else {
- LOG_F(ERROR, "ILLEGAL SUBOPCODE: %d \n", subop_grab);
- ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x80000);
- }
-#else
- SubOpcode31Grabber[subop_grab]();
-#endif // EXHAUSTIVE_DEBUG
-}
+ uint16_t subop_grab = (ppc_cur_instruction & 0x7FF) >> 1;
-void ppc_opcode59() {
- uint16_t subop_grab = ppc_cur_instruction & 2047;
-#ifdef EXHAUSTIVE_DEBUG
- uint32_t regrab = (uint32_t)subop_grab;
- LOG_F(INFO, "Executing Opcode 59 table subopcode entry \n", regrab);
- if (SubOpcode59Grabber.count(subop_grab) == 1) {
- SubOpcode59Grabber[subop_grab]();
- } else {
- LOG_F(ERROR, "ILLEGAL SUBOPCODE: %d \n", subop_grab);
- ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x80000);
- }
-#else
- SubOpcode59Grabber[subop_grab]();
-#endif // EXHAUSTIVE_DEBUG
-}
+ rc_flag = ppc_cur_instruction & 0x1;
+ oe_flag = ppc_cur_instruction & 0x400;
-void ppc_opcode63() {
- uint16_t subop_grab = ppc_cur_instruction & 2047;
#ifdef EXHAUSTIVE_DEBUG
uint32_t regrab = (uint32_t)subop_grab;
LOG_F(INFO, "Executing Opcode 63 table subopcode entry \n", regrab);
- if (SubOpcode63Grabber.count(subop_grab) == 1) {
- SubOpcode63Grabber[subop_grab]();
- } else {
- LOG_F(ERROR, "ILLEGAL SUBOPCODE: %d \n", subop_grab);
- ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x80000);
- }
-#else
- SubOpcode63Grabber[subop_grab]();
#endif // EXHAUSTIVE_DEBUG
+
+ SubOpcode31Grabber[subop_grab]();
+}
+
+void ppc_opcode59() {
+ uint16_t subop_grab = (ppc_cur_instruction & 0x7FF) >> 1;
+ rc_flag = subop_grab & 1;
+#ifdef EXHAUSTIVE_DEBUG
+ uint32_t regrab = (uint32_t)subop_grab;
+ LOG_F(INFO, "Executing Opcode 59 table subopcode entry \n", regrab);
+#endif // EXHAUSTIVE_DEBUG
+ SubOpcode59Grabber[subop_grab]();
+}
+
+void ppc_opcode63() {
+ uint16_t subop_grab = (ppc_cur_instruction & 0x7FF) >> 1;
+ rc_flag = subop_grab & 1;
+#ifdef EXHAUSTIVE_DEBUG
+ uint32_t regrab = (uint32_t)subop_grab;
+ LOG_F(INFO, "Executing Opcode 63 table subopcode entry \n", regrab);
+#endif // EXHAUSTIVE_DEBUG
+ SubOpcode63Grabber[subop_grab]();
}
/* Dispatch using main opcode */
@@ -704,6 +445,209 @@ void test_timebase_update()
}
+void initialize_ppc_opcode_tables() {
+ SubOpcode31Grabber[0] = ppc_cmp;
+ SubOpcode31Grabber[4] = ppc_tw;
+ SubOpcode31Grabber[32] = ppc_cmpl;
+
+ SubOpcode31Grabber[8] = SubOpcode31Grabber[520] = ppc_subfc;
+ SubOpcode31Grabber[40] = SubOpcode31Grabber[552] = ppc_subf;
+ SubOpcode31Grabber[104] = SubOpcode31Grabber[616] = ppc_neg;
+ SubOpcode31Grabber[136] = SubOpcode31Grabber[648] = ppc_subfe;
+ SubOpcode31Grabber[200] = SubOpcode31Grabber[712] = ppc_subfze;
+ SubOpcode31Grabber[232] = SubOpcode31Grabber[744] = ppc_subfme;
+
+ SubOpcode31Grabber[10] = SubOpcode31Grabber[522] = ppc_addc;
+ SubOpcode31Grabber[138] = SubOpcode31Grabber[650] = ppc_adde;
+ SubOpcode31Grabber[202] = SubOpcode31Grabber[714] = ppc_addze;
+ SubOpcode31Grabber[234] = SubOpcode31Grabber[746] = ppc_addme;
+ SubOpcode31Grabber[266] = SubOpcode31Grabber[778] = ppc_add;
+
+ SubOpcode31Grabber[11] = ppc_mulhwu;
+ SubOpcode31Grabber[75] = ppc_mulhw;
+ SubOpcode31Grabber[235] = SubOpcode31Grabber[747] = ppc_mullw;
+ SubOpcode31Grabber[459] = SubOpcode31Grabber[971] = ppc_divwu;
+ SubOpcode31Grabber[491] = SubOpcode31Grabber[1003] = ppc_divw;
+
+ SubOpcode31Grabber[20] = ppc_lwarx;
+ SubOpcode31Grabber[23] = ppc_lwzx;
+ SubOpcode31Grabber[55] = ppc_lwzux;
+ SubOpcode31Grabber[87] = ppc_lbzx;
+ SubOpcode31Grabber[119] = ppc_lbzux;
+ SubOpcode31Grabber[279] = ppc_lhzx;
+ SubOpcode31Grabber[311] = ppc_lhzux;
+ SubOpcode31Grabber[343] = ppc_lhax;
+ SubOpcode31Grabber[375] = ppc_lhaux;
+ SubOpcode31Grabber[533] = ppc_lswx;
+ SubOpcode31Grabber[534] = ppc_lwbrx;
+ SubOpcode31Grabber[535] = ppc_lfsx;
+ SubOpcode31Grabber[567] = ppc_lfsux;
+ SubOpcode31Grabber[597] = ppc_lswi;
+ SubOpcode31Grabber[599] = ppc_lfdx;
+ SubOpcode31Grabber[631] = ppc_lfdux;
+ SubOpcode31Grabber[790] = ppc_lhbrx;
+
+ SubOpcode31Grabber[150] = ppc_stwcx;
+ SubOpcode31Grabber[151] = ppc_stwx;
+ SubOpcode31Grabber[183] = ppc_stwux;
+ SubOpcode31Grabber[215] = ppc_stbx;
+ SubOpcode31Grabber[247] = ppc_stbux;
+ SubOpcode31Grabber[407] = ppc_sthx;
+ SubOpcode31Grabber[439] = ppc_sthux;
+ SubOpcode31Grabber[661] = ppc_stswx;
+ SubOpcode31Grabber[662] = ppc_stwbrx;
+ SubOpcode31Grabber[663] = ppc_stfsx;
+ SubOpcode31Grabber[695] = ppc_stfsux;
+ SubOpcode31Grabber[725] = ppc_stswi;
+ SubOpcode31Grabber[727] = ppc_stfdx;
+ SubOpcode31Grabber[759] = ppc_stfdux;
+ SubOpcode31Grabber[918] = ppc_sthbrx;
+ SubOpcode31Grabber[983] = ppc_stfiwx;
+
+ SubOpcode31Grabber[24] = ppc_slw;
+ SubOpcode31Grabber[28] = ppc_and;
+ SubOpcode31Grabber[60] = ppc_andc;
+ SubOpcode31Grabber[124] = ppc_nor;
+ SubOpcode31Grabber[284] = ppc_eqv;
+ SubOpcode31Grabber[316] = ppc_xor;
+ SubOpcode31Grabber[412] = ppc_orc;
+ SubOpcode31Grabber[444] = ppc_or;
+ SubOpcode31Grabber[476] = ppc_nand;
+ SubOpcode31Grabber[536] = ppc_srw;
+ SubOpcode31Grabber[792] = ppc_sraw;
+ SubOpcode31Grabber[824] = ppc_srawi;
+ SubOpcode31Grabber[922] = ppc_extsh;
+ SubOpcode31Grabber[954] = ppc_extsb;
+
+ SubOpcode31Grabber[26] = ppc_cntlzw;
+
+ SubOpcode31Grabber[19] = ppc_mfcr;
+ SubOpcode31Grabber[83] = ppc_mfmsr;
+ SubOpcode31Grabber[144] = ppc_mtcrf;
+ SubOpcode31Grabber[146] = ppc_mtmsr;
+ SubOpcode31Grabber[210] = ppc_mtsr;
+ SubOpcode31Grabber[242] = ppc_mtsrin;
+ SubOpcode31Grabber[339] = ppc_mfspr;
+ SubOpcode31Grabber[371] = ppc_mftb;
+ SubOpcode31Grabber[467] = ppc_mtspr;
+ SubOpcode31Grabber[512] = ppc_mcrxr;
+ SubOpcode31Grabber[595] = ppc_mfsr;
+ SubOpcode31Grabber[659] = ppc_mfsrin;
+
+ SubOpcode31Grabber[54] = ppc_dcbst;
+ SubOpcode31Grabber[86] = ppc_dcbf;
+ SubOpcode31Grabber[246] = ppc_dcbtst;
+ SubOpcode31Grabber[278] = ppc_dcbt;
+ SubOpcode31Grabber[598] = ppc_sync;
+ SubOpcode31Grabber[470] = ppc_dcbi;
+ SubOpcode31Grabber[1014] = ppc_dcbz;
+
+ SubOpcode31Grabber[29] = power_maskg;
+ SubOpcode31Grabber[107] = SubOpcode31Grabber[619] = power_mul;
+ SubOpcode31Grabber[152] = power_slq;
+ SubOpcode31Grabber[153] = power_sle;
+ SubOpcode31Grabber[184] = power_sliq;
+ SubOpcode31Grabber[216] = power_sllq;
+ SubOpcode31Grabber[217] = power_sleq;
+ SubOpcode31Grabber[248] = power_slliq;
+ SubOpcode31Grabber[264] = SubOpcode31Grabber[776] = power_doz;
+ SubOpcode31Grabber[277] = power_lscbx;
+ SubOpcode31Grabber[331] = SubOpcode31Grabber[843] = power_div;
+ SubOpcode31Grabber[360] = SubOpcode31Grabber[872] = power_abs;
+ SubOpcode31Grabber[363] = SubOpcode31Grabber[875] = power_divs;
+ SubOpcode31Grabber[488] = SubOpcode31Grabber[1000] = power_nabs;
+ SubOpcode31Grabber[531] = power_clcs;
+ SubOpcode31Grabber[537] = power_rrib;
+ SubOpcode31Grabber[541] = power_maskir;
+ SubOpcode31Grabber[664] = power_srq;
+ SubOpcode31Grabber[665] = power_sre;
+ SubOpcode31Grabber[696] = power_sriq;
+ SubOpcode31Grabber[728] = power_srlq;
+ SubOpcode31Grabber[729] = power_sreq;
+ SubOpcode31Grabber[760] = power_srliq;
+ SubOpcode31Grabber[920] = power_sraq;
+ SubOpcode31Grabber[921] = power_srea;
+ SubOpcode31Grabber[952] = power_sraiq;
+
+ SubOpcode31Grabber[306] = ppc_tlbie;
+ SubOpcode31Grabber[370] = ppc_tlbia;
+ SubOpcode31Grabber[566] = ppc_tlbsync;
+ SubOpcode31Grabber[854] = ppc_eieio;
+ SubOpcode31Grabber[982] = ppc_icbi;
+ SubOpcode31Grabber[978] = ppc_tlbld;
+ SubOpcode31Grabber[1010] = ppc_tlbli;
+
+ SubOpcode63Grabber[18] = ppc_fdivs;
+ SubOpcode63Grabber[20] = ppc_fsubs;
+ SubOpcode63Grabber[22] = ppc_fsqrts;
+ SubOpcode63Grabber[24] = ppc_fres;
+
+ for (int i = 25; i < 1024; i += 32) {
+ SubOpcode63Grabber[i] = ppc_fmults;
+ }
+
+ for (int i = 28; i < 1024; i += 32) {
+ SubOpcode63Grabber[i] = ppc_fmsubs;
+ }
+
+ for (int i = 29; i < 1024; i += 32) {
+ SubOpcode63Grabber[i] = ppc_fmadds;
+ }
+
+ for (int i = 30; i < 1024; i += 32) {
+ SubOpcode63Grabber[i] = ppc_fnmsubs;
+ }
+
+ for (int i = 31; i < 1024; i += 32) {
+ SubOpcode63Grabber[i] = ppc_fnmadds;
+ }
+
+ SubOpcode63Grabber[0] = ppc_fcmpu;
+ SubOpcode63Grabber[12] = ppc_frsp;
+ SubOpcode63Grabber[14] = ppc_fctiw;
+ SubOpcode63Grabber[15] = ppc_fctiwz;
+ SubOpcode63Grabber[18] = ppc_fdiv;
+ SubOpcode63Grabber[20] = ppc_fsub;
+ SubOpcode63Grabber[21] = ppc_fadd;
+ SubOpcode63Grabber[22] = ppc_fsqrt;
+ SubOpcode63Grabber[26] = ppc_frsqrte;
+ SubOpcode63Grabber[32] = ppc_fcmpo;
+ SubOpcode63Grabber[38] = ppc_mtfsb1;
+ SubOpcode63Grabber[40] = ppc_fneg;
+ SubOpcode63Grabber[64] = ppc_mcrfs;
+ SubOpcode63Grabber[70] = ppc_mtfsb0;
+ SubOpcode63Grabber[72] = ppc_fmr;
+ SubOpcode63Grabber[134] = ppc_mtfsfi;
+ SubOpcode63Grabber[136] = ppc_fnabs;
+ SubOpcode63Grabber[264] = ppc_fabs;
+ SubOpcode63Grabber[583] = ppc_mffs;
+ SubOpcode63Grabber[711] = ppc_mtfsf;
+
+ for (int i = 23; i < 1024; i += 32) {
+ SubOpcode63Grabber[i] = ppc_fsel;
+ }
+
+ for (int i = 25; i < 1024; i += 32) {
+ SubOpcode63Grabber[i] = ppc_fmult;
+ }
+
+ for (int i = 28; i < 1024; i += 32) {
+ SubOpcode63Grabber[i] = ppc_fmsub;
+ }
+
+ for (int i = 29; i < 1024; i += 32) {
+ SubOpcode63Grabber[i] = ppc_fmadd;
+ }
+
+ for (int i = 30; i < 1024; i += 32) {
+ SubOpcode63Grabber[i] = ppc_fnmsub;
+ }
+
+ for (int i = 31; i < 1024; i += 32) {
+ SubOpcode63Grabber[i] = ppc_fnmadd;
+ }
+}
+
void ppc_cpu_init(MemCtrlBase* mem_ctrl, uint32_t proc_version) {
int i;
diff --git a/cpu/ppc/ppcfpopcodes.cpp b/cpu/ppc/ppcfpopcodes.cpp
index eff138b..b0bfa3b 100644
--- a/cpu/ppc/ppcfpopcodes.cpp
+++ b/cpu/ppc/ppcfpopcodes.cpp
@@ -378,16 +378,9 @@ void ppc_fadd() {
ppc_dblresult64_d = ppc_dblresult64_a + ppc_dblresult64_b;
ppc_store_dfpresult(false);
}
-}
-void ppc_fadddot() {
- ppc_grab_regsfpdab(false);
-
- if (!ppc_confirm_inf_nan(reg_a, reg_b, false, 58)) {
- ppc_dblresult64_d = ppc_dblresult64_a + ppc_dblresult64_b;
- ppc_store_dfpresult(false);
- }
- ppc_changecrf1();
+ if (rc_flag)
+ ppc_changecrf1();
}
void ppc_fsub() {
@@ -397,16 +390,9 @@ void ppc_fsub() {
ppc_dblresult64_d = ppc_dblresult64_a - ppc_dblresult64_b;
ppc_store_dfpresult(false);
}
-}
-void ppc_fsubdot() {
- ppc_grab_regsfpdab(false);
-
- if (!ppc_confirm_inf_nan(reg_a, reg_b, false, 56)) {
- ppc_dblresult64_d = ppc_dblresult64_a - ppc_dblresult64_b;
- ppc_store_dfpresult(false);
- }
- ppc_changecrf1();
+ if (rc_flag)
+ ppc_changecrf1();
}
void ppc_fdiv() {
@@ -416,16 +402,9 @@ void ppc_fdiv() {
ppc_dblresult64_d = ppc_dblresult64_a / ppc_dblresult64_b;
ppc_store_dfpresult(false);
}
-}
-void ppc_fdivdot() {
- ppc_grab_regsfpdab(false);
-
- if (!ppc_confirm_inf_nan(reg_a, reg_b, false, 36)) {
- ppc_dblresult64_d = ppc_dblresult64_a / ppc_dblresult64_b;
- ppc_store_dfpresult(false);
- }
- ppc_changecrf1();
+ if (rc_flag)
+ ppc_changecrf1();
}
void ppc_fmult() {
@@ -435,17 +414,9 @@ void ppc_fmult() {
ppc_dblresult64_d = ppc_dblresult64_a * ppc_dblresult64_b;
ppc_store_dfpresult(false);
}
-}
-void ppc_fmultdot() {
- ppc_grab_regsfpdac(false);
-
- if (!ppc_confirm_inf_nan(reg_a, reg_b, false, 50)) {
- ppc_dblresult64_d = ppc_dblresult64_a * ppc_dblresult64_b;
- ppc_store_dfpresult(false);
- }
-
- ppc_changecrf1();
+ if (rc_flag)
+ ppc_changecrf1();
}
void ppc_fmadd() {
@@ -459,20 +430,9 @@ void ppc_fmadd() {
}
ppc_store_dfpresult(false);
-}
-void ppc_fmadddot() {
- ppc_grab_regsfpdabc(false);
-
- if (!ppc_confirm_inf_nan(reg_a, reg_c, false, 50)) {
- ppc_dblresult64_d = (ppc_dblresult64_a * ppc_dblresult64_c);
- if (!ppc_confirm_inf_nan(reg_a, reg_b, false, 58)) {
- ppc_dblresult64_d += ppc_dblresult64_b;
- }
- }
-
- ppc_store_dfpresult(false);
- ppc_changecrf1();
+ if (rc_flag)
+ ppc_changecrf1();
}
void ppc_fmsub() {
@@ -486,20 +446,9 @@ void ppc_fmsub() {
}
ppc_store_dfpresult(false);
-}
-void ppc_fmsubdot() {
- ppc_grab_regsfpdabc(false);
-
- if (!ppc_confirm_inf_nan(reg_a, reg_c, false, 50)) {
- ppc_dblresult64_d = (ppc_dblresult64_a * ppc_dblresult64_c);
- if (!ppc_confirm_inf_nan(reg_d, reg_b, false, 56)) {
- ppc_dblresult64_d -= ppc_dblresult64_b;
- }
- }
-
- ppc_store_dfpresult(false);
- ppc_changecrf1();
+ if (rc_flag)
+ ppc_changecrf1();
}
void ppc_fnmadd() {
@@ -514,22 +463,9 @@ void ppc_fnmadd() {
ppc_dblresult64_d = -ppc_dblresult64_d;
ppc_store_dfpresult(false);
-}
-void ppc_fnmadddot() {
- ppc_grab_regsfpdabc(false);
-
- if (!ppc_confirm_inf_nan(reg_a, reg_c, false, 50)) {
- ppc_dblresult64_d = (ppc_dblresult64_a * ppc_dblresult64_c);
- if (!ppc_confirm_inf_nan(reg_a, reg_b, false, 58)) {
- ppc_dblresult64_d += ppc_dblresult64_b;
- }
- }
-
- ppc_dblresult64_d = -ppc_dblresult64_d;
-
- ppc_store_dfpresult(false);
- ppc_changecrf1();
+ if (rc_flag)
+ ppc_changecrf1();
}
void ppc_fnmsub() {
@@ -544,21 +480,9 @@ void ppc_fnmsub() {
ppc_dblresult64_d = -ppc_dblresult64_d;
ppc_store_dfpresult(false);
-}
-void ppc_fnmsubdot() {
- ppc_grab_regsfpdabc(false);
-
- if (!ppc_confirm_inf_nan(reg_a, reg_c, false, 50)) {
- ppc_dblresult64_d = (ppc_dblresult64_a * ppc_dblresult64_c);
- if (!ppc_confirm_inf_nan(reg_d, reg_b, false, 56)) {
- ppc_dblresult64_d -= ppc_dblresult64_b;
- }
- }
- ppc_dblresult64_d = -ppc_dblresult64_d;
-
- ppc_store_dfpresult(false);
- ppc_changecrf1();
+ if (rc_flag)
+ ppc_changecrf1();
}
void ppc_fadds() {
@@ -569,18 +493,9 @@ void ppc_fadds() {
ppc_dblresult64_d = static_cast(intermediate);
ppc_store_dfpresult(false);
}
-}
-void ppc_faddsdot() {
- ppc_grab_regsfpdab(false);
-
- if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 58)) {
- float intermediate = (float)ppc_dblresult64_a + (float)ppc_dblresult64_b;
- ppc_dblresult64_d = static_cast(intermediate);
- ppc_store_dfpresult(false);
- }
-
- ppc_changecrf1();
+ if (rc_flag)
+ ppc_changecrf1();
}
void ppc_fsubs() {
@@ -591,18 +506,9 @@ void ppc_fsubs() {
ppc_dblresult64_d = static_cast(intermediate);
ppc_store_dfpresult(false);
}
-}
-void ppc_fsubsdot() {
- ppc_grab_regsfpdab(false);
-
- if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 56)) {
- float intermediate = (float)ppc_dblresult64_a - (float)ppc_dblresult64_b;
- ppc_dblresult64_d = static_cast(intermediate);
- ppc_store_dfpresult(false);
- }
-
- ppc_changecrf1();
+ if (rc_flag)
+ ppc_changecrf1();
}
void ppc_fmults() {
@@ -613,17 +519,9 @@ void ppc_fmults() {
ppc_dblresult64_d = static_cast(intermediate);
ppc_store_dfpresult(false);
}
-}
-void ppc_fmultsdot() {
- ppc_grab_regsfpdac(false);
-
- if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 50)) {
- float intermediate = (float)ppc_dblresult64_a * (float)ppc_dblresult64_b;
- ppc_dblresult64_d = static_cast(intermediate);
- ppc_store_dfpresult(false);
- }
- ppc_changecrf1();
+ if (rc_flag)
+ ppc_changecrf1();
}
void ppc_fdivs() {
@@ -634,18 +532,9 @@ void ppc_fdivs() {
ppc_dblresult64_d = static_cast(intermediate);
ppc_store_dfpresult(false);
}
-}
-void ppc_fdivsdot() {
- ppc_grab_regsfpdab(false);
-
- if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 36)) {
- float intermediate = (float)ppc_dblresult64_a / (float)ppc_dblresult64_b;
- ppc_dblresult64_d = static_cast(intermediate);
- ppc_store_dfpresult(false);
- }
-
- ppc_changecrf1();
+ if (rc_flag)
+ ppc_changecrf1();
}
void ppc_fmadds() {
@@ -662,24 +551,9 @@ void ppc_fmadds() {
ppc_store_dfpresult(false);
}
}
-}
-void ppc_fmaddsdot() {
- ppc_grab_regsfpdabc(false);
-
- float intermediate;
-
- if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 58)) {
- intermediate = (float)ppc_dblresult64_a * (float)ppc_dblresult64_c;
- if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 58)) {
- intermediate += (float)ppc_dblresult64_b;
- ppc_dblresult64_d = static_cast(intermediate);
-
- ppc_store_dfpresult(false);
- }
- }
-
- ppc_changecrf1();
+ if (rc_flag)
+ ppc_changecrf1();
}
void ppc_fmsubs() {
@@ -696,24 +570,9 @@ void ppc_fmsubs() {
ppc_store_dfpresult(false);
}
}
-}
-void ppc_fmsubsdot() {
- ppc_grab_regsfpdabc(false);
-
- float intermediate;
-
- if (!ppc_confirm_inf_nan(reg_a, reg_c, false, 50)) {
- intermediate = (float)ppc_dblresult64_a * (float)ppc_dblresult64_c;
- if (!ppc_confirm_inf_nan(reg_d, reg_b, false, 56)) {
- intermediate -= (float)ppc_dblresult64_b;
- ppc_dblresult64_d = static_cast(intermediate);
-
- ppc_store_dfpresult(false);
- }
- }
-
- ppc_changecrf1();
+ if (rc_flag)
+ ppc_changecrf1();
}
void ppc_fnmadds() {
@@ -721,24 +580,6 @@ void ppc_fnmadds() {
float intermediate;
- if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 58)) {
- intermediate = (float)ppc_dblresult64_a * (float)ppc_dblresult64_c;
- if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 58)) {
- intermediate += (float)ppc_dblresult64_b;
- intermediate = -intermediate;
-
- ppc_dblresult64_d = static_cast(intermediate);
- }
- }
-
- ppc_store_dfpresult(false);
-}
-
-void ppc_fnmaddsdot() {
- ppc_grab_regsfpdabc(false);
-
- float intermediate;
-
if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 58)) {
intermediate = (float)ppc_dblresult64_a * (float)ppc_dblresult64_c;
if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 58)) {
@@ -751,7 +592,8 @@ void ppc_fnmaddsdot() {
}
}
- ppc_changecrf1();
+ if (rc_flag)
+ ppc_changecrf1();
}
void ppc_fnmsubs() {
@@ -770,25 +612,9 @@ void ppc_fnmsubs() {
ppc_store_dfpresult(false);
}
}
-}
-void ppc_fnmsubsdot() {
- ppc_grab_regsfpdabc(false);
-
- float intermediate;
-
- if (!ppc_confirm_inf_nan(reg_a, reg_c, false, 50)) {
- intermediate = (float)ppc_dblresult64_a * (float)ppc_dblresult64_c;
- if (!ppc_confirm_inf_nan(reg_d, reg_b, false, 56)) {
- intermediate -= (float)ppc_dblresult64_b;
- intermediate = -intermediate;
-
- ppc_dblresult64_d = static_cast(intermediate);
-
- ppc_store_dfpresult(false);
- }
- }
- ppc_changecrf1();
+ if (rc_flag)
+ ppc_changecrf1();
}
void ppc_fabs() {
@@ -797,15 +623,9 @@ void ppc_fabs() {
ppc_dblresult64_d = abs(ppc_dblresult64_b);
ppc_store_dfpresult(false);
-}
-void ppc_fabsdot() {
- ppc_grab_regsfpdb(false);
-
- ppc_dblresult64_d = abs(ppc_dblresult64_b);
-
- ppc_store_dfpresult(false);
- ppc_changecrf1();
+ if (rc_flag)
+ ppc_changecrf1();
}
void ppc_fnabs() {
@@ -815,16 +635,9 @@ void ppc_fnabs() {
ppc_dblresult64_d = -ppc_dblresult64_d;
ppc_store_dfpresult(false);
-}
-void ppc_fnabsdot() {
- ppc_grab_regsfpdb(false);
-
- ppc_dblresult64_d = abs(ppc_dblresult64_b);
- ppc_dblresult64_d = -ppc_dblresult64_d;
-
- ppc_store_dfpresult(false);
- ppc_changecrf1();
+ if (rc_flag)
+ ppc_changecrf1();
}
void ppc_fneg() {
@@ -833,15 +646,9 @@ void ppc_fneg() {
ppc_dblresult64_d = -ppc_dblresult64_d;
ppc_store_dfpresult(false);
-}
-void ppc_fnegdot() {
- ppc_grab_regsfpdb(false);
-
- ppc_dblresult64_d = -ppc_dblresult64_d;
-
- ppc_store_dfpresult(false);
- ppc_changecrf1();
+ if (rc_flag)
+ ppc_changecrf1();
}
void ppc_fsel() {
@@ -854,32 +661,18 @@ void ppc_fsel() {
}
ppc_store_dfpresult(false);
-}
-void ppc_fseldot() {
- ppc_grab_regsfpdabc(false);
-
- if (ppc_dblresult64_a >= 0.0) {
- ppc_dblresult64_d = ppc_dblresult64_c;
- } else {
- ppc_dblresult64_d = ppc_dblresult64_b;
- }
-
- ppc_store_dfpresult(false);
- ppc_changecrf1();
+ if (rc_flag)
+ ppc_changecrf1();
}
void ppc_fsqrt() {
ppc_grab_regsfpdb(false);
ppc_dblresult64_d = std::sqrt(ppc_dblresult64_b);
ppc_store_dfpresult(false);
-}
-void ppc_fsqrtdot() {
- ppc_grab_regsfpdb(false);
- ppc_dblresult64_d = std::sqrt(ppc_dblresult64_b);
- ppc_store_dfpresult(false);
- ppc_changecrf1();
+ if (rc_flag)
+ ppc_changecrf1();
}
void ppc_fsqrts() {
@@ -890,17 +683,9 @@ void ppc_fsqrts() {
uint64_t* pre_final = (uint64_t*)&test;
ppc_result64_d = *pre_final;
ppc_store_dfpresult(true);
-}
-void ppc_fsqrtsdot() {
- ppc_grab_regsfpdb(true);
- uint32_t test = (uint32_t)ppc_result64_b;
- test += 127 << 23;
- test >>= 1;
- uint64_t* pre_final = (uint64_t*)&test;
- ppc_result64_d = *pre_final;
- ppc_store_dfpresult(true);
- ppc_changecrf1();
+ if (rc_flag)
+ ppc_changecrf1();
}
void ppc_frsqrte() {
@@ -912,18 +697,9 @@ void ppc_frsqrte() {
ppc_dblresult64_d = testd2;
ppc_store_dfpresult(false);
-}
-void ppc_frsqrtedot() {
- ppc_grab_regsfpdb(false);
- double testd2 = (double)ppc_result64_b;
- for (int i = 0; i < 10; i++) {
- testd2 = testd2 * (1.5 - (testd2 * .5) * testd2 * testd2);
- }
- ppc_dblresult64_d = testd2;
-
- ppc_store_dfpresult(false);
- ppc_changecrf1();
+ if (rc_flag)
+ ppc_changecrf1();
}
void ppc_frsp() {
@@ -932,15 +708,9 @@ void ppc_frsp() {
float testf2 = (float)testd2;
ppc_dblresult64_d = (double)testf2;
ppc_store_dfpresult(false);
-}
-void ppc_frspdot() {
- ppc_grab_regsfpdb(false);
- double testd2 = (double)ppc_result64_b;
- float testf2 = (float)testd2;
- ppc_dblresult64_d = (double)testf2;
- ppc_store_dfpresult(false);
- ppc_changecrf1();
+ if (rc_flag)
+ ppc_changecrf1();
}
void ppc_fres() {
@@ -949,15 +719,9 @@ void ppc_fres() {
testf2 = 1 / testf2;
ppc_dblresult64_d = (double)testf2;
ppc_store_dfpresult(false);
-}
-void ppc_fresdot() {
- ppc_grab_regsfpdb(false);
- float testf2 = (float)ppc_dblresult64_b;
- testf2 = 1 / testf2;
- ppc_dblresult64_d = (double)testf2;
- ppc_store_dfpresult(false);
- ppc_changecrf1();
+ if (rc_flag)
+ ppc_changecrf1();
}
void ppc_fctiw() {
@@ -975,24 +739,9 @@ void ppc_fctiw() {
}
ppc_store_dfpresult(true);
-}
-void ppc_fctiwdot() {
- ppc_grab_regsfpdb(false);
-
- switch (ppc_state.fpscr & 0x3) {
- case 0:
- ppc_result64_d = round_to_nearest(ppc_dblresult64_b);
- case 1:
- ppc_result64_d = round_to_zero(ppc_dblresult64_b);
- case 2:
- ppc_result64_d = round_to_pos_inf(ppc_dblresult64_b);
- case 3:
- ppc_result64_d = round_to_neg_inf(ppc_dblresult64_b);
- }
-
- ppc_store_dfpresult(true);
- ppc_changecrf1();
+ if (rc_flag)
+ ppc_changecrf1();
}
void ppc_fctiwz() {
@@ -1000,14 +749,9 @@ void ppc_fctiwz() {
ppc_result64_d = round_to_zero(ppc_dblresult64_b);
ppc_store_result_regd();
-}
-void ppc_fctiwzdot() {
- ppc_grab_regsfpdb(false);
- ppc_result64_d = round_to_zero(ppc_dblresult64_b);
-
- ppc_store_result_regd();
- ppc_changecrf1();
+ if (rc_flag)
+ ppc_changecrf1();
}
// Floating Point Store and Load
diff --git a/cpu/ppc/ppcopcodes.cpp b/cpu/ppc/ppcopcodes.cpp
index bcfd278..cd3bab1 100644
--- a/cpu/ppc/ppcopcodes.cpp
+++ b/cpu/ppc/ppcopcodes.cpp
@@ -227,29 +227,10 @@ void ppc_addis() {
void ppc_add() {
ppc_grab_regsdab();
ppc_result_d = ppc_result_a + ppc_result_b;
- ppc_store_result_regd();
-}
-
-void ppc_adddot() {
- ppc_grab_regsdab();
- ppc_result_d = ppc_result_a + ppc_result_b;
- ppc_changecrf0(ppc_result_d);
- ppc_store_result_regd();
-}
-
-// addo + addodot
-void ppc_addo() {
- ppc_grab_regsdab();
- ppc_result_d = ppc_result_a + ppc_result_b;
- ppc_setsoov(ppc_result_a, ~ppc_result_b, ppc_result_d);
- ppc_store_result_regd();
-}
-
-void ppc_addodot() {
- ppc_grab_regsdab();
- ppc_result_d = ppc_result_a + ppc_result_b;
- ppc_setsoov(ppc_result_a, ~ppc_result_b, ppc_result_d);
- ppc_changecrf0(ppc_result_d);
+ if (oe_flag)
+ ppc_setsoov(ppc_result_a, ~ppc_result_b, ppc_result_d);
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_d);
ppc_store_result_regd();
}
@@ -257,31 +238,12 @@ void ppc_addc() {
ppc_grab_regsdab();
ppc_result_d = ppc_result_a + ppc_result_b;
ppc_carry(ppc_result_a, ppc_result_d);
- ppc_store_result_regd();
-}
-void ppc_addcdot() {
- ppc_grab_regsdab();
- ppc_result_d = ppc_result_a + ppc_result_b;
- ppc_carry(ppc_result_a, ppc_result_d);
- ppc_changecrf0(ppc_result_d);
- ppc_store_result_regd();
-}
+ if (oe_flag)
+ ppc_setsoov(ppc_result_a, ~ppc_result_b, ppc_result_d);
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_d);
-void ppc_addco() {
- ppc_grab_regsdab();
- ppc_result_d = ppc_result_a + ppc_result_b;
- ppc_setsoov(ppc_result_a, ~ppc_result_b, ppc_result_d);
- ppc_carry(ppc_result_a, ppc_result_d);
- ppc_store_result_regd();
-}
-
-void ppc_addcodot() {
- ppc_grab_regsdab();
- ppc_result_d = ppc_result_a + ppc_result_b;
- ppc_setsoov(ppc_result_a, ~ppc_result_b, ppc_result_d);
- ppc_carry(ppc_result_a, ppc_result_d);
- ppc_changecrf0(ppc_result_d);
ppc_store_result_regd();
}
@@ -289,51 +251,18 @@ void ppc_adde() {
ppc_grab_regsdab();
uint32_t xer_ca = !!(ppc_state.spr[SPR::XER] & 0x20000000);
ppc_result_d = ppc_result_a + ppc_result_b + xer_ca;
- if ((ppc_result_d < ppc_result_a) || (xer_ca && (ppc_result_d == ppc_result_a))) {
- ppc_state.spr[SPR::XER] |= 0x20000000UL;
- } else {
- ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL;
- }
- ppc_store_result_regd();
-}
-void ppc_addedot() {
- ppc_grab_regsdab();
- uint32_t xer_ca = !!(ppc_state.spr[SPR::XER] & 0x20000000);
- ppc_result_d = ppc_result_a + ppc_result_b + xer_ca;
if ((ppc_result_d < ppc_result_a) || (xer_ca && (ppc_result_d == ppc_result_a))) {
ppc_state.spr[SPR::XER] |= 0x20000000UL;
} else {
ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL;
}
- ppc_changecrf0(ppc_result_d);
- ppc_store_result_regd();
-}
-void ppc_addeo() {
- ppc_grab_regsdab();
- uint32_t xer_ca = !!(ppc_state.spr[SPR::XER] & 0x20000000);
- ppc_result_d = ppc_result_a + ppc_result_b + xer_ca;
- if ((ppc_result_d < ppc_result_a) || (xer_ca && (ppc_result_d == ppc_result_a))) {
- ppc_state.spr[SPR::XER] |= 0x20000000UL;
- } else {
- ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL;
- }
- ppc_setsoov(ppc_result_a, ~ppc_result_b, ppc_result_d);
- ppc_store_result_regd();
-}
+ if (oe_flag)
+ ppc_setsoov(ppc_result_a, ~ppc_result_b, ppc_result_d);
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_d);
-void ppc_addeodot() {
- ppc_grab_regsdab();
- uint32_t xer_ca = !!(ppc_state.spr[SPR::XER] & 0x20000000);
- ppc_result_d = ppc_result_a + ppc_result_b + xer_ca;
- if ((ppc_result_d < ppc_result_a) || (xer_ca && (ppc_result_d == ppc_result_a))) {
- ppc_state.spr[SPR::XER] |= 0x20000000UL;
- } else {
- ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL;
- }
- ppc_setsoov(ppc_result_a, ~ppc_result_b, ppc_result_d);
- ppc_changecrf0(ppc_result_d);
ppc_store_result_regd();
}
@@ -341,51 +270,18 @@ void ppc_addme() {
ppc_grab_regsda();
uint32_t xer_ca = !!(ppc_state.spr[SPR::XER] & 0x20000000);
ppc_result_d = ppc_result_a + xer_ca - 1;
- if (((xer_ca - 1) < 0xFFFFFFFFUL) | (ppc_result_d < ppc_result_a)) {
- ppc_state.spr[SPR::XER] |= 0x20000000UL;
- } else {
- ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL;
- }
- ppc_store_result_regd();
-}
-void ppc_addmedot() {
- ppc_grab_regsda();
- uint32_t xer_ca = !!(ppc_state.spr[SPR::XER] & 0x20000000);
- ppc_result_d = ppc_result_a + xer_ca - 1;
if (((xer_ca - 1) < 0xFFFFFFFFUL) | (ppc_result_d < ppc_result_a)) {
ppc_state.spr[SPR::XER] |= 0x20000000UL;
} else {
ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL;
}
- ppc_changecrf0(ppc_result_d);
- ppc_store_result_regd();
-}
-void ppc_addmeo() {
- ppc_grab_regsda();
- uint32_t xer_ca = !!(ppc_state.spr[SPR::XER] & 0x20000000);
- ppc_result_d = ppc_result_a + xer_ca - 1;
- ppc_setsoov(ppc_result_a, 0, ppc_result_d);
- if (((xer_ca - 1) < 0xFFFFFFFFUL) | (ppc_result_d < ppc_result_a)) {
- ppc_state.spr[SPR::XER] |= 0x20000000UL;
- } else {
- ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL;
- }
- ppc_store_result_regd();
-}
+ if (oe_flag)
+ ppc_setsoov(ppc_result_a, 0, ppc_result_d);
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_d);
-void ppc_addmeodot() {
- ppc_grab_regsda();
- uint32_t xer_ca = !!(ppc_state.spr[SPR::XER] & 0x20000000);
- ppc_result_d = ppc_result_a + xer_ca - 1;
- ppc_setsoov(ppc_result_a, 0, ppc_result_d);
- ppc_changecrf0(ppc_result_d);
- if (((xer_ca - 1) < 0xFFFFFFFFUL) | (ppc_result_d < ppc_result_a)) {
- ppc_state.spr[SPR::XER] |= 0x20000000UL;
- } else {
- ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL;
- }
ppc_store_result_regd();
}
@@ -393,79 +289,30 @@ void ppc_addze() {
ppc_grab_regsda();
uint32_t grab_xer = !!(ppc_state.spr[SPR::XER] & 0x20000000);
ppc_result_d = ppc_result_a + grab_xer;
- if (ppc_result_d < ppc_result_a) {
- ppc_state.spr[SPR::XER] |= 0x20000000UL;
- } else {
- ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL;
- }
- ppc_store_result_regd();
-}
-void ppc_addzedot() {
- ppc_grab_regsda();
- uint32_t grab_xer = !!(ppc_state.spr[SPR::XER] & 0x20000000);
- ppc_result_d = ppc_result_a + grab_xer;
if (ppc_result_d < ppc_result_a) {
ppc_state.spr[SPR::XER] |= 0x20000000UL;
} else {
ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL;
}
- ppc_changecrf0(ppc_result_d);
- ppc_store_result_regd();
-}
+
+ if (oe_flag)
+ ppc_setsoov(ppc_result_a, 0xFFFFFFFFUL, ppc_result_d);
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_d);
-void ppc_addzeo() {
- ppc_grab_regsda();
- uint32_t grab_xer = !!(ppc_state.spr[SPR::XER] & 0x20000000);
- ppc_result_d = ppc_result_a + grab_xer;
- ppc_setsoov(ppc_result_a, 0xFFFFFFFFUL, ppc_result_d);
- if (ppc_result_d < ppc_result_a) {
- ppc_state.spr[SPR::XER] |= 0x20000000UL;
- } else {
- ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL;
- }
- ppc_store_result_regd();
-}
-
-void ppc_addzeodot() {
- ppc_grab_regsda();
- uint32_t grab_xer = !!(ppc_state.spr[SPR::XER] & 0x20000000);
- ppc_result_d = ppc_result_a + grab_xer;
- ppc_setsoov(ppc_result_a, 0xFFFFFFFFUL, ppc_result_d);
- if (ppc_result_d < ppc_result_a) {
- ppc_state.spr[SPR::XER] |= 0x20000000UL;
- } else {
- ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL;
- }
- ppc_changecrf0(ppc_result_d);
ppc_store_result_regd();
}
void ppc_subf() {
ppc_grab_regsdab();
ppc_result_d = ppc_result_b - ppc_result_a;
- ppc_store_result_regd();
-}
-void ppc_subfdot() {
- ppc_grab_regsdab();
- ppc_result_d = ppc_result_b - ppc_result_a;
- ppc_changecrf0(ppc_result_d);
- ppc_store_result_regd();
-}
+ if (oe_flag)
+ ppc_setsoov(ppc_result_b, ppc_result_a, ppc_result_d);
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_d);
-void ppc_subfo() {
- ppc_grab_regsdab();
- ppc_result_d = ppc_result_b - ppc_result_a;
- ppc_setsoov(ppc_result_b, ppc_result_a, ppc_result_d);
- ppc_store_result_regd();
-}
-
-void ppc_subfodot() {
- ppc_grab_regsdab();
- ppc_result_d = ppc_result_b - ppc_result_a;
- ppc_setsoov(ppc_result_b, ppc_result_a, ppc_result_d);
- ppc_changecrf0(ppc_result_d);
ppc_store_result_regd();
}
@@ -473,31 +320,12 @@ void ppc_subfc() {
ppc_grab_regsdab();
ppc_result_d = ppc_result_b - ppc_result_a;
ppc_carry_sub(ppc_result_a, ppc_result_b);
- ppc_store_result_regd();
-}
-void ppc_subfcdot() {
- ppc_grab_regsdab();
- ppc_result_d = ppc_result_b - ppc_result_a;
- ppc_carry_sub(ppc_result_a, ppc_result_b);
- ppc_changecrf0(ppc_result_d);
- ppc_store_result_regd();
-}
+ if (oe_flag)
+ ppc_setsoov(ppc_result_b, ppc_result_a, ppc_result_d);
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_d);
-void ppc_subfco() {
- ppc_grab_regsdab();
- ppc_result_d = ppc_result_b - ppc_result_a;
- ppc_setsoov(ppc_result_b, ppc_result_a, ppc_result_d);
- ppc_carry_sub(ppc_result_a, ppc_result_b);
- ppc_store_result_regd();
-}
-
-void ppc_subfcodot() {
- ppc_grab_regsdab();
- ppc_result_d = ppc_result_b - ppc_result_a;
- ppc_setsoov(ppc_result_b, ppc_result_a, ppc_result_d);
- ppc_carry_sub(ppc_result_a, ppc_result_b);
- ppc_changecrf0(ppc_result_d);
ppc_store_result_regd();
}
@@ -513,34 +341,12 @@ void ppc_subfe() {
uint32_t grab_xer = !!(ppc_state.spr[SPR::XER] & 0x20000000);
ppc_result_d = ~ppc_result_a + ppc_result_b + grab_xer;
ppc_carry(~ppc_result_a, ppc_result_d);
- ppc_store_result_regd();
-}
-void ppc_subfedot() {
- ppc_grab_regsdab();
- uint32_t grab_xer = !!(ppc_state.spr[SPR::XER] & 0x20000000);
- ppc_result_d = ~ppc_result_a + ppc_result_b + grab_xer;
- ppc_carry(~ppc_result_a, ppc_result_d);
- ppc_changecrf0(ppc_result_d);
- ppc_store_result_regd();
-}
+ if (oe_flag)
+ ppc_setsoov(ppc_result_b, ppc_result_a, ppc_result_d);
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_d);
-void ppc_subfeo() {
- ppc_grab_regsdab();
- uint32_t grab_xer = !!(ppc_state.spr[SPR::XER] & 0x20000000);
- ppc_result_d = ~ppc_result_a + ppc_result_b + grab_xer;
- ppc_setsoov(ppc_result_b, ppc_result_a, ppc_result_d);
- ppc_carry(~ppc_result_a, ppc_result_d);
- ppc_store_result_regd();
-}
-
-void ppc_subfeodot() {
- ppc_grab_regsdab();
- uint32_t grab_xer = !!(ppc_state.spr[SPR::XER] & 0x20000000);
- ppc_result_d = ~ppc_result_a + ppc_result_b + grab_xer;
- ppc_setsoov(ppc_result_b, ppc_result_a, ppc_result_d);
- ppc_carry(~ppc_result_a, ppc_result_d);
- ppc_changecrf0(ppc_result_d);
ppc_store_result_regd();
}
@@ -549,34 +355,12 @@ void ppc_subfme() {
uint32_t grab_xer = !!(ppc_state.spr[SPR::XER] & 0x20000000);
ppc_result_d = ~ppc_result_a + grab_xer - 1;
ppc_carry(~ppc_result_a, ppc_result_d);
- ppc_store_result_regd();
-}
+
+ if (oe_flag)
+ ppc_setsoov(0xFFFFFFFF, ppc_result_a, ppc_result_d);
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_d);
-void ppc_subfmedot() {
- ppc_grab_regsda();
- uint32_t grab_xer = !!(ppc_state.spr[SPR::XER] & 0x20000000);
- ppc_result_d = ~ppc_result_a + grab_xer - 1;
- ppc_carry(~ppc_result_a, ppc_result_d);
- ppc_changecrf0(ppc_result_d);
- ppc_store_result_regd();
-}
-
-void ppc_subfmeo() {
- ppc_grab_regsda();
- uint32_t grab_xer = !!(ppc_state.spr[SPR::XER] & 0x20000000);
- ppc_result_d = ~ppc_result_a + grab_xer - 1;
- ppc_setsoov(ppc_result_b, ppc_result_a, ppc_result_d);
- ppc_carry(~ppc_result_a, ppc_result_d);
- ppc_store_result_regd();
-}
-
-void ppc_subfmeodot() {
- ppc_grab_regsda();
- uint32_t grab_xer = !!(ppc_state.spr[SPR::XER] & 0x20000000);
- ppc_result_d = ~ppc_result_a + grab_xer - 1;
- ppc_setsoov(ppc_result_b, ppc_result_a, ppc_result_d);
- ppc_carry(~ppc_result_a, ppc_result_d);
- ppc_changecrf0(ppc_result_d);
ppc_store_result_regd();
}
@@ -584,31 +368,12 @@ void ppc_subfze() {
ppc_grab_regsda();
ppc_result_d = ~ppc_result_a + (ppc_state.spr[SPR::XER] & 0x20000000);
ppc_carry(~ppc_result_a, ppc_result_d);
- ppc_store_result_regd();
-}
-void ppc_subfzedot() {
- ppc_grab_regsda();
- ppc_result_d = ~ppc_result_a + (ppc_state.spr[SPR::XER] & 0x20000000);
- ppc_carry(~ppc_result_a, ppc_result_d);
- ppc_changecrf0(ppc_result_d);
- ppc_store_result_regd();
-}
+ if (oe_flag)
+ ppc_setsoov(0, ppc_result_a, ppc_result_d);
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_d);
-void ppc_subfzeo() {
- ppc_grab_regsda();
- ppc_result_d = ~ppc_result_a + (ppc_state.spr[SPR::XER] & 0x20000000);
- ppc_setsoov(ppc_result_b, ppc_result_a, ppc_result_d);
- ppc_carry(~ppc_result_a, ppc_result_d);
- ppc_store_result_regd();
-}
-
-void ppc_subfzeodot() {
- ppc_grab_regsda();
- ppc_result_d = ~ppc_result_a + (ppc_state.spr[SPR::XER] & 0x20000000);
- ppc_setsoov(ppc_result_b, ppc_result_a, ppc_result_d);
- ppc_carry(~ppc_result_a, ppc_result_d);
- ppc_changecrf0(ppc_result_d);
ppc_store_result_regd();
}
@@ -616,26 +381,20 @@ void ppc_subfzeodot() {
void ppc_and() {
ppc_grab_regssab();
ppc_result_a = ppc_result_d & ppc_result_b;
- ppc_store_result_rega();
-}
-void ppc_anddot() {
- ppc_grab_regssab();
- ppc_result_a = ppc_result_d & ppc_result_b;
- ppc_changecrf0(ppc_result_a);
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_a);
+
ppc_store_result_rega();
}
void ppc_andc() {
ppc_grab_regssab();
ppc_result_a = ppc_result_d & ~(ppc_result_b);
- ppc_store_result_rega();
-}
-void ppc_andcdot() {
- ppc_grab_regssab();
- ppc_result_a = ppc_result_d & ~(ppc_result_b);
- ppc_changecrf0(ppc_result_a);
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_a);
+
ppc_store_result_rega();
}
@@ -656,39 +415,30 @@ void ppc_andisdot() {
void ppc_nand() {
ppc_grab_regssab();
ppc_result_a = ~(ppc_result_d & ppc_result_b);
- ppc_store_result_rega();
-}
-void ppc_nanddot() {
- ppc_grab_regssab();
- ppc_result_a = ~(ppc_result_d & ppc_result_b);
- ppc_changecrf0(ppc_result_a);
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_a);
+
ppc_store_result_rega();
}
void ppc_or() {
ppc_grab_regssab();
ppc_result_a = ppc_result_d | ppc_result_b;
- ppc_store_result_rega();
-}
-void ppc_ordot() {
- ppc_grab_regssab();
- ppc_result_a = ppc_result_d | ppc_result_b;
- ppc_changecrf0(ppc_result_a);
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_a);
+
ppc_store_result_rega();
}
void ppc_orc() {
ppc_grab_regssab();
ppc_result_a = ppc_result_d | ~(ppc_result_b);
- ppc_store_result_rega();
-}
-void ppc_orcdot() {
- ppc_grab_regssab();
- ppc_result_a = ppc_result_d | ~(ppc_result_b);
- ppc_changecrf0(ppc_result_a);
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_a);
+
ppc_store_result_rega();
}
@@ -707,39 +457,30 @@ void ppc_oris() {
void ppc_eqv() {
ppc_grab_regssab();
ppc_result_a = ~(ppc_result_d ^ ppc_result_b);
- ppc_store_result_rega();
-}
-void ppc_eqvdot() {
- ppc_grab_regssab();
- ppc_result_a = ~(ppc_result_d ^ ppc_result_b);
- ppc_changecrf0(ppc_result_a);
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_a);
+
ppc_store_result_rega();
}
void ppc_nor() {
ppc_grab_regssab();
ppc_result_a = ~(ppc_result_d | ppc_result_b);
- ppc_store_result_rega();
-}
-void ppc_nordot() {
- ppc_grab_regssab();
- ppc_result_a = ~(ppc_result_d | ppc_result_b);
- ppc_changecrf0(ppc_result_a);
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_a);
+
ppc_store_result_rega();
}
void ppc_xor() {
ppc_grab_regssab();
ppc_result_a = ppc_result_d ^ ppc_result_b;
- ppc_store_result_rega();
-}
-void ppc_xordot() {
- ppc_grab_regssab();
- ppc_result_a = ppc_result_d ^ ppc_result_b;
- ppc_changecrf0(ppc_result_a);
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_a);
+
ppc_store_result_rega();
}
@@ -758,34 +499,17 @@ void ppc_xoris() {
void ppc_neg() {
ppc_grab_regsda();
ppc_result_d = ~(ppc_result_a) + 1;
- ppc_store_result_regd();
-}
-void ppc_negdot() {
- ppc_grab_regsda();
- ppc_result_d = ~(ppc_result_a) + 1;
- ppc_changecrf0(ppc_result_d);
- ppc_store_result_regd();
-}
+ if (oe_flag) {
+ if (ppc_result_a == 0x80000000)
+ ppc_state.spr[SPR::XER] |= 0xC0000000;
+ else
+ ppc_state.spr[SPR::XER] &= 0xBFFFFFFF;
+ }
+
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_d);
-void ppc_nego() {
- ppc_grab_regsda();
- ppc_result_d = ~(ppc_result_a) + 1;
- if (ppc_result_a == 0x80000000)
- ppc_state.spr[SPR::XER] |= 0xc0000000;
- else
- ppc_state.spr[SPR::XER] &= 0xBFFFFFFF;
- ppc_store_result_regd();
-}
-
-void ppc_negodot() {
- ppc_grab_regsda();
- ppc_result_d = ~(ppc_result_a) + 1;
- if (ppc_result_a == 0x80000000)
- ppc_state.spr[SPR::XER] |= 0xc0000000;
- else
- ppc_state.spr[SPR::XER] &= 0xBFFFFFFF;
- ppc_changecrf0(ppc_result_d);
ppc_store_result_regd();
}
@@ -806,27 +530,11 @@ void ppc_cntlzw() {
}
#endif
ppc_result_a = lead;
- ppc_store_result_rega();
-}
-void ppc_cntlzwdot() {
- ppc_grab_regssa();
-
- uint32_t lead = 0;
- uint32_t bit_check = ppc_result_d;
-
-#ifdef USE_GCC_BUILTINS
- lead = __builtin_clz(bit_check);
-#elif defined USE_VS_BUILTINS
- lead = __lzcnt(bit_check);
-#else
- for (uint32_t mask = 0x80000000UL; mask; lead++, mask >>= 1) {
- if (bit_check & mask)
- break;
+ if (rc_flag) {
+ ppc_changecrf0(ppc_result_a);
}
-#endif
- ppc_result_a = lead;
- ppc_changecrf0(ppc_result_a);
+
ppc_store_result_rega();
}
@@ -834,14 +542,10 @@ void ppc_mulhwu() {
ppc_grab_regsdab();
uint64_t product = (uint64_t)ppc_result_a * (uint64_t)ppc_result_b;
ppc_result_d = (uint32_t)(product >> 32);
- ppc_store_result_regd();
-}
-void ppc_mulhwudot() {
- ppc_grab_regsdab();
- uint64_t product = (uint64_t)ppc_result_a * (uint64_t)ppc_result_b;
- ppc_result_d = (uint32_t)(product >> 32);
- ppc_changecrf0(ppc_result_d);
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_d);
+
ppc_store_result_regd();
}
@@ -849,54 +553,30 @@ void ppc_mulhw() {
ppc_grab_regsdab();
int64_t product = (int64_t)(int32_t)ppc_result_a * (int64_t)(int32_t)ppc_result_b;
ppc_result_d = product >> 32;
- ppc_store_result_regd();
-}
-void ppc_mulhwdot() {
- ppc_grab_regsdab();
- int64_t product = (int64_t)(int32_t)ppc_result_a * (int64_t)(int32_t)ppc_result_b;
- ppc_result_d = product >> 32;
- ppc_changecrf0(ppc_result_d);
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_d);
+
ppc_store_result_regd();
}
void ppc_mullw() {
ppc_grab_regsdab();
int64_t product = (int64_t)(int32_t)ppc_result_a * (int64_t)(int32_t)ppc_result_b;
- ppc_result_d = (uint32_t)product;
- ppc_store_result_regd();
-}
-void ppc_mullwdot() {
- ppc_grab_regsdab();
- int64_t product = (int64_t)(int32_t)ppc_result_a * (int64_t)(int32_t)ppc_result_b;
- ppc_result_d = (uint32_t)product;
- ppc_changecrf0(ppc_result_d);
- ppc_store_result_regd();
-}
-
-void ppc_mullwo() {
- ppc_grab_regsdab();
- int64_t product = (int64_t)(int32_t)ppc_result_a * (int64_t)(int32_t)ppc_result_b;
- if (product != (int64_t)(int32_t)product) {
- ppc_state.spr[SPR::XER] |= 0xC0000000;
- } else {
- ppc_state.spr[SPR::XER] &= 0xBFFFFFFFUL;
+ if (oe_flag) {
+ if (product != (int64_t)(int32_t)product) {
+ ppc_state.spr[SPR::XER] |= 0xC0000000;
+ } else {
+ ppc_state.spr[SPR::XER] &= 0xBFFFFFFFUL;
+ }
}
- ppc_result_d = (uint32_t)product;
- ppc_store_result_regd();
-}
-void ppc_mullwodot() {
- ppc_grab_regsdab();
- int64_t product = (int64_t)(int32_t)ppc_result_a * (int64_t)(int32_t)ppc_result_b;
- if (product != (int64_t)(int32_t)product) {
- ppc_state.spr[SPR::XER] |= 0xC0000000;
- } else {
- ppc_state.spr[SPR::XER] &= 0xBFFFFFFFUL;
- }
- ppc_result_d = (uint32_t)product;
- ppc_changecrf0(ppc_result_d);
+ ppc_result_d = (uint32_t)product;
+
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_d);
+
ppc_store_result_regd();
}
@@ -907,68 +587,32 @@ void ppc_mulli() {
ppc_store_result_regd();
}
-
void ppc_divw() {
ppc_grab_regsdab();
if (!ppc_result_b) { /* handle the "anything / 0" case */
ppc_result_d = (ppc_result_a & 0x80000000) ? -1 : 0; /* UNDOCUMENTED! */
+
+ if (oe_flag)
+ ppc_state.spr[SPR::XER] |= 0xC0000000;
+
} else if (ppc_result_a == 0x80000000UL && ppc_result_b == 0xFFFFFFFFUL) {
ppc_result_d = 0xFFFFFFFF;
- } else { /* normal signed devision */
+
+ if (oe_flag)
+ ppc_state.spr[SPR::XER] |= 0xC0000000;
+
+ }
+ else { /* normal signed devision */
ppc_result_d = (int32_t)ppc_result_a / (int32_t)ppc_result_b;
+
+ if (oe_flag)
+ ppc_state.spr[SPR::XER] &= 0xBFFFFFFFUL;
}
- ppc_store_result_regd();
-}
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_d);
-void ppc_divwdot() {
- ppc_grab_regsdab();
-
- if (!ppc_result_b) { /* handle the "anything / 0" case */
- ppc_result_d = (ppc_result_a & 0x80000000) ? -1 : 0; /* UNDOCUMENTED! */
- } else if (ppc_result_a == 0x80000000UL && ppc_result_b == 0xFFFFFFFFUL) {
- ppc_result_d = 0xFFFFFFFF;
- } else { /* normal signed devision */
- ppc_result_d = (int32_t)ppc_result_a / (int32_t)ppc_result_b;
- }
-
- ppc_changecrf0(ppc_result_d);
- ppc_store_result_regd();
-}
-
-void ppc_divwo() {
- ppc_grab_regsdab();
-
- if (!ppc_result_b) { /* handle the "anything / 0" case */
- ppc_result_d = (ppc_result_a & 0x80000000) ? -1 : 0; /* UNDOCUMENTED! */
- ppc_state.spr[SPR::XER] |= 0xC0000000;
- } else if (ppc_result_a == 0x80000000UL && ppc_result_b == 0xFFFFFFFFUL) {
- ppc_result_d = 0xFFFFFFFF;
- ppc_state.spr[SPR::XER] |= 0xC0000000;
- } else { /* normal signed devision */
- ppc_result_d = (int32_t)ppc_result_a / (int32_t)ppc_result_b;
- ppc_state.spr[SPR::XER] &= 0xBFFFFFFFUL;
- }
-
- ppc_store_result_regd();
-}
-
-void ppc_divwodot() {
- ppc_grab_regsdab();
-
- if (!ppc_result_b) { /* handle the "anything / 0" case */
- ppc_result_d = (ppc_result_a & 0x80000000) ? -1 : 0; /* UNDOCUMENTED! */
- ppc_state.spr[SPR::XER] |= 0xC0000000;
- } else if (ppc_result_a == 0x80000000UL && ppc_result_b == 0xFFFFFFFFUL) {
- ppc_result_d = 0xFFFFFFFF;
- ppc_state.spr[SPR::XER] |= 0xC0000000;
- } else { /* normal signed devision */
- ppc_result_d = (int32_t)ppc_result_a / (int32_t)ppc_result_b;
- ppc_state.spr[SPR::XER] &= 0xBFFFFFFFUL;
- }
-
- ppc_changecrf0(ppc_result_d);
ppc_store_result_regd();
}
@@ -977,49 +621,22 @@ void ppc_divwu() {
if (!ppc_result_b) { /* division by zero */
ppc_result_d = 0;
+
+ if (oe_flag)
+ ppc_state.spr[SPR::XER] |= 0xC0000000;
+
+ if (rc_flag)
+ ppc_state.cr |= 0x20000000;
+
} else {
ppc_result_d = ppc_result_a / ppc_result_b;
+
+ if (oe_flag)
+ ppc_state.spr[SPR::XER] &= 0xBFFFFFFFUL;
}
- ppc_store_result_regd();
-}
-
-void ppc_divwudot() {
- ppc_grab_regsdab();
-
- if (!ppc_result_b) { /* division by zero */
- ppc_result_d = 0;
- ppc_state.cr |= 0x20000000;
- } else {
- ppc_result_d = ppc_result_a / ppc_result_b;
+ if (rc_flag)
ppc_changecrf0(ppc_result_d);
- }
- ppc_store_result_regd();
-}
-void ppc_divwuo() {
- ppc_grab_regsdab();
-
- if (!ppc_result_b) { /* division by zero */
- ppc_result_d = 0;
- ppc_state.spr[SPR::XER] |= 0xC0000000;
- } else {
- ppc_result_d = ppc_result_a / ppc_result_b;
- ppc_state.spr[SPR::XER] &= 0xBFFFFFFFUL;
- }
- ppc_store_result_regd();
-}
-
-void ppc_divwuodot() {
- ppc_grab_regsdab();
-
- if (!ppc_result_b) { /* division by zero */
- ppc_result_d = 0;
- ppc_state.spr[SPR::XER] |= 0xC0000000;
- } else {
- ppc_result_d = ppc_result_a / ppc_result_b;
- ppc_state.spr[SPR::XER] &= 0xBFFFFFFFUL;
- }
- ppc_changecrf0(ppc_result_d);
ppc_store_result_regd();
}
@@ -1032,17 +649,10 @@ void ppc_slw() {
} else {
ppc_result_a = ppc_result_d << (ppc_result_b & 0x1F);
}
- ppc_store_result_rega();
-}
-void ppc_slwdot() {
- ppc_grab_regssab();
- if (ppc_result_b & 0x20) {
- ppc_result_a = 0;
- } else {
- ppc_result_a = ppc_result_d << (ppc_result_b & 0x1F);
- }
- ppc_changecrf0(ppc_result_a);
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_a);
+
ppc_store_result_rega();
}
@@ -1053,17 +663,10 @@ void ppc_srw() {
} else {
ppc_result_a = ppc_result_d >> (ppc_result_b & 0x1F);
}
- ppc_store_result_rega();
-}
-void ppc_srwdot() {
- ppc_grab_regssab();
- if (ppc_result_b & 0x20) {
- ppc_result_a = 0;
- } else {
- ppc_result_a = ppc_result_d >> (ppc_result_b & 0x1F);
- }
- ppc_changecrf0(ppc_result_a);
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_a);
+
ppc_store_result_rega();
}
@@ -1082,25 +685,10 @@ void ppc_sraw() {
ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL;
}
}
- ppc_store_result_rega();
-}
-void ppc_srawdot() {
- ppc_grab_regssab();
- if (ppc_result_b & 0x20) {
- ppc_result_a = (int32_t)ppc_result_d >> 31;
- ppc_state.spr[SPR::XER] |= (ppc_result_a & 1) << 29;
- } else {
- uint32_t shift = ppc_result_b & 0x1F;
- uint32_t mask = (1 << shift) - 1;
- ppc_result_a = (int32_t)ppc_result_d >> shift;
- if ((ppc_result_d & 0x80000000UL) && (ppc_result_d & mask)) {
- ppc_state.spr[SPR::XER] |= 0x20000000UL;
- } else {
- ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL;
- }
- }
- ppc_changecrf0(ppc_result_a);
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_a);
+
ppc_store_result_rega();
}
@@ -1114,20 +702,10 @@ void ppc_srawi() {
} else {
ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL;
}
- ppc_store_result_rega();
-}
-void ppc_srawidot() {
- ppc_grab_regssa();
- unsigned shift = (ppc_cur_instruction >> 11) & 0x1F;
- uint32_t mask = (1 << shift) - 1;
- ppc_result_a = (int32_t)ppc_result_d >> shift;
- if ((ppc_result_d & 0x80000000UL) && (ppc_result_d & mask)) {
- ppc_state.spr[SPR::XER] |= 0x20000000UL;
- } else {
- ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL;
- }
- ppc_changecrf0(ppc_result_a);
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_a);
+
ppc_store_result_rega();
}
@@ -1351,15 +929,10 @@ void ppc_extsb() {
ppc_result_d = ppc_result_d & 0xFF;
ppc_result_a = (ppc_result_d < 0x80) ? (ppc_result_d & 0x000000FF)
: (0xFFFFFF00UL | (ppc_result_d & 0x000000FF));
- ppc_store_result_rega();
-}
-void ppc_extsbdot() {
- ppc_grab_regssa();
- ppc_result_d = ppc_result_d & 0xFF;
- ppc_result_a = (ppc_result_d < 0x80) ? (ppc_result_d & 0x000000FF)
- : (0xFFFFFF00UL | (ppc_result_d & 0x000000FF));
- ppc_changecrf0(ppc_result_a);
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_a);
+
ppc_store_result_rega();
}
@@ -1368,15 +941,9 @@ void ppc_extsh() {
ppc_result_d = ppc_result_d & 0xFFFF;
ppc_result_a = (ppc_result_d < 0x8000) ? (ppc_result_d & 0x0000FFFF)
: (0xFFFF0000UL | (ppc_result_d & 0x0000FFFF));
- ppc_store_result_rega();
-}
+ if (rc_flag)
+ ppc_changecrf0(ppc_result_a);
-void ppc_extshdot() {
- ppc_grab_regssa();
- ppc_result_d = ppc_result_d & 0xFFFF;
- ppc_result_a = (ppc_result_d < 0x8000) ? (ppc_result_d & 0x0000FFFF)
- : (0xFFFF0000UL | (ppc_result_d & 0x0000FFFF));
- ppc_changecrf0(ppc_result_a);
ppc_store_result_rega();
}
@@ -1895,14 +1462,18 @@ void ppc_stwx() {
void ppc_stwcx() {
// PLACEHOLDER CODE FOR STWCX - We need to check for reserve memory
- ppc_grab_regssab();
- ppc_effective_address = (reg_a == 0) ? ppc_result_b : (ppc_result_a + ppc_result_b);
- if (ppc_state.reserve) {
- mem_write_dword(ppc_effective_address, ppc_result_d);
- ppc_state.cr |= (ppc_state.spr[SPR::XER] & 0x80000000) ? 0x30000000 : 0x20000000;
- ppc_state.reserve = false;
+ if (rc_flag == 0) {
+ ppc_illegalsubop31();
} else {
- ppc_state.cr |= (ppc_state.spr[SPR::XER] & 0x80000000) ? 0x10000000 : 0;
+ ppc_grab_regssab();
+ ppc_effective_address = (reg_a == 0) ? ppc_result_b : (ppc_result_a + ppc_result_b);
+ if (ppc_state.reserve) {
+ mem_write_dword(ppc_effective_address, ppc_result_d);
+ ppc_state.cr |= (ppc_state.spr[SPR::XER] & 0x80000000) ? 0x30000000 : 0x20000000;
+ ppc_state.reserve = false;
+ } else {
+ ppc_state.cr |= (ppc_state.spr[SPR::XER] & 0x80000000) ? 0x10000000 : 0;
+ }
}
}
diff --git a/cpu/ppc/test/ppctests.cpp b/cpu/ppc/test/ppctests.cpp
index 1e1a043..0f3b512 100644
--- a/cpu/ppc/test/ppctests.cpp
+++ b/cpu/ppc/test/ppctests.cpp
@@ -142,6 +142,8 @@ static void read_test_data() {
}
int main() {
+ initialize_ppc_opcode_tables(); //kludge
+
cout << "Running DingusPPC emulator tests..." << endl << endl;
ntested = 0;
diff --git a/main.cpp b/main.cpp
index 7a66297..f2527ac 100644
--- a/main.cpp
+++ b/main.cpp
@@ -121,6 +121,8 @@ int main(int argc, char** argv) {
loguru::init(argc, argv);
}
+ initialize_ppc_opcode_tables(); //Temp location for initializing opcode tables
+
if (*machine_opt) {
LOG_F(INFO, "Machine option was passed in: %s", machine_str.c_str());
} else {