authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-10-25 23:25:56+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-10-25 23:25:56+02:00
logcc394431ae6eb69e7abd677c268a8ab7299f8aeb
treed5aa705cdc7d701b53f32a8c2acc099c2dbd90c5
parent10ea7accf76d4ad59222ea5ff3585d6cc7cfe3b0
parented00afbc4c1eec6d599ac277e364b4a1ed11fe5c
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #17699 from ziglang/elf-better-alloc

elf: allocated PHDR table always immediately succeeding the EHDR

40 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}
4343
44test "test_divmodti4" {44test "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 }
373373
374 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
375
374 const num_threads = 4;376 const num_threads = 4;
375377
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}
736736
737test "URI escaping" {737test "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";
742740
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 or738 if (builtin.zig_backend == .stage2_wasm or
739 builtin.zig_backend == .stage2_arm or739 builtin.zig_backend == .stage2_arm or
740 builtin.zig_backend == .stage2_aarch64 or740 builtin.zig_backend == .stage2_aarch64 or
741 builtin.zig_backend == .stage2_x86_64 or
742 builtin.zig_backend == .stage2_x86 or741 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 or743 builtin.zig_backend == .stage2_riscv64 or
744 builtin.zig_backend == .stage2_sparc64 or744 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}
2424
25test "LZMA: decompress empty world" {25test "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}
8987
90test "LZMA: too big uncompressed size in header" {88test "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}
9894
99test "LZMA: too small uncompressed size in header" {95test "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 @@
1const std = @import("std");1const std = @import("std");
2const builtin = @import("builtin");
3const crypto = std.crypto;2const crypto = std.crypto;
43
5const IdentityElementError = crypto.errors.IdentityElementError;4const IdentityElementError = crypto.errors.IdentityElementError;
...@@ -112,8 +111,6 @@ pub const Curve25519 = struct {...@@ -112,8 +111,6 @@ pub const Curve25519 = struct {
112};111};
113112
114test "curve25519" {113test "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}
129126
130test "curve25519 small order check" {127test "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};
485485
486test "ed25519 key pair creation" {486test "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 @@
1const std = @import("std");1const std = @import("std");
2const builtin = @import("builtin");
3const crypto = std.crypto;2const crypto = std.crypto;
4const debug = std.debug;3const debug = std.debug;
5const fmt = std.fmt;4const fmt = std.fmt;
...@@ -495,8 +494,6 @@ pub const Edwards25519 = struct {...@@ -495,8 +494,6 @@ pub const Edwards25519 = struct {
495const htest = @import("../test.zig");494const htest = @import("../test.zig");
496495
497test "edwards25519 packing/unpacking" {496test "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}
534531
535test "edwards25519 point addition/subtraction" {532test "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}
550545
551test "edwards25519 uniform-to-point" {546test "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" {
562555
563// Test vectors from draft-irtf-cfrg-hash-to-curve-12556// Test vectors from draft-irtf-cfrg-hash-to-curve-12
564test "edwards25519 hash-to-curve operation" {557test "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..]);
569560
...@@ -572,8 +563,6 @@ test "edwards25519 hash-to-curve operation" {...@@ -572,8 +563,6 @@ test "edwards25519 hash-to-curve operation" {
572}563}
573564
574test "edwards25519 implicit reduction of invalid scalars" {565test "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};
169169
170test "ristretto255" {170test "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 @@
1const std = @import("std");1const std = @import("std");
2const builtin = @import("builtin");
3const crypto = std.crypto;2const crypto = std.crypto;
4const mem = std.mem;3const mem = std.mem;
5const fmt = std.fmt;4const fmt = std.fmt;
...@@ -83,8 +82,6 @@ pub const X25519 = struct {...@@ -83,8 +82,6 @@ pub const X25519 = struct {
83const htest = @import("../test.zig");82const htest = @import("../test.zig");
8483
85test "x25519 public key calculation from secret key" {84test "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}
9592
96test "x25519 rfc7748 vector1" {93test "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 };
10196
...@@ -106,8 +101,6 @@ test "x25519 rfc7748 vector1" {...@@ -106,8 +101,6 @@ test "x25519 rfc7748 vector1" {
106}101}
107102
108test "x25519 rfc7748 vector2" {103test "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 };
113106
...@@ -118,8 +111,6 @@ test "x25519 rfc7748 vector2" {...@@ -118,8 +111,6 @@ test "x25519 rfc7748 vector2" {
118}111}
119112
120test "x25519 rfc7748 one iteration" {113test "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 };
125116
...@@ -180,8 +171,6 @@ test "x25519 rfc7748 1,000,000 iterations" {...@@ -180,8 +171,6 @@ test "x25519 rfc7748 1,000,000 iterations" {
180}171}
181172
182test "edwards25519 -> curve25519 map" {173test "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" {
821821
822// https://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04#section-7822// https://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04#section-7
823test "crypto.chacha20 test vector 1" {823test "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}
858856
859test "crypto.chacha20 test vector 2" {857test "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}
894890
895test "crypto.chacha20 test vector 3" {891test "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}
930924
931test "crypto.chacha20 test vector 4" {925test "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}
966958
967test "crypto.chacha20 test vector 5" {959test "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}
599599
600test "xsalsa20poly1305 box" {600test "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}
615613
616test "xsalsa20poly1305 sealedbox" {614test "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}
21302130
2131test "int.specifier" {2131test "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}
21822180
2183test "buffer" {2181test "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}
23802376
2381test "float.scientific.precision" {2377test "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}
24582452
2459test "float.decimal" {2453test "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}
24832475
2484test "float.libc.sanity" {2476test "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}
25042494
2505test "custom" {2495test "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}
26842672
2685test "formatType max_depth" {2673test "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}
27602746
2761test "positional with specifier" {2747test "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}
27662750
2767test "positional/alignment/width/precision" {2751test "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}
27722754
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}
8585
86test "fmt.parseFloat #11169" {86test "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}
9189
...@@ -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}
164test "fmt.parseFloat hex.f128" {162test "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;
16061606
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();
16111609
...@@ -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;
16341632
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();
16391635
lib/std/json.zig-4
...@@ -24,8 +24,6 @@ test Scanner {...@@ -24,8 +24,6 @@ test Scanner {
24}24}
2525
26test parseFromSlice {26test 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}
4543
46test writeStream {44test 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}
373373
374test "parse" {374test "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}
406404
407test "parse into that allocates a slice" {405test "parse into that allocates a slice" {
408 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
409
410 {406 {
411 // string as string407 // 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}
428424
429test "parse into sentinel slice" {425test "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}
436430
437test "parse into tagged union" {431test "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}
453445
454test "parse into tagged union errors" {446test "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" {
485const test_const_value: usize = 123;475const test_const_value: usize = 123;
486476
487test "parse into struct with default const pointer field" {477test "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};
503491
504test "freeing parsed structs with pointers to default values" {492test "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}
518504
519test "parse into struct where destination and source lengths mismatch" {505test "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}
525509
526test "parse into struct with misc fields" {510test "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}
602584
603test "parse into struct with strings and arrays with sentinels" {585test "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}
632612
633test "parse into struct with duplicate field" {613test "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 };
638616
...@@ -652,8 +630,6 @@ test "parse into struct with duplicate field" {...@@ -652,8 +630,6 @@ test "parse into struct with duplicate field" {
652}630}
653631
654test "parse into struct ignoring unknown fields" {632test "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}
693669
694test "parse into tuple" {670test "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};
750724
751test "parse into recursive union definition" {725test "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};
773745
774test "parse into double recursive union definition" {746test "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}
786756
787test "parse exponential into int" {757test "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}
796764
797test "parseFromTokenSource" {765test "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}
817783
818test "max_value_len" {784test "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}
823787
...@@ -856,8 +820,6 @@ fn assertKey(...@@ -856,8 +820,6 @@ fn assertKey(
856 }820 }
857}821}
858test "json parse partial" {822test "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}
914876
915test "json parse allocate when streaming" {877test "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}
199199
200test "emit_strings_as_arrays" {200test "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}
17571757
1758test "readIntBig and readIntLittle" {1758test "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 }
17631761
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;
5const testing = std.testing;5const testing = std.testing;
66
7test "parse and render IPv6 addresses" {7test "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;
109
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}
7271
73test "parse and render IPv4 addresses" {72test "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;
7674
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), %%rsi431 \\ leaq %[stack_offset:c](%%rdi), %%rsi
432 \\ movq %%rdi, %%r8432 \\ movq %%rdi, %%r8
433 \\ xorl %%edi, %%edi433 \\ xorl %%edi, %%edi
434 \\ movq %[sigaltstack], %%rax434 \\ movl %[sigaltstack], %%eax
435 \\ syscall435 \\ syscall
436 \\ testq %%rax, %%rax436 \\ testq %%rax, %%rax
437 \\ jnz 0f437 \\ jnz 0f
438 \\ movq %[sigprocmask], %%rax438 \\ movl %[sigprocmask], %%eax
439 \\ xorl %%esi, %%esi439 \\ xorl %%esi, %%esi
440 \\ leaq %[sigmask_offset:c](%%r8), %%rdx440 \\ leaq %[sigmask_offset:c](%%r8), %%rdx
441 \\ movl %[sigset_size], %%r10d441 \\ 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 {
509test "dl_iterate_phdr" {509test "dl_iterate_phdr" {
510 if (builtin.object_format != .elf) return error.SkipZigTest;510 if (builtin.object_format != .elf) return error.SkipZigTest;
511511
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;
806804
807 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
808
809 // https://github.com/ziglang/zig/issues/7427805 // 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}
159159
160test "Random intLessThan" {160test "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 {
733733
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 }
738745
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 {
745752
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 }
750764
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 }
775789
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 };
783807
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}
792792
793test "CrossTarget.parse" {793test "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}
9696
97test "escape invalid identifiers" {97test "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 {
5846pub fn backendSupportsFeature(mod: Module, feature: Feature) bool {5846pub 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 or5848 .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 or5851 .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 or5853 .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}
11461146
1147/// A `cc` of `.z_and_np` clobbers `reg2`!1147/// A `cc` of `.z_and_np` clobbers `reg2`!
1148fn asmCmovccRegisterRegister(self: *Self, cc: bits.Condition, reg1: Register, reg2: Register) !void {1148fn 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}
11691169
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!
1171fn asmCmovccRegisterMemory(self: *Self, cc: bits.Condition, reg: Register, m: Memory) !void {1171fn 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}
12061206
1207fn asmSetccRegister(self: *Self, reg: Register, cc: bits.Condition) !void {1207fn 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}
12301230
1231fn asmSetccMemory(self: *Self, m: Memory, cc: bits.Condition) !void {1231fn 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}
12811281
1282fn asmJccReloc(self: *Self, target: Mir.Inst.Index, cc: bits.Condition) !Mir.Inst.Index {1282fn 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 );
18061806
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);
18091809
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);
22662269
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 {
2298fn freeValue(self: *Self, value: MCValue) !void {2301fn 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 }
24232426
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)];
24302435
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 );
32483253
...@@ -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 );
33313336
...@@ -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 );
34073412
...@@ -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);
36183623
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());
36213626
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(
36313636
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 });
36693803
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 };
36753808
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);
36833811
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 else3814 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 {
3741fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue, rhs: MCValue) !void {3868fn 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}
37863915
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 {
39814110
3982fn airUnwrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {4111fn 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}
39894118
3990fn 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) -> E4119// *(E!T) -> E
4033fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void {4120fn 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 {
40674154
4068// *(E!T) -> *T4155// *(E!T) -> *T
4069fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {4156fn 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;
40724158 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}
41034163
4104fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {4164fn 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}
41524212
4213fn 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
4255fn 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
4153fn airErrReturnTrace(self: *Self, inst: Air.Inst.Index) !void {4278fn 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}
1024810377
10249fn airTryPtr(self: *Self, inst: Air.Inst.Index) !void {10378fn 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}
1025810386
10259fn genTry(10387fn 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);
1027110396
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);
1027410402
10275 const reloc = try self.genCondBrMir(Type.anyerror, is_err_mcv);10403 const reloc = try self.genCondBrMir(Type.anyerror, is_err_mcv);
1027610404
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 }
1028010408
10281 self.scope_generation += 1;10409 self.scope_generation += 1;
10282 const state = try self.saveState();10410 const state = try self.saveState();
1028310411
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(
1029210420
10293 try self.performReloc(reloc);10421 try self.performReloc(reloc);
1029410422
10295 for (liveness_cond_br.then_deaths) |operand| try self.processDeath(operand);10423 for (liveness_cond_br.then_deaths) |death| try self.processDeath(death);
1029610424
10297 const result = if (self.liveness.isUnused(inst))10425 const result = if (self.liveness.isUnused(inst))
10298 .unreach10426 .unreach
10427 else if (operand_is_ptr)
10428 try self.genUnwrapErrUnionPayloadPtrMir(inst, operand_ty, operand_mcv)
10299 else10429 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}
1030310433
...@@ -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();
1039310523
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 {
1040210532
10403 try self.performReloc(reloc);10533 try self.performReloc(reloc);
1040410534
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
1051710647
10518fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) !MCValue {10648fn 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);
1052410652
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 else10657 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}
1055010680
10551fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, ty: Type, operand: MCValue) !MCValue {10681fn 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);
1055410684 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 }
1055810685
10559 try self.spillEflagsIfOccupied();10686 try self.spillEflagsIfOccupied();
1056010687
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);
1056610693
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 }
1059610723
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}
1060010727
10601fn isNonErr(self: *Self, inst: Air.Inst.Index, ty: Type, operand: MCValue) !MCValue {10728fn 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
10757fn 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
10772fn 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}
1066110832
10662fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void {10833fn 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;
1066510835 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}
1068810840
...@@ -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}
1069610848
10697fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void {10849fn 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;
1070010851 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}
1072310856
...@@ -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 }
1081510948
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 orelse11502 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) catch11504 .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..]) orelse11529 .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-bit12011 // 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);
1293613101
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 {
1308413249
13085 try self.genSetReg(len_reg, Type.usize, len);13250 try self.genSetReg(len_reg, Type.usize, len);
1308613251
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);
1308913254
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);
1404514210
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);
1408414249
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 {
3838
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});
167167
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 }
208208
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 // X87262 // X87
263 fabs, fchs, ffree, fisttp, fld, fst, fstp,263 fabs, fchs, ffree, fisttp, fld, fldenv, fnstenv, fst, fstenv, fstp,
264 // MMX264 // 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 // F16C406 // F16C
...@@ -411,7 +415,7 @@ pub const Mnemonic = enum {...@@ -411,7 +415,7 @@ pub const Mnemonic = enum {
411415
412pub const OpEn = enum {416pub const OpEn = enum {
413 // zig fmt: off417 // 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: on621 // 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: on637 // 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 1395 /// Return the count of number of bits set to 1
396 popcnt,396 popcnt,
397 /// Pop stack into EFLAGS register
398 popfq,
397 /// Push399 /// Push
398 push,400 push,
401 /// Push EFLAGS register onto the stack
402 pushfq,
399 /// Rotate left through carry403 /// Rotate left through carry
400 /// Rotate right through carry404 /// 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 value463 /// 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 value469 /// Store floating-point value
462 st,470 st,
471 /// Store x87 FPU environment
472 stenv,
463473
464 /// Pack with signed saturation474 /// 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 saturation515 /// Subtract packed unsigned integers with unsigned saturation
506 subus,516 subus,
507517
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 values523 /// Convert packed doubleword integers to packed single-precision floating-point values
509 /// Convert packed doubleword integers to packed double-precision floating-point values524 /// 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 }
10811096
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};
10861105
1087pub const Imm32 = struct {1106pub 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 };
471471
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) {
508509
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 };
522535
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});
114114
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 }
223223
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 }
301301
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;
337337
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();
371371
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 },
123123
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 },
127126
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 },
131130
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 },
135134
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 },
249248
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 },
254253
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 },
259258
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 },
268267
269 .{ .cpuid, .np, &.{}, &.{ 0x0f, 0xa2 }, 0, .none, .none },268 .{ .cpuid, .zo, &.{}, &.{ 0x0f, 0xa2 }, 0, .none, .none },
270269
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 },
297296
298 .{ .int3, .np, &.{}, &.{ 0xcc }, 0, .none, .none },297 .{ .int3, .zo, &.{}, &.{ 0xcc }, 0, .none, .none },
299298
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 },
338337
339 .{ .lfence, .np, &.{}, &.{ 0x0f, 0xae, 0xe8 }, 0, .none, .none },338 .{ .lfence, .zo, &.{}, &.{ 0x0f, 0xae, 0xe8 }, 0, .none, .none },
340339
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 },
345344
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 },
350349
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 },
354353
355 .{ .mfence, .np, &.{}, &.{ 0x0f, 0xae, 0xf0 }, 0, .none, .none },354 .{ .mfence, .zo, &.{}, &.{ 0x0f, 0xae, 0xf0 }, 0, .none, .none },
356355
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 },
398397
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 },
403402
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 },
408407
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 },
442441
443 .{ .nop, .np, &.{}, &.{ 0x90 }, 0, .none, .none },442 .{ .nop, .zo, &.{}, &.{ 0x90 }, 0, .none, .none },
444443
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 },
473472
474 .{ .pause, .np, &.{}, &.{ 0xf3, 0x90 }, 0, .none, .none },473 .{ .pause, .zo, &.{}, &.{ 0xf3, 0x90 }, 0, .none, .none },
475474
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 },
484483
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 },
492493
493 .{ .ret, .np, &.{}, &.{ 0xc3 }, 0, .none, .none },494 .{ .pushfq, .zo, &.{}, &.{ 0x9c }, 0, .none, .none },
495
496 .{ .ret, .zo, &.{}, &.{ 0xc3 }, 0, .none, .none },
494497
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 },
613616
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 },
618621
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 },
623626
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 },
684687
685 .{ .sfence, .np, &.{}, &.{ 0x0f, 0xae, 0xf8 }, 0, .none, .none },688 .{ .sfence, .zo, &.{}, &.{ 0x0f, 0xae, 0xf8 }, 0, .none, .none },
686689
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 },
732735
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 },
737740
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 },
742745
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 },
765768
766 .{ .syscall, .np, &.{}, &.{ 0x0f, 0x05 }, 0, .none, .none },769 .{ .syscall, .zo, &.{}, &.{ 0x0f, 0x05 }, 0, .none, .none },
767770
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 },
786789
787 .{ .ud2, .np, &.{}, &.{ 0x0f, 0x0b }, 0, .none, .none },790 .{ .ud2, .zo, &.{}, &.{ 0x0f, 0x0b }, 0, .none, .none },
788791
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 },
811814
812 .{ .xgetbv, .np, &.{}, &.{ 0x0f, 0x01 }, 0, .none, .none },815 .{ .xgetbv, .zo, &.{}, &.{ 0x0f, 0x01, 0xd0 }, 0, .none, .none },
813816
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 },
836839
837 // X87840 // X87
838 .{ .fabs, .np, &.{}, &.{ 0xd9, 0xe1 }, 0, .none, .x87 },841 .{ .fabs, .zo, &.{}, &.{ 0xd9, 0xe1 }, 0, .none, .x87 },
839842
840 .{ .fchs, .np, &.{}, &.{ 0xd9, 0xe0 }, 0, .none, .x87 },843 .{ .fchs, .zo, &.{}, &.{ 0xd9, 0xe0 }, 0, .none, .x87 },
841844
842 .{ .ffree, .o, &.{ .st }, &.{ 0xdd, 0xc0 }, 0, .none, .x87 },845 .{ .ffree, .o, &.{ .st }, &.{ 0xdd, 0xc0 }, 0, .none, .x87 },
843846
...@@ -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 },
852855
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 },
860865
866 .{ .fstenv, .m, &.{ .m }, &.{ 0x9b, 0xd9 }, 6, .none, .x87 },
867 .{ .fnstenv, .m, &.{ .m }, &.{ 0xd9 }, 6, .none, .x87 },
868
861 // SSE869 // SSE
862 .{ .addps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x58 }, 0, .none, .sse },870 .{ .addps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x58 }, 0, .none, .sse },
863871
...@@ -890,6 +898,8 @@ pub const table = [_]Entry{...@@ -890,6 +898,8 @@ pub const table = [_]Entry{
890898
891 .{ .divss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5e }, 0, .none, .sse },899 .{ .divss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5e }, 0, .none, .sse },
892900
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 },
894904
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{
929939
930 .{ .sqrtss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x51 }, 0, .none, .sse },940 .{ .sqrtss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x51 }, 0, .none, .sse },
931941
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 },
933945
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{
13651377
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 },
13671379
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 },
13701384
...@@ -1635,6 +1649,8 @@ pub const table = [_]Entry{...@@ -1635,6 +1649,8 @@ pub const table = [_]Entry{
16351649
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 },
16371651
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 },
16401656
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);
861861
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);
863869
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).?;
14661465
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 };
15111510
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_PHDR48/// PT_PHDR
49phdr_table_index: ?u16 = null,49phdr_table_index: ?u16 = null,
50/// PT_LOAD for PHDR table50/// PT_LOAD for PHDR table
51/// We add this special load segment to ensure the PHDR table is always51/// We add this special load segment to ensure the EHDR and PHDR table are always
52/// loaded into memory.52/// loaded into memory.
53phdr_table_load_index: ?u16 = null,53phdr_table_load_index: ?u16 = null,
54/// PT_INTERP54/// 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 }
310321
...@@ -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;
708721
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;
869884
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);
875890
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();
16021617
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 });
38453861
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 }
38643882
...@@ -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 }
38853904
...@@ -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 }
39073929
...@@ -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 }
39163939
...@@ -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 }
39243948
...@@ -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 }
39423967
...@@ -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 });
39794009
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}
40264061
4027fn initSpecialPhdrs(self: *Elf) !void {4062fn 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}
46154652
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.)
4656fn 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 required4668/// 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}
46344686
4635/// Allocates PHDR table in virtual memory and in file.4687/// Allocates PHDR table in virtual memory and in file.
4636fn allocatePhdrTable(self: *Elf) void {4688fn 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.?];
46404692
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);
46464703
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 }
46514714
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}
46624720
...@@ -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};
56555714
5656pub fn addSection(self: *Elf, opts: AddSectionOpts) !u16 {5715pub 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}
62336292
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.
6298const number_of_zig_segments = 5;
6299const max_number_of_object_segments = 9;
6300const max_number_of_special_phdrs = 5;
6301
6234const default_entry_addr = 0x8000000;6302const default_entry_addr = 0x8000000;
62356303
6236pub const base_tag: link.File.Tag = .elf;6304pub 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 {
670670
671test "128-bit multiplication" {671test "128-bit multiplication" {
672 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO672 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; // TODO673 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
675 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO674 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
676 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO675 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;
679679
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 {
10061006
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 or1008 if ((test_target.target.getCpuArch() != .x86_64 or
1009 test_target.target.getObjectFormat() != .elf) and1009 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;
10121012