SMTStabilizer API
Public API documentation for SMTStabilizer
Loading...
Searching...
No Matches
gmp_utils.cpp
Go to the documentation of this file.
1/***
2 * Bitwuzla: Satisfiability Modulo Theories (SMT) solver.
3 *
4 * Copyright (C) 2025 by the authors listed in the AUTHORS file at
5 * https://github.com/bitwuzla/bitwuzla/blob/main/AUTHORS
6 *
7 * This file is part of Bitwuzla under the MIT license. See COPYING for more
8 * information at https://github.com/bitwuzla/bitwuzla/blob/main/COPYING
9 */
10// Modified by Xiang Zhang, 2026
11// Additional changes licensed under the MIT License
12#include "util/gmp_utils.h"
13
14#include <cassert>
15#include <cstddef>
16#include <cstdint>
17
18#include "util/hash.h"
19
20namespace stabilizer::util {
21
22void mpz_set_ull(mpz_t rop, uint64_t op) {
23 if constexpr (sizeof(uint64_t) != sizeof(unsigned long)) {
24 uint32_t hi = static_cast<uint32_t>(op >> 32);
25 uint32_t lo = static_cast<uint32_t>(op);
26 mpz_set_ui(rop, hi);
27 mpz_mul_2exp(rop, rop, 32);
28 mpz_add_ui(rop, rop, lo);
29 }
30 else {
31 mpz_set_ui(rop, op);
32 }
33}
34
35uint64_t mpz_get_ull(const mpz_t op) {
36 if (mp_bits_per_limb == 64) {
37 mp_limb_t limb = mpz_getlimbn(op, 0);
38 return limb;
39 }
40 assert(mp_bits_per_limb == 32);
41 assert(mpz_size(op) >= 1);
42 uint64_t limb_lo = static_cast<uint64_t>(mpz_getlimbn(op, 0));
43 uint64_t limb_hi = 0;
44 if (mpz_size(op) >= 2) {
45 limb_hi = static_cast<uint64_t>(mpz_getlimbn(op, 1));
46 }
47 return (limb_hi << 32) | limb_lo;
48}
49
50void mpz_init_set_ull(mpz_t rop, uint64_t op) {
51 if (sizeof(mp_bitcnt_t) == 4) // 32 bit
52 {
53 uint32_t hi = static_cast<uint32_t>(op >> 32);
54 uint32_t lo = static_cast<uint32_t>(op);
55 mpz_init_set_ui(rop, hi);
56 mpz_mul_2exp(rop, rop, 32);
57 mpz_add_ui(rop, rop, lo);
58 }
59 else {
60 mpz_init_set_ui(rop, op);
61 }
62}
63
64mpz_class uint64_to_mpz_class(uint64_t op) {
65 uint32_t hi = static_cast<uint32_t>(op >> 32);
66 uint32_t lo = static_cast<uint32_t>(op);
67 mpz_class res(hi);
68 res = (res << 32) + lo;
69 return res;
70}
71
72void mpz_init_set_sll(mpz_t rop, int64_t op) {
73 if (sizeof(mp_bitcnt_t) == 4) // 32 bit
74 {
75 int32_t hi = static_cast<int32_t>(op >> 32);
76 int32_t lo = static_cast<int32_t>(op);
77 mpz_init_set_si(rop, hi);
78 mpz_mul_2exp(rop, rop, 32);
79 mpz_add_ui(rop, rop, lo);
80 }
81 else {
82 mpz_init_set_si(rop, op);
83 }
84}
85
86size_t mpz_hash(const mpz_t op, uint64_t start) {
87 uint64_t i, j = 0, n, res = start;
88 uint64_t x, p0, p1;
89
90 // least significant limb is at index 0
91 mp_limb_t limb;
92 for (i = 0, j = 0, n = mpz_size(op); i < n; ++i) {
93 p0 = hash::s_hash_primes[j++];
94 if (j == hash::s_n_primes)
95 j = 0;
96 p1 = hash::s_hash_primes[j++];
97 if (j == hash::s_n_primes)
98 j = 0;
99 limb = mpz_getlimbn(op, i);
100 if (mp_bits_per_limb == 64) {
101 uint64_t lo = limb;
102 uint64_t hi = (limb >> 32);
103 x = lo ^ res;
104 x = ((x >> 16) ^ x) * p0;
105 x = ((x >> 16) ^ x) * p1;
106 x = ((x >> 16) ^ x);
107 p0 = hash::s_hash_primes[j++];
108 if (j == hash::s_n_primes)
109 j = 0;
110 p1 = hash::s_hash_primes[j++];
111 if (j == hash::s_n_primes)
112 j = 0;
113 x = x ^ hi;
114 }
115 else {
116 assert(mp_bits_per_limb == 32);
117 x = res ^ limb;
118 }
119 x = ((x >> 16) ^ x) * p0;
120 x = ((x >> 16) ^ x) * p1;
121 res = ((x >> 16) ^ x);
122 }
123 return res;
124}
125
126// These functions only guard their *_ui counterparts with an assertion for the
127// Windows 32-bit case. In the cases where these functions are used we should
128// never use values that require more than 32 bit.
129void mpz_fdiv_q_2exp_ull(mpz_t q, const mpz_t n, uint64_t b) {
130 assert(sizeof(mp_bitcnt_t) == 8 || b <= UINT32_MAX);
131 mpz_fdiv_q_2exp(q, n, b);
132}
133
134void mpz_fdiv_r_2exp_ull(mpz_t r, const mpz_t n, uint64_t b) {
135 assert(sizeof(mp_bitcnt_t) == 8 || b <= UINT32_MAX);
136 mpz_fdiv_r_2exp(r, n, b);
137}
138
139void mpz_mul_2exp_ull(mpz_t rop, const mpz_t op1, uint64_t op2) {
140 assert(sizeof(mp_bitcnt_t) == 8 || op2 <= UINT32_MAX);
141 mpz_mul_2exp(rop, op1, op2);
142}
143
144} // namespace stabilizer::util
mpz_class uint64_to_mpz_class(uint64_t op)
Definition gmp_utils.cpp:64
void mpz_set_ull(mpz_t rop, uint64_t op)
Definition gmp_utils.cpp:22
void mpz_fdiv_r_2exp_ull(mpz_t r, const mpz_t n, uint64_t b)
void mpz_init_set_sll(mpz_t rop, int64_t op)
Definition gmp_utils.cpp:72
void mpz_fdiv_q_2exp_ull(mpz_t q, const mpz_t n, uint64_t b)
uint64_t mpz_get_ull(const mpz_t op)
Definition gmp_utils.cpp:35
void mpz_init_set_ull(mpz_t rop, uint64_t op)
Definition gmp_utils.cpp:50
size_t mpz_hash(const mpz_t op, uint64_t start)
Definition gmp_utils.cpp:86
void mpz_mul_2exp_ull(mpz_t rop, const mpz_t op1, uint64_t op2)