| ... | @@ -5821,29 +5821,21 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, | ... | @@ -5821,29 +5821,21 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, |
| 5821 | if (air.next()) |next_air_tag| continue :air_tag next_air_tag; | 5821 | if (air.next()) |next_air_tag| continue :air_tag next_air_tag; |
| 5822 | }, | 5822 | }, |
| 5823 | .unwrap_errunion_err_ptr => { | 5823 | .unwrap_errunion_err_ptr => { |
| 5824 | if (isel.live_values.fetchRemove(air.inst_index)) |error_ptr_vi| unused: { | 5824 | if (isel.live_values.fetchRemove(air.inst_index)) |error_vi| { |
| 5825 | defer error_ptr_vi.value.deref(isel); | 5825 | defer error_vi.value.deref(isel); |
| 5826 | const ty_op = air.data(air.inst_index).ty_op; | 5826 | const ty_op = air.data(air.inst_index).ty_op; |
| 5827 | switch (codegen.errUnionErrorOffset( | 5827 | const error_union_ptr_ty = isel.air.typeOf(ty_op.operand, ip); |
| 5828 | isel.air.typeOf(ty_op.operand, ip).childType(zcu).errorUnionPayload(zcu), | 5828 | const error_union_ptr_info = error_union_ptr_ty.ptrInfo(zcu); |
| 5829 | zcu, | 5829 | const error_union_ptr_vi = try isel.use(ty_op.operand); |
| 5830 | )) { | 5830 | const error_union_ptr_mat = try error_union_ptr_vi.matReg(isel); |
| 5831 | 0 => try error_ptr_vi.value.move(isel, ty_op.operand), | 5831 | _ = try error_vi.value.load(isel, ty_op.ty.toType(), error_union_ptr_mat.ra, .{ |
| 5832 | else => |error_offset| { | 5832 | .offset = codegen.errUnionErrorOffset( |
| 5833 | const error_ptr_ra = try error_ptr_vi.value.defReg(isel) orelse break :unused; | 5833 | ZigType.fromInterned(error_union_ptr_info.child).errorUnionPayload(zcu), |
| 5834 | const error_union_ptr_vi = try isel.use(ty_op.operand); | 5834 | zcu, |
| 5835 | const error_union_ptr_mat = try error_union_ptr_vi.matReg(isel); | 5835 | ), |
| 5836 | const lo12: u12 = @truncate(error_offset >> 0); | 5836 | .@"volatile" = error_union_ptr_info.flags.is_volatile, |
| 5837 | const hi12: u12 = @intCast(error_offset >> 12); | 5837 | }); |
| 5838 | if (hi12 > 0) try isel.emit(.add( | 5838 | try error_union_ptr_mat.finish(isel); |
| 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 | } | | |
| 5847 | } | 5839 | } |
| 5848 | if (air.next()) |next_air_tag| continue :air_tag next_air_tag; | 5840 | if (air.next()) |next_air_tag| continue :air_tag next_air_tag; |
| 5849 | }, | 5841 | }, |
| ... | @@ -8011,6 +8003,7 @@ pub fn layout( | ... | @@ -8011,6 +8003,7 @@ pub fn layout( |
| 8011 | while (save_index < saves.len) { | 8003 | while (save_index < saves.len) { |
| 8012 | if (save_index + 2 <= saves.len and saves[save_index + 1].needs_restore and | 8004 | if (save_index + 2 <= saves.len and saves[save_index + 1].needs_restore and |
| 8013 | saves[save_index + 0].class == saves[save_index + 1].class and | 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 | saves[save_index + 0].offset + saves[save_index + 0].size == saves[save_index + 1].offset) | 8007 | saves[save_index + 0].offset + saves[save_index + 0].size == saves[save_index + 1].offset) |
| 8015 | { | 8008 | { |
| 8016 | try isel.emit(.ldp( | 8009 | try isel.emit(.ldp( |
| ... | @@ -8317,7 +8310,7 @@ fn elemPtr( | ... | @@ -8317,7 +8310,7 @@ fn elemPtr( |
| 8317 | }), | 8310 | }), |
| 8318 | 2 => { | 8311 | 2 => { |
| 8319 | const shift: u6 = @intCast(@ctz(elem_size)); | 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 | .add => switch (base_ra) { | 8314 | .add => switch (base_ra) { |
| 8322 | else => { | 8315 | else => { |
| 8323 | const temp_ra = try isel.allocIntReg(); | 8316 | const temp_ra = try isel.allocIntReg(); |
| ... | @@ -8326,7 +8319,7 @@ fn elemPtr( | ... | @@ -8326,7 +8319,7 @@ fn elemPtr( |
| 8326 | .register = temp_ra.x(), | 8319 | .register = temp_ra.x(), |
| 8327 | .shift = .{ .lsl = shift }, | 8320 | .shift = .{ .lsl = shift }, |
| 8328 | } })); | 8321 | } })); |
| 8329 | break :temp_ra temp_ra; | 8322 | break :temp_ra .{ temp_ra, true }; |
| 8330 | }, | 8323 | }, |
| 8331 | .zr => { | 8324 | .zr => { |
| 8332 | if (shift > 0) try isel.emit(.ubfm(elem_ptr_ra.x(), elem_ptr_ra.x(), .{ | 8325 | if (shift > 0) try isel.emit(.ubfm(elem_ptr_ra.x(), elem_ptr_ra.x(), .{ |
| ... | @@ -8334,7 +8327,7 @@ fn elemPtr( | ... | @@ -8334,7 +8327,7 @@ fn elemPtr( |
| 8334 | .immr = -%shift, | 8327 | .immr = -%shift, |
| 8335 | .imms = ~shift, | 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 | .sub => { | 8333 | .sub => { |
| ... | @@ -8344,10 +8337,10 @@ fn elemPtr( | ... | @@ -8344,10 +8337,10 @@ fn elemPtr( |
| 8344 | .register = temp_ra.x(), | 8337 | .register = temp_ra.x(), |
| 8345 | .shift = .{ .lsl = shift }, | 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 | try isel.emit(.add(temp_ra.x(), index_mat.ra.x(), .{ .shifted_register = .{ | 8344 | try isel.emit(.add(temp_ra.x(), index_mat.ra.x(), .{ .shifted_register = .{ |
| 8352 | .register = index_mat.ra.x(), | 8345 | .register = index_mat.ra.x(), |
| 8353 | .shift = .{ .lsl = @intCast(63 - @clz(elem_size) - shift) }, | 8346 | .shift = .{ .lsl = @intCast(63 - @clz(elem_size) - shift) }, |
| ... | @@ -9276,7 +9269,14 @@ pub const Value = struct { | ... | @@ -9276,7 +9269,14 @@ pub const Value = struct { |
| 9276 | part_offset -= part_size; | 9269 | part_offset -= part_size; |
| 9277 | var wrapped_res_part_it = res_vi.field(ty, part_offset, part_size); | 9270 | var wrapped_res_part_it = res_vi.field(ty, part_offset, part_size); |
| 9278 | const wrapped_res_part_vi = try wrapped_res_part_it.only(isel); | 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 | const unwrapped_res_part_ra = unwrapped_res_part_ra: { | 9280 | const unwrapped_res_part_ra = unwrapped_res_part_ra: { |
| 9281 | if (!need_wrap) break :unwrapped_res_part_ra wrapped_res_part_ra; | 9281 | if (!need_wrap) break :unwrapped_res_part_ra wrapped_res_part_ra; |
| 9282 | if (int_info.bits % 32 == 0) { | 9282 | if (int_info.bits % 32 == 0) { |