| ... | ... | @@ -5821,29 +5821,21 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, |
| 5821 | 5821 | if (air.next()) |next_air_tag| continue :air_tag next_air_tag; |
| 5822 | 5822 | }, |
| 5823 | 5823 | .unwrap_errunion_err_ptr => { |
| 5824 | | if (isel.live_values.fetchRemove(air.inst_index)) |error_ptr_vi| unused: { |
| 5825 | | defer error_ptr_vi.value.deref(isel); |
| 5824 | if (isel.live_values.fetchRemove(air.inst_index)) |error_vi| { |
| 5825 | defer error_vi.value.deref(isel); |
| 5826 | 5826 | const ty_op = air.data(air.inst_index).ty_op; |
| 5827 | | switch (codegen.errUnionErrorOffset( |
| 5828 | | isel.air.typeOf(ty_op.operand, ip).childType(zcu).errorUnionPayload(zcu), |
| 5829 | | zcu, |
| 5830 | | )) { |
| 5831 | | 0 => try error_ptr_vi.value.move(isel, ty_op.operand), |
| 5832 | | else => |error_offset| { |
| 5833 | | const error_ptr_ra = try error_ptr_vi.value.defReg(isel) orelse break :unused; |
| 5834 | | const error_union_ptr_vi = try isel.use(ty_op.operand); |
| 5835 | | const error_union_ptr_mat = try error_union_ptr_vi.matReg(isel); |
| 5836 | | const lo12: u12 = @truncate(error_offset >> 0); |
| 5837 | | const hi12: u12 = @intCast(error_offset >> 12); |
| 5838 | | if (hi12 > 0) try isel.emit(.add( |
| 5839 | | error_ptr_ra.x(), |
| 5840 | | if (lo12 > 0) error_ptr_ra.x() else error_union_ptr_mat.ra.x(), |
| 5841 | | .{ .shifted_immediate = .{ .immediate = hi12, .lsl = .@"12" } }, |
| 5842 | | )); |
| 5843 | | if (lo12 > 0) try isel.emit(.add(error_ptr_ra.x(), error_union_ptr_mat.ra.x(), .{ .immediate = lo12 })); |
| 5844 | | try error_union_ptr_mat.finish(isel); |
| 5845 | | }, |
| 5846 | | } |
| 5827 | const error_union_ptr_ty = isel.air.typeOf(ty_op.operand, ip); |
| 5828 | const error_union_ptr_info = error_union_ptr_ty.ptrInfo(zcu); |
| 5829 | const error_union_ptr_vi = try isel.use(ty_op.operand); |
| 5830 | const error_union_ptr_mat = try error_union_ptr_vi.matReg(isel); |
| 5831 | _ = try error_vi.value.load(isel, ty_op.ty.toType(), error_union_ptr_mat.ra, .{ |
| 5832 | .offset = codegen.errUnionErrorOffset( |
| 5833 | ZigType.fromInterned(error_union_ptr_info.child).errorUnionPayload(zcu), |
| 5834 | zcu, |
| 5835 | ), |
| 5836 | .@"volatile" = error_union_ptr_info.flags.is_volatile, |
| 5837 | }); |
| 5838 | try error_union_ptr_mat.finish(isel); |
| 5847 | 5839 | } |
| 5848 | 5840 | if (air.next()) |next_air_tag| continue :air_tag next_air_tag; |
| 5849 | 5841 | }, |
| ... | ... | @@ -8031,6 +8023,7 @@ pub fn layout( |
| 8031 | 8023 | while (save_index < saves.len) { |
| 8032 | 8024 | if (save_index + 2 <= saves.len and saves[save_index + 1].needs_restore and |
| 8033 | 8025 | saves[save_index + 0].class == saves[save_index + 1].class and |
| 8026 | saves[save_index + 0].size == saves[save_index + 1].size and |
| 8034 | 8027 | saves[save_index + 0].offset + saves[save_index + 0].size == saves[save_index + 1].offset) |
| 8035 | 8028 | { |
| 8036 | 8029 | try isel.emit(.ldp( |
| ... | ... | @@ -8337,7 +8330,7 @@ fn elemPtr( |
| 8337 | 8330 | }), |
| 8338 | 8331 | 2 => { |
| 8339 | 8332 | const shift: u6 = @intCast(@ctz(elem_size)); |
| 8340 | | const temp_ra = temp_ra: switch (op) { |
| 8333 | const temp_ra, const free_temp_ra = temp_ra: switch (op) { |
| 8341 | 8334 | .add => switch (base_ra) { |
| 8342 | 8335 | else => { |
| 8343 | 8336 | const temp_ra = try isel.allocIntReg(); |
| ... | ... | @@ -8346,7 +8339,7 @@ fn elemPtr( |
| 8346 | 8339 | .register = temp_ra.x(), |
| 8347 | 8340 | .shift = .{ .lsl = shift }, |
| 8348 | 8341 | } })); |
| 8349 | | break :temp_ra temp_ra; |
| 8342 | break :temp_ra .{ temp_ra, true }; |
| 8350 | 8343 | }, |
| 8351 | 8344 | .zr => { |
| 8352 | 8345 | if (shift > 0) try isel.emit(.ubfm(elem_ptr_ra.x(), elem_ptr_ra.x(), .{ |
| ... | ... | @@ -8354,7 +8347,7 @@ fn elemPtr( |
| 8354 | 8347 | .immr = -%shift, |
| 8355 | 8348 | .imms = ~shift, |
| 8356 | 8349 | })); |
| 8357 | | break :temp_ra elem_ptr_ra; |
| 8350 | break :temp_ra .{ elem_ptr_ra, false }; |
| 8358 | 8351 | }, |
| 8359 | 8352 | }, |
| 8360 | 8353 | .sub => { |
| ... | ... | @@ -8364,10 +8357,10 @@ fn elemPtr( |
| 8364 | 8357 | .register = temp_ra.x(), |
| 8365 | 8358 | .shift = .{ .lsl = shift }, |
| 8366 | 8359 | } })); |
| 8367 | | break :temp_ra temp_ra; |
| 8360 | break :temp_ra .{ temp_ra, true }; |
| 8368 | 8361 | }, |
| 8369 | 8362 | }; |
| 8370 | | defer if (temp_ra != elem_ptr_ra) isel.freeReg(temp_ra); |
| 8363 | defer if (free_temp_ra) isel.freeReg(temp_ra); |
| 8371 | 8364 | try isel.emit(.add(temp_ra.x(), index_mat.ra.x(), .{ .shifted_register = .{ |
| 8372 | 8365 | .register = index_mat.ra.x(), |
| 8373 | 8366 | .shift = .{ .lsl = @intCast(63 - @clz(elem_size) - shift) }, |
| ... | ... | @@ -9296,7 +9289,14 @@ pub const Value = struct { |
| 9296 | 9289 | part_offset -= part_size; |
| 9297 | 9290 | var wrapped_res_part_it = res_vi.field(ty, part_offset, part_size); |
| 9298 | 9291 | const wrapped_res_part_vi = try wrapped_res_part_it.only(isel); |
| 9299 | | const wrapped_res_part_ra = try wrapped_res_part_vi.?.defReg(isel) orelse if (need_carry) .zr else continue; |
| 9292 | const wrapped_res_part_ra = wrapped_res_part_ra: { |
| 9293 | const overflow_ra_lock: RegLock = switch (opts.overflow) { |
| 9294 | .ra => |ra| isel.lockReg(ra), |
| 9295 | else => .empty, |
| 9296 | }; |
| 9297 | defer overflow_ra_lock.unlock(isel); |
| 9298 | break :wrapped_res_part_ra try wrapped_res_part_vi.?.defReg(isel) orelse if (need_carry) .zr else continue; |
| 9299 | }; |
| 9300 | 9300 | const unwrapped_res_part_ra = unwrapped_res_part_ra: { |
| 9301 | 9301 | if (!need_wrap) break :unwrapped_res_part_ra wrapped_res_part_ra; |
| 9302 | 9302 | if (int_info.bits % 32 == 0) { |