authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-08-15 07:16:22-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-08-15 07:16:22-04:00
logcf46cd5f2b0f87430185c5d89056321d16f42d58
tree1fb55a248604b229b06d078d164810d9a8b31db2
parent38f898e9c74df3b25e1443273b19bc91e732798c

organize file path of compiler_rt


4 files changed, 528 insertions(+), 515 deletions(-)

CMakeLists.txt+1-1
...@@ -311,7 +311,7 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/special/bootstrap.zig" DESTINATION "${ZIG...@@ -311,7 +311,7 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/special/bootstrap.zig" DESTINATION "${ZIG
311install(FILES "${CMAKE_SOURCE_DIR}/std/special/build_file_template.zig" DESTINATION "${ZIG_STD_DEST}/special")311install(FILES "${CMAKE_SOURCE_DIR}/std/special/build_file_template.zig" DESTINATION "${ZIG_STD_DEST}/special")
312install(FILES "${CMAKE_SOURCE_DIR}/std/special/build_runner.zig" DESTINATION "${ZIG_STD_DEST}/special")312install(FILES "${CMAKE_SOURCE_DIR}/std/special/build_runner.zig" DESTINATION "${ZIG_STD_DEST}/special")
313install(FILES "${CMAKE_SOURCE_DIR}/std/special/builtin.zig" DESTINATION "${ZIG_STD_DEST}/special")313install(FILES "${CMAKE_SOURCE_DIR}/std/special/builtin.zig" DESTINATION "${ZIG_STD_DEST}/special")
314install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt.zig" DESTINATION "${ZIG_STD_DEST}/special")314install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt/index.zig" DESTINATION "${ZIG_STD_DEST}/special/compiler_rt")
315install(FILES "${CMAKE_SOURCE_DIR}/std/special/test_runner.zig" DESTINATION "${ZIG_STD_DEST}/special")315install(FILES "${CMAKE_SOURCE_DIR}/std/special/test_runner.zig" DESTINATION "${ZIG_STD_DEST}/special")
316install(FILES "${CMAKE_SOURCE_DIR}/std/special/zigrt.zig" DESTINATION "${ZIG_STD_DEST}/special")316install(FILES "${CMAKE_SOURCE_DIR}/std/special/zigrt.zig" DESTINATION "${ZIG_STD_DEST}/special")
317317
src/link.cpp+20-7
...@@ -31,11 +31,7 @@ static const char *get_libc_static_file(CodeGen *g, const char *file) {...@@ -31,11 +31,7 @@ static const char *get_libc_static_file(CodeGen *g, const char *file) {
31 return buf_ptr(out_buf);31 return buf_ptr(out_buf);
32}32}
3333
34static Buf *build_o(CodeGen *parent_gen, const char *oname) {34static Buf *build_o_raw(CodeGen *parent_gen, const char *oname, Buf *full_path) {
35 Buf *source_basename = buf_sprintf("%s.zig", oname);
36 Buf *full_path = buf_alloc();
37 os_path_join(parent_gen->zig_std_special_dir, source_basename, full_path);
38
39 ZigTarget *child_target = parent_gen->is_native_target ? nullptr : &parent_gen->zig_target;35 ZigTarget *child_target = parent_gen->is_native_target ? nullptr : &parent_gen->zig_target;
40 CodeGen *child_gen = codegen_create(full_path, child_target, OutTypeObj, parent_gen->build_mode);36 CodeGen *child_gen = codegen_create(full_path, child_target, OutTypeObj, parent_gen->build_mode);
4137
...@@ -65,6 +61,23 @@ static Buf *build_o(CodeGen *parent_gen, const char *oname) {...@@ -65,6 +61,23 @@ static Buf *build_o(CodeGen *parent_gen, const char *oname) {
65 return output_path;61 return output_path;
66}62}
6763
64static Buf *build_o(CodeGen *parent_gen, const char *oname) {
65 Buf *source_basename = buf_sprintf("%s.zig", oname);
66 Buf *full_path = buf_alloc();
67 os_path_join(parent_gen->zig_std_special_dir, source_basename, full_path);
68
69 return build_o_raw(parent_gen, oname, full_path);
70}
71
72static Buf *build_compiler_rt(CodeGen *parent_gen) {
73 Buf *dir_path = buf_alloc();
74 os_path_join(parent_gen->zig_std_special_dir, buf_create_from_str("compiler_rt"), dir_path);
75 Buf *full_path = buf_alloc();
76 os_path_join(dir_path, buf_create_from_str("index.zig"), full_path);
77
78 return build_o_raw(parent_gen, "compiler_rt", full_path);
79}
80
68static const char *get_exe_file_extension(CodeGen *g) {81static const char *get_exe_file_extension(CodeGen *g) {
69 if (g->zig_target.os == ZigLLVM_Win32) {82 if (g->zig_target.os == ZigLLVM_Win32) {
70 return ".exe";83 return ".exe";
...@@ -263,7 +276,7 @@ static void construct_linker_job_elf(LinkJob *lj) {...@@ -263,7 +276,7 @@ static void construct_linker_job_elf(LinkJob *lj) {
263 Buf *builtin_o_path = build_o(g, "builtin");276 Buf *builtin_o_path = build_o(g, "builtin");
264 lj->args.append(buf_ptr(builtin_o_path));277 lj->args.append(buf_ptr(builtin_o_path));
265278
266 Buf *compiler_rt_o_path = build_o(g, "compiler_rt");279 Buf *compiler_rt_o_path = build_compiler_rt(g);
267 lj->args.append(buf_ptr(compiler_rt_o_path));280 lj->args.append(buf_ptr(compiler_rt_o_path));
268 }281 }
269282
...@@ -401,7 +414,7 @@ static void construct_linker_job_coff(LinkJob *lj) {...@@ -401,7 +414,7 @@ static void construct_linker_job_coff(LinkJob *lj) {
401 Buf *builtin_o_path = build_o(g, "builtin");414 Buf *builtin_o_path = build_o(g, "builtin");
402 lj->args.append(buf_ptr(builtin_o_path));415 lj->args.append(buf_ptr(builtin_o_path));
403416
404 Buf *compiler_rt_o_path = build_o(g, "compiler_rt");417 Buf *compiler_rt_o_path = build_compiler_rt(g);
405 lj->args.append(buf_ptr(compiler_rt_o_path));418 lj->args.append(buf_ptr(compiler_rt_o_path));
406 }419 }
407420
std/special/compiler_rt.zig deleted-507
...@@ -1,507 +0,0 @@
1const builtin = @import("builtin");
2
3const CHAR_BIT = 8;
4const du_int = u64;
5const di_int = i64;
6const si_int = c_int;
7const su_int = c_uint;
8
9const udwords = [2]su_int;
10const low = if (builtin.is_big_endian) 1 else 0;
11const high = 1 - low;
12
13export fn __udivdi3(a: du_int, b: du_int) -> du_int {
14 @setDebugSafety(this, false);
15 return __udivmoddi4(a, b, null);
16}
17
18fn du_int_to_udwords(x: du_int) -> udwords {
19 @setDebugSafety(this, false);
20 return *@ptrCast(&udwords, &x);
21}
22
23export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
24 @setDebugSafety(this, false);
25
26 const n_uword_bits = @sizeOf(su_int) * CHAR_BIT;
27 const n_udword_bits = @sizeOf(du_int) * CHAR_BIT;
28 var n = du_int_to_udwords(a);
29 var d = du_int_to_udwords(b);
30 var q: udwords = undefined;
31 var r: udwords = undefined;
32 var sr: c_uint = undefined;
33 // special cases, X is unknown, K != 0
34 if (n[high] == 0) {
35 if (d[high] == 0) {
36 // 0 X
37 // ---
38 // 0 X
39 if (maybe_rem) |rem| {
40 *rem = n[low] % d[low];
41 }
42 return n[low] / d[low];
43 }
44 // 0 X
45 // ---
46 // K X
47 if (maybe_rem) |rem| {
48 *rem = n[low];
49 }
50 return 0;
51 }
52 // n[high] != 0
53 if (d[low] == 0) {
54 if (d[high] == 0) {
55 // K X
56 // ---
57 // 0 0
58 if (maybe_rem) |rem| {
59 *rem = n[high] % d[low];
60 }
61 return n[high] / d[low];
62 }
63 // d[high] != 0
64 if (n[low] == 0) {
65 // K 0
66 // ---
67 // K 0
68 if (maybe_rem) |rem| {
69 r[high] = n[high] % d[high];
70 r[low] = 0;
71 *rem = *@ptrCast(&du_int, &r[0]);
72 }
73 return n[high] / d[high];
74 }
75 // K K
76 // ---
77 // K 0
78 // if d is a power of 2
79 if ((d[high] & (d[high] - 1)) == 0) {
80 if (maybe_rem) |rem| {
81 r[low] = n[low];
82 r[high] = n[high] & (d[high] - 1);
83 *rem = *@ptrCast(&du_int, &r[0]);
84 }
85 return n[high] >> @ctz(d[high]);
86 }
87 // K K
88 // ---
89 // K 0
90 sr = @clz(su_int(d[high])) - @clz(su_int(n[high]));
91 // 0 <= sr <= n_uword_bits - 2 or sr large
92 if (sr > n_uword_bits - 2) {
93 if (maybe_rem) |rem| {
94 *rem = *@ptrCast(&du_int, &n[0]);
95 }
96 return 0;
97 }
98 sr += 1;
99 // 1 <= sr <= n_uword_bits - 1
100 // q.all = n.all << (n_udword_bits - sr);
101 q[low] = 0;
102 q[high] = n[low] << (n_uword_bits - sr);
103 // r.all = n.all >> sr;
104 r[high] = n[high] >> sr;
105 r[low] = (n[high] << (n_uword_bits - sr)) | (n[low] >> sr);
106 } else {
107 // d[low] != 0
108 if (d[high] == 0) {
109 // K X
110 // ---
111 // 0 K
112 // if d is a power of 2
113 if ((d[low] & (d[low] - 1)) == 0) {
114 if (maybe_rem) |rem| {
115 *rem = n[low] & (d[low] - 1);
116 }
117 if (d[low] == 1) {
118 return *@ptrCast(&du_int, &n[0]);
119 }
120 sr = @ctz(d[low]);
121 q[high] = n[high] >> sr;
122 q[low] = (n[high] << (n_uword_bits - sr)) | (n[low] >> sr);
123 return *@ptrCast(&du_int, &q[0]);
124 }
125 // K X
126 // ---
127 // 0 K
128 sr = 1 + n_uword_bits + @clz(su_int(d[low])) - @clz(su_int(n[high]));
129 // 2 <= sr <= n_udword_bits - 1
130 // q.all = n.all << (n_udword_bits - sr);
131 // r.all = n.all >> sr;
132 if (sr == n_uword_bits) {
133 q[low] = 0;
134 q[high] = n[low];
135 r[high] = 0;
136 r[low] = n[high];
137 } else if (sr < n_uword_bits) {
138 // 2 <= sr <= n_uword_bits - 1
139 q[low] = 0;
140 q[high] = n[low] << (n_uword_bits - sr);
141 r[high] = n[high] >> sr;
142 r[low] = (n[high] << (n_uword_bits - sr)) | (n[low] >> sr);
143 } else {
144 // n_uword_bits + 1 <= sr <= n_udword_bits - 1
145 q[low] = n[low] << (n_udword_bits - sr);
146 q[high] = (n[high] << (n_udword_bits - sr)) |
147 (n[low] >> (sr - n_uword_bits));
148 r[high] = 0;
149 r[low] = n[high] >> (sr - n_uword_bits);
150 }
151 } else {
152 // K X
153 // ---
154 // K K
155 sr = @clz(su_int(d[high])) - @clz(su_int(n[high]));
156 // 0 <= sr <= n_uword_bits - 1 or sr large
157 if (sr > n_uword_bits - 1) {
158 if (maybe_rem) |rem| {
159 *rem = *@ptrCast(&du_int, &n[0]);
160 }
161 return 0;
162 }
163 sr += 1;
164 // 1 <= sr <= n_uword_bits
165 // q.all = n.all << (n_udword_bits - sr);
166 q[low] = 0;
167 if (sr == n_uword_bits) {
168 q[high] = n[low];
169 r[high] = 0;
170 r[low] = n[high];
171 } else {
172 q[high] = n[low] << (n_uword_bits - sr);
173 r[high] = n[high] >> sr;
174 r[low] = (n[high] << (n_uword_bits - sr)) | (n[low] >> sr);
175 }
176 }
177 }
178 // Not a special case
179 // q and r are initialized with:
180 // q.all = n.all << (n_udword_bits - sr);
181 // r.all = n.all >> sr;
182 // 1 <= sr <= n_udword_bits - 1
183 var carry: su_int = 0;
184 while (sr > 0) {
185 // r:q = ((r:q) << 1) | carry
186 r[high] = (r[high] << 1) | (r[low] >> (n_uword_bits - 1));
187 r[low] = (r[low] << 1) | (q[high] >> (n_uword_bits - 1));
188 q[high] = (q[high] << 1) | (q[low] >> (n_uword_bits - 1));
189 q[low] = (q[low] << 1) | carry;
190 // carry = 0;
191 // if (r.all >= d.all)
192 // {
193 // r.all -= d.all;
194 // carry = 1;
195 // }
196 const s: di_int = (di_int)(*@ptrCast(&du_int, &d[0]) - *@ptrCast(&du_int, &r[0]) - 1) >> (n_udword_bits - 1);
197 carry = su_int(s & 1);
198 *@ptrCast(&du_int, &r[0]) -= *@ptrCast(&du_int, &d[0]) & u64(s);
199
200 sr -= 1;
201 }
202 *@ptrCast(&du_int, &q[0]) = (*@ptrCast(&du_int, &q[0]) << 1) | u64(carry);
203 if (maybe_rem) |rem| {
204 *rem = *@ptrCast(&du_int, &r[0]);
205 }
206 return *@ptrCast(&du_int, &q[0]);
207}
208
209export fn __umoddi3(a: du_int, b: du_int) -> du_int {
210 @setDebugSafety(this, false);
211
212 var r: du_int = undefined;
213 _ = __udivmoddi4(a, b, &r);
214 return r;
215}
216
217fn isArmArch() -> bool {
218 return switch (builtin.arch) {
219 builtin.Arch.armv8_2a,
220 builtin.Arch.armv8_1a,
221 builtin.Arch.armv8,
222 builtin.Arch.armv8m_baseline,
223 builtin.Arch.armv8m_mainline,
224 builtin.Arch.armv7,
225 builtin.Arch.armv7em,
226 builtin.Arch.armv7m,
227 builtin.Arch.armv7s,
228 builtin.Arch.armv7k,
229 builtin.Arch.armv6,
230 builtin.Arch.armv6m,
231 builtin.Arch.armv6k,
232 builtin.Arch.armv6t2,
233 builtin.Arch.armv5,
234 builtin.Arch.armv5te,
235 builtin.Arch.armv4t,
236 builtin.Arch.armeb => true,
237 else => false,
238 };
239}
240
241export nakedcc fn __aeabi_uidivmod() {
242 @setDebugSafety(this, false);
243
244 if (comptime isArmArch()) {
245 asm volatile (
246 \\ push { lr }
247 \\ sub sp, sp, #4
248 \\ mov r2, sp
249 \\ bl __udivmodsi4
250 \\ ldr r1, [sp]
251 \\ add sp, sp, #4
252 \\ pop { pc }
253 ::: "r2", "r1");
254 unreachable;
255 }
256
257 @setGlobalLinkage(__aeabi_uidivmod, builtin.GlobalLinkage.Internal);
258}
259
260export fn __udivmodsi4(a: su_int, b: su_int, rem: &su_int) -> su_int {
261 @setDebugSafety(this, false);
262
263 const d = __udivsi3(a, b);
264 *rem = su_int(si_int(a) -% (si_int(d) * si_int(b)));
265 return d;
266}
267
268
269// TODO make this an alias instead of an extra function call
270// https://github.com/andrewrk/zig/issues/256
271
272export fn __aeabi_uidiv(n: su_int, d: su_int) -> su_int {
273 @setDebugSafety(this, false);
274
275 return __udivsi3(n, d);
276}
277
278export fn __udivsi3(n: su_int, d: su_int) -> su_int {
279 @setDebugSafety(this, false);
280
281 const n_uword_bits: c_uint = @sizeOf(su_int) * CHAR_BIT;
282 // special cases
283 if (d == 0)
284 return 0; // ?!
285 if (n == 0)
286 return 0;
287 var sr: c_uint = @clz(d) - @clz(n);
288 // 0 <= sr <= n_uword_bits - 1 or sr large
289 if (sr > n_uword_bits - 1) // d > r
290 return 0;
291 if (sr == n_uword_bits - 1) // d == 1
292 return n;
293 sr += 1;
294 // 1 <= sr <= n_uword_bits - 1
295 // Not a special case
296 var q: su_int = n << (n_uword_bits - sr);
297 var r: su_int = n >> sr;
298 var carry: su_int = 0;
299 while (sr > 0) : (sr -= 1) {
300 // r:q = ((r:q) << 1) | carry
301 r = (r << 1) | (q >> (n_uword_bits - 1));
302 q = (q << 1) | carry;
303 // carry = 0;
304 // if (r.all >= d.all)
305 // {
306 // r.all -= d.all;
307 // carry = 1;
308 // }
309 const s = si_int(d - r - 1) >> si_int(n_uword_bits - 1);
310 carry = su_int(s & 1);
311 r -= d & su_int(s);
312 }
313 q = (q << 1) | carry;
314 return q;
315}
316
317test "test_umoddi3" {
318 test_one_umoddi3(0, 1, 0);
319 test_one_umoddi3(2, 1, 0);
320 test_one_umoddi3(0x8000000000000000, 1, 0x0);
321 test_one_umoddi3(0x8000000000000000, 2, 0x0);
322 test_one_umoddi3(0xFFFFFFFFFFFFFFFF, 2, 0x1);
323}
324
325fn test_one_umoddi3(a: du_int, b: du_int, expected_r: du_int) {
326 const r = __umoddi3(a, b);
327 assert(r == expected_r);
328}
329
330test "test_udivmoddi4" {
331 const cases = [][4]du_int {
332 []du_int{0x0000000000000000, 0x0000000000000001, 0x0000000000000000, 0x0000000000000000},
333 []du_int{0x0000000080000000, 0x0000000100000001, 0x0000000000000000, 0x0000000080000000},
334 []du_int{0x7FFFFFFF00000001, 0x0000000000000001, 0x7FFFFFFF00000001, 0x0000000000000000},
335 []du_int{0x7FFFFFFF7FFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x7FFFFFFF7FFFFFFF},
336 []du_int{0x8000000000000002, 0xFFFFFFFFFFFFFFFE, 0x0000000000000000, 0x8000000000000002},
337 []du_int{0x80000000FFFFFFFD, 0xFFFFFFFFFFFFFFFD, 0x0000000000000000, 0x80000000FFFFFFFD},
338 []du_int{0xFFFFFFFD00000010, 0xFFFFFFFF80000000, 0x0000000000000000, 0xFFFFFFFD00000010},
339 []du_int{0xFFFFFFFDFFFFFFFF, 0xFFFFFFFF7FFFFFFF, 0x0000000000000000, 0xFFFFFFFDFFFFFFFF},
340 []du_int{0xFFFFFFFE0747AE14, 0xFFFFFFFF0747AE14, 0x0000000000000000, 0xFFFFFFFE0747AE14},
341 []du_int{0xFFFFFFFF00000001, 0xFFFFFFFF078644FA, 0x0000000000000000, 0xFFFFFFFF00000001},
342 []du_int{0xFFFFFFFF80000000, 0xFFFFFFFF00000010, 0x0000000000000001, 0x000000007FFFFFF0},
343 []du_int{0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000001, 0x0000000000000000},
344 };
345
346 for (cases) |case| {
347 test_one_udivmoddi4(case[0], case[1], case[2], case[3]);
348 }
349}
350
351fn test_one_udivmoddi4(a: du_int, b: du_int, expected_q: du_int, expected_r: du_int) {
352 var r: du_int = undefined;
353 const q = __udivmoddi4(a, b, &r);
354 assert(q == expected_q);
355 assert(r == expected_r);
356}
357
358test "test_udivsi3" {
359 const cases = [][3]su_int {
360 []su_int{0x00000000, 0x00000001, 0x00000000},
361 []su_int{0x00000000, 0x00000002, 0x00000000},
362 []su_int{0x00000000, 0x00000003, 0x00000000},
363 []su_int{0x00000000, 0x00000010, 0x00000000},
364 []su_int{0x00000000, 0x078644FA, 0x00000000},
365 []su_int{0x00000000, 0x0747AE14, 0x00000000},
366 []su_int{0x00000000, 0x7FFFFFFF, 0x00000000},
367 []su_int{0x00000000, 0x80000000, 0x00000000},
368 []su_int{0x00000000, 0xFFFFFFFD, 0x00000000},
369 []su_int{0x00000000, 0xFFFFFFFE, 0x00000000},
370 []su_int{0x00000000, 0xFFFFFFFF, 0x00000000},
371 []su_int{0x00000001, 0x00000001, 0x00000001},
372 []su_int{0x00000001, 0x00000002, 0x00000000},
373 []su_int{0x00000001, 0x00000003, 0x00000000},
374 []su_int{0x00000001, 0x00000010, 0x00000000},
375 []su_int{0x00000001, 0x078644FA, 0x00000000},
376 []su_int{0x00000001, 0x0747AE14, 0x00000000},
377 []su_int{0x00000001, 0x7FFFFFFF, 0x00000000},
378 []su_int{0x00000001, 0x80000000, 0x00000000},
379 []su_int{0x00000001, 0xFFFFFFFD, 0x00000000},
380 []su_int{0x00000001, 0xFFFFFFFE, 0x00000000},
381 []su_int{0x00000001, 0xFFFFFFFF, 0x00000000},
382 []su_int{0x00000002, 0x00000001, 0x00000002},
383 []su_int{0x00000002, 0x00000002, 0x00000001},
384 []su_int{0x00000002, 0x00000003, 0x00000000},
385 []su_int{0x00000002, 0x00000010, 0x00000000},
386 []su_int{0x00000002, 0x078644FA, 0x00000000},
387 []su_int{0x00000002, 0x0747AE14, 0x00000000},
388 []su_int{0x00000002, 0x7FFFFFFF, 0x00000000},
389 []su_int{0x00000002, 0x80000000, 0x00000000},
390 []su_int{0x00000002, 0xFFFFFFFD, 0x00000000},
391 []su_int{0x00000002, 0xFFFFFFFE, 0x00000000},
392 []su_int{0x00000002, 0xFFFFFFFF, 0x00000000},
393 []su_int{0x00000003, 0x00000001, 0x00000003},
394 []su_int{0x00000003, 0x00000002, 0x00000001},
395 []su_int{0x00000003, 0x00000003, 0x00000001},
396 []su_int{0x00000003, 0x00000010, 0x00000000},
397 []su_int{0x00000003, 0x078644FA, 0x00000000},
398 []su_int{0x00000003, 0x0747AE14, 0x00000000},
399 []su_int{0x00000003, 0x7FFFFFFF, 0x00000000},
400 []su_int{0x00000003, 0x80000000, 0x00000000},
401 []su_int{0x00000003, 0xFFFFFFFD, 0x00000000},
402 []su_int{0x00000003, 0xFFFFFFFE, 0x00000000},
403 []su_int{0x00000003, 0xFFFFFFFF, 0x00000000},
404 []su_int{0x00000010, 0x00000001, 0x00000010},
405 []su_int{0x00000010, 0x00000002, 0x00000008},
406 []su_int{0x00000010, 0x00000003, 0x00000005},
407 []su_int{0x00000010, 0x00000010, 0x00000001},
408 []su_int{0x00000010, 0x078644FA, 0x00000000},
409 []su_int{0x00000010, 0x0747AE14, 0x00000000},
410 []su_int{0x00000010, 0x7FFFFFFF, 0x00000000},
411 []su_int{0x00000010, 0x80000000, 0x00000000},
412 []su_int{0x00000010, 0xFFFFFFFD, 0x00000000},
413 []su_int{0x00000010, 0xFFFFFFFE, 0x00000000},
414 []su_int{0x00000010, 0xFFFFFFFF, 0x00000000},
415 []su_int{0x078644FA, 0x00000001, 0x078644FA},
416 []su_int{0x078644FA, 0x00000002, 0x03C3227D},
417 []su_int{0x078644FA, 0x00000003, 0x028216FE},
418 []su_int{0x078644FA, 0x00000010, 0x0078644F},
419 []su_int{0x078644FA, 0x078644FA, 0x00000001},
420 []su_int{0x078644FA, 0x0747AE14, 0x00000001},
421 []su_int{0x078644FA, 0x7FFFFFFF, 0x00000000},
422 []su_int{0x078644FA, 0x80000000, 0x00000000},
423 []su_int{0x078644FA, 0xFFFFFFFD, 0x00000000},
424 []su_int{0x078644FA, 0xFFFFFFFE, 0x00000000},
425 []su_int{0x078644FA, 0xFFFFFFFF, 0x00000000},
426 []su_int{0x0747AE14, 0x00000001, 0x0747AE14},
427 []su_int{0x0747AE14, 0x00000002, 0x03A3D70A},
428 []su_int{0x0747AE14, 0x00000003, 0x026D3A06},
429 []su_int{0x0747AE14, 0x00000010, 0x00747AE1},
430 []su_int{0x0747AE14, 0x078644FA, 0x00000000},
431 []su_int{0x0747AE14, 0x0747AE14, 0x00000001},
432 []su_int{0x0747AE14, 0x7FFFFFFF, 0x00000000},
433 []su_int{0x0747AE14, 0x80000000, 0x00000000},
434 []su_int{0x0747AE14, 0xFFFFFFFD, 0x00000000},
435 []su_int{0x0747AE14, 0xFFFFFFFE, 0x00000000},
436 []su_int{0x0747AE14, 0xFFFFFFFF, 0x00000000},
437 []su_int{0x7FFFFFFF, 0x00000001, 0x7FFFFFFF},
438 []su_int{0x7FFFFFFF, 0x00000002, 0x3FFFFFFF},
439 []su_int{0x7FFFFFFF, 0x00000003, 0x2AAAAAAA},
440 []su_int{0x7FFFFFFF, 0x00000010, 0x07FFFFFF},
441 []su_int{0x7FFFFFFF, 0x078644FA, 0x00000011},
442 []su_int{0x7FFFFFFF, 0x0747AE14, 0x00000011},
443 []su_int{0x7FFFFFFF, 0x7FFFFFFF, 0x00000001},
444 []su_int{0x7FFFFFFF, 0x80000000, 0x00000000},
445 []su_int{0x7FFFFFFF, 0xFFFFFFFD, 0x00000000},
446 []su_int{0x7FFFFFFF, 0xFFFFFFFE, 0x00000000},
447 []su_int{0x7FFFFFFF, 0xFFFFFFFF, 0x00000000},
448 []su_int{0x80000000, 0x00000001, 0x80000000},
449 []su_int{0x80000000, 0x00000002, 0x40000000},
450 []su_int{0x80000000, 0x00000003, 0x2AAAAAAA},
451 []su_int{0x80000000, 0x00000010, 0x08000000},
452 []su_int{0x80000000, 0x078644FA, 0x00000011},
453 []su_int{0x80000000, 0x0747AE14, 0x00000011},
454 []su_int{0x80000000, 0x7FFFFFFF, 0x00000001},
455 []su_int{0x80000000, 0x80000000, 0x00000001},
456 []su_int{0x80000000, 0xFFFFFFFD, 0x00000000},
457 []su_int{0x80000000, 0xFFFFFFFE, 0x00000000},
458 []su_int{0x80000000, 0xFFFFFFFF, 0x00000000},
459 []su_int{0xFFFFFFFD, 0x00000001, 0xFFFFFFFD},
460 []su_int{0xFFFFFFFD, 0x00000002, 0x7FFFFFFE},
461 []su_int{0xFFFFFFFD, 0x00000003, 0x55555554},
462 []su_int{0xFFFFFFFD, 0x00000010, 0x0FFFFFFF},
463 []su_int{0xFFFFFFFD, 0x078644FA, 0x00000022},
464 []su_int{0xFFFFFFFD, 0x0747AE14, 0x00000023},
465 []su_int{0xFFFFFFFD, 0x7FFFFFFF, 0x00000001},
466 []su_int{0xFFFFFFFD, 0x80000000, 0x00000001},
467 []su_int{0xFFFFFFFD, 0xFFFFFFFD, 0x00000001},
468 []su_int{0xFFFFFFFD, 0xFFFFFFFE, 0x00000000},
469 []su_int{0xFFFFFFFD, 0xFFFFFFFF, 0x00000000},
470 []su_int{0xFFFFFFFE, 0x00000001, 0xFFFFFFFE},
471 []su_int{0xFFFFFFFE, 0x00000002, 0x7FFFFFFF},
472 []su_int{0xFFFFFFFE, 0x00000003, 0x55555554},
473 []su_int{0xFFFFFFFE, 0x00000010, 0x0FFFFFFF},
474 []su_int{0xFFFFFFFE, 0x078644FA, 0x00000022},
475 []su_int{0xFFFFFFFE, 0x0747AE14, 0x00000023},
476 []su_int{0xFFFFFFFE, 0x7FFFFFFF, 0x00000002},
477 []su_int{0xFFFFFFFE, 0x80000000, 0x00000001},
478 []su_int{0xFFFFFFFE, 0xFFFFFFFD, 0x00000001},
479 []su_int{0xFFFFFFFE, 0xFFFFFFFE, 0x00000001},
480 []su_int{0xFFFFFFFE, 0xFFFFFFFF, 0x00000000},
481 []su_int{0xFFFFFFFF, 0x00000001, 0xFFFFFFFF},
482 []su_int{0xFFFFFFFF, 0x00000002, 0x7FFFFFFF},
483 []su_int{0xFFFFFFFF, 0x00000003, 0x55555555},
484 []su_int{0xFFFFFFFF, 0x00000010, 0x0FFFFFFF},
485 []su_int{0xFFFFFFFF, 0x078644FA, 0x00000022},
486 []su_int{0xFFFFFFFF, 0x0747AE14, 0x00000023},
487 []su_int{0xFFFFFFFF, 0x7FFFFFFF, 0x00000002},
488 []su_int{0xFFFFFFFF, 0x80000000, 0x00000001},
489 []su_int{0xFFFFFFFF, 0xFFFFFFFD, 0x00000001},
490 []su_int{0xFFFFFFFF, 0xFFFFFFFE, 0x00000001},
491 []su_int{0xFFFFFFFF, 0xFFFFFFFF, 0x00000001},
492 };
493
494 for (cases) |case| {
495 test_one_udivsi3(case[0], case[1], case[2]);
496 }
497}
498
499fn test_one_udivsi3(a: su_int, b: su_int, expected_q: su_int) {
500 const q: su_int = __udivsi3(a, b);
501 assert(q == expected_q);
502}
503
504
505fn assert(ok: bool) {
506 if (!ok) unreachable;
507}
std/special/compiler_rt/index.zig created+507
...@@ -0,0 +1,507 @@
1const builtin = @import("builtin");
2
3const CHAR_BIT = 8;
4const du_int = u64;
5const di_int = i64;
6const si_int = c_int;
7const su_int = c_uint;
8
9const udwords = [2]su_int;
10const low = if (builtin.is_big_endian) 1 else 0;
11const high = 1 - low;
12
13export fn __udivdi3(a: du_int, b: du_int) -> du_int {
14 @setDebugSafety(this, false);
15 return __udivmoddi4(a, b, null);
16}
17
18fn du_int_to_udwords(x: du_int) -> udwords {
19 @setDebugSafety(this, false);
20 return *@ptrCast(&udwords, &x);
21}
22
23export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
24 @setDebugSafety(this, false);
25
26 const n_uword_bits = @sizeOf(su_int) * CHAR_BIT;
27 const n_udword_bits = @sizeOf(du_int) * CHAR_BIT;
28 var n = du_int_to_udwords(a);
29 var d = du_int_to_udwords(b);
30 var q: udwords = undefined;
31 var r: udwords = undefined;
32 var sr: c_uint = undefined;
33 // special cases, X is unknown, K != 0
34 if (n[high] == 0) {
35 if (d[high] == 0) {
36 // 0 X
37 // ---
38 // 0 X
39 if (maybe_rem) |rem| {
40 *rem = n[low] % d[low];
41 }
42 return n[low] / d[low];
43 }
44 // 0 X
45 // ---
46 // K X
47 if (maybe_rem) |rem| {
48 *rem = n[low];
49 }
50 return 0;
51 }
52 // n[high] != 0
53 if (d[low] == 0) {
54 if (d[high] == 0) {
55 // K X
56 // ---
57 // 0 0
58 if (maybe_rem) |rem| {
59 *rem = n[high] % d[low];
60 }
61 return n[high] / d[low];
62 }
63 // d[high] != 0
64 if (n[low] == 0) {
65 // K 0
66 // ---
67 // K 0
68 if (maybe_rem) |rem| {
69 r[high] = n[high] % d[high];
70 r[low] = 0;
71 *rem = *@ptrCast(&du_int, &r[0]);
72 }
73 return n[high] / d[high];
74 }
75 // K K
76 // ---
77 // K 0
78 // if d is a power of 2
79 if ((d[high] & (d[high] - 1)) == 0) {
80 if (maybe_rem) |rem| {
81 r[low] = n[low];
82 r[high] = n[high] & (d[high] - 1);
83 *rem = *@ptrCast(&du_int, &r[0]);
84 }
85 return n[high] >> @ctz(d[high]);
86 }
87 // K K
88 // ---
89 // K 0
90 sr = @clz(su_int(d[high])) - @clz(su_int(n[high]));
91 // 0 <= sr <= n_uword_bits - 2 or sr large
92 if (sr > n_uword_bits - 2) {
93 if (maybe_rem) |rem| {
94 *rem = *@ptrCast(&du_int, &n[0]);
95 }
96 return 0;
97 }
98 sr += 1;
99 // 1 <= sr <= n_uword_bits - 1
100 // q.all = n.all << (n_udword_bits - sr);
101 q[low] = 0;
102 q[high] = n[low] << (n_uword_bits - sr);
103 // r.all = n.all >> sr;
104 r[high] = n[high] >> sr;
105 r[low] = (n[high] << (n_uword_bits - sr)) | (n[low] >> sr);
106 } else {
107 // d[low] != 0
108 if (d[high] == 0) {
109 // K X
110 // ---
111 // 0 K
112 // if d is a power of 2
113 if ((d[low] & (d[low] - 1)) == 0) {
114 if (maybe_rem) |rem| {
115 *rem = n[low] & (d[low] - 1);
116 }
117 if (d[low] == 1) {
118 return *@ptrCast(&du_int, &n[0]);
119 }
120 sr = @ctz(d[low]);
121 q[high] = n[high] >> sr;
122 q[low] = (n[high] << (n_uword_bits - sr)) | (n[low] >> sr);
123 return *@ptrCast(&du_int, &q[0]);
124 }
125 // K X
126 // ---
127 // 0 K
128 sr = 1 + n_uword_bits + @clz(su_int(d[low])) - @clz(su_int(n[high]));
129 // 2 <= sr <= n_udword_bits - 1
130 // q.all = n.all << (n_udword_bits - sr);
131 // r.all = n.all >> sr;
132 if (sr == n_uword_bits) {
133 q[low] = 0;
134 q[high] = n[low];
135 r[high] = 0;
136 r[low] = n[high];
137 } else if (sr < n_uword_bits) {
138 // 2 <= sr <= n_uword_bits - 1
139 q[low] = 0;
140 q[high] = n[low] << (n_uword_bits - sr);
141 r[high] = n[high] >> sr;
142 r[low] = (n[high] << (n_uword_bits - sr)) | (n[low] >> sr);
143 } else {
144 // n_uword_bits + 1 <= sr <= n_udword_bits - 1
145 q[low] = n[low] << (n_udword_bits - sr);
146 q[high] = (n[high] << (n_udword_bits - sr)) |
147 (n[low] >> (sr - n_uword_bits));
148 r[high] = 0;
149 r[low] = n[high] >> (sr - n_uword_bits);
150 }
151 } else {
152 // K X
153 // ---
154 // K K
155 sr = @clz(su_int(d[high])) - @clz(su_int(n[high]));
156 // 0 <= sr <= n_uword_bits - 1 or sr large
157 if (sr > n_uword_bits - 1) {
158 if (maybe_rem) |rem| {
159 *rem = *@ptrCast(&du_int, &n[0]);
160 }
161 return 0;
162 }
163 sr += 1;
164 // 1 <= sr <= n_uword_bits
165 // q.all = n.all << (n_udword_bits - sr);
166 q[low] = 0;
167 if (sr == n_uword_bits) {
168 q[high] = n[low];
169 r[high] = 0;
170 r[low] = n[high];
171 } else {
172 q[high] = n[low] << (n_uword_bits - sr);
173 r[high] = n[high] >> sr;
174 r[low] = (n[high] << (n_uword_bits - sr)) | (n[low] >> sr);
175 }
176 }
177 }
178 // Not a special case
179 // q and r are initialized with:
180 // q.all = n.all << (n_udword_bits - sr);
181 // r.all = n.all >> sr;
182 // 1 <= sr <= n_udword_bits - 1
183 var carry: su_int = 0;
184 while (sr > 0) {
185 // r:q = ((r:q) << 1) | carry
186 r[high] = (r[high] << 1) | (r[low] >> (n_uword_bits - 1));
187 r[low] = (r[low] << 1) | (q[high] >> (n_uword_bits - 1));
188 q[high] = (q[high] << 1) | (q[low] >> (n_uword_bits - 1));
189 q[low] = (q[low] << 1) | carry;
190 // carry = 0;
191 // if (r.all >= d.all)
192 // {
193 // r.all -= d.all;
194 // carry = 1;
195 // }
196 const s: di_int = (di_int)(*@ptrCast(&du_int, &d[0]) - *@ptrCast(&du_int, &r[0]) - 1) >> (n_udword_bits - 1);
197 carry = su_int(s & 1);
198 *@ptrCast(&du_int, &r[0]) -= *@ptrCast(&du_int, &d[0]) & u64(s);
199
200 sr -= 1;
201 }
202 *@ptrCast(&du_int, &q[0]) = (*@ptrCast(&du_int, &q[0]) << 1) | u64(carry);
203 if (maybe_rem) |rem| {
204 *rem = *@ptrCast(&du_int, &r[0]);
205 }
206 return *@ptrCast(&du_int, &q[0]);
207}
208
209export fn __umoddi3(a: du_int, b: du_int) -> du_int {
210 @setDebugSafety(this, false);
211
212 var r: du_int = undefined;
213 _ = __udivmoddi4(a, b, &r);
214 return r;
215}
216
217fn isArmArch() -> bool {
218 return switch (builtin.arch) {
219 builtin.Arch.armv8_2a,
220 builtin.Arch.armv8_1a,
221 builtin.Arch.armv8,
222 builtin.Arch.armv8m_baseline,
223 builtin.Arch.armv8m_mainline,
224 builtin.Arch.armv7,
225 builtin.Arch.armv7em,
226 builtin.Arch.armv7m,
227 builtin.Arch.armv7s,
228 builtin.Arch.armv7k,
229 builtin.Arch.armv6,
230 builtin.Arch.armv6m,
231 builtin.Arch.armv6k,
232 builtin.Arch.armv6t2,
233 builtin.Arch.armv5,
234 builtin.Arch.armv5te,
235 builtin.Arch.armv4t,
236 builtin.Arch.armeb => true,
237 else => false,
238 };
239}
240
241export nakedcc fn __aeabi_uidivmod() {
242 @setDebugSafety(this, false);
243
244 if (comptime isArmArch()) {
245 asm volatile (
246 \\ push { lr }
247 \\ sub sp, sp, #4
248 \\ mov r2, sp
249 \\ bl __udivmodsi4
250 \\ ldr r1, [sp]
251 \\ add sp, sp, #4
252 \\ pop { pc }
253 ::: "r2", "r1");
254 unreachable;
255 }
256
257 @setGlobalLinkage(__aeabi_uidivmod, builtin.GlobalLinkage.Internal);
258}
259
260export fn __udivmodsi4(a: su_int, b: su_int, rem: &su_int) -> su_int {
261 @setDebugSafety(this, false);
262
263 const d = __udivsi3(a, b);
264 *rem = su_int(si_int(a) -% (si_int(d) * si_int(b)));
265 return d;
266}
267
268
269// TODO make this an alias instead of an extra function call
270// https://github.com/andrewrk/zig/issues/256
271
272export fn __aeabi_uidiv(n: su_int, d: su_int) -> su_int {
273 @setDebugSafety(this, false);
274
275 return __udivsi3(n, d);
276}
277
278export fn __udivsi3(n: su_int, d: su_int) -> su_int {
279 @setDebugSafety(this, false);
280
281 const n_uword_bits: c_uint = @sizeOf(su_int) * CHAR_BIT;
282 // special cases
283 if (d == 0)
284 return 0; // ?!
285 if (n == 0)
286 return 0;
287 var sr: c_uint = @clz(d) - @clz(n);
288 // 0 <= sr <= n_uword_bits - 1 or sr large
289 if (sr > n_uword_bits - 1) // d > r
290 return 0;
291 if (sr == n_uword_bits - 1) // d == 1
292 return n;
293 sr += 1;
294 // 1 <= sr <= n_uword_bits - 1
295 // Not a special case
296 var q: su_int = n << (n_uword_bits - sr);
297 var r: su_int = n >> sr;
298 var carry: su_int = 0;
299 while (sr > 0) : (sr -= 1) {
300 // r:q = ((r:q) << 1) | carry
301 r = (r << 1) | (q >> (n_uword_bits - 1));
302 q = (q << 1) | carry;
303 // carry = 0;
304 // if (r.all >= d.all)
305 // {
306 // r.all -= d.all;
307 // carry = 1;
308 // }
309 const s = si_int(d - r - 1) >> si_int(n_uword_bits - 1);
310 carry = su_int(s & 1);
311 r -= d & su_int(s);
312 }
313 q = (q << 1) | carry;
314 return q;
315}
316
317test "test_umoddi3" {
318 test_one_umoddi3(0, 1, 0);
319 test_one_umoddi3(2, 1, 0);
320 test_one_umoddi3(0x8000000000000000, 1, 0x0);
321 test_one_umoddi3(0x8000000000000000, 2, 0x0);
322 test_one_umoddi3(0xFFFFFFFFFFFFFFFF, 2, 0x1);
323}
324
325fn test_one_umoddi3(a: du_int, b: du_int, expected_r: du_int) {
326 const r = __umoddi3(a, b);
327 assert(r == expected_r);
328}
329
330test "test_udivmoddi4" {
331 const cases = [][4]du_int {
332 []du_int{0x0000000000000000, 0x0000000000000001, 0x0000000000000000, 0x0000000000000000},
333 []du_int{0x0000000080000000, 0x0000000100000001, 0x0000000000000000, 0x0000000080000000},
334 []du_int{0x7FFFFFFF00000001, 0x0000000000000001, 0x7FFFFFFF00000001, 0x0000000000000000},
335 []du_int{0x7FFFFFFF7FFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x7FFFFFFF7FFFFFFF},
336 []du_int{0x8000000000000002, 0xFFFFFFFFFFFFFFFE, 0x0000000000000000, 0x8000000000000002},
337 []du_int{0x80000000FFFFFFFD, 0xFFFFFFFFFFFFFFFD, 0x0000000000000000, 0x80000000FFFFFFFD},
338 []du_int{0xFFFFFFFD00000010, 0xFFFFFFFF80000000, 0x0000000000000000, 0xFFFFFFFD00000010},
339 []du_int{0xFFFFFFFDFFFFFFFF, 0xFFFFFFFF7FFFFFFF, 0x0000000000000000, 0xFFFFFFFDFFFFFFFF},
340 []du_int{0xFFFFFFFE0747AE14, 0xFFFFFFFF0747AE14, 0x0000000000000000, 0xFFFFFFFE0747AE14},
341 []du_int{0xFFFFFFFF00000001, 0xFFFFFFFF078644FA, 0x0000000000000000, 0xFFFFFFFF00000001},
342 []du_int{0xFFFFFFFF80000000, 0xFFFFFFFF00000010, 0x0000000000000001, 0x000000007FFFFFF0},
343 []du_int{0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000001, 0x0000000000000000},
344 };
345
346 for (cases) |case| {
347 test_one_udivmoddi4(case[0], case[1], case[2], case[3]);
348 }
349}
350
351fn test_one_udivmoddi4(a: du_int, b: du_int, expected_q: du_int, expected_r: du_int) {
352 var r: du_int = undefined;
353 const q = __udivmoddi4(a, b, &r);
354 assert(q == expected_q);
355 assert(r == expected_r);
356}
357
358test "test_udivsi3" {
359 const cases = [][3]su_int {
360 []su_int{0x00000000, 0x00000001, 0x00000000},
361 []su_int{0x00000000, 0x00000002, 0x00000000},
362 []su_int{0x00000000, 0x00000003, 0x00000000},
363 []su_int{0x00000000, 0x00000010, 0x00000000},
364 []su_int{0x00000000, 0x078644FA, 0x00000000},
365 []su_int{0x00000000, 0x0747AE14, 0x00000000},
366 []su_int{0x00000000, 0x7FFFFFFF, 0x00000000},
367 []su_int{0x00000000, 0x80000000, 0x00000000},
368 []su_int{0x00000000, 0xFFFFFFFD, 0x00000000},
369 []su_int{0x00000000, 0xFFFFFFFE, 0x00000000},
370 []su_int{0x00000000, 0xFFFFFFFF, 0x00000000},
371 []su_int{0x00000001, 0x00000001, 0x00000001},
372 []su_int{0x00000001, 0x00000002, 0x00000000},
373 []su_int{0x00000001, 0x00000003, 0x00000000},
374 []su_int{0x00000001, 0x00000010, 0x00000000},
375 []su_int{0x00000001, 0x078644FA, 0x00000000},
376 []su_int{0x00000001, 0x0747AE14, 0x00000000},
377 []su_int{0x00000001, 0x7FFFFFFF, 0x00000000},
378 []su_int{0x00000001, 0x80000000, 0x00000000},
379 []su_int{0x00000001, 0xFFFFFFFD, 0x00000000},
380 []su_int{0x00000001, 0xFFFFFFFE, 0x00000000},
381 []su_int{0x00000001, 0xFFFFFFFF, 0x00000000},
382 []su_int{0x00000002, 0x00000001, 0x00000002},
383 []su_int{0x00000002, 0x00000002, 0x00000001},
384 []su_int{0x00000002, 0x00000003, 0x00000000},
385 []su_int{0x00000002, 0x00000010, 0x00000000},
386 []su_int{0x00000002, 0x078644FA, 0x00000000},
387 []su_int{0x00000002, 0x0747AE14, 0x00000000},
388 []su_int{0x00000002, 0x7FFFFFFF, 0x00000000},
389 []su_int{0x00000002, 0x80000000, 0x00000000},
390 []su_int{0x00000002, 0xFFFFFFFD, 0x00000000},
391 []su_int{0x00000002, 0xFFFFFFFE, 0x00000000},
392 []su_int{0x00000002, 0xFFFFFFFF, 0x00000000},
393 []su_int{0x00000003, 0x00000001, 0x00000003},
394 []su_int{0x00000003, 0x00000002, 0x00000001},
395 []su_int{0x00000003, 0x00000003, 0x00000001},
396 []su_int{0x00000003, 0x00000010, 0x00000000},
397 []su_int{0x00000003, 0x078644FA, 0x00000000},
398 []su_int{0x00000003, 0x0747AE14, 0x00000000},
399 []su_int{0x00000003, 0x7FFFFFFF, 0x00000000},
400 []su_int{0x00000003, 0x80000000, 0x00000000},
401 []su_int{0x00000003, 0xFFFFFFFD, 0x00000000},
402 []su_int{0x00000003, 0xFFFFFFFE, 0x00000000},
403 []su_int{0x00000003, 0xFFFFFFFF, 0x00000000},
404 []su_int{0x00000010, 0x00000001, 0x00000010},
405 []su_int{0x00000010, 0x00000002, 0x00000008},
406 []su_int{0x00000010, 0x00000003, 0x00000005},
407 []su_int{0x00000010, 0x00000010, 0x00000001},
408 []su_int{0x00000010, 0x078644FA, 0x00000000},
409 []su_int{0x00000010, 0x0747AE14, 0x00000000},
410 []su_int{0x00000010, 0x7FFFFFFF, 0x00000000},
411 []su_int{0x00000010, 0x80000000, 0x00000000},
412 []su_int{0x00000010, 0xFFFFFFFD, 0x00000000},
413 []su_int{0x00000010, 0xFFFFFFFE, 0x00000000},
414 []su_int{0x00000010, 0xFFFFFFFF, 0x00000000},
415 []su_int{0x078644FA, 0x00000001, 0x078644FA},
416 []su_int{0x078644FA, 0x00000002, 0x03C3227D},
417 []su_int{0x078644FA, 0x00000003, 0x028216FE},
418 []su_int{0x078644FA, 0x00000010, 0x0078644F},
419 []su_int{0x078644FA, 0x078644FA, 0x00000001},
420 []su_int{0x078644FA, 0x0747AE14, 0x00000001},
421 []su_int{0x078644FA, 0x7FFFFFFF, 0x00000000},
422 []su_int{0x078644FA, 0x80000000, 0x00000000},
423 []su_int{0x078644FA, 0xFFFFFFFD, 0x00000000},
424 []su_int{0x078644FA, 0xFFFFFFFE, 0x00000000},
425 []su_int{0x078644FA, 0xFFFFFFFF, 0x00000000},
426 []su_int{0x0747AE14, 0x00000001, 0x0747AE14},
427 []su_int{0x0747AE14, 0x00000002, 0x03A3D70A},
428 []su_int{0x0747AE14, 0x00000003, 0x026D3A06},
429 []su_int{0x0747AE14, 0x00000010, 0x00747AE1},
430 []su_int{0x0747AE14, 0x078644FA, 0x00000000},
431 []su_int{0x0747AE14, 0x0747AE14, 0x00000001},
432 []su_int{0x0747AE14, 0x7FFFFFFF, 0x00000000},
433 []su_int{0x0747AE14, 0x80000000, 0x00000000},
434 []su_int{0x0747AE14, 0xFFFFFFFD, 0x00000000},
435 []su_int{0x0747AE14, 0xFFFFFFFE, 0x00000000},
436 []su_int{0x0747AE14, 0xFFFFFFFF, 0x00000000},
437 []su_int{0x7FFFFFFF, 0x00000001, 0x7FFFFFFF},
438 []su_int{0x7FFFFFFF, 0x00000002, 0x3FFFFFFF},
439 []su_int{0x7FFFFFFF, 0x00000003, 0x2AAAAAAA},
440 []su_int{0x7FFFFFFF, 0x00000010, 0x07FFFFFF},
441 []su_int{0x7FFFFFFF, 0x078644FA, 0x00000011},
442 []su_int{0x7FFFFFFF, 0x0747AE14, 0x00000011},
443 []su_int{0x7FFFFFFF, 0x7FFFFFFF, 0x00000001},
444 []su_int{0x7FFFFFFF, 0x80000000, 0x00000000},
445 []su_int{0x7FFFFFFF, 0xFFFFFFFD, 0x00000000},
446 []su_int{0x7FFFFFFF, 0xFFFFFFFE, 0x00000000},
447 []su_int{0x7FFFFFFF, 0xFFFFFFFF, 0x00000000},
448 []su_int{0x80000000, 0x00000001, 0x80000000},
449 []su_int{0x80000000, 0x00000002, 0x40000000},
450 []su_int{0x80000000, 0x00000003, 0x2AAAAAAA},
451 []su_int{0x80000000, 0x00000010, 0x08000000},
452 []su_int{0x80000000, 0x078644FA, 0x00000011},
453 []su_int{0x80000000, 0x0747AE14, 0x00000011},
454 []su_int{0x80000000, 0x7FFFFFFF, 0x00000001},
455 []su_int{0x80000000, 0x80000000, 0x00000001},
456 []su_int{0x80000000, 0xFFFFFFFD, 0x00000000},
457 []su_int{0x80000000, 0xFFFFFFFE, 0x00000000},
458 []su_int{0x80000000, 0xFFFFFFFF, 0x00000000},
459 []su_int{0xFFFFFFFD, 0x00000001, 0xFFFFFFFD},
460 []su_int{0xFFFFFFFD, 0x00000002, 0x7FFFFFFE},
461 []su_int{0xFFFFFFFD, 0x00000003, 0x55555554},
462 []su_int{0xFFFFFFFD, 0x00000010, 0x0FFFFFFF},
463 []su_int{0xFFFFFFFD, 0x078644FA, 0x00000022},
464 []su_int{0xFFFFFFFD, 0x0747AE14, 0x00000023},
465 []su_int{0xFFFFFFFD, 0x7FFFFFFF, 0x00000001},
466 []su_int{0xFFFFFFFD, 0x80000000, 0x00000001},
467 []su_int{0xFFFFFFFD, 0xFFFFFFFD, 0x00000001},
468 []su_int{0xFFFFFFFD, 0xFFFFFFFE, 0x00000000},
469 []su_int{0xFFFFFFFD, 0xFFFFFFFF, 0x00000000},
470 []su_int{0xFFFFFFFE, 0x00000001, 0xFFFFFFFE},
471 []su_int{0xFFFFFFFE, 0x00000002, 0x7FFFFFFF},
472 []su_int{0xFFFFFFFE, 0x00000003, 0x55555554},
473 []su_int{0xFFFFFFFE, 0x00000010, 0x0FFFFFFF},
474 []su_int{0xFFFFFFFE, 0x078644FA, 0x00000022},
475 []su_int{0xFFFFFFFE, 0x0747AE14, 0x00000023},
476 []su_int{0xFFFFFFFE, 0x7FFFFFFF, 0x00000002},
477 []su_int{0xFFFFFFFE, 0x80000000, 0x00000001},
478 []su_int{0xFFFFFFFE, 0xFFFFFFFD, 0x00000001},
479 []su_int{0xFFFFFFFE, 0xFFFFFFFE, 0x00000001},
480 []su_int{0xFFFFFFFE, 0xFFFFFFFF, 0x00000000},
481 []su_int{0xFFFFFFFF, 0x00000001, 0xFFFFFFFF},
482 []su_int{0xFFFFFFFF, 0x00000002, 0x7FFFFFFF},
483 []su_int{0xFFFFFFFF, 0x00000003, 0x55555555},
484 []su_int{0xFFFFFFFF, 0x00000010, 0x0FFFFFFF},
485 []su_int{0xFFFFFFFF, 0x078644FA, 0x00000022},
486 []su_int{0xFFFFFFFF, 0x0747AE14, 0x00000023},
487 []su_int{0xFFFFFFFF, 0x7FFFFFFF, 0x00000002},
488 []su_int{0xFFFFFFFF, 0x80000000, 0x00000001},
489 []su_int{0xFFFFFFFF, 0xFFFFFFFD, 0x00000001},
490 []su_int{0xFFFFFFFF, 0xFFFFFFFE, 0x00000001},
491 []su_int{0xFFFFFFFF, 0xFFFFFFFF, 0x00000001},
492 };
493
494 for (cases) |case| {
495 test_one_udivsi3(case[0], case[1], case[2]);
496 }
497}
498
499fn test_one_udivsi3(a: su_int, b: su_int, expected_q: su_int) {
500 const q: su_int = __udivsi3(a, b);
501 assert(q == expected_q);
502}
503
504
505fn assert(ok: bool) {
506 if (!ok) unreachable;
507}