Skip to content
This repository was archived by the owner on Sep 2, 2025. It is now read-only.

Commit b6a24d6

Browse files
committed
Inline int_div_impl.inc
1 parent aa5854c commit b6a24d6

File tree

10 files changed

+165
-148
lines changed

10 files changed

+165
-148
lines changed

divdi3.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,12 @@
1414

1515
// Returns: a / b
1616

17-
#define fixint_t di_int
18-
#define fixuint_t du_int
19-
#define COMPUTE_UDIV(a, b) __udivmoddi4((a), (b), (du_int *)0)
20-
#include "int_div_impl.inc"
21-
22-
COMPILER_RT_ABI di_int __divdi3(di_int a, di_int b) { return __divXi3(a, b); }
17+
COMPILER_RT_ABI di_int __divdi3(di_int a, di_int b) {
18+
const int N = (int)(sizeof(di_int) * CHAR_BIT) - 1;
19+
di_int s_a = a >> N; // s_a = a < 0 ? -1 : 0
20+
di_int s_b = b >> N; // s_b = b < 0 ? -1 : 0
21+
du_int a_u = (du_int)(a ^ s_a) + (-s_a); // negate if s_a == -1
22+
du_int b_u = (du_int)(b ^ s_b) + (-s_b); // negate if s_b == -1
23+
s_a ^= s_b; // sign of quotient
24+
return (__udivmoddi4(a_u, b_u, (du_int *)0) ^ s_a) + (-s_a); // negate if s_a == -1
25+
}

divsi3.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,20 @@
1414

1515
// Returns: a / b
1616

17-
#define fixint_t si_int
18-
#define fixuint_t su_int
1917
// On CPUs without unsigned hardware division support,
2018
// this calls __udivsi3 (notice the cast to su_int).
2119
// On CPUs with unsigned hardware division support,
2220
// this uses the unsigned division instruction.
23-
#define COMPUTE_UDIV(a, b) ((su_int)(a) / (su_int)(b))
24-
#include "int_div_impl.inc"
2521

26-
COMPILER_RT_ABI si_int __divsi3(si_int a, si_int b) { return __divXi3(a, b); }
22+
COMPILER_RT_ABI si_int __divsi3(si_int a, si_int b) {
23+
const int N = (int)(sizeof(si_int) * CHAR_BIT) - 1;
24+
si_int s_a = a >> N; // s_a = a < 0 ? -1 : 0
25+
si_int s_b = b >> N; // s_b = b < 0 ? -1 : 0
26+
su_int a_u = (su_int)(a ^ s_a) + (-s_a); // negate if s_a == -1
27+
su_int b_u = (su_int)(b ^ s_b) + (-s_b); // negate if s_b == -1
28+
s_a ^= s_b; // sign of quotient
29+
return (((su_int)a_u / (su_int)b_u) ^ s_a) + (-s_a); // negate if s_a == -1
30+
}
2731

2832
#if defined(__ARM_EABI__)
2933
COMPILER_RT_ALIAS(__divsi3, __aeabi_idiv)

divti3.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,14 @@
1616

1717
// Returns: a / b
1818

19-
#define fixint_t ti_int
20-
#define fixuint_t tu_int
21-
#define COMPUTE_UDIV(a, b) __udivmodti4((a), (b), (tu_int *)0)
22-
#include "int_div_impl.inc"
23-
24-
COMPILER_RT_ABI ti_int __divti3(ti_int a, ti_int b) { return __divXi3(a, b); }
19+
COMPILER_RT_ABI ti_int __divti3(ti_int a, ti_int b) {
20+
const int N = (int)(sizeof(ti_int) * CHAR_BIT) - 1;
21+
ti_int s_a = a >> N; // s_a = a < 0 ? -1 : 0
22+
ti_int s_b = b >> N; // s_b = b < 0 ? -1 : 0
23+
tu_int a_u = (tu_int)(a ^ s_a) + (-s_a); // negate if s_a == -1
24+
tu_int b_u = (tu_int)(b ^ s_b) + (-s_b); // negate if s_b == -1
25+
s_a ^= s_b; // sign of quotient
26+
return (__udivmodti4(a_u, b_u, (tu_int *)0) ^ s_a) + (-s_a); // negate if s_a == -1
27+
}
2528

2629
#endif // CRT_HAS_128BIT

int_div_impl.inc

Lines changed: 0 additions & 95 deletions
This file was deleted.

moddi3.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,13 @@
1414

1515
// Returns: a % b
1616

17-
#define fixint_t di_int
18-
#define fixuint_t du_int
19-
#define ASSIGN_UMOD(res, a, b) __udivmoddi4((a), (b), &(res))
20-
#include "int_div_impl.inc"
21-
22-
COMPILER_RT_ABI di_int __moddi3(di_int a, di_int b) { return __modXi3(a, b); }
17+
COMPILER_RT_ABI di_int __moddi3(di_int a, di_int b) {
18+
const int N = (int)(sizeof(di_int) * CHAR_BIT) - 1;
19+
di_int s = b >> N; // s = b < 0 ? -1 : 0
20+
du_int b_u = (du_int)(b ^ s) + (-s); // negate if s == -1
21+
s = a >> N; // s = a < 0 ? -1 : 0
22+
du_int a_u = (du_int)(a ^ s) + (-s); // negate if s == -1
23+
du_int res;
24+
__udivmoddi4(a_u, b_u, &res);
25+
return (res ^ s) + (-s); // negate if s == -1
26+
}

modti3.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,15 @@
1616

1717
// Returns: a % b
1818

19-
#define fixint_t ti_int
20-
#define fixuint_t tu_int
21-
#define ASSIGN_UMOD(res, a, b) __udivmodti4((a), (b), &(res))
22-
#include "int_div_impl.inc"
23-
24-
COMPILER_RT_ABI ti_int __modti3(ti_int a, ti_int b) { return __modXi3(a, b); }
19+
COMPILER_RT_ABI ti_int __modti3(ti_int a, ti_int b) {
20+
const int N = (int)(sizeof(ti_int) * CHAR_BIT) - 1;
21+
ti_int s = b >> N; // s = b < 0 ? -1 : 0
22+
tu_int b_u = (tu_int)(b ^ s) + (-s); // negate if s == -1
23+
s = a >> N; // s = a < 0 ? -1 : 0
24+
tu_int a_u = (tu_int)(a ^ s) + (-s); // negate if s == -1
25+
tu_int res;
26+
__udivmodti4(a_u, b_u, &res);
27+
return (res ^ s) + (-s); // negate if s == -1
28+
}
2529

2630
#endif // CRT_HAS_128BIT

udivdi3.c

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,36 @@
1212

1313
#include "int_lib.h"
1414

15-
typedef du_int fixuint_t;
16-
typedef di_int fixint_t;
17-
#include "int_div_impl.inc"
18-
1915
// Returns: a / b
2016

21-
COMPILER_RT_ABI du_int __udivdi3(du_int a, du_int b) {
22-
return __udivXi3(a, b);
17+
#undef clz
18+
#define clz(a) (sizeof(a) == sizeof(unsigned long long) ? __builtin_clzll(a) : clzsi(a))
19+
20+
// Adapted from Figure 3-40 of The PowerPC Compiler Writer's Guide
21+
COMPILER_RT_ABI du_int __udivdi3(du_int n, du_int d) {
22+
const unsigned N = sizeof(du_int) * CHAR_BIT;
23+
// d == 0 cases are unspecified.
24+
unsigned sr = (d ? clz(d) : N) - (n ? clz(n) : N);
25+
// 0 <= sr <= N - 1 or sr is very large.
26+
if (sr > N - 1) // n < d
27+
return 0;
28+
if (sr == N - 1) // d == 1
29+
return n;
30+
++sr;
31+
// 1 <= sr <= N - 1. Shifts do not trigger UB.
32+
du_int r = n >> sr;
33+
n <<= N - sr;
34+
du_int carry = 0;
35+
for (; sr > 0; --sr) {
36+
r = (r << 1) | (n >> (N - 1));
37+
n = (n << 1) | carry;
38+
// Branch-less version of:
39+
// carry = 0;
40+
// if (r >= d) r -= d, carry = 1;
41+
const di_int s = (di_int)(d - r - 1) >> (N - 1);
42+
carry = s & 1;
43+
r -= d & s;
44+
}
45+
n = (n << 1) | carry;
46+
return n;
2347
}

udivsi3.c

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,38 @@
1212

1313
#include "int_lib.h"
1414

15-
typedef su_int fixuint_t;
16-
typedef si_int fixint_t;
17-
#include "int_div_impl.inc"
18-
1915
// Returns: a / b
2016

21-
COMPILER_RT_ABI su_int __udivsi3(su_int a, su_int b) {
22-
return __udivXi3(a, b);
17+
#undef clz
18+
#define clz(a) (sizeof(a) == sizeof(unsigned long long) ? __builtin_clzll(a) : clzsi(a))
19+
20+
// Adapted from Figure 3-40 of The PowerPC Compiler Writer's Guide
21+
COMPILER_RT_ABI su_int __udivsi3(su_int n, su_int d) {
22+
const unsigned N = sizeof(su_int) * CHAR_BIT;
23+
// d == 0 cases are unspecified.
24+
unsigned sr = (d ? clz(d) : N) - (n ? clz(n) : N);
25+
// 0 <= sr <= N - 1 or sr is very large.
26+
if (sr > N - 1) // n < d
27+
return 0;
28+
if (sr == N - 1) // d == 1
29+
return n;
30+
++sr;
31+
// 1 <= sr <= N - 1. Shifts do not trigger UB.
32+
su_int r = n >> sr;
33+
n <<= N - sr;
34+
su_int carry = 0;
35+
for (; sr > 0; --sr) {
36+
r = (r << 1) | (n >> (N - 1));
37+
n = (n << 1) | carry;
38+
// Branch-less version of:
39+
// carry = 0;
40+
// if (r >= d) r -= d, carry = 1;
41+
const si_int s = (si_int)(d - r - 1) >> (N - 1);
42+
carry = s & 1;
43+
r -= d & s;
44+
}
45+
n = (n << 1) | carry;
46+
return n;
2347
}
2448

2549
#if defined(__ARM_EABI__)

umoddi3.c

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,35 @@
1212

1313
#include "int_lib.h"
1414

15-
typedef du_int fixuint_t;
16-
typedef di_int fixint_t;
17-
#include "int_div_impl.inc"
18-
1915
// Returns: a % b
2016

21-
COMPILER_RT_ABI du_int __umoddi3(du_int a, du_int b) {
22-
return __umodXi3(a, b);
17+
#undef clz
18+
#define clz(a) (sizeof(a) == sizeof(unsigned long long) ? __builtin_clzll(a) : clzsi(a))
19+
20+
// Mostly identical to __udivdi3 but the return values are different.
21+
COMPILER_RT_ABI du_int __umoddi3(du_int n, du_int d) {
22+
const unsigned N = sizeof(du_int) * CHAR_BIT;
23+
// d == 0 cases are unspecified.
24+
unsigned sr = (d ? clz(d) : N) - (n ? clz(n) : N);
25+
// 0 <= sr <= N - 1 or sr is very large.
26+
if (sr > N - 1) // n < d
27+
return n;
28+
if (sr == N - 1) // d == 1
29+
return 0;
30+
++sr;
31+
// 1 <= sr <= N - 1. Shifts do not trigger UB.
32+
du_int r = n >> sr;
33+
n <<= N - sr;
34+
du_int carry = 0;
35+
for (; sr > 0; --sr) {
36+
r = (r << 1) | (n >> (N - 1));
37+
n = (n << 1) | carry;
38+
// Branch-less version of:
39+
// carry = 0;
40+
// if (r >= d) r -= d, carry = 1;
41+
const di_int s = (di_int)(d - r - 1) >> (N - 1);
42+
carry = s & 1;
43+
r -= d & s;
44+
}
45+
return r;
2346
}

umodsi3.c

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,35 @@
1212

1313
#include "int_lib.h"
1414

15-
typedef su_int fixuint_t;
16-
typedef si_int fixint_t;
17-
#include "int_div_impl.inc"
18-
1915
// Returns: a % b
2016

21-
COMPILER_RT_ABI su_int __umodsi3(su_int a, su_int b) {
22-
return __umodXi3(a, b);
17+
#undef clz
18+
#define clz(a) (sizeof(a) == sizeof(unsigned long long) ? __builtin_clzll(a) : clzsi(a))
19+
20+
// Mostly identical to __udivsi3 but the return values are different.
21+
COMPILER_RT_ABI su_int __umodsi3(su_int n, su_int d) {
22+
const unsigned N = sizeof(su_int) * CHAR_BIT;
23+
// d == 0 cases are unspecified.
24+
unsigned sr = (d ? clz(d) : N) - (n ? clz(n) : N);
25+
// 0 <= sr <= N - 1 or sr is very large.
26+
if (sr > N - 1) // n < d
27+
return n;
28+
if (sr == N - 1) // d == 1
29+
return 0;
30+
++sr;
31+
// 1 <= sr <= N - 1. Shifts do not trigger UB.
32+
su_int r = n >> sr;
33+
n <<= N - sr;
34+
su_int carry = 0;
35+
for (; sr > 0; --sr) {
36+
r = (r << 1) | (n >> (N - 1));
37+
n = (n << 1) | carry;
38+
// Branch-less version of:
39+
// carry = 0;
40+
// if (r >= d) r -= d, carry = 1;
41+
const si_int s = (si_int)(d - r - 1) >> (N - 1);
42+
carry = s & 1;
43+
r -= d & s;
44+
}
45+
return r;
2346
}

0 commit comments

Comments
 (0)