diff options
author | Yotam Barnoy | 2010-09-20 14:10:44 +0000 |
---|---|---|
committer | Yotam Barnoy | 2010-09-20 14:10:44 +0000 |
commit | f7f743ac31d0ec5af6d21aa217dae7387498af42 (patch) | |
tree | 3a16e7a42185cb21acaafc6ce9a27513bbd54b37 /backends/platform | |
parent | 05f0ebf2620969277ff94ce486e13b19eb46c1c9 (diff) | |
download | scummvm-rg350-f7f743ac31d0ec5af6d21aa217dae7387498af42.tar.gz scummvm-rg350-f7f743ac31d0ec5af6d21aa217dae7387498af42.tar.bz2 scummvm-rg350-f7f743ac31d0ec5af6d21aa217dae7387498af42.zip |
PSP: switch from wrapping memcpy to defining our own memcpy
The advantage is that we get to do inlining and even use lwl and lwr instructions where appropriate. We have to do it ourselves because the PSP doesn't tolerate built-in instructions, but also we have a more efficient memcpy than the lib's.
svn-id: r52817
Diffstat (limited to 'backends/platform')
-rw-r--r-- | backends/platform/psp/memory.cpp | 17 | ||||
-rw-r--r-- | backends/platform/psp/memory.h | 35 |
2 files changed, 32 insertions, 20 deletions
diff --git a/backends/platform/psp/memory.cpp b/backends/platform/psp/memory.cpp index 83ba36767a..1e08173286 100644 --- a/backends/platform/psp/memory.cpp +++ b/backends/platform/psp/memory.cpp @@ -37,23 +37,6 @@ //#define TEST_MEMORY_COPY -extern "C" { - -#ifdef TEST_MEMORY_COPY /* we won't be able to run in this case b/c of printouts */ -extern void *__real_memcpy(void *dst, void *src, size_t bytes); -#endif - -void *__wrap_memcpy(void *dst, void *src, size_t bytes) { -#ifdef TEST_MEMORY_COPY /* we won't be able to run in this case */ - return __real_memcpy(dst, src, bytes); -#else - PspMemory::fastCopy((byte *)dst, (byte *)src, bytes); - return dst; -#endif -} - -} - void PspMemory::copy(byte *dst, const byte *src, uint32 bytes) { DEBUG_ENTER_FUNC(); diff --git a/backends/platform/psp/memory.h b/backends/platform/psp/memory.h index 3cd441a69f..f54436fb99 100644 --- a/backends/platform/psp/memory.h +++ b/backends/platform/psp/memory.h @@ -32,7 +32,19 @@ //#define __PSP_DEBUG_PRINT__ -#include "backends/platform/psp/trace.h" +//#include "backends/platform/psp/trace.h" + +// These instructions don't generate automatically but are faster then copying byte by byte +inline void lwl_copy(byte *dst, const byte *src) { + register uint32 data; + asm volatile ("lwr %0,0(%1)\n\t" + "lwl %0,3(%1)\n\t" + : "=&r" (data) : "r" (src), "m" (*src)); + + asm volatile ("swr %1,0(%2)\n\t" + "swl %1,3(%2)\n\t" + : "=m" (*dst) : "r" (data), "r" (dst)); +} /** * Class that does memory copying and swapping if needed @@ -46,22 +58,39 @@ private: static inline void copy8(byte *dst, const byte *src, int32 bytes) { //PSP_DEBUG_PRINT("copy8 called with dst[%p], src[%p], bytes[%d]\n", dst, src, bytes); - for (;bytes; bytes--) { + uint32 words = bytes >> 2; + for (; words; words--) { + lwl_copy(dst, src); + dst += 4; + src += 4; + } + + uint32 bytesLeft = bytes & 0x3; + for (; bytesLeft; bytesLeft--) { *dst++ = *src++; } } public: // This is the interface to the outside world - static void fastCopy(byte *dst, const byte *src, uint32 bytes) { + static void *fastCopy(void *dstv, const void *srcv, int32 bytes) { + byte *dst = (byte *)dstv; + byte *src = (byte *)srcv; + if (bytes < MIN_AMOUNT_FOR_COMPLEX_COPY) { copy8(dst, src, bytes); } else { // go to more powerful copy copy(dst, src, bytes); } + + return dstv; } }; +inline void *psp_memcpy(void *dst, const void *src, int32 bytes) { + return PspMemory::fastCopy(dst, src, bytes); +} + #endif /* PSP_MEMORY_H */ #if defined(PSP_INCLUDE_SWAP) && !defined(PSP_MEMORY_SWAP_H) |