mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-06 03:05:28 -05:00
fix(ccint): pick popcount at runtime on 64 bits
(we can compile on 64 bits, at least for bytecode, and execute on 32 bits native or jsoo's 32 bits; therefore we need to pick the implementation at runtime).
This commit is contained in:
parent
858dee7279
commit
fc57765c31
1 changed files with 22 additions and 13 deletions
|
|
@ -204,7 +204,20 @@ let shims_int_post_408 = "
|
||||||
(** {{: https://caml.inria.fr/pub/docs/manual-ocaml/libref/Int.html} Documentation for the standard Int module}*)
|
(** {{: https://caml.inria.fr/pub/docs/manual-ocaml/libref/Int.html} Documentation for the standard Int module}*)
|
||||||
"
|
"
|
||||||
|
|
||||||
let shims_int_64bit = "
|
let shims_int_non_64bit = "
|
||||||
|
(* we use the simple version for non-64 bits. *)
|
||||||
|
let popcount (b:int) : int =
|
||||||
|
let rec loop count x =
|
||||||
|
if x=0 then count
|
||||||
|
else loop (count+1) (x land (x-1))
|
||||||
|
in
|
||||||
|
loop 0 b
|
||||||
|
|
||||||
|
"
|
||||||
|
|
||||||
|
(* 64 bits: include basic version *)
|
||||||
|
let shims_int_64bit =
|
||||||
|
shims_int_non_64bit ^ "
|
||||||
(*
|
(*
|
||||||
from https://en.wikipedia.org/wiki/Hamming_weight
|
from https://en.wikipedia.org/wiki/Hamming_weight
|
||||||
|
|
||||||
|
|
@ -225,7 +238,7 @@ let shims_int_64bit = "
|
||||||
m2 = 0x3333333333333333
|
m2 = 0x3333333333333333
|
||||||
m4 = 0x0f0f0f0f0f0f0f0f
|
m4 = 0x0f0f0f0f0f0f0f0f
|
||||||
*)
|
*)
|
||||||
let popcount (b:int) : int =
|
let popcount_64_ (b:int) : int =
|
||||||
let b = b - ((b lsr 1) land 0x5555555555555555) in
|
let b = b - ((b lsr 1) land 0x5555555555555555) in
|
||||||
let b = (b land 0x3333333333333333) + ((b lsr 2) land 0x3333333333333333) in
|
let b = (b land 0x3333333333333333) + ((b lsr 2) land 0x3333333333333333) in
|
||||||
let b = (b + (b lsr 4)) land 0x0f0f0f0f0f0f0f0f in
|
let b = (b + (b lsr 4)) land 0x0f0f0f0f0f0f0f0f in
|
||||||
|
|
@ -233,17 +246,13 @@ let popcount (b:int) : int =
|
||||||
let b = b + (b lsr 16) in
|
let b = b + (b lsr 16) in
|
||||||
let b = b + (b lsr 32) in
|
let b = b + (b lsr 32) in
|
||||||
b land 0x7f
|
b land 0x7f
|
||||||
"
|
|
||||||
|
|
||||||
let shims_int_non_64bit = "
|
|
||||||
(* we use the simple version for non-64 bits. *)
|
|
||||||
let popcount (b:int) : int =
|
|
||||||
let rec loop count x =
|
|
||||||
if x=0 then count
|
|
||||||
else loop (count+1) (x land (x-1))
|
|
||||||
in
|
|
||||||
loop 0 b
|
|
||||||
|
|
||||||
|
(* pick at runtime, see:
|
||||||
|
- https://github.com/c-cube/ocaml-containers/issues/346
|
||||||
|
- https://github.com/ocsigen/js_of_ocaml/issues/1079
|
||||||
|
*)
|
||||||
|
let popcount =
|
||||||
|
if Sys.int_size = 63 then popcount_64_ else popcount
|
||||||
"
|
"
|
||||||
|
|
||||||
let () =
|
let () =
|
||||||
|
|
@ -270,7 +279,7 @@ let () =
|
||||||
try C.ocaml_config_var_exn c "int_size" |> int_of_string
|
try C.ocaml_config_var_exn c "int_size" |> int_of_string
|
||||||
with e ->
|
with e ->
|
||||||
let n = Sys.int_size in (* default to current version *)
|
let n = Sys.int_size in (* default to current version *)
|
||||||
Printf.eprintf "cannot obtain target word_size:\n%s\ndefaulting to %d\n%!"
|
Printf.eprintf "cannot obtain target int_size:\n%s\ndefaulting to %d\n%!"
|
||||||
(Printexc.to_string e) n;
|
(Printexc.to_string e) n;
|
||||||
n
|
n
|
||||||
in
|
in
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue