| author | |
| committer | |
| log | 645a38aeb69846b7b692fabdd63f62d6e5a17464 |
| tree | 99c4f0f99473166983a22483d46a0bfc193f7038 |
| parent | 3391ad7a9091edec0b368b0e98e61ec02043e91b |
| parent | 8a5899f53c50fc59168ecb80fa804bd9eb653fea |
Reviewed-on: https://codeberg.org/ziglang/zig/pulls/356136 files changed, 328 insertions(+), 40 deletions(-)
lib/std/Thread.zig+1-1| ... | ... | @@ -1376,7 +1376,7 @@ const LinuxThreadImpl = struct { |
| 1376 | 1376 | \\ mov %%g1, %%o0 // ptr |
| 1377 | 1377 | \\ mov %%g2, %%o1 // len |
| 1378 | 1378 | \\ mov 73, %%g1 // SYS_munmap |
| 1379 | \\ t 0x3 # ST_FLUSH_WINDOWS | |
| 1379 | \\ t 0x3 // ST_FLUSH_WINDOWS | |
| 1380 | 1380 | \\ t 0x10 |
| 1381 | 1381 | \\ mov 1, %%g1 // SYS_exit |
| 1382 | 1382 | \\ mov 0, %%o0 |
lib/std/os.zig-4| ... | ... | @@ -15,8 +15,6 @@ pub fn targetRequiresLibC(target: *const std.Target) bool { |
| 15 | 15 | if (target.requiresLibC()) return true; |
| 16 | 16 | return switch (target.os.tag) { |
| 17 | 17 | .linux => switch (target.cpu.arch) { |
| 18 | // https://codeberg.org/ziglang/zig/issues/30942 | |
| 19 | .csky, | |
| 20 | 18 | // https://codeberg.org/ziglang/zig/issues/30943 |
| 21 | 19 | .hppa, |
| 22 | 20 | .hppa64, |
| ... | ... | @@ -26,8 +24,6 @@ pub fn targetRequiresLibC(target: *const std.Target) bool { |
| 26 | 24 | // https://codeberg.org/ziglang/zig/issues/30946 |
| 27 | 25 | .sh, |
| 28 | 26 | .sheb, |
| 29 | // https://codeberg.org/ziglang/zig/issues/30945 | |
| 30 | .sparc, | |
| 31 | 27 | => true, |
| 32 | 28 | else => false, |
| 33 | 29 | }, |
lib/std/os/linux.zig+5-4| ... | ... | @@ -51,6 +51,7 @@ const arch_bits = switch (native_arch) { |
| 51 | 51 | .riscv32 => @import("linux/riscv32.zig"), |
| 52 | 52 | .riscv64 => @import("linux/riscv64.zig"), |
| 53 | 53 | .s390x => @import("linux/s390x.zig"), |
| 54 | .sparc => @import("linux/sparc.zig"), | |
| 54 | 55 | .sparc64 => @import("linux/sparc64.zig"), |
| 55 | 56 | .x86 => @import("linux/x86.zig"), |
| 56 | 57 | .x86_64 => switch (builtin.abi) { |
| ... | ... | @@ -223,7 +224,7 @@ pub const MAP = switch (native_arch) { |
| 223 | 224 | UNINITIALIZED: bool = false, |
| 224 | 225 | _: u5 = 0, |
| 225 | 226 | }, |
| 226 | .sparc64 => packed struct(u32) { | |
| 227 | .sparc, .sparc64 => packed struct(u32) { | |
| 227 | 228 | TYPE: MAP_TYPE, |
| 228 | 229 | FIXED: bool = false, |
| 229 | 230 | ANONYMOUS: bool = false, |
| ... | ... | @@ -444,7 +445,7 @@ pub const O = switch (native_arch) { |
| 444 | 445 | TMPFILE: bool = false, |
| 445 | 446 | _23: u9 = 0, |
| 446 | 447 | }, |
| 447 | .sparc64 => packed struct(u32) { | |
| 448 | .sparc, .sparc64 => packed struct(u32) { | |
| 448 | 449 | ACCMODE: ACCMODE = .RDONLY, |
| 449 | 450 | _2: u1 = 0, |
| 450 | 451 | APPEND: bool = false, |
| ... | ... | @@ -1994,7 +1995,7 @@ pub const F = struct { |
| 1994 | 1995 | const SETLKW = 7; |
| 1995 | 1996 | }, |
| 1996 | 1997 | }, |
| 1997 | .alpha, .sparc64 => struct { | |
| 1998 | .alpha, .sparc, .sparc64 => struct { | |
| 1998 | 1999 | const GETLK = 7; |
| 1999 | 2000 | const SETLK = 8; |
| 2000 | 2001 | const SETLKW = 9; |
| ... | ... | @@ -6585,7 +6586,7 @@ const TFD_TIMER = packed struct(u32) { |
| 6585 | 6586 | }; |
| 6586 | 6587 | |
| 6587 | 6588 | pub const TFD = switch (native_arch) { |
| 6588 | .sparc64 => packed struct(u32) { | |
| 6589 | .sparc, .sparc64 => packed struct(u32) { | |
| 6589 | 6590 | _0: u14 = 0, |
| 6590 | 6591 | NONBLOCK: bool = false, |
| 6591 | 6592 | _15: u7 = 0, |
lib/std/os/linux/sparc.zig created+277| ... | ... | @@ -0,0 +1,277 @@ |
| 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 ( | |
| 11 | \\ t 0x10 | |
| 12 | \\ bcc 1f | |
| 13 | \\ nop | |
| 14 | \\ neg %%o0 | |
| 15 | \\1: | |
| 16 | : [ret] "={o0}" (-> u32), | |
| 17 | : [number] "{g1}" (@intFromEnum(number)), | |
| 18 | : .{ .memory = true, .xcc = true, .o1 = true, .o2 = true, .o3 = true, .o4 = true, .o5 = true, .o7 = true }); | |
| 19 | } | |
| 20 | ||
| 21 | pub fn syscall1( | |
| 22 | number: SYS, | |
| 23 | arg1: syscall_arg_t, | |
| 24 | ) u32 { | |
| 25 | return asm volatile ( | |
| 26 | \\ t 0x10 | |
| 27 | \\ bcc 1f | |
| 28 | \\ nop | |
| 29 | \\ neg %%o0 | |
| 30 | \\1: | |
| 31 | : [ret] "={o0}" (-> u32), | |
| 32 | : [number] "{g1}" (@intFromEnum(number)), | |
| 33 | [arg1] "{o0}" (arg1), | |
| 34 | : .{ .memory = true, .xcc = true, .o1 = true, .o2 = true, .o3 = true, .o4 = true, .o5 = true, .o7 = true }); | |
| 35 | } | |
| 36 | ||
| 37 | pub fn syscall2( | |
| 38 | number: SYS, | |
| 39 | arg1: syscall_arg_t, | |
| 40 | arg2: syscall_arg_t, | |
| 41 | ) u32 { | |
| 42 | return asm volatile ( | |
| 43 | \\ t 0x10 | |
| 44 | \\ bcc 1f | |
| 45 | \\ nop | |
| 46 | \\ neg %%o0 | |
| 47 | \\1: | |
| 48 | : [ret] "={o0}" (-> u32), | |
| 49 | : [number] "{g1}" (@intFromEnum(number)), | |
| 50 | [arg1] "{o0}" (arg1), | |
| 51 | [arg2] "{o1}" (arg2), | |
| 52 | : .{ .memory = true, .xcc = true, .o1 = true, .o2 = true, .o3 = true, .o4 = true, .o5 = true, .o7 = true }); | |
| 53 | } | |
| 54 | ||
| 55 | pub fn syscall3( | |
| 56 | number: SYS, | |
| 57 | arg1: syscall_arg_t, | |
| 58 | arg2: syscall_arg_t, | |
| 59 | arg3: syscall_arg_t, | |
| 60 | ) u32 { | |
| 61 | return asm volatile ( | |
| 62 | \\ t 0x10 | |
| 63 | \\ bcc 1f | |
| 64 | \\ nop | |
| 65 | \\ neg %%o0 | |
| 66 | \\1: | |
| 67 | : [ret] "={o0}" (-> u32), | |
| 68 | : [number] "{g1}" (@intFromEnum(number)), | |
| 69 | [arg1] "{o0}" (arg1), | |
| 70 | [arg2] "{o1}" (arg2), | |
| 71 | [arg3] "{o2}" (arg3), | |
| 72 | : .{ .memory = true, .xcc = true, .o1 = true, .o2 = true, .o3 = true, .o4 = true, .o5 = true, .o7 = true }); | |
| 73 | } | |
| 74 | ||
| 75 | pub fn syscall4( | |
| 76 | number: SYS, | |
| 77 | arg1: syscall_arg_t, | |
| 78 | arg2: syscall_arg_t, | |
| 79 | arg3: syscall_arg_t, | |
| 80 | arg4: syscall_arg_t, | |
| 81 | ) u32 { | |
| 82 | return asm volatile ( | |
| 83 | \\ t 0x10 | |
| 84 | \\ bcc 1f | |
| 85 | \\ nop | |
| 86 | \\ neg %%o0 | |
| 87 | \\1: | |
| 88 | : [ret] "={o0}" (-> u32), | |
| 89 | : [number] "{g1}" (@intFromEnum(number)), | |
| 90 | [arg1] "{o0}" (arg1), | |
| 91 | [arg2] "{o1}" (arg2), | |
| 92 | [arg3] "{o2}" (arg3), | |
| 93 | [arg4] "{o3}" (arg4), | |
| 94 | : .{ .memory = true, .xcc = true, .o1 = true, .o2 = true, .o3 = true, .o4 = true, .o5 = true, .o7 = true }); | |
| 95 | } | |
| 96 | ||
| 97 | pub fn syscall5( | |
| 98 | number: SYS, | |
| 99 | arg1: syscall_arg_t, | |
| 100 | arg2: syscall_arg_t, | |
| 101 | arg3: syscall_arg_t, | |
| 102 | arg4: syscall_arg_t, | |
| 103 | arg5: syscall_arg_t, | |
| 104 | ) u32 { | |
| 105 | return asm volatile ( | |
| 106 | \\ t 0x10 | |
| 107 | \\ bcc 1f | |
| 108 | \\ nop | |
| 109 | \\ neg %%o0 | |
| 110 | \\1: | |
| 111 | : [ret] "={o0}" (-> u32), | |
| 112 | : [number] "{g1}" (@intFromEnum(number)), | |
| 113 | [arg1] "{o0}" (arg1), | |
| 114 | [arg2] "{o1}" (arg2), | |
| 115 | [arg3] "{o2}" (arg3), | |
| 116 | [arg4] "{o3}" (arg4), | |
| 117 | [arg5] "{o4}" (arg5), | |
| 118 | : .{ .memory = true, .xcc = true, .o1 = true, .o2 = true, .o3 = true, .o4 = true, .o5 = true, .o7 = true }); | |
| 119 | } | |
| 120 | ||
| 121 | pub fn syscall6( | |
| 122 | number: SYS, | |
| 123 | arg1: syscall_arg_t, | |
| 124 | arg2: syscall_arg_t, | |
| 125 | arg3: syscall_arg_t, | |
| 126 | arg4: syscall_arg_t, | |
| 127 | arg5: syscall_arg_t, | |
| 128 | arg6: syscall_arg_t, | |
| 129 | ) u32 { | |
| 130 | return asm volatile ( | |
| 131 | \\ t 0x10 | |
| 132 | \\ bcc 1f | |
| 133 | \\ nop | |
| 134 | \\ neg %%o0 | |
| 135 | \\1: | |
| 136 | : [ret] "={o0}" (-> u32), | |
| 137 | : [number] "{g1}" (@intFromEnum(number)), | |
| 138 | [arg1] "{o0}" (arg1), | |
| 139 | [arg2] "{o1}" (arg2), | |
| 140 | [arg3] "{o2}" (arg3), | |
| 141 | [arg4] "{o3}" (arg4), | |
| 142 | [arg5] "{o4}" (arg5), | |
| 143 | [arg6] "{o5}" (arg6), | |
| 144 | : .{ .memory = true, .xcc = true, .o1 = true, .o2 = true, .o3 = true, .o4 = true, .o5 = true, .o7 = true }); | |
| 145 | } | |
| 146 | ||
| 147 | pub fn syscall_pipe( | |
| 148 | fd: *[2]std.os.linux.fd_t, | |
| 149 | ) u32 { | |
| 150 | return asm volatile ( | |
| 151 | \\ mov %[arg], %%g3 | |
| 152 | \\ t 0x10 | |
| 153 | \\ bcc 1f | |
| 154 | \\ nop | |
| 155 | \\ # Return the error code | |
| 156 | \\ ba 2f | |
| 157 | \\ neg %%o0 | |
| 158 | \\1: | |
| 159 | \\ st %%o0, [%%g3+0] | |
| 160 | \\ st %%o1, [%%g3+4] | |
| 161 | \\ clr %%o0 | |
| 162 | \\2: | |
| 163 | : [ret] "={o0}" (-> u32), | |
| 164 | : [number] "{g1}" (@intFromEnum(SYS.pipe)), | |
| 165 | [arg] "r" (fd), | |
| 166 | : .{ .memory = true, .g3 = true }); | |
| 167 | } | |
| 168 | ||
| 169 | pub fn syscall_fork() u32 { | |
| 170 | // Linux/sparc fork() returns two values in %o0 and %o1: | |
| 171 | // - On the parent's side, %o0 is the child's PID and %o1 is 0. | |
| 172 | // - On the child's side, %o0 is the parent's PID and %o1 is 1. | |
| 173 | // We need to clear the child's %o0 so that the return values | |
| 174 | // conform to the libc convention. | |
| 175 | return asm volatile ( | |
| 176 | \\ t 0x10 | |
| 177 | \\ bcc 1f | |
| 178 | \\ nop | |
| 179 | \\ ba 2f | |
| 180 | \\ neg %%o0 | |
| 181 | \\1: | |
| 182 | \\ # Clear the child's %%o0 | |
| 183 | \\ dec %%o1 | |
| 184 | \\ and %%o1, %%o0, %%o0 | |
| 185 | \\2: | |
| 186 | : [ret] "={o0}" (-> u32), | |
| 187 | : [number] "{g1}" (@intFromEnum(SYS.fork)), | |
| 188 | : .{ .memory = true, .xcc = true, .o1 = true, .o2 = true, .o3 = true, .o4 = true, .o5 = true, .o7 = true }); | |
| 189 | } | |
| 190 | ||
| 191 | pub fn clone() callconv(.naked) u32 { | |
| 192 | // __clone(func, stack, flags, arg, ptid, tls, ctid) | |
| 193 | // i0, i1, i2, i3, i4, i5, sp | |
| 194 | // | |
| 195 | // syscall(SYS_clone, flags, stack, ptid, tls, ctid) | |
| 196 | // g1 o0, o1, o2, o3, o4 | |
| 197 | asm volatile ( | |
| 198 | \\ save %%sp, -96, %%sp | |
| 199 | \\ | |
| 200 | \\ // clone() on SPARC can fail with EFAULT if %%sp points to uncommitted memory, so flush | |
| 201 | \\ // all register windows up to this point to ensure that the kernel has enough committed | |
| 202 | \\ // memory for its stack frame. | |
| 203 | \\ save %%sp, -96, %%sp | |
| 204 | \\ t 0x3 | |
| 205 | \\ restore | |
| 206 | \\ | |
| 207 | \\ # Save the func pointer and the arg pointer | |
| 208 | \\ mov %%i0, %%g2 | |
| 209 | \\ mov %%i3, %%g3 | |
| 210 | \\ | |
| 211 | \\ # Shuffle the arguments | |
| 212 | \\ mov 217, %%g1 // SYS_clone | |
| 213 | \\ mov %%i2, %%o0 | |
| 214 | \\ | |
| 215 | \\ # Align, and add some extra space for the initial frame | |
| 216 | \\ and %%i1, -8, %%i1 | |
| 217 | \\ sub %%i1, 96 + 2047, %%o1 | |
| 218 | \\ | |
| 219 | \\ mov %%i4, %%o2 | |
| 220 | \\ mov %%i5, %%o3 | |
| 221 | \\ ld [%%fp + 92 + 2047], %%o4 | |
| 222 | \\ t 0x10 | |
| 223 | \\ bcs 1f | |
| 224 | \\ nop | |
| 225 | \\ # The child pid is returned in o0 while o1 tells if this | |
| 226 | \\ # process is the child (=1) or the parent (=0). | |
| 227 | \\ tst %%o1 | |
| 228 | \\ bne 2f | |
| 229 | \\ nop | |
| 230 | \\ | |
| 231 | \\ # Parent process, return the child pid | |
| 232 | \\ mov %%o0, %%i0 | |
| 233 | \\ ret | |
| 234 | \\ restore | |
| 235 | \\ | |
| 236 | \\1: | |
| 237 | \\ # The syscall failed | |
| 238 | \\ sub %%g0, %%o0, %%i0 | |
| 239 | \\ ret | |
| 240 | \\ restore | |
| 241 | \\ | |
| 242 | \\2: | |
| 243 | \\ # Child process | |
| 244 | ); | |
| 245 | if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile ( | |
| 246 | \\ .cfi_undefined %%i7 | |
| 247 | ); | |
| 248 | asm volatile ( | |
| 249 | \\ mov %%g0, %%fp | |
| 250 | \\ mov %%g0, %%i7 | |
| 251 | \\ | |
| 252 | \\ # call func(arg) | |
| 253 | \\ call %%g2 | |
| 254 | \\ mov %%g3, %%o0 | |
| 255 | \\ # Exit | |
| 256 | \\ mov 1, %%g1 // SYS_exit | |
| 257 | \\ t 0x10 | |
| 258 | ); | |
| 259 | } | |
| 260 | ||
| 261 | pub const restore = restore_rt; | |
| 262 | ||
| 263 | // Need to use C ABI here instead of naked | |
| 264 | // to prevent an infinite loop when calling rt_sigreturn. | |
| 265 | pub fn restore_rt() callconv(.c) void { | |
| 266 | return asm volatile ("t 0x10" | |
| 267 | : | |
| 268 | : [number] "{g1}" (@intFromEnum(SYS.rt_sigreturn)), | |
| 269 | : .{ .memory = true, .xcc = true, .o0 = true, .o1 = true, .o2 = true, .o3 = true, .o4 = true, .o5 = true, .o7 = true }); | |
| 270 | } | |
| 271 | ||
| 272 | pub const VDSO = struct { | |
| 273 | pub const CGT_SYM = "__vdso_clock_gettime"; | |
| 274 | pub const CGT_VER = "LINUX_2.6"; | |
| 275 | }; | |
| 276 | ||
| 277 | pub const time_t = i32; |
lib/std/os/linux/sparc64.zig+44-30| ... | ... | @@ -10,9 +10,9 @@ pub fn syscall0( |
| 10 | 10 | return asm volatile ( |
| 11 | 11 | \\ t 0x6d |
| 12 | 12 | \\ bcc,pt %%xcc, 1f |
| 13 | \\ nop | |
| 13 | \\ nop | |
| 14 | 14 | \\ neg %%o0 |
| 15 | \\ 1: | |
| 15 | \\1: | |
| 16 | 16 | : [ret] "={o0}" (-> u64), |
| 17 | 17 | : [number] "{g1}" (@intFromEnum(number)), |
| 18 | 18 | : .{ .memory = true, .xcc = true, .o1 = true, .o2 = true, .o3 = true, .o4 = true, .o5 = true, .o7 = true }); |
| ... | ... | @@ -25,9 +25,9 @@ pub fn syscall1( |
| 25 | 25 | return asm volatile ( |
| 26 | 26 | \\ t 0x6d |
| 27 | 27 | \\ bcc,pt %%xcc, 1f |
| 28 | \\ nop | |
| 28 | \\ nop | |
| 29 | 29 | \\ neg %%o0 |
| 30 | \\ 1: | |
| 30 | \\1: | |
| 31 | 31 | : [ret] "={o0}" (-> u64), |
| 32 | 32 | : [number] "{g1}" (@intFromEnum(number)), |
| 33 | 33 | [arg1] "{o0}" (arg1), |
| ... | ... | @@ -42,9 +42,9 @@ pub fn syscall2( |
| 42 | 42 | return asm volatile ( |
| 43 | 43 | \\ t 0x6d |
| 44 | 44 | \\ bcc,pt %%xcc, 1f |
| 45 | \\ nop | |
| 45 | \\ nop | |
| 46 | 46 | \\ neg %%o0 |
| 47 | \\ 1: | |
| 47 | \\1: | |
| 48 | 48 | : [ret] "={o0}" (-> u64), |
| 49 | 49 | : [number] "{g1}" (@intFromEnum(number)), |
| 50 | 50 | [arg1] "{o0}" (arg1), |
| ... | ... | @@ -61,9 +61,9 @@ pub fn syscall3( |
| 61 | 61 | return asm volatile ( |
| 62 | 62 | \\ t 0x6d |
| 63 | 63 | \\ bcc,pt %%xcc, 1f |
| 64 | \\ nop | |
| 64 | \\ nop | |
| 65 | 65 | \\ neg %%o0 |
| 66 | \\ 1: | |
| 66 | \\1: | |
| 67 | 67 | : [ret] "={o0}" (-> u64), |
| 68 | 68 | : [number] "{g1}" (@intFromEnum(number)), |
| 69 | 69 | [arg1] "{o0}" (arg1), |
| ... | ... | @@ -82,9 +82,9 @@ pub fn syscall4( |
| 82 | 82 | return asm volatile ( |
| 83 | 83 | \\ t 0x6d |
| 84 | 84 | \\ bcc,pt %%xcc, 1f |
| 85 | \\ nop | |
| 85 | \\ nop | |
| 86 | 86 | \\ neg %%o0 |
| 87 | \\ 1: | |
| 87 | \\1: | |
| 88 | 88 | : [ret] "={o0}" (-> u64), |
| 89 | 89 | : [number] "{g1}" (@intFromEnum(number)), |
| 90 | 90 | [arg1] "{o0}" (arg1), |
| ... | ... | @@ -105,9 +105,9 @@ pub fn syscall5( |
| 105 | 105 | return asm volatile ( |
| 106 | 106 | \\ t 0x6d |
| 107 | 107 | \\ bcc,pt %%xcc, 1f |
| 108 | \\ nop | |
| 108 | \\ nop | |
| 109 | 109 | \\ neg %%o0 |
| 110 | \\ 1: | |
| 110 | \\1: | |
| 111 | 111 | : [ret] "={o0}" (-> u64), |
| 112 | 112 | : [number] "{g1}" (@intFromEnum(number)), |
| 113 | 113 | [arg1] "{o0}" (arg1), |
| ... | ... | @@ -130,9 +130,9 @@ pub fn syscall6( |
| 130 | 130 | return asm volatile ( |
| 131 | 131 | \\ t 0x6d |
| 132 | 132 | \\ bcc,pt %%xcc, 1f |
| 133 | \\ nop | |
| 133 | \\ nop | |
| 134 | 134 | \\ neg %%o0 |
| 135 | \\ 1: | |
| 135 | \\1: | |
| 136 | 136 | : [ret] "={o0}" (-> u64), |
| 137 | 137 | : [number] "{g1}" (@intFromEnum(number)), |
| 138 | 138 | [arg1] "{o0}" (arg1), |
| ... | ... | @@ -151,10 +151,10 @@ pub fn syscall_pipe( |
| 151 | 151 | \\ mov %[arg], %%g3 |
| 152 | 152 | \\ t 0x6d |
| 153 | 153 | \\ bcc,pt %%xcc, 1f |
| 154 | \\ nop | |
| 154 | \\ nop | |
| 155 | 155 | \\ # Return the error code |
| 156 | 156 | \\ ba 2f |
| 157 | \\ neg %%o0 | |
| 157 | \\ neg %%o0 | |
| 158 | 158 | \\1: |
| 159 | 159 | \\ st %%o0, [%%g3+0] |
| 160 | 160 | \\ st %%o1, [%%g3+4] |
| ... | ... | @@ -175,14 +175,14 @@ pub fn syscall_fork() u64 { |
| 175 | 175 | return asm volatile ( |
| 176 | 176 | \\ t 0x6d |
| 177 | 177 | \\ bcc,pt %%xcc, 1f |
| 178 | \\ nop | |
| 178 | \\ nop | |
| 179 | 179 | \\ ba 2f |
| 180 | \\ neg %%o0 | |
| 181 | \\ 1: | |
| 180 | \\ neg %%o0 | |
| 181 | \\1: | |
| 182 | 182 | \\ # Clear the child's %%o0 |
| 183 | 183 | \\ dec %%o1 |
| 184 | 184 | \\ and %%o1, %%o0, %%o0 |
| 185 | \\ 2: | |
| 185 | \\2: | |
| 186 | 186 | : [ret] "={o0}" (-> u64), |
| 187 | 187 | : [number] "{g1}" (@intFromEnum(SYS.fork)), |
| 188 | 188 | : .{ .memory = true, .xcc = true, .o1 = true, .o2 = true, .o3 = true, .o4 = true, .o5 = true, .o7 = true }); |
| ... | ... | @@ -196,33 +196,48 @@ pub fn clone() callconv(.naked) u64 { |
| 196 | 196 | // g1 o0, o1, o2, o3, o4 |
| 197 | 197 | asm volatile ( |
| 198 | 198 | \\ save %%sp, -192, %%sp |
| 199 | \\ | |
| 200 | \\ // clone() on SPARC can fail with EFAULT if %%sp points to uncommitted memory, so flush | |
| 201 | \\ // all register windows up to this point to ensure that the kernel has enough committed | |
| 202 | \\ // memory for its stack frame. | |
| 203 | \\ save %%sp, -192, %%sp | |
| 204 | \\ flushw | |
| 205 | \\ restore | |
| 206 | \\ | |
| 199 | 207 | \\ # Save the func pointer and the arg pointer |
| 200 | 208 | \\ mov %%i0, %%g2 |
| 201 | 209 | \\ mov %%i3, %%g3 |
| 210 | \\ | |
| 202 | 211 | \\ # Shuffle the arguments |
| 203 | 212 | \\ mov 217, %%g1 // SYS_clone |
| 204 | 213 | \\ mov %%i2, %%o0 |
| 205 | \\ # Add some extra space for the initial frame | |
| 206 | \\ sub %%i1, 176 + 2047, %%o1 | |
| 214 | \\ | |
| 215 | \\ # Align, and add some extra space for the initial frame | |
| 216 | \\ and %%i1, -16, %%i1 | |
| 217 | \\ sub %%i1, 192 + 2047, %%o1 | |
| 218 | \\ | |
| 207 | 219 | \\ mov %%i4, %%o2 |
| 208 | 220 | \\ mov %%i5, %%o3 |
| 209 | \\ ldx [%%fp + 0x8af], %%o4 | |
| 221 | \\ ldx [%%fp + 176 + 2047], %%o4 | |
| 210 | 222 | \\ t 0x6d |
| 211 | 223 | \\ bcs,pn %%xcc, 1f |
| 212 | \\ nop | |
| 224 | \\ nop | |
| 213 | 225 | \\ # The child pid is returned in o0 while o1 tells if this |
| 214 | \\ # process is # the child (=1) or the parent (=0). | |
| 226 | \\ # process is the child (=1) or the parent (=0). | |
| 215 | 227 | \\ brnz %%o1, 2f |
| 216 | \\ nop | |
| 228 | \\ nop | |
| 229 | \\ | |
| 217 | 230 | \\ # Parent process, return the child pid |
| 218 | 231 | \\ mov %%o0, %%i0 |
| 219 | 232 | \\ ret |
| 220 | \\ restore | |
| 233 | \\ restore | |
| 234 | \\ | |
| 221 | 235 | \\1: |
| 222 | 236 | \\ # The syscall failed |
| 223 | 237 | \\ sub %%g0, %%o0, %%i0 |
| 224 | 238 | \\ ret |
| 225 | \\ restore | |
| 239 | \\ restore | |
| 240 | \\ | |
| 226 | 241 | \\2: |
| 227 | 242 | \\ # Child process |
| 228 | 243 | ); |
| ... | ... | @@ -234,9 +249,8 @@ pub fn clone() callconv(.naked) u64 { |
| 234 | 249 | \\ mov %%g0, %%i7 |
| 235 | 250 | \\ |
| 236 | 251 | \\ # call func(arg) |
| 237 | \\ mov %%g0, %%fp | |
| 238 | 252 | \\ call %%g2 |
| 239 | \\ mov %%g3, %%o0 | |
| 253 | \\ mov %%g3, %%o0 | |
| 240 | 254 | \\ # Exit |
| 241 | 255 | \\ mov 1, %%g1 // SYS_exit |
| 242 | 256 | \\ t 0x6d |
lib/std/zig/system.zig+1-1| ... | ... | @@ -152,7 +152,7 @@ pub fn getExternalExecutor(io: Io, candidate: *const std.Target, options: GetExt |
| 152 | 152 | // TODO: Actually check the SuperH version. |
| 153 | 153 | .sh => "qemu-sh4", |
| 154 | 154 | .sheb => "qemu-sh4eb", |
| 155 | .sparc => if (candidate.cpu.has(.sparc, .v8plus)) "qemu-sparc32plus" else "qemu-sparc", | |
| 155 | .sparc => "qemu-sparc32plus", | |
| 156 | 156 | .thumb => "qemu-arm", |
| 157 | 157 | .thumbeb => "qemu-armeb", |
| 158 | 158 | else => "qemu-" ++ @tagName(t), |