authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-15 18:39:50-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2020-01-15 18:39:50-05:00
log8a792db2d8b0ea775cb255c31c207c513a45ff01
tree715943b6a0bae51670176ab0a25826cc7ee1cf08
parent0ea96c11ef5eca9cfd19233b6d51b00ba33da716
parente8012740b90f9acf286d852755d358eb4c708ab5
signature Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #4187 from LemonBoy/builtin-rearrange

Some needed work on builtins

7 files changed, 743 insertions(+), 1402 deletions(-)

lib/std/os/linux/arm-eabi.zig-9
......@@ -88,15 +88,6 @@ pub fn syscall6(
8888/// This matches the libc clone function.
8989pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
9090
91// LLVM calls this when the read-tp-hard feature is set to false. Currently, there is no way to pass
92// that to llvm via zig, see https://github.com/ziglang/zig/issues/2883.
93// LLVM expects libc to provide this function as __aeabi_read_tp, so it is exported if needed from special/c.zig.
94pub fn getThreadPointer() callconv(.C) usize {
95 return asm volatile ("mrc p15, 0, %[ret], c13, c0, 3"
96 : [ret] "=r" (-> usize)
97 );
98}
99
10091pub fn restore() callconv(.Naked) void {
10192 return asm volatile ("svc #0"
10293 :
lib/std/special/c.zig-2
......@@ -32,8 +32,6 @@ comptime {
3232 @export(strlen, .{ .name = "strlen", .linkage = .Strong });
3333 } else if (is_msvc) {
3434 @export(_fltused, .{ .name = "_fltused", .linkage = .Strong });
35 } else if (builtin.arch == builtin.Arch.arm and builtin.os == .linux) {
36 @export(std.os.linux.getThreadPointer, .{ .name = "__aeabi_read_tp", .linkage = .Strong });
3735 }
3836}
3937
lib/std/special/compiler_rt.zig+34-1379
......@@ -127,59 +127,57 @@ comptime {
127127 @export(@import("compiler_rt/fixtfsi.zig").__fixtfsi, .{ .name = "__fixtfsi", .linkage = linkage });
128128 @export(@import("compiler_rt/fixtfti.zig").__fixtfti, .{ .name = "__fixtfti", .linkage = linkage });
129129
130 @export(@import("compiler_rt/udivmoddi4.zig").__udivmoddi4, .{ .name = "__udivmoddi4", .linkage = linkage });
130 @export(@import("compiler_rt/int.zig").__udivmoddi4, .{ .name = "__udivmoddi4", .linkage = linkage });
131131 @export(@import("compiler_rt/popcountdi2.zig").__popcountdi2, .{ .name = "__popcountdi2", .linkage = linkage });
132132
133133 @export(@import("compiler_rt/muldi3.zig").__muldi3, .{ .name = "__muldi3", .linkage = linkage });
134 @export(__divmoddi4, .{ .name = "__divmoddi4", .linkage = linkage });
135 @export(__divsi3, .{ .name = "__divsi3", .linkage = linkage });
136 @export(__divdi3, .{ .name = "__divdi3", .linkage = linkage });
137 @export(__udivsi3, .{ .name = "__udivsi3", .linkage = linkage });
138 @export(__udivdi3, .{ .name = "__udivdi3", .linkage = linkage });
139 @export(__modsi3, .{ .name = "__modsi3", .linkage = linkage });
140 @export(__moddi3, .{ .name = "__moddi3", .linkage = linkage });
141 @export(__umodsi3, .{ .name = "__umodsi3", .linkage = linkage });
142 @export(__umoddi3, .{ .name = "__umoddi3", .linkage = linkage });
143 @export(__divmodsi4, .{ .name = "__divmodsi4", .linkage = linkage });
144 @export(__udivmodsi4, .{ .name = "__udivmodsi4", .linkage = linkage });
134 @export(@import("compiler_rt/int.zig").__divmoddi4, .{ .name = "__divmoddi4", .linkage = linkage });
135 @export(@import("compiler_rt/int.zig").__divsi3, .{ .name = "__divsi3", .linkage = linkage });
136 @export(@import("compiler_rt/int.zig").__divdi3, .{ .name = "__divdi3", .linkage = linkage });
137 @export(@import("compiler_rt/int.zig").__udivsi3, .{ .name = "__udivsi3", .linkage = linkage });
138 @export(@import("compiler_rt/int.zig").__udivdi3, .{ .name = "__udivdi3", .linkage = linkage });
139 @export(@import("compiler_rt/int.zig").__modsi3, .{ .name = "__modsi3", .linkage = linkage });
140 @export(@import("compiler_rt/int.zig").__moddi3, .{ .name = "__moddi3", .linkage = linkage });
141 @export(@import("compiler_rt/int.zig").__umodsi3, .{ .name = "__umodsi3", .linkage = linkage });
142 @export(@import("compiler_rt/int.zig").__umoddi3, .{ .name = "__umoddi3", .linkage = linkage });
143 @export(@import("compiler_rt/int.zig").__divmodsi4, .{ .name = "__divmodsi4", .linkage = linkage });
144 @export(@import("compiler_rt/int.zig").__udivmodsi4, .{ .name = "__udivmodsi4", .linkage = linkage });
145145
146146 @export(@import("compiler_rt/negXf2.zig").__negsf2, .{ .name = "__negsf2", .linkage = linkage });
147147 @export(@import("compiler_rt/negXf2.zig").__negdf2, .{ .name = "__negdf2", .linkage = linkage });
148148
149149 if (is_arm_arch and !is_arm_64 and !is_test) {
150 @export(__aeabi_unwind_cpp_pr0, .{ .name = "__aeabi_unwind_cpp_pr0", .linkage = strong_linkage });
151 @export(__aeabi_unwind_cpp_pr1, .{ .name = "__aeabi_unwind_cpp_pr1", .linkage = linkage });
152 @export(__aeabi_unwind_cpp_pr2, .{ .name = "__aeabi_unwind_cpp_pr2", .linkage = linkage });
150 @export(@import("compiler_rt/arm.zig").__aeabi_unwind_cpp_pr0, .{ .name = "__aeabi_unwind_cpp_pr0", .linkage = strong_linkage });
151 @export(@import("compiler_rt/arm.zig").__aeabi_unwind_cpp_pr1, .{ .name = "__aeabi_unwind_cpp_pr1", .linkage = linkage });
152 @export(@import("compiler_rt/arm.zig").__aeabi_unwind_cpp_pr2, .{ .name = "__aeabi_unwind_cpp_pr2", .linkage = linkage });
153153
154154 @export(@import("compiler_rt/muldi3.zig").__muldi3, .{ .name = "__aeabi_lmul", .linkage = linkage });
155155
156 @export(__aeabi_ldivmod, .{ .name = "__aeabi_ldivmod", .linkage = linkage });
157 @export(__aeabi_uldivmod, .{ .name = "__aeabi_uldivmod", .linkage = linkage });
156 @export(@import("compiler_rt/arm.zig").__aeabi_ldivmod, .{ .name = "__aeabi_ldivmod", .linkage = linkage });
157 @export(@import("compiler_rt/arm.zig").__aeabi_uldivmod, .{ .name = "__aeabi_uldivmod", .linkage = linkage });
158158
159 @export(__divsi3, .{ .name = "__aeabi_idiv", .linkage = linkage });
160 @export(__aeabi_idivmod, .{ .name = "__aeabi_idivmod", .linkage = linkage });
161 @export(__udivsi3, .{ .name = "__aeabi_uidiv", .linkage = linkage });
162 @export(__aeabi_uidivmod, .{ .name = "__aeabi_uidivmod", .linkage = linkage });
159 @export(@import("compiler_rt/int.zig").__divsi3, .{ .name = "__aeabi_idiv", .linkage = linkage });
160 @export(@import("compiler_rt/arm.zig").__aeabi_idivmod, .{ .name = "__aeabi_idivmod", .linkage = linkage });
161 @export(@import("compiler_rt/int.zig").__udivsi3, .{ .name = "__aeabi_uidiv", .linkage = linkage });
162 @export(@import("compiler_rt/arm.zig").__aeabi_uidivmod, .{ .name = "__aeabi_uidivmod", .linkage = linkage });
163163
164 @export(__aeabi_memcpy, .{ .name = "__aeabi_memcpy", .linkage = linkage });
165 @export(__aeabi_memcpy, .{ .name = "__aeabi_memcpy4", .linkage = linkage });
166 @export(__aeabi_memcpy, .{ .name = "__aeabi_memcpy8", .linkage = linkage });
164 @export(@import("compiler_rt/arm.zig").__aeabi_memcpy, .{ .name = "__aeabi_memcpy", .linkage = linkage });
165 @export(@import("compiler_rt/arm.zig").__aeabi_memcpy, .{ .name = "__aeabi_memcpy4", .linkage = linkage });
166 @export(@import("compiler_rt/arm.zig").__aeabi_memcpy, .{ .name = "__aeabi_memcpy8", .linkage = linkage });
167167
168 @export(__aeabi_memmove, .{ .name = "__aeabi_memmove", .linkage = linkage });
169 @export(__aeabi_memmove, .{ .name = "__aeabi_memmove4", .linkage = linkage });
170 @export(__aeabi_memmove, .{ .name = "__aeabi_memmove8", .linkage = linkage });
168 @export(@import("compiler_rt/arm.zig").__aeabi_memmove, .{ .name = "__aeabi_memmove", .linkage = linkage });
169 @export(@import("compiler_rt/arm.zig").__aeabi_memmove, .{ .name = "__aeabi_memmove4", .linkage = linkage });
170 @export(@import("compiler_rt/arm.zig").__aeabi_memmove, .{ .name = "__aeabi_memmove8", .linkage = linkage });
171171
172 @export(__aeabi_memset, .{ .name = "__aeabi_memset", .linkage = linkage });
173 @export(__aeabi_memset, .{ .name = "__aeabi_memset4", .linkage = linkage });
174 @export(__aeabi_memset, .{ .name = "__aeabi_memset8", .linkage = linkage });
172 @export(@import("compiler_rt/arm.zig").__aeabi_memset, .{ .name = "__aeabi_memset", .linkage = linkage });
173 @export(@import("compiler_rt/arm.zig").__aeabi_memset, .{ .name = "__aeabi_memset4", .linkage = linkage });
174 @export(@import("compiler_rt/arm.zig").__aeabi_memset, .{ .name = "__aeabi_memset8", .linkage = linkage });
175175
176 @export(__aeabi_memclr, .{ .name = "__aeabi_memclr", .linkage = linkage });
177 @export(__aeabi_memclr, .{ .name = "__aeabi_memclr4", .linkage = linkage });
178 @export(__aeabi_memclr, .{ .name = "__aeabi_memclr8", .linkage = linkage });
176 @export(@import("compiler_rt/arm.zig").__aeabi_memclr, .{ .name = "__aeabi_memclr", .linkage = linkage });
177 @export(@import("compiler_rt/arm.zig").__aeabi_memclr, .{ .name = "__aeabi_memclr4", .linkage = linkage });
178 @export(@import("compiler_rt/arm.zig").__aeabi_memclr, .{ .name = "__aeabi_memclr8", .linkage = linkage });
179179
180 @export(__aeabi_memcmp, .{ .name = "__aeabi_memcmp", .linkage = linkage });
181 @export(__aeabi_memcmp, .{ .name = "__aeabi_memcmp4", .linkage = linkage });
182 @export(__aeabi_memcmp, .{ .name = "__aeabi_memcmp8", .linkage = linkage });
180 @export(@import("compiler_rt/arm.zig").__aeabi_read_tp, .{ .name = "__aeabi_read_tp", .linkage = linkage });
183181
184182 @export(@import("compiler_rt/extendXfYf2.zig").__aeabi_f2d, .{ .name = "__aeabi_f2d", .linkage = linkage });
185183 @export(@import("compiler_rt/floatsiXf.zig").__aeabi_i2d, .{ .name = "__aeabi_i2d", .linkage = linkage });
......@@ -301,8 +299,6 @@ const std = @import("std");
301299const assert = std.debug.assert;
302300const testing = std.testing;
303301
304const __udivmoddi4 = @import("compiler_rt/udivmoddi4.zig").__udivmoddi4;
305
306302// Avoid dragging in the runtime safety mechanisms into this .o file,
307303// unless we're trying to test this file.
308304pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn {
......@@ -325,108 +321,6 @@ extern var __stack_chk_guard: usize = blk: {
325321 break :blk @bitCast(usize, buf);
326322};
327323
328fn __aeabi_unwind_cpp_pr0() callconv(.C) void {
329 unreachable;
330}
331fn __aeabi_unwind_cpp_pr1() callconv(.C) void {
332 unreachable;
333}
334fn __aeabi_unwind_cpp_pr2() callconv(.C) void {
335 unreachable;
336}
337
338fn __divmoddi4(a: i64, b: i64, rem: *i64) callconv(.C) i64 {
339 @setRuntimeSafety(is_test);
340
341 const d = __divdi3(a, b);
342 rem.* = a -% (d *% b);
343 return d;
344}
345
346fn __divdi3(a: i64, b: i64) callconv(.C) i64 {
347 @setRuntimeSafety(is_test);
348
349 // Set aside the sign of the quotient.
350 const sign = @bitCast(u64, (a ^ b) >> 63);
351 // Take absolute value of a and b via abs(x) = (x^(x >> 63)) - (x >> 63).
352 const abs_a = (a ^ (a >> 63)) -% (a >> 63);
353 const abs_b = (b ^ (b >> 63)) -% (b >> 63);
354 // Unsigned division
355 const res = __udivmoddi4(@bitCast(u64, abs_a), @bitCast(u64, abs_b), null);
356 // Apply sign of quotient to result and return.
357 return @bitCast(i64, (res ^ sign) -% sign);
358}
359
360fn __moddi3(a: i64, b: i64) callconv(.C) i64 {
361 @setRuntimeSafety(is_test);
362
363 // Take absolute value of a and b via abs(x) = (x^(x >> 63)) - (x >> 63).
364 const abs_a = (a ^ (a >> 63)) -% (a >> 63);
365 const abs_b = (b ^ (b >> 63)) -% (b >> 63);
366 // Unsigned division
367 var r: u64 = undefined;
368 _ = __udivmoddi4(@bitCast(u64, abs_a), @bitCast(u64, abs_b), &r);
369 // Apply the sign of the dividend and return.
370 return (@bitCast(i64, r) ^ (a >> 63)) -% (a >> 63);
371}
372
373fn __udivdi3(a: u64, b: u64) callconv(.C) u64 {
374 @setRuntimeSafety(is_test);
375 return __udivmoddi4(a, b, null);
376}
377
378fn __umoddi3(a: u64, b: u64) callconv(.C) u64 {
379 @setRuntimeSafety(is_test);
380
381 var r: u64 = undefined;
382 _ = __udivmoddi4(a, b, &r);
383 return r;
384}
385
386fn __aeabi_uidivmod(n: u32, d: u32) callconv(.C) extern struct {
387 q: u32,
388 r: u32,
389} {
390 @setRuntimeSafety(is_test);
391
392 var result: @TypeOf(__aeabi_uidivmod).ReturnType = undefined;
393 result.q = __udivmodsi4(n, d, &result.r);
394 return result;
395}
396
397fn __aeabi_uldivmod(n: u64, d: u64) callconv(.C) extern struct {
398 q: u64,
399 r: u64,
400} {
401 @setRuntimeSafety(is_test);
402
403 var result: @TypeOf(__aeabi_uldivmod).ReturnType = undefined;
404 result.q = __udivmoddi4(n, d, &result.r);
405 return result;
406}
407
408fn __aeabi_idivmod(n: i32, d: i32) callconv(.C) extern struct {
409 q: i32,
410 r: i32,
411} {
412 @setRuntimeSafety(is_test);
413
414 var result: @TypeOf(__aeabi_idivmod).ReturnType = undefined;
415 result.q = __divmodsi4(n, d, &result.r);
416 return result;
417}
418
419fn __aeabi_ldivmod(n: i64, d: i64) callconv(.C) extern struct {
420 q: i64,
421 r: i64,
422} {
423 @setRuntimeSafety(is_test);
424
425 var result: @TypeOf(__aeabi_ldivmod).ReturnType = undefined;
426 result.q = __divmoddi4(n, d, &result.r);
427 return result;
428}
429
430324const is_arm_64 = switch (builtin.arch) {
431325 builtin.Arch.aarch64,
432326 builtin.Arch.aarch64_be,
......@@ -446,1242 +340,3 @@ const is_arm_arch = switch (builtin.arch) {
446340};
447341
448342const is_arm_32 = is_arm_arch and !is_arm_64;
449
450const use_thumb_1 = usesThumb1(builtin.arch);
451
452fn usesThumb1(arch: builtin.Arch) bool {
453 return switch (arch) {
454 .arm => |sub_arch| switch (sub_arch) {
455 .v6m => true,
456 else => false,
457 },
458 .armeb => |sub_arch| switch (sub_arch) {
459 .v6m => true,
460 else => false,
461 },
462 .thumb => |sub_arch| switch (sub_arch) {
463 .v5,
464 .v5te,
465 .v4t,
466 .v6,
467 .v6m,
468 .v6k,
469 => true,
470 else => false,
471 },
472 .thumbeb => |sub_arch| switch (sub_arch) {
473 .v5,
474 .v5te,
475 .v4t,
476 .v6,
477 .v6m,
478 .v6k,
479 => true,
480 else => false,
481 },
482 else => false,
483 };
484}
485
486test "usesThumb1" {
487 testing.expect(usesThumb1(builtin.Arch{ .arm = .v6m }));
488 testing.expect(!usesThumb1(builtin.Arch{ .arm = .v5 }));
489 //etc.
490
491 testing.expect(usesThumb1(builtin.Arch{ .armeb = .v6m }));
492 testing.expect(!usesThumb1(builtin.Arch{ .armeb = .v5 }));
493 //etc.
494
495 testing.expect(usesThumb1(builtin.Arch{ .thumb = .v5 }));
496 testing.expect(usesThumb1(builtin.Arch{ .thumb = .v5te }));
497 testing.expect(usesThumb1(builtin.Arch{ .thumb = .v4t }));
498 testing.expect(usesThumb1(builtin.Arch{ .thumb = .v6 }));
499 testing.expect(usesThumb1(builtin.Arch{ .thumb = .v6k }));
500 testing.expect(usesThumb1(builtin.Arch{ .thumb = .v6m }));
501 testing.expect(!usesThumb1(builtin.Arch{ .thumb = .v6t2 }));
502 //etc.
503
504 testing.expect(usesThumb1(builtin.Arch{ .thumbeb = .v5 }));
505 testing.expect(usesThumb1(builtin.Arch{ .thumbeb = .v5te }));
506 testing.expect(usesThumb1(builtin.Arch{ .thumbeb = .v4t }));
507 testing.expect(usesThumb1(builtin.Arch{ .thumbeb = .v6 }));
508 testing.expect(usesThumb1(builtin.Arch{ .thumbeb = .v6k }));
509 testing.expect(usesThumb1(builtin.Arch{ .thumbeb = .v6m }));
510 testing.expect(!usesThumb1(builtin.Arch{ .thumbeb = .v6t2 }));
511 //etc.
512
513 testing.expect(!usesThumb1(builtin.Arch{ .aarch64 = .v8 }));
514 testing.expect(!usesThumb1(builtin.Arch{ .aarch64_be = .v8 }));
515 testing.expect(!usesThumb1(builtin.Arch.x86_64));
516 testing.expect(!usesThumb1(builtin.Arch.riscv32));
517 //etc.
518}
519
520const use_thumb_1_pre_armv6 = usesThumb1PreArmv6(builtin.arch);
521
522fn usesThumb1PreArmv6(arch: builtin.Arch) bool {
523 return switch (arch) {
524 .thumb => |sub_arch| switch (sub_arch) {
525 .v5, .v5te, .v4t => true,
526 else => false,
527 },
528 .thumbeb => |sub_arch| switch (sub_arch) {
529 .v5, .v5te, .v4t => true,
530 else => false,
531 },
532 else => false,
533 };
534}
535
536fn __aeabi_memcpy() callconv(.Naked) noreturn {
537 @setRuntimeSafety(false);
538 if (use_thumb_1) {
539 asm volatile (
540 \\ push {r7, lr}
541 \\ bl memcpy
542 \\ pop {r7, pc}
543 );
544 } else {
545 asm volatile (
546 \\ b memcpy
547 );
548 }
549 unreachable;
550}
551
552fn __aeabi_memmove() callconv(.Naked) noreturn {
553 @setRuntimeSafety(false);
554 if (use_thumb_1) {
555 asm volatile (
556 \\ push {r7, lr}
557 \\ bl memmove
558 \\ pop {r7, pc}
559 );
560 } else {
561 asm volatile (
562 \\ b memmove
563 );
564 }
565 unreachable;
566}
567
568fn __aeabi_memset() callconv(.Naked) noreturn {
569 @setRuntimeSafety(false);
570 if (use_thumb_1_pre_armv6) {
571 asm volatile (
572 \\ eors r1, r2
573 \\ eors r2, r1
574 \\ eors r1, r2
575 \\ push {r7, lr}
576 \\ b memset
577 \\ pop {r7, pc}
578 );
579 } else if (use_thumb_1) {
580 asm volatile (
581 \\ mov r3, r1
582 \\ mov r1, r2
583 \\ mov r2, r3
584 \\ push {r7, lr}
585 \\ b memset
586 \\ pop {r7, pc}
587 );
588 } else {
589 asm volatile (
590 \\ mov r3, r1
591 \\ mov r1, r2
592 \\ mov r2, r3
593 \\ b memset
594 );
595 }
596 unreachable;
597}
598
599fn __aeabi_memclr() callconv(.Naked) noreturn {
600 @setRuntimeSafety(false);
601 if (use_thumb_1_pre_armv6) {
602 asm volatile (
603 \\ adds r2, r1, #0
604 \\ movs r1, #0
605 \\ push {r7, lr}
606 \\ bl memset
607 \\ pop {r7, pc}
608 );
609 } else if (use_thumb_1) {
610 asm volatile (
611 \\ mov r2, r1
612 \\ movs r1, #0
613 \\ push {r7, lr}
614 \\ bl memset
615 \\ pop {r7, pc}
616 );
617 } else {
618 asm volatile (
619 \\ mov r2, r1
620 \\ movs r1, #0
621 \\ b memset
622 );
623 }
624 unreachable;
625}
626
627fn __aeabi_memcmp() callconv(.Naked) noreturn {
628 @setRuntimeSafety(false);
629 if (use_thumb_1) {
630 asm volatile (
631 \\ push {r7, lr}
632 \\ bl memcmp
633 \\ pop {r7, pc}
634 );
635 } else {
636 asm volatile (
637 \\ b memcmp
638 );
639 }
640 unreachable;
641}
642
643fn __divmodsi4(a: i32, b: i32, rem: *i32) callconv(.C) i32 {
644 @setRuntimeSafety(is_test);
645
646 const d = __divsi3(a, b);
647 rem.* = a -% (d * b);
648 return d;
649}
650
651fn __udivmodsi4(a: u32, b: u32, rem: *u32) callconv(.C) u32 {
652 @setRuntimeSafety(is_test);
653
654 const d = __udivsi3(a, b);
655 rem.* = @bitCast(u32, @bitCast(i32, a) -% (@bitCast(i32, d) * @bitCast(i32, b)));
656 return d;
657}
658
659fn __divsi3(n: i32, d: i32) callconv(.C) i32 {
660 @setRuntimeSafety(is_test);
661
662 // Set aside the sign of the quotient.
663 const sign = @bitCast(u32, (n ^ d) >> 31);
664 // Take absolute value of a and b via abs(x) = (x^(x >> 31)) - (x >> 31).
665 const abs_n = (n ^ (n >> 31)) -% (n >> 31);
666 const abs_d = (d ^ (d >> 31)) -% (d >> 31);
667 // abs(a) / abs(b)
668 const res = @bitCast(u32, abs_n) / @bitCast(u32, abs_d);
669 // Apply sign of quotient to result and return.
670 return @bitCast(i32, (res ^ sign) -% sign);
671}
672
673fn __udivsi3(n: u32, d: u32) callconv(.C) u32 {
674 @setRuntimeSafety(is_test);
675
676 const n_uword_bits: c_uint = u32.bit_count;
677 // special cases
678 if (d == 0) return 0; // ?!
679 if (n == 0) return 0;
680 var sr = @bitCast(c_uint, @as(c_int, @clz(u32, d)) - @as(c_int, @clz(u32, n)));
681 // 0 <= sr <= n_uword_bits - 1 or sr large
682 if (sr > n_uword_bits - 1) {
683 // d > r
684 return 0;
685 }
686 if (sr == n_uword_bits - 1) {
687 // d == 1
688 return n;
689 }
690 sr += 1;
691 // 1 <= sr <= n_uword_bits - 1
692 // Not a special case
693 var q: u32 = n << @intCast(u5, n_uword_bits - sr);
694 var r: u32 = n >> @intCast(u5, sr);
695 var carry: u32 = 0;
696 while (sr > 0) : (sr -= 1) {
697 // r:q = ((r:q) << 1) | carry
698 r = (r << 1) | (q >> @intCast(u5, n_uword_bits - 1));
699 q = (q << 1) | carry;
700 // carry = 0;
701 // if (r.all >= d.all)
702 // {
703 // r.all -= d.all;
704 // carry = 1;
705 // }
706 const s = @intCast(i32, d -% r -% 1) >> @intCast(u5, n_uword_bits - 1);
707 carry = @intCast(u32, s & 1);
708 r -= d & @bitCast(u32, s);
709 }
710 q = (q << 1) | carry;
711 return q;
712}
713
714fn __modsi3(n: i32, d: i32) callconv(.C) i32 {
715 @setRuntimeSafety(is_test);
716
717 return n -% __divsi3(n, d) *% d;
718}
719
720fn __umodsi3(n: u32, d: u32) callconv(.C) u32 {
721 @setRuntimeSafety(is_test);
722
723 return n -% __udivsi3(n, d) *% d;
724}
725
726test "test_umoddi3" {
727 test_one_umoddi3(0, 1, 0);
728 test_one_umoddi3(2, 1, 0);
729 test_one_umoddi3(0x8000000000000000, 1, 0x0);
730 test_one_umoddi3(0x8000000000000000, 2, 0x0);
731 test_one_umoddi3(0xFFFFFFFFFFFFFFFF, 2, 0x1);
732}
733
734fn test_one_umoddi3(a: u64, b: u64, expected_r: u64) void {
735 const r = __umoddi3(a, b);
736 testing.expect(r == expected_r);
737}
738
739test "test_udivsi3" {
740 const cases = [_][3]u32{
741 [_]u32{
742 0x00000000,
743 0x00000001,
744 0x00000000,
745 },
746 [_]u32{
747 0x00000000,
748 0x00000002,
749 0x00000000,
750 },
751 [_]u32{
752 0x00000000,
753 0x00000003,
754 0x00000000,
755 },
756 [_]u32{
757 0x00000000,
758 0x00000010,
759 0x00000000,
760 },
761 [_]u32{
762 0x00000000,
763 0x078644FA,
764 0x00000000,
765 },
766 [_]u32{
767 0x00000000,
768 0x0747AE14,
769 0x00000000,
770 },
771 [_]u32{
772 0x00000000,
773 0x7FFFFFFF,
774 0x00000000,
775 },
776 [_]u32{
777 0x00000000,
778 0x80000000,
779 0x00000000,
780 },
781 [_]u32{
782 0x00000000,
783 0xFFFFFFFD,
784 0x00000000,
785 },
786 [_]u32{
787 0x00000000,
788 0xFFFFFFFE,
789 0x00000000,
790 },
791 [_]u32{
792 0x00000000,
793 0xFFFFFFFF,
794 0x00000000,
795 },
796 [_]u32{
797 0x00000001,
798 0x00000001,
799 0x00000001,
800 },
801 [_]u32{
802 0x00000001,
803 0x00000002,
804 0x00000000,
805 },
806 [_]u32{
807 0x00000001,
808 0x00000003,
809 0x00000000,
810 },
811 [_]u32{
812 0x00000001,
813 0x00000010,
814 0x00000000,
815 },
816 [_]u32{
817 0x00000001,
818 0x078644FA,
819 0x00000000,
820 },
821 [_]u32{
822 0x00000001,
823 0x0747AE14,
824 0x00000000,
825 },
826 [_]u32{
827 0x00000001,
828 0x7FFFFFFF,
829 0x00000000,
830 },
831 [_]u32{
832 0x00000001,
833 0x80000000,
834 0x00000000,
835 },
836 [_]u32{
837 0x00000001,
838 0xFFFFFFFD,
839 0x00000000,
840 },
841 [_]u32{
842 0x00000001,
843 0xFFFFFFFE,
844 0x00000000,
845 },
846 [_]u32{
847 0x00000001,
848 0xFFFFFFFF,
849 0x00000000,
850 },
851 [_]u32{
852 0x00000002,
853 0x00000001,
854 0x00000002,
855 },
856 [_]u32{
857 0x00000002,
858 0x00000002,
859 0x00000001,
860 },
861 [_]u32{
862 0x00000002,
863 0x00000003,
864 0x00000000,
865 },
866 [_]u32{
867 0x00000002,
868 0x00000010,
869 0x00000000,
870 },
871 [_]u32{
872 0x00000002,
873 0x078644FA,
874 0x00000000,
875 },
876 [_]u32{
877 0x00000002,
878 0x0747AE14,
879 0x00000000,
880 },
881 [_]u32{
882 0x00000002,
883 0x7FFFFFFF,
884 0x00000000,
885 },
886 [_]u32{
887 0x00000002,
888 0x80000000,
889 0x00000000,
890 },
891 [_]u32{
892 0x00000002,
893 0xFFFFFFFD,
894 0x00000000,
895 },
896 [_]u32{
897 0x00000002,
898 0xFFFFFFFE,
899 0x00000000,
900 },
901 [_]u32{
902 0x00000002,
903 0xFFFFFFFF,
904 0x00000000,
905 },
906 [_]u32{
907 0x00000003,
908 0x00000001,
909 0x00000003,
910 },
911 [_]u32{
912 0x00000003,
913 0x00000002,
914 0x00000001,
915 },
916 [_]u32{
917 0x00000003,
918 0x00000003,
919 0x00000001,
920 },
921 [_]u32{
922 0x00000003,
923 0x00000010,
924 0x00000000,
925 },
926 [_]u32{
927 0x00000003,
928 0x078644FA,
929 0x00000000,
930 },
931 [_]u32{
932 0x00000003,
933 0x0747AE14,
934 0x00000000,
935 },
936 [_]u32{
937 0x00000003,
938 0x7FFFFFFF,
939 0x00000000,
940 },
941 [_]u32{
942 0x00000003,
943 0x80000000,
944 0x00000000,
945 },
946 [_]u32{
947 0x00000003,
948 0xFFFFFFFD,
949 0x00000000,
950 },
951 [_]u32{
952 0x00000003,
953 0xFFFFFFFE,
954 0x00000000,
955 },
956 [_]u32{
957 0x00000003,
958 0xFFFFFFFF,
959 0x00000000,
960 },
961 [_]u32{
962 0x00000010,
963 0x00000001,
964 0x00000010,
965 },
966 [_]u32{
967 0x00000010,
968 0x00000002,
969 0x00000008,
970 },
971 [_]u32{
972 0x00000010,
973 0x00000003,
974 0x00000005,
975 },
976 [_]u32{
977 0x00000010,
978 0x00000010,
979 0x00000001,
980 },
981 [_]u32{
982 0x00000010,
983 0x078644FA,
984 0x00000000,
985 },
986 [_]u32{
987 0x00000010,
988 0x0747AE14,
989 0x00000000,
990 },
991 [_]u32{
992 0x00000010,
993 0x7FFFFFFF,
994 0x00000000,
995 },
996 [_]u32{
997 0x00000010,
998 0x80000000,
999 0x00000000,
1000 },
1001 [_]u32{
1002 0x00000010,
1003 0xFFFFFFFD,
1004 0x00000000,
1005 },
1006 [_]u32{
1007 0x00000010,
1008 0xFFFFFFFE,
1009 0x00000000,
1010 },
1011 [_]u32{
1012 0x00000010,
1013 0xFFFFFFFF,
1014 0x00000000,
1015 },
1016 [_]u32{
1017 0x078644FA,
1018 0x00000001,
1019 0x078644FA,
1020 },
1021 [_]u32{
1022 0x078644FA,
1023 0x00000002,
1024 0x03C3227D,
1025 },
1026 [_]u32{
1027 0x078644FA,
1028 0x00000003,
1029 0x028216FE,
1030 },
1031 [_]u32{
1032 0x078644FA,
1033 0x00000010,
1034 0x0078644F,
1035 },
1036 [_]u32{
1037 0x078644FA,
1038 0x078644FA,
1039 0x00000001,
1040 },
1041 [_]u32{
1042 0x078644FA,
1043 0x0747AE14,
1044 0x00000001,
1045 },
1046 [_]u32{
1047 0x078644FA,
1048 0x7FFFFFFF,
1049 0x00000000,
1050 },
1051 [_]u32{
1052 0x078644FA,
1053 0x80000000,
1054 0x00000000,
1055 },
1056 [_]u32{
1057 0x078644FA,
1058 0xFFFFFFFD,
1059 0x00000000,
1060 },
1061 [_]u32{
1062 0x078644FA,
1063 0xFFFFFFFE,
1064 0x00000000,
1065 },
1066 [_]u32{
1067 0x078644FA,
1068 0xFFFFFFFF,
1069 0x00000000,
1070 },
1071 [_]u32{
1072 0x0747AE14,
1073 0x00000001,
1074 0x0747AE14,
1075 },
1076 [_]u32{
1077 0x0747AE14,
1078 0x00000002,
1079 0x03A3D70A,
1080 },
1081 [_]u32{
1082 0x0747AE14,
1083 0x00000003,
1084 0x026D3A06,
1085 },
1086 [_]u32{
1087 0x0747AE14,
1088 0x00000010,
1089 0x00747AE1,
1090 },
1091 [_]u32{
1092 0x0747AE14,
1093 0x078644FA,
1094 0x00000000,
1095 },
1096 [_]u32{
1097 0x0747AE14,
1098 0x0747AE14,
1099 0x00000001,
1100 },
1101 [_]u32{
1102 0x0747AE14,
1103 0x7FFFFFFF,
1104 0x00000000,
1105 },
1106 [_]u32{
1107 0x0747AE14,
1108 0x80000000,
1109 0x00000000,
1110 },
1111 [_]u32{
1112 0x0747AE14,
1113 0xFFFFFFFD,
1114 0x00000000,
1115 },
1116 [_]u32{
1117 0x0747AE14,
1118 0xFFFFFFFE,
1119 0x00000000,
1120 },
1121 [_]u32{
1122 0x0747AE14,
1123 0xFFFFFFFF,
1124 0x00000000,
1125 },
1126 [_]u32{
1127 0x7FFFFFFF,
1128 0x00000001,
1129 0x7FFFFFFF,
1130 },
1131 [_]u32{
1132 0x7FFFFFFF,
1133 0x00000002,
1134 0x3FFFFFFF,
1135 },
1136 [_]u32{
1137 0x7FFFFFFF,
1138 0x00000003,
1139 0x2AAAAAAA,
1140 },
1141 [_]u32{
1142 0x7FFFFFFF,
1143 0x00000010,
1144 0x07FFFFFF,
1145 },
1146 [_]u32{
1147 0x7FFFFFFF,
1148 0x078644FA,
1149 0x00000011,
1150 },
1151 [_]u32{
1152 0x7FFFFFFF,
1153 0x0747AE14,
1154 0x00000011,
1155 },
1156 [_]u32{
1157 0x7FFFFFFF,
1158 0x7FFFFFFF,
1159 0x00000001,
1160 },
1161 [_]u32{
1162 0x7FFFFFFF,
1163 0x80000000,
1164 0x00000000,
1165 },
1166 [_]u32{
1167 0x7FFFFFFF,
1168 0xFFFFFFFD,
1169 0x00000000,
1170 },
1171 [_]u32{
1172 0x7FFFFFFF,
1173 0xFFFFFFFE,
1174 0x00000000,
1175 },
1176 [_]u32{
1177 0x7FFFFFFF,
1178 0xFFFFFFFF,
1179 0x00000000,
1180 },
1181 [_]u32{
1182 0x80000000,
1183 0x00000001,
1184 0x80000000,
1185 },
1186 [_]u32{
1187 0x80000000,
1188 0x00000002,
1189 0x40000000,
1190 },
1191 [_]u32{
1192 0x80000000,
1193 0x00000003,
1194 0x2AAAAAAA,
1195 },
1196 [_]u32{
1197 0x80000000,
1198 0x00000010,
1199 0x08000000,
1200 },
1201 [_]u32{
1202 0x80000000,
1203 0x078644FA,
1204 0x00000011,
1205 },
1206 [_]u32{
1207 0x80000000,
1208 0x0747AE14,
1209 0x00000011,
1210 },
1211 [_]u32{
1212 0x80000000,
1213 0x7FFFFFFF,
1214 0x00000001,
1215 },
1216 [_]u32{
1217 0x80000000,
1218 0x80000000,
1219 0x00000001,
1220 },
1221 [_]u32{
1222 0x80000000,
1223 0xFFFFFFFD,
1224 0x00000000,
1225 },
1226 [_]u32{
1227 0x80000000,
1228 0xFFFFFFFE,
1229 0x00000000,
1230 },
1231 [_]u32{
1232 0x80000000,
1233 0xFFFFFFFF,
1234 0x00000000,
1235 },
1236 [_]u32{
1237 0xFFFFFFFD,
1238 0x00000001,
1239 0xFFFFFFFD,
1240 },
1241 [_]u32{
1242 0xFFFFFFFD,
1243 0x00000002,
1244 0x7FFFFFFE,
1245 },
1246 [_]u32{
1247 0xFFFFFFFD,
1248 0x00000003,
1249 0x55555554,
1250 },
1251 [_]u32{
1252 0xFFFFFFFD,
1253 0x00000010,
1254 0x0FFFFFFF,
1255 },
1256 [_]u32{
1257 0xFFFFFFFD,
1258 0x078644FA,
1259 0x00000022,
1260 },
1261 [_]u32{
1262 0xFFFFFFFD,
1263 0x0747AE14,
1264 0x00000023,
1265 },
1266 [_]u32{
1267 0xFFFFFFFD,
1268 0x7FFFFFFF,
1269 0x00000001,
1270 },
1271 [_]u32{
1272 0xFFFFFFFD,
1273 0x80000000,
1274 0x00000001,
1275 },
1276 [_]u32{
1277 0xFFFFFFFD,
1278 0xFFFFFFFD,
1279 0x00000001,
1280 },
1281 [_]u32{
1282 0xFFFFFFFD,
1283 0xFFFFFFFE,
1284 0x00000000,
1285 },
1286 [_]u32{
1287 0xFFFFFFFD,
1288 0xFFFFFFFF,
1289 0x00000000,
1290 },
1291 [_]u32{
1292 0xFFFFFFFE,
1293 0x00000001,
1294 0xFFFFFFFE,
1295 },
1296 [_]u32{
1297 0xFFFFFFFE,
1298 0x00000002,
1299 0x7FFFFFFF,
1300 },
1301 [_]u32{
1302 0xFFFFFFFE,
1303 0x00000003,
1304 0x55555554,
1305 },
1306 [_]u32{
1307 0xFFFFFFFE,
1308 0x00000010,
1309 0x0FFFFFFF,
1310 },
1311 [_]u32{
1312 0xFFFFFFFE,
1313 0x078644FA,
1314 0x00000022,
1315 },
1316 [_]u32{
1317 0xFFFFFFFE,
1318 0x0747AE14,
1319 0x00000023,
1320 },
1321 [_]u32{
1322 0xFFFFFFFE,
1323 0x7FFFFFFF,
1324 0x00000002,
1325 },
1326 [_]u32{
1327 0xFFFFFFFE,
1328 0x80000000,
1329 0x00000001,
1330 },
1331 [_]u32{
1332 0xFFFFFFFE,
1333 0xFFFFFFFD,
1334 0x00000001,
1335 },
1336 [_]u32{
1337 0xFFFFFFFE,
1338 0xFFFFFFFE,
1339 0x00000001,
1340 },
1341 [_]u32{
1342 0xFFFFFFFE,
1343 0xFFFFFFFF,
1344 0x00000000,
1345 },
1346 [_]u32{
1347 0xFFFFFFFF,
1348 0x00000001,
1349 0xFFFFFFFF,
1350 },
1351 [_]u32{
1352 0xFFFFFFFF,
1353 0x00000002,
1354 0x7FFFFFFF,
1355 },
1356 [_]u32{
1357 0xFFFFFFFF,
1358 0x00000003,
1359 0x55555555,
1360 },
1361 [_]u32{
1362 0xFFFFFFFF,
1363 0x00000010,
1364 0x0FFFFFFF,
1365 },
1366 [_]u32{
1367 0xFFFFFFFF,
1368 0x078644FA,
1369 0x00000022,
1370 },
1371 [_]u32{
1372 0xFFFFFFFF,
1373 0x0747AE14,
1374 0x00000023,
1375 },
1376 [_]u32{
1377 0xFFFFFFFF,
1378 0x7FFFFFFF,
1379 0x00000002,
1380 },
1381 [_]u32{
1382 0xFFFFFFFF,
1383 0x80000000,
1384 0x00000001,
1385 },
1386 [_]u32{
1387 0xFFFFFFFF,
1388 0xFFFFFFFD,
1389 0x00000001,
1390 },
1391 [_]u32{
1392 0xFFFFFFFF,
1393 0xFFFFFFFE,
1394 0x00000001,
1395 },
1396 [_]u32{
1397 0xFFFFFFFF,
1398 0xFFFFFFFF,
1399 0x00000001,
1400 },
1401 };
1402
1403 for (cases) |case| {
1404 test_one_udivsi3(case[0], case[1], case[2]);
1405 }
1406}
1407
1408fn test_one_udivsi3(a: u32, b: u32, expected_q: u32) void {
1409 const q: u32 = __udivsi3(a, b);
1410 testing.expect(q == expected_q);
1411}
1412
1413test "test_divsi3" {
1414 const cases = [_][3]i32{
1415 [_]i32{ 0, 1, 0 },
1416 [_]i32{ 0, -1, 0 },
1417 [_]i32{ 2, 1, 2 },
1418 [_]i32{ 2, -1, -2 },
1419 [_]i32{ -2, 1, -2 },
1420 [_]i32{ -2, -1, 2 },
1421
1422 [_]i32{ @bitCast(i32, @as(u32, 0x80000000)), 1, @bitCast(i32, @as(u32, 0x80000000)) },
1423 [_]i32{ @bitCast(i32, @as(u32, 0x80000000)), -1, @bitCast(i32, @as(u32, 0x80000000)) },
1424 [_]i32{ @bitCast(i32, @as(u32, 0x80000000)), -2, 0x40000000 },
1425 [_]i32{ @bitCast(i32, @as(u32, 0x80000000)), 2, @bitCast(i32, @as(u32, 0xC0000000)) },
1426 };
1427
1428 for (cases) |case| {
1429 test_one_divsi3(case[0], case[1], case[2]);
1430 }
1431}
1432
1433fn test_one_divsi3(a: i32, b: i32, expected_q: i32) void {
1434 const q: i32 = __divsi3(a, b);
1435 testing.expect(q == expected_q);
1436}
1437
1438test "test_divmodsi4" {
1439 const cases = [_][4]i32{
1440 [_]i32{ 0, 1, 0, 0 },
1441 [_]i32{ 0, -1, 0, 0 },
1442 [_]i32{ 2, 1, 2, 0 },
1443 [_]i32{ 2, -1, -2, 0 },
1444 [_]i32{ -2, 1, -2, 0 },
1445 [_]i32{ -2, -1, 2, 0 },
1446 [_]i32{ 7, 5, 1, 2 },
1447 [_]i32{ -7, 5, -1, -2 },
1448 [_]i32{ 19, 5, 3, 4 },
1449 [_]i32{ 19, -5, -3, 4 },
1450
1451 [_]i32{ @bitCast(i32, @as(u32, 0x80000000)), 8, @bitCast(i32, @as(u32, 0xf0000000)), 0 },
1452 [_]i32{ @bitCast(i32, @as(u32, 0x80000007)), 8, @bitCast(i32, @as(u32, 0xf0000001)), -1 },
1453 };
1454
1455 for (cases) |case| {
1456 test_one_divmodsi4(case[0], case[1], case[2], case[3]);
1457 }
1458}
1459
1460fn test_one_divmodsi4(a: i32, b: i32, expected_q: i32, expected_r: i32) void {
1461 var r: i32 = undefined;
1462 const q: i32 = __divmodsi4(a, b, &r);
1463 testing.expect(q == expected_q and r == expected_r);
1464}
1465
1466test "test_divdi3" {
1467 const cases = [_][3]i64{
1468 [_]i64{ 0, 1, 0 },
1469 [_]i64{ 0, -1, 0 },
1470 [_]i64{ 2, 1, 2 },
1471 [_]i64{ 2, -1, -2 },
1472 [_]i64{ -2, 1, -2 },
1473 [_]i64{ -2, -1, 2 },
1474
1475 [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), 1, @bitCast(i64, @as(u64, 0x8000000000000000)) },
1476 [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), -1, @bitCast(i64, @as(u64, 0x8000000000000000)) },
1477 [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), -2, 0x4000000000000000 },
1478 [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), 2, @bitCast(i64, @as(u64, 0xC000000000000000)) },
1479 };
1480
1481 for (cases) |case| {
1482 test_one_divdi3(case[0], case[1], case[2]);
1483 }
1484}
1485
1486fn test_one_divdi3(a: i64, b: i64, expected_q: i64) void {
1487 const q: i64 = __divdi3(a, b);
1488 testing.expect(q == expected_q);
1489}
1490
1491test "test_moddi3" {
1492 const cases = [_][3]i64{
1493 [_]i64{ 0, 1, 0 },
1494 [_]i64{ 0, -1, 0 },
1495 [_]i64{ 5, 3, 2 },
1496 [_]i64{ 5, -3, 2 },
1497 [_]i64{ -5, 3, -2 },
1498 [_]i64{ -5, -3, -2 },
1499
1500 [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), 1, 0 },
1501 [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), -1, 0 },
1502 [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), 2, 0 },
1503 [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), -2, 0 },
1504 [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), 3, -2 },
1505 [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), -3, -2 },
1506 };
1507
1508 for (cases) |case| {
1509 test_one_moddi3(case[0], case[1], case[2]);
1510 }
1511}
1512
1513fn test_one_moddi3(a: i64, b: i64, expected_r: i64) void {
1514 const r: i64 = __moddi3(a, b);
1515 testing.expect(r == expected_r);
1516}
1517
1518test "test_modsi3" {
1519 const cases = [_][3]i32{
1520 [_]i32{ 0, 1, 0 },
1521 [_]i32{ 0, -1, 0 },
1522 [_]i32{ 5, 3, 2 },
1523 [_]i32{ 5, -3, 2 },
1524 [_]i32{ -5, 3, -2 },
1525 [_]i32{ -5, -3, -2 },
1526 [_]i32{ @bitCast(i32, @intCast(u32, 0x80000000)), 1, 0x0 },
1527 [_]i32{ @bitCast(i32, @intCast(u32, 0x80000000)), 2, 0x0 },
1528 [_]i32{ @bitCast(i32, @intCast(u32, 0x80000000)), -2, 0x0 },
1529 [_]i32{ @bitCast(i32, @intCast(u32, 0x80000000)), 3, -2 },
1530 [_]i32{ @bitCast(i32, @intCast(u32, 0x80000000)), -3, -2 },
1531 };
1532
1533 for (cases) |case| {
1534 test_one_modsi3(case[0], case[1], case[2]);
1535 }
1536}
1537
1538fn test_one_modsi3(a: i32, b: i32, expected_r: i32) void {
1539 const r: i32 = __modsi3(a, b);
1540 testing.expect(r == expected_r);
1541}
1542
1543test "test_umodsi3" {
1544 const cases = [_][3]u32{
1545 [_]u32{ 0x00000000, 0x00000001, 0x00000000 },
1546 [_]u32{ 0x00000000, 0x00000002, 0x00000000 },
1547 [_]u32{ 0x00000000, 0x00000003, 0x00000000 },
1548 [_]u32{ 0x00000000, 0x00000010, 0x00000000 },
1549 [_]u32{ 0x00000000, 0x078644FA, 0x00000000 },
1550 [_]u32{ 0x00000000, 0x0747AE14, 0x00000000 },
1551 [_]u32{ 0x00000000, 0x7FFFFFFF, 0x00000000 },
1552 [_]u32{ 0x00000000, 0x80000000, 0x00000000 },
1553 [_]u32{ 0x00000000, 0xFFFFFFFD, 0x00000000 },
1554 [_]u32{ 0x00000000, 0xFFFFFFFE, 0x00000000 },
1555 [_]u32{ 0x00000000, 0xFFFFFFFF, 0x00000000 },
1556 [_]u32{ 0x00000001, 0x00000001, 0x00000000 },
1557 [_]u32{ 0x00000001, 0x00000002, 0x00000001 },
1558 [_]u32{ 0x00000001, 0x00000003, 0x00000001 },
1559 [_]u32{ 0x00000001, 0x00000010, 0x00000001 },
1560 [_]u32{ 0x00000001, 0x078644FA, 0x00000001 },
1561 [_]u32{ 0x00000001, 0x0747AE14, 0x00000001 },
1562 [_]u32{ 0x00000001, 0x7FFFFFFF, 0x00000001 },
1563 [_]u32{ 0x00000001, 0x80000000, 0x00000001 },
1564 [_]u32{ 0x00000001, 0xFFFFFFFD, 0x00000001 },
1565 [_]u32{ 0x00000001, 0xFFFFFFFE, 0x00000001 },
1566 [_]u32{ 0x00000001, 0xFFFFFFFF, 0x00000001 },
1567 [_]u32{ 0x00000002, 0x00000001, 0x00000000 },
1568 [_]u32{ 0x00000002, 0x00000002, 0x00000000 },
1569 [_]u32{ 0x00000002, 0x00000003, 0x00000002 },
1570 [_]u32{ 0x00000002, 0x00000010, 0x00000002 },
1571 [_]u32{ 0x00000002, 0x078644FA, 0x00000002 },
1572 [_]u32{ 0x00000002, 0x0747AE14, 0x00000002 },
1573 [_]u32{ 0x00000002, 0x7FFFFFFF, 0x00000002 },
1574 [_]u32{ 0x00000002, 0x80000000, 0x00000002 },
1575 [_]u32{ 0x00000002, 0xFFFFFFFD, 0x00000002 },
1576 [_]u32{ 0x00000002, 0xFFFFFFFE, 0x00000002 },
1577 [_]u32{ 0x00000002, 0xFFFFFFFF, 0x00000002 },
1578 [_]u32{ 0x00000003, 0x00000001, 0x00000000 },
1579 [_]u32{ 0x00000003, 0x00000002, 0x00000001 },
1580 [_]u32{ 0x00000003, 0x00000003, 0x00000000 },
1581 [_]u32{ 0x00000003, 0x00000010, 0x00000003 },
1582 [_]u32{ 0x00000003, 0x078644FA, 0x00000003 },
1583 [_]u32{ 0x00000003, 0x0747AE14, 0x00000003 },
1584 [_]u32{ 0x00000003, 0x7FFFFFFF, 0x00000003 },
1585 [_]u32{ 0x00000003, 0x80000000, 0x00000003 },
1586 [_]u32{ 0x00000003, 0xFFFFFFFD, 0x00000003 },
1587 [_]u32{ 0x00000003, 0xFFFFFFFE, 0x00000003 },
1588 [_]u32{ 0x00000003, 0xFFFFFFFF, 0x00000003 },
1589 [_]u32{ 0x00000010, 0x00000001, 0x00000000 },
1590 [_]u32{ 0x00000010, 0x00000002, 0x00000000 },
1591 [_]u32{ 0x00000010, 0x00000003, 0x00000001 },
1592 [_]u32{ 0x00000010, 0x00000010, 0x00000000 },
1593 [_]u32{ 0x00000010, 0x078644FA, 0x00000010 },
1594 [_]u32{ 0x00000010, 0x0747AE14, 0x00000010 },
1595 [_]u32{ 0x00000010, 0x7FFFFFFF, 0x00000010 },
1596 [_]u32{ 0x00000010, 0x80000000, 0x00000010 },
1597 [_]u32{ 0x00000010, 0xFFFFFFFD, 0x00000010 },
1598 [_]u32{ 0x00000010, 0xFFFFFFFE, 0x00000010 },
1599 [_]u32{ 0x00000010, 0xFFFFFFFF, 0x00000010 },
1600 [_]u32{ 0x078644FA, 0x00000001, 0x00000000 },
1601 [_]u32{ 0x078644FA, 0x00000002, 0x00000000 },
1602 [_]u32{ 0x078644FA, 0x00000003, 0x00000000 },
1603 [_]u32{ 0x078644FA, 0x00000010, 0x0000000A },
1604 [_]u32{ 0x078644FA, 0x078644FA, 0x00000000 },
1605 [_]u32{ 0x078644FA, 0x0747AE14, 0x003E96E6 },
1606 [_]u32{ 0x078644FA, 0x7FFFFFFF, 0x078644FA },
1607 [_]u32{ 0x078644FA, 0x80000000, 0x078644FA },
1608 [_]u32{ 0x078644FA, 0xFFFFFFFD, 0x078644FA },
1609 [_]u32{ 0x078644FA, 0xFFFFFFFE, 0x078644FA },
1610 [_]u32{ 0x078644FA, 0xFFFFFFFF, 0x078644FA },
1611 [_]u32{ 0x0747AE14, 0x00000001, 0x00000000 },
1612 [_]u32{ 0x0747AE14, 0x00000002, 0x00000000 },
1613 [_]u32{ 0x0747AE14, 0x00000003, 0x00000002 },
1614 [_]u32{ 0x0747AE14, 0x00000010, 0x00000004 },
1615 [_]u32{ 0x0747AE14, 0x078644FA, 0x0747AE14 },
1616 [_]u32{ 0x0747AE14, 0x0747AE14, 0x00000000 },
1617 [_]u32{ 0x0747AE14, 0x7FFFFFFF, 0x0747AE14 },
1618 [_]u32{ 0x0747AE14, 0x80000000, 0x0747AE14 },
1619 [_]u32{ 0x0747AE14, 0xFFFFFFFD, 0x0747AE14 },
1620 [_]u32{ 0x0747AE14, 0xFFFFFFFE, 0x0747AE14 },
1621 [_]u32{ 0x0747AE14, 0xFFFFFFFF, 0x0747AE14 },
1622 [_]u32{ 0x7FFFFFFF, 0x00000001, 0x00000000 },
1623 [_]u32{ 0x7FFFFFFF, 0x00000002, 0x00000001 },
1624 [_]u32{ 0x7FFFFFFF, 0x00000003, 0x00000001 },
1625 [_]u32{ 0x7FFFFFFF, 0x00000010, 0x0000000F },
1626 [_]u32{ 0x7FFFFFFF, 0x078644FA, 0x00156B65 },
1627 [_]u32{ 0x7FFFFFFF, 0x0747AE14, 0x043D70AB },
1628 [_]u32{ 0x7FFFFFFF, 0x7FFFFFFF, 0x00000000 },
1629 [_]u32{ 0x7FFFFFFF, 0x80000000, 0x7FFFFFFF },
1630 [_]u32{ 0x7FFFFFFF, 0xFFFFFFFD, 0x7FFFFFFF },
1631 [_]u32{ 0x7FFFFFFF, 0xFFFFFFFE, 0x7FFFFFFF },
1632 [_]u32{ 0x7FFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF },
1633 [_]u32{ 0x80000000, 0x00000001, 0x00000000 },
1634 [_]u32{ 0x80000000, 0x00000002, 0x00000000 },
1635 [_]u32{ 0x80000000, 0x00000003, 0x00000002 },
1636 [_]u32{ 0x80000000, 0x00000010, 0x00000000 },
1637 [_]u32{ 0x80000000, 0x078644FA, 0x00156B66 },
1638 [_]u32{ 0x80000000, 0x0747AE14, 0x043D70AC },
1639 [_]u32{ 0x80000000, 0x7FFFFFFF, 0x00000001 },
1640 [_]u32{ 0x80000000, 0x80000000, 0x00000000 },
1641 [_]u32{ 0x80000000, 0xFFFFFFFD, 0x80000000 },
1642 [_]u32{ 0x80000000, 0xFFFFFFFE, 0x80000000 },
1643 [_]u32{ 0x80000000, 0xFFFFFFFF, 0x80000000 },
1644 [_]u32{ 0xFFFFFFFD, 0x00000001, 0x00000000 },
1645 [_]u32{ 0xFFFFFFFD, 0x00000002, 0x00000001 },
1646 [_]u32{ 0xFFFFFFFD, 0x00000003, 0x00000001 },
1647 [_]u32{ 0xFFFFFFFD, 0x00000010, 0x0000000D },
1648 [_]u32{ 0xFFFFFFFD, 0x078644FA, 0x002AD6C9 },
1649 [_]u32{ 0xFFFFFFFD, 0x0747AE14, 0x01333341 },
1650 [_]u32{ 0xFFFFFFFD, 0x7FFFFFFF, 0x7FFFFFFE },
1651 [_]u32{ 0xFFFFFFFD, 0x80000000, 0x7FFFFFFD },
1652 [_]u32{ 0xFFFFFFFD, 0xFFFFFFFD, 0x00000000 },
1653 [_]u32{ 0xFFFFFFFD, 0xFFFFFFFE, 0xFFFFFFFD },
1654 [_]u32{ 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFD },
1655 [_]u32{ 0xFFFFFFFE, 0x00000001, 0x00000000 },
1656 [_]u32{ 0xFFFFFFFE, 0x00000002, 0x00000000 },
1657 [_]u32{ 0xFFFFFFFE, 0x00000003, 0x00000002 },
1658 [_]u32{ 0xFFFFFFFE, 0x00000010, 0x0000000E },
1659 [_]u32{ 0xFFFFFFFE, 0x078644FA, 0x002AD6CA },
1660 [_]u32{ 0xFFFFFFFE, 0x0747AE14, 0x01333342 },
1661 [_]u32{ 0xFFFFFFFE, 0x7FFFFFFF, 0x00000000 },
1662 [_]u32{ 0xFFFFFFFE, 0x80000000, 0x7FFFFFFE },
1663 [_]u32{ 0xFFFFFFFE, 0xFFFFFFFD, 0x00000001 },
1664 [_]u32{ 0xFFFFFFFE, 0xFFFFFFFE, 0x00000000 },
1665 [_]u32{ 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFE },
1666 [_]u32{ 0xFFFFFFFF, 0x00000001, 0x00000000 },
1667 [_]u32{ 0xFFFFFFFF, 0x00000002, 0x00000001 },
1668 [_]u32{ 0xFFFFFFFF, 0x00000003, 0x00000000 },
1669 [_]u32{ 0xFFFFFFFF, 0x00000010, 0x0000000F },
1670 [_]u32{ 0xFFFFFFFF, 0x078644FA, 0x002AD6CB },
1671 [_]u32{ 0xFFFFFFFF, 0x0747AE14, 0x01333343 },
1672 [_]u32{ 0xFFFFFFFF, 0x7FFFFFFF, 0x00000001 },
1673 [_]u32{ 0xFFFFFFFF, 0x80000000, 0x7FFFFFFF },
1674 [_]u32{ 0xFFFFFFFF, 0xFFFFFFFD, 0x00000002 },
1675 [_]u32{ 0xFFFFFFFF, 0xFFFFFFFE, 0x00000001 },
1676 [_]u32{ 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000 },
1677 };
1678
1679 for (cases) |case| {
1680 test_one_umodsi3(case[0], case[1], case[2]);
1681 }
1682}
1683
1684fn test_one_umodsi3(a: u32, b: u32, expected_r: u32) void {
1685 const r: u32 = __umodsi3(a, b);
1686 testing.expect(r == expected_r);
1687}
lib/std/special/compiler_rt/arm.zig created+128
......@@ -0,0 +1,128 @@
1// ARM specific builtins
2const builtin = @import("builtin");
3const is_test = builtin.is_test;
4
5const __divmodsi4 = @import("int.zig").__divmodsi4;
6const __udivmodsi4 = @import("int.zig").__udivmodsi4;
7const __divmoddi4 = @import("int.zig").__divmoddi4;
8const __udivmoddi4 = @import("int.zig").__udivmoddi4;
9
10extern fn memset(dest: ?[*]u8, c: u8, n: usize) ?[*]u8;
11extern fn memcpy(noalias dest: ?[*]u8, noalias src: ?[*]const u8, n: usize) ?[*]u8;
12extern fn memmove(dest: ?[*]u8, src: ?[*]const u8, n: usize) ?[*]u8;
13
14pub fn __aeabi_memcpy(dest: [*]u8, src: [*]u8, n: usize) callconv(.AAPCS) void {
15 @setRuntimeSafety(false);
16 _ = memcpy(dest, src, n);
17}
18
19pub fn __aeabi_memmove(dest: [*]u8, src: [*]u8, n: usize) callconv(.AAPCS) void {
20 @setRuntimeSafety(false);
21 _ = memmove(dest, src, n);
22}
23
24pub fn __aeabi_memset(dest: [*]u8, n: usize, c: u8) callconv(.AAPCS) void {
25 @setRuntimeSafety(false);
26 // This is dentical to the standard `memset` definition but with the last
27 // two arguments swapped
28 _ = memset(dest, c, n);
29}
30
31pub fn __aeabi_memclr(dest: [*]u8, n: usize) callconv(.AAPCS) void {
32 @setRuntimeSafety(false);
33 _ = memset(dest, 0, n);
34}
35
36pub fn __aeabi_unwind_cpp_pr0() callconv(.C) void {
37 unreachable;
38}
39pub fn __aeabi_unwind_cpp_pr1() callconv(.C) void {
40 unreachable;
41}
42pub fn __aeabi_unwind_cpp_pr2() callconv(.C) void {
43 unreachable;
44}
45
46// This function can only clobber r0 according to the ABI
47pub fn __aeabi_read_tp() callconv(.Naked) void {
48 asm volatile (
49 \\ mrc p15, 0, r0, c13, c0, 3
50 \\ bx lr
51 );
52 unreachable;
53}
54
55// The following functions are wrapped in an asm block to ensure the required
56// calling convention is always respected
57
58pub fn __aeabi_uidivmod() callconv(.Naked) void {
59 // Divide r0 by r1; the quotient goes in r0, the remainder in r1
60 asm volatile (
61 \\ push {lr}
62 \\ sub sp, #4
63 \\ mov r2, sp
64 \\ bl __udivmodsi4
65 \\ ldr r1, [sp]
66 \\ add sp, #4
67 \\ pop {pc}
68 :
69 :
70 : "memory"
71 );
72 unreachable;
73}
74
75pub fn __aeabi_uldivmod() callconv(.Naked) void {
76 // Divide r1:r0 by r3:r2; the quotient goes in r1:r0, the remainder in r3:r2
77 asm volatile (
78 \\ push {r4, lr}
79 \\ sub sp, #16
80 \\ add r4, sp, #8
81 \\ str r4, [sp]
82 \\ bl __udivmoddi4
83 \\ ldr r2, [sp, #8]
84 \\ ldr r3, [sp, #12]
85 \\ add sp, #16
86 \\ pop {r4, pc}
87 :
88 :
89 : "memory"
90 );
91 unreachable;
92}
93
94pub fn __aeabi_idivmod() callconv(.Naked) void {
95 // Divide r0 by r1; the quotient goes in r0, the remainder in r1
96 asm volatile (
97 \\ push {lr}
98 \\ sub sp, #4
99 \\ mov r2, sp
100 \\ bl __divmodsi4
101 \\ ldr r1, [sp]
102 \\ add sp, #4
103 \\ pop {pc}
104 :
105 :
106 : "memory"
107 );
108 unreachable;
109}
110
111pub fn __aeabi_ldivmod() callconv(.Naked) void {
112 // Divide r1:r0 by r3:r2; the quotient goes in r1:r0, the remainder in r3:r2
113 asm volatile (
114 \\ push {r4, lr}
115 \\ sub sp, #16
116 \\ add r4, sp, #8
117 \\ str r4, [sp]
118 \\ bl __divmoddi4
119 \\ ldr r2, [sp, #8]
120 \\ ldr r3, [sp, #12]
121 \\ add sp, #16
122 \\ pop {r4, pc}
123 :
124 :
125 : "memory"
126 );
127 unreachable;
128}
lib/std/special/compiler_rt/int.zig created+580
......@@ -0,0 +1,580 @@
1// Builtin functions that operate on integer types
2const builtin = @import("builtin");
3const testing = @import("std").testing;
4
5const udivmod = @import("udivmod.zig").udivmod;
6
7pub fn __divmoddi4(a: i64, b: i64, rem: *i64) callconv(.C) i64 {
8 @setRuntimeSafety(builtin.is_test);
9
10 const d = __divdi3(a, b);
11 rem.* = a -% (d *% b);
12 return d;
13}
14
15pub fn __udivmoddi4(a: u64, b: u64, maybe_rem: ?*u64) callconv(.C) u64 {
16 @setRuntimeSafety(builtin.is_test);
17 return udivmod(u64, a, b, maybe_rem);
18}
19
20test "test_udivmoddi4" {
21 _ = @import("udivmoddi4_test.zig");
22}
23
24pub fn __divdi3(a: i64, b: i64) callconv(.C) i64 {
25 @setRuntimeSafety(builtin.is_test);
26
27 // Set aside the sign of the quotient.
28 const sign = @bitCast(u64, (a ^ b) >> 63);
29 // Take absolute value of a and b via abs(x) = (x^(x >> 63)) - (x >> 63).
30 const abs_a = (a ^ (a >> 63)) -% (a >> 63);
31 const abs_b = (b ^ (b >> 63)) -% (b >> 63);
32 // Unsigned division
33 const res = __udivmoddi4(@bitCast(u64, abs_a), @bitCast(u64, abs_b), null);
34 // Apply sign of quotient to result and return.
35 return @bitCast(i64, (res ^ sign) -% sign);
36}
37
38test "test_divdi3" {
39 const cases = [_][3]i64{
40 [_]i64{ 0, 1, 0 },
41 [_]i64{ 0, -1, 0 },
42 [_]i64{ 2, 1, 2 },
43 [_]i64{ 2, -1, -2 },
44 [_]i64{ -2, 1, -2 },
45 [_]i64{ -2, -1, 2 },
46
47 [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), 1, @bitCast(i64, @as(u64, 0x8000000000000000)) },
48 [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), -1, @bitCast(i64, @as(u64, 0x8000000000000000)) },
49 [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), -2, 0x4000000000000000 },
50 [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), 2, @bitCast(i64, @as(u64, 0xC000000000000000)) },
51 };
52
53 for (cases) |case| {
54 test_one_divdi3(case[0], case[1], case[2]);
55 }
56}
57
58fn test_one_divdi3(a: i64, b: i64, expected_q: i64) void {
59 const q: i64 = __divdi3(a, b);
60 testing.expect(q == expected_q);
61}
62
63pub fn __moddi3(a: i64, b: i64) callconv(.C) i64 {
64 @setRuntimeSafety(builtin.is_test);
65
66 // Take absolute value of a and b via abs(x) = (x^(x >> 63)) - (x >> 63).
67 const abs_a = (a ^ (a >> 63)) -% (a >> 63);
68 const abs_b = (b ^ (b >> 63)) -% (b >> 63);
69 // Unsigned division
70 var r: u64 = undefined;
71 _ = __udivmoddi4(@bitCast(u64, abs_a), @bitCast(u64, abs_b), &r);
72 // Apply the sign of the dividend and return.
73 return (@bitCast(i64, r) ^ (a >> 63)) -% (a >> 63);
74}
75
76test "test_moddi3" {
77 const cases = [_][3]i64{
78 [_]i64{ 0, 1, 0 },
79 [_]i64{ 0, -1, 0 },
80 [_]i64{ 5, 3, 2 },
81 [_]i64{ 5, -3, 2 },
82 [_]i64{ -5, 3, -2 },
83 [_]i64{ -5, -3, -2 },
84
85 [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), 1, 0 },
86 [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), -1, 0 },
87 [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), 2, 0 },
88 [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), -2, 0 },
89 [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), 3, -2 },
90 [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), -3, -2 },
91 };
92
93 for (cases) |case| {
94 test_one_moddi3(case[0], case[1], case[2]);
95 }
96}
97
98fn test_one_moddi3(a: i64, b: i64, expected_r: i64) void {
99 const r: i64 = __moddi3(a, b);
100 testing.expect(r == expected_r);
101}
102
103pub fn __udivdi3(a: u64, b: u64) callconv(.C) u64 {
104 @setRuntimeSafety(builtin.is_test);
105 return __udivmoddi4(a, b, null);
106}
107
108pub fn __umoddi3(a: u64, b: u64) callconv(.C) u64 {
109 @setRuntimeSafety(builtin.is_test);
110
111 var r: u64 = undefined;
112 _ = __udivmoddi4(a, b, &r);
113 return r;
114}
115
116test "test_umoddi3" {
117 test_one_umoddi3(0, 1, 0);
118 test_one_umoddi3(2, 1, 0);
119 test_one_umoddi3(0x8000000000000000, 1, 0x0);
120 test_one_umoddi3(0x8000000000000000, 2, 0x0);
121 test_one_umoddi3(0xFFFFFFFFFFFFFFFF, 2, 0x1);
122}
123
124fn test_one_umoddi3(a: u64, b: u64, expected_r: u64) void {
125 const r = __umoddi3(a, b);
126 testing.expect(r == expected_r);
127}
128
129pub fn __divmodsi4(a: i32, b: i32, rem: *i32) callconv(.C) i32 {
130 @setRuntimeSafety(builtin.is_test);
131
132 const d = __divsi3(a, b);
133 rem.* = a -% (d * b);
134 return d;
135}
136
137test "test_divmodsi4" {
138 const cases = [_][4]i32{
139 [_]i32{ 0, 1, 0, 0 },
140 [_]i32{ 0, -1, 0, 0 },
141 [_]i32{ 2, 1, 2, 0 },
142 [_]i32{ 2, -1, -2, 0 },
143 [_]i32{ -2, 1, -2, 0 },
144 [_]i32{ -2, -1, 2, 0 },
145 [_]i32{ 7, 5, 1, 2 },
146 [_]i32{ -7, 5, -1, -2 },
147 [_]i32{ 19, 5, 3, 4 },
148 [_]i32{ 19, -5, -3, 4 },
149
150 [_]i32{ @bitCast(i32, @as(u32, 0x80000000)), 8, @bitCast(i32, @as(u32, 0xf0000000)), 0 },
151 [_]i32{ @bitCast(i32, @as(u32, 0x80000007)), 8, @bitCast(i32, @as(u32, 0xf0000001)), -1 },
152 };
153
154 for (cases) |case| {
155 test_one_divmodsi4(case[0], case[1], case[2], case[3]);
156 }
157}
158
159fn test_one_divmodsi4(a: i32, b: i32, expected_q: i32, expected_r: i32) void {
160 var r: i32 = undefined;
161 const q: i32 = __divmodsi4(a, b, &r);
162 testing.expect(q == expected_q and r == expected_r);
163}
164
165pub fn __udivmodsi4(a: u32, b: u32, rem: *u32) callconv(.C) u32 {
166 @setRuntimeSafety(builtin.is_test);
167
168 const d = __udivsi3(a, b);
169 rem.* = @bitCast(u32, @bitCast(i32, a) -% (@bitCast(i32, d) * @bitCast(i32, b)));
170 return d;
171}
172
173pub fn __divsi3(n: i32, d: i32) callconv(.C) i32 {
174 @setRuntimeSafety(builtin.is_test);
175
176 // Set aside the sign of the quotient.
177 const sign = @bitCast(u32, (n ^ d) >> 31);
178 // Take absolute value of a and b via abs(x) = (x^(x >> 31)) - (x >> 31).
179 const abs_n = (n ^ (n >> 31)) -% (n >> 31);
180 const abs_d = (d ^ (d >> 31)) -% (d >> 31);
181 // abs(a) / abs(b)
182 const res = @bitCast(u32, abs_n) / @bitCast(u32, abs_d);
183 // Apply sign of quotient to result and return.
184 return @bitCast(i32, (res ^ sign) -% sign);
185}
186
187test "test_divsi3" {
188 const cases = [_][3]i32{
189 [_]i32{ 0, 1, 0 },
190 [_]i32{ 0, -1, 0 },
191 [_]i32{ 2, 1, 2 },
192 [_]i32{ 2, -1, -2 },
193 [_]i32{ -2, 1, -2 },
194 [_]i32{ -2, -1, 2 },
195
196 [_]i32{ @bitCast(i32, @as(u32, 0x80000000)), 1, @bitCast(i32, @as(u32, 0x80000000)) },
197 [_]i32{ @bitCast(i32, @as(u32, 0x80000000)), -1, @bitCast(i32, @as(u32, 0x80000000)) },
198 [_]i32{ @bitCast(i32, @as(u32, 0x80000000)), -2, 0x40000000 },
199 [_]i32{ @bitCast(i32, @as(u32, 0x80000000)), 2, @bitCast(i32, @as(u32, 0xC0000000)) },
200 };
201
202 for (cases) |case| {
203 test_one_divsi3(case[0], case[1], case[2]);
204 }
205}
206
207fn test_one_divsi3(a: i32, b: i32, expected_q: i32) void {
208 const q: i32 = __divsi3(a, b);
209 testing.expect(q == expected_q);
210}
211
212pub fn __udivsi3(n: u32, d: u32) callconv(.C) u32 {
213 @setRuntimeSafety(builtin.is_test);
214
215 const n_uword_bits: c_uint = u32.bit_count;
216 // special cases
217 if (d == 0) return 0; // ?!
218 if (n == 0) return 0;
219 var sr = @bitCast(c_uint, @as(c_int, @clz(u32, d)) - @as(c_int, @clz(u32, n)));
220 // 0 <= sr <= n_uword_bits - 1 or sr large
221 if (sr > n_uword_bits - 1) {
222 // d > r
223 return 0;
224 }
225 if (sr == n_uword_bits - 1) {
226 // d == 1
227 return n;
228 }
229 sr += 1;
230 // 1 <= sr <= n_uword_bits - 1
231 // Not a special case
232 var q: u32 = n << @intCast(u5, n_uword_bits - sr);
233 var r: u32 = n >> @intCast(u5, sr);
234 var carry: u32 = 0;
235 while (sr > 0) : (sr -= 1) {
236 // r:q = ((r:q) << 1) | carry
237 r = (r << 1) | (q >> @intCast(u5, n_uword_bits - 1));
238 q = (q << 1) | carry;
239 // carry = 0;
240 // if (r.all >= d.all)
241 // {
242 // r.all -= d.all;
243 // carry = 1;
244 // }
245 const s = @intCast(i32, d -% r -% 1) >> @intCast(u5, n_uword_bits - 1);
246 carry = @intCast(u32, s & 1);
247 r -= d & @bitCast(u32, s);
248 }
249 q = (q << 1) | carry;
250 return q;
251}
252
253test "test_udivsi3" {
254 const cases = [_][3]u32{
255 [_]u32{ 0x00000000, 0x00000001, 0x00000000 },
256 [_]u32{ 0x00000000, 0x00000002, 0x00000000 },
257 [_]u32{ 0x00000000, 0x00000003, 0x00000000 },
258 [_]u32{ 0x00000000, 0x00000010, 0x00000000 },
259 [_]u32{ 0x00000000, 0x078644FA, 0x00000000 },
260 [_]u32{ 0x00000000, 0x0747AE14, 0x00000000 },
261 [_]u32{ 0x00000000, 0x7FFFFFFF, 0x00000000 },
262 [_]u32{ 0x00000000, 0x80000000, 0x00000000 },
263 [_]u32{ 0x00000000, 0xFFFFFFFD, 0x00000000 },
264 [_]u32{ 0x00000000, 0xFFFFFFFE, 0x00000000 },
265 [_]u32{ 0x00000000, 0xFFFFFFFF, 0x00000000 },
266 [_]u32{ 0x00000001, 0x00000001, 0x00000001 },
267 [_]u32{ 0x00000001, 0x00000002, 0x00000000 },
268 [_]u32{ 0x00000001, 0x00000003, 0x00000000 },
269 [_]u32{ 0x00000001, 0x00000010, 0x00000000 },
270 [_]u32{ 0x00000001, 0x078644FA, 0x00000000 },
271 [_]u32{ 0x00000001, 0x0747AE14, 0x00000000 },
272 [_]u32{ 0x00000001, 0x7FFFFFFF, 0x00000000 },
273 [_]u32{ 0x00000001, 0x80000000, 0x00000000 },
274 [_]u32{ 0x00000001, 0xFFFFFFFD, 0x00000000 },
275 [_]u32{ 0x00000001, 0xFFFFFFFE, 0x00000000 },
276 [_]u32{ 0x00000001, 0xFFFFFFFF, 0x00000000 },
277 [_]u32{ 0x00000002, 0x00000001, 0x00000002 },
278 [_]u32{ 0x00000002, 0x00000002, 0x00000001 },
279 [_]u32{ 0x00000002, 0x00000003, 0x00000000 },
280 [_]u32{ 0x00000002, 0x00000010, 0x00000000 },
281 [_]u32{ 0x00000002, 0x078644FA, 0x00000000 },
282 [_]u32{ 0x00000002, 0x0747AE14, 0x00000000 },
283 [_]u32{ 0x00000002, 0x7FFFFFFF, 0x00000000 },
284 [_]u32{ 0x00000002, 0x80000000, 0x00000000 },
285 [_]u32{ 0x00000002, 0xFFFFFFFD, 0x00000000 },
286 [_]u32{ 0x00000002, 0xFFFFFFFE, 0x00000000 },
287 [_]u32{ 0x00000002, 0xFFFFFFFF, 0x00000000 },
288 [_]u32{ 0x00000003, 0x00000001, 0x00000003 },
289 [_]u32{ 0x00000003, 0x00000002, 0x00000001 },
290 [_]u32{ 0x00000003, 0x00000003, 0x00000001 },
291 [_]u32{ 0x00000003, 0x00000010, 0x00000000 },
292 [_]u32{ 0x00000003, 0x078644FA, 0x00000000 },
293 [_]u32{ 0x00000003, 0x0747AE14, 0x00000000 },
294 [_]u32{ 0x00000003, 0x7FFFFFFF, 0x00000000 },
295 [_]u32{ 0x00000003, 0x80000000, 0x00000000 },
296 [_]u32{ 0x00000003, 0xFFFFFFFD, 0x00000000 },
297 [_]u32{ 0x00000003, 0xFFFFFFFE, 0x00000000 },
298 [_]u32{ 0x00000003, 0xFFFFFFFF, 0x00000000 },
299 [_]u32{ 0x00000010, 0x00000001, 0x00000010 },
300 [_]u32{ 0x00000010, 0x00000002, 0x00000008 },
301 [_]u32{ 0x00000010, 0x00000003, 0x00000005 },
302 [_]u32{ 0x00000010, 0x00000010, 0x00000001 },
303 [_]u32{ 0x00000010, 0x078644FA, 0x00000000 },
304 [_]u32{ 0x00000010, 0x0747AE14, 0x00000000 },
305 [_]u32{ 0x00000010, 0x7FFFFFFF, 0x00000000 },
306 [_]u32{ 0x00000010, 0x80000000, 0x00000000 },
307 [_]u32{ 0x00000010, 0xFFFFFFFD, 0x00000000 },
308 [_]u32{ 0x00000010, 0xFFFFFFFE, 0x00000000 },
309 [_]u32{ 0x00000010, 0xFFFFFFFF, 0x00000000 },
310 [_]u32{ 0x078644FA, 0x00000001, 0x078644FA },
311 [_]u32{ 0x078644FA, 0x00000002, 0x03C3227D },
312 [_]u32{ 0x078644FA, 0x00000003, 0x028216FE },
313 [_]u32{ 0x078644FA, 0x00000010, 0x0078644F },
314 [_]u32{ 0x078644FA, 0x078644FA, 0x00000001 },
315 [_]u32{ 0x078644FA, 0x0747AE14, 0x00000001 },
316 [_]u32{ 0x078644FA, 0x7FFFFFFF, 0x00000000 },
317 [_]u32{ 0x078644FA, 0x80000000, 0x00000000 },
318 [_]u32{ 0x078644FA, 0xFFFFFFFD, 0x00000000 },
319 [_]u32{ 0x078644FA, 0xFFFFFFFE, 0x00000000 },
320 [_]u32{ 0x078644FA, 0xFFFFFFFF, 0x00000000 },
321 [_]u32{ 0x0747AE14, 0x00000001, 0x0747AE14 },
322 [_]u32{ 0x0747AE14, 0x00000002, 0x03A3D70A },
323 [_]u32{ 0x0747AE14, 0x00000003, 0x026D3A06 },
324 [_]u32{ 0x0747AE14, 0x00000010, 0x00747AE1 },
325 [_]u32{ 0x0747AE14, 0x078644FA, 0x00000000 },
326 [_]u32{ 0x0747AE14, 0x0747AE14, 0x00000001 },
327 [_]u32{ 0x0747AE14, 0x7FFFFFFF, 0x00000000 },
328 [_]u32{ 0x0747AE14, 0x80000000, 0x00000000 },
329 [_]u32{ 0x0747AE14, 0xFFFFFFFD, 0x00000000 },
330 [_]u32{ 0x0747AE14, 0xFFFFFFFE, 0x00000000 },
331 [_]u32{ 0x0747AE14, 0xFFFFFFFF, 0x00000000 },
332 [_]u32{ 0x7FFFFFFF, 0x00000001, 0x7FFFFFFF },
333 [_]u32{ 0x7FFFFFFF, 0x00000002, 0x3FFFFFFF },
334 [_]u32{ 0x7FFFFFFF, 0x00000003, 0x2AAAAAAA },
335 [_]u32{ 0x7FFFFFFF, 0x00000010, 0x07FFFFFF },
336 [_]u32{ 0x7FFFFFFF, 0x078644FA, 0x00000011 },
337 [_]u32{ 0x7FFFFFFF, 0x0747AE14, 0x00000011 },
338 [_]u32{ 0x7FFFFFFF, 0x7FFFFFFF, 0x00000001 },
339 [_]u32{ 0x7FFFFFFF, 0x80000000, 0x00000000 },
340 [_]u32{ 0x7FFFFFFF, 0xFFFFFFFD, 0x00000000 },
341 [_]u32{ 0x7FFFFFFF, 0xFFFFFFFE, 0x00000000 },
342 [_]u32{ 0x7FFFFFFF, 0xFFFFFFFF, 0x00000000 },
343 [_]u32{ 0x80000000, 0x00000001, 0x80000000 },
344 [_]u32{ 0x80000000, 0x00000002, 0x40000000 },
345 [_]u32{ 0x80000000, 0x00000003, 0x2AAAAAAA },
346 [_]u32{ 0x80000000, 0x00000010, 0x08000000 },
347 [_]u32{ 0x80000000, 0x078644FA, 0x00000011 },
348 [_]u32{ 0x80000000, 0x0747AE14, 0x00000011 },
349 [_]u32{ 0x80000000, 0x7FFFFFFF, 0x00000001 },
350 [_]u32{ 0x80000000, 0x80000000, 0x00000001 },
351 [_]u32{ 0x80000000, 0xFFFFFFFD, 0x00000000 },
352 [_]u32{ 0x80000000, 0xFFFFFFFE, 0x00000000 },
353 [_]u32{ 0x80000000, 0xFFFFFFFF, 0x00000000 },
354 [_]u32{ 0xFFFFFFFD, 0x00000001, 0xFFFFFFFD },
355 [_]u32{ 0xFFFFFFFD, 0x00000002, 0x7FFFFFFE },
356 [_]u32{ 0xFFFFFFFD, 0x00000003, 0x55555554 },
357 [_]u32{ 0xFFFFFFFD, 0x00000010, 0x0FFFFFFF },
358 [_]u32{ 0xFFFFFFFD, 0x078644FA, 0x00000022 },
359 [_]u32{ 0xFFFFFFFD, 0x0747AE14, 0x00000023 },
360 [_]u32{ 0xFFFFFFFD, 0x7FFFFFFF, 0x00000001 },
361 [_]u32{ 0xFFFFFFFD, 0x80000000, 0x00000001 },
362 [_]u32{ 0xFFFFFFFD, 0xFFFFFFFD, 0x00000001 },
363 [_]u32{ 0xFFFFFFFD, 0xFFFFFFFE, 0x00000000 },
364 [_]u32{ 0xFFFFFFFD, 0xFFFFFFFF, 0x00000000 },
365 [_]u32{ 0xFFFFFFFE, 0x00000001, 0xFFFFFFFE },
366 [_]u32{ 0xFFFFFFFE, 0x00000002, 0x7FFFFFFF },
367 [_]u32{ 0xFFFFFFFE, 0x00000003, 0x55555554 },
368 [_]u32{ 0xFFFFFFFE, 0x00000010, 0x0FFFFFFF },
369 [_]u32{ 0xFFFFFFFE, 0x078644FA, 0x00000022 },
370 [_]u32{ 0xFFFFFFFE, 0x0747AE14, 0x00000023 },
371 [_]u32{ 0xFFFFFFFE, 0x7FFFFFFF, 0x00000002 },
372 [_]u32{ 0xFFFFFFFE, 0x80000000, 0x00000001 },
373 [_]u32{ 0xFFFFFFFE, 0xFFFFFFFD, 0x00000001 },
374 [_]u32{ 0xFFFFFFFE, 0xFFFFFFFE, 0x00000001 },
375 [_]u32{ 0xFFFFFFFE, 0xFFFFFFFF, 0x00000000 },
376 [_]u32{ 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF },
377 [_]u32{ 0xFFFFFFFF, 0x00000002, 0x7FFFFFFF },
378 [_]u32{ 0xFFFFFFFF, 0x00000003, 0x55555555 },
379 [_]u32{ 0xFFFFFFFF, 0x00000010, 0x0FFFFFFF },
380 [_]u32{ 0xFFFFFFFF, 0x078644FA, 0x00000022 },
381 [_]u32{ 0xFFFFFFFF, 0x0747AE14, 0x00000023 },
382 [_]u32{ 0xFFFFFFFF, 0x7FFFFFFF, 0x00000002 },
383 [_]u32{ 0xFFFFFFFF, 0x80000000, 0x00000001 },
384 [_]u32{ 0xFFFFFFFF, 0xFFFFFFFD, 0x00000001 },
385 [_]u32{ 0xFFFFFFFF, 0xFFFFFFFE, 0x00000001 },
386 [_]u32{ 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001 },
387 };
388
389 for (cases) |case| {
390 test_one_udivsi3(case[0], case[1], case[2]);
391 }
392}
393
394fn test_one_udivsi3(a: u32, b: u32, expected_q: u32) void {
395 const q: u32 = __udivsi3(a, b);
396 testing.expect(q == expected_q);
397}
398
399pub fn __modsi3(n: i32, d: i32) callconv(.C) i32 {
400 @setRuntimeSafety(builtin.is_test);
401
402 return n -% __divsi3(n, d) *% d;
403}
404
405test "test_modsi3" {
406 const cases = [_][3]i32{
407 [_]i32{ 0, 1, 0 },
408 [_]i32{ 0, -1, 0 },
409 [_]i32{ 5, 3, 2 },
410 [_]i32{ 5, -3, 2 },
411 [_]i32{ -5, 3, -2 },
412 [_]i32{ -5, -3, -2 },
413 [_]i32{ @bitCast(i32, @intCast(u32, 0x80000000)), 1, 0x0 },
414 [_]i32{ @bitCast(i32, @intCast(u32, 0x80000000)), 2, 0x0 },
415 [_]i32{ @bitCast(i32, @intCast(u32, 0x80000000)), -2, 0x0 },
416 [_]i32{ @bitCast(i32, @intCast(u32, 0x80000000)), 3, -2 },
417 [_]i32{ @bitCast(i32, @intCast(u32, 0x80000000)), -3, -2 },
418 };
419
420 for (cases) |case| {
421 test_one_modsi3(case[0], case[1], case[2]);
422 }
423}
424
425fn test_one_modsi3(a: i32, b: i32, expected_r: i32) void {
426 const r: i32 = __modsi3(a, b);
427 testing.expect(r == expected_r);
428}
429
430pub fn __umodsi3(n: u32, d: u32) callconv(.C) u32 {
431 @setRuntimeSafety(builtin.is_test);
432
433 return n -% __udivsi3(n, d) *% d;
434}
435
436test "test_umodsi3" {
437 const cases = [_][3]u32{
438 [_]u32{ 0x00000000, 0x00000001, 0x00000000 },
439 [_]u32{ 0x00000000, 0x00000002, 0x00000000 },
440 [_]u32{ 0x00000000, 0x00000003, 0x00000000 },
441 [_]u32{ 0x00000000, 0x00000010, 0x00000000 },
442 [_]u32{ 0x00000000, 0x078644FA, 0x00000000 },
443 [_]u32{ 0x00000000, 0x0747AE14, 0x00000000 },
444 [_]u32{ 0x00000000, 0x7FFFFFFF, 0x00000000 },
445 [_]u32{ 0x00000000, 0x80000000, 0x00000000 },
446 [_]u32{ 0x00000000, 0xFFFFFFFD, 0x00000000 },
447 [_]u32{ 0x00000000, 0xFFFFFFFE, 0x00000000 },
448 [_]u32{ 0x00000000, 0xFFFFFFFF, 0x00000000 },
449 [_]u32{ 0x00000001, 0x00000001, 0x00000000 },
450 [_]u32{ 0x00000001, 0x00000002, 0x00000001 },
451 [_]u32{ 0x00000001, 0x00000003, 0x00000001 },
452 [_]u32{ 0x00000001, 0x00000010, 0x00000001 },
453 [_]u32{ 0x00000001, 0x078644FA, 0x00000001 },
454 [_]u32{ 0x00000001, 0x0747AE14, 0x00000001 },
455 [_]u32{ 0x00000001, 0x7FFFFFFF, 0x00000001 },
456 [_]u32{ 0x00000001, 0x80000000, 0x00000001 },
457 [_]u32{ 0x00000001, 0xFFFFFFFD, 0x00000001 },
458 [_]u32{ 0x00000001, 0xFFFFFFFE, 0x00000001 },
459 [_]u32{ 0x00000001, 0xFFFFFFFF, 0x00000001 },
460 [_]u32{ 0x00000002, 0x00000001, 0x00000000 },
461 [_]u32{ 0x00000002, 0x00000002, 0x00000000 },
462 [_]u32{ 0x00000002, 0x00000003, 0x00000002 },
463 [_]u32{ 0x00000002, 0x00000010, 0x00000002 },
464 [_]u32{ 0x00000002, 0x078644FA, 0x00000002 },
465 [_]u32{ 0x00000002, 0x0747AE14, 0x00000002 },
466 [_]u32{ 0x00000002, 0x7FFFFFFF, 0x00000002 },
467 [_]u32{ 0x00000002, 0x80000000, 0x00000002 },
468 [_]u32{ 0x00000002, 0xFFFFFFFD, 0x00000002 },
469 [_]u32{ 0x00000002, 0xFFFFFFFE, 0x00000002 },
470 [_]u32{ 0x00000002, 0xFFFFFFFF, 0x00000002 },
471 [_]u32{ 0x00000003, 0x00000001, 0x00000000 },
472 [_]u32{ 0x00000003, 0x00000002, 0x00000001 },
473 [_]u32{ 0x00000003, 0x00000003, 0x00000000 },
474 [_]u32{ 0x00000003, 0x00000010, 0x00000003 },
475 [_]u32{ 0x00000003, 0x078644FA, 0x00000003 },
476 [_]u32{ 0x00000003, 0x0747AE14, 0x00000003 },
477 [_]u32{ 0x00000003, 0x7FFFFFFF, 0x00000003 },
478 [_]u32{ 0x00000003, 0x80000000, 0x00000003 },
479 [_]u32{ 0x00000003, 0xFFFFFFFD, 0x00000003 },
480 [_]u32{ 0x00000003, 0xFFFFFFFE, 0x00000003 },
481 [_]u32{ 0x00000003, 0xFFFFFFFF, 0x00000003 },
482 [_]u32{ 0x00000010, 0x00000001, 0x00000000 },
483 [_]u32{ 0x00000010, 0x00000002, 0x00000000 },
484 [_]u32{ 0x00000010, 0x00000003, 0x00000001 },
485 [_]u32{ 0x00000010, 0x00000010, 0x00000000 },
486 [_]u32{ 0x00000010, 0x078644FA, 0x00000010 },
487 [_]u32{ 0x00000010, 0x0747AE14, 0x00000010 },
488 [_]u32{ 0x00000010, 0x7FFFFFFF, 0x00000010 },
489 [_]u32{ 0x00000010, 0x80000000, 0x00000010 },
490 [_]u32{ 0x00000010, 0xFFFFFFFD, 0x00000010 },
491 [_]u32{ 0x00000010, 0xFFFFFFFE, 0x00000010 },
492 [_]u32{ 0x00000010, 0xFFFFFFFF, 0x00000010 },
493 [_]u32{ 0x078644FA, 0x00000001, 0x00000000 },
494 [_]u32{ 0x078644FA, 0x00000002, 0x00000000 },
495 [_]u32{ 0x078644FA, 0x00000003, 0x00000000 },
496 [_]u32{ 0x078644FA, 0x00000010, 0x0000000A },
497 [_]u32{ 0x078644FA, 0x078644FA, 0x00000000 },
498 [_]u32{ 0x078644FA, 0x0747AE14, 0x003E96E6 },
499 [_]u32{ 0x078644FA, 0x7FFFFFFF, 0x078644FA },
500 [_]u32{ 0x078644FA, 0x80000000, 0x078644FA },
501 [_]u32{ 0x078644FA, 0xFFFFFFFD, 0x078644FA },
502 [_]u32{ 0x078644FA, 0xFFFFFFFE, 0x078644FA },
503 [_]u32{ 0x078644FA, 0xFFFFFFFF, 0x078644FA },
504 [_]u32{ 0x0747AE14, 0x00000001, 0x00000000 },
505 [_]u32{ 0x0747AE14, 0x00000002, 0x00000000 },
506 [_]u32{ 0x0747AE14, 0x00000003, 0x00000002 },
507 [_]u32{ 0x0747AE14, 0x00000010, 0x00000004 },
508 [_]u32{ 0x0747AE14, 0x078644FA, 0x0747AE14 },
509 [_]u32{ 0x0747AE14, 0x0747AE14, 0x00000000 },
510 [_]u32{ 0x0747AE14, 0x7FFFFFFF, 0x0747AE14 },
511 [_]u32{ 0x0747AE14, 0x80000000, 0x0747AE14 },
512 [_]u32{ 0x0747AE14, 0xFFFFFFFD, 0x0747AE14 },
513 [_]u32{ 0x0747AE14, 0xFFFFFFFE, 0x0747AE14 },
514 [_]u32{ 0x0747AE14, 0xFFFFFFFF, 0x0747AE14 },
515 [_]u32{ 0x7FFFFFFF, 0x00000001, 0x00000000 },
516 [_]u32{ 0x7FFFFFFF, 0x00000002, 0x00000001 },
517 [_]u32{ 0x7FFFFFFF, 0x00000003, 0x00000001 },
518 [_]u32{ 0x7FFFFFFF, 0x00000010, 0x0000000F },
519 [_]u32{ 0x7FFFFFFF, 0x078644FA, 0x00156B65 },
520 [_]u32{ 0x7FFFFFFF, 0x0747AE14, 0x043D70AB },
521 [_]u32{ 0x7FFFFFFF, 0x7FFFFFFF, 0x00000000 },
522 [_]u32{ 0x7FFFFFFF, 0x80000000, 0x7FFFFFFF },
523 [_]u32{ 0x7FFFFFFF, 0xFFFFFFFD, 0x7FFFFFFF },
524 [_]u32{ 0x7FFFFFFF, 0xFFFFFFFE, 0x7FFFFFFF },
525 [_]u32{ 0x7FFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF },
526 [_]u32{ 0x80000000, 0x00000001, 0x00000000 },
527 [_]u32{ 0x80000000, 0x00000002, 0x00000000 },
528 [_]u32{ 0x80000000, 0x00000003, 0x00000002 },
529 [_]u32{ 0x80000000, 0x00000010, 0x00000000 },
530 [_]u32{ 0x80000000, 0x078644FA, 0x00156B66 },
531 [_]u32{ 0x80000000, 0x0747AE14, 0x043D70AC },
532 [_]u32{ 0x80000000, 0x7FFFFFFF, 0x00000001 },
533 [_]u32{ 0x80000000, 0x80000000, 0x00000000 },
534 [_]u32{ 0x80000000, 0xFFFFFFFD, 0x80000000 },
535 [_]u32{ 0x80000000, 0xFFFFFFFE, 0x80000000 },
536 [_]u32{ 0x80000000, 0xFFFFFFFF, 0x80000000 },
537 [_]u32{ 0xFFFFFFFD, 0x00000001, 0x00000000 },
538 [_]u32{ 0xFFFFFFFD, 0x00000002, 0x00000001 },
539 [_]u32{ 0xFFFFFFFD, 0x00000003, 0x00000001 },
540 [_]u32{ 0xFFFFFFFD, 0x00000010, 0x0000000D },
541 [_]u32{ 0xFFFFFFFD, 0x078644FA, 0x002AD6C9 },
542 [_]u32{ 0xFFFFFFFD, 0x0747AE14, 0x01333341 },
543 [_]u32{ 0xFFFFFFFD, 0x7FFFFFFF, 0x7FFFFFFE },
544 [_]u32{ 0xFFFFFFFD, 0x80000000, 0x7FFFFFFD },
545 [_]u32{ 0xFFFFFFFD, 0xFFFFFFFD, 0x00000000 },
546 [_]u32{ 0xFFFFFFFD, 0xFFFFFFFE, 0xFFFFFFFD },
547 [_]u32{ 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFD },
548 [_]u32{ 0xFFFFFFFE, 0x00000001, 0x00000000 },
549 [_]u32{ 0xFFFFFFFE, 0x00000002, 0x00000000 },
550 [_]u32{ 0xFFFFFFFE, 0x00000003, 0x00000002 },
551 [_]u32{ 0xFFFFFFFE, 0x00000010, 0x0000000E },
552 [_]u32{ 0xFFFFFFFE, 0x078644FA, 0x002AD6CA },
553 [_]u32{ 0xFFFFFFFE, 0x0747AE14, 0x01333342 },
554 [_]u32{ 0xFFFFFFFE, 0x7FFFFFFF, 0x00000000 },
555 [_]u32{ 0xFFFFFFFE, 0x80000000, 0x7FFFFFFE },
556 [_]u32{ 0xFFFFFFFE, 0xFFFFFFFD, 0x00000001 },
557 [_]u32{ 0xFFFFFFFE, 0xFFFFFFFE, 0x00000000 },
558 [_]u32{ 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFE },
559 [_]u32{ 0xFFFFFFFF, 0x00000001, 0x00000000 },
560 [_]u32{ 0xFFFFFFFF, 0x00000002, 0x00000001 },
561 [_]u32{ 0xFFFFFFFF, 0x00000003, 0x00000000 },
562 [_]u32{ 0xFFFFFFFF, 0x00000010, 0x0000000F },
563 [_]u32{ 0xFFFFFFFF, 0x078644FA, 0x002AD6CB },
564 [_]u32{ 0xFFFFFFFF, 0x0747AE14, 0x01333343 },
565 [_]u32{ 0xFFFFFFFF, 0x7FFFFFFF, 0x00000001 },
566 [_]u32{ 0xFFFFFFFF, 0x80000000, 0x7FFFFFFF },
567 [_]u32{ 0xFFFFFFFF, 0xFFFFFFFD, 0x00000002 },
568 [_]u32{ 0xFFFFFFFF, 0xFFFFFFFE, 0x00000001 },
569 [_]u32{ 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000 },
570 };
571
572 for (cases) |case| {
573 test_one_umodsi3(case[0], case[1], case[2]);
574 }
575}
576
577fn test_one_umodsi3(a: u32, b: u32, expected_r: u32) void {
578 const r: u32 = __umodsi3(a, b);
579 testing.expect(r == expected_r);
580}
lib/std/special/compiler_rt/udivmoddi4.zig deleted-11
......@@ -1,11 +0,0 @@
1const udivmod = @import("udivmod.zig").udivmod;
2const builtin = @import("builtin");
3
4pub fn __udivmoddi4(a: u64, b: u64, maybe_rem: ?*u64) callconv(.C) u64 {
5 @setRuntimeSafety(builtin.is_test);
6 return udivmod(u64, a, b, maybe_rem);
7}
8
9test "import udivmoddi4" {
10 _ = @import("udivmoddi4_test.zig");
11}
lib/std/special/compiler_rt/udivmoddi4_test.zig+1-1
......@@ -1,6 +1,6 @@
11// Disable formatting to avoid unnecessary source repository bloat.
22// zig fmt: off
3const __udivmoddi4 = @import("udivmoddi4.zig").__udivmoddi4;
3const __udivmoddi4 = @import("int.zig").__udivmoddi4;
44const testing = @import("std").testing;
55
66fn test__udivmoddi4(a: u64, b: u64, expected_q: u64, expected_r: u64) void {