@zigc/lib 0.17.0-dev.340 → 0.17.0-dev.387

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.
@@ -5,6 +5,7 @@ pub const Native = if (@hasDecl(root, "debug") and @hasDecl(root.debug, "CpuCont
5
5
  root.debug.CpuContext
6
6
  else switch (native_arch) {
7
7
  .aarch64, .aarch64_be => Aarch64,
8
+ .alpha => Alpha,
8
9
  .arc, .arceb => Arc,
9
10
  .arm, .armeb, .thumb, .thumbeb => Arm,
10
11
  .csky => Csky,
@@ -13,6 +14,7 @@ else switch (native_arch) {
13
14
  .lanai => Lanai,
14
15
  .loongarch32, .loongarch64 => LoongArch,
15
16
  .m68k => M68k,
17
+ .m88k => M88k,
16
18
  .mips, .mipsel, .mips64, .mips64el => Mips,
17
19
  .or1k => Or1k,
18
20
  .powerpc, .powerpcle, .powerpc64, .powerpc64le => Powerpc,
@@ -61,6 +63,13 @@ pub fn fromPosixSignalContext(ctx_ptr: ?*const anyopaque) ?Native {
61
63
  },
62
64
  .pc = @truncate(uc.mcontext.pc),
63
65
  };
66
+ } else if (native_arch == .m88k and native_os == .openbsd) {
67
+ // OpenBSD makes no effort to clear the V and E bits of the SXIP register when presenting it
68
+ // to user space, so we need to do that here.
69
+ return .{
70
+ .r = uc.mcontext.r,
71
+ .xip = uc.mcontext.xip & ~@as(u32, 0b11),
72
+ };
64
73
  } else if (native_arch.isMIPS32() and native_os == .linux) {
65
74
  // The O32 kABI uses 64-bit fields for some reason.
66
75
  return .{
@@ -103,6 +112,10 @@ pub fn fromPosixSignalContext(ctx_ptr: ?*const anyopaque) ?Native {
103
112
  .sp = uc.mcontext.sp,
104
113
  .pc = uc.mcontext.pc,
105
114
  },
115
+ .alpha => .{
116
+ .r = uc.mcontext.r,
117
+ .pc = uc.mcontext.pc,
118
+ },
106
119
  .csky => .{
107
120
  .r = uc.mcontext.r0_13 ++
108
121
  [_]u32{ uc.mcontext.r14, uc.mcontext.r15 } ++
@@ -293,6 +306,75 @@ const Aarch64 = extern struct {
293
306
  }
294
307
  };
295
308
 
309
+ const Alpha = extern struct {
310
+ /// The numbered general-purpose registers R0 - R31.
311
+ r: [32]u64,
312
+ pc: u64,
313
+
314
+ pub inline fn current() Alpha {
315
+ var ctx: Alpha = undefined;
316
+ asm volatile (
317
+ \\ stq $0 , 0x000($0)
318
+ \\ stq $1 , 0x008($0)
319
+ \\ stq $2 , 0x010($0)
320
+ \\ stq $3 , 0x018($0)
321
+ \\ stq $4 , 0x020($0)
322
+ \\ stq $5 , 0x028($0)
323
+ \\ stq $6 , 0x030($0)
324
+ \\ stq $7 , 0x038($0)
325
+ \\ stq $8 , 0x040($0)
326
+ \\ stq $9 , 0x048($0)
327
+ \\ stq $10, 0x050($0)
328
+ \\ stq $11, 0x058($0)
329
+ \\ stq $12, 0x060($0)
330
+ \\ stq $13, 0x068($0)
331
+ \\ stq $14, 0x070($0)
332
+ \\ stq $15, 0x078($0)
333
+ \\ stq $16, 0x080($0)
334
+ \\ stq $17, 0x088($0)
335
+ \\ stq $18, 0x090($0)
336
+ \\ stq $19, 0x098($0)
337
+ \\ stq $20, 0x0a0($0)
338
+ \\ stq $21, 0x0a8($0)
339
+ \\ stq $22, 0x0b0($0)
340
+ \\ stq $23, 0x0b8($0)
341
+ \\ stq $24, 0x0c0($0)
342
+ \\ stq $25, 0x0c8($0)
343
+ \\ stq $26, 0x0d0($0)
344
+ \\ stq $27, 0x0d8($0)
345
+ \\ stq $28, 0x0e0($0)
346
+ \\ stq $29, 0x0e8($0)
347
+ \\ stq $30, 0x0f0($0)
348
+ \\
349
+ \\ br $1, 1f
350
+ \\1:
351
+ \\ stq $1, 0x100($0)
352
+ :
353
+ : [ctx] "{r0}" (&ctx),
354
+ : .{ .r1 = true, .memory = true });
355
+ return ctx;
356
+ }
357
+
358
+ pub fn getFp(ctx: *const Alpha) u64 {
359
+ return ctx.r[15];
360
+ }
361
+ pub fn getPc(ctx: *const Alpha) u64 {
362
+ return ctx.pc;
363
+ }
364
+
365
+ pub fn dwarfRegisterBytes(ctx: *Aarch64, register_num: u16) DwarfRegisterError![]u8 {
366
+ switch (register_num) {
367
+ 0...31 => return @ptrCast(&ctx.r[register_num]),
368
+ 64 => return @ptrCast(&ctx.pc),
369
+
370
+ 32...63 => return error.UnsupportedRegister, // f0 - f31
371
+ 66 => return error.UnsupportedRegister, // uniq
372
+
373
+ else => return error.InvalidRegister,
374
+ }
375
+ }
376
+ };
377
+
296
378
  /// This is an `extern struct` so that inline assembly in `current` can use field offsets.
297
379
  const Arc = extern struct {
298
380
  /// The numbered general-purpose registers r0 - r31.
@@ -820,6 +902,75 @@ const M68k = extern struct {
820
902
  }
821
903
  };
822
904
 
905
+ /// This is an `extern struct` so that inline assembly in `current` can use field offsets.
906
+ const M88k = extern struct {
907
+ /// The numbered general-purpose registers r0 - r31.
908
+ r: [32]u32,
909
+ xip: u32,
910
+
911
+ pub inline fn current() M88k {
912
+ var ctx: M88k = undefined;
913
+ asm volatile (
914
+ \\ st %%r0, %%r2, 0
915
+ \\ st %%r1, %%r2, 4
916
+ \\ st %%r2, %%r2, 8
917
+ \\ st %%r3, %%r2, 12
918
+ \\ st %%r4, %%r2, 16
919
+ \\ st %%r5, %%r2, 20
920
+ \\ st %%r6, %%r2, 24
921
+ \\ st %%r7, %%r2, 28
922
+ \\ st %%r8, %%r2, 32
923
+ \\ st %%r9, %%r2, 36
924
+ \\ st %%r10, %%r2, 40
925
+ \\ st %%r11, %%r2, 44
926
+ \\ st %%r12, %%r2, 48
927
+ \\ st %%r13, %%r2, 52
928
+ \\ st %%r14, %%r2, 56
929
+ \\ st %%r15, %%r2, 60
930
+ \\ st %%r16, %%r2, 64
931
+ \\ st %%r17, %%r2, 68
932
+ \\ st %%r18, %%r2, 72
933
+ \\ st %%r19, %%r2, 76
934
+ \\ st %%r20, %%r2, 80
935
+ \\ st %%r21, %%r2, 84
936
+ \\ st %%r22, %%r2, 88
937
+ \\ st %%r23, %%r2, 92
938
+ \\ st %%r24, %%r2, 96
939
+ \\ st %%r25, %%r2, 100
940
+ \\ st %%r26, %%r2, 104
941
+ \\ st %%r27, %%r2, 108
942
+ \\ st %%r28, %%r2, 112
943
+ \\ st %%r29, %%r2, 116
944
+ \\ st %%r30, %%r2, 120
945
+ \\ st %%r31, %%r2, 124
946
+ \\ bsr.n 1f
947
+ \\1:
948
+ \\ st %%r1, %%r2, 128
949
+ :
950
+ : [ctx] "{r2}" (&ctx),
951
+ : .{ .r1 = true, .memory = true });
952
+ return ctx;
953
+ }
954
+
955
+ pub fn getFp(ctx: *const M88k) u32 {
956
+ return ctx.r[30];
957
+ }
958
+ pub fn getPc(ctx: *const M88k) u32 {
959
+ return ctx.xip;
960
+ }
961
+
962
+ pub fn dwarfRegisterBytes(ctx: *M88k, register_num: u16) DwarfRegisterError![]u8 {
963
+ switch (register_num) {
964
+ 0...31 => return @ptrCast(&ctx.r[register_num]),
965
+ 64 => return @ptrCast(&ctx.xip),
966
+
967
+ 32...63 => return error.UnsupportedRegister, // x0 - x31
968
+
969
+ else => return error.InvalidRegister,
970
+ }
971
+ }
972
+ };
973
+
823
974
  /// This is an `extern struct` so that inline assembly in `current` can use field offsets.
824
975
  const Mips = extern struct {
825
976
  /// The numbered general-purpose registers r0 - r31. r0 must be zero.
@@ -2256,9 +2407,11 @@ const signal_ucontext_t = switch (native_os) {
2256
2407
  .alpha => extern struct {
2257
2408
  _cookie: i64,
2258
2409
  _mask: i64,
2259
- pc: u64,
2260
- _ps: i64,
2261
- r: [32]u64,
2410
+ mcontext: extern struct {
2411
+ pc: u64,
2412
+ _ps: i64,
2413
+ r: [32]u64,
2414
+ },
2262
2415
  },
2263
2416
  // https://github.com/openbsd/src/blob/42468faed8369d07ae49ae02dd71ec34f59b66cd/sys/arch/arm/include/signal.h
2264
2417
  .arm => extern struct {
@@ -2287,6 +2440,18 @@ const signal_ucontext_t = switch (native_os) {
2287
2440
  r23_29: [7]u32,
2288
2441
  r31: u32,
2289
2442
  },
2443
+ // https://github.com/openbsd/src/blob/42468faed8369d07ae49ae02dd71ec34f59b66cd/sys/arch/m88k/include/signal.h
2444
+ .m88k => extern struct {
2445
+ _cookie: i32,
2446
+ _mask: i32,
2447
+ mcontext: extern struct {
2448
+ r: [32]u32,
2449
+ _epsr: u32,
2450
+ _fpsr: u32,
2451
+ _fpcr: u32,
2452
+ xip: u32,
2453
+ },
2454
+ },
2290
2455
  // https://github.com/openbsd/src/blob/42468faed8369d07ae49ae02dd71ec34f59b66cd/sys/arch/mips64/include/signal.h
2291
2456
  .mips64, .mips64el => extern struct {
2292
2457
  _cookie: i64,
package/std/debug.zig CHANGED
@@ -495,7 +495,7 @@ pub fn defaultPanic(msg: []const u8, first_trace_addr: ?usize) noreturn {
495
495
  if (use_trap_panic) @trap();
496
496
 
497
497
  switch (builtin.os.tag) {
498
- .freestanding, .other, .@"3ds", .vita => {
498
+ .freestanding, .other, .@"3ds", .psp, .vita => {
499
499
  @trap();
500
500
  },
501
501
  .uefi => {
package/std/heap.zig CHANGED
@@ -608,6 +608,7 @@ const page_size_min_default: ?usize = switch (builtin.os.tag) {
608
608
  .hppa => 4 << 10,
609
609
  .x86, .x86_64 => 4 << 10,
610
610
  .thumb, .thumbeb, .arm, .armeb, .aarch64, .aarch64_be => 4 << 10,
611
+ .m88k => 4 << 10,
611
612
  .mips64, .mips64el => 4 << 10,
612
613
  .powerpc, .powerpc64, .powerpc64le, .powerpcle => 4 << 10,
613
614
  .riscv64 => 4 << 10,
@@ -771,6 +772,7 @@ const page_size_max_default: ?usize = switch (builtin.os.tag) {
771
772
  .hppa => 4 << 10,
772
773
  .x86, .x86_64 => 4 << 10,
773
774
  .thumb, .thumbeb, .arm, .armeb, .aarch64, .aarch64_be => 4 << 10,
775
+ .m88k => 4 << 10,
774
776
  .mips64, .mips64el => 16 << 10,
775
777
  .powerpc, .powerpc64, .powerpc64le, .powerpcle => 4 << 10,
776
778
  .riscv64 => 4 << 10,
@@ -1553,6 +1553,77 @@ pub const Clobbers = switch (@import("builtin").cpu.arch) {
1553
1553
  r14: bool = false,
1554
1554
  r15: bool = false,
1555
1555
  },
1556
+ .m88k => packed struct {
1557
+ /// Whether the inline assembly code may perform stores to memory
1558
+ /// addresses other than those derived from input pointer provenance.
1559
+ memory: bool = false,
1560
+
1561
+ r0: bool = false,
1562
+ r1: bool = false,
1563
+ r2: bool = false,
1564
+ r3: bool = false,
1565
+ r4: bool = false,
1566
+ r5: bool = false,
1567
+ r6: bool = false,
1568
+ r7: bool = false,
1569
+ r8: bool = false,
1570
+ r9: bool = false,
1571
+ r10: bool = false,
1572
+ r11: bool = false,
1573
+ r12: bool = false,
1574
+ r13: bool = false,
1575
+ r14: bool = false,
1576
+ r15: bool = false,
1577
+ r16: bool = false,
1578
+ r17: bool = false,
1579
+ r18: bool = false,
1580
+ r19: bool = false,
1581
+ r20: bool = false,
1582
+ r21: bool = false,
1583
+ r22: bool = false,
1584
+ r23: bool = false,
1585
+ r24: bool = false,
1586
+ r25: bool = false,
1587
+ r26: bool = false,
1588
+ r27: bool = false,
1589
+ r28: bool = false,
1590
+ r29: bool = false,
1591
+ r30: bool = false,
1592
+ r31: bool = false,
1593
+
1594
+ x0: bool = false,
1595
+ x1: bool = false,
1596
+ x2: bool = false,
1597
+ x3: bool = false,
1598
+ x4: bool = false,
1599
+ x5: bool = false,
1600
+ x6: bool = false,
1601
+ x7: bool = false,
1602
+ x8: bool = false,
1603
+ x9: bool = false,
1604
+ x10: bool = false,
1605
+ x11: bool = false,
1606
+ x12: bool = false,
1607
+ x13: bool = false,
1608
+ x14: bool = false,
1609
+ x15: bool = false,
1610
+ x16: bool = false,
1611
+ x17: bool = false,
1612
+ x18: bool = false,
1613
+ x19: bool = false,
1614
+ x20: bool = false,
1615
+ x21: bool = false,
1616
+ x22: bool = false,
1617
+ x23: bool = false,
1618
+ x24: bool = false,
1619
+ x25: bool = false,
1620
+ x26: bool = false,
1621
+ x27: bool = false,
1622
+ x28: bool = false,
1623
+ x29: bool = false,
1624
+ x30: bool = false,
1625
+ x31: bool = false,
1626
+ },
1556
1627
  .m68k => packed struct {
1557
1628
  /// Whether the inline assembly code may perform stores to memory
1558
1629
  /// addresses other than those derived from input pointer provenance.
package/std/lang.zig CHANGED
@@ -292,6 +292,8 @@ pub const CallingConvention = union(enum(u8)) {
292
292
  m68k_rtd: CommonOptions,
293
293
  m68k_interrupt: CommonOptions,
294
294
 
295
+ m88k_sysv: CommonOptions,
296
+
295
297
  /// The standard `microblaze`/`microblazeel` calling convention.
296
298
  microblaze_std: CommonOptions,
297
299
  microblaze_interrupt: MicroblazeInterruptOptions,
@@ -0,0 +1,358 @@
1
+ const builtin = @import("builtin");
2
+ const std = @import("../../std.zig");
3
+ const SYS = std.os.linux.SYS;
4
+
5
+ pub fn syscall0(number: SYS) u64 {
6
+ return asm volatile (
7
+ \\ callsys
8
+ \\ beq $19, 1f
9
+ \\ negq $0, $0
10
+ \\1:
11
+ : [ret] "={$0}" (-> u64),
12
+ : [number] "{$0}" (number),
13
+ : .{
14
+ .r1 = true,
15
+ .r2 = true,
16
+ .r3 = true,
17
+ .r4 = true,
18
+ .r5 = true,
19
+ .r6 = true,
20
+ .r7 = true,
21
+ .r8 = true,
22
+ .r22 = true,
23
+ .r23 = true,
24
+ .r24 = true,
25
+ .r25 = true,
26
+ .r27 = true,
27
+ .r28 = true,
28
+ .memory = true,
29
+ .r16 = true,
30
+ .r17 = true,
31
+ .r18 = true,
32
+ .r20 = true,
33
+ .r21 = true,
34
+ });
35
+ }
36
+
37
+ pub fn syscall1(number: SYS, arg1: u64) u64 {
38
+ // These registers are both inputs and clobbers.
39
+ var r16_out: u64 = undefined;
40
+ return asm volatile (
41
+ \\ callsys
42
+ \\ beq $19, 1f
43
+ \\ negq $0, $0
44
+ \\1:
45
+ : [ret] "={$0}" (-> u64),
46
+ [r16_out] "={$16}" (r16_out),
47
+ : [number] "{$0}" (number),
48
+ [arg1] "{$16}" (arg1),
49
+ : .{
50
+ .r1 = true,
51
+ .r2 = true,
52
+ .r3 = true,
53
+ .r4 = true,
54
+ .r5 = true,
55
+ .r6 = true,
56
+ .r7 = true,
57
+ .r8 = true,
58
+ .r22 = true,
59
+ .r23 = true,
60
+ .r24 = true,
61
+ .r25 = true,
62
+ .r27 = true,
63
+ .r28 = true,
64
+ .memory = true,
65
+ .r17 = true,
66
+ .r18 = true,
67
+ .r20 = true,
68
+ .r21 = true,
69
+ });
70
+ }
71
+
72
+ pub fn syscall2(number: SYS, arg1: u64, arg2: u64) u64 {
73
+ // These registers are both inputs and clobbers.
74
+ var r16_out: u64 = undefined;
75
+ var r17_out: u64 = undefined;
76
+ return asm volatile (
77
+ \\ callsys
78
+ \\ beq $19, 1f
79
+ \\ negq $0, $0
80
+ \\1:
81
+ : [ret] "={$0}" (-> u64),
82
+ [r16_out] "={$16}" (r16_out),
83
+ [r17_out] "={$17}" (r17_out),
84
+ : [number] "{$0}" (number),
85
+ [arg1] "{$16}" (arg1),
86
+ [arg2] "{$17}" (arg2),
87
+ : .{
88
+ .r1 = true,
89
+ .r2 = true,
90
+ .r3 = true,
91
+ .r4 = true,
92
+ .r5 = true,
93
+ .r6 = true,
94
+ .r7 = true,
95
+ .r8 = true,
96
+ .r22 = true,
97
+ .r23 = true,
98
+ .r24 = true,
99
+ .r25 = true,
100
+ .r27 = true,
101
+ .r28 = true,
102
+ .memory = true,
103
+ .r18 = true,
104
+ .r20 = true,
105
+ .r21 = true,
106
+ });
107
+ }
108
+
109
+ pub fn syscall3(number: SYS, arg1: u64, arg2: u64, arg3: u64) u64 {
110
+ // These registers are both inputs and clobbers.
111
+ var r16_out: u64 = undefined;
112
+ var r17_out: u64 = undefined;
113
+ var r18_out: u64 = undefined;
114
+ return asm volatile (
115
+ \\ callsys
116
+ \\ beq $19, 1f
117
+ \\ negq $0, $0
118
+ \\1:
119
+ : [ret] "={$0}" (-> u64),
120
+ [r16_out] "={$16}" (r16_out),
121
+ [r17_out] "={$17}" (r17_out),
122
+ [r18_out] "={$18}" (r18_out),
123
+ : [number] "{$0}" (number),
124
+ [arg1] "{$16}" (arg1),
125
+ [arg2] "{$17}" (arg2),
126
+ [arg3] "{$18}" (arg3),
127
+ : .{
128
+ .r1 = true,
129
+ .r2 = true,
130
+ .r3 = true,
131
+ .r4 = true,
132
+ .r5 = true,
133
+ .r6 = true,
134
+ .r7 = true,
135
+ .r8 = true,
136
+ .r22 = true,
137
+ .r23 = true,
138
+ .r24 = true,
139
+ .r25 = true,
140
+ .r27 = true,
141
+ .r28 = true,
142
+ .memory = true,
143
+ .r20 = true,
144
+ .r21 = true,
145
+ });
146
+ }
147
+
148
+ pub fn syscall4(number: SYS, arg1: u64, arg2: u64, arg3: u64, arg4: u64) u64 {
149
+ // These registers are both inputs and clobbers.
150
+ var r16_out: u64 = undefined;
151
+ var r17_out: u64 = undefined;
152
+ var r18_out: u64 = undefined;
153
+ var r19_out: u64 = undefined;
154
+ return asm volatile (
155
+ \\ callsys
156
+ \\ beq $19, 1f
157
+ \\ negq $0, $0
158
+ \\1:
159
+ : [ret] "={$0}" (-> u64),
160
+ [r16_out] "={$16}" (r16_out),
161
+ [r17_out] "={$17}" (r17_out),
162
+ [r18_out] "={$18}" (r18_out),
163
+ [r19_out] "={$19}" (r19_out),
164
+ : [number] "{$0}" (number),
165
+ [arg1] "{$16}" (arg1),
166
+ [arg2] "{$17}" (arg2),
167
+ [arg3] "{$18}" (arg3),
168
+ [arg4] "{$19}" (arg4),
169
+ : .{
170
+ .r1 = true,
171
+ .r2 = true,
172
+ .r3 = true,
173
+ .r4 = true,
174
+ .r5 = true,
175
+ .r6 = true,
176
+ .r7 = true,
177
+ .r8 = true,
178
+ .r22 = true,
179
+ .r23 = true,
180
+ .r24 = true,
181
+ .r25 = true,
182
+ .r27 = true,
183
+ .r28 = true,
184
+ .memory = true,
185
+ .r20 = true,
186
+ .r21 = true,
187
+ });
188
+ }
189
+
190
+ pub fn syscall5(number: SYS, arg1: u64, arg2: u64, arg3: u64, arg4: u64, arg5: u64) u64 {
191
+ // These registers are both inputs and clobbers.
192
+ var r16_out: u64 = undefined;
193
+ var r17_out: u64 = undefined;
194
+ var r18_out: u64 = undefined;
195
+ var r19_out: u64 = undefined;
196
+ var r20_out: u64 = undefined;
197
+ return asm volatile (
198
+ \\ callsys
199
+ \\ beq $19, 1f
200
+ \\ negq $0, $0
201
+ \\1:
202
+ : [ret] "={$0}" (-> u64),
203
+ [r16_out] "={$16}" (r16_out),
204
+ [r17_out] "={$17}" (r17_out),
205
+ [r18_out] "={$18}" (r18_out),
206
+ [r19_out] "={$19}" (r19_out),
207
+ [r20_out] "={$20}" (r20_out),
208
+ : [number] "{$0}" (number),
209
+ [arg1] "{$16}" (arg1),
210
+ [arg2] "{$17}" (arg2),
211
+ [arg3] "{$18}" (arg3),
212
+ [arg4] "{$19}" (arg4),
213
+ [arg5] "{$20}" (arg5),
214
+ : .{
215
+ .r1 = true,
216
+ .r2 = true,
217
+ .r3 = true,
218
+ .r4 = true,
219
+ .r5 = true,
220
+ .r6 = true,
221
+ .r7 = true,
222
+ .r8 = true,
223
+ .r22 = true,
224
+ .r23 = true,
225
+ .r24 = true,
226
+ .r25 = true,
227
+ .r27 = true,
228
+ .r28 = true,
229
+ .memory = true,
230
+ .r21 = true,
231
+ });
232
+ }
233
+
234
+ pub fn syscall6(
235
+ number: SYS,
236
+ arg1: u64,
237
+ arg2: u64,
238
+ arg3: u64,
239
+ arg4: u64,
240
+ arg5: u64,
241
+ arg6: u64,
242
+ ) u64 {
243
+ // These registers are both inputs and clobbers.
244
+ var r16_out: u64 = undefined;
245
+ var r17_out: u64 = undefined;
246
+ var r18_out: u64 = undefined;
247
+ var r19_out: u64 = undefined;
248
+ var r20_out: u64 = undefined;
249
+ var r21_out: u64 = undefined;
250
+ return asm volatile (
251
+ \\ callsys
252
+ \\ beq $19, 1f
253
+ \\ negq $0, $0
254
+ \\1:
255
+ : [ret] "={$0}" (-> u64),
256
+ [r16_out] "={$16}" (r16_out),
257
+ [r17_out] "={$17}" (r17_out),
258
+ [r18_out] "={$18}" (r18_out),
259
+ [r19_out] "={$19}" (r19_out),
260
+ [r20_out] "={$20}" (r20_out),
261
+ [r21_out] "={$21}" (r21_out),
262
+ : [number] "{$0}" (number),
263
+ [arg1] "{$16}" (arg1),
264
+ [arg2] "{$17}" (arg2),
265
+ [arg3] "{$18}" (arg3),
266
+ [arg4] "{$19}" (arg4),
267
+ [arg5] "{$20}" (arg5),
268
+ [arg6] "{$21}" (arg6),
269
+ : .{
270
+ .r1 = true,
271
+ .r2 = true,
272
+ .r3 = true,
273
+ .r4 = true,
274
+ .r5 = true,
275
+ .r6 = true,
276
+ .r7 = true,
277
+ .r8 = true,
278
+ .r22 = true,
279
+ .r23 = true,
280
+ .r24 = true,
281
+ .r25 = true,
282
+ .r27 = true,
283
+ .r28 = true,
284
+ .memory = true,
285
+ });
286
+ }
287
+
288
+ pub fn clone() callconv(.naked) u64 {
289
+ // __clone(func, stack, flags, arg, ptid, tls, ctid)
290
+ // a0, a1, a2, a3, a4, a5, +0
291
+ //
292
+ // syscall(SYS_clone, flags, stack, ptid, ctid, tls)
293
+ // v0 a0, a1, a2, a3, a4
294
+ asm volatile (
295
+ // a0 = $16, a1 = $17, a2 = $18, a3 = $19,
296
+ // a4 = $20, a5 = $21, sp = $30, v0 = $0
297
+ \\ # Save function pointer and argument pointer on new thread stack
298
+ \\ ldi $1, -8
299
+ \\ and $17, $17, $1
300
+ \\ lda $17, -16($17)
301
+ \\ stq $16, 0($17)
302
+ \\ stq $19, 8($17)
303
+ \\
304
+ \\ # Shuffle (fn,sp,fl,arg,ptid,tls,ctid) to (fl,sp,ptid,ctid,tls)
305
+ \\ mov $18, $16
306
+ \\ mov $20, $18
307
+ \\ ldq $19, 0($30)
308
+ \\ mov $21, $20
309
+ \\
310
+ \\ # Actual syscall
311
+ \\ ldi $0, 312 # SYS_clone
312
+ \\ callsys
313
+ \\ beq $19, 1f
314
+ \\ negq $0, $0
315
+ \\ ret
316
+ \\1:
317
+ \\ beq $0, 2f
318
+ \\ ret
319
+ \\2:
320
+ );
321
+ if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
322
+ // ra = $26
323
+ \\ .cfi_undefined $26
324
+ );
325
+ asm volatile (
326
+ // v0 = $0, t9 = $23, a0 = $16, ra = $26, sp = $30, fp = $15
327
+ \\ mov 0, $15
328
+ \\
329
+ \\ ldq $23, 0($30)
330
+ \\ ldq $16, 8($30)
331
+ \\ lda $30, 16($30)
332
+ \\ jsr $26, ($23)
333
+ \\
334
+ \\ mov $0, $16
335
+ \\ ldi $0, 1 # SYS_EXIT
336
+ \\ callsys
337
+ );
338
+ }
339
+
340
+ pub fn restore() noreturn {
341
+ asm volatile (
342
+ // v0 = $0, a0 = $16, sp = $30
343
+ \\ mov $30, $16
344
+ \\ ldi $0, 103 # SIGRETURN
345
+ \\ callsys
346
+ );
347
+ }
348
+
349
+ pub fn restore_rt() noreturn {
350
+ asm volatile (
351
+ // v0 = $0, a0 = $16, sp = $30
352
+ \\ mov $30, $16
353
+ \\ ldi $0, 351 # RT_SIGRETURN
354
+ \\ callsys
355
+ );
356
+ }
357
+
358
+ pub const VDSO = void;