git.cappig.dev / apheleiaOS.git master

1
#include <base/types.h>
2
3
#if defined(__has_attribute)
4
#if __has_attribute(weak)
5
#define WEAK_ATTR __attribute__((weak))
6
#endif
7
#endif
8
#ifndef WEAK_ATTR
9
#define WEAK_ATTR
10
#endif
11
12
static u64 udivmod64(u64 n, u64 d, u64 *rem) {
13
    if (d == 0) {
14
        if (rem) {
15
            *rem = 0;
16
        }
17
        return 0;
18
    }
19
20
    u64 q = 0;
21
    u64 r = 0;
22
23
    for (int i = 63; i >= 0; i--) {
24
        r = (r << 1) | ((n >> i) & 1ULL);
25
        if (r >= d) {
26
            r -= d;
27
            q |= (1ULL << i);
28
        }
29
    }
30
31
    if (rem) {
32
        *rem = r;
33
    }
34
35
    return q;
36
}
37
38
WEAK_ATTR u64 __udivdi3(u64 n, u64 d) {
39
    return udivmod64(n, d, 0);
40
}
41
42
WEAK_ATTR u64 __umoddi3(u64 n, u64 d) {
43
    u64 r = 0;
44
    udivmod64(n, d, &r);
45
    return r;
46
}
47
48
WEAK_ATTR i64 __divdi3(i64 n, i64 d) {
49
    int neg = 0;
50
    u64 un = (u64)n;
51
    u64 ud = (u64)d;
52
53
    if (n < 0) {
54
        neg ^= 1;
55
        un = (u64)(-n);
56
    }
57
    if (d < 0) {
58
        neg ^= 1;
59
        ud = (u64)(-d);
60
    }
61
62
    u64 q = udivmod64(un, ud, 0);
63
    return neg ? -(i64)q : (i64)q;
64
}
65
66
WEAK_ATTR i64 __moddi3(i64 n, i64 d) {
67
    int neg = 0;
68
    u64 un = (u64)n;
69
    u64 ud = (u64)d;
70
71
    if (n < 0) {
72
        neg = 1;
73
        un = (u64)(-n);
74
    }
75
    if (d < 0) {
76
        ud = (u64)(-d);
77
    }
78
79
    u64 r = 0;
80
    udivmod64(un, ud, &r);
81
    return neg ? -(i64)r : (i64)r;
82
}
83
84
WEAK_ATTR u64 __udivmoddi4(u64 n, u64 d, u64 *rem) {
85
    return udivmod64(n, d, rem);
86
}
87
88
WEAK_ATTR i64 __divmoddi4(i64 n, i64 d, i64 *rem) {
89
    int neg = 0;
90
    u64 un = (u64)n;
91
    u64 ud = (u64)d;
92
93
    if (n < 0) {
94
        neg ^= 1;
95
        un = (u64)(-n);
96
    }
97
    if (d < 0) {
98
        neg ^= 1;
99
        ud = (u64)(-d);
100
    }
101
102
    u64 r = 0;
103
    u64 q = udivmod64(un, ud, &r);
104
105
    if (rem) {
106
        i64 rr = (i64)r;
107
        if (n < 0) {
108
            rr = -rr;
109
        }
110
        *rem = rr;
111
    }
112
113
    return neg ? -(i64)q : (i64)q;
114
}