╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ compiler_rt.zig ──────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭ find file ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╮ ╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │ │ │http│ ssh │ │ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╯ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
561 } 562 563 fn __aeabi_fneg(a: f32) callconv(.{ .arm_aapcs = .{} }) f32 { 564 return fneg(a); 565 } 566 567 fn __aeabi_dneg(a: f64) callconv(.{ .arm_aapcs = .{} }) f64 { 568 return fneg(a); 569 } 570 571 /// Allows to access underlying bits as two equally sized lower and higher 572 /// signed or unsigned integers. 573 pub fn HalveInt(comptime T: type, comptime signed_half: bool) type { 574 return extern union { 575 pub const bits = @divExact(@typeInfo(T).int.bits, 2); 576 pub const HalfTU = @Int(.unsigned, bits); 577 pub const HalfTS = @Int(.signed, bits); 578 pub const HalfT = if (signed_half) HalfTS else HalfTU; 579 580 all: T, 581 s: if (native_endian == .little) 582 extern struct { low: HalfT, high: HalfT } 583 else 584 extern struct { high: HalfT, low: HalfT }, 585 }; 586 } 587 588 pub fn __negsi2(a: i32) callconv(.c) i32 { 589 return negXi2(i32, a); 590 } 591 592 pub fn __negdi2(a: i64) callconv(.c) i64 { 593 return negXi2(i64, a); 594 } 595 596 pub fn __negti2(a: i128) callconv(.c) i128 { 597 return negXi2(i128, a); 598 } 599 600 inline fn negXi2(comptime T: type, a: T) T { 601 return -a; 602 } 603 604 fn memsetSmallPowerOf2(d: [*]u8, b: u8, comptime size: usize) void { 605 @disableIntrinsics(); 606 607 if (size > @sizeOf(usize)) { 608 d[0..size].* = @splat(b); 609 } else { 610 const T = @Int(.unsigned, 8 * size); 611 var splatted: T = 0; // Setting this to undefined causes a memset call and thus infinite recursion in Debug test-compiler-rt. 612 @as(*[size]u8, @ptrCast(&splatted)).* = @splat(b); 613 @as(*align(1) T, @ptrCast(d)).* = splatted; 614 } 615 } 616 617 fn shortMemset( 618 log_min: comptime_int, 619 log_max: comptime_int, 620 d: [*]u8, 621 b: u8, 622 len: usize, 623 ) void { 624 @disableIntrinsics(); 625 626 if (log_min + 1 != log_max) { 627 const mid = (log_min + log_max) / 2; 628 if (len > 1 << mid) { 629 shortMemset(mid, log_max, d, b, len); 630 } else { 631 shortMemset(log_min, mid, d, b, len); 632 } 633 } else { 634 const size = 1 << log_min; 635 636 memsetSmallPowerOf2(d, b, size); 637 memsetSmallPowerOf2(d + len - size, b, size); 638 } 639 } 640 641 fn fastMemset(dest: ?[*]u8, c: c_int, len: usize) callconv(.c) ?[*]u8 { 642 @disableIntrinsics(); 643 644 const b: u8 = @truncate(@as(c_uint, @bitCast(c))); 645 const n = std.simd.suggestVectorLength(u8) orelse @sizeOf(usize); 646 647 const d = dest.?; 648 649 if (len > 2 * n) { 650 memsetSmallPowerOf2(d, b, n); 651 652 const begin_aligned = std.mem.alignBackward(usize, @intFromPtr(d) + n, n); 653 const end_aligned = std.mem.alignForward(usize, @intFromPtr(d) + len - n, n); 654 655 const aligned_ptr: [*]align(n) u8 = @ptrFromInt(begin_aligned); 656 657 var i: usize = 0; 658 while (true) { 659 memsetSmallPowerOf2(aligned_ptr + n * i, b, n); 660 661 i += 1; 662 if (i == @divExact(end_aligned - begin_aligned, n)) 663 break; 664 } 665 666 memsetSmallPowerOf2(d + len - n, b, n); 667 } else { 668 if (len == 0) return dest; 669 670 shortMemset(0, @ctz(@as(usize, 2 * n)), d, b, len); 671 } 672 673 return dest; 674 } 675 676 fn smallMemset(dest: ?[*]u8, c: c_int, len: usize) callconv(.c) ?[*]u8 { 677 @disableIntrinsics(); 678 679 const b: u8 = @truncate(@as(c_uint, @bitCast(c))); 680 681 if (len != 0) { 682 var d = dest.?; 683 var n = len; 684 while (true) { 685 d[0] = b; 686 n -= 1; 687 if (n == 0) break; 688 d += 1; 689 } 690 } 691 692 return dest; 693 } 694 695 pub const memset = if (builtin.optimize == .small) 696 smallMemset 697 else 698 fastMemset; 699 700 pub fn bcmp(vl: [*]allowzero const u8, vr: [*]allowzero const u8, n: usize) callconv(.c) c_int { 701 @setRuntimeSafety(false); 702 703 var index: usize = 0; 704 while (index != n) : (index += 1) { 705 if (vl[index] != vr[index]) { 706 return 1; 707 } 708 } 709 710 return 0; 711 } 712 713 test "bcmp" { 714 const base_arr = &[_]u8{ 1, 1, 1 }; 715 const arr1 = &[_]u8{ 1, 1, 1 }; 716 const arr2 = &[_]u8{ 1, 0, 1 }; 717 const arr3 = &[_]u8{ 1, 2, 1 }; 718 719 try std.testing.expect(bcmp(base_arr[0..], arr1[0..], base_arr.len) == 0); 720 try std.testing.expect(bcmp(base_arr[0..], arr2[0..], base_arr.len) != 0); 721 try std.testing.expect(bcmp(base_arr[0..], arr3[0..], base_arr.len) != 0); 722 } 723 724 test { 725 _ = @import("compiler_rt/negsi2_test.zig"); 726 _ = @import("compiler_rt/negdi2_test.zig"); 727 _ = @import("compiler_rt/negti2_test.zig"); 728 } 729