aboutsummaryrefslogtreecommitdiff
path: root/backends/platform
diff options
context:
space:
mode:
authorYotam Barnoy2010-09-20 14:10:44 +0000
committerYotam Barnoy2010-09-20 14:10:44 +0000
commitf7f743ac31d0ec5af6d21aa217dae7387498af42 (patch)
tree3a16e7a42185cb21acaafc6ce9a27513bbd54b37 /backends/platform
parent05f0ebf2620969277ff94ce486e13b19eb46c1c9 (diff)
downloadscummvm-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.cpp17
-rw-r--r--backends/platform/psp/memory.h35
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)