Skip to content

Commit 3a6309e

Browse files
committed
Merge pull request #1918 from bettio/intn-consistent-api
intn: make API more consistent Make sure that every arith. operation has a signed version, and `intn_digit_t` type is always used. These changes are made under both the "Apache 2.0" and the "GNU Lesser General Public License 2.1 or later" license terms (dual license). SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
2 parents 0afc977 + 32cb1a5 commit 3a6309e

File tree

3 files changed

+49
-29
lines changed

3 files changed

+49
-29
lines changed

src/libAtomVM/bif.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -899,8 +899,8 @@ static term mul_maybe_bigint(Context *ctx, uint32_t fail_label, uint32_t live, t
899899
}
900900

901901
intn_digit_t bigres[INTN_MAX_RES_LEN];
902-
intn_mulmnu(bn1, bn1_len, bn2, bn2_len, bigres);
903-
intn_integer_sign_t res_sign = intn_muldiv_sign(bn1_sign, bn2_sign);
902+
intn_integer_sign_t res_sign;
903+
intn_mulmn(bn1, bn1_len, bn1_sign, bn2, bn2_len, bn2_sign, bigres, &res_sign);
904904

905905
return make_bigint(ctx, fail_label, live, bigres, bigres_len, res_sign);
906906
}
@@ -1066,8 +1066,8 @@ static term div_maybe_bigint(Context *ctx, uint32_t fail_label, uint32_t live, t
10661066
}
10671067

10681068
intn_digit_t bigres[INTN_MAX_RES_LEN];
1069-
size_t bigres_len = intn_divmnu(bn1, bn1_len, bn2, bn2_len, bigres, NULL, NULL);
1070-
intn_integer_sign_t res_sign = intn_muldiv_sign(bn1_sign, bn2_sign);
1069+
intn_integer_sign_t res_sign;
1070+
size_t bigres_len = intn_divmn(bn1, bn1_len, bn1_sign, bn2, bn2_len, bn2_sign, bigres, &res_sign, NULL, NULL);
10711071

10721072
return make_bigint(ctx, fail_label, live, bigres, bigres_len, res_sign);
10731073
}

src/libAtomVM/intn.c

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,16 @@
3838
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
3939
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
4040

41+
/* Uncomment this for debug:
42+
void print_num(const intn_digit_t num[], int len)
43+
{
44+
for (int i = 0; i < len; i++) {
45+
fprintf(stderr, "0x%x ", (unsigned int) num[i]);
46+
}
47+
fprintf(stderr, "\n");
48+
}
49+
*/
50+
4151
static size_t neg_and_count_in_place(intn_digit_t out[], size_t len);
4252

4353
static inline size_t pad_uint16_to_digits(uint16_t n16[], size_t n16_len)
@@ -117,9 +127,9 @@ static void mulmnu32(const uint32_t u[], size_t m, const uint32_t v[], size_t n,
117127
*/
118128
}
119129

120-
void intn_mulmnu(const uint32_t u[], size_t m, const uint32_t v[], size_t n, uint32_t w[])
130+
void intn_mulmnu(const uint32_t m[], size_t m_len, const uint32_t n[], size_t n_len, uint32_t out[])
121131
{
122-
mulmnu32(u, m, v, n, w);
132+
mulmnu32(m, m_len, n, n_len, out);
123133
}
124134

125135
#else
@@ -170,10 +180,10 @@ static void mulmnu16(const uint16_t u[], size_t m, const uint16_t v[], size_t n,
170180
*/
171181
}
172182

173-
void intn_mulmnu(const uint32_t u[], size_t m, const uint32_t v[], size_t n, uint32_t w[])
183+
void intn_mulmnu(const uint32_t m[], size_t m_len, const uint32_t n[], size_t n_len, uint32_t out[])
174184
{
175185
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
176-
mulmnu16((const uint16_t *) u, m * 2, (const uint16_t *) v, n * 2, (uint16_t *) w);
186+
mulmnu16((const uint16_t *) m, m_len * 2, (const uint16_t *) n, n_len * 2, (uint16_t *) out);
177187
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
178188
#error "Big endian not yet supported"
179189
#else
@@ -429,14 +439,6 @@ size_t intn_divmnu(const intn_digit_t m[], size_t m_len, const intn_digit_t n[],
429439
return padded_q_len / UINT16_IN_A_DIGIT;
430440
}
431441

432-
void print_num(const uint32_t num[], int len)
433-
{
434-
for (int i = 0; i < len; i++) {
435-
fprintf(stderr, "0x%x ", (unsigned int) num[i]);
436-
}
437-
fprintf(stderr, "\n");
438-
}
439-
440442
// This function assumes no leading zeros (lenght is used in comparison)
441443
// Caller must ensure this precondition
442444
int intn_cmp(const intn_digit_t a[], size_t a_len, const intn_digit_t b[], size_t b_len)
@@ -787,7 +789,7 @@ size_t intn_bnot(const intn_digit_t m[], size_t m_len, intn_integer_sign_t m_sig
787789
return res_count;
788790
}
789791

790-
size_t intn_bsl(const intn_digit_t num[], size_t len, size_t n, uint32_t *out)
792+
size_t intn_bsl(const intn_digit_t num[], size_t len, size_t n, intn_digit_t *out)
791793
{
792794
size_t digit_bit_size = sizeof(uint32_t) * 8;
793795

@@ -864,7 +866,7 @@ void bsru(
864866
}
865867

866868
size_t intn_bsr(
867-
const intn_digit_t num[], size_t len, intn_integer_sign_t num_sign, size_t n, uint32_t *out)
869+
const intn_digit_t num[], size_t len, intn_integer_sign_t num_sign, size_t n, intn_digit_t *out)
868870
{
869871
size_t digit_bit_size = sizeof(uint32_t) * 8;
870872
size_t counted_digits = intn_count_digits(num, len);

src/libAtomVM/intn.h

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ typedef enum
7070

7171
typedef uint32_t intn_digit_t;
7272

73+
// Uncomment this for debug
74+
// void print_num(const intn_digit_t num[], int len);
75+
7376
int intn_cmp(const intn_digit_t a[], size_t a_len, const intn_digit_t b[], size_t b_len);
7477

7578
size_t intn_addmnu(
@@ -90,14 +93,34 @@ size_t intn_submn(const intn_digit_t m[], size_t m_len, intn_integer_sign_t m_si
9093

9194
size_t intn_sub_int64(int64_t num1, int64_t num2, intn_digit_t *out, intn_integer_sign_t *out_sign);
9295

96+
static inline intn_integer_sign_t intn_muldiv_sign(intn_integer_sign_t s1, intn_integer_sign_t s2)
97+
{
98+
return (intn_integer_sign_t) ((unsigned int) s1 ^ (unsigned int) s2) & IntNNegativeInteger;
99+
}
100+
93101
void intn_mulmnu(
94-
const intn_digit_t u[], size_t m, const intn_digit_t v[], size_t n, intn_digit_t w[]);
102+
const intn_digit_t m[], size_t m_len, const intn_digit_t n[], size_t n_len, intn_digit_t out[]);
103+
104+
static inline void intn_mulmn(const intn_digit_t m[], size_t m_len, intn_integer_sign_t m_sign,
105+
const intn_digit_t n[], size_t n_len, intn_integer_sign_t n_sign, intn_digit_t out[],
106+
intn_integer_sign_t *out_sign)
107+
{
108+
*out_sign = intn_muldiv_sign(m_sign, n_sign);
109+
intn_mulmnu(m, m_len, n, n_len, out);
110+
}
111+
95112
void intn_mul_int64(int64_t num1, int64_t num2, intn_digit_t *out, intn_integer_sign_t *out_sign);
96113

97114
size_t intn_divmnu(const intn_digit_t m[], size_t m_len, const intn_digit_t n[], size_t n_len,
98115
intn_digit_t q_out[], intn_digit_t r_out[], size_t *r_out_len);
99116

100-
void print_num(const uint32_t num[], int len);
117+
static inline size_t intn_divmn(const intn_digit_t m[], size_t m_len, intn_integer_sign_t m_sign,
118+
const intn_digit_t n[], size_t n_len, intn_integer_sign_t n_sign, intn_digit_t q_out[],
119+
intn_integer_sign_t *qout_sign, intn_digit_t r_out[], size_t *r_out_len)
120+
{
121+
*qout_sign = intn_muldiv_sign(m_sign, n_sign);
122+
return intn_divmnu(m, m_len, n, n_len, q_out, r_out, r_out_len);
123+
}
101124

102125
size_t intn_bormn(const intn_digit_t m[], size_t m_len, intn_integer_sign_t m_sign,
103126
const intn_digit_t n[], size_t n_len, intn_integer_sign_t n_sign, intn_digit_t out[],
@@ -114,10 +137,10 @@ size_t intn_bxormn(const intn_digit_t m[], size_t m_len, intn_integer_sign_t m_s
114137
size_t intn_bnot(const intn_digit_t m[], size_t m_len, intn_integer_sign_t m_sign,
115138
intn_digit_t out[], intn_integer_sign_t *out_sign);
116139

117-
size_t intn_bsl(const intn_digit_t num[], size_t len, size_t n, uint32_t *out);
140+
size_t intn_bsl(const intn_digit_t num[], size_t len, size_t n, intn_digit_t *out);
118141

119142
size_t intn_bsr(
120-
const intn_digit_t num[], size_t len, intn_integer_sign_t num_sign, size_t n, uint32_t *out);
143+
const intn_digit_t num[], size_t len, intn_integer_sign_t num_sign, size_t n, intn_digit_t *out);
121144

122145
size_t intn_count_digits(const intn_digit_t *num, size_t num_len);
123146

@@ -149,7 +172,7 @@ static inline void intn_copy(
149172
memset(out + num_len, 0, (extend_to - num_len) * sizeof(intn_digit_t));
150173
}
151174

152-
static inline void intn_u64_to_digits(uint64_t absu64, uint32_t out[])
175+
static inline void intn_u64_to_digits(uint64_t absu64, intn_digit_t out[])
153176
{
154177
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
155178
memcpy(out, &absu64, sizeof(absu64));
@@ -162,7 +185,7 @@ static inline void intn_u64_to_digits(uint64_t absu64, uint32_t out[])
162185
#endif
163186
}
164187

165-
static inline void int64_to_intn_2(int64_t i64, uint32_t out[], intn_integer_sign_t *out_sign)
188+
static inline void int64_to_intn_2(int64_t i64, intn_digit_t out[], intn_integer_sign_t *out_sign)
166189
{
167190
bool is_negative;
168191
uint64_t absu64 = int64_safe_unsigned_abs_set_flag(i64, &is_negative);
@@ -212,9 +235,4 @@ static inline bool intn_fits_int64(const intn_digit_t num[], size_t len, intn_in
212235
return false;
213236
}
214237

215-
static inline intn_integer_sign_t intn_muldiv_sign(intn_integer_sign_t s1, intn_integer_sign_t s2)
216-
{
217-
return (intn_integer_sign_t) ((unsigned int) s1 ^ (unsigned int) s2) & IntNNegativeInteger;
218-
}
219-
220238
#endif

0 commit comments

Comments
 (0)