drkIIRaziel said:
The way the memory is mapped right now its either directly mapped (an array) or a handler (calls an external function).I can only have 'fast path' for the array case as the handlers need to be generic.I use a 256 entry lookup table and map in 16 MB segments.Each mapping can be a handler or a masked array {u32 val=LUT[addr>>24];u32* ptr=val&~1F; return ptr[(addr<<val)>>val]; //for the 'fast path'}.Anyway, memory just calls C functions for now, its not yet a significant bottleneck =P
Even if the C functions themselves aren't the bottleneck, it's the requirement for your register allocation... That fast path is so small and requires so few registers..
It's actually kind of interesting though, that you say they're not a bottleneck when it's not as if you're getting anywhere close to fullspeed >_> So how do you know that there are no improvements to be had here?
drkIIRaziel said:
You have no idea if a memory access reads from ram, or needs to call C code.This requires a possible save/restore of 10 registers for 1:1 mapping on each memory opcode (And for code that does lots of h/w reads in a row thats gonna get ugly real fast).On other cpu (like mips) most memory accesses to registers are detectable constants so you can use special code to save on register store/loads.
Yes, a potential save/restore that happens a statistically low amount of time, that's kind of the point, also it wouldn't be 10 registers but I digress... Who cares if a bunch of H/W reads are done in a row if they're still a very low percentage statistically? You have an entire frame to make up the difference. Unless we're talking about an idle loop, which you should be able to detect/eliminate for other obviously beneficial purposes.
Or do you really think that hardware registers are read anywhere close to the amount SH4 registers you're not allocating, which is currently all of them?
This should also only apply if reading hardware registers can have side effects. On some platforms it can, on say GBA it doesn't - I don't know about DC, but if there are no side effects then you should map to memory if possible.
By the way, how are these detectable constants on say PSP, if you don't know if the values in RAM you're seeding from will change and can't detect it with MMU?
drkIIRaziel said:
Yup, i profiled that one
.Most (all ?) sh4 code is VERY badly written, with very bad register usage and a special love for doing reg -> stack -> reg -> stack -> reg operations just to move data around.It seems the compiler really did a bad job at optimizing the code.The 'hand-tuned' parts that use assembly rely mostly on fpu (most of the work is done using fpu) and that has a nice 1:1 mapping for psp.Pandora will be less efficient on that part but it has larger cache so it should be allright.I don't do any kind of register allocation on psp anyway, and pandora probably doesn't need it to get fullspeed in some games.
You said yourself that games tend to use a fixed 8 registers so why not make a static allocation for at least those registers? You should have that amount available in callee save regs for both MIPS and ARM, it seems like you're turning down a free meal otherwise...