| ... | @@ -302,7 +302,6 @@ comptime { | ... | @@ -302,7 +302,6 @@ comptime { |
| 302 | _ = @import("compiler_rt/memcpy.zig"); | 302 | _ = @import("compiler_rt/memcpy.zig"); |
| 303 | if (!ofmt_c) { | 303 | if (!ofmt_c) { |
| 304 | symbol(&memset, "memset"); | 304 | symbol(&memset, "memset"); |
| 305 | symbol(&__memset, "__memset"); | | |
| 306 | } | 305 | } |
| 307 | _ = @import("compiler_rt/memmove.zig"); | 306 | _ = @import("compiler_rt/memmove.zig"); |
| 308 | symbol(&memcmp, "memcmp"); | 307 | symbol(&memcmp, "memcmp"); |
| ... | @@ -650,14 +649,80 @@ inline fn negXi2(comptime T: type, a: T) T { | ... | @@ -650,14 +649,80 @@ inline fn negXi2(comptime T: type, a: T) T { |
| 650 | return -a; | 649 | return -a; |
| 651 | } | 650 | } |
| 652 | | 651 | |
| 653 | pub fn memset(dest: ?[*]u8, c: u8, len: usize) callconv(.c) ?[*]u8 { | 652 | fn memsetSmallPowerOf2(d: [*]u8, b: u8, comptime size: usize) void { |
| 654 | @setRuntimeSafety(false); | 653 | if (size > @sizeOf(usize)) { |
| | 654 | d[0..size].* = @splat(b); |
| | 655 | } else { |
| | 656 | const T = @Int(.unsigned, 8 * size); |
| | 657 | var splatted: T = 0; // Setting this to undefined causes a memset call and thus infinite recursion in Debug test-compiler-rt. |
| | 658 | @as(*[size]u8, @ptrCast(&splatted)).* = @splat(b); |
| | 659 | @as(*align(1) T, @ptrCast(d)).* = splatted; |
| | 660 | } |
| | 661 | } |
| | 662 | |
| | 663 | fn shortMemset( |
| | 664 | log_min: comptime_int, |
| | 665 | log_max: comptime_int, |
| | 666 | d: [*]u8, |
| | 667 | b: u8, |
| | 668 | len: usize, |
| | 669 | ) void { |
| | 670 | if (log_min + 1 != log_max) { |
| | 671 | const mid = (log_min + log_max) / 2; |
| | 672 | if (len > 1 << mid) { |
| | 673 | shortMemset(mid, log_max, d, b, len); |
| | 674 | } else { |
| | 675 | shortMemset(log_min, mid, d, b, len); |
| | 676 | } |
| | 677 | } else { |
| | 678 | const size = 1 << log_min; |
| | 679 | |
| | 680 | memsetSmallPowerOf2(d, b, size); |
| | 681 | memsetSmallPowerOf2(d + len - size, b, size); |
| | 682 | } |
| | 683 | } |
| | 684 | |
| | 685 | fn fastMemset(dest: ?[*]u8, c: c_int, len: usize) callconv(.c) ?[*]u8 { |
| | 686 | const b: u8 = @truncate(@as(c_uint, @bitCast(c))); |
| | 687 | const n = std.simd.suggestVectorLength(u8) orelse @sizeOf(usize); |
| | 688 | |
| | 689 | const d = dest.?; |
| | 690 | |
| | 691 | if (len > 2 * n) { |
| | 692 | memsetSmallPowerOf2(d, b, n); |
| | 693 | |
| | 694 | const begin_aligned = std.mem.alignBackward(usize, @intFromPtr(d) + n, n); |
| | 695 | const end_aligned = std.mem.alignForward(usize, @intFromPtr(d) + len - n, n); |
| | 696 | |
| | 697 | const aligned_ptr: [*]align(n) u8 = @ptrFromInt(begin_aligned); |
| | 698 | |
| | 699 | var i: usize = 0; |
| | 700 | while (true) { |
| | 701 | memsetSmallPowerOf2(aligned_ptr + n * i, b, n); |
| | 702 | |
| | 703 | i += 1; |
| | 704 | if (i == @divExact(end_aligned - begin_aligned, n)) |
| | 705 | break; |
| | 706 | } |
| | 707 | |
| | 708 | memsetSmallPowerOf2(d + len - n, b, n); |
| | 709 | } else { |
| | 710 | if (len == 0) return dest; |
| | 711 | |
| | 712 | shortMemset(0, @ctz(@as(usize, 2 * n)), d, b, len); |
| | 713 | } |
| | 714 | |
| | 715 | return dest; |
| | 716 | } |
| | 717 | |
| | 718 | fn smallMemset(dest: ?[*]u8, c: c_int, len: usize) callconv(.c) ?[*]u8 { |
| | 719 | const b: u8 = @truncate(@as(c_uint, @bitCast(c))); |
| 655 | | 720 | |
| 656 | if (len != 0) { | 721 | if (len != 0) { |
| 657 | var d = dest.?; | 722 | var d = dest.?; |
| 658 | var n = len; | 723 | var n = len; |
| 659 | while (true) { | 724 | while (true) { |
| 660 | d[0] = c; | 725 | d[0] = b; |
| 661 | n -= 1; | 726 | n -= 1; |
| 662 | if (n == 0) break; | 727 | if (n == 0) break; |
| 663 | d += 1; | 728 | d += 1; |
| ... | @@ -667,11 +732,10 @@ pub fn memset(dest: ?[*]u8, c: u8, len: usize) callconv(.c) ?[*]u8 { | ... | @@ -667,11 +732,10 @@ pub fn memset(dest: ?[*]u8, c: u8, len: usize) callconv(.c) ?[*]u8 { |
| 667 | return dest; | 732 | return dest; |
| 668 | } | 733 | } |
| 669 | | 734 | |
| 670 | pub fn __memset(dest: ?[*]u8, c: u8, n: usize, dest_n: usize) callconv(.c) ?[*]u8 { | 735 | pub const memset = if (builtin.optimize == .small) |
| 671 | if (dest_n < n) | 736 | smallMemset |
| 672 | @panic("buffer overflow"); | 737 | else |
| 673 | return memset(dest, c, n); | 738 | fastMemset; |
| 674 | } | | |
| 675 | | 739 | |
| 676 | pub fn bcmp(vl: [*]allowzero const u8, vr: [*]allowzero const u8, n: usize) callconv(.c) c_int { | 740 | pub fn bcmp(vl: [*]allowzero const u8, vr: [*]allowzero const u8, n: usize) callconv(.c) c_int { |
| 677 | @setRuntimeSafety(false); | 741 | @setRuntimeSafety(false); |