summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
authorArne Döring <arne.doering@gmx.net>2019-02-05 09:31:37 +0100
committerAndreas Rumpf <rumpf_a@web.de>2019-02-05 09:31:37 +0100
commit824f39b32e04e31514aade50da38516b8fadac12 (patch)
treed35bb7ae0e67c16f9cc5879f99eda7b7c79f59bb /lib
parentbcb5995ddf1228a53e01c9947e5229994e1bf364 (diff)
downloadNim-824f39b32e04e31514aade50da38516b8fadac12.tar.gz
Vm bitops fixes (#10520)
Diffstat (limited to 'lib')
-rw-r--r--lib/pure/bitops.nim27
1 files changed, 17 insertions, 10 deletions
diff --git a/lib/pure/bitops.nim b/lib/pure/bitops.nim
index d258a42de..0eee3cd70 100644
--- a/lib/pure/bitops.nim
+++ b/lib/pure/bitops.nim
@@ -33,6 +33,18 @@ const useICC_builtins = defined(icc) and useBuiltins
 const useVCC_builtins = defined(vcc) and useBuiltins
 const arch64 = sizeof(int) == 8
 
+template forwardImpl(impl, arg) {.dirty.} =
+  when sizeof(x) <= 4:
+    when x is SomeSignedInt:
+      impl(cast[uint32](x.int32))
+    else:
+      impl(x.uint32)
+  else:
+    when x is SomeSignedInt:
+      impl(cast[uint64](x.int64))
+    else:
+      impl(x.uint64)
+
 when defined(nimHasalignOf):
 
   import macros
@@ -243,8 +255,7 @@ proc countSetBits*(x: SomeInteger): int {.inline, nosideeffect.} =
   # TODO: figure out if ICC support _popcnt32/_popcnt64 on platform without POPCNT.
   # like GCC and MSVC
   when nimvm:
-    when sizeof(x) <= 4: result = countSetBits_nim(x.uint32)
-    else:                result = countSetBits_nim(x.uint64)
+    result = forwardImpl(countSetBits_nim, x)
   else:
     when useGCC_builtins:
       when sizeof(x) <= 4: result = builtin_popcount(x.cuint).int
@@ -274,8 +285,7 @@ proc parityBits*(x: SomeInteger): int {.inline, nosideeffect.} =
   # Can be used a base if creating ASM version.
   # https://stackoverflow.com/questions/21617970/how-to-check-if-value-has-even-parity-of-bits-or-odd
   when nimvm:
-    when sizeof(x) <= 4: result = parity_impl(x.uint32)
-    else:                result = parity_impl(x.uint64)
+    result = forwardImpl(parity_impl, x)
   else:
     when useGCC_builtins:
       when sizeof(x) <= 4: result = builtin_parity(x.uint32).int
@@ -293,8 +303,7 @@ proc firstSetBit*(x: SomeInteger): int {.inline, nosideeffect.} =
     when noUndefined:
       if x == 0:
         return 0
-    when sizeof(x) <= 4: result = firstSetBit_nim(x.uint32)
-    else:                result = firstSetBit_nim(x.uint64)
+    result = forwardImpl(firstSetBit_nim, x)
   else:
     when noUndefined and not useGCC_builtins:
       if x == 0:
@@ -328,8 +337,7 @@ proc fastLog2*(x: SomeInteger): int {.inline, nosideeffect.} =
     if x == 0:
       return -1
   when nimvm:
-    when sizeof(x) <= 4: result = fastlog2_nim(x.uint32)
-    else:                result = fastlog2_nim(x.uint64)
+    result = forwardImpl(fastlog2_nim, x)
   else:
     when useGCC_builtins:
       when sizeof(x) <= 4: result = 31 - builtin_clz(x.uint32).int
@@ -360,8 +368,7 @@ proc countLeadingZeroBits*(x: SomeInteger): int {.inline, nosideeffect.} =
     if x == 0:
       return 0
   when nimvm:
-      when sizeof(x) <= 4: result = sizeof(x)*8 - 1 - fastlog2_nim(x.uint32)
-      else:                result = sizeof(x)*8 - 1 - fastlog2_nim(x.uint64)
+    result = sizeof(x)*8 - 1 - forwardImpl(fastlog2_nim, x)
   else:
     when useGCC_builtins:
       when sizeof(x) <= 4: result = builtin_clz(x.uint32).int - (32 - sizeof(x)*8)
:36:14 +0200 committer Araq <rumpf_a@web.de> 2014-08-28 22:36:14 +0200 Nimrod renamed to Nim' href='/ahoang/Nim/commit/doc/docs.txt?h=devel&id=3ea64469008c30682a0cc7b92e3f553a07f30a37'>3ea644690 ^
4aba7421f ^

b2e997759 ^
3ea644690 ^
b2e997759 ^

e792940f5 ^
405b86068
439aa2d04 ^
405b86068

783273032 ^

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36