summaryrefslogtreecommitdiff
path: root/src/wincrt.c
diff options
context:
space:
mode:
authorGravatar Michael Smith <mikesmiffy128@gmail.com> 2025-12-27 03:05:05 +0000
committerGravatar Michael Smith <mikesmiffy128@gmail.com> 2026-02-16 19:11:24 +0000
commit8d4b47298b6c9eeb9a3f79a5b80d894f80ed4a45 (patch)
tree63a8ea6f645b997fd7943a58a002e66244fa49ac /src/wincrt.c
parente7943fb834cbcaec585ed68e67b5f17ceda504f7 (diff)
downloadsst-8d4b47298b6c9eeb9a3f79a5b80d894f80ed4a45.tar.gz
sst-8d4b47298b6c9eeb9a3f79a5b80d894f80ed4a45.zip
Do away with memcpy/memset/memcmp
Now everything is either explicitly a rep thing, or explicitly some other small run of reasonably efficient instructions. No library calls or function call overhead of any kind. Code size remains nice and small. Ban a few other bad libc functions while we're at it. More can be added later if we decide that's a useful idea. This will require some discipline and workarounds to cope with Clang's tendency to shove mem* calls in places you don't want them even when you tell it not to. Well, c'est la vie. I'm a little nervous that the __builtin_memmove() usage in shuntvars() could still one day emit actual library calls. It appears we're not importing memmove() from anywhere at the moment, though. So I guess it's good enough for now. Also I had to get rid of alloca() in con_.c but that was kind of bad anyway, so that's fine.
Diffstat (limited to 'src/wincrt.c')
-rw-r--r--src/wincrt.c71
1 files changed, 6 insertions, 65 deletions
diff --git a/src/wincrt.c b/src/wincrt.c
index 9a0326b..5d5883e 100644
--- a/src/wincrt.c
+++ b/src/wincrt.c
@@ -2,72 +2,13 @@
// We get most of the libc functions from ucrtbase.dll, which comes with
// Windows, but for some reason a few of the intrinsic-y things are part of
-// vcruntime, which does *not* come with Windows!!! We can statically link just
-// that part but it adds ~12KiB of random useless bloat to our binary. So, let's
-// just implement the handful of required things here instead. This is only for
-// release/non-debug builds; we want the extra checks in Microsoft's CRT when
-// debugging.
+// vcruntime, which does *not* come with Windows!!!
//
-// Is it actually reasonable to have to do any of this? Of course not.
-
-// Note: these functions have ifdefs with non-asm fallbacks just in case this
-// file is ever useful somewhere else, but generally we assume this codebase
-// will be built with Clang.
-
-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) {
-#if defined(__GNUC__) || defined(__clang__)
- void *r = x;
- __asm volatile (
- "rep movsb\n"
- : "+D" (x), "+S" (y), "+c" (sz)
- :
- : "memory"
- );
- return r;
-#else
- char *restrict xb = x; const char *restrict yb = y;
- for (unsigned int i = 0; i < sz; ++i) xb[i] = yb[i];
- return x;
-#endif
-}
-
-void *memset(void *x, int c, unsigned int sz) {
-#if defined(__GNUC__) || defined(__clang__)
- void *r = x;
- __asm volatile (
- "rep stosb\n"
- : "+D" (x), "+c" (sz)
- : "a"(c)
- : "memory"
- );
- return r;
-#else
- const unsigned char *xb = x;
- for (unsigned int i = 0; i < len; ++i) xb[i] = (unsigned char)c;
- return x;
-#endif
-}
+// At this point, we no longer use memcpy/memcmp/memset (preferring to use the
+// x86 single-instruction equivalents and/or explicit builtins/intrinsics).
+//
+// So all we actually have to define here are a couple of dummy symbols to
+// appease the linker.
int __stdcall _DllMainCRTStartup(void *inst, unsigned int reason,
void *reserved) {