Skip to content

Commit 52c9780

Browse files
committed
Initial iteration of the MSVC MPIR support.
1 parent fb4db22 commit 52c9780

File tree

7 files changed

+147
-4
lines changed

7 files changed

+147
-4
lines changed

.github/workflows/benchmark.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ jobs:
5454
git clone https://github.com/Chia-Network/clvm_tools.git --branch=main --single-branch
5555
python -m pip install ./clvm_tools
5656
python -m pip install colorama
57+
git clone https://github.com/Chia-Network/mpir_gc_x64.git --depth 1
5758
maturin develop --release
5859
5960
- name: Run benchmarks (Windows)

Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,9 @@ lazy_static = "=1.4.0"
2626
bls12_381 = "=0.5.0"
2727
sha2 = "=0.9.5"
2828

29+
[target.'cfg(unix)'.dependencies]
2930
# we just want the GMP bindings, so we disable default features
3031
gmp-mpfr-sys = { version = "=1.4", default-features = false }
31-
32-
[target.'cfg(unix)'.dependencies]
3332
openssl = { version = "0.10.35", features = ["vendored"] }
3433

3534
[target.'cfg(target_family="wasm")'.dependencies]

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ Use `maturin` to build the python interface. First, install into current virtual
99
$ pip install maturin
1010
```
1111

12+
As we need `MPIR` for MSVC builds, prepare this dependency with
13+
14+
```
15+
$ git clone https://github.com/Chia-Network/mpir_gc_x64.git --depth 1
16+
```
17+
1218
Build `clvm_rs` directly into the current virtualenv with
1319

1420
```

build.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
fn main() {
2+
#[cfg(windows)]
3+
{
4+
println!("cargo:rustc-link-lib=mpir");
5+
println!("cargo:rustc-link-search=mpir_gc_x64");
6+
}
7+
}

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ pub mod f_table;
88
mod gen;
99
mod int_to_bytes;
1010
pub mod more_ops;
11+
#[cfg(windows)]
12+
mod mpir_msvc;
1113
pub mod node;
1214
mod number;
1315
mod op_utils;

src/mpir_msvc.rs

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
#![allow(non_camel_case_types, non_snake_case)]
2+
3+
use core::ptr::NonNull;
4+
use std::cmp::Ordering;
5+
use std::ffi::c_void;
6+
7+
#[repr(C)]
8+
#[derive(Clone, Copy, Debug)]
9+
pub struct mpz_t {
10+
pub alloc: c_int,
11+
pub size: c_int,
12+
pub d: NonNull<c_ulonglong>,
13+
}
14+
15+
// FIXME: Inspect c_* for type mismatches
16+
#[cfg(test)]
17+
type c_char = i8;
18+
type c_int = i32;
19+
type c_long = i64;
20+
type c_ulong = u64;
21+
type c_ulonglong = u64;
22+
type mpz_srcptr = *const mpz_t;
23+
type mpz_ptr = *mut mpz_t;
24+
type bitcnt_t = c_ulong;
25+
26+
extern "C" {
27+
#[link_name = "__gmpz_init"]
28+
pub fn mpz_init(x: mpz_ptr);
29+
#[cfg(test)]
30+
#[link_name = "__gmpz_init_set_str"]
31+
pub fn mpz_init_set_str(rop: mpz_ptr, str: *const c_char, base: c_int) -> c_int;
32+
#[cfg(test)]
33+
#[link_name = "__gmpz_get_str"]
34+
pub fn mpz_get_str(str: *mut c_char, base: c_int, op: mpz_srcptr) -> *mut c_char;
35+
#[link_name = "__gmpz_import"]
36+
pub fn mpz_import(
37+
rop: mpz_ptr,
38+
count: usize,
39+
order: c_int,
40+
size: usize,
41+
endian: c_int,
42+
nails: usize,
43+
op: *const c_void,
44+
);
45+
#[link_name = "__gmpz_add_ui"]
46+
pub fn mpz_add_ui(rop: mpz_ptr, op1: mpz_srcptr, op2: c_ulong);
47+
#[link_name = "__gmpz_set"]
48+
pub fn mpz_set(rop: mpz_ptr, op: mpz_srcptr);
49+
#[link_name = "__gmpz_export"]
50+
pub fn mpz_export(
51+
rop: *mut c_void,
52+
countp: *mut usize,
53+
order: c_int,
54+
size: usize,
55+
endian: c_int,
56+
nails: usize,
57+
op: mpz_srcptr,
58+
) -> *mut c_void;
59+
#[link_name = "__gmpz_sizeinbase"]
60+
pub fn mpz_sizeinbase(arg1: mpz_srcptr, arg2: c_int) -> usize;
61+
#[link_name = "__gmpz_fdiv_qr"]
62+
pub fn mpz_fdiv_qr(q: mpz_ptr, r: mpz_ptr, n: mpz_srcptr, d: mpz_srcptr);
63+
#[link_name = "__gmpz_fdiv_q"]
64+
pub fn mpz_fdiv_q(q: mpz_ptr, n: mpz_srcptr, d: mpz_srcptr);
65+
#[link_name = "__gmpz_fdiv_r"]
66+
pub fn mpz_fdiv_r(r: mpz_ptr, n: mpz_srcptr, d: mpz_srcptr);
67+
#[link_name = "__gmpz_fdiv_q_2exp"]
68+
pub fn mpz_fdiv_q_2exp(q: mpz_ptr, n: mpz_srcptr, b: bitcnt_t);
69+
#[link_name = "__gmpz_init_set_ui"]
70+
pub fn mpz_init_set_ui(rop: mpz_ptr, op: c_ulong);
71+
#[link_name = "__gmpz_init_set_si"]
72+
pub fn mpz_init_set_si(rop: mpz_ptr, op: c_long);
73+
#[link_name = "__gmpz_clear"]
74+
pub fn mpz_clear(x: mpz_ptr);
75+
#[link_name = "__gmpz_add"]
76+
pub fn mpz_add(rop: mpz_ptr, op1: mpz_srcptr, op2: mpz_srcptr);
77+
#[link_name = "__gmpz_sub"]
78+
pub fn mpz_sub(rop: mpz_ptr, op1: mpz_srcptr, op2: mpz_srcptr);
79+
#[link_name = "__gmpz_mul"]
80+
pub fn mpz_mul(rop: mpz_ptr, op1: mpz_srcptr, op2: mpz_srcptr);
81+
#[link_name = "__gmpz_mul_2exp"]
82+
pub fn mpz_mul_2exp(rop: mpz_ptr, op1: mpz_srcptr, op2: bitcnt_t);
83+
#[link_name = "__gmpz_get_si"]
84+
pub fn mpz_get_si(op: mpz_srcptr) -> c_long;
85+
#[link_name = "__gmpz_and"]
86+
pub fn mpz_and(rop: mpz_ptr, op1: mpz_srcptr, op2: mpz_srcptr);
87+
#[link_name = "__gmpz_ior"]
88+
pub fn mpz_ior(rop: mpz_ptr, op1: mpz_srcptr, op2: mpz_srcptr);
89+
#[link_name = "__gmpz_xor"]
90+
pub fn mpz_xor(rop: mpz_ptr, op1: mpz_srcptr, op2: mpz_srcptr);
91+
#[link_name = "__gmpz_com"]
92+
pub fn mpz_com(rop: mpz_ptr, op: mpz_srcptr);
93+
#[link_name = "__gmpz_cmp"]
94+
pub fn mpz_cmp(op1: mpz_srcptr, op2: mpz_srcptr) -> c_int;
95+
#[link_name = "__gmpz_cmp_si"]
96+
pub fn mpz_cmp_si(op1: mpz_srcptr, op2: c_long) -> c_int;
97+
#[link_name = "__gmpz_cmp_ui"]
98+
pub fn mpz_cmp_ui(op1: mpz_srcptr, op2: c_ulong) -> c_int;
99+
}
100+
101+
#[inline]
102+
pub unsafe extern "C" fn mpz_neg(rop: mpz_ptr, op: mpz_srcptr) {
103+
if rop as mpz_srcptr != op {
104+
mpz_set(rop, op);
105+
}
106+
(*rop).size = -(*rop).size;
107+
}
108+
109+
#[inline]
110+
pub unsafe extern "C" fn mpz_sgn(op: mpz_srcptr) -> c_int {
111+
match { (*op).size }.cmp(&0) {
112+
Ordering::Less => -1,
113+
Ordering::Equal => 0,
114+
Ordering::Greater => 1,
115+
}
116+
}
117+
118+
#[inline]
119+
pub unsafe extern "C" fn mpz_get_ui(op: mpz_srcptr) -> c_ulong {
120+
if { (*op).size } != 0 {
121+
let p = (*op).d.as_ptr();
122+
(*p) as c_ulong
123+
} else {
124+
0
125+
}
126+
}

src/number.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
use crate::allocator::{Allocator, NodePtr};
2+
#[cfg(windows)]
3+
use crate::mpir_msvc as gmp;
24
use crate::node::Node;
35
use crate::reduction::EvalErr;
46
use core::mem::MaybeUninit;
7+
#[cfg(not(windows))]
58
use gmp_mpfr_sys::gmp;
9+
use std::cmp::Ordering;
610
use std::cmp::PartialOrd;
711
use std::ffi::c_void;
812
use std::ops::Drop;
913
use std::ops::{
1014
AddAssign, BitAndAssign, BitOrAssign, BitXorAssign, MulAssign, Not, Shl, Shr, SubAssign,
1115
};
1216

13-
use std::cmp::Ordering;
14-
1517
#[allow(clippy::enum_variant_names)]
1618
#[derive(PartialEq)]
1719
pub enum Sign {

0 commit comments

Comments
 (0)