diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2025-09-21 01:49:28 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-09-21 01:49:28 -0700 |
| commit | 010d9a63f20d8a4bd14cff0ada690b2d127a0371 (patch) | |
| tree | 12b56ddfe5a5b235ef0676832902a0b04ad7d57a /src/codegen/aarch64 | |
| parent | 3fbb88c4bd146ca7bd9e7ab5da9c4b05298f3b34 (diff) | |
| parent | 633162eb0c8d302ba7585cd308e01237409f042e (diff) | |
| download | zig-010d9a63f20d8a4bd14cff0ada690b2d127a0371.tar.gz zig-010d9a63f20d8a4bd14cff0ada690b2d127a0371.zip | |
Merge pull request #25154 from ziglang/no-decl-val-3
rework byval ZIR instructions; forbid runtime vector indexes
Diffstat (limited to 'src/codegen/aarch64')
| -rw-r--r-- | src/codegen/aarch64/Select.zig | 76 |
1 files changed, 48 insertions, 28 deletions
diff --git a/src/codegen/aarch64/Select.zig b/src/codegen/aarch64/Select.zig index b4550b28a5..43edde274c 100644 --- a/src/codegen/aarch64/Select.zig +++ b/src/codegen/aarch64/Select.zig @@ -5821,29 +5821,21 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, if (air.next()) |next_air_tag| continue :air_tag next_air_tag; }, .unwrap_errunion_err_ptr => { - if (isel.live_values.fetchRemove(air.inst_index)) |error_ptr_vi| unused: { - defer error_ptr_vi.value.deref(isel); + if (isel.live_values.fetchRemove(air.inst_index)) |error_vi| { + defer error_vi.value.deref(isel); const ty_op = air.data(air.inst_index).ty_op; - switch (codegen.errUnionErrorOffset( - isel.air.typeOf(ty_op.operand, ip).childType(zcu).errorUnionPayload(zcu), - zcu, - )) { - 0 => try error_ptr_vi.value.move(isel, ty_op.operand), - else => |error_offset| { - const error_ptr_ra = try error_ptr_vi.value.defReg(isel) orelse break :unused; - const error_union_ptr_vi = try isel.use(ty_op.operand); - const error_union_ptr_mat = try error_union_ptr_vi.matReg(isel); - const lo12: u12 = @truncate(error_offset >> 0); - const hi12: u12 = @intCast(error_offset >> 12); - if (hi12 > 0) try isel.emit(.add( - error_ptr_ra.x(), - if (lo12 > 0) error_ptr_ra.x() else error_union_ptr_mat.ra.x(), - .{ .shifted_immediate = .{ .immediate = hi12, .lsl = .@"12" } }, - )); - if (lo12 > 0) try isel.emit(.add(error_ptr_ra.x(), error_union_ptr_mat.ra.x(), .{ .immediate = lo12 })); - try error_union_ptr_mat.finish(isel); - }, - } + const error_union_ptr_ty = isel.air.typeOf(ty_op.operand, ip); + const error_union_ptr_info = error_union_ptr_ty.ptrInfo(zcu); + const error_union_ptr_vi = try isel.use(ty_op.operand); + const error_union_ptr_mat = try error_union_ptr_vi.matReg(isel); + _ = try error_vi.value.load(isel, ty_op.ty.toType(), error_union_ptr_mat.ra, .{ + .offset = codegen.errUnionErrorOffset( + ZigType.fromInterned(error_union_ptr_info.child).errorUnionPayload(zcu), + zcu, + ), + .@"volatile" = error_union_ptr_info.flags.is_volatile, + }); + try error_union_ptr_mat.finish(isel); } if (air.next()) |next_air_tag| continue :air_tag next_air_tag; }, @@ -6147,6 +6139,26 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, } if (air.next()) |next_air_tag| continue :air_tag next_air_tag; }, + .ptr_slice_len_ptr => { + if (isel.live_values.fetchRemove(air.inst_index)) |dst_vi| unused: { + defer dst_vi.value.deref(isel); + const ty_op = air.data(air.inst_index).ty_op; + const dst_ra = try dst_vi.value.defReg(isel) orelse break :unused; + const src_vi = try isel.use(ty_op.operand); + const src_mat = try src_vi.matReg(isel); + try isel.emit(.add(dst_ra.x(), src_mat.ra.x(), .{ .immediate = 8 })); + try src_mat.finish(isel); + } + if (air.next()) |next_air_tag| continue :air_tag next_air_tag; + }, + .ptr_slice_ptr_ptr => { + if (isel.live_values.fetchRemove(air.inst_index)) |dst_vi| { + defer dst_vi.value.deref(isel); + const ty_op = air.data(air.inst_index).ty_op; + try dst_vi.value.move(isel, ty_op.operand); + } + if (air.next()) |next_air_tag| continue :air_tag next_air_tag; + }, .array_elem_val => { if (isel.live_values.fetchRemove(air.inst_index)) |elem_vi| unused: { defer elem_vi.value.deref(isel); @@ -8011,6 +8023,7 @@ pub fn layout( while (save_index < saves.len) { if (save_index + 2 <= saves.len and saves[save_index + 1].needs_restore and saves[save_index + 0].class == saves[save_index + 1].class and + saves[save_index + 0].size == saves[save_index + 1].size and saves[save_index + 0].offset + saves[save_index + 0].size == saves[save_index + 1].offset) { try isel.emit(.ldp( @@ -8317,7 +8330,7 @@ fn elemPtr( }), 2 => { const shift: u6 = @intCast(@ctz(elem_size)); - const temp_ra = temp_ra: switch (op) { + const temp_ra, const free_temp_ra = temp_ra: switch (op) { .add => switch (base_ra) { else => { const temp_ra = try isel.allocIntReg(); @@ -8326,7 +8339,7 @@ fn elemPtr( .register = temp_ra.x(), .shift = .{ .lsl = shift }, } })); - break :temp_ra temp_ra; + break :temp_ra .{ temp_ra, true }; }, .zr => { if (shift > 0) try isel.emit(.ubfm(elem_ptr_ra.x(), elem_ptr_ra.x(), .{ @@ -8334,7 +8347,7 @@ fn elemPtr( .immr = -%shift, .imms = ~shift, })); - break :temp_ra elem_ptr_ra; + break :temp_ra .{ elem_ptr_ra, false }; }, }, .sub => { @@ -8344,10 +8357,10 @@ fn elemPtr( .register = temp_ra.x(), .shift = .{ .lsl = shift }, } })); - break :temp_ra temp_ra; + break :temp_ra .{ temp_ra, true }; }, }; - defer if (temp_ra != elem_ptr_ra) isel.freeReg(temp_ra); + defer if (free_temp_ra) isel.freeReg(temp_ra); try isel.emit(.add(temp_ra.x(), index_mat.ra.x(), .{ .shifted_register = .{ .register = index_mat.ra.x(), .shift = .{ .lsl = @intCast(63 - @clz(elem_size) - shift) }, @@ -9276,7 +9289,14 @@ pub const Value = struct { part_offset -= part_size; var wrapped_res_part_it = res_vi.field(ty, part_offset, part_size); const wrapped_res_part_vi = try wrapped_res_part_it.only(isel); - const wrapped_res_part_ra = try wrapped_res_part_vi.?.defReg(isel) orelse if (need_carry) .zr else continue; + const wrapped_res_part_ra = wrapped_res_part_ra: { + const overflow_ra_lock: RegLock = switch (opts.overflow) { + .ra => |ra| isel.lockReg(ra), + else => .empty, + }; + defer overflow_ra_lock.unlock(isel); + break :wrapped_res_part_ra try wrapped_res_part_vi.?.defReg(isel) orelse if (need_carry) .zr else continue; + }; const unwrapped_res_part_ra = unwrapped_res_part_ra: { if (!need_wrap) break :unwrapped_res_part_ra wrapped_res_part_ra; if (int_info.bits % 32 == 0) { |
