| ... | ... | @@ -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 | }, |
| ... | ... | @@ -8011,6 +8003,7 @@ pub fn layout( |
| 8011 | 8003 | while (save_index < saves.len) { |
| 8012 | 8004 | if (save_index + 2 <= saves.len and saves[save_index + 1].needs_restore and |
| 8013 | 8005 | saves[save_index + 0].class == saves[save_index + 1].class and |
| 8006 | saves[save_index + 0].size == saves[save_index + 1].size and |
| 8014 | 8007 | saves[save_index + 0].offset + saves[save_index + 0].size == saves[save_index + 1].offset) |
| 8015 | 8008 | { |
| 8016 | 8009 | try isel.emit(.ldp( |
| ... | ... | @@ -8317,7 +8310,7 @@ fn elemPtr( |
| 8317 | 8310 | }), |
| 8318 | 8311 | 2 => { |
| 8319 | 8312 | const shift: u6 = @intCast(@ctz(elem_size)); |
| 8320 | | const temp_ra = temp_ra: switch (op) { |
| 8313 | const temp_ra, const free_temp_ra = temp_ra: switch (op) { |
| 8321 | 8314 | .add => switch (base_ra) { |
| 8322 | 8315 | else => { |
| 8323 | 8316 | const temp_ra = try isel.allocIntReg(); |
| ... | ... | @@ -8326,7 +8319,7 @@ fn elemPtr( |
| 8326 | 8319 | .register = temp_ra.x(), |
| 8327 | 8320 | .shift = .{ .lsl = shift }, |
| 8328 | 8321 | } })); |
| 8329 | | break :temp_ra temp_ra; |
| 8322 | break :temp_ra .{ temp_ra, true }; |
| 8330 | 8323 | }, |
| 8331 | 8324 | .zr => { |
| 8332 | 8325 | if (shift > 0) try isel.emit(.ubfm(elem_ptr_ra.x(), elem_ptr_ra.x(), .{ |
| ... | ... | @@ -8334,7 +8327,7 @@ fn elemPtr( |
| 8334 | 8327 | .immr = -%shift, |
| 8335 | 8328 | .imms = ~shift, |
| 8336 | 8329 | })); |
| 8337 | | break :temp_ra elem_ptr_ra; |
| 8330 | break :temp_ra .{ elem_ptr_ra, false }; |
| 8338 | 8331 | }, |
| 8339 | 8332 | }, |
| 8340 | 8333 | .sub => { |
| ... | ... | @@ -8344,10 +8337,10 @@ fn elemPtr( |
| 8344 | 8337 | .register = temp_ra.x(), |
| 8345 | 8338 | .shift = .{ .lsl = shift }, |
| 8346 | 8339 | } })); |
| 8347 | | break :temp_ra temp_ra; |
| 8340 | break :temp_ra .{ temp_ra, true }; |
| 8348 | 8341 | }, |
| 8349 | 8342 | }; |
| 8350 | | defer if (temp_ra != elem_ptr_ra) isel.freeReg(temp_ra); |
| 8343 | defer if (free_temp_ra) isel.freeReg(temp_ra); |
| 8351 | 8344 | try isel.emit(.add(temp_ra.x(), index_mat.ra.x(), .{ .shifted_register = .{ |
| 8352 | 8345 | .register = index_mat.ra.x(), |
| 8353 | 8346 | .shift = .{ .lsl = @intCast(63 - @clz(elem_size) - shift) }, |
| ... | ... | @@ -9276,7 +9269,14 @@ pub const Value = struct { |
| 9276 | 9269 | part_offset -= part_size; |
| 9277 | 9270 | var wrapped_res_part_it = res_vi.field(ty, part_offset, part_size); |
| 9278 | 9271 | const wrapped_res_part_vi = try wrapped_res_part_it.only(isel); |
| 9279 | | const wrapped_res_part_ra = try wrapped_res_part_vi.?.defReg(isel) orelse if (need_carry) .zr else continue; |
| 9272 | const wrapped_res_part_ra = wrapped_res_part_ra: { |
| 9273 | const overflow_ra_lock: RegLock = switch (opts.overflow) { |
| 9274 | .ra => |ra| isel.lockReg(ra), |
| 9275 | else => .empty, |
| 9276 | }; |
| 9277 | defer overflow_ra_lock.unlock(isel); |
| 9278 | break :wrapped_res_part_ra try wrapped_res_part_vi.?.defReg(isel) orelse if (need_carry) .zr else continue; |
| 9279 | }; |
| 9280 | 9280 | const unwrapped_res_part_ra = unwrapped_res_part_ra: { |
| 9281 | 9281 | if (!need_wrap) break :unwrapped_res_part_ra wrapped_res_part_ra; |
| 9282 | 9282 | if (int_info.bits % 32 == 0) { |