summaryrefslogtreecommitdiff
path: root/psp
diff options
context:
space:
mode:
authorDavid Guillen Fandos2021-03-23 19:05:35 +0100
committerDavid Guillen Fandos2021-03-23 19:09:56 +0100
commit11ec213c99d5d22905ff82cf3fb26ba6a8adf290 (patch)
tree0af3ed99246d3bdb2d2b22f1420bddf2fafba507 /psp
parent7e27010a3c08811e4ed04097e1961009c3fef8d7 (diff)
downloadpicogpsp-11ec213c99d5d22905ff82cf3fb26ba6a8adf290.tar.gz
picogpsp-11ec213c99d5d22905ff82cf3fb26ba6a8adf290.tar.bz2
picogpsp-11ec213c99d5d22905ff82cf3fb26ba6a8adf290.zip
Make ewram memory lineal
This saves a few cycles in MIPS and simplifies a bit the core. Removed the write map, only affects interpreter performance very minimally. Rewired ARM and x86 handlers to support direct access to I/EWRAM (and VRAM on ARM) to compensate. Overall performance is slightly better but code is cleaner and allows for further improvements in the dynarecs.
Diffstat (limited to 'psp')
-rw-r--r--psp/mips_emit.h80
-rw-r--r--psp/mips_stub.S4
2 files changed, 22 insertions, 62 deletions
diff --git a/psp/mips_emit.h b/psp/mips_emit.h
index 8d1d8d8..b75f7f5 100644
--- a/psp/mips_emit.h
+++ b/psp/mips_emit.h
@@ -1010,47 +1010,10 @@ u32 generate_load_rm_sh_##flags_op(u32 rm) \
{ \
u32 _address = (u32)(address); \
u32 _address_hi = (_address + 0x8000) >> 16; \
- generate_load_imm(ireg, address); \
mips_emit_lui(ireg, _address_hi >> 16) \
generate_load_memory_##type(ireg, _address - (_address_hi << 16)); \
} \
-#define generate_known_address_load_builder(type) \
- u32 generate_known_address_load_##type(u32 rd, u32 address) \
- { \
- switch(address >> 24) \
- { \
- /* Read from the BIOS ROM, can be converted to an immediate load. \
- Only really possible to do this from the BIOS but should be okay \
- to allow it everywhere */ \
- case 0x00: \
- u32 imm = read_memory_constant_##type(address); \
- generate_load_imm(arm_to_mips_reg[rd], imm); \
- return 1; \
- \
- /* Read from RAM, can be converted to a load */ \
- case 0x02: \
- generate_load_memory(type, arm_to_mips_reg[rd], (u8 *)ewram + \
- (address & 0x7FFF) + ((address & 0x38000) * 2) + 0x8000); \
- return 1; \
- \
- case 0x03: \
- generate_load_memory(type, arm_to_mips_reg[rd], (u8 *)iwram + \
- (address & 0x7FFF) + 0x8000); \
- return 1; \
- \
- /* Read from gamepak ROM, this has to be an immediate load because \
- it might not actually be in memory anymore when we get to it. */ \
- case 0x08: \
- u32 imm = read_memory_constant_##type(address); \
- generate_load_imm(arm_to_mips_reg[rd], imm); \
- return 1; \
- \
- default: \
- return 0; \
- } \
- } \
-
#define generate_block_extra_vars() \
u32 stored_pc = pc; \
u8 *update_trampoline \
@@ -1060,12 +1023,6 @@ u32 generate_load_rm_sh_##flags_op(u32 rm) \
generate_load_rm_sh_builder(flags); \
generate_load_rm_sh_builder(no_flags); \
\
-/* generate_known_address_load_builder(u8); \
- generate_known_address_load_builder(u16); \
- generate_known_address_load_builder(u32); \
- generate_known_address_load_builder(s8); \
- generate_known_address_load_builder(s16); */ \
- \
u32 generate_load_offset_sh(u32 rm) \
{ \
switch((opcode >> 5) & 0x03) \
@@ -2787,12 +2744,13 @@ static void emit_pmemld_stub(
mips_emit_lui(reg_rv, ((base_addr + 0x8000) >> 16));
if (region == 2) {
- // EWRAM is a bit special
+ // Can't do EWRAM with an `andi` instruction (18 bits mask)
+ mips_emit_ext(reg_a0, reg_a0, 0, 18); // &= 0x3ffff
+ if (!aligned && alignment != 0) {
+ mips_emit_ins(reg_a0, reg_zero, 0, size);// addr & ~1/2 (align to size)
+ }
// Need to insert a zero in the addr (due to how it's mapped)
- mips_emit_andi(reg_temp, reg_a0, memmask); // Clears all but 15 bits (LSB)
- mips_emit_ext(reg_a0, reg_a0, 15, 3); // Gets the 3 higher bits (from the 18)
- mips_emit_ins(reg_temp, reg_a0, 16, 3); // Puts the 3 bits into bits 18..16
- mips_emit_addu(reg_rv, reg_rv, reg_temp); // Adds to the base addr
+ mips_emit_addu(reg_rv, reg_rv, reg_a0); // Adds to the base addr
} else if (region == 6) {
// VRAM is mirrored every 128KB but the last 32KB is mapped to the previous
mips_emit_ext(reg_temp, reg_a0, 15, 2); // Extract bits 15 and 16
@@ -2862,12 +2820,13 @@ static void emit_pmemst_stub(
}
if (region == 2) {
- // EWRAM is a bit special
+ // Can't do EWRAM with an `andi` instruction (18 bits mask)
+ mips_emit_ext(reg_a0, reg_a0, 0, 18); // &= 0x3ffff
+ if (!aligned && realsize != 0) {
+ mips_emit_ins(reg_a0, reg_zero, 0, size);// addr & ~1/2 (align to size)
+ }
// Need to insert a zero in the addr (due to how it's mapped)
- mips_emit_andi(reg_temp, reg_a0, memmask); // Clears all but 15 bits (LSB)
- mips_emit_ext(reg_a0, reg_a0, 15, 3); // Gets the 3 higher bits (from the 18)
- mips_emit_ins(reg_temp, reg_a0, 16, 3); // Puts the 3 bits into bits 18..16
- mips_emit_addu(reg_rv, reg_rv, reg_temp); // Adds to the base addr
+ mips_emit_addu(reg_rv, reg_rv, reg_a0); // Adds to the base addr
} else if (region == 6) {
// VRAM is mirrored every 128KB but the last 32KB is mapped to the previous
mips_emit_ext(reg_temp, reg_a0, 15, 2); // Extract bits 15 and 16
@@ -2888,7 +2847,12 @@ static void emit_pmemst_stub(
// Generate SMC write and tracking
// TODO: Should we have SMC checks here also for aligned?
if (meminfo->check_smc && !aligned) {
- mips_emit_addiu(reg_temp, reg_rv, 0x8000); // -32KB is the addr of the SMC buffer
+ if (region == 2) {
+ mips_emit_lui(reg_temp, 0x40000 >> 16);
+ mips_emit_addu(reg_temp, reg_rv, reg_temp); // SMC lives after the ewram
+ } else {
+ mips_emit_addiu(reg_temp, reg_rv, 0x8000); // -32KB is the addr of the SMC buffer
+ }
if (realsize == 2) {
mips_emit_lw(reg_temp, reg_temp, base_addr);
} else if (realsize == 1) {
@@ -3272,8 +3236,8 @@ void init_emitter() {
const t_stub_meminfo ldinfo [] = {
{ emit_pmemld_stub, 0, 0x4000, false, false, (u32)bios_rom },
// 1 Open load / Ignore store
- { emit_pmemld_stub, 2, 0x8000, true, false, (u32)&ewram[0x8000] },
- { emit_pmemld_stub, 3, 0x8000, true, false, (u32)&iwram[0x8000] }, // memsize wrong on purpose, see above
+ { emit_pmemld_stub, 2, 0x8000, true, false, (u32)ewram }, // memsize wrong on purpose
+ { emit_pmemld_stub, 3, 0x8000, true, false, (u32)&iwram[0x8000] },
{ emit_pmemld_stub, 4, 0x400, false, false, (u32)io_registers },
{ emit_pmemld_stub, 5, 0x400, false, true, (u32)palette_ram },
{ emit_pmemld_stub, 6, 0x0, false, true, (u32)vram }, // same, vram is a special case
@@ -3308,8 +3272,8 @@ void init_emitter() {
}
const t_stub_meminfo stinfo [] = {
- { emit_pmemst_stub, 2, 0x8000, true, false, (u32)&ewram[0x8000] },
- { emit_pmemst_stub, 3, 0x8000, true, false, (u32)&iwram[0x8000] }, // memsize wrong on purpose, see above
+ { emit_pmemst_stub, 2, 0x8000, true, false, (u32)ewram },
+ { emit_pmemst_stub, 3, 0x8000, true, false, (u32)&iwram[0x8000] },
// I/O is special and mapped with a function call
{ emit_palette_hdl, 5, 0x400, false, true, (u32)palette_ram },
{ emit_pmemst_stub, 6, 0x0, false, true, (u32)vram }, // same, vram is a special case
diff --git a/psp/mips_stub.S b/psp/mips_stub.S
index 2d40bf8..5e5a479 100644
--- a/psp/mips_stub.S
+++ b/psp/mips_stub.S
@@ -44,7 +44,6 @@
.global write_io_epilogue
.global memory_map_read
-.global memory_map_write
.global tmemld
.global tmemst
.global tmemst
@@ -609,9 +608,6 @@ execute_arm_translate_internal:
.data
.align 6
-memory_map_write:
- .space 0x8000
-
memory_map_read:
.space 0x8000