authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-25 18:15:24-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-25 18:15:24-07:00
log45a35d448e85351756fe18e901748c4446a1b56a
tree21d079e9d889054e1697f0f18c18021aa08c5c37
parent8c4482ed78fb651c0288f0cd2bdaf328564c6a49
parent733b2082565a86daac6f2b22a1a27f0b60621b4e

Merge remote-tracking branch 'origin/zstd' into wrangle-writer-buffering


24 files changed, 1062 insertions(+), 489 deletions(-)

lib/compiler/std-docs.zig+3-2
......@@ -348,8 +348,9 @@ fn buildWasmBinary(
348348 };
349349 }
350350
351 if (poller.reader(.stderr).buffer.len > 0) {
352 std.debug.print("{s}", .{poller.reader(.stderr).buffered()});
351 const stderr = poller.reader(.stderr);
352 if (stderr.bufferedLen() > 0) {
353 std.debug.print("{s}", .{stderr.buffered()});
353354 }
354355
355356 // Send EOF to stdin.
lib/init/build.zig-1
......@@ -1,4 +1,3 @@
1//! Use `zig init --strip` next time to generate a project without comments.
21const std = @import("std");
32
43// 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 {
373373}
374374
375375/// Helper for bridging to the new `Reader` API while upgrading.
376pub fn adaptToNewApi(self: *const Self) Adapter {
376pub fn adaptToNewApi(self: *const Self, buffer: []u8) Adapter {
377377 return .{
378378 .derp_reader = self.*,
379379 .new_interface = .{
380 .buffer = &.{},
380 .buffer = buffer,
381381 .vtable = &.{ .stream = Adapter.stream },
382382 .seek = 0,
383383 .end = 0,
lib/std/Io/Reader.zig+28-2
......@@ -185,6 +185,32 @@ pub fn streamExact64(r: *Reader, w: *Writer, n: u64) StreamError!void {
185185 while (remaining != 0) remaining -= try r.stream(w, .limited64(remaining));
186186}
187187
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`.
194pub 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
188214/// "Pump" data from the reader to the writer, handling `error.EndOfStream` as
189215/// a success case.
190216///
......@@ -240,7 +266,7 @@ pub fn allocRemaining(r: *Reader, gpa: Allocator, limit: Limit) LimitedAllocErro
240266/// such case, the next byte that would be read will be the first one to exceed
241267/// `limit`, and all preceeding bytes have been appended to `list`.
242268///
243/// Asserts `buffer` has nonzero capacity.
269/// If `limit` is not `Limit.unlimited`, asserts `buffer` has nonzero capacity.
244270///
245271/// See also:
246272/// * `allocRemaining`
......@@ -251,7 +277,7 @@ pub fn appendRemaining(
251277 list: *std.ArrayListAlignedUnmanaged(u8, alignment),
252278 limit: Limit,
253279) 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.
255281 const buffer_contents = r.buffer[r.seek..r.end];
256282 const copy_len = limit.minInt(buffer_contents.len);
257283 try list.appendSlice(gpa, r.buffer[0..copy_len]);
lib/std/Io/Writer.zig+70-23
......@@ -256,10 +256,10 @@ test "fixed buffer flush" {
256256 try testing.expectEqual(10, buffer[0]);
257257}
258258
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
260260/// implementation, keeping them buffered.
261pub fn drainPreserve(w: *Writer, preserve_length: usize) Error!void {
262 const temp_end = w.end -| preserve_length;
261pub fn drainPreserve(w: *Writer, preserve_len: usize) Error!void {
262 const temp_end = w.end -| preserve_len;
263263 const preserved = w.buffer[temp_end..w.end];
264264 w.end = temp_end;
265265 defer w.end += preserved.len;
......@@ -310,24 +310,38 @@ pub fn writableSliceGreedy(w: *Writer, minimum_length: usize) Error![]u8 {
310310}
311311
312312/// Asserts the provided buffer has total capacity enough for `minimum_length`
313/// and `preserve_length` combined.
313/// and `preserve_len` combined.
314314///
315315/// Does not `advance` the buffer end position.
316316///
317/// When draining the buffer, ensures that at least `preserve_length` bytes
317/// When draining the buffer, ensures that at least `preserve_len` bytes
318318/// remain buffered.
319319///
320/// If `preserve_length` is zero, this is equivalent to `writableSliceGreedy`.
321pub fn writableSliceGreedyPreserve(w: *Writer, preserve_length: usize, minimum_length: usize) Error![]u8 {
322 assert(w.buffer.len >= preserve_length + minimum_length);
320/// If `preserve_len` is zero, this is equivalent to `writableSliceGreedy`.
321pub fn writableSliceGreedyPreserve(w: *Writer, preserve_len: usize, minimum_length: usize) Error![]u8 {
322 assert(w.buffer.len >= preserve_len + minimum_length);
323323 while (w.buffer.len - w.end < minimum_length) {
324 try drainPreserve(w, preserve_length);
324 try drainPreserve(w, preserve_len);
325325 } else {
326326 @branchHint(.likely);
327327 return w.buffer[w.end..];
328328 }
329329}
330330
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`.
339pub 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
331345pub const WritableVectorIterator = struct {
332346 first: []u8,
333347 middle: []const []u8 = &.{},
......@@ -523,16 +537,16 @@ pub fn write(w: *Writer, bytes: []const u8) Error!usize {
523537 return w.vtable.drain(w, &.{bytes}, 1);
524538}
525539
526/// Asserts `buffer` capacity exceeds `preserve_length`.
527pub fn writePreserve(w: *Writer, preserve_length: usize, bytes: []const u8) Error!usize {
528 assert(preserve_length <= w.buffer.len);
540/// Asserts `buffer` capacity exceeds `preserve_len`.
541pub fn writePreserve(w: *Writer, preserve_len: usize, bytes: []const u8) Error!usize {
542 assert(preserve_len <= w.buffer.len);
529543 if (w.end + bytes.len <= w.buffer.len) {
530544 @branchHint(.likely);
531545 @memcpy(w.buffer[w.end..][0..bytes.len], bytes);
532546 w.end += bytes.len;
533547 return bytes.len;
534548 }
535 const temp_end = w.end -| preserve_length;
549 const temp_end = w.end -| preserve_len;
536550 const preserved = w.buffer[temp_end..w.end];
537551 w.end = temp_end;
538552 defer w.end += preserved.len;
......@@ -552,13 +566,13 @@ pub fn writeAll(w: *Writer, bytes: []const u8) Error!void {
552566/// Calls `drain` as many times as necessary such that all of `bytes` are
553567/// transferred.
554568///
555/// When draining the buffer, ensures that at least `preserve_length` bytes
569/// When draining the buffer, ensures that at least `preserve_len` bytes
556570/// remain buffered.
557571///
558/// Asserts `buffer` capacity exceeds `preserve_length`.
559pub fn writeAllPreserve(w: *Writer, preserve_length: usize, bytes: []const u8) Error!void {
572/// Asserts `buffer` capacity exceeds `preserve_len`.
573pub fn writeAllPreserve(w: *Writer, preserve_len: usize, bytes: []const u8) Error!void {
560574 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..]);
562576}
563577
564578/// Renders fmt string with args, calling `writer` with slices of bytes.
......@@ -761,11 +775,11 @@ pub fn writeByte(w: *Writer, byte: u8) Error!void {
761775 }
762776}
763777
764/// When draining the buffer, ensures that at least `preserve_length` bytes
778/// When draining the buffer, ensures that at least `preserve_len` bytes
765779/// remain buffered.
766pub fn writeBytePreserve(w: *Writer, preserve_length: usize, byte: u8) Error!void {
780pub fn writeBytePreserve(w: *Writer, preserve_len: usize, byte: u8) Error!void {
767781 while (w.buffer.len - w.end == 0) {
768 try drainPreserve(w, preserve_length);
782 try drainPreserve(w, preserve_len);
769783 } else {
770784 @branchHint(.likely);
771785 w.buffer[w.end] = byte;
......@@ -788,10 +802,42 @@ test splatByteAll {
788802 try testing.expectEqualStrings("7" ** 45, aw.writer.buffered());
789803}
790804
805pub 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
791831/// Writes the same byte many times, allowing short writes.
792832///
793833/// Does maximum of one underlying `VTable.drain`.
794834pub 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 }
795841 return writeSplat(w, &.{&.{byte}}, n);
796842}
797843
......@@ -801,9 +847,10 @@ pub fn splatBytesAll(w: *Writer, bytes: []const u8, splat: usize) Error!void {
801847 var remaining_bytes: usize = bytes.len * splat;
802848 remaining_bytes -= try w.splatBytes(bytes, splat);
803849 while (remaining_bytes > 0) {
804 const leftover = remaining_bytes % bytes.len;
805 const buffers: [2][]const u8 = .{ bytes[bytes.len - leftover ..], bytes };
806 remaining_bytes -= try w.writeSplat(&buffers, splat);
850 const leftover_splat = remaining_bytes / bytes.len;
851 const leftover_bytes = remaining_bytes % bytes.len;
852 const buffers: [2][]const u8 = .{ bytes[bytes.len - leftover_bytes ..], bytes };
853 remaining_bytes -= try w.writeSplat(&buffers, leftover_splat);
807854 }
808855}
809856
lib/std/compress/xz.zig+30-3
......@@ -47,7 +47,7 @@ pub fn Decompress(comptime ReaderType: type) type {
4747
4848 var check: Check = undefined;
4949 const hash_a = blk: {
50 var hasher = std.compress.hashedReader(source, Crc32.init());
50 var hasher = hashedReader(source, Crc32.init());
5151 try readStreamFlags(hasher.reader(), &check);
5252 break :blk hasher.hasher.final();
5353 };
......@@ -80,7 +80,7 @@ pub fn Decompress(comptime ReaderType: type) type {
8080 return r;
8181
8282 const index_size = blk: {
83 var hasher = std.compress.hashedReader(self.in_reader, Crc32.init());
83 var hasher = hashedReader(self.in_reader, Crc32.init());
8484 hasher.hasher.update(&[1]u8{0x00});
8585
8686 var counter = std.io.countingReader(hasher.reader());
......@@ -115,7 +115,7 @@ pub fn Decompress(comptime ReaderType: type) type {
115115 const hash_a = try self.in_reader.readInt(u32, .little);
116116
117117 const hash_b = blk: {
118 var hasher = std.compress.hashedReader(self.in_reader, Crc32.init());
118 var hasher = hashedReader(self.in_reader, Crc32.init());
119119 const hashed_reader = hasher.reader();
120120
121121 const backward_size = (@as(u64, try hashed_reader.readInt(u32, .little)) + 1) * 4;
......@@ -140,6 +140,33 @@ pub fn Decompress(comptime ReaderType: type) type {
140140 };
141141}
142142
143pub 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
163pub fn hashedReader(
164 reader: anytype,
165 hasher: anytype,
166) HashedReader(@TypeOf(reader), @TypeOf(hasher)) {
167 return .{ .child_reader = reader, .hasher = hasher };
168}
169
143170test {
144171 _ = @import("xz/test.zig");
145172}
lib/std/compress/xz/block.zig+1-1
......@@ -91,7 +91,7 @@ pub fn Decoder(comptime ReaderType: type) type {
9191
9292 // Block Header
9393 {
94 var header_hasher = std.compress.hashedReader(block_reader, Crc32.init());
94 var header_hasher = xz.hashedReader(block_reader, Crc32.init());
9595 const header_reader = header_hasher.reader();
9696
9797 const header_size = @as(u64, try header_reader.readByte()) * 4;
lib/std/compress/zstd.zig+4-5
......@@ -1,12 +1,11 @@
11const std = @import("../std.zig");
22const assert = std.debug.assert;
33
4pub const Decompress = @import("zstd/Decompress.zig");
5
46/// Recommended amount by the standard. Lower than this may result in inability
57/// to decompress common streams.
68pub const default_window_len = 8 * 1024 * 1024;
7
8pub const Decompress = @import("zstd/Decompress.zig");
9
109pub const block_size_max = 1 << 17;
1110
1211pub const literals_length_default_distribution = [36]i16{
......@@ -85,7 +84,7 @@ fn testDecompress(gpa: std.mem.Allocator, compressed: []const u8) ![]u8 {
8584
8685 var in: std.io.Reader = .fixed(compressed);
8786 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);
8988
9089 return out.toOwnedSlice(gpa);
9190}
......@@ -108,7 +107,7 @@ fn testExpectDecompressError(err: anyerror, compressed: []const u8) !void {
108107 var zstd_stream: Decompress = .init(&in, &.{}, .{});
109108 try std.testing.expectError(
110109 error.ReadFailed,
111 zstd_stream.interface.appendRemaining(gpa, null, &out, .unlimited),
110 zstd_stream.reader.appendRemaining(gpa, null, &out, .unlimited),
112111 );
113112 try std.testing.expectError(err, zstd_stream.err orelse {});
114113}
lib/std/compress/zstd/Decompress.zig+69-68
......@@ -10,6 +10,7 @@ input: *Reader,
1010reader: Reader,
1111state: State,
1212verify_checksum: bool,
13window_len: u32,
1314err: ?Error = null,
1415
1516const State = union(enum) {
......@@ -22,11 +23,16 @@ const State = union(enum) {
2223 frame: Frame,
2324 checksum: ?u32,
2425 decompressed_size: usize,
26 decode: Frame.Zstandard.Decode,
2527 };
2628};
2729
2830pub 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,
3036};
3137
3238pub const Error = error{
......@@ -63,11 +69,14 @@ pub const Error = error{
6369 WindowSizeUnknown,
6470};
6571
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`.
6674pub fn init(input: *Reader, buffer: []u8, options: Options) Decompress {
6775 return .{
6876 .input = input,
6977 .state = .new_frame,
7078 .verify_checksum = options.verify_checksum,
79 .window_len = options.window_len,
7180 .reader = .{
7281 .vtable = &.{ .stream = stream },
7382 .buffer = buffer,
......@@ -130,6 +139,7 @@ fn initFrame(d: *Decompress, window_size_max: usize, magic: Frame.Magic) !void {
130139 .frame = try Frame.init(header, window_size_max, d.verify_checksum),
131140 .checksum = null,
132141 .decompressed_size = 0,
142 .decode = .init,
133143 } };
134144 },
135145 .skippable => {
......@@ -139,11 +149,11 @@ fn initFrame(d: *Decompress, window_size_max: usize, magic: Frame.Magic) !void {
139149 }
140150}
141151
142fn readInFrame(d: *Decompress, bw: *Writer, limit: Limit, state: *State.InFrame) !usize {
152fn readInFrame(d: *Decompress, w: *Writer, limit: Limit, state: *State.InFrame) !usize {
143153 const in = d.input;
154 const window_len = d.window_len;
144155
145 const header_bytes = try in.takeArray(3);
146 const block_header: Frame.Zstandard.Block.Header = @bitCast(header_bytes.*);
156 const block_header = try in.takeStruct(Frame.Zstandard.Block.Header, .little);
147157 const block_size = block_header.size;
148158 const frame_block_size_max = state.frame.block_size_max;
149159 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)
151161 var bytes_written: usize = 0;
152162 switch (block_header.type) {
153163 .raw => {
154 try in.readAll(bw, .limited(block_size));
164 try in.streamExactPreserve(w, window_len, block_size);
155165 bytes_written = block_size;
156166 },
157167 .rle => {
158168 const byte = try in.takeByte();
159 try bw.splatByteAll(byte, block_size);
169 try w.splatBytePreserve(window_len, byte, block_size);
160170 bytes_written = block_size;
161171 },
162172 .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;
166173 var literals_buffer: [zstd.block_size_max]u8 = undefined;
167174 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);
169175 var remaining: Limit = .limited(block_size);
170176 const literals = try LiteralsSection.decode(in, &remaining, &literals_buffer);
171177 const sequences_header = try SequencesSection.Header.decode(in, &remaining);
172178
179 const decode = &state.decode;
173180 try decode.prepare(in, &remaining, literals, sequences_header);
174181
175182 {
176183 if (sequence_buffer.len < @intFromEnum(remaining))
177184 return error.SequenceBufferUndersize;
178185 const seq_slice = remaining.slice(&sequence_buffer);
179 try in.readSlice(seq_slice);
186 try in.readSliceAll(seq_slice);
180187 var bit_stream = try ReverseBitReader.init(seq_slice);
181188
182189 if (sequences_header.sequence_count > 0) {
183190 try decode.readInitialFseState(&bit_stream);
184191
185192 // Ensures the following calls to `decodeSequence` will not flush.
186 if (frame_block_size_max > bw.buffer.len) return error.OutputBufferUndersize;
187 const dest = (try bw.writableSliceGreedy(frame_block_size_max))[0..frame_block_size_max];
193 if (window_len + frame_block_size_max > w.buffer.len) return error.OutputBufferUndersize;
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;
188196 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);
190198 try decode.updateState(.literal, &bit_stream);
191199 try decode.updateState(.match, &bit_stream);
192200 try decode.updateState(.offset, &bit_stream);
193201 }
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);
195203 if (bytes_written > dest.len) return error.MalformedSequence;
196 bw.advance(bytes_written);
204 w.advance(bytes_written);
197205 }
198206
199207 if (!bit_stream.isEmpty()) {
......@@ -203,7 +211,7 @@ fn readInFrame(d: *Decompress, bw: *Writer, limit: Limit, state: *State.InFrame)
203211
204212 if (decode.literal_written_count < literals.header.regenerated_size) {
205213 const len = literals.header.regenerated_size - decode.literal_written_count;
206 try decode.decodeLiterals(bw, len);
214 try decode.decodeLiterals(w, len);
207215 decode.literal_written_count += len;
208216 bytes_written += len;
209217 }
......@@ -216,11 +224,6 @@ fn readInFrame(d: *Decompress, bw: *Writer, limit: Limit, state: *State.InFrame)
216224 }
217225
218226 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 }
224227 },
225228 .reserved => return error.ReservedBlock,
226229 }
......@@ -232,6 +235,8 @@ fn readInFrame(d: *Decompress, bw: *Writer, limit: Limit, state: *State.InFrame)
232235 }
233236 }
234237
238 state.decompressed_size += bytes_written;
239
235240 if (block_header.last) {
236241 if (state.frame.has_checksum) {
237242 const expected_checksum = try in.takeInt(u32, .little);
......@@ -246,6 +251,8 @@ fn readInFrame(d: *Decompress, bw: *Writer, limit: Limit, state: *State.InFrame)
246251 }
247252 }
248253 d.state = .new_frame;
254 } else if (state.frame.content_size) |content_size| {
255 if (state.decompressed_size > content_size) return error.MalformedFrame;
249256 }
250257
251258 return bytes_written;
......@@ -367,9 +374,9 @@ pub const Frame = struct {
367374 match: StateData(9),
368375 literal: StateData(9),
369376
370 offset_fse_buffer: []Table.Fse,
371 match_fse_buffer: []Table.Fse,
372 literal_fse_buffer: []Table.Fse,
377 literal_fse_buffer: [zstd.table_size_max.literal]Table.Fse,
378 match_fse_buffer: [zstd.table_size_max.match]Table.Fse,
379 offset_fse_buffer: [zstd.table_size_max.offset]Table.Fse,
373380
374381 fse_tables_undefined: bool,
375382
......@@ -391,36 +398,30 @@ pub const Frame = struct {
391398 };
392399 }
393400
394 pub fn init(
395 literal_fse_buffer: []Table.Fse,
396 match_fse_buffer: []Table.Fse,
397 offset_fse_buffer: []Table.Fse,
398 ) Decode {
399 return .{
400 .repeat_offsets = .{
401 zstd.start_repeated_offset_1,
402 zstd.start_repeated_offset_2,
403 zstd.start_repeated_offset_3,
404 },
401 const init: Decode = .{
402 .repeat_offsets = .{
403 zstd.start_repeated_offset_1,
404 zstd.start_repeated_offset_2,
405 zstd.start_repeated_offset_3,
406 },
405407
406 .offset = undefined,
407 .match = undefined,
408 .literal = undefined,
408 .offset = undefined,
409 .match = undefined,
410 .literal = undefined,
409411
410 .literal_fse_buffer = literal_fse_buffer,
411 .match_fse_buffer = match_fse_buffer,
412 .offset_fse_buffer = offset_fse_buffer,
412 .literal_fse_buffer = undefined,
413 .match_fse_buffer = undefined,
414 .offset_fse_buffer = undefined,
413415
414 .fse_tables_undefined = true,
416 .fse_tables_undefined = true,
415417
416 .literal_written_count = 0,
417 .literal_header = undefined,
418 .literal_streams = undefined,
419 .literal_stream_reader = undefined,
420 .literal_stream_index = undefined,
421 .huffman_tree = null,
422 };
423 }
418 .literal_written_count = 0,
419 .literal_header = undefined,
420 .literal_streams = undefined,
421 .literal_stream_reader = undefined,
422 .literal_stream_index = undefined,
423 .huffman_tree = null,
424 };
424425
425426 pub const PrepareError = error{
426427 /// the (reversed) literal bitstream's first byte does not have any bits set
......@@ -502,12 +503,12 @@ pub const Frame = struct {
502503 return self.repeat_offsets[0];
503504 }
504505
505 const DataType = enum { offset, match, literal };
506 const WhichFse = enum { offset, match, literal };
506507
507508 /// TODO: don't use `@field`
508509 fn updateState(
509510 self: *Decode,
510 comptime choice: DataType,
511 comptime choice: WhichFse,
511512 bit_reader: *ReverseBitReader,
512513 ) error{ MalformedFseBits, EndOfStream }!void {
513514 switch (@field(self, @tagName(choice)).table) {
......@@ -537,7 +538,7 @@ pub const Frame = struct {
537538 self: *Decode,
538539 in: *Reader,
539540 remaining: *Limit,
540 comptime choice: DataType,
541 comptime choice: WhichFse,
541542 mode: SequencesSection.Header.Mode,
542543 ) !void {
543544 const field_name = @tagName(choice);
......@@ -564,10 +565,10 @@ pub const Frame = struct {
564565 &bit_reader,
565566 @field(zstd.table_symbol_count_max, field_name),
566567 @field(zstd.table_accuracy_log_max, field_name),
567 @field(self, field_name ++ "_fse_buffer"),
568 &@field(self, field_name ++ "_fse_buffer"),
568569 );
569570 @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],
571572 };
572573 @field(self, field_name).accuracy_log = std.math.log2_int_ceil(usize, table_size);
573574 in.toss(bit_reader.index);
......@@ -696,19 +697,19 @@ pub const Frame = struct {
696697 };
697698 }
698699
699 /// Decode `len` bytes of literals into `dest`.
700 fn decodeLiterals(self: *Decode, dest: *Writer, len: usize) !void {
701 switch (self.literal_header.block_type) {
700 /// Decode `len` bytes of literals into `w`.
701 fn decodeLiterals(d: *Decode, w: *Writer, len: usize) !void {
702 switch (d.literal_header.block_type) {
702703 .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]);
704705 },
705706 .rle => {
706 try dest.splatByteAll(self.literal_streams.one[0], len);
707 try w.splatByteAll(d.literal_streams.one[0], len);
707708 },
708709 .compressed, .treeless => {
709 if (len > dest.buffer.len) return error.OutputBufferUndersize;
710 const buf = try dest.writableSlice(len);
711 const huffman_tree = self.huffman_tree.?;
710 if (len > w.buffer.len) return error.OutputBufferUndersize;
711 const buf = try w.writableSlice(len);
712 const huffman_tree = d.huffman_tree.?;
712713 const max_bit_count = huffman_tree.max_bit_count;
713714 const starting_bit_count = LiteralsSection.HuffmanTree.weightToBitCount(
714715 huffman_tree.nodes[huffman_tree.symbol_count_minus_one].weight,
......@@ -720,7 +721,7 @@ pub const Frame = struct {
720721 for (buf) |*out| {
721722 var prefix: u16 = 0;
722723 while (true) {
723 const new_bits = try self.readLiteralsBits(bit_count_to_read);
724 const new_bits = try d.readLiteralsBits(bit_count_to_read);
724725 prefix <<= bit_count_to_read;
725726 prefix |= new_bits;
726727 bits_read += bit_count_to_read;
......@@ -750,7 +751,7 @@ pub const Frame = struct {
750751 }
751752
752753 /// TODO: don't use `@field`
753 fn getCode(self: *Decode, comptime choice: DataType) u32 {
754 fn getCode(self: *Decode, comptime choice: WhichFse) u32 {
754755 return switch (@field(self, @tagName(choice)).table) {
755756 .rle => |value| value,
756757 .fse => |table| table[@field(self, @tagName(choice)).state].symbol,
......@@ -1166,7 +1167,7 @@ pub const LiteralsSection = struct {
11661167 .raw => {
11671168 if (buffer.len < header.regenerated_size) return error.MalformedLiteralsSection;
11681169 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]);
11701171 return .{
11711172 .header = header,
11721173 .huffman_tree = null,
......@@ -1193,7 +1194,7 @@ pub const LiteralsSection = struct {
11931194 return error.MalformedLiteralsSection;
11941195 if (total_streams_size > buffer.len) return error.MalformedLiteralsSection;
11951196 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]);
11971198 const stream_data = buffer[0..total_streams_size];
11981199 const streams = try Streams.decode(header.size_format, stream_data);
11991200 return .{
lib/std/fs/File.zig+13-1
......@@ -1809,7 +1809,19 @@ pub const Writer = struct {
18091809 /// along with other write failures.
18101810 pub fn end(w: *Writer) EndError!void {
18111811 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 }
18131825 }
18141826};
18151827
lib/std/posix.zig+3-2
......@@ -1052,6 +1052,7 @@ pub const TruncateError = error{
10521052 FileBusy,
10531053 AccessDenied,
10541054 PermissionDenied,
1055 NonResizable,
10551056} || UnexpectedError;
10561057
10571058/// Length must be positive when treated as an i64.
......@@ -1091,7 +1092,7 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void {
10911092 .PERM => return error.PermissionDenied,
10921093 .TXTBSY => return error.FileBusy,
10931094 .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,
10951096 .NOTCAPABLE => return error.AccessDenied,
10961097 else => |err| return unexpectedErrno(err),
10971098 }
......@@ -1107,7 +1108,7 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void {
11071108 .PERM => return error.PermissionDenied,
11081109 .TXTBSY => return error.FileBusy,
11091110 .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.
11111112 else => |err| return unexpectedErrno(err),
11121113 }
11131114 }
src/Compilation.zig+8
......@@ -4880,6 +4880,14 @@ fn docsCopyFallible(comp: *Compilation) anyerror!void {
48804880 try seen_table.ensureUnusedCapacity(comp.gpa, deps.len);
48814881 for (deps) |dep| seen_table.putAssumeCapacity(dep, dep.fully_qualified_name);
48824882 }
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 };
48834891}
48844892
48854893fn docsCopyModule(
src/Package/Fetch.zig+7-8
......@@ -1198,7 +1198,8 @@ fn unpackResource(
11981198
11991199 switch (file_type) {
12001200 .tar => {
1201 var adapter = resource.reader().adaptToNewApi();
1201 var adapter_buffer: [1024]u8 = undefined;
1202 var adapter = resource.reader().adaptToNewApi(&adapter_buffer);
12021203 return unpackTarball(f, tmp_directory.handle, &adapter.new_interface);
12031204 },
12041205 .@"tar.gz" => {
......@@ -1227,14 +1228,12 @@ fn unpackResource(
12271228 .@"tar.zst" => {
12281229 const window_size = std.compress.zstd.default_window_len;
12291230 const window_buffer = try f.arena.allocator().create([window_size]u8);
1230 const reader = resource.reader();
1231 var br = std.io.bufferedReaderSize(std.crypto.tls.max_ciphertext_record_len, reader);
1232 var dcp = std.compress.zstd.decompressor(br.reader(), .{
1233 .window_buffer = window_buffer,
1231 var adapter_buffer: [std.crypto.tls.max_ciphertext_record_len]u8 = undefined;
1232 var adapter = resource.reader().adaptToNewApi(&adapter_buffer);
1233 var decompress: std.compress.zstd.Decompress = .init(&adapter.new_interface, window_buffer, .{
1234 .verify_checksum = false,
12341235 });
1235 var adapter_buffer: [1024]u8 = undefined;
1236 var adapter = dcp.reader().adaptToNewApi(&adapter_buffer);
1237 return try unpackTarball(f, tmp_directory.handle, &adapter.new_interface);
1236 return try unpackTarball(f, tmp_directory.handle, &decompress.reader);
12381237 },
12391238 .git_pack => return unpackGitPack(f, tmp_directory.handle, &resource.git) catch |err| switch (err) {
12401239 error.FetchFailed => return error.FetchFailed,
src/codegen/aarch64.zig+1-3
......@@ -113,9 +113,7 @@ pub fn generate(
113113 },
114114 .stack_slot => |stack_slot| {
115115 assert(stack_slot.base == .sp);
116 passed_vi.setParent(&isel, .{
117 .stack_slot = named_stack_args.withOffset(stack_slot.offset),
118 });
116 passed_vi.changeStackSlot(&isel, named_stack_args.withOffset(stack_slot.offset));
119117 },
120118 .address, .value, .constant => unreachable,
121119 }
src/codegen/aarch64/Assemble.zig+11-2
......@@ -215,6 +215,7 @@ fn nextToken(as: *Assemble, buf: *[token_buf_len]u8, comptime opts: struct {
215215
216216const SymbolSpec = union(enum) {
217217 reg: struct { format: aarch64.encoding.Register.Format, allow_sp: bool = false },
218 systemreg,
218219 imm: struct {
219220 type: std.builtin.Type.Int,
220221 multiple_of: comptime_int = 1,
......@@ -227,6 +228,7 @@ const SymbolSpec = union(enum) {
227228 fn Storage(comptime spec: SymbolSpec) type {
228229 return switch (spec) {
229230 .reg => aarch64.encoding.Register,
231 .systemreg => aarch64.encoding.Register.System,
230232 .imm => |imm| @Type(.{ .int = imm.type }),
231233 .extend => Instruction.DataProcessingRegister.AddSubtractExtendedRegister.Option,
232234 .shift => Instruction.DataProcessingRegister.Shift.Op,
......@@ -238,8 +240,7 @@ const SymbolSpec = union(enum) {
238240 const Result = Storage(spec);
239241 switch (spec) {
240242 .reg => |reg_spec| {
241 var buf: [token_buf_len]u8 = undefined;
242 const reg = Result.parse(std.ascii.lowerString(&buf, token[0..@min(token.len, buf.len)])) orelse {
243 const reg = Result.parse(token) orelse {
243244 log.debug("invalid register: \"{f}\"", .{std.zig.fmtString(token)});
244245 return null;
245246 };
......@@ -253,6 +254,14 @@ const SymbolSpec = union(enum) {
253254 }
254255 return reg;
255256 },
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 },
256265 .imm => |imm_spec| {
257266 const imm = std.fmt.parseInt(Result, token, 0) catch {
258267 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 {
55355535 2 => if (elem_is_vector) .ldr(elem_ra.h(), .{ .extended_register = .{
55365536 .base = base_mat.ra.x(),
55375537 .index = index_mat.ra.x(),
5538 .extend = .{ .lsl = 0 },
5538 .extend = .{ .lsl = 1 },
55395539 } }) else switch (elem_vi.value.signedness(isel)) {
55405540 .signed => .ldrsh(elem_ra.w(), .{ .extended_register = .{
55415541 .base = base_mat.ra.x(),
......@@ -5558,15 +5558,14 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
55585558 .index = index_mat.ra.x(),
55595559 .extend = .{ .lsl = 3 },
55605560 } }),
5561 16 => .ldr(elem_ra.q(), .{ .extended_register = .{
5561 16 => if (elem_is_vector) .ldr(elem_ra.q(), .{ .extended_register = .{
55625562 .base = base_mat.ra.x(),
55635563 .index = index_mat.ra.x(),
55645564 .extend = .{ .lsl = 4 },
5565 } }),
5565 } }) else unreachable,
55665566 });
55675567 try index_mat.finish(isel);
55685568 try base_mat.finish(isel);
5569 break :unused;
55705569 } else {
55715570 const elem_ptr_ra = try isel.allocIntReg();
55725571 defer isel.freeReg(elem_ptr_ra);
......@@ -5611,66 +5610,81 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
56115610 const ptr_ty = isel.air.typeOf(bin_op.lhs, ip);
56125611 const ptr_info = ptr_ty.ptrInfo(zcu);
56135612 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) {
56155615 0 => unreachable,
5616 1, 2, 4, 8 => {
5617 const elem_ra = try elem_vi.value.defReg(isel) orelse break :unused;
5618 const base_vi = try isel.use(bin_op.lhs);
5619 const index_vi = try isel.use(bin_op.rhs);
5620 const base_mat = try base_vi.matReg(isel);
5621 const index_mat = try index_vi.matReg(isel);
5622 try isel.emit(switch (elem_size) {
5623 else => unreachable,
5624 1 => switch (elem_vi.value.signedness(isel)) {
5625 .signed => .ldrsb(elem_ra.w(), .{ .extended_register = .{
5626 .base = base_mat.ra.x(),
5627 .index = index_mat.ra.x(),
5628 .extend = .{ .lsl = 0 },
5629 } }),
5630 .unsigned => .ldrb(elem_ra.w(), .{ .extended_register = .{
5631 .base = base_mat.ra.x(),
5632 .index = index_mat.ra.x(),
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 = .{
5616 1, 2, 4, 8 => true,
5617 16 => elem_is_vector,
5618 else => false,
5619 }) {
5620 const elem_ra = try elem_vi.value.defReg(isel) orelse break :unused;
5621 const base_vi = try isel.use(bin_op.lhs);
5622 const index_vi = try isel.use(bin_op.rhs);
5623 const base_mat = try base_vi.matReg(isel);
5624 const index_mat = try index_vi.matReg(isel);
5625 try isel.emit(switch (elem_size) {
5626 else => unreachable,
5627 1 => if (elem_is_vector) .ldr(elem_ra.b(), .{ .extended_register = .{
5628 .base = base_mat.ra.x(),
5629 .index = index_mat.ra.x(),
5630 .extend = .{ .lsl = 0 },
5631 } }) else switch (elem_vi.value.signedness(isel)) {
5632 .signed => .ldrsb(elem_ra.w(), .{ .extended_register = .{
56495633 .base = base_mat.ra.x(),
56505634 .index = index_mat.ra.x(),
5651 .extend = .{ .lsl = 2 },
5635 .extend = .{ .lsl = 0 },
56525636 } }),
5653 8 => .ldr(elem_ra.x(), .{ .extended_register = .{
5637 .unsigned => .ldrb(elem_ra.w(), .{ .extended_register = .{
56545638 .base = base_mat.ra.x(),
56555639 .index = index_mat.ra.x(),
5656 .extend = .{ .lsl = 3 },
5640 .extend = .{ .lsl = 0 },
56575641 } }),
5658 });
5659 try index_mat.finish(isel);
5660 try base_mat.finish(isel);
5661 },
5662 else => {
5663 const elem_ptr_ra = try isel.allocIntReg();
5664 defer isel.freeReg(elem_ptr_ra);
5665 if (!try elem_vi.value.load(isel, ptr_ty.elemType2(zcu), elem_ptr_ra, .{
5666 .@"volatile" = ptr_info.flags.is_volatile,
5667 })) break :unused;
5668 const base_vi = try isel.use(bin_op.lhs);
5669 const base_mat = try base_vi.matReg(isel);
5670 const index_vi = try isel.use(bin_op.rhs);
5671 try isel.elemPtr(elem_ptr_ra, base_mat.ra, .add, elem_size, index_vi);
5672 try base_mat.finish(isel);
5673 },
5642 },
5643 2 => if (elem_is_vector) .ldr(elem_ra.h(), .{ .extended_register = .{
5644 .base = base_mat.ra.x(),
5645 .index = index_mat.ra.x(),
5646 .extend = .{ .lsl = 1 },
5647 } }) else switch (elem_vi.value.signedness(isel)) {
5648 .signed => .ldrsh(elem_ra.w(), .{ .extended_register = .{
5649 .base = base_mat.ra.x(),
5650 .index = index_mat.ra.x(),
5651 .extend = .{ .lsl = 1 },
5652 } }),
5653 .unsigned => .ldrh(elem_ra.w(), .{ .extended_register = .{
5654 .base = base_mat.ra.x(),
5655 .index = index_mat.ra.x(),
5656 .extend = .{ .lsl = 1 },
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);
56745688 }
56755689 }
56765690 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 {
62506264 try agg_part_vi.?.move(isel, elems[field_index]);
62516265 field_offset += field_size;
62526266 }
6253 assert(field_offset == agg_vi.value.size(isel));
6267 assert(loaded_struct.flagsUnordered(ip).alignment.forward(field_offset) == agg_vi.value.size(isel));
62546268 },
62556269 .tuple_type => |tuple_type| {
62566270 const elems: []const Air.Inst.Ref =
62576271 @ptrCast(isel.air.extra.items[ty_pl.payload..][0..tuple_type.types.len]);
6272 var tuple_align: InternPool.Alignment = .@"1";
62586273 var field_offset: u64 = 0;
62596274 for (
62606275 tuple_type.types.get(ip),
......@@ -6263,7 +6278,9 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) !void {
62636278 ) |field_ty_index, field_val, elem| {
62646279 if (field_val != .none) continue;
62656280 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);
62676284 const field_size = field_ty.abiSize(zcu);
62686285 if (field_size == 0) continue;
62696286 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 {
62716288 try agg_part_vi.?.move(isel, elem);
62726289 field_offset += field_size;
62736290 }
6274 assert(field_offset == agg_vi.value.size(isel));
6291 assert(tuple_align.forward(field_offset) == agg_vi.value.size(isel));
62756292 },
62766293 else => return isel.fail("aggregate init {f}", .{isel.fmtType(agg_ty)}),
62776294 }
......@@ -7283,6 +7300,175 @@ fn ctzLimb(
72837300 }
72847301}
72857302
7303fn 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
72867472fn storeReg(
72877473 isel: *Select,
72887474 ra: Register.Alias,
......@@ -7558,6 +7744,13 @@ pub const Value = struct {
75587744 };
75597745 }
75607746
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
75617754 pub fn parent(vi: Value.Index, isel: *Select) Parent {
75627755 const value = vi.get(isel);
75637756 return switch (value.flags.parent_tag) {
......@@ -8070,123 +8263,7 @@ pub const Value = struct {
80708263 }),
80718264 64 => {},
80728265 };
8073 try isel.emit(emit: switch (part_size) {
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 });
8266 try isel.loadReg(part_ra, part_size, part_vi.signedness(isel), base_ra, opts.offset);
81908267 if (part_ra != .zr) {
81918268 const live_vi = isel.live_registers.getPtr(part_ra);
81928269 assert(live_vi.* == .allocating);
......@@ -9104,7 +9181,7 @@ pub const Value = struct {
91049181 const live_vi = isel.live_registers.getPtr(mat.ra);
91059182 assert(live_vi.* == .allocating);
91069183 var vi = mat.vi;
9107 var offset: i65 = 0;
9184 var offset: u64 = 0;
91089185 const size = mat.vi.size(isel);
91099186 free: while (true) {
91109187 if (vi.register(isel)) |ra| {
......@@ -9156,93 +9233,16 @@ pub const Value = struct {
91569233 live_vi.* = mat.vi;
91579234 return;
91589235 },
9159 .stack_slot => |stack_slot| {
9160 offset += stack_slot.offset;
9161 break :free try isel.emit(switch (size) {
9162 else => unreachable,
9163 1 => if (mat.ra.isVector()) .ldr(mat.ra.b(), .{ .unsigned_offset = .{
9164 .base = stack_slot.base.x(),
9165 .offset = @intCast(offset),
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 },
9236 .stack_slot => |stack_slot| break :free try isel.loadReg(
9237 mat.ra,
9238 size,
9239 mat.vi.signedness(isel),
9240 stack_slot.base,
9241 @as(i65, stack_slot.offset) + offset,
9242 ),
92039243 .address => |base_vi| {
92049244 const base_mat = try base_vi.matReg(isel);
9205 try isel.emit(switch (size) {
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 });
9245 try isel.loadReg(mat.ra, size, mat.vi.signedness(isel), base_mat.ra, offset);
92469246 break :free try base_mat.finish(isel);
92479247 },
92489248 .value => |parent_vi| vi = parent_vi,
src/codegen/aarch64/encoding.zig+434-41
......@@ -1072,7 +1072,7 @@ pub const Register = struct {
10721072 }
10731073
10741074 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])) {
10761076 else => null,
10771077 'r' => if (std.fmt.parseInt(u5, reg[1..], 10)) |n| switch (n) {
10781078 0...30 => .{
......@@ -1087,27 +1087,27 @@ pub const Register = struct {
10871087 .format = .{ .integer = .doubleword },
10881088 },
10891089 31 => null,
1090 } else |_| if (std.mem.eql(u8, reg, "xzr")) .xzr else null,
1090 } else |_| if (toLowerEqlAssertLower(reg, "xzr")) .xzr else null,
10911091 'w' => if (std.fmt.parseInt(u5, reg[1..], 10)) |n| switch (n) {
10921092 0...30 => .{
10931093 .alias = @enumFromInt(@intFromEnum(Alias.r0) + n),
10941094 .format = .{ .integer = .word },
10951095 },
10961096 31 => null,
1097 } else |_| if (std.mem.eql(u8, reg, "wzr"))
1097 } else |_| if (toLowerEqlAssertLower(reg, "wzr"))
10981098 .wzr
1099 else if (std.mem.eql(u8, reg, "wsp"))
1099 else if (toLowerEqlAssertLower(reg, "wsp"))
11001100 .wsp
11011101 else
11021102 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"))
11041104 .ip0
1105 else if (std.mem.eql(u8, reg, "ip1"))
1105 else if (toLowerEqlAssertLower(reg, "ip1"))
11061106 .ip1
11071107 else
11081108 null,
1109 'f' => return if (std.mem.eql(u8, reg, "fp")) .fp else null,
1110 'p' => return if (std.mem.eql(u8, reg, "pc")) .pc else null,
1109 'f' => return if (toLowerEqlAssertLower(reg, "fp")) .fp else null,
1110 'p' => return if (toLowerEqlAssertLower(reg, "pc")) .pc else null,
11111111 'v' => if (std.fmt.parseInt(u5, reg[1..], 10)) |n| .{
11121112 .alias = @enumFromInt(@intFromEnum(Alias.v0) + n),
11131113 .format = .alias,
......@@ -1123,7 +1123,7 @@ pub const Register = struct {
11231123 's' => if (std.fmt.parseInt(u5, reg[1..], 10)) |n| .{
11241124 .alias = @enumFromInt(@intFromEnum(Alias.v0) + n),
11251125 .format = .{ .scalar = .single },
1126 } else |_| if (std.mem.eql(u8, reg, "sp")) .sp else null,
1126 } else |_| if (toLowerEqlAssertLower(reg, "sp")) .sp else null,
11271127 'h' => if (std.fmt.parseInt(u5, reg[1..], 10)) |n| .{
11281128 .alias = @enumFromInt(@intFromEnum(Alias.v0) + n),
11291129 .format = .{ .scalar = .half },
......@@ -1141,6 +1141,422 @@ pub const Register = struct {
11411141 pub fn fmtCase(reg: Register, case: aarch64.Disassemble.Case) aarch64.Disassemble.RegisterFormatter {
11421142 return .{ .reg = reg, .case = case };
11431143 }
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 }
11441560};
11451561
11461562/// C1.2.4 Condition code
......@@ -2385,12 +2801,7 @@ pub const Instruction = packed union {
23852801
23862802 pub const Group = packed struct {
23872803 Rt: Register.Encoded,
2388 op2: u3,
2389 CRm: u4,
2390 CRn: u4,
2391 op1: u3,
2392 o0: u1,
2393 decoded20: u1 = 0b1,
2804 systemreg: Register.System,
23942805 L: L,
23952806 decoded22: u10 = 0b1101010100,
23962807 };
......@@ -2398,12 +2809,7 @@ pub const Instruction = packed union {
23982809 /// C6.2.230 MSR (register)
23992810 pub const Msr = packed struct {
24002811 Rt: Register.Encoded,
2401 op2: u3,
2402 CRm: u4,
2403 CRn: u4,
2404 op1: u3,
2405 o0: u1,
2406 decoded20: u1 = 0b1,
2812 systemreg: Register.System,
24072813 L: L = .msr,
24082814 decoded22: u10 = 0b1101010100,
24092815 };
......@@ -2411,12 +2817,7 @@ pub const Instruction = packed union {
24112817 /// C6.2.228 MRS
24122818 pub const Mrs = packed struct {
24132819 Rt: Register.Encoded,
2414 op2: u3,
2415 CRm: u4,
2416 CRn: u4,
2417 op1: u3,
2418 o0: u1,
2419 decoded20: u1 = 0b1,
2820 systemreg: Register.System,
24202821 L: L = .mrs,
24212822 decoded22: u10 = 0b1101010100,
24222823 };
......@@ -10585,30 +10986,22 @@ pub const Instruction = packed union {
1058510986 } } };
1058610987 }
1058710988 /// C6.2.228 MRS
10588 pub fn mrs(t: Register, op0: u2, op1: u3, n: u4, m: u4, op2: u3) Instruction {
10589 assert(t.format.integer == .doubleword);
10989 pub fn mrs(t: Register, systemreg: Register.System) Instruction {
10990 assert(t.format.integer == .doubleword and systemreg.op0 >= 0b10);
1059010991 return .{ .branch_exception_generating_system = .{ .system_register_move = .{
1059110992 .mrs = .{
1059210993 .Rt = t.alias.encode(.{}),
10593 .op2 = op2,
10594 .CRm = m,
10595 .CRn = n,
10596 .op1 = op1,
10597 .o0 = @intCast(op0 - 0b10),
10994 .systemreg = systemreg,
1059810995 },
1059910996 } } };
1060010997 }
1060110998 /// C6.2.230 MSR (register)
10602 pub fn msr(op0: u2, op1: u3, n: u4, m: u4, op2: u3, t: Register) Instruction {
10603 assert(t.format.integer == .doubleword);
10999 pub fn msr(systemreg: Register.System, t: Register) Instruction {
11000 assert(systemreg.op0 >= 0b10 and t.format.integer == .doubleword);
1060411001 return .{ .branch_exception_generating_system = .{ .system_register_move = .{
1060511002 .msr = .{
1060611003 .Rt = t.alias.encode(.{}),
10607 .op2 = op2,
10608 .CRm = m,
10609 .CRn = n,
10610 .op1 = op1,
10611 .o0 = @intCast(op0 - 0b10),
11004 .systemreg = systemreg,
1061211005 },
1061311006 } } };
1061411007 }
src/codegen/aarch64/instructions.zon+12-2
......@@ -851,11 +851,21 @@
851851 },
852852 // C6.2.228 MRS
853853 .{
854 .pattern = "MRS <Xt>, CTR_EL0",
854 .pattern = "MRS <Xt>, <systemreg>",
855855 .symbols = .{
856856 .Xt = .{ .reg = .{ .format = .{ .integer = .doubleword } } },
857 .systemreg = .systemreg,
857858 },
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 },
859869 },
860870 // C6.2.234 NEG
861871 .{
src/main.zig+92-54
......@@ -4648,14 +4648,14 @@ const usage_init =
46484648fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
46494649 dev.check(.init_command);
46504650
4651 var strip = false;
4651 var template: enum { example, minimal } = .example;
46524652 {
46534653 var i: usize = 0;
46544654 while (i < args.len) : (i += 1) {
46554655 const arg = args[i];
46564656 if (mem.startsWith(u8, arg, "-")) {
4657 if (mem.eql(u8, arg, "-s") or mem.eql(u8, arg, "--strip")) {
4658 strip = true;
4657 if (mem.eql(u8, arg, "-m") or mem.eql(u8, arg, "--minimal")) {
4658 template = .minimal;
46594659 } else if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) {
46604660 try fs.File.stdout().writeAll(usage_init);
46614661 return cleanExit();
......@@ -4668,40 +4668,79 @@ fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
46684668 }
46694669 }
46704670
4671 var templates = findTemplates(gpa, arena, strip);
4672 defer templates.deinit();
4673
46744671 const cwd_path = try introspect.getResolvedCwd(arena);
46754672 const cwd_basename = fs.path.basename(cwd_path);
46764673 const sanitized_root_name = try sanitizeExampleName(arena, cwd_basename);
46774674
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
46874675 const fingerprint: Package.Fingerprint = .generate(sanitized_root_name);
46884676
4689 for (template_paths) |template_path| {
4690 if (templates.write(arena, fs.cwd(), sanitized_root_name, template_path, fingerprint)) |_| {
4691 std.log.info("created {s}", .{template_path});
4692 ok_count += 1;
4693 } else |err| switch (err) {
4694 error.PathAlreadyExists => std.log.info("preserving already existing file: {s}", .{
4695 template_path,
4696 }),
4697 else => std.log.err("unable to write {s}: {s}\n", .{ template_path, @errorName(err) }),
4698 }
4699 }
4677 switch (template) {
4678 .example => {
4679 var templates = findTemplates(gpa, arena);
4680 defer templates.deinit();
4681
4682 const s = fs.path.sep_str;
4683 const template_paths = [_][]const u8{
4684 Package.build_zig_basename,
4685 Package.Manifest.basename,
4686 "src" ++ s ++ "main.zig",
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 }
47004702
4701 if (ok_count == template_paths.len) {
4702 std.log.info("see `zig build --help` for a menu of options", .{});
4703 if (ok_count == template_paths.len) {
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 },
47034743 }
4704 return cleanExit();
47054744}
47064745
47074746fn sanitizeExampleName(arena: Allocator, bytes: []const u8) error{OutOfMemory}![]const u8 {
......@@ -7229,13 +7268,20 @@ fn loadManifest(
72297268 0,
72307269 ) catch |err| switch (err) {
72317270 error.FileNotFound => {
7232 const fingerprint: Package.Fingerprint = .generate(options.root_name);
7233 var templates = findTemplates(gpa, arena, true);
7234 defer templates.deinit();
7235 templates.write(arena, options.dir, options.root_name, Package.Manifest.basename, fingerprint) catch |e| {
7236 fatal("unable to write {s}: {s}", .{
7237 Package.Manifest.basename, @errorName(e),
7238 });
7271 writeSimpleTemplateFile(Package.Manifest.basename,
7272 \\.{{
7273 \\ .name = .{s},
7274 \\ .version = "{s}",
7275 \\ .paths = .{{""}},
7276 \\ .fingerprint = 0x{x},
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) });
72397285 };
72407286 continue;
72417287 },
......@@ -7276,7 +7322,6 @@ const Templates = struct {
72767322 zig_lib_directory: Cache.Directory,
72777323 dir: fs.Dir,
72787324 buffer: std.ArrayList(u8),
7279 strip: bool,
72807325
72817326 fn deinit(templates: *Templates) void {
72827327 templates.zig_lib_directory.handle.close();
......@@ -7305,23 +7350,9 @@ const Templates = struct {
73057350 };
73067351 templates.buffer.clearRetainingCapacity();
73077352 try templates.buffer.ensureUnusedCapacity(contents.len);
7308 var new_line = templates.strip;
73097353 var i: usize = 0;
73107354 while (i < contents.len) {
7311 if (new_line) {
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] == '.') {
7355 if (contents[i] == '_' or contents[i] == '.') {
73257356 // Both '_' and '.' are allowed because depending on the context
73267357 // one prefix will be valid, while the other might not.
73277358 if (std.mem.startsWith(u8, contents[i + 1 ..], "NAME")) {
......@@ -7350,8 +7381,16 @@ const Templates = struct {
73507381 });
73517382 }
73527383};
7384fn 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}
73537392
7354fn findTemplates(gpa: Allocator, arena: Allocator, strip: bool) Templates {
7393fn findTemplates(gpa: Allocator, arena: Allocator) Templates {
73557394 const cwd_path = introspect.getResolvedCwd(arena) catch |err| {
73567395 fatal("unable to get cwd: {s}", .{@errorName(err)});
73577396 };
......@@ -7375,7 +7414,6 @@ fn findTemplates(gpa: Allocator, arena: Allocator, strip: bool) Templates {
73757414 .zig_lib_directory = zig_lib_directory,
73767415 .dir = template_dir,
73777416 .buffer = std.ArrayList(u8).init(gpa),
7378 .strip = strip,
73797417 };
73807418}
73817419
stage1/wasm2c.c+1-1
......@@ -316,10 +316,10 @@ int main(int argc, char **argv) {
316316 "}\n"
317317 "\n"
318318 "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"
320319 " uint32_t r = *p;\n"
321320 " uint32_t new_p = r + n;\n"
322321 " if (new_p > UINT32_C(0xFFFF)) return UINT32_C(0xFFFFFFFF);\n"
322 " uint8_t *new_m = *m;\n"
323323 " uint32_t new_c = *c;\n"
324324 " if (new_c < new_p) {\n"
325325 " 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 {
471471}
472472
473473test "array 2D const double ptr" {
474 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
475474 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
476475 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
477476 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
......@@ -484,7 +483,6 @@ test "array 2D const double ptr" {
484483}
485484
486485test "array 2D const double ptr with offset" {
487 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
488486 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
489487 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
490488 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
......@@ -497,7 +495,6 @@ test "array 2D const double ptr with offset" {
497495}
498496
499497test "array 3D const double ptr with offset" {
500 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
501498 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
502499 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
503500 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)" {
18161816}
18171817
18181818test "peer type resolution: three-way resolution combines error set and optional" {
1819 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
18201819 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
18211820 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
18221821 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
test/behavior/pointers.zig-1
......@@ -436,7 +436,6 @@ test "pointer sentinel with optional element" {
436436}
437437
438438test "pointer sentinel with +inf" {
439 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
440439 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
441440 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
442441 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
test/tests.zig+10
......@@ -2016,6 +2016,16 @@ pub fn addCliTests(b: *std.Build) *Step {
20162016 step.dependOn(&cleanup.step);
20172017 }
20182018
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
20192029 // Test Godbolt API
20202030 if (builtin.os.tag == .linux and builtin.cpu.arch == .x86_64) {
20212031 const tmp_path = b.makeTempPath();