diff options
Diffstat (limited to 'include/ruby/internal/memory.h')
-rw-r--r-- | include/ruby/internal/memory.h | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/include/ruby/internal/memory.h b/include/ruby/internal/memory.h index 64e850c65e..d231e62982 100644 --- a/include/ruby/internal/memory.h +++ b/include/ruby/internal/memory.h @@ -38,9 +38,14 @@ # include <alloca.h> #endif -#if defined(_MSC_VER) && defined(_M_AMD64) +#if defined(_MSC_VER) && defined(_WIN64) # include <intrin.h> +# if defined(_M_AMD64) # pragma intrinsic(_umul128) +# endif +# if defined(_M_ARM64) +# pragma intrinsic(__umulh) +# endif #endif #include "ruby/internal/attr/alloc_size.h" @@ -581,12 +586,16 @@ rbimpl_size_mul_overflow(size_t x, size_t y) ret.left = dz > SIZE_MAX; ret.right = RBIMPL_CAST((size_t)dz); -#elif defined(_MSC_VER) && defined(_WIN64) +#elif defined(_MSC_VER) && defined(_M_AMD64) unsigned __int64 dp = 0; unsigned __int64 dz = _umul128(x, y, &dp); ret.left = RBIMPL_CAST((bool)dp); ret.right = RBIMPL_CAST((size_t)dz); +#elif defined(_MSC_VER) && defined(_M_ARM64) + ret.left = __umulh(x, y) != 0; + ret.right = x * y; + #else /* https://wiki.sei.cmu.edu/confluence/display/c/INT30-C.+Ensure+that+unsigned+integer+operations+do+not+wrap */ ret.left = (y != 0) && (x > SIZE_MAX / y); |