| author | |
| committer | |
| log | 45a35d448e85351756fe18e901748c4446a1b56a |
| tree | 21d079e9d889054e1697f0f18c18021aa08c5c37 |
| parent | 8c4482ed78fb651c0288f0cd2bdaf328564c6a49 |
| parent | 733b2082565a86daac6f2b22a1a27f0b60621b4e |
24 files changed, 1062 insertions(+), 489 deletions(-)
lib/compiler/std-docs.zig+3-2| ... | @@ -348,8 +348,9 @@ fn buildWasmBinary( | ... | @@ -348,8 +348,9 @@ fn buildWasmBinary( |
| 348 | }; | 348 | }; |
| 349 | } | 349 | } |
| 350 | 350 | ||
| 351 | if (poller.reader(.stderr).buffer.len > 0) { | 351 | const stderr = poller.reader(.stderr); |
| 352 | std.debug.print("{s}", .{poller.reader(.stderr).buffered()}); | 352 | if (stderr.bufferedLen() > 0) { |
| 353 | std.debug.print("{s}", .{stderr.buffered()}); | ||
| 353 | } | 354 | } |
| 354 | 355 | ||
| 355 | // Send EOF to stdin. | 356 | // Send EOF to stdin. |
lib/init/build.zig-1| ... | @@ -1,4 +1,3 @@ | ... | @@ -1,4 +1,3 @@ |
| 1 | //! Use `zig init --strip` next time to generate a project without comments. | ||
| 2 | const std = @import("std"); | 1 | const std = @import("std"); |
| 3 | 2 | ||
| 4 | // Although this function looks imperative, it does not perform the build | 3 | // Although this function looks imperative, it does not perform the build |
lib/std/Io/DeprecatedReader.zig+2-2| ... | @@ -373,11 +373,11 @@ pub fn discard(self: Self) anyerror!u64 { | ... | @@ -373,11 +373,11 @@ pub fn discard(self: Self) anyerror!u64 { |
| 373 | } | 373 | } |
| 374 | 374 | ||
| 375 | /// Helper for bridging to the new `Reader` API while upgrading. | 375 | /// Helper for bridging to the new `Reader` API while upgrading. |
| 376 | pub fn adaptToNewApi(self: *const Self) Adapter { | 376 | pub fn adaptToNewApi(self: *const Self, buffer: []u8) Adapter { |
| 377 | return .{ | 377 | return .{ |
| 378 | .derp_reader = self.*, | 378 | .derp_reader = self.*, |
| 379 | .new_interface = .{ | 379 | .new_interface = .{ |
| 380 | .buffer = &.{}, | 380 | .buffer = buffer, |
| 381 | .vtable = &.{ .stream = Adapter.stream }, | 381 | .vtable = &.{ .stream = Adapter.stream }, |
| 382 | .seek = 0, | 382 | .seek = 0, |
| 383 | .end = 0, | 383 | .end = 0, |
lib/std/Io/Reader.zig+28-2| ... | @@ -185,6 +185,32 @@ pub fn streamExact64(r: *Reader, w: *Writer, n: u64) StreamError!void { | ... | @@ -185,6 +185,32 @@ pub fn streamExact64(r: *Reader, w: *Writer, n: u64) StreamError!void { |
| 185 | while (remaining != 0) remaining -= try r.stream(w, .limited64(remaining)); | 185 | while (remaining != 0) remaining -= try r.stream(w, .limited64(remaining)); |
| 186 | } | 186 | } |
| 187 | 187 | ||
| 188 | /// "Pump" exactly `n` bytes from the reader to the writer. | ||
| 189 | /// | ||
| 190 | /// When draining `w`, ensures that at least `preserve_len` bytes remain | ||
| 191 | /// buffered. | ||
| 192 | /// | ||
| 193 | /// Asserts `Writer.buffer` capacity exceeds `preserve_len`. | ||
| 194 | pub fn streamExactPreserve(r: *Reader, w: *Writer, preserve_len: usize, n: usize) StreamError!void { | ||
| 195 | if (w.end + n <= w.buffer.len) { | ||
| 196 | @branchHint(.likely); | ||
| 197 | return streamExact(r, w, n); | ||
| 198 | } | ||
| 199 | // If `n` is large, we can ignore `preserve_len` up to a point. | ||
| 200 | var remaining = n; | ||
| 201 | while (remaining > preserve_len) { | ||
| 202 | assert(remaining != 0); | ||
| 203 | remaining -= try r.stream(w, .limited(remaining - preserve_len)); | ||
| 204 | if (w.end + remaining <= w.buffer.len) return streamExact(r, w, remaining); | ||
| 205 | } | ||
| 206 | // All the next bytes received must be preserved. | ||
| 207 | if (preserve_len < w.end) { | ||
| 208 | @memmove(w.buffer[0..preserve_len], w.buffer[w.end - preserve_len ..][0..preserve_len]); | ||
| 209 | w.end = preserve_len; | ||
| 210 | } | ||
| 211 | return streamExact(r, w, remaining); | ||
| 212 | } | ||
| 213 | |||
| 188 | /// "Pump" data from the reader to the writer, handling `error.EndOfStream` as | 214 | /// "Pump" data from the reader to the writer, handling `error.EndOfStream` as |
| 189 | /// a success case. | 215 | /// a success case. |
| 190 | /// | 216 | /// |
| ... | @@ -240,7 +266,7 @@ pub fn allocRemaining(r: *Reader, gpa: Allocator, limit: Limit) LimitedAllocErro | ... | @@ -240,7 +266,7 @@ pub fn allocRemaining(r: *Reader, gpa: Allocator, limit: Limit) LimitedAllocErro |
| 240 | /// such case, the next byte that would be read will be the first one to exceed | 266 | /// such case, the next byte that would be read will be the first one to exceed |
| 241 | /// `limit`, and all preceeding bytes have been appended to `list`. | 267 | /// `limit`, and all preceeding bytes have been appended to `list`. |
| 242 | /// | 268 | /// |
| 243 | /// Asserts `buffer` has nonzero capacity. | 269 | /// If `limit` is not `Limit.unlimited`, asserts `buffer` has nonzero capacity. |
| 244 | /// | 270 | /// |
| 245 | /// See also: | 271 | /// See also: |
| 246 | /// * `allocRemaining` | 272 | /// * `allocRemaining` |
| ... | @@ -251,7 +277,7 @@ pub fn appendRemaining( | ... | @@ -251,7 +277,7 @@ pub fn appendRemaining( |
| 251 | list: *std.ArrayListAlignedUnmanaged(u8, alignment), | 277 | list: *std.ArrayListAlignedUnmanaged(u8, alignment), |
| 252 | limit: Limit, | 278 | limit: Limit, |
| 253 | ) LimitedAllocError!void { | 279 | ) LimitedAllocError!void { |
| 254 | assert(r.buffer.len != 0); // Needed to detect limit exceeded without losing data. | 280 | if (limit != .unlimited) assert(r.buffer.len != 0); // Needed to detect limit exceeded without losing data. |
| 255 | const buffer_contents = r.buffer[r.seek..r.end]; | 281 | const buffer_contents = r.buffer[r.seek..r.end]; |
| 256 | const copy_len = limit.minInt(buffer_contents.len); | 282 | const copy_len = limit.minInt(buffer_contents.len); |
| 257 | try list.appendSlice(gpa, r.buffer[0..copy_len]); | 283 | try list.appendSlice(gpa, r.buffer[0..copy_len]); |
lib/std/Io/Writer.zig+70-23| ... | @@ -256,10 +256,10 @@ test "fixed buffer flush" { | ... | @@ -256,10 +256,10 @@ test "fixed buffer flush" { |
| 256 | try testing.expectEqual(10, buffer[0]); | 256 | try testing.expectEqual(10, buffer[0]); |
| 257 | } | 257 | } |
| 258 | 258 | ||
| 259 | /// Calls `VTable.drain` but hides the last `preserve_length` bytes from the | 259 | /// Calls `VTable.drain` but hides the last `preserve_len` bytes from the |
| 260 | /// implementation, keeping them buffered. | 260 | /// implementation, keeping them buffered. |
| 261 | pub fn drainPreserve(w: *Writer, preserve_length: usize) Error!void { | 261 | pub fn drainPreserve(w: *Writer, preserve_len: usize) Error!void { |
| 262 | const temp_end = w.end -| preserve_length; | 262 | const temp_end = w.end -| preserve_len; |
| 263 | const preserved = w.buffer[temp_end..w.end]; | 263 | const preserved = w.buffer[temp_end..w.end]; |
| 264 | w.end = temp_end; | 264 | w.end = temp_end; |
| 265 | defer w.end += preserved.len; | 265 | defer w.end += preserved.len; |
| ... | @@ -310,24 +310,38 @@ pub fn writableSliceGreedy(w: *Writer, minimum_length: usize) Error![]u8 { | ... | @@ -310,24 +310,38 @@ pub fn writableSliceGreedy(w: *Writer, minimum_length: usize) Error![]u8 { |
| 310 | } | 310 | } |
| 311 | 311 | ||
| 312 | /// Asserts the provided buffer has total capacity enough for `minimum_length` | 312 | /// Asserts the provided buffer has total capacity enough for `minimum_length` |
| 313 | /// and `preserve_length` combined. | 313 | /// and `preserve_len` combined. |
| 314 | /// | 314 | /// |
| 315 | /// Does not `advance` the buffer end position. | 315 | /// Does not `advance` the buffer end position. |
| 316 | /// | 316 | /// |
| 317 | /// When draining the buffer, ensures that at least `preserve_length` bytes | 317 | /// When draining the buffer, ensures that at least `preserve_len` bytes |
| 318 | /// remain buffered. | 318 | /// remain buffered. |
| 319 | /// | 319 | /// |
| 320 | /// If `preserve_length` is zero, this is equivalent to `writableSliceGreedy`. | 320 | /// If `preserve_len` is zero, this is equivalent to `writableSliceGreedy`. |
| 321 | pub fn writableSliceGreedyPreserve(w: *Writer, preserve_length: usize, minimum_length: usize) Error![]u8 { | 321 | pub fn writableSliceGreedyPreserve(w: *Writer, preserve_len: usize, minimum_length: usize) Error![]u8 { |
| 322 | assert(w.buffer.len >= preserve_length + minimum_length); | 322 | assert(w.buffer.len >= preserve_len + minimum_length); |
| 323 | while (w.buffer.len - w.end < minimum_length) { | 323 | while (w.buffer.len - w.end < minimum_length) { |
| 324 | try drainPreserve(w, preserve_length); | 324 | try drainPreserve(w, preserve_len); |
| 325 | } else { | 325 | } else { |
| 326 | @branchHint(.likely); | 326 | @branchHint(.likely); |
| 327 | return w.buffer[w.end..]; | 327 | return w.buffer[w.end..]; |
| 328 | } | 328 | } |
| 329 | } | 329 | } |
| 330 | 330 | ||
| 331 | /// Asserts the provided buffer has total capacity enough for `len`. | ||
| 332 | /// | ||
| 333 | /// Advances the buffer end position by `len`. | ||
| 334 | /// | ||
| 335 | /// When draining the buffer, ensures that at least `preserve_len` bytes | ||
| 336 | /// remain buffered. | ||
| 337 | /// | ||
| 338 | /// If `preserve_len` is zero, this is equivalent to `writableSlice`. | ||
| 339 | pub fn writableSlicePreserve(w: *Writer, preserve_len: usize, len: usize) Error![]u8 { | ||
| 340 | const big_slice = try w.writableSliceGreedyPreserve(preserve_len, len); | ||
| 341 | advance(w, len); | ||
| 342 | return big_slice[0..len]; | ||
| 343 | } | ||
| 344 | |||
| 331 | pub const WritableVectorIterator = struct { | 345 | pub const WritableVectorIterator = struct { |
| 332 | first: []u8, | 346 | first: []u8, |
| 333 | middle: []const []u8 = &.{}, | 347 | middle: []const []u8 = &.{}, |
| ... | @@ -523,16 +537,16 @@ pub fn write(w: *Writer, bytes: []const u8) Error!usize { | ... | @@ -523,16 +537,16 @@ pub fn write(w: *Writer, bytes: []const u8) Error!usize { |
| 523 | return w.vtable.drain(w, &.{bytes}, 1); | 537 | return w.vtable.drain(w, &.{bytes}, 1); |
| 524 | } | 538 | } |
| 525 | 539 | ||
| 526 | /// Asserts `buffer` capacity exceeds `preserve_length`. | 540 | /// Asserts `buffer` capacity exceeds `preserve_len`. |
| 527 | pub fn writePreserve(w: *Writer, preserve_length: usize, bytes: []const u8) Error!usize { | 541 | pub fn writePreserve(w: *Writer, preserve_len: usize, bytes: []const u8) Error!usize { |
| 528 | assert(preserve_length <= w.buffer.len); | 542 | assert(preserve_len <= w.buffer.len); |
| 529 | if (w.end + bytes.len <= w.buffer.len) { | 543 | if (w.end + bytes.len <= w.buffer.len) { |
| 530 | @branchHint(.likely); | 544 | @branchHint(.likely); |
| 531 | @memcpy(w.buffer[w.end..][0..bytes.len], bytes); | 545 | @memcpy(w.buffer[w.end..][0..bytes.len], bytes); |
| 532 | w.end += bytes.len; | 546 | w.end += bytes.len; |
| 533 | return bytes.len; | 547 | return bytes.len; |
| 534 | } | 548 | } |
| 535 | const temp_end = w.end -| preserve_length; | 549 | const temp_end = w.end -| preserve_len; |
| 536 | const preserved = w.buffer[temp_end..w.end]; | 550 | const preserved = w.buffer[temp_end..w.end]; |
| 537 | w.end = temp_end; | 551 | w.end = temp_end; |
| 538 | defer w.end += preserved.len; | 552 | defer w.end += preserved.len; |
| ... | @@ -552,13 +566,13 @@ pub fn writeAll(w: *Writer, bytes: []const u8) Error!void { | ... | @@ -552,13 +566,13 @@ pub fn writeAll(w: *Writer, bytes: []const u8) Error!void { |
| 552 | /// Calls `drain` as many times as necessary such that all of `bytes` are | 566 | /// Calls `drain` as many times as necessary such that all of `bytes` are |
| 553 | /// transferred. | 567 | /// transferred. |
| 554 | /// | 568 | /// |
| 555 | /// When draining the buffer, ensures that at least `preserve_length` bytes | 569 | /// When draining the buffer, ensures that at least `preserve_len` bytes |
| 556 | /// remain buffered. | 570 | /// remain buffered. |
| 557 | /// | 571 | /// |
| 558 | /// Asserts `buffer` capacity exceeds `preserve_length`. | 572 | /// Asserts `buffer` capacity exceeds `preserve_len`. |
| 559 | pub fn writeAllPreserve(w: *Writer, preserve_length: usize, bytes: []const u8) Error!void { | 573 | pub fn writeAllPreserve(w: *Writer, preserve_len: usize, bytes: []const u8) Error!void { |
| 560 | var index: usize = 0; | 574 | var index: usize = 0; |
| 561 | while (index < bytes.len) index += try w.writePreserve(preserve_length, bytes[index..]); | 575 | while (index < bytes.len) index += try w.writePreserve(preserve_len, bytes[index..]); |
| 562 | } | 576 | } |
| 563 | 577 | ||
| 564 | /// Renders fmt string with args, calling `writer` with slices of bytes. | 578 | /// Renders fmt string with args, calling `writer` with slices of bytes. |
| ... | @@ -761,11 +775,11 @@ pub fn writeByte(w: *Writer, byte: u8) Error!void { | ... | @@ -761,11 +775,11 @@ pub fn writeByte(w: *Writer, byte: u8) Error!void { |
| 761 | } | 775 | } |
| 762 | } | 776 | } |
| 763 | 777 | ||
| 764 | /// When draining the buffer, ensures that at least `preserve_length` bytes | 778 | /// When draining the buffer, ensures that at least `preserve_len` bytes |
| 765 | /// remain buffered. | 779 | /// remain buffered. |
| 766 | pub fn writeBytePreserve(w: *Writer, preserve_length: usize, byte: u8) Error!void { | 780 | pub fn writeBytePreserve(w: *Writer, preserve_len: usize, byte: u8) Error!void { |
| 767 | while (w.buffer.len - w.end == 0) { | 781 | while (w.buffer.len - w.end == 0) { |
| 768 | try drainPreserve(w, preserve_length); | 782 | try drainPreserve(w, preserve_len); |
| 769 | } else { | 783 | } else { |
| 770 | @branchHint(.likely); | 784 | @branchHint(.likely); |
| 771 | w.buffer[w.end] = byte; | 785 | w.buffer[w.end] = byte; |
| ... | @@ -788,10 +802,42 @@ test splatByteAll { | ... | @@ -788,10 +802,42 @@ test splatByteAll { |
| 788 | try testing.expectEqualStrings("7" ** 45, aw.writer.buffered()); | 802 | try testing.expectEqualStrings("7" ** 45, aw.writer.buffered()); |
| 789 | } | 803 | } |
| 790 | 804 | ||
| 805 | pub fn splatBytePreserve(w: *Writer, preserve_len: usize, byte: u8, n: usize) Error!void { | ||
| 806 | const new_end = w.end + n; | ||
| 807 | if (new_end <= w.buffer.len) { | ||
| 808 | @memset(w.buffer[w.end..][0..n], byte); | ||
| 809 | w.end = new_end; | ||
| 810 | return; | ||
| 811 | } | ||
| 812 | // If `n` is large, we can ignore `preserve_len` up to a point. | ||
| 813 | var remaining = n; | ||
| 814 | while (remaining > preserve_len) { | ||
| 815 | assert(remaining != 0); | ||
| 816 | remaining -= try splatByte(w, byte, remaining - preserve_len); | ||
| 817 | if (w.end + remaining <= w.buffer.len) { | ||
| 818 | @memset(w.buffer[w.end..][0..remaining], byte); | ||
| 819 | w.end += remaining; | ||
| 820 | return; | ||
| 821 | } | ||
| 822 | } | ||
| 823 | // All the next bytes received must be preserved. | ||
| 824 | if (preserve_len < w.end) { | ||
| 825 | @memmove(w.buffer[0..preserve_len], w.buffer[w.end - preserve_len ..][0..preserve_len]); | ||
| 826 | w.end = preserve_len; | ||
| 827 | } | ||
| 828 | while (remaining > 0) remaining -= try w.splatByte(byte, remaining); | ||
| 829 | } | ||
| 830 | |||
| 791 | /// Writes the same byte many times, allowing short writes. | 831 | /// Writes the same byte many times, allowing short writes. |
| 792 | /// | 832 | /// |
| 793 | /// Does maximum of one underlying `VTable.drain`. | 833 | /// Does maximum of one underlying `VTable.drain`. |
| 794 | pub fn splatByte(w: *Writer, byte: u8, n: usize) Error!usize { | 834 | pub fn splatByte(w: *Writer, byte: u8, n: usize) Error!usize { |
| 835 | if (w.end + n <= w.buffer.len) { | ||
| 836 | @branchHint(.likely); | ||
| 837 | @memset(w.buffer[w.end..][0..n], byte); | ||
| 838 | w.end += n; | ||
| 839 | return n; | ||
| 840 | } | ||
| 795 | return writeSplat(w, &.{&.{byte}}, n); | 841 | return writeSplat(w, &.{&.{byte}}, n); |
| 796 | } | 842 | } |
| 797 | 843 | ||
| ... | @@ -801,9 +847,10 @@ pub fn splatBytesAll(w: *Writer, bytes: []const u8, splat: usize) Error!void { | ... | @@ -801,9 +847,10 @@ pub fn splatBytesAll(w: *Writer, bytes: []const u8, splat: usize) Error!void { |
| 801 | var remaining_bytes: usize = bytes.len * splat; | 847 | var remaining_bytes: usize = bytes.len * splat; |
| 802 | remaining_bytes -= try w.splatBytes(bytes, splat); | 848 | remaining_bytes -= try w.splatBytes(bytes, splat); |
| 803 | while (remaining_bytes > 0) { | 849 | while (remaining_bytes > 0) { |
| 804 | const leftover = remaining_bytes % bytes.len; | 850 | const leftover_splat = remaining_bytes / bytes.len; |
| 805 | const buffers: [2][]const u8 = .{ bytes[bytes.len - leftover ..], bytes }; | 851 | const leftover_bytes = remaining_bytes % bytes.len; |
| 806 | remaining_bytes -= try w.writeSplat(&buffers, splat); | 852 | const buffers: [2][]const u8 = .{ bytes[bytes.len - leftover_bytes ..], bytes }; |
| 853 | remaining_bytes -= try w.writeSplat(&buffers, leftover_splat); | ||
| 807 | } | 854 | } |
| 808 | } | 855 | } |
| 809 | 856 |
lib/std/compress/xz.zig+30-3| ... | @@ -47,7 +47,7 @@ pub fn Decompress(comptime ReaderType: type) type { | ... | @@ -47,7 +47,7 @@ pub fn Decompress(comptime ReaderType: type) type { |
| 47 | 47 | ||
| 48 | var check: Check = undefined; | 48 | var check: Check = undefined; |
| 49 | const hash_a = blk: { | 49 | const hash_a = blk: { |
| 50 | var hasher = std.compress.hashedReader(source, Crc32.init()); | 50 | var hasher = hashedReader(source, Crc32.init()); |
| 51 | try readStreamFlags(hasher.reader(), &check); | 51 | try readStreamFlags(hasher.reader(), &check); |
| 52 | break :blk hasher.hasher.final(); | 52 | break :blk hasher.hasher.final(); |
| 53 | }; | 53 | }; |
| ... | @@ -80,7 +80,7 @@ pub fn Decompress(comptime ReaderType: type) type { | ... | @@ -80,7 +80,7 @@ pub fn Decompress(comptime ReaderType: type) type { |
| 80 | return r; | 80 | return r; |
| 81 | 81 | ||
| 82 | const index_size = blk: { | 82 | const index_size = blk: { |
| 83 | var hasher = std.compress.hashedReader(self.in_reader, Crc32.init()); | 83 | var hasher = hashedReader(self.in_reader, Crc32.init()); |
| 84 | hasher.hasher.update(&[1]u8{0x00}); | 84 | hasher.hasher.update(&[1]u8{0x00}); |
| 85 | 85 | ||
| 86 | var counter = std.io.countingReader(hasher.reader()); | 86 | var counter = std.io.countingReader(hasher.reader()); |
| ... | @@ -115,7 +115,7 @@ pub fn Decompress(comptime ReaderType: type) type { | ... | @@ -115,7 +115,7 @@ pub fn Decompress(comptime ReaderType: type) type { |
| 115 | const hash_a = try self.in_reader.readInt(u32, .little); | 115 | const hash_a = try self.in_reader.readInt(u32, .little); |
| 116 | 116 | ||
| 117 | const hash_b = blk: { | 117 | const hash_b = blk: { |
| 118 | var hasher = std.compress.hashedReader(self.in_reader, Crc32.init()); | 118 | var hasher = hashedReader(self.in_reader, Crc32.init()); |
| 119 | const hashed_reader = hasher.reader(); | 119 | const hashed_reader = hasher.reader(); |
| 120 | 120 | ||
| 121 | const backward_size = (@as(u64, try hashed_reader.readInt(u32, .little)) + 1) * 4; | 121 | const backward_size = (@as(u64, try hashed_reader.readInt(u32, .little)) + 1) * 4; |
| ... | @@ -140,6 +140,33 @@ pub fn Decompress(comptime ReaderType: type) type { | ... | @@ -140,6 +140,33 @@ pub fn Decompress(comptime ReaderType: type) type { |
| 140 | }; | 140 | }; |
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | pub fn HashedReader(ReaderType: type, HasherType: type) type { | ||
| 144 | return struct { | ||
| 145 | child_reader: ReaderType, | ||
| 146 | hasher: HasherType, | ||
| 147 | |||
| 148 | pub const Error = ReaderType.Error; | ||
| 149 | pub const Reader = std.io.GenericReader(*@This(), Error, read); | ||
| 150 | |||
| 151 | pub fn read(self: *@This(), buf: []u8) Error!usize { | ||
| 152 | const amt = try self.child_reader.read(buf); | ||
| 153 | self.hasher.update(buf[0..amt]); | ||
| 154 | return amt; | ||
| 155 | } | ||
| 156 | |||
| 157 | pub fn reader(self: *@This()) Reader { | ||
| 158 | return .{ .context = self }; | ||
| 159 | } | ||
| 160 | }; | ||
| 161 | } | ||
| 162 | |||
| 163 | pub fn hashedReader( | ||
| 164 | reader: anytype, | ||
| 165 | hasher: anytype, | ||
| 166 | ) HashedReader(@TypeOf(reader), @TypeOf(hasher)) { | ||
| 167 | return .{ .child_reader = reader, .hasher = hasher }; | ||
| 168 | } | ||
| 169 | |||
| 143 | test { | 170 | test { |
| 144 | _ = @import("xz/test.zig"); | 171 | _ = @import("xz/test.zig"); |
| 145 | } | 172 | } |
lib/std/compress/xz/block.zig+1-1| ... | @@ -91,7 +91,7 @@ pub fn Decoder(comptime ReaderType: type) type { | ... | @@ -91,7 +91,7 @@ pub fn Decoder(comptime ReaderType: type) type { |
| 91 | 91 | ||
| 92 | // Block Header | 92 | // Block Header |
| 93 | { | 93 | { |
| 94 | var header_hasher = std.compress.hashedReader(block_reader, Crc32.init()); | 94 | var header_hasher = xz.hashedReader(block_reader, Crc32.init()); |
| 95 | const header_reader = header_hasher.reader(); | 95 | const header_reader = header_hasher.reader(); |
| 96 | 96 | ||
| 97 | const header_size = @as(u64, try header_reader.readByte()) * 4; | 97 | const header_size = @as(u64, try header_reader.readByte()) * 4; |
lib/std/compress/zstd.zig+4-5| ... | @@ -1,12 +1,11 @@ | ... | @@ -1,12 +1,11 @@ |
| 1 | const std = @import("../std.zig"); | 1 | const std = @import("../std.zig"); |
| 2 | const assert = std.debug.assert; | 2 | const assert = std.debug.assert; |
| 3 | 3 | ||
| 4 | pub const Decompress = @import("zstd/Decompress.zig"); | ||
| 5 | |||
| 4 | /// Recommended amount by the standard. Lower than this may result in inability | 6 | /// Recommended amount by the standard. Lower than this may result in inability |
| 5 | /// to decompress common streams. | 7 | /// to decompress common streams. |
| 6 | pub const default_window_len = 8 * 1024 * 1024; | 8 | pub const default_window_len = 8 * 1024 * 1024; |
| 7 | |||
| 8 | pub const Decompress = @import("zstd/Decompress.zig"); | ||
| 9 | |||
| 10 | pub const block_size_max = 1 << 17; | 9 | pub const block_size_max = 1 << 17; |
| 11 | 10 | ||
| 12 | pub const literals_length_default_distribution = [36]i16{ | 11 | pub const literals_length_default_distribution = [36]i16{ |
| ... | @@ -85,7 +84,7 @@ fn testDecompress(gpa: std.mem.Allocator, compressed: []const u8) ![]u8 { | ... | @@ -85,7 +84,7 @@ fn testDecompress(gpa: std.mem.Allocator, compressed: []const u8) ![]u8 { |
| 85 | 84 | ||
| 86 | var in: std.io.Reader = .fixed(compressed); | 85 | var in: std.io.Reader = .fixed(compressed); |
| 87 | var zstd_stream: Decompress = .init(&in, &.{}, .{}); | 86 | var zstd_stream: Decompress = .init(&in, &.{}, .{}); |
| 88 | try zstd_stream.interface.appendRemaining(gpa, null, &out, .unlimited); | 87 | try zstd_stream.reader.appendRemaining(gpa, null, &out, .unlimited); |
| 89 | 88 | ||
| 90 | return out.toOwnedSlice(gpa); | 89 | return out.toOwnedSlice(gpa); |
| 91 | } | 90 | } |
| ... | @@ -108,7 +107,7 @@ fn testExpectDecompressError(err: anyerror, compressed: []const u8) !void { | ... | @@ -108,7 +107,7 @@ fn testExpectDecompressError(err: anyerror, compressed: []const u8) !void { |
| 108 | var zstd_stream: Decompress = .init(&in, &.{}, .{}); | 107 | var zstd_stream: Decompress = .init(&in, &.{}, .{}); |
| 109 | try std.testing.expectError( | 108 | try std.testing.expectError( |
| 110 | error.ReadFailed, | 109 | error.ReadFailed, |
| 111 | zstd_stream.interface.appendRemaining(gpa, null, &out, .unlimited), | 110 | zstd_stream.reader.appendRemaining(gpa, null, &out, .unlimited), |
| 112 | ); | 111 | ); |
| 113 | try std.testing.expectError(err, zstd_stream.err orelse {}); | 112 | try std.testing.expectError(err, zstd_stream.err orelse {}); |
| 114 | } | 113 | } |
lib/std/compress/zstd/Decompress.zig+69-68| ... | @@ -10,6 +10,7 @@ input: *Reader, | ... | @@ -10,6 +10,7 @@ input: *Reader, |
| 10 | reader: Reader, | 10 | reader: Reader, |
| 11 | state: State, | 11 | state: State, |
| 12 | verify_checksum: bool, | 12 | verify_checksum: bool, |
| 13 | window_len: u32, | ||
| 13 | err: ?Error = null, | 14 | err: ?Error = null, |
| 14 | 15 | ||
| 15 | const State = union(enum) { | 16 | const State = union(enum) { |
| ... | @@ -22,11 +23,16 @@ const State = union(enum) { | ... | @@ -22,11 +23,16 @@ const State = union(enum) { |
| 22 | frame: Frame, | 23 | frame: Frame, |
| 23 | checksum: ?u32, | 24 | checksum: ?u32, |
| 24 | decompressed_size: usize, | 25 | decompressed_size: usize, |
| 26 | decode: Frame.Zstandard.Decode, | ||
| 25 | }; | 27 | }; |
| 26 | }; | 28 | }; |
| 27 | 29 | ||
| 28 | pub const Options = struct { | 30 | pub const Options = struct { |
| 29 | verify_checksum: bool = true, | 31 | /// Verifying checksums is not implemented yet and will cause a panic if |
| 32 | /// you set this to true. | ||
| 33 | verify_checksum: bool = false, | ||
| 34 | /// Affects the minimum capacity of the provided buffer. | ||
| 35 | window_len: u32 = zstd.default_window_len, | ||
| 30 | }; | 36 | }; |
| 31 | 37 | ||
| 32 | pub const Error = error{ | 38 | pub const Error = error{ |
| ... | @@ -63,11 +69,14 @@ pub const Error = error{ | ... | @@ -63,11 +69,14 @@ pub const Error = error{ |
| 63 | WindowSizeUnknown, | 69 | WindowSizeUnknown, |
| 64 | }; | 70 | }; |
| 65 | 71 | ||
| 72 | /// If buffer that is written to is not big enough, some streams will fail with | ||
| 73 | /// `error.OutputBufferUndersize`. A safe value is `zstd.default_window_len * 2`. | ||
| 66 | pub fn init(input: *Reader, buffer: []u8, options: Options) Decompress { | 74 | pub fn init(input: *Reader, buffer: []u8, options: Options) Decompress { |
| 67 | return .{ | 75 | return .{ |
| 68 | .input = input, | 76 | .input = input, |
| 69 | .state = .new_frame, | 77 | .state = .new_frame, |
| 70 | .verify_checksum = options.verify_checksum, | 78 | .verify_checksum = options.verify_checksum, |
| 79 | .window_len = options.window_len, | ||
| 71 | .reader = .{ | 80 | .reader = .{ |
| 72 | .vtable = &.{ .stream = stream }, | 81 | .vtable = &.{ .stream = stream }, |
| 73 | .buffer = buffer, | 82 | .buffer = buffer, |
| ... | @@ -130,6 +139,7 @@ fn initFrame(d: *Decompress, window_size_max: usize, magic: Frame.Magic) !void { | ... | @@ -130,6 +139,7 @@ fn initFrame(d: *Decompress, window_size_max: usize, magic: Frame.Magic) !void { |
| 130 | .frame = try Frame.init(header, window_size_max, d.verify_checksum), | 139 | .frame = try Frame.init(header, window_size_max, d.verify_checksum), |
| 131 | .checksum = null, | 140 | .checksum = null, |
| 132 | .decompressed_size = 0, | 141 | .decompressed_size = 0, |
| 142 | .decode = .init, | ||
| 133 | } }; | 143 | } }; |
| 134 | }, | 144 | }, |
| 135 | .skippable => { | 145 | .skippable => { |
| ... | @@ -139,11 +149,11 @@ fn initFrame(d: *Decompress, window_size_max: usize, magic: Frame.Magic) !void { | ... | @@ -139,11 +149,11 @@ fn initFrame(d: *Decompress, window_size_max: usize, magic: Frame.Magic) !void { |
| 139 | } | 149 | } |
| 140 | } | 150 | } |
| 141 | 151 | ||
| 142 | fn readInFrame(d: *Decompress, bw: *Writer, limit: Limit, state: *State.InFrame) !usize { | 152 | fn readInFrame(d: *Decompress, w: *Writer, limit: Limit, state: *State.InFrame) !usize { |
| 143 | const in = d.input; | 153 | const in = d.input; |
| 154 | const window_len = d.window_len; | ||
| 144 | 155 | ||
| 145 | const header_bytes = try in.takeArray(3); | 156 | const block_header = try in.takeStruct(Frame.Zstandard.Block.Header, .little); |
| 146 | const block_header: Frame.Zstandard.Block.Header = @bitCast(header_bytes.*); | ||
| 147 | const block_size = block_header.size; | 157 | const block_size = block_header.size; |
| 148 | const frame_block_size_max = state.frame.block_size_max; | 158 | const frame_block_size_max = state.frame.block_size_max; |
| 149 | if (frame_block_size_max < block_size) return error.BlockOversize; | 159 | if (frame_block_size_max < block_size) return error.BlockOversize; |
| ... | @@ -151,49 +161,47 @@ fn readInFrame(d: *Decompress, bw: *Writer, limit: Limit, state: *State.InFrame) | ... | @@ -151,49 +161,47 @@ fn readInFrame(d: *Decompress, bw: *Writer, limit: Limit, state: *State.InFrame) |
| 151 | var bytes_written: usize = 0; | 161 | var bytes_written: usize = 0; |
| 152 | switch (block_header.type) { | 162 | switch (block_header.type) { |
| 153 | .raw => { | 163 | .raw => { |
| 154 | try in.readAll(bw, .limited(block_size)); | 164 | try in.streamExactPreserve(w, window_len, block_size); |
| 155 | bytes_written = block_size; | 165 | bytes_written = block_size; |
| 156 | }, | 166 | }, |
| 157 | .rle => { | 167 | .rle => { |
| 158 | const byte = try in.takeByte(); | 168 | const byte = try in.takeByte(); |
| 159 | try bw.splatByteAll(byte, block_size); | 169 | try w.splatBytePreserve(window_len, byte, block_size); |
| 160 | bytes_written = block_size; | 170 | bytes_written = block_size; |
| 161 | }, | 171 | }, |
| 162 | .compressed => { | 172 | .compressed => { |
| 163 | var literal_fse_buffer: [zstd.table_size_max.literal]Table.Fse = undefined; | ||
| 164 | var match_fse_buffer: [zstd.table_size_max.match]Table.Fse = undefined; | ||
| 165 | var offset_fse_buffer: [zstd.table_size_max.offset]Table.Fse = undefined; | ||
| 166 | var literals_buffer: [zstd.block_size_max]u8 = undefined; | 173 | var literals_buffer: [zstd.block_size_max]u8 = undefined; |
| 167 | var sequence_buffer: [zstd.block_size_max]u8 = undefined; | 174 | var sequence_buffer: [zstd.block_size_max]u8 = undefined; |
| 168 | var decode: Frame.Zstandard.Decode = .init(&literal_fse_buffer, &match_fse_buffer, &offset_fse_buffer); | ||
| 169 | var remaining: Limit = .limited(block_size); | 175 | var remaining: Limit = .limited(block_size); |
| 170 | const literals = try LiteralsSection.decode(in, &remaining, &literals_buffer); | 176 | const literals = try LiteralsSection.decode(in, &remaining, &literals_buffer); |
| 171 | const sequences_header = try SequencesSection.Header.decode(in, &remaining); | 177 | const sequences_header = try SequencesSection.Header.decode(in, &remaining); |
| 172 | 178 | ||
| 179 | const decode = &state.decode; | ||
| 173 | try decode.prepare(in, &remaining, literals, sequences_header); | 180 | try decode.prepare(in, &remaining, literals, sequences_header); |
| 174 | 181 | ||
| 175 | { | 182 | { |
| 176 | if (sequence_buffer.len < @intFromEnum(remaining)) | 183 | if (sequence_buffer.len < @intFromEnum(remaining)) |
| 177 | return error.SequenceBufferUndersize; | 184 | return error.SequenceBufferUndersize; |
| 178 | const seq_slice = remaining.slice(&sequence_buffer); | 185 | const seq_slice = remaining.slice(&sequence_buffer); |
| 179 | try in.readSlice(seq_slice); | 186 | try in.readSliceAll(seq_slice); |
| 180 | var bit_stream = try ReverseBitReader.init(seq_slice); | 187 | var bit_stream = try ReverseBitReader.init(seq_slice); |
| 181 | 188 | ||
| 182 | if (sequences_header.sequence_count > 0) { | 189 | if (sequences_header.sequence_count > 0) { |
| 183 | try decode.readInitialFseState(&bit_stream); | 190 | try decode.readInitialFseState(&bit_stream); |
| 184 | 191 | ||
| 185 | // Ensures the following calls to `decodeSequence` will not flush. | 192 | // Ensures the following calls to `decodeSequence` will not flush. |
| 186 | if (frame_block_size_max > bw.buffer.len) return error.OutputBufferUndersize; | 193 | if (window_len + frame_block_size_max > w.buffer.len) return error.OutputBufferUndersize; |
| 187 | const dest = (try bw.writableSliceGreedy(frame_block_size_max))[0..frame_block_size_max]; | 194 | const dest = (try w.writableSliceGreedyPreserve(window_len, frame_block_size_max))[0..frame_block_size_max]; |
| 195 | const write_pos = dest.ptr - w.buffer.ptr; | ||
| 188 | for (0..sequences_header.sequence_count - 1) |_| { | 196 | for (0..sequences_header.sequence_count - 1) |_| { |
| 189 | bytes_written += try decode.decodeSequence(dest, bytes_written, &bit_stream); | 197 | bytes_written += try decode.decodeSequence(w.buffer, write_pos + bytes_written, &bit_stream); |
| 190 | try decode.updateState(.literal, &bit_stream); | 198 | try decode.updateState(.literal, &bit_stream); |
| 191 | try decode.updateState(.match, &bit_stream); | 199 | try decode.updateState(.match, &bit_stream); |
| 192 | try decode.updateState(.offset, &bit_stream); | 200 | try decode.updateState(.offset, &bit_stream); |
| 193 | } | 201 | } |
| 194 | bytes_written += try decode.decodeSequence(dest, bytes_written, &bit_stream); | 202 | bytes_written += try decode.decodeSequence(w.buffer, write_pos + bytes_written, &bit_stream); |
| 195 | if (bytes_written > dest.len) return error.MalformedSequence; | 203 | if (bytes_written > dest.len) return error.MalformedSequence; |
| 196 | bw.advance(bytes_written); | 204 | w.advance(bytes_written); |
| 197 | } | 205 | } |
| 198 | 206 | ||
| 199 | if (!bit_stream.isEmpty()) { | 207 | if (!bit_stream.isEmpty()) { |
| ... | @@ -203,7 +211,7 @@ fn readInFrame(d: *Decompress, bw: *Writer, limit: Limit, state: *State.InFrame) | ... | @@ -203,7 +211,7 @@ fn readInFrame(d: *Decompress, bw: *Writer, limit: Limit, state: *State.InFrame) |
| 203 | 211 | ||
| 204 | if (decode.literal_written_count < literals.header.regenerated_size) { | 212 | if (decode.literal_written_count < literals.header.regenerated_size) { |
| 205 | const len = literals.header.regenerated_size - decode.literal_written_count; | 213 | const len = literals.header.regenerated_size - decode.literal_written_count; |
| 206 | try decode.decodeLiterals(bw, len); | 214 | try decode.decodeLiterals(w, len); |
| 207 | decode.literal_written_count += len; | 215 | decode.literal_written_count += len; |
| 208 | bytes_written += len; | 216 | bytes_written += len; |
| 209 | } | 217 | } |
| ... | @@ -216,11 +224,6 @@ fn readInFrame(d: *Decompress, bw: *Writer, limit: Limit, state: *State.InFrame) | ... | @@ -216,11 +224,6 @@ fn readInFrame(d: *Decompress, bw: *Writer, limit: Limit, state: *State.InFrame) |
| 216 | } | 224 | } |
| 217 | 225 | ||
| 218 | if (bytes_written > frame_block_size_max) return error.BlockOversize; | 226 | if (bytes_written > frame_block_size_max) return error.BlockOversize; |
| 219 | |||
| 220 | state.decompressed_size += bytes_written; | ||
| 221 | if (state.frame.content_size) |size| { | ||
| 222 | if (state.decompressed_size > size) return error.MalformedFrame; | ||
| 223 | } | ||
| 224 | }, | 227 | }, |
| 225 | .reserved => return error.ReservedBlock, | 228 | .reserved => return error.ReservedBlock, |
| 226 | } | 229 | } |
| ... | @@ -232,6 +235,8 @@ fn readInFrame(d: *Decompress, bw: *Writer, limit: Limit, state: *State.InFrame) | ... | @@ -232,6 +235,8 @@ fn readInFrame(d: *Decompress, bw: *Writer, limit: Limit, state: *State.InFrame) |
| 232 | } | 235 | } |
| 233 | } | 236 | } |
| 234 | 237 | ||
| 238 | state.decompressed_size += bytes_written; | ||
| 239 | |||
| 235 | if (block_header.last) { | 240 | if (block_header.last) { |
| 236 | if (state.frame.has_checksum) { | 241 | if (state.frame.has_checksum) { |
| 237 | const expected_checksum = try in.takeInt(u32, .little); | 242 | const expected_checksum = try in.takeInt(u32, .little); |
| ... | @@ -246,6 +251,8 @@ fn readInFrame(d: *Decompress, bw: *Writer, limit: Limit, state: *State.InFrame) | ... | @@ -246,6 +251,8 @@ fn readInFrame(d: *Decompress, bw: *Writer, limit: Limit, state: *State.InFrame) |
| 246 | } | 251 | } |
| 247 | } | 252 | } |
| 248 | d.state = .new_frame; | 253 | d.state = .new_frame; |
| 254 | } else if (state.frame.content_size) |content_size| { | ||
| 255 | if (state.decompressed_size > content_size) return error.MalformedFrame; | ||
| 249 | } | 256 | } |
| 250 | 257 | ||
| 251 | return bytes_written; | 258 | return bytes_written; |
| ... | @@ -367,9 +374,9 @@ pub const Frame = struct { | ... | @@ -367,9 +374,9 @@ pub const Frame = struct { |
| 367 | match: StateData(9), | 374 | match: StateData(9), |
| 368 | literal: StateData(9), | 375 | literal: StateData(9), |
| 369 | 376 | ||
| 370 | offset_fse_buffer: []Table.Fse, | 377 | literal_fse_buffer: [zstd.table_size_max.literal]Table.Fse, |
| 371 | match_fse_buffer: []Table.Fse, | 378 | match_fse_buffer: [zstd.table_size_max.match]Table.Fse, |
| 372 | literal_fse_buffer: []Table.Fse, | 379 | offset_fse_buffer: [zstd.table_size_max.offset]Table.Fse, |
| 373 | 380 | ||
| 374 | fse_tables_undefined: bool, | 381 | fse_tables_undefined: bool, |
| 375 | 382 | ||
| ... | @@ -391,36 +398,30 @@ pub const Frame = struct { | ... | @@ -391,36 +398,30 @@ pub const Frame = struct { |
| 391 | }; | 398 | }; |
| 392 | } | 399 | } |
| 393 | 400 | ||
| 394 | pub fn init( | 401 | const init: Decode = .{ |
| 395 | literal_fse_buffer: []Table.Fse, | 402 | .repeat_offsets = .{ |
| 396 | match_fse_buffer: []Table.Fse, | 403 | zstd.start_repeated_offset_1, |
| 397 | offset_fse_buffer: []Table.Fse, | 404 | zstd.start_repeated_offset_2, |
| 398 | ) Decode { | 405 | zstd.start_repeated_offset_3, |
| 399 | return .{ | 406 | }, |
| 400 | .repeat_offsets = .{ | ||
| 401 | zstd.start_repeated_offset_1, | ||
| 402 | zstd.start_repeated_offset_2, | ||
| 403 | zstd.start_repeated_offset_3, | ||
| 404 | }, | ||
| 405 | 407 | ||
| 406 | .offset = undefined, | 408 | .offset = undefined, |
| 407 | .match = undefined, | 409 | .match = undefined, |
| 408 | .literal = undefined, | 410 | .literal = undefined, |
| 409 | 411 | ||
| 410 | .literal_fse_buffer = literal_fse_buffer, | 412 | .literal_fse_buffer = undefined, |
| 411 | .match_fse_buffer = match_fse_buffer, | 413 | .match_fse_buffer = undefined, |
| 412 | .offset_fse_buffer = offset_fse_buffer, | 414 | .offset_fse_buffer = undefined, |
| 413 | 415 | ||
| 414 | .fse_tables_undefined = true, | 416 | .fse_tables_undefined = true, |
| 415 | 417 | ||
| 416 | .literal_written_count = 0, | 418 | .literal_written_count = 0, |
| 417 | .literal_header = undefined, | 419 | .literal_header = undefined, |
| 418 | .literal_streams = undefined, | 420 | .literal_streams = undefined, |
| 419 | .literal_stream_reader = undefined, | 421 | .literal_stream_reader = undefined, |
| 420 | .literal_stream_index = undefined, | 422 | .literal_stream_index = undefined, |
| 421 | .huffman_tree = null, | 423 | .huffman_tree = null, |
| 422 | }; | 424 | }; |
| 423 | } | ||
| 424 | 425 | ||
| 425 | pub const PrepareError = error{ | 426 | pub const PrepareError = error{ |
| 426 | /// the (reversed) literal bitstream's first byte does not have any bits set | 427 | /// the (reversed) literal bitstream's first byte does not have any bits set |
| ... | @@ -502,12 +503,12 @@ pub const Frame = struct { | ... | @@ -502,12 +503,12 @@ pub const Frame = struct { |
| 502 | return self.repeat_offsets[0]; | 503 | return self.repeat_offsets[0]; |
| 503 | } | 504 | } |
| 504 | 505 | ||
| 505 | const DataType = enum { offset, match, literal }; | 506 | const WhichFse = enum { offset, match, literal }; |
| 506 | 507 | ||
| 507 | /// TODO: don't use `@field` | 508 | /// TODO: don't use `@field` |
| 508 | fn updateState( | 509 | fn updateState( |
| 509 | self: *Decode, | 510 | self: *Decode, |
| 510 | comptime choice: DataType, | 511 | comptime choice: WhichFse, |
| 511 | bit_reader: *ReverseBitReader, | 512 | bit_reader: *ReverseBitReader, |
| 512 | ) error{ MalformedFseBits, EndOfStream }!void { | 513 | ) error{ MalformedFseBits, EndOfStream }!void { |
| 513 | switch (@field(self, @tagName(choice)).table) { | 514 | switch (@field(self, @tagName(choice)).table) { |
| ... | @@ -537,7 +538,7 @@ pub const Frame = struct { | ... | @@ -537,7 +538,7 @@ pub const Frame = struct { |
| 537 | self: *Decode, | 538 | self: *Decode, |
| 538 | in: *Reader, | 539 | in: *Reader, |
| 539 | remaining: *Limit, | 540 | remaining: *Limit, |
| 540 | comptime choice: DataType, | 541 | comptime choice: WhichFse, |
| 541 | mode: SequencesSection.Header.Mode, | 542 | mode: SequencesSection.Header.Mode, |
| 542 | ) !void { | 543 | ) !void { |
| 543 | const field_name = @tagName(choice); | 544 | const field_name = @tagName(choice); |
| ... | @@ -564,10 +565,10 @@ pub const Frame = struct { | ... | @@ -564,10 +565,10 @@ pub const Frame = struct { |
| 564 | &bit_reader, | 565 | &bit_reader, |
| 565 | @field(zstd.table_symbol_count_max, field_name), | 566 | @field(zstd.table_symbol_count_max, field_name), |
| 566 | @field(zstd.table_accuracy_log_max, field_name), | 567 | @field(zstd.table_accuracy_log_max, field_name), |
| 567 | @field(self, field_name ++ "_fse_buffer"), | 568 | &@field(self, field_name ++ "_fse_buffer"), |
| 568 | ); | 569 | ); |
| 569 | @field(self, field_name).table = .{ | 570 | @field(self, field_name).table = .{ |
| 570 | .fse = @field(self, field_name ++ "_fse_buffer")[0..table_size], | 571 | .fse = (&@field(self, field_name ++ "_fse_buffer"))[0..table_size], |
| 571 | }; | 572 | }; |
| 572 | @field(self, field_name).accuracy_log = std.math.log2_int_ceil(usize, table_size); | 573 | @field(self, field_name).accuracy_log = std.math.log2_int_ceil(usize, table_size); |
| 573 | in.toss(bit_reader.index); | 574 | in.toss(bit_reader.index); |
| ... | @@ -696,19 +697,19 @@ pub const Frame = struct { | ... | @@ -696,19 +697,19 @@ pub const Frame = struct { |
| 696 | }; | 697 | }; |
| 697 | } | 698 | } |
| 698 | 699 | ||
| 699 | /// Decode `len` bytes of literals into `dest`. | 700 | /// Decode `len` bytes of literals into `w`. |
| 700 | fn decodeLiterals(self: *Decode, dest: *Writer, len: usize) !void { | 701 | fn decodeLiterals(d: *Decode, w: *Writer, len: usize) !void { |
| 701 | switch (self.literal_header.block_type) { | 702 | switch (d.literal_header.block_type) { |
| 702 | .raw => { | 703 | .raw => { |
| 703 | try dest.writeAll(self.literal_streams.one[self.literal_written_count..][0..len]); | 704 | try w.writeAll(d.literal_streams.one[d.literal_written_count..][0..len]); |
| 704 | }, | 705 | }, |
| 705 | .rle => { | 706 | .rle => { |
| 706 | try dest.splatByteAll(self.literal_streams.one[0], len); | 707 | try w.splatByteAll(d.literal_streams.one[0], len); |
| 707 | }, | 708 | }, |
| 708 | .compressed, .treeless => { | 709 | .compressed, .treeless => { |
| 709 | if (len > dest.buffer.len) return error.OutputBufferUndersize; | 710 | if (len > w.buffer.len) return error.OutputBufferUndersize; |
| 710 | const buf = try dest.writableSlice(len); | 711 | const buf = try w.writableSlice(len); |
| 711 | const huffman_tree = self.huffman_tree.?; | 712 | const huffman_tree = d.huffman_tree.?; |
| 712 | const max_bit_count = huffman_tree.max_bit_count; | 713 | const max_bit_count = huffman_tree.max_bit_count; |
| 713 | const starting_bit_count = LiteralsSection.HuffmanTree.weightToBitCount( | 714 | const starting_bit_count = LiteralsSection.HuffmanTree.weightToBitCount( |
| 714 | huffman_tree.nodes[huffman_tree.symbol_count_minus_one].weight, | 715 | huffman_tree.nodes[huffman_tree.symbol_count_minus_one].weight, |
| ... | @@ -720,7 +721,7 @@ pub const Frame = struct { | ... | @@ -720,7 +721,7 @@ pub const Frame = struct { |
| 720 | for (buf) |*out| { | 721 | for (buf) |*out| { |
| 721 | var prefix: u16 = 0; | 722 | var prefix: u16 = 0; |
| 722 | while (true) { | 723 | while (true) { |
| 723 | const new_bits = try self.readLiteralsBits(bit_count_to_read); | 724 | const new_bits = try d.readLiteralsBits(bit_count_to_read); |
| 724 | prefix <<= bit_count_to_read; | 725 | prefix <<= bit_count_to_read; |
| 725 | prefix |= new_bits; | 726 | prefix |= new_bits; |
| 726 | bits_read += bit_count_to_read; | 727 | bits_read += bit_count_to_read; |
| ... | @@ -750,7 +751,7 @@ pub const Frame = struct { | ... | @@ -750,7 +751,7 @@ pub const Frame = struct { |
| 750 | } | 751 | } |
| 751 | 752 | ||
| 752 | /// TODO: don't use `@field` | 753 | /// TODO: don't use `@field` |
| 753 | fn getCode(self: *Decode, comptime choice: DataType) u32 { | 754 | fn getCode(self: *Decode, comptime choice: WhichFse) u32 { |
| 754 | return switch (@field(self, @tagName(choice)).table) { | 755 | return switch (@field(self, @tagName(choice)).table) { |
| 755 | .rle => |value| value, | 756 | .rle => |value| value, |
| 756 | .fse => |table| table[@field(self, @tagName(choice)).state].symbol, | 757 | .fse => |table| table[@field(self, @tagName(choice)).state].symbol, |
| ... | @@ -1166,7 +1167,7 @@ pub const LiteralsSection = struct { | ... | @@ -1166,7 +1167,7 @@ pub const LiteralsSection = struct { |
| 1166 | .raw => { | 1167 | .raw => { |
| 1167 | if (buffer.len < header.regenerated_size) return error.MalformedLiteralsSection; | 1168 | if (buffer.len < header.regenerated_size) return error.MalformedLiteralsSection; |
| 1168 | remaining.* = remaining.subtract(header.regenerated_size) orelse return error.EndOfStream; | 1169 | remaining.* = remaining.subtract(header.regenerated_size) orelse return error.EndOfStream; |
| 1169 | try in.readSlice(buffer[0..header.regenerated_size]); | 1170 | try in.readSliceAll(buffer[0..header.regenerated_size]); |
| 1170 | return .{ | 1171 | return .{ |
| 1171 | .header = header, | 1172 | .header = header, |
| 1172 | .huffman_tree = null, | 1173 | .huffman_tree = null, |
| ... | @@ -1193,7 +1194,7 @@ pub const LiteralsSection = struct { | ... | @@ -1193,7 +1194,7 @@ pub const LiteralsSection = struct { |
| 1193 | return error.MalformedLiteralsSection; | 1194 | return error.MalformedLiteralsSection; |
| 1194 | if (total_streams_size > buffer.len) return error.MalformedLiteralsSection; | 1195 | if (total_streams_size > buffer.len) return error.MalformedLiteralsSection; |
| 1195 | remaining.* = remaining.subtract(total_streams_size) orelse return error.EndOfStream; | 1196 | remaining.* = remaining.subtract(total_streams_size) orelse return error.EndOfStream; |
| 1196 | try in.readSlice(buffer[0..total_streams_size]); | 1197 | try in.readSliceAll(buffer[0..total_streams_size]); |
| 1197 | const stream_data = buffer[0..total_streams_size]; | 1198 | const stream_data = buffer[0..total_streams_size]; |
| 1198 | const streams = try Streams.decode(header.size_format, stream_data); | 1199 | const streams = try Streams.decode(header.size_format, stream_data); |
| 1199 | return .{ | 1200 | return .{ |
lib/std/fs/File.zig+13-1| ... | @@ -1809,7 +1809,19 @@ pub const Writer = struct { | ... | @@ -1809,7 +1809,19 @@ pub const Writer = struct { |
| 1809 | /// along with other write failures. | 1809 | /// along with other write failures. |
| 1810 | pub fn end(w: *Writer) EndError!void { | 1810 | pub fn end(w: *Writer) EndError!void { |
| 1811 | try w.interface.flush(); | 1811 | try w.interface.flush(); |
| 1812 | return w.file.setEndPos(w.pos); | 1812 | switch (w.mode) { |
| 1813 | .positional, | ||
| 1814 | .positional_reading, | ||
| 1815 | => w.file.setEndPos(w.pos) catch |err| switch (err) { | ||
| 1816 | error.NonResizable => return, | ||
| 1817 | else => |e| return e, | ||
| 1818 | }, | ||
| 1819 | |||
| 1820 | .streaming, | ||
| 1821 | .streaming_reading, | ||
| 1822 | .failure, | ||
| 1823 | => {}, | ||
| 1824 | } | ||
| 1813 | } | 1825 | } |
| 1814 | }; | 1826 | }; |
| 1815 | 1827 |
lib/std/posix.zig+3-2| ... | @@ -1052,6 +1052,7 @@ pub const TruncateError = error{ | ... | @@ -1052,6 +1052,7 @@ pub const TruncateError = error{ |
| 1052 | FileBusy, | 1052 | FileBusy, |
| 1053 | AccessDenied, | 1053 | AccessDenied, |
| 1054 | PermissionDenied, | 1054 | PermissionDenied, |
| 1055 | NonResizable, | ||
| 1055 | } || UnexpectedError; | 1056 | } || UnexpectedError; |
| 1056 | 1057 | ||
| 1057 | /// Length must be positive when treated as an i64. | 1058 | /// Length must be positive when treated as an i64. |
| ... | @@ -1091,7 +1092,7 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void { | ... | @@ -1091,7 +1092,7 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void { |
| 1091 | .PERM => return error.PermissionDenied, | 1092 | .PERM => return error.PermissionDenied, |
| 1092 | .TXTBSY => return error.FileBusy, | 1093 | .TXTBSY => return error.FileBusy, |
| 1093 | .BADF => unreachable, // Handle not open for writing | 1094 | .BADF => unreachable, // Handle not open for writing |
| 1094 | .INVAL => unreachable, // Handle not open for writing, negative length, or non-resizable handle | 1095 | .INVAL => return error.NonResizable, |
| 1095 | .NOTCAPABLE => return error.AccessDenied, | 1096 | .NOTCAPABLE => return error.AccessDenied, |
| 1096 | else => |err| return unexpectedErrno(err), | 1097 | else => |err| return unexpectedErrno(err), |
| 1097 | } | 1098 | } |
| ... | @@ -1107,7 +1108,7 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void { | ... | @@ -1107,7 +1108,7 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void { |
| 1107 | .PERM => return error.PermissionDenied, | 1108 | .PERM => return error.PermissionDenied, |
| 1108 | .TXTBSY => return error.FileBusy, | 1109 | .TXTBSY => return error.FileBusy, |
| 1109 | .BADF => unreachable, // Handle not open for writing | 1110 | .BADF => unreachable, // Handle not open for writing |
| 1110 | .INVAL => unreachable, // Handle not open for writing, negative length, or non-resizable handle | 1111 | .INVAL => return error.NonResizable, // This is returned for /dev/null for example. |
| 1111 | else => |err| return unexpectedErrno(err), | 1112 | else => |err| return unexpectedErrno(err), |
| 1112 | } | 1113 | } |
| 1113 | } | 1114 | } |
src/Compilation.zig+8| ... | @@ -4880,6 +4880,14 @@ fn docsCopyFallible(comp: *Compilation) anyerror!void { | ... | @@ -4880,6 +4880,14 @@ fn docsCopyFallible(comp: *Compilation) anyerror!void { |
| 4880 | try seen_table.ensureUnusedCapacity(comp.gpa, deps.len); | 4880 | try seen_table.ensureUnusedCapacity(comp.gpa, deps.len); |
| 4881 | for (deps) |dep| seen_table.putAssumeCapacity(dep, dep.fully_qualified_name); | 4881 | for (deps) |dep| seen_table.putAssumeCapacity(dep, dep.fully_qualified_name); |
| 4882 | } | 4882 | } |
| 4883 | |||
| 4884 | tar_file_writer.end() catch |err| { | ||
| 4885 | return comp.lockAndSetMiscFailure( | ||
| 4886 | .docs_copy, | ||
| 4887 | "unable to write '{f}/sources.tar': {t}", | ||
| 4888 | .{ docs_path, err }, | ||
| 4889 | ); | ||
| 4890 | }; | ||
| 4883 | } | 4891 | } |
| 4884 | 4892 | ||
| 4885 | fn docsCopyModule( | 4893 | fn docsCopyModule( |
src/Package/Fetch.zig+7-8| ... | @@ -1198,7 +1198,8 @@ fn unpackResource( | ... | @@ -1198,7 +1198,8 @@ fn unpackResource( |
| 1198 | 1198 | ||
| 1199 | switch (file_type) { | 1199 | switch (file_type) { |
| 1200 | .tar => { | 1200 | .tar => { |
| 1201 | var adapter = resource.reader().adaptToNewApi(); | 1201 | var adapter_buffer: [1024]u8 = undefined; |
| 1202 | var adapter = resource.reader().adaptToNewApi(&adapter_buffer); | ||
| 1202 | return unpackTarball(f, tmp_directory.handle, &adapter.new_interface); | 1203 | return unpackTarball(f, tmp_directory.handle, &adapter.new_interface); |
| 1203 | }, | 1204 | }, |
| 1204 | .@"tar.gz" => { | 1205 | .@"tar.gz" => { |
| ... | @@ -1227,14 +1228,12 @@ fn unpackResource( | ... | @@ -1227,14 +1228,12 @@ fn unpackResource( |
| 1227 | .@"tar.zst" => { | 1228 | .@"tar.zst" => { |
| 1228 | const window_size = std.compress.zstd.default_window_len; | 1229 | const window_size = std.compress.zstd.default_window_len; |
| 1229 | const window_buffer = try f.arena.allocator().create([window_size]u8); | 1230 | const window_buffer = try f.arena.allocator().create([window_size]u8); |
| 1230 | const reader = resource.reader(); | 1231 | var adapter_buffer: [std.crypto.tls.max_ciphertext_record_len]u8 = undefined; |
| 1231 | var br = std.io.bufferedReaderSize(std.crypto.tls.max_ciphertext_record_len, reader); | 1232 | var adapter = resource.reader().adaptToNewApi(&adapter_buffer); |
| 1232 | var dcp = std.compress.zstd.decompressor(br.reader(), .{ | 1233 | var decompress: std.compress.zstd.Decompress = .init(&adapter.new_interface, window_buffer, .{ |
| 1233 | .window_buffer = window_buffer, | 1234 | .verify_checksum = false, |
| 1234 | }); | 1235 | }); |
| 1235 | var adapter_buffer: [1024]u8 = undefined; | 1236 | return try unpackTarball(f, tmp_directory.handle, &decompress.reader); |
| 1236 | var adapter = dcp.reader().adaptToNewApi(&adapter_buffer); | ||
| 1237 | return try unpackTarball(f, tmp_directory.handle, &adapter.new_interface); | ||
| 1238 | }, | 1237 | }, |
| 1239 | .git_pack => return unpackGitPack(f, tmp_directory.handle, &resource.git) catch |err| switch (err) { | 1238 | .git_pack => return unpackGitPack(f, tmp_directory.handle, &resource.git) catch |err| switch (err) { |
| 1240 | error.FetchFailed => return error.FetchFailed, | 1239 | error.FetchFailed => return error.FetchFailed, |
src/codegen/aarch64.zig+1-3| ... | @@ -113,9 +113,7 @@ pub fn generate( | ... | @@ -113,9 +113,7 @@ pub fn generate( |
| 113 | }, | 113 | }, |
| 114 | .stack_slot => |stack_slot| { | 114 | .stack_slot => |stack_slot| { |
| 115 | assert(stack_slot.base == .sp); | 115 | assert(stack_slot.base == .sp); |
| 116 | passed_vi.setParent(&isel, .{ | 116 | passed_vi.changeStackSlot(&isel, named_stack_args.withOffset(stack_slot.offset)); |
| 117 | .stack_slot = named_stack_args.withOffset(stack_slot.offset), | ||
| 118 | }); | ||
| 119 | }, | 117 | }, |
| 120 | .address, .value, .constant => unreachable, | 118 | .address, .value, .constant => unreachable, |
| 121 | } | 119 | } |
src/codegen/aarch64/Assemble.zig+11-2| ... | @@ -215,6 +215,7 @@ fn nextToken(as: *Assemble, buf: *[token_buf_len]u8, comptime opts: struct { | ... | @@ -215,6 +215,7 @@ fn nextToken(as: *Assemble, buf: *[token_buf_len]u8, comptime opts: struct { |
| 215 | 215 | ||
| 216 | const SymbolSpec = union(enum) { | 216 | const SymbolSpec = union(enum) { |
| 217 | reg: struct { format: aarch64.encoding.Register.Format, allow_sp: bool = false }, | 217 | reg: struct { format: aarch64.encoding.Register.Format, allow_sp: bool = false }, |
| 218 | systemreg, | ||
| 218 | imm: struct { | 219 | imm: struct { |
| 219 | type: std.builtin.Type.Int, | 220 | type: std.builtin.Type.Int, |
| 220 | multiple_of: comptime_int = 1, | 221 | multiple_of: comptime_int = 1, |
| ... | @@ -227,6 +228,7 @@ const SymbolSpec = union(enum) { | ... | @@ -227,6 +228,7 @@ const SymbolSpec = union(enum) { |
| 227 | fn Storage(comptime spec: SymbolSpec) type { | 228 | fn Storage(comptime spec: SymbolSpec) type { |
| 228 | return switch (spec) { | 229 | return switch (spec) { |
| 229 | .reg => aarch64.encoding.Register, | 230 | .reg => aarch64.encoding.Register, |
| 231 | .systemreg => aarch64.encoding.Register.System, | ||
| 230 | .imm => |imm| @Type(.{ .int = imm.type }), | 232 | .imm => |imm| @Type(.{ .int = imm.type }), |
| 231 | .extend => Instruction.DataProcessingRegister.AddSubtractExtendedRegister.Option, | 233 | .extend => Instruction.DataProcessingRegister.AddSubtractExtendedRegister.Option, |
| 232 | .shift => Instruction.DataProcessingRegister.Shift.Op, | 234 | .shift => Instruction.DataProcessingRegister.Shift.Op, |
| ... | @@ -238,8 +240,7 @@ const SymbolSpec = union(enum) { | ... | @@ -238,8 +240,7 @@ const SymbolSpec = union(enum) { |
| 238 | const Result = Storage(spec); | 240 | const Result = Storage(spec); |
| 239 | switch (spec) { | 241 | switch (spec) { |
| 240 | .reg => |reg_spec| { | 242 | .reg => |reg_spec| { |
| 241 | var buf: [token_buf_len]u8 = undefined; | 243 | const reg = Result.parse(token) orelse { |
| 242 | const reg = Result.parse(std.ascii.lowerString(&buf, token[0..@min(token.len, buf.len)])) orelse { | ||
| 243 | log.debug("invalid register: \"{f}\"", .{std.zig.fmtString(token)}); | 244 | log.debug("invalid register: \"{f}\"", .{std.zig.fmtString(token)}); |
| 244 | return null; | 245 | return null; |
| 245 | }; | 246 | }; |
| ... | @@ -253,6 +254,14 @@ const SymbolSpec = union(enum) { | ... | @@ -253,6 +254,14 @@ const SymbolSpec = union(enum) { |
| 253 | } | 254 | } |
| 254 | return reg; | 255 | return reg; |
| 255 | }, | 256 | }, |
| 257 | .systemreg => { | ||
| 258 | const systemreg = Result.parse(token) orelse { | ||
| 259 | log.debug("invalid system register: \"{f}\"", .{std.zig.fmtString(token)}); | ||
| 260 | return null; | ||
| 261 | }; | ||
| 262 | assert(systemreg.op0 >= 2); | ||
| 263 | return systemreg; | ||
| 264 | }, | ||
| 256 | .imm => |imm_spec| { | 265 | .imm => |imm_spec| { |
| 257 | const imm = std.fmt.parseInt(Result, token, 0) catch { | 266 | const imm = std.fmt.parseInt(Result, token, 0) catch { |
| 258 | log.debug("invalid immediate: \"{f}\"", .{std.zig.fmtString(token)}); | 267 | log.debug("invalid immediate: \"{f}\"", .{std.zig.fmtString(token)}); |
src/codegen/aarch64/Select.zig+263-263| ... | @@ -5535,7 +5535,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void { | ... | @@ -5535,7 +5535,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void { |
| 5535 | 2 => if (elem_is_vector) .ldr(elem_ra.h(), .{ .extended_register = .{ | 5535 | 2 => if (elem_is_vector) .ldr(elem_ra.h(), .{ .extended_register = .{ |
| 5536 | .base = base_mat.ra.x(), | 5536 | .base = base_mat.ra.x(), |
| 5537 | .index = index_mat.ra.x(), | 5537 | .index = index_mat.ra.x(), |
| 5538 | .extend = .{ .lsl = 0 }, | 5538 | .extend = .{ .lsl = 1 }, |
| 5539 | } }) else switch (elem_vi.value.signedness(isel)) { | 5539 | } }) else switch (elem_vi.value.signedness(isel)) { |
| 5540 | .signed => .ldrsh(elem_ra.w(), .{ .extended_register = .{ | 5540 | .signed => .ldrsh(elem_ra.w(), .{ .extended_register = .{ |
| 5541 | .base = base_mat.ra.x(), | 5541 | .base = base_mat.ra.x(), |
| ... | @@ -5558,15 +5558,14 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void { | ... | @@ -5558,15 +5558,14 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void { |
| 5558 | .index = index_mat.ra.x(), | 5558 | .index = index_mat.ra.x(), |
| 5559 | .extend = .{ .lsl = 3 }, | 5559 | .extend = .{ .lsl = 3 }, |
| 5560 | } }), | 5560 | } }), |
| 5561 | 16 => .ldr(elem_ra.q(), .{ .extended_register = .{ | 5561 | 16 => if (elem_is_vector) .ldr(elem_ra.q(), .{ .extended_register = .{ |
| 5562 | .base = base_mat.ra.x(), | 5562 | .base = base_mat.ra.x(), |
| 5563 | .index = index_mat.ra.x(), | 5563 | .index = index_mat.ra.x(), |
| 5564 | .extend = .{ .lsl = 4 }, | 5564 | .extend = .{ .lsl = 4 }, |
| 5565 | } }), | 5565 | } }) else unreachable, |
| 5566 | }); | 5566 | }); |
| 5567 | try index_mat.finish(isel); | 5567 | try index_mat.finish(isel); |
| 5568 | try base_mat.finish(isel); | 5568 | try base_mat.finish(isel); |
| 5569 | break :unused; | ||
| 5570 | } else { | 5569 | } else { |
| 5571 | const elem_ptr_ra = try isel.allocIntReg(); | 5570 | const elem_ptr_ra = try isel.allocIntReg(); |
| 5572 | defer isel.freeReg(elem_ptr_ra); | 5571 | defer isel.freeReg(elem_ptr_ra); |
| ... | @@ -5611,66 +5610,81 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void { | ... | @@ -5611,66 +5610,81 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void { |
| 5611 | const ptr_ty = isel.air.typeOf(bin_op.lhs, ip); | 5610 | const ptr_ty = isel.air.typeOf(bin_op.lhs, ip); |
| 5612 | const ptr_info = ptr_ty.ptrInfo(zcu); | 5611 | const ptr_info = ptr_ty.ptrInfo(zcu); |
| 5613 | const elem_size = elem_vi.value.size(isel); | 5612 | const elem_size = elem_vi.value.size(isel); |
| 5614 | switch (elem_size) { | 5613 | const elem_is_vector = elem_vi.value.isVector(isel); |
| 5614 | if (switch (elem_size) { | ||
| 5615 | 0 => unreachable, | 5615 | 0 => unreachable, |
| 5616 | 1, 2, 4, 8 => { | 5616 | 1, 2, 4, 8 => true, |
| 5617 | const elem_ra = try elem_vi.value.defReg(isel) orelse break :unused; | 5617 | 16 => elem_is_vector, |
| 5618 | const base_vi = try isel.use(bin_op.lhs); | 5618 | else => false, |
| 5619 | const index_vi = try isel.use(bin_op.rhs); | 5619 | }) { |
| 5620 | const base_mat = try base_vi.matReg(isel); | 5620 | const elem_ra = try elem_vi.value.defReg(isel) orelse break :unused; |
| 5621 | const index_mat = try index_vi.matReg(isel); | 5621 | const base_vi = try isel.use(bin_op.lhs); |
| 5622 | try isel.emit(switch (elem_size) { | 5622 | const index_vi = try isel.use(bin_op.rhs); |
| 5623 | else => unreachable, | 5623 | const base_mat = try base_vi.matReg(isel); |
| 5624 | 1 => switch (elem_vi.value.signedness(isel)) { | 5624 | const index_mat = try index_vi.matReg(isel); |
| 5625 | .signed => .ldrsb(elem_ra.w(), .{ .extended_register = .{ | 5625 | try isel.emit(switch (elem_size) { |
| 5626 | .base = base_mat.ra.x(), | 5626 | else => unreachable, |
| 5627 | .index = index_mat.ra.x(), | 5627 | 1 => if (elem_is_vector) .ldr(elem_ra.b(), .{ .extended_register = .{ |
| 5628 | .extend = .{ .lsl = 0 }, | 5628 | .base = base_mat.ra.x(), |
| 5629 | } }), | 5629 | .index = index_mat.ra.x(), |
| 5630 | .unsigned => .ldrb(elem_ra.w(), .{ .extended_register = .{ | 5630 | .extend = .{ .lsl = 0 }, |
| 5631 | .base = base_mat.ra.x(), | 5631 | } }) else switch (elem_vi.value.signedness(isel)) { |
| 5632 | .index = index_mat.ra.x(), | 5632 | .signed => .ldrsb(elem_ra.w(), .{ .extended_register = .{ |
| 5633 | .extend = .{ .lsl = 0 }, | ||
| 5634 | } }), | ||
| 5635 | }, | ||
| 5636 | 2 => switch (elem_vi.value.signedness(isel)) { | ||
| 5637 | .signed => .ldrsh(elem_ra.w(), .{ .extended_register = .{ | ||
| 5638 | .base = base_mat.ra.x(), | ||
| 5639 | .index = index_mat.ra.x(), | ||
| 5640 | .extend = .{ .lsl = 1 }, | ||
| 5641 | } }), | ||
| 5642 | .unsigned => .ldrh(elem_ra.w(), .{ .extended_register = .{ | ||
| 5643 | .base = base_mat.ra.x(), | ||
| 5644 | .index = index_mat.ra.x(), | ||
| 5645 | .extend = .{ .lsl = 1 }, | ||
| 5646 | } }), | ||
| 5647 | }, | ||
| 5648 | 4 => .ldr(elem_ra.w(), .{ .extended_register = .{ | ||
| 5649 | .base = base_mat.ra.x(), | 5633 | .base = base_mat.ra.x(), |
| 5650 | .index = index_mat.ra.x(), | 5634 | .index = index_mat.ra.x(), |
| 5651 | .extend = .{ .lsl = 2 }, | 5635 | .extend = .{ .lsl = 0 }, |
| 5652 | } }), | 5636 | } }), |
| 5653 | 8 => .ldr(elem_ra.x(), .{ .extended_register = .{ | 5637 | .unsigned => .ldrb(elem_ra.w(), .{ .extended_register = .{ |
| 5654 | .base = base_mat.ra.x(), | 5638 | .base = base_mat.ra.x(), |
| 5655 | .index = index_mat.ra.x(), | 5639 | .index = index_mat.ra.x(), |
| 5656 | .extend = .{ .lsl = 3 }, | 5640 | .extend = .{ .lsl = 0 }, |
| 5657 | } }), | 5641 | } }), |
| 5658 | }); | 5642 | }, |
| 5659 | try index_mat.finish(isel); | 5643 | 2 => if (elem_is_vector) .ldr(elem_ra.h(), .{ .extended_register = .{ |
| 5660 | try base_mat.finish(isel); | 5644 | .base = base_mat.ra.x(), |
| 5661 | }, | 5645 | .index = index_mat.ra.x(), |
| 5662 | else => { | 5646 | .extend = .{ .lsl = 1 }, |
| 5663 | const elem_ptr_ra = try isel.allocIntReg(); | 5647 | } }) else switch (elem_vi.value.signedness(isel)) { |
| 5664 | defer isel.freeReg(elem_ptr_ra); | 5648 | .signed => .ldrsh(elem_ra.w(), .{ .extended_register = .{ |
| 5665 | if (!try elem_vi.value.load(isel, ptr_ty.elemType2(zcu), elem_ptr_ra, .{ | 5649 | .base = base_mat.ra.x(), |
| 5666 | .@"volatile" = ptr_info.flags.is_volatile, | 5650 | .index = index_mat.ra.x(), |
| 5667 | })) break :unused; | 5651 | .extend = .{ .lsl = 1 }, |
| 5668 | const base_vi = try isel.use(bin_op.lhs); | 5652 | } }), |
| 5669 | const base_mat = try base_vi.matReg(isel); | 5653 | .unsigned => .ldrh(elem_ra.w(), .{ .extended_register = .{ |
| 5670 | const index_vi = try isel.use(bin_op.rhs); | 5654 | .base = base_mat.ra.x(), |
| 5671 | try isel.elemPtr(elem_ptr_ra, base_mat.ra, .add, elem_size, index_vi); | 5655 | .index = index_mat.ra.x(), |
| 5672 | try base_mat.finish(isel); | 5656 | .extend = .{ .lsl = 1 }, |
| 5673 | }, | 5657 | } }), |
| 5658 | }, | ||
| 5659 | 4 => .ldr(if (elem_is_vector) elem_ra.s() else elem_ra.w(), .{ .extended_register = .{ | ||
| 5660 | .base = base_mat.ra.x(), | ||
| 5661 | .index = index_mat.ra.x(), | ||
| 5662 | .extend = .{ .lsl = 2 }, | ||
| 5663 | } }), | ||
| 5664 | 8 => .ldr(if (elem_is_vector) elem_ra.d() else elem_ra.x(), .{ .extended_register = .{ | ||
| 5665 | .base = base_mat.ra.x(), | ||
| 5666 | .index = index_mat.ra.x(), | ||
| 5667 | .extend = .{ .lsl = 3 }, | ||
| 5668 | } }), | ||
| 5669 | 16 => if (elem_is_vector) .ldr(elem_ra.q(), .{ .extended_register = .{ | ||
| 5670 | .base = base_mat.ra.x(), | ||
| 5671 | .index = index_mat.ra.x(), | ||
| 5672 | .extend = .{ .lsl = 4 }, | ||
| 5673 | } }) else unreachable, | ||
| 5674 | }); | ||
| 5675 | try index_mat.finish(isel); | ||
| 5676 | try base_mat.finish(isel); | ||
| 5677 | } else { | ||
| 5678 | const elem_ptr_ra = try isel.allocIntReg(); | ||
| 5679 | defer isel.freeReg(elem_ptr_ra); | ||
| 5680 | if (!try elem_vi.value.load(isel, ptr_ty.elemType2(zcu), elem_ptr_ra, .{ | ||
| 5681 | .@"volatile" = ptr_info.flags.is_volatile, | ||
| 5682 | })) break :unused; | ||
| 5683 | const base_vi = try isel.use(bin_op.lhs); | ||
| 5684 | const base_mat = try base_vi.matReg(isel); | ||
| 5685 | const index_vi = try isel.use(bin_op.rhs); | ||
| 5686 | try isel.elemPtr(elem_ptr_ra, base_mat.ra, .add, elem_size, index_vi); | ||
| 5687 | try base_mat.finish(isel); | ||
| 5674 | } | 5688 | } |
| 5675 | } | 5689 | } |
| 5676 | if (air.next()) |next_air_tag| continue :air_tag next_air_tag; | 5690 | if (air.next()) |next_air_tag| continue :air_tag next_air_tag; |
| ... | @@ -6250,11 +6264,12 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void { | ... | @@ -6250,11 +6264,12 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void { |
| 6250 | try agg_part_vi.?.move(isel, elems[field_index]); | 6264 | try agg_part_vi.?.move(isel, elems[field_index]); |
| 6251 | field_offset += field_size; | 6265 | field_offset += field_size; |
| 6252 | } | 6266 | } |
| 6253 | assert(field_offset == agg_vi.value.size(isel)); | 6267 | assert(loaded_struct.flagsUnordered(ip).alignment.forward(field_offset) == agg_vi.value.size(isel)); |
| 6254 | }, | 6268 | }, |
| 6255 | .tuple_type => |tuple_type| { | 6269 | .tuple_type => |tuple_type| { |
| 6256 | const elems: []const Air.Inst.Ref = | 6270 | const elems: []const Air.Inst.Ref = |
| 6257 | @ptrCast(isel.air.extra.items[ty_pl.payload..][0..tuple_type.types.len]); | 6271 | @ptrCast(isel.air.extra.items[ty_pl.payload..][0..tuple_type.types.len]); |
| 6272 | var tuple_align: InternPool.Alignment = .@"1"; | ||
| 6258 | var field_offset: u64 = 0; | 6273 | var field_offset: u64 = 0; |
| 6259 | for ( | 6274 | for ( |
| 6260 | tuple_type.types.get(ip), | 6275 | tuple_type.types.get(ip), |
| ... | @@ -6263,7 +6278,9 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void { | ... | @@ -6263,7 +6278,9 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void { |
| 6263 | ) |field_ty_index, field_val, elem| { | 6278 | ) |field_ty_index, field_val, elem| { |
| 6264 | if (field_val != .none) continue; | 6279 | if (field_val != .none) continue; |
| 6265 | const field_ty: ZigType = .fromInterned(field_ty_index); | 6280 | const field_ty: ZigType = .fromInterned(field_ty_index); |
| 6266 | field_offset = field_ty.abiAlignment(zcu).forward(field_offset); | 6281 | const field_align = field_ty.abiAlignment(zcu); |
| 6282 | tuple_align = tuple_align.maxStrict(field_align); | ||
| 6283 | field_offset = field_align.forward(field_offset); | ||
| 6267 | const field_size = field_ty.abiSize(zcu); | 6284 | const field_size = field_ty.abiSize(zcu); |
| 6268 | if (field_size == 0) continue; | 6285 | if (field_size == 0) continue; |
| 6269 | var agg_part_it = agg_vi.value.field(agg_ty, field_offset, field_size); | 6286 | var agg_part_it = agg_vi.value.field(agg_ty, field_offset, field_size); |
| ... | @@ -6271,7 +6288,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void { | ... | @@ -6271,7 +6288,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void { |
| 6271 | try agg_part_vi.?.move(isel, elem); | 6288 | try agg_part_vi.?.move(isel, elem); |
| 6272 | field_offset += field_size; | 6289 | field_offset += field_size; |
| 6273 | } | 6290 | } |
| 6274 | assert(field_offset == agg_vi.value.size(isel)); | 6291 | assert(tuple_align.forward(field_offset) == agg_vi.value.size(isel)); |
| 6275 | }, | 6292 | }, |
| 6276 | else => return isel.fail("aggregate init {f}", .{isel.fmtType(agg_ty)}), | 6293 | else => return isel.fail("aggregate init {f}", .{isel.fmtType(agg_ty)}), |
| 6277 | } | 6294 | } |
| ... | @@ -7283,6 +7300,175 @@ fn ctzLimb( | ... | @@ -7283,6 +7300,175 @@ fn ctzLimb( |
| 7283 | } | 7300 | } |
| 7284 | } | 7301 | } |
| 7285 | 7302 | ||
| 7303 | fn loadReg( | ||
| 7304 | isel: *Select, | ||
| 7305 | ra: Register.Alias, | ||
| 7306 | size: u64, | ||
| 7307 | signedness: std.builtin.Signedness, | ||
| 7308 | base_ra: Register.Alias, | ||
| 7309 | offset: i65, | ||
| 7310 | ) !void { | ||
| 7311 | switch (size) { | ||
| 7312 | 0 => unreachable, | ||
| 7313 | 1 => { | ||
| 7314 | if (std.math.cast(u12, offset)) |unsigned_offset| return isel.emit(if (ra.isVector()) .ldr( | ||
| 7315 | ra.b(), | ||
| 7316 | .{ .unsigned_offset = .{ | ||
| 7317 | .base = base_ra.x(), | ||
| 7318 | .offset = unsigned_offset, | ||
| 7319 | } }, | ||
| 7320 | ) else switch (signedness) { | ||
| 7321 | .signed => .ldrsb(ra.w(), .{ .unsigned_offset = .{ | ||
| 7322 | .base = base_ra.x(), | ||
| 7323 | .offset = unsigned_offset, | ||
| 7324 | } }), | ||
| 7325 | .unsigned => .ldrb(ra.w(), .{ .unsigned_offset = .{ | ||
| 7326 | .base = base_ra.x(), | ||
| 7327 | .offset = unsigned_offset, | ||
| 7328 | } }), | ||
| 7329 | }); | ||
| 7330 | if (std.math.cast(i9, offset)) |signed_offset| return isel.emit(if (ra.isVector()) | ||
| 7331 | .ldur(ra.b(), base_ra.x(), signed_offset) | ||
| 7332 | else switch (signedness) { | ||
| 7333 | .signed => .ldursb(ra.w(), base_ra.x(), signed_offset), | ||
| 7334 | .unsigned => .ldurb(ra.w(), base_ra.x(), signed_offset), | ||
| 7335 | }); | ||
| 7336 | }, | ||
| 7337 | 2 => { | ||
| 7338 | if (std.math.cast(u13, offset)) |unsigned_offset| if (unsigned_offset % 2 == 0) | ||
| 7339 | return isel.emit(if (ra.isVector()) .ldr( | ||
| 7340 | ra.h(), | ||
| 7341 | .{ .unsigned_offset = .{ | ||
| 7342 | .base = base_ra.x(), | ||
| 7343 | .offset = unsigned_offset, | ||
| 7344 | } }, | ||
| 7345 | ) else switch (signedness) { | ||
| 7346 | .signed => .ldrsh( | ||
| 7347 | ra.w(), | ||
| 7348 | .{ .unsigned_offset = .{ | ||
| 7349 | .base = base_ra.x(), | ||
| 7350 | .offset = unsigned_offset, | ||
| 7351 | } }, | ||
| 7352 | ), | ||
| 7353 | .unsigned => .ldrh( | ||
| 7354 | ra.w(), | ||
| 7355 | .{ .unsigned_offset = .{ | ||
| 7356 | .base = base_ra.x(), | ||
| 7357 | .offset = unsigned_offset, | ||
| 7358 | } }, | ||
| 7359 | ), | ||
| 7360 | }); | ||
| 7361 | if (std.math.cast(i9, offset)) |signed_offset| return isel.emit(if (ra.isVector()) | ||
| 7362 | .ldur(ra.h(), base_ra.x(), signed_offset) | ||
| 7363 | else switch (signedness) { | ||
| 7364 | .signed => .ldursh(ra.w(), base_ra.x(), signed_offset), | ||
| 7365 | .unsigned => .ldurh(ra.w(), base_ra.x(), signed_offset), | ||
| 7366 | }); | ||
| 7367 | }, | ||
| 7368 | 3 => { | ||
| 7369 | const lo16_ra = try isel.allocIntReg(); | ||
| 7370 | defer isel.freeReg(lo16_ra); | ||
| 7371 | try isel.emit(.orr(ra.w(), lo16_ra.w(), .{ .shifted_register = .{ | ||
| 7372 | .register = ra.w(), | ||
| 7373 | .shift = .{ .lsl = 16 }, | ||
| 7374 | } })); | ||
| 7375 | try isel.loadReg(ra, 1, signedness, base_ra, offset + 2); | ||
| 7376 | return isel.loadReg(lo16_ra, 2, .unsigned, base_ra, offset); | ||
| 7377 | }, | ||
| 7378 | 4 => { | ||
| 7379 | if (std.math.cast(u14, offset)) |unsigned_offset| if (unsigned_offset % 4 == 0) return isel.emit(.ldr( | ||
| 7380 | if (ra.isVector()) ra.s() else ra.w(), | ||
| 7381 | .{ .unsigned_offset = .{ | ||
| 7382 | .base = base_ra.x(), | ||
| 7383 | .offset = unsigned_offset, | ||
| 7384 | } }, | ||
| 7385 | )); | ||
| 7386 | if (std.math.cast(i9, offset)) |signed_offset| return isel.emit(.ldur( | ||
| 7387 | if (ra.isVector()) ra.s() else ra.w(), | ||
| 7388 | base_ra.x(), | ||
| 7389 | signed_offset, | ||
| 7390 | )); | ||
| 7391 | }, | ||
| 7392 | 5, 6 => { | ||
| 7393 | const lo32_ra = try isel.allocIntReg(); | ||
| 7394 | defer isel.freeReg(lo32_ra); | ||
| 7395 | try isel.emit(.orr(ra.x(), lo32_ra.x(), .{ .shifted_register = .{ | ||
| 7396 | .register = ra.x(), | ||
| 7397 | .shift = .{ .lsl = 32 }, | ||
| 7398 | } })); | ||
| 7399 | try isel.loadReg(ra, size - 4, signedness, base_ra, offset + 4); | ||
| 7400 | return isel.loadReg(lo32_ra, 4, .unsigned, base_ra, offset); | ||
| 7401 | }, | ||
| 7402 | 7 => { | ||
| 7403 | const lo32_ra = try isel.allocIntReg(); | ||
| 7404 | defer isel.freeReg(lo32_ra); | ||
| 7405 | const lo48_ra = try isel.allocIntReg(); | ||
| 7406 | defer isel.freeReg(lo48_ra); | ||
| 7407 | try isel.emit(.orr(ra.x(), lo48_ra.x(), .{ .shifted_register = .{ | ||
| 7408 | .register = ra.x(), | ||
| 7409 | .shift = .{ .lsl = 32 + 16 }, | ||
| 7410 | } })); | ||
| 7411 | try isel.loadReg(ra, 1, signedness, base_ra, offset + 4 + 2); | ||
| 7412 | try isel.emit(.orr(lo48_ra.x(), lo32_ra.x(), .{ .shifted_register = .{ | ||
| 7413 | .register = lo48_ra.x(), | ||
| 7414 | .shift = .{ .lsl = 32 }, | ||
| 7415 | } })); | ||
| 7416 | try isel.loadReg(lo48_ra, 2, .unsigned, base_ra, offset + 4); | ||
| 7417 | return isel.loadReg(lo32_ra, 4, .unsigned, base_ra, offset); | ||
| 7418 | }, | ||
| 7419 | 8 => { | ||
| 7420 | if (std.math.cast(u15, offset)) |unsigned_offset| if (unsigned_offset % 8 == 0) return isel.emit(.ldr( | ||
| 7421 | if (ra.isVector()) ra.d() else ra.x(), | ||
| 7422 | .{ .unsigned_offset = .{ | ||
| 7423 | .base = base_ra.x(), | ||
| 7424 | .offset = unsigned_offset, | ||
| 7425 | } }, | ||
| 7426 | )); | ||
| 7427 | if (std.math.cast(i9, offset)) |signed_offset| return isel.emit(.ldur( | ||
| 7428 | if (ra.isVector()) ra.d() else ra.x(), | ||
| 7429 | base_ra.x(), | ||
| 7430 | signed_offset, | ||
| 7431 | )); | ||
| 7432 | }, | ||
| 7433 | 16 => { | ||
| 7434 | if (std.math.cast(u16, offset)) |unsigned_offset| if (unsigned_offset % 16 == 0) return isel.emit(.ldr( | ||
| 7435 | ra.q(), | ||
| 7436 | .{ .unsigned_offset = .{ | ||
| 7437 | .base = base_ra.x(), | ||
| 7438 | .offset = unsigned_offset, | ||
| 7439 | } }, | ||
| 7440 | )); | ||
| 7441 | if (std.math.cast(i9, offset)) |signed_offset| return isel.emit(.ldur(ra.q(), base_ra.x(), signed_offset)); | ||
| 7442 | }, | ||
| 7443 | else => return isel.fail("bad load size: {d}", .{size}), | ||
| 7444 | } | ||
| 7445 | const ptr_ra = try isel.allocIntReg(); | ||
| 7446 | defer isel.freeReg(ptr_ra); | ||
| 7447 | try isel.loadReg(ra, size, signedness, ptr_ra, 0); | ||
| 7448 | if (std.math.cast(u24, offset)) |pos_offset| { | ||
| 7449 | const lo12: u12 = @truncate(pos_offset >> 0); | ||
| 7450 | const hi12: u12 = @intCast(pos_offset >> 12); | ||
| 7451 | if (hi12 > 0) try isel.emit(.add( | ||
| 7452 | ptr_ra.x(), | ||
| 7453 | if (lo12 > 0) ptr_ra.x() else base_ra.x(), | ||
| 7454 | .{ .shifted_immediate = .{ .immediate = hi12, .lsl = .@"12" } }, | ||
| 7455 | )); | ||
| 7456 | if (lo12 > 0 or hi12 == 0) try isel.emit(.add(ptr_ra.x(), base_ra.x(), .{ .immediate = lo12 })); | ||
| 7457 | } else if (std.math.cast(u24, -offset)) |neg_offset| { | ||
| 7458 | const lo12: u12 = @truncate(neg_offset >> 0); | ||
| 7459 | const hi12: u12 = @intCast(neg_offset >> 12); | ||
| 7460 | if (hi12 > 0) try isel.emit(.sub( | ||
| 7461 | ptr_ra.x(), | ||
| 7462 | if (lo12 > 0) ptr_ra.x() else base_ra.x(), | ||
| 7463 | .{ .shifted_immediate = .{ .immediate = hi12, .lsl = .@"12" } }, | ||
| 7464 | )); | ||
| 7465 | if (lo12 > 0 or hi12 == 0) try isel.emit(.sub(ptr_ra.x(), base_ra.x(), .{ .immediate = lo12 })); | ||
| 7466 | } else { | ||
| 7467 | try isel.emit(.add(ptr_ra.x(), base_ra.x(), .{ .register = ptr_ra.x() })); | ||
| 7468 | try isel.movImmediate(ptr_ra.x(), @truncate(@as(u65, @bitCast(offset)))); | ||
| 7469 | } | ||
| 7470 | } | ||
| 7471 | |||
| 7286 | fn storeReg( | 7472 | fn storeReg( |
| 7287 | isel: *Select, | 7473 | isel: *Select, |
| 7288 | ra: Register.Alias, | 7474 | ra: Register.Alias, |
| ... | @@ -7558,6 +7744,13 @@ pub const Value = struct { | ... | @@ -7558,6 +7744,13 @@ pub const Value = struct { |
| 7558 | }; | 7744 | }; |
| 7559 | } | 7745 | } |
| 7560 | 7746 | ||
| 7747 | pub fn changeStackSlot(vi: Value.Index, isel: *Select, new_stack_slot: Indirect) void { | ||
| 7748 | const value = vi.get(isel); | ||
| 7749 | assert(value.flags.parent_tag == .stack_slot); | ||
| 7750 | value.flags.parent_tag = .unallocated; | ||
| 7751 | vi.setParent(isel, .{ .stack_slot = new_stack_slot }); | ||
| 7752 | } | ||
| 7753 | |||
| 7561 | pub fn parent(vi: Value.Index, isel: *Select) Parent { | 7754 | pub fn parent(vi: Value.Index, isel: *Select) Parent { |
| 7562 | const value = vi.get(isel); | 7755 | const value = vi.get(isel); |
| 7563 | return switch (value.flags.parent_tag) { | 7756 | return switch (value.flags.parent_tag) { |
| ... | @@ -8070,123 +8263,7 @@ pub const Value = struct { | ... | @@ -8070,123 +8263,7 @@ pub const Value = struct { |
| 8070 | }), | 8263 | }), |
| 8071 | 64 => {}, | 8264 | 64 => {}, |
| 8072 | }; | 8265 | }; |
| 8073 | try isel.emit(emit: switch (part_size) { | 8266 | try isel.loadReg(part_ra, part_size, part_vi.signedness(isel), base_ra, opts.offset); |
| 8074 | else => return isel.fail("bad load size of {d}", .{part_size}), | ||
| 8075 | 1 => if (part_is_vector) .ldr(part_ra.b(), .{ .unsigned_offset = .{ | ||
| 8076 | .base = base_ra.x(), | ||
| 8077 | .offset = @intCast(opts.offset), | ||
| 8078 | } }) else switch (part_vi.signedness(isel)) { | ||
| 8079 | .signed => .ldrsb(part_ra.w(), .{ .unsigned_offset = .{ | ||
| 8080 | .base = base_ra.x(), | ||
| 8081 | .offset = @intCast(opts.offset), | ||
| 8082 | } }), | ||
| 8083 | .unsigned => .ldrb(part_ra.w(), .{ .unsigned_offset = .{ | ||
| 8084 | .base = base_ra.x(), | ||
| 8085 | .offset = @intCast(opts.offset), | ||
| 8086 | } }), | ||
| 8087 | }, | ||
| 8088 | 2 => if (part_is_vector) .ldr(part_ra.h(), .{ .unsigned_offset = .{ | ||
| 8089 | .base = base_ra.x(), | ||
| 8090 | .offset = @intCast(opts.offset), | ||
| 8091 | } }) else switch (part_vi.signedness(isel)) { | ||
| 8092 | .signed => .ldrsh(part_ra.w(), .{ .unsigned_offset = .{ | ||
| 8093 | .base = base_ra.x(), | ||
| 8094 | .offset = @intCast(opts.offset), | ||
| 8095 | } }), | ||
| 8096 | .unsigned => .ldrh(part_ra.w(), .{ .unsigned_offset = .{ | ||
| 8097 | .base = base_ra.x(), | ||
| 8098 | .offset = @intCast(opts.offset), | ||
| 8099 | } }), | ||
| 8100 | }, | ||
| 8101 | 3 => { | ||
| 8102 | const lo16_ra = try isel.allocIntReg(); | ||
| 8103 | defer isel.freeReg(lo16_ra); | ||
| 8104 | try isel.emit(.orr(part_ra.w(), lo16_ra.w(), .{ .shifted_register = .{ | ||
| 8105 | .register = part_ra.w(), | ||
| 8106 | .shift = .{ .lsl = 16 }, | ||
| 8107 | } })); | ||
| 8108 | try isel.emit(switch (part_vi.signedness(isel)) { | ||
| 8109 | .signed => .ldrsb(part_ra.w(), .{ .unsigned_offset = .{ | ||
| 8110 | .base = base_ra.x(), | ||
| 8111 | .offset = @intCast(opts.offset + 2), | ||
| 8112 | } }), | ||
| 8113 | .unsigned => .ldrb(part_ra.w(), .{ .unsigned_offset = .{ | ||
| 8114 | .base = base_ra.x(), | ||
| 8115 | .offset = @intCast(opts.offset + 2), | ||
| 8116 | } }), | ||
| 8117 | }); | ||
| 8118 | break :emit .ldrh(lo16_ra.w(), .{ .unsigned_offset = .{ | ||
| 8119 | .base = base_ra.x(), | ||
| 8120 | .offset = @intCast(opts.offset), | ||
| 8121 | } }); | ||
| 8122 | }, | ||
| 8123 | 4 => .ldr(if (part_is_vector) part_ra.s() else part_ra.w(), .{ .unsigned_offset = .{ | ||
| 8124 | .base = base_ra.x(), | ||
| 8125 | .offset = @intCast(opts.offset), | ||
| 8126 | } }), | ||
| 8127 | 5 => { | ||
| 8128 | const lo32_ra = try isel.allocIntReg(); | ||
| 8129 | defer isel.freeReg(lo32_ra); | ||
| 8130 | try isel.emit(.orr(part_ra.x(), lo32_ra.x(), .{ .shifted_register = .{ | ||
| 8131 | .register = part_ra.x(), | ||
| 8132 | .shift = .{ .lsl = 32 }, | ||
| 8133 | } })); | ||
| 8134 | try isel.emit(switch (part_vi.signedness(isel)) { | ||
| 8135 | .signed => .ldrsb(part_ra.w(), .{ .unsigned_offset = .{ | ||
| 8136 | .base = base_ra.x(), | ||
| 8137 | .offset = @intCast(opts.offset + 4), | ||
| 8138 | } }), | ||
| 8139 | .unsigned => .ldrb(part_ra.w(), .{ .unsigned_offset = .{ | ||
| 8140 | .base = base_ra.x(), | ||
| 8141 | .offset = @intCast(opts.offset + 4), | ||
| 8142 | } }), | ||
| 8143 | }); | ||
| 8144 | break :emit .ldr(lo32_ra.w(), .{ .unsigned_offset = .{ | ||
| 8145 | .base = base_ra.x(), | ||
| 8146 | .offset = @intCast(opts.offset), | ||
| 8147 | } }); | ||
| 8148 | }, | ||
| 8149 | 7 => { | ||
| 8150 | const lo32_ra = try isel.allocIntReg(); | ||
| 8151 | defer isel.freeReg(lo32_ra); | ||
| 8152 | const lo48_ra = try isel.allocIntReg(); | ||
| 8153 | defer isel.freeReg(lo48_ra); | ||
| 8154 | try isel.emit(.orr(part_ra.x(), lo48_ra.x(), .{ .shifted_register = .{ | ||
| 8155 | .register = part_ra.x(), | ||
| 8156 | .shift = .{ .lsl = 32 + 16 }, | ||
| 8157 | } })); | ||
| 8158 | try isel.emit(switch (part_vi.signedness(isel)) { | ||
| 8159 | .signed => .ldrsb(part_ra.w(), .{ .unsigned_offset = .{ | ||
| 8160 | .base = base_ra.x(), | ||
| 8161 | .offset = @intCast(opts.offset + 4 + 2), | ||
| 8162 | } }), | ||
| 8163 | .unsigned => .ldrb(part_ra.w(), .{ .unsigned_offset = .{ | ||
| 8164 | .base = base_ra.x(), | ||
| 8165 | .offset = @intCast(opts.offset + 4 + 2), | ||
| 8166 | } }), | ||
| 8167 | }); | ||
| 8168 | try isel.emit(.orr(lo48_ra.x(), lo32_ra.x(), .{ .shifted_register = .{ | ||
| 8169 | .register = lo48_ra.x(), | ||
| 8170 | .shift = .{ .lsl = 32 }, | ||
| 8171 | } })); | ||
| 8172 | try isel.emit(.ldrh(lo48_ra.w(), .{ .unsigned_offset = .{ | ||
| 8173 | .base = base_ra.x(), | ||
| 8174 | .offset = @intCast(opts.offset + 4), | ||
| 8175 | } })); | ||
| 8176 | break :emit .ldr(lo32_ra.w(), .{ .unsigned_offset = .{ | ||
| 8177 | .base = base_ra.x(), | ||
| 8178 | .offset = @intCast(opts.offset), | ||
| 8179 | } }); | ||
| 8180 | }, | ||
| 8181 | 8 => .ldr(if (part_is_vector) part_ra.d() else part_ra.x(), .{ .unsigned_offset = .{ | ||
| 8182 | .base = base_ra.x(), | ||
| 8183 | .offset = @intCast(opts.offset), | ||
| 8184 | } }), | ||
| 8185 | 16 => .ldr(part_ra.q(), .{ .unsigned_offset = .{ | ||
| 8186 | .base = base_ra.x(), | ||
| 8187 | .offset = @intCast(opts.offset), | ||
| 8188 | } }), | ||
| 8189 | }); | ||
| 8190 | if (part_ra != .zr) { | 8267 | if (part_ra != .zr) { |
| 8191 | const live_vi = isel.live_registers.getPtr(part_ra); | 8268 | const live_vi = isel.live_registers.getPtr(part_ra); |
| 8192 | assert(live_vi.* == .allocating); | 8269 | assert(live_vi.* == .allocating); |
| ... | @@ -9104,7 +9181,7 @@ pub const Value = struct { | ... | @@ -9104,7 +9181,7 @@ pub const Value = struct { |
| 9104 | const live_vi = isel.live_registers.getPtr(mat.ra); | 9181 | const live_vi = isel.live_registers.getPtr(mat.ra); |
| 9105 | assert(live_vi.* == .allocating); | 9182 | assert(live_vi.* == .allocating); |
| 9106 | var vi = mat.vi; | 9183 | var vi = mat.vi; |
| 9107 | var offset: i65 = 0; | 9184 | var offset: u64 = 0; |
| 9108 | const size = mat.vi.size(isel); | 9185 | const size = mat.vi.size(isel); |
| 9109 | free: while (true) { | 9186 | free: while (true) { |
| 9110 | if (vi.register(isel)) |ra| { | 9187 | if (vi.register(isel)) |ra| { |
| ... | @@ -9156,93 +9233,16 @@ pub const Value = struct { | ... | @@ -9156,93 +9233,16 @@ pub const Value = struct { |
| 9156 | live_vi.* = mat.vi; | 9233 | live_vi.* = mat.vi; |
| 9157 | return; | 9234 | return; |
| 9158 | }, | 9235 | }, |
| 9159 | .stack_slot => |stack_slot| { | 9236 | .stack_slot => |stack_slot| break :free try isel.loadReg( |
| 9160 | offset += stack_slot.offset; | 9237 | mat.ra, |
| 9161 | break :free try isel.emit(switch (size) { | 9238 | size, |
| 9162 | else => unreachable, | 9239 | mat.vi.signedness(isel), |
| 9163 | 1 => if (mat.ra.isVector()) .ldr(mat.ra.b(), .{ .unsigned_offset = .{ | 9240 | stack_slot.base, |
| 9164 | .base = stack_slot.base.x(), | 9241 | @as(i65, stack_slot.offset) + offset, |
| 9165 | .offset = @intCast(offset), | 9242 | ), |
| 9166 | } }) else switch (mat.vi.signedness(isel)) { | ||
| 9167 | .signed => .ldrsb(mat.ra.w(), .{ .unsigned_offset = .{ | ||
| 9168 | .base = stack_slot.base.x(), | ||
| 9169 | .offset = @intCast(offset), | ||
| 9170 | } }), | ||
| 9171 | .unsigned => .ldrb(mat.ra.w(), .{ .unsigned_offset = .{ | ||
| 9172 | .base = stack_slot.base.x(), | ||
| 9173 | .offset = @intCast(offset), | ||
| 9174 | } }), | ||
| 9175 | }, | ||
| 9176 | 2 => if (mat.ra.isVector()) .ldr(mat.ra.h(), .{ .unsigned_offset = .{ | ||
| 9177 | .base = stack_slot.base.x(), | ||
| 9178 | .offset = @intCast(offset), | ||
| 9179 | } }) else switch (mat.vi.signedness(isel)) { | ||
| 9180 | .signed => .ldrsh(mat.ra.w(), .{ .unsigned_offset = .{ | ||
| 9181 | .base = stack_slot.base.x(), | ||
| 9182 | .offset = @intCast(offset), | ||
| 9183 | } }), | ||
| 9184 | .unsigned => .ldrh(mat.ra.w(), .{ .unsigned_offset = .{ | ||
| 9185 | .base = stack_slot.base.x(), | ||
| 9186 | .offset = @intCast(offset), | ||
| 9187 | } }), | ||
| 9188 | }, | ||
| 9189 | 4 => .ldr(if (mat.ra.isVector()) mat.ra.s() else mat.ra.w(), .{ .unsigned_offset = .{ | ||
| 9190 | .base = stack_slot.base.x(), | ||
| 9191 | .offset = @intCast(offset), | ||
| 9192 | } }), | ||
| 9193 | 8 => .ldr(if (mat.ra.isVector()) mat.ra.d() else mat.ra.x(), .{ .unsigned_offset = .{ | ||
| 9194 | .base = stack_slot.base.x(), | ||
| 9195 | .offset = @intCast(offset), | ||
| 9196 | } }), | ||
| 9197 | 16 => .ldr(mat.ra.q(), .{ .unsigned_offset = .{ | ||
| 9198 | .base = stack_slot.base.x(), | ||
| 9199 | .offset = @intCast(offset), | ||
| 9200 | } }), | ||
| 9201 | }); | ||
| 9202 | }, | ||
| 9203 | .address => |base_vi| { | 9243 | .address => |base_vi| { |
| 9204 | const base_mat = try base_vi.matReg(isel); | 9244 | const base_mat = try base_vi.matReg(isel); |
| 9205 | try isel.emit(switch (size) { | 9245 | try isel.loadReg(mat.ra, size, mat.vi.signedness(isel), base_mat.ra, offset); |
| 9206 | else => unreachable, | ||
| 9207 | 1 => if (mat.ra.isVector()) .ldr(mat.ra.b(), .{ .unsigned_offset = .{ | ||
| 9208 | .base = base_mat.ra.x(), | ||
| 9209 | .offset = @intCast(offset), | ||
| 9210 | } }) else switch (mat.vi.signedness(isel)) { | ||
| 9211 | .signed => .ldrsb(mat.ra.w(), .{ .unsigned_offset = .{ | ||
| 9212 | .base = base_mat.ra.x(), | ||
| 9213 | .offset = @intCast(offset), | ||
| 9214 | } }), | ||
| 9215 | .unsigned => .ldrb(mat.ra.w(), .{ .unsigned_offset = .{ | ||
| 9216 | .base = base_mat.ra.x(), | ||
| 9217 | .offset = @intCast(offset), | ||
| 9218 | } }), | ||
| 9219 | }, | ||
| 9220 | 2 => if (mat.ra.isVector()) .ldr(mat.ra.h(), .{ .unsigned_offset = .{ | ||
| 9221 | .base = base_mat.ra.x(), | ||
| 9222 | .offset = @intCast(offset), | ||
| 9223 | } }) else switch (mat.vi.signedness(isel)) { | ||
| 9224 | .signed => .ldrsh(mat.ra.w(), .{ .unsigned_offset = .{ | ||
| 9225 | .base = base_mat.ra.x(), | ||
| 9226 | .offset = @intCast(offset), | ||
| 9227 | } }), | ||
| 9228 | .unsigned => .ldrh(mat.ra.w(), .{ .unsigned_offset = .{ | ||
| 9229 | .base = base_mat.ra.x(), | ||
| 9230 | .offset = @intCast(offset), | ||
| 9231 | } }), | ||
| 9232 | }, | ||
| 9233 | 4 => .ldr(if (mat.ra.isVector()) mat.ra.s() else mat.ra.w(), .{ .unsigned_offset = .{ | ||
| 9234 | .base = base_mat.ra.x(), | ||
| 9235 | .offset = @intCast(offset), | ||
| 9236 | } }), | ||
| 9237 | 8 => .ldr(if (mat.ra.isVector()) mat.ra.d() else mat.ra.x(), .{ .unsigned_offset = .{ | ||
| 9238 | .base = base_mat.ra.x(), | ||
| 9239 | .offset = @intCast(offset), | ||
| 9240 | } }), | ||
| 9241 | 16 => .ldr(mat.ra.q(), .{ .unsigned_offset = .{ | ||
| 9242 | .base = base_mat.ra.x(), | ||
| 9243 | .offset = @intCast(offset), | ||
| 9244 | } }), | ||
| 9245 | }); | ||
| 9246 | break :free try base_mat.finish(isel); | 9246 | break :free try base_mat.finish(isel); |
| 9247 | }, | 9247 | }, |
| 9248 | .value => |parent_vi| vi = parent_vi, | 9248 | .value => |parent_vi| vi = parent_vi, |
src/codegen/aarch64/encoding.zig+434-41| ... | @@ -1072,7 +1072,7 @@ pub const Register = struct { | ... | @@ -1072,7 +1072,7 @@ pub const Register = struct { |
| 1072 | } | 1072 | } |
| 1073 | 1073 | ||
| 1074 | pub fn parse(reg: []const u8) ?Register { | 1074 | pub fn parse(reg: []const u8) ?Register { |
| 1075 | return if (reg.len == 0) null else switch (reg[0]) { | 1075 | return if (reg.len == 0) null else switch (std.ascii.toLower(reg[0])) { |
| 1076 | else => null, | 1076 | else => null, |
| 1077 | 'r' => if (std.fmt.parseInt(u5, reg[1..], 10)) |n| switch (n) { | 1077 | 'r' => if (std.fmt.parseInt(u5, reg[1..], 10)) |n| switch (n) { |
| 1078 | 0...30 => .{ | 1078 | 0...30 => .{ |
| ... | @@ -1087,27 +1087,27 @@ pub const Register = struct { | ... | @@ -1087,27 +1087,27 @@ pub const Register = struct { |
| 1087 | .format = .{ .integer = .doubleword }, | 1087 | .format = .{ .integer = .doubleword }, |
| 1088 | }, | 1088 | }, |
| 1089 | 31 => null, | 1089 | 31 => null, |
| 1090 | } else |_| if (std.mem.eql(u8, reg, "xzr")) .xzr else null, | 1090 | } else |_| if (toLowerEqlAssertLower(reg, "xzr")) .xzr else null, |
| 1091 | 'w' => if (std.fmt.parseInt(u5, reg[1..], 10)) |n| switch (n) { | 1091 | 'w' => if (std.fmt.parseInt(u5, reg[1..], 10)) |n| switch (n) { |
| 1092 | 0...30 => .{ | 1092 | 0...30 => .{ |
| 1093 | .alias = @enumFromInt(@intFromEnum(Alias.r0) + n), | 1093 | .alias = @enumFromInt(@intFromEnum(Alias.r0) + n), |
| 1094 | .format = .{ .integer = .word }, | 1094 | .format = .{ .integer = .word }, |
| 1095 | }, | 1095 | }, |
| 1096 | 31 => null, | 1096 | 31 => null, |
| 1097 | } else |_| if (std.mem.eql(u8, reg, "wzr")) | 1097 | } else |_| if (toLowerEqlAssertLower(reg, "wzr")) |
| 1098 | .wzr | 1098 | .wzr |
| 1099 | else if (std.mem.eql(u8, reg, "wsp")) | 1099 | else if (toLowerEqlAssertLower(reg, "wsp")) |
| 1100 | .wsp | 1100 | .wsp |
| 1101 | else | 1101 | else |
| 1102 | null, | 1102 | null, |
| 1103 | 'i' => return if (std.mem.eql(u8, reg, "ip") or std.mem.eql(u8, reg, "ip0")) | 1103 | 'i' => return if (toLowerEqlAssertLower(reg, "ip") or toLowerEqlAssertLower(reg, "ip0")) |
| 1104 | .ip0 | 1104 | .ip0 |
| 1105 | else if (std.mem.eql(u8, reg, "ip1")) | 1105 | else if (toLowerEqlAssertLower(reg, "ip1")) |
| 1106 | .ip1 | 1106 | .ip1 |
| 1107 | else | 1107 | else |
| 1108 | null, | 1108 | null, |
| 1109 | 'f' => return if (std.mem.eql(u8, reg, "fp")) .fp else null, | 1109 | 'f' => return if (toLowerEqlAssertLower(reg, "fp")) .fp else null, |
| 1110 | 'p' => return if (std.mem.eql(u8, reg, "pc")) .pc else null, | 1110 | 'p' => return if (toLowerEqlAssertLower(reg, "pc")) .pc else null, |
| 1111 | 'v' => if (std.fmt.parseInt(u5, reg[1..], 10)) |n| .{ | 1111 | 'v' => if (std.fmt.parseInt(u5, reg[1..], 10)) |n| .{ |
| 1112 | .alias = @enumFromInt(@intFromEnum(Alias.v0) + n), | 1112 | .alias = @enumFromInt(@intFromEnum(Alias.v0) + n), |
| 1113 | .format = .alias, | 1113 | .format = .alias, |
| ... | @@ -1123,7 +1123,7 @@ pub const Register = struct { | ... | @@ -1123,7 +1123,7 @@ pub const Register = struct { |
| 1123 | 's' => if (std.fmt.parseInt(u5, reg[1..], 10)) |n| .{ | 1123 | 's' => if (std.fmt.parseInt(u5, reg[1..], 10)) |n| .{ |
| 1124 | .alias = @enumFromInt(@intFromEnum(Alias.v0) + n), | 1124 | .alias = @enumFromInt(@intFromEnum(Alias.v0) + n), |
| 1125 | .format = .{ .scalar = .single }, | 1125 | .format = .{ .scalar = .single }, |
| 1126 | } else |_| if (std.mem.eql(u8, reg, "sp")) .sp else null, | 1126 | } else |_| if (toLowerEqlAssertLower(reg, "sp")) .sp else null, |
| 1127 | 'h' => if (std.fmt.parseInt(u5, reg[1..], 10)) |n| .{ | 1127 | 'h' => if (std.fmt.parseInt(u5, reg[1..], 10)) |n| .{ |
| 1128 | .alias = @enumFromInt(@intFromEnum(Alias.v0) + n), | 1128 | .alias = @enumFromInt(@intFromEnum(Alias.v0) + n), |
| 1129 | .format = .{ .scalar = .half }, | 1129 | .format = .{ .scalar = .half }, |
| ... | @@ -1141,6 +1141,422 @@ pub const Register = struct { | ... | @@ -1141,6 +1141,422 @@ pub const Register = struct { |
| 1141 | pub fn fmtCase(reg: Register, case: aarch64.Disassemble.Case) aarch64.Disassemble.RegisterFormatter { | 1141 | pub fn fmtCase(reg: Register, case: aarch64.Disassemble.Case) aarch64.Disassemble.RegisterFormatter { |
| 1142 | return .{ .reg = reg, .case = case }; | 1142 | return .{ .reg = reg, .case = case }; |
| 1143 | } | 1143 | } |
| 1144 | |||
| 1145 | pub const System = packed struct(u16) { | ||
| 1146 | op2: u3, | ||
| 1147 | CRm: u4, | ||
| 1148 | CRn: u4, | ||
| 1149 | op1: u3, | ||
| 1150 | op0: u2, | ||
| 1151 | |||
| 1152 | // D19.2 General system control registers | ||
| 1153 | /// D19.2.1 ACCDATA_EL1, Accelerator Data | ||
| 1154 | pub const accdata_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b1101, .CRm = 0b0000, .op2 = 0b101 }; | ||
| 1155 | /// D19.2.2 ACTLR_EL1, Auxiliary Control Register (EL1) | ||
| 1156 | pub const actlr_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0001, .CRm = 0b0000, .op2 = 0b001 }; | ||
| 1157 | /// D19.2.3 ACTLR_EL2, Auxiliary Control Register (EL2) | ||
| 1158 | pub const actlr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0001, .CRm = 0b0000, .op2 = 0b001 }; | ||
| 1159 | /// D19.2.4 ACTLR_EL3, Auxiliary Control Register (EL3) | ||
| 1160 | pub const actlr_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b0001, .CRm = 0b0000, .op2 = 0b001 }; | ||
| 1161 | /// D19.2.5 AFSR0_EL1, Auxiliary Fault Status Register 0 (EL1) | ||
| 1162 | pub const afsr0_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0101, .CRm = 0b0001, .op2 = 0b000 }; | ||
| 1163 | /// D19.2.5 AFSR0_EL12, Auxiliary Fault Status Register 0 (EL12) | ||
| 1164 | pub const afsr0_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b0101, .CRm = 0b0001, .op2 = 0b000 }; | ||
| 1165 | /// D19.2.6 AFSR0_EL2, Auxiliary Fault Status Register 0 (EL2) | ||
| 1166 | pub const afsr0_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0101, .CRm = 0b0001, .op2 = 0b000 }; | ||
| 1167 | /// D19.2.7 AFSR0_EL3, Auxiliary Fault Status Register 0 (EL3) | ||
| 1168 | pub const afsr0_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b0101, .CRm = 0b0001, .op2 = 0b000 }; | ||
| 1169 | /// D19.2.8 AFSR1_EL1, Auxiliary Fault Status Register 1 (EL1) | ||
| 1170 | pub const afsr1_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0101, .CRm = 0b0001, .op2 = 0b001 }; | ||
| 1171 | /// D19.2.8 AFSR1_EL12, Auxiliary Fault Status Register 1 (EL12) | ||
| 1172 | pub const afsr1_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b0101, .CRm = 0b0001, .op2 = 0b001 }; | ||
| 1173 | /// D19.2.9 AFSR1_EL2, Auxiliary Fault Status Register 1 (EL2) | ||
| 1174 | pub const afsr1_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0101, .CRm = 0b0001, .op2 = 0b001 }; | ||
| 1175 | /// D19.2.10 AFSR1_EL3, Auxiliary Fault Status Register 1 (EL3) | ||
| 1176 | pub const afsr1_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b0101, .CRm = 0b0001, .op2 = 0b001 }; | ||
| 1177 | /// D19.2.11 AIDR_EL1, Auxiliary ID Register | ||
| 1178 | pub const aidr_el1: System = .{ .op0 = 0b11, .op1 = 0b001, .CRn = 0b0000, .CRm = 0b0000, .op2 = 0b111 }; | ||
| 1179 | /// D19.2.12 AMAIR_EL1, Auxiliary Memory Attribute Indirection Register (EL1) | ||
| 1180 | pub const amair_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b1010, .CRm = 0b0011, .op2 = 0b000 }; | ||
| 1181 | /// D19.2.12 AMAIR_EL12, Auxiliary Memory Attribute Indirection Register (EL12) | ||
| 1182 | pub const amair_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b1010, .CRm = 0b0011, .op2 = 0b000 }; | ||
| 1183 | /// D19.2.13 AMAIR_EL2, Auxiliary Memory Attribute Indirection Register (EL2) | ||
| 1184 | pub const amair_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b1010, .CRm = 0b0011, .op2 = 0b000 }; | ||
| 1185 | /// D19.2.14 AMAIR_EL3, Auxiliary Memory Attribute Indirection Register (EL3) | ||
| 1186 | pub const amair_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b1010, .CRm = 0b0011, .op2 = 0b000 }; | ||
| 1187 | /// D19.2.15 APDAKeyHi_EL1, Pointer Authentication Key A for Data (bits[127:64]) | ||
| 1188 | pub const apdakeyhi_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0010, .CRm = 0b0010, .op2 = 0b001 }; | ||
| 1189 | /// D19.2.16 APDAKeyLo_EL1, Pointer Authentication Key A for Data (bits[63:0]) | ||
| 1190 | pub const apdakeylo_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0010, .CRm = 0b0010, .op2 = 0b000 }; | ||
| 1191 | /// D19.2.17 APDBKeyHi_EL1, Pointer Authentication Key B for Data (bits[127:64]) | ||
| 1192 | pub const apdbkeyhi_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0010, .CRm = 0b0010, .op2 = 0b011 }; | ||
| 1193 | /// D19.2.18 APDAKeyHi_EL1, Pointer Authentication Key B for Data (bits[63:0]) | ||
| 1194 | pub const apdbkeylo_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0010, .CRm = 0b0010, .op2 = 0b010 }; | ||
| 1195 | /// D19.2.19 APGAKeyHi_EL1, Pointer Authentication Key A for Code (bits[127:64]) | ||
| 1196 | pub const apgakeyhi_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0010, .CRm = 0b0011, .op2 = 0b001 }; | ||
| 1197 | /// D19.2.20 APGAKeyLo_EL1, Pointer Authentication Key A for Code (bits[63:0]) | ||
| 1198 | pub const apgakeylo_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0010, .CRm = 0b0011, .op2 = 0b000 }; | ||
| 1199 | /// D19.2.21 APIAKeyHi_EL1, Pointer Authentication Key A for Instruction (bits[127:64]) | ||
| 1200 | pub const apiakeyhi_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0010, .CRm = 0b0001, .op2 = 0b001 }; | ||
| 1201 | /// D19.2.22 APIAKeyLo_EL1, Pointer Authentication Key A for Instruction (bits[63:0]) | ||
| 1202 | pub const apiakeylo_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0010, .CRm = 0b0001, .op2 = 0b000 }; | ||
| 1203 | /// D19.2.23 APIBKeyHi_EL1, Pointer Authentication Key B for Instruction (bits[127:64]) | ||
| 1204 | pub const apibkeyhi_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0010, .CRm = 0b0001, .op2 = 0b011 }; | ||
| 1205 | /// D19.2.24 APIBKeyLo_EL1, Pointer Authentication Key B for Instruction (bits[63:0]) | ||
| 1206 | pub const apibkeylo_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0010, .CRm = 0b0001, .op2 = 0b010 }; | ||
| 1207 | /// D19.2.25 CCSIDR2_EL1, Current Cache Size ID Register 2 | ||
| 1208 | pub const ccsidr2_el1: System = .{ .op0 = 0b11, .op1 = 0b001, .CRn = 0b0000, .CRm = 0b0000, .op2 = 0b010 }; | ||
| 1209 | /// D19.2.26 CCSIDR_EL1, Current Cache Size ID Register | ||
| 1210 | pub const ccsidr_el1: System = .{ .op0 = 0b11, .op1 = 0b001, .CRn = 0b0000, .CRm = 0b0000, .op2 = 0b000 }; | ||
| 1211 | /// D19.2.27 CLIDR_EL1, Cache Level ID Register | ||
| 1212 | pub const clidr_el1: System = .{ .op0 = 0b11, .op1 = 0b001, .CRn = 0b0000, .CRm = 0b0000, .op2 = 0b001 }; | ||
| 1213 | /// D19.2.28 CONTEXTIDR_EL1, Context ID Register (EL1) | ||
| 1214 | pub const contextidr_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b1101, .CRm = 0b0000, .op2 = 0b001 }; | ||
| 1215 | /// D19.2.28 CONTEXTIDR_EL12, Context ID Register (EL12) | ||
| 1216 | pub const contextidr_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b1101, .CRm = 0b0000, .op2 = 0b001 }; | ||
| 1217 | /// D19.2.29 CONTEXTIDR_EL2, Context ID Register (EL2) | ||
| 1218 | pub const contextidr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b1101, .CRm = 0b0000, .op2 = 0b001 }; | ||
| 1219 | /// D19.2.30 CPACR_EL1, Architectural Feature Access Control Register | ||
| 1220 | pub const cpacr_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0001, .CRm = 0b0000, .op2 = 0b010 }; | ||
| 1221 | /// D19.2.30 CPACR_EL12, Architectural Feature Access Control Register | ||
| 1222 | pub const cpacr_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b0001, .CRm = 0b0000, .op2 = 0b010 }; | ||
| 1223 | /// D19.2.31 CPACR_EL2, Architectural Feature Trap Register (EL2) | ||
| 1224 | pub const cptr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0001, .CRm = 0b0001, .op2 = 0b010 }; | ||
| 1225 | /// D19.2.32 CPACR_EL3, Architectural Feature Trap Register (EL3) | ||
| 1226 | pub const cptr_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b0001, .CRm = 0b0001, .op2 = 0b010 }; | ||
| 1227 | /// D19.2.33 CSSELR_EL1, Cache Size Selection Register | ||
| 1228 | pub const csselr_el1: System = .{ .op0 = 0b11, .op1 = 0b010, .CRn = 0b0000, .CRm = 0b0000, .op2 = 0b000 }; | ||
| 1229 | /// D19.2.34 CTR_EL0, Cache Type Register | ||
| 1230 | pub const ctr_el0: System = .{ .op0 = 0b11, .op1 = 0b011, .CRn = 0b0000, .CRm = 0b0000, .op2 = 0b001 }; | ||
| 1231 | /// D19.2.35 DACR32_EL2, Domain Access Control Register | ||
| 1232 | pub const dacr32_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0011, .CRm = 0b0000, .op2 = 0b000 }; | ||
| 1233 | /// D19.2.36 DCZID_EL0, Data Cache Zero ID Register | ||
| 1234 | pub const dczid_el0: System = .{ .op0 = 0b11, .op1 = 0b011, .CRn = 0b0000, .CRm = 0b0000, .op2 = 0b111 }; | ||
| 1235 | /// D19.2.37 ESR_EL1, Exception Syndrome Register (EL1) | ||
| 1236 | pub const esr_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0101, .CRm = 0b0010, .op2 = 0b000 }; | ||
| 1237 | /// D19.2.37 ESR_EL12, Exception Syndrome Register (EL12) | ||
| 1238 | pub const esr_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b0101, .CRm = 0b0010, .op2 = 0b000 }; | ||
| 1239 | /// D19.2.38 ESR_EL2, Exception Syndrome Register (EL2) | ||
| 1240 | pub const esr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0101, .CRm = 0b0010, .op2 = 0b000 }; | ||
| 1241 | /// D19.2.39 ESR_EL3, Exception Syndrome Register (EL3) | ||
| 1242 | pub const esr_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b0101, .CRm = 0b0010, .op2 = 0b000 }; | ||
| 1243 | /// D19.2.40 FAR_EL1, Fault Address Register (EL1) | ||
| 1244 | pub const far_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0110, .CRm = 0b0000, .op2 = 0b000 }; | ||
| 1245 | /// D19.2.40 FAR_EL12, Fault Address Register (EL12) | ||
| 1246 | pub const far_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b0110, .CRm = 0b0000, .op2 = 0b000 }; | ||
| 1247 | /// D19.2.41 FAR_EL2, Fault Address Register (EL2) | ||
| 1248 | pub const far_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0110, .CRm = 0b0000, .op2 = 0b000 }; | ||
| 1249 | /// D19.2.42 FAR_EL3, Fault Address Register (EL3) | ||
| 1250 | pub const far_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b0110, .CRm = 0b0000, .op2 = 0b000 }; | ||
| 1251 | /// D19.2.43 FPEXC32_EL2, Floating-Point Exception Control Register | ||
| 1252 | pub const fpexc32_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0101, .CRm = 0b0011, .op2 = 0b000 }; | ||
| 1253 | /// D19.2.44 GCR_EL1, Tag Control Register | ||
| 1254 | pub const gcr_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0001, .CRm = 0b0000, .op2 = 0b110 }; | ||
| 1255 | /// D19.2.45 GMID_EL1, Tag Control Register | ||
| 1256 | pub const gmid_el1: System = .{ .op0 = 0b11, .op1 = 0b001, .CRn = 0b0000, .CRm = 0b0000, .op2 = 0b100 }; | ||
| 1257 | /// D19.2.46 HACR_EL2, Hypervisor Auxiliary Control Register | ||
| 1258 | pub const hacr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0001, .CRm = 0b0001, .op2 = 0b111 }; | ||
| 1259 | /// D19.2.47 HAFGRTR_EL2, Hypervisor Activity Monitors Fine-Grained Read Trap Register | ||
| 1260 | pub const hafgrtr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0011, .CRm = 0b0001, .op2 = 0b110 }; | ||
| 1261 | /// D19.2.48 HCR_EL2, Hypervisor Configuration Register | ||
| 1262 | pub const hcr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0001, .CRm = 0b0001, .op2 = 0b000 }; | ||
| 1263 | /// D19.2.49 HCRX_EL2, Extended Hypervisor Configuration Register | ||
| 1264 | pub const hcrx_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0001, .CRm = 0b0010, .op2 = 0b010 }; | ||
| 1265 | /// D19.2.50 HDFGRTR_EL2, Hypervisor Debug Fine-Grained Read Trap Register | ||
| 1266 | pub const hdfgrtr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0011, .CRm = 0b0001, .op2 = 0b100 }; | ||
| 1267 | /// D19.2.51 HDFGWTR_EL2, Hypervisor Debug Fine-Grained Write Trap Register | ||
| 1268 | pub const hdfgwtr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0011, .CRm = 0b0001, .op2 = 0b101 }; | ||
| 1269 | /// D19.2.52 HFGITR_EL2, Hypervisor Fine-Grained Instruction Trap Register | ||
| 1270 | pub const hfgitr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0001, .CRm = 0b0001, .op2 = 0b110 }; | ||
| 1271 | /// D19.2.53 HFGRTR_EL2, Hypervisor Fine-Grained Read Trap Register | ||
| 1272 | pub const hfgrtr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0001, .CRm = 0b0001, .op2 = 0b100 }; | ||
| 1273 | /// D19.2.54 HFGWTR_EL2, Hypervisor Fine-Grained Write Trap Register | ||
| 1274 | pub const hfgwtr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0001, .CRm = 0b0001, .op2 = 0b101 }; | ||
| 1275 | /// D19.2.55 HPFAR_EL2, Hypervisor IPA Fault Address Register | ||
| 1276 | pub const hpfar_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0110, .CRm = 0b0000, .op2 = 0b100 }; | ||
| 1277 | /// D19.2.56 HSTR_EL2, Hypervisor System Trap Register | ||
| 1278 | pub const hstr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0001, .CRm = 0b0001, .op2 = 0b011 }; | ||
| 1279 | /// D19.2.57 ID_AA64AFR0_EL1, AArch64 Auxiliary Feature Register 0 | ||
| 1280 | pub const id_aa64afr0_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0101, .op2 = 0b100 }; | ||
| 1281 | /// D19.2.58 ID_AA64AFR1_EL1, AArch64 Auxiliary Feature Register 1 | ||
| 1282 | pub const id_aa64afr1_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0101, .op2 = 0b101 }; | ||
| 1283 | /// D19.2.59 ID_AA64DFR0_EL1, AArch64 Debug Feature Register 0 | ||
| 1284 | pub const id_aa64dfr0_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0101, .op2 = 0b000 }; | ||
| 1285 | /// D19.2.60 ID_AA64DFR1_EL1, AArch64 Debug Feature Register 1 | ||
| 1286 | pub const id_aa64dfr1_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0101, .op2 = 0b001 }; | ||
| 1287 | /// D19.2.61 ID_AA64ISAR0_EL1, AArch64 Instruction Set Attribute Register 0 | ||
| 1288 | pub const id_aa64isar0_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0110, .op2 = 0b000 }; | ||
| 1289 | /// D19.2.62 ID_AA64ISAR1_EL1, AArch64 Instruction Set Attribute Register 1 | ||
| 1290 | pub const id_aa64isar1_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0110, .op2 = 0b001 }; | ||
| 1291 | /// D19.2.63 ID_AA64ISAR2_EL1, AArch64 Instruction Set Attribute Register 2 | ||
| 1292 | pub const id_aa64isar2_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0110, .op2 = 0b010 }; | ||
| 1293 | /// D19.2.64 ID_AA64MMFR0_EL1, AArch64 Memory Model Feature Register 0 | ||
| 1294 | pub const id_aa64mmfr0_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0111, .op2 = 0b000 }; | ||
| 1295 | /// D19.2.65 ID_AA64MMFR1_EL1, AArch64 Memory Model Feature Register 1 | ||
| 1296 | pub const id_aa64mmfr1_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0111, .op2 = 0b001 }; | ||
| 1297 | /// D19.2.66 ID_AA64MMFR2_EL1, AArch64 Memory Model Feature Register 2 | ||
| 1298 | pub const id_aa64mmfr2_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0111, .op2 = 0b010 }; | ||
| 1299 | /// D19.2.67 ID_AA64MMFR3_EL1, AArch64 Memory Model Feature Register 3 | ||
| 1300 | pub const id_aa64mmfr3_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0111, .op2 = 0b011 }; | ||
| 1301 | /// D19.2.68 ID_AA64MMFR4_EL1, AArch64 Memory Model Feature Register 4 | ||
| 1302 | pub const id_aa64mmfr4_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0111, .op2 = 0b100 }; | ||
| 1303 | /// D19.2.69 ID_AA64PFR0_EL1, AArch64 Processor Feature Register 0 | ||
| 1304 | pub const id_aa64pfr0_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0100, .op2 = 0b000 }; | ||
| 1305 | /// D19.2.70 ID_AA64PFR1_EL1, AArch64 Processor Feature Register 1 | ||
| 1306 | pub const id_aa64pfr1_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0100, .op2 = 0b001 }; | ||
| 1307 | /// D19.2.71 ID_AA64PFR2_EL1, AArch64 Processor Feature Register 2 | ||
| 1308 | pub const id_aa64pfr2_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0100, .op2 = 0b010 }; | ||
| 1309 | /// D19.2.72 ID_AA64SMFR0_EL1, SME Feature ID Register 0 | ||
| 1310 | pub const id_aa64smfr0_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0100, .op2 = 0b101 }; | ||
| 1311 | /// D19.2.73 ID_AA64ZFR0_EL1, SVE Feature ID Register 0 | ||
| 1312 | pub const id_aa64zfr0_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0100, .op2 = 0b100 }; | ||
| 1313 | /// D19.2.74 ID_AFR0_EL1, AArch32 Auxiliary Feature Register 0 | ||
| 1314 | pub const id_afr0_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0001, .op2 = 0b011 }; | ||
| 1315 | /// D19.2.75 ID_DFR0_EL1, AArch32 Debug Feature Register 0 | ||
| 1316 | pub const id_dfr0_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0001, .op2 = 0b010 }; | ||
| 1317 | /// D19.2.76 ID_DFR1_EL1, AArch32 Debug Feature Register 1 | ||
| 1318 | pub const id_dfr1_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0011, .op2 = 0b101 }; | ||
| 1319 | /// D19.2.77 ID_ISAR0_EL1, AArch32 Instruction Set Attribute Register 0 | ||
| 1320 | pub const id_isar0_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0010, .op2 = 0b000 }; | ||
| 1321 | /// D19.2.78 ID_ISAR1_EL1, AArch32 Instruction Set Attribute Register 1 | ||
| 1322 | pub const id_isar1_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0010, .op2 = 0b001 }; | ||
| 1323 | /// D19.2.79 ID_ISAR2_EL1, AArch32 Instruction Set Attribute Register 2 | ||
| 1324 | pub const id_isar2_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0010, .op2 = 0b010 }; | ||
| 1325 | /// D19.2.80 ID_ISAR3_EL1, AArch32 Instruction Set Attribute Register 3 | ||
| 1326 | pub const id_isar3_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0010, .op2 = 0b011 }; | ||
| 1327 | /// D19.2.81 ID_ISAR4_EL1, AArch32 Instruction Set Attribute Register 4 | ||
| 1328 | pub const id_isar4_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0010, .op2 = 0b100 }; | ||
| 1329 | /// D19.2.82 ID_ISAR5_EL1, AArch32 Instruction Set Attribute Register 5 | ||
| 1330 | pub const id_isar5_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0010, .op2 = 0b101 }; | ||
| 1331 | /// D19.2.83 ID_ISAR6_EL1, AArch32 Instruction Set Attribute Register 6 | ||
| 1332 | pub const id_isar6_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0010, .op2 = 0b111 }; | ||
| 1333 | /// D19.2.84 ID_MMFR0_EL1, AArch32 Memory Model Feature Register 0 | ||
| 1334 | pub const id_mmfr0_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0001, .op2 = 0b100 }; | ||
| 1335 | /// D19.2.85 ID_MMFR1_EL1, AArch32 Memory Model Feature Register 1 | ||
| 1336 | pub const id_mmfr1_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0001, .op2 = 0b101 }; | ||
| 1337 | /// D19.2.86 ID_MMFR2_EL1, AArch32 Memory Model Feature Register 2 | ||
| 1338 | pub const id_mmfr2_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0001, .op2 = 0b110 }; | ||
| 1339 | /// D19.2.87 ID_MMFR3_EL1, AArch32 Memory Model Feature Register 3 | ||
| 1340 | pub const id_mmfr3_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0001, .op2 = 0b111 }; | ||
| 1341 | /// D19.2.88 ID_MMFR4_EL1, AArch32 Memory Model Feature Register 4 | ||
| 1342 | pub const id_mmfr4_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0010, .op2 = 0b110 }; | ||
| 1343 | /// D19.2.89 ID_MMFR5_EL1, AArch32 Memory Model Feature Register 5 | ||
| 1344 | pub const id_mmfr5_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0011, .op2 = 0b110 }; | ||
| 1345 | /// D19.2.90 ID_PFR0_EL1, AArch32 Processor Feature Register 0 | ||
| 1346 | pub const id_pfr0_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0001, .op2 = 0b000 }; | ||
| 1347 | /// D19.2.91 ID_PFR1_EL1, AArch32 Processor Feature Register 1 | ||
| 1348 | pub const id_pfr1_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0001, .op2 = 0b001 }; | ||
| 1349 | /// D19.2.92 ID_PFR2_EL1, AArch32 Processor Feature Register 2 | ||
| 1350 | pub const id_pfr2_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0011, .op2 = 0b100 }; | ||
| 1351 | /// D19.2.93 IFSR32_EL2, Instruction Fault Status Register (EL2) | ||
| 1352 | pub const ifsr32_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0101, .CRm = 0b0000, .op2 = 0b001 }; | ||
| 1353 | /// D19.2.94 ISR_EL1, Interrupt Status Register | ||
| 1354 | pub const isr_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b1100, .CRm = 0b0001, .op2 = 0b000 }; | ||
| 1355 | /// D19.2.95 LORC_EL1, LORegion Control (EL1) | ||
| 1356 | pub const lorc_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b1010, .CRm = 0b0100, .op2 = 0b011 }; | ||
| 1357 | /// D19.2.96 LOREA_EL1, LORegion End Address (EL1) | ||
| 1358 | pub const lorea_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b1010, .CRm = 0b0100, .op2 = 0b001 }; | ||
| 1359 | /// D19.2.97 SORID_EL1, LORegionID (EL1) | ||
| 1360 | pub const lorid_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b1010, .CRm = 0b0100, .op2 = 0b111 }; | ||
| 1361 | /// D19.2.98 LORN_EL1, LORegion Number (EL1) | ||
| 1362 | pub const lorn_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b1010, .CRm = 0b0100, .op2 = 0b010 }; | ||
| 1363 | /// D19.2.99 LORSA_EL1, LORegion Start Address (EL1) | ||
| 1364 | pub const lorsa_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b1010, .CRm = 0b0100, .op2 = 0b000 }; | ||
| 1365 | /// D19.2.100 MAIR_EL1, Memory Attribute Indirection Register (EL1) | ||
| 1366 | pub const mair_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b1010, .CRm = 0b0010, .op2 = 0b000 }; | ||
| 1367 | /// D19.2.100 MAIR_EL12, Memory Attribute Indirection Register (EL12) | ||
| 1368 | pub const mair_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b1010, .CRm = 0b0010, .op2 = 0b000 }; | ||
| 1369 | /// D19.2.101 MAIR_EL2, Memory Attribute Indirection Register (EL2) | ||
| 1370 | pub const mair_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b1010, .CRm = 0b0010, .op2 = 0b000 }; | ||
| 1371 | /// D19.2.102 MAIR_EL3, Memory Attribute Indirection Register (EL3) | ||
| 1372 | pub const mair_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b1010, .CRm = 0b0010, .op2 = 0b000 }; | ||
| 1373 | /// D19.2.103 MIDR_EL1, Main ID Register | ||
| 1374 | pub const midr_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0000, .op2 = 0b000 }; | ||
| 1375 | /// D19.2.104 MPIDR_EL1, Multiprocessor Affinity Register | ||
| 1376 | pub const mpidr_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0000, .op2 = 0b101 }; | ||
| 1377 | /// D19.2.105 MVFR0_EL1, AArch32 Media and VFP Feature Register 0 | ||
| 1378 | pub const mvfr0_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0011, .op2 = 0b000 }; | ||
| 1379 | /// D19.2.106 MVFR1_EL1, AArch32 Media and VFP Feature Register 1 | ||
| 1380 | pub const mvfr1_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0011, .op2 = 0b001 }; | ||
| 1381 | /// D19.2.107 MVFR2_EL1, AArch32 Media and VFP Feature Register 2 | ||
| 1382 | pub const mvfr2_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0011, .op2 = 0b010 }; | ||
| 1383 | /// D19.2.108 PAR_EL1, Physical Address Register | ||
| 1384 | pub const par_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0111, .CRm = 0b0100, .op2 = 0b000 }; | ||
| 1385 | /// D19.2.109 REVIDR_EL1, Revision ID Register | ||
| 1386 | pub const revidr_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0000, .CRm = 0b0000, .op2 = 0b110 }; | ||
| 1387 | /// D19.2.110 RGSR_EL1, Random Allocation Tag Seed Register | ||
| 1388 | pub const rgsr_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0001, .CRm = 0b0000, .op2 = 0b101 }; | ||
| 1389 | /// D19.2.111 RMR_EL1, Reset Management Register (EL1) | ||
| 1390 | pub const rmr_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b1100, .CRm = 0b0000, .op2 = 0b010 }; | ||
| 1391 | /// D19.2.112 RMR_EL2, Reset Management Register (EL2) | ||
| 1392 | pub const rmr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b1100, .CRm = 0b0000, .op2 = 0b010 }; | ||
| 1393 | /// D19.2.113 RMR_EL3, Reset Management Register (EL3) | ||
| 1394 | pub const rmr_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b1100, .CRm = 0b0000, .op2 = 0b010 }; | ||
| 1395 | /// D19.2.114 RNDR, Random Number | ||
| 1396 | pub const rndr: System = .{ .op0 = 0b11, .op1 = 0b011, .CRn = 0b0010, .CRm = 0b0100, .op2 = 0b000 }; | ||
| 1397 | /// D19.2.115 RNDRRS, Reseeded Random Number | ||
| 1398 | pub const rndrrs: System = .{ .op0 = 0b11, .op1 = 0b011, .CRn = 0b0010, .CRm = 0b0100, .op2 = 0b001 }; | ||
| 1399 | /// D19.2.116 RVBAR_EL1, Reset Vector Base Address Register (if EL2 and EL3 not implemented) | ||
| 1400 | pub const rvbar_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b1100, .CRm = 0b0000, .op2 = 0b001 }; | ||
| 1401 | /// D19.2.117 RVBAR_EL2, Reset Vector Base Address Register (if EL3 not implemented) | ||
| 1402 | pub const rvbar_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b1100, .CRm = 0b0000, .op2 = 0b001 }; | ||
| 1403 | /// D19.2.118 RVBAR_EL3, Reset Vector Base Address Register (if EL3 implemented) | ||
| 1404 | pub const rvbar_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b1100, .CRm = 0b0000, .op2 = 0b001 }; | ||
| 1405 | /// D19.2.120 SCR_EL3, Secure Configuration Register | ||
| 1406 | pub const scr_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b0001, .CRm = 0b0001, .op2 = 0b000 }; | ||
| 1407 | /// D19.2.121 SCTLR2_EL1, System Control Register (EL1) | ||
| 1408 | pub const sctlr2_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0001, .CRm = 0b0000, .op2 = 0b011 }; | ||
| 1409 | /// D19.2.121 SCTLR2_EL12, System Control Register (EL12) | ||
| 1410 | pub const sctlr2_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b0001, .CRm = 0b0000, .op2 = 0b011 }; | ||
| 1411 | /// D19.2.122 SCTLR2_EL2, System Control Register (EL2) | ||
| 1412 | pub const sctlr2_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0001, .CRm = 0b0000, .op2 = 0b011 }; | ||
| 1413 | /// D19.2.123 SCTLR2_EL3, System Control Register (EL3) | ||
| 1414 | pub const sctlr2_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b0001, .CRm = 0b0000, .op2 = 0b011 }; | ||
| 1415 | /// D19.2.124 SCTLR_EL1, System Control Register (EL1) | ||
| 1416 | pub const sctlr_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0001, .CRm = 0b0000, .op2 = 0b000 }; | ||
| 1417 | /// D19.2.124 SCTLR_EL12, System Control Register (EL12) | ||
| 1418 | pub const sctlr_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b0001, .CRm = 0b0000, .op2 = 0b000 }; | ||
| 1419 | /// D19.2.125 SCTLR_EL2, System Control Register (EL2) | ||
| 1420 | pub const sctlr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0001, .CRm = 0b0000, .op2 = 0b000 }; | ||
| 1421 | /// D19.2.126 SCTLR_EL3, System Control Register (EL3) | ||
| 1422 | pub const sctlr_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b0001, .CRm = 0b0000, .op2 = 0b000 }; | ||
| 1423 | /// D19.2.127 SCXTNUM_EL0, EL0 Read/Write Software Context Number | ||
| 1424 | pub const scxtnum_el0: System = .{ .op0 = 0b11, .op1 = 0b011, .CRn = 0b1101, .CRm = 0b0000, .op2 = 0b111 }; | ||
| 1425 | /// D19.2.128 SCXTNUM_EL1, EL1 Read/Write Software Context Number | ||
| 1426 | pub const scxtnum_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b1101, .CRm = 0b0000, .op2 = 0b111 }; | ||
| 1427 | /// D19.2.128 SCXTNUM_EL12, EL12 Read/Write Software Context Number | ||
| 1428 | pub const scxtnum_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b1101, .CRm = 0b0000, .op2 = 0b111 }; | ||
| 1429 | /// D19.2.129 SCXTNUM_EL2, EL2 Read/Write Software Context Number | ||
| 1430 | pub const scxtnum_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b1101, .CRm = 0b0000, .op2 = 0b111 }; | ||
| 1431 | /// D19.2.130 SCXTNUM_EL3, EL3 Read/Write Software Context Number | ||
| 1432 | pub const scxtnum_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b1101, .CRm = 0b0000, .op2 = 0b111 }; | ||
| 1433 | /// D19.2.131 SMCR_EL1, SME Control Register (EL1) | ||
| 1434 | pub const smcr_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0001, .CRm = 0b0010, .op2 = 0b110 }; | ||
| 1435 | /// D19.2.131 SMCR_EL12, SME Control Register (EL12) | ||
| 1436 | pub const smcr_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b0001, .CRm = 0b0010, .op2 = 0b110 }; | ||
| 1437 | /// D19.2.132 SMCR_EL2, SME Control Register (EL2) | ||
| 1438 | pub const smcr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0001, .CRm = 0b0010, .op2 = 0b110 }; | ||
| 1439 | /// D19.2.133 SMCR_EL3, SME Control Register (EL3) | ||
| 1440 | pub const smcr_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b0001, .CRm = 0b0010, .op2 = 0b110 }; | ||
| 1441 | /// D19.2.134 SMIDR_EL1, Streaming Mode Identification Register | ||
| 1442 | pub const smidr_el1: System = .{ .op0 = 0b11, .op1 = 0b001, .CRn = 0b0000, .CRm = 0b0000, .op2 = 0b110 }; | ||
| 1443 | /// D19.2.135 SMPRIMAP_EL2, Streaming Mode Priority Mapping Register | ||
| 1444 | pub const smprimap_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0001, .CRm = 0b0010, .op2 = 0b101 }; | ||
| 1445 | /// D19.2.136 SMPRI_EL1, Streaming Mode Priority Register | ||
| 1446 | pub const smpri_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0001, .CRm = 0b0010, .op2 = 0b100 }; | ||
| 1447 | /// D19.2.137 TCR2_EL1, Extended Translation Control Register (EL1) | ||
| 1448 | pub const tcr2_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0010, .CRm = 0b0000, .op2 = 0b011 }; | ||
| 1449 | /// D19.2.137 TCR2_EL12, Extended Translation Control Register (EL12) | ||
| 1450 | pub const tcr2_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b0010, .CRm = 0b0000, .op2 = 0b011 }; | ||
| 1451 | /// D19.2.138 TCR2_EL2, Extended Translation Control Register (EL2) | ||
| 1452 | pub const tcr2_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0010, .CRm = 0b0000, .op2 = 0b011 }; | ||
| 1453 | /// D19.2.139 TCR_EL1, Translation Control Register (EL1) | ||
| 1454 | pub const tcr_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0010, .CRm = 0b0000, .op2 = 0b010 }; | ||
| 1455 | /// D19.2.139 TCR_EL12, Translation Control Register (EL12) | ||
| 1456 | pub const tcr_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b0010, .CRm = 0b0000, .op2 = 0b010 }; | ||
| 1457 | /// D19.2.140 TCR_EL2, Translation Control Register (EL2) | ||
| 1458 | pub const tcr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0010, .CRm = 0b0000, .op2 = 0b010 }; | ||
| 1459 | /// D19.2.141 TCR_EL3, Translation Control Register (EL3) | ||
| 1460 | pub const tcr_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b0010, .CRm = 0b0000, .op2 = 0b010 }; | ||
| 1461 | /// D19.2.142 TFSRE0_EL1, Tag Fault Status Register (EL0) | ||
| 1462 | pub const tfsre0_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0101, .CRm = 0b0110, .op2 = 0b001 }; | ||
| 1463 | /// D19.2.143 TFSR_EL1, Tag Fault Status Register (EL1) | ||
| 1464 | pub const tfsr_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0101, .CRm = 0b0110, .op2 = 0b000 }; | ||
| 1465 | /// D19.2.143 TFSR_EL12, Tag Fault Status Register (EL12) | ||
| 1466 | pub const tfsr_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b0101, .CRm = 0b0110, .op2 = 0b000 }; | ||
| 1467 | /// D19.2.144 TFSR_EL2, Tag Fault Status Register (EL2) | ||
| 1468 | pub const tfsr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0101, .CRm = 0b0110, .op2 = 0b000 }; | ||
| 1469 | /// D19.2.145 TFSR_EL3, Tag Fault Status Register (EL3) | ||
| 1470 | pub const tfsr_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b0101, .CRm = 0b0110, .op2 = 0b000 }; | ||
| 1471 | /// D19.2.146 TPIDR2_EL0, EL0 Read/Write Software Thread ID Register 2 | ||
| 1472 | pub const tpidr2_el0: System = .{ .op0 = 0b11, .op1 = 0b011, .CRn = 0b1101, .CRm = 0b0000, .op2 = 0b101 }; | ||
| 1473 | /// D19.2.147 TPIDR_EL0, EL0 Read/Write Software Thread ID Register | ||
| 1474 | pub const tpidr_el0: System = .{ .op0 = 0b11, .op1 = 0b011, .CRn = 0b1101, .CRm = 0b0000, .op2 = 0b010 }; | ||
| 1475 | /// D19.2.148 TPIDR_EL1, EL1 Read/Write Software Thread ID Register | ||
| 1476 | pub const tpidr_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b1101, .CRm = 0b0000, .op2 = 0b100 }; | ||
| 1477 | /// D19.2.149 TPIDR_EL2, EL2 Read/Write Software Thread ID Register | ||
| 1478 | pub const tpidr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b1101, .CRm = 0b0000, .op2 = 0b010 }; | ||
| 1479 | /// D19.2.150 TPIDR_EL3, EL3 Read/Write Software Thread ID Register | ||
| 1480 | pub const tpidr_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b1101, .CRm = 0b0000, .op2 = 0b010 }; | ||
| 1481 | /// D19.2.151 TPIDRRO_EL0, EL0 Read-Only Software Thread ID Register | ||
| 1482 | pub const tpidrro_el3: System = .{ .op0 = 0b11, .op1 = 0b011, .CRn = 0b1101, .CRm = 0b0000, .op2 = 0b011 }; | ||
| 1483 | /// D19.2.152 TTBR0_EL1, Translation Table Base Register 0 (EL1) | ||
| 1484 | pub const ttbr0_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0010, .CRm = 0b0000, .op2 = 0b000 }; | ||
| 1485 | /// D19.2.152 TTBR0_EL12, Translation Table Base Register 0 (EL12) | ||
| 1486 | pub const ttbr0_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b0010, .CRm = 0b0000, .op2 = 0b000 }; | ||
| 1487 | /// D19.2.153 TTBR0_EL2, Translation Table Base Register 0 (EL2) | ||
| 1488 | pub const ttbr0_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0010, .CRm = 0b0000, .op2 = 0b000 }; | ||
| 1489 | /// D19.2.154 TTBR0_EL3, Translation Table Base Register 0 (EL3) | ||
| 1490 | pub const ttbr0_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b0010, .CRm = 0b0000, .op2 = 0b000 }; | ||
| 1491 | /// D19.2.155 TTBR1_EL1, Translation Table Base Register 1 (EL1) | ||
| 1492 | pub const ttbr1_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0010, .CRm = 0b0000, .op2 = 0b001 }; | ||
| 1493 | /// D19.2.155 TTBR1_EL12, Translation Table Base Register 1 (EL12) | ||
| 1494 | pub const ttbr1_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b0010, .CRm = 0b0000, .op2 = 0b001 }; | ||
| 1495 | /// D19.2.156 TTBR1_EL2, Translation Table Base Register 1 (EL2) | ||
| 1496 | pub const ttbr1_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0010, .CRm = 0b0000, .op2 = 0b001 }; | ||
| 1497 | /// D19.2.157 VBAR_EL1, Vector Base Address Register (EL1) | ||
| 1498 | pub const vbar_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b1100, .CRm = 0b0000, .op2 = 0b000 }; | ||
| 1499 | /// D19.2.157 VBAR_EL12, Vector Base Address Register (EL12) | ||
| 1500 | pub const vbar_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b1100, .CRm = 0b0000, .op2 = 0b000 }; | ||
| 1501 | /// D19.2.158 VBAR_EL2, Vector Base Address Register (EL2) | ||
| 1502 | pub const vbar_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b1100, .CRm = 0b0000, .op2 = 0b000 }; | ||
| 1503 | /// D19.2.159 VBAR_EL3, Vector Base Address Register (EL3) | ||
| 1504 | pub const vbar_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b1100, .CRm = 0b0000, .op2 = 0b000 }; | ||
| 1505 | /// D19.2.160 VMPIDR_EL2, Virtualization Multiprocessor ID Register | ||
| 1506 | pub const vmpidr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0000, .CRm = 0b0000, .op2 = 0b101 }; | ||
| 1507 | /// D19.2.161 VNCR_EL2, Virtual Nested Control Register | ||
| 1508 | pub const nvcr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0010, .CRm = 0b0010, .op2 = 0b000 }; | ||
| 1509 | /// D19.2.162 VPIDR_EL2, Virtualization Processor ID Register | ||
| 1510 | pub const vpidr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0000, .CRm = 0b0000, .op2 = 0b000 }; | ||
| 1511 | /// D19.2.163 VSTCR_EL2, Virtualization Secure Translation Control Register | ||
| 1512 | pub const vstcr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0010, .CRm = 0b0110, .op2 = 0b010 }; | ||
| 1513 | /// D19.2.164 VSTTBR_EL2, Virtualization Secure Translation Table Base Register | ||
| 1514 | pub const vsttbr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0010, .CRm = 0b0110, .op2 = 0b000 }; | ||
| 1515 | /// D19.2.165 VTCR_EL2, Virtualization Translation Control Register | ||
| 1516 | pub const vtcr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0010, .CRm = 0b0001, .op2 = 0b010 }; | ||
| 1517 | /// D19.2.166 VTTBR_EL2, Virtualization Translation Table Base Register | ||
| 1518 | pub const vttbr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0010, .CRm = 0b0001, .op2 = 0b000 }; | ||
| 1519 | /// D19.2.167 ZCR_EL1, SVE Control Register (EL1) | ||
| 1520 | pub const zcr_el1: System = .{ .op0 = 0b11, .op1 = 0b000, .CRn = 0b0001, .CRm = 0b0010, .op2 = 0b000 }; | ||
| 1521 | /// D19.2.167 ZCR_EL12, SVE Control Register (EL12) | ||
| 1522 | pub const zcr_el12: System = .{ .op0 = 0b11, .op1 = 0b101, .CRn = 0b0001, .CRm = 0b0010, .op2 = 0b000 }; | ||
| 1523 | /// D19.2.168 ZCR_EL2, SVE Control Register (EL2) | ||
| 1524 | pub const zcr_el2: System = .{ .op0 = 0b11, .op1 = 0b100, .CRn = 0b0001, .CRm = 0b0010, .op2 = 0b000 }; | ||
| 1525 | /// D19.2.169 ZCR_EL3, SVE Control Register (EL3) | ||
| 1526 | pub const zcr_el3: System = .{ .op0 = 0b11, .op1 = 0b110, .CRn = 0b0001, .CRm = 0b0010, .op2 = 0b000 }; | ||
| 1527 | |||
| 1528 | pub fn parse(reg: []const u8) ?System { | ||
| 1529 | if (reg.len >= 10 and std.ascii.toLower(reg[0]) == 's') encoded: { | ||
| 1530 | var symbol_it = std.mem.splitScalar(u8, reg[1..], '_'); | ||
| 1531 | const op0 = std.fmt.parseInt(u2, symbol_it.next() orelse break :encoded, 10) catch break :encoded; | ||
| 1532 | if (op0 < 0b10) break :encoded; | ||
| 1533 | const op1 = std.fmt.parseInt(u3, symbol_it.next() orelse break :encoded, 10) catch break :encoded; | ||
| 1534 | const n = symbol_it.next() orelse break :encoded; | ||
| 1535 | if (n.len == 0 or std.ascii.toLower(n[0]) != 'c') break :encoded; | ||
| 1536 | const CRn = std.fmt.parseInt(u4, n[1..], 10) catch break :encoded; | ||
| 1537 | const m = symbol_it.next() orelse break :encoded; | ||
| 1538 | if (m.len == 0 or std.ascii.toLower(m[0]) != 'c') break :encoded; | ||
| 1539 | const CRm = std.fmt.parseInt(u4, m[1..], 10) catch break :encoded; | ||
| 1540 | const op2 = std.fmt.parseInt(u3, symbol_it.next() orelse break :encoded, 10) catch break :encoded; | ||
| 1541 | if (symbol_it.next() != null) break :encoded; | ||
| 1542 | return .{ .op0 = op0, .op1 = op1, .CRn = CRn, .CRm = CRm, .op2 = op2 }; | ||
| 1543 | } | ||
| 1544 | inline for (@typeInfo(System).@"struct".decls) |decl| { | ||
| 1545 | if (@TypeOf(@field(System, decl.name)) != System) continue; | ||
| 1546 | if (toLowerEqlAssertLower(reg, decl.name)) return @field(System, decl.name); | ||
| 1547 | } | ||
| 1548 | return null; | ||
| 1549 | } | ||
| 1550 | }; | ||
| 1551 | |||
| 1552 | fn toLowerEqlAssertLower(lhs: []const u8, rhs: []const u8) bool { | ||
| 1553 | if (lhs.len != rhs.len) return false; | ||
| 1554 | for (lhs, rhs) |l, r| { | ||
| 1555 | assert(!std.ascii.isUpper(r)); | ||
| 1556 | if (std.ascii.toLower(l) != r) return false; | ||
| 1557 | } | ||
| 1558 | return true; | ||
| 1559 | } | ||
| 1144 | }; | 1560 | }; |
| 1145 | 1561 | ||
| 1146 | /// C1.2.4 Condition code | 1562 | /// C1.2.4 Condition code |
| ... | @@ -2385,12 +2801,7 @@ pub const Instruction = packed union { | ... | @@ -2385,12 +2801,7 @@ pub const Instruction = packed union { |
| 2385 | 2801 | ||
| 2386 | pub const Group = packed struct { | 2802 | pub const Group = packed struct { |
| 2387 | Rt: Register.Encoded, | 2803 | Rt: Register.Encoded, |
| 2388 | op2: u3, | 2804 | systemreg: Register.System, |
| 2389 | CRm: u4, | ||
| 2390 | CRn: u4, | ||
| 2391 | op1: u3, | ||
| 2392 | o0: u1, | ||
| 2393 | decoded20: u1 = 0b1, | ||
| 2394 | L: L, | 2805 | L: L, |
| 2395 | decoded22: u10 = 0b1101010100, | 2806 | decoded22: u10 = 0b1101010100, |
| 2396 | }; | 2807 | }; |
| ... | @@ -2398,12 +2809,7 @@ pub const Instruction = packed union { | ... | @@ -2398,12 +2809,7 @@ pub const Instruction = packed union { |
| 2398 | /// C6.2.230 MSR (register) | 2809 | /// C6.2.230 MSR (register) |
| 2399 | pub const Msr = packed struct { | 2810 | pub const Msr = packed struct { |
| 2400 | Rt: Register.Encoded, | 2811 | Rt: Register.Encoded, |
| 2401 | op2: u3, | 2812 | systemreg: Register.System, |
| 2402 | CRm: u4, | ||
| 2403 | CRn: u4, | ||
| 2404 | op1: u3, | ||
| 2405 | o0: u1, | ||
| 2406 | decoded20: u1 = 0b1, | ||
| 2407 | L: L = .msr, | 2813 | L: L = .msr, |
| 2408 | decoded22: u10 = 0b1101010100, | 2814 | decoded22: u10 = 0b1101010100, |
| 2409 | }; | 2815 | }; |
| ... | @@ -2411,12 +2817,7 @@ pub const Instruction = packed union { | ... | @@ -2411,12 +2817,7 @@ pub const Instruction = packed union { |
| 2411 | /// C6.2.228 MRS | 2817 | /// C6.2.228 MRS |
| 2412 | pub const Mrs = packed struct { | 2818 | pub const Mrs = packed struct { |
| 2413 | Rt: Register.Encoded, | 2819 | Rt: Register.Encoded, |
| 2414 | op2: u3, | 2820 | systemreg: Register.System, |
| 2415 | CRm: u4, | ||
| 2416 | CRn: u4, | ||
| 2417 | op1: u3, | ||
| 2418 | o0: u1, | ||
| 2419 | decoded20: u1 = 0b1, | ||
| 2420 | L: L = .mrs, | 2821 | L: L = .mrs, |
| 2421 | decoded22: u10 = 0b1101010100, | 2822 | decoded22: u10 = 0b1101010100, |
| 2422 | }; | 2823 | }; |
| ... | @@ -10585,30 +10986,22 @@ pub const Instruction = packed union { | ... | @@ -10585,30 +10986,22 @@ pub const Instruction = packed union { |
| 10585 | } } }; | 10986 | } } }; |
| 10586 | } | 10987 | } |
| 10587 | /// C6.2.228 MRS | 10988 | /// C6.2.228 MRS |
| 10588 | pub fn mrs(t: Register, op0: u2, op1: u3, n: u4, m: u4, op2: u3) Instruction { | 10989 | pub fn mrs(t: Register, systemreg: Register.System) Instruction { |
| 10589 | assert(t.format.integer == .doubleword); | 10990 | assert(t.format.integer == .doubleword and systemreg.op0 >= 0b10); |
| 10590 | return .{ .branch_exception_generating_system = .{ .system_register_move = .{ | 10991 | return .{ .branch_exception_generating_system = .{ .system_register_move = .{ |
| 10591 | .mrs = .{ | 10992 | .mrs = .{ |
| 10592 | .Rt = t.alias.encode(.{}), | 10993 | .Rt = t.alias.encode(.{}), |
| 10593 | .op2 = op2, | 10994 | .systemreg = systemreg, |
| 10594 | .CRm = m, | ||
| 10595 | .CRn = n, | ||
| 10596 | .op1 = op1, | ||
| 10597 | .o0 = @intCast(op0 - 0b10), | ||
| 10598 | }, | 10995 | }, |
| 10599 | } } }; | 10996 | } } }; |
| 10600 | } | 10997 | } |
| 10601 | /// C6.2.230 MSR (register) | 10998 | /// C6.2.230 MSR (register) |
| 10602 | pub fn msr(op0: u2, op1: u3, n: u4, m: u4, op2: u3, t: Register) Instruction { | 10999 | pub fn msr(systemreg: Register.System, t: Register) Instruction { |
| 10603 | assert(t.format.integer == .doubleword); | 11000 | assert(systemreg.op0 >= 0b10 and t.format.integer == .doubleword); |
| 10604 | return .{ .branch_exception_generating_system = .{ .system_register_move = .{ | 11001 | return .{ .branch_exception_generating_system = .{ .system_register_move = .{ |
| 10605 | .msr = .{ | 11002 | .msr = .{ |
| 10606 | .Rt = t.alias.encode(.{}), | 11003 | .Rt = t.alias.encode(.{}), |
| 10607 | .op2 = op2, | 11004 | .systemreg = systemreg, |
| 10608 | .CRm = m, | ||
| 10609 | .CRn = n, | ||
| 10610 | .op1 = op1, | ||
| 10611 | .o0 = @intCast(op0 - 0b10), | ||
| 10612 | }, | 11005 | }, |
| 10613 | } } }; | 11006 | } } }; |
| 10614 | } | 11007 | } |
src/codegen/aarch64/instructions.zon+12-2| ... | @@ -851,11 +851,21 @@ | ... | @@ -851,11 +851,21 @@ |
| 851 | }, | 851 | }, |
| 852 | // C6.2.228 MRS | 852 | // C6.2.228 MRS |
| 853 | .{ | 853 | .{ |
| 854 | .pattern = "MRS <Xt>, CTR_EL0", | 854 | .pattern = "MRS <Xt>, <systemreg>", |
| 855 | .symbols = .{ | 855 | .symbols = .{ |
| 856 | .Xt = .{ .reg = .{ .format = .{ .integer = .doubleword } } }, | 856 | .Xt = .{ .reg = .{ .format = .{ .integer = .doubleword } } }, |
| 857 | .systemreg = .systemreg, | ||
| 857 | }, | 858 | }, |
| 858 | .encode = .{ .mrs, .Xt, 0b11, 0b011, 0b0000, 0b0000, 0b001 }, | 859 | .encode = .{ .mrs, .Xt, .systemreg }, |
| 860 | }, | ||
| 861 | // C6.2.230 MSR (register) | ||
| 862 | .{ | ||
| 863 | .pattern = "MSR <systemreg>, <Xt>", | ||
| 864 | .symbols = .{ | ||
| 865 | .systemreg = .systemreg, | ||
| 866 | .Xt = .{ .reg = .{ .format = .{ .integer = .doubleword } } }, | ||
| 867 | }, | ||
| 868 | .encode = .{ .msr, .systemreg, .Xt }, | ||
| 859 | }, | 869 | }, |
| 860 | // C6.2.234 NEG | 870 | // C6.2.234 NEG |
| 861 | .{ | 871 | .{ |
src/main.zig+92-54| ... | @@ -4648,14 +4648,14 @@ const usage_init = | ... | @@ -4648,14 +4648,14 @@ const usage_init = |
| 4648 | fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | 4648 | fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 4649 | dev.check(.init_command); | 4649 | dev.check(.init_command); |
| 4650 | 4650 | ||
| 4651 | var strip = false; | 4651 | var template: enum { example, minimal } = .example; |
| 4652 | { | 4652 | { |
| 4653 | var i: usize = 0; | 4653 | var i: usize = 0; |
| 4654 | while (i < args.len) : (i += 1) { | 4654 | while (i < args.len) : (i += 1) { |
| 4655 | const arg = args[i]; | 4655 | const arg = args[i]; |
| 4656 | if (mem.startsWith(u8, arg, "-")) { | 4656 | if (mem.startsWith(u8, arg, "-")) { |
| 4657 | if (mem.eql(u8, arg, "-s") or mem.eql(u8, arg, "--strip")) { | 4657 | if (mem.eql(u8, arg, "-m") or mem.eql(u8, arg, "--minimal")) { |
| 4658 | strip = true; | 4658 | template = .minimal; |
| 4659 | } else if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { | 4659 | } else if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { |
| 4660 | try fs.File.stdout().writeAll(usage_init); | 4660 | try fs.File.stdout().writeAll(usage_init); |
| 4661 | return cleanExit(); | 4661 | return cleanExit(); |
| ... | @@ -4668,40 +4668,79 @@ fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -4668,40 +4668,79 @@ fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 4668 | } | 4668 | } |
| 4669 | } | 4669 | } |
| 4670 | 4670 | ||
| 4671 | var templates = findTemplates(gpa, arena, strip); | ||
| 4672 | defer templates.deinit(); | ||
| 4673 | |||
| 4674 | const cwd_path = try introspect.getResolvedCwd(arena); | 4671 | const cwd_path = try introspect.getResolvedCwd(arena); |
| 4675 | const cwd_basename = fs.path.basename(cwd_path); | 4672 | const cwd_basename = fs.path.basename(cwd_path); |
| 4676 | const sanitized_root_name = try sanitizeExampleName(arena, cwd_basename); | 4673 | const sanitized_root_name = try sanitizeExampleName(arena, cwd_basename); |
| 4677 | 4674 | ||
| 4678 | const s = fs.path.sep_str; | ||
| 4679 | const template_paths = [_][]const u8{ | ||
| 4680 | Package.build_zig_basename, | ||
| 4681 | Package.Manifest.basename, | ||
| 4682 | "src" ++ s ++ "main.zig", | ||
| 4683 | "src" ++ s ++ "root.zig", | ||
| 4684 | }; | ||
| 4685 | var ok_count: usize = 0; | ||
| 4686 | |||
| 4687 | const fingerprint: Package.Fingerprint = .generate(sanitized_root_name); | 4675 | const fingerprint: Package.Fingerprint = .generate(sanitized_root_name); |
| 4688 | 4676 | ||
| 4689 | for (template_paths) |template_path| { | 4677 | switch (template) { |
| 4690 | if (templates.write(arena, fs.cwd(), sanitized_root_name, template_path, fingerprint)) |_| { | 4678 | .example => { |
| 4691 | std.log.info("created {s}", .{template_path}); | 4679 | var templates = findTemplates(gpa, arena); |
| 4692 | ok_count += 1; | 4680 | defer templates.deinit(); |
| 4693 | } else |err| switch (err) { | 4681 | |
| 4694 | error.PathAlreadyExists => std.log.info("preserving already existing file: {s}", .{ | 4682 | const s = fs.path.sep_str; |
| 4695 | template_path, | 4683 | const template_paths = [_][]const u8{ |
| 4696 | }), | 4684 | Package.build_zig_basename, |
| 4697 | else => std.log.err("unable to write {s}: {s}\n", .{ template_path, @errorName(err) }), | 4685 | Package.Manifest.basename, |
| 4698 | } | 4686 | "src" ++ s ++ "main.zig", |
| 4699 | } | 4687 | "src" ++ s ++ "root.zig", |
| 4688 | }; | ||
| 4689 | var ok_count: usize = 0; | ||
| 4690 | |||
| 4691 | for (template_paths) |template_path| { | ||
| 4692 | if (templates.write(arena, fs.cwd(), sanitized_root_name, template_path, fingerprint)) |_| { | ||
| 4693 | std.log.info("created {s}", .{template_path}); | ||
| 4694 | ok_count += 1; | ||
| 4695 | } else |err| switch (err) { | ||
| 4696 | error.PathAlreadyExists => std.log.info("preserving already existing file: {s}", .{ | ||
| 4697 | template_path, | ||
| 4698 | }), | ||
| 4699 | else => std.log.err("unable to write {s}: {s}\n", .{ template_path, @errorName(err) }), | ||
| 4700 | } | ||
| 4701 | } | ||
| 4700 | 4702 | ||
| 4701 | if (ok_count == template_paths.len) { | 4703 | if (ok_count == template_paths.len) { |
| 4702 | std.log.info("see `zig build --help` for a menu of options", .{}); | 4704 | std.log.info("see `zig build --help` for a menu of options", .{}); |
| 4705 | } | ||
| 4706 | return cleanExit(); | ||
| 4707 | }, | ||
| 4708 | .minimal => { | ||
| 4709 | writeSimpleTemplateFile(Package.Manifest.basename, | ||
| 4710 | \\.{{ | ||
| 4711 | \\ .name = .{s}, | ||
| 4712 | \\ .version = "{s}", | ||
| 4713 | \\ .paths = .{{""}}, | ||
| 4714 | \\ .fingerprint = 0x{x}, | ||
| 4715 | \\}} | ||
| 4716 | \\ | ||
| 4717 | , .{ | ||
| 4718 | sanitized_root_name, | ||
| 4719 | build_options.version, | ||
| 4720 | fingerprint.int(), | ||
| 4721 | }) catch |err| switch (err) { | ||
| 4722 | else => fatal("failed to create '{s}': {s}", .{ Package.Manifest.basename, @errorName(err) }), | ||
| 4723 | error.PathAlreadyExists => fatal("refusing to overwrite '{s}'", .{Package.Manifest.basename}), | ||
| 4724 | }; | ||
| 4725 | writeSimpleTemplateFile(Package.build_zig_basename, | ||
| 4726 | \\const std = @import("std"); | ||
| 4727 | \\pub fn build(b: *std.Build) void {{ | ||
| 4728 | \\ _ = b; // stub | ||
| 4729 | \\}} | ||
| 4730 | \\ | ||
| 4731 | , .{}) catch |err| switch (err) { | ||
| 4732 | else => fatal("failed to create '{s}': {s}", .{ Package.build_zig_basename, @errorName(err) }), | ||
| 4733 | // `build.zig` already existing is okay: the user has just used `zig init` to set up | ||
| 4734 | // their `build.zig.zon` *after* writing their `build.zig`. So this one isn't fatal. | ||
| 4735 | error.PathAlreadyExists => { | ||
| 4736 | std.log.info("successfully populated '{s}', preserving existing '{s}'", .{ Package.Manifest.basename, Package.build_zig_basename }); | ||
| 4737 | return cleanExit(); | ||
| 4738 | }, | ||
| 4739 | }; | ||
| 4740 | std.log.info("successfully populated '{s}' and '{s}'", .{ Package.Manifest.basename, Package.build_zig_basename }); | ||
| 4741 | return cleanExit(); | ||
| 4742 | }, | ||
| 4703 | } | 4743 | } |
| 4704 | return cleanExit(); | ||
| 4705 | } | 4744 | } |
| 4706 | 4745 | ||
| 4707 | fn sanitizeExampleName(arena: Allocator, bytes: []const u8) error{OutOfMemory}![]const u8 { | 4746 | fn sanitizeExampleName(arena: Allocator, bytes: []const u8) error{OutOfMemory}![]const u8 { |
| ... | @@ -7229,13 +7268,20 @@ fn loadManifest( | ... | @@ -7229,13 +7268,20 @@ fn loadManifest( |
| 7229 | 0, | 7268 | 0, |
| 7230 | ) catch |err| switch (err) { | 7269 | ) catch |err| switch (err) { |
| 7231 | error.FileNotFound => { | 7270 | error.FileNotFound => { |
| 7232 | const fingerprint: Package.Fingerprint = .generate(options.root_name); | 7271 | writeSimpleTemplateFile(Package.Manifest.basename, |
| 7233 | var templates = findTemplates(gpa, arena, true); | 7272 | \\.{{ |
| 7234 | defer templates.deinit(); | 7273 | \\ .name = .{s}, |
| 7235 | templates.write(arena, options.dir, options.root_name, Package.Manifest.basename, fingerprint) catch |e| { | 7274 | \\ .version = "{s}", |
| 7236 | fatal("unable to write {s}: {s}", .{ | 7275 | \\ .paths = .{{""}}, |
| 7237 | Package.Manifest.basename, @errorName(e), | 7276 | \\ .fingerprint = 0x{x}, |
| 7238 | }); | 7277 | \\}} |
| 7278 | \\ | ||
| 7279 | , .{ | ||
| 7280 | options.root_name, | ||
| 7281 | build_options.version, | ||
| 7282 | Package.Fingerprint.generate(options.root_name).int(), | ||
| 7283 | }) catch |e| { | ||
| 7284 | fatal("unable to write {s}: {s}", .{ Package.Manifest.basename, @errorName(e) }); | ||
| 7239 | }; | 7285 | }; |
| 7240 | continue; | 7286 | continue; |
| 7241 | }, | 7287 | }, |
| ... | @@ -7276,7 +7322,6 @@ const Templates = struct { | ... | @@ -7276,7 +7322,6 @@ const Templates = struct { |
| 7276 | zig_lib_directory: Cache.Directory, | 7322 | zig_lib_directory: Cache.Directory, |
| 7277 | dir: fs.Dir, | 7323 | dir: fs.Dir, |
| 7278 | buffer: std.ArrayList(u8), | 7324 | buffer: std.ArrayList(u8), |
| 7279 | strip: bool, | ||
| 7280 | 7325 | ||
| 7281 | fn deinit(templates: *Templates) void { | 7326 | fn deinit(templates: *Templates) void { |
| 7282 | templates.zig_lib_directory.handle.close(); | 7327 | templates.zig_lib_directory.handle.close(); |
| ... | @@ -7305,23 +7350,9 @@ const Templates = struct { | ... | @@ -7305,23 +7350,9 @@ const Templates = struct { |
| 7305 | }; | 7350 | }; |
| 7306 | templates.buffer.clearRetainingCapacity(); | 7351 | templates.buffer.clearRetainingCapacity(); |
| 7307 | try templates.buffer.ensureUnusedCapacity(contents.len); | 7352 | try templates.buffer.ensureUnusedCapacity(contents.len); |
| 7308 | var new_line = templates.strip; | ||
| 7309 | var i: usize = 0; | 7353 | var i: usize = 0; |
| 7310 | while (i < contents.len) { | 7354 | while (i < contents.len) { |
| 7311 | if (new_line) { | 7355 | if (contents[i] == '_' or contents[i] == '.') { |
| 7312 | const trimmed = std.mem.trimLeft(u8, contents[i..], " "); | ||
| 7313 | if (std.mem.startsWith(u8, trimmed, "//")) { | ||
| 7314 | i += std.mem.indexOfScalar(u8, contents[i..], '\n') orelse break; | ||
| 7315 | i += 1; | ||
| 7316 | continue; | ||
| 7317 | } else { | ||
| 7318 | new_line = false; | ||
| 7319 | } | ||
| 7320 | } | ||
| 7321 | |||
| 7322 | if (templates.strip and contents[i] == '\n') { | ||
| 7323 | new_line = true; | ||
| 7324 | } else if (contents[i] == '_' or contents[i] == '.') { | ||
| 7325 | // Both '_' and '.' are allowed because depending on the context | 7356 | // Both '_' and '.' are allowed because depending on the context |
| 7326 | // one prefix will be valid, while the other might not. | 7357 | // one prefix will be valid, while the other might not. |
| 7327 | if (std.mem.startsWith(u8, contents[i + 1 ..], "NAME")) { | 7358 | if (std.mem.startsWith(u8, contents[i + 1 ..], "NAME")) { |
| ... | @@ -7350,8 +7381,16 @@ const Templates = struct { | ... | @@ -7350,8 +7381,16 @@ const Templates = struct { |
| 7350 | }); | 7381 | }); |
| 7351 | } | 7382 | } |
| 7352 | }; | 7383 | }; |
| 7384 | fn writeSimpleTemplateFile(file_name: []const u8, comptime fmt: []const u8, args: anytype) !void { | ||
| 7385 | const f = try fs.cwd().createFile(file_name, .{ .exclusive = true }); | ||
| 7386 | defer f.close(); | ||
| 7387 | var buf: [4096]u8 = undefined; | ||
| 7388 | var fw = f.writer(&buf); | ||
| 7389 | try fw.interface.print(fmt, args); | ||
| 7390 | try fw.interface.flush(); | ||
| 7391 | } | ||
| 7353 | 7392 | ||
| 7354 | fn findTemplates(gpa: Allocator, arena: Allocator, strip: bool) Templates { | 7393 | fn findTemplates(gpa: Allocator, arena: Allocator) Templates { |
| 7355 | const cwd_path = introspect.getResolvedCwd(arena) catch |err| { | 7394 | const cwd_path = introspect.getResolvedCwd(arena) catch |err| { |
| 7356 | fatal("unable to get cwd: {s}", .{@errorName(err)}); | 7395 | fatal("unable to get cwd: {s}", .{@errorName(err)}); |
| 7357 | }; | 7396 | }; |
| ... | @@ -7375,7 +7414,6 @@ fn findTemplates(gpa: Allocator, arena: Allocator, strip: bool) Templates { | ... | @@ -7375,7 +7414,6 @@ fn findTemplates(gpa: Allocator, arena: Allocator, strip: bool) Templates { |
| 7375 | .zig_lib_directory = zig_lib_directory, | 7414 | .zig_lib_directory = zig_lib_directory, |
| 7376 | .dir = template_dir, | 7415 | .dir = template_dir, |
| 7377 | .buffer = std.ArrayList(u8).init(gpa), | 7416 | .buffer = std.ArrayList(u8).init(gpa), |
| 7378 | .strip = strip, | ||
| 7379 | }; | 7417 | }; |
| 7380 | } | 7418 | } |
| 7381 | 7419 |
stage1/wasm2c.c+1-1| ... | @@ -316,10 +316,10 @@ int main(int argc, char **argv) { | ... | @@ -316,10 +316,10 @@ int main(int argc, char **argv) { |
| 316 | "}\n" | 316 | "}\n" |
| 317 | "\n" | 317 | "\n" |
| 318 | "static uint32_t memory_grow(uint8_t **m, uint32_t *p, uint32_t *c, uint32_t n) {\n" | 318 | "static uint32_t memory_grow(uint8_t **m, uint32_t *p, uint32_t *c, uint32_t n) {\n" |
| 319 | " uint8_t *new_m = *m;\n" | ||
| 320 | " uint32_t r = *p;\n" | 319 | " uint32_t r = *p;\n" |
| 321 | " uint32_t new_p = r + n;\n" | 320 | " uint32_t new_p = r + n;\n" |
| 322 | " if (new_p > UINT32_C(0xFFFF)) return UINT32_C(0xFFFFFFFF);\n" | 321 | " if (new_p > UINT32_C(0xFFFF)) return UINT32_C(0xFFFFFFFF);\n" |
| 322 | " uint8_t *new_m = *m;\n" | ||
| 323 | " uint32_t new_c = *c;\n" | 323 | " uint32_t new_c = *c;\n" |
| 324 | " if (new_c < new_p) {\n" | 324 | " if (new_c < new_p) {\n" |
| 325 | " do new_c += new_c / 2 + 8; while (new_c < new_p);\n" | 325 | " do new_c += new_c / 2 + 8; while (new_c < new_p);\n" |
test/behavior/basic.zig-3| ... | @@ -471,7 +471,6 @@ fn testPointerToVoidReturnType2() *const void { | ... | @@ -471,7 +471,6 @@ fn testPointerToVoidReturnType2() *const void { |
| 471 | } | 471 | } |
| 472 | 472 | ||
| 473 | test "array 2D const double ptr" { | 473 | test "array 2D const double ptr" { |
| 474 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | ||
| 475 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 474 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 476 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 475 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 477 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 476 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| ... | @@ -484,7 +483,6 @@ test "array 2D const double ptr" { | ... | @@ -484,7 +483,6 @@ test "array 2D const double ptr" { |
| 484 | } | 483 | } |
| 485 | 484 | ||
| 486 | test "array 2D const double ptr with offset" { | 485 | test "array 2D const double ptr with offset" { |
| 487 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | ||
| 488 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 486 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 489 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 487 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 490 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 488 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| ... | @@ -497,7 +495,6 @@ test "array 2D const double ptr with offset" { | ... | @@ -497,7 +495,6 @@ test "array 2D const double ptr with offset" { |
| 497 | } | 495 | } |
| 498 | 496 | ||
| 499 | test "array 3D const double ptr with offset" { | 497 | test "array 3D const double ptr with offset" { |
| 500 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | ||
| 501 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 498 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 502 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 499 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 503 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 500 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
test/behavior/cast.zig-1| ... | @@ -1816,7 +1816,6 @@ test "peer type resolution: C pointer and @TypeOf(null)" { | ... | @@ -1816,7 +1816,6 @@ test "peer type resolution: C pointer and @TypeOf(null)" { |
| 1816 | } | 1816 | } |
| 1817 | 1817 | ||
| 1818 | test "peer type resolution: three-way resolution combines error set and optional" { | 1818 | test "peer type resolution: three-way resolution combines error set and optional" { |
| 1819 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | ||
| 1820 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1819 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1821 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1820 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1822 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 1821 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
test/behavior/pointers.zig-1| ... | @@ -436,7 +436,6 @@ test "pointer sentinel with optional element" { | ... | @@ -436,7 +436,6 @@ test "pointer sentinel with optional element" { |
| 436 | } | 436 | } |
| 437 | 437 | ||
| 438 | test "pointer sentinel with +inf" { | 438 | test "pointer sentinel with +inf" { |
| 439 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | ||
| 440 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 439 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 441 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 440 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 442 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 441 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
test/tests.zig+10| ... | @@ -2016,6 +2016,16 @@ pub fn addCliTests(b: *std.Build) *Step { | ... | @@ -2016,6 +2016,16 @@ pub fn addCliTests(b: *std.Build) *Step { |
| 2016 | step.dependOn(&cleanup.step); | 2016 | step.dependOn(&cleanup.step); |
| 2017 | } | 2017 | } |
| 2018 | 2018 | ||
| 2019 | { | ||
| 2020 | // Test `zig init -m`. | ||
| 2021 | const tmp_path = b.makeTempPath(); | ||
| 2022 | const init_exe = b.addSystemCommand(&.{ b.graph.zig_exe, "init", "-m" }); | ||
| 2023 | init_exe.setCwd(.{ .cwd_relative = tmp_path }); | ||
| 2024 | init_exe.setName("zig init -m"); | ||
| 2025 | init_exe.expectStdOutEqual(""); | ||
| 2026 | init_exe.expectStdErrEqual("info: successfully populated 'build.zig.zon' and 'build.zig'\n"); | ||
| 2027 | } | ||
| 2028 | |||
| 2019 | // Test Godbolt API | 2029 | // Test Godbolt API |
| 2020 | if (builtin.os.tag == .linux and builtin.cpu.arch == .x86_64) { | 2030 | if (builtin.os.tag == .linux and builtin.cpu.arch == .x86_64) { |
| 2021 | const tmp_path = b.makeTempPath(); | 2031 | const tmp_path = b.makeTempPath(); |