Reserve a register for ppcState.

The register is RBP, previously in the GPR allocation order.  The next
commit will investigate whether there are too few GPRs (now or before),
but for now there is no replacement.

Previously, it was accessed RIP relatively; using RBP, anything in the
first 0x100 bytes of ppcState (including all the GPRs) can be accessed
with three fewer bytes.  Code to access ppcState is generated constantly
(mostly by register save/load), so in principle, this should improve
instruction cache footprint significantly.  It seems that this makes a
significant performance difference in practice.

The vast majority of this commit is mechanically replacing
M(&PowerPC::ppcState.x) with a new macro PPCSTATE(x).

Version 2: gets most of the cases which were using the register access
macros.
This commit is contained in:
comex committed 2014-09-06 13:16:18 -04:00
1 parent 387e1e3f21
commit 48891c6359
17 files changed
+238 -212

No files matched your search

+20 -5
View File
@@ -4,6 +4,8 @@
#pragma once
#include <tuple>
#include "Common/BreakPoints.h"
#include "Common/Common.h"
@@ -30,11 +32,6 @@ struct GC_ALIGNED64(PowerPCState)
{
u32 gpr[32]; // General purpose registers. r1 = stack pointer.
// The paired singles are strange : PS0 is stored in the full 64 bits of each FPR
// but ps calculations are only done in 32-bit precision, and PS1 is only 32 bits.
// Since we want to use SIMD, SSE2 is the only viable alternative - 2x double.
u64 ps[32][2];
u32 pc; // program counter
u32 npc;
@@ -64,6 +61,20 @@ struct GC_ALIGNED64(PowerPCState)
// This variable should be inside of the CoreTiming namespace if we wanted to be correct.
int downcount;
#if _M_X86_64
// This member exists for the purpose of an assertion in x86 JitBase.cpp
// that its offset <= 0x100. To minimize code size on x86, we want as much
// useful stuff in the one-byte offset range as possible - which is why ps
// is sitting down here. It currently doesn't make a difference on other
// supported architectures.
std::tuple<> above_fits_in_first_0x100;
#endif
// The paired singles are strange : PS0 is stored in the full 64 bits of each FPR
// but ps calculations are only done in 32-bit precision, and PS1 is only 32 bits.
// Since we want to use SIMD, SSE2 is the only viable alternative - 2x double.
GC_ALIGNED16(u64 ps[32][2]);
u32 sr[16]; // Segment registers.
// special purpose registers - controls quantizers, DMA, and lots of other misc extensions.
@@ -84,6 +95,10 @@ struct GC_ALIGNED64(PowerPCState)
InstructionCache iCache;
};
#if _M_X86_64
static_assert(offsetof(PowerPC::PowerPCState, above_fits_in_first_0x100) <= 0x100, "top of PowerPCState too big");
#endif
enum CPUState
{
CPU_RUNNING = 0,