Compare commits

...

3 Commits

Author SHA1 Message Date
Rosalie Wanders cd89473f7e beep boop more wip changes 2025-09-28 14:18:53 +02:00
Rosalie Wanders b89fed20e8 Fix 2 small tests 2025-09-28 13:02:40 +02:00
Rosalie Wanders 28af6a436e 3rdParty: make mupen64plus-core use 64bit cop0 registers 2025-09-28 13:02:40 +02:00
12 changed files with 153 additions and 136 deletions
@@ -58,7 +58,7 @@ void pif_bootrom_hle_execute(struct r4300_core* r4300)
unsigned int tv_type = get_tv_type(); /* 0:PAL, 1:NTSC, 2:MPAL */
int64_t* r4300_gpregs = r4300_regs(r4300);
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
/* setup CP0 registers */
cp0_regs[CP0_STATUS_REG] = 0x34000000;
@@ -136,7 +136,7 @@ void cached_interp_##name##_OUT(void) \
void cached_interp_##name##_IDLE(void) \
{ \
DECLARE_R4300 \
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0); \
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0); \
int* cp0_cycle_count = r4300_cp0_cycle_count(&r4300->cp0); \
const int take_jump = (condition); \
if (cop1 && check_cop1_unusable(r4300)) return; \
+11 -11
View File
@@ -49,7 +49,7 @@ void init_cp0(struct cp0* cp0, unsigned int count_per_op, unsigned int count_per
void poweron_cp0(struct cp0* cp0)
{
uint32_t* cp0_regs;
uint64_t* cp0_regs;
unsigned int* cp0_next_interrupt;
int* cp0_cycle_count;
@@ -65,7 +65,7 @@ void poweron_cp0(struct cp0* cp0)
cp0_regs[CP0_COUNT_REG] = UINT32_C(0x5000);
cp0_regs[CP0_CAUSE_REG] = UINT32_C(0x5c);
cp0_regs[CP0_CONTEXT_REG] = UINT32_C(0x7ffff0);
cp0_regs[CP0_EPC_REG] = UINT32_C(0xffffffff);
cp0_regs[CP0_EPC_REG] = UINT64_C(0xffffffffffffffff);
cp0_regs[CP0_BADVADDR_REG] = UINT32_C(0xffffffff);
cp0_regs[CP0_ERROREPC_REG] = UINT32_C(0xffffffff);
@@ -81,7 +81,7 @@ void poweron_cp0(struct cp0* cp0)
}
uint32_t* r4300_cp0_regs(struct cp0* cp0)
uint64_t* r4300_cp0_regs(struct cp0* cp0)
{
#ifndef NEW_DYNAREC
return cp0->regs;
@@ -124,7 +124,7 @@ int* r4300_cp0_cycle_count(struct cp0* cp0)
int check_cop1_unusable(struct r4300_core* r4300)
{
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
if (!(cp0_regs[CP0_STATUS_REG] & CP0_STATUS_CU1))
{
@@ -137,7 +137,7 @@ int check_cop1_unusable(struct r4300_core* r4300)
int check_cop2_unusable(struct r4300_core* r4300)
{
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
if (!(cp0_regs[CP0_STATUS_REG] & CP0_STATUS_CU2))
{
@@ -151,7 +151,7 @@ int check_cop2_unusable(struct r4300_core* r4300)
void cp0_update_count(struct r4300_core* r4300)
{
struct cp0* cp0 = &r4300->cp0;
uint32_t* cp0_regs = r4300_cp0_regs(cp0);
uint64_t* cp0_regs = r4300_cp0_regs(cp0);
#ifdef NEW_DYNAREC
if (r4300->emumode != EMUMODE_DYNAREC)
@@ -213,7 +213,7 @@ static void exception_epilog(struct r4300_core* r4300)
void TLB_refill_exception(struct r4300_core* r4300, uint32_t address, int w)
{
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
int usual_handler = 0, i;
if (r4300->emumode != EMUMODE_DYNAREC && w != 2) {
@@ -246,8 +246,8 @@ void TLB_refill_exception(struct r4300_core* r4300, uint32_t address, int w)
if (r4300->emumode != EMUMODE_PURE_INTERPRETER)
{
cp0_regs[CP0_EPC_REG] = (w != 2)
? *r4300_pc(r4300)
: address;
? SE32(*r4300_pc(r4300))
: SE32(address);
}
else {
cp0_regs[CP0_EPC_REG] = *r4300_pc(r4300);
@@ -297,12 +297,12 @@ void TLB_refill_exception(struct r4300_core* r4300, uint32_t address, int w)
void exception_general(struct r4300_core* r4300)
{
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
cp0_update_count(r4300);
cp0_regs[CP0_STATUS_REG] |= CP0_STATUS_EXL;
cp0_regs[CP0_EPC_REG] = *r4300_pc(r4300);
cp0_regs[CP0_EPC_REG] = SE32(*r4300_pc(r4300));
if (r4300->delay_slot == 1 || r4300->delay_slot == 3)
{
+2 -2
View File
@@ -184,7 +184,7 @@ struct cp0
{
#ifndef NEW_DYNAREC
/* New dynarec uses a different memory layout */
uint32_t regs[CP0_REGS_COUNT];
uint64_t regs[CP0_REGS_COUNT];
uint64_t latch;
#endif
@@ -227,7 +227,7 @@ struct cp0
void init_cp0(struct cp0* cp0, unsigned int count_per_op, unsigned int count_per_op_denom_pot, struct new_dynarec_hot_state* new_dynarec_hot_state, const struct interrupt_handler* interrupt_handlers);
void poweron_cp0(struct cp0* cp0);
uint32_t* r4300_cp0_regs(struct cp0* cp0);
uint64_t* r4300_cp0_regs(struct cp0* cp0);
uint64_t* r4300_cp0_latch(struct cp0* cp0);
uint32_t* r4300_cp0_last_addr(struct cp0* cp0);
unsigned int* r4300_cp0_next_interrupt(struct cp0* cp0);
+12 -12
View File
@@ -100,7 +100,7 @@ static void clear_queue(struct interrupt_queue* q)
static int before_event(const struct cp0* cp0, unsigned int evt1, unsigned int evt2, int type2)
{
const uint32_t* cp0_regs = r4300_cp0_regs((struct cp0*)cp0); /* OK to cast away const qualifier */
const uint64_t* cp0_regs = r4300_cp0_regs((struct cp0*)cp0); /* OK to cast away const qualifier */
uint32_t count = cp0_regs[CP0_COUNT_REG];
int* cp0_cycle_count = r4300_cp0_cycle_count((struct cp0*)cp0);
@@ -128,7 +128,7 @@ unsigned int add_random_interrupt_time(struct r4300_core* r4300)
void add_interrupt_event(struct cp0* cp0, int type, unsigned int delay)
{
const uint32_t* cp0_regs = r4300_cp0_regs(cp0);
const uint64_t* cp0_regs = r4300_cp0_regs(cp0);
add_interrupt_event_count(cp0, type, cp0_regs[CP0_COUNT_REG] + delay);
}
@@ -136,7 +136,7 @@ void add_interrupt_event_count(struct cp0* cp0, int type, unsigned int count)
{
struct node* event;
struct node* e;
const uint32_t* cp0_regs = r4300_cp0_regs(cp0);
const uint64_t* cp0_regs = r4300_cp0_regs(cp0);
unsigned int* cp0_next_interrupt = r4300_cp0_next_interrupt(cp0);
int* cp0_cycle_count = r4300_cp0_cycle_count(cp0);
@@ -191,7 +191,7 @@ void add_interrupt_event_count(struct cp0* cp0, int type, unsigned int count)
void remove_interrupt_event(struct cp0* cp0)
{
struct node* e;
const uint32_t* cp0_regs = r4300_cp0_regs(cp0);
const uint64_t* cp0_regs = r4300_cp0_regs(cp0);
unsigned int* cp0_next_interrupt = r4300_cp0_next_interrupt(cp0);
int* cp0_cycle_count = r4300_cp0_cycle_count(cp0);
@@ -264,7 +264,7 @@ void remove_event(struct interrupt_queue* q, int type)
void translate_event_queue(struct cp0* cp0, unsigned int base)
{
struct node* e;
uint32_t* cp0_regs = r4300_cp0_regs(cp0);
uint64_t* cp0_regs = r4300_cp0_regs(cp0);
int* cp0_cycle_count = r4300_cp0_cycle_count(cp0);
remove_event(&cp0->q, COMPARE_INT);
@@ -309,7 +309,7 @@ int save_eventqueue_infos(const struct cp0* cp0, char *buf)
void load_eventqueue_infos(struct cp0* cp0, const char *buf)
{
int len = 0;
uint32_t* cp0_regs = r4300_cp0_regs(cp0);
uint64_t* cp0_regs = r4300_cp0_regs(cp0);
clear_queue(&cp0->q);
@@ -335,7 +335,7 @@ void init_interrupt(struct cp0* cp0)
void r4300_check_interrupt(struct r4300_core* r4300, uint32_t cause_ip, int set_cause)
{
struct node* event;
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
unsigned int* cp0_next_interrupt = r4300_cp0_next_interrupt(&r4300->cp0);
int* cp0_cycle_count = r4300_cp0_cycle_count(&r4300->cp0);
@@ -379,7 +379,7 @@ void r4300_check_interrupt(struct r4300_core* r4300, uint32_t cause_ip, int set_
void raise_maskable_interrupt(struct r4300_core* r4300, uint32_t cause_ip)
{
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
cp0_regs[CP0_CAUSE_REG] = (cp0_regs[CP0_CAUSE_REG] | cause_ip) & ~CP0_CAUSE_EXCCODE_MASK;
if (!(cp0_regs[CP0_STATUS_REG] & cp0_regs[CP0_CAUSE_REG] & UINT32_C(0xff00))) {
@@ -396,7 +396,7 @@ void raise_maskable_interrupt(struct r4300_core* r4300, uint32_t cause_ip)
void compare_int_handler(void* opaque)
{
struct r4300_core* r4300 = (struct r4300_core*)opaque;
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
int* cp0_cycle_count = r4300_cp0_cycle_count(&r4300->cp0);
/* Add count_per_op to avoid wrong event order in case CP0_COUNT_REG == CP0_COMPARE_REG */
@@ -422,7 +422,7 @@ void check_int_handler(void* opaque)
void special_int_handler(void* opaque)
{
struct cp0* cp0 = (struct cp0*)opaque;
const uint32_t* cp0_regs = r4300_cp0_regs(cp0);
const uint64_t* cp0_regs = r4300_cp0_regs(cp0);
remove_interrupt_event(cp0);
add_interrupt_event_count(cp0, SPECIAL_INT, ((cp0_regs[CP0_COUNT_REG] & UINT32_C(0x80000000)) ^ UINT32_C(0x80000000)));
@@ -434,7 +434,7 @@ void nmi_int_handler(void* opaque)
{
struct device* dev = (struct device*)opaque;
struct r4300_core* r4300 = &dev->r4300;
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
reset_pif(&dev->pif, 1);
@@ -537,7 +537,7 @@ static void call_interrupt_handler(const struct cp0* cp0, size_t index)
void gen_interrupt(struct r4300_core* r4300)
{
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
unsigned int* cp0_next_interrupt = r4300_cp0_next_interrupt(&r4300->cp0);
int* cp0_cycle_count = r4300_cp0_cycle_count(&r4300->cp0);
@@ -115,7 +115,7 @@ DECLARE_INSTRUCTION(RESERVED)
{
DECLARE_R4300
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
DebugMessage(M64MSG_ERROR, "reserved opcode: %" PRIX32 ":%" PRIX32, PCADDR, *fast_mem_access(r4300, PCADDR));
@@ -127,7 +127,7 @@ DECLARE_INSTRUCTION(RESERVED_COP2)
{
DECLARE_R4300
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
if (check_cop2_unusable(r4300)) { return; }
@@ -140,7 +140,7 @@ DECLARE_INSTRUCTION(RESERVED_COP2)
DECLARE_INSTRUCTION(BREAK)
{
DECLARE_R4300
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_BP;
exception_general(r4300);
@@ -221,11 +221,23 @@ DECLARE_INSTRUCTION(LL)
DECLARE_INSTRUCTION(LW)
{
DECLARE_R4300
const uint32_t lsaddr = (uint32_t) irs32 + (uint32_t) iimmediate;
const uint64_t lsaddr = (int64_t) irs + (int16_t) iimmediate;
int64_t *lsrtp = &irt;
ADD_TO_PC(1);
uint32_t value;
if (lsaddr & 3) {
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
//
cp0_regs[CP0_CONTEXT_REG] = (cp0_regs[CP0_CONTEXT_REG] & 0xffffffffff800000) | (lsaddr >> 9 & 0x00000000007FFFF0);
cp0_regs[CP0_XCONTEXT_REG] = (cp0_regs[CP0_CONTEXT_REG] & 0xffffffffff800000) | (lsaddr >> 9 & 0x7FFFFFF0) | (lsaddr >> 31 & 0x80000000) | ((int64_t)1 << 32);
cp0_regs[CP0_BADVADDR_REG] = lsaddr;
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_ADEL;
exception_general(r4300);
return;
}
ADD_TO_PC(1);
if (r4300_read_aligned_word(r4300, lsaddr, &value)) {
*lsrtp = SE32(value);
}
@@ -374,8 +386,19 @@ DECLARE_INSTRUCTION(SC)
DECLARE_INSTRUCTION(SW)
{
DECLARE_R4300
const uint32_t lsaddr = (uint32_t) irs32 + (uint32_t) iimmediate;
const uint64_t lsaddr = (int64_t) irs + (int16_t) iimmediate;
int64_t *lsrtp = &irt;
if (lsaddr & 3) {
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
cp0_regs[CP0_CONTEXT_REG] = (lsaddr >> 9 & 0x007FFFF0);
cp0_regs[CP0_XCONTEXT_REG] = (lsaddr >> 9 & 0x7FFFFFF0) | (lsaddr >> 31 & 0x80000000) | ((int64_t)1 << 32);
cp0_regs[CP0_BADVADDR_REG] = lsaddr;
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_ADES;
exception_general(r4300);
return;
}
ADD_TO_PC(1);
r4300_write_aligned_word(r4300, lsaddr, (uint32_t)*lsrtp, ~UINT32_C(0));
@@ -993,7 +1016,7 @@ DECLARE_INSTRUCTION(CACHE)
DECLARE_INSTRUCTION(ERET)
{
DECLARE_R4300
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
int* cp0_cycle_count = r4300_cp0_cycle_count(&r4300->cp0);
cp0_update_count(r4300);
@@ -1022,7 +1045,7 @@ DECLARE_INSTRUCTION(SYNC)
DECLARE_INSTRUCTION(SYSCALL)
{
DECLARE_R4300
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_SYS;
exception_general(r4300);
@@ -1034,7 +1057,7 @@ DECLARE_INSTRUCTION(SYSCALL)
DECLARE_INSTRUCTION(name) \
{ \
DECLARE_R4300 \
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0); \
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0); \
if (cond) \
{ \
cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_TR; \
@@ -1067,7 +1090,7 @@ DECLARE_INSTRUCTION(TLBP)
{
DECLARE_R4300
int i;
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
cp0_regs[CP0_INDEX_REG] |= UINT32_C(0x80000000);
for (i = 0; i < 32; ++i)
@@ -1087,7 +1110,7 @@ DECLARE_INSTRUCTION(TLBP)
DECLARE_INSTRUCTION(TLBR)
{
DECLARE_R4300
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
int index;
index = cp0_regs[CP0_INDEX_REG] & UINT32_C(0x1F);
@@ -1104,7 +1127,7 @@ DECLARE_INSTRUCTION(TLBR)
static void TLBWrite(struct r4300_core* r4300, unsigned int idx)
{
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
uint32_t pc_addr = *r4300_pc(r4300);
if (pc_addr >= r4300->cp0.tlb.entries[idx].start_even && pc_addr < r4300->cp0.tlb.entries[idx].end_even && r4300->cp0.tlb.entries[idx].v_even)
@@ -1218,7 +1241,7 @@ static void TLBWrite(struct r4300_core* r4300, unsigned int idx)
DECLARE_INSTRUCTION(TLBWR)
{
DECLARE_R4300
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
cp0_update_count(r4300);
cp0_regs[CP0_RANDOM_REG] = (cp0_regs[CP0_COUNT_REG]/r4300->cp0.count_per_op % (32 - cp0_regs[CP0_WIRED_REG]))
+ cp0_regs[CP0_WIRED_REG];
@@ -1229,31 +1252,32 @@ DECLARE_INSTRUCTION(TLBWR)
DECLARE_INSTRUCTION(TLBWI)
{
DECLARE_R4300
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
TLBWrite(r4300, cp0_regs[CP0_INDEX_REG] & UINT32_C(0x3F));
ADD_TO_PC(1);
}
/* CP0 load/store instructions */
#include <stdio.h>
DECLARE_INSTRUCTION(MFC0)
static osal_inline uint64_t get_cp0_register(struct r4300_core* r4300, uint8_t reg)
{
DECLARE_R4300
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
uint64_t* cp0_latch = r4300_cp0_latch(&r4300->cp0);
switch(rfs)
uint64_t data;
switch (reg)
{
case CP0_RANDOM_REG:
cp0_update_count(r4300);
cp0_regs[CP0_RANDOM_REG] = (cp0_regs[CP0_COUNT_REG]/r4300->cp0.count_per_op % (32 - cp0_regs[CP0_WIRED_REG]))
+ cp0_regs[CP0_WIRED_REG];
rrt = SE32(cp0_regs[rfs]);
data = cp0_regs[reg];
break;
case CP0_COUNT_REG:
cp0_update_count(r4300);
rrt = SE32(cp0_regs[rfs]);
data = cp0_regs[reg];
break;
case CP0_UNUSED_7:
case CP0_UNUSED_21:
@@ -1262,90 +1286,53 @@ DECLARE_INSTRUCTION(MFC0)
case CP0_UNUSED_24:
case CP0_UNUSED_25:
case CP0_UNUSED_31:
rrt = (*cp0_latch);
data = (*cp0_latch);
break;
default:
rrt = SE32(cp0_regs[rfs]);
data = cp0_regs[reg];
break;
}
ADD_TO_PC(1);
return data;
}
DECLARE_INSTRUCTION(DMFC0)
static osal_inline void set_cp0_register(struct r4300_core* r4300, uint8_t reg, uint64_t value)
{
DECLARE_R4300
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
uint64_t* cp0_latch = r4300_cp0_latch(&r4300->cp0);
switch(rfs)
{
case CP0_RANDOM_REG:
cp0_update_count(r4300);
cp0_regs[CP0_RANDOM_REG] = (cp0_regs[CP0_COUNT_REG]/r4300->cp0.count_per_op % (32 - cp0_regs[CP0_WIRED_REG]))
+ cp0_regs[CP0_WIRED_REG];
rrt = cp0_regs[rfs];
break;
case CP0_COUNT_REG:
cp0_update_count(r4300);
rrt = cp0_regs[rfs];
break;
case CP0_EPC_REG:
rrt = SE32(cp0_regs[rfs]);
break;
case CP0_UNUSED_7:
case CP0_UNUSED_21:
case CP0_UNUSED_22:
case CP0_UNUSED_23:
case CP0_UNUSED_24:
case CP0_UNUSED_25:
case CP0_UNUSED_31:
rrt = (*cp0_latch);
break;
default:
rrt = cp0_regs[rfs];
break;
}
ADD_TO_PC(1);
}
DECLARE_INSTRUCTION(MTC0)
{
DECLARE_R4300
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
uint64_t* cp0_latch = r4300_cp0_latch(&r4300->cp0);
int* cp0_cycle_count = r4300_cp0_cycle_count(&r4300->cp0);
(*cp0_latch) = rrt32;
(*cp0_latch) = value;
switch(rfs)
switch (reg)
{
case CP0_INDEX_REG:
cp0_regs[CP0_INDEX_REG] = rrt32 & UINT32_C(0x8000003F);
cp0_regs[CP0_INDEX_REG] = value & UINT32_C(0x8000003F);
if ((cp0_regs[CP0_INDEX_REG] & UINT32_C(0x3F)) > UINT32_C(31))
{
DebugMessage(M64MSG_ERROR, "MTC0 instruction writing Index register with TLB index > 31");
*r4300_stop(r4300)=1;
//DebugMessage(M64MSG_ERROR, "MTC0 instruction writing Index register with TLB index > 31");
//*r4300_stop(r4300)=1;
}
break;
case CP0_RANDOM_REG:
break;
case CP0_ENTRYLO0_REG:
cp0_regs[CP0_ENTRYLO0_REG] = rrt32 & UINT32_C(0x3FFFFFFF);
cp0_regs[CP0_ENTRYLO0_REG] = value & UINT32_C(0x3FFFFFFF);
break;
case CP0_ENTRYLO1_REG:
cp0_regs[CP0_ENTRYLO1_REG] = rrt32 & UINT32_C(0x3FFFFFFF);
cp0_regs[CP0_ENTRYLO1_REG] = value & UINT32_C(0x3FFFFFFF);
break;
case CP0_CONTEXT_REG:
cp0_regs[CP0_CONTEXT_REG] = (rrt32 & UINT32_C(0xFF800000))
| (cp0_regs[CP0_CONTEXT_REG] & UINT32_C(0x007FFFF0));
// 0xffffffffff800000
cp0_regs[CP0_CONTEXT_REG] = value & UINT64_C(0xffffffffff800000);
break;
case CP0_XCONTEXT_REG:
//cp0_regs[CP0_XCONTEXT_REG] = value & UINT64_C(0xffffffffff800000);
break;
case CP0_PAGEMASK_REG:
cp0_regs[CP0_PAGEMASK_REG] = rrt32 & UINT32_C(0x01FFE000);
cp0_regs[CP0_PAGEMASK_REG] = value & UINT32_C(0x01FFE000);
break;
case CP0_WIRED_REG:
cp0_regs[CP0_WIRED_REG] = rrt32 & UINT32_C(0x0000003F);
cp0_regs[CP0_WIRED_REG] = value & UINT32_C(0x0000003F);
cp0_regs[CP0_RANDOM_REG] = UINT32_C(31);
break;
case CP0_BADVADDR_REG:
@@ -1355,10 +1342,10 @@ DECLARE_INSTRUCTION(MTC0)
r4300->cp0.interrupt_unsafe_state |= INTR_UNSAFE_R4300;
if (*cp0_cycle_count >= 0) { gen_interrupt(r4300); }
r4300->cp0.interrupt_unsafe_state &= ~INTR_UNSAFE_R4300;
translate_event_queue(&r4300->cp0, rrt32);
translate_event_queue(&r4300->cp0, value);
break;
case CP0_ENTRYHI_REG:
cp0_regs[CP0_ENTRYHI_REG] = rrt32 & UINT32_C(0xFFFFE0FF);
cp0_regs[CP0_ENTRYHI_REG] = value & UINT32_C(0xFFFFE0FF);
break;
case CP0_COMPARE_REG:
cp0_update_count(r4300);
@@ -1367,21 +1354,21 @@ DECLARE_INSTRUCTION(MTC0)
/* Add count_per_op to avoid wrong event order in case CP0_COUNT_REG == CP0_COMPARE_REG */
cp0_regs[CP0_COUNT_REG] += r4300->cp0.count_per_op;
*cp0_cycle_count += r4300->cp0.count_per_op;
add_interrupt_event_count(&r4300->cp0, COMPARE_INT, rrt32);
add_interrupt_event_count(&r4300->cp0, COMPARE_INT, value);
cp0_regs[CP0_COUNT_REG] -= r4300->cp0.count_per_op;
/* Update next interrupt in case first event is COMPARE_INT */
*cp0_cycle_count = cp0_regs[CP0_COUNT_REG] - r4300->cp0.q.first->data.count;
cp0_regs[CP0_COMPARE_REG] = rrt32;
cp0_regs[CP0_COMPARE_REG] = value;
cp0_regs[CP0_CAUSE_REG] &= ~CP0_CAUSE_IP7;
break;
case CP0_STATUS_REG:
rrt32 &= ~UINT32_C(0x080000); /* 19th bit isn't writable */
value &= ~UINT32_C(0x080000); /* 19th bit isn't writable */
if((rrt32 & CP0_STATUS_FR) != (cp0_regs[CP0_STATUS_REG] & CP0_STATUS_FR))
set_fpr_pointers(&r4300->cp1, rrt32);
if((value & CP0_STATUS_FR) != (cp0_regs[CP0_STATUS_REG] & CP0_STATUS_FR))
set_fpr_pointers(&r4300->cp1, value);
cp0_regs[CP0_STATUS_REG] = rrt32;
cp0_regs[CP0_STATUS_REG] = value;
ADD_TO_PC(1);
cp0_update_count(r4300);
r4300_check_interrupt(r4300, CP0_CAUSE_IP2, r4300->mi->regs[MI_INTR_REG] & r4300->mi->regs[MI_INTR_MASK_REG]); // ???
@@ -1391,50 +1378,79 @@ DECLARE_INSTRUCTION(MTC0)
return;
case CP0_CAUSE_REG:
cp0_regs[CP0_CAUSE_REG] &= ~(CP0_CAUSE_IP0 | CP0_CAUSE_IP1);
cp0_regs[CP0_CAUSE_REG] |= rrt32 & (CP0_CAUSE_IP0 | CP0_CAUSE_IP1);
cp0_regs[CP0_CAUSE_REG] |= value & (CP0_CAUSE_IP0 | CP0_CAUSE_IP1);
break;
case CP0_EPC_REG:
cp0_regs[CP0_EPC_REG] = rrt32;
cp0_regs[CP0_EPC_REG] = value;
break;
case CP0_PREVID_REG:
break;
case CP0_CONFIG_REG:
cp0_regs[CP0_CONFIG_REG] = (rrt32 & UINT32_C(0x0000000F))
cp0_regs[CP0_CONFIG_REG] = (value & UINT32_C(0x0000000F))
| (cp0_regs[CP0_CONFIG_REG] & UINT32_C(0x00008000))
| (cp0_regs[CP0_CONFIG_REG] & UINT32_C(0x7FFFFFFF));
break;
case CP0_LLADDR_REG:
cp0_regs[CP0_LLADDR_REG] = rrt32;
cp0_regs[CP0_LLADDR_REG] = value;
break;
case CP0_WATCHLO_REG:
cp0_regs[CP0_WATCHLO_REG] = rrt32;
cp0_regs[CP0_WATCHLO_REG] = value;
break;
case CP0_WATCHHI_REG:
cp0_regs[CP0_WATCHHI_REG] = rrt32;
break;
case CP0_XCONTEXT_REG:
cp0_regs[CP0_WATCHHI_REG] = value;
break;
case CP0_CACHEERR_REG:
break;
case CP0_PARITYERR_REG:
cp0_regs[CP0_PARITYERR_REG] = rrt32 & UINT32_C(0x000000FF);
cp0_regs[CP0_PARITYERR_REG] = value & UINT32_C(0x000000FF);
break;
case CP0_TAGLO_REG:
cp0_regs[CP0_TAGLO_REG] = rrt32 & UINT32_C(0x0FFFFFC0);
cp0_regs[CP0_TAGLO_REG] = value & UINT32_C(0x0FFFFFC0);
break;
case CP0_TAGHI_REG:
cp0_regs[CP0_TAGHI_REG] = 0;
break;
case CP0_ERROREPC_REG:
cp0_regs[CP0_ERROREPC_REG] = rrt32;
cp0_regs[CP0_ERROREPC_REG] = value;
break;
default:
break;
}
}
DECLARE_INSTRUCTION(MFC0)
{
DECLARE_R4300
rrt32 = SE32(get_cp0_register(r4300, rfs));
ADD_TO_PC(1);
}
DECLARE_INSTRUCTION(DMFC0)
{
DECLARE_R4300
rrt = get_cp0_register(r4300, rfs);
ADD_TO_PC(1);
}
DECLARE_INSTRUCTION(MTC0)
{
DECLARE_R4300
set_cp0_register(r4300, rfs, rrt32);
if (rfs == CP0_STATUS_REG)
return;
ADD_TO_PC(1);
}
DECLARE_INSTRUCTION(DMTC0)
{
DECLARE_R4300
set_cp0_register(r4300, rfs, rrt);
if (rfs == CP0_STATUS_REG)
return;
ADD_TO_PC(1);
}
/* CP1 load/store instructions */
DECLARE_INSTRUCTION(LWC1)
@@ -1517,7 +1533,7 @@ DECLARE_INSTRUCTION(DCFC1)
DECLARE_R4300
if (check_cop1_unusable(r4300)) { return; }
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
fpu_reset_cause(r4300_cp1_fcr31(&r4300->cp1));
@@ -1563,7 +1579,7 @@ DECLARE_INSTRUCTION(DCTC1)
DECLARE_R4300
if (check_cop1_unusable(r4300)) { return; }
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0);
fpu_reset_cause(r4300_cp1_fcr31(&r4300->cp1));
@@ -66,7 +66,7 @@ struct new_dynarec_hot_state
int64_t regs[32];
int64_t hi;
int64_t lo;
uint32_t cp0_regs[32];
uint64_t cp0_regs[32];
uint64_t cp0_latch;
float* cp1_regs_simple[32];
double* cp1_regs_double[32];
@@ -76,7 +76,7 @@ static void InterpretOpcode(struct r4300_core* r4300);
} \
static void name##_IDLE(struct r4300_core* r4300, uint32_t op) \
{ \
uint32_t* cp0_regs = r4300_cp0_regs(&r4300->cp0); \
uint64_t* cp0_regs = r4300_cp0_regs(&r4300->cp0); \
int* cp0_cycle_count = r4300_cp0_cycle_count(&r4300->cp0); \
const int take_jump = (condition); \
if (cop1 && check_cop1_unusable(r4300)) return; \
@@ -443,9 +443,11 @@ void InterpretOpcode(struct r4300_core* r4300)
else NOP(r4300, 0);
break;
case 4: /* Coprocessor 0 opcode 4: MTC0 */
case 5: /* Coprocessor 0 opcode 5: DMTC0 */
MTC0(r4300, op);
break;
case 5: /* Coprocessor 0 opcode 5: DMTC0 */
DMTC0(r4300, op);
break;
case 16: /* Coprocessor 0 opcode 16: TLB */
switch (op & 0x3F) {
case 1: TLBR(r4300, op); break;
@@ -686,8 +688,7 @@ void InterpretOpcode(struct r4300_core* r4300)
else NOP(r4300, 0);
break;
case 35: /* Major opcode 35: LW */
if (RT_OF(op) != 0) LW(r4300, op);
else NOP(r4300, 0);
LW(r4300, op);
break;
case 36: /* Major opcode 36: LBU */
if (RT_OF(op) != 0) LBU(r4300, op);
@@ -40,7 +40,7 @@ static uint32_t get_remaining_dma_length(struct ai_controller* ai)
{
unsigned int* next_ai_event;
unsigned int remaining_dma_duration;
const uint32_t* cp0_regs;
const uint64_t* cp0_regs;
if (ai->fifo[0].duration == 0)
return 0;
@@ -87,7 +87,7 @@ void read_vi_regs(void* opaque, uint32_t address, uint32_t* value)
{
struct vi_controller* vi = (struct vi_controller*)opaque;
uint32_t reg = vi_reg(address);
const uint32_t* cp0_regs = r4300_cp0_regs(&vi->mi->r4300->cp0);
const uint64_t* cp0_regs = r4300_cp0_regs(&vi->mi->r4300->cp0);
if (reg == VI_CURRENT_REG)
{
+1 -1
View File
@@ -818,7 +818,7 @@ void netplay_check_sync(struct cp0* cp0)
if (l_vi_counter % 600 == 0)
{
const uint32_t* cp0_regs = r4300_cp0_regs(cp0);
const uint64_t* cp0_regs = r4300_cp0_regs(cp0);
l_check_sync_packet->data[0] = UDP_SYNC_DATA;
netplay_write32(l_vi_counter, &l_check_sync_packet->data[1]); //current VI count
+4 -4
View File
@@ -208,7 +208,7 @@ static int savestates_load_m64p(struct device* dev, char *filepath)
unsigned char using_tlb_data[4];
unsigned char data_0001_0200[4096]; // 4k for extra state from v1.2
uint32_t* cp0_regs = r4300_cp0_regs(&dev->r4300.cp0);
uint64_t* cp0_regs = r4300_cp0_regs(&dev->r4300.cp0);
SDL_LockMutex(savestates_lock);
@@ -990,7 +990,7 @@ static int savestates_load_pj64(struct device* dev,
size_t savestateSize;
unsigned char *savestateData, *curr;
uint32_t* cp0_regs = r4300_cp0_regs(&dev->r4300.cp0);
uint64_t* cp0_regs = r4300_cp0_regs(&dev->r4300.cp0);
/* Read and check Project64 magic number. */
if (!read_func(handle, header, 8))
@@ -1543,7 +1543,7 @@ static int savestates_save_m64p(const struct device* dev, char *filepath)
char *curr;
/* OK to cast away const qualifier */
const uint32_t* cp0_regs = r4300_cp0_regs((struct cp0*)&dev->r4300.cp0);
const uint64_t* cp0_regs = r4300_cp0_regs((struct cp0*)&dev->r4300.cp0);
save = malloc(sizeof(*save));
if (!save) {
@@ -1951,7 +1951,7 @@ static int savestates_save_pj64(const struct device* dev,
size_t savestateSize;
unsigned char *savestateData, *curr;
const uint32_t* cp0_regs = r4300_cp0_regs((struct cp0*)&dev->r4300.cp0);
const uint64_t* cp0_regs = r4300_cp0_regs((struct cp0*)&dev->r4300.cp0);
// Allocate memory for the save state data
savestateSize = 8 + SaveRDRAMSize + 0x2754;