| author | |
| committer | |
| log | e84cda0ebf8886346d42db78e8f3eb8d0bf515bd |
| tree | 9e0ed316fd374bcc3f7a4f26ff70291a9d1ca9fb |
| parent | 8f5c333ebe6631629be3b88d797a03b1d677d439 |
| parent | 228c956377e4f33e45fad7e0ba5d9eb5073803a5 |
| signature |
CBE: fix regressions and get new targets passing behavior tests43 files changed, 769 insertions(+), 515 deletions(-)
lib/c.zig+91-96| ... | @@ -200,72 +200,67 @@ fn clone() callconv(.Naked) void { | ... | @@ -200,72 +200,67 @@ fn clone() callconv(.Naked) void { |
| 200 | // syscall(SYS_clone, flags, stack, ptid, tls, ctid) | 200 | // syscall(SYS_clone, flags, stack, ptid, tls, ctid) |
| 201 | // eax, ebx, ecx, edx, esi, edi | 201 | // eax, ebx, ecx, edx, esi, edi |
| 202 | asm volatile ( | 202 | asm volatile ( |
| 203 | \\ push %%ebp | 203 | \\ pushl %%ebp |
| 204 | \\ mov %%esp,%%ebp | 204 | \\ movl %%esp,%%ebp |
| 205 | \\ push %%ebx | 205 | \\ pushl %%ebx |
| 206 | \\ push %%esi | 206 | \\ pushl %%esi |
| 207 | \\ push %%edi | 207 | \\ pushl %%edi |
| 208 | \\ // Setup the arguments | 208 | \\ // Setup the arguments |
| 209 | \\ mov 16(%%ebp),%%ebx | 209 | \\ movl 16(%%ebp),%%ebx |
| 210 | \\ mov 12(%%ebp),%%ecx | 210 | \\ movl 12(%%ebp),%%ecx |
| 211 | \\ and $-16,%%ecx | 211 | \\ andl $-16,%%ecx |
| 212 | \\ sub $20,%%ecx | 212 | \\ subl $20,%%ecx |
| 213 | \\ mov 20(%%ebp),%%eax | 213 | \\ movl 20(%%ebp),%%eax |
| 214 | \\ mov %%eax,4(%%ecx) | 214 | \\ movl %%eax,4(%%ecx) |
| 215 | \\ mov 8(%%ebp),%%eax | 215 | \\ movl 8(%%ebp),%%eax |
| 216 | \\ mov %%eax,0(%%ecx) | 216 | \\ movl %%eax,0(%%ecx) |
| 217 | \\ mov 24(%%ebp),%%edx | 217 | \\ movl 24(%%ebp),%%edx |
| 218 | \\ mov 28(%%ebp),%%esi | 218 | \\ movl 28(%%ebp),%%esi |
| 219 | \\ mov 32(%%ebp),%%edi | 219 | \\ movl 32(%%ebp),%%edi |
| 220 | \\ mov $120,%%eax | 220 | \\ movl $120,%%eax |
| 221 | \\ int $128 | 221 | \\ int $128 |
| 222 | \\ test %%eax,%%eax | 222 | \\ testl %%eax,%%eax |
| 223 | \\ jnz 1f | 223 | \\ jnz 1f |
| 224 | \\ pop %%eax | 224 | \\ popl %%eax |
| 225 | \\ xor %%ebp,%%ebp | 225 | \\ xorl %%ebp,%%ebp |
| 226 | \\ call *%%eax | 226 | \\ calll *%%eax |
| 227 | \\ mov %%eax,%%ebx | 227 | \\ movl %%eax,%%ebx |
| 228 | \\ xor %%eax,%%eax | 228 | \\ movl $1,%%eax |
| 229 | \\ inc %%eax | ||
| 230 | \\ int $128 | 229 | \\ int $128 |
| 231 | \\ hlt | ||
| 232 | \\1: | 230 | \\1: |
| 233 | \\ pop %%edi | 231 | \\ popl %%edi |
| 234 | \\ pop %%esi | 232 | \\ popl %%esi |
| 235 | \\ pop %%ebx | 233 | \\ popl %%ebx |
| 236 | \\ pop %%ebp | 234 | \\ popl %%ebp |
| 237 | \\ ret | 235 | \\ retl |
| 238 | ); | 236 | ); |
| 239 | }, | 237 | }, |
| 240 | .x86_64 => { | 238 | .x86_64 => { |
| 241 | asm volatile ( | 239 | asm volatile ( |
| 242 | \\ xor %%eax,%%eax | 240 | \\ movl $56,%%eax // SYS_clone |
| 243 | \\ mov $56,%%al // SYS_clone | 241 | \\ movq %%rdi,%%r11 |
| 244 | \\ mov %%rdi,%%r11 | 242 | \\ movq %%rdx,%%rdi |
| 245 | \\ mov %%rdx,%%rdi | 243 | \\ movq %%r8,%%rdx |
| 246 | \\ mov %%r8,%%rdx | 244 | \\ movq %%r9,%%r8 |
| 247 | \\ mov %%r9,%%r8 | 245 | \\ movq 8(%%rsp),%%r10 |
| 248 | \\ mov 8(%%rsp),%%r10 | 246 | \\ movq %%r11,%%r9 |
| 249 | \\ mov %%r11,%%r9 | 247 | \\ andq $-16,%%rsi |
| 250 | \\ and $-16,%%rsi | 248 | \\ subq $8,%%rsi |
| 251 | \\ sub $8,%%rsi | 249 | \\ movq %%rcx,(%%rsi) |
| 252 | \\ mov %%rcx,(%%rsi) | ||
| 253 | \\ syscall | 250 | \\ syscall |
| 254 | \\ test %%eax,%%eax | 251 | \\ testq %%rax,%%rax |
| 255 | \\ jnz 1f | 252 | \\ jnz 1f |
| 256 | \\ xor %%ebp,%%ebp | 253 | \\ xorl %%ebp,%%ebp |
| 257 | \\ pop %%rdi | 254 | \\ popq %%rdi |
| 258 | \\ call *%%r9 | 255 | \\ callq *%%r9 |
| 259 | \\ mov %%eax,%%edi | 256 | \\ movl %%eax,%%edi |
| 260 | \\ xor %%eax,%%eax | 257 | \\ movl $60,%%eax // SYS_exit |
| 261 | \\ mov $60,%%al // SYS_exit | ||
| 262 | \\ syscall | 258 | \\ syscall |
| 263 | \\ hlt | ||
| 264 | \\1: ret | 259 | \\1: ret |
| 265 | \\ | 260 | \\ |
| 266 | ); | 261 | ); |
| 267 | }, | 262 | }, |
| 268 | .aarch64 => { | 263 | .aarch64, .aarch64_be => { |
| 269 | // __clone(func, stack, flags, arg, ptid, tls, ctid) | 264 | // __clone(func, stack, flags, arg, ptid, tls, ctid) |
| 270 | // x0, x1, w2, x3, x4, x5, x6 | 265 | // x0, x1, w2, x3, x4, x5, x6 |
| 271 | 266 | ||
| ... | @@ -400,69 +395,69 @@ fn clone() callconv(.Naked) void { | ... | @@ -400,69 +395,69 @@ fn clone() callconv(.Naked) void { |
| 400 | \\ syscall | 395 | \\ syscall |
| 401 | ); | 396 | ); |
| 402 | }, | 397 | }, |
| 403 | .powerpc => { | 398 | .powerpc, .powerpcle => { |
| 404 | // __clone(func, stack, flags, arg, ptid, tls, ctid) | 399 | // __clone(func, stack, flags, arg, ptid, tls, ctid) |
| 405 | // 3, 4, 5, 6, 7, 8, 9 | 400 | // 3, 4, 5, 6, 7, 8, 9 |
| 406 | 401 | ||
| 407 | // syscall(SYS_clone, flags, stack, ptid, tls, ctid) | 402 | // syscall(SYS_clone, flags, stack, ptid, tls, ctid) |
| 408 | // 0 3, 4, 5, 6, 7 | 403 | // 0 3, 4, 5, 6, 7 |
| 409 | asm volatile ( | 404 | asm volatile ( |
| 410 | \\# store non-volatile regs r30, r31 on stack in order to put our | 405 | \\ # store non-volatile regs r30, r31 on stack in order to put our |
| 411 | \\# start func and its arg there | 406 | \\ # start func and its arg there |
| 412 | \\stwu 30, -16(1) | 407 | \\ stwu 30, -16(1) |
| 413 | \\stw 31, 4(1) | 408 | \\ stw 31, 4(1) |
| 414 | \\ | 409 | \\ |
| 415 | \\# save r3 (func) into r30, and r6(arg) into r31 | 410 | \\ # save r3 (func) into r30, and r6(arg) into r31 |
| 416 | \\mr 30, 3 | 411 | \\ mr 30, 3 |
| 417 | \\mr 31, 6 | 412 | \\ mr 31, 6 |
| 418 | \\ | 413 | \\ |
| 419 | \\# create initial stack frame for new thread | 414 | \\ # create initial stack frame for new thread |
| 420 | \\clrrwi 4, 4, 4 | 415 | \\ clrrwi 4, 4, 4 |
| 421 | \\li 0, 0 | 416 | \\ li 0, 0 |
| 422 | \\stwu 0, -16(4) | 417 | \\ stwu 0, -16(4) |
| 423 | \\ | 418 | \\ |
| 424 | \\#move c into first arg | 419 | \\ #move c into first arg |
| 425 | \\mr 3, 5 | 420 | \\ mr 3, 5 |
| 426 | \\#mr 4, 4 | 421 | \\ #mr 4, 4 |
| 427 | \\mr 5, 7 | 422 | \\ mr 5, 7 |
| 428 | \\mr 6, 8 | 423 | \\ mr 6, 8 |
| 429 | \\mr 7, 9 | 424 | \\ mr 7, 9 |
| 430 | \\ | 425 | \\ |
| 431 | \\# move syscall number into r0 | 426 | \\ # move syscall number into r0 |
| 432 | \\li 0, 120 | 427 | \\ li 0, 120 |
| 433 | \\ | 428 | \\ |
| 434 | \\sc | 429 | \\ sc |
| 435 | \\ | 430 | \\ |
| 436 | \\# check for syscall error | 431 | \\ # check for syscall error |
| 437 | \\bns+ 1f # jump to label 1 if no summary overflow. | 432 | \\ bns+ 1f # jump to label 1 if no summary overflow. |
| 438 | \\#else | 433 | \\ #else |
| 439 | \\neg 3, 3 #negate the result (errno) | 434 | \\ neg 3, 3 #negate the result (errno) |
| 440 | \\1: | 435 | \\ 1: |
| 441 | \\# compare sc result with 0 | 436 | \\ # compare sc result with 0 |
| 442 | \\cmpwi cr7, 3, 0 | 437 | \\ cmpwi cr7, 3, 0 |
| 443 | \\ | 438 | \\ |
| 444 | \\# if not 0, jump to end | 439 | \\ # if not 0, jump to end |
| 445 | \\bne cr7, 2f | 440 | \\ bne cr7, 2f |
| 446 | \\ | 441 | \\ |
| 447 | \\#else: we're the child | 442 | \\ #else: we're the child |
| 448 | \\#call funcptr: move arg (d) into r3 | 443 | \\ #call funcptr: move arg (d) into r3 |
| 449 | \\mr 3, 31 | 444 | \\ mr 3, 31 |
| 450 | \\#move r30 (funcptr) into CTR reg | 445 | \\ #move r30 (funcptr) into CTR reg |
| 451 | \\mtctr 30 | 446 | \\ mtctr 30 |
| 452 | \\# call CTR reg | 447 | \\ # call CTR reg |
| 453 | \\bctrl | 448 | \\ bctrl |
| 454 | \\# mov SYS_exit into r0 (the exit param is already in r3) | 449 | \\ # mov SYS_exit into r0 (the exit param is already in r3) |
| 455 | \\li 0, 1 | 450 | \\ li 0, 1 |
| 456 | \\sc | 451 | \\ sc |
| 457 | \\ | 452 | \\ |
| 458 | \\2: | 453 | \\ 2: |
| 459 | \\ | 454 | \\ |
| 460 | \\# restore stack | 455 | \\ # restore stack |
| 461 | \\lwz 30, 0(1) | 456 | \\ lwz 30, 0(1) |
| 462 | \\lwz 31, 4(1) | 457 | \\ lwz 31, 4(1) |
| 463 | \\addi 1, 1, 16 | 458 | \\ addi 1, 1, 16 |
| 464 | \\ | 459 | \\ |
| 465 | \\blr | 460 | \\ blr |
| 466 | ); | 461 | ); |
| 467 | }, | 462 | }, |
| 468 | .powerpc64, .powerpc64le => { | 463 | .powerpc64, .powerpc64le => { |
lib/compiler_rt/arm.zig+1-1| ... | @@ -9,7 +9,7 @@ pub const panic = common.panic; | ... | @@ -9,7 +9,7 @@ pub const panic = common.panic; |
| 9 | 9 | ||
| 10 | comptime { | 10 | comptime { |
| 11 | if (!builtin.is_test) { | 11 | if (!builtin.is_test) { |
| 12 | if (arch.isARM() or arch.isThumb()) { | 12 | if (arch.isArmOrThumb()) { |
| 13 | @export(__aeabi_unwind_cpp_pr0, .{ .name = "__aeabi_unwind_cpp_pr0", .linkage = common.linkage, .visibility = common.visibility }); | 13 | @export(__aeabi_unwind_cpp_pr0, .{ .name = "__aeabi_unwind_cpp_pr0", .linkage = common.linkage, .visibility = common.visibility }); |
| 14 | @export(__aeabi_unwind_cpp_pr1, .{ .name = "__aeabi_unwind_cpp_pr1", .linkage = common.linkage, .visibility = common.visibility }); | 14 | @export(__aeabi_unwind_cpp_pr1, .{ .name = "__aeabi_unwind_cpp_pr1", .linkage = common.linkage, .visibility = common.visibility }); |
| 15 | @export(__aeabi_unwind_cpp_pr2, .{ .name = "__aeabi_unwind_cpp_pr2", .linkage = common.linkage, .visibility = common.visibility }); | 15 | @export(__aeabi_unwind_cpp_pr2, .{ .name = "__aeabi_unwind_cpp_pr2", .linkage = common.linkage, .visibility = common.visibility }); |
lib/compiler_rt/clzsi2_test.zig+1-1| ... | @@ -268,7 +268,7 @@ test "clzsi2" { | ... | @@ -268,7 +268,7 @@ test "clzsi2" { |
| 268 | try test__clzsi2(0xFE000000, 0); | 268 | try test__clzsi2(0xFE000000, 0); |
| 269 | try test__clzsi2(0xFF000000, 0); | 269 | try test__clzsi2(0xFF000000, 0); |
| 270 | // arm and thumb1 assume input a != 0 | 270 | // arm and thumb1 assume input a != 0 |
| 271 | if (!builtin.cpu.arch.isARM() and !builtin.cpu.arch.isThumb()) | 271 | if (!builtin.cpu.arch.isArmOrThumb()) |
| 272 | try test__clzsi2(0x00000000, 32); | 272 | try test__clzsi2(0x00000000, 32); |
| 273 | try test__clzsi2(0x00000001, 31); | 273 | try test__clzsi2(0x00000001, 31); |
| 274 | try test__clzsi2(0x00000002, 30); | 274 | try test__clzsi2(0x00000002, 30); |
lib/std/Thread.zig+8-6| ... | @@ -1275,12 +1275,14 @@ const LinuxThreadImpl = struct { | ... | @@ -1275,12 +1275,14 @@ const LinuxThreadImpl = struct { |
| 1275 | .entry_number = os.linux.tls.tls_image.gdt_entry_number, | 1275 | .entry_number = os.linux.tls.tls_image.gdt_entry_number, |
| 1276 | .base_addr = tls_ptr, | 1276 | .base_addr = tls_ptr, |
| 1277 | .limit = 0xfffff, | 1277 | .limit = 0xfffff, |
| 1278 | .seg_32bit = 1, | 1278 | .flags = .{ |
| 1279 | .contents = 0, // Data | 1279 | .seg_32bit = 1, |
| 1280 | .read_exec_only = 0, | 1280 | .contents = 0, // Data |
| 1281 | .limit_in_pages = 1, | 1281 | .read_exec_only = 0, |
| 1282 | .seg_not_present = 0, | 1282 | .limit_in_pages = 1, |
| 1283 | .useable = 1, | 1283 | .seg_not_present = 0, |
| 1284 | .useable = 1, | ||
| 1285 | }, | ||
| 1284 | }; | 1286 | }; |
| 1285 | } | 1287 | } |
| 1286 | 1288 |
lib/std/builtin.zig+1-1| ... | @@ -568,7 +568,7 @@ pub const VaListX86_64 = extern struct { | ... | @@ -568,7 +568,7 @@ pub const VaListX86_64 = extern struct { |
| 568 | /// This data structure is used by the Zig language code generation and | 568 | /// This data structure is used by the Zig language code generation and |
| 569 | /// therefore must be kept in sync with the compiler implementation. | 569 | /// therefore must be kept in sync with the compiler implementation. |
| 570 | pub const VaList = switch (builtin.cpu.arch) { | 570 | pub const VaList = switch (builtin.cpu.arch) { |
| 571 | .aarch64 => switch (builtin.os.tag) { | 571 | .aarch64, .aarch64_be => switch (builtin.os.tag) { |
| 572 | .windows => *u8, | 572 | .windows => *u8, |
| 573 | .ios, .macos, .tvos, .watchos => *u8, | 573 | .ios, .macos, .tvos, .watchos => *u8, |
| 574 | else => @compileError("disabled due to miscompilations"), // VaListAarch64, | 574 | else => @compileError("disabled due to miscompilations"), // VaListAarch64, |
lib/std/os/linux.zig+6-8| ... | @@ -35,13 +35,13 @@ const syscall_bits = switch (native_arch) { | ... | @@ -35,13 +35,13 @@ const syscall_bits = switch (native_arch) { |
| 35 | const arch_bits = switch (native_arch) { | 35 | const arch_bits = switch (native_arch) { |
| 36 | .x86 => @import("linux/x86.zig"), | 36 | .x86 => @import("linux/x86.zig"), |
| 37 | .x86_64 => @import("linux/x86_64.zig"), | 37 | .x86_64 => @import("linux/x86_64.zig"), |
| 38 | .aarch64 => @import("linux/arm64.zig"), | 38 | .aarch64, .aarch64_be => @import("linux/arm64.zig"), |
| 39 | .arm, .thumb => @import("linux/arm-eabi.zig"), | 39 | .arm, .thumb => @import("linux/arm-eabi.zig"), |
| 40 | .riscv64 => @import("linux/riscv64.zig"), | 40 | .riscv64 => @import("linux/riscv64.zig"), |
| 41 | .sparc64 => @import("linux/sparc64.zig"), | 41 | .sparc64 => @import("linux/sparc64.zig"), |
| 42 | .mips, .mipsel => @import("linux/mips.zig"), | 42 | .mips, .mipsel => @import("linux/mips.zig"), |
| 43 | .mips64, .mips64el => @import("linux/mips64.zig"), | 43 | .mips64, .mips64el => @import("linux/mips64.zig"), |
| 44 | .powerpc => @import("linux/powerpc.zig"), | 44 | .powerpc, .powerpcle => @import("linux/powerpc.zig"), |
| 45 | .powerpc64, .powerpc64le => @import("linux/powerpc64.zig"), | 45 | .powerpc64, .powerpc64le => @import("linux/powerpc64.zig"), |
| 46 | else => struct {}, | 46 | else => struct {}, |
| 47 | }; | 47 | }; |
| ... | @@ -98,13 +98,13 @@ pub const syscalls = @import("linux/syscalls.zig"); | ... | @@ -98,13 +98,13 @@ pub const syscalls = @import("linux/syscalls.zig"); |
| 98 | pub const SYS = switch (@import("builtin").cpu.arch) { | 98 | pub const SYS = switch (@import("builtin").cpu.arch) { |
| 99 | .x86 => syscalls.X86, | 99 | .x86 => syscalls.X86, |
| 100 | .x86_64 => syscalls.X64, | 100 | .x86_64 => syscalls.X64, |
| 101 | .aarch64 => syscalls.Arm64, | 101 | .aarch64, .aarch64_be => syscalls.Arm64, |
| 102 | .arm, .thumb => syscalls.Arm, | 102 | .arm, .thumb => syscalls.Arm, |
| 103 | .riscv64 => syscalls.RiscV64, | 103 | .riscv64 => syscalls.RiscV64, |
| 104 | .sparc64 => syscalls.Sparc64, | 104 | .sparc64 => syscalls.Sparc64, |
| 105 | .mips, .mipsel => syscalls.Mips, | 105 | .mips, .mipsel => syscalls.Mips, |
| 106 | .mips64, .mips64el => syscalls.Mips64, | 106 | .mips64, .mips64el => syscalls.Mips64, |
| 107 | .powerpc => syscalls.PowerPC, | 107 | .powerpc, .powerpcle => syscalls.PowerPC, |
| 108 | .powerpc64, .powerpc64le => syscalls.PowerPC64, | 108 | .powerpc64, .powerpc64le => syscalls.PowerPC64, |
| 109 | else => @compileError("The Zig Standard Library is missing syscall definitions for the target CPU architecture"), | 109 | else => @compileError("The Zig Standard Library is missing syscall definitions for the target CPU architecture"), |
| 110 | }; | 110 | }; |
| ... | @@ -1176,14 +1176,12 @@ pub fn sigaction(sig: u6, noalias act: ?*const Sigaction, noalias oact: ?*Sigact | ... | @@ -1176,14 +1176,12 @@ pub fn sigaction(sig: u6, noalias act: ?*const Sigaction, noalias oact: ?*Sigact |
| 1176 | const mask_size = @sizeOf(@TypeOf(ksa.mask)); | 1176 | const mask_size = @sizeOf(@TypeOf(ksa.mask)); |
| 1177 | 1177 | ||
| 1178 | if (act) |new| { | 1178 | if (act) |new| { |
| 1179 | const restore_rt_ptr = &restore_rt; | 1179 | const restorer_fn = if ((new.flags & SA.SIGINFO) != 0) &restore_rt else &restore; |
| 1180 | const restore_ptr = &restore; | ||
| 1181 | const restorer_fn = if ((new.flags & SA.SIGINFO) != 0) restore_rt_ptr else restore_ptr; | ||
| 1182 | ksa = k_sigaction{ | 1180 | ksa = k_sigaction{ |
| 1183 | .handler = new.handler.handler, | 1181 | .handler = new.handler.handler, |
| 1184 | .flags = new.flags | SA.RESTORER, | 1182 | .flags = new.flags | SA.RESTORER, |
| 1185 | .mask = undefined, | 1183 | .mask = undefined, |
| 1186 | .restorer = @as(k_sigaction_funcs.restorer, @ptrCast(restorer_fn)), | 1184 | .restorer = @ptrCast(restorer_fn), |
| 1187 | }; | 1185 | }; |
| 1188 | @memcpy(@as([*]u8, @ptrCast(&ksa.mask))[0..mask_size], @as([*]const u8, @ptrCast(&new.mask))); | 1186 | @memcpy(@as([*]u8, @ptrCast(&ksa.mask))[0..mask_size], @as([*]const u8, @ptrCast(&new.mask))); |
| 1189 | } | 1187 | } |
lib/std/os/linux/arm-eabi.zig+32-12| ... | @@ -103,20 +103,40 @@ const CloneFn = *const fn (arg: usize) callconv(.C) u8; | ... | @@ -103,20 +103,40 @@ const CloneFn = *const fn (arg: usize) callconv(.C) u8; |
| 103 | /// This matches the libc clone function. | 103 | /// This matches the libc clone function. |
| 104 | pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize; | 104 | pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize; |
| 105 | 105 | ||
| 106 | pub fn restore() callconv(.Naked) void { | 106 | pub fn restore() callconv(.Naked) noreturn { |
| 107 | return asm volatile ("svc #0" | 107 | switch (@import("builtin").zig_backend) { |
| 108 | : | 108 | .stage2_c => asm volatile ( |
| 109 | : [number] "{r7}" (@intFromEnum(SYS.sigreturn)), | 109 | \\ mov r7, %[number] |
| 110 | : "memory" | 110 | \\ svc #0 |
| 111 | ); | 111 | : |
| 112 | : [number] "I" (@intFromEnum(SYS.sigreturn)), | ||
| 113 | : "memory" | ||
| 114 | ), | ||
| 115 | else => asm volatile ( | ||
| 116 | \\ svc #0 | ||
| 117 | : | ||
| 118 | : [number] "{r7}" (@intFromEnum(SYS.sigreturn)), | ||
| 119 | : "memory" | ||
| 120 | ), | ||
| 121 | } | ||
| 112 | } | 122 | } |
| 113 | 123 | ||
| 114 | pub fn restore_rt() callconv(.Naked) void { | 124 | pub fn restore_rt() callconv(.Naked) noreturn { |
| 115 | return asm volatile ("svc #0" | 125 | switch (@import("builtin").zig_backend) { |
| 116 | : | 126 | .stage2_c => asm volatile ( |
| 117 | : [number] "{r7}" (@intFromEnum(SYS.rt_sigreturn)), | 127 | \\ mov r7, %[number] |
| 118 | : "memory" | 128 | \\ svc #0 |
| 119 | ); | 129 | : |
| 130 | : [number] "I" (@intFromEnum(SYS.rt_sigreturn)), | ||
| 131 | : "memory" | ||
| 132 | ), | ||
| 133 | else => asm volatile ( | ||
| 134 | \\ svc #0 | ||
| 135 | : | ||
| 136 | : [number] "{r7}" (@intFromEnum(SYS.rt_sigreturn)), | ||
| 137 | : "memory" | ||
| 138 | ), | ||
| 139 | } | ||
| 120 | } | 140 | } |
| 121 | 141 | ||
| 122 | pub const MMAP2_UNIT = 4096; | 142 | pub const MMAP2_UNIT = 4096; |
lib/std/os/linux/arm64.zig+4-3| ... | @@ -105,16 +105,17 @@ pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: * | ... | @@ -105,16 +105,17 @@ pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: * |
| 105 | 105 | ||
| 106 | pub const restore = restore_rt; | 106 | pub const restore = restore_rt; |
| 107 | 107 | ||
| 108 | pub fn restore_rt() callconv(.Naked) void { | 108 | pub fn restore_rt() callconv(.Naked) noreturn { |
| 109 | switch (@import("builtin").zig_backend) { | 109 | switch (@import("builtin").zig_backend) { |
| 110 | .stage2_c => return asm volatile ( | 110 | .stage2_c => asm volatile ( |
| 111 | \\ mov x8, %[number] | 111 | \\ mov x8, %[number] |
| 112 | \\ svc #0 | 112 | \\ svc #0 |
| 113 | : | 113 | : |
| 114 | : [number] "i" (@intFromEnum(SYS.rt_sigreturn)), | 114 | : [number] "i" (@intFromEnum(SYS.rt_sigreturn)), |
| 115 | : "memory", "cc" | 115 | : "memory", "cc" |
| 116 | ), | 116 | ), |
| 117 | else => return asm volatile ("svc #0" | 117 | else => asm volatile ( |
| 118 | \\ svc #0 | ||
| 118 | : | 119 | : |
| 119 | : [number] "{x8}" (@intFromEnum(SYS.rt_sigreturn)), | 120 | : [number] "{x8}" (@intFromEnum(SYS.rt_sigreturn)), |
| 120 | : "memory", "cc" | 121 | : "memory", "cc" |
lib/std/os/linux/mips.zig+6-4| ... | @@ -195,16 +195,18 @@ const CloneFn = *const fn (arg: usize) callconv(.C) u8; | ... | @@ -195,16 +195,18 @@ const CloneFn = *const fn (arg: usize) callconv(.C) u8; |
| 195 | /// This matches the libc clone function. | 195 | /// This matches the libc clone function. |
| 196 | pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize; | 196 | pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize; |
| 197 | 197 | ||
| 198 | pub fn restore() callconv(.Naked) void { | 198 | pub fn restore() callconv(.Naked) noreturn { |
| 199 | return asm volatile ("syscall" | 199 | asm volatile ( |
| 200 | \\ syscall | ||
| 200 | : | 201 | : |
| 201 | : [number] "{$2}" (@intFromEnum(SYS.sigreturn)), | 202 | : [number] "{$2}" (@intFromEnum(SYS.sigreturn)), |
| 202 | : "$1", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25", "hi", "lo", "memory" | 203 | : "$1", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25", "hi", "lo", "memory" |
| 203 | ); | 204 | ); |
| 204 | } | 205 | } |
| 205 | 206 | ||
| 206 | pub fn restore_rt() callconv(.Naked) void { | 207 | pub fn restore_rt() callconv(.Naked) noreturn { |
| 207 | return asm volatile ("syscall" | 208 | asm volatile ( |
| 209 | \\ syscall | ||
| 208 | : | 210 | : |
| 209 | : [number] "{$2}" (@intFromEnum(SYS.rt_sigreturn)), | 211 | : [number] "{$2}" (@intFromEnum(SYS.rt_sigreturn)), |
| 210 | : "$1", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25", "hi", "lo", "memory" | 212 | : "$1", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25", "hi", "lo", "memory" |
lib/std/os/linux/mips64.zig+6-4| ... | @@ -180,16 +180,18 @@ const CloneFn = *const fn (arg: usize) callconv(.C) u8; | ... | @@ -180,16 +180,18 @@ const CloneFn = *const fn (arg: usize) callconv(.C) u8; |
| 180 | /// This matches the libc clone function. | 180 | /// This matches the libc clone function. |
| 181 | pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize; | 181 | pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize; |
| 182 | 182 | ||
| 183 | pub fn restore() callconv(.Naked) void { | 183 | pub fn restore() callconv(.Naked) noreturn { |
| 184 | return asm volatile ("syscall" | 184 | asm volatile ( |
| 185 | \\ syscall | ||
| 185 | : | 186 | : |
| 186 | : [number] "{$2}" (@intFromEnum(SYS.rt_sigreturn)), | 187 | : [number] "{$2}" (@intFromEnum(SYS.rt_sigreturn)), |
| 187 | : "$1", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25", "hi", "lo", "memory" | 188 | : "$1", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25", "hi", "lo", "memory" |
| 188 | ); | 189 | ); |
| 189 | } | 190 | } |
| 190 | 191 | ||
| 191 | pub fn restore_rt() callconv(.Naked) void { | 192 | pub fn restore_rt() callconv(.Naked) noreturn { |
| 192 | return asm volatile ("syscall" | 193 | asm volatile ( |
| 194 | \\ syscall | ||
| 193 | : | 195 | : |
| 194 | : [number] "{$2}" (@intFromEnum(SYS.rt_sigreturn)), | 196 | : [number] "{$2}" (@intFromEnum(SYS.rt_sigreturn)), |
| 195 | : "$1", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25", "hi", "lo", "memory" | 197 | : "$1", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25", "hi", "lo", "memory" |
lib/std/os/linux/powerpc.zig+3-2| ... | @@ -133,8 +133,9 @@ pub extern fn clone(func: CloneFn, stack: usize, flags: usize, arg: usize, ptid: | ... | @@ -133,8 +133,9 @@ pub extern fn clone(func: CloneFn, stack: usize, flags: usize, arg: usize, ptid: |
| 133 | 133 | ||
| 134 | pub const restore = restore_rt; | 134 | pub const restore = restore_rt; |
| 135 | 135 | ||
| 136 | pub fn restore_rt() callconv(.Naked) void { | 136 | pub fn restore_rt() callconv(.Naked) noreturn { |
| 137 | return asm volatile ("sc" | 137 | asm volatile ( |
| 138 | \\ sc | ||
| 138 | : | 139 | : |
| 139 | : [number] "{r0}" (@intFromEnum(SYS.rt_sigreturn)), | 140 | : [number] "{r0}" (@intFromEnum(SYS.rt_sigreturn)), |
| 140 | : "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" | 141 | : "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" |
lib/std/os/linux/powerpc64.zig+3-2| ... | @@ -133,8 +133,9 @@ pub extern fn clone(func: CloneFn, stack: usize, flags: usize, arg: usize, ptid: | ... | @@ -133,8 +133,9 @@ pub extern fn clone(func: CloneFn, stack: usize, flags: usize, arg: usize, ptid: |
| 133 | 133 | ||
| 134 | pub const restore = restore_rt; | 134 | pub const restore = restore_rt; |
| 135 | 135 | ||
| 136 | pub fn restore_rt() callconv(.Naked) void { | 136 | pub fn restore_rt() callconv(.Naked) noreturn { |
| 137 | return asm volatile ("sc" | 137 | asm volatile ( |
| 138 | \\ sc | ||
| 138 | : | 139 | : |
| 139 | : [number] "{r0}" (@intFromEnum(SYS.rt_sigreturn)), | 140 | : [number] "{r0}" (@intFromEnum(SYS.rt_sigreturn)), |
| 140 | : "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" | 141 | : "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" |
lib/std/os/linux/riscv64.zig+3-2| ... | @@ -101,8 +101,9 @@ pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: * | ... | @@ -101,8 +101,9 @@ pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: * |
| 101 | 101 | ||
| 102 | pub const restore = restore_rt; | 102 | pub const restore = restore_rt; |
| 103 | 103 | ||
| 104 | pub fn restore_rt() callconv(.Naked) void { | 104 | pub fn restore_rt() callconv(.Naked) noreturn { |
| 105 | return asm volatile ("ecall" | 105 | asm volatile ( |
| 106 | \\ ecall | ||
| 106 | : | 107 | : |
| 107 | : [number] "{x17}" (@intFromEnum(SYS.rt_sigreturn)), | 108 | : [number] "{x17}" (@intFromEnum(SYS.rt_sigreturn)), |
| 108 | : "memory" | 109 | : "memory" |
lib/std/os/linux/thumb.zig+4-4| ... | @@ -141,8 +141,8 @@ pub fn syscall6( | ... | @@ -141,8 +141,8 @@ pub fn syscall6( |
| 141 | ); | 141 | ); |
| 142 | } | 142 | } |
| 143 | 143 | ||
| 144 | pub fn restore() callconv(.Naked) void { | 144 | pub fn restore() callconv(.Naked) noreturn { |
| 145 | return asm volatile ( | 145 | asm volatile ( |
| 146 | \\ mov r7, %[number] | 146 | \\ mov r7, %[number] |
| 147 | \\ svc #0 | 147 | \\ svc #0 |
| 148 | : | 148 | : |
| ... | @@ -150,8 +150,8 @@ pub fn restore() callconv(.Naked) void { | ... | @@ -150,8 +150,8 @@ pub fn restore() callconv(.Naked) void { |
| 150 | ); | 150 | ); |
| 151 | } | 151 | } |
| 152 | 152 | ||
| 153 | pub fn restore_rt() callconv(.Naked) void { | 153 | pub fn restore_rt() callconv(.Naked) noreturn { |
| 154 | return asm volatile ( | 154 | asm volatile ( |
| 155 | \\ mov r7, %[number] | 155 | \\ mov r7, %[number] |
| 156 | \\ svc #0 | 156 | \\ svc #0 |
| 157 | : | 157 | : |
lib/std/os/linux/tls.zig+11-9| ... | @@ -48,7 +48,7 @@ const TLSVariant = enum { | ... | @@ -48,7 +48,7 @@ const TLSVariant = enum { |
| 48 | }; | 48 | }; |
| 49 | 49 | ||
| 50 | const tls_variant = switch (native_arch) { | 50 | const tls_variant = switch (native_arch) { |
| 51 | .arm, .armeb, .thumb, .aarch64, .aarch64_be, .riscv32, .riscv64, .mips, .mipsel, .mips64, .mips64el, .powerpc, .powerpc64, .powerpc64le => TLSVariant.VariantI, | 51 | .arm, .armeb, .thumb, .aarch64, .aarch64_be, .riscv32, .riscv64, .mips, .mipsel, .mips64, .mips64el, .powerpc, .powerpcle, .powerpc64, .powerpc64le => TLSVariant.VariantI, |
| 52 | .x86_64, .x86, .sparc64 => TLSVariant.VariantII, | 52 | .x86_64, .x86, .sparc64 => TLSVariant.VariantII, |
| 53 | else => @compileError("undefined tls_variant for this architecture"), | 53 | else => @compileError("undefined tls_variant for this architecture"), |
| 54 | }; | 54 | }; |
| ... | @@ -115,12 +115,14 @@ pub fn setThreadPointer(addr: usize) void { | ... | @@ -115,12 +115,14 @@ pub fn setThreadPointer(addr: usize) void { |
| 115 | .entry_number = tls_image.gdt_entry_number, | 115 | .entry_number = tls_image.gdt_entry_number, |
| 116 | .base_addr = addr, | 116 | .base_addr = addr, |
| 117 | .limit = 0xfffff, | 117 | .limit = 0xfffff, |
| 118 | .seg_32bit = 1, | 118 | .flags = .{ |
| 119 | .contents = 0, // Data | 119 | .seg_32bit = 1, |
| 120 | .read_exec_only = 0, | 120 | .contents = 0, // Data |
| 121 | .limit_in_pages = 1, | 121 | .read_exec_only = 0, |
| 122 | .seg_not_present = 0, | 122 | .limit_in_pages = 1, |
| 123 | .useable = 1, | 123 | .seg_not_present = 0, |
| 124 | .useable = 1, | ||
| 125 | }, | ||
| 124 | }; | 126 | }; |
| 125 | const rc = std.os.linux.syscall1(.set_thread_area, @intFromPtr(&user_desc)); | 127 | const rc = std.os.linux.syscall1(.set_thread_area, @intFromPtr(&user_desc)); |
| 126 | assert(rc == 0); | 128 | assert(rc == 0); |
| ... | @@ -138,7 +140,7 @@ pub fn setThreadPointer(addr: usize) void { | ... | @@ -138,7 +140,7 @@ pub fn setThreadPointer(addr: usize) void { |
| 138 | const rc = std.os.linux.syscall2(.arch_prctl, std.os.linux.ARCH.SET_FS, addr); | 140 | const rc = std.os.linux.syscall2(.arch_prctl, std.os.linux.ARCH.SET_FS, addr); |
| 139 | assert(rc == 0); | 141 | assert(rc == 0); |
| 140 | }, | 142 | }, |
| 141 | .aarch64 => { | 143 | .aarch64, .aarch64_be => { |
| 142 | asm volatile ( | 144 | asm volatile ( |
| 143 | \\ msr tpidr_el0, %[addr] | 145 | \\ msr tpidr_el0, %[addr] |
| 144 | : | 146 | : |
| ... | @@ -160,7 +162,7 @@ pub fn setThreadPointer(addr: usize) void { | ... | @@ -160,7 +162,7 @@ pub fn setThreadPointer(addr: usize) void { |
| 160 | const rc = std.os.linux.syscall1(.set_thread_area, addr); | 162 | const rc = std.os.linux.syscall1(.set_thread_area, addr); |
| 161 | assert(rc == 0); | 163 | assert(rc == 0); |
| 162 | }, | 164 | }, |
| 163 | .powerpc => { | 165 | .powerpc, .powerpcle => { |
| 164 | asm volatile ( | 166 | asm volatile ( |
| 165 | \\ mr 2, %[addr] | 167 | \\ mr 2, %[addr] |
| 166 | : | 168 | : |
lib/std/os/linux/x86.zig+57-57| ... | @@ -123,46 +123,40 @@ const CloneFn = *const fn (arg: usize) callconv(.C) u8; | ... | @@ -123,46 +123,40 @@ const CloneFn = *const fn (arg: usize) callconv(.C) u8; |
| 123 | /// This matches the libc clone function. | 123 | /// This matches the libc clone function. |
| 124 | pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize; | 124 | pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize; |
| 125 | 125 | ||
| 126 | pub fn restore() callconv(.Naked) void { | 126 | pub fn restore() callconv(.Naked) noreturn { |
| 127 | switch (@import("builtin").zig_backend) { | 127 | switch (@import("builtin").zig_backend) { |
| 128 | .stage2_c => asm volatile ( | 128 | .stage2_c => asm volatile ( |
| 129 | \\ movl %[number], %%eax | 129 | \\ movl %[number], %%eax |
| 130 | \\ int $0x80 | 130 | \\ int $0x80 |
| 131 | \\ ret | ||
| 132 | : | 131 | : |
| 133 | : [number] "i" (@intFromEnum(SYS.sigreturn)), | 132 | : [number] "i" (@intFromEnum(SYS.sigreturn)), |
| 134 | : "memory" | 133 | : "memory" |
| 135 | ), | 134 | ), |
| 136 | else => asm volatile ( | 135 | else => asm volatile ( |
| 137 | \\ int $0x80 | 136 | \\ int $0x80 |
| 138 | \\ ret | ||
| 139 | : | 137 | : |
| 140 | : [number] "{eax}" (@intFromEnum(SYS.sigreturn)), | 138 | : [number] "{eax}" (@intFromEnum(SYS.sigreturn)), |
| 141 | : "memory" | 139 | : "memory" |
| 142 | ), | 140 | ), |
| 143 | } | 141 | } |
| 144 | unreachable; | ||
| 145 | } | 142 | } |
| 146 | 143 | ||
| 147 | pub fn restore_rt() callconv(.Naked) void { | 144 | pub fn restore_rt() callconv(.Naked) noreturn { |
| 148 | switch (@import("builtin").zig_backend) { | 145 | switch (@import("builtin").zig_backend) { |
| 149 | .stage2_c => asm volatile ( | 146 | .stage2_c => asm volatile ( |
| 150 | \\ movl %[number], %%eax | 147 | \\ movl %[number], %%eax |
| 151 | \\ int $0x80 | 148 | \\ int $0x80 |
| 152 | \\ ret | ||
| 153 | : | 149 | : |
| 154 | : [number] "i" (@intFromEnum(SYS.rt_sigreturn)), | 150 | : [number] "i" (@intFromEnum(SYS.rt_sigreturn)), |
| 155 | : "memory" | 151 | : "memory" |
| 156 | ), | 152 | ), |
| 157 | else => asm volatile ( | 153 | else => asm volatile ( |
| 158 | \\ int $0x80 | 154 | \\ int $0x80 |
| 159 | \\ ret | ||
| 160 | : | 155 | : |
| 161 | : [number] "{eax}" (@intFromEnum(SYS.rt_sigreturn)), | 156 | : [number] "{eax}" (@intFromEnum(SYS.rt_sigreturn)), |
| 162 | : "memory" | 157 | : "memory" |
| 163 | ), | 158 | ), |
| 164 | } | 159 | } |
| 165 | unreachable; | ||
| 166 | } | 160 | } |
| 167 | 161 | ||
| 168 | pub const O = struct { | 162 | pub const O = struct { |
| ... | @@ -354,16 +348,19 @@ pub const ucontext_t = extern struct { | ... | @@ -354,16 +348,19 @@ pub const ucontext_t = extern struct { |
| 354 | 348 | ||
| 355 | pub const Elf_Symndx = u32; | 349 | pub const Elf_Symndx = u32; |
| 356 | 350 | ||
| 357 | pub const user_desc = packed struct { | 351 | pub const user_desc = extern struct { |
| 358 | entry_number: u32, | 352 | entry_number: u32, |
| 359 | base_addr: u32, | 353 | base_addr: u32, |
| 360 | limit: u32, | 354 | limit: u32, |
| 361 | seg_32bit: u1, | 355 | flags: packed struct(u32) { |
| 362 | contents: u2, | 356 | seg_32bit: u1, |
| 363 | read_exec_only: u1, | 357 | contents: u2, |
| 364 | limit_in_pages: u1, | 358 | read_exec_only: u1, |
| 365 | seg_not_present: u1, | 359 | limit_in_pages: u1, |
| 366 | useable: u1, | 360 | seg_not_present: u1, |
| 361 | useable: u1, | ||
| 362 | _: u25 = undefined, | ||
| 363 | }, | ||
| 367 | }; | 364 | }; |
| 368 | 365 | ||
| 369 | /// socketcall() call numbers | 366 | /// socketcall() call numbers |
| ... | @@ -398,77 +395,80 @@ noinline fn getContextReturnAddress() usize { | ... | @@ -398,77 +395,80 @@ noinline fn getContextReturnAddress() usize { |
| 398 | return @returnAddress(); | 395 | return @returnAddress(); |
| 399 | } | 396 | } |
| 400 | 397 | ||
| 401 | pub fn getContextInternal() callconv(.Naked) void { | 398 | pub fn getContextInternal() callconv(.Naked) usize { |
| 402 | asm volatile ( | 399 | asm volatile ( |
| 403 | \\ movl $0, (%[flags_offset])(%%edx) | 400 | \\ movl $0, %[flags_offset:c](%%edx) |
| 404 | \\ movl $0, (%[link_offset])(%%edx) | 401 | \\ movl $0, %[link_offset:c](%%edx) |
| 405 | \\ movl %%edi, (%[edi_offset])(%%edx) | 402 | \\ movl %%edi, %[edi_offset:c](%%edx) |
| 406 | \\ movl %%esi, (%[esi_offset])(%%edx) | 403 | \\ movl %%esi, %[esi_offset:c](%%edx) |
| 407 | \\ movl %%ebp, (%[ebp_offset])(%%edx) | 404 | \\ movl %%ebp, %[ebp_offset:c](%%edx) |
| 408 | \\ movl %%ebx, (%[ebx_offset])(%%edx) | 405 | \\ movl %%ebx, %[ebx_offset:c](%%edx) |
| 409 | \\ movl %%edx, (%[edx_offset])(%%edx) | 406 | \\ movl %%edx, %[edx_offset:c](%%edx) |
| 410 | \\ movl %%ecx, (%[ecx_offset])(%%edx) | 407 | \\ movl %%ecx, %[ecx_offset:c](%%edx) |
| 411 | \\ movl %%eax, (%[eax_offset])(%%edx) | 408 | \\ movl %%eax, %[eax_offset:c](%%edx) |
| 412 | \\ movl (%%esp), %%ecx | 409 | \\ movl (%%esp), %%ecx |
| 413 | \\ movl %%ecx, (%[eip_offset])(%%edx) | 410 | \\ movl %%ecx, %[eip_offset:c](%%edx) |
| 414 | \\ leal 4(%%esp), %%ecx | 411 | \\ leal 4(%%esp), %%ecx |
| 415 | \\ movl %%ecx, (%[esp_offset])(%%edx) | 412 | \\ movl %%ecx, %[esp_offset:c](%%edx) |
| 416 | \\ xorl %%ecx, %%ecx | 413 | \\ xorl %%ecx, %%ecx |
| 417 | \\ movw %%fs, %%cx | 414 | \\ movw %%fs, %%cx |
| 418 | \\ movl %%ecx, (%[fs_offset])(%%edx) | 415 | \\ movl %%ecx, %[fs_offset:c](%%edx) |
| 419 | \\ leal (%[regspace_offset])(%%edx), %%ecx | 416 | \\ leal %[regspace_offset:c](%%edx), %%ecx |
| 420 | \\ movl %%ecx, (%[fpregs_offset])(%%edx) | 417 | \\ movl %%ecx, %[fpregs_offset:c](%%edx) |
| 421 | \\ fnstenv (%%ecx) | 418 | \\ fnstenv (%%ecx) |
| 422 | \\ fldenv (%%ecx) | 419 | \\ fldenv (%%ecx) |
| 423 | \\ pushl %%ebx | 420 | \\ pushl %%ebx |
| 424 | \\ pushl %%esi | 421 | \\ pushl %%esi |
| 425 | \\ xorl %%ebx, %%ebx | 422 | \\ xorl %%ebx, %%ebx |
| 426 | \\ movl %[sigaltstack], %%eax | 423 | \\ movl %[sigaltstack], %%eax |
| 427 | \\ leal (%[stack_offset])(%%edx), %%ecx | 424 | \\ leal %[stack_offset:c](%%edx), %%ecx |
| 428 | \\ int $0x80 | 425 | \\ int $0x80 |
| 429 | \\ cmpl $0, %%eax | 426 | \\ testl %%eax, %%eax |
| 430 | \\ jne return | 427 | \\ jnz 0f |
| 431 | \\ movl %[sigprocmask], %%eax | 428 | \\ movl %[sigprocmask], %%eax |
| 432 | \\ xorl %%ecx, %%ecx | 429 | \\ xorl %%ecx, %%ecx |
| 433 | \\ leal (%[sigmask_offset])(%%edx), %%edx | 430 | \\ leal %[sigmask_offset:c](%%edx), %%edx |
| 434 | \\ movl %[sigset_size], %%esi | 431 | \\ movl %[sigset_size], %%esi |
| 435 | \\ int $0x80 | 432 | \\ int $0x80 |
| 436 | \\ return: | 433 | \\0: |
| 437 | \\ popl %%esi | 434 | \\ popl %%esi |
| 438 | \\ popl %%ebx | 435 | \\ popl %%ebx |
| 436 | \\ retl | ||
| 439 | : | 437 | : |
| 440 | : [flags_offset] "p" (@offsetOf(ucontext_t, "flags")), | 438 | : [flags_offset] "i" (@offsetOf(ucontext_t, "flags")), |
| 441 | [link_offset] "p" (@offsetOf(ucontext_t, "link")), | 439 | [link_offset] "i" (@offsetOf(ucontext_t, "link")), |
| 442 | [edi_offset] "p" (comptime gpRegisterOffset(REG.EDI)), | 440 | [edi_offset] "i" (comptime gpRegisterOffset(REG.EDI)), |
| 443 | [esi_offset] "p" (comptime gpRegisterOffset(REG.ESI)), | 441 | [esi_offset] "i" (comptime gpRegisterOffset(REG.ESI)), |
| 444 | [ebp_offset] "p" (comptime gpRegisterOffset(REG.EBP)), | 442 | [ebp_offset] "i" (comptime gpRegisterOffset(REG.EBP)), |
| 445 | [esp_offset] "p" (comptime gpRegisterOffset(REG.ESP)), | 443 | [esp_offset] "i" (comptime gpRegisterOffset(REG.ESP)), |
| 446 | [ebx_offset] "p" (comptime gpRegisterOffset(REG.EBX)), | 444 | [ebx_offset] "i" (comptime gpRegisterOffset(REG.EBX)), |
| 447 | [edx_offset] "p" (comptime gpRegisterOffset(REG.EDX)), | 445 | [edx_offset] "i" (comptime gpRegisterOffset(REG.EDX)), |
| 448 | [ecx_offset] "p" (comptime gpRegisterOffset(REG.ECX)), | 446 | [ecx_offset] "i" (comptime gpRegisterOffset(REG.ECX)), |
| 449 | [eax_offset] "p" (comptime gpRegisterOffset(REG.EAX)), | 447 | [eax_offset] "i" (comptime gpRegisterOffset(REG.EAX)), |
| 450 | [eip_offset] "p" (comptime gpRegisterOffset(REG.EIP)), | 448 | [eip_offset] "i" (comptime gpRegisterOffset(REG.EIP)), |
| 451 | [fs_offset] "p" (comptime gpRegisterOffset(REG.FS)), | 449 | [fs_offset] "i" (comptime gpRegisterOffset(REG.FS)), |
| 452 | [fpregs_offset] "p" (@offsetOf(ucontext_t, "mcontext") + @offsetOf(mcontext_t, "fpregs")), | 450 | [fpregs_offset] "i" (@offsetOf(ucontext_t, "mcontext") + @offsetOf(mcontext_t, "fpregs")), |
| 453 | [regspace_offset] "p" (@offsetOf(ucontext_t, "regspace")), | 451 | [regspace_offset] "i" (@offsetOf(ucontext_t, "regspace")), |
| 454 | [sigaltstack] "i" (@intFromEnum(linux.SYS.sigaltstack)), | 452 | [sigaltstack] "i" (@intFromEnum(linux.SYS.sigaltstack)), |
| 455 | [stack_offset] "p" (@offsetOf(ucontext_t, "stack")), | 453 | [stack_offset] "i" (@offsetOf(ucontext_t, "stack")), |
| 456 | [sigprocmask] "i" (@intFromEnum(linux.SYS.rt_sigprocmask)), | 454 | [sigprocmask] "i" (@intFromEnum(linux.SYS.rt_sigprocmask)), |
| 457 | [sigmask_offset] "p" (@offsetOf(ucontext_t, "sigmask")), | 455 | [sigmask_offset] "i" (@offsetOf(ucontext_t, "sigmask")), |
| 458 | [sigset_size] "i" (linux.NSIG / 8), | 456 | [sigset_size] "i" (linux.NSIG / 8), |
| 459 | : "memory", "eax", "ecx", "edx" | 457 | : "cc", "memory", "eax", "ecx", "edx" |
| 460 | ); | 458 | ); |
| 461 | } | 459 | } |
| 462 | 460 | ||
| 463 | pub inline fn getcontext(context: *ucontext_t) usize { | 461 | pub inline fn getcontext(context: *ucontext_t) usize { |
| 464 | // This method is used so that getContextInternal can control | 462 | // This method is used so that getContextInternal can control |
| 465 | // its prologue in order to read ESP from a constant offset. | 463 | // its prologue in order to read ESP from a constant offset. |
| 466 | // The unused &getContextInternal input is required so the function is included in the binary. | 464 | // An aligned stack is not needed for getContextInternal. |
| 465 | var clobber_edx: usize = undefined; | ||
| 467 | return asm volatile ( | 466 | return asm volatile ( |
| 468 | \\ call os.linux.x86.getContextInternal | 467 | \\ calll %[getContextInternal:P] |
| 469 | : [ret] "={eax}" (-> usize), | 468 | : [_] "={eax}" (-> usize), |
| 470 | : [context] "{edx}" (context), | 469 | [_] "={edx}" (clobber_edx), |
| 470 | : [_] "{edx}" (context), | ||
| 471 | [getContextInternal] "X" (&getContextInternal), | 471 | [getContextInternal] "X" (&getContextInternal), |
| 472 | : "memory", "ecx" | 472 | : "cc", "memory", "ecx" |
| 473 | ); | 473 | ); |
| 474 | } | 474 | } |
lib/std/os/linux/x86_64.zig+67-67| ... | @@ -107,25 +107,22 @@ pub extern fn clone(func: CloneFn, stack: usize, flags: usize, arg: usize, ptid: | ... | @@ -107,25 +107,22 @@ pub extern fn clone(func: CloneFn, stack: usize, flags: usize, arg: usize, ptid: |
| 107 | 107 | ||
| 108 | pub const restore = restore_rt; | 108 | pub const restore = restore_rt; |
| 109 | 109 | ||
| 110 | pub fn restore_rt() callconv(.Naked) void { | 110 | pub fn restore_rt() callconv(.Naked) noreturn { |
| 111 | switch (@import("builtin").zig_backend) { | 111 | switch (@import("builtin").zig_backend) { |
| 112 | .stage2_c => asm volatile ( | 112 | .stage2_c => asm volatile ( |
| 113 | \\ movl %[number], %%eax | 113 | \\ movl %[number], %%eax |
| 114 | \\ syscall | 114 | \\ syscall |
| 115 | \\ retq | ||
| 116 | : | 115 | : |
| 117 | : [number] "i" (@intFromEnum(SYS.rt_sigreturn)), | 116 | : [number] "i" (@intFromEnum(SYS.rt_sigreturn)), |
| 118 | : "rcx", "r11", "memory" | 117 | : "rcx", "r11", "memory" |
| 119 | ), | 118 | ), |
| 120 | else => asm volatile ( | 119 | else => asm volatile ( |
| 121 | \\ syscall | 120 | \\ syscall |
| 122 | \\ retq | ||
| 123 | : | 121 | : |
| 124 | : [number] "{rax}" (@intFromEnum(SYS.rt_sigreturn)), | 122 | : [number] "{rax}" (@intFromEnum(SYS.rt_sigreturn)), |
| 125 | : "rcx", "r11", "memory" | 123 | : "rcx", "r11", "memory" |
| 126 | ), | 124 | ), |
| 127 | } | 125 | } |
| 128 | unreachable; | ||
| 129 | } | 126 | } |
| 130 | 127 | ||
| 131 | pub const mode_t = usize; | 128 | pub const mode_t = usize; |
| ... | @@ -400,92 +397,95 @@ fn gpRegisterOffset(comptime reg_index: comptime_int) usize { | ... | @@ -400,92 +397,95 @@ fn gpRegisterOffset(comptime reg_index: comptime_int) usize { |
| 400 | return @offsetOf(ucontext_t, "mcontext") + @offsetOf(mcontext_t, "gregs") + @sizeOf(usize) * reg_index; | 397 | return @offsetOf(ucontext_t, "mcontext") + @offsetOf(mcontext_t, "gregs") + @sizeOf(usize) * reg_index; |
| 401 | } | 398 | } |
| 402 | 399 | ||
| 403 | fn getContextInternal() callconv(.Naked) void { | 400 | fn getContextInternal() callconv(.Naked) usize { |
| 404 | // TODO: Read GS/FS registers? | 401 | // TODO: Read GS/FS registers? |
| 405 | asm volatile ( | 402 | asm volatile ( |
| 406 | \\ movq $0, (%[flags_offset])(%%rdi) | 403 | \\ movq $0, %[flags_offset:c](%%rdi) |
| 407 | \\ movq $0, (%[link_offset])(%%rdi) | 404 | \\ movq $0, %[link_offset:c](%%rdi) |
| 408 | \\ movq %%r8, (%[r8_offset])(%%rdi) | 405 | \\ movq %%r8, %[r8_offset:c](%%rdi) |
| 409 | \\ movq %%r9, (%[r9_offset])(%%rdi) | 406 | \\ movq %%r9, %[r9_offset:c](%%rdi) |
| 410 | \\ movq %%r10, (%[r10_offset])(%%rdi) | 407 | \\ movq %%r10, %[r10_offset:c](%%rdi) |
| 411 | \\ movq %%r11, (%[r11_offset])(%%rdi) | 408 | \\ movq %%r11, %[r11_offset:c](%%rdi) |
| 412 | \\ movq %%r12, (%[r12_offset])(%%rdi) | 409 | \\ movq %%r12, %[r12_offset:c](%%rdi) |
| 413 | \\ movq %%r13, (%[r13_offset])(%%rdi) | 410 | \\ movq %%r13, %[r13_offset:c](%%rdi) |
| 414 | \\ movq %%r14, (%[r14_offset])(%%rdi) | 411 | \\ movq %%r14, %[r14_offset:c](%%rdi) |
| 415 | \\ movq %%r15, (%[r15_offset])(%%rdi) | 412 | \\ movq %%r15, %[r15_offset:c](%%rdi) |
| 416 | \\ movq %%rdi, (%[rdi_offset])(%%rdi) | 413 | \\ movq %%rdi, %[rdi_offset:c](%%rdi) |
| 417 | \\ movq %%rsi, (%[rsi_offset])(%%rdi) | 414 | \\ movq %%rsi, %[rsi_offset:c](%%rdi) |
| 418 | \\ movq %%rbp, (%[rbp_offset])(%%rdi) | 415 | \\ movq %%rbp, %[rbp_offset:c](%%rdi) |
| 419 | \\ movq %%rbx, (%[rbx_offset])(%%rdi) | 416 | \\ movq %%rbx, %[rbx_offset:c](%%rdi) |
| 420 | \\ movq %%rdx, (%[rdx_offset])(%%rdi) | 417 | \\ movq %%rdx, %[rdx_offset:c](%%rdi) |
| 421 | \\ movq %%rax, (%[rax_offset])(%%rdi) | 418 | \\ movq %%rax, %[rax_offset:c](%%rdi) |
| 422 | \\ movq %%rcx, (%[rcx_offset])(%%rdi) | 419 | \\ movq %%rcx, %[rcx_offset:c](%%rdi) |
| 423 | \\ movq (%%rsp), %%rcx | 420 | \\ movq (%%rsp), %%rcx |
| 424 | \\ movq %%rcx, (%[rip_offset])(%%rdi) | 421 | \\ movq %%rcx, %[rip_offset:c](%%rdi) |
| 425 | \\ leaq 8(%%rsp), %%rcx | 422 | \\ leaq 8(%%rsp), %%rcx |
| 426 | \\ movq %%rcx, (%[rsp_offset])(%%rdi) | 423 | \\ movq %%rcx, %[rsp_offset:c](%%rdi) |
| 427 | \\ pushfq | 424 | \\ pushfq |
| 428 | \\ popq (%[efl_offset])(%%rdi) | 425 | \\ popq %[efl_offset:c](%%rdi) |
| 429 | \\ leaq (%[fpmem_offset])(%%rdi), %%rcx | 426 | \\ leaq %[fpmem_offset:c](%%rdi), %%rcx |
| 430 | \\ movq %%rcx, (%[fpstate_offset])(%%rdi) | 427 | \\ movq %%rcx, %[fpstate_offset:c](%%rdi) |
| 431 | \\ fnstenv (%%rcx) | 428 | \\ fnstenv (%%rcx) |
| 432 | \\ fldenv (%%rcx) | 429 | \\ fldenv (%%rcx) |
| 433 | \\ stmxcsr (%[mxcsr_offset])(%%rdi) | 430 | \\ stmxcsr %[mxcsr_offset:c](%%rdi) |
| 434 | \\ leaq (%[stack_offset])(%%rdi), %%rsi | 431 | \\ leaq %[stack_offset:c](%%rdi), %%rsi |
| 435 | \\ movq %%rdi, %%r8 | 432 | \\ movq %%rdi, %%r8 |
| 436 | \\ xorq %%rdi, %%rdi | 433 | \\ xorl %%edi, %%edi |
| 437 | \\ movq %[sigaltstack], %%rax | 434 | \\ movq %[sigaltstack], %%rax |
| 438 | \\ syscall | 435 | \\ syscall |
| 439 | \\ cmpq $0, %%rax | 436 | \\ testq %%rax, %%rax |
| 440 | \\ jne return | 437 | \\ jnz 0f |
| 441 | \\ movq %[sigprocmask], %%rax | 438 | \\ movq %[sigprocmask], %%rax |
| 442 | \\ xorq %%rsi, %%rsi | 439 | \\ xorl %%esi, %%esi |
| 443 | \\ leaq (%[sigmask_offset])(%%r8), %%rdx | 440 | \\ leaq %[sigmask_offset:c](%%r8), %%rdx |
| 444 | \\ movq %[sigset_size], %%r10 | 441 | \\ movl %[sigset_size], %%r10d |
| 445 | \\ syscall | 442 | \\ syscall |
| 446 | \\ return: | 443 | \\0: |
| 444 | \\ retq | ||
| 447 | : | 445 | : |
| 448 | : [flags_offset] "p" (@offsetOf(ucontext_t, "flags")), | 446 | : [flags_offset] "i" (@offsetOf(ucontext_t, "flags")), |
| 449 | [link_offset] "p" (@offsetOf(ucontext_t, "link")), | 447 | [link_offset] "i" (@offsetOf(ucontext_t, "link")), |
| 450 | [r8_offset] "p" (comptime gpRegisterOffset(REG.R8)), | 448 | [r8_offset] "i" (comptime gpRegisterOffset(REG.R8)), |
| 451 | [r9_offset] "p" (comptime gpRegisterOffset(REG.R9)), | 449 | [r9_offset] "i" (comptime gpRegisterOffset(REG.R9)), |
| 452 | [r10_offset] "p" (comptime gpRegisterOffset(REG.R10)), | 450 | [r10_offset] "i" (comptime gpRegisterOffset(REG.R10)), |
| 453 | [r11_offset] "p" (comptime gpRegisterOffset(REG.R11)), | 451 | [r11_offset] "i" (comptime gpRegisterOffset(REG.R11)), |
| 454 | [r12_offset] "p" (comptime gpRegisterOffset(REG.R12)), | 452 | [r12_offset] "i" (comptime gpRegisterOffset(REG.R12)), |
| 455 | [r13_offset] "p" (comptime gpRegisterOffset(REG.R13)), | 453 | [r13_offset] "i" (comptime gpRegisterOffset(REG.R13)), |
| 456 | [r14_offset] "p" (comptime gpRegisterOffset(REG.R14)), | 454 | [r14_offset] "i" (comptime gpRegisterOffset(REG.R14)), |
| 457 | [r15_offset] "p" (comptime gpRegisterOffset(REG.R15)), | 455 | [r15_offset] "i" (comptime gpRegisterOffset(REG.R15)), |
| 458 | [rdi_offset] "p" (comptime gpRegisterOffset(REG.RDI)), | 456 | [rdi_offset] "i" (comptime gpRegisterOffset(REG.RDI)), |
| 459 | [rsi_offset] "p" (comptime gpRegisterOffset(REG.RSI)), | 457 | [rsi_offset] "i" (comptime gpRegisterOffset(REG.RSI)), |
| 460 | [rbp_offset] "p" (comptime gpRegisterOffset(REG.RBP)), | 458 | [rbp_offset] "i" (comptime gpRegisterOffset(REG.RBP)), |
| 461 | [rbx_offset] "p" (comptime gpRegisterOffset(REG.RBX)), | 459 | [rbx_offset] "i" (comptime gpRegisterOffset(REG.RBX)), |
| 462 | [rdx_offset] "p" (comptime gpRegisterOffset(REG.RDX)), | 460 | [rdx_offset] "i" (comptime gpRegisterOffset(REG.RDX)), |
| 463 | [rax_offset] "p" (comptime gpRegisterOffset(REG.RAX)), | 461 | [rax_offset] "i" (comptime gpRegisterOffset(REG.RAX)), |
| 464 | [rcx_offset] "p" (comptime gpRegisterOffset(REG.RCX)), | 462 | [rcx_offset] "i" (comptime gpRegisterOffset(REG.RCX)), |
| 465 | [rsp_offset] "p" (comptime gpRegisterOffset(REG.RSP)), | 463 | [rsp_offset] "i" (comptime gpRegisterOffset(REG.RSP)), |
| 466 | [rip_offset] "p" (comptime gpRegisterOffset(REG.RIP)), | 464 | [rip_offset] "i" (comptime gpRegisterOffset(REG.RIP)), |
| 467 | [efl_offset] "p" (comptime gpRegisterOffset(REG.EFL)), | 465 | [efl_offset] "i" (comptime gpRegisterOffset(REG.EFL)), |
| 468 | [fpstate_offset] "p" (@offsetOf(ucontext_t, "mcontext") + @offsetOf(mcontext_t, "fpregs")), | 466 | [fpstate_offset] "i" (@offsetOf(ucontext_t, "mcontext") + @offsetOf(mcontext_t, "fpregs")), |
| 469 | [fpmem_offset] "p" (@offsetOf(ucontext_t, "fpregs_mem")), | 467 | [fpmem_offset] "i" (@offsetOf(ucontext_t, "fpregs_mem")), |
| 470 | [mxcsr_offset] "p" (@offsetOf(ucontext_t, "fpregs_mem") + @offsetOf(fpstate, "mxcsr")), | 468 | [mxcsr_offset] "i" (@offsetOf(ucontext_t, "fpregs_mem") + @offsetOf(fpstate, "mxcsr")), |
| 471 | [sigaltstack] "i" (@intFromEnum(linux.SYS.sigaltstack)), | 469 | [sigaltstack] "i" (@intFromEnum(linux.SYS.sigaltstack)), |
| 472 | [stack_offset] "p" (@offsetOf(ucontext_t, "stack")), | 470 | [stack_offset] "i" (@offsetOf(ucontext_t, "stack")), |
| 473 | [sigprocmask] "i" (@intFromEnum(linux.SYS.rt_sigprocmask)), | 471 | [sigprocmask] "i" (@intFromEnum(linux.SYS.rt_sigprocmask)), |
| 474 | [sigmask_offset] "p" (@offsetOf(ucontext_t, "sigmask")), | 472 | [sigmask_offset] "i" (@offsetOf(ucontext_t, "sigmask")), |
| 475 | [sigset_size] "i" (linux.NSIG / 8), | 473 | [sigset_size] "i" (linux.NSIG / 8), |
| 476 | : "memory", "rcx", "rdx", "rdi", "rsi", "r8", "r10", "r11" | 474 | : "cc", "memory", "rax", "rcx", "rdx", "rdi", "rsi", "r8", "r10", "r11" |
| 477 | ); | 475 | ); |
| 478 | } | 476 | } |
| 479 | 477 | ||
| 480 | pub inline fn getcontext(context: *ucontext_t) usize { | 478 | pub inline fn getcontext(context: *ucontext_t) usize { |
| 481 | // This method is used so that getContextInternal can control | 479 | // This method is used so that getContextInternal can control |
| 482 | // its prologue in order to read RSP from a constant offset | 480 | // its prologue in order to read RSP from a constant offset |
| 483 | // The unused &getContextInternal input is required so the function is included in the binary. | 481 | // An aligned stack is not needed for getContextInternal. |
| 482 | var clobber_rdi: usize = undefined; | ||
| 484 | return asm volatile ( | 483 | return asm volatile ( |
| 485 | \\ call os.linux.x86_64.getContextInternal | 484 | \\ callq %[getContextInternal:P] |
| 486 | : [ret] "={rax}" (-> usize), | 485 | : [_] "={rax}" (-> usize), |
| 487 | : [context] "{rdi}" (context), | 486 | [_] "={rdi}" (clobber_rdi), |
| 487 | : [_] "{rdi}" (context), | ||
| 488 | [getContextInternal] "X" (&getContextInternal), | 488 | [getContextInternal] "X" (&getContextInternal), |
| 489 | : "memory", "rcx", "rdx", "rdi", "rsi", "r8", "r10", "r11" | 489 | : "cc", "memory", "rcx", "rdx", "rsi", "r8", "r10", "r11" |
| 490 | ); | 490 | ); |
| 491 | } | 491 | } |
lib/std/start.zig+86-112| ... | @@ -101,7 +101,7 @@ fn main2() callconv(.C) c_int { | ... | @@ -101,7 +101,7 @@ fn main2() callconv(.C) c_int { |
| 101 | return 0; | 101 | return 0; |
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | fn _start2() callconv(.Naked) noreturn { | 104 | fn _start2() noreturn { |
| 105 | callMain2(); | 105 | callMain2(); |
| 106 | } | 106 | } |
| 107 | 107 | ||
| ... | @@ -254,116 +254,92 @@ fn EfiMain(handle: uefi.Handle, system_table: *uefi.tables.SystemTable) callconv | ... | @@ -254,116 +254,92 @@ fn EfiMain(handle: uefi.Handle, system_table: *uefi.tables.SystemTable) callconv |
| 254 | } | 254 | } |
| 255 | 255 | ||
| 256 | fn _start() callconv(.Naked) noreturn { | 256 | fn _start() callconv(.Naked) noreturn { |
| 257 | switch (builtin.zig_backend) { | 257 | asm volatile (switch (native_arch) { |
| 258 | .stage2_c => { | 258 | .x86_64 => |
| 259 | @export(argc_argv_ptr, .{ .name = "argc_argv_ptr" }); | 259 | \\ xorl %%ebp, %%ebp |
| 260 | @export(posixCallMainAndExit, .{ .name = "_posixCallMainAndExit" }); | 260 | \\ movq %%rsp, %[argc_argv_ptr] |
| 261 | switch (native_arch) { | 261 | \\ andq $-16, %%rsp |
| 262 | .x86_64 => asm volatile ( | 262 | \\ callq %[posixCallMainAndExit:P] |
| 263 | \\ xorl %%ebp, %%ebp | 263 | , |
| 264 | \\ movq %%rsp, argc_argv_ptr | 264 | .x86 => |
| 265 | \\ andq $-16, %%rsp | 265 | \\ xorl %%ebp, %%ebp |
| 266 | \\ call _posixCallMainAndExit | 266 | \\ movl %%esp, %[argc_argv_ptr] |
| 267 | ), | 267 | \\ andl $-16, %%esp |
| 268 | .x86 => asm volatile ( | 268 | \\ calll %[posixCallMainAndExit:P] |
| 269 | \\ xorl %%ebp, %%ebp | 269 | , |
| 270 | \\ movl %%esp, argc_argv_ptr | 270 | .aarch64, .aarch64_be => |
| 271 | \\ andl $-16, %%esp | 271 | \\ mov fp, #0 |
| 272 | \\ jmp _posixCallMainAndExit | 272 | \\ mov lr, #0 |
| 273 | ), | 273 | \\ mov x0, sp |
| 274 | .aarch64, .aarch64_be => asm volatile ( | 274 | \\ str x0, %[argc_argv_ptr] |
| 275 | \\ mov fp, #0 | 275 | \\ b %[posixCallMainAndExit] |
| 276 | \\ mov lr, #0 | 276 | , |
| 277 | \\ mov x0, sp | 277 | .arm, .armeb, .thumb, .thumbeb => |
| 278 | \\ adrp x1, argc_argv_ptr | 278 | \\ mov fp, #0 |
| 279 | \\ str x0, [x1, :lo12:argc_argv_ptr] | 279 | \\ mov lr, #0 |
| 280 | \\ b _posixCallMainAndExit | 280 | \\ str sp, %[argc_argv_ptr] |
| 281 | ), | 281 | \\ and sp, #-16 |
| 282 | .arm, .armeb, .thumb => asm volatile ( | 282 | \\ b %[posixCallMainAndExit] |
| 283 | \\ mov fp, #0 | 283 | , |
| 284 | \\ mov lr, #0 | 284 | .riscv64 => |
| 285 | \\ str sp, argc_argv_ptr | 285 | \\ li s0, 0 |
| 286 | \\ and sp, #-16 | 286 | \\ li ra, 0 |
| 287 | \\ b _posixCallMainAndExit | 287 | \\ sd sp, %[argc_argv_ptr] |
| 288 | ), | 288 | \\ andi sp, sp, -16 |
| 289 | else => @compileError("unsupported arch"), | 289 | \\ tail %[posixCallMainAndExit]@plt |
| 290 | } | 290 | , |
| 291 | unreachable; | 291 | .mips, .mipsel => |
| 292 | }, | 292 | // The lr is already zeroed on entry, as specified by the ABI. |
| 293 | else => switch (native_arch) { | 293 | \\ addiu $fp, $zero, 0 |
| 294 | .x86_64 => { | 294 | \\ sw $sp, %[argc_argv_ptr] |
| 295 | argc_argv_ptr = asm volatile ( | 295 | \\ .set push |
| 296 | \\ xor %%ebp, %%ebp | 296 | \\ .set noat |
| 297 | : [argc] "={rsp}" (-> [*]usize), | 297 | \\ addiu $1, $zero, -16 |
| 298 | ); | 298 | \\ and $sp, $sp, $1 |
| 299 | }, | 299 | \\ .set pop |
| 300 | .x86 => { | 300 | \\ j %[posixCallMainAndExit] |
| 301 | argc_argv_ptr = asm volatile ( | 301 | , |
| 302 | \\ xor %%ebp, %%ebp | 302 | .mips64, .mips64el => |
| 303 | : [argc] "={esp}" (-> [*]usize), | 303 | // The lr is already zeroed on entry, as specified by the ABI. |
| 304 | ); | 304 | \\ addiu $fp, $zero, 0 |
| 305 | }, | 305 | \\ sd $sp, %[argc_argv_ptr] |
| 306 | .aarch64, .aarch64_be, .arm, .armeb, .thumb => { | 306 | \\ .set push |
| 307 | argc_argv_ptr = asm volatile ( | 307 | \\ .set noat |
| 308 | \\ mov fp, #0 | 308 | \\ daddiu $1, $zero, -16 |
| 309 | \\ mov lr, #0 | 309 | \\ and $sp, $sp, $1 |
| 310 | : [argc] "={sp}" (-> [*]usize), | 310 | \\ .set pop |
| 311 | ); | 311 | \\ j %[posixCallMainAndExit] |
| 312 | }, | 312 | , |
| 313 | .riscv64 => { | 313 | .powerpc, .powerpcle => |
| 314 | argc_argv_ptr = asm volatile ( | 314 | // Setup the initial stack frame and clear the back chain pointer. |
| 315 | \\ li s0, 0 | 315 | \\ stw 1, %[argc_argv_ptr] |
| 316 | \\ li ra, 0 | 316 | \\ li 0, 0 |
| 317 | : [argc] "={sp}" (-> [*]usize), | 317 | \\ stwu 1, -16(1) |
| 318 | ); | 318 | \\ stw 0, 0(1) |
| 319 | }, | 319 | \\ mtlr 0 |
| 320 | .mips, .mipsel, .mips64, .mips64el => { | 320 | \\ b %[posixCallMainAndExit] |
| 321 | // The lr is already zeroed on entry, as specified by the ABI. | 321 | , |
| 322 | argc_argv_ptr = asm volatile ( | 322 | .powerpc64, .powerpc64le => |
| 323 | \\ move $fp, $0 | 323 | // Setup the initial stack frame and clear the back chain pointer. |
| 324 | : [argc] "={sp}" (-> [*]usize), | 324 | // TODO: Support powerpc64 (big endian) on ELFv2. |
| 325 | ); | 325 | \\ std 1, %[argc_argv_ptr] |
| 326 | }, | 326 | \\ li 0, 0 |
| 327 | .powerpc => { | 327 | \\ stdu 0, -32(1) |
| 328 | // Setup the initial stack frame and clear the back chain pointer. | 328 | \\ mtlr 0 |
| 329 | argc_argv_ptr = asm volatile ( | 329 | \\ b %[posixCallMainAndExit] |
| 330 | \\ mr 4, 1 | 330 | , |
| 331 | \\ li 0, 0 | 331 | .sparc64 => |
| 332 | \\ stwu 1,-16(1) | 332 | // argc is stored after a register window (16 registers) plus stack bias |
| 333 | \\ stw 0, 0(1) | 333 | \\ mov %%g0, %%i6 |
| 334 | \\ mtlr 0 | 334 | \\ add %%o6, 2175, %%l0 |
| 335 | : [argc] "={r4}" (-> [*]usize), | 335 | \\ stx %%l0, %[argc_argv_ptr] |
| 336 | : | 336 | \\ ba %[posixCallMainAndExit] |
| 337 | : "r0" | 337 | , |
| 338 | ); | ||
| 339 | }, | ||
| 340 | .powerpc64le => { | ||
| 341 | // Setup the initial stack frame and clear the back chain pointer. | ||
| 342 | // TODO: Support powerpc64 (big endian) on ELFv2. | ||
| 343 | argc_argv_ptr = asm volatile ( | ||
| 344 | \\ mr 4, 1 | ||
| 345 | \\ li 0, 0 | ||
| 346 | \\ stdu 0, -32(1) | ||
| 347 | \\ mtlr 0 | ||
| 348 | : [argc] "={r4}" (-> [*]usize), | ||
| 349 | : | ||
| 350 | : "r0" | ||
| 351 | ); | ||
| 352 | }, | ||
| 353 | .sparc64 => { | ||
| 354 | // argc is stored after a register window (16 registers) plus stack bias | ||
| 355 | argc_argv_ptr = asm ( | ||
| 356 | \\ mov %%g0, %%i6 | ||
| 357 | \\ add %%o6, 2175, %[argc] | ||
| 358 | : [argc] "=r" (-> [*]usize), | ||
| 359 | ); | ||
| 360 | }, | ||
| 361 | else => @compileError("unsupported arch"), | 338 | else => @compileError("unsupported arch"), |
| 362 | }, | 339 | } |
| 363 | } | 340 | : [argc_argv_ptr] "=m" (argc_argv_ptr), |
| 364 | // If LLVM inlines stack variables into _start, they will overwrite | 341 | : [posixCallMainAndExit] "X" (&posixCallMainAndExit), |
| 365 | // the command line argument data. | 342 | ); |
| 366 | @call(.never_inline, posixCallMainAndExit, .{}); | ||
| 367 | } | 343 | } |
| 368 | 344 | ||
| 369 | fn WinStartup() callconv(std.os.windows.WINAPI) noreturn { | 345 | fn WinStartup() callconv(std.os.windows.WINAPI) noreturn { |
| ... | @@ -390,8 +366,6 @@ fn wWinMainCRTStartup() callconv(std.os.windows.WINAPI) noreturn { | ... | @@ -390,8 +366,6 @@ fn wWinMainCRTStartup() callconv(std.os.windows.WINAPI) noreturn { |
| 390 | } | 366 | } |
| 391 | 367 | ||
| 392 | fn posixCallMainAndExit() callconv(.C) noreturn { | 368 | fn posixCallMainAndExit() callconv(.C) noreturn { |
| 393 | @setAlignStack(16); | ||
| 394 | |||
| 395 | const argc = argc_argv_ptr[0]; | 369 | const argc = argc_argv_ptr[0]; |
| 396 | const argv = @as([*][*:0]u8, @ptrCast(argc_argv_ptr + 1)); | 370 | const argv = @as([*][*:0]u8, @ptrCast(argc_argv_ptr + 1)); |
| 397 | 371 |
lib/std/target.zig+5| ... | @@ -899,6 +899,10 @@ pub const Target = struct { | ... | @@ -899,6 +899,10 @@ pub const Target = struct { |
| 899 | }; | 899 | }; |
| 900 | } | 900 | } |
| 901 | 901 | ||
| 902 | pub fn isArmOrThumb(arch: Arch) bool { | ||
| 903 | return arch.isARM() or arch.isThumb(); | ||
| 904 | } | ||
| 905 | |||
| 902 | pub fn isWasm(arch: Arch) bool { | 906 | pub fn isWasm(arch: Arch) bool { |
| 903 | return switch (arch) { | 907 | return switch (arch) { |
| 904 | .wasm32, .wasm64 => true, | 908 | .wasm32, .wasm64 => true, |
| ... | @@ -1960,6 +1964,7 @@ pub const Target = struct { | ... | @@ -1960,6 +1964,7 @@ pub const Target = struct { |
| 1960 | .thumbeb, | 1964 | .thumbeb, |
| 1961 | => return if (target.os.tag.isDarwin() or target.os.tag == .windows) .signed else .unsigned, | 1965 | => return if (target.os.tag.isDarwin() or target.os.tag == .windows) .signed else .unsigned, |
| 1962 | .powerpc, .powerpc64 => return if (target.os.tag.isDarwin()) .signed else .unsigned, | 1966 | .powerpc, .powerpc64 => return if (target.os.tag.isDarwin()) .signed else .unsigned, |
| 1967 | .powerpcle, | ||
| 1963 | .powerpc64le, | 1968 | .powerpc64le, |
| 1964 | .s390x, | 1969 | .s390x, |
| 1965 | .xcore, | 1970 | .xcore, |
lib/zig.h+76-13| ... | @@ -1176,10 +1176,10 @@ typedef signed __int128 zig_i128; | ... | @@ -1176,10 +1176,10 @@ typedef signed __int128 zig_i128; |
| 1176 | 1176 | ||
| 1177 | #if zig_little_endian | 1177 | #if zig_little_endian |
| 1178 | typedef struct { zig_align(16) uint64_t lo; uint64_t hi; } zig_u128; | 1178 | typedef struct { zig_align(16) uint64_t lo; uint64_t hi; } zig_u128; |
| 1179 | typedef struct { zig_align(16) uint64_t lo; int64_t hi; } zig_i128; | 1179 | typedef struct { zig_align(16) uint64_t lo; int64_t hi; } zig_i128; |
| 1180 | #else | 1180 | #else |
| 1181 | typedef struct { zig_align(16) uint64_t hi; uint64_t lo; } zig_u128; | 1181 | typedef struct { zig_align(16) uint64_t hi; uint64_t lo; } zig_u128; |
| 1182 | typedef struct { zig_align(16) int64_t hi; uint64_t lo; } zig_i128; | 1182 | typedef struct { zig_align(16) int64_t hi; uint64_t lo; } zig_i128; |
| 1183 | #endif | 1183 | #endif |
| 1184 | 1184 | ||
| 1185 | #define zig_make_u128(hi, lo) ((zig_u128){ .h##i = (hi), .l##o = (lo) }) | 1185 | #define zig_make_u128(hi, lo) ((zig_u128){ .h##i = (hi), .l##o = (lo) }) |
| ... | @@ -3197,11 +3197,9 @@ zig_convert_builtin(zig_compiler_rt_f16, zig_f16, trunc, zig_f64, | ... | @@ -3197,11 +3197,9 @@ zig_convert_builtin(zig_compiler_rt_f16, zig_f16, trunc, zig_f64, |
| 3197 | zig_convert_builtin(zig_f16, zig_f16, trunc, zig_f80, zig_f80, 2) | 3197 | zig_convert_builtin(zig_f16, zig_f16, trunc, zig_f80, zig_f80, 2) |
| 3198 | zig_convert_builtin(zig_f16, zig_f16, trunc, zig_f128, zig_f128, 2) | 3198 | zig_convert_builtin(zig_f16, zig_f16, trunc, zig_f128, zig_f128, 2) |
| 3199 | zig_convert_builtin(zig_f32, zig_f32, extend, zig_compiler_rt_f16, zig_f16, 2) | 3199 | zig_convert_builtin(zig_f32, zig_f32, extend, zig_compiler_rt_f16, zig_f16, 2) |
| 3200 | zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f64, zig_f64, 2) | ||
| 3201 | zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f80, zig_f80, 2) | 3200 | zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f80, zig_f80, 2) |
| 3202 | zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f128, zig_f128, 2) | 3201 | zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f128, zig_f128, 2) |
| 3203 | zig_convert_builtin(zig_f64, zig_f64, extend, zig_compiler_rt_f16, zig_f16, 2) | 3202 | zig_convert_builtin(zig_f64, zig_f64, extend, zig_compiler_rt_f16, zig_f16, 2) |
| 3204 | zig_convert_builtin(zig_f64, zig_f64, extend, zig_f32, zig_f32, 2) | ||
| 3205 | zig_convert_builtin(zig_f64, zig_f64, trunc, zig_f80, zig_f80, 2) | 3203 | zig_convert_builtin(zig_f64, zig_f64, trunc, zig_f80, zig_f80, 2) |
| 3206 | zig_convert_builtin(zig_f64, zig_f64, trunc, zig_f128, zig_f128, 2) | 3204 | zig_convert_builtin(zig_f64, zig_f64, trunc, zig_f128, zig_f128, 2) |
| 3207 | zig_convert_builtin(zig_f80, zig_f80, extend, zig_f16, zig_f16, 2) | 3205 | zig_convert_builtin(zig_f80, zig_f80, extend, zig_f16, zig_f16, 2) |
| ... | @@ -3213,6 +3211,21 @@ zig_convert_builtin(zig_f128, zig_f128, extend, zig_f32, | ... | @@ -3213,6 +3211,21 @@ zig_convert_builtin(zig_f128, zig_f128, extend, zig_f32, |
| 3213 | zig_convert_builtin(zig_f128, zig_f128, extend, zig_f64, zig_f64, 2) | 3211 | zig_convert_builtin(zig_f128, zig_f128, extend, zig_f64, zig_f64, 2) |
| 3214 | zig_convert_builtin(zig_f128, zig_f128, extend, zig_f80, zig_f80, 2) | 3212 | zig_convert_builtin(zig_f128, zig_f128, extend, zig_f80, zig_f80, 2) |
| 3215 | 3213 | ||
| 3214 | #ifdef __ARM_EABI__ | ||
| 3215 | |||
| 3216 | zig_extern zig_callconv(pcs("aapcs")) zig_f32 __aeabi_d2f(zig_f64); | ||
| 3217 | static inline zig_f32 zig_truncdfsf(zig_f64 arg) { return __aeabi_d2f(arg); } | ||
| 3218 | |||
| 3219 | zig_extern zig_callconv(pcs("aapcs")) zig_f64 __aeabi_f2d(zig_f32); | ||
| 3220 | static inline zig_f64 zig_extendsfdf(zig_f32 arg) { return __aeabi_f2d(arg); } | ||
| 3221 | |||
| 3222 | #else /* __ARM_EABI__ */ | ||
| 3223 | |||
| 3224 | zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f64, zig_f64, 2) | ||
| 3225 | zig_convert_builtin(zig_f64, zig_f64, extend, zig_f32, zig_f32, 2) | ||
| 3226 | |||
| 3227 | #endif /* __ARM_EABI__ */ | ||
| 3228 | |||
| 3216 | #define zig_float_negate_builtin_0(w, c, sb) \ | 3229 | #define zig_float_negate_builtin_0(w, c, sb) \ |
| 3217 | zig_expand_concat(zig_xor_, zig_repr_f##w)(arg, zig_make_f##w(-0x0.0p0, c sb)) | 3230 | zig_expand_concat(zig_xor_, zig_repr_f##w)(arg, zig_make_f##w(-0x0.0p0, c sb)) |
| 3218 | #define zig_float_negate_builtin_1(w, c, sb) -arg | 3231 | #define zig_float_negate_builtin_1(w, c, sb) -arg |
| ... | @@ -3255,17 +3268,11 @@ zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0))) | ... | @@ -3255,17 +3268,11 @@ zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0))) |
| 3255 | return lhs operator rhs; \ | 3268 | return lhs operator rhs; \ |
| 3256 | } | 3269 | } |
| 3257 | 3270 | ||
| 3258 | #define zig_float_builtins(w) \ | 3271 | #define zig_common_float_builtins(w) \ |
| 3259 | zig_convert_builtin( int32_t, int32_t, fix, zig_f##w, zig_f##w, ) \ | ||
| 3260 | zig_convert_builtin(uint32_t, uint32_t, fixuns, zig_f##w, zig_f##w, ) \ | ||
| 3261 | zig_convert_builtin( int64_t, int64_t, fix, zig_f##w, zig_f##w, ) \ | 3272 | zig_convert_builtin( int64_t, int64_t, fix, zig_f##w, zig_f##w, ) \ |
| 3262 | zig_convert_builtin(uint64_t, uint64_t, fixuns, zig_f##w, zig_f##w, ) \ | ||
| 3263 | zig_convert_builtin(zig_i128, zig_i128, fix, zig_f##w, zig_f##w, ) \ | 3273 | zig_convert_builtin(zig_i128, zig_i128, fix, zig_f##w, zig_f##w, ) \ |
| 3264 | zig_convert_builtin(zig_u128, zig_u128, fixuns, zig_f##w, zig_f##w, ) \ | 3274 | zig_convert_builtin(zig_u128, zig_u128, fixuns, zig_f##w, zig_f##w, ) \ |
| 3265 | zig_convert_builtin(zig_f##w, zig_f##w, float, int32_t, int32_t, ) \ | ||
| 3266 | zig_convert_builtin(zig_f##w, zig_f##w, floatun, uint32_t, uint32_t, ) \ | ||
| 3267 | zig_convert_builtin(zig_f##w, zig_f##w, float, int64_t, int64_t, ) \ | 3275 | zig_convert_builtin(zig_f##w, zig_f##w, float, int64_t, int64_t, ) \ |
| 3268 | zig_convert_builtin(zig_f##w, zig_f##w, floatun, uint64_t, uint64_t, ) \ | ||
| 3269 | zig_convert_builtin(zig_f##w, zig_f##w, float, zig_i128, zig_i128, ) \ | 3276 | zig_convert_builtin(zig_f##w, zig_f##w, float, zig_i128, zig_i128, ) \ |
| 3270 | zig_convert_builtin(zig_f##w, zig_f##w, floatun, zig_u128, zig_u128, ) \ | 3277 | zig_convert_builtin(zig_f##w, zig_f##w, floatun, zig_u128, zig_u128, ) \ |
| 3271 | zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, cmp) \ | 3278 | zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, cmp) \ |
| ... | @@ -3309,12 +3316,68 @@ zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0))) | ... | @@ -3309,12 +3316,68 @@ zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0))) |
| 3309 | static inline zig_f##w zig_mod_f##w(zig_f##w lhs, zig_f##w rhs) { \ | 3316 | static inline zig_f##w zig_mod_f##w(zig_f##w lhs, zig_f##w rhs) { \ |
| 3310 | return zig_sub_f##w(lhs, zig_mul_f##w(zig_div_floor_f##w(lhs, rhs), rhs)); \ | 3317 | return zig_sub_f##w(lhs, zig_mul_f##w(zig_div_floor_f##w(lhs, rhs), rhs)); \ |
| 3311 | } | 3318 | } |
| 3319 | zig_common_float_builtins(16) | ||
| 3320 | zig_common_float_builtins(32) | ||
| 3321 | zig_common_float_builtins(64) | ||
| 3322 | zig_common_float_builtins(80) | ||
| 3323 | zig_common_float_builtins(128) | ||
| 3324 | |||
| 3325 | #define zig_float_builtins(w) \ | ||
| 3326 | zig_convert_builtin( int32_t, int32_t, fix, zig_f##w, zig_f##w, ) \ | ||
| 3327 | zig_convert_builtin(uint32_t, uint32_t, fixuns, zig_f##w, zig_f##w, ) \ | ||
| 3328 | zig_convert_builtin(uint64_t, uint64_t, fixuns, zig_f##w, zig_f##w, ) \ | ||
| 3329 | zig_convert_builtin(zig_f##w, zig_f##w, float, int32_t, int32_t, ) \ | ||
| 3330 | zig_convert_builtin(zig_f##w, zig_f##w, floatun, uint32_t, uint32_t, ) \ | ||
| 3331 | zig_convert_builtin(zig_f##w, zig_f##w, floatun, uint64_t, uint64_t, ) | ||
| 3312 | zig_float_builtins(16) | 3332 | zig_float_builtins(16) |
| 3313 | zig_float_builtins(32) | ||
| 3314 | zig_float_builtins(64) | ||
| 3315 | zig_float_builtins(80) | 3333 | zig_float_builtins(80) |
| 3316 | zig_float_builtins(128) | 3334 | zig_float_builtins(128) |
| 3317 | 3335 | ||
| 3336 | #ifdef __ARM_EABI__ | ||
| 3337 | |||
| 3338 | zig_extern zig_callconv(pcs("aapcs")) int32_t __aeabi_f2iz(zig_f32); | ||
| 3339 | static inline int32_t zig_fixsfsi(zig_f32 arg) { return __aeabi_f2iz(arg); } | ||
| 3340 | |||
| 3341 | zig_extern zig_callconv(pcs("aapcs")) uint32_t __aeabi_f2uiz(zig_f32); | ||
| 3342 | static inline uint32_t zig_fixunssfsi(zig_f32 arg) { return __aeabi_f2uiz(arg); } | ||
| 3343 | |||
| 3344 | zig_extern zig_callconv(pcs("aapcs")) uint64_t __aeabi_f2ulz(zig_f32); | ||
| 3345 | static inline uint64_t zig_fixunssfdi(zig_f32 arg) { return __aeabi_f2ulz(arg); } | ||
| 3346 | |||
| 3347 | zig_extern zig_callconv(pcs("aapcs")) zig_f32 __aeabi_i2f(int32_t); | ||
| 3348 | static inline zig_f32 zig_floatsisf(int32_t arg) { return __aeabi_i2f(arg); } | ||
| 3349 | |||
| 3350 | zig_extern zig_callconv(pcs("aapcs")) zig_f32 __aeabi_ui2f(uint32_t); | ||
| 3351 | static inline zig_f32 zig_floatunsisf(uint32_t arg) { return __aeabi_ui2f(arg); } | ||
| 3352 | |||
| 3353 | zig_extern zig_callconv(pcs("aapcs")) zig_f32 __aeabi_ul2f(uint64_t); | ||
| 3354 | static inline zig_f32 zig_floatundisf(uint64_t arg) { return __aeabi_ul2f(arg); } | ||
| 3355 | |||
| 3356 | zig_extern zig_callconv(pcs("aapcs")) int32_t __aeabi_d2iz(zig_f64); | ||
| 3357 | static inline int32_t zig_fixdfsi(zig_f64 arg) { return __aeabi_d2iz(arg); } | ||
| 3358 | |||
| 3359 | zig_extern zig_callconv(pcs("aapcs")) uint32_t __aeabi_d2uiz(zig_f64); | ||
| 3360 | static inline uint32_t zig_fixunsdfsi(zig_f64 arg) { return __aeabi_d2uiz(arg); } | ||
| 3361 | |||
| 3362 | zig_extern zig_callconv(pcs("aapcs")) uint64_t __aeabi_d2ulz(zig_f64); | ||
| 3363 | static inline uint64_t zig_fixunsdfdi(zig_f64 arg) { return __aeabi_d2ulz(arg); } | ||
| 3364 | |||
| 3365 | zig_extern zig_callconv(pcs("aapcs")) zig_f64 __aeabi_i2d(int32_t); | ||
| 3366 | static inline zig_f64 zig_floatsidf(int32_t arg) { return __aeabi_i2d(arg); } | ||
| 3367 | |||
| 3368 | zig_extern zig_callconv(pcs("aapcs")) zig_f64 __aeabi_ui2d(uint32_t); | ||
| 3369 | static inline zig_f64 zig_floatunsidf(uint32_t arg) { return __aeabi_ui2d(arg); } | ||
| 3370 | |||
| 3371 | zig_extern zig_callconv(pcs("aapcs")) zig_f64 __aeabi_ul2d(uint64_t); | ||
| 3372 | static inline zig_f64 zig_floatundidf(uint64_t arg) { return __aeabi_ul2d(arg); } | ||
| 3373 | |||
| 3374 | #else /* __ARM_EABI__ */ | ||
| 3375 | |||
| 3376 | zig_float_builtins(32) | ||
| 3377 | zig_float_builtins(64) | ||
| 3378 | |||
| 3379 | #endif /* __ARM_EABI__ */ | ||
| 3380 | |||
| 3318 | /* ============================ Atomics Support ============================= */ | 3381 | /* ============================ Atomics Support ============================= */ |
| 3319 | 3382 | ||
| 3320 | /* Note that atomics should be implemented as macros because most | 3383 | /* Note that atomics should be implemented as macros because most |
src/Module.zig+3| ... | @@ -4186,6 +4186,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void { | ... | @@ -4186,6 +4186,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void { |
| 4186 | .owner_decl = new_decl, | 4186 | .owner_decl = new_decl, |
| 4187 | .owner_decl_index = new_decl_index, | 4187 | .owner_decl_index = new_decl_index, |
| 4188 | .func_index = .none, | 4188 | .func_index = .none, |
| 4189 | .func_is_naked = false, | ||
| 4189 | .fn_ret_ty = Type.void, | 4190 | .fn_ret_ty = Type.void, |
| 4190 | .fn_ret_ty_ies = null, | 4191 | .fn_ret_ty_ies = null, |
| 4191 | .owner_func_index = .none, | 4192 | .owner_func_index = .none, |
| ... | @@ -4268,6 +4269,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool { | ... | @@ -4268,6 +4269,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool { |
| 4268 | .owner_decl = decl, | 4269 | .owner_decl = decl, |
| 4269 | .owner_decl_index = decl_index, | 4270 | .owner_decl_index = decl_index, |
| 4270 | .func_index = .none, | 4271 | .func_index = .none, |
| 4272 | .func_is_naked = false, | ||
| 4271 | .fn_ret_ty = Type.void, | 4273 | .fn_ret_ty = Type.void, |
| 4272 | .fn_ret_ty_ies = null, | 4274 | .fn_ret_ty_ies = null, |
| 4273 | .owner_func_index = .none, | 4275 | .owner_func_index = .none, |
| ... | @@ -5213,6 +5215,7 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato | ... | @@ -5213,6 +5215,7 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato |
| 5213 | .owner_decl = decl, | 5215 | .owner_decl = decl, |
| 5214 | .owner_decl_index = decl_index, | 5216 | .owner_decl_index = decl_index, |
| 5215 | .func_index = func_index, | 5217 | .func_index = func_index, |
| 5218 | .func_is_naked = fn_ty_info.cc == .Naked, | ||
| 5216 | .fn_ret_ty = fn_ty_info.return_type.toType(), | 5219 | .fn_ret_ty = fn_ty_info.return_type.toType(), |
| 5217 | .fn_ret_ty_ies = null, | 5220 | .fn_ret_ty_ies = null, |
| 5218 | .owner_func_index = func_index, | 5221 | .owner_func_index = func_index, |
src/Sema.zig+28-3| ... | @@ -30,6 +30,8 @@ owner_func_index: InternPool.Index, | ... | @@ -30,6 +30,8 @@ owner_func_index: InternPool.Index, |
| 30 | /// an inline or comptime function call. | 30 | /// an inline or comptime function call. |
| 31 | /// This could be `none`, a `func_decl`, or a `func_instance`. | 31 | /// This could be `none`, a `func_decl`, or a `func_instance`. |
| 32 | func_index: InternPool.Index, | 32 | func_index: InternPool.Index, |
| 33 | /// Whether the type of func_index has a calling convention of `.Naked`. | ||
| 34 | func_is_naked: bool, | ||
| 33 | /// Used to restore the error return trace when returning a non-error from a function. | 35 | /// Used to restore the error return trace when returning a non-error from a function. |
| 34 | error_return_trace_index_on_fn_entry: Air.Inst.Ref = .none, | 36 | error_return_trace_index_on_fn_entry: Air.Inst.Ref = .none, |
| 35 | /// When semantic analysis needs to know the return type of the function whose body | 37 | /// When semantic analysis needs to know the return type of the function whose body |
| ... | @@ -6827,6 +6829,10 @@ fn analyzeCall( | ... | @@ -6827,6 +6829,10 @@ fn analyzeCall( |
| 6827 | var is_inline_call = is_comptime_call or modifier == .always_inline or | 6829 | var is_inline_call = is_comptime_call or modifier == .always_inline or |
| 6828 | func_ty_info.cc == .Inline; | 6830 | func_ty_info.cc == .Inline; |
| 6829 | 6831 | ||
| 6832 | if (sema.func_is_naked and !is_inline_call and !is_comptime_call) { | ||
| 6833 | return sema.fail(block, call_src, "runtime call not allowed in naked function", .{}); | ||
| 6834 | } | ||
| 6835 | |||
| 6830 | if (!is_inline_call and is_generic_call) { | 6836 | if (!is_inline_call and is_generic_call) { |
| 6831 | if (sema.instantiateGenericCall( | 6837 | if (sema.instantiateGenericCall( |
| 6832 | block, | 6838 | block, |
| ... | @@ -7509,6 +7515,9 @@ fn instantiateGenericCall( | ... | @@ -7509,6 +7515,9 @@ fn instantiateGenericCall( |
| 7509 | .owner_decl = sema.owner_decl, | 7515 | .owner_decl = sema.owner_decl, |
| 7510 | .owner_decl_index = sema.owner_decl_index, | 7516 | .owner_decl_index = sema.owner_decl_index, |
| 7511 | .func_index = sema.owner_func_index, | 7517 | .func_index = sema.owner_func_index, |
| 7518 | // This may not be known yet, since the calling convention could be generic, but there | ||
| 7519 | // should be no illegal instructions encountered while creating the function anyway. | ||
| 7520 | .func_is_naked = false, | ||
| 7512 | .fn_ret_ty = Type.void, | 7521 | .fn_ret_ty = Type.void, |
| 7513 | .fn_ret_ty_ies = null, | 7522 | .fn_ret_ty_ies = null, |
| 7514 | .owner_func_index = .none, | 7523 | .owner_func_index = .none, |
| ... | @@ -18193,10 +18202,20 @@ fn zirRetImplicit( | ... | @@ -18193,10 +18202,20 @@ fn zirRetImplicit( |
| 18193 | const tracy = trace(@src()); | 18202 | const tracy = trace(@src()); |
| 18194 | defer tracy.end(); | 18203 | defer tracy.end(); |
| 18195 | 18204 | ||
| 18205 | if (block.inlining == null and sema.func_is_naked) { | ||
| 18206 | assert(!block.is_comptime); | ||
| 18207 | if (block.wantSafety()) { | ||
| 18208 | // Calling a safety function from a naked function would not be legal. | ||
| 18209 | _ = try block.addNoOp(.trap); | ||
| 18210 | } else { | ||
| 18211 | try block.addUnreachable(false); | ||
| 18212 | } | ||
| 18213 | return always_noreturn; | ||
| 18214 | } | ||
| 18215 | |||
| 18196 | const mod = sema.mod; | 18216 | const mod = sema.mod; |
| 18197 | const inst_data = sema.code.instructions.items(.data)[inst].un_tok; | 18217 | const inst_data = sema.code.instructions.items(.data)[inst].un_tok; |
| 18198 | const operand = try sema.resolveInst(inst_data.operand); | 18218 | const operand = try sema.resolveInst(inst_data.operand); |
| 18199 | |||
| 18200 | const r_brace_src = inst_data.src(); | 18219 | const r_brace_src = inst_data.src(); |
| 18201 | const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 }; | 18220 | const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 }; |
| 18202 | const base_tag = sema.fn_ret_ty.baseZigTypeTag(mod); | 18221 | const base_tag = sema.fn_ret_ty.baseZigTypeTag(mod); |
| ... | @@ -18222,7 +18241,7 @@ fn zirRetImplicit( | ... | @@ -18222,7 +18241,7 @@ fn zirRetImplicit( |
| 18222 | return sema.failWithOwnedErrorMsg(msg); | 18241 | return sema.failWithOwnedErrorMsg(msg); |
| 18223 | } | 18242 | } |
| 18224 | 18243 | ||
| 18225 | return sema.analyzeRet(block, operand, .unneeded); | 18244 | return sema.analyzeRet(block, operand, r_brace_src); |
| 18226 | } | 18245 | } |
| 18227 | 18246 | ||
| 18228 | fn zirRetNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index { | 18247 | fn zirRetNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index { |
| ... | @@ -18244,7 +18263,7 @@ fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir | ... | @@ -18244,7 +18263,7 @@ fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir |
| 18244 | const src = inst_data.src(); | 18263 | const src = inst_data.src(); |
| 18245 | const ret_ptr = try sema.resolveInst(inst_data.operand); | 18264 | const ret_ptr = try sema.resolveInst(inst_data.operand); |
| 18246 | 18265 | ||
| 18247 | if (block.is_comptime or block.inlining != null) { | 18266 | if (block.is_comptime or block.inlining != null or sema.func_is_naked) { |
| 18248 | const operand = try sema.analyzeLoad(block, src, ret_ptr, src); | 18267 | const operand = try sema.analyzeLoad(block, src, ret_ptr, src); |
| 18249 | return sema.analyzeRet(block, operand, src); | 18268 | return sema.analyzeRet(block, operand, src); |
| 18250 | } | 18269 | } |
| ... | @@ -18450,6 +18469,8 @@ fn analyzeRet( | ... | @@ -18450,6 +18469,8 @@ fn analyzeRet( |
| 18450 | return always_noreturn; | 18469 | return always_noreturn; |
| 18451 | } else if (block.is_comptime) { | 18470 | } else if (block.is_comptime) { |
| 18452 | return sema.fail(block, src, "function called at runtime cannot return value at comptime", .{}); | 18471 | return sema.fail(block, src, "function called at runtime cannot return value at comptime", .{}); |
| 18472 | } else if (sema.func_is_naked) { | ||
| 18473 | return sema.fail(block, src, "cannot return from naked function", .{}); | ||
| 18453 | } | 18474 | } |
| 18454 | 18475 | ||
| 18455 | try sema.resolveTypeLayout(sema.fn_ret_ty); | 18476 | try sema.resolveTypeLayout(sema.fn_ret_ty); |
| ... | @@ -33571,6 +33592,7 @@ fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!voi | ... | @@ -33571,6 +33592,7 @@ fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!voi |
| 33571 | .owner_decl = decl, | 33592 | .owner_decl = decl, |
| 33572 | .owner_decl_index = decl_index, | 33593 | .owner_decl_index = decl_index, |
| 33573 | .func_index = .none, | 33594 | .func_index = .none, |
| 33595 | .func_is_naked = false, | ||
| 33574 | .fn_ret_ty = Type.void, | 33596 | .fn_ret_ty = Type.void, |
| 33575 | .fn_ret_ty_ies = null, | 33597 | .fn_ret_ty_ies = null, |
| 33576 | .owner_func_index = .none, | 33598 | .owner_func_index = .none, |
| ... | @@ -33622,6 +33644,7 @@ fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!voi | ... | @@ -33622,6 +33644,7 @@ fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!voi |
| 33622 | .owner_decl = decl, | 33644 | .owner_decl = decl, |
| 33623 | .owner_decl_index = decl_index, | 33645 | .owner_decl_index = decl_index, |
| 33624 | .func_index = .none, | 33646 | .func_index = .none, |
| 33647 | .func_is_naked = false, | ||
| 33625 | .fn_ret_ty = Type.void, | 33648 | .fn_ret_ty = Type.void, |
| 33626 | .fn_ret_ty_ies = null, | 33649 | .fn_ret_ty_ies = null, |
| 33627 | .owner_func_index = .none, | 33650 | .owner_func_index = .none, |
| ... | @@ -34405,6 +34428,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void | ... | @@ -34405,6 +34428,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void |
| 34405 | .owner_decl = decl, | 34428 | .owner_decl = decl, |
| 34406 | .owner_decl_index = decl_index, | 34429 | .owner_decl_index = decl_index, |
| 34407 | .func_index = .none, | 34430 | .func_index = .none, |
| 34431 | .func_is_naked = false, | ||
| 34408 | .fn_ret_ty = Type.void, | 34432 | .fn_ret_ty = Type.void, |
| 34409 | .fn_ret_ty_ies = null, | 34433 | .fn_ret_ty_ies = null, |
| 34410 | .owner_func_index = .none, | 34434 | .owner_func_index = .none, |
| ... | @@ -34748,6 +34772,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { | ... | @@ -34748,6 +34772,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 34748 | .owner_decl = decl, | 34772 | .owner_decl = decl, |
| 34749 | .owner_decl_index = decl_index, | 34773 | .owner_decl_index = decl_index, |
| 34750 | .func_index = .none, | 34774 | .func_index = .none, |
| 34775 | .func_is_naked = false, | ||
| 34751 | .fn_ret_ty = Type.void, | 34776 | .fn_ret_ty = Type.void, |
| 34752 | .fn_ret_ty_ies = null, | 34777 | .fn_ret_ty_ies = null, |
| 34753 | .owner_func_index = .none, | 34778 | .owner_func_index = .none, |
src/TypedValue.zig+1| ... | @@ -196,6 +196,7 @@ pub fn print( | ... | @@ -196,6 +196,7 @@ pub fn print( |
| 196 | .undef => return writer.writeAll("undefined"), | 196 | .undef => return writer.writeAll("undefined"), |
| 197 | .runtime_value => return writer.writeAll("(runtime value)"), | 197 | .runtime_value => return writer.writeAll("(runtime value)"), |
| 198 | .simple_value => |simple_value| switch (simple_value) { | 198 | .simple_value => |simple_value| switch (simple_value) { |
| 199 | .void => return writer.writeAll("{}"), | ||
| 199 | .empty_struct => return printAggregate(ty, val, writer, level, mod), | 200 | .empty_struct => return printAggregate(ty, val, writer, level, mod), |
| 200 | .generic_poison => return writer.writeAll("(generic poison)"), | 201 | .generic_poison => return writer.writeAll("(generic poison)"), |
| 201 | else => return writer.writeAll(@tagName(simple_value)), | 202 | else => return writer.writeAll(@tagName(simple_value)), |
src/arch/x86_64/CodeGen.zig+155-54| ... | @@ -177,7 +177,7 @@ pub const MCValue = union(enum) { | ... | @@ -177,7 +177,7 @@ pub const MCValue = union(enum) { |
| 177 | /// The value is a tuple { wrapped, overflow } where wrapped value is stored in the GP register. | 177 | /// The value is a tuple { wrapped, overflow } where wrapped value is stored in the GP register. |
| 178 | register_overflow: struct { reg: Register, eflags: Condition }, | 178 | register_overflow: struct { reg: Register, eflags: Condition }, |
| 179 | /// The value is in memory at a hard-coded address. | 179 | /// The value is in memory at a hard-coded address. |
| 180 | /// If the type is a pointer, it means the pointer address is at this memory location. | 180 | /// If the type is a pointer, it means the pointer address is stored at this memory location. |
| 181 | memory: u64, | 181 | memory: u64, |
| 182 | /// The value is in memory at a constant offset from the address in a register. | 182 | /// The value is in memory at a constant offset from the address in a register. |
| 183 | indirect: RegisterOffset, | 183 | indirect: RegisterOffset, |
| ... | @@ -300,7 +300,7 @@ pub const MCValue = union(enum) { | ... | @@ -300,7 +300,7 @@ pub const MCValue = union(enum) { |
| 300 | .load_tlv, | 300 | .load_tlv, |
| 301 | .load_frame, | 301 | .load_frame, |
| 302 | .reserved_frame, | 302 | .reserved_frame, |
| 303 | => unreachable, // not a dereferenceable | 303 | => unreachable, // not dereferenceable |
| 304 | .immediate => |addr| .{ .memory = addr }, | 304 | .immediate => |addr| .{ .memory = addr }, |
| 305 | .register => |reg| .{ .indirect = .{ .reg = reg } }, | 305 | .register => |reg| .{ .indirect = .{ .reg = reg } }, |
| 306 | .register_offset => |reg_off| .{ .indirect = reg_off }, | 306 | .register_offset => |reg_off| .{ .indirect = reg_off }, |
| ... | @@ -3468,14 +3468,14 @@ fn genInlineIntDivFloor(self: *Self, ty: Type, lhs: MCValue, rhs: MCValue) !MCVa | ... | @@ -3468,14 +3468,14 @@ fn genInlineIntDivFloor(self: *Self, ty: Type, lhs: MCValue, rhs: MCValue) !MCVa |
| 3468 | const mod = self.bin_file.options.module.?; | 3468 | const mod = self.bin_file.options.module.?; |
| 3469 | const abi_size: u32 = @intCast(ty.abiSize(mod)); | 3469 | const abi_size: u32 = @intCast(ty.abiSize(mod)); |
| 3470 | const int_info = ty.intInfo(mod); | 3470 | const int_info = ty.intInfo(mod); |
| 3471 | const dividend: Register = switch (lhs) { | 3471 | const dividend = switch (lhs) { |
| 3472 | .register => |reg| reg, | 3472 | .register => |reg| reg, |
| 3473 | else => try self.copyToTmpRegister(ty, lhs), | 3473 | else => try self.copyToTmpRegister(ty, lhs), |
| 3474 | }; | 3474 | }; |
| 3475 | const dividend_lock = self.register_manager.lockReg(dividend); | 3475 | const dividend_lock = self.register_manager.lockReg(dividend); |
| 3476 | defer if (dividend_lock) |lock| self.register_manager.unlockReg(lock); | 3476 | defer if (dividend_lock) |lock| self.register_manager.unlockReg(lock); |
| 3477 | 3477 | ||
| 3478 | const divisor: Register = switch (rhs) { | 3478 | const divisor = switch (rhs) { |
| 3479 | .register => |reg| reg, | 3479 | .register => |reg| reg, |
| 3480 | else => try self.copyToTmpRegister(ty, rhs), | 3480 | else => try self.copyToTmpRegister(ty, rhs), |
| 3481 | }; | 3481 | }; |
| ... | @@ -9184,6 +9184,7 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -9184,6 +9184,7 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void { |
| 9184 | } | 9184 | } |
| 9185 | 9185 | ||
| 9186 | fn airAsm(self: *Self, inst: Air.Inst.Index) !void { | 9186 | fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 9187 | const mod = self.bin_file.options.module.?; | ||
| 9187 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 9188 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 9188 | const extra = self.air.extraData(Air.Asm, ty_pl.payload); | 9189 | const extra = self.air.extraData(Air.Asm, ty_pl.payload); |
| 9189 | const clobbers_len: u31 = @truncate(extra.data.flags); | 9190 | const clobbers_len: u31 = @truncate(extra.data.flags); |
| ... | @@ -9196,23 +9197,15 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -9196,23 +9197,15 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 9196 | 9197 | ||
| 9197 | var result: MCValue = .none; | 9198 | var result: MCValue = .none; |
| 9198 | var args = std.StringArrayHashMap(MCValue).init(self.gpa); | 9199 | var args = std.StringArrayHashMap(MCValue).init(self.gpa); |
| 9199 | try args.ensureTotalCapacity(outputs.len + inputs.len + clobbers_len); | 9200 | try args.ensureTotalCapacity(outputs.len + inputs.len); |
| 9200 | defer { | 9201 | defer { |
| 9201 | for (args.values()) |arg| switch (arg) { | 9202 | for (args.values()) |arg| if (arg.getReg()) |reg| |
| 9202 | .register => |reg| self.register_manager.unlockReg(.{ .register = reg }), | 9203 | self.register_manager.unlockReg(.{ .register = reg }); |
| 9203 | else => {}, | ||
| 9204 | }; | ||
| 9205 | args.deinit(); | 9204 | args.deinit(); |
| 9206 | } | 9205 | } |
| 9207 | 9206 | ||
| 9208 | if (outputs.len > 1) { | 9207 | var outputs_extra_i = extra_i; |
| 9209 | return self.fail("TODO implement codegen for asm with more than 1 output", .{}); | ||
| 9210 | } | ||
| 9211 | |||
| 9212 | for (outputs) |output| { | 9208 | for (outputs) |output| { |
| 9213 | if (output != .none) { | ||
| 9214 | return self.fail("TODO implement codegen for non-expr asm", .{}); | ||
| 9215 | } | ||
| 9216 | const extra_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]); | 9209 | const extra_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]); |
| 9217 | const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0); | 9210 | const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0); |
| 9218 | const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0); | 9211 | const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0); |
| ... | @@ -9220,21 +9213,48 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -9220,21 +9213,48 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 9220 | // for the string, we still use the next u32 for the null terminator. | 9213 | // for the string, we still use the next u32 for the null terminator. |
| 9221 | extra_i += (constraint.len + name.len + (2 + 3)) / 4; | 9214 | extra_i += (constraint.len + name.len + (2 + 3)) / 4; |
| 9222 | 9215 | ||
| 9223 | const mcv: MCValue = if (mem.eql(u8, constraint, "=r")) | 9216 | const maybe_inst = switch (output) { |
| 9224 | .{ .register = self.register_manager.tryAllocReg(inst, gp) orelse | 9217 | .none => inst, |
| 9225 | return self.fail("ran out of registers lowering inline asm", .{}) } | 9218 | else => null, |
| 9219 | }; | ||
| 9220 | const ty = switch (output) { | ||
| 9221 | .none => self.typeOfIndex(inst), | ||
| 9222 | else => self.typeOf(output).childType(mod), | ||
| 9223 | }; | ||
| 9224 | const arg_maybe_reg: ?Register = if (mem.eql(u8, constraint, "=r")) | ||
| 9225 | self.register_manager.tryAllocReg(maybe_inst, regClassForType(ty, mod)) orelse | ||
| 9226 | return self.fail("ran out of registers lowering inline asm", .{}) | ||
| 9227 | else if (mem.eql(u8, constraint, "=m")) | ||
| 9228 | if (output != .none) null else return self.fail( | ||
| 9229 | "memory constraint unsupported for asm result", | ||
| 9230 | .{}, | ||
| 9231 | ) | ||
| 9232 | else if (mem.eql(u8, constraint, "=g")) | ||
| 9233 | self.register_manager.tryAllocReg(maybe_inst, regClassForType(ty, mod)) orelse | ||
| 9234 | if (output != .none) null else return self.fail( | ||
| 9235 | "ran out of register lowering inline asm", | ||
| 9236 | .{}, | ||
| 9237 | ) | ||
| 9226 | else if (mem.startsWith(u8, constraint, "={") and mem.endsWith(u8, constraint, "}")) | 9238 | else if (mem.startsWith(u8, constraint, "={") and mem.endsWith(u8, constraint, "}")) |
| 9227 | .{ .register = parseRegName(constraint["={".len .. constraint.len - "}".len]) orelse | 9239 | parseRegName(constraint["={".len .. constraint.len - "}".len]) orelse |
| 9228 | return self.fail("unrecognized register constraint: '{s}'", .{constraint}) } | 9240 | return self.fail("invalid register constraint: '{s}'", .{constraint}) |
| 9229 | else | 9241 | else |
| 9230 | return self.fail("unrecognized constraint: '{s}'", .{constraint}); | 9242 | return self.fail("invalid constraint: '{s}'", .{constraint}); |
| 9231 | args.putAssumeCapacity(name, mcv); | 9243 | const arg_mcv: MCValue = if (arg_maybe_reg) |reg| .{ .register = reg } else arg: { |
| 9232 | switch (mcv) { | 9244 | const ptr_mcv = try self.resolveInst(output); |
| 9233 | .register => |reg| _ = if (RegisterManager.indexOfRegIntoTracked(reg)) |_| | 9245 | switch (ptr_mcv) { |
| 9234 | self.register_manager.lockRegAssumeUnused(reg), | 9246 | .immediate => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |_| |
| 9235 | else => {}, | 9247 | break :arg ptr_mcv.deref(), |
| 9236 | } | 9248 | .register, .register_offset, .lea_frame => break :arg ptr_mcv.deref(), |
| 9237 | if (output == .none) result = mcv; | 9249 | else => {}, |
| 9250 | } | ||
| 9251 | break :arg .{ .indirect = .{ .reg = try self.copyToTmpRegister(Type.usize, ptr_mcv) } }; | ||
| 9252 | }; | ||
| 9253 | if (arg_mcv.getReg()) |reg| if (RegisterManager.indexOfRegIntoTracked(reg)) |_| { | ||
| 9254 | _ = self.register_manager.lockRegAssumeUnused(reg); | ||
| 9255 | }; | ||
| 9256 | args.putAssumeCapacity(name, arg_mcv); | ||
| 9257 | if (output == .none) result = arg_mcv; | ||
| 9238 | } | 9258 | } |
| 9239 | 9259 | ||
| 9240 | for (inputs) |input| { | 9260 | for (inputs) |input| { |
| ... | @@ -9245,16 +9265,53 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -9245,16 +9265,53 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 9245 | // for the string, we still use the next u32 for the null terminator. | 9265 | // for the string, we still use the next u32 for the null terminator. |
| 9246 | extra_i += (constraint.len + name.len + (2 + 3)) / 4; | 9266 | extra_i += (constraint.len + name.len + (2 + 3)) / 4; |
| 9247 | 9267 | ||
| 9248 | if (constraint.len < 3 or constraint[0] != '{' or constraint[constraint.len - 1] != '}') { | 9268 | const ty = self.typeOf(input); |
| 9249 | return self.fail("unrecognized asm input constraint: '{s}'", .{constraint}); | 9269 | const input_mcv = try self.resolveInst(input); |
| 9250 | } | 9270 | const arg_mcv: MCValue = if (mem.eql(u8, constraint, "r")) switch (input_mcv) { |
| 9251 | const reg_name = constraint[1 .. constraint.len - 1]; | 9271 | .register => input_mcv, |
| 9252 | const reg = parseRegName(reg_name) orelse | 9272 | else => .{ .register = try self.copyToTmpRegister(ty, input_mcv) }, |
| 9253 | return self.fail("unrecognized register: '{s}'", .{reg_name}); | 9273 | } else if (mem.eql(u8, constraint, "m")) arg: { |
| 9254 | 9274 | switch (input_mcv) { | |
| 9255 | const arg_mcv = try self.resolveInst(input); | 9275 | .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |_| |
| 9256 | try self.register_manager.getReg(reg, null); | 9276 | break :arg input_mcv, |
| 9257 | try self.genSetReg(reg, self.typeOf(input), arg_mcv); | 9277 | .indirect, .load_frame => break :arg input_mcv, |
| 9278 | .load_direct, .load_got, .load_tlv => {}, | ||
| 9279 | else => { | ||
| 9280 | const temp_mcv = try self.allocTempRegOrMem(ty, false); | ||
| 9281 | try self.genCopy(ty, temp_mcv, input_mcv); | ||
| 9282 | break :arg temp_mcv; | ||
| 9283 | }, | ||
| 9284 | } | ||
| 9285 | const addr_reg = self.register_manager.tryAllocReg(null, gp) orelse { | ||
| 9286 | const temp_mcv = try self.allocTempRegOrMem(ty, false); | ||
| 9287 | try self.genCopy(ty, temp_mcv, input_mcv); | ||
| 9288 | break :arg temp_mcv; | ||
| 9289 | }; | ||
| 9290 | try self.genSetReg(addr_reg, Type.usize, input_mcv.address()); | ||
| 9291 | break :arg .{ .indirect = .{ .reg = addr_reg } }; | ||
| 9292 | } else if (mem.eql(u8, constraint, "g")) arg: { | ||
| 9293 | switch (input_mcv) { | ||
| 9294 | .register, .indirect, .load_frame => break :arg input_mcv, | ||
| 9295 | .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |_| | ||
| 9296 | break :arg input_mcv, | ||
| 9297 | else => {}, | ||
| 9298 | } | ||
| 9299 | const temp_mcv = try self.allocTempRegOrMem(ty, true); | ||
| 9300 | try self.genCopy(ty, temp_mcv, input_mcv); | ||
| 9301 | break :arg temp_mcv; | ||
| 9302 | } else if (mem.eql(u8, constraint, "X")) | ||
| 9303 | input_mcv | ||
| 9304 | else if (mem.startsWith(u8, constraint, "{") and mem.endsWith(u8, constraint, "}")) arg: { | ||
| 9305 | const reg = parseRegName(constraint["{".len .. constraint.len - "}".len]) orelse | ||
| 9306 | return self.fail("invalid register constraint: '{s}'", .{constraint}); | ||
| 9307 | try self.register_manager.getReg(reg, null); | ||
| 9308 | try self.genSetReg(reg, ty, input_mcv); | ||
| 9309 | break :arg .{ .register = reg }; | ||
| 9310 | } else return self.fail("invalid constraint: '{s}'", .{constraint}); | ||
| 9311 | if (arg_mcv.getReg()) |reg| if (RegisterManager.indexOfRegIntoTracked(reg)) |_| { | ||
| 9312 | _ = self.register_manager.lockReg(reg); | ||
| 9313 | }; | ||
| 9314 | args.putAssumeCapacity(name, arg_mcv); | ||
| 9258 | } | 9315 | } |
| 9259 | 9316 | ||
| 9260 | { | 9317 | { |
| ... | @@ -9293,7 +9350,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -9293,7 +9350,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 9293 | } | 9350 | } |
| 9294 | } | 9351 | } |
| 9295 | break :mnem std.meta.stringToEnum(Mir.Inst.Tag, mnem_str) orelse | 9352 | break :mnem std.meta.stringToEnum(Mir.Inst.Tag, mnem_str) orelse |
| 9296 | return self.fail("Invalid mnemonic: '{s}'", .{mnem_str}); | 9353 | return self.fail("invalid mnemonic: '{s}'", .{mnem_str}); |
| 9297 | } }; | 9354 | } }; |
| 9298 | 9355 | ||
| 9299 | var op_it = mem.tokenizeScalar(u8, mnem_it.rest(), ','); | 9356 | var op_it = mem.tokenizeScalar(u8, mnem_it.rest(), ','); |
| ... | @@ -9304,43 +9361,73 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -9304,43 +9361,73 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 9304 | if (mem.startsWith(u8, op_str, "%%")) { | 9361 | if (mem.startsWith(u8, op_str, "%%")) { |
| 9305 | const colon = mem.indexOfScalarPos(u8, op_str, "%%".len + 2, ':'); | 9362 | const colon = mem.indexOfScalarPos(u8, op_str, "%%".len + 2, ':'); |
| 9306 | const reg = parseRegName(op_str["%%".len .. colon orelse op_str.len]) orelse | 9363 | const reg = parseRegName(op_str["%%".len .. colon orelse op_str.len]) orelse |
| 9307 | return self.fail("Invalid register: '{s}'", .{op_str}); | 9364 | return self.fail("invalid register: '{s}'", .{op_str}); |
| 9308 | if (colon) |colon_pos| { | 9365 | if (colon) |colon_pos| { |
| 9309 | const disp = std.fmt.parseInt(i32, op_str[colon_pos + 1 ..], 0) catch | 9366 | const disp = std.fmt.parseInt(i32, op_str[colon_pos + 1 ..], 0) catch |
| 9310 | return self.fail("Invalid displacement: '{s}'", .{op_str}); | 9367 | return self.fail("invalid displacement: '{s}'", .{op_str}); |
| 9311 | op.* = .{ .mem = Memory.sib( | 9368 | op.* = .{ .mem = Memory.sib( |
| 9312 | mnem_size orelse return self.fail("Unknown size: '{s}'", .{op_str}), | 9369 | mnem_size orelse return self.fail("unknown size: '{s}'", .{op_str}), |
| 9313 | .{ .base = .{ .reg = reg }, .disp = disp }, | 9370 | .{ .base = .{ .reg = reg }, .disp = disp }, |
| 9314 | ) }; | 9371 | ) }; |
| 9315 | } else { | 9372 | } else { |
| 9316 | if (mnem_size) |size| if (reg.bitSize() != size.bitSize()) | 9373 | if (mnem_size) |size| if (reg.bitSize() != size.bitSize()) |
| 9317 | return self.fail("Invalid register size: '{s}'", .{op_str}); | 9374 | return self.fail("invalid register size: '{s}'", .{op_str}); |
| 9318 | op.* = .{ .reg = reg }; | 9375 | op.* = .{ .reg = reg }; |
| 9319 | } | 9376 | } |
| 9320 | } else if (mem.startsWith(u8, op_str, "%[") and mem.endsWith(u8, op_str, "]")) { | 9377 | } else if (mem.startsWith(u8, op_str, "%[") and mem.endsWith(u8, op_str, "]")) { |
| 9321 | switch (args.get(op_str["%[".len .. op_str.len - "]".len]) orelse | 9378 | const colon = mem.indexOfScalarPos(u8, op_str, "%[".len, ':'); |
| 9322 | return self.fail("No matching constraint: '{s}'", .{op_str})) { | 9379 | const modifier = if (colon) |colon_pos| |
| 9323 | .register => |reg| op.* = .{ .reg = reg }, | 9380 | op_str[colon_pos + 1 .. op_str.len - "]".len] |
| 9324 | else => return self.fail("Invalid constraint: '{s}'", .{op_str}), | 9381 | else |
| 9325 | } | 9382 | ""; |
| 9383 | op.* = switch (args.get(op_str["%[".len .. colon orelse op_str.len - "]".len]) orelse | ||
| 9384 | return self.fail("no matching constraint: '{s}'", .{op_str})) { | ||
| 9385 | .register => |reg| if (std.mem.eql(u8, modifier, "")) | ||
| 9386 | .{ .reg = reg } | ||
| 9387 | else | ||
| 9388 | return self.fail("invalid modifier: '{s}'", .{modifier}), | ||
| 9389 | .memory => |addr| if (std.mem.eql(u8, modifier, "") or | ||
| 9390 | std.mem.eql(u8, modifier, "P")) | ||
| 9391 | .{ .mem = Memory.sib( | ||
| 9392 | mnem_size orelse return self.fail("unknown size: '{s}'", .{op_str}), | ||
| 9393 | .{ .base = .{ .reg = .ds }, .disp = @intCast(@as(i64, @bitCast(addr))) }, | ||
| 9394 | ) } | ||
| 9395 | else | ||
| 9396 | return self.fail("invalid modifier: '{s}'", .{modifier}), | ||
| 9397 | .indirect => |reg_off| if (std.mem.eql(u8, modifier, "")) | ||
| 9398 | .{ .mem = Memory.sib( | ||
| 9399 | mnem_size orelse return self.fail("unknown size: '{s}'", .{op_str}), | ||
| 9400 | .{ .base = .{ .reg = reg_off.reg }, .disp = reg_off.off }, | ||
| 9401 | ) } | ||
| 9402 | else | ||
| 9403 | return self.fail("invalid modifier: '{s}'", .{modifier}), | ||
| 9404 | .load_frame => |frame_addr| if (std.mem.eql(u8, modifier, "")) | ||
| 9405 | .{ .mem = Memory.sib( | ||
| 9406 | mnem_size orelse return self.fail("unknown size: '{s}'", .{op_str}), | ||
| 9407 | .{ .base = .{ .frame = frame_addr.index }, .disp = frame_addr.off }, | ||
| 9408 | ) } | ||
| 9409 | else | ||
| 9410 | return self.fail("invalid modifier: '{s}'", .{modifier}), | ||
| 9411 | else => return self.fail("invalid constraint: '{s}'", .{op_str}), | ||
| 9412 | }; | ||
| 9326 | } else if (mem.startsWith(u8, op_str, "$")) { | 9413 | } else if (mem.startsWith(u8, op_str, "$")) { |
| 9327 | if (std.fmt.parseInt(i32, op_str["$".len..], 0)) |s| { | 9414 | if (std.fmt.parseInt(i32, op_str["$".len..], 0)) |s| { |
| 9328 | if (mnem_size) |size| { | 9415 | if (mnem_size) |size| { |
| 9329 | const max = @as(u64, math.maxInt(u64)) >> @intCast(64 - (size.bitSize() - 1)); | 9416 | const max = @as(u64, math.maxInt(u64)) >> @intCast(64 - (size.bitSize() - 1)); |
| 9330 | if ((if (s < 0) ~s else s) > max) | 9417 | if ((if (s < 0) ~s else s) > max) |
| 9331 | return self.fail("Invalid immediate size: '{s}'", .{op_str}); | 9418 | return self.fail("invalid immediate size: '{s}'", .{op_str}); |
| 9332 | } | 9419 | } |
| 9333 | op.* = .{ .imm = Immediate.s(s) }; | 9420 | op.* = .{ .imm = Immediate.s(s) }; |
| 9334 | } else |_| if (std.fmt.parseInt(u64, op_str["$".len..], 0)) |u| { | 9421 | } else |_| if (std.fmt.parseInt(u64, op_str["$".len..], 0)) |u| { |
| 9335 | if (mnem_size) |size| { | 9422 | if (mnem_size) |size| { |
| 9336 | const max = @as(u64, math.maxInt(u64)) >> @intCast(64 - size.bitSize()); | 9423 | const max = @as(u64, math.maxInt(u64)) >> @intCast(64 - size.bitSize()); |
| 9337 | if (u > max) | 9424 | if (u > max) |
| 9338 | return self.fail("Invalid immediate size: '{s}'", .{op_str}); | 9425 | return self.fail("invalid immediate size: '{s}'", .{op_str}); |
| 9339 | } | 9426 | } |
| 9340 | op.* = .{ .imm = Immediate.u(u) }; | 9427 | op.* = .{ .imm = Immediate.u(u) }; |
| 9341 | } else |_| return self.fail("Invalid immediate: '{s}'", .{op_str}); | 9428 | } else |_| return self.fail("invalid immediate: '{s}'", .{op_str}); |
| 9342 | } else return self.fail("Invalid operand: '{s}'", .{op_str}); | 9429 | } else return self.fail("invalid operand: '{s}'", .{op_str}); |
| 9343 | } else if (op_it.next()) |op_str| return self.fail("Extra operand: '{s}'", .{op_str}); | 9430 | } else if (op_it.next()) |op_str| return self.fail("extra operand: '{s}'", .{op_str}); |
| 9344 | 9431 | ||
| 9345 | (switch (ops[0]) { | 9432 | (switch (ops[0]) { |
| 9346 | .none => self.asmOpOnly(mnem_tag), | 9433 | .none => self.asmOpOnly(mnem_tag), |
| ... | @@ -9407,6 +9494,20 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -9407,6 +9494,20 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 9407 | }; | 9494 | }; |
| 9408 | } | 9495 | } |
| 9409 | 9496 | ||
| 9497 | for (outputs, args.values()[0..outputs.len]) |output, mcv| { | ||
| 9498 | const extra_bytes = std.mem.sliceAsBytes(self.air.extra[outputs_extra_i..]); | ||
| 9499 | const constraint = | ||
| 9500 | std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[outputs_extra_i..]), 0); | ||
| 9501 | const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0); | ||
| 9502 | // This equation accounts for the fact that even if we have exactly 4 bytes | ||
| 9503 | // for the string, we still use the next u32 for the null terminator. | ||
| 9504 | outputs_extra_i += (constraint.len + name.len + (2 + 3)) / 4; | ||
| 9505 | |||
| 9506 | if (output == .none) continue; | ||
| 9507 | if (mcv != .register) continue; | ||
| 9508 | try self.store(self.typeOf(output), try self.resolveInst(output), mcv); | ||
| 9509 | } | ||
| 9510 | |||
| 9410 | simple: { | 9511 | simple: { |
| 9411 | var buf = [1]Air.Inst.Ref{.none} ** (Liveness.bpi - 1); | 9512 | var buf = [1]Air.Inst.Ref{.none} ** (Liveness.bpi - 1); |
| 9412 | var buf_index: usize = 0; | 9513 | var buf_index: usize = 0; |
src/codegen/c.zig+52-35| ... | @@ -30,7 +30,7 @@ pub const CValue = union(enum) { | ... | @@ -30,7 +30,7 @@ pub const CValue = union(enum) { |
| 30 | /// Address of a local. | 30 | /// Address of a local. |
| 31 | local_ref: LocalIndex, | 31 | local_ref: LocalIndex, |
| 32 | /// A constant instruction, to be rendered inline. | 32 | /// A constant instruction, to be rendered inline. |
| 33 | constant: Air.Inst.Ref, | 33 | constant: InternPool.Index, |
| 34 | /// Index into the parameters | 34 | /// Index into the parameters |
| 35 | arg: usize, | 35 | arg: usize, |
| 36 | /// The array field of a parameter | 36 | /// The array field of a parameter |
| ... | @@ -302,7 +302,7 @@ pub const Function = struct { | ... | @@ -302,7 +302,7 @@ pub const Function = struct { |
| 302 | try f.object.dg.renderValue(writer, ty, val, .StaticInitializer); | 302 | try f.object.dg.renderValue(writer, ty, val, .StaticInitializer); |
| 303 | try writer.writeAll(";\n "); | 303 | try writer.writeAll(";\n "); |
| 304 | break :result decl_c_value; | 304 | break :result decl_c_value; |
| 305 | } else .{ .constant = ref }; | 305 | } else .{ .constant = val.toIntern() }; |
| 306 | 306 | ||
| 307 | gop.value_ptr.* = result; | 307 | gop.value_ptr.* = result; |
| 308 | return result; | 308 | return result; |
| ... | @@ -352,57 +352,63 @@ pub const Function = struct { | ... | @@ -352,57 +352,63 @@ pub const Function = struct { |
| 352 | 352 | ||
| 353 | fn writeCValue(f: *Function, w: anytype, c_value: CValue, location: ValueRenderLocation) !void { | 353 | fn writeCValue(f: *Function, w: anytype, c_value: CValue, location: ValueRenderLocation) !void { |
| 354 | switch (c_value) { | 354 | switch (c_value) { |
| 355 | .constant => |inst| { | 355 | .constant => |val| try f.object.dg.renderValue( |
| 356 | const mod = f.object.dg.module; | 356 | w, |
| 357 | const ty = f.typeOf(inst); | 357 | f.object.dg.module.intern_pool.typeOf(val).toType(), |
| 358 | const val = (try f.air.value(inst, mod)).?; | 358 | val.toValue(), |
| 359 | return f.object.dg.renderValue(w, ty, val, location); | 359 | location, |
| 360 | }, | 360 | ), |
| 361 | .undef => |ty| return f.object.dg.renderValue(w, ty, Value.undef, location), | 361 | .undef => |ty| try f.object.dg.renderValue(w, ty, Value.undef, location), |
| 362 | else => return f.object.dg.writeCValue(w, c_value), | 362 | else => try f.object.dg.writeCValue(w, c_value), |
| 363 | } | 363 | } |
| 364 | } | 364 | } |
| 365 | 365 | ||
| 366 | fn writeCValueDeref(f: *Function, w: anytype, c_value: CValue) !void { | 366 | fn writeCValueDeref(f: *Function, w: anytype, c_value: CValue) !void { |
| 367 | switch (c_value) { | 367 | switch (c_value) { |
| 368 | .constant => |inst| { | 368 | .constant => |val| { |
| 369 | const mod = f.object.dg.module; | ||
| 370 | const ty = f.typeOf(inst); | ||
| 371 | const val = (try f.air.value(inst, mod)).?; | ||
| 372 | try w.writeAll("(*"); | 369 | try w.writeAll("(*"); |
| 373 | try f.object.dg.renderValue(w, ty, val, .Other); | 370 | try f.object.dg.renderValue( |
| 374 | return w.writeByte(')'); | 371 | w, |
| 372 | f.object.dg.module.intern_pool.typeOf(val).toType(), | ||
| 373 | val.toValue(), | ||
| 374 | .Other, | ||
| 375 | ); | ||
| 376 | try w.writeByte(')'); | ||
| 375 | }, | 377 | }, |
| 376 | else => return f.object.dg.writeCValueDeref(w, c_value), | 378 | else => try f.object.dg.writeCValueDeref(w, c_value), |
| 377 | } | 379 | } |
| 378 | } | 380 | } |
| 379 | 381 | ||
| 380 | fn writeCValueMember(f: *Function, w: anytype, c_value: CValue, member: CValue) !void { | 382 | fn writeCValueMember(f: *Function, w: anytype, c_value: CValue, member: CValue) !void { |
| 381 | switch (c_value) { | 383 | switch (c_value) { |
| 382 | .constant => |inst| { | 384 | .constant => |val| { |
| 383 | const mod = f.object.dg.module; | 385 | try f.object.dg.renderValue( |
| 384 | const ty = f.typeOf(inst); | 386 | w, |
| 385 | const val = (try f.air.value(inst, mod)).?; | 387 | f.object.dg.module.intern_pool.typeOf(val).toType(), |
| 386 | try f.object.dg.renderValue(w, ty, val, .Other); | 388 | val.toValue(), |
| 389 | .Other, | ||
| 390 | ); | ||
| 387 | try w.writeByte('.'); | 391 | try w.writeByte('.'); |
| 388 | return f.writeCValue(w, member, .Other); | 392 | try f.writeCValue(w, member, .Other); |
| 389 | }, | 393 | }, |
| 390 | else => return f.object.dg.writeCValueMember(w, c_value, member), | 394 | else => try f.object.dg.writeCValueMember(w, c_value, member), |
| 391 | } | 395 | } |
| 392 | } | 396 | } |
| 393 | 397 | ||
| 394 | fn writeCValueDerefMember(f: *Function, w: anytype, c_value: CValue, member: CValue) !void { | 398 | fn writeCValueDerefMember(f: *Function, w: anytype, c_value: CValue, member: CValue) !void { |
| 395 | switch (c_value) { | 399 | switch (c_value) { |
| 396 | .constant => |inst| { | 400 | .constant => |val| { |
| 397 | const mod = f.object.dg.module; | ||
| 398 | const ty = f.typeOf(inst); | ||
| 399 | const val = (try f.air.value(inst, mod)).?; | ||
| 400 | try w.writeByte('('); | 401 | try w.writeByte('('); |
| 401 | try f.object.dg.renderValue(w, ty, val, .Other); | 402 | try f.object.dg.renderValue( |
| 403 | w, | ||
| 404 | f.object.dg.module.intern_pool.typeOf(val).toType(), | ||
| 405 | val.toValue(), | ||
| 406 | .Other, | ||
| 407 | ); | ||
| 402 | try w.writeAll(")->"); | 408 | try w.writeAll(")->"); |
| 403 | return f.writeCValue(w, member, .Other); | 409 | try f.writeCValue(w, member, .Other); |
| 404 | }, | 410 | }, |
| 405 | else => return f.object.dg.writeCValueDerefMember(w, c_value, member), | 411 | else => try f.object.dg.writeCValueDerefMember(w, c_value, member), |
| 406 | } | 412 | } |
| 407 | } | 413 | } |
| 408 | 414 | ||
| ... | @@ -4763,11 +4769,22 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4763,11 +4769,22 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4763 | return .none; | 4769 | return .none; |
| 4764 | } | 4770 | } |
| 4765 | 4771 | ||
| 4766 | fn asmInputNeedsLocal(constraint: []const u8, value: CValue) bool { | 4772 | fn asmInputNeedsLocal(f: *Function, constraint: []const u8, value: CValue) bool { |
| 4773 | const target = f.object.dg.module.getTarget(); | ||
| 4767 | return switch (constraint[0]) { | 4774 | return switch (constraint[0]) { |
| 4768 | '{' => true, | 4775 | '{' => true, |
| 4769 | 'i', 'r' => false, | 4776 | 'i', 'r' => false, |
| 4770 | else => value == .constant, | 4777 | 'I' => !target.cpu.arch.isArmOrThumb(), |
| 4778 | else => switch (value) { | ||
| 4779 | .constant => |val| switch (f.object.dg.module.intern_pool.indexToKey(val)) { | ||
| 4780 | .ptr => |ptr| switch (ptr.addr) { | ||
| 4781 | .decl => false, | ||
| 4782 | else => true, | ||
| 4783 | }, | ||
| 4784 | else => true, | ||
| 4785 | }, | ||
| 4786 | else => false, | ||
| 4787 | }, | ||
| 4771 | }; | 4788 | }; |
| 4772 | } | 4789 | } |
| 4773 | 4790 | ||
| ... | @@ -4848,7 +4865,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4848,7 +4865,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4848 | 4865 | ||
| 4849 | const is_reg = constraint[0] == '{'; | 4866 | const is_reg = constraint[0] == '{'; |
| 4850 | const input_val = try f.resolveInst(input); | 4867 | const input_val = try f.resolveInst(input); |
| 4851 | if (asmInputNeedsLocal(constraint, input_val)) { | 4868 | if (asmInputNeedsLocal(f, constraint, input_val)) { |
| 4852 | const input_ty = f.typeOf(input); | 4869 | const input_ty = f.typeOf(input); |
| 4853 | if (is_reg) try writer.writeAll("register "); | 4870 | if (is_reg) try writer.writeAll("register "); |
| 4854 | const alignment = 0; | 4871 | const alignment = 0; |
| ... | @@ -4969,7 +4986,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4969,7 +4986,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4969 | const is_reg = constraint[0] == '{'; | 4986 | const is_reg = constraint[0] == '{'; |
| 4970 | const input_val = try f.resolveInst(input); | 4987 | const input_val = try f.resolveInst(input); |
| 4971 | try writer.print("{s}(", .{fmtStringLiteral(if (is_reg) "r" else constraint, null)}); | 4988 | try writer.print("{s}(", .{fmtStringLiteral(if (is_reg) "r" else constraint, null)}); |
| 4972 | try f.writeCValue(writer, if (asmInputNeedsLocal(constraint, input_val)) local: { | 4989 | try f.writeCValue(writer, if (asmInputNeedsLocal(f, constraint, input_val)) local: { |
| 4973 | const input_local = .{ .local = locals_index }; | 4990 | const input_local = .{ .local = locals_index }; |
| 4974 | locals_index += 1; | 4991 | locals_index += 1; |
| 4975 | break :local input_local; | 4992 | break :local input_local; |
src/codegen/llvm.zig+9-7| ... | @@ -417,7 +417,7 @@ const DataLayoutBuilder = struct { | ... | @@ -417,7 +417,7 @@ const DataLayoutBuilder = struct { |
| 417 | if (idx != size) try writer.print(":{d}", .{idx}); | 417 | if (idx != size) try writer.print(":{d}", .{idx}); |
| 418 | } | 418 | } |
| 419 | } | 419 | } |
| 420 | if (self.target.cpu.arch.isARM() or self.target.cpu.arch.isThumb()) | 420 | if (self.target.cpu.arch.isArmOrThumb()) |
| 421 | try writer.writeAll("-Fi8"); // for thumb interwork | 421 | try writer.writeAll("-Fi8"); // for thumb interwork |
| 422 | if (self.target.cpu.arch != .hexagon) { | 422 | if (self.target.cpu.arch != .hexagon) { |
| 423 | if (self.target.cpu.arch == .s390x) try self.typeAlignment(.integer, 1, 8, 8, false, writer); | 423 | if (self.target.cpu.arch == .s390x) try self.typeAlignment(.integer, 1, 8, 8, false, writer); |
| ... | @@ -620,7 +620,7 @@ const DataLayoutBuilder = struct { | ... | @@ -620,7 +620,7 @@ const DataLayoutBuilder = struct { |
| 620 | else => {}, | 620 | else => {}, |
| 621 | } | 621 | } |
| 622 | }, | 622 | }, |
| 623 | .vector => if (self.target.cpu.arch.isARM() or self.target.cpu.arch.isThumb()) { | 623 | .vector => if (self.target.cpu.arch.isArmOrThumb()) { |
| 624 | switch (size) { | 624 | switch (size) { |
| 625 | 128 => abi = 64, | 625 | 128 => abi = 64, |
| 626 | else => {}, | 626 | else => {}, |
| ... | @@ -670,7 +670,7 @@ const DataLayoutBuilder = struct { | ... | @@ -670,7 +670,7 @@ const DataLayoutBuilder = struct { |
| 670 | else => {}, | 670 | else => {}, |
| 671 | }, | 671 | }, |
| 672 | .aggregate => if (self.target.os.tag == .uefi or self.target.os.tag == .windows or | 672 | .aggregate => if (self.target.os.tag == .uefi or self.target.os.tag == .windows or |
| 673 | self.target.cpu.arch.isARM() or self.target.cpu.arch.isThumb()) | 673 | self.target.cpu.arch.isArmOrThumb()) |
| 674 | { | 674 | { |
| 675 | pref = @min(pref, self.target.ptrBitWidth()); | 675 | pref = @min(pref, self.target.ptrBitWidth()); |
| 676 | } else if (self.target.cpu.arch == .hexagon) { | 676 | } else if (self.target.cpu.arch == .hexagon) { |
| ... | @@ -6809,8 +6809,6 @@ pub const FuncGen = struct { | ... | @@ -6809,8 +6809,6 @@ pub const FuncGen = struct { |
| 6809 | } | 6809 | } |
| 6810 | llvm_constraints.appendAssumeCapacity('='); | 6810 | llvm_constraints.appendAssumeCapacity('='); |
| 6811 | 6811 | ||
| 6812 | // Pass any non-return outputs indirectly, if the constraint accepts a memory location | ||
| 6813 | is_indirect.* = (output != .none) and constraintAllowsMemory(constraint); | ||
| 6814 | if (output != .none) { | 6812 | if (output != .none) { |
| 6815 | const output_inst = try self.resolveInst(output); | 6813 | const output_inst = try self.resolveInst(output); |
| 6816 | const output_ty = self.typeOf(output); | 6814 | const output_ty = self.typeOf(output); |
| ... | @@ -6825,6 +6823,8 @@ pub const FuncGen = struct { | ... | @@ -6825,6 +6823,8 @@ pub const FuncGen = struct { |
| 6825 | }), | 6823 | }), |
| 6826 | } | 6824 | } |
| 6827 | 6825 | ||
| 6826 | // Pass any non-return outputs indirectly, if the constraint accepts a memory location | ||
| 6827 | is_indirect.* = constraintAllowsMemory(constraint); | ||
| 6828 | if (is_indirect.*) { | 6828 | if (is_indirect.*) { |
| 6829 | // Pass the result by reference as an indirect output (e.g. "=*m") | 6829 | // Pass the result by reference as an indirect output (e.g. "=*m") |
| 6830 | llvm_constraints.appendAssumeCapacity('*'); | 6830 | llvm_constraints.appendAssumeCapacity('*'); |
| ... | @@ -6841,11 +6841,13 @@ pub const FuncGen = struct { | ... | @@ -6841,11 +6841,13 @@ pub const FuncGen = struct { |
| 6841 | } else { | 6841 | } else { |
| 6842 | switch (constraint[0]) { | 6842 | switch (constraint[0]) { |
| 6843 | '=' => {}, | 6843 | '=' => {}, |
| 6844 | else => return self.todo("unsupported output constraint on result type '{c}'", .{ | 6844 | else => return self.todo("unsupported output constraint on result type '{s}'", .{ |
| 6845 | constraint[0], | 6845 | constraint, |
| 6846 | }), | 6846 | }), |
| 6847 | } | 6847 | } |
| 6848 | 6848 | ||
| 6849 | is_indirect.* = false; | ||
| 6850 | |||
| 6849 | const ret_ty = self.typeOfIndex(inst); | 6851 | const ret_ty = self.typeOfIndex(inst); |
| 6850 | llvm_ret_types[llvm_ret_i] = try o.lowerType(ret_ty); | 6852 | llvm_ret_types[llvm_ret_i] = try o.lowerType(ret_ty); |
| 6851 | llvm_ret_i += 1; | 6853 | llvm_ret_i += 1; |
src/link/Elf.zig+1-1| ... | @@ -1654,7 +1654,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v | ... | @@ -1654,7 +1654,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 1654 | } | 1654 | } |
| 1655 | 1655 | ||
| 1656 | if (self.base.options.link_mode == .Static) { | 1656 | if (self.base.options.link_mode == .Static) { |
| 1657 | if (target.cpu.arch.isARM() or target.cpu.arch.isThumb()) { | 1657 | if (target.cpu.arch.isArmOrThumb()) { |
| 1658 | try argv.append("-Bstatic"); | 1658 | try argv.append("-Bstatic"); |
| 1659 | } else { | 1659 | } else { |
| 1660 | try argv.append("-static"); | 1660 | try argv.append("-static"); |
test/behavior/align.zig+3-2| ... | @@ -198,11 +198,12 @@ test "alignment and size of structs with 128-bit fields" { | ... | @@ -198,11 +198,12 @@ test "alignment and size of structs with 128-bit fields" { |
| 198 | 198 | ||
| 199 | else => return error.SkipZigTest, | 199 | else => return error.SkipZigTest, |
| 200 | }; | 200 | }; |
| 201 | const min_struct_align = if (builtin.zig_backend == .stage2_c) 16 else 0; | ||
| 201 | comptime { | 202 | comptime { |
| 202 | assert(@alignOf(A) == expected.a_align); | 203 | assert(@alignOf(A) == @max(expected.a_align, min_struct_align)); |
| 203 | assert(@sizeOf(A) == expected.a_size); | 204 | assert(@sizeOf(A) == expected.a_size); |
| 204 | 205 | ||
| 205 | assert(@alignOf(B) == expected.b_align); | 206 | assert(@alignOf(B) == @max(expected.b_align, min_struct_align)); |
| 206 | assert(@sizeOf(B) == expected.b_size); | 207 | assert(@sizeOf(B) == expected.b_size); |
| 207 | 208 | ||
| 208 | assert(@alignOf(u128) == expected.u128_align); | 209 | assert(@alignOf(u128) == expected.u128_align); |
test/behavior/bitcast.zig+1-1| ... | @@ -421,7 +421,7 @@ test "bitcast nan float does modify signaling bit" { | ... | @@ -421,7 +421,7 @@ test "bitcast nan float does modify signaling bit" { |
| 421 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 421 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 422 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 422 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 423 | // TODO: https://github.com/ziglang/zig/issues/14366 | 423 | // TODO: https://github.com/ziglang/zig/issues/14366 |
| 424 | if (builtin.cpu.arch == .arm and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; | 424 | if (builtin.zig_backend == .stage2_llvm and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; |
| 425 | 425 | ||
| 426 | // 16 bit | 426 | // 16 bit |
| 427 | const snan_f16_const = math.nan_f16; | 427 | const snan_f16_const = math.nan_f16; |
test/behavior/call_tail.zig+10-1| ... | @@ -32,7 +32,16 @@ noinline fn insertionSort(data: []u64) void { | ... | @@ -32,7 +32,16 @@ noinline fn insertionSort(data: []u64) void { |
| 32 | 32 | ||
| 33 | test "arguments pointed to on stack into tailcall" { | 33 | test "arguments pointed to on stack into tailcall" { |
| 34 | switch (builtin.cpu.arch) { | 34 | switch (builtin.cpu.arch) { |
| 35 | .wasm32, .mips, .mipsel, .powerpc, .powerpcle, .powerpc64le => return error.SkipZigTest, | 35 | .wasm32, |
| 36 | .mips, | ||
| 37 | .mipsel, | ||
| 38 | .mips64, | ||
| 39 | .mips64el, | ||
| 40 | .powerpc, | ||
| 41 | .powerpcle, | ||
| 42 | .powerpc64, | ||
| 43 | .powerpc64le, | ||
| 44 | => return error.SkipZigTest, | ||
| 36 | else => {}, | 45 | else => {}, |
| 37 | } | 46 | } |
| 38 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 47 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
test/behavior/cast.zig+2| ... | @@ -123,6 +123,7 @@ test "@floatFromInt(f80)" { | ... | @@ -123,6 +123,7 @@ test "@floatFromInt(f80)" { |
| 123 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 123 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 124 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 124 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 125 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 125 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 126 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 126 | 127 | ||
| 127 | const S = struct { | 128 | const S = struct { |
| 128 | fn doTheTest(comptime Int: type) !void { | 129 | fn doTheTest(comptime Int: type) !void { |
| ... | @@ -1369,6 +1370,7 @@ test "cast f16 to wider types" { | ... | @@ -1369,6 +1370,7 @@ test "cast f16 to wider types" { |
| 1369 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1370 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1370 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1371 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1371 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1372 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1373 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 1372 | 1374 | ||
| 1373 | const S = struct { | 1375 | const S = struct { |
| 1374 | fn doTheTest() !void { | 1376 | fn doTheTest() !void { |
test/behavior/eval.zig+1| ... | @@ -533,6 +533,7 @@ test "runtime 128 bit integer division" { | ... | @@ -533,6 +533,7 @@ test "runtime 128 bit integer division" { |
| 533 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 533 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 534 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 534 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 535 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 535 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 536 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 536 | 537 | ||
| 537 | var a: u128 = 152313999999999991610955792383; | 538 | var a: u128 = 152313999999999991610955792383; |
| 538 | var b: u128 = 10000000000000000000; | 539 | var b: u128 = 10000000000000000000; |
test/behavior/floatop.zig+9| ... | @@ -554,6 +554,7 @@ test "another, possibly redundant, @fabs test" { | ... | @@ -554,6 +554,7 @@ test "another, possibly redundant, @fabs test" { |
| 554 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 554 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 555 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 555 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 556 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 556 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 557 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 557 | 558 | ||
| 558 | try testFabsLegacy(f128, 12.0); | 559 | try testFabsLegacy(f128, 12.0); |
| 559 | try comptime testFabsLegacy(f128, 12.0); | 560 | try comptime testFabsLegacy(f128, 12.0); |
| ... | @@ -576,6 +577,7 @@ test "@fabs f80" { | ... | @@ -576,6 +577,7 @@ test "@fabs f80" { |
| 576 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 577 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 577 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 578 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 578 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 579 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 580 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 579 | 581 | ||
| 580 | try testFabsLegacy(f80, 12.0); | 582 | try testFabsLegacy(f80, 12.0); |
| 581 | try comptime testFabsLegacy(f80, 12.0); | 583 | try comptime testFabsLegacy(f80, 12.0); |
| ... | @@ -593,6 +595,7 @@ test "a third @fabs test, surely there should not be three fabs tests" { | ... | @@ -593,6 +595,7 @@ test "a third @fabs test, surely there should not be three fabs tests" { |
| 593 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 595 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 594 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 596 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 595 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 597 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 598 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 596 | 599 | ||
| 597 | inline for ([_]type{ f16, f32, f64, f80, f128, c_longdouble }) |T| { | 600 | inline for ([_]type{ f16, f32, f64, f80, f128, c_longdouble }) |T| { |
| 598 | // normals | 601 | // normals |
| ... | @@ -684,6 +687,7 @@ test "@floor f80" { | ... | @@ -684,6 +687,7 @@ test "@floor f80" { |
| 684 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 687 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 685 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 688 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 686 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 689 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 690 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 687 | 691 | ||
| 688 | if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) { | 692 | if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) { |
| 689 | // https://github.com/ziglang/zig/issues/12602 | 693 | // https://github.com/ziglang/zig/issues/12602 |
| ... | @@ -700,6 +704,7 @@ test "@floor f128" { | ... | @@ -700,6 +704,7 @@ test "@floor f128" { |
| 700 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 704 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 701 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 705 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 702 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 706 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 707 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 703 | 708 | ||
| 704 | try testFloorLegacy(f128, 12.0); | 709 | try testFloorLegacy(f128, 12.0); |
| 705 | try comptime testFloorLegacy(f128, 12.0); | 710 | try comptime testFloorLegacy(f128, 12.0); |
| ... | @@ -780,6 +785,7 @@ test "@ceil f80" { | ... | @@ -780,6 +785,7 @@ test "@ceil f80" { |
| 780 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 785 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 781 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 786 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 782 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 787 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 788 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 783 | 789 | ||
| 784 | if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) { | 790 | if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) { |
| 785 | // https://github.com/ziglang/zig/issues/12602 | 791 | // https://github.com/ziglang/zig/issues/12602 |
| ... | @@ -796,6 +802,7 @@ test "@ceil f128" { | ... | @@ -796,6 +802,7 @@ test "@ceil f128" { |
| 796 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 802 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 797 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 803 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 798 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 804 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 805 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 799 | 806 | ||
| 800 | try testCeilLegacy(f128, 12.0); | 807 | try testCeilLegacy(f128, 12.0); |
| 801 | try comptime testCeilLegacy(f128, 12.0); | 808 | try comptime testCeilLegacy(f128, 12.0); |
| ... | @@ -875,6 +882,7 @@ test "@trunc f80" { | ... | @@ -875,6 +882,7 @@ test "@trunc f80" { |
| 875 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 882 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 876 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 883 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 877 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 884 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 885 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 878 | 886 | ||
| 879 | if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) { | 887 | if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) { |
| 880 | // https://github.com/ziglang/zig/issues/12602 | 888 | // https://github.com/ziglang/zig/issues/12602 |
| ... | @@ -897,6 +905,7 @@ test "@trunc f128" { | ... | @@ -897,6 +905,7 @@ test "@trunc f128" { |
| 897 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 905 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 898 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 906 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 899 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 907 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 908 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 900 | 909 | ||
| 901 | try testTruncLegacy(f128, 12.0); | 910 | try testTruncLegacy(f128, 12.0); |
| 902 | try comptime testTruncLegacy(f128, 12.0); | 911 | try comptime testTruncLegacy(f128, 12.0); |
test/behavior/fn.zig+1| ... | @@ -151,6 +151,7 @@ fn fnWithUnreachable() noreturn { | ... | @@ -151,6 +151,7 @@ fn fnWithUnreachable() noreturn { |
| 151 | 151 | ||
| 152 | test "extern struct with stdcallcc fn pointer" { | 152 | test "extern struct with stdcallcc fn pointer" { |
| 153 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 153 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 154 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch == .x86) return error.SkipZigTest; | ||
| 154 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 155 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 155 | 156 | ||
| 156 | const S = extern struct { | 157 | const S = extern struct { |
test/behavior/math.zig+4| ... | @@ -664,6 +664,7 @@ test "128-bit multiplication" { | ... | @@ -664,6 +664,7 @@ test "128-bit multiplication" { |
| 664 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 664 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 665 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 665 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 666 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 666 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 667 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 667 | 668 | ||
| 668 | { | 669 | { |
| 669 | var a: i128 = 3; | 670 | var a: i128 = 3; |
| ... | @@ -1311,6 +1312,7 @@ test "remainder division" { | ... | @@ -1311,6 +1312,7 @@ test "remainder division" { |
| 1311 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1312 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1312 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1313 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1313 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1314 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1315 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 1314 | 1316 | ||
| 1315 | if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) { | 1317 | if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) { |
| 1316 | // https://github.com/ziglang/zig/issues/12602 | 1318 | // https://github.com/ziglang/zig/issues/12602 |
| ... | @@ -1455,6 +1457,7 @@ test "@round f80" { | ... | @@ -1455,6 +1457,7 @@ test "@round f80" { |
| 1455 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1457 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1456 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1458 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1457 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1459 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1460 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 1458 | 1461 | ||
| 1459 | try testRound(f80, 12.0); | 1462 | try testRound(f80, 12.0); |
| 1460 | try comptime testRound(f80, 12.0); | 1463 | try comptime testRound(f80, 12.0); |
| ... | @@ -1467,6 +1470,7 @@ test "@round f128" { | ... | @@ -1467,6 +1470,7 @@ test "@round f128" { |
| 1467 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1470 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1468 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1471 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1469 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1472 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1473 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 1470 | 1474 | ||
| 1471 | try testRound(f128, 12.0); | 1475 | try testRound(f128, 12.0); |
| 1472 | try comptime testRound(f128, 12.0); | 1476 | try comptime testRound(f128, 12.0); |
test/behavior/maximum_minimum.zig+1| ... | @@ -110,6 +110,7 @@ test "@min/max for floats" { | ... | @@ -110,6 +110,7 @@ test "@min/max for floats" { |
| 110 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 110 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 111 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 111 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 112 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 112 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 113 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 113 | 114 | ||
| 114 | const S = struct { | 115 | const S = struct { |
| 115 | fn doTheTest(comptime T: type) !void { | 116 | fn doTheTest(comptime T: type) !void { |
test/behavior/muladd.zig+4| ... | @@ -56,6 +56,7 @@ test "@mulAdd f80" { | ... | @@ -56,6 +56,7 @@ test "@mulAdd f80" { |
| 56 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 56 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 57 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 57 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 58 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 58 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 59 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 59 | 60 | ||
| 60 | try comptime testMulAdd80(); | 61 | try comptime testMulAdd80(); |
| 61 | try testMulAdd80(); | 62 | try testMulAdd80(); |
| ... | @@ -75,6 +76,7 @@ test "@mulAdd f128" { | ... | @@ -75,6 +76,7 @@ test "@mulAdd f128" { |
| 75 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 76 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 76 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 77 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 77 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 78 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 79 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 78 | 80 | ||
| 79 | try comptime testMulAdd128(); | 81 | try comptime testMulAdd128(); |
| 80 | try testMulAdd128(); | 82 | try testMulAdd128(); |
| ... | @@ -177,6 +179,7 @@ test "vector f80" { | ... | @@ -177,6 +179,7 @@ test "vector f80" { |
| 177 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 179 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 178 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 180 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 179 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 181 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 182 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 180 | 183 | ||
| 181 | try comptime vector80(); | 184 | try comptime vector80(); |
| 182 | try vector80(); | 185 | try vector80(); |
| ... | @@ -201,6 +204,7 @@ test "vector f128" { | ... | @@ -201,6 +204,7 @@ test "vector f128" { |
| 201 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 204 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 202 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 205 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 203 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 206 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 207 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 204 | 208 | ||
| 205 | try comptime vector128(); | 209 | try comptime vector128(); |
| 206 | try vector128(); | 210 | try vector128(); |
test/behavior/saturating_arithmetic.zig+1| ... | @@ -157,6 +157,7 @@ test "saturating multiplication" { | ... | @@ -157,6 +157,7 @@ test "saturating multiplication" { |
| 157 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 157 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 158 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 158 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 159 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 159 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 160 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 160 | 161 | ||
| 161 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .wasm32) { | 162 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .wasm32) { |
| 162 | // https://github.com/ziglang/zig/issues/9660 | 163 | // https://github.com/ziglang/zig/issues/9660 |
test/behavior/struct.zig+3-2| ... | @@ -428,7 +428,7 @@ test "packed struct 24bits" { | ... | @@ -428,7 +428,7 @@ test "packed struct 24bits" { |
| 428 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 428 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 429 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 429 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 430 | if (builtin.cpu.arch == .wasm32) return error.SkipZigTest; // TODO | 430 | if (builtin.cpu.arch == .wasm32) return error.SkipZigTest; // TODO |
| 431 | if (builtin.cpu.arch == .arm) return error.SkipZigTest; // TODO | 431 | if (comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; // TODO |
| 432 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 432 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 433 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 433 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 434 | 434 | ||
| ... | @@ -824,6 +824,7 @@ test "non-packed struct with u128 entry in union" { | ... | @@ -824,6 +824,7 @@ test "non-packed struct with u128 entry in union" { |
| 824 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 824 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 825 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 825 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 826 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 826 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 827 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 827 | 828 | ||
| 828 | const U = union(enum) { | 829 | const U = union(enum) { |
| 829 | Num: u128, | 830 | Num: u128, |
| ... | @@ -944,7 +945,7 @@ test "comptime struct field" { | ... | @@ -944,7 +945,7 @@ test "comptime struct field" { |
| 944 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 945 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 945 | 946 | ||
| 946 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 947 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 947 | if (builtin.cpu.arch == .arm) return error.SkipZigTest; // TODO | 948 | if (comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; // TODO |
| 948 | 949 | ||
| 949 | const T = struct { | 950 | const T = struct { |
| 950 | a: i32, | 951 | a: i32, |
test/behavior/var_args.zig+4-4| ... | @@ -101,7 +101,7 @@ test "simple variadic function" { | ... | @@ -101,7 +101,7 @@ test "simple variadic function" { |
| 101 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 101 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 102 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 102 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 103 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 103 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 104 | if (builtin.cpu.arch == .aarch64 and builtin.os.tag != .macos) { | 104 | if (builtin.os.tag != .macos and comptime builtin.cpu.arch.isAARCH64()) { |
| 105 | // https://github.com/ziglang/zig/issues/14096 | 105 | // https://github.com/ziglang/zig/issues/14096 |
| 106 | return error.SkipZigTest; | 106 | return error.SkipZigTest; |
| 107 | } | 107 | } |
| ... | @@ -151,7 +151,7 @@ test "variadic functions" { | ... | @@ -151,7 +151,7 @@ test "variadic functions" { |
| 151 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 151 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 152 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 152 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 153 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 153 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 154 | if (builtin.cpu.arch == .aarch64 and builtin.os.tag != .macos) { | 154 | if (builtin.os.tag != .macos and comptime builtin.cpu.arch.isAARCH64()) { |
| 155 | // https://github.com/ziglang/zig/issues/14096 | 155 | // https://github.com/ziglang/zig/issues/14096 |
| 156 | return error.SkipZigTest; | 156 | return error.SkipZigTest; |
| 157 | } | 157 | } |
| ... | @@ -195,7 +195,7 @@ test "copy VaList" { | ... | @@ -195,7 +195,7 @@ test "copy VaList" { |
| 195 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 195 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 196 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 196 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 197 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 197 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 198 | if (builtin.cpu.arch == .aarch64 and builtin.os.tag != .macos) { | 198 | if (builtin.os.tag != .macos and comptime builtin.cpu.arch.isAARCH64()) { |
| 199 | // https://github.com/ziglang/zig/issues/14096 | 199 | // https://github.com/ziglang/zig/issues/14096 |
| 200 | return error.SkipZigTest; | 200 | return error.SkipZigTest; |
| 201 | } | 201 | } |
| ... | @@ -228,7 +228,7 @@ test "unused VaList arg" { | ... | @@ -228,7 +228,7 @@ test "unused VaList arg" { |
| 228 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 228 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 229 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 229 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 230 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 230 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 231 | if (builtin.cpu.arch == .aarch64 and builtin.os.tag != .macos) { | 231 | if (builtin.os.tag != .macos and comptime builtin.cpu.arch.isAARCH64()) { |
| 232 | // https://github.com/ziglang/zig/issues/14096 | 232 | // https://github.com/ziglang/zig/issues/14096 |
| 233 | return error.SkipZigTest; | 233 | return error.SkipZigTest; |
| 234 | } | 234 | } |
test/behavior/vector.zig+3| ... | @@ -102,6 +102,7 @@ test "vector float operators" { | ... | @@ -102,6 +102,7 @@ test "vector float operators" { |
| 102 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 102 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 103 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 103 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 104 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 104 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 105 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 105 | 106 | ||
| 106 | inline for ([_]type{ f16, f32, f64, f80, f128 }) |T| { | 107 | inline for ([_]type{ f16, f32, f64, f80, f128 }) |T| { |
| 107 | const S = struct { | 108 | const S = struct { |
| ... | @@ -494,6 +495,7 @@ test "vector division operators" { | ... | @@ -494,6 +495,7 @@ test "vector division operators" { |
| 494 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 495 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 495 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 496 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 496 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 497 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 498 | if (builtin.zig_backend == .stage2_llvm and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 497 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 499 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 498 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 500 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 499 | 501 | ||
| ... | @@ -705,6 +707,7 @@ test "vector reduce operation" { | ... | @@ -705,6 +707,7 @@ test "vector reduce operation" { |
| 705 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 707 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 706 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 708 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 707 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 709 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 710 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 708 | 711 | ||
| 709 | const S = struct { | 712 | const S = struct { |
| 710 | fn testReduce(comptime op: std.builtin.ReduceOp, x: anytype, expected: anytype) !void { | 713 | fn testReduce(comptime op: std.builtin.ReduceOp, x: anytype, expected: anytype) !void { |
test/src/Cases.zig+1-1| ... | @@ -1524,7 +1524,7 @@ fn runOneCase( | ... | @@ -1524,7 +1524,7 @@ fn runOneCase( |
| 1524 | } | 1524 | } |
| 1525 | } else switch (host.getExternalExecutor(target_info, .{ .link_libc = case.link_libc })) { | 1525 | } else switch (host.getExternalExecutor(target_info, .{ .link_libc = case.link_libc })) { |
| 1526 | .native => { | 1526 | .native => { |
| 1527 | if (case.backend == .stage2 and case.target.getCpuArch() == .arm) { | 1527 | if (case.backend == .stage2 and case.target.getCpuArch().isArmOrThumb()) { |
| 1528 | // https://github.com/ziglang/zig/issues/13623 | 1528 | // https://github.com/ziglang/zig/issues/13623 |
| 1529 | continue :update; // Pass test. | 1529 | continue :update; // Pass test. |
| 1530 | } | 1530 | } |
test/tests.zig+1| ... | @@ -1053,6 +1053,7 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { | ... | @@ -1053,6 +1053,7 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { |
| 1053 | // TODO stop violating these pedantic errors. spotted on linux | 1053 | // TODO stop violating these pedantic errors. spotted on linux |
| 1054 | "-Wno-address-of-packed-member", | 1054 | "-Wno-address-of-packed-member", |
| 1055 | "-Wno-gnu-folding-constant", | 1055 | "-Wno-gnu-folding-constant", |
| 1056 | "-Wno-incompatible-function-pointer-types", | ||
| 1056 | "-Wno-incompatible-pointer-types", | 1057 | "-Wno-incompatible-pointer-types", |
| 1057 | "-Wno-overlength-strings", | 1058 | "-Wno-overlength-strings", |
| 1058 | // TODO stop violating these pedantic errors. spotted on darwin | 1059 | // TODO stop violating these pedantic errors. spotted on darwin |