aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarat Dukhan <maratek@gmail.com>2020-04-12 14:57:43 -0700
committerMarat Dukhan <maratek@gmail.com>2020-04-12 14:57:43 -0700
commitd25336a3bb2e3125368d061ce10ae934e70f6d63 (patch)
treeee1d22cb34b30f33221592beedec0af6a0add604
parent0bc00d197a714492cd000b7a71aa01176e579155 (diff)
downloadFXdiv-d25336a3bb2e3125368d061ce10ae934e70f6d63.tar.gz
Use _udiv64 and _udiv128 intrinsics on MSVC
-rw-r--r--include/fxdiv.h9
1 files changed, 9 insertions, 0 deletions
diff --git a/include/fxdiv.h b/include/fxdiv.h
index 2c275e1..918ad9e 100644
--- a/include/fxdiv.h
+++ b/include/fxdiv.h
@@ -14,6 +14,9 @@
#if defined(_MSC_VER)
#include <intrin.h>
+ #if defined(_M_IX86) || defined(_M_X64)
+ #include <immintrin.h>
+ #endif
#endif
#ifndef FXDIV_USE_INLINE_ASSEMBLY
@@ -168,6 +171,9 @@ static inline struct fxdiv_divisor_uint32_t fxdiv_init_uint32_t(uint32_t d) {
__asm__("DIVL %[d]"
: "=a" (q), "+d" (u_hi)
: [d] "r" (d), "a" (0));
+ #elif (defined(_MSC_VER) && _MSC_VER >= 1920) && (defined(_M_IX86) || defined(_M_X64))
+ unsigned int remainder;
+ const uint32_t q = (uint32_t) _udiv64((unsigned __int64) ((uint64_t) u_hi << 32), (unsigned int) d, &remainder);
#else
const uint32_t q = ((uint64_t) u_hi << 32) / d;
#endif
@@ -261,6 +267,9 @@ static inline struct fxdiv_divisor_uint64_t fxdiv_init_uint64_t(uint64_t d) {
__asm__("DIVQ %[d]"
: "=a" (q), "+d" (u_hi)
: [d] "r" (d), "a" (UINT64_C(0)));
+ #elif (defined(_MSC_VER) && _MSC_VER >= 1920) && defined(_M_X64)
+ unsigned __int64 remainder;
+ const uint64_t q = (uint64_t) _udiv128((unsigned __int64) u_hi, 0, (unsigned __int64) d, &remainder);
#else
/* Implementation based on code from Hacker's delight */