summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNebuleon <nebuleon@alakazam>2017-04-12 05:58:57 +0000
committerNebuleon <nebuleon@alakazam>2017-04-12 07:50:55 +0000
commit14b4bd17bb6568a2d8b6aaf6acd089b936ceb680 (patch)
tree00ab784a777b16d971d99e4050a44a79ee583ff3
parentd489dca1a9846d8cee23654bc3958f571da97c93 (diff)
downloadReGBA-14b4bd17bb6568a2d8b6aaf6acd089b936ceb680.zip
ReGBA-14b4bd17bb6568a2d8b6aaf6acd089b936ceb680.tar.gz
ReGBA-14b4bd17bb6568a2d8b6aaf6acd089b936ceb680.tar.bz2
mips: Embed constants from Thumb PC-relative LDR instructions in ROM
Formerly those effective constants would be reloaded from the ROM at every access; now, they are emitted directly in native code. Execution-wise, this saves 13 instructions minus those needed by the constant load; code generation-wise, this saves 4 instructions minus those needed by the constant load.
-rw-r--r--source/cpu_asm.c8
-rw-r--r--source/dstwo/gui.c7
-rw-r--r--source/mips/emit.h31
-rw-r--r--source/opendingux/gui.c6
-rw-r--r--source/stats.c1
-rw-r--r--source/stats.h3
6 files changed, 51 insertions, 5 deletions
diff --git a/source/cpu_asm.c b/source/cpu_asm.c
index f2e34d1..b9f93d5 100644
--- a/source/cpu_asm.c
+++ b/source/cpu_asm.c
@@ -262,7 +262,7 @@ typedef struct
extern void call_bios_hle(void* func);
#define check_pc_region(pc) \
- new_pc_region = (pc >> 15); \
+ new_pc_region = (pc) >> 15; \
if(new_pc_region != pc_region) \
{ \
pc_region = new_pc_region; \
@@ -1892,8 +1892,10 @@ static void arm_flag_status(block_data_arm_type* block_data, uint32_t opcode)
\
case 0x48 ... 0x4F: \
/* LDR r0..r7, [pc + imm] */ \
- thumb_access_memory(load, imm, (((opcode >> 8) & 0xFF) - 0x48), 0, 0, \
- pc_relative, ((pc & ~2) + (imm << 2) + 4), u32); \
+ thumb_ldr_from_pc(((opcode >> 8) & 0xFF) - 0x48, \
+ ((pc & ~2) + (imm << 2) + 4), u32); \
+ /*thumb_access_memory(load, imm, (((opcode >> 8) & 0xFF) - 0x48), 0, 0, \
+ pc_relative, ((pc & ~2) + (imm << 2) + 4), u32);*/ \
break; \
\
case 0x50 ... 0x51: \
diff --git a/source/dstwo/gui.c b/source/dstwo/gui.c
index 5cd8550..84b8f54 100644
--- a/source/dstwo/gui.c
+++ b/source/dstwo/gui.c
@@ -2938,6 +2938,7 @@ const char* TextFramesRendered = "Frames rendered";
#ifdef PERFORMANCE_IMPACTING_STATISTICS
const char* TextARMOpcodes = "ARM opcodes decoded";
const char* TextThumbOpcodes = "Thumb opcodes decoded";
+const char* TextThumbROMConstants = "Thumb ROM constants";
const char* TextWrongAddressLines = "Memory accessors patched";
#endif
@@ -2962,6 +2963,10 @@ static struct Entry ExecutionStats_ThumbOpcodes = {
ENTRY_DISPLAY(&TextThumbOpcodes, &Stats.ThumbOpcodesDecoded, TYPE_UINT64)
};
+static struct Entry ExecutionStats_ThumbROMConstants = {
+ ENTRY_DISPLAY(&TextThumbROMConstants, &Stats.ThumbROMConstants, TYPE_UINT64)
+};
+
static struct Entry ExecutionStats_WrongAddressLines = {
ENTRY_DISPLAY(&TextWrongAddressLines, &Stats.WrongAddressLineCount, TYPE_UINT32)
};
@@ -2971,7 +2976,7 @@ struct Menu ExecutionStats = {
.Parent = &Debugging, .Title = &TextExecutionStats,
.Entries = { &Back, &ExecutionStats_BufferUnderruns, &ExecutionStats_FramesEmulated, &ExecutionStats_FramesRendered,
#ifdef PERFORMANCE_IMPACTING_STATISTICS
- &ExecutionStats_ARMOpcodes, &ExecutionStats_ThumbOpcodes, &ExecutionStats_WrongAddressLines,
+ &ExecutionStats_ARMOpcodes, &ExecutionStats_ThumbOpcodes, &ExecutionStats_ThumbROMConstants, &ExecutionStats_WrongAddressLines,
#endif
NULL }
};
diff --git a/source/mips/emit.h b/source/mips/emit.h
index d46678b..c6d8a9b 100644
--- a/source/mips/emit.h
+++ b/source/mips/emit.h
@@ -2306,6 +2306,37 @@ uint32_t execute_store_cpsr_body(uint32_t _cpsr, uint32_t store_mask, uint32_t a
thumb_access_memory_##access_type(mem_type, reg_rd); \
} \
+#ifdef PERFORMANCE_IMPACTING_STATISTICS
+
+static inline void StatsAddThumbROMConstant(void)
+{
+ Stats.ThumbROMConstants++;
+}
+
+#else
+
+static inline void StatsAddThumbROMConstant(void) {}
+
+#endif /* PERFORMANCE_IMPACTING_STATISTICS */
+
+#define thumb_ldr_from_pc(reg_rd, offset, mem_type) \
+{ \
+ thumb_decode_imm(); \
+ if ((offset) >= 0x08000000 && (offset) < 0x0E000000) \
+ { \
+ StatsAddThumbROMConstant(); \
+ cycle_count += 2; \
+ check_pc_region(offset); \
+ generate_load_imm(arm_to_mips_reg[reg_rd], \
+ ADDRESS32(memory_map_read[pc_region], (offset) & 0x7FFF)); \
+ } \
+ else \
+ { \
+ thumb_access_memory_generate_address_pc_relative(offset, 0, \
+ 0); \
+ thumb_access_memory_load(mem_type, reg_rd); \
+ } \
+} \
#define thumb_block_address_preadjust_no(base_reg) \
mips_emit_addu(reg_a2, arm_to_mips_reg[base_reg], reg_zero) \
diff --git a/source/opendingux/gui.c b/source/opendingux/gui.c
index beffcdd..d123e77 100644
--- a/source/opendingux/gui.c
+++ b/source/opendingux/gui.c
@@ -1066,6 +1066,10 @@ static struct MenuEntry ExecutionMenu_ThumbOps = {
ENTRY_DISPLAY("Thumb opcodes decoded", &Stats.ThumbOpcodesDecoded, TYPE_UINT64)
};
+static struct MenuEntry ExecutionMenu_ThumbROMConsts = {
+ ENTRY_DISPLAY("Thumb ROM constants", &Stats.ThumbROMConstants, TYPE_UINT64)
+};
+
static struct MenuEntry ExecutionMenu_MemAccessors = {
ENTRY_DISPLAY("Memory accessors patched", &Stats.WrongAddressLineCount, TYPE_UINT32)
};
@@ -1075,7 +1079,7 @@ static struct Menu ExecutionMenu = {
.Parent = &DebugMenu, .Title = "Execution statistics",
.Entries = { &ExecutionMenu_SoundUnderruns, &ExecutionMenu_FramesEmulated, &ExecutionMenu_FramesRendered
#ifdef PERFORMANCE_IMPACTING_STATISTICS
- , &ExecutionMenu_ARMOps, &ExecutionMenu_ThumbOps, &ExecutionMenu_MemAccessors
+ , &ExecutionMenu_ARMOps, &ExecutionMenu_ThumbOps, &ExecutionMenu_ThumbROMConsts, &ExecutionMenu_MemAccessors
#endif
, NULL }
};
diff --git a/source/stats.c b/source/stats.c
index f3e3b68..3bd4e2d 100644
--- a/source/stats.c
+++ b/source/stats.c
@@ -65,6 +65,7 @@ void StatsInitGame(void)
#ifdef PERFORMANCE_IMPACTING_STATISTICS
Stats.ARMOpcodesDecoded = 0;
Stats.ThumbOpcodesDecoded = 0;
+ Stats.ThumbROMConstants = 0;
Stats.BlockReuseCount = 0;
Stats.BlockRecompilationCount = 0;
Stats.OpcodeReuseCount = 0;
diff --git a/source/stats.h b/source/stats.h
index 6632ec4..d0018a1 100644
--- a/source/stats.h
+++ b/source/stats.h
@@ -60,6 +60,9 @@ struct ReGBA_Stats {
* scratch since the current game started running? */
uint64_t ARMOpcodesDecoded;
uint64_t ThumbOpcodesDecoded;
+ /* How many times have we met a Thumb PC-relative LDR instruction that
+ * loads from the ROM? */
+ uint64_t ThumbROMConstants;
/* How many times have we recompiled a block anew since the current
* game started running? */
uint64_t BlockRecompilationCount;