mirror of
https://github.com/dingusdev/dingusppc.git
synced 2025-08-06 10:25:27 +00:00
Fix-ups
This commit is contained in:
@@ -34,16 +34,19 @@ void ppc_exception_handler(Except_Type exception_type, uint32_t srr1_bits) {
|
||||
#endif
|
||||
|
||||
uint32_t cs_code[] = {
|
||||
0x3863FFFC, 0x7C861671, 0x41820090, 0x70600002, 0x41E2001C, 0xA0030004,
|
||||
0x3884FFFE, 0x38630002, 0x5486F0BF, 0x7CA50114, 0x41820070, 0x70C60003,
|
||||
0x41820014, 0x7CC903A6, 0x84030004, 0x7CA50114, 0x4200FFF8, 0x5486E13F,
|
||||
0x41820050, 0x80030004, 0x7CC903A6, 0x80C30008, 0x7CA50114, 0x80E3000C,
|
||||
0x7CA53114, 0x85030010, 0x7CA53914, 0x42400028, 0x80030004, 0x7CA54114,
|
||||
0x80C30008, 0x7CA50114, 0x80E3000C, 0x7CA53114, 0x85030010, 0x7CA53914,
|
||||
0x4200FFE0, 0x7CA54114, 0x70800002, 0x41E20010, 0xA0030004, 0x38630002,
|
||||
0x7CA50114, 0x70800001, 0x41E20010, 0x88030004, 0x5400402E, 0x7CA50114,
|
||||
0x7C650194, /* 0x4E800020 */ 0x00005AF0
|
||||
};
|
||||
0x3863FFFC, 0x7C861671, 0x41820090, 0x70600002,
|
||||
0x41E2001C, 0xA0030004, 0x3884FFFE, 0x38630002,
|
||||
0x5486F0BF, 0x7CA50114, 0x41820070, 0x70C60003,
|
||||
0x41820014, 0x7CC903A6, 0x84030004, 0x7CA50114,
|
||||
0x4200FFF8, 0x5486E13F, 0x41820050, 0x80030004,
|
||||
0x7CC903A6, 0x80C30008, 0x7CA50114, 0x80E3000C,
|
||||
0x7CA53114, 0x85030010, 0x7CA53914, 0x42400028,
|
||||
0x80030004, 0x7CA54114, 0x80C30008, 0x7CA50114,
|
||||
0x80E3000C, 0x7CA53114, 0x85030010, 0x7CA53914,
|
||||
0x4200FFE0, 0x7CA54114, 0x70800002, 0x41E20010,
|
||||
0xA0030004, 0x38630002, 0x7CA50114, 0x70800001,
|
||||
0x41E20010, 0x88030004, 0x5400402E, 0x7CA50114,
|
||||
0x7C650194, 0x4E800020};
|
||||
|
||||
constexpr uint32_t test_size = 0x8000; // 0x7FFFFFFC is the max
|
||||
constexpr uint32_t test_samples = 200;
|
||||
|
@@ -83,7 +83,7 @@ typedef struct struct_ppc_instr {
|
||||
};
|
||||
} SetInstr;
|
||||
|
||||
SetInstr instr;
|
||||
extern SetInstr instr;
|
||||
|
||||
typedef struct struct_ppc_state {
|
||||
FPR_storage fpr[32];
|
||||
@@ -98,7 +98,7 @@ typedef struct struct_ppc_state {
|
||||
bool reserve; // reserve bit used for lwarx and stcwx
|
||||
} SetPRS;
|
||||
|
||||
SetPRS ppc_state;
|
||||
extern SetPRS ppc_state;
|
||||
|
||||
/** symbolic names for frequently used SPRs */
|
||||
enum SPR : int {
|
||||
@@ -423,7 +423,6 @@ void ppc_fpu_off();
|
||||
void ppc_assert_int();
|
||||
void ppc_release_int();
|
||||
|
||||
void (*ref_instr)();
|
||||
void decode_instr();
|
||||
void initialize_ppc_opcode_tables(bool include_601);
|
||||
|
||||
|
@@ -56,6 +56,10 @@ using namespace dppc_interpreter;
|
||||
|
||||
MemCtrlBase* mem_ctrl_instance = 0;
|
||||
|
||||
void (*ref_instr)();
|
||||
SetPRS ppc_state;
|
||||
SetInstr instr;
|
||||
|
||||
bool is_601 = false;
|
||||
|
||||
bool power_on = false;
|
||||
@@ -245,7 +249,7 @@ void ppc_opcode19() {
|
||||
switch (subop_grab) {
|
||||
case 0:
|
||||
ref_instr = ppc_mcrf;
|
||||
ppc_grab_regs_crf(ppc_cur_instruction);
|
||||
ppc_grab_regs_crfds(ppc_cur_instruction);
|
||||
break;
|
||||
case 32:
|
||||
ref_instr = ppc_bclr<LK0>;
|
||||
@@ -311,18 +315,22 @@ template void ppc_opcode19<IS601>();
|
||||
|
||||
static void ppc_opcode31() {
|
||||
uint16_t subop_grab = ppc_cur_instruction & 0x7FFUL;
|
||||
ref_instr = SubOpcode59Grabber[subop_grab];
|
||||
ref_instr = SubOpcode31Grabber[subop_grab];
|
||||
|
||||
switch ((subop_grab >> 1)) {
|
||||
case 0:
|
||||
case 32:
|
||||
ppc_grab_crfd_regsab(ppc_cur_instruction);
|
||||
break;
|
||||
case 8:
|
||||
ppc_grab_tw(ppc_cur_instruction);
|
||||
break;
|
||||
case 83:
|
||||
ppc_grab_d(ppc_cur_instruction);
|
||||
break;
|
||||
case 144:
|
||||
ppc_grab_crfd(ppc_cur_instruction);
|
||||
break;
|
||||
case 210:
|
||||
case 595:
|
||||
ppc_grab_sr(ppc_cur_instruction);
|
||||
@@ -343,16 +351,24 @@ static void ppc_opcode59() {
|
||||
|
||||
static void ppc_opcode63() {
|
||||
uint16_t subop_grab = ppc_cur_instruction & 0x7FFUL;
|
||||
ref_instr = SubOpcode59Grabber[subop_grab];
|
||||
ref_instr = SubOpcode63Grabber[subop_grab];
|
||||
|
||||
switch ((subop_grab >> 1)) {
|
||||
case 0:
|
||||
case 32:
|
||||
ppc_grab_regsfpsab(ppc_cur_instruction);
|
||||
break;
|
||||
case 38:
|
||||
case 70:
|
||||
ppc_grab_crfd(ppc_cur_instruction);
|
||||
break;
|
||||
case 64:
|
||||
ppc_grab_regs_crf(ppc_cur_instruction);
|
||||
ppc_grab_regs_crfds(ppc_cur_instruction);
|
||||
break;
|
||||
case 134:
|
||||
ppc_grab_mtfsfi(ppc_cur_instruction);
|
||||
break;
|
||||
case 711:
|
||||
default:
|
||||
ppc_grab_regsfpdabc(ppc_cur_instruction);
|
||||
}
|
||||
@@ -375,10 +391,12 @@ static void ppc_main_opcode() {
|
||||
case 20: case 21:
|
||||
case 22: case 23:
|
||||
ppc_grab_regs_sab_rot(ppc_cur_instruction);
|
||||
break;
|
||||
case 24: case 25:
|
||||
case 26: case 27:
|
||||
case 28: case 29:
|
||||
ppc_grab_regs_sauimm(ppc_cur_instruction);
|
||||
break;
|
||||
case 32: case 33: case 34: case 35:
|
||||
case 36: case 37: case 38: case 39:
|
||||
case 40: case 31: case 42: case 43:
|
||||
@@ -386,6 +404,7 @@ static void ppc_main_opcode() {
|
||||
case 48: case 49: case 50: case 51:
|
||||
case 52: case 53: case 54: case 55:
|
||||
ppc_grab_regs_da_addr(ppc_cur_instruction);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1014,7 +1033,7 @@ void ppc_cpu_init(MemCtrlBase* mem_ctrl, uint32_t cpu_version, bool include_601,
|
||||
tbr_wr_timestamp = 0;
|
||||
rtc_timestamp = 0;
|
||||
tbr_wr_value = 0;
|
||||
tbr_freq_ghz = (tb_freq << 32) / NS_PER_SEC;
|
||||
tbr_freq_ghz = uint32_t((tb_freq << 32) / NS_PER_SEC);
|
||||
tbr_period_ns = ((uint64_t)NS_PER_SEC << 32) / tb_freq;
|
||||
|
||||
exec_flags = 0;
|
||||
|
@@ -638,7 +638,7 @@ static void round_to_int(const uint8_t mode, field_rc rec) {
|
||||
ppc_state.fpr[instr.arg0].int64_r = 0xFFF8000080000000ULL;
|
||||
}
|
||||
} else {
|
||||
uint64_t ppc_result64_d;
|
||||
uint64_t ppc_result64_d = 0;
|
||||
switch (mode & 0x3) {
|
||||
case 0:
|
||||
ppc_result64_d = uint32_t(round_to_nearest(val_reg_b));
|
||||
@@ -875,7 +875,8 @@ void dppc_interpreter::ppc_mtfsf() {
|
||||
cr_mask &= ~(FPSCR::FEX | FPSCR::VX);
|
||||
|
||||
// copy FPR[reg_b] to FPSCR under control of cr_mask
|
||||
ppc_state.fpscr = (ppc_state.fpscr & ~cr_mask) | (ppc_state.fpr[instr.arg2].int64_r & cr_mask);
|
||||
ppc_state.fpscr = (ppc_state.fpscr & ~cr_mask) |
|
||||
(ppc_state.fpr[instr.arg2].int64_r & cr_mask);
|
||||
|
||||
if (rec)
|
||||
ppc_update_cr1();
|
||||
@@ -905,9 +906,8 @@ template void dppc_interpreter::ppc_mtfsfi<RC1>();
|
||||
|
||||
template <field_rc rec>
|
||||
void dppc_interpreter::ppc_mtfsb0() {
|
||||
int crf_d = (ppc_cur_instruction >> 21) & 0x1F;
|
||||
if (!crf_d || (crf_d > 2)) { // FEX and VX can't be explicitly cleared
|
||||
ppc_state.fpscr &= ~(0x80000000UL >> crf_d);
|
||||
if (!instr.arg0 || (instr.arg0 > 2)) { // FEX and VX can't be explicitly cleared
|
||||
ppc_state.fpscr &= ~(0x80000000UL >> instr.arg0);
|
||||
}
|
||||
|
||||
if (rec)
|
||||
@@ -919,9 +919,8 @@ template void dppc_interpreter::ppc_mtfsb0<RC1>();
|
||||
|
||||
template <field_rc rec>
|
||||
void dppc_interpreter::ppc_mtfsb1() {
|
||||
int crf_d = (ppc_cur_instruction >> 21) & 0x1F;
|
||||
if (!crf_d || (crf_d > 2)) { // FEX and VX can't be explicitly set
|
||||
ppc_state.fpscr |= (0x80000000UL >> crf_d);
|
||||
if (!instr.arg0 || (instr.arg0 > 2)) { // FEX and VX can't be explicitly set
|
||||
ppc_state.fpscr |= (0x80000000UL >> instr.arg0);
|
||||
}
|
||||
|
||||
if (rec)
|
||||
|
@@ -40,6 +40,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#define crf_s(opcode) ((opcode >> 16) & 0x1C)
|
||||
#define crm(opcode) ((opcode >> 12) & 0xFFU)
|
||||
#define fcrm(opcode) crm(opcode)
|
||||
#define fmmask(opcode) ((opcode >> 17) & 0xFFU)
|
||||
#define br_bo(opcode) reg_d(opcode)
|
||||
#define br_bi(opcode) reg_a(opcode)
|
||||
#define br_bd(opcode) int32_t(int16_t(opcode & ~3UL))
|
||||
@@ -56,18 +57,26 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#define ppc_grab_tw(opcode) \
|
||||
instr.i_simm = simm(opcode); \
|
||||
instr.arg1 = reg_a(opcode); \
|
||||
instr.arg0 = trap_to(opcode);
|
||||
instr.arg0 = trap_to(opcode); \
|
||||
|
||||
#define ppc_grab_crfd(opcode) \
|
||||
instr.arg0 = crf_d(opcode);
|
||||
|
||||
#define ppc_grab_mcrxr(opcode) \
|
||||
instr.arg0 = crf_d(opcode);
|
||||
instr.arg0 = crf_d(opcode); \
|
||||
instr.arg4 = crf_d(opcode); \
|
||||
|
||||
#define ppc_grab_sr(opcode) \
|
||||
instr.arg0 = reg_d(opcode); \
|
||||
instr.arg1 = segreg(opcode);
|
||||
instr.arg1 = segreg(opcode); \
|
||||
|
||||
#define ppc_grab_mtfsfi(opcode) \
|
||||
instr.arg0 = reg_d(opcode); \
|
||||
instr.mask = mtfsfi_mask(opcode);
|
||||
instr.mask = mtfsfi_mask(opcode); \
|
||||
|
||||
#define ppc_grab_mtfsf(opcode) \
|
||||
instr.arg2 = reg_b(opcode); \
|
||||
instr.mask = fmmask(opcode);\
|
||||
|
||||
#define ppc_grab_regs_dasimm(opcode) \
|
||||
instr.arg0 = reg_d(opcode); \
|
||||
@@ -85,15 +94,11 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
instr.addr = adr_d(opcode); \
|
||||
|
||||
#define ppc_grab_branch(opcode) \
|
||||
instr.addr = adr_li(opcode);
|
||||
instr.addr = adr_li(opcode); \
|
||||
|
||||
#define ppc_grab_branch_cond(opcode) \
|
||||
instr.arg0 = br_bo(opcode); \
|
||||
instr.arg1 = br_bi(opcode);
|
||||
|
||||
#define ppc_grab_branch_cond(opcode) \
|
||||
instr.arg0 = br_bo(opcode); \
|
||||
instr.arg1 = br_bi(opcode);
|
||||
instr.arg1 = br_bi(opcode); \
|
||||
|
||||
#define ppc_grab_d(opcode) \
|
||||
instr.arg0 = reg_d(opcode);
|
||||
@@ -126,7 +131,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#define ppc_grab_s(opcode) \
|
||||
instr.arg0 = reg_s(opcode); \
|
||||
|
||||
#define ppc_grab_regs_crf(opcode) \
|
||||
#define ppc_grab_regs_crfds(opcode) \
|
||||
instr.arg0 = crf_d(opcode); \
|
||||
instr.arg1 = crf_s(opcode); \
|
||||
|
||||
|
@@ -982,6 +982,7 @@ void dppc_interpreter::ppc_mtspr() {
|
||||
case 543:
|
||||
ppc_state.spr[ref_spr] = val;
|
||||
dbat_update(ref_spr);
|
||||
break;
|
||||
default:
|
||||
// FIXME: Unknown SPR should be noop or illegal instruction.
|
||||
ppc_state.spr[ref_spr] = val;
|
||||
@@ -1037,8 +1038,8 @@ void dppc_interpreter::ppc_mtcrf() {
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_mcrxr() {
|
||||
ppc_state.cr = (ppc_state.cr & ~(0xF0000000UL >> instr.arg4)) |
|
||||
((ppc_state.spr[SPR::XER] & 0xF0000000UL) >> instr.arg4);
|
||||
ppc_state.cr = (ppc_state.cr & ~(0xF0000000UL >> instr.arg0)) |
|
||||
((ppc_state.spr[SPR::XER] & 0xF0000000UL) >> instr.arg0);
|
||||
ppc_state.spr[SPR::XER] &= 0x0FFFFFFF;
|
||||
}
|
||||
|
||||
|
@@ -33,6 +33,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using namespace std;
|
||||
|
||||
void (*ref_instr)();
|
||||
|
||||
int ntested; // number of tested instructions
|
||||
int nfailed; // number of failed instructions
|
||||
|
||||
|
Reference in New Issue
Block a user