| author | |
| committer | |
| log | cc394431ae6eb69e7abd677c268a8ab7299f8aeb |
| tree | d5aa705cdc7d701b53f32a8c2acc099c2dbd90c5 |
| parent | 10ea7accf76d4ad59222ea5ff3585d6cc7cfe3b0 |
| parent | ed00afbc4c1eec6d599ac277e364b4a1ed11fe5c |
| signature |
elf: allocated PHDR table always immediately succeeding the EHDR40 files changed, 686 insertions(+), 502 deletions(-)
lib/compiler_rt/int.zig-2| ... | @@ -42,8 +42,6 @@ pub fn __divmodti4(a: i128, b: i128, rem: *i128) callconv(.C) i128 { | ... | @@ -42,8 +42,6 @@ pub fn __divmodti4(a: i128, b: i128, rem: *i128) callconv(.C) i128 { |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | test "test_divmodti4" { | 44 | test "test_divmodti4" { |
| 45 | if (@import("builtin").zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 46 | |||
| 47 | const cases = [_][4]i128{ | 45 | const cases = [_][4]i128{ |
| 48 | [_]i128{ 0, 1, 0, 0 }, | 46 | [_]i128{ 0, 1, 0, 0 }, |
| 49 | [_]i128{ 0, -1, 0, 0 }, | 47 | [_]i128{ 0, -1, 0, 0 }, |
lib/std/Thread/Condition.zig+2| ... | @@ -371,6 +371,8 @@ test "Condition - signal" { | ... | @@ -371,6 +371,8 @@ test "Condition - signal" { |
| 371 | return error.SkipZigTest; | 371 | return error.SkipZigTest; |
| 372 | } | 372 | } |
| 373 | 373 | ||
| 374 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 375 | |||
| 374 | const num_threads = 4; | 376 | const num_threads = 4; |
| 375 | 377 | ||
| 376 | const SignalTest = struct { | 378 | const SignalTest = struct { |
lib/std/Uri.zig-2| ... | @@ -735,8 +735,6 @@ test "Special test" { | ... | @@ -735,8 +735,6 @@ test "Special test" { |
| 735 | } | 735 | } |
| 736 | 736 | ||
| 737 | test "URI escaping" { | 737 | test "URI escaping" { |
| 738 | if (@import("builtin").zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 739 | |||
| 740 | const input = "\\ö/ äöß ~~.adas-https://canvas:123/#ads&&sad"; | 738 | const input = "\\ö/ äöß ~~.adas-https://canvas:123/#ads&&sad"; |
| 741 | const expected = "%5C%C3%B6%2F%20%C3%A4%C3%B6%C3%9F%20~~.adas-https%3A%2F%2Fcanvas%3A123%2F%23ads%26%26sad"; | 739 | const expected = "%5C%C3%B6%2F%20%C3%A4%C3%B6%C3%9F%20~~.adas-https%3A%2F%2Fcanvas%3A123%2F%23ads%26%26sad"; |
| 742 | 740 |
lib/std/builtin.zig+8-1| ... | @@ -738,8 +738,8 @@ pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace, ret_addr | ... | @@ -738,8 +738,8 @@ pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace, ret_addr |
| 738 | if (builtin.zig_backend == .stage2_wasm or | 738 | if (builtin.zig_backend == .stage2_wasm or |
| 739 | builtin.zig_backend == .stage2_arm or | 739 | builtin.zig_backend == .stage2_arm or |
| 740 | builtin.zig_backend == .stage2_aarch64 or | 740 | builtin.zig_backend == .stage2_aarch64 or |
| 741 | builtin.zig_backend == .stage2_x86_64 or | ||
| 742 | builtin.zig_backend == .stage2_x86 or | 741 | builtin.zig_backend == .stage2_x86 or |
| 742 | (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) or | ||
| 743 | builtin.zig_backend == .stage2_riscv64 or | 743 | builtin.zig_backend == .stage2_riscv64 or |
| 744 | builtin.zig_backend == .stage2_sparc64 or | 744 | builtin.zig_backend == .stage2_sparc64 or |
| 745 | builtin.zig_backend == .stage2_spirv64) | 745 | builtin.zig_backend == .stage2_spirv64) |
| ... | @@ -808,6 +808,13 @@ pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace, ret_addr | ... | @@ -808,6 +808,13 @@ pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace, ret_addr |
| 808 | std.os.abort(); | 808 | std.os.abort(); |
| 809 | }, | 809 | }, |
| 810 | .cuda, .amdhsa => std.os.abort(), | 810 | .cuda, .amdhsa => std.os.abort(), |
| 811 | .plan9 => { | ||
| 812 | var status: [std.os.plan9.ERRMAX]u8 = undefined; | ||
| 813 | const len = @min(msg.len, status.len - 1); | ||
| 814 | @memcpy(status[0..len], msg[0..len]); | ||
| 815 | status[len] = 0; | ||
| 816 | std.os.plan9.exits(status[0..len :0]); | ||
| 817 | }, | ||
| 811 | else => { | 818 | else => { |
| 812 | const first_trace_addr = ret_addr orelse @returnAddress(); | 819 | const first_trace_addr = ret_addr orelse @returnAddress(); |
| 813 | std.debug.panicImpl(error_return_trace, first_trace_addr, msg); | 820 | std.debug.panicImpl(error_return_trace, first_trace_addr, msg); |
lib/std/compress/lzma/test.zig-6| ... | @@ -23,8 +23,6 @@ fn testDecompressError(expected: anyerror, compressed: []const u8) !void { | ... | @@ -23,8 +23,6 @@ fn testDecompressError(expected: anyerror, compressed: []const u8) !void { |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | test "LZMA: decompress empty world" { | 25 | test "LZMA: decompress empty world" { |
| 26 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 27 | |||
| 28 | try testDecompressEqual( | 26 | try testDecompressEqual( |
| 29 | "", | 27 | "", |
| 30 | &[_]u8{ | 28 | &[_]u8{ |
| ... | @@ -88,8 +86,6 @@ test "LZMA: known size with end of payload marker" { | ... | @@ -88,8 +86,6 @@ test "LZMA: known size with end of payload marker" { |
| 88 | } | 86 | } |
| 89 | 87 | ||
| 90 | test "LZMA: too big uncompressed size in header" { | 88 | test "LZMA: too big uncompressed size in header" { |
| 91 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 92 | |||
| 93 | try testDecompressError( | 89 | try testDecompressError( |
| 94 | error.CorruptInput, | 90 | error.CorruptInput, |
| 95 | @embedFile("testdata/bad-too_big_size-with_eopm.lzma"), | 91 | @embedFile("testdata/bad-too_big_size-with_eopm.lzma"), |
| ... | @@ -97,8 +93,6 @@ test "LZMA: too big uncompressed size in header" { | ... | @@ -97,8 +93,6 @@ test "LZMA: too big uncompressed size in header" { |
| 97 | } | 93 | } |
| 98 | 94 | ||
| 99 | test "LZMA: too small uncompressed size in header" { | 95 | test "LZMA: too small uncompressed size in header" { |
| 100 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 101 | |||
| 102 | try testDecompressError( | 96 | try testDecompressError( |
| 103 | error.CorruptInput, | 97 | error.CorruptInput, |
| 104 | @embedFile("testdata/bad-too_small_size-without_eopm-3.lzma"), | 98 | @embedFile("testdata/bad-too_small_size-without_eopm-3.lzma"), |
lib/std/crypto/25519/curve25519.zig-5| ... | @@ -1,5 +1,4 @@ | ... | @@ -1,5 +1,4 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const builtin = @import("builtin"); | ||
| 3 | const crypto = std.crypto; | 2 | const crypto = std.crypto; |
| 4 | 3 | ||
| 5 | const IdentityElementError = crypto.errors.IdentityElementError; | 4 | const IdentityElementError = crypto.errors.IdentityElementError; |
| ... | @@ -112,8 +111,6 @@ pub const Curve25519 = struct { | ... | @@ -112,8 +111,6 @@ pub const Curve25519 = struct { |
| 112 | }; | 111 | }; |
| 113 | 112 | ||
| 114 | test "curve25519" { | 113 | test "curve25519" { |
| 115 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 116 | |||
| 117 | var s = [32]u8{ 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8 }; | 114 | var s = [32]u8{ 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8 }; |
| 118 | const p = try Curve25519.basePoint.clampedMul(s); | 115 | const p = try Curve25519.basePoint.clampedMul(s); |
| 119 | try p.rejectIdentity(); | 116 | try p.rejectIdentity(); |
| ... | @@ -128,8 +125,6 @@ test "curve25519" { | ... | @@ -128,8 +125,6 @@ test "curve25519" { |
| 128 | } | 125 | } |
| 129 | 126 | ||
| 130 | test "curve25519 small order check" { | 127 | test "curve25519 small order check" { |
| 131 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 132 | |||
| 133 | var s: [32]u8 = [_]u8{1} ++ [_]u8{0} ** 31; | 128 | var s: [32]u8 = [_]u8{1} ++ [_]u8{0} ** 31; |
| 134 | const small_order_ss: [7][32]u8 = .{ | 129 | const small_order_ss: [7][32]u8 = .{ |
| 135 | .{ | 130 | .{ |
lib/std/crypto/25519/ed25519.zig-2| ... | @@ -484,8 +484,6 @@ pub const Ed25519 = struct { | ... | @@ -484,8 +484,6 @@ pub const Ed25519 = struct { |
| 484 | }; | 484 | }; |
| 485 | 485 | ||
| 486 | test "ed25519 key pair creation" { | 486 | test "ed25519 key pair creation" { |
| 487 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 488 | |||
| 489 | var seed: [32]u8 = undefined; | 487 | var seed: [32]u8 = undefined; |
| 490 | _ = try fmt.hexToBytes(seed[0..], "8052030376d47112be7f73ed7a019293dd12ad910b654455798b4667d73de166"); | 488 | _ = try fmt.hexToBytes(seed[0..], "8052030376d47112be7f73ed7a019293dd12ad910b654455798b4667d73de166"); |
| 491 | const key_pair = try Ed25519.KeyPair.create(seed); | 489 | const key_pair = try Ed25519.KeyPair.create(seed); |
lib/std/crypto/25519/edwards25519.zig-11| ... | @@ -1,5 +1,4 @@ | ... | @@ -1,5 +1,4 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const builtin = @import("builtin"); | ||
| 3 | const crypto = std.crypto; | 2 | const crypto = std.crypto; |
| 4 | const debug = std.debug; | 3 | const debug = std.debug; |
| 5 | const fmt = std.fmt; | 4 | const fmt = std.fmt; |
| ... | @@ -495,8 +494,6 @@ pub const Edwards25519 = struct { | ... | @@ -495,8 +494,6 @@ pub const Edwards25519 = struct { |
| 495 | const htest = @import("../test.zig"); | 494 | const htest = @import("../test.zig"); |
| 496 | 495 | ||
| 497 | test "edwards25519 packing/unpacking" { | 496 | test "edwards25519 packing/unpacking" { |
| 498 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 499 | |||
| 500 | const s = [_]u8{170} ++ [_]u8{0} ** 31; | 497 | const s = [_]u8{170} ++ [_]u8{0} ** 31; |
| 501 | var b = Edwards25519.basePoint; | 498 | var b = Edwards25519.basePoint; |
| 502 | const pk = try b.mul(s); | 499 | const pk = try b.mul(s); |
| ... | @@ -533,8 +530,6 @@ test "edwards25519 packing/unpacking" { | ... | @@ -533,8 +530,6 @@ test "edwards25519 packing/unpacking" { |
| 533 | } | 530 | } |
| 534 | 531 | ||
| 535 | test "edwards25519 point addition/subtraction" { | 532 | test "edwards25519 point addition/subtraction" { |
| 536 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 537 | |||
| 538 | var s1: [32]u8 = undefined; | 533 | var s1: [32]u8 = undefined; |
| 539 | var s2: [32]u8 = undefined; | 534 | var s2: [32]u8 = undefined; |
| 540 | crypto.random.bytes(&s1); | 535 | crypto.random.bytes(&s1); |
| ... | @@ -549,8 +544,6 @@ test "edwards25519 point addition/subtraction" { | ... | @@ -549,8 +544,6 @@ test "edwards25519 point addition/subtraction" { |
| 549 | } | 544 | } |
| 550 | 545 | ||
| 551 | test "edwards25519 uniform-to-point" { | 546 | test "edwards25519 uniform-to-point" { |
| 552 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 553 | |||
| 554 | var r = [32]u8{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 }; | 547 | var r = [32]u8{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 }; |
| 555 | var p = Edwards25519.fromUniform(r); | 548 | var p = Edwards25519.fromUniform(r); |
| 556 | try htest.assertEqual("0691eee3cf70a0056df6bfa03120635636581b5c4ea571dfc680f78c7e0b4137", p.toBytes()[0..]); | 549 | try htest.assertEqual("0691eee3cf70a0056df6bfa03120635636581b5c4ea571dfc680f78c7e0b4137", p.toBytes()[0..]); |
| ... | @@ -562,8 +555,6 @@ test "edwards25519 uniform-to-point" { | ... | @@ -562,8 +555,6 @@ test "edwards25519 uniform-to-point" { |
| 562 | 555 | ||
| 563 | // Test vectors from draft-irtf-cfrg-hash-to-curve-12 | 556 | // Test vectors from draft-irtf-cfrg-hash-to-curve-12 |
| 564 | test "edwards25519 hash-to-curve operation" { | 557 | test "edwards25519 hash-to-curve operation" { |
| 565 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 566 | |||
| 567 | var p = Edwards25519.fromString(true, "QUUX-V01-CS02-with-edwards25519_XMD:SHA-512_ELL2_RO_", "abc"); | 558 | var p = Edwards25519.fromString(true, "QUUX-V01-CS02-with-edwards25519_XMD:SHA-512_ELL2_RO_", "abc"); |
| 568 | try htest.assertEqual("31558a26887f23fb8218f143e69d5f0af2e7831130bd5b432ef23883b895839a", p.toBytes()[0..]); | 559 | try htest.assertEqual("31558a26887f23fb8218f143e69d5f0af2e7831130bd5b432ef23883b895839a", p.toBytes()[0..]); |
| 569 | 560 | ||
| ... | @@ -572,8 +563,6 @@ test "edwards25519 hash-to-curve operation" { | ... | @@ -572,8 +563,6 @@ test "edwards25519 hash-to-curve operation" { |
| 572 | } | 563 | } |
| 573 | 564 | ||
| 574 | test "edwards25519 implicit reduction of invalid scalars" { | 565 | test "edwards25519 implicit reduction of invalid scalars" { |
| 575 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 576 | |||
| 577 | const s = [_]u8{0} ** 31 ++ [_]u8{255}; | 566 | const s = [_]u8{0} ** 31 ++ [_]u8{255}; |
| 578 | const p1 = try Edwards25519.basePoint.mulPublic(s); | 567 | const p1 = try Edwards25519.basePoint.mulPublic(s); |
| 579 | const p2 = try Edwards25519.basePoint.mul(s); | 568 | const p2 = try Edwards25519.basePoint.mul(s); |
lib/std/crypto/25519/ristretto255.zig-2| ... | @@ -168,8 +168,6 @@ pub const Ristretto255 = struct { | ... | @@ -168,8 +168,6 @@ pub const Ristretto255 = struct { |
| 168 | }; | 168 | }; |
| 169 | 169 | ||
| 170 | test "ristretto255" { | 170 | test "ristretto255" { |
| 171 | if (@import("builtin").zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 172 | |||
| 173 | const p = Ristretto255.basePoint; | 171 | const p = Ristretto255.basePoint; |
| 174 | var buf: [256]u8 = undefined; | 172 | var buf: [256]u8 = undefined; |
| 175 | try std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{s}", .{std.fmt.fmtSliceHexUpper(&p.toBytes())}), "E2F2AE0A6ABC4E71A884A961C500515F58E30B6AA582DD8DB6A65945E08D2D76"); | 173 | try std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{s}", .{std.fmt.fmtSliceHexUpper(&p.toBytes())}), "E2F2AE0A6ABC4E71A884A961C500515F58E30B6AA582DD8DB6A65945E08D2D76"); |
lib/std/crypto/25519/x25519.zig-11| ... | @@ -1,5 +1,4 @@ | ... | @@ -1,5 +1,4 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const builtin = @import("builtin"); | ||
| 3 | const crypto = std.crypto; | 2 | const crypto = std.crypto; |
| 4 | const mem = std.mem; | 3 | const mem = std.mem; |
| 5 | const fmt = std.fmt; | 4 | const fmt = std.fmt; |
| ... | @@ -83,8 +82,6 @@ pub const X25519 = struct { | ... | @@ -83,8 +82,6 @@ pub const X25519 = struct { |
| 83 | const htest = @import("../test.zig"); | 82 | const htest = @import("../test.zig"); |
| 84 | 83 | ||
| 85 | test "x25519 public key calculation from secret key" { | 84 | test "x25519 public key calculation from secret key" { |
| 86 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 87 | |||
| 88 | var sk: [32]u8 = undefined; | 85 | var sk: [32]u8 = undefined; |
| 89 | var pk_expected: [32]u8 = undefined; | 86 | var pk_expected: [32]u8 = undefined; |
| 90 | _ = try fmt.hexToBytes(sk[0..], "8052030376d47112be7f73ed7a019293dd12ad910b654455798b4667d73de166"); | 87 | _ = try fmt.hexToBytes(sk[0..], "8052030376d47112be7f73ed7a019293dd12ad910b654455798b4667d73de166"); |
| ... | @@ -94,8 +91,6 @@ test "x25519 public key calculation from secret key" { | ... | @@ -94,8 +91,6 @@ test "x25519 public key calculation from secret key" { |
| 94 | } | 91 | } |
| 95 | 92 | ||
| 96 | test "x25519 rfc7748 vector1" { | 93 | test "x25519 rfc7748 vector1" { |
| 97 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 98 | |||
| 99 | const secret_key = [32]u8{ 0xa5, 0x46, 0xe3, 0x6b, 0xf0, 0x52, 0x7c, 0x9d, 0x3b, 0x16, 0x15, 0x4b, 0x82, 0x46, 0x5e, 0xdd, 0x62, 0x14, 0x4c, 0x0a, 0xc1, 0xfc, 0x5a, 0x18, 0x50, 0x6a, 0x22, 0x44, 0xba, 0x44, 0x9a, 0xc4 }; | 94 | const secret_key = [32]u8{ 0xa5, 0x46, 0xe3, 0x6b, 0xf0, 0x52, 0x7c, 0x9d, 0x3b, 0x16, 0x15, 0x4b, 0x82, 0x46, 0x5e, 0xdd, 0x62, 0x14, 0x4c, 0x0a, 0xc1, 0xfc, 0x5a, 0x18, 0x50, 0x6a, 0x22, 0x44, 0xba, 0x44, 0x9a, 0xc4 }; |
| 100 | const public_key = [32]u8{ 0xe6, 0xdb, 0x68, 0x67, 0x58, 0x30, 0x30, 0xdb, 0x35, 0x94, 0xc1, 0xa4, 0x24, 0xb1, 0x5f, 0x7c, 0x72, 0x66, 0x24, 0xec, 0x26, 0xb3, 0x35, 0x3b, 0x10, 0xa9, 0x03, 0xa6, 0xd0, 0xab, 0x1c, 0x4c }; | 95 | const public_key = [32]u8{ 0xe6, 0xdb, 0x68, 0x67, 0x58, 0x30, 0x30, 0xdb, 0x35, 0x94, 0xc1, 0xa4, 0x24, 0xb1, 0x5f, 0x7c, 0x72, 0x66, 0x24, 0xec, 0x26, 0xb3, 0x35, 0x3b, 0x10, 0xa9, 0x03, 0xa6, 0xd0, 0xab, 0x1c, 0x4c }; |
| 101 | 96 | ||
| ... | @@ -106,8 +101,6 @@ test "x25519 rfc7748 vector1" { | ... | @@ -106,8 +101,6 @@ test "x25519 rfc7748 vector1" { |
| 106 | } | 101 | } |
| 107 | 102 | ||
| 108 | test "x25519 rfc7748 vector2" { | 103 | test "x25519 rfc7748 vector2" { |
| 109 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 110 | |||
| 111 | const secret_key = [32]u8{ 0x4b, 0x66, 0xe9, 0xd4, 0xd1, 0xb4, 0x67, 0x3c, 0x5a, 0xd2, 0x26, 0x91, 0x95, 0x7d, 0x6a, 0xf5, 0xc1, 0x1b, 0x64, 0x21, 0xe0, 0xea, 0x01, 0xd4, 0x2c, 0xa4, 0x16, 0x9e, 0x79, 0x18, 0xba, 0x0d }; | 104 | const secret_key = [32]u8{ 0x4b, 0x66, 0xe9, 0xd4, 0xd1, 0xb4, 0x67, 0x3c, 0x5a, 0xd2, 0x26, 0x91, 0x95, 0x7d, 0x6a, 0xf5, 0xc1, 0x1b, 0x64, 0x21, 0xe0, 0xea, 0x01, 0xd4, 0x2c, 0xa4, 0x16, 0x9e, 0x79, 0x18, 0xba, 0x0d }; |
| 112 | const public_key = [32]u8{ 0xe5, 0x21, 0x0f, 0x12, 0x78, 0x68, 0x11, 0xd3, 0xf4, 0xb7, 0x95, 0x9d, 0x05, 0x38, 0xae, 0x2c, 0x31, 0xdb, 0xe7, 0x10, 0x6f, 0xc0, 0x3c, 0x3e, 0xfc, 0x4c, 0xd5, 0x49, 0xc7, 0x15, 0xa4, 0x93 }; | 105 | const public_key = [32]u8{ 0xe5, 0x21, 0x0f, 0x12, 0x78, 0x68, 0x11, 0xd3, 0xf4, 0xb7, 0x95, 0x9d, 0x05, 0x38, 0xae, 0x2c, 0x31, 0xdb, 0xe7, 0x10, 0x6f, 0xc0, 0x3c, 0x3e, 0xfc, 0x4c, 0xd5, 0x49, 0xc7, 0x15, 0xa4, 0x93 }; |
| 113 | 106 | ||
| ... | @@ -118,8 +111,6 @@ test "x25519 rfc7748 vector2" { | ... | @@ -118,8 +111,6 @@ test "x25519 rfc7748 vector2" { |
| 118 | } | 111 | } |
| 119 | 112 | ||
| 120 | test "x25519 rfc7748 one iteration" { | 113 | test "x25519 rfc7748 one iteration" { |
| 121 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 122 | |||
| 123 | const initial_value = [32]u8{ 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | 114 | const initial_value = [32]u8{ 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; |
| 124 | const expected_output = [32]u8{ 0x42, 0x2c, 0x8e, 0x7a, 0x62, 0x27, 0xd7, 0xbc, 0xa1, 0x35, 0x0b, 0x3e, 0x2b, 0xb7, 0x27, 0x9f, 0x78, 0x97, 0xb8, 0x7b, 0xb6, 0x85, 0x4b, 0x78, 0x3c, 0x60, 0xe8, 0x03, 0x11, 0xae, 0x30, 0x79 }; | 115 | const expected_output = [32]u8{ 0x42, 0x2c, 0x8e, 0x7a, 0x62, 0x27, 0xd7, 0xbc, 0xa1, 0x35, 0x0b, 0x3e, 0x2b, 0xb7, 0x27, 0x9f, 0x78, 0x97, 0xb8, 0x7b, 0xb6, 0x85, 0x4b, 0x78, 0x3c, 0x60, 0xe8, 0x03, 0x11, 0xae, 0x30, 0x79 }; |
| 125 | 116 | ||
| ... | @@ -180,8 +171,6 @@ test "x25519 rfc7748 1,000,000 iterations" { | ... | @@ -180,8 +171,6 @@ test "x25519 rfc7748 1,000,000 iterations" { |
| 180 | } | 171 | } |
| 181 | 172 | ||
| 182 | test "edwards25519 -> curve25519 map" { | 173 | test "edwards25519 -> curve25519 map" { |
| 183 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 184 | |||
| 185 | const ed_kp = try crypto.sign.Ed25519.KeyPair.create([_]u8{0x42} ** 32); | 174 | const ed_kp = try crypto.sign.Ed25519.KeyPair.create([_]u8{0x42} ** 32); |
| 186 | const mont_kp = try X25519.KeyPair.fromEd25519(ed_kp); | 175 | const mont_kp = try X25519.KeyPair.fromEd25519(ed_kp); |
| 187 | try htest.assertEqual("90e7595fc89e52fdfddce9c6a43d74dbf6047025ee0462d2d172e8b6a2841d6e", &mont_kp.secret_key); | 176 | try htest.assertEqual("90e7595fc89e52fdfddce9c6a43d74dbf6047025ee0462d2d172e8b6a2841d6e", &mont_kp.secret_key); |
lib/std/crypto/chacha20.zig-10| ... | @@ -821,8 +821,6 @@ test "crypto.chacha20 test vector sunscreen" { | ... | @@ -821,8 +821,6 @@ test "crypto.chacha20 test vector sunscreen" { |
| 821 | 821 | ||
| 822 | // https://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04#section-7 | 822 | // https://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04#section-7 |
| 823 | test "crypto.chacha20 test vector 1" { | 823 | test "crypto.chacha20 test vector 1" { |
| 824 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 825 | |||
| 826 | const expected_result = [_]u8{ | 824 | const expected_result = [_]u8{ |
| 827 | 0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90, | 825 | 0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90, |
| 828 | 0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28, | 826 | 0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28, |
| ... | @@ -857,8 +855,6 @@ test "crypto.chacha20 test vector 1" { | ... | @@ -857,8 +855,6 @@ test "crypto.chacha20 test vector 1" { |
| 857 | } | 855 | } |
| 858 | 856 | ||
| 859 | test "crypto.chacha20 test vector 2" { | 857 | test "crypto.chacha20 test vector 2" { |
| 860 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 861 | |||
| 862 | const expected_result = [_]u8{ | 858 | const expected_result = [_]u8{ |
| 863 | 0x45, 0x40, 0xf0, 0x5a, 0x9f, 0x1f, 0xb2, 0x96, | 859 | 0x45, 0x40, 0xf0, 0x5a, 0x9f, 0x1f, 0xb2, 0x96, |
| 864 | 0xd7, 0x73, 0x6e, 0x7b, 0x20, 0x8e, 0x3c, 0x96, | 860 | 0xd7, 0x73, 0x6e, 0x7b, 0x20, 0x8e, 0x3c, 0x96, |
| ... | @@ -893,8 +889,6 @@ test "crypto.chacha20 test vector 2" { | ... | @@ -893,8 +889,6 @@ test "crypto.chacha20 test vector 2" { |
| 893 | } | 889 | } |
| 894 | 890 | ||
| 895 | test "crypto.chacha20 test vector 3" { | 891 | test "crypto.chacha20 test vector 3" { |
| 896 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 897 | |||
| 898 | const expected_result = [_]u8{ | 892 | const expected_result = [_]u8{ |
| 899 | 0xde, 0x9c, 0xba, 0x7b, 0xf3, 0xd6, 0x9e, 0xf5, | 893 | 0xde, 0x9c, 0xba, 0x7b, 0xf3, 0xd6, 0x9e, 0xf5, |
| 900 | 0xe7, 0x86, 0xdc, 0x63, 0x97, 0x3f, 0x65, 0x3a, | 894 | 0xe7, 0x86, 0xdc, 0x63, 0x97, 0x3f, 0x65, 0x3a, |
| ... | @@ -929,8 +923,6 @@ test "crypto.chacha20 test vector 3" { | ... | @@ -929,8 +923,6 @@ test "crypto.chacha20 test vector 3" { |
| 929 | } | 923 | } |
| 930 | 924 | ||
| 931 | test "crypto.chacha20 test vector 4" { | 925 | test "crypto.chacha20 test vector 4" { |
| 932 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 933 | |||
| 934 | const expected_result = [_]u8{ | 926 | const expected_result = [_]u8{ |
| 935 | 0xef, 0x3f, 0xdf, 0xd6, 0xc6, 0x15, 0x78, 0xfb, | 927 | 0xef, 0x3f, 0xdf, 0xd6, 0xc6, 0x15, 0x78, 0xfb, |
| 936 | 0xf5, 0xcf, 0x35, 0xbd, 0x3d, 0xd3, 0x3b, 0x80, | 928 | 0xf5, 0xcf, 0x35, 0xbd, 0x3d, 0xd3, 0x3b, 0x80, |
| ... | @@ -965,8 +957,6 @@ test "crypto.chacha20 test vector 4" { | ... | @@ -965,8 +957,6 @@ test "crypto.chacha20 test vector 4" { |
| 965 | } | 957 | } |
| 966 | 958 | ||
| 967 | test "crypto.chacha20 test vector 5" { | 959 | test "crypto.chacha20 test vector 5" { |
| 968 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 969 | |||
| 970 | const expected_result = [_]u8{ | 960 | const expected_result = [_]u8{ |
| 971 | 0xf7, 0x98, 0xa1, 0x89, 0xf1, 0x95, 0xe6, 0x69, | 961 | 0xf7, 0x98, 0xa1, 0x89, 0xf1, 0x95, 0xe6, 0x69, |
| 972 | 0x82, 0x10, 0x5f, 0xfb, 0x64, 0x0b, 0xb7, 0x75, | 962 | 0x82, 0x10, 0x5f, 0xfb, 0x64, 0x0b, 0xb7, 0x75, |
lib/std/crypto/salsa20.zig-4| ... | @@ -598,8 +598,6 @@ test "xsalsa20poly1305 secretbox" { | ... | @@ -598,8 +598,6 @@ test "xsalsa20poly1305 secretbox" { |
| 598 | } | 598 | } |
| 599 | 599 | ||
| 600 | test "xsalsa20poly1305 box" { | 600 | test "xsalsa20poly1305 box" { |
| 601 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 602 | |||
| 603 | var msg: [100]u8 = undefined; | 601 | var msg: [100]u8 = undefined; |
| 604 | var msg2: [msg.len]u8 = undefined; | 602 | var msg2: [msg.len]u8 = undefined; |
| 605 | var nonce: [Box.nonce_length]u8 = undefined; | 603 | var nonce: [Box.nonce_length]u8 = undefined; |
| ... | @@ -614,8 +612,6 @@ test "xsalsa20poly1305 box" { | ... | @@ -614,8 +612,6 @@ test "xsalsa20poly1305 box" { |
| 614 | } | 612 | } |
| 615 | 613 | ||
| 616 | test "xsalsa20poly1305 sealedbox" { | 614 | test "xsalsa20poly1305 sealedbox" { |
| 617 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 618 | |||
| 619 | var msg: [100]u8 = undefined; | 615 | var msg: [100]u8 = undefined; |
| 620 | var msg2: [msg.len]u8 = undefined; | 616 | var msg2: [msg.len]u8 = undefined; |
| 621 | var boxed: [msg.len + SealedBox.seal_length]u8 = undefined; | 617 | var boxed: [msg.len + SealedBox.seal_length]u8 = undefined; |
lib/std/debug.zig+1-1| ... | @@ -671,8 +671,8 @@ pub const StackIterator = struct { | ... | @@ -671,8 +671,8 @@ pub const StackIterator = struct { |
| 671 | if (self.unwind_state) |*unwind_state| { | 671 | if (self.unwind_state) |*unwind_state| { |
| 672 | if (!unwind_state.failed) { | 672 | if (!unwind_state.failed) { |
| 673 | if (unwind_state.dwarf_context.pc == 0) return null; | 673 | if (unwind_state.dwarf_context.pc == 0) return null; |
| 674 | defer self.fp = unwind_state.dwarf_context.getFp() catch 0; | ||
| 674 | if (self.next_unwind()) |return_address| { | 675 | if (self.next_unwind()) |return_address| { |
| 675 | self.fp = unwind_state.dwarf_context.getFp() catch 0; | ||
| 676 | return return_address; | 676 | return return_address; |
| 677 | } else |err| { | 677 | } else |err| { |
| 678 | unwind_state.last_error = err; | 678 | unwind_state.last_error = err; |
lib/std/fmt.zig-18| ... | @@ -2129,8 +2129,6 @@ test "int.small" { | ... | @@ -2129,8 +2129,6 @@ test "int.small" { |
| 2129 | } | 2129 | } |
| 2130 | 2130 | ||
| 2131 | test "int.specifier" { | 2131 | test "int.specifier" { |
| 2132 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 2133 | |||
| 2134 | { | 2132 | { |
| 2135 | const value: u8 = 'a'; | 2133 | const value: u8 = 'a'; |
| 2136 | try expectFmt("u8: a\n", "u8: {c}\n", .{value}); | 2134 | try expectFmt("u8: a\n", "u8: {c}\n", .{value}); |
| ... | @@ -2181,8 +2179,6 @@ test "int.padded" { | ... | @@ -2181,8 +2179,6 @@ test "int.padded" { |
| 2181 | } | 2179 | } |
| 2182 | 2180 | ||
| 2183 | test "buffer" { | 2181 | test "buffer" { |
| 2184 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 2185 | |||
| 2186 | { | 2182 | { |
| 2187 | var buf1: [32]u8 = undefined; | 2183 | var buf1: [32]u8 = undefined; |
| 2188 | var fbs = std.io.fixedBufferStream(&buf1); | 2184 | var fbs = std.io.fixedBufferStream(&buf1); |
| ... | @@ -2379,8 +2375,6 @@ test "float.scientific" { | ... | @@ -2379,8 +2375,6 @@ test "float.scientific" { |
| 2379 | } | 2375 | } |
| 2380 | 2376 | ||
| 2381 | test "float.scientific.precision" { | 2377 | test "float.scientific.precision" { |
| 2382 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 2383 | |||
| 2384 | try expectFmt("f64: 1.40971e-42", "f64: {e:.5}", .{@as(f64, 1.409706e-42)}); | 2378 | try expectFmt("f64: 1.40971e-42", "f64: {e:.5}", .{@as(f64, 1.409706e-42)}); |
| 2385 | try expectFmt("f64: 1.00000e-09", "f64: {e:.5}", .{@as(f64, @as(f32, @bitCast(@as(u32, 814313563))))}); | 2379 | try expectFmt("f64: 1.00000e-09", "f64: {e:.5}", .{@as(f64, @as(f32, @bitCast(@as(u32, 814313563))))}); |
| 2386 | try expectFmt("f64: 7.81250e-03", "f64: {e:.5}", .{@as(f64, @as(f32, @bitCast(@as(u32, 1006632960))))}); | 2380 | try expectFmt("f64: 7.81250e-03", "f64: {e:.5}", .{@as(f64, @as(f32, @bitCast(@as(u32, 1006632960))))}); |
| ... | @@ -2457,8 +2451,6 @@ test "float.hexadecimal.precision" { | ... | @@ -2457,8 +2451,6 @@ test "float.hexadecimal.precision" { |
| 2457 | } | 2451 | } |
| 2458 | 2452 | ||
| 2459 | test "float.decimal" { | 2453 | test "float.decimal" { |
| 2460 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 2461 | |||
| 2462 | try expectFmt("f64: 152314000000000000000000000000", "f64: {d}", .{@as(f64, 1.52314e+29)}); | 2454 | try expectFmt("f64: 152314000000000000000000000000", "f64: {d}", .{@as(f64, 1.52314e+29)}); |
| 2463 | try expectFmt("f32: 0", "f32: {d}", .{@as(f32, 0.0)}); | 2455 | try expectFmt("f32: 0", "f32: {d}", .{@as(f32, 0.0)}); |
| 2464 | try expectFmt("f32: 0", "f32: {d:.0}", .{@as(f32, 0.0)}); | 2456 | try expectFmt("f32: 0", "f32: {d:.0}", .{@as(f32, 0.0)}); |
| ... | @@ -2482,8 +2474,6 @@ test "float.decimal" { | ... | @@ -2482,8 +2474,6 @@ test "float.decimal" { |
| 2482 | } | 2474 | } |
| 2483 | 2475 | ||
| 2484 | test "float.libc.sanity" { | 2476 | test "float.libc.sanity" { |
| 2485 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 2486 | |||
| 2487 | try expectFmt("f64: 0.00001", "f64: {d:.5}", .{@as(f64, @as(f32, @bitCast(@as(u32, 916964781))))}); | 2477 | try expectFmt("f64: 0.00001", "f64: {d:.5}", .{@as(f64, @as(f32, @bitCast(@as(u32, 916964781))))}); |
| 2488 | try expectFmt("f64: 0.00001", "f64: {d:.5}", .{@as(f64, @as(f32, @bitCast(@as(u32, 925353389))))}); | 2478 | try expectFmt("f64: 0.00001", "f64: {d:.5}", .{@as(f64, @as(f32, @bitCast(@as(u32, 925353389))))}); |
| 2489 | try expectFmt("f64: 0.10000", "f64: {d:.5}", .{@as(f64, @as(f32, @bitCast(@as(u32, 1036831278))))}); | 2479 | try expectFmt("f64: 0.10000", "f64: {d:.5}", .{@as(f64, @as(f32, @bitCast(@as(u32, 1036831278))))}); |
| ... | @@ -2503,8 +2493,6 @@ test "float.libc.sanity" { | ... | @@ -2503,8 +2493,6 @@ test "float.libc.sanity" { |
| 2503 | } | 2493 | } |
| 2504 | 2494 | ||
| 2505 | test "custom" { | 2495 | test "custom" { |
| 2506 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 2507 | |||
| 2508 | const Vec2 = struct { | 2496 | const Vec2 = struct { |
| 2509 | const SelfType = @This(); | 2497 | const SelfType = @This(); |
| 2510 | x: f32, | 2498 | x: f32, |
| ... | @@ -2683,8 +2671,6 @@ test "formatFloatValue with comptime_float" { | ... | @@ -2683,8 +2671,6 @@ test "formatFloatValue with comptime_float" { |
| 2683 | } | 2671 | } |
| 2684 | 2672 | ||
| 2685 | test "formatType max_depth" { | 2673 | test "formatType max_depth" { |
| 2686 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 2687 | |||
| 2688 | const Vec2 = struct { | 2674 | const Vec2 = struct { |
| 2689 | const SelfType = @This(); | 2675 | const SelfType = @This(); |
| 2690 | x: f32, | 2676 | x: f32, |
| ... | @@ -2759,14 +2745,10 @@ test "positional" { | ... | @@ -2759,14 +2745,10 @@ test "positional" { |
| 2759 | } | 2745 | } |
| 2760 | 2746 | ||
| 2761 | test "positional with specifier" { | 2747 | test "positional with specifier" { |
| 2762 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 2763 | |||
| 2764 | try expectFmt("10.0", "{0d:.1}", .{@as(f64, 9.999)}); | 2748 | try expectFmt("10.0", "{0d:.1}", .{@as(f64, 9.999)}); |
| 2765 | } | 2749 | } |
| 2766 | 2750 | ||
| 2767 | test "positional/alignment/width/precision" { | 2751 | test "positional/alignment/width/precision" { |
| 2768 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 2769 | |||
| 2770 | try expectFmt("10.0", "{0d: >3.1}", .{@as(f64, 9.999)}); | 2752 | try expectFmt("10.0", "{0d: >3.1}", .{@as(f64, 9.999)}); |
| 2771 | } | 2753 | } |
| 2772 | 2754 |
lib/std/fmt/parse_float.zig-4| ... | @@ -84,8 +84,6 @@ test "fmt.parseFloat nan and inf" { | ... | @@ -84,8 +84,6 @@ test "fmt.parseFloat nan and inf" { |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | test "fmt.parseFloat #11169" { | 86 | test "fmt.parseFloat #11169" { |
| 87 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 88 | |||
| 89 | try expectEqual(try parseFloat(f128, "9007199254740993.0"), 9007199254740993.0); | 87 | try expectEqual(try parseFloat(f128, "9007199254740993.0"), 9007199254740993.0); |
| 90 | } | 88 | } |
| 91 | 89 | ||
| ... | @@ -162,8 +160,6 @@ test "fmt.parseFloat hex.f64" { | ... | @@ -162,8 +160,6 @@ test "fmt.parseFloat hex.f64" { |
| 162 | try testing.expectEqual(try parseFloat(f64, "-0x1p-1074"), -math.floatTrueMin(f64)); | 160 | try testing.expectEqual(try parseFloat(f64, "-0x1p-1074"), -math.floatTrueMin(f64)); |
| 163 | } | 161 | } |
| 164 | test "fmt.parseFloat hex.f128" { | 162 | test "fmt.parseFloat hex.f128" { |
| 165 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 166 | |||
| 167 | try testing.expectEqual(try parseFloat(f128, "0x1p0"), 1.0); | 163 | try testing.expectEqual(try parseFloat(f128, "0x1p0"), 1.0); |
| 168 | try testing.expectEqual(try parseFloat(f128, "-0x1p-1"), -0.5); | 164 | try testing.expectEqual(try parseFloat(f128, "-0x1p-1"), -0.5); |
| 169 | try testing.expectEqual(try parseFloat(f128, "0x10p+10"), 16384.0); | 165 | try testing.expectEqual(try parseFloat(f128, "0x10p+10"), 16384.0); |
lib/std/fs/test.zig-4| ... | @@ -1604,8 +1604,6 @@ test "File.Permissions" { | ... | @@ -1604,8 +1604,6 @@ test "File.Permissions" { |
| 1604 | if (builtin.os.tag == .wasi) | 1604 | if (builtin.os.tag == .wasi) |
| 1605 | return error.SkipZigTest; | 1605 | return error.SkipZigTest; |
| 1606 | 1606 | ||
| 1607 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 1608 | |||
| 1609 | var tmp = tmpDir(.{}); | 1607 | var tmp = tmpDir(.{}); |
| 1610 | defer tmp.cleanup(); | 1608 | defer tmp.cleanup(); |
| 1611 | 1609 | ||
| ... | @@ -1632,8 +1630,6 @@ test "File.PermissionsUnix" { | ... | @@ -1632,8 +1630,6 @@ test "File.PermissionsUnix" { |
| 1632 | if (builtin.os.tag == .windows or builtin.os.tag == .wasi) | 1630 | if (builtin.os.tag == .windows or builtin.os.tag == .wasi) |
| 1633 | return error.SkipZigTest; | 1631 | return error.SkipZigTest; |
| 1634 | 1632 | ||
| 1635 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 1636 | |||
| 1637 | var tmp = tmpDir(.{}); | 1633 | var tmp = tmpDir(.{}); |
| 1638 | defer tmp.cleanup(); | 1634 | defer tmp.cleanup(); |
| 1639 | 1635 |
lib/std/json.zig-4| ... | @@ -24,8 +24,6 @@ test Scanner { | ... | @@ -24,8 +24,6 @@ test Scanner { |
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | test parseFromSlice { | 26 | test parseFromSlice { |
| 27 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 28 | |||
| 29 | var parsed_str = try parseFromSlice([]const u8, testing.allocator, "\"a\\u0020b\"", .{}); | 27 | var parsed_str = try parseFromSlice([]const u8, testing.allocator, "\"a\\u0020b\"", .{}); |
| 30 | defer parsed_str.deinit(); | 28 | defer parsed_str.deinit(); |
| 31 | try testing.expectEqualSlices(u8, "a b", parsed_str.value); | 29 | try testing.expectEqualSlices(u8, "a b", parsed_str.value); |
| ... | @@ -44,8 +42,6 @@ test Value { | ... | @@ -44,8 +42,6 @@ test Value { |
| 44 | } | 42 | } |
| 45 | 43 | ||
| 46 | test writeStream { | 44 | test writeStream { |
| 47 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 48 | |||
| 49 | var out = ArrayList(u8).init(testing.allocator); | 45 | var out = ArrayList(u8).init(testing.allocator); |
| 50 | defer out.deinit(); | 46 | defer out.deinit(); |
| 51 | var write_stream = writeStream(out.writer(), .{ .whitespace = .indent_2 }); | 47 | var write_stream = writeStream(out.writer(), .{ .whitespace = .indent_2 }); |
lib/std/json/static_test.zig-40| ... | @@ -372,8 +372,6 @@ test "test all types" { | ... | @@ -372,8 +372,6 @@ test "test all types" { |
| 372 | } | 372 | } |
| 373 | 373 | ||
| 374 | test "parse" { | 374 | test "parse" { |
| 375 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 376 | |||
| 377 | try testing.expectEqual(false, try parseFromSliceLeaky(bool, testing.allocator, "false", .{})); | 375 | try testing.expectEqual(false, try parseFromSliceLeaky(bool, testing.allocator, "false", .{})); |
| 378 | try testing.expectEqual(true, try parseFromSliceLeaky(bool, testing.allocator, "true", .{})); | 376 | try testing.expectEqual(true, try parseFromSliceLeaky(bool, testing.allocator, "true", .{})); |
| 379 | try testing.expectEqual(@as(u1, 1), try parseFromSliceLeaky(u1, testing.allocator, "1", .{})); | 377 | try testing.expectEqual(@as(u1, 1), try parseFromSliceLeaky(u1, testing.allocator, "1", .{})); |
| ... | @@ -405,8 +403,6 @@ test "parse into enum" { | ... | @@ -405,8 +403,6 @@ test "parse into enum" { |
| 405 | } | 403 | } |
| 406 | 404 | ||
| 407 | test "parse into that allocates a slice" { | 405 | test "parse into that allocates a slice" { |
| 408 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 409 | |||
| 410 | { | 406 | { |
| 411 | // string as string | 407 | // string as string |
| 412 | const parsed = try parseFromSlice([]u8, testing.allocator, "\"foo\"", .{}); | 408 | const parsed = try parseFromSlice([]u8, testing.allocator, "\"foo\"", .{}); |
| ... | @@ -427,16 +423,12 @@ test "parse into that allocates a slice" { | ... | @@ -427,16 +423,12 @@ test "parse into that allocates a slice" { |
| 427 | } | 423 | } |
| 428 | 424 | ||
| 429 | test "parse into sentinel slice" { | 425 | test "parse into sentinel slice" { |
| 430 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 431 | |||
| 432 | const parsed = try parseFromSlice([:0]const u8, testing.allocator, "\"\\n\"", .{}); | 426 | const parsed = try parseFromSlice([:0]const u8, testing.allocator, "\"\\n\"", .{}); |
| 433 | defer parsed.deinit(); | 427 | defer parsed.deinit(); |
| 434 | try testing.expect(std.mem.eql(u8, parsed.value, "\n")); | 428 | try testing.expect(std.mem.eql(u8, parsed.value, "\n")); |
| 435 | } | 429 | } |
| 436 | 430 | ||
| 437 | test "parse into tagged union" { | 431 | test "parse into tagged union" { |
| 438 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 439 | |||
| 440 | const T = union(enum) { | 432 | const T = union(enum) { |
| 441 | nothing, | 433 | nothing, |
| 442 | int: i32, | 434 | int: i32, |
| ... | @@ -452,8 +444,6 @@ test "parse into tagged union" { | ... | @@ -452,8 +444,6 @@ test "parse into tagged union" { |
| 452 | } | 444 | } |
| 453 | 445 | ||
| 454 | test "parse into tagged union errors" { | 446 | test "parse into tagged union errors" { |
| 455 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 456 | |||
| 457 | const T = union(enum) { | 447 | const T = union(enum) { |
| 458 | nothing, | 448 | nothing, |
| 459 | int: i32, | 449 | int: i32, |
| ... | @@ -485,8 +475,6 @@ test "parse into struct with no fields" { | ... | @@ -485,8 +475,6 @@ test "parse into struct with no fields" { |
| 485 | const test_const_value: usize = 123; | 475 | const test_const_value: usize = 123; |
| 486 | 476 | ||
| 487 | test "parse into struct with default const pointer field" { | 477 | test "parse into struct with default const pointer field" { |
| 488 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 489 | |||
| 490 | const T = struct { a: *const usize = &test_const_value }; | 478 | const T = struct { a: *const usize = &test_const_value }; |
| 491 | const parsed = try parseFromSlice(T, testing.allocator, "{}", .{}); | 479 | const parsed = try parseFromSlice(T, testing.allocator, "{}", .{}); |
| 492 | defer parsed.deinit(); | 480 | defer parsed.deinit(); |
| ... | @@ -502,8 +490,6 @@ const test_default_str_slice: [2][]const u8 = [_][]const u8{ | ... | @@ -502,8 +490,6 @@ const test_default_str_slice: [2][]const u8 = [_][]const u8{ |
| 502 | }; | 490 | }; |
| 503 | 491 | ||
| 504 | test "freeing parsed structs with pointers to default values" { | 492 | test "freeing parsed structs with pointers to default values" { |
| 505 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 506 | |||
| 507 | const T = struct { | 493 | const T = struct { |
| 508 | int: *const usize = &test_default_usize, | 494 | int: *const usize = &test_default_usize, |
| 509 | int_ptr: *allowzero align(1) const usize = test_default_usize_ptr, | 495 | int_ptr: *allowzero align(1) const usize = test_default_usize_ptr, |
| ... | @@ -517,15 +503,11 @@ test "freeing parsed structs with pointers to default values" { | ... | @@ -517,15 +503,11 @@ test "freeing parsed structs with pointers to default values" { |
| 517 | } | 503 | } |
| 518 | 504 | ||
| 519 | test "parse into struct where destination and source lengths mismatch" { | 505 | test "parse into struct where destination and source lengths mismatch" { |
| 520 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 521 | |||
| 522 | const T = struct { a: [2]u8 }; | 506 | const T = struct { a: [2]u8 }; |
| 523 | try testing.expectError(error.LengthMismatch, parseFromSlice(T, testing.allocator, "{\"a\": \"bbb\"}", .{})); | 507 | try testing.expectError(error.LengthMismatch, parseFromSlice(T, testing.allocator, "{\"a\": \"bbb\"}", .{})); |
| 524 | } | 508 | } |
| 525 | 509 | ||
| 526 | test "parse into struct with misc fields" { | 510 | test "parse into struct with misc fields" { |
| 527 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 528 | |||
| 529 | const T = struct { | 511 | const T = struct { |
| 530 | int: i64, | 512 | int: i64, |
| 531 | float: f64, | 513 | float: f64, |
| ... | @@ -601,8 +583,6 @@ test "parse into struct with misc fields" { | ... | @@ -601,8 +583,6 @@ test "parse into struct with misc fields" { |
| 601 | } | 583 | } |
| 602 | 584 | ||
| 603 | test "parse into struct with strings and arrays with sentinels" { | 585 | test "parse into struct with strings and arrays with sentinels" { |
| 604 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 605 | |||
| 606 | const T = struct { | 586 | const T = struct { |
| 607 | language: [:0]const u8, | 587 | language: [:0]const u8, |
| 608 | language_without_sentinel: []const u8, | 588 | language_without_sentinel: []const u8, |
| ... | @@ -631,8 +611,6 @@ test "parse into struct with strings and arrays with sentinels" { | ... | @@ -631,8 +611,6 @@ test "parse into struct with strings and arrays with sentinels" { |
| 631 | } | 611 | } |
| 632 | 612 | ||
| 633 | test "parse into struct with duplicate field" { | 613 | test "parse into struct with duplicate field" { |
| 634 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 635 | |||
| 636 | const options_first = ParseOptions{ .duplicate_field_behavior = .use_first }; | 614 | const options_first = ParseOptions{ .duplicate_field_behavior = .use_first }; |
| 637 | const options_last = ParseOptions{ .duplicate_field_behavior = .use_last }; | 615 | const options_last = ParseOptions{ .duplicate_field_behavior = .use_last }; |
| 638 | 616 | ||
| ... | @@ -652,8 +630,6 @@ test "parse into struct with duplicate field" { | ... | @@ -652,8 +630,6 @@ test "parse into struct with duplicate field" { |
| 652 | } | 630 | } |
| 653 | 631 | ||
| 654 | test "parse into struct ignoring unknown fields" { | 632 | test "parse into struct ignoring unknown fields" { |
| 655 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 656 | |||
| 657 | const T = struct { | 633 | const T = struct { |
| 658 | int: i64, | 634 | int: i64, |
| 659 | language: []const u8, | 635 | language: []const u8, |
| ... | @@ -692,8 +668,6 @@ test "parse into struct ignoring unknown fields" { | ... | @@ -692,8 +668,6 @@ test "parse into struct ignoring unknown fields" { |
| 692 | } | 668 | } |
| 693 | 669 | ||
| 694 | test "parse into tuple" { | 670 | test "parse into tuple" { |
| 695 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 696 | |||
| 697 | const Union = union(enum) { | 671 | const Union = union(enum) { |
| 698 | char: u8, | 672 | char: u8, |
| 699 | float: f64, | 673 | float: f64, |
| ... | @@ -749,8 +723,6 @@ const ParseIntoRecursiveUnionDefinitionValue = union(enum) { | ... | @@ -749,8 +723,6 @@ const ParseIntoRecursiveUnionDefinitionValue = union(enum) { |
| 749 | }; | 723 | }; |
| 750 | 724 | ||
| 751 | test "parse into recursive union definition" { | 725 | test "parse into recursive union definition" { |
| 752 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 753 | |||
| 754 | const T = struct { | 726 | const T = struct { |
| 755 | values: ParseIntoRecursiveUnionDefinitionValue, | 727 | values: ParseIntoRecursiveUnionDefinitionValue, |
| 756 | }; | 728 | }; |
| ... | @@ -772,8 +744,6 @@ const ParseIntoDoubleRecursiveUnionValueSecond = union(enum) { | ... | @@ -772,8 +744,6 @@ const ParseIntoDoubleRecursiveUnionValueSecond = union(enum) { |
| 772 | }; | 744 | }; |
| 773 | 745 | ||
| 774 | test "parse into double recursive union definition" { | 746 | test "parse into double recursive union definition" { |
| 775 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 776 | |||
| 777 | const T = struct { | 747 | const T = struct { |
| 778 | values: ParseIntoDoubleRecursiveUnionValueFirst, | 748 | values: ParseIntoDoubleRecursiveUnionValueFirst, |
| 779 | }; | 749 | }; |
| ... | @@ -785,8 +755,6 @@ test "parse into double recursive union definition" { | ... | @@ -785,8 +755,6 @@ test "parse into double recursive union definition" { |
| 785 | } | 755 | } |
| 786 | 756 | ||
| 787 | test "parse exponential into int" { | 757 | test "parse exponential into int" { |
| 788 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 789 | |||
| 790 | const T = struct { int: i64 }; | 758 | const T = struct { int: i64 }; |
| 791 | const r = try parseFromSliceLeaky(T, testing.allocator, "{ \"int\": 4.2e2 }", .{}); | 759 | const r = try parseFromSliceLeaky(T, testing.allocator, "{ \"int\": 4.2e2 }", .{}); |
| 792 | try testing.expectEqual(@as(i64, 420), r.int); | 760 | try testing.expectEqual(@as(i64, 420), r.int); |
| ... | @@ -795,8 +763,6 @@ test "parse exponential into int" { | ... | @@ -795,8 +763,6 @@ test "parse exponential into int" { |
| 795 | } | 763 | } |
| 796 | 764 | ||
| 797 | test "parseFromTokenSource" { | 765 | test "parseFromTokenSource" { |
| 798 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 799 | |||
| 800 | { | 766 | { |
| 801 | var scanner = JsonScanner.initCompleteInput(testing.allocator, "123"); | 767 | var scanner = JsonScanner.initCompleteInput(testing.allocator, "123"); |
| 802 | defer scanner.deinit(); | 768 | defer scanner.deinit(); |
| ... | @@ -816,8 +782,6 @@ test "parseFromTokenSource" { | ... | @@ -816,8 +782,6 @@ test "parseFromTokenSource" { |
| 816 | } | 782 | } |
| 817 | 783 | ||
| 818 | test "max_value_len" { | 784 | test "max_value_len" { |
| 819 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 820 | |||
| 821 | try testing.expectError(error.ValueTooLong, parseFromSlice([]u8, testing.allocator, "\"0123456789\"", .{ .max_value_len = 5 })); | 785 | try testing.expectError(error.ValueTooLong, parseFromSlice([]u8, testing.allocator, "\"0123456789\"", .{ .max_value_len = 5 })); |
| 822 | } | 786 | } |
| 823 | 787 | ||
| ... | @@ -856,8 +820,6 @@ fn assertKey( | ... | @@ -856,8 +820,6 @@ fn assertKey( |
| 856 | } | 820 | } |
| 857 | } | 821 | } |
| 858 | test "json parse partial" { | 822 | test "json parse partial" { |
| 859 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 860 | |||
| 861 | const Inner = struct { | 823 | const Inner = struct { |
| 862 | num: u32, | 824 | num: u32, |
| 863 | yes: bool, | 825 | yes: bool, |
| ... | @@ -913,8 +875,6 @@ test "json parse partial" { | ... | @@ -913,8 +875,6 @@ test "json parse partial" { |
| 913 | } | 875 | } |
| 914 | 876 | ||
| 915 | test "json parse allocate when streaming" { | 877 | test "json parse allocate when streaming" { |
| 916 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 917 | |||
| 918 | const T = struct { | 878 | const T = struct { |
| 919 | not_const: []u8, | 879 | not_const: []u8, |
| 920 | is_const: []const u8, | 880 | is_const: []const u8, |
lib/std/json/stringify_test.zig-2| ... | @@ -198,8 +198,6 @@ test "stringify struct" { | ... | @@ -198,8 +198,6 @@ test "stringify struct" { |
| 198 | } | 198 | } |
| 199 | 199 | ||
| 200 | test "emit_strings_as_arrays" { | 200 | test "emit_strings_as_arrays" { |
| 201 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 202 | |||
| 203 | // Should only affect string values, not object keys. | 201 | // Should only affect string values, not object keys. |
| 204 | try testStringify("{\"foo\":\"bar\"}", .{ .foo = "bar" }, .{}); | 202 | try testStringify("{\"foo\":\"bar\"}", .{ .foo = "bar" }, .{}); |
| 205 | try testStringify("{\"foo\":[98,97,114]}", .{ .foo = "bar" }, .{ .emit_strings_as_arrays = true }); | 203 | try testStringify("{\"foo\":[98,97,114]}", .{ .foo = "bar" }, .{ .emit_strings_as_arrays = true }); |
lib/std/mem.zig+2-4| ... | @@ -1756,10 +1756,8 @@ test "comptime read/write int" { | ... | @@ -1756,10 +1756,8 @@ test "comptime read/write int" { |
| 1756 | } | 1756 | } |
| 1757 | 1757 | ||
| 1758 | test "readIntBig and readIntLittle" { | 1758 | test "readIntBig and readIntLittle" { |
| 1759 | switch (builtin.zig_backend) { | 1759 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; |
| 1760 | .stage2_c, .stage2_x86_64 => return error.SkipZigTest, | 1760 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 1761 | else => {}, | ||
| 1762 | } | ||
| 1763 | 1761 | ||
| 1764 | try testing.expect(readIntSliceBig(u0, &[_]u8{}) == 0x0); | 1762 | try testing.expect(readIntSliceBig(u0, &[_]u8{}) == 0x0); |
| 1765 | try testing.expect(readIntSliceLittle(u0, &[_]u8{}) == 0x0); | 1763 | try testing.expect(readIntSliceLittle(u0, &[_]u8{}) == 0x0); |
lib/std/net/test.zig-2| ... | @@ -5,7 +5,6 @@ const mem = std.mem; | ... | @@ -5,7 +5,6 @@ const mem = std.mem; |
| 5 | const testing = std.testing; | 5 | const testing = std.testing; |
| 6 | 6 | ||
| 7 | test "parse and render IPv6 addresses" { | 7 | test "parse and render IPv6 addresses" { |
| 8 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 9 | if (builtin.os.tag == .wasi) return error.SkipZigTest; | 8 | if (builtin.os.tag == .wasi) return error.SkipZigTest; |
| 10 | 9 | ||
| 11 | var buffer: [100]u8 = undefined; | 10 | var buffer: [100]u8 = undefined; |
| ... | @@ -71,7 +70,6 @@ test "invalid but parseable IPv6 scope ids" { | ... | @@ -71,7 +70,6 @@ test "invalid but parseable IPv6 scope ids" { |
| 71 | } | 70 | } |
| 72 | 71 | ||
| 73 | test "parse and render IPv4 addresses" { | 72 | test "parse and render IPv4 addresses" { |
| 74 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 75 | if (builtin.os.tag == .wasi) return error.SkipZigTest; | 73 | if (builtin.os.tag == .wasi) return error.SkipZigTest; |
| 76 | 74 | ||
| 77 | var buffer: [18]u8 = undefined; | 75 | var buffer: [18]u8 = undefined; |
lib/std/os/linux/x86_64.zig+2-2| ... | @@ -431,11 +431,11 @@ fn getContextInternal() callconv(.Naked) usize { | ... | @@ -431,11 +431,11 @@ fn getContextInternal() callconv(.Naked) usize { |
| 431 | \\ leaq %[stack_offset:c](%%rdi), %%rsi | 431 | \\ leaq %[stack_offset:c](%%rdi), %%rsi |
| 432 | \\ movq %%rdi, %%r8 | 432 | \\ movq %%rdi, %%r8 |
| 433 | \\ xorl %%edi, %%edi | 433 | \\ xorl %%edi, %%edi |
| 434 | \\ movq %[sigaltstack], %%rax | 434 | \\ movl %[sigaltstack], %%eax |
| 435 | \\ syscall | 435 | \\ syscall |
| 436 | \\ testq %%rax, %%rax | 436 | \\ testq %%rax, %%rax |
| 437 | \\ jnz 0f | 437 | \\ jnz 0f |
| 438 | \\ movq %[sigprocmask], %%rax | 438 | \\ movl %[sigprocmask], %%eax |
| 439 | \\ xorl %%esi, %%esi | 439 | \\ xorl %%esi, %%esi |
| 440 | \\ leaq %[sigmask_offset:c](%%r8), %%rdx | 440 | \\ leaq %[sigmask_offset:c](%%r8), %%rdx |
| 441 | \\ movl %[sigset_size], %%r10d | 441 | \\ movl %[sigset_size], %%r10d |
lib/std/os/test.zig-4| ... | @@ -509,8 +509,6 @@ fn iter_fn(info: *dl_phdr_info, size: usize, counter: *usize) IterFnError!void { | ... | @@ -509,8 +509,6 @@ fn iter_fn(info: *dl_phdr_info, size: usize, counter: *usize) IterFnError!void { |
| 509 | test "dl_iterate_phdr" { | 509 | test "dl_iterate_phdr" { |
| 510 | if (builtin.object_format != .elf) return error.SkipZigTest; | 510 | if (builtin.object_format != .elf) return error.SkipZigTest; |
| 511 | 511 | ||
| 512 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 513 | |||
| 514 | var counter: usize = 0; | 512 | var counter: usize = 0; |
| 515 | try os.dl_iterate_phdr(&counter, IterFnError, iter_fn); | 513 | try os.dl_iterate_phdr(&counter, IterFnError, iter_fn); |
| 516 | try expect(counter != 0); | 514 | try expect(counter != 0); |
| ... | @@ -804,8 +802,6 @@ test "sigaction" { | ... | @@ -804,8 +802,6 @@ test "sigaction" { |
| 804 | if (native_os == .wasi or native_os == .windows) | 802 | if (native_os == .wasi or native_os == .windows) |
| 805 | return error.SkipZigTest; | 803 | return error.SkipZigTest; |
| 806 | 804 | ||
| 807 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 808 | |||
| 809 | // https://github.com/ziglang/zig/issues/7427 | 805 | // https://github.com/ziglang/zig/issues/7427 |
| 810 | if (native_os == .linux and builtin.target.cpu.arch == .x86) | 806 | if (native_os == .linux and builtin.target.cpu.arch == .x86) |
| 811 | return error.SkipZigTest; | 807 | return error.SkipZigTest; |
lib/std/rand/test.zig-2| ... | @@ -158,8 +158,6 @@ fn testRandomEnumValue() !void { | ... | @@ -158,8 +158,6 @@ fn testRandomEnumValue() !void { |
| 158 | } | 158 | } |
| 159 | 159 | ||
| 160 | test "Random intLessThan" { | 160 | test "Random intLessThan" { |
| 161 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 162 | |||
| 163 | @setEvalBranchQuota(10000); | 161 | @setEvalBranchQuota(10000); |
| 164 | try testRandomIntLessThan(); | 162 | try testRandomIntLessThan(); |
| 165 | try comptime testRandomIntLessThan(); | 163 | try comptime testRandomIntLessThan(); |
lib/std/target.zig+30-6| ... | @@ -733,7 +733,14 @@ pub const Target = struct { | ... | @@ -733,7 +733,14 @@ pub const Target = struct { |
| 733 | 733 | ||
| 734 | /// Adds the specified feature set but not its dependencies. | 734 | /// Adds the specified feature set but not its dependencies. |
| 735 | pub fn addFeatureSet(set: *Set, other_set: Set) void { | 735 | pub fn addFeatureSet(set: *Set, other_set: Set) void { |
| 736 | set.ints = @as(@Vector(usize_count, usize), set.ints) | @as(@Vector(usize_count, usize), other_set.ints); | 736 | switch (builtin.zig_backend) { |
| 737 | .stage2_x86_64 => { | ||
| 738 | for (&set.ints, other_set.ints) |*set_int, other_set_int| set_int.* |= other_set_int; | ||
| 739 | }, | ||
| 740 | else => { | ||
| 741 | set.ints = @as(@Vector(usize_count, usize), set.ints) | @as(@Vector(usize_count, usize), other_set.ints); | ||
| 742 | }, | ||
| 743 | } | ||
| 737 | } | 744 | } |
| 738 | 745 | ||
| 739 | /// Removes the specified feature but not its dependents. | 746 | /// Removes the specified feature but not its dependents. |
| ... | @@ -745,7 +752,14 @@ pub const Target = struct { | ... | @@ -745,7 +752,14 @@ pub const Target = struct { |
| 745 | 752 | ||
| 746 | /// Removes the specified feature but not its dependents. | 753 | /// Removes the specified feature but not its dependents. |
| 747 | pub fn removeFeatureSet(set: *Set, other_set: Set) void { | 754 | pub fn removeFeatureSet(set: *Set, other_set: Set) void { |
| 748 | set.ints = @as(@Vector(usize_count, usize), set.ints) & ~@as(@Vector(usize_count, usize), other_set.ints); | 755 | switch (builtin.zig_backend) { |
| 756 | .stage2_x86_64 => { | ||
| 757 | for (&set.ints, other_set.ints) |*set_int, other_set_int| set_int.* &= ~other_set_int; | ||
| 758 | }, | ||
| 759 | else => { | ||
| 760 | set.ints = @as(@Vector(usize_count, usize), set.ints) & ~@as(@Vector(usize_count, usize), other_set.ints); | ||
| 761 | }, | ||
| 762 | } | ||
| 749 | } | 763 | } |
| 750 | 764 | ||
| 751 | pub fn populateDependencies(set: *Set, all_features_list: []const Cpu.Feature) void { | 765 | pub fn populateDependencies(set: *Set, all_features_list: []const Cpu.Feature) void { |
| ... | @@ -774,10 +788,20 @@ pub const Target = struct { | ... | @@ -774,10 +788,20 @@ pub const Target = struct { |
| 774 | } | 788 | } |
| 775 | 789 | ||
| 776 | pub fn isSuperSetOf(set: Set, other_set: Set) bool { | 790 | pub fn isSuperSetOf(set: Set, other_set: Set) bool { |
| 777 | const V = @Vector(usize_count, usize); | 791 | switch (builtin.zig_backend) { |
| 778 | const set_v: V = set.ints; | 792 | .stage2_x86_64 => { |
| 779 | const other_v: V = other_set.ints; | 793 | var result = true; |
| 780 | return @reduce(.And, (set_v & other_v) == other_v); | 794 | for (&set.ints, other_set.ints) |*set_int, other_set_int| |
| 795 | result = result and (set_int.* & other_set_int) == other_set_int; | ||
| 796 | return result; | ||
| 797 | }, | ||
| 798 | else => { | ||
| 799 | const V = @Vector(usize_count, usize); | ||
| 800 | const set_v: V = set.ints; | ||
| 801 | const other_v: V = other_set.ints; | ||
| 802 | return @reduce(.And, (set_v & other_v) == other_v); | ||
| 803 | }, | ||
| 804 | } | ||
| 781 | } | 805 | } |
| 782 | }; | 806 | }; |
| 783 | 807 |
lib/std/zig/CrossTarget.zig-2| ... | @@ -791,8 +791,6 @@ fn parseOs(result: *CrossTarget, diags: *ParseOptions.Diagnostics, text: []const | ... | @@ -791,8 +791,6 @@ fn parseOs(result: *CrossTarget, diags: *ParseOptions.Diagnostics, text: []const |
| 791 | } | 791 | } |
| 792 | 792 | ||
| 793 | test "CrossTarget.parse" { | 793 | test "CrossTarget.parse" { |
| 794 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 795 | |||
| 796 | if (builtin.target.isGnuLibC()) { | 794 | if (builtin.target.isGnuLibC()) { |
| 797 | var cross_target = try CrossTarget.parse(.{}); | 795 | var cross_target = try CrossTarget.parse(.{}); |
| 798 | cross_target.setGnuLibCVersion(2, 1, 1); | 796 | cross_target.setGnuLibCVersion(2, 1, 1); |
lib/std/zig/fmt.zig-2| ... | @@ -95,8 +95,6 @@ pub fn fmtEscapes(bytes: []const u8) std.fmt.Formatter(stringEscape) { | ... | @@ -95,8 +95,6 @@ pub fn fmtEscapes(bytes: []const u8) std.fmt.Formatter(stringEscape) { |
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | test "escape invalid identifiers" { | 97 | test "escape invalid identifiers" { |
| 98 | if (@import("builtin").zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 99 | |||
| 100 | const expectFmt = std.testing.expectFmt; | 98 | const expectFmt = std.testing.expectFmt; |
| 101 | try expectFmt("@\"while\"", "{}", .{fmtId("while")}); | 99 | try expectFmt("@\"while\"", "{}", .{fmtId("while")}); |
| 102 | try expectFmt("hello", "{}", .{fmtId("hello")}); | 100 | try expectFmt("hello", "{}", .{fmtId("hello")}); |
src/Module.zig+2-1| ... | @@ -5846,7 +5846,8 @@ pub const Feature = enum { | ... | @@ -5846,7 +5846,8 @@ pub const Feature = enum { |
| 5846 | pub fn backendSupportsFeature(mod: Module, feature: Feature) bool { | 5846 | pub fn backendSupportsFeature(mod: Module, feature: Feature) bool { |
| 5847 | return switch (feature) { | 5847 | return switch (feature) { |
| 5848 | .panic_fn => mod.comp.bin_file.options.target.ofmt == .c or | 5848 | .panic_fn => mod.comp.bin_file.options.target.ofmt == .c or |
| 5849 | mod.comp.bin_file.options.use_llvm, | 5849 | mod.comp.bin_file.options.use_llvm or |
| 5850 | mod.comp.bin_file.options.target.cpu.arch == .x86_64, | ||
| 5850 | .panic_unwrap_error => mod.comp.bin_file.options.target.ofmt == .c or | 5851 | .panic_unwrap_error => mod.comp.bin_file.options.target.ofmt == .c or |
| 5851 | mod.comp.bin_file.options.use_llvm, | 5852 | mod.comp.bin_file.options.use_llvm, |
| 5852 | .safety_check_formatted => mod.comp.bin_file.options.target.ofmt == .c or | 5853 | .safety_check_formatted => mod.comp.bin_file.options.target.ofmt == .c or |
src/arch/x86_64/CodeGen.zig+409-244| ... | @@ -1145,7 +1145,7 @@ fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 { | ... | @@ -1145,7 +1145,7 @@ fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 { |
| 1145 | } | 1145 | } |
| 1146 | 1146 | ||
| 1147 | /// A `cc` of `.z_and_np` clobbers `reg2`! | 1147 | /// A `cc` of `.z_and_np` clobbers `reg2`! |
| 1148 | fn asmCmovccRegisterRegister(self: *Self, cc: bits.Condition, reg1: Register, reg2: Register) !void { | 1148 | fn asmCmovccRegisterRegister(self: *Self, cc: Condition, reg1: Register, reg2: Register) !void { |
| 1149 | _ = try self.addInst(.{ | 1149 | _ = try self.addInst(.{ |
| 1150 | .tag = switch (cc) { | 1150 | .tag = switch (cc) { |
| 1151 | else => .cmov, | 1151 | else => .cmov, |
| ... | @@ -1168,7 +1168,7 @@ fn asmCmovccRegisterRegister(self: *Self, cc: bits.Condition, reg1: Register, re | ... | @@ -1168,7 +1168,7 @@ fn asmCmovccRegisterRegister(self: *Self, cc: bits.Condition, reg1: Register, re |
| 1168 | } | 1168 | } |
| 1169 | 1169 | ||
| 1170 | /// A `cc` of `.z_and_np` is not supported by this encoding! | 1170 | /// A `cc` of `.z_and_np` is not supported by this encoding! |
| 1171 | fn asmCmovccRegisterMemory(self: *Self, cc: bits.Condition, reg: Register, m: Memory) !void { | 1171 | fn asmCmovccRegisterMemory(self: *Self, cc: Condition, reg: Register, m: Memory) !void { |
| 1172 | _ = try self.addInst(.{ | 1172 | _ = try self.addInst(.{ |
| 1173 | .tag = switch (cc) { | 1173 | .tag = switch (cc) { |
| 1174 | else => .cmov, | 1174 | else => .cmov, |
| ... | @@ -1204,7 +1204,7 @@ fn asmCmovccRegisterMemory(self: *Self, cc: bits.Condition, reg: Register, m: Me | ... | @@ -1204,7 +1204,7 @@ fn asmCmovccRegisterMemory(self: *Self, cc: bits.Condition, reg: Register, m: Me |
| 1204 | }); | 1204 | }); |
| 1205 | } | 1205 | } |
| 1206 | 1206 | ||
| 1207 | fn asmSetccRegister(self: *Self, reg: Register, cc: bits.Condition) !void { | 1207 | fn asmSetccRegister(self: *Self, cc: Condition, reg: Register) !void { |
| 1208 | _ = try self.addInst(.{ | 1208 | _ = try self.addInst(.{ |
| 1209 | .tag = switch (cc) { | 1209 | .tag = switch (cc) { |
| 1210 | else => .set, | 1210 | else => .set, |
| ... | @@ -1228,7 +1228,7 @@ fn asmSetccRegister(self: *Self, reg: Register, cc: bits.Condition) !void { | ... | @@ -1228,7 +1228,7 @@ fn asmSetccRegister(self: *Self, reg: Register, cc: bits.Condition) !void { |
| 1228 | }); | 1228 | }); |
| 1229 | } | 1229 | } |
| 1230 | 1230 | ||
| 1231 | fn asmSetccMemory(self: *Self, m: Memory, cc: bits.Condition) !void { | 1231 | fn asmSetccMemory(self: *Self, cc: Condition, m: Memory) !void { |
| 1232 | const payload = switch (m) { | 1232 | const payload = switch (m) { |
| 1233 | .sib => try self.addExtra(Mir.MemorySib.encode(m)), | 1233 | .sib => try self.addExtra(Mir.MemorySib.encode(m)), |
| 1234 | .rip => try self.addExtra(Mir.MemoryRip.encode(m)), | 1234 | .rip => try self.addExtra(Mir.MemoryRip.encode(m)), |
| ... | @@ -1279,7 +1279,7 @@ fn asmJmpReloc(self: *Self, target: Mir.Inst.Index) !Mir.Inst.Index { | ... | @@ -1279,7 +1279,7 @@ fn asmJmpReloc(self: *Self, target: Mir.Inst.Index) !Mir.Inst.Index { |
| 1279 | }); | 1279 | }); |
| 1280 | } | 1280 | } |
| 1281 | 1281 | ||
| 1282 | fn asmJccReloc(self: *Self, target: Mir.Inst.Index, cc: bits.Condition) !Mir.Inst.Index { | 1282 | fn asmJccReloc(self: *Self, cc: Condition, target: Mir.Inst.Index) !Mir.Inst.Index { |
| 1283 | return self.addInst(.{ | 1283 | return self.addInst(.{ |
| 1284 | .tag = switch (cc) { | 1284 | .tag = switch (cc) { |
| 1285 | else => .j, | 1285 | else => .j, |
| ... | @@ -1759,8 +1759,8 @@ fn gen(self: *Self) InnerError!void { | ... | @@ -1759,8 +1759,8 @@ fn gen(self: *Self) InnerError!void { |
| 1759 | const cc = abi.resolveCallingConvention(fn_info.cc, self.target.*); | 1759 | const cc = abi.resolveCallingConvention(fn_info.cc, self.target.*); |
| 1760 | if (cc != .Naked) { | 1760 | if (cc != .Naked) { |
| 1761 | try self.asmRegister(.{ ._, .push }, .rbp); | 1761 | try self.asmRegister(.{ ._, .push }, .rbp); |
| 1762 | const backpatch_push_callee_preserved_regs = try self.asmPlaceholder(); | ||
| 1763 | try self.asmRegisterRegister(.{ ._, .mov }, .rbp, .rsp); | 1762 | try self.asmRegisterRegister(.{ ._, .mov }, .rbp, .rsp); |
| 1763 | const backpatch_push_callee_preserved_regs = try self.asmPlaceholder(); | ||
| 1764 | const backpatch_frame_align = try self.asmPlaceholder(); | 1764 | const backpatch_frame_align = try self.asmPlaceholder(); |
| 1765 | const backpatch_frame_align_extra = try self.asmPlaceholder(); | 1765 | const backpatch_frame_align_extra = try self.asmPlaceholder(); |
| 1766 | const backpatch_stack_alloc = try self.asmPlaceholder(); | 1766 | const backpatch_stack_alloc = try self.asmPlaceholder(); |
| ... | @@ -1805,7 +1805,7 @@ fn gen(self: *Self) InnerError!void { | ... | @@ -1805,7 +1805,7 @@ fn gen(self: *Self) InnerError!void { |
| 1805 | ); | 1805 | ); |
| 1806 | 1806 | ||
| 1807 | try self.asmRegisterImmediate(.{ ._, .cmp }, .al, Immediate.u(info.fp_count)); | 1807 | try self.asmRegisterImmediate(.{ ._, .cmp }, .al, Immediate.u(info.fp_count)); |
| 1808 | const skip_sse_reloc = try self.asmJccReloc(undefined, .na); | 1808 | const skip_sse_reloc = try self.asmJccReloc(.na, undefined); |
| 1809 | 1809 | ||
| 1810 | const vec_2_f64 = try mod.vectorType(.{ .len = 2, .child = .f64_type }); | 1810 | const vec_2_f64 = try mod.vectorType(.{ .len = 2, .child = .f64_type }); |
| 1811 | for (abi.SysV.c_abi_sse_param_regs[info.fp_count..], info.fp_count..) |reg, reg_i| | 1811 | for (abi.SysV.c_abi_sse_param_regs[info.fp_count..], info.fp_count..) |reg, reg_i| |
| ... | @@ -1913,11 +1913,14 @@ fn gen(self: *Self) InnerError!void { | ... | @@ -1913,11 +1913,14 @@ fn gen(self: *Self) InnerError!void { |
| 1913 | } | 1913 | } |
| 1914 | if (need_frame_align or need_stack_adjust) { | 1914 | if (need_frame_align or need_stack_adjust) { |
| 1915 | self.mir_instructions.set(backpatch_stack_dealloc, .{ | 1915 | self.mir_instructions.set(backpatch_stack_dealloc, .{ |
| 1916 | .tag = .mov, | 1916 | .tag = .lea, |
| 1917 | .ops = .rr, | 1917 | .ops = .rm_sib, |
| 1918 | .data = .{ .rr = .{ | 1918 | .data = .{ .rx = .{ |
| 1919 | .r1 = .rsp, | 1919 | .r1 = .rsp, |
| 1920 | .r2 = .rbp, | 1920 | .payload = try self.addExtra(Mir.MemorySib.encode(Memory.sib(.qword, .{ |
| 1921 | .base = .{ .reg = .rbp }, | ||
| 1922 | .disp = -frame_layout.save_reg_list.size(), | ||
| 1923 | }))), | ||
| 1921 | } }, | 1924 | } }, |
| 1922 | }); | 1925 | }); |
| 1923 | } | 1926 | } |
| ... | @@ -2262,7 +2265,7 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void { | ... | @@ -2262,7 +2265,7 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void { |
| 2262 | const tag_val = try mod.enumValueFieldIndex(enum_ty, index); | 2265 | const tag_val = try mod.enumValueFieldIndex(enum_ty, index); |
| 2263 | const tag_mcv = try self.genTypedValue(.{ .ty = enum_ty, .val = tag_val }); | 2266 | const tag_mcv = try self.genTypedValue(.{ .ty = enum_ty, .val = tag_val }); |
| 2264 | try self.genBinOpMir(.{ ._, .cmp }, enum_ty, enum_mcv, tag_mcv); | 2267 | try self.genBinOpMir(.{ ._, .cmp }, enum_ty, enum_mcv, tag_mcv); |
| 2265 | const skip_reloc = try self.asmJccReloc(undefined, .ne); | 2268 | const skip_reloc = try self.asmJccReloc(.ne, undefined); |
| 2266 | 2269 | ||
| 2267 | try self.genSetMem( | 2270 | try self.genSetMem( |
| 2268 | .{ .reg = ret_reg }, | 2271 | .{ .reg = ret_reg }, |
| ... | @@ -2298,8 +2301,8 @@ fn getValue(self: *Self, value: MCValue, inst: ?Air.Inst.Index) void { | ... | @@ -2298,8 +2301,8 @@ fn getValue(self: *Self, value: MCValue, inst: ?Air.Inst.Index) void { |
| 2298 | fn freeValue(self: *Self, value: MCValue) !void { | 2301 | fn freeValue(self: *Self, value: MCValue) !void { |
| 2299 | switch (value) { | 2302 | switch (value) { |
| 2300 | .register => |reg| { | 2303 | .register => |reg| { |
| 2301 | if (reg.class() == .x87) try self.asmRegister(.{ .f_, .free }, reg); | ||
| 2302 | self.register_manager.freeReg(reg); | 2304 | self.register_manager.freeReg(reg); |
| 2305 | if (reg.class() == .x87) try self.asmRegister(.{ .f_, .free }, reg); | ||
| 2303 | }, | 2306 | }, |
| 2304 | .register_pair => |regs| for (regs) |reg| self.register_manager.freeReg(reg), | 2307 | .register_pair => |regs| for (regs) |reg| self.register_manager.freeReg(reg), |
| 2305 | .register_offset => |reg_off| self.register_manager.freeReg(reg_off.reg), | 2308 | .register_offset => |reg_off| self.register_manager.freeReg(reg_off.reg), |
| ... | @@ -2416,17 +2419,19 @@ fn computeFrameLayout(self: *Self, cc: std.builtin.CallingConvention) !FrameLayo | ... | @@ -2416,17 +2419,19 @@ fn computeFrameLayout(self: *Self, cc: std.builtin.CallingConvention) !FrameLayo |
| 2416 | const callee_preserved_regs = | 2419 | const callee_preserved_regs = |
| 2417 | abi.getCalleePreservedRegs(abi.resolveCallingConvention(cc, self.target.*)); | 2420 | abi.getCalleePreservedRegs(abi.resolveCallingConvention(cc, self.target.*)); |
| 2418 | for (callee_preserved_regs) |reg| { | 2421 | for (callee_preserved_regs) |reg| { |
| 2419 | if (self.register_manager.isRegAllocated(reg)) { | 2422 | if (self.register_manager.isRegAllocated(reg) or true) { |
| 2420 | save_reg_list.push(callee_preserved_regs, reg); | 2423 | save_reg_list.push(callee_preserved_regs, reg); |
| 2421 | } | 2424 | } |
| 2422 | } | 2425 | } |
| 2423 | 2426 | ||
| 2424 | var rbp_offset: i32 = @intCast(save_reg_list.count() * 8); | 2427 | var rbp_offset: i32 = 0; |
| 2425 | self.setFrameLoc(.base_ptr, .rbp, &rbp_offset, false); | 2428 | self.setFrameLoc(.base_ptr, .rbp, &rbp_offset, false); |
| 2426 | self.setFrameLoc(.ret_addr, .rbp, &rbp_offset, false); | 2429 | self.setFrameLoc(.ret_addr, .rbp, &rbp_offset, false); |
| 2427 | self.setFrameLoc(.args_frame, .rbp, &rbp_offset, false); | 2430 | self.setFrameLoc(.args_frame, .rbp, &rbp_offset, false); |
| 2428 | const stack_frame_align_offset = | 2431 | const stack_frame_align_offset = if (need_align_stack) |
| 2429 | if (need_align_stack) 0 else frame_offset[@intFromEnum(FrameIndex.args_frame)]; | 2432 | 0 |
| 2433 | else | ||
| 2434 | save_reg_list.size() + frame_offset[@intFromEnum(FrameIndex.args_frame)]; | ||
| 2430 | 2435 | ||
| 2431 | var rsp_offset: i32 = 0; | 2436 | var rsp_offset: i32 = 0; |
| 2432 | self.setFrameLoc(.call_frame, .rsp, &rsp_offset, true); | 2437 | self.setFrameLoc(.call_frame, .rsp, &rsp_offset, true); |
| ... | @@ -3242,7 +3247,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3242,7 +3247,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { |
| 3242 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | 3247 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 3243 | const ty = self.typeOf(bin_op.lhs); | 3248 | const ty = self.typeOf(bin_op.lhs); |
| 3244 | if (ty.zigTypeTag(mod) == .Vector or ty.abiSize(mod) > 8) return self.fail( | 3249 | if (ty.zigTypeTag(mod) == .Vector or ty.abiSize(mod) > 8) return self.fail( |
| 3245 | "TODO implement addMulSat for {}", | 3250 | "TODO implement airAddSat for {}", |
| 3246 | .{ty.fmt(mod)}, | 3251 | .{ty.fmt(mod)}, |
| 3247 | ); | 3252 | ); |
| 3248 | 3253 | ||
| ... | @@ -3325,7 +3330,7 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3325,7 +3330,7 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void { |
| 3325 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | 3330 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 3326 | const ty = self.typeOf(bin_op.lhs); | 3331 | const ty = self.typeOf(bin_op.lhs); |
| 3327 | if (ty.zigTypeTag(mod) == .Vector or ty.abiSize(mod) > 8) return self.fail( | 3332 | if (ty.zigTypeTag(mod) == .Vector or ty.abiSize(mod) > 8) return self.fail( |
| 3328 | "TODO implement addMulSat for {}", | 3333 | "TODO implement airSubSat for {}", |
| 3329 | .{ty.fmt(mod)}, | 3334 | .{ty.fmt(mod)}, |
| 3330 | ); | 3335 | ); |
| 3331 | 3336 | ||
| ... | @@ -3401,7 +3406,7 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3401,7 +3406,7 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void { |
| 3401 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | 3406 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 3402 | const ty = self.typeOf(bin_op.lhs); | 3407 | const ty = self.typeOf(bin_op.lhs); |
| 3403 | if (ty.zigTypeTag(mod) == .Vector or ty.abiSize(mod) > 8) return self.fail( | 3408 | if (ty.zigTypeTag(mod) == .Vector or ty.abiSize(mod) > 8) return self.fail( |
| 3404 | "TODO implement addMulSat for {}", | 3409 | "TODO implement airMulSat for {}", |
| 3405 | .{ty.fmt(mod)}, | 3410 | .{ty.fmt(mod)}, |
| 3406 | ); | 3411 | ); |
| 3407 | 3412 | ||
| ... | @@ -3617,7 +3622,7 @@ fn genSetFrameTruncatedOverflowCompare( | ... | @@ -3617,7 +3622,7 @@ fn genSetFrameTruncatedOverflowCompare( |
| 3617 | defer for (temp_locks) |lock| self.register_manager.unlockReg(lock); | 3622 | defer for (temp_locks) |lock| self.register_manager.unlockReg(lock); |
| 3618 | 3623 | ||
| 3619 | const overflow_reg = temp_regs[0]; | 3624 | const overflow_reg = temp_regs[0]; |
| 3620 | if (overflow_cc) |cc| try self.asmSetccRegister(overflow_reg.to8(), cc); | 3625 | if (overflow_cc) |cc| try self.asmSetccRegister(cc, overflow_reg.to8()); |
| 3621 | 3626 | ||
| 3622 | const scratch_reg = temp_regs[1]; | 3627 | const scratch_reg = temp_regs[1]; |
| 3623 | const hi_limb_off = if (int_info.bits <= 64) 0 else (int_info.bits - 1) / 64 * 8; | 3628 | const hi_limb_off = if (int_info.bits <= 64) 0 else (int_info.bits - 1) / 64 * 8; |
| ... | @@ -3631,7 +3636,7 @@ fn genSetFrameTruncatedOverflowCompare( | ... | @@ -3631,7 +3636,7 @@ fn genSetFrameTruncatedOverflowCompare( |
| 3631 | 3636 | ||
| 3632 | const eq_reg = temp_regs[2]; | 3637 | const eq_reg = temp_regs[2]; |
| 3633 | if (overflow_cc) |_| { | 3638 | if (overflow_cc) |_| { |
| 3634 | try self.asmSetccRegister(eq_reg.to8(), .ne); | 3639 | try self.asmSetccRegister(.ne, eq_reg.to8()); |
| 3635 | try self.genBinOpMir( | 3640 | try self.genBinOpMir( |
| 3636 | .{ ._, .@"or" }, | 3641 | .{ ._, .@"or" }, |
| 3637 | Type.u8, | 3642 | Type.u8, |
| ... | @@ -3660,28 +3665,150 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3660,28 +3665,150 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 3660 | const mod = self.bin_file.options.module.?; | 3665 | const mod = self.bin_file.options.module.?; |
| 3661 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 3666 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 3662 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; | 3667 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 3668 | const tuple_ty = self.typeOfIndex(inst); | ||
| 3663 | const dst_ty = self.typeOf(bin_op.lhs); | 3669 | const dst_ty = self.typeOf(bin_op.lhs); |
| 3664 | const result: MCValue = switch (dst_ty.zigTypeTag(mod)) { | 3670 | const result: MCValue = switch (dst_ty.zigTypeTag(mod)) { |
| 3665 | .Vector => return self.fail("TODO implement airMulWithOverflow for {}", .{dst_ty.fmt(mod)}), | 3671 | .Vector => return self.fail("TODO implement airMulWithOverflow for {}", .{dst_ty.fmt(mod)}), |
| 3666 | .Int => result: { | 3672 | .Int => result: { |
| 3673 | const dst_info = dst_ty.intInfo(mod); | ||
| 3674 | const lhs_active_bits = self.activeIntBits(bin_op.lhs); | ||
| 3675 | const rhs_active_bits = self.activeIntBits(bin_op.rhs); | ||
| 3676 | const src_bits = @max(lhs_active_bits, rhs_active_bits, dst_info.bits / 2); | ||
| 3677 | const src_ty = try mod.intType(dst_info.signedness, src_bits); | ||
| 3678 | |||
| 3679 | if (src_bits > 64 and src_bits <= 128 and | ||
| 3680 | dst_info.bits > 64 and dst_info.bits <= 128) switch (dst_info.signedness) { | ||
| 3681 | .signed => { | ||
| 3682 | const ptr_c_int = try mod.singleMutPtrType(Type.c_int); | ||
| 3683 | const overflow = try self.allocTempRegOrMem(Type.c_int, false); | ||
| 3684 | const result = try self.genCall(.{ .lib = .{ | ||
| 3685 | .return_type = .i128_type, | ||
| 3686 | .param_types = &.{ .i128_type, .i128_type, ptr_c_int.toIntern() }, | ||
| 3687 | .callee = "__muloti4", | ||
| 3688 | } }, &.{ Type.i128, Type.i128, ptr_c_int }, &.{ | ||
| 3689 | .{ .air_ref = bin_op.lhs }, | ||
| 3690 | .{ .air_ref = bin_op.rhs }, | ||
| 3691 | overflow.address(), | ||
| 3692 | }); | ||
| 3693 | |||
| 3694 | const dst_mcv = try self.allocRegOrMem(inst, false); | ||
| 3695 | try self.genSetMem( | ||
| 3696 | .{ .frame = dst_mcv.load_frame.index }, | ||
| 3697 | @intCast(tuple_ty.structFieldOffset(0, mod)), | ||
| 3698 | tuple_ty.structFieldType(0, mod), | ||
| 3699 | result, | ||
| 3700 | ); | ||
| 3701 | try self.asmMemoryImmediate( | ||
| 3702 | .{ ._, .cmp }, | ||
| 3703 | overflow.mem(self.memPtrSize(Type.c_int)), | ||
| 3704 | Immediate.s(0), | ||
| 3705 | ); | ||
| 3706 | try self.genSetMem( | ||
| 3707 | .{ .frame = dst_mcv.load_frame.index }, | ||
| 3708 | @intCast(tuple_ty.structFieldOffset(1, mod)), | ||
| 3709 | tuple_ty.structFieldType(1, mod), | ||
| 3710 | .{ .eflags = .ne }, | ||
| 3711 | ); | ||
| 3712 | try self.freeValue(overflow); | ||
| 3713 | break :result dst_mcv; | ||
| 3714 | }, | ||
| 3715 | .unsigned => { | ||
| 3716 | try self.spillEflagsIfOccupied(); | ||
| 3717 | try self.spillRegisters(&.{ .rax, .rdx }); | ||
| 3718 | const reg_locks = self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx }); | ||
| 3719 | defer for (reg_locks) |lock| self.register_manager.unlockReg(lock); | ||
| 3720 | |||
| 3721 | const tmp_regs = | ||
| 3722 | try self.register_manager.allocRegs(4, .{null} ** 4, abi.RegisterClass.gp); | ||
| 3723 | const tmp_locks = self.register_manager.lockRegsAssumeUnused(4, tmp_regs); | ||
| 3724 | defer for (tmp_locks) |lock| self.register_manager.unlockReg(lock); | ||
| 3725 | |||
| 3726 | const lhs_mcv = try self.resolveInst(bin_op.lhs); | ||
| 3727 | const rhs_mcv = try self.resolveInst(bin_op.rhs); | ||
| 3728 | |||
| 3729 | if (lhs_mcv.isMemory()) | ||
| 3730 | try self.asmRegisterMemory(.{ ._, .mov }, .rax, lhs_mcv.mem(.qword)) | ||
| 3731 | else | ||
| 3732 | try self.asmRegisterRegister(.{ ._, .mov }, .rax, lhs_mcv.register_pair[0]); | ||
| 3733 | if (rhs_mcv.isMemory()) try self.asmRegisterMemory( | ||
| 3734 | .{ ._, .mov }, | ||
| 3735 | tmp_regs[0], | ||
| 3736 | rhs_mcv.address().offset(8).deref().mem(.qword), | ||
| 3737 | ) else try self.asmRegisterRegister( | ||
| 3738 | .{ ._, .mov }, | ||
| 3739 | tmp_regs[0], | ||
| 3740 | rhs_mcv.register_pair[1], | ||
| 3741 | ); | ||
| 3742 | try self.asmRegisterRegister(.{ ._, .@"test" }, tmp_regs[0], tmp_regs[0]); | ||
| 3743 | try self.asmSetccRegister(.nz, tmp_regs[1].to8()); | ||
| 3744 | try self.asmRegisterRegister(.{ .i_, .mul }, tmp_regs[0], .rax); | ||
| 3745 | try self.asmSetccRegister(.o, tmp_regs[2].to8()); | ||
| 3746 | if (rhs_mcv.isMemory()) | ||
| 3747 | try self.asmMemory(.{ ._, .mul }, rhs_mcv.mem(.qword)) | ||
| 3748 | else | ||
| 3749 | try self.asmRegister(.{ ._, .mul }, rhs_mcv.register_pair[0]); | ||
| 3750 | try self.asmRegisterRegister(.{ ._, .add }, .rdx, tmp_regs[0]); | ||
| 3751 | try self.asmSetccRegister(.c, tmp_regs[3].to8()); | ||
| 3752 | try self.asmRegisterRegister(.{ ._, .@"or" }, tmp_regs[2].to8(), tmp_regs[3].to8()); | ||
| 3753 | if (lhs_mcv.isMemory()) try self.asmRegisterMemory( | ||
| 3754 | .{ ._, .mov }, | ||
| 3755 | tmp_regs[0], | ||
| 3756 | lhs_mcv.address().offset(8).deref().mem(.qword), | ||
| 3757 | ) else try self.asmRegisterRegister( | ||
| 3758 | .{ ._, .mov }, | ||
| 3759 | tmp_regs[0], | ||
| 3760 | lhs_mcv.register_pair[1], | ||
| 3761 | ); | ||
| 3762 | try self.asmRegisterRegister(.{ ._, .@"test" }, tmp_regs[0], tmp_regs[0]); | ||
| 3763 | try self.asmSetccRegister(.nz, tmp_regs[3].to8()); | ||
| 3764 | try self.asmRegisterRegister( | ||
| 3765 | .{ ._, .@"and" }, | ||
| 3766 | tmp_regs[1].to8(), | ||
| 3767 | tmp_regs[3].to8(), | ||
| 3768 | ); | ||
| 3769 | try self.asmRegisterRegister(.{ ._, .@"or" }, tmp_regs[1].to8(), tmp_regs[2].to8()); | ||
| 3770 | if (rhs_mcv.isMemory()) | ||
| 3771 | try self.asmRegisterMemory(.{ .i_, .mul }, tmp_regs[0], rhs_mcv.mem(.qword)) | ||
| 3772 | else | ||
| 3773 | try self.asmRegisterRegister( | ||
| 3774 | .{ .i_, .mul }, | ||
| 3775 | tmp_regs[0], | ||
| 3776 | rhs_mcv.register_pair[0], | ||
| 3777 | ); | ||
| 3778 | try self.asmSetccRegister(.o, tmp_regs[2].to8()); | ||
| 3779 | try self.asmRegisterRegister(.{ ._, .@"or" }, tmp_regs[1].to8(), tmp_regs[2].to8()); | ||
| 3780 | try self.asmRegisterRegister(.{ ._, .add }, .rdx, tmp_regs[0]); | ||
| 3781 | try self.asmSetccRegister(.c, tmp_regs[2].to8()); | ||
| 3782 | try self.asmRegisterRegister(.{ ._, .@"or" }, tmp_regs[1].to8(), tmp_regs[2].to8()); | ||
| 3783 | |||
| 3784 | const dst_mcv = try self.allocRegOrMem(inst, false); | ||
| 3785 | try self.genSetMem( | ||
| 3786 | .{ .frame = dst_mcv.load_frame.index }, | ||
| 3787 | @intCast(tuple_ty.structFieldOffset(0, mod)), | ||
| 3788 | tuple_ty.structFieldType(0, mod), | ||
| 3789 | .{ .register_pair = .{ .rax, .rdx } }, | ||
| 3790 | ); | ||
| 3791 | try self.genSetMem( | ||
| 3792 | .{ .frame = dst_mcv.load_frame.index }, | ||
| 3793 | @intCast(tuple_ty.structFieldOffset(1, mod)), | ||
| 3794 | tuple_ty.structFieldType(1, mod), | ||
| 3795 | .{ .register = tmp_regs[1] }, | ||
| 3796 | ); | ||
| 3797 | break :result dst_mcv; | ||
| 3798 | }, | ||
| 3799 | }; | ||
| 3800 | |||
| 3667 | try self.spillEflagsIfOccupied(); | 3801 | try self.spillEflagsIfOccupied(); |
| 3668 | try self.spillRegisters(&.{ .rax, .rdx }); | 3802 | try self.spillRegisters(&.{ .rax, .rdx }); |
| 3669 | 3803 | ||
| 3670 | const dst_info = dst_ty.intInfo(mod); | ||
| 3671 | const cc: Condition = switch (dst_info.signedness) { | 3804 | const cc: Condition = switch (dst_info.signedness) { |
| 3672 | .unsigned => .c, | 3805 | .unsigned => .c, |
| 3673 | .signed => .o, | 3806 | .signed => .o, |
| 3674 | }; | 3807 | }; |
| 3675 | 3808 | ||
| 3676 | const lhs_active_bits = self.activeIntBits(bin_op.lhs); | ||
| 3677 | const rhs_active_bits = self.activeIntBits(bin_op.rhs); | ||
| 3678 | const src_bits = @max(lhs_active_bits, rhs_active_bits, dst_info.bits / 2); | ||
| 3679 | const src_ty = try mod.intType(dst_info.signedness, src_bits); | ||
| 3680 | |||
| 3681 | const lhs = try self.resolveInst(bin_op.lhs); | 3809 | const lhs = try self.resolveInst(bin_op.lhs); |
| 3682 | const rhs = try self.resolveInst(bin_op.rhs); | 3810 | const rhs = try self.resolveInst(bin_op.rhs); |
| 3683 | 3811 | ||
| 3684 | const tuple_ty = self.typeOfIndex(inst); | ||
| 3685 | const extra_bits = if (dst_info.bits <= 64) | 3812 | const extra_bits = if (dst_info.bits <= 64) |
| 3686 | self.regExtraBits(dst_ty) | 3813 | self.regExtraBits(dst_ty) |
| 3687 | else | 3814 | else |
| ... | @@ -3741,6 +3868,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3741,6 +3868,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 3741 | fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue, rhs: MCValue) !void { | 3868 | fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue, rhs: MCValue) !void { |
| 3742 | const mod = self.bin_file.options.module.?; | 3869 | const mod = self.bin_file.options.module.?; |
| 3743 | const abi_size: u32 = @intCast(ty.abiSize(mod)); | 3870 | const abi_size: u32 = @intCast(ty.abiSize(mod)); |
| 3871 | const bit_size: u32 = @intCast(self.regBitSize(ty)); | ||
| 3744 | if (abi_size > 8) { | 3872 | if (abi_size > 8) { |
| 3745 | return self.fail("TODO implement genIntMulDivOpMir for ABI size larger than 8", .{}); | 3873 | return self.fail("TODO implement genIntMulDivOpMir for ABI size larger than 8", .{}); |
| 3746 | } | 3874 | } |
| ... | @@ -3752,14 +3880,14 @@ fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue | ... | @@ -3752,14 +3880,14 @@ fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue |
| 3752 | .div => switch (tag[0]) { | 3880 | .div => switch (tag[0]) { |
| 3753 | ._ => { | 3881 | ._ => { |
| 3754 | const hi_reg: Register = | 3882 | const hi_reg: Register = |
| 3755 | switch (self.regBitSize(ty)) { | 3883 | switch (bit_size) { |
| 3756 | 8 => .ah, | 3884 | 8 => .ah, |
| 3757 | 16, 32, 64 => .edx, | 3885 | 16, 32, 64 => .edx, |
| 3758 | else => unreachable, | 3886 | else => unreachable, |
| 3759 | }; | 3887 | }; |
| 3760 | try self.asmRegisterRegister(.{ ._, .xor }, hi_reg, hi_reg); | 3888 | try self.asmRegisterRegister(.{ ._, .xor }, hi_reg, hi_reg); |
| 3761 | }, | 3889 | }, |
| 3762 | .i_ => try self.asmOpOnly(.{ ._, switch (self.regBitSize(ty)) { | 3890 | .i_ => try self.asmOpOnly(.{ ._, switch (bit_size) { |
| 3763 | 8 => .cbw, | 3891 | 8 => .cbw, |
| 3764 | 16 => .cwd, | 3892 | 16 => .cwd, |
| 3765 | 32 => .cdq, | 3893 | 32 => .cdq, |
| ... | @@ -3782,6 +3910,7 @@ fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue | ... | @@ -3782,6 +3910,7 @@ fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue |
| 3782 | ), | 3910 | ), |
| 3783 | else => unreachable, | 3911 | else => unreachable, |
| 3784 | } | 3912 | } |
| 3913 | if (tag[1] == .div and bit_size == 8) try self.asmRegisterRegister(.{ ._, .mov }, .dl, .ah); | ||
| 3785 | } | 3914 | } |
| 3786 | 3915 | ||
| 3787 | /// Always returns a register. | 3916 | /// Always returns a register. |
| ... | @@ -3981,54 +4110,12 @@ fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3981,54 +4110,12 @@ fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { |
| 3981 | 4110 | ||
| 3982 | fn airUnwrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { | 4111 | fn airUnwrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 3983 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 4112 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 3984 | const err_union_ty = self.typeOf(ty_op.operand); | 4113 | const operand_ty = self.typeOf(ty_op.operand); |
| 3985 | const operand = try self.resolveInst(ty_op.operand); | 4114 | const operand = try self.resolveInst(ty_op.operand); |
| 3986 | const result = try self.genUnwrapErrorUnionPayloadMir(inst, err_union_ty, operand); | 4115 | const result = try self.genUnwrapErrUnionPayloadMir(inst, operand_ty, operand); |
| 3987 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 4116 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 3988 | } | 4117 | } |
| 3989 | 4118 | ||
| 3990 | fn genUnwrapErrorUnionPayloadMir( | ||
| 3991 | self: *Self, | ||
| 3992 | maybe_inst: ?Air.Inst.Index, | ||
| 3993 | err_union_ty: Type, | ||
| 3994 | err_union: MCValue, | ||
| 3995 | ) !MCValue { | ||
| 3996 | const mod = self.bin_file.options.module.?; | ||
| 3997 | const payload_ty = err_union_ty.errorUnionPayload(mod); | ||
| 3998 | |||
| 3999 | const result: MCValue = result: { | ||
| 4000 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .none; | ||
| 4001 | |||
| 4002 | const payload_off = errUnionPayloadOffset(payload_ty, mod); | ||
| 4003 | switch (err_union) { | ||
| 4004 | .load_frame => |frame_addr| break :result .{ .load_frame = .{ | ||
| 4005 | .index = frame_addr.index, | ||
| 4006 | .off = frame_addr.off + @as(i32, @intCast(payload_off)), | ||
| 4007 | } }, | ||
| 4008 | .register => |reg| { | ||
| 4009 | // TODO reuse operand | ||
| 4010 | const eu_lock = self.register_manager.lockReg(reg); | ||
| 4011 | defer if (eu_lock) |lock| self.register_manager.unlockReg(lock); | ||
| 4012 | |||
| 4013 | const result_mcv: MCValue = if (maybe_inst) |inst| | ||
| 4014 | try self.copyToRegisterWithInstTracking(inst, err_union_ty, err_union) | ||
| 4015 | else | ||
| 4016 | .{ .register = try self.copyToTmpRegister(err_union_ty, err_union) }; | ||
| 4017 | if (payload_off > 0) try self.genShiftBinOpMir( | ||
| 4018 | .{ ._r, .sh }, | ||
| 4019 | err_union_ty, | ||
| 4020 | result_mcv, | ||
| 4021 | .{ .immediate = @as(u6, @intCast(payload_off * 8)) }, | ||
| 4022 | ) else try self.truncateRegister(payload_ty, result_mcv.register); | ||
| 4023 | break :result result_mcv; | ||
| 4024 | }, | ||
| 4025 | else => return self.fail("TODO implement genUnwrapErrorUnionPayloadMir for {}", .{err_union}), | ||
| 4026 | } | ||
| 4027 | }; | ||
| 4028 | |||
| 4029 | return result; | ||
| 4030 | } | ||
| 4031 | |||
| 4032 | // *(E!T) -> E | 4119 | // *(E!T) -> E |
| 4033 | fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void { | 4120 | fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4034 | const mod = self.bin_file.options.module.?; | 4121 | const mod = self.bin_file.options.module.?; |
| ... | @@ -4067,38 +4154,11 @@ fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4067,38 +4154,11 @@ fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4067 | 4154 | ||
| 4068 | // *(E!T) -> *T | 4155 | // *(E!T) -> *T |
| 4069 | fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void { | 4156 | fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4070 | const mod = self.bin_file.options.module.?; | ||
| 4071 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 4157 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 4072 | 4158 | const operand_ty = self.typeOf(ty_op.operand); | |
| 4073 | const src_ty = self.typeOf(ty_op.operand); | 4159 | const operand = try self.resolveInst(ty_op.operand); |
| 4074 | const src_mcv = try self.resolveInst(ty_op.operand); | 4160 | const result = try self.genUnwrapErrUnionPayloadPtrMir(inst, operand_ty, operand); |
| 4075 | const src_reg = switch (src_mcv) { | 4161 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 4076 | .register => |reg| reg, | ||
| 4077 | else => try self.copyToTmpRegister(src_ty, src_mcv), | ||
| 4078 | }; | ||
| 4079 | const src_lock = self.register_manager.lockRegAssumeUnused(src_reg); | ||
| 4080 | defer self.register_manager.unlockReg(src_lock); | ||
| 4081 | |||
| 4082 | const dst_ty = self.typeOfIndex(inst); | ||
| 4083 | const dst_reg = if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) | ||
| 4084 | src_reg | ||
| 4085 | else | ||
| 4086 | try self.register_manager.allocReg(inst, abi.RegisterClass.gp); | ||
| 4087 | const dst_mcv = MCValue{ .register = dst_reg }; | ||
| 4088 | const dst_lock = self.register_manager.lockReg(dst_reg); | ||
| 4089 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); | ||
| 4090 | |||
| 4091 | const eu_ty = src_ty.childType(mod); | ||
| 4092 | const pl_ty = eu_ty.errorUnionPayload(mod); | ||
| 4093 | const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, mod)); | ||
| 4094 | const dst_abi_size: u32 = @intCast(dst_ty.abiSize(mod)); | ||
| 4095 | try self.asmRegisterMemory( | ||
| 4096 | .{ ._, .lea }, | ||
| 4097 | registerAlias(dst_reg, dst_abi_size), | ||
| 4098 | Memory.sib(.qword, .{ .base = .{ .reg = src_reg }, .disp = pl_off }), | ||
| 4099 | ); | ||
| 4100 | |||
| 4101 | return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none }); | ||
| 4102 | } | 4162 | } |
| 4103 | 4163 | ||
| 4104 | fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { | 4164 | fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { |
| ... | @@ -4150,6 +4210,71 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4150,6 +4210,71 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { |
| 4150 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 4210 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 4151 | } | 4211 | } |
| 4152 | 4212 | ||
| 4213 | fn genUnwrapErrUnionPayloadMir( | ||
| 4214 | self: *Self, | ||
| 4215 | maybe_inst: ?Air.Inst.Index, | ||
| 4216 | err_union_ty: Type, | ||
| 4217 | err_union: MCValue, | ||
| 4218 | ) !MCValue { | ||
| 4219 | const mod = self.bin_file.options.module.?; | ||
| 4220 | const payload_ty = err_union_ty.errorUnionPayload(mod); | ||
| 4221 | |||
| 4222 | const result: MCValue = result: { | ||
| 4223 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .none; | ||
| 4224 | |||
| 4225 | const payload_off: u31 = @intCast(errUnionPayloadOffset(payload_ty, mod)); | ||
| 4226 | switch (err_union) { | ||
| 4227 | .load_frame => |frame_addr| break :result .{ .load_frame = .{ | ||
| 4228 | .index = frame_addr.index, | ||
| 4229 | .off = frame_addr.off + payload_off, | ||
| 4230 | } }, | ||
| 4231 | .register => |reg| { | ||
| 4232 | // TODO reuse operand | ||
| 4233 | const eu_lock = self.register_manager.lockReg(reg); | ||
| 4234 | defer if (eu_lock) |lock| self.register_manager.unlockReg(lock); | ||
| 4235 | |||
| 4236 | const result_mcv: MCValue = if (maybe_inst) |inst| | ||
| 4237 | try self.copyToRegisterWithInstTracking(inst, err_union_ty, err_union) | ||
| 4238 | else | ||
| 4239 | .{ .register = try self.copyToTmpRegister(err_union_ty, err_union) }; | ||
| 4240 | if (payload_off > 0) try self.genShiftBinOpMir( | ||
| 4241 | .{ ._r, .sh }, | ||
| 4242 | err_union_ty, | ||
| 4243 | result_mcv, | ||
| 4244 | .{ .immediate = @as(u6, @intCast(payload_off * 8)) }, | ||
| 4245 | ) else try self.truncateRegister(payload_ty, result_mcv.register); | ||
| 4246 | break :result result_mcv; | ||
| 4247 | }, | ||
| 4248 | else => return self.fail("TODO implement genUnwrapErrUnionPayloadMir for {}", .{err_union}), | ||
| 4249 | } | ||
| 4250 | }; | ||
| 4251 | |||
| 4252 | return result; | ||
| 4253 | } | ||
| 4254 | |||
| 4255 | fn genUnwrapErrUnionPayloadPtrMir( | ||
| 4256 | self: *Self, | ||
| 4257 | maybe_inst: ?Air.Inst.Index, | ||
| 4258 | ptr_ty: Type, | ||
| 4259 | ptr_mcv: MCValue, | ||
| 4260 | ) !MCValue { | ||
| 4261 | const mod = self.bin_file.options.module.?; | ||
| 4262 | const err_union_ty = ptr_ty.childType(mod); | ||
| 4263 | const payload_ty = err_union_ty.errorUnionPayload(mod); | ||
| 4264 | |||
| 4265 | const result: MCValue = result: { | ||
| 4266 | const payload_off = errUnionPayloadOffset(payload_ty, mod); | ||
| 4267 | const result_mcv: MCValue = if (maybe_inst) |inst| | ||
| 4268 | try self.copyToRegisterWithInstTracking(inst, ptr_ty, ptr_mcv) | ||
| 4269 | else | ||
| 4270 | .{ .register = try self.copyToTmpRegister(ptr_ty, ptr_mcv) }; | ||
| 4271 | try self.genBinOpMir(.{ ._, .add }, ptr_ty, result_mcv, .{ .immediate = payload_off }); | ||
| 4272 | break :result result_mcv; | ||
| 4273 | }; | ||
| 4274 | |||
| 4275 | return result; | ||
| 4276 | } | ||
| 4277 | |||
| 4153 | fn airErrReturnTrace(self: *Self, inst: Air.Inst.Index) !void { | 4278 | fn airErrReturnTrace(self: *Self, inst: Air.Inst.Index) !void { |
| 4154 | _ = inst; | 4279 | _ = inst; |
| 4155 | return self.fail("TODO implement airErrReturnTrace for {}", .{self.target.cpu.arch}); | 4280 | return self.fail("TODO implement airErrReturnTrace for {}", .{self.target.cpu.arch}); |
| ... | @@ -6425,7 +6550,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6425,7 +6550,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 6425 | break :result .{ .eflags = ro.eflags }; | 6550 | break :result .{ .eflags = ro.eflags }; |
| 6426 | } else { | 6551 | } else { |
| 6427 | const dst_reg = try self.register_manager.allocReg(inst, abi.RegisterClass.gp); | 6552 | const dst_reg = try self.register_manager.allocReg(inst, abi.RegisterClass.gp); |
| 6428 | try self.asmSetccRegister(dst_reg.to8(), ro.eflags); | 6553 | try self.asmSetccRegister(ro.eflags, dst_reg.to8()); |
| 6429 | break :result .{ .register = dst_reg.to8() }; | 6554 | break :result .{ .register = dst_reg.to8() }; |
| 6430 | }, | 6555 | }, |
| 6431 | else => unreachable, | 6556 | else => unreachable, |
| ... | @@ -9712,55 +9837,59 @@ fn genCall(self: *Self, info: union(enum) { | ... | @@ -9712,55 +9837,59 @@ fn genCall(self: *Self, info: union(enum) { |
| 9712 | switch (info) { | 9837 | switch (info) { |
| 9713 | .air => |callee| if (try self.air.value(callee, mod)) |func_value| { | 9838 | .air => |callee| if (try self.air.value(callee, mod)) |func_value| { |
| 9714 | const func_key = mod.intern_pool.indexToKey(func_value.ip_index); | 9839 | const func_key = mod.intern_pool.indexToKey(func_value.ip_index); |
| 9715 | if (switch (func_key) { | 9840 | switch (switch (func_key) { |
| 9716 | .func => |func| func.owner_decl, | 9841 | else => func_key, |
| 9717 | .ptr => |ptr| switch (ptr.addr) { | 9842 | .ptr => |ptr| switch (ptr.addr) { |
| 9718 | .decl => |decl| decl, | 9843 | .decl => |decl| mod.intern_pool.indexToKey(try mod.declPtr(decl).internValue(mod)), |
| 9719 | else => null, | 9844 | else => func_key, |
| 9720 | }, | 9845 | }, |
| 9721 | else => null, | 9846 | }) { |
| 9722 | }) |owner_decl| { | 9847 | .func => |func| { |
| 9723 | if (self.bin_file.cast(link.File.Elf)) |elf_file| { | 9848 | try mod.markDeclAlive(mod.declPtr(func.owner_decl)); |
| 9724 | const sym_index = try elf_file.getOrCreateMetadataForDecl(owner_decl); | 9849 | if (self.bin_file.cast(link.File.Elf)) |elf_file| { |
| 9725 | const sym = elf_file.symbol(sym_index); | 9850 | const sym_index = try elf_file.getOrCreateMetadataForDecl(func.owner_decl); |
| 9726 | _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file); | 9851 | const sym = elf_file.symbol(sym_index); |
| 9727 | if (self.bin_file.options.pic) { | 9852 | _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file); |
| 9728 | try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym.esym_index }); | 9853 | if (self.bin_file.options.pic) { |
| 9854 | try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym.esym_index }); | ||
| 9855 | try self.asmRegister(.{ ._, .call }, .rax); | ||
| 9856 | } else { | ||
| 9857 | _ = try self.addInst(.{ | ||
| 9858 | .tag = .call, | ||
| 9859 | .ops = .direct_got_reloc, | ||
| 9860 | .data = .{ .reloc = .{ | ||
| 9861 | .atom_index = try self.owner.getSymbolIndex(self), | ||
| 9862 | .sym_index = sym.esym_index, | ||
| 9863 | } }, | ||
| 9864 | }); | ||
| 9865 | } | ||
| 9866 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { | ||
| 9867 | const atom = try coff_file.getOrCreateAtomForDecl(func.owner_decl); | ||
| 9868 | const sym_index = coff_file.getAtom(atom).getSymbolIndex().?; | ||
| 9869 | try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index }); | ||
| 9729 | try self.asmRegister(.{ ._, .call }, .rax); | 9870 | try self.asmRegister(.{ ._, .call }, .rax); |
| 9730 | } else { | 9871 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { |
| 9731 | _ = try self.addInst(.{ | 9872 | const atom = try macho_file.getOrCreateAtomForDecl(func.owner_decl); |
| 9732 | .tag = .call, | 9873 | const sym_index = macho_file.getAtom(atom).getSymbolIndex().?; |
| 9733 | .ops = .direct_got_reloc, | 9874 | try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index }); |
| 9734 | .data = .{ .reloc = .{ | 9875 | try self.asmRegister(.{ ._, .call }, .rax); |
| 9735 | .atom_index = try self.owner.getSymbolIndex(self), | 9876 | } else if (self.bin_file.cast(link.File.Plan9)) |p9| { |
| 9736 | .sym_index = sym.esym_index, | 9877 | const atom_index = try p9.seeDecl(func.owner_decl); |
| 9737 | } }, | 9878 | const atom = p9.getAtom(atom_index); |
| 9738 | }); | 9879 | try self.asmMemory(.{ ._, .call }, Memory.sib(.qword, .{ |
| 9739 | } | 9880 | .base = .{ .reg = .ds }, |
| 9740 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { | 9881 | .disp = @intCast(atom.getOffsetTableAddress(p9)), |
| 9741 | const atom = try coff_file.getOrCreateAtomForDecl(owner_decl); | 9882 | })); |
| 9742 | const sym_index = coff_file.getAtom(atom).getSymbolIndex().?; | 9883 | } else unreachable; |
| 9743 | try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index }); | 9884 | }, |
| 9744 | try self.asmRegister(.{ ._, .call }, .rax); | 9885 | .extern_func => |extern_func| { |
| 9745 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { | 9886 | const owner_decl = mod.declPtr(extern_func.decl); |
| 9746 | const atom = try macho_file.getOrCreateAtomForDecl(owner_decl); | 9887 | try mod.markDeclAlive(owner_decl); |
| 9747 | const sym_index = macho_file.getAtom(atom).getSymbolIndex().?; | 9888 | const lib_name = mod.intern_pool.stringToSliceUnwrap(extern_func.lib_name); |
| 9748 | try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index }); | 9889 | const decl_name = mod.intern_pool.stringToSlice(owner_decl.name); |
| 9749 | try self.asmRegister(.{ ._, .call }, .rax); | 9890 | try self.genExternSymbolRef(.call, lib_name, decl_name); |
| 9750 | } else if (self.bin_file.cast(link.File.Plan9)) |p9| { | 9891 | }, |
| 9751 | const atom_index = try p9.seeDecl(owner_decl); | 9892 | else => return self.fail("TODO implement calling bitcasted functions", .{}), |
| 9752 | const atom = p9.getAtom(atom_index); | ||
| 9753 | try self.asmMemory(.{ ._, .call }, Memory.sib(.qword, .{ | ||
| 9754 | .base = .{ .reg = .ds }, | ||
| 9755 | .disp = @intCast(atom.getOffsetTableAddress(p9)), | ||
| 9756 | })); | ||
| 9757 | } else unreachable; | ||
| 9758 | } else if (func_value.getExternFunc(mod)) |extern_func| { | ||
| 9759 | const lib_name = mod.intern_pool.stringToSliceUnwrap(extern_func.lib_name); | ||
| 9760 | const decl_name = mod.intern_pool.stringToSlice(mod.declPtr(extern_func.decl).name); | ||
| 9761 | try self.genExternSymbolRef(.call, lib_name, decl_name); | ||
| 9762 | } else { | ||
| 9763 | return self.fail("TODO implement calling bitcasted functions", .{}); | ||
| 9764 | } | 9893 | } |
| 9765 | } else { | 9894 | } else { |
| 9766 | assert(self.typeOf(callee).zigTypeTag(mod) == .Pointer); | 9895 | assert(self.typeOf(callee).zigTypeTag(mod) == .Pointer); |
| ... | @@ -10241,47 +10370,46 @@ fn airTry(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -10241,47 +10370,46 @@ fn airTry(self: *Self, inst: Air.Inst.Index) !void { |
| 10241 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; | 10370 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
| 10242 | const extra = self.air.extraData(Air.Try, pl_op.payload); | 10371 | const extra = self.air.extraData(Air.Try, pl_op.payload); |
| 10243 | const body = self.air.extra[extra.end..][0..extra.data.body_len]; | 10372 | const body = self.air.extra[extra.end..][0..extra.data.body_len]; |
| 10244 | const err_union_ty = self.typeOf(pl_op.operand); | 10373 | const operand_ty = self.typeOf(pl_op.operand); |
| 10245 | const result = try self.genTry(inst, pl_op.operand, body, err_union_ty, false); | 10374 | const result = try self.genTry(inst, pl_op.operand, body, operand_ty, false); |
| 10246 | return self.finishAir(inst, result, .{ .none, .none, .none }); | 10375 | return self.finishAir(inst, result, .{ .none, .none, .none }); |
| 10247 | } | 10376 | } |
| 10248 | 10377 | ||
| 10249 | fn airTryPtr(self: *Self, inst: Air.Inst.Index) !void { | 10378 | fn airTryPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 10250 | const mod = self.bin_file.options.module.?; | ||
| 10251 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 10379 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 10252 | const extra = self.air.extraData(Air.TryPtr, ty_pl.payload); | 10380 | const extra = self.air.extraData(Air.TryPtr, ty_pl.payload); |
| 10253 | const body = self.air.extra[extra.end..][0..extra.data.body_len]; | 10381 | const body = self.air.extra[extra.end..][0..extra.data.body_len]; |
| 10254 | const err_union_ty = self.typeOf(extra.data.ptr).childType(mod); | 10382 | const operand_ty = self.typeOf(extra.data.ptr); |
| 10255 | const result = try self.genTry(inst, extra.data.ptr, body, err_union_ty, true); | 10383 | const result = try self.genTry(inst, extra.data.ptr, body, operand_ty, true); |
| 10256 | return self.finishAir(inst, result, .{ .none, .none, .none }); | 10384 | return self.finishAir(inst, result, .{ .none, .none, .none }); |
| 10257 | } | 10385 | } |
| 10258 | 10386 | ||
| 10259 | fn genTry( | 10387 | fn genTry( |
| 10260 | self: *Self, | 10388 | self: *Self, |
| 10261 | inst: Air.Inst.Index, | 10389 | inst: Air.Inst.Index, |
| 10262 | err_union: Air.Inst.Ref, | 10390 | operand: Air.Inst.Ref, |
| 10263 | body: []const Air.Inst.Index, | 10391 | body: []const Air.Inst.Index, |
| 10264 | err_union_ty: Type, | 10392 | operand_ty: Type, |
| 10265 | operand_is_ptr: bool, | 10393 | operand_is_ptr: bool, |
| 10266 | ) !MCValue { | 10394 | ) !MCValue { |
| 10267 | if (operand_is_ptr) { | ||
| 10268 | return self.fail("TODO genTry for pointers", .{}); | ||
| 10269 | } | ||
| 10270 | const liveness_cond_br = self.liveness.getCondBr(inst); | 10395 | const liveness_cond_br = self.liveness.getCondBr(inst); |
| 10271 | 10396 | ||
| 10272 | const err_union_mcv = try self.resolveInst(err_union); | 10397 | const operand_mcv = try self.resolveInst(operand); |
| 10273 | const is_err_mcv = try self.isErr(null, err_union_ty, err_union_mcv); | 10398 | const is_err_mcv = if (operand_is_ptr) |
| 10399 | try self.isErrPtr(null, operand_ty, operand_mcv) | ||
| 10400 | else | ||
| 10401 | try self.isErr(null, operand_ty, operand_mcv); | ||
| 10274 | 10402 | ||
| 10275 | const reloc = try self.genCondBrMir(Type.anyerror, is_err_mcv); | 10403 | const reloc = try self.genCondBrMir(Type.anyerror, is_err_mcv); |
| 10276 | 10404 | ||
| 10277 | if (self.liveness.operandDies(inst, 0)) { | 10405 | if (self.liveness.operandDies(inst, 0)) { |
| 10278 | if (Air.refToIndex(err_union)) |err_union_inst| try self.processDeath(err_union_inst); | 10406 | if (Air.refToIndex(operand)) |operand_inst| try self.processDeath(operand_inst); |
| 10279 | } | 10407 | } |
| 10280 | 10408 | ||
| 10281 | self.scope_generation += 1; | 10409 | self.scope_generation += 1; |
| 10282 | const state = try self.saveState(); | 10410 | const state = try self.saveState(); |
| 10283 | 10411 | ||
| 10284 | for (liveness_cond_br.else_deaths) |operand| try self.processDeath(operand); | 10412 | for (liveness_cond_br.else_deaths) |death| try self.processDeath(death); |
| 10285 | try self.genBody(body); | 10413 | try self.genBody(body); |
| 10286 | try self.restoreState(state, &.{}, .{ | 10414 | try self.restoreState(state, &.{}, .{ |
| 10287 | .emit_instructions = false, | 10415 | .emit_instructions = false, |
| ... | @@ -10292,12 +10420,14 @@ fn genTry( | ... | @@ -10292,12 +10420,14 @@ fn genTry( |
| 10292 | 10420 | ||
| 10293 | try self.performReloc(reloc); | 10421 | try self.performReloc(reloc); |
| 10294 | 10422 | ||
| 10295 | for (liveness_cond_br.then_deaths) |operand| try self.processDeath(operand); | 10423 | for (liveness_cond_br.then_deaths) |death| try self.processDeath(death); |
| 10296 | 10424 | ||
| 10297 | const result = if (self.liveness.isUnused(inst)) | 10425 | const result = if (self.liveness.isUnused(inst)) |
| 10298 | .unreach | 10426 | .unreach |
| 10427 | else if (operand_is_ptr) | ||
| 10428 | try self.genUnwrapErrUnionPayloadPtrMir(inst, operand_ty, operand_mcv) | ||
| 10299 | else | 10429 | else |
| 10300 | try self.genUnwrapErrorUnionPayloadMir(inst, err_union_ty, err_union_mcv); | 10430 | try self.genUnwrapErrUnionPayloadMir(inst, operand_ty, operand_mcv); |
| 10301 | return result; | 10431 | return result; |
| 10302 | } | 10432 | } |
| 10303 | 10433 | ||
| ... | @@ -10348,12 +10478,12 @@ fn genCondBrMir(self: *Self, ty: Type, mcv: MCValue) !Mir.Inst.Index { | ... | @@ -10348,12 +10478,12 @@ fn genCondBrMir(self: *Self, ty: Type, mcv: MCValue) !Mir.Inst.Index { |
| 10348 | switch (mcv) { | 10478 | switch (mcv) { |
| 10349 | .eflags => |cc| { | 10479 | .eflags => |cc| { |
| 10350 | // Here we map the opposites since the jump is to the false branch. | 10480 | // Here we map the opposites since the jump is to the false branch. |
| 10351 | return self.asmJccReloc(undefined, cc.negate()); | 10481 | return self.asmJccReloc(cc.negate(), undefined); |
| 10352 | }, | 10482 | }, |
| 10353 | .register => |reg| { | 10483 | .register => |reg| { |
| 10354 | try self.spillEflagsIfOccupied(); | 10484 | try self.spillEflagsIfOccupied(); |
| 10355 | try self.asmRegisterImmediate(.{ ._, .@"test" }, reg, Immediate.u(1)); | 10485 | try self.asmRegisterImmediate(.{ ._, .@"test" }, reg, Immediate.u(1)); |
| 10356 | return self.asmJccReloc(undefined, .e); | 10486 | return self.asmJccReloc(.e, undefined); |
| 10357 | }, | 10487 | }, |
| 10358 | .immediate, | 10488 | .immediate, |
| 10359 | .load_frame, | 10489 | .load_frame, |
| ... | @@ -10391,7 +10521,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -10391,7 +10521,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { |
| 10391 | self.scope_generation += 1; | 10521 | self.scope_generation += 1; |
| 10392 | const state = try self.saveState(); | 10522 | const state = try self.saveState(); |
| 10393 | 10523 | ||
| 10394 | for (liveness_cond_br.then_deaths) |operand| try self.processDeath(operand); | 10524 | for (liveness_cond_br.then_deaths) |death| try self.processDeath(death); |
| 10395 | try self.genBody(then_body); | 10525 | try self.genBody(then_body); |
| 10396 | try self.restoreState(state, &.{}, .{ | 10526 | try self.restoreState(state, &.{}, .{ |
| 10397 | .emit_instructions = false, | 10527 | .emit_instructions = false, |
| ... | @@ -10402,7 +10532,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -10402,7 +10532,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { |
| 10402 | 10532 | ||
| 10403 | try self.performReloc(reloc); | 10533 | try self.performReloc(reloc); |
| 10404 | 10534 | ||
| 10405 | for (liveness_cond_br.else_deaths) |operand| try self.processDeath(operand); | 10535 | for (liveness_cond_br.else_deaths) |death| try self.processDeath(death); |
| 10406 | try self.genBody(else_body); | 10536 | try self.genBody(else_body); |
| 10407 | try self.restoreState(state, &.{}, .{ | 10537 | try self.restoreState(state, &.{}, .{ |
| 10408 | .emit_instructions = false, | 10538 | .emit_instructions = false, |
| ... | @@ -10517,11 +10647,11 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC | ... | @@ -10517,11 +10647,11 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC |
| 10517 | 10647 | ||
| 10518 | fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) !MCValue { | 10648 | fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) !MCValue { |
| 10519 | const mod = self.bin_file.options.module.?; | 10649 | const mod = self.bin_file.options.module.?; |
| 10520 | try self.spillEflagsIfOccupied(); | ||
| 10521 | |||
| 10522 | const opt_ty = ptr_ty.childType(mod); | 10650 | const opt_ty = ptr_ty.childType(mod); |
| 10523 | const pl_ty = opt_ty.optionalChild(mod); | 10651 | const pl_ty = opt_ty.optionalChild(mod); |
| 10524 | 10652 | ||
| 10653 | try self.spillEflagsIfOccupied(); | ||
| 10654 | |||
| 10525 | const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod)) | 10655 | const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod)) |
| 10526 | .{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(mod) else pl_ty } | 10656 | .{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(mod) else pl_ty } |
| 10527 | else | 10657 | else |
| ... | @@ -10548,27 +10678,24 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) | ... | @@ -10548,27 +10678,24 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) |
| 10548 | return .{ .eflags = .e }; | 10678 | return .{ .eflags = .e }; |
| 10549 | } | 10679 | } |
| 10550 | 10680 | ||
| 10551 | fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, ty: Type, operand: MCValue) !MCValue { | 10681 | fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, eu_ty: Type, eu_mcv: MCValue) !MCValue { |
| 10552 | const mod = self.bin_file.options.module.?; | 10682 | const mod = self.bin_file.options.module.?; |
| 10553 | const err_type = ty.errorUnionSet(mod); | 10683 | const err_ty = eu_ty.errorUnionSet(mod); |
| 10554 | 10684 | if (err_ty.errorSetIsEmpty(mod)) return MCValue{ .immediate = 0 }; // always false | |
| 10555 | if (err_type.errorSetIsEmpty(mod)) { | ||
| 10556 | return MCValue{ .immediate = 0 }; // always false | ||
| 10557 | } | ||
| 10558 | 10685 | ||
| 10559 | try self.spillEflagsIfOccupied(); | 10686 | try self.spillEflagsIfOccupied(); |
| 10560 | 10687 | ||
| 10561 | const err_off = errUnionErrorOffset(ty.errorUnionPayload(mod), mod); | 10688 | const err_off: u31 = @intCast(errUnionErrorOffset(eu_ty.errorUnionPayload(mod), mod)); |
| 10562 | switch (operand) { | 10689 | switch (eu_mcv) { |
| 10563 | .register => |reg| { | 10690 | .register => |reg| { |
| 10564 | const eu_lock = self.register_manager.lockReg(reg); | 10691 | const eu_lock = self.register_manager.lockReg(reg); |
| 10565 | defer if (eu_lock) |lock| self.register_manager.unlockReg(lock); | 10692 | defer if (eu_lock) |lock| self.register_manager.unlockReg(lock); |
| 10566 | 10693 | ||
| 10567 | const tmp_reg = try self.copyToTmpRegister(ty, operand); | 10694 | const tmp_reg = try self.copyToTmpRegister(eu_ty, eu_mcv); |
| 10568 | if (err_off > 0) { | 10695 | if (err_off > 0) { |
| 10569 | try self.genShiftBinOpMir( | 10696 | try self.genShiftBinOpMir( |
| 10570 | .{ ._r, .sh }, | 10697 | .{ ._r, .sh }, |
| 10571 | ty, | 10698 | eu_ty, |
| 10572 | .{ .register = tmp_reg }, | 10699 | .{ .register = tmp_reg }, |
| 10573 | .{ .immediate = @as(u6, @intCast(err_off * 8)) }, | 10700 | .{ .immediate = @as(u6, @intCast(err_off * 8)) }, |
| 10574 | ); | 10701 | ); |
| ... | @@ -10587,19 +10714,63 @@ fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, ty: Type, operand: MCValue) ! | ... | @@ -10587,19 +10714,63 @@ fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, ty: Type, operand: MCValue) ! |
| 10587 | Type.anyerror, | 10714 | Type.anyerror, |
| 10588 | .{ .load_frame = .{ | 10715 | .{ .load_frame = .{ |
| 10589 | .index = frame_addr.index, | 10716 | .index = frame_addr.index, |
| 10590 | .off = frame_addr.off + @as(i32, @intCast(err_off)), | 10717 | .off = frame_addr.off + err_off, |
| 10591 | } }, | 10718 | } }, |
| 10592 | .{ .immediate = 0 }, | 10719 | .{ .immediate = 0 }, |
| 10593 | ), | 10720 | ), |
| 10594 | else => return self.fail("TODO implement isErr for {}", .{operand}), | 10721 | else => return self.fail("TODO implement isErr for {}", .{eu_mcv}), |
| 10595 | } | 10722 | } |
| 10596 | 10723 | ||
| 10597 | if (maybe_inst) |inst| self.eflags_inst = inst; | 10724 | if (maybe_inst) |inst| self.eflags_inst = inst; |
| 10598 | return MCValue{ .eflags = .a }; | 10725 | return MCValue{ .eflags = .a }; |
| 10599 | } | 10726 | } |
| 10600 | 10727 | ||
| 10601 | fn isNonErr(self: *Self, inst: Air.Inst.Index, ty: Type, operand: MCValue) !MCValue { | 10728 | fn isErrPtr(self: *Self, maybe_inst: ?Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) !MCValue { |
| 10602 | const is_err_res = try self.isErr(inst, ty, operand); | 10729 | const mod = self.bin_file.options.module.?; |
| 10730 | const eu_ty = ptr_ty.childType(mod); | ||
| 10731 | const err_ty = eu_ty.errorUnionSet(mod); | ||
| 10732 | if (err_ty.errorSetIsEmpty(mod)) return MCValue{ .immediate = 0 }; // always false | ||
| 10733 | |||
| 10734 | try self.spillEflagsIfOccupied(); | ||
| 10735 | |||
| 10736 | const ptr_reg = switch (ptr_mcv) { | ||
| 10737 | .register => |reg| reg, | ||
| 10738 | else => try self.copyToTmpRegister(ptr_ty, ptr_mcv), | ||
| 10739 | }; | ||
| 10740 | const ptr_lock = self.register_manager.lockReg(ptr_reg); | ||
| 10741 | defer if (ptr_lock) |lock| self.register_manager.unlockReg(lock); | ||
| 10742 | |||
| 10743 | const err_off: u31 = @intCast(errUnionErrorOffset(eu_ty.errorUnionPayload(mod), mod)); | ||
| 10744 | try self.asmMemoryImmediate( | ||
| 10745 | .{ ._, .cmp }, | ||
| 10746 | Memory.sib(self.memPtrSize(Type.anyerror), .{ | ||
| 10747 | .base = .{ .reg = ptr_reg }, | ||
| 10748 | .disp = err_off, | ||
| 10749 | }), | ||
| 10750 | Immediate.u(0), | ||
| 10751 | ); | ||
| 10752 | |||
| 10753 | if (maybe_inst) |inst| self.eflags_inst = inst; | ||
| 10754 | return MCValue{ .eflags = .a }; | ||
| 10755 | } | ||
| 10756 | |||
| 10757 | fn isNonErr(self: *Self, inst: Air.Inst.Index, eu_ty: Type, eu_mcv: MCValue) !MCValue { | ||
| 10758 | const is_err_res = try self.isErr(inst, eu_ty, eu_mcv); | ||
| 10759 | switch (is_err_res) { | ||
| 10760 | .eflags => |cc| { | ||
| 10761 | assert(cc == .a); | ||
| 10762 | return MCValue{ .eflags = cc.negate() }; | ||
| 10763 | }, | ||
| 10764 | .immediate => |imm| { | ||
| 10765 | assert(imm == 0); | ||
| 10766 | return MCValue{ .immediate = @intFromBool(imm == 0) }; | ||
| 10767 | }, | ||
| 10768 | else => unreachable, | ||
| 10769 | } | ||
| 10770 | } | ||
| 10771 | |||
| 10772 | fn isNonErrPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) !MCValue { | ||
| 10773 | const is_err_res = try self.isErrPtr(inst, ptr_ty, ptr_mcv); | ||
| 10603 | switch (is_err_res) { | 10774 | switch (is_err_res) { |
| 10604 | .eflags => |cc| { | 10775 | .eflags => |cc| { |
| 10605 | assert(cc == .a); | 10776 | assert(cc == .a); |
| ... | @@ -10607,7 +10778,7 @@ fn isNonErr(self: *Self, inst: Air.Inst.Index, ty: Type, operand: MCValue) !MCVa | ... | @@ -10607,7 +10778,7 @@ fn isNonErr(self: *Self, inst: Air.Inst.Index, ty: Type, operand: MCValue) !MCVa |
| 10607 | }, | 10778 | }, |
| 10608 | .immediate => |imm| { | 10779 | .immediate => |imm| { |
| 10609 | assert(imm == 0); | 10780 | assert(imm == 0); |
| 10610 | return MCValue{ .immediate = 1 }; | 10781 | return MCValue{ .immediate = @intFromBool(imm == 0) }; |
| 10611 | }, | 10782 | }, |
| 10612 | else => unreachable, | 10783 | else => unreachable, |
| 10613 | } | 10784 | } |
| ... | @@ -10660,29 +10831,10 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -10660,29 +10831,10 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index) !void { |
| 10660 | } | 10831 | } |
| 10661 | 10832 | ||
| 10662 | fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void { | 10833 | fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 10663 | const mod = self.bin_file.options.module.?; | ||
| 10664 | const un_op = self.air.instructions.items(.data)[inst].un_op; | 10834 | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| 10665 | 10835 | const operand = try self.resolveInst(un_op); | |
| 10666 | const operand_ptr = try self.resolveInst(un_op); | 10836 | const ty = self.typeOf(un_op); |
| 10667 | const operand_ptr_lock: ?RegisterLock = switch (operand_ptr) { | 10837 | const result = try self.isErrPtr(inst, ty, operand); |
| 10668 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), | ||
| 10669 | else => null, | ||
| 10670 | }; | ||
| 10671 | defer if (operand_ptr_lock) |lock| self.register_manager.unlockReg(lock); | ||
| 10672 | |||
| 10673 | const operand: MCValue = blk: { | ||
| 10674 | if (self.reuseOperand(inst, un_op, 0, operand_ptr)) { | ||
| 10675 | // The MCValue that holds the pointer can be re-used as the value. | ||
| 10676 | break :blk operand_ptr; | ||
| 10677 | } else { | ||
| 10678 | break :blk try self.allocRegOrMem(inst, true); | ||
| 10679 | } | ||
| 10680 | }; | ||
| 10681 | const ptr_ty = self.typeOf(un_op); | ||
| 10682 | try self.load(operand, ptr_ty, operand_ptr); | ||
| 10683 | |||
| 10684 | const result = try self.isErr(inst, ptr_ty.childType(mod), operand); | ||
| 10685 | |||
| 10686 | return self.finishAir(inst, result, .{ un_op, .none, .none }); | 10838 | return self.finishAir(inst, result, .{ un_op, .none, .none }); |
| 10687 | } | 10839 | } |
| 10688 | 10840 | ||
| ... | @@ -10695,29 +10847,10 @@ fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -10695,29 +10847,10 @@ fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void { |
| 10695 | } | 10847 | } |
| 10696 | 10848 | ||
| 10697 | fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void { | 10849 | fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 10698 | const mod = self.bin_file.options.module.?; | ||
| 10699 | const un_op = self.air.instructions.items(.data)[inst].un_op; | 10850 | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| 10700 | 10851 | const operand = try self.resolveInst(un_op); | |
| 10701 | const operand_ptr = try self.resolveInst(un_op); | 10852 | const ty = self.typeOf(un_op); |
| 10702 | const operand_ptr_lock: ?RegisterLock = switch (operand_ptr) { | 10853 | const result = try self.isNonErrPtr(inst, ty, operand); |
| 10703 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), | ||
| 10704 | else => null, | ||
| 10705 | }; | ||
| 10706 | defer if (operand_ptr_lock) |lock| self.register_manager.unlockReg(lock); | ||
| 10707 | |||
| 10708 | const operand: MCValue = blk: { | ||
| 10709 | if (self.reuseOperand(inst, un_op, 0, operand_ptr)) { | ||
| 10710 | // The MCValue that holds the pointer can be re-used as the value. | ||
| 10711 | break :blk operand_ptr; | ||
| 10712 | } else { | ||
| 10713 | break :blk try self.allocRegOrMem(inst, true); | ||
| 10714 | } | ||
| 10715 | }; | ||
| 10716 | const ptr_ty = self.typeOf(un_op); | ||
| 10717 | try self.load(operand, ptr_ty, operand_ptr); | ||
| 10718 | |||
| 10719 | const result = try self.isNonErr(inst, ptr_ty.childType(mod), operand); | ||
| 10720 | |||
| 10721 | return self.finishAir(inst, result, .{ un_op, .none, .none }); | 10854 | return self.finishAir(inst, result, .{ un_op, .none, .none }); |
| 10722 | } | 10855 | } |
| 10723 | 10856 | ||
| ... | @@ -10810,7 +10943,7 @@ fn airSwitchBr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -10810,7 +10943,7 @@ fn airSwitchBr(self: *Self, inst: Air.Inst.Index) !void { |
| 10810 | for (items, relocs, 0..) |item, *reloc, i| { | 10943 | for (items, relocs, 0..) |item, *reloc, i| { |
| 10811 | const item_mcv = try self.resolveInst(item); | 10944 | const item_mcv = try self.resolveInst(item); |
| 10812 | try self.genBinOpMir(.{ ._, .cmp }, condition_ty, condition, item_mcv); | 10945 | try self.genBinOpMir(.{ ._, .cmp }, condition_ty, condition, item_mcv); |
| 10813 | reloc.* = try self.asmJccReloc(undefined, if (i < relocs.len - 1) .e else .ne); | 10946 | reloc.* = try self.asmJccReloc(if (i < relocs.len - 1) .e else .ne, undefined); |
| 10814 | } | 10947 | } |
| 10815 | 10948 | ||
| 10816 | for (liveness.deaths[case_i]) |operand| try self.processDeath(operand); | 10949 | for (liveness.deaths[case_i]) |operand| try self.processDeath(operand); |
| ... | @@ -11210,6 +11343,15 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -11210,6 +11343,15 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 11210 | mnem_size = null; | 11343 | mnem_size = null; |
| 11211 | break :mnem std.meta.stringToEnum(Instruction.Mnemonic, mnem_str); | 11344 | break :mnem std.meta.stringToEnum(Instruction.Mnemonic, mnem_str); |
| 11212 | } orelse return self.fail("invalid mnemonic: '{s}'", .{mnem_str}); | 11345 | } orelse return self.fail("invalid mnemonic: '{s}'", .{mnem_str}); |
| 11346 | if (@as(?Memory.PtrSize, switch (mnem_tag) { | ||
| 11347 | .fldenv, .fnstenv, .fstenv => .none, | ||
| 11348 | .ldmxcsr, .stmxcsr, .vldmxcsr, .vstmxcsr => .dword, | ||
| 11349 | else => null, | ||
| 11350 | })) |fixed_mnem_size| { | ||
| 11351 | if (mnem_size) |size| if (size != fixed_mnem_size) | ||
| 11352 | return self.fail("invalid size: '{s}'", .{mnem_str}); | ||
| 11353 | mnem_size = fixed_mnem_size; | ||
| 11354 | } | ||
| 11213 | const mnem_name = @tagName(mnem_tag); | 11355 | const mnem_name = @tagName(mnem_tag); |
| 11214 | const mnem_fixed_tag: Mir.Inst.FixedTag = for (std.enums.values(Mir.Inst.Fixes)) |fixes| { | 11356 | const mnem_fixed_tag: Mir.Inst.FixedTag = for (std.enums.values(Mir.Inst.Fixes)) |fixes| { |
| 11215 | const fixes_name = @tagName(fixes); | 11357 | const fixes_name = @tagName(fixes); |
| ... | @@ -11359,8 +11501,31 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -11359,8 +11501,31 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 11359 | if (sib_it.next()) |_| return self.fail("invalid memory operand: '{s}'", .{op_str}); | 11501 | if (sib_it.next()) |_| return self.fail("invalid memory operand: '{s}'", .{op_str}); |
| 11360 | op.* = .{ .mem = Memory.sib(mnem_size orelse | 11502 | op.* = .{ .mem = Memory.sib(mnem_size orelse |
| 11361 | return self.fail("unknown size: '{s}'", .{op_str}), .{ | 11503 | return self.fail("unknown size: '{s}'", .{op_str}), .{ |
| 11362 | .disp = if (open > 0) std.fmt.parseInt(i32, op_str[0..open], 0) catch | 11504 | .disp = if (mem.startsWith(u8, op_str[0..open], "%[") and |
| 11363 | return self.fail("invalid displacement: '{s}'", .{op_str}) else 0, | 11505 | mem.endsWith(u8, op_str[0..open], "]")) |
| 11506 | disp: { | ||
| 11507 | const colon = mem.indexOfScalarPos(u8, op_str[0..open], "%[".len, ':'); | ||
| 11508 | const modifier = if (colon) |colon_pos| | ||
| 11509 | op_str[colon_pos + ":".len .. open - "]".len] | ||
| 11510 | else | ||
| 11511 | ""; | ||
| 11512 | break :disp switch (args.items[ | ||
| 11513 | arg_map.get(op_str["%[".len .. colon orelse open - "]".len]) orelse | ||
| 11514 | return self.fail("no matching constraint: '{s}'", .{op_str}) | ||
| 11515 | ]) { | ||
| 11516 | .immediate => |imm| if (mem.eql(u8, modifier, "") or | ||
| 11517 | mem.eql(u8, modifier, "c")) | ||
| 11518 | math.cast(i32, @as(i64, @bitCast(imm))) orelse | ||
| 11519 | return self.fail("invalid displacement: '{s}'", .{op_str}) | ||
| 11520 | else | ||
| 11521 | return self.fail("invalid modifier: '{s}'", .{modifier}), | ||
| 11522 | else => return self.fail("invalid constraint: '{s}'", .{op_str}), | ||
| 11523 | }; | ||
| 11524 | } else if (open > 0) | ||
| 11525 | std.fmt.parseInt(i32, op_str[0..open], 0) catch | ||
| 11526 | return self.fail("invalid displacement: '{s}'", .{op_str}) | ||
| 11527 | else | ||
| 11528 | 0, | ||
| 11364 | .base = if (base_str.len > 0) .{ .reg = parseRegName(base_str["%%".len..]) orelse | 11529 | .base = if (base_str.len > 0) .{ .reg = parseRegName(base_str["%%".len..]) orelse |
| 11365 | return self.fail("invalid base register: '{s}'", .{base_str}) } else .none, | 11530 | return self.fail("invalid base register: '{s}'", .{base_str}) } else .none, |
| 11366 | .scale_index = if (index_str.len > 0) .{ | 11531 | .scale_index = if (index_str.len > 0) .{ |
| ... | @@ -11840,7 +12005,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr | ... | @@ -11840,7 +12005,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 11840 | .reserved_frame, | 12005 | .reserved_frame, |
| 11841 | => unreachable, | 12006 | => unreachable, |
| 11842 | .undef => {}, | 12007 | .undef => {}, |
| 11843 | .eflags => |cc| try self.asmSetccRegister(dst_reg.to8(), cc), | 12008 | .eflags => |cc| try self.asmSetccRegister(cc, dst_reg.to8()), |
| 11844 | .immediate => |imm| { | 12009 | .immediate => |imm| { |
| 11845 | if (imm == 0) { | 12010 | if (imm == 0) { |
| 11846 | // 32-bit moves zero-extend to 64-bit, so xoring the 32-bit | 12011 | // 32-bit moves zero-extend to 64-bit, so xoring the 32-bit |
| ... | @@ -12110,7 +12275,7 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal | ... | @@ -12110,7 +12275,7 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal |
| 12110 | ); | 12275 | ); |
| 12111 | }, | 12276 | }, |
| 12112 | }, | 12277 | }, |
| 12113 | .eflags => |cc| try self.asmSetccMemory(Memory.sib(.byte, .{ .base = base, .disp = disp }), cc), | 12278 | .eflags => |cc| try self.asmSetccMemory(cc, Memory.sib(.byte, .{ .base = base, .disp = disp })), |
| 12114 | .register => |src_reg| try (try self.moveStrategy(ty, switch (base) { | 12279 | .register => |src_reg| try (try self.moveStrategy(ty, switch (base) { |
| 12115 | .none => ty.abiAlignment(mod).check(@as(u32, @bitCast(disp))), | 12280 | .none => ty.abiAlignment(mod).check(@as(u32, @bitCast(disp))), |
| 12116 | .reg => |reg| switch (reg) { | 12281 | .reg => |reg| switch (reg) { |
| ... | @@ -12870,7 +13035,7 @@ fn atomicOp( | ... | @@ -12870,7 +13035,7 @@ fn atomicOp( |
| 12870 | ptr_mem, | 13035 | ptr_mem, |
| 12871 | registerAlias(tmp_reg, val_abi_size), | 13036 | registerAlias(tmp_reg, val_abi_size), |
| 12872 | ); | 13037 | ); |
| 12873 | _ = try self.asmJccReloc(loop, .ne); | 13038 | _ = try self.asmJccReloc(.ne, loop); |
| 12874 | return if (unused) .unreach else .{ .register = .rax }; | 13039 | return if (unused) .unreach else .{ .register = .rax }; |
| 12875 | } else { | 13040 | } else { |
| 12876 | try self.asmRegisterMemory(.{ ._, .mov }, .rax, Memory.sib(.qword, .{ | 13041 | try self.asmRegisterMemory(.{ ._, .mov }, .rax, Memory.sib(.qword, .{ |
| ... | @@ -12932,7 +13097,7 @@ fn atomicOp( | ... | @@ -12932,7 +13097,7 @@ fn atomicOp( |
| 12932 | }), | 13097 | }), |
| 12933 | }; | 13098 | }; |
| 12934 | try self.asmMemory(.{ .@"lock _16b", .cmpxchg }, ptr_mem); | 13099 | try self.asmMemory(.{ .@"lock _16b", .cmpxchg }, ptr_mem); |
| 12935 | _ = try self.asmJccReloc(loop, .ne); | 13100 | _ = try self.asmJccReloc(.ne, loop); |
| 12936 | 13101 | ||
| 12937 | if (unused) return .unreach; | 13102 | if (unused) return .unreach; |
| 12938 | const dst_mcv = try self.allocTempRegOrMem(val_ty, false); | 13103 | const dst_mcv = try self.allocTempRegOrMem(val_ty, false); |
| ... | @@ -13084,7 +13249,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { | ... | @@ -13084,7 +13249,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { |
| 13084 | 13249 | ||
| 13085 | try self.genSetReg(len_reg, Type.usize, len); | 13250 | try self.genSetReg(len_reg, Type.usize, len); |
| 13086 | 13251 | ||
| 13087 | const skip_reloc = try self.asmJccReloc(undefined, .z); | 13252 | const skip_reloc = try self.asmJccReloc(.z, undefined); |
| 13088 | try self.store(slice_ptr_ty, ptr, src_val); | 13253 | try self.store(slice_ptr_ty, ptr, src_val); |
| 13089 | 13254 | ||
| 13090 | const second_elem_ptr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); | 13255 | const second_elem_ptr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); |
| ... | @@ -14041,7 +14206,7 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -14041,7 +14206,7 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { |
| 14041 | try self.asmRegisterImmediate(.{ ._, .cmp }, offset_reg, Immediate.u( | 14206 | try self.asmRegisterImmediate(.{ ._, .cmp }, offset_reg, Immediate.u( |
| 14042 | abi.SysV.c_abi_int_param_regs.len * 8, | 14207 | abi.SysV.c_abi_int_param_regs.len * 8, |
| 14043 | )); | 14208 | )); |
| 14044 | const mem_reloc = try self.asmJccReloc(undefined, .ae); | 14209 | const mem_reloc = try self.asmJccReloc(.ae, undefined); |
| 14045 | 14210 | ||
| 14046 | try self.genSetReg(addr_reg, ptr_anyopaque_ty, reg_save_area); | 14211 | try self.genSetReg(addr_reg, ptr_anyopaque_ty, reg_save_area); |
| 14047 | if (!unused) | 14212 | if (!unused) |
| ... | @@ -14080,7 +14245,7 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -14080,7 +14245,7 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { |
| 14080 | try self.asmRegisterImmediate(.{ ._, .cmp }, offset_reg, Immediate.u( | 14245 | try self.asmRegisterImmediate(.{ ._, .cmp }, offset_reg, Immediate.u( |
| 14081 | abi.SysV.c_abi_int_param_regs.len * 8 + abi.SysV.c_abi_sse_param_regs.len * 16, | 14246 | abi.SysV.c_abi_int_param_regs.len * 8 + abi.SysV.c_abi_sse_param_regs.len * 16, |
| 14082 | )); | 14247 | )); |
| 14083 | const mem_reloc = try self.asmJccReloc(undefined, .ae); | 14248 | const mem_reloc = try self.asmJccReloc(.ae, undefined); |
| 14084 | 14249 | ||
| 14085 | try self.genSetReg(addr_reg, ptr_anyopaque_ty, reg_save_area); | 14250 | try self.genSetReg(addr_reg, ptr_anyopaque_ty, reg_save_area); |
| 14086 | if (!unused) | 14251 | if (!unused) |
src/arch/x86_64/Disassembler.zig+1-1| ... | @@ -38,7 +38,7 @@ pub fn next(dis: *Disassembler) Error!?Instruction { | ... | @@ -38,7 +38,7 @@ pub fn next(dis: *Disassembler) Error!?Instruction { |
| 38 | 38 | ||
| 39 | const enc = try dis.parseEncoding(prefixes) orelse return error.UnknownOpcode; | 39 | const enc = try dis.parseEncoding(prefixes) orelse return error.UnknownOpcode; |
| 40 | switch (enc.data.op_en) { | 40 | switch (enc.data.op_en) { |
| 41 | .np => return inst(enc, .{}), | 41 | .zo => return inst(enc, .{}), |
| 42 | .d, .i => { | 42 | .d, .i => { |
| 43 | const imm = try dis.parseImm(enc.data.ops[0]); | 43 | const imm = try dis.parseImm(enc.data.ops[0]); |
| 44 | return inst(enc, .{ | 44 | return inst(enc, .{ |
src/arch/x86_64/Encoding.zig+13-8| ... | @@ -166,7 +166,7 @@ pub fn format( | ... | @@ -166,7 +166,7 @@ pub fn format( |
| 166 | for (opc) |byte| try writer.print("{x:0>2} ", .{byte}); | 166 | for (opc) |byte| try writer.print("{x:0>2} ", .{byte}); |
| 167 | 167 | ||
| 168 | switch (encoding.data.op_en) { | 168 | switch (encoding.data.op_en) { |
| 169 | .np, .fd, .td, .i, .zi, .d => {}, | 169 | .zo, .fd, .td, .i, .zi, .d => {}, |
| 170 | .o, .oi => { | 170 | .o, .oi => { |
| 171 | const tag = switch (encoding.data.ops[0]) { | 171 | const tag = switch (encoding.data.ops[0]) { |
| 172 | .r8 => "rb", | 172 | .r8 => "rb", |
| ... | @@ -203,7 +203,7 @@ pub fn format( | ... | @@ -203,7 +203,7 @@ pub fn format( |
| 203 | try writer.print("{s} ", .{tag}); | 203 | try writer.print("{s} ", .{tag}); |
| 204 | }, | 204 | }, |
| 205 | .rvmr => try writer.writeAll("/is4 "), | 205 | .rvmr => try writer.writeAll("/is4 "), |
| 206 | .np, .fd, .td, .o, .m, .m1, .mc, .mr, .rm, .mrc, .rm0, .rvm, .mvr => {}, | 206 | .zo, .fd, .td, .o, .m, .m1, .mc, .mr, .rm, .mrc, .rm0, .rvm, .mvr => {}, |
| 207 | } | 207 | } |
| 208 | 208 | ||
| 209 | try writer.print("{s} ", .{@tagName(encoding.mnemonic)}); | 209 | try writer.print("{s} ", .{@tagName(encoding.mnemonic)}); |
| ... | @@ -246,7 +246,7 @@ pub const Mnemonic = enum { | ... | @@ -246,7 +246,7 @@ pub const Mnemonic = enum { |
| 246 | movsx, movsxd, movzx, mul, | 246 | movsx, movsxd, movzx, mul, |
| 247 | neg, nop, not, | 247 | neg, nop, not, |
| 248 | @"or", | 248 | @"or", |
| 249 | pause, pop, popcnt, push, | 249 | pause, pop, popcnt, popfq, push, pushfq, |
| 250 | rcl, rcr, ret, rol, ror, | 250 | rcl, rcr, ret, rol, ror, |
| 251 | sal, sar, sbb, | 251 | sal, sar, sbb, |
| 252 | scas, scasb, scasd, scasq, scasw, | 252 | scas, scasb, scasd, scasq, scasw, |
| ... | @@ -260,7 +260,7 @@ pub const Mnemonic = enum { | ... | @@ -260,7 +260,7 @@ pub const Mnemonic = enum { |
| 260 | ud2, | 260 | ud2, |
| 261 | xadd, xchg, xgetbv, xor, | 261 | xadd, xchg, xgetbv, xor, |
| 262 | // X87 | 262 | // X87 |
| 263 | fabs, fchs, ffree, fisttp, fld, fst, fstp, | 263 | fabs, fchs, ffree, fisttp, fld, fldenv, fnstenv, fst, fstenv, fstp, |
| 264 | // MMX | 264 | // MMX |
| 265 | movd, movq, | 265 | movd, movq, |
| 266 | packssdw, packsswb, packuswb, | 266 | packssdw, packsswb, packuswb, |
| ... | @@ -280,6 +280,7 @@ pub const Mnemonic = enum { | ... | @@ -280,6 +280,7 @@ pub const Mnemonic = enum { |
| 280 | cmpps, cmpss, | 280 | cmpps, cmpss, |
| 281 | cvtpi2ps, cvtps2pi, cvtsi2ss, cvtss2si, cvttps2pi, cvttss2si, | 281 | cvtpi2ps, cvtps2pi, cvtsi2ss, cvtss2si, cvttps2pi, cvttss2si, |
| 282 | divps, divss, | 282 | divps, divss, |
| 283 | ldmxcsr, | ||
| 283 | maxps, maxss, | 284 | maxps, maxss, |
| 284 | minps, minss, | 285 | minps, minss, |
| 285 | movaps, movhlps, movlhps, | 286 | movaps, movhlps, movlhps, |
| ... | @@ -291,6 +292,7 @@ pub const Mnemonic = enum { | ... | @@ -291,6 +292,7 @@ pub const Mnemonic = enum { |
| 291 | pmaxsw, pmaxub, pminsw, pminub, pmovmskb, | 292 | pmaxsw, pmaxub, pminsw, pminub, pmovmskb, |
| 292 | shufps, | 293 | shufps, |
| 293 | sqrtps, sqrtss, | 294 | sqrtps, sqrtss, |
| 295 | stmxcsr, | ||
| 294 | subps, subss, | 296 | subps, subss, |
| 295 | ucomiss, | 297 | ucomiss, |
| 296 | xorps, | 298 | xorps, |
| ... | @@ -358,6 +360,7 @@ pub const Mnemonic = enum { | ... | @@ -358,6 +360,7 @@ pub const Mnemonic = enum { |
| 358 | vdivpd, vdivps, vdivsd, vdivss, | 360 | vdivpd, vdivps, vdivsd, vdivss, |
| 359 | vextractf128, vextractps, | 361 | vextractf128, vextractps, |
| 360 | vinsertf128, vinsertps, | 362 | vinsertf128, vinsertps, |
| 363 | vldmxcsr, | ||
| 361 | vmaxpd, vmaxps, vmaxsd, vmaxss, | 364 | vmaxpd, vmaxps, vmaxsd, vmaxss, |
| 362 | vminpd, vminps, vminsd, vminss, | 365 | vminpd, vminps, vminsd, vminss, |
| 363 | vmovapd, vmovaps, | 366 | vmovapd, vmovaps, |
| ... | @@ -397,6 +400,7 @@ pub const Mnemonic = enum { | ... | @@ -397,6 +400,7 @@ pub const Mnemonic = enum { |
| 397 | vroundpd, vroundps, vroundsd, vroundss, | 400 | vroundpd, vroundps, vroundsd, vroundss, |
| 398 | vshufpd, vshufps, | 401 | vshufpd, vshufps, |
| 399 | vsqrtpd, vsqrtps, vsqrtsd, vsqrtss, | 402 | vsqrtpd, vsqrtps, vsqrtsd, vsqrtss, |
| 403 | vstmxcsr, | ||
| 400 | vsubpd, vsubps, vsubsd, vsubss, | 404 | vsubpd, vsubps, vsubsd, vsubss, |
| 401 | vxorpd, vxorps, | 405 | vxorpd, vxorps, |
| 402 | // F16C | 406 | // F16C |
| ... | @@ -411,7 +415,7 @@ pub const Mnemonic = enum { | ... | @@ -411,7 +415,7 @@ pub const Mnemonic = enum { |
| 411 | 415 | ||
| 412 | pub const OpEn = enum { | 416 | pub const OpEn = enum { |
| 413 | // zig fmt: off | 417 | // zig fmt: off |
| 414 | np, | 418 | zo, |
| 415 | o, oi, | 419 | o, oi, |
| 416 | i, zi, | 420 | i, zi, |
| 417 | d, m, | 421 | d, m, |
| ... | @@ -481,6 +485,7 @@ pub const Op = enum { | ... | @@ -481,6 +485,7 @@ pub const Op = enum { |
| 481 | .mem => |mem| switch (mem) { | 485 | .mem => |mem| switch (mem) { |
| 482 | .moffs => .moffs, | 486 | .moffs => .moffs, |
| 483 | .sib, .rip => switch (mem.bitSize()) { | 487 | .sib, .rip => switch (mem.bitSize()) { |
| 488 | 0 => .m, | ||
| 484 | 8 => .m8, | 489 | 8 => .m8, |
| 485 | 16 => .m16, | 490 | 16 => .m16, |
| 486 | 32 => .m32, | 491 | 32 => .m32, |
| ... | @@ -610,7 +615,7 @@ pub const Op = enum { | ... | @@ -610,7 +615,7 @@ pub const Op = enum { |
| 610 | .imm8s, .imm16s, .imm32s, | 615 | .imm8s, .imm16s, .imm32s, |
| 611 | .rel8, .rel16, .rel32, | 616 | .rel8, .rel16, .rel32, |
| 612 | .unity, | 617 | .unity, |
| 613 | => true, | 618 | => true, |
| 614 | else => false, | 619 | else => false, |
| 615 | }; | 620 | }; |
| 616 | // zig fmt: on | 621 | // zig fmt: on |
| ... | @@ -626,7 +631,7 @@ pub const Op = enum { | ... | @@ -626,7 +631,7 @@ pub const Op = enum { |
| 626 | .mm_m64, | 631 | .mm_m64, |
| 627 | .xmm_m32, .xmm_m64, .xmm_m128, | 632 | .xmm_m32, .xmm_m64, .xmm_m128, |
| 628 | .ymm_m256, | 633 | .ymm_m256, |
| 629 | => true, | 634 | => true, |
| 630 | else => false, | 635 | else => false, |
| 631 | }; | 636 | }; |
| 632 | // zig fmt: on | 637 | // zig fmt: on |
| ... | @@ -657,7 +662,7 @@ pub const Op = enum { | ... | @@ -657,7 +662,7 @@ pub const Op = enum { |
| 657 | /// Given an operand `op` checks if `target` is a subset for the purposes of the encoding. | 662 | /// Given an operand `op` checks if `target` is a subset for the purposes of the encoding. |
| 658 | pub fn isSubset(op: Op, target: Op) bool { | 663 | pub fn isSubset(op: Op, target: Op) bool { |
| 659 | switch (op) { | 664 | switch (op) { |
| 660 | .m, .o16, .o32, .o64 => unreachable, | 665 | .o16, .o32, .o64 => unreachable, |
| 661 | .moffs, .sreg => return op == target, | 666 | .moffs, .sreg => return op == target, |
| 662 | .none => switch (target) { | 667 | .none => switch (target) { |
| 663 | .o16, .o32, .o64, .none => return true, | 668 | .o16, .o32, .o64, .none => return true, |
src/arch/x86_64/Mir.zig+20-1| ... | @@ -394,8 +394,12 @@ pub const Inst = struct { | ... | @@ -394,8 +394,12 @@ pub const Inst = struct { |
| 394 | pop, | 394 | pop, |
| 395 | /// Return the count of number of bits set to 1 | 395 | /// Return the count of number of bits set to 1 |
| 396 | popcnt, | 396 | popcnt, |
| 397 | /// Pop stack into EFLAGS register | ||
| 398 | popfq, | ||
| 397 | /// Push | 399 | /// Push |
| 398 | push, | 400 | push, |
| 401 | /// Push EFLAGS register onto the stack | ||
| 402 | pushfq, | ||
| 399 | /// Rotate left through carry | 403 | /// Rotate left through carry |
| 400 | /// Rotate right through carry | 404 | /// Rotate right through carry |
| 401 | rc, | 405 | rc, |
| ... | @@ -458,8 +462,14 @@ pub const Inst = struct { | ... | @@ -458,8 +462,14 @@ pub const Inst = struct { |
| 458 | istt, | 462 | istt, |
| 459 | /// Load floating-point value | 463 | /// Load floating-point value |
| 460 | ld, | 464 | ld, |
| 465 | /// Load x87 FPU environment | ||
| 466 | ldenv, | ||
| 467 | /// Store x87 FPU environment | ||
| 468 | nstenv, | ||
| 461 | /// Store floating-point value | 469 | /// Store floating-point value |
| 462 | st, | 470 | st, |
| 471 | /// Store x87 FPU environment | ||
| 472 | stenv, | ||
| 463 | 473 | ||
| 464 | /// Pack with signed saturation | 474 | /// Pack with signed saturation |
| 465 | ackssw, | 475 | ackssw, |
| ... | @@ -505,6 +515,11 @@ pub const Inst = struct { | ... | @@ -505,6 +515,11 @@ pub const Inst = struct { |
| 505 | /// Subtract packed unsigned integers with unsigned saturation | 515 | /// Subtract packed unsigned integers with unsigned saturation |
| 506 | subus, | 516 | subus, |
| 507 | 517 | ||
| 518 | /// Load MXCSR register | ||
| 519 | ldmxcsr, | ||
| 520 | /// Store MXCSR register state | ||
| 521 | stmxcsr, | ||
| 522 | |||
| 508 | /// Convert packed doubleword integers to packed single-precision floating-point values | 523 | /// Convert packed doubleword integers to packed single-precision floating-point values |
| 509 | /// Convert packed doubleword integers to packed double-precision floating-point values | 524 | /// Convert packed doubleword integers to packed double-precision floating-point values |
| 510 | cvtpi2, | 525 | cvtpi2, |
| ... | @@ -1079,9 +1094,13 @@ pub const RegisterList = struct { | ... | @@ -1079,9 +1094,13 @@ pub const RegisterList = struct { |
| 1079 | return self.bitset.iterator(options); | 1094 | return self.bitset.iterator(options); |
| 1080 | } | 1095 | } |
| 1081 | 1096 | ||
| 1082 | pub fn count(self: Self) u32 { | 1097 | pub fn count(self: Self) i32 { |
| 1083 | return @intCast(self.bitset.count()); | 1098 | return @intCast(self.bitset.count()); |
| 1084 | } | 1099 | } |
| 1100 | |||
| 1101 | pub fn size(self: Self) i32 { | ||
| 1102 | return @intCast(self.bitset.count() * 8); | ||
| 1103 | } | ||
| 1085 | }; | 1104 | }; |
| 1086 | 1105 | ||
| 1087 | pub const Imm32 = struct { | 1106 | pub const Imm32 = struct { |
src/arch/x86_64/bits.zig+13| ... | @@ -470,6 +470,7 @@ pub const Memory = union(enum) { | ... | @@ -470,6 +470,7 @@ pub const Memory = union(enum) { |
| 470 | }; | 470 | }; |
| 471 | 471 | ||
| 472 | pub const PtrSize = enum { | 472 | pub const PtrSize = enum { |
| 473 | none, | ||
| 473 | byte, | 474 | byte, |
| 474 | word, | 475 | word, |
| 475 | dword, | 476 | dword, |
| ... | @@ -508,6 +509,7 @@ pub const Memory = union(enum) { | ... | @@ -508,6 +509,7 @@ pub const Memory = union(enum) { |
| 508 | 509 | ||
| 509 | pub fn bitSize(s: PtrSize) u64 { | 510 | pub fn bitSize(s: PtrSize) u64 { |
| 510 | return switch (s) { | 511 | return switch (s) { |
| 512 | .none => 0, | ||
| 511 | .byte => 8, | 513 | .byte => 8, |
| 512 | .word => 16, | 514 | .word => 16, |
| 513 | .dword => 32, | 515 | .dword => 32, |
| ... | @@ -518,6 +520,17 @@ pub const Memory = union(enum) { | ... | @@ -518,6 +520,17 @@ pub const Memory = union(enum) { |
| 518 | .zword => 512, | 520 | .zword => 512, |
| 519 | }; | 521 | }; |
| 520 | } | 522 | } |
| 523 | |||
| 524 | pub fn format( | ||
| 525 | s: PtrSize, | ||
| 526 | comptime _: []const u8, | ||
| 527 | _: std.fmt.FormatOptions, | ||
| 528 | writer: anytype, | ||
| 529 | ) @TypeOf(writer).Error!void { | ||
| 530 | if (s == .none) return; | ||
| 531 | try writer.writeAll(@tagName(s)); | ||
| 532 | try writer.writeAll(" ptr"); | ||
| 533 | } | ||
| 521 | }; | 534 | }; |
| 522 | 535 | ||
| 523 | pub const Sib = struct { | 536 | pub const Sib = struct { |
src/arch/x86_64/encoder.zig+6-6| ... | @@ -102,7 +102,7 @@ pub const Instruction = struct { | ... | @@ -102,7 +102,7 @@ pub const Instruction = struct { |
| 102 | .reg => |reg| try writer.writeAll(@tagName(reg)), | 102 | .reg => |reg| try writer.writeAll(@tagName(reg)), |
| 103 | .mem => |mem| switch (mem) { | 103 | .mem => |mem| switch (mem) { |
| 104 | .rip => |rip| { | 104 | .rip => |rip| { |
| 105 | try writer.print("{s} ptr [rip", .{@tagName(rip.ptr_size)}); | 105 | try writer.print("{} [rip", .{rip.ptr_size}); |
| 106 | if (rip.disp != 0) try writer.print(" {c} 0x{x}", .{ | 106 | if (rip.disp != 0) try writer.print(" {c} 0x{x}", .{ |
| 107 | @as(u8, if (rip.disp < 0) '-' else '+'), | 107 | @as(u8, if (rip.disp < 0) '-' else '+'), |
| 108 | @abs(rip.disp), | 108 | @abs(rip.disp), |
| ... | @@ -110,7 +110,7 @@ pub const Instruction = struct { | ... | @@ -110,7 +110,7 @@ pub const Instruction = struct { |
| 110 | try writer.writeByte(']'); | 110 | try writer.writeByte(']'); |
| 111 | }, | 111 | }, |
| 112 | .sib => |sib| { | 112 | .sib => |sib| { |
| 113 | try writer.print("{s} ptr ", .{@tagName(sib.ptr_size)}); | 113 | try writer.print("{} ", .{sib.ptr_size}); |
| 114 | 114 | ||
| 115 | if (mem.isSegmentRegister()) { | 115 | if (mem.isSegmentRegister()) { |
| 116 | return writer.print("{s}:0x{x}", .{ @tagName(sib.base.reg), sib.disp }); | 116 | return writer.print("{s}:0x{x}", .{ @tagName(sib.base.reg), sib.disp }); |
| ... | @@ -222,7 +222,7 @@ pub const Instruction = struct { | ... | @@ -222,7 +222,7 @@ pub const Instruction = struct { |
| 222 | } | 222 | } |
| 223 | 223 | ||
| 224 | switch (data.op_en) { | 224 | switch (data.op_en) { |
| 225 | .np, .o => {}, | 225 | .zo, .o => {}, |
| 226 | .i, .d => try encodeImm(inst.ops[0].imm, data.ops[0], encoder), | 226 | .i, .d => try encodeImm(inst.ops[0].imm, data.ops[0], encoder), |
| 227 | .zi, .oi => try encodeImm(inst.ops[1].imm, data.ops[1], encoder), | 227 | .zi, .oi => try encodeImm(inst.ops[1].imm, data.ops[1], encoder), |
| 228 | .fd => try encoder.imm64(inst.ops[1].mem.moffs.offset), | 228 | .fd => try encoder.imm64(inst.ops[1].mem.moffs.offset), |
| ... | @@ -300,7 +300,7 @@ pub const Instruction = struct { | ... | @@ -300,7 +300,7 @@ pub const Instruction = struct { |
| 300 | } | 300 | } |
| 301 | 301 | ||
| 302 | const segment_override: ?Register = switch (op_en) { | 302 | const segment_override: ?Register = switch (op_en) { |
| 303 | .i, .zi, .o, .oi, .d, .np => null, | 303 | .zo, .i, .zi, .o, .oi, .d => null, |
| 304 | .fd => inst.ops[1].mem.base().reg, | 304 | .fd => inst.ops[1].mem.base().reg, |
| 305 | .td => inst.ops[0].mem.base().reg, | 305 | .td => inst.ops[0].mem.base().reg, |
| 306 | .rm, .rmi, .rm0 => if (inst.ops[1].isSegmentRegister()) | 306 | .rm, .rmi, .rm0 => if (inst.ops[1].isSegmentRegister()) |
| ... | @@ -336,7 +336,7 @@ pub const Instruction = struct { | ... | @@ -336,7 +336,7 @@ pub const Instruction = struct { |
| 336 | rex.w = inst.encoding.data.mode == .long; | 336 | rex.w = inst.encoding.data.mode == .long; |
| 337 | 337 | ||
| 338 | switch (op_en) { | 338 | switch (op_en) { |
| 339 | .np, .i, .zi, .fd, .td, .d => {}, | 339 | .zo, .i, .zi, .fd, .td, .d => {}, |
| 340 | .o, .oi => rex.b = inst.ops[0].reg.isExtended(), | 340 | .o, .oi => rex.b = inst.ops[0].reg.isExtended(), |
| 341 | .m, .mi, .m1, .mc, .mr, .rm, .rmi, .mri, .mrc, .rm0 => { | 341 | .m, .mi, .m1, .mc, .mr, .rm, .rmi, .mri, .mrc, .rm0 => { |
| 342 | const r_op = switch (op_en) { | 342 | const r_op = switch (op_en) { |
| ... | @@ -370,7 +370,7 @@ pub const Instruction = struct { | ... | @@ -370,7 +370,7 @@ pub const Instruction = struct { |
| 370 | vex.w = inst.encoding.data.mode.isLong(); | 370 | vex.w = inst.encoding.data.mode.isLong(); |
| 371 | 371 | ||
| 372 | switch (op_en) { | 372 | switch (op_en) { |
| 373 | .np, .i, .zi, .fd, .td, .d => {}, | 373 | .zo, .i, .zi, .fd, .td, .d => {}, |
| 374 | .o, .oi => vex.b = inst.ops[0].reg.isExtended(), | 374 | .o, .oi => vex.b = inst.ops[0].reg.isExtended(), |
| 375 | .m, .mi, .m1, .mc, .mr, .rm, .rmi, .mri, .mrc, .rm0, .vmi, .rvm, .rvmr, .rvmi, .mvr => { | 375 | .m, .mi, .m1, .mc, .mr, .rm, .rmi, .mri, .mrc, .rm0, .vmi, .rvm, .rvmr, .rvmi, .mvr => { |
| 376 | const r_op = switch (op_en) { | 376 | const r_op = switch (op_en) { |
src/arch/x86_64/encodings.zig+76-60| ... | @@ -121,17 +121,16 @@ pub const table = [_]Entry{ | ... | @@ -121,17 +121,16 @@ pub const table = [_]Entry{ |
| 121 | .{ .bts, .mi, &.{ .rm32, .imm8 }, &.{ 0x0f, 0xba }, 5, .none, .none }, | 121 | .{ .bts, .mi, &.{ .rm32, .imm8 }, &.{ 0x0f, 0xba }, 5, .none, .none }, |
| 122 | .{ .bts, .mi, &.{ .rm64, .imm8 }, &.{ 0x0f, 0xba }, 5, .long, .none }, | 122 | .{ .bts, .mi, &.{ .rm64, .imm8 }, &.{ 0x0f, 0xba }, 5, .long, .none }, |
| 123 | 123 | ||
| 124 | // This is M encoding according to Intel, but D makes more sense here. | ||
| 125 | .{ .call, .d, &.{ .rel32 }, &.{ 0xe8 }, 0, .none, .none }, | 124 | .{ .call, .d, &.{ .rel32 }, &.{ 0xe8 }, 0, .none, .none }, |
| 126 | .{ .call, .m, &.{ .rm64 }, &.{ 0xff }, 2, .none, .none }, | 125 | .{ .call, .m, &.{ .rm64 }, &.{ 0xff }, 2, .none, .none }, |
| 127 | 126 | ||
| 128 | .{ .cbw, .np, &.{ .o16 }, &.{ 0x98 }, 0, .short, .none }, | 127 | .{ .cbw, .zo, &.{ .o16 }, &.{ 0x98 }, 0, .short, .none }, |
| 129 | .{ .cwde, .np, &.{ .o32 }, &.{ 0x98 }, 0, .none, .none }, | 128 | .{ .cwde, .zo, &.{ .o32 }, &.{ 0x98 }, 0, .none, .none }, |
| 130 | .{ .cdqe, .np, &.{ .o64 }, &.{ 0x98 }, 0, .long, .none }, | 129 | .{ .cdqe, .zo, &.{ .o64 }, &.{ 0x98 }, 0, .long, .none }, |
| 131 | 130 | ||
| 132 | .{ .cwd, .np, &.{ .o16 }, &.{ 0x99 }, 0, .short, .none }, | 131 | .{ .cwd, .zo, &.{ .o16 }, &.{ 0x99 }, 0, .short, .none }, |
| 133 | .{ .cdq, .np, &.{ .o32 }, &.{ 0x99 }, 0, .none, .none }, | 132 | .{ .cdq, .zo, &.{ .o32 }, &.{ 0x99 }, 0, .none, .none }, |
| 134 | .{ .cqo, .np, &.{ .o64 }, &.{ 0x99 }, 0, .long, .none }, | 133 | .{ .cqo, .zo, &.{ .o64 }, &.{ 0x99 }, 0, .long, .none }, |
| 135 | 134 | ||
| 136 | .{ .cmova, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x47 }, 0, .short, .none }, | 135 | .{ .cmova, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x47 }, 0, .short, .none }, |
| 137 | .{ .cmova, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x47 }, 0, .none, .none }, | 136 | .{ .cmova, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x47 }, 0, .none, .none }, |
| ... | @@ -247,15 +246,15 @@ pub const table = [_]Entry{ | ... | @@ -247,15 +246,15 @@ pub const table = [_]Entry{ |
| 247 | .{ .cmp, .rm, &.{ .r32, .rm32 }, &.{ 0x3b }, 0, .none, .none }, | 246 | .{ .cmp, .rm, &.{ .r32, .rm32 }, &.{ 0x3b }, 0, .none, .none }, |
| 248 | .{ .cmp, .rm, &.{ .r64, .rm64 }, &.{ 0x3b }, 0, .long, .none }, | 247 | .{ .cmp, .rm, &.{ .r64, .rm64 }, &.{ 0x3b }, 0, .long, .none }, |
| 249 | 248 | ||
| 250 | .{ .cmps, .np, &.{ .m8, .m8 }, &.{ 0xa6 }, 0, .none, .none }, | 249 | .{ .cmps, .zo, &.{ .m8, .m8 }, &.{ 0xa6 }, 0, .none, .none }, |
| 251 | .{ .cmps, .np, &.{ .m16, .m16 }, &.{ 0xa7 }, 0, .short, .none }, | 250 | .{ .cmps, .zo, &.{ .m16, .m16 }, &.{ 0xa7 }, 0, .short, .none }, |
| 252 | .{ .cmps, .np, &.{ .m32, .m32 }, &.{ 0xa7 }, 0, .none, .none }, | 251 | .{ .cmps, .zo, &.{ .m32, .m32 }, &.{ 0xa7 }, 0, .none, .none }, |
| 253 | .{ .cmps, .np, &.{ .m64, .m64 }, &.{ 0xa7 }, 0, .long, .none }, | 252 | .{ .cmps, .zo, &.{ .m64, .m64 }, &.{ 0xa7 }, 0, .long, .none }, |
| 254 | 253 | ||
| 255 | .{ .cmpsb, .np, &.{}, &.{ 0xa6 }, 0, .none, .none }, | 254 | .{ .cmpsb, .zo, &.{}, &.{ 0xa6 }, 0, .none, .none }, |
| 256 | .{ .cmpsw, .np, &.{}, &.{ 0xa7 }, 0, .short, .none }, | 255 | .{ .cmpsw, .zo, &.{}, &.{ 0xa7 }, 0, .short, .none }, |
| 257 | .{ .cmpsd, .np, &.{}, &.{ 0xa7 }, 0, .none, .none }, | 256 | .{ .cmpsd, .zo, &.{}, &.{ 0xa7 }, 0, .none, .none }, |
| 258 | .{ .cmpsq, .np, &.{}, &.{ 0xa7 }, 0, .long, .none }, | 257 | .{ .cmpsq, .zo, &.{}, &.{ 0xa7 }, 0, .long, .none }, |
| 259 | 258 | ||
| 260 | .{ .cmpxchg, .mr, &.{ .rm8, .r8 }, &.{ 0x0f, 0xb0 }, 0, .none, .none }, | 259 | .{ .cmpxchg, .mr, &.{ .rm8, .r8 }, &.{ 0x0f, 0xb0 }, 0, .none, .none }, |
| 261 | .{ .cmpxchg, .mr, &.{ .rm8, .r8 }, &.{ 0x0f, 0xb0 }, 0, .rex, .none }, | 260 | .{ .cmpxchg, .mr, &.{ .rm8, .r8 }, &.{ 0x0f, 0xb0 }, 0, .rex, .none }, |
| ... | @@ -266,7 +265,7 @@ pub const table = [_]Entry{ | ... | @@ -266,7 +265,7 @@ pub const table = [_]Entry{ |
| 266 | .{ .cmpxchg8b, .m, &.{ .m64 }, &.{ 0x0f, 0xc7 }, 1, .none, .none }, | 265 | .{ .cmpxchg8b, .m, &.{ .m64 }, &.{ 0x0f, 0xc7 }, 1, .none, .none }, |
| 267 | .{ .cmpxchg16b, .m, &.{ .m128 }, &.{ 0x0f, 0xc7 }, 1, .long, .none }, | 266 | .{ .cmpxchg16b, .m, &.{ .m128 }, &.{ 0x0f, 0xc7 }, 1, .long, .none }, |
| 268 | 267 | ||
| 269 | .{ .cpuid, .np, &.{}, &.{ 0x0f, 0xa2 }, 0, .none, .none }, | 268 | .{ .cpuid, .zo, &.{}, &.{ 0x0f, 0xa2 }, 0, .none, .none }, |
| 270 | 269 | ||
| 271 | .{ .div, .m, &.{ .rm8 }, &.{ 0xf6 }, 6, .none, .none }, | 270 | .{ .div, .m, &.{ .rm8 }, &.{ 0xf6 }, 6, .none, .none }, |
| 272 | .{ .div, .m, &.{ .rm8 }, &.{ 0xf6 }, 6, .rex, .none }, | 271 | .{ .div, .m, &.{ .rm8 }, &.{ 0xf6 }, 6, .rex, .none }, |
| ... | @@ -295,7 +294,7 @@ pub const table = [_]Entry{ | ... | @@ -295,7 +294,7 @@ pub const table = [_]Entry{ |
| 295 | .{ .imul, .rmi, &.{ .r32, .rm32, .imm32 }, &.{ 0x69 }, 0, .none, .none }, | 294 | .{ .imul, .rmi, &.{ .r32, .rm32, .imm32 }, &.{ 0x69 }, 0, .none, .none }, |
| 296 | .{ .imul, .rmi, &.{ .r64, .rm64, .imm32 }, &.{ 0x69 }, 0, .long, .none }, | 295 | .{ .imul, .rmi, &.{ .r64, .rm64, .imm32 }, &.{ 0x69 }, 0, .long, .none }, |
| 297 | 296 | ||
| 298 | .{ .int3, .np, &.{}, &.{ 0xcc }, 0, .none, .none }, | 297 | .{ .int3, .zo, &.{}, &.{ 0xcc }, 0, .none, .none }, |
| 299 | 298 | ||
| 300 | .{ .ja, .d, &.{ .rel32 }, &.{ 0x0f, 0x87 }, 0, .none, .none }, | 299 | .{ .ja, .d, &.{ .rel32 }, &.{ 0x0f, 0x87 }, 0, .none, .none }, |
| 301 | .{ .jae, .d, &.{ .rel32 }, &.{ 0x0f, 0x83 }, 0, .none, .none }, | 300 | .{ .jae, .d, &.{ .rel32 }, &.{ 0x0f, 0x83 }, 0, .none, .none }, |
| ... | @@ -336,23 +335,23 @@ pub const table = [_]Entry{ | ... | @@ -336,23 +335,23 @@ pub const table = [_]Entry{ |
| 336 | .{ .lea, .rm, &.{ .r32, .m }, &.{ 0x8d }, 0, .none, .none }, | 335 | .{ .lea, .rm, &.{ .r32, .m }, &.{ 0x8d }, 0, .none, .none }, |
| 337 | .{ .lea, .rm, &.{ .r64, .m }, &.{ 0x8d }, 0, .long, .none }, | 336 | .{ .lea, .rm, &.{ .r64, .m }, &.{ 0x8d }, 0, .long, .none }, |
| 338 | 337 | ||
| 339 | .{ .lfence, .np, &.{}, &.{ 0x0f, 0xae, 0xe8 }, 0, .none, .none }, | 338 | .{ .lfence, .zo, &.{}, &.{ 0x0f, 0xae, 0xe8 }, 0, .none, .none }, |
| 340 | 339 | ||
| 341 | .{ .lods, .np, &.{ .m8 }, &.{ 0xac }, 0, .none, .none }, | 340 | .{ .lods, .zo, &.{ .m8 }, &.{ 0xac }, 0, .none, .none }, |
| 342 | .{ .lods, .np, &.{ .m16 }, &.{ 0xad }, 0, .short, .none }, | 341 | .{ .lods, .zo, &.{ .m16 }, &.{ 0xad }, 0, .short, .none }, |
| 343 | .{ .lods, .np, &.{ .m32 }, &.{ 0xad }, 0, .none, .none }, | 342 | .{ .lods, .zo, &.{ .m32 }, &.{ 0xad }, 0, .none, .none }, |
| 344 | .{ .lods, .np, &.{ .m64 }, &.{ 0xad }, 0, .long, .none }, | 343 | .{ .lods, .zo, &.{ .m64 }, &.{ 0xad }, 0, .long, .none }, |
| 345 | 344 | ||
| 346 | .{ .lodsb, .np, &.{}, &.{ 0xac }, 0, .none, .none }, | 345 | .{ .lodsb, .zo, &.{}, &.{ 0xac }, 0, .none, .none }, |
| 347 | .{ .lodsw, .np, &.{}, &.{ 0xad }, 0, .short, .none }, | 346 | .{ .lodsw, .zo, &.{}, &.{ 0xad }, 0, .short, .none }, |
| 348 | .{ .lodsd, .np, &.{}, &.{ 0xad }, 0, .none, .none }, | 347 | .{ .lodsd, .zo, &.{}, &.{ 0xad }, 0, .none, .none }, |
| 349 | .{ .lodsq, .np, &.{}, &.{ 0xad }, 0, .long, .none }, | 348 | .{ .lodsq, .zo, &.{}, &.{ 0xad }, 0, .long, .none }, |
| 350 | 349 | ||
| 351 | .{ .lzcnt, .rm, &.{ .r16, .rm16 }, &.{ 0xf3, 0x0f, 0xbd }, 0, .short, .lzcnt }, | 350 | .{ .lzcnt, .rm, &.{ .r16, .rm16 }, &.{ 0xf3, 0x0f, 0xbd }, 0, .short, .lzcnt }, |
| 352 | .{ .lzcnt, .rm, &.{ .r32, .rm32 }, &.{ 0xf3, 0x0f, 0xbd }, 0, .none, .lzcnt }, | 351 | .{ .lzcnt, .rm, &.{ .r32, .rm32 }, &.{ 0xf3, 0x0f, 0xbd }, 0, .none, .lzcnt }, |
| 353 | .{ .lzcnt, .rm, &.{ .r64, .rm64 }, &.{ 0xf3, 0x0f, 0xbd }, 0, .long, .lzcnt }, | 352 | .{ .lzcnt, .rm, &.{ .r64, .rm64 }, &.{ 0xf3, 0x0f, 0xbd }, 0, .long, .lzcnt }, |
| 354 | 353 | ||
| 355 | .{ .mfence, .np, &.{}, &.{ 0x0f, 0xae, 0xf0 }, 0, .none, .none }, | 354 | .{ .mfence, .zo, &.{}, &.{ 0x0f, 0xae, 0xf0 }, 0, .none, .none }, |
| 356 | 355 | ||
| 357 | .{ .mov, .mr, &.{ .rm8, .r8 }, &.{ 0x88 }, 0, .none, .none }, | 356 | .{ .mov, .mr, &.{ .rm8, .r8 }, &.{ 0x88 }, 0, .none, .none }, |
| 358 | .{ .mov, .mr, &.{ .rm8, .r8 }, &.{ 0x88 }, 0, .rex, .none }, | 357 | .{ .mov, .mr, &.{ .rm8, .r8 }, &.{ 0x88 }, 0, .rex, .none }, |
| ... | @@ -396,15 +395,15 @@ pub const table = [_]Entry{ | ... | @@ -396,15 +395,15 @@ pub const table = [_]Entry{ |
| 396 | .{ .movbe, .mr, &.{ .m32, .r32 }, &.{ 0x0f, 0x38, 0xf1 }, 0, .none, .movbe }, | 395 | .{ .movbe, .mr, &.{ .m32, .r32 }, &.{ 0x0f, 0x38, 0xf1 }, 0, .none, .movbe }, |
| 397 | .{ .movbe, .mr, &.{ .m64, .r64 }, &.{ 0x0f, 0x38, 0xf1 }, 0, .long, .movbe }, | 396 | .{ .movbe, .mr, &.{ .m64, .r64 }, &.{ 0x0f, 0x38, 0xf1 }, 0, .long, .movbe }, |
| 398 | 397 | ||
| 399 | .{ .movs, .np, &.{ .m8, .m8 }, &.{ 0xa4 }, 0, .none, .none }, | 398 | .{ .movs, .zo, &.{ .m8, .m8 }, &.{ 0xa4 }, 0, .none, .none }, |
| 400 | .{ .movs, .np, &.{ .m16, .m16 }, &.{ 0xa5 }, 0, .short, .none }, | 399 | .{ .movs, .zo, &.{ .m16, .m16 }, &.{ 0xa5 }, 0, .short, .none }, |
| 401 | .{ .movs, .np, &.{ .m32, .m32 }, &.{ 0xa5 }, 0, .none, .none }, | 400 | .{ .movs, .zo, &.{ .m32, .m32 }, &.{ 0xa5 }, 0, .none, .none }, |
| 402 | .{ .movs, .np, &.{ .m64, .m64 }, &.{ 0xa5 }, 0, .long, .none }, | 401 | .{ .movs, .zo, &.{ .m64, .m64 }, &.{ 0xa5 }, 0, .long, .none }, |
| 403 | 402 | ||
| 404 | .{ .movsb, .np, &.{}, &.{ 0xa4 }, 0, .none, .none }, | 403 | .{ .movsb, .zo, &.{}, &.{ 0xa4 }, 0, .none, .none }, |
| 405 | .{ .movsw, .np, &.{}, &.{ 0xa5 }, 0, .short, .none }, | 404 | .{ .movsw, .zo, &.{}, &.{ 0xa5 }, 0, .short, .none }, |
| 406 | .{ .movsd, .np, &.{}, &.{ 0xa5 }, 0, .none, .none }, | 405 | .{ .movsd, .zo, &.{}, &.{ 0xa5 }, 0, .none, .none }, |
| 407 | .{ .movsq, .np, &.{}, &.{ 0xa5 }, 0, .long, .none }, | 406 | .{ .movsq, .zo, &.{}, &.{ 0xa5 }, 0, .long, .none }, |
| 408 | 407 | ||
| 409 | .{ .movsx, .rm, &.{ .r16, .rm8 }, &.{ 0x0f, 0xbe }, 0, .short, .none }, | 408 | .{ .movsx, .rm, &.{ .r16, .rm8 }, &.{ 0x0f, 0xbe }, 0, .short, .none }, |
| 410 | .{ .movsx, .rm, &.{ .r16, .rm8 }, &.{ 0x0f, 0xbe }, 0, .rex_short, .none }, | 409 | .{ .movsx, .rm, &.{ .r16, .rm8 }, &.{ 0x0f, 0xbe }, 0, .rex_short, .none }, |
| ... | @@ -440,7 +439,7 @@ pub const table = [_]Entry{ | ... | @@ -440,7 +439,7 @@ pub const table = [_]Entry{ |
| 440 | .{ .neg, .m, &.{ .rm32 }, &.{ 0xf7 }, 3, .none, .none }, | 439 | .{ .neg, .m, &.{ .rm32 }, &.{ 0xf7 }, 3, .none, .none }, |
| 441 | .{ .neg, .m, &.{ .rm64 }, &.{ 0xf7 }, 3, .long, .none }, | 440 | .{ .neg, .m, &.{ .rm64 }, &.{ 0xf7 }, 3, .long, .none }, |
| 442 | 441 | ||
| 443 | .{ .nop, .np, &.{}, &.{ 0x90 }, 0, .none, .none }, | 442 | .{ .nop, .zo, &.{}, &.{ 0x90 }, 0, .none, .none }, |
| 444 | 443 | ||
| 445 | .{ .not, .m, &.{ .rm8 }, &.{ 0xf6 }, 2, .none, .none }, | 444 | .{ .not, .m, &.{ .rm8 }, &.{ 0xf6 }, 2, .none, .none }, |
| 446 | .{ .not, .m, &.{ .rm8 }, &.{ 0xf6 }, 2, .rex, .none }, | 445 | .{ .not, .m, &.{ .rm8 }, &.{ 0xf6 }, 2, .rex, .none }, |
| ... | @@ -471,7 +470,7 @@ pub const table = [_]Entry{ | ... | @@ -471,7 +470,7 @@ pub const table = [_]Entry{ |
| 471 | .{ .@"or", .rm, &.{ .r32, .rm32 }, &.{ 0x0b }, 0, .none, .none }, | 470 | .{ .@"or", .rm, &.{ .r32, .rm32 }, &.{ 0x0b }, 0, .none, .none }, |
| 472 | .{ .@"or", .rm, &.{ .r64, .rm64 }, &.{ 0x0b }, 0, .long, .none }, | 471 | .{ .@"or", .rm, &.{ .r64, .rm64 }, &.{ 0x0b }, 0, .long, .none }, |
| 473 | 472 | ||
| 474 | .{ .pause, .np, &.{}, &.{ 0xf3, 0x90 }, 0, .none, .none }, | 473 | .{ .pause, .zo, &.{}, &.{ 0xf3, 0x90 }, 0, .none, .none }, |
| 475 | 474 | ||
| 476 | .{ .pop, .o, &.{ .r16 }, &.{ 0x58 }, 0, .short, .none }, | 475 | .{ .pop, .o, &.{ .r16 }, &.{ 0x58 }, 0, .short, .none }, |
| 477 | .{ .pop, .o, &.{ .r64 }, &.{ 0x58 }, 0, .none, .none }, | 476 | .{ .pop, .o, &.{ .r64 }, &.{ 0x58 }, 0, .none, .none }, |
| ... | @@ -482,6 +481,8 @@ pub const table = [_]Entry{ | ... | @@ -482,6 +481,8 @@ pub const table = [_]Entry{ |
| 482 | .{ .popcnt, .rm, &.{ .r32, .rm32 }, &.{ 0xf3, 0x0f, 0xb8 }, 0, .none, .popcnt }, | 481 | .{ .popcnt, .rm, &.{ .r32, .rm32 }, &.{ 0xf3, 0x0f, 0xb8 }, 0, .none, .popcnt }, |
| 483 | .{ .popcnt, .rm, &.{ .r64, .rm64 }, &.{ 0xf3, 0x0f, 0xb8 }, 0, .long, .popcnt }, | 482 | .{ .popcnt, .rm, &.{ .r64, .rm64 }, &.{ 0xf3, 0x0f, 0xb8 }, 0, .long, .popcnt }, |
| 484 | 483 | ||
| 484 | .{ .popfq, .zo, &.{}, &.{ 0x9d }, 0, .none, .none }, | ||
| 485 | |||
| 485 | .{ .push, .o, &.{ .r16 }, &.{ 0x50 }, 0, .short, .none }, | 486 | .{ .push, .o, &.{ .r16 }, &.{ 0x50 }, 0, .short, .none }, |
| 486 | .{ .push, .o, &.{ .r64 }, &.{ 0x50 }, 0, .none, .none }, | 487 | .{ .push, .o, &.{ .r64 }, &.{ 0x50 }, 0, .none, .none }, |
| 487 | .{ .push, .m, &.{ .rm16 }, &.{ 0xff }, 6, .short, .none }, | 488 | .{ .push, .m, &.{ .rm16 }, &.{ 0xff }, 6, .short, .none }, |
| ... | @@ -490,7 +491,9 @@ pub const table = [_]Entry{ | ... | @@ -490,7 +491,9 @@ pub const table = [_]Entry{ |
| 490 | .{ .push, .i, &.{ .imm16 }, &.{ 0x68 }, 0, .short, .none }, | 491 | .{ .push, .i, &.{ .imm16 }, &.{ 0x68 }, 0, .short, .none }, |
| 491 | .{ .push, .i, &.{ .imm32 }, &.{ 0x68 }, 0, .none, .none }, | 492 | .{ .push, .i, &.{ .imm32 }, &.{ 0x68 }, 0, .none, .none }, |
| 492 | 493 | ||
| 493 | .{ .ret, .np, &.{}, &.{ 0xc3 }, 0, .none, .none }, | 494 | .{ .pushfq, .zo, &.{}, &.{ 0x9c }, 0, .none, .none }, |
| 495 | |||
| 496 | .{ .ret, .zo, &.{}, &.{ 0xc3 }, 0, .none, .none }, | ||
| 494 | 497 | ||
| 495 | .{ .rcl, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 2, .none, .none }, | 498 | .{ .rcl, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 2, .none, .none }, |
| 496 | .{ .rcl, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 2, .rex, .none }, | 499 | .{ .rcl, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 2, .rex, .none }, |
| ... | @@ -611,15 +614,15 @@ pub const table = [_]Entry{ | ... | @@ -611,15 +614,15 @@ pub const table = [_]Entry{ |
| 611 | .{ .sbb, .rm, &.{ .r32, .rm32 }, &.{ 0x1b }, 0, .none, .none }, | 614 | .{ .sbb, .rm, &.{ .r32, .rm32 }, &.{ 0x1b }, 0, .none, .none }, |
| 612 | .{ .sbb, .rm, &.{ .r64, .rm64 }, &.{ 0x1b }, 0, .long, .none }, | 615 | .{ .sbb, .rm, &.{ .r64, .rm64 }, &.{ 0x1b }, 0, .long, .none }, |
| 613 | 616 | ||
| 614 | .{ .scas, .np, &.{ .m8 }, &.{ 0xae }, 0, .none, .none }, | 617 | .{ .scas, .zo, &.{ .m8 }, &.{ 0xae }, 0, .none, .none }, |
| 615 | .{ .scas, .np, &.{ .m16 }, &.{ 0xaf }, 0, .short, .none }, | 618 | .{ .scas, .zo, &.{ .m16 }, &.{ 0xaf }, 0, .short, .none }, |
| 616 | .{ .scas, .np, &.{ .m32 }, &.{ 0xaf }, 0, .none, .none }, | 619 | .{ .scas, .zo, &.{ .m32 }, &.{ 0xaf }, 0, .none, .none }, |
| 617 | .{ .scas, .np, &.{ .m64 }, &.{ 0xaf }, 0, .long, .none }, | 620 | .{ .scas, .zo, &.{ .m64 }, &.{ 0xaf }, 0, .long, .none }, |
| 618 | 621 | ||
| 619 | .{ .scasb, .np, &.{}, &.{ 0xae }, 0, .none, .none }, | 622 | .{ .scasb, .zo, &.{}, &.{ 0xae }, 0, .none, .none }, |
| 620 | .{ .scasw, .np, &.{}, &.{ 0xaf }, 0, .short, .none }, | 623 | .{ .scasw, .zo, &.{}, &.{ 0xaf }, 0, .short, .none }, |
| 621 | .{ .scasd, .np, &.{}, &.{ 0xaf }, 0, .none, .none }, | 624 | .{ .scasd, .zo, &.{}, &.{ 0xaf }, 0, .none, .none }, |
| 622 | .{ .scasq, .np, &.{}, &.{ 0xaf }, 0, .long, .none }, | 625 | .{ .scasq, .zo, &.{}, &.{ 0xaf }, 0, .long, .none }, |
| 623 | 626 | ||
| 624 | .{ .seta, .m, &.{ .rm8 }, &.{ 0x0f, 0x97 }, 0, .none, .none }, | 627 | .{ .seta, .m, &.{ .rm8 }, &.{ 0x0f, 0x97 }, 0, .none, .none }, |
| 625 | .{ .seta, .m, &.{ .rm8 }, &.{ 0x0f, 0x97 }, 0, .rex, .none }, | 628 | .{ .seta, .m, &.{ .rm8 }, &.{ 0x0f, 0x97 }, 0, .rex, .none }, |
| ... | @@ -682,7 +685,7 @@ pub const table = [_]Entry{ | ... | @@ -682,7 +685,7 @@ pub const table = [_]Entry{ |
| 682 | .{ .setz, .m, &.{ .rm8 }, &.{ 0x0f, 0x94 }, 0, .none, .none }, | 685 | .{ .setz, .m, &.{ .rm8 }, &.{ 0x0f, 0x94 }, 0, .none, .none }, |
| 683 | .{ .setz, .m, &.{ .rm8 }, &.{ 0x0f, 0x94 }, 0, .rex, .none }, | 686 | .{ .setz, .m, &.{ .rm8 }, &.{ 0x0f, 0x94 }, 0, .rex, .none }, |
| 684 | 687 | ||
| 685 | .{ .sfence, .np, &.{}, &.{ 0x0f, 0xae, 0xf8 }, 0, .none, .none }, | 688 | .{ .sfence, .zo, &.{}, &.{ 0x0f, 0xae, 0xf8 }, 0, .none, .none }, |
| 686 | 689 | ||
| 687 | .{ .shl, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 4, .none, .none }, | 690 | .{ .shl, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 4, .none, .none }, |
| 688 | .{ .shl, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 4, .rex, .none }, | 691 | .{ .shl, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 4, .rex, .none }, |
| ... | @@ -730,15 +733,15 @@ pub const table = [_]Entry{ | ... | @@ -730,15 +733,15 @@ pub const table = [_]Entry{ |
| 730 | .{ .shrd, .mrc, &.{ .rm32, .r32, .cl }, &.{ 0x0f, 0xad }, 0, .none, .none }, | 733 | .{ .shrd, .mrc, &.{ .rm32, .r32, .cl }, &.{ 0x0f, 0xad }, 0, .none, .none }, |
| 731 | .{ .shrd, .mrc, &.{ .rm64, .r64, .cl }, &.{ 0x0f, 0xad }, 0, .long, .none }, | 734 | .{ .shrd, .mrc, &.{ .rm64, .r64, .cl }, &.{ 0x0f, 0xad }, 0, .long, .none }, |
| 732 | 735 | ||
| 733 | .{ .stos, .np, &.{ .m8 }, &.{ 0xaa }, 0, .none, .none }, | 736 | .{ .stos, .zo, &.{ .m8 }, &.{ 0xaa }, 0, .none, .none }, |
| 734 | .{ .stos, .np, &.{ .m16 }, &.{ 0xab }, 0, .short, .none }, | 737 | .{ .stos, .zo, &.{ .m16 }, &.{ 0xab }, 0, .short, .none }, |
| 735 | .{ .stos, .np, &.{ .m32 }, &.{ 0xab }, 0, .none, .none }, | 738 | .{ .stos, .zo, &.{ .m32 }, &.{ 0xab }, 0, .none, .none }, |
| 736 | .{ .stos, .np, &.{ .m64 }, &.{ 0xab }, 0, .long, .none }, | 739 | .{ .stos, .zo, &.{ .m64 }, &.{ 0xab }, 0, .long, .none }, |
| 737 | 740 | ||
| 738 | .{ .stosb, .np, &.{}, &.{ 0xaa }, 0, .none, .none }, | 741 | .{ .stosb, .zo, &.{}, &.{ 0xaa }, 0, .none, .none }, |
| 739 | .{ .stosw, .np, &.{}, &.{ 0xab }, 0, .short, .none }, | 742 | .{ .stosw, .zo, &.{}, &.{ 0xab }, 0, .short, .none }, |
| 740 | .{ .stosd, .np, &.{}, &.{ 0xab }, 0, .none, .none }, | 743 | .{ .stosd, .zo, &.{}, &.{ 0xab }, 0, .none, .none }, |
| 741 | .{ .stosq, .np, &.{}, &.{ 0xab }, 0, .long, .none }, | 744 | .{ .stosq, .zo, &.{}, &.{ 0xab }, 0, .long, .none }, |
| 742 | 745 | ||
| 743 | .{ .sub, .zi, &.{ .al, .imm8 }, &.{ 0x2c }, 0, .none, .none }, | 746 | .{ .sub, .zi, &.{ .al, .imm8 }, &.{ 0x2c }, 0, .none, .none }, |
| 744 | .{ .sub, .zi, &.{ .ax, .imm16 }, &.{ 0x2d }, 0, .short, .none }, | 747 | .{ .sub, .zi, &.{ .ax, .imm16 }, &.{ 0x2d }, 0, .short, .none }, |
| ... | @@ -763,7 +766,7 @@ pub const table = [_]Entry{ | ... | @@ -763,7 +766,7 @@ pub const table = [_]Entry{ |
| 763 | .{ .sub, .rm, &.{ .r32, .rm32 }, &.{ 0x2b }, 0, .none, .none }, | 766 | .{ .sub, .rm, &.{ .r32, .rm32 }, &.{ 0x2b }, 0, .none, .none }, |
| 764 | .{ .sub, .rm, &.{ .r64, .rm64 }, &.{ 0x2b }, 0, .long, .none }, | 767 | .{ .sub, .rm, &.{ .r64, .rm64 }, &.{ 0x2b }, 0, .long, .none }, |
| 765 | 768 | ||
| 766 | .{ .syscall, .np, &.{}, &.{ 0x0f, 0x05 }, 0, .none, .none }, | 769 | .{ .syscall, .zo, &.{}, &.{ 0x0f, 0x05 }, 0, .none, .none }, |
| 767 | 770 | ||
| 768 | .{ .@"test", .zi, &.{ .al, .imm8 }, &.{ 0xa8 }, 0, .none, .none }, | 771 | .{ .@"test", .zi, &.{ .al, .imm8 }, &.{ 0xa8 }, 0, .none, .none }, |
| 769 | .{ .@"test", .zi, &.{ .ax, .imm16 }, &.{ 0xa9 }, 0, .short, .none }, | 772 | .{ .@"test", .zi, &.{ .ax, .imm16 }, &.{ 0xa9 }, 0, .short, .none }, |
| ... | @@ -784,7 +787,7 @@ pub const table = [_]Entry{ | ... | @@ -784,7 +787,7 @@ pub const table = [_]Entry{ |
| 784 | .{ .tzcnt, .rm, &.{ .r32, .rm32 }, &.{ 0xf3, 0x0f, 0xbc }, 0, .none, .bmi }, | 787 | .{ .tzcnt, .rm, &.{ .r32, .rm32 }, &.{ 0xf3, 0x0f, 0xbc }, 0, .none, .bmi }, |
| 785 | .{ .tzcnt, .rm, &.{ .r64, .rm64 }, &.{ 0xf3, 0x0f, 0xbc }, 0, .long, .bmi }, | 788 | .{ .tzcnt, .rm, &.{ .r64, .rm64 }, &.{ 0xf3, 0x0f, 0xbc }, 0, .long, .bmi }, |
| 786 | 789 | ||
| 787 | .{ .ud2, .np, &.{}, &.{ 0x0f, 0x0b }, 0, .none, .none }, | 790 | .{ .ud2, .zo, &.{}, &.{ 0x0f, 0x0b }, 0, .none, .none }, |
| 788 | 791 | ||
| 789 | .{ .xadd, .mr, &.{ .rm8, .r8 }, &.{ 0x0f, 0xc0 }, 0, .none, .none }, | 792 | .{ .xadd, .mr, &.{ .rm8, .r8 }, &.{ 0x0f, 0xc0 }, 0, .none, .none }, |
| 790 | .{ .xadd, .mr, &.{ .rm8, .r8 }, &.{ 0x0f, 0xc0 }, 0, .rex, .none }, | 793 | .{ .xadd, .mr, &.{ .rm8, .r8 }, &.{ 0x0f, 0xc0 }, 0, .rex, .none }, |
| ... | @@ -809,7 +812,7 @@ pub const table = [_]Entry{ | ... | @@ -809,7 +812,7 @@ pub const table = [_]Entry{ |
| 809 | .{ .xchg, .rm, &.{ .r32, .rm32 }, &.{ 0x87 }, 0, .none, .none }, | 812 | .{ .xchg, .rm, &.{ .r32, .rm32 }, &.{ 0x87 }, 0, .none, .none }, |
| 810 | .{ .xchg, .rm, &.{ .r64, .rm64 }, &.{ 0x87 }, 0, .long, .none }, | 813 | .{ .xchg, .rm, &.{ .r64, .rm64 }, &.{ 0x87 }, 0, .long, .none }, |
| 811 | 814 | ||
| 812 | .{ .xgetbv, .np, &.{}, &.{ 0x0f, 0x01 }, 0, .none, .none }, | 815 | .{ .xgetbv, .zo, &.{}, &.{ 0x0f, 0x01, 0xd0 }, 0, .none, .none }, |
| 813 | 816 | ||
| 814 | .{ .xor, .zi, &.{ .al, .imm8 }, &.{ 0x34 }, 0, .none, .none }, | 817 | .{ .xor, .zi, &.{ .al, .imm8 }, &.{ 0x34 }, 0, .none, .none }, |
| 815 | .{ .xor, .zi, &.{ .ax, .imm16 }, &.{ 0x35 }, 0, .short, .none }, | 818 | .{ .xor, .zi, &.{ .ax, .imm16 }, &.{ 0x35 }, 0, .short, .none }, |
| ... | @@ -835,9 +838,9 @@ pub const table = [_]Entry{ | ... | @@ -835,9 +838,9 @@ pub const table = [_]Entry{ |
| 835 | .{ .xor, .rm, &.{ .r64, .rm64 }, &.{ 0x33 }, 0, .long, .none }, | 838 | .{ .xor, .rm, &.{ .r64, .rm64 }, &.{ 0x33 }, 0, .long, .none }, |
| 836 | 839 | ||
| 837 | // X87 | 840 | // X87 |
| 838 | .{ .fabs, .np, &.{}, &.{ 0xd9, 0xe1 }, 0, .none, .x87 }, | 841 | .{ .fabs, .zo, &.{}, &.{ 0xd9, 0xe1 }, 0, .none, .x87 }, |
| 839 | 842 | ||
| 840 | .{ .fchs, .np, &.{}, &.{ 0xd9, 0xe0 }, 0, .none, .x87 }, | 843 | .{ .fchs, .zo, &.{}, &.{ 0xd9, 0xe0 }, 0, .none, .x87 }, |
| 841 | 844 | ||
| 842 | .{ .ffree, .o, &.{ .st }, &.{ 0xdd, 0xc0 }, 0, .none, .x87 }, | 845 | .{ .ffree, .o, &.{ .st }, &.{ 0xdd, 0xc0 }, 0, .none, .x87 }, |
| 843 | 846 | ||
| ... | @@ -850,6 +853,8 @@ pub const table = [_]Entry{ | ... | @@ -850,6 +853,8 @@ pub const table = [_]Entry{ |
| 850 | .{ .fld, .m, &.{ .m80 }, &.{ 0xdb }, 5, .none, .x87 }, | 853 | .{ .fld, .m, &.{ .m80 }, &.{ 0xdb }, 5, .none, .x87 }, |
| 851 | .{ .fld, .o, &.{ .st }, &.{ 0xd9, 0xc0 }, 0, .none, .x87 }, | 854 | .{ .fld, .o, &.{ .st }, &.{ 0xd9, 0xc0 }, 0, .none, .x87 }, |
| 852 | 855 | ||
| 856 | .{ .fldenv, .m, &.{ .m }, &.{ 0xd9 }, 4, .none, .x87 }, | ||
| 857 | |||
| 853 | .{ .fst, .m, &.{ .m32 }, &.{ 0xd9 }, 2, .none, .x87 }, | 858 | .{ .fst, .m, &.{ .m32 }, &.{ 0xd9 }, 2, .none, .x87 }, |
| 854 | .{ .fst, .m, &.{ .m64 }, &.{ 0xdd }, 2, .none, .x87 }, | 859 | .{ .fst, .m, &.{ .m64 }, &.{ 0xdd }, 2, .none, .x87 }, |
| 855 | .{ .fst, .o, &.{ .st }, &.{ 0xdd, 0xd0 }, 0, .none, .x87 }, | 860 | .{ .fst, .o, &.{ .st }, &.{ 0xdd, 0xd0 }, 0, .none, .x87 }, |
| ... | @@ -858,6 +863,9 @@ pub const table = [_]Entry{ | ... | @@ -858,6 +863,9 @@ pub const table = [_]Entry{ |
| 858 | .{ .fstp, .m, &.{ .m80 }, &.{ 0xdb }, 7, .none, .x87 }, | 863 | .{ .fstp, .m, &.{ .m80 }, &.{ 0xdb }, 7, .none, .x87 }, |
| 859 | .{ .fstp, .o, &.{ .st }, &.{ 0xdd, 0xd8 }, 0, .none, .x87 }, | 864 | .{ .fstp, .o, &.{ .st }, &.{ 0xdd, 0xd8 }, 0, .none, .x87 }, |
| 860 | 865 | ||
| 866 | .{ .fstenv, .m, &.{ .m }, &.{ 0x9b, 0xd9 }, 6, .none, .x87 }, | ||
| 867 | .{ .fnstenv, .m, &.{ .m }, &.{ 0xd9 }, 6, .none, .x87 }, | ||
| 868 | |||
| 861 | // SSE | 869 | // SSE |
| 862 | .{ .addps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x58 }, 0, .none, .sse }, | 870 | .{ .addps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x58 }, 0, .none, .sse }, |
| 863 | 871 | ||
| ... | @@ -890,6 +898,8 @@ pub const table = [_]Entry{ | ... | @@ -890,6 +898,8 @@ pub const table = [_]Entry{ |
| 890 | 898 | ||
| 891 | .{ .divss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5e }, 0, .none, .sse }, | 899 | .{ .divss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5e }, 0, .none, .sse }, |
| 892 | 900 | ||
| 901 | .{ .ldmxcsr, .m, &.{ .m32 }, &.{ 0x0f, 0xae }, 2, .none, .sse }, | ||
| 902 | |||
| 893 | .{ .maxps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x5f }, 0, .none, .sse }, | 903 | .{ .maxps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x5f }, 0, .none, .sse }, |
| 894 | 904 | ||
| 895 | .{ .maxss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5f }, 0, .none, .sse }, | 905 | .{ .maxss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5f }, 0, .none, .sse }, |
| ... | @@ -929,6 +939,8 @@ pub const table = [_]Entry{ | ... | @@ -929,6 +939,8 @@ pub const table = [_]Entry{ |
| 929 | 939 | ||
| 930 | .{ .sqrtss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x51 }, 0, .none, .sse }, | 940 | .{ .sqrtss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x51 }, 0, .none, .sse }, |
| 931 | 941 | ||
| 942 | .{ .stmxcsr, .m, &.{ .m32 }, &.{ 0x0f, 0xae }, 3, .none, .sse }, | ||
| 943 | |||
| 932 | .{ .subps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x5c }, 0, .none, .sse }, | 944 | .{ .subps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x5c }, 0, .none, .sse }, |
| 933 | 945 | ||
| 934 | .{ .subss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5c }, 0, .none, .sse }, | 946 | .{ .subss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5c }, 0, .none, .sse }, |
| ... | @@ -1365,6 +1377,8 @@ pub const table = [_]Entry{ | ... | @@ -1365,6 +1377,8 @@ pub const table = [_]Entry{ |
| 1365 | 1377 | ||
| 1366 | .{ .vinsertps, .rvmi, &.{ .xmm, .xmm, .xmm_m32, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x21 }, 0, .vex_128_wig, .avx }, | 1378 | .{ .vinsertps, .rvmi, &.{ .xmm, .xmm, .xmm_m32, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x21 }, 0, .vex_128_wig, .avx }, |
| 1367 | 1379 | ||
| 1380 | .{ .vldmxcsr, .m, &.{ .m32 }, &.{ 0x0f, 0xae }, 2, .vex_lz_wig, .avx }, | ||
| 1381 | |||
| 1368 | .{ .vmaxpd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x5f }, 0, .vex_128_wig, .avx }, | 1382 | .{ .vmaxpd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x5f }, 0, .vex_128_wig, .avx }, |
| 1369 | .{ .vmaxpd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x5f }, 0, .vex_256_wig, .avx }, | 1383 | .{ .vmaxpd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x5f }, 0, .vex_256_wig, .avx }, |
| 1370 | 1384 | ||
| ... | @@ -1635,6 +1649,8 @@ pub const table = [_]Entry{ | ... | @@ -1635,6 +1649,8 @@ pub const table = [_]Entry{ |
| 1635 | 1649 | ||
| 1636 | .{ .vsqrtss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x51 }, 0, .vex_lig_wig, .avx }, | 1650 | .{ .vsqrtss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x51 }, 0, .vex_lig_wig, .avx }, |
| 1637 | 1651 | ||
| 1652 | .{ .vstmxcsr, .m, &.{ .m32 }, &.{ 0x0f, 0xae }, 3, .vex_lz_wig, .avx }, | ||
| 1653 | |||
| 1638 | .{ .vsubpd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x5c }, 0, .vex_128_wig, .avx }, | 1654 | .{ .vsubpd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x5c }, 0, .vex_128_wig, .avx }, |
| 1639 | .{ .vsubpd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x5c }, 0, .vex_256_wig, .avx }, | 1655 | .{ .vsubpd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x5c }, 0, .vex_256_wig, .avx }, |
| 1640 | 1656 |
src/codegen.zig+7-1| ... | @@ -850,7 +850,7 @@ fn genDeclRef( | ... | @@ -850,7 +850,7 @@ fn genDeclRef( |
| 850 | bin_file: *link.File, | 850 | bin_file: *link.File, |
| 851 | src_loc: Module.SrcLoc, | 851 | src_loc: Module.SrcLoc, |
| 852 | tv: TypedValue, | 852 | tv: TypedValue, |
| 853 | decl_index: Module.Decl.Index, | 853 | ptr_decl_index: Module.Decl.Index, |
| 854 | ) CodeGenError!GenResult { | 854 | ) CodeGenError!GenResult { |
| 855 | const mod = bin_file.options.module.?; | 855 | const mod = bin_file.options.module.?; |
| 856 | log.debug("genDeclRef: ty = {}, val = {}", .{ tv.ty.fmt(mod), tv.val.fmtValue(tv.ty, mod) }); | 856 | log.debug("genDeclRef: ty = {}, val = {}", .{ tv.ty.fmt(mod), tv.val.fmtValue(tv.ty, mod) }); |
| ... | @@ -859,6 +859,12 @@ fn genDeclRef( | ... | @@ -859,6 +859,12 @@ fn genDeclRef( |
| 859 | const ptr_bits = target.ptrBitWidth(); | 859 | const ptr_bits = target.ptrBitWidth(); |
| 860 | const ptr_bytes: u64 = @divExact(ptr_bits, 8); | 860 | const ptr_bytes: u64 = @divExact(ptr_bits, 8); |
| 861 | 861 | ||
| 862 | const ptr_decl = mod.declPtr(ptr_decl_index); | ||
| 863 | const decl_index = switch (mod.intern_pool.indexToKey(try ptr_decl.internValue(mod))) { | ||
| 864 | .func => |func| func.owner_decl, | ||
| 865 | .extern_func => |extern_func| extern_func.decl, | ||
| 866 | else => ptr_decl_index, | ||
| 867 | }; | ||
| 862 | const decl = mod.declPtr(decl_index); | 868 | const decl = mod.declPtr(decl_index); |
| 863 | 869 | ||
| 864 | if (!decl.ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) { | 870 | if (!decl.ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) { |
src/link/Coff.zig+1-2| ... | @@ -1461,7 +1461,6 @@ pub fn updateDeclExports( | ... | @@ -1461,7 +1461,6 @@ pub fn updateDeclExports( |
| 1461 | const decl = mod.declPtr(decl_index); | 1461 | const decl = mod.declPtr(decl_index); |
| 1462 | const atom_index = try self.getOrCreateAtomForDecl(decl_index); | 1462 | const atom_index = try self.getOrCreateAtomForDecl(decl_index); |
| 1463 | const atom = self.getAtom(atom_index); | 1463 | const atom = self.getAtom(atom_index); |
| 1464 | const decl_sym = atom.getSymbol(self); | ||
| 1465 | const decl_metadata = self.decls.getPtr(decl_index).?; | 1464 | const decl_metadata = self.decls.getPtr(decl_index).?; |
| 1466 | 1465 | ||
| 1467 | for (exports) |exp| { | 1466 | for (exports) |exp| { |
| ... | @@ -1505,7 +1504,7 @@ pub fn updateDeclExports( | ... | @@ -1505,7 +1504,7 @@ pub fn updateDeclExports( |
| 1505 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null }; | 1504 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null }; |
| 1506 | const sym = self.getSymbolPtr(sym_loc); | 1505 | const sym = self.getSymbolPtr(sym_loc); |
| 1507 | try self.setSymbolName(sym, mod.intern_pool.stringToSlice(exp.opts.name)); | 1506 | try self.setSymbolName(sym, mod.intern_pool.stringToSlice(exp.opts.name)); |
| 1508 | sym.value = decl_sym.value; | 1507 | sym.value = atom.getSymbol(self).value; |
| 1509 | sym.section_number = @as(coff.SectionNumber, @enumFromInt(self.text_section_index.? + 1)); | 1508 | sym.section_number = @as(coff.SectionNumber, @enumFromInt(self.text_section_index.? + 1)); |
| 1510 | sym.type = .{ .complex_type = .FUNCTION, .base_type = .NULL }; | 1509 | sym.type = .{ .complex_type = .FUNCTION, .base_type = .NULL }; |
| 1511 | 1510 |
src/link/Elf.zig+91-23| ... | @@ -48,7 +48,7 @@ phdr_zig_load_zerofill_index: ?u16 = null, | ... | @@ -48,7 +48,7 @@ phdr_zig_load_zerofill_index: ?u16 = null, |
| 48 | /// PT_PHDR | 48 | /// PT_PHDR |
| 49 | phdr_table_index: ?u16 = null, | 49 | phdr_table_index: ?u16 = null, |
| 50 | /// PT_LOAD for PHDR table | 50 | /// PT_LOAD for PHDR table |
| 51 | /// We add this special load segment to ensure the PHDR table is always | 51 | /// We add this special load segment to ensure the EHDR and PHDR table are always |
| 52 | /// loaded into memory. | 52 | /// loaded into memory. |
| 53 | phdr_table_load_index: ?u16 = null, | 53 | phdr_table_load_index: ?u16 = null, |
| 54 | /// PT_INTERP | 54 | /// PT_INTERP |
| ... | @@ -289,22 +289,33 @@ pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Option | ... | @@ -289,22 +289,33 @@ pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Option |
| 289 | .p64 => @alignOf(elf.Elf64_Phdr), | 289 | .p64 => @alignOf(elf.Elf64_Phdr), |
| 290 | }; | 290 | }; |
| 291 | const image_base = self.calcImageBase(); | 291 | const image_base = self.calcImageBase(); |
| 292 | const offset: u64 = switch (self.ptr_width) { | 292 | const ehsize: u64 = switch (self.ptr_width) { |
| 293 | .p32 => @sizeOf(elf.Elf32_Ehdr), | 293 | .p32 => @sizeOf(elf.Elf32_Ehdr), |
| 294 | .p64 => @sizeOf(elf.Elf64_Ehdr), | 294 | .p64 => @sizeOf(elf.Elf64_Ehdr), |
| 295 | }; | 295 | }; |
| 296 | const phsize: u64 = switch (self.ptr_width) { | ||
| 297 | .p32 => @sizeOf(elf.Elf32_Phdr), | ||
| 298 | .p64 => @sizeOf(elf.Elf64_Phdr), | ||
| 299 | }; | ||
| 300 | const max_nphdrs = comptime getMaxNumberOfPhdrs(); | ||
| 301 | const reserved: u64 = mem.alignForward(u64, padToIdeal(max_nphdrs * phsize), self.page_size); | ||
| 296 | self.phdr_table_index = try self.addPhdr(.{ | 302 | self.phdr_table_index = try self.addPhdr(.{ |
| 297 | .type = elf.PT_PHDR, | 303 | .type = elf.PT_PHDR, |
| 298 | .flags = elf.PF_R, | 304 | .flags = elf.PF_R, |
| 299 | .@"align" = p_align, | 305 | .@"align" = p_align, |
| 300 | .addr = image_base + offset, | 306 | .addr = image_base + ehsize, |
| 301 | .offset = offset, | 307 | .offset = ehsize, |
| 308 | .filesz = reserved, | ||
| 309 | .memsz = reserved, | ||
| 302 | }); | 310 | }); |
| 303 | self.phdr_table_load_index = try self.addPhdr(.{ | 311 | self.phdr_table_load_index = try self.addPhdr(.{ |
| 304 | .type = elf.PT_LOAD, | 312 | .type = elf.PT_LOAD, |
| 305 | .flags = elf.PF_R, | 313 | .flags = elf.PF_R, |
| 306 | .@"align" = self.page_size, | 314 | .@"align" = self.page_size, |
| 307 | .addr = image_base, | 315 | .addr = image_base, |
| 316 | .offset = 0, | ||
| 317 | .filesz = reserved + ehsize, | ||
| 318 | .memsz = reserved + ehsize, | ||
| 308 | }); | 319 | }); |
| 309 | } | 320 | } |
| 310 | 321 | ||
| ... | @@ -543,7 +554,7 @@ fn detectAllocCollision(self: *Elf, start: u64, size: u64) ?u64 { | ... | @@ -543,7 +554,7 @@ fn detectAllocCollision(self: *Elf, start: u64, size: u64) ?u64 { |
| 543 | const shdr_size: u64 = if (small_ptr) @sizeOf(elf.Elf32_Shdr) else @sizeOf(elf.Elf64_Shdr); | 554 | const shdr_size: u64 = if (small_ptr) @sizeOf(elf.Elf32_Shdr) else @sizeOf(elf.Elf64_Shdr); |
| 544 | const tight_size = self.shdrs.items.len * shdr_size; | 555 | const tight_size = self.shdrs.items.len * shdr_size; |
| 545 | const increased_size = padToIdeal(tight_size); | 556 | const increased_size = padToIdeal(tight_size); |
| 546 | const test_end = off + increased_size; | 557 | const test_end = off +| increased_size; |
| 547 | if (end > off and start < test_end) { | 558 | if (end > off and start < test_end) { |
| 548 | return test_end; | 559 | return test_end; |
| 549 | } | 560 | } |
| ... | @@ -552,7 +563,7 @@ fn detectAllocCollision(self: *Elf, start: u64, size: u64) ?u64 { | ... | @@ -552,7 +563,7 @@ fn detectAllocCollision(self: *Elf, start: u64, size: u64) ?u64 { |
| 552 | for (self.shdrs.items) |shdr| { | 563 | for (self.shdrs.items) |shdr| { |
| 553 | if (shdr.sh_type == elf.SHT_NOBITS) continue; | 564 | if (shdr.sh_type == elf.SHT_NOBITS) continue; |
| 554 | const increased_size = padToIdeal(shdr.sh_size); | 565 | const increased_size = padToIdeal(shdr.sh_size); |
| 555 | const test_end = shdr.sh_offset + increased_size; | 566 | const test_end = shdr.sh_offset +| increased_size; |
| 556 | if (end > shdr.sh_offset and start < test_end) { | 567 | if (end > shdr.sh_offset and start < test_end) { |
| 557 | return test_end; | 568 | return test_end; |
| 558 | } | 569 | } |
| ... | @@ -561,7 +572,7 @@ fn detectAllocCollision(self: *Elf, start: u64, size: u64) ?u64 { | ... | @@ -561,7 +572,7 @@ fn detectAllocCollision(self: *Elf, start: u64, size: u64) ?u64 { |
| 561 | for (self.phdrs.items) |phdr| { | 572 | for (self.phdrs.items) |phdr| { |
| 562 | if (phdr.p_type != elf.PT_LOAD) continue; | 573 | if (phdr.p_type != elf.PT_LOAD) continue; |
| 563 | const increased_size = padToIdeal(phdr.p_filesz); | 574 | const increased_size = padToIdeal(phdr.p_filesz); |
| 564 | const test_end = phdr.p_offset + increased_size; | 575 | const test_end = phdr.p_offset +| increased_size; |
| 565 | if (end > phdr.p_offset and start < test_end) { | 576 | if (end > phdr.p_offset and start < test_end) { |
| 566 | return test_end; | 577 | return test_end; |
| 567 | } | 578 | } |
| ... | @@ -653,6 +664,7 @@ pub fn allocateAllocSection(self: *Elf, opts: AllocateAllocSectionOpts) error{Ou | ... | @@ -653,6 +664,7 @@ pub fn allocateAllocSection(self: *Elf, opts: AllocateAllocSectionOpts) error{Ou |
| 653 | .type = opts.type, | 664 | .type = opts.type, |
| 654 | .flags = opts.flags, | 665 | .flags = opts.flags, |
| 655 | .addralign = opts.alignment, | 666 | .addralign = opts.alignment, |
| 667 | .offset = std.math.maxInt(u64), | ||
| 656 | }); | 668 | }); |
| 657 | const shdr = &self.shdrs.items[index]; | 669 | const shdr = &self.shdrs.items[index]; |
| 658 | try self.phdr_to_shdr_table.putNoClobber(gpa, index, opts.phdr_index); | 670 | try self.phdr_to_shdr_table.putNoClobber(gpa, index, opts.phdr_index); |
| ... | @@ -690,6 +702,7 @@ fn allocateNonAllocSection(self: *Elf, opts: AllocateNonAllocSectionOpts) error{ | ... | @@ -690,6 +702,7 @@ fn allocateNonAllocSection(self: *Elf, opts: AllocateNonAllocSectionOpts) error{ |
| 690 | .info = opts.info, | 702 | .info = opts.info, |
| 691 | .addralign = opts.alignment, | 703 | .addralign = opts.alignment, |
| 692 | .entsize = opts.entsize, | 704 | .entsize = opts.entsize, |
| 705 | .offset = std.math.maxInt(u64), | ||
| 693 | }); | 706 | }); |
| 694 | const shdr = &self.shdrs.items[index]; | 707 | const shdr = &self.shdrs.items[index]; |
| 695 | const off = self.findFreeSpace(opts.size, opts.alignment); | 708 | const off = self.findFreeSpace(opts.size, opts.alignment); |
| ... | @@ -706,6 +719,8 @@ pub fn initMetadata(self: *Elf) !void { | ... | @@ -706,6 +719,8 @@ pub fn initMetadata(self: *Elf) !void { |
| 706 | const ptr_bit_width = self.base.options.target.ptrBitWidth(); | 719 | const ptr_bit_width = self.base.options.target.ptrBitWidth(); |
| 707 | const is_linux = self.base.options.target.os.tag == .linux; | 720 | const is_linux = self.base.options.target.os.tag == .linux; |
| 708 | 721 | ||
| 722 | comptime assert(number_of_zig_segments == 5); | ||
| 723 | |||
| 709 | if (self.phdr_zig_load_re_index == null) { | 724 | if (self.phdr_zig_load_re_index == null) { |
| 710 | self.phdr_zig_load_re_index = try self.allocateSegment(.{ | 725 | self.phdr_zig_load_re_index = try self.allocateSegment(.{ |
| 711 | .addr = if (ptr_bit_width >= 32) 0x8000000 else 0x8000, | 726 | .addr = if (ptr_bit_width >= 32) 0x8000000 else 0x8000, |
| ... | @@ -868,10 +883,10 @@ pub fn growAllocSection(self: *Elf, shdr_index: u16, needed_size: u64) !void { | ... | @@ -868,10 +883,10 @@ pub fn growAllocSection(self: *Elf, shdr_index: u16, needed_size: u64) !void { |
| 868 | const is_zerofill = shdr.sh_type == elf.SHT_NOBITS; | 883 | const is_zerofill = shdr.sh_type == elf.SHT_NOBITS; |
| 869 | 884 | ||
| 870 | if (needed_size > self.allocatedSize(shdr.sh_offset) and !is_zerofill) { | 885 | if (needed_size > self.allocatedSize(shdr.sh_offset) and !is_zerofill) { |
| 871 | // Must move the entire section. | ||
| 872 | const new_offset = self.findFreeSpace(needed_size, self.page_size); | ||
| 873 | const existing_size = shdr.sh_size; | 886 | const existing_size = shdr.sh_size; |
| 874 | shdr.sh_size = 0; | 887 | shdr.sh_size = 0; |
| 888 | // Must move the entire section. | ||
| 889 | const new_offset = self.findFreeSpace(needed_size, self.page_size); | ||
| 875 | 890 | ||
| 876 | log.debug("new '{s}' file offset 0x{x} to 0x{x}", .{ | 891 | log.debug("new '{s}' file offset 0x{x} to 0x{x}", .{ |
| 877 | self.shstrtab.getAssumeExists(shdr.sh_name), | 892 | self.shstrtab.getAssumeExists(shdr.sh_name), |
| ... | @@ -1600,7 +1615,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node | ... | @@ -1600,7 +1615,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1600 | try self.setVersionSymtab(); | 1615 | try self.setVersionSymtab(); |
| 1601 | try self.updateSectionSizes(); | 1616 | try self.updateSectionSizes(); |
| 1602 | 1617 | ||
| 1603 | self.allocatePhdrTable(); | 1618 | try self.allocatePhdrTable(); |
| 1604 | try self.allocateAllocSections(); | 1619 | try self.allocateAllocSections(); |
| 1605 | try self.sortPhdrs(); | 1620 | try self.sortPhdrs(); |
| 1606 | try self.allocateNonAllocSections(); | 1621 | try self.allocateNonAllocSections(); |
| ... | @@ -3841,6 +3856,7 @@ fn initSections(self: *Elf) !void { | ... | @@ -3841,6 +3856,7 @@ fn initSections(self: *Elf) !void { |
| 3841 | .type = elf.SHT_PROGBITS, | 3856 | .type = elf.SHT_PROGBITS, |
| 3842 | .flags = elf.SHF_ALLOC, | 3857 | .flags = elf.SHF_ALLOC, |
| 3843 | .addralign = ptr_size, | 3858 | .addralign = ptr_size, |
| 3859 | .offset = std.math.maxInt(u64), | ||
| 3844 | }); | 3860 | }); |
| 3845 | 3861 | ||
| 3846 | if (self.base.options.eh_frame_hdr) { | 3862 | if (self.base.options.eh_frame_hdr) { |
| ... | @@ -3849,6 +3865,7 @@ fn initSections(self: *Elf) !void { | ... | @@ -3849,6 +3865,7 @@ fn initSections(self: *Elf) !void { |
| 3849 | .type = elf.SHT_PROGBITS, | 3865 | .type = elf.SHT_PROGBITS, |
| 3850 | .flags = elf.SHF_ALLOC, | 3866 | .flags = elf.SHF_ALLOC, |
| 3851 | .addralign = 4, | 3867 | .addralign = 4, |
| 3868 | .offset = std.math.maxInt(u64), | ||
| 3852 | }); | 3869 | }); |
| 3853 | } | 3870 | } |
| 3854 | } | 3871 | } |
| ... | @@ -3859,6 +3876,7 @@ fn initSections(self: *Elf) !void { | ... | @@ -3859,6 +3876,7 @@ fn initSections(self: *Elf) !void { |
| 3859 | .type = elf.SHT_PROGBITS, | 3876 | .type = elf.SHT_PROGBITS, |
| 3860 | .flags = elf.SHF_ALLOC | elf.SHF_WRITE, | 3877 | .flags = elf.SHF_ALLOC | elf.SHF_WRITE, |
| 3861 | .addralign = ptr_size, | 3878 | .addralign = ptr_size, |
| 3879 | .offset = std.math.maxInt(u64), | ||
| 3862 | }); | 3880 | }); |
| 3863 | } | 3881 | } |
| 3864 | 3882 | ||
| ... | @@ -3880,6 +3898,7 @@ fn initSections(self: *Elf) !void { | ... | @@ -3880,6 +3898,7 @@ fn initSections(self: *Elf) !void { |
| 3880 | .flags = elf.SHF_ALLOC, | 3898 | .flags = elf.SHF_ALLOC, |
| 3881 | .addralign = @alignOf(elf.Elf64_Rela), | 3899 | .addralign = @alignOf(elf.Elf64_Rela), |
| 3882 | .entsize = @sizeOf(elf.Elf64_Rela), | 3900 | .entsize = @sizeOf(elf.Elf64_Rela), |
| 3901 | .offset = std.math.maxInt(u64), | ||
| 3883 | }); | 3902 | }); |
| 3884 | } | 3903 | } |
| 3885 | 3904 | ||
| ... | @@ -3889,12 +3908,14 @@ fn initSections(self: *Elf) !void { | ... | @@ -3889,12 +3908,14 @@ fn initSections(self: *Elf) !void { |
| 3889 | .type = elf.SHT_PROGBITS, | 3908 | .type = elf.SHT_PROGBITS, |
| 3890 | .flags = elf.SHF_ALLOC | elf.SHF_EXECINSTR, | 3909 | .flags = elf.SHF_ALLOC | elf.SHF_EXECINSTR, |
| 3891 | .addralign = 16, | 3910 | .addralign = 16, |
| 3911 | .offset = std.math.maxInt(u64), | ||
| 3892 | }); | 3912 | }); |
| 3893 | self.got_plt_section_index = try self.addSection(.{ | 3913 | self.got_plt_section_index = try self.addSection(.{ |
| 3894 | .name = ".got.plt", | 3914 | .name = ".got.plt", |
| 3895 | .type = elf.SHT_PROGBITS, | 3915 | .type = elf.SHT_PROGBITS, |
| 3896 | .flags = elf.SHF_ALLOC | elf.SHF_WRITE, | 3916 | .flags = elf.SHF_ALLOC | elf.SHF_WRITE, |
| 3897 | .addralign = @alignOf(u64), | 3917 | .addralign = @alignOf(u64), |
| 3918 | .offset = std.math.maxInt(u64), | ||
| 3898 | }); | 3919 | }); |
| 3899 | self.rela_plt_section_index = try self.addSection(.{ | 3920 | self.rela_plt_section_index = try self.addSection(.{ |
| 3900 | .name = ".rela.plt", | 3921 | .name = ".rela.plt", |
| ... | @@ -3902,6 +3923,7 @@ fn initSections(self: *Elf) !void { | ... | @@ -3902,6 +3923,7 @@ fn initSections(self: *Elf) !void { |
| 3902 | .flags = elf.SHF_ALLOC, | 3923 | .flags = elf.SHF_ALLOC, |
| 3903 | .addralign = @alignOf(elf.Elf64_Rela), | 3924 | .addralign = @alignOf(elf.Elf64_Rela), |
| 3904 | .entsize = @sizeOf(elf.Elf64_Rela), | 3925 | .entsize = @sizeOf(elf.Elf64_Rela), |
| 3926 | .offset = std.math.maxInt(u64), | ||
| 3905 | }); | 3927 | }); |
| 3906 | } | 3928 | } |
| 3907 | 3929 | ||
| ... | @@ -3911,6 +3933,7 @@ fn initSections(self: *Elf) !void { | ... | @@ -3911,6 +3933,7 @@ fn initSections(self: *Elf) !void { |
| 3911 | .type = elf.SHT_PROGBITS, | 3933 | .type = elf.SHT_PROGBITS, |
| 3912 | .flags = elf.SHF_ALLOC | elf.SHF_EXECINSTR, | 3934 | .flags = elf.SHF_ALLOC | elf.SHF_EXECINSTR, |
| 3913 | .addralign = 16, | 3935 | .addralign = 16, |
| 3936 | .offset = std.math.maxInt(u64), | ||
| 3914 | }); | 3937 | }); |
| 3915 | } | 3938 | } |
| 3916 | 3939 | ||
| ... | @@ -3919,6 +3942,7 @@ fn initSections(self: *Elf) !void { | ... | @@ -3919,6 +3942,7 @@ fn initSections(self: *Elf) !void { |
| 3919 | .name = ".copyrel", | 3942 | .name = ".copyrel", |
| 3920 | .type = elf.SHT_NOBITS, | 3943 | .type = elf.SHT_NOBITS, |
| 3921 | .flags = elf.SHF_ALLOC | elf.SHF_WRITE, | 3944 | .flags = elf.SHF_ALLOC | elf.SHF_WRITE, |
| 3945 | .offset = std.math.maxInt(u64), | ||
| 3922 | }); | 3946 | }); |
| 3923 | } | 3947 | } |
| 3924 | 3948 | ||
| ... | @@ -3937,6 +3961,7 @@ fn initSections(self: *Elf) !void { | ... | @@ -3937,6 +3961,7 @@ fn initSections(self: *Elf) !void { |
| 3937 | .type = elf.SHT_PROGBITS, | 3961 | .type = elf.SHT_PROGBITS, |
| 3938 | .flags = elf.SHF_ALLOC, | 3962 | .flags = elf.SHF_ALLOC, |
| 3939 | .addralign = 1, | 3963 | .addralign = 1, |
| 3964 | .offset = std.math.maxInt(u64), | ||
| 3940 | }); | 3965 | }); |
| 3941 | } | 3966 | } |
| 3942 | 3967 | ||
| ... | @@ -3947,6 +3972,7 @@ fn initSections(self: *Elf) !void { | ... | @@ -3947,6 +3972,7 @@ fn initSections(self: *Elf) !void { |
| 3947 | .type = elf.SHT_STRTAB, | 3972 | .type = elf.SHT_STRTAB, |
| 3948 | .entsize = 1, | 3973 | .entsize = 1, |
| 3949 | .addralign = 1, | 3974 | .addralign = 1, |
| 3975 | .offset = std.math.maxInt(u64), | ||
| 3950 | }); | 3976 | }); |
| 3951 | self.dynamic_section_index = try self.addSection(.{ | 3977 | self.dynamic_section_index = try self.addSection(.{ |
| 3952 | .name = ".dynamic", | 3978 | .name = ".dynamic", |
| ... | @@ -3954,6 +3980,7 @@ fn initSections(self: *Elf) !void { | ... | @@ -3954,6 +3980,7 @@ fn initSections(self: *Elf) !void { |
| 3954 | .type = elf.SHT_DYNAMIC, | 3980 | .type = elf.SHT_DYNAMIC, |
| 3955 | .entsize = @sizeOf(elf.Elf64_Dyn), | 3981 | .entsize = @sizeOf(elf.Elf64_Dyn), |
| 3956 | .addralign = @alignOf(elf.Elf64_Dyn), | 3982 | .addralign = @alignOf(elf.Elf64_Dyn), |
| 3983 | .offset = std.math.maxInt(u64), | ||
| 3957 | }); | 3984 | }); |
| 3958 | self.dynsymtab_section_index = try self.addSection(.{ | 3985 | self.dynsymtab_section_index = try self.addSection(.{ |
| 3959 | .name = ".dynsym", | 3986 | .name = ".dynsym", |
| ... | @@ -3962,6 +3989,7 @@ fn initSections(self: *Elf) !void { | ... | @@ -3962,6 +3989,7 @@ fn initSections(self: *Elf) !void { |
| 3962 | .addralign = @alignOf(elf.Elf64_Sym), | 3989 | .addralign = @alignOf(elf.Elf64_Sym), |
| 3963 | .entsize = @sizeOf(elf.Elf64_Sym), | 3990 | .entsize = @sizeOf(elf.Elf64_Sym), |
| 3964 | .info = 1, | 3991 | .info = 1, |
| 3992 | .offset = std.math.maxInt(u64), | ||
| 3965 | }); | 3993 | }); |
| 3966 | self.hash_section_index = try self.addSection(.{ | 3994 | self.hash_section_index = try self.addSection(.{ |
| 3967 | .name = ".hash", | 3995 | .name = ".hash", |
| ... | @@ -3969,12 +3997,14 @@ fn initSections(self: *Elf) !void { | ... | @@ -3969,12 +3997,14 @@ fn initSections(self: *Elf) !void { |
| 3969 | .type = elf.SHT_HASH, | 3997 | .type = elf.SHT_HASH, |
| 3970 | .addralign = 4, | 3998 | .addralign = 4, |
| 3971 | .entsize = 4, | 3999 | .entsize = 4, |
| 4000 | .offset = std.math.maxInt(u64), | ||
| 3972 | }); | 4001 | }); |
| 3973 | self.gnu_hash_section_index = try self.addSection(.{ | 4002 | self.gnu_hash_section_index = try self.addSection(.{ |
| 3974 | .name = ".gnu.hash", | 4003 | .name = ".gnu.hash", |
| 3975 | .flags = elf.SHF_ALLOC, | 4004 | .flags = elf.SHF_ALLOC, |
| 3976 | .type = elf.SHT_GNU_HASH, | 4005 | .type = elf.SHT_GNU_HASH, |
| 3977 | .addralign = 8, | 4006 | .addralign = 8, |
| 4007 | .offset = std.math.maxInt(u64), | ||
| 3978 | }); | 4008 | }); |
| 3979 | 4009 | ||
| 3980 | const needs_versions = for (self.dynsym.entries.items) |entry| { | 4010 | const needs_versions = for (self.dynsym.entries.items) |entry| { |
| ... | @@ -3988,12 +4018,14 @@ fn initSections(self: *Elf) !void { | ... | @@ -3988,12 +4018,14 @@ fn initSections(self: *Elf) !void { |
| 3988 | .type = elf.SHT_GNU_VERSYM, | 4018 | .type = elf.SHT_GNU_VERSYM, |
| 3989 | .addralign = @alignOf(elf.Elf64_Versym), | 4019 | .addralign = @alignOf(elf.Elf64_Versym), |
| 3990 | .entsize = @sizeOf(elf.Elf64_Versym), | 4020 | .entsize = @sizeOf(elf.Elf64_Versym), |
| 4021 | .offset = std.math.maxInt(u64), | ||
| 3991 | }); | 4022 | }); |
| 3992 | self.verneed_section_index = try self.addSection(.{ | 4023 | self.verneed_section_index = try self.addSection(.{ |
| 3993 | .name = ".gnu.version_r", | 4024 | .name = ".gnu.version_r", |
| 3994 | .flags = elf.SHF_ALLOC, | 4025 | .flags = elf.SHF_ALLOC, |
| 3995 | .type = elf.SHT_GNU_VERNEED, | 4026 | .type = elf.SHT_GNU_VERNEED, |
| 3996 | .addralign = @alignOf(elf.Elf64_Verneed), | 4027 | .addralign = @alignOf(elf.Elf64_Verneed), |
| 4028 | .offset = std.math.maxInt(u64), | ||
| 3997 | }); | 4029 | }); |
| 3998 | } | 4030 | } |
| 3999 | } | 4031 | } |
| ... | @@ -4004,6 +4036,7 @@ fn initSections(self: *Elf) !void { | ... | @@ -4004,6 +4036,7 @@ fn initSections(self: *Elf) !void { |
| 4004 | .type = elf.SHT_SYMTAB, | 4036 | .type = elf.SHT_SYMTAB, |
| 4005 | .addralign = if (small_ptr) @alignOf(elf.Elf32_Sym) else @alignOf(elf.Elf64_Sym), | 4037 | .addralign = if (small_ptr) @alignOf(elf.Elf32_Sym) else @alignOf(elf.Elf64_Sym), |
| 4006 | .entsize = if (small_ptr) @sizeOf(elf.Elf32_Sym) else @sizeOf(elf.Elf64_Sym), | 4038 | .entsize = if (small_ptr) @sizeOf(elf.Elf32_Sym) else @sizeOf(elf.Elf64_Sym), |
| 4039 | .offset = std.math.maxInt(u64), | ||
| 4007 | }); | 4040 | }); |
| 4008 | } | 4041 | } |
| 4009 | if (self.strtab_section_index == null) { | 4042 | if (self.strtab_section_index == null) { |
| ... | @@ -4012,6 +4045,7 @@ fn initSections(self: *Elf) !void { | ... | @@ -4012,6 +4045,7 @@ fn initSections(self: *Elf) !void { |
| 4012 | .type = elf.SHT_STRTAB, | 4045 | .type = elf.SHT_STRTAB, |
| 4013 | .entsize = 1, | 4046 | .entsize = 1, |
| 4014 | .addralign = 1, | 4047 | .addralign = 1, |
| 4048 | .offset = std.math.maxInt(u64), | ||
| 4015 | }); | 4049 | }); |
| 4016 | } | 4050 | } |
| 4017 | if (self.shstrtab_section_index == null) { | 4051 | if (self.shstrtab_section_index == null) { |
| ... | @@ -4020,11 +4054,14 @@ fn initSections(self: *Elf) !void { | ... | @@ -4020,11 +4054,14 @@ fn initSections(self: *Elf) !void { |
| 4020 | .type = elf.SHT_STRTAB, | 4054 | .type = elf.SHT_STRTAB, |
| 4021 | .entsize = 1, | 4055 | .entsize = 1, |
| 4022 | .addralign = 1, | 4056 | .addralign = 1, |
| 4057 | .offset = std.math.maxInt(u64), | ||
| 4023 | }); | 4058 | }); |
| 4024 | } | 4059 | } |
| 4025 | } | 4060 | } |
| 4026 | 4061 | ||
| 4027 | fn initSpecialPhdrs(self: *Elf) !void { | 4062 | fn initSpecialPhdrs(self: *Elf) !void { |
| 4063 | comptime assert(max_number_of_special_phdrs == 5); | ||
| 4064 | |||
| 4028 | if (self.interp_section_index != null) { | 4065 | if (self.interp_section_index != null) { |
| 4029 | self.phdr_interp_index = try self.addPhdr(.{ | 4066 | self.phdr_interp_index = try self.addPhdr(.{ |
| 4030 | .type = elf.PT_INTERP, | 4067 | .type = elf.PT_INTERP, |
| ... | @@ -4613,6 +4650,21 @@ fn shdrToPhdrFlags(sh_flags: u64) u32 { | ... | @@ -4613,6 +4650,21 @@ fn shdrToPhdrFlags(sh_flags: u64) u32 { |
| 4613 | return out_flags; | 4650 | return out_flags; |
| 4614 | } | 4651 | } |
| 4615 | 4652 | ||
| 4653 | /// Returns maximum number of program headers that may be emitted by the linker. | ||
| 4654 | /// (This is an upper bound so that we can reserve enough space for the header and progam header | ||
| 4655 | /// table without running out of space and being forced to move things around.) | ||
| 4656 | fn getMaxNumberOfPhdrs() u64 { | ||
| 4657 | // First, assume we compile Zig's source incrementally, this gives us: | ||
| 4658 | var num: u64 = number_of_zig_segments; | ||
| 4659 | // Next, the estimated maximum number of segments the linker can emit for input sections are: | ||
| 4660 | num += max_number_of_object_segments; | ||
| 4661 | // Next, any other non-loadable program headers, including TLS, DYNAMIC, GNU_STACK, GNU_EH_FRAME, INTERP: | ||
| 4662 | num += max_number_of_special_phdrs; | ||
| 4663 | // Finally, PHDR program header and corresponding read-only load segment: | ||
| 4664 | num += 2; | ||
| 4665 | return num; | ||
| 4666 | } | ||
| 4667 | |||
| 4616 | /// Calculates how many segments (PT_LOAD progam headers) are required | 4668 | /// Calculates how many segments (PT_LOAD progam headers) are required |
| 4617 | /// to cover the set of sections. | 4669 | /// to cover the set of sections. |
| 4618 | /// We permit a maximum of 3**2 number of segments. | 4670 | /// We permit a maximum of 3**2 number of segments. |
| ... | @@ -4633,30 +4685,36 @@ fn calcNumberOfSegments(self: *Elf) usize { | ... | @@ -4633,30 +4685,36 @@ fn calcNumberOfSegments(self: *Elf) usize { |
| 4633 | } | 4685 | } |
| 4634 | 4686 | ||
| 4635 | /// Allocates PHDR table in virtual memory and in file. | 4687 | /// Allocates PHDR table in virtual memory and in file. |
| 4636 | fn allocatePhdrTable(self: *Elf) void { | 4688 | fn allocatePhdrTable(self: *Elf) error{OutOfMemory}!void { |
| 4637 | const new_load_segments = self.calcNumberOfSegments(); | 4689 | const new_load_segments = self.calcNumberOfSegments(); |
| 4638 | const phdr_table = &self.phdrs.items[self.phdr_table_index.?]; | 4690 | const phdr_table = &self.phdrs.items[self.phdr_table_index.?]; |
| 4639 | const phdr_table_load = &self.phdrs.items[self.phdr_table_load_index.?]; | 4691 | const phdr_table_load = &self.phdrs.items[self.phdr_table_load_index.?]; |
| 4640 | 4692 | ||
| 4693 | const ehsize: u64 = switch (self.ptr_width) { | ||
| 4694 | .p32 => @sizeOf(elf.Elf32_Ehdr), | ||
| 4695 | .p64 => @sizeOf(elf.Elf64_Ehdr), | ||
| 4696 | }; | ||
| 4641 | const phsize: u64 = switch (self.ptr_width) { | 4697 | const phsize: u64 = switch (self.ptr_width) { |
| 4642 | .p32 => @sizeOf(elf.Elf32_Phdr), | 4698 | .p32 => @sizeOf(elf.Elf32_Phdr), |
| 4643 | .p64 => @sizeOf(elf.Elf64_Phdr), | 4699 | .p64 => @sizeOf(elf.Elf64_Phdr), |
| 4644 | }; | 4700 | }; |
| 4645 | const needed_size = (self.phdrs.items.len + new_load_segments) * phsize; | 4701 | const needed_size = (self.phdrs.items.len + new_load_segments) * phsize; |
| 4702 | const available_space = self.allocatedSize(phdr_table.p_offset); | ||
| 4646 | 4703 | ||
| 4647 | if (needed_size > self.allocatedSize(phdr_table.p_offset)) { | 4704 | if (needed_size > available_space) { |
| 4648 | phdr_table.p_offset = 0; | 4705 | // In this case, we have two options: |
| 4649 | phdr_table.p_offset = self.findFreeSpace(needed_size, phdr_table.p_align); | 4706 | // 1. increase the available padding for EHDR + PHDR table so that we don't overflow it |
| 4707 | // (revisit getMaxNumberOfPhdrs()) | ||
| 4708 | // 2. shift everything in file to free more space for EHDR + PHDR table | ||
| 4709 | // TODO verify `getMaxNumberOfPhdrs()` is accurate and convert this into no-op | ||
| 4710 | var err = try self.addErrorWithNotes(1); | ||
| 4711 | try err.addMsg(self, "fatal linker error: not enough space reserved for EHDR and PHDR table", .{}); | ||
| 4712 | try err.addNote(self, "required 0x{x}, available 0x{x}", .{ needed_size, available_space }); | ||
| 4650 | } | 4713 | } |
| 4651 | 4714 | ||
| 4652 | phdr_table_load.p_offset = mem.alignBackward(u64, phdr_table.p_offset, phdr_table_load.p_align); | 4715 | phdr_table_load.p_filesz = needed_size + ehsize; |
| 4653 | const load_align_offset = phdr_table.p_offset - phdr_table_load.p_offset; | 4716 | phdr_table_load.p_memsz = needed_size + ehsize; |
| 4654 | phdr_table_load.p_filesz = load_align_offset + needed_size; | ||
| 4655 | phdr_table_load.p_memsz = load_align_offset + needed_size; | ||
| 4656 | |||
| 4657 | phdr_table.p_filesz = needed_size; | 4717 | phdr_table.p_filesz = needed_size; |
| 4658 | phdr_table.p_vaddr = phdr_table_load.p_vaddr + load_align_offset; | ||
| 4659 | phdr_table.p_paddr = phdr_table_load.p_paddr + load_align_offset; | ||
| 4660 | phdr_table.p_memsz = needed_size; | 4718 | phdr_table.p_memsz = needed_size; |
| 4661 | } | 4719 | } |
| 4662 | 4720 | ||
| ... | @@ -4701,7 +4759,7 @@ fn allocateAllocSections(self: *Elf) error{OutOfMemory}!void { | ... | @@ -4701,7 +4759,7 @@ fn allocateAllocSections(self: *Elf) error{OutOfMemory}!void { |
| 4701 | // with `findFreeSpace` mechanics than anything else. | 4759 | // with `findFreeSpace` mechanics than anything else. |
| 4702 | const Cover = std.ArrayList(u16); | 4760 | const Cover = std.ArrayList(u16); |
| 4703 | const gpa = self.base.allocator; | 4761 | const gpa = self.base.allocator; |
| 4704 | var covers: [9]Cover = undefined; | 4762 | var covers: [max_number_of_object_segments]Cover = undefined; |
| 4705 | for (&covers) |*cover| { | 4763 | for (&covers) |*cover| { |
| 4706 | cover.* = Cover.init(gpa); | 4764 | cover.* = Cover.init(gpa); |
| 4707 | } | 4765 | } |
| ... | @@ -5651,6 +5709,7 @@ pub const AddSectionOpts = struct { | ... | @@ -5651,6 +5709,7 @@ pub const AddSectionOpts = struct { |
| 5651 | info: u32 = 0, | 5709 | info: u32 = 0, |
| 5652 | addralign: u64 = 0, | 5710 | addralign: u64 = 0, |
| 5653 | entsize: u64 = 0, | 5711 | entsize: u64 = 0, |
| 5712 | offset: u64 = 0, | ||
| 5654 | }; | 5713 | }; |
| 5655 | 5714 | ||
| 5656 | pub fn addSection(self: *Elf, opts: AddSectionOpts) !u16 { | 5715 | pub fn addSection(self: *Elf, opts: AddSectionOpts) !u16 { |
| ... | @@ -5662,7 +5721,7 @@ pub fn addSection(self: *Elf, opts: AddSectionOpts) !u16 { | ... | @@ -5662,7 +5721,7 @@ pub fn addSection(self: *Elf, opts: AddSectionOpts) !u16 { |
| 5662 | .sh_type = opts.type, | 5721 | .sh_type = opts.type, |
| 5663 | .sh_flags = opts.flags, | 5722 | .sh_flags = opts.flags, |
| 5664 | .sh_addr = 0, | 5723 | .sh_addr = 0, |
| 5665 | .sh_offset = 0, | 5724 | .sh_offset = opts.offset, |
| 5666 | .sh_size = 0, | 5725 | .sh_size = 0, |
| 5667 | .sh_link = opts.link, | 5726 | .sh_link = opts.link, |
| 5668 | .sh_info = opts.info, | 5727 | .sh_info = opts.info, |
| ... | @@ -6231,6 +6290,15 @@ pub fn lsearch(comptime T: type, haystack: []align(1) const T, predicate: anytyp | ... | @@ -6231,6 +6290,15 @@ pub fn lsearch(comptime T: type, haystack: []align(1) const T, predicate: anytyp |
| 6231 | return i; | 6290 | return i; |
| 6232 | } | 6291 | } |
| 6233 | 6292 | ||
| 6293 | /// The following three values are only observed at compile-time and used to emit a compile error | ||
| 6294 | /// to remind the programmer to update expected maximum numbers of different program header types | ||
| 6295 | /// so that we reserve enough space for the program header table up-front. | ||
| 6296 | /// Bump these numbers when adding or deleting a Zig specific pre-allocated segment, or adding | ||
| 6297 | /// more special-purpose program headers. | ||
| 6298 | const number_of_zig_segments = 5; | ||
| 6299 | const max_number_of_object_segments = 9; | ||
| 6300 | const max_number_of_special_phdrs = 5; | ||
| 6301 | |||
| 6234 | const default_entry_addr = 0x8000000; | 6302 | const default_entry_addr = 0x8000000; |
| 6235 | 6303 | ||
| 6236 | pub const base_tag: link.File.Tag = .elf; | 6304 | pub const base_tag: link.File.Tag = .elf; |
test/behavior/math.zig+1-1| ... | @@ -670,11 +670,11 @@ fn should_not_be_zero(x: f128) !void { | ... | @@ -670,11 +670,11 @@ fn should_not_be_zero(x: f128) !void { |
| 670 | 670 | ||
| 671 | test "128-bit multiplication" { | 671 | test "128-bit multiplication" { |
| 672 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 672 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 673 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 674 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 673 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 675 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 674 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 676 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 675 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 677 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 676 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 677 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | ||
| 678 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | 678 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; |
| 679 | 679 | ||
| 680 | { | 680 | { |
test/tests.zig+1-1| ... | @@ -1006,7 +1006,7 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { | ... | @@ -1006,7 +1006,7 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { |
| 1006 | 1006 | ||
| 1007 | // TODO get std lib tests passing for other self-hosted backends. | 1007 | // TODO get std lib tests passing for other self-hosted backends. |
| 1008 | if ((test_target.target.getCpuArch() != .x86_64 or | 1008 | if ((test_target.target.getCpuArch() != .x86_64 or |
| 1009 | test_target.target.getObjectFormat() != .elf) and | 1009 | test_target.target.getOsTag() != .linux) and |
| 1010 | test_target.use_llvm == false and mem.eql(u8, options.name, "std")) | 1010 | test_target.use_llvm == false and mem.eql(u8, options.name, "std")) |
| 1011 | continue; | 1011 | continue; |
| 1012 | 1012 |