|
1 | 1 | /////////////////////////////////////////////////////////////////////////////// |
2 | | -// Copyright Christopher Kormanyos 2025. |
| 2 | +// Copyright Christopher Kormanyos 2025 - 2026. |
3 | 3 | // Distributed under the Boost Software License, |
4 | 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt |
5 | 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) |
|
8 | 8 | // Originally from (but strongly modified from): |
9 | 9 | /****************************************************************************************** |
10 | 10 | Filename : StdLib.c |
11 | | -
|
12 | | - Core : Xtensa LX7 |
13 | | -
|
14 | | - MCU : ESP32-S3 |
15 | | -
|
| 11 | + |
16 | 12 | Author : Chalandi Amine |
17 | | -
|
| 13 | + |
18 | 14 | Owner : Chalandi Amine |
19 | | -
|
| 15 | + |
20 | 16 | Date : 22.02.2025 |
21 | | -
|
22 | | - Description : Hand-written StdLib functions |
23 | | -
|
| 17 | + |
| 18 | + Description : Handwritten StdLib functions |
| 19 | + |
24 | 20 | ******************************************************************************************/ |
25 | 21 |
|
26 | 22 | #include <cstddef> |
|
29 | 25 |
|
30 | 26 | extern "C" { |
31 | 27 |
|
32 | | -using DItype = signed long long; |
33 | | -using UDItype = unsigned long long; |
34 | | -using USItype = unsigned int; |
35 | | - |
36 | | -extern auto __builtin_clzll(unsigned long long) -> int; |
37 | | - |
38 | | -using DWtype = DItype; |
39 | | -using UDWtype = UDItype; |
40 | | -using UWtype = USItype; |
41 | | - |
42 | | -auto __udivdi3 (UDWtype n, UDWtype d) -> UDWtype; |
43 | | -auto __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp) -> UDWtype; |
44 | | -auto __umoddi3 (UDWtype u, UDWtype v) -> UDWtype; |
45 | | - |
46 | | -auto __udivdi3 (UDWtype n, UDWtype d) -> UDWtype |
47 | | -{ |
48 | | - return __udivmoddi4 (n, d, (UDWtype *) 0); |
49 | | -} |
50 | | - |
51 | | -auto __umoddi3 (UDWtype u, UDWtype v) -> UDWtype |
52 | | -{ |
53 | | - UDWtype w; |
54 | | - |
55 | | - (void) __udivmoddi4 (u, v, &w); |
56 | | - |
57 | | - return w; |
58 | | -} |
59 | | - |
60 | | -auto __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp) -> UDWtype |
61 | | -{ |
62 | | - UDWtype q = 0, r = n, y = d; |
63 | | - UWtype lz1, lz2, i, k; |
64 | | - |
65 | | - // Implements align divisor shift dividend method. This algorithm |
66 | | - // aligns the divisor under the dividend and then perform number of |
67 | | - // test-subtract iterations which shift the dividend left. Number of |
68 | | - // iterations is k + 1 where k is the number of bit positions the |
69 | | - // divisor must be shifted left to align it under the dividend. |
70 | | - // quotient bits can be saved in the rightmost positions of the dividend |
71 | | - // as it shifts left on each test-subtract iteration. |
72 | | - |
73 | | - if (y <= r) |
74 | | - { |
75 | | - lz1 = static_cast<USItype>(__builtin_clzll(static_cast<unsigned long long>(d))); |
76 | | - lz2 = static_cast<USItype>(__builtin_clzll(static_cast<unsigned long long>(n))); |
77 | | - |
78 | | - k = lz1 - lz2; |
79 | | - y = (y << k); |
80 | | - |
81 | | - // Dividend can exceed 2 ^ (width - 1) - 1 but still be less than the |
82 | | - // aligned divisor. Normal iteration can drops the high order bit |
83 | | - // of the dividend. Therefore, first test-subtract iteration is a |
84 | | - // special case, saving its quotient bit in a separate location and |
85 | | - // not shifting the dividend. |
86 | | - |
87 | | - if (r >= y) |
88 | | - { |
89 | | - r = r - y; |
90 | | - q = (1ULL << k); |
91 | | - } |
92 | | - |
93 | | - if (k > 0) |
94 | | - { |
95 | | - y = y >> 1; |
96 | | - |
97 | | - // k additional iterations where k regular test subtract shift |
98 | | - // dividend iterations are done. |
99 | | - |
100 | | - i = k; |
101 | | - |
102 | | - do |
103 | | - { |
104 | | - if (r >= y) |
105 | | - { |
106 | | - r = ((r - y) << 1) + 1; |
107 | | - } |
108 | | - else |
109 | | - { |
110 | | - r = (r << 1); |
111 | | - } |
112 | | - |
113 | | - i = i - 1; |
114 | | - } |
115 | | - while (i != 0); |
116 | | - |
117 | | - // First quotient bit is combined with the quotient bits resulting |
118 | | - // from the k regular iterations. |
119 | | - |
120 | | - q = q + r; |
121 | | - r = r >> k; |
122 | | - q = q - (r << k); |
123 | | - } |
124 | | - } |
125 | | - |
126 | | - if (rp) |
127 | | - { |
128 | | - *rp = r; |
129 | | - } |
130 | | - |
131 | | - return q; |
132 | | -} |
133 | | - |
134 | 28 | #if defined(__GNUC__) |
135 | 29 | #pragma GCC diagnostic push |
136 | 30 | #pragma GCC diagnostic ignored "-Wcast-align" |
|
0 commit comments