@zigc/lib 0.17.0-dev.704 → 0.17.0-dev.813

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/c/math.zig +10 -0
  2. package/compiler/Maker/Step/TranslateC.zig +8 -4
  3. package/compiler_rt/log.zig +230 -3
  4. package/compiler_rt/log10.zig +228 -3
  5. package/compiler_rt/log2.zig +221 -3
  6. package/compiler_rt/log_f128.zig +173 -0
  7. package/package.json +1 -1
  8. package/std/Io/Writer.zig +6 -2
  9. package/std/Thread.zig +22 -2
  10. package/std/c/darwin.zig +6 -0
  11. package/std/c.zig +26 -5
  12. package/std/compress/flate/Compress.zig +4 -2
  13. package/std/crypto/ff.zig +3 -1
  14. package/std/crypto/tls/Client.zig +17 -2
  15. package/std/debug/cpu_context.zig +3 -3
  16. package/std/heap/BrkAllocator.zig +1 -1
  17. package/std/json/static.zig +2 -1
  18. package/std/math/isnan.zig +5 -0
  19. package/std/math/log1p.zig +13 -19
  20. package/std/math.zig +5 -0
  21. package/std/meta.zig +3 -12
  22. package/std/os/linux/csky.zig +165 -0
  23. package/std/os/linux/microblaze.zig +170 -0
  24. package/std/os/linux/sh.zig +239 -0
  25. package/std/os/linux/sparc.zig +277 -0
  26. package/std/os/linux/sparc64.zig +44 -30
  27. package/std/os/linux/syscalls.zig +1718 -12
  28. package/std/os/linux.zig +37 -8
  29. package/std/os/uefi/protocol/file.zig +16 -0
  30. package/std/os.zig +0 -10
  31. package/std/start.zig +5 -5
  32. package/std/static_string_map.zig +59 -1
  33. package/std/zig/LibCInstallation.zig +2 -2
  34. package/std/zig/Parse.zig +1 -1
  35. package/std/zig/PkgConfig.zig +5 -0
  36. package/std/zig/system/darwin/macos.zig +11 -7
  37. package/std/zig/system.zig +1 -1
  38. package/zig.h +38 -10
  39. package/libc/musl/src/math/i386/log1p.s +0 -25
  40. package/libc/musl/src/math/i386/log1pf.s +0 -26
  41. package/libc/musl/src/math/log1p.c +0 -122
  42. package/libc/musl/src/math/log1pf.c +0 -77
@@ -1202,6 +1202,7 @@ fn readIndirect(c: *Client) Reader.Error!usize {
1202
1202
  .tls_1_2 => {
1203
1203
  const pv = &p.tls_1_2;
1204
1204
  const P = @TypeOf(p.*);
1205
+ if (record_len < P.record_iv_length + P.mac_length) return failRead(c, error.TlsRecordOverflow);
1205
1206
  const message_len: u16 = record_len - P.record_iv_length - P.mac_length;
1206
1207
  const ad_header = input.take(tls.record_header_len) catch unreachable; // already peeked
1207
1208
  const ad = mem.toBytes(big(c.read_seq)) ++
@@ -1674,7 +1675,7 @@ else
1674
1675
  .ECDHE_RSA_WITH_AES_256_GCM_SHA384,
1675
1676
  });
1676
1677
 
1677
- fn testReadError(input_buf: []const u8, cipher: tls.ApplicationCipher) ReadError {
1678
+ fn testReadError(input_buf: []const u8, tls_version: tls.ProtocolVersion, cipher: tls.ApplicationCipher) ReadError {
1678
1679
  var input_reader: Reader = .fixed(input_buf);
1679
1680
  var read_buf: [tls.max_ciphertext_record_len]u8 = undefined;
1680
1681
  var c: Client = .{
@@ -1687,7 +1688,7 @@ fn testReadError(input_buf: []const u8, cipher: tls.ApplicationCipher) ReadError
1687
1688
  },
1688
1689
  .output = undefined,
1689
1690
  .writer = undefined,
1690
- .tls_version = .tls_1_3,
1691
+ .tls_version = tls_version,
1691
1692
  .read_seq = 0,
1692
1693
  .write_seq = 0,
1693
1694
  .received_close_notify = false,
@@ -1715,6 +1716,7 @@ test "empty inner plaintext" {
1715
1716
 
1716
1717
  try std.testing.expectEqual(error.TlsDecodeError, testReadError(
1717
1718
  &record_header ++ ciphertext ++ tag,
1719
+ .tls_1_3,
1718
1720
  .{ .CHACHA20_POLY1305_SHA256 = .{ .tls_1_3 = .{
1719
1721
  .server_key = key,
1720
1722
  .server_iv = iv,
@@ -1734,6 +1736,7 @@ test "record shorter than tag" {
1734
1736
 
1735
1737
  try std.testing.expectEqual(error.TlsRecordOverflow, testReadError(
1736
1738
  &wire,
1739
+ .tls_1_3,
1737
1740
  .{ .CHACHA20_POLY1305_SHA256 = .{ .tls_1_3 = .{
1738
1741
  .server_key = undefined,
1739
1742
  .server_iv = undefined,
@@ -1744,3 +1747,15 @@ test "record shorter than tag" {
1744
1747
  } } },
1745
1748
  ));
1746
1749
  }
1750
+
1751
+ test "TLS 1.2 record shorter than IV plus tag" {
1752
+ const P = tls.ApplicationCipherT(crypto.aead.aes_gcm.Aes128Gcm, crypto.hash.sha2.Sha256, 8);
1753
+ const record_len: u16 = P.record_iv_length + P.mac_length - 1;
1754
+ const header = [_]u8{ 0x17, 0x03, 0x03 } ++ mem.toBytes(big(record_len));
1755
+
1756
+ try std.testing.expectEqual(error.TlsRecordOverflow, testReadError(
1757
+ &(header ++ @as([record_len]u8, @splat(0))),
1758
+ .tls_1_2,
1759
+ .{ .AES_128_GCM_SHA256 = .{ .tls_1_2 = mem.zeroes(P.Tls_1_2) } },
1760
+ ));
1761
+ }
@@ -50,7 +50,7 @@ pub fn fromPosixSignalContext(ctx_ptr: ?*const anyopaque) ?Native {
50
50
  };
51
51
 
52
52
  // I have no idea why the kernel is storing these registers in such a bizarre order...
53
- std.mem.reverse(native.r[0..]);
53
+ std.mem.reverse(u32, native.r[0..]);
54
54
 
55
55
  return native;
56
56
  } else if (native_arch == .loongarch32 and native_os == .linux) {
@@ -350,7 +350,7 @@ const Alpha = extern struct {
350
350
  \\1:
351
351
  \\ stq $1, 0x100($0)
352
352
  :
353
- : [ctx] "{r0}" (&ctx),
353
+ : [ctx] "{$0}" (&ctx),
354
354
  : .{ .r1 = true, .memory = true });
355
355
  return ctx;
356
356
  }
@@ -362,7 +362,7 @@ const Alpha = extern struct {
362
362
  return ctx.pc;
363
363
  }
364
364
 
365
- pub fn dwarfRegisterBytes(ctx: *Aarch64, register_num: u16) DwarfRegisterError![]u8 {
365
+ pub fn dwarfRegisterBytes(ctx: *Alpha, register_num: u16) DwarfRegisterError![]u8 {
366
366
  switch (register_num) {
367
367
  0...31 => return @ptrCast(&ctx.r[register_num]),
368
368
  64 => return @ptrCast(&ctx.pc),
@@ -45,7 +45,7 @@ const size_class_count = math.log2(bigpage_size) - min_class;
45
45
  /// 1 - 2 bigpages
46
46
  /// 2 - 4 bigpages
47
47
  /// etc.
48
- const big_size_class_count = math.log2(bigpage_count);
48
+ const big_size_class_count = math.log2(bigpage_count) + 1;
49
49
 
50
50
  fn alloc(ctx: *anyopaque, len: usize, alignment: Alignment, return_address: usize) ?[*]u8 {
51
51
  _ = ctx;
@@ -32,6 +32,7 @@ pub const ParseOptions = struct {
32
32
  /// The default for `parseFromSlice` or `parseFromTokenSource` with a `*std.json.Scanner` input
33
33
  /// is the length of the input slice, which means `error.ValueTooLong` will never be returned.
34
34
  /// The default for `parseFromTokenSource` with a `*std.json.Reader` is `std.json.default_max_value_len`.
35
+ /// Ignored for values that don't need allocation or are not copied (see `allocate`).
35
36
  /// Ignored for `parseFromValue` and `parseFromValueLeaky`.
36
37
  max_value_len: ?usize = null,
37
38
 
@@ -495,7 +496,7 @@ pub fn innerParse(
495
496
  if (ptrInfo.sentinel()) |s| {
496
497
  // Use our own array list so we can append the sentinel.
497
498
  var value_list = ArrayList(u8).init(allocator);
498
- _ = try source.allocNextIntoArrayList(&value_list, .alloc_always);
499
+ _ = try source.allocNextIntoArrayListMax(&value_list, .alloc_always, options.max_value_len.?);
499
500
  return try value_list.toOwnedSliceSentinel(s);
500
501
  }
501
502
  if (ptrInfo.attrs.@"const") {
@@ -29,6 +29,11 @@ test isNan {
29
29
  test isSignalNan {
30
30
  if (builtin.zig_backend == .stage2_x86_64 and builtin.object_format == .coff and builtin.abi != .gnu) return error.SkipZigTest;
31
31
 
32
+ if (builtin.os.tag == .windows) {
33
+ // https://codeberg.org/ziglang/zig/issues/35519
34
+ return error.SkipZigTest;
35
+ }
36
+
32
37
  inline for ([_]type{ f16, f32, f64, f80, f128, c_longdouble }) |T| {
33
38
  // TODO: Signalling NaN values get converted to quiet NaN values in
34
39
  // some cases where they shouldn't such that this can fail.
@@ -43,17 +43,14 @@ fn log1p_32(x: f32) f32 {
43
43
 
44
44
  // 1 + x < sqrt(2)+
45
45
  if (ix < 0x3ED413D0 or ix >> 31 != 0) {
46
- // x <= -1.0
47
- if (ix >= 0xBF800000) {
46
+ // x = -1.0
47
+ if (ix == 0xBF800000)
48
48
  // log1p(-1) = -inf
49
- if (x == -1.0) {
50
- return -math.inf(f32);
51
- }
49
+ return x / 0.0;
50
+ // x < -1.0
51
+ if (ix > 0xBF800000)
52
52
  // log1p(x < -1) = nan
53
- else {
54
- return math.nan(f32);
55
- }
56
- }
53
+ return (x - x) / 0.0;
57
54
  // |x| < 2^(-24)
58
55
  if ((ix << 1) < (0x33800000 << 1)) {
59
56
  // underflow if subnormal
@@ -122,21 +119,18 @@ fn log1p_64(x: f64) f64 {
122
119
 
123
120
  // 1 + x < sqrt(2)
124
121
  if (hx < 0x3FDA827A or hx >> 31 != 0) {
125
- // x <= -1.0
126
- if (hx >= 0xBFF00000) {
122
+ // x = -1.0
123
+ if (ix == 0xBFF0000000000000)
127
124
  // log1p(-1) = -inf
128
- if (x == -1.0) {
129
- return -math.inf(f64);
130
- }
125
+ return x / 0.0;
126
+ // x < -1.0
127
+ if (hx >= 0xBFF00000)
131
128
  // log1p(x < -1) = nan
132
- else {
133
- return math.nan(f64);
134
- }
135
- }
129
+ return (x - x) / 0.0;
136
130
  // |x| < 2^(-53)
137
131
  if ((hx << 1) < (0x3CA00000 << 1)) {
138
132
  if ((hx & 0x7FF00000) == 0) {
139
- math.raiseUnderflow();
133
+ mem.doNotOptimizeAway(@as(f32, @floatCast(x)));
140
134
  }
141
135
  return x;
142
136
  }
package/std/math.zig CHANGED
@@ -461,6 +461,11 @@ pub fn wrap(x: anytype, r: anytype) @TypeOf(x) {
461
461
  }
462
462
  }
463
463
  test wrap {
464
+ if (builtin.os.tag == .windows and builtin.cpu.arch == .x86) {
465
+ // https://codeberg.org/ziglang/zig/issues/35520
466
+ return error.SkipZigTest;
467
+ }
468
+
464
469
  // Within range
465
470
  try testing.expect(wrap(@as(i32, -75), @as(i32, 180)) == -75);
466
471
  try testing.expect(wrap(@as(i32, -75), @as(i32, -180)) == -75);
package/std/meta.zig CHANGED
@@ -15,7 +15,7 @@ test {
15
15
  }
16
16
 
17
17
  /// Returns the variant of an enum type, `T`, which is named `str`, or `null` if no such variant exists.
18
- pub fn stringToEnum(comptime T: type, str: []const u8) ?T {
18
+ pub fn stringToEnum(comptime T: type, tag_name: []const u8) ?T {
19
19
  // Using StaticStringMap here is more performant, but it will start to take too
20
20
  // long to compile if the enum is large enough, due to the current limits of comptime
21
21
  // performance when doing things like constructing lookup maps at comptime.
@@ -23,19 +23,10 @@ pub fn stringToEnum(comptime T: type, str: []const u8) ?T {
23
23
  // - https://github.com/ziglang/zig/issues/4055
24
24
  // - https://github.com/ziglang/zig/issues/3863
25
25
  if (@typeInfo(T).@"enum".field_names.len <= 100) {
26
- const kvs = comptime build_kvs: {
27
- const EnumKV = struct { []const u8, T };
28
- var kvs_array: [@typeInfo(T).@"enum".field_names.len]EnumKV = undefined;
29
- for (@typeInfo(T).@"enum".field_names, 0..) |name, i| {
30
- kvs_array[i] = .{ name, @field(T, name) };
31
- }
32
- break :build_kvs kvs_array[0..];
33
- };
34
- const map = std.StaticStringMap(T).initComptime(kvs);
35
- return map.get(str);
26
+ return std.StaticStringMap(T).initEnum().get(tag_name);
36
27
  } else {
37
28
  inline for (@typeInfo(T).@"enum".field_names) |name| {
38
- if (mem.eql(u8, str, name)) {
29
+ if (mem.eql(u8, tag_name, name)) {
39
30
  return @field(T, name);
40
31
  }
41
32
  }
@@ -0,0 +1,165 @@
1
+ const builtin = @import("builtin");
2
+ const std = @import("../../std.zig");
3
+ const SYS = std.os.linux.SYS;
4
+
5
+ pub const syscall_arg_t = u32;
6
+
7
+ pub fn syscall0(
8
+ number: SYS,
9
+ ) u32 {
10
+ return asm volatile ("trap 0"
11
+ : [ret] "={r0}" (-> u32),
12
+ : [number] "{r7}" (@intFromEnum(number)),
13
+ : .{ .memory = true });
14
+ }
15
+
16
+ pub fn syscall1(
17
+ number: SYS,
18
+ arg1: syscall_arg_t,
19
+ ) u32 {
20
+ return asm volatile ("trap 0"
21
+ : [ret] "={r0}" (-> u32),
22
+ : [number] "{r7}" (@intFromEnum(number)),
23
+ [arg1] "{r0}" (arg1),
24
+ : .{ .memory = true });
25
+ }
26
+
27
+ pub fn syscall2(
28
+ number: SYS,
29
+ arg1: syscall_arg_t,
30
+ arg2: syscall_arg_t,
31
+ ) u32 {
32
+ return asm volatile ("trap 0"
33
+ : [ret] "={r0}" (-> u32),
34
+ : [number] "{r7}" (@intFromEnum(number)),
35
+ [arg1] "{r0}" (arg1),
36
+ [arg2] "{r1}" (arg2),
37
+ : .{ .memory = true });
38
+ }
39
+
40
+ pub fn syscall3(
41
+ number: SYS,
42
+ arg1: syscall_arg_t,
43
+ arg2: syscall_arg_t,
44
+ arg3: syscall_arg_t,
45
+ ) u32 {
46
+ return asm volatile ("trap 0"
47
+ : [ret] "={r0}" (-> u32),
48
+ : [number] "{r7}" (@intFromEnum(number)),
49
+ [arg1] "{r0}" (arg1),
50
+ [arg2] "{r1}" (arg2),
51
+ [arg3] "{r2}" (arg3),
52
+ : .{ .memory = true });
53
+ }
54
+
55
+ pub fn syscall4(
56
+ number: SYS,
57
+ arg1: syscall_arg_t,
58
+ arg2: syscall_arg_t,
59
+ arg3: syscall_arg_t,
60
+ arg4: syscall_arg_t,
61
+ ) u32 {
62
+ return asm volatile ("trap 0"
63
+ : [ret] "={r0}" (-> u32),
64
+ : [number] "{r7}" (@intFromEnum(number)),
65
+ [arg1] "{r0}" (arg1),
66
+ [arg2] "{r1}" (arg2),
67
+ [arg3] "{r2}" (arg3),
68
+ [arg4] "{r3}" (arg4),
69
+ : .{ .memory = true });
70
+ }
71
+
72
+ pub fn syscall5(
73
+ number: SYS,
74
+ arg1: syscall_arg_t,
75
+ arg2: syscall_arg_t,
76
+ arg3: syscall_arg_t,
77
+ arg4: syscall_arg_t,
78
+ arg5: syscall_arg_t,
79
+ ) u32 {
80
+ return asm volatile ("trap 0"
81
+ : [ret] "={r0}" (-> u32),
82
+ : [number] "{r7}" (@intFromEnum(number)),
83
+ [arg1] "{r0}" (arg1),
84
+ [arg2] "{r1}" (arg2),
85
+ [arg3] "{r2}" (arg3),
86
+ [arg4] "{r3}" (arg4),
87
+ [arg5] "{r4}" (arg5),
88
+ : .{ .memory = true });
89
+ }
90
+
91
+ pub fn syscall6(
92
+ number: SYS,
93
+ arg1: syscall_arg_t,
94
+ arg2: syscall_arg_t,
95
+ arg3: syscall_arg_t,
96
+ arg4: syscall_arg_t,
97
+ arg5: syscall_arg_t,
98
+ arg6: syscall_arg_t,
99
+ ) u32 {
100
+ return asm volatile ("trap 0"
101
+ : [ret] "={r0}" (-> u32),
102
+ : [number] "{r7}" (@intFromEnum(number)),
103
+ [arg1] "{r0}" (arg1),
104
+ [arg2] "{r1}" (arg2),
105
+ [arg3] "{r2}" (arg3),
106
+ [arg4] "{r3}" (arg4),
107
+ [arg5] "{r4}" (arg5),
108
+ [arg6] "{r5}" (arg6),
109
+ : .{ .memory = true });
110
+ }
111
+
112
+ pub fn clone() callconv(.naked) u32 {
113
+ // __clone(func, stack, flags, arg, ptid, tls, ctid)
114
+ // r0, r1, r2, r3, +0, +4, +8
115
+ //
116
+ // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
117
+ // r7 r0, r1, r2, r3, r4
118
+ asm volatile (
119
+ \\ // Preserve callee-saved registers.
120
+ \\ mov t0, r4
121
+ \\ mov t1, r7
122
+ \\
123
+ \\ andi r1, r1, -8
124
+ \\
125
+ \\ subi r1, 8
126
+ \\ stw r0, (r1, 0)
127
+ \\ stw r3, (r1, 4)
128
+ \\
129
+ \\ movi r7, 220 // SYS_clone
130
+ \\ mov r0, r2
131
+ \\ ldw r2, (sp, 0)
132
+ \\ ldw r3, (sp, 8)
133
+ \\ ldw r4, (sp, 4)
134
+ \\ trap 0
135
+ \\
136
+ \\ cmpnei r0, 0
137
+ \\ jbf 1f
138
+ \\
139
+ \\ // parent
140
+ \\ mov r7, t1
141
+ \\ mov r4, t0
142
+ \\ rts
143
+ \\
144
+ \\ // child
145
+ \\1:
146
+ );
147
+ if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
148
+ \\ .cfi_undefined lr
149
+ );
150
+ asm volatile (
151
+ \\ movi r8, 0
152
+ \\ movi lr, 0
153
+ \\
154
+ \\ ldw r0, (sp, 4)
155
+ \\ ldw r1, (sp, 0)
156
+ \\ jsr r1
157
+ \\
158
+ \\ movi r7, 93 // SYS_exit
159
+ \\ trap 0
160
+ );
161
+ }
162
+
163
+ pub const time_t = i32;
164
+
165
+ pub const VDSO = void;
@@ -0,0 +1,170 @@
1
+ const builtin = @import("builtin");
2
+ const std = @import("../../std.zig");
3
+ const SYS = std.os.linux.SYS;
4
+
5
+ pub const syscall_arg_t = u32;
6
+
7
+ pub fn syscall0(
8
+ number: SYS,
9
+ ) u32 {
10
+ return asm volatile ("brki r14, 0x8"
11
+ : [ret] "={r3}" (-> u32),
12
+ : [number] "{r12}" (@intFromEnum(number)),
13
+ : .{ .r4 = true, .memory = true });
14
+ }
15
+
16
+ pub fn syscall1(
17
+ number: SYS,
18
+ arg1: syscall_arg_t,
19
+ ) u32 {
20
+ return asm volatile ("brki r14, 0x8"
21
+ : [ret] "={r3}" (-> u32),
22
+ : [number] "{r12}" (@intFromEnum(number)),
23
+ [arg1] "{r5}" (arg1),
24
+ : .{ .r4 = true, .memory = true });
25
+ }
26
+
27
+ pub fn syscall2(
28
+ number: SYS,
29
+ arg1: syscall_arg_t,
30
+ arg2: syscall_arg_t,
31
+ ) u32 {
32
+ return asm volatile ("brki r14, 0x8"
33
+ : [ret] "={r3}" (-> u32),
34
+ : [number] "{r12}" (@intFromEnum(number)),
35
+ [arg1] "{r5}" (arg1),
36
+ [arg2] "{r6}" (arg2),
37
+ : .{ .r4 = true, .memory = true });
38
+ }
39
+
40
+ pub fn syscall3(
41
+ number: SYS,
42
+ arg1: syscall_arg_t,
43
+ arg2: syscall_arg_t,
44
+ arg3: syscall_arg_t,
45
+ ) u32 {
46
+ return asm volatile ("brki r14, 0x8"
47
+ : [ret] "={r3}" (-> u32),
48
+ : [number] "{r12}" (@intFromEnum(number)),
49
+ [arg1] "{r5}" (arg1),
50
+ [arg2] "{r6}" (arg2),
51
+ [arg3] "{r7}" (arg3),
52
+ : .{ .r4 = true, .memory = true });
53
+ }
54
+
55
+ pub fn syscall4(
56
+ number: SYS,
57
+ arg1: syscall_arg_t,
58
+ arg2: syscall_arg_t,
59
+ arg3: syscall_arg_t,
60
+ arg4: syscall_arg_t,
61
+ ) u32 {
62
+ return asm volatile ("brki r14, 0x8"
63
+ : [ret] "={r3}" (-> u32),
64
+ : [number] "{r12}" (@intFromEnum(number)),
65
+ [arg1] "{r5}" (arg1),
66
+ [arg2] "{r6}" (arg2),
67
+ [arg3] "{r7}" (arg3),
68
+ [arg4] "{r8}" (arg4),
69
+ : .{ .r4 = true, .memory = true });
70
+ }
71
+
72
+ pub fn syscall5(
73
+ number: SYS,
74
+ arg1: syscall_arg_t,
75
+ arg2: syscall_arg_t,
76
+ arg3: syscall_arg_t,
77
+ arg4: syscall_arg_t,
78
+ arg5: syscall_arg_t,
79
+ ) u32 {
80
+ return asm volatile ("brki r14, 0x8"
81
+ : [ret] "={r3}" (-> u32),
82
+ : [number] "{r12}" (@intFromEnum(number)),
83
+ [arg1] "{r5}" (arg1),
84
+ [arg2] "{r6}" (arg2),
85
+ [arg3] "{r7}" (arg3),
86
+ [arg4] "{r8}" (arg4),
87
+ [arg5] "{r9}" (arg5),
88
+ : .{ .r4 = true, .memory = true });
89
+ }
90
+
91
+ pub fn syscall6(
92
+ number: SYS,
93
+ arg1: syscall_arg_t,
94
+ arg2: syscall_arg_t,
95
+ arg3: syscall_arg_t,
96
+ arg4: syscall_arg_t,
97
+ arg5: syscall_arg_t,
98
+ arg6: syscall_arg_t,
99
+ ) u32 {
100
+ return asm volatile ("brki r14, 0x8"
101
+ : [ret] "={r3}" (-> u32),
102
+ : [number] "{r12}" (@intFromEnum(number)),
103
+ [arg1] "{r5}" (arg1),
104
+ [arg2] "{r6}" (arg2),
105
+ [arg3] "{r7}" (arg3),
106
+ [arg4] "{r8}" (arg4),
107
+ [arg5] "{r9}" (arg5),
108
+ [arg6] "{r10}" (arg6),
109
+ : .{ .r4 = true, .memory = true });
110
+ }
111
+
112
+ pub fn clone() callconv(.naked) u32 {
113
+ // __clone(func, stack, flags, arg, ptid, tls, ctid)
114
+ // r5, r6, r7, r8, r9, r10, +28
115
+ //
116
+ // syscall(SYS_clone, flags, stack, ptid, ctid, tls)
117
+ // r12 r5, r6, r8, r9, r10
118
+ asm volatile (
119
+ \\ andi r6, r6, -4
120
+ \\
121
+ \\ addi r6, r6, -8
122
+ \\ swi r5, r6, 0
123
+ \\ swi r8, r6, 4
124
+ \\
125
+ \\ ori r12, r0, 120 # SYS_clone
126
+ \\ ori r5, r7, 0
127
+ \\ ori r7, r0, 0 # stack size
128
+ \\ ori r8, r9, 0
129
+ \\ lwi r9, r1, 28
130
+ \\ brki r14, 0x8
131
+ \\ beqi r3, 1f
132
+ \\
133
+ \\ // parent
134
+ \\ rtsd r15, 8
135
+ \\ nop
136
+ \\
137
+ \\ // child
138
+ \\1:
139
+ \\ ori r15, r0, 0
140
+ \\ ori r19, r0, 0
141
+ \\
142
+ \\ lwi r3, r1, 0
143
+ \\ lwi r5, r1, 4
144
+ \\ brald r15, r3
145
+ \\ nop
146
+ \\
147
+ \\ ori r12, r0, 1 # SYS_exit
148
+ \\ brki r14, 0x8
149
+ );
150
+ }
151
+
152
+ pub fn restore() callconv(.naked) noreturn {
153
+ asm volatile (
154
+ \\ brki r14, 0x8
155
+ :
156
+ : [number] "{r7}" (@intFromEnum(SYS.sigreturn)),
157
+ );
158
+ }
159
+
160
+ pub fn restore_rt() callconv(.naked) noreturn {
161
+ asm volatile (
162
+ \\ brki r14, 0x8
163
+ :
164
+ : [number] "{r7}" (@intFromEnum(SYS.rt_sigreturn)),
165
+ );
166
+ }
167
+
168
+ pub const time_t = i32;
169
+
170
+ pub const VDSO = void;