diff options
author | 2025-05-05 00:26:34 +0100 | |
---|---|---|
committer | 2025-05-05 00:26:34 +0100 | |
commit | 618a1d60ddc98bf41b7a3e8216746d1eff827110 (patch) | |
tree | 5d85bf04b04bae6c3f4e990f41b2b3b872ff2f6e /src/wincrt.c | |
parent | 32971d95964d4f18c6aaae01464d30a14ecd7b92 (diff) | |
download | sst-618a1d60ddc98bf41b7a3e8216746d1eff827110.tar.gz sst-618a1d60ddc98bf41b7a3e8216746d1eff827110.zip |
Improve the memcpy/memcmp functions a bit
I think memcpy might have been returning the wrong thing before,
actually, but I guess it didn't matter in practice. Who the hell uses
the return value from memcpy?
Diffstat (limited to 'src/wincrt.c')
-rw-r--r-- | src/wincrt.c | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/src/wincrt.c b/src/wincrt.c index 177ce45..ced1203 100644 --- a/src/wincrt.c +++ b/src/wincrt.c @@ -10,29 +10,42 @@ // // Is it actually reasonable to have to do any of this? Of course not. -// TODO(opt): this feels like a sad implementation, can we do marginally better? -int memcmp(const void *x_, const void *y_, unsigned int sz) { +int memcmp(const void *restrict x, const void *restrict y, unsigned int sz) { +#if defined(__GNUC__) || defined(__clang__) + int a, b; + __asm__ volatile ( + "xor %%eax, %%eax\n" + "repz cmpsb\n" + : "+D" (x), "+S" (y), "+c" (sz), "=@cca"(a), "=@ccb"(b) + : + : "ax", "memory" + ); + return b - a; +#else const char *x = x_, *y = y_; for (unsigned int i = 0; i < sz; ++i) { if (x[i] > y[i]) return 1; if (x[i] < y[i]) return -1; } return 0; +#endif } void *memcpy(void *restrict x, const void *restrict y, unsigned int sz) { -#ifdef __clang__ +#if defined(__GNUC__) || defined(__clang__) + void *r = x; __asm__ volatile ( - "rep movsb\n" : - "+D" (x), "+S" (y), "+c" (sz) : + "rep movsb\n" + : "+D" (x), "+S" (y), "+c" (sz) : - "memory" + : "memory" ); -#else // terrible fallback just in case someone wants to use this with MSVC + return r; +#else char *restrict xb = x; const char *restrict yb = y; for (unsigned int i = 0; i < sz; ++i) xb[i] = yb[i]; -#endif return x; +#endif } int __stdcall _DllMainCRTStartup(void *inst, unsigned int reason, |