| author | |
| committer | |
| log | a9b68308b9eeb494524e2b7ab0d63cfa6b623cd0 |
| tree | 0c6de0921db3a4f661be1d07415cb7a264234aa1 |
| parent | 9177e0da4f8e3480f5a7fade6c42f2ec81f5ffd5 |
- cbe: Implement linksection support, to support TLS when not linking libc
- cbe: Support under-aligned variables / struct fields
- cbe: Support packed structs (in the C definition of packed)
- windows: Fix regression with x86 _tls_array
- compiler_rt: Add 128-bit atomics to compiler_rt
- tests: Re-enable threadlocal tests on cbe+windows, and llvm+x86
- tests: Re-enable f80 tests that now pass
- ci: change windows ci to run the CBE behaviour tests with -lc, to match how the compiler is bootstrapped
- update zig1.wasm10 files changed, 190 insertions(+), 33 deletions(-)
ci/x86_64-windows-debug.ps1+3-2| ... | ... | @@ -76,7 +76,8 @@ Write-Output "Build x86_64-windows-msvc behavior tests using the C backend..." |
| 76 | 76 | -ofmt=c ` |
| 77 | 77 | -femit-bin="test-x86_64-windows-msvc.c" ` |
| 78 | 78 | --test-no-exec ` |
| 79 | -target x86_64-windows-msvc | |
| 79 | -target x86_64-windows-msvc ` | |
| 80 | -lc | |
| 80 | 81 | CheckLastExitCode |
| 81 | 82 | |
| 82 | 83 | & "stage3-debug\bin\zig.exe" build-obj ` |
| ... | ... | @@ -99,7 +100,7 @@ Enter-VsDevShell -VsInstallPath "C:\Program Files\Microsoft Visual Studio\2022\E |
| 99 | 100 | CheckLastExitCode |
| 100 | 101 | |
| 101 | 102 | Write-Output "Build and run behavior tests with msvc..." |
| 102 | & cl.exe -I..\lib test-x86_64-windows-msvc.c compiler_rt-x86_64-windows-msvc.c /W3 /Z7 -link -nologo -debug -subsystem:console -entry:wWinMainCRTStartup kernel32.lib ntdll.lib vcruntime.lib libucrt.lib | |
| 103 | & cl.exe -I..\lib test-x86_64-windows-msvc.c compiler_rt-x86_64-windows-msvc.c /W3 /Z7 -link -nologo -debug -subsystem:console kernel32.lib ntdll.lib libcmt.lib | |
| 103 | 104 | CheckLastExitCode |
| 104 | 105 | |
| 105 | 106 | & .\test-x86_64-windows-msvc.exe |
ci/x86_64-windows-release.ps1+3-2| ... | ... | @@ -76,7 +76,8 @@ Write-Output "Build x86_64-windows-msvc behavior tests using the C backend..." |
| 76 | 76 | -ofmt=c ` |
| 77 | 77 | -femit-bin="test-x86_64-windows-msvc.c" ` |
| 78 | 78 | --test-no-exec ` |
| 79 | -target x86_64-windows-msvc | |
| 79 | -target x86_64-windows-msvc ` | |
| 80 | -lc | |
| 80 | 81 | CheckLastExitCode |
| 81 | 82 | |
| 82 | 83 | & "stage3-release\bin\zig.exe" build-obj ` |
| ... | ... | @@ -99,7 +100,7 @@ Enter-VsDevShell -VsInstallPath "C:\Program Files\Microsoft Visual Studio\2022\E |
| 99 | 100 | CheckLastExitCode |
| 100 | 101 | |
| 101 | 102 | Write-Output "Build and run behavior tests with msvc..." |
| 102 | & cl.exe -I..\lib test-x86_64-windows-msvc.c compiler_rt-x86_64-windows-msvc.c /W3 /Z7 -link -nologo -debug -subsystem:console -entry:wWinMainCRTStartup kernel32.lib ntdll.lib vcruntime.lib libucrt.lib | |
| 103 | & cl.exe -I..\lib test-x86_64-windows-msvc.c compiler_rt-x86_64-windows-msvc.c /W3 /Z7 -link -nologo -debug -subsystem:console kernel32.lib ntdll.lib libcmt.lib | |
| 103 | 104 | CheckLastExitCode |
| 104 | 105 | |
| 105 | 106 | & .\test-x86_64-windows-msvc.exe |
lib/compiler_rt/atomics.zig+104| ... | ... | @@ -192,6 +192,10 @@ fn __atomic_load_8(src: *u64, model: i32) callconv(.C) u64 { |
| 192 | 192 | return atomic_load_N(u64, src, model); |
| 193 | 193 | } |
| 194 | 194 | |
| 195 | fn __atomic_load_16(src: *u128, model: i32) callconv(.C) u128 { | |
| 196 | return atomic_load_N(u128, src, model); | |
| 197 | } | |
| 198 | ||
| 195 | 199 | inline fn atomic_store_N(comptime T: type, dst: *T, value: T, model: i32) void { |
| 196 | 200 | _ = model; |
| 197 | 201 | if (@sizeOf(T) > largest_atomic_size) { |
| ... | ... | @@ -219,6 +223,10 @@ fn __atomic_store_8(dst: *u64, value: u64, model: i32) callconv(.C) void { |
| 219 | 223 | return atomic_store_N(u64, dst, value, model); |
| 220 | 224 | } |
| 221 | 225 | |
| 226 | fn __atomic_store_16(dst: *u128, value: u128, model: i32) callconv(.C) void { | |
| 227 | return atomic_store_N(u128, dst, value, model); | |
| 228 | } | |
| 229 | ||
| 222 | 230 | fn wideUpdate(comptime T: type, ptr: *T, val: T, update: anytype) T { |
| 223 | 231 | const WideAtomic = std.meta.Int(.unsigned, smallest_atomic_fetch_exch_size * 8); |
| 224 | 232 | |
| ... | ... | @@ -282,6 +290,10 @@ fn __atomic_exchange_8(ptr: *u64, val: u64, model: i32) callconv(.C) u64 { |
| 282 | 290 | return atomic_exchange_N(u64, ptr, val, model); |
| 283 | 291 | } |
| 284 | 292 | |
| 293 | fn __atomic_exchange_16(ptr: *u128, val: u128, model: i32) callconv(.C) u128 { | |
| 294 | return atomic_exchange_N(u128, ptr, val, model); | |
| 295 | } | |
| 296 | ||
| 285 | 297 | inline fn atomic_compare_exchange_N( |
| 286 | 298 | comptime T: type, |
| 287 | 299 | ptr: *T, |
| ... | ... | @@ -327,6 +339,10 @@ fn __atomic_compare_exchange_8(ptr: *u64, expected: *u64, desired: u64, success: |
| 327 | 339 | return atomic_compare_exchange_N(u64, ptr, expected, desired, success, failure); |
| 328 | 340 | } |
| 329 | 341 | |
| 342 | fn __atomic_compare_exchange_16(ptr: *u128, expected: *u128, desired: u128, success: i32, failure: i32) callconv(.C) i32 { | |
| 343 | return atomic_compare_exchange_N(u128, ptr, expected, desired, success, failure); | |
| 344 | } | |
| 345 | ||
| 330 | 346 | inline fn fetch_op_N(comptime T: type, comptime op: std.builtin.AtomicRmwOp, ptr: *T, val: T, model: i32) T { |
| 331 | 347 | _ = model; |
| 332 | 348 | const Updater = struct { |
| ... | ... | @@ -338,6 +354,8 @@ inline fn fetch_op_N(comptime T: type, comptime op: std.builtin.AtomicRmwOp, ptr |
| 338 | 354 | .Nand => ~(old & new), |
| 339 | 355 | .Or => old | new, |
| 340 | 356 | .Xor => old ^ new, |
| 357 | .Max => @max(old, new), | |
| 358 | .Min => @min(old, new), | |
| 341 | 359 | else => @compileError("unsupported atomic op"), |
| 342 | 360 | }; |
| 343 | 361 | } |
| ... | ... | @@ -374,6 +392,10 @@ fn __atomic_fetch_add_8(ptr: *u64, val: u64, model: i32) callconv(.C) u64 { |
| 374 | 392 | return fetch_op_N(u64, .Add, ptr, val, model); |
| 375 | 393 | } |
| 376 | 394 | |
| 395 | fn __atomic_fetch_add_16(ptr: *u128, val: u128, model: i32) callconv(.C) u128 { | |
| 396 | return fetch_op_N(u128, .Add, ptr, val, model); | |
| 397 | } | |
| 398 | ||
| 377 | 399 | fn __atomic_fetch_sub_1(ptr: *u8, val: u8, model: i32) callconv(.C) u8 { |
| 378 | 400 | return fetch_op_N(u8, .Sub, ptr, val, model); |
| 379 | 401 | } |
| ... | ... | @@ -390,6 +412,10 @@ fn __atomic_fetch_sub_8(ptr: *u64, val: u64, model: i32) callconv(.C) u64 { |
| 390 | 412 | return fetch_op_N(u64, .Sub, ptr, val, model); |
| 391 | 413 | } |
| 392 | 414 | |
| 415 | fn __atomic_fetch_sub_16(ptr: *u128, val: u128, model: i32) callconv(.C) u128 { | |
| 416 | return fetch_op_N(u128, .Sub, ptr, val, model); | |
| 417 | } | |
| 418 | ||
| 393 | 419 | fn __atomic_fetch_and_1(ptr: *u8, val: u8, model: i32) callconv(.C) u8 { |
| 394 | 420 | return fetch_op_N(u8, .And, ptr, val, model); |
| 395 | 421 | } |
| ... | ... | @@ -406,6 +432,10 @@ fn __atomic_fetch_and_8(ptr: *u64, val: u64, model: i32) callconv(.C) u64 { |
| 406 | 432 | return fetch_op_N(u64, .And, ptr, val, model); |
| 407 | 433 | } |
| 408 | 434 | |
| 435 | fn __atomic_fetch_and_16(ptr: *u128, val: u128, model: i32) callconv(.C) u128 { | |
| 436 | return fetch_op_N(u128, .And, ptr, val, model); | |
| 437 | } | |
| 438 | ||
| 409 | 439 | fn __atomic_fetch_or_1(ptr: *u8, val: u8, model: i32) callconv(.C) u8 { |
| 410 | 440 | return fetch_op_N(u8, .Or, ptr, val, model); |
| 411 | 441 | } |
| ... | ... | @@ -422,6 +452,10 @@ fn __atomic_fetch_or_8(ptr: *u64, val: u64, model: i32) callconv(.C) u64 { |
| 422 | 452 | return fetch_op_N(u64, .Or, ptr, val, model); |
| 423 | 453 | } |
| 424 | 454 | |
| 455 | fn __atomic_fetch_or_16(ptr: *u128, val: u128, model: i32) callconv(.C) u128 { | |
| 456 | return fetch_op_N(u128, .Or, ptr, val, model); | |
| 457 | } | |
| 458 | ||
| 425 | 459 | fn __atomic_fetch_xor_1(ptr: *u8, val: u8, model: i32) callconv(.C) u8 { |
| 426 | 460 | return fetch_op_N(u8, .Xor, ptr, val, model); |
| 427 | 461 | } |
| ... | ... | @@ -438,6 +472,10 @@ fn __atomic_fetch_xor_8(ptr: *u64, val: u64, model: i32) callconv(.C) u64 { |
| 438 | 472 | return fetch_op_N(u64, .Xor, ptr, val, model); |
| 439 | 473 | } |
| 440 | 474 | |
| 475 | fn __atomic_fetch_xor_16(ptr: *u128, val: u128, model: i32) callconv(.C) u128 { | |
| 476 | return fetch_op_N(u128, .Xor, ptr, val, model); | |
| 477 | } | |
| 478 | ||
| 441 | 479 | fn __atomic_fetch_nand_1(ptr: *u8, val: u8, model: i32) callconv(.C) u8 { |
| 442 | 480 | return fetch_op_N(u8, .Nand, ptr, val, model); |
| 443 | 481 | } |
| ... | ... | @@ -454,6 +492,50 @@ fn __atomic_fetch_nand_8(ptr: *u64, val: u64, model: i32) callconv(.C) u64 { |
| 454 | 492 | return fetch_op_N(u64, .Nand, ptr, val, model); |
| 455 | 493 | } |
| 456 | 494 | |
| 495 | fn __atomic_fetch_nand_16(ptr: *u128, val: u128, model: i32) callconv(.C) u128 { | |
| 496 | return fetch_op_N(u128, .Nand, ptr, val, model); | |
| 497 | } | |
| 498 | ||
| 499 | fn __atomic_fetch_umax_1(ptr: *u8, val: u8, model: i32) callconv(.C) u8 { | |
| 500 | return fetch_op_N(u8, .Max, ptr, val, model); | |
| 501 | } | |
| 502 | ||
| 503 | fn __atomic_fetch_umax_2(ptr: *u16, val: u16, model: i32) callconv(.C) u16 { | |
| 504 | return fetch_op_N(u16, .Max, ptr, val, model); | |
| 505 | } | |
| 506 | ||
| 507 | fn __atomic_fetch_umax_4(ptr: *u32, val: u32, model: i32) callconv(.C) u32 { | |
| 508 | return fetch_op_N(u32, .Max, ptr, val, model); | |
| 509 | } | |
| 510 | ||
| 511 | fn __atomic_fetch_umax_8(ptr: *u64, val: u64, model: i32) callconv(.C) u64 { | |
| 512 | return fetch_op_N(u64, .Max, ptr, val, model); | |
| 513 | } | |
| 514 | ||
| 515 | fn __atomic_fetch_umax_16(ptr: *u128, val: u128, model: i32) callconv(.C) u128 { | |
| 516 | return fetch_op_N(u128, .Max, ptr, val, model); | |
| 517 | } | |
| 518 | ||
| 519 | fn __atomic_fetch_umin_1(ptr: *u8, val: u8, model: i32) callconv(.C) u8 { | |
| 520 | return fetch_op_N(u8, .Min, ptr, val, model); | |
| 521 | } | |
| 522 | ||
| 523 | fn __atomic_fetch_umin_2(ptr: *u16, val: u16, model: i32) callconv(.C) u16 { | |
| 524 | return fetch_op_N(u16, .Min, ptr, val, model); | |
| 525 | } | |
| 526 | ||
| 527 | fn __atomic_fetch_umin_4(ptr: *u32, val: u32, model: i32) callconv(.C) u32 { | |
| 528 | return fetch_op_N(u32, .Min, ptr, val, model); | |
| 529 | } | |
| 530 | ||
| 531 | fn __atomic_fetch_umin_8(ptr: *u64, val: u64, model: i32) callconv(.C) u64 { | |
| 532 | return fetch_op_N(u64, .Min, ptr, val, model); | |
| 533 | } | |
| 534 | ||
| 535 | fn __atomic_fetch_umin_16(ptr: *u128, val: u128, model: i32) callconv(.C) u128 { | |
| 536 | return fetch_op_N(u128, .Min, ptr, val, model); | |
| 537 | } | |
| 538 | ||
| 457 | 539 | comptime { |
| 458 | 540 | if (supports_atomic_ops and builtin.object_format != .c) { |
| 459 | 541 | @export(__atomic_load, .{ .name = "__atomic_load", .linkage = linkage, .visibility = visibility }); |
| ... | ... | @@ -465,50 +547,72 @@ comptime { |
| 465 | 547 | @export(__atomic_fetch_add_2, .{ .name = "__atomic_fetch_add_2", .linkage = linkage, .visibility = visibility }); |
| 466 | 548 | @export(__atomic_fetch_add_4, .{ .name = "__atomic_fetch_add_4", .linkage = linkage, .visibility = visibility }); |
| 467 | 549 | @export(__atomic_fetch_add_8, .{ .name = "__atomic_fetch_add_8", .linkage = linkage, .visibility = visibility }); |
| 550 | @export(__atomic_fetch_add_16, .{ .name = "__atomic_fetch_add_16", .linkage = linkage, .visibility = visibility }); | |
| 468 | 551 | |
| 469 | 552 | @export(__atomic_fetch_sub_1, .{ .name = "__atomic_fetch_sub_1", .linkage = linkage, .visibility = visibility }); |
| 470 | 553 | @export(__atomic_fetch_sub_2, .{ .name = "__atomic_fetch_sub_2", .linkage = linkage, .visibility = visibility }); |
| 471 | 554 | @export(__atomic_fetch_sub_4, .{ .name = "__atomic_fetch_sub_4", .linkage = linkage, .visibility = visibility }); |
| 472 | 555 | @export(__atomic_fetch_sub_8, .{ .name = "__atomic_fetch_sub_8", .linkage = linkage, .visibility = visibility }); |
| 556 | @export(__atomic_fetch_sub_16, .{ .name = "__atomic_fetch_sub_16", .linkage = linkage, .visibility = visibility }); | |
| 473 | 557 | |
| 474 | 558 | @export(__atomic_fetch_and_1, .{ .name = "__atomic_fetch_and_1", .linkage = linkage, .visibility = visibility }); |
| 475 | 559 | @export(__atomic_fetch_and_2, .{ .name = "__atomic_fetch_and_2", .linkage = linkage, .visibility = visibility }); |
| 476 | 560 | @export(__atomic_fetch_and_4, .{ .name = "__atomic_fetch_and_4", .linkage = linkage, .visibility = visibility }); |
| 477 | 561 | @export(__atomic_fetch_and_8, .{ .name = "__atomic_fetch_and_8", .linkage = linkage, .visibility = visibility }); |
| 562 | @export(__atomic_fetch_and_16, .{ .name = "__atomic_fetch_and_16", .linkage = linkage, .visibility = visibility }); | |
| 478 | 563 | |
| 479 | 564 | @export(__atomic_fetch_or_1, .{ .name = "__atomic_fetch_or_1", .linkage = linkage, .visibility = visibility }); |
| 480 | 565 | @export(__atomic_fetch_or_2, .{ .name = "__atomic_fetch_or_2", .linkage = linkage, .visibility = visibility }); |
| 481 | 566 | @export(__atomic_fetch_or_4, .{ .name = "__atomic_fetch_or_4", .linkage = linkage, .visibility = visibility }); |
| 482 | 567 | @export(__atomic_fetch_or_8, .{ .name = "__atomic_fetch_or_8", .linkage = linkage, .visibility = visibility }); |
| 568 | @export(__atomic_fetch_or_16, .{ .name = "__atomic_fetch_or_16", .linkage = linkage, .visibility = visibility }); | |
| 483 | 569 | |
| 484 | 570 | @export(__atomic_fetch_xor_1, .{ .name = "__atomic_fetch_xor_1", .linkage = linkage, .visibility = visibility }); |
| 485 | 571 | @export(__atomic_fetch_xor_2, .{ .name = "__atomic_fetch_xor_2", .linkage = linkage, .visibility = visibility }); |
| 486 | 572 | @export(__atomic_fetch_xor_4, .{ .name = "__atomic_fetch_xor_4", .linkage = linkage, .visibility = visibility }); |
| 487 | 573 | @export(__atomic_fetch_xor_8, .{ .name = "__atomic_fetch_xor_8", .linkage = linkage, .visibility = visibility }); |
| 574 | @export(__atomic_fetch_xor_16, .{ .name = "__atomic_fetch_xor_16", .linkage = linkage, .visibility = visibility }); | |
| 488 | 575 | |
| 489 | 576 | @export(__atomic_fetch_nand_1, .{ .name = "__atomic_fetch_nand_1", .linkage = linkage, .visibility = visibility }); |
| 490 | 577 | @export(__atomic_fetch_nand_2, .{ .name = "__atomic_fetch_nand_2", .linkage = linkage, .visibility = visibility }); |
| 491 | 578 | @export(__atomic_fetch_nand_4, .{ .name = "__atomic_fetch_nand_4", .linkage = linkage, .visibility = visibility }); |
| 492 | 579 | @export(__atomic_fetch_nand_8, .{ .name = "__atomic_fetch_nand_8", .linkage = linkage, .visibility = visibility }); |
| 580 | @export(__atomic_fetch_nand_16, .{ .name = "__atomic_fetch_nand_16", .linkage = linkage, .visibility = visibility }); | |
| 581 | ||
| 582 | @export(__atomic_fetch_umax_1, .{ .name = "__atomic_fetch_umax_1", .linkage = linkage, .visibility = visibility }); | |
| 583 | @export(__atomic_fetch_umax_2, .{ .name = "__atomic_fetch_umax_2", .linkage = linkage, .visibility = visibility }); | |
| 584 | @export(__atomic_fetch_umax_4, .{ .name = "__atomic_fetch_umax_4", .linkage = linkage, .visibility = visibility }); | |
| 585 | @export(__atomic_fetch_umax_8, .{ .name = "__atomic_fetch_umax_8", .linkage = linkage, .visibility = visibility }); | |
| 586 | @export(__atomic_fetch_umax_16, .{ .name = "__atomic_fetch_umax_16", .linkage = linkage, .visibility = visibility }); | |
| 587 | ||
| 588 | @export(__atomic_fetch_umin_1, .{ .name = "__atomic_fetch_umin_1", .linkage = linkage, .visibility = visibility }); | |
| 589 | @export(__atomic_fetch_umin_2, .{ .name = "__atomic_fetch_umin_2", .linkage = linkage, .visibility = visibility }); | |
| 590 | @export(__atomic_fetch_umin_4, .{ .name = "__atomic_fetch_umin_4", .linkage = linkage, .visibility = visibility }); | |
| 591 | @export(__atomic_fetch_umin_8, .{ .name = "__atomic_fetch_umin_8", .linkage = linkage, .visibility = visibility }); | |
| 592 | @export(__atomic_fetch_umin_16, .{ .name = "__atomic_fetch_umin_16", .linkage = linkage, .visibility = visibility }); | |
| 493 | 593 | |
| 494 | 594 | @export(__atomic_load_1, .{ .name = "__atomic_load_1", .linkage = linkage, .visibility = visibility }); |
| 495 | 595 | @export(__atomic_load_2, .{ .name = "__atomic_load_2", .linkage = linkage, .visibility = visibility }); |
| 496 | 596 | @export(__atomic_load_4, .{ .name = "__atomic_load_4", .linkage = linkage, .visibility = visibility }); |
| 497 | 597 | @export(__atomic_load_8, .{ .name = "__atomic_load_8", .linkage = linkage, .visibility = visibility }); |
| 598 | @export(__atomic_load_16, .{ .name = "__atomic_load_16", .linkage = linkage, .visibility = visibility }); | |
| 498 | 599 | |
| 499 | 600 | @export(__atomic_store_1, .{ .name = "__atomic_store_1", .linkage = linkage, .visibility = visibility }); |
| 500 | 601 | @export(__atomic_store_2, .{ .name = "__atomic_store_2", .linkage = linkage, .visibility = visibility }); |
| 501 | 602 | @export(__atomic_store_4, .{ .name = "__atomic_store_4", .linkage = linkage, .visibility = visibility }); |
| 502 | 603 | @export(__atomic_store_8, .{ .name = "__atomic_store_8", .linkage = linkage, .visibility = visibility }); |
| 604 | @export(__atomic_store_16, .{ .name = "__atomic_store_16", .linkage = linkage, .visibility = visibility }); | |
| 503 | 605 | |
| 504 | 606 | @export(__atomic_exchange_1, .{ .name = "__atomic_exchange_1", .linkage = linkage, .visibility = visibility }); |
| 505 | 607 | @export(__atomic_exchange_2, .{ .name = "__atomic_exchange_2", .linkage = linkage, .visibility = visibility }); |
| 506 | 608 | @export(__atomic_exchange_4, .{ .name = "__atomic_exchange_4", .linkage = linkage, .visibility = visibility }); |
| 507 | 609 | @export(__atomic_exchange_8, .{ .name = "__atomic_exchange_8", .linkage = linkage, .visibility = visibility }); |
| 610 | @export(__atomic_exchange_16, .{ .name = "__atomic_exchange_16", .linkage = linkage, .visibility = visibility }); | |
| 508 | 611 | |
| 509 | 612 | @export(__atomic_compare_exchange_1, .{ .name = "__atomic_compare_exchange_1", .linkage = linkage, .visibility = visibility }); |
| 510 | 613 | @export(__atomic_compare_exchange_2, .{ .name = "__atomic_compare_exchange_2", .linkage = linkage, .visibility = visibility }); |
| 511 | 614 | @export(__atomic_compare_exchange_4, .{ .name = "__atomic_compare_exchange_4", .linkage = linkage, .visibility = visibility }); |
| 512 | 615 | @export(__atomic_compare_exchange_8, .{ .name = "__atomic_compare_exchange_8", .linkage = linkage, .visibility = visibility }); |
| 616 | @export(__atomic_compare_exchange_16, .{ .name = "__atomic_compare_exchange_16", .linkage = linkage, .visibility = visibility }); | |
| 513 | 617 | } |
| 514 | 618 | } |
lib/std/start_windows_tls.zig+5-3| ... | ... | @@ -7,12 +7,14 @@ export var _tls_end: u8 linksection(".tls$ZZZ") = 0; |
| 7 | 7 | export var __xl_a: std.os.windows.PIMAGE_TLS_CALLBACK linksection(".CRT$XLA") = null; |
| 8 | 8 | export var __xl_z: std.os.windows.PIMAGE_TLS_CALLBACK linksection(".CRT$XLZ") = null; |
| 9 | 9 | |
| 10 | const tls_array: u32 = 0x2c; | |
| 11 | 10 | comptime { |
| 12 | if (builtin.target.cpu.arch == .x86) { | |
| 11 | if (builtin.target.cpu.arch == .x86 and builtin.zig_backend != .stage2_c) { | |
| 13 | 12 | // The __tls_array is the offset of the ThreadLocalStoragePointer field |
| 14 | 13 | // in the TEB block whose base address held in the %fs segment. |
| 15 | @export(tls_array, .{ .name = "_tls_array" }); | |
| 14 | asm ( | |
| 15 | \\ .global __tls_array | |
| 16 | \\ __tls_array = 0x2C | |
| 17 | ); | |
| 16 | 18 | } |
| 17 | 19 | } |
| 18 | 20 |
lib/zig.h+24| ... | ... | @@ -93,6 +93,14 @@ typedef char bool; |
| 93 | 93 | #define zig_align zig_align_unavailable |
| 94 | 94 | #endif |
| 95 | 95 | |
| 96 | #if zig_has_attribute(aligned) | |
| 97 | #define zig_under_align(alignment) __attribute__((aligned(alignment))) | |
| 98 | #elif _MSC_VER | |
| 99 | #define zig_under_align(alignment) zig_align(alignment) | |
| 100 | #else | |
| 101 | #define zig_align zig_align_unavailable | |
| 102 | #endif | |
| 103 | ||
| 96 | 104 | #if zig_has_attribute(aligned) |
| 97 | 105 | #define zig_align_fn(alignment) __attribute__((aligned(alignment))) |
| 98 | 106 | #elif _MSC_VER |
| ... | ... | @@ -101,6 +109,22 @@ typedef char bool; |
| 101 | 109 | #define zig_align_fn zig_align_fn_unavailable |
| 102 | 110 | #endif |
| 103 | 111 | |
| 112 | #if zig_has_attribute(packed) | |
| 113 | #define zig_packed(definition) __attribute__((packed)) definition | |
| 114 | #elif _MSC_VER | |
| 115 | #define zig_packed(definition) __pragma(pack(1)) definition __pragma(pack()) | |
| 116 | #else | |
| 117 | #define zig_packed(definition) zig_packed_unavailable | |
| 118 | #endif | |
| 119 | ||
| 120 | #if zig_has_attribute(section) | |
| 121 | #define zig_linksection(name, def, ...) def __attribute__((section(name))) | |
| 122 | #elif _MSC_VER | |
| 123 | #define zig_linksection(name, def, ...) __pragma(section(name, __VA_ARGS__)) __declspec(allocate(name)) def | |
| 124 | #else | |
| 125 | #define zig_linksection(name, def, ...) zig_linksection_unavailable | |
| 126 | #endif | |
| 127 | ||
| 104 | 128 | #if zig_has_builtin(unreachable) || defined(zig_gnuc) |
| 105 | 129 | #define zig_unreachable() __builtin_unreachable() |
| 106 | 130 | #else |
src/codegen/c.zig+39-15| ... | ... | @@ -1663,6 +1663,22 @@ pub const DeclGen = struct { |
| 1663 | 1663 | defer buffer.deinit(); |
| 1664 | 1664 | |
| 1665 | 1665 | try buffer.appendSlice("struct "); |
| 1666 | ||
| 1667 | var needs_pack_attr = false; | |
| 1668 | { | |
| 1669 | var it = t.structFields().iterator(); | |
| 1670 | while (it.next()) |field| { | |
| 1671 | const field_ty = field.value_ptr.ty; | |
| 1672 | if (!field_ty.hasRuntimeBits()) continue; | |
| 1673 | const alignment = field.value_ptr.abi_align; | |
| 1674 | if (alignment != 0 and alignment < field_ty.abiAlignment(dg.module.getTarget())) { | |
| 1675 | needs_pack_attr = true; | |
| 1676 | try buffer.appendSlice("zig_packed("); | |
| 1677 | break; | |
| 1678 | } | |
| 1679 | } | |
| 1680 | } | |
| 1681 | ||
| 1666 | 1682 | try buffer.appendSlice(name); |
| 1667 | 1683 | try buffer.appendSlice(" {\n"); |
| 1668 | 1684 | { |
| ... | ... | @@ -1672,7 +1688,7 @@ pub const DeclGen = struct { |
| 1672 | 1688 | const field_ty = field.value_ptr.ty; |
| 1673 | 1689 | if (!field_ty.hasRuntimeBits()) continue; |
| 1674 | 1690 | |
| 1675 | const alignment = field.value_ptr.abi_align; | |
| 1691 | const alignment = field.value_ptr.alignment(dg.module.getTarget(), t.containerLayout()); | |
| 1676 | 1692 | const field_name = CValue{ .identifier = field.key_ptr.* }; |
| 1677 | 1693 | try buffer.append(' '); |
| 1678 | 1694 | try dg.renderTypeAndName(buffer.writer(), field_ty, field_name, .Mut, alignment, .Complete); |
| ... | ... | @@ -1682,7 +1698,7 @@ pub const DeclGen = struct { |
| 1682 | 1698 | } |
| 1683 | 1699 | if (empty) try buffer.appendSlice(" char empty_struct;\n"); |
| 1684 | 1700 | } |
| 1685 | try buffer.appendSlice("};\n"); | |
| 1701 | if (needs_pack_attr) try buffer.appendSlice("});\n") else try buffer.appendSlice("};\n"); | |
| 1686 | 1702 | |
| 1687 | 1703 | const rendered = try buffer.toOwnedSlice(); |
| 1688 | 1704 | errdefer dg.typedefs.allocator.free(rendered); |
| ... | ... | @@ -2367,8 +2383,13 @@ pub const DeclGen = struct { |
| 2367 | 2383 | depth += 1; |
| 2368 | 2384 | } |
| 2369 | 2385 | |
| 2370 | if (alignment != 0 and alignment > ty.abiAlignment(target)) { | |
| 2371 | try w.print("zig_align({}) ", .{alignment}); | |
| 2386 | if (alignment != 0) { | |
| 2387 | const abi_alignment = ty.abiAlignment(target); | |
| 2388 | if (alignment < abi_alignment) { | |
| 2389 | try w.print("zig_under_align({}) ", .{alignment}); | |
| 2390 | } else if (alignment > abi_alignment) { | |
| 2391 | try w.print("zig_align({}) ", .{alignment}); | |
| 2392 | } | |
| 2372 | 2393 | } |
| 2373 | 2394 | try dg.renderType(w, render_ty, kind); |
| 2374 | 2395 | |
| ... | ... | @@ -2860,27 +2881,30 @@ pub fn genDecl(o: *Object) !void { |
| 2860 | 2881 | const w = o.writer(); |
| 2861 | 2882 | if (!is_global) try w.writeAll("static "); |
| 2862 | 2883 | if (variable.is_threadlocal) try w.writeAll("zig_threadlocal "); |
| 2884 | if (o.dg.decl.@"linksection") |section| try w.print("zig_linksection(\"{s}\", ", .{section}); | |
| 2863 | 2885 | try o.dg.renderTypeAndName(w, o.dg.decl.ty, decl_c_value, .Mut, o.dg.decl.@"align", .Complete); |
| 2886 | if (o.dg.decl.@"linksection" != null) try w.writeAll(", read, write)"); | |
| 2864 | 2887 | try w.writeAll(" = "); |
| 2865 | 2888 | try o.dg.renderValue(w, tv.ty, variable.init, .StaticInitializer); |
| 2866 | 2889 | try w.writeByte(';'); |
| 2867 | 2890 | try o.indent_writer.insertNewline(); |
| 2868 | 2891 | } else { |
| 2892 | const is_global = o.dg.module.decl_exports.contains(o.dg.decl_index); | |
| 2893 | const fwd_decl_writer = o.dg.fwd_decl.writer(); | |
| 2869 | 2894 | const decl_c_value: CValue = .{ .decl = o.dg.decl_index }; |
| 2870 | 2895 | |
| 2871 | const fwd_decl_writer = o.dg.fwd_decl.writer(); | |
| 2872 | try fwd_decl_writer.writeAll("static "); | |
| 2873 | try o.dg.renderTypeAndName(fwd_decl_writer, tv.ty, decl_c_value, .Mut, o.dg.decl.@"align", .Complete); | |
| 2896 | try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static "); | |
| 2897 | try o.dg.renderTypeAndName(fwd_decl_writer, tv.ty, decl_c_value, .Const, o.dg.decl.@"align", .Complete); | |
| 2874 | 2898 | try fwd_decl_writer.writeAll(";\n"); |
| 2875 | 2899 | |
| 2876 | const writer = o.writer(); | |
| 2877 | try writer.writeAll("static "); | |
| 2878 | // TODO ask the Decl if it is const | |
| 2879 | // https://github.com/ziglang/zig/issues/7582 | |
| 2880 | try o.dg.renderTypeAndName(writer, tv.ty, decl_c_value, .Mut, o.dg.decl.@"align", .Complete); | |
| 2881 | try writer.writeAll(" = "); | |
| 2882 | try o.dg.renderValue(writer, tv.ty, tv.val, .StaticInitializer); | |
| 2883 | try writer.writeAll(";\n"); | |
| 2900 | const w = o.writer(); | |
| 2901 | if (!is_global) try w.writeAll("static "); | |
| 2902 | if (o.dg.decl.@"linksection") |section| try w.print("zig_linksection(\"{s}\", ", .{section}); | |
| 2903 | try o.dg.renderTypeAndName(w, tv.ty, decl_c_value, .Const, o.dg.decl.@"align", .Complete); | |
| 2904 | if (o.dg.decl.@"linksection" != null) try w.writeAll(", read)"); | |
| 2905 | try w.writeAll(" = "); | |
| 2906 | try o.dg.renderValue(w, tv.ty, tv.val, .StaticInitializer); | |
| 2907 | try w.writeAll(";\n"); | |
| 2884 | 2908 | } |
| 2885 | 2909 | } |
| 2886 | 2910 |
stage1/zig1.wasm| Binary files a/stage1/zig1.wasm and b/stage1/zig1.wasm differ |
test/behavior/math.zig-3| ... | ... | @@ -1332,7 +1332,6 @@ test "float remainder division using @rem" { |
| 1332 | 1332 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1333 | 1333 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1334 | 1334 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1335 | if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/12602 | |
| 1336 | 1335 | |
| 1337 | 1336 | comptime try frem(f16); |
| 1338 | 1337 | comptime try frem(f32); |
| ... | ... | @@ -1375,7 +1374,6 @@ test "float modulo division using @mod" { |
| 1375 | 1374 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1376 | 1375 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1377 | 1376 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1378 | if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/12602 | |
| 1379 | 1377 | |
| 1380 | 1378 | comptime try fmod(f16); |
| 1381 | 1379 | comptime try fmod(f32); |
| ... | ... | @@ -1438,7 +1436,6 @@ test "@round f80" { |
| 1438 | 1436 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1439 | 1437 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1440 | 1438 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1441 | if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/12602 | |
| 1442 | 1439 | |
| 1443 | 1440 | try testRound(f80, 12.0); |
| 1444 | 1441 | comptime try testRound(f80, 12.0); |
test/behavior/muladd.zig-2| ... | ... | @@ -50,7 +50,6 @@ test "@mulAdd f80" { |
| 50 | 50 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 51 | 51 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 52 | 52 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 53 | if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/12602 | |
| 54 | 53 | |
| 55 | 54 | comptime try testMulAdd80(); |
| 56 | 55 | try testMulAdd80(); |
| ... | ... | @@ -178,7 +177,6 @@ test "vector f80" { |
| 178 | 177 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 179 | 178 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 180 | 179 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 181 | if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/12602 | |
| 182 | 180 | |
| 183 | 181 | comptime try vector80(); |
| 184 | 182 | try vector80(); |
test/behavior/threadlocal.zig+12-6| ... | ... | @@ -7,8 +7,10 @@ test "thread local variable" { |
| 7 | 7 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 8 | 8 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 9 | 9 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 10 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch != .x86_64) return error.SkipZigTest; // TODO | |
| 11 | if (builtin.zig_backend == .stage2_c and builtin.os.tag == .windows) return error.SkipZigTest; // TODO | |
| 10 | if (builtin.zig_backend == .stage2_llvm) switch (builtin.cpu.arch) { | |
| 11 | .x86_64, .x86 => {}, | |
| 12 | else => return error.SkipZigTest, | |
| 13 | }; // TODO | |
| 12 | 14 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 13 | 15 | |
| 14 | 16 | const S = struct { |
| ... | ... | @@ -23,8 +25,10 @@ test "pointer to thread local array" { |
| 23 | 25 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 24 | 26 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 25 | 27 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 26 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch != .x86_64) return error.SkipZigTest; // TODO | |
| 27 | if (builtin.zig_backend == .stage2_c and builtin.os.tag == .windows) return error.SkipZigTest; // TODO | |
| 28 | if (builtin.zig_backend == .stage2_llvm) switch (builtin.cpu.arch) { | |
| 29 | .x86_64, .x86 => {}, | |
| 30 | else => return error.SkipZigTest, | |
| 31 | }; // TODO | |
| 28 | 32 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 29 | 33 | |
| 30 | 34 | const s = "Hello world"; |
| ... | ... | @@ -39,8 +43,10 @@ test "reference a global threadlocal variable" { |
| 39 | 43 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 40 | 44 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 41 | 45 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 42 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch != .x86_64) return error.SkipZigTest; // TODO | |
| 43 | if (builtin.zig_backend == .stage2_c and builtin.os.tag == .windows) return error.SkipZigTest; // TODO | |
| 46 | if (builtin.zig_backend == .stage2_llvm) switch (builtin.cpu.arch) { | |
| 47 | .x86_64, .x86 => {}, | |
| 48 | else => return error.SkipZigTest, | |
| 49 | }; // TODO | |
| 44 | 50 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 45 | 51 | |
| 46 | 52 | _ = nrfx_uart_rx(&g_uart0); |