diff --git a/include/ppc970/cache.h b/include/ppc970/cache.h index 284ebde..b748689 100644 --- a/include/ppc970/cache.h +++ b/include/ppc970/cache.h @@ -37,4 +37,50 @@ cache_inhibited_access(uint16_t, 16) cache_inhibited_access(uint32_t, 32) cache_inhibited_access(uint64_t, 64) +#define _FWOVERLAP(s, d, size) ((d >= s) && ((type_u)d < ((type_u)s + size))) + +// 3.1 +#define _FWMOVE(s, d, size, t) \ + { t *s1=(t *)s, *d1=(t *)d; \ + while (size > 0) { *d1++ = *s1++; size -= sizeof(t); } } + +#define _BWMOVE(s, d, size, t) { \ + t *s1=(t *)((char *)s+size), *d1=(t *)((char *)d+size); \ + while (size > 0) { *--d1 = *--s1; size -= sizeof(t); } \ +} + + +#define _MOVE(s, d, size, t) if _FWOVERLAP(s, d, size) _BWMOVE(s, d, size, t) else _FWMOVE(s, d, size, t) + +#define _FASTMOVE(s, d, size) \ + switch (((type_u)s | (type_u)d | size) & (sizeof(type_u)-1)) { \ + case 0: _MOVE(s, d, size, type_u); break; \ + case sizeof(type_l): _MOVE(s, d, size, type_l); break; \ + case sizeof(type_w): _MOVE(s, d, size, type_w); break; \ + default: _MOVE(s, d, size, type_c); break; \ + } + +// Device IO block data helpers +#define _FWRMOVE(s, d, size, t) \ + { t *s1=(t *)s, *d1=(t *)d; SET_CI; \ + while (size > 0) { *d1++ = *s1++; size -= sizeof(t); } \ + CLR_CI; \ +} + +#define _BWRMOVE(s, d, size, t) { \ + t *s1=(t *)((char *)s+size), *d1=(t *)((char *)d+size); SET_CI; \ + while (size > 0) { *--d1 = *--s1; size -= sizeof(t); } \ + CLR_CI; \ +} + +#define _RMOVE(s, d, size, t) if _FWOVERLAP(s, d, size) _BWRMOVE(s, d, size, t) else _FWRMOVE(s, d, size, t) + +#define _FASTRMOVE(s, d, size) \ + switch (((type_u)s | (type_u)d | size) & (sizeof(type_u)-1)) { \ + case 0: _RMOVE(s, d, size, type_u); break; \ + case sizeof(type_l): _RMOVE(s, d, size, type_l); break; \ + case sizeof(type_w): _RMOVE(s, d, size, type_w); break; \ + default: _RMOVE(s, d, size, type_c); break; \ + } + #endif diff --git a/include/ppcp7/cache.h b/include/ppcp7/cache.h index 168a787..dc68371 100644 --- a/include/ppcp7/cache.h +++ b/include/ppcp7/cache.h @@ -35,7 +35,7 @@ : "r0", "r6", "r7", "r8", "r9", "r10", "r11", \ "r12", "memory", "cr0", "cr1", "cr5", \ "cr6", "cr7", "ctr", "xer"); \ - return arg0 ? -1 : arg1; \ + return arg0 ? (type)-1 : arg1; \ } \ static inline void ci_write_##size(type * addr, type data) \ { \ @@ -63,6 +63,65 @@ cache_inhibited_access(uint16_t, 16) cache_inhibited_access(uint32_t, 32) cache_inhibited_access(uint64_t, 64) +#define _FWOVERLAP(s, d, size) ((d >= s) && ((type_u)d < ((type_u)s + size))) + +// 3.1 +#define _FWMOVE(s, d, size, t) \ + { t *s1=(t *)s, *d1=(t *)d; \ + while (size > 0) { *d1++ = *s1++; size -= sizeof(t); } } + +#define _BWMOVE(s, d, size, t) { \ + t *s1=(t *)((char *)s+size), *d1=(t *)((char *)d+size); \ + while (size > 0) { *--d1 = *--s1; size -= sizeof(t); } \ +} + + +#define _MOVE(s, d, size, t) if _FWOVERLAP(s, d, size) _BWMOVE(s, d, size, t) else _FWMOVE(s, d, size, t) + +#define _FASTMOVE(s, d, size) \ + switch (((type_u)s | (type_u)d | size) & (sizeof(type_u)-1)) { \ + case 0: _MOVE(s, d, size, type_u); break; \ + case sizeof(type_l): _MOVE(s, d, size, type_l); break; \ + case sizeof(type_w): _MOVE(s, d, size, type_w); break; \ + default: _MOVE(s, d, size, type_c); break; \ + } + +static inline void ci_rmove(void *dst, void *src, unsigned long esize, + unsigned long count) +{ + register uint64_t arg0 asm ("r3"); + register uint64_t arg1 asm ("r4"); + register uint64_t arg2 asm ("r5"); + register uint64_t arg3 asm ("r6"); + register uint64_t arg4 asm ("r7"); + register uint64_t arg5 asm ("r8"); + + arg0 = 0xf001; /* KVMPPC_H_LOGICAL_MEMOP */ + arg1 = (uint64_t)dst; + arg2 = (uint64_t)src; + arg3 = esize; + arg4 = count; + arg5 = 0; /* 0 = copy */ + + asm volatile(".long 0x44000022 \n" /* HVCALL */ + : "=&r"(arg0),"=&r"(arg1),"=&r"(arg2), + "=&r"(arg3),"=&r"(arg4),"=&r"(arg5) + : "0"(arg0),"1"(arg1),"2"(arg2), + "3"(arg3),"4"(arg4),"5"(arg5) + : "r0", "r9", "r10", "r11", + "r12", "memory", "cr0", "cr1", "cr5", + "cr6", "cr7", "ctr", "xer"); +} + +#define _FASTRMOVE(s, d, size) do { \ + switch (((type_u)s | (type_u)d | size) & (sizeof(type_u)-1)) {\ + case 0: ci_rmove(d,s,3,size>>3); break; \ + case sizeof(type_l): ci_rmove(d,s,2,size>>2); break; \ + case sizeof(type_w): ci_rmove(d,s,1,size>>1); break; \ + default: ci_rmove(d,s,0,size); break; \ + } \ + } while(0) + static inline uint16_t bswap16_load(uint64_t addr) { unsigned int val; diff --git a/slof/paflof.c b/slof/paflof.c index b49c5c6..46326fe 100644 --- a/slof/paflof.c +++ b/slof/paflof.c @@ -22,6 +22,8 @@ #include #include #include +#include + #include ISTR(TARG,h) #define LAST_ELEMENT(x) x[sizeof x / sizeof x[0] - 1] @@ -29,6 +31,7 @@ /* Hack to get around static inline issues */ #include "../lib/libhvcall/libhvcall.h" + extern char _start_OF[]; unsigned long fdt_start; diff --git a/slof/prim.code b/slof/prim.code index 9a4d0e2..9fbed71 100644 --- a/slof/prim.code +++ b/slof/prim.code @@ -445,30 +445,6 @@ code_EXECUTE: // don't need this as prim } - - -// 3.1 -#define _FWMOVE(s, d, size, t) \ - { t *s1=(t *)s, *d1=(t *)d; \ - while (size > 0) { *d1++ = *s1++; size -= sizeof(t); } } - -#define _BWMOVE(s, d, size, t) { \ - t *s1=(t *)((char *)s+size), *d1=(t *)((char *)d+size); \ - while (size > 0) { *--d1 = *--s1; size -= sizeof(t); } \ -} - -#define _FWOVERLAP(s, d, size) ((d >= s) && ((type_u)d < ((type_u)s + size))) - -#define _MOVE(s, d, size, t) if _FWOVERLAP(s, d, size) _BWMOVE(s, d, size, t) else _FWMOVE(s, d, size, t) - -#define _FASTMOVE(s, d, size) \ - switch (((type_u)s | (type_u)d | size) & (sizeof(type_u)-1)) { \ - case 0: _MOVE(s, d, size, type_u); break; \ - case sizeof(type_l): _MOVE(s, d, size, type_l); break; \ - case sizeof(type_w): _MOVE(s, d, size, type_w); break; \ - default: _MOVE(s, d, size, type_c); break; \ - } - PRIM(MOVE) type_u n = TOS.u; POP; unsigned char *q = TOS.a; POP; @@ -535,38 +511,14 @@ code_COMP: NEXT; } -// Device IO block data helpers -#define _FWRMOVE(s, d, size, t) \ - { t *s1=(t *)s, *d1=(t *)d; SET_CI; \ - while (size > 0) { *d1++ = *s1++; size -= sizeof(t); } \ - CLR_CI; \ -} -#define _BWRMOVE(s, d, size, t) { \ - t *s1=(t *)((char *)s+size), *d1=(t *)((char *)d+size); SET_CI; \ - while (size > 0) { *--d1 = *--s1; size -= sizeof(t); } \ - CLR_CI; \ -} +PRIM(RMOVE) + type_u size = ((dp--)->u); + type_u *d = (type_u *)((dp--)->u); + type_u *s = (type_u *)((dp--)->u); + _FASTRMOVE(s, d, size); -#define _RMOVE(s, d, size, t) if _FWOVERLAP(s, d, size) _BWRMOVE(s, d, size, t) else _FWRMOVE(s, d, size, t) - -#define _FASTRMOVE(s, d, size) \ - switch (((type_u)s | (type_u)d | size) & (sizeof(type_u)-1)) { \ - case 0: _RMOVE(s, d, size, type_u); break; \ - case sizeof(type_l): _RMOVE(s, d, size, type_l); break; \ - case sizeof(type_w): _RMOVE(s, d, size, type_w); break; \ - default: _RMOVE(s, d, size, type_c); break; \ - } - -code_RMOVE: - { - type_u size = ((dp--)->u); - type_u *d = (type_u *)((dp--)->u); - type_u *s = (type_u *)((dp--)->u); - - _FASTRMOVE(s, d, size); - NEXT; - } + MIRP // String compare, case insensitive: