summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Michael Smith <mikesmiffy128@gmail.com> 2025-05-05 00:26:34 +0100
committerGravatar Michael Smith <mikesmiffy128@gmail.com> 2025-05-05 00:26:34 +0100
commit618a1d60ddc98bf41b7a3e8216746d1eff827110 (patch)
tree5d85bf04b04bae6c3f4e990f41b2b3b872ff2f6e /src
parent32971d95964d4f18c6aaae01464d30a14ecd7b92 (diff)
downloadsst-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')
-rw-r--r--src/wincrt.c29
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,