Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use one struct for R4300 registers on all architectures #134

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
378 changes: 181 additions & 197 deletions src/memory/memory.c

Large diffs are not rendered by default.

23 changes: 10 additions & 13 deletions src/memory/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,16 @@

#include <stdint.h>

#define read_word_in_memory() readmem[address>>16]()
#define read_byte_in_memory() readmemb[address>>16]()
#define read_hword_in_memory() readmemh[address>>16]()
#define read_dword_in_memory() readmemd[address>>16]()
#define write_word_in_memory() writemem[address>>16]()
#define write_byte_in_memory() writememb[address >>16]()
#define write_hword_in_memory() writememh[address >>16]()
#define write_dword_in_memory() writememd[address >>16]()

extern uint32_t address, cpu_word;
extern uint8_t cpu_byte;
extern uint16_t cpu_hword;
extern uint64_t cpu_dword, *rdword;
#include "r4300/r4300.h"

#define read_word_in_memory() readmem[g_state.access_addr >> 16]()
#define read_byte_in_memory() readmemb[g_state.access_addr >> 16]()
#define read_hword_in_memory() readmemh[g_state.access_addr >> 16]()
#define read_dword_in_memory() readmemd[g_state.access_addr >> 16]()
#define write_word_in_memory() writemem[g_state.access_addr >> 16]()
#define write_byte_in_memory() writememb[g_state.access_addr >> 16]()
#define write_hword_in_memory() writememh[g_state.access_addr >> 16]()
#define write_dword_in_memory() writememd[g_state.access_addr >> 16]()

extern void (*readmem[0x10000])(void);
extern void (*readmemb[0x10000])(void);
Expand Down
28 changes: 14 additions & 14 deletions src/r4300/cached_interp.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,18 +73,18 @@ unsigned int jump_to_address;
const uint32_t jump_target = (destination); \
int64_t *link_register = (link); \
if (cop1 && check_cop1_unusable()) return; \
if (link_register != &reg[0]) \
if (link_register != &g_state.regs.gpr[0]) \
{ \
*link_register = SE32(PC->addr + 8); \
} \
if (!likely || take_jump) \
{ \
PC++; \
delay_slot=1; \
g_state.delay_slot = 1; \
UPDATE_DEBUGGER(); \
PC->ops(); \
cp0_update_count(); \
delay_slot=0; \
g_state.delay_slot = 0; \
if (take_jump && !skip_jump) \
{ \
PC=actual->block+((jump_target-actual->start)>>2); \
Expand All @@ -96,26 +96,26 @@ unsigned int jump_to_address;
cp0_update_count(); \
} \
last_addr = PC->addr; \
if (next_interupt <= g_cp0_regs[CP0_COUNT_REG]) gen_interupt(); \
if (g_state.next_interrupt <= g_state.regs.cp0[CP0_COUNT_REG]) gen_interupt(); \
} \
static void name##_OUT(void) \
{ \
const int take_jump = (condition); \
const uint32_t jump_target = (destination); \
int64_t *link_register = (link); \
if (cop1 && check_cop1_unusable()) return; \
if (link_register != &reg[0]) \
if (link_register != &g_state.regs.gpr[0]) \
{ \
*link_register = SE32(PC->addr + 8); \
} \
if (!likely || take_jump) \
{ \
PC++; \
delay_slot=1; \
g_state.delay_slot = 1; \
UPDATE_DEBUGGER(); \
PC->ops(); \
cp0_update_count(); \
delay_slot=0; \
g_state.delay_slot = 0; \
if (take_jump && !skip_jump) \
{ \
jump_to(jump_target); \
Expand All @@ -127,7 +127,7 @@ unsigned int jump_to_address;
cp0_update_count(); \
} \
last_addr = PC->addr; \
if (next_interupt <= g_cp0_regs[CP0_COUNT_REG]) gen_interupt(); \
if (g_state.next_interrupt <= g_state.regs.cp0[CP0_COUNT_REG]) gen_interupt(); \
} \
static void name##_IDLE(void) \
{ \
Expand All @@ -137,18 +137,18 @@ unsigned int jump_to_address;
if (take_jump) \
{ \
cp0_update_count(); \
skip = next_interupt - g_cp0_regs[CP0_COUNT_REG]; \
if (skip > 3) g_cp0_regs[CP0_COUNT_REG] += (skip & UINT32_C(0xFFFFFFFC)); \
skip = g_state.next_interrupt - g_state.regs.cp0[CP0_COUNT_REG]; \
if (skip > 3) g_state.regs.cp0[CP0_COUNT_REG] += (skip & UINT32_C(0xFFFFFFFC)); \
else name(); \
} \
else name(); \
}

#define CHECK_MEMORY() \
if (!invalid_code[address>>12]) \
if (blocks[address>>12]->block[(address&0xFFF)/4].ops != \
if (!invalid_code[g_state.access_addr >> 12]) \
if (blocks[g_state.access_addr >> 12]->block[(g_state.access_addr & 0xFFF) / 4].ops != \
current_instruction_table.NOTCOMPILED) \
invalid_code[address>>12] = 1;
invalid_code[g_state.access_addr >> 12] = 1;

// two functions are defined from the macros above but never used
// these prototype declarations will prevent a warning
Expand All @@ -164,7 +164,7 @@ unsigned int jump_to_address;
// -----------------------------------------------------------
static void FIN_BLOCK(void)
{
if (!delay_slot)
if (!g_state.delay_slot)
{
jump_to((PC-1)->addr+4);
/*#ifdef DBG
Expand Down
15 changes: 4 additions & 11 deletions src/r4300/cp0.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,24 +36,17 @@
#include "debugger/dbg_types.h"
#endif

/* global variable */
#if NEW_DYNAREC != NEW_DYNAREC_ARM
/* ARM backend requires a different memory layout
* and therefore manually allocate that variable */
uint32_t g_cp0_regs[CP0_REGS_COUNT];
#endif

/* global functions */
uint32_t* r4300_cp0_regs(void)
{
return g_cp0_regs;
return g_state.regs.cp0;
}

int check_cop1_unusable(void)
{
if (!(g_cp0_regs[CP0_STATUS_REG] & UINT32_C(0x20000000)))
if (!(g_state.regs.cp0[CP0_STATUS_REG] & UINT32_C(0x20000000)))
{
g_cp0_regs[CP0_CAUSE_REG] = (UINT32_C(11) << 2) | UINT32_C(0x10000000);
g_state.regs.cp0[CP0_CAUSE_REG] = (UINT32_C(11) << 2) | UINT32_C(0x10000000);
exception_general();
return 1;
}
Expand All @@ -66,7 +59,7 @@ void cp0_update_count(void)
if (r4300emu != CORE_DYNAREC)
{
#endif
g_cp0_regs[CP0_COUNT_REG] += ((PC->addr - last_addr) >> 2) * count_per_op;
g_state.regs.cp0[CP0_COUNT_REG] += ((PC->addr - last_addr) >> 2) * count_per_op;
last_addr = PC->addr;
#ifdef NEW_DYNAREC
}
Expand Down
2 changes: 0 additions & 2 deletions src/r4300/cp0_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@

#include "cp0.h"

extern unsigned int g_cp0_regs[CP0_REGS_COUNT];

int check_cop1_unusable(void);

#endif /* M64P_R4300_CP0_PRIVATE_H */
Expand Down
52 changes: 20 additions & 32 deletions src/r4300/cp1.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,9 @@

#include <stdint.h>

#include "r4300.h"
#include "new_dynarec/new_dynarec.h"

#if NEW_DYNAREC != NEW_DYNAREC_ARM
float *reg_cop1_simple[32];
double *reg_cop1_double[32];
uint32_t FCR0, FCR31;
#else
/* ARM backend requires a different memory layout
* and therefore manually allocates these variables */
extern float *reg_cop1_simple[32];
extern double *reg_cop1_double[32];
extern uint32_t FCR0, FCR31;
#endif
int64_t reg_cop1_fgr_64[32];

/* This is the x86 version of the rounding mode contained in FCR31.
* It should not really be here. Its size should also really be uint16_t,
* because FLDCW (Floating-point LoaD Control Word) loads 16-bit control
Expand All @@ -46,27 +34,27 @@ uint32_t rounding_mode = UINT32_C(0x33F);

int64_t* r4300_cp1_regs(void)
{
return reg_cop1_fgr_64;
return g_state.regs.fpr_data;
}

float** r4300_cp1_regs_simple(void)
{
return reg_cop1_simple;
return g_state.regs.cp1_s;
}

double** r4300_cp1_regs_double(void)
{
return reg_cop1_double;
return g_state.regs.cp1_d;
}

uint32_t* r4300_cp1_fcr0(void)
{
return &FCR0;
return &g_state.regs.fcr_0;
}

uint32_t* r4300_cp1_fcr31(void)
{
return &FCR31;
return &g_state.regs.fcr_31;
}


Expand Down Expand Up @@ -94,34 +82,34 @@ void shuffle_fpr_data(uint32_t oldStatus, uint32_t newStatus)
// retrieve 32 FPR values from packed 32-bit FGR registers
for (i = 0; i < 32; i++)
{
temp_fgr_32[i] = *((int32_t *) &reg_cop1_fgr_64[i>>1] + ((i & 1) ^ isBigEndian));
temp_fgr_32[i] = *((int32_t *) &g_state.regs.fpr_data[i>>1] + ((i & 1) ^ isBigEndian));
}
// unpack them into 32 64-bit registers, taking the high 32-bits from their temporary place in the upper 16 FGRs
for (i = 0; i < 32; i++)
{
int32_t high32 = *((int32_t *) &reg_cop1_fgr_64[(i>>1)+16] + (i & 1));
*((int32_t *) &reg_cop1_fgr_64[i] + isBigEndian) = temp_fgr_32[i];
*((int32_t *) &reg_cop1_fgr_64[i] + (isBigEndian^1)) = high32;
int32_t high32 = *((int32_t *) &g_state.regs.fpr_data[(i>>1)+16] + (i & 1));
*((int32_t *) &g_state.regs.fpr_data[i] + isBigEndian) = temp_fgr_32[i];
*((int32_t *) &g_state.regs.fpr_data[i] + (isBigEndian^1)) = high32;
}
}
else
{ // switching into 32-bit mode
// retrieve the high 32 bits from each 64-bit FGR register and store in temp array
for (i = 0; i < 32; i++)
{
temp_fgr_32[i] = *((int32_t *) &reg_cop1_fgr_64[i] + (isBigEndian^1));
temp_fgr_32[i] = *((int32_t *) &g_state.regs.fpr_data[i] + (isBigEndian^1));
}
// take the low 32 bits from each register and pack them together into 64-bit pairs
for (i = 0; i < 16; i++)
{
uint32_t least32 = *((uint32_t *) &reg_cop1_fgr_64[i*2] + isBigEndian);
uint32_t most32 = *((uint32_t *) &reg_cop1_fgr_64[i*2+1] + isBigEndian);
reg_cop1_fgr_64[i] = ((uint64_t) most32 << 32) | (uint64_t) least32;
uint32_t least32 = *((uint32_t *) &g_state.regs.fpr_data[i*2] + isBigEndian);
uint32_t most32 = *((uint32_t *) &g_state.regs.fpr_data[i*2+1] + isBigEndian);
g_state.regs.fpr_data[i] = ((uint64_t) most32 << 32) | (uint64_t) least32;
}
// store the high bits in the upper 16 FGRs, which wont be accessible in 32-bit mode
for (i = 0; i < 32; i++)
{
*((int32_t *) &reg_cop1_fgr_64[(i>>1)+16] + (i & 1)) = temp_fgr_32[i];
*((int32_t *) &g_state.regs.fpr_data[(i>>1)+16] + (i & 1)) = temp_fgr_32[i];
}
}
}
Expand All @@ -141,16 +129,16 @@ void set_fpr_pointers(uint32_t newStatus)
{
for (i = 0; i < 32; i++)
{
reg_cop1_double[i] = (double*) &reg_cop1_fgr_64[i];
reg_cop1_simple[i] = ((float*) &reg_cop1_fgr_64[i]) + isBigEndian;
g_state.regs.cp1_d[i] = (double*) &g_state.regs.fpr_data[i];
g_state.regs.cp1_s[i] = ((float*) &g_state.regs.fpr_data[i]) + isBigEndian;
}
}
else
{
for (i = 0; i < 32; i++)
{
reg_cop1_double[i] = (double*) &reg_cop1_fgr_64[i>>1];
reg_cop1_simple[i] = ((float*) &reg_cop1_fgr_64[i>>1]) + ((i & 1) ^ isBigEndian);
g_state.regs.cp1_d[i] = (double*) &g_state.regs.fpr_data[i>>1];
g_state.regs.cp1_s[i] = ((float*) &g_state.regs.fpr_data[i>>1]) + ((i & 1) ^ isBigEndian);
}
}
}
Expand All @@ -160,7 +148,7 @@ void set_fpr_pointers(uint32_t newStatus)
* place for this. */
void update_x86_rounding_mode(uint32_t FCR31)
{
switch (FCR31 & 3)
switch (g_state.regs.fcr_31 & 3)
{
case 0: /* Round to nearest, or to even if equidistant */
rounding_mode = UINT32_C(0x33F);
Expand Down
4 changes: 0 additions & 4 deletions src/r4300/cp1_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,6 @@

#include "cp1.h"

extern float *reg_cop1_simple[32];
extern double *reg_cop1_double[32];
extern uint32_t FCR0, FCR31;
extern int64_t reg_cop1_fgr_64[32];
extern uint32_t rounding_mode;

#endif /* M64P_R4300_CP1_PRIVATE_H */
Expand Down