| ... | @@ -3798,11 +3798,13 @@ fn airShlSat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3798,11 +3798,13 @@ fn airShlSat(self: *Self, inst: Air.Inst.Index) !void { |
| 3798 | } | 3798 | } |
| 3799 | | 3799 | |
| 3800 | fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void { | 3800 | fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void { |
| | 3801 | const mod = self.bin_file.options.module.?; |
| 3801 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 3802 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 3802 | const result: MCValue = result: { | 3803 | const result: MCValue = result: { |
| 3803 | const pl_ty = self.typeOfIndex(inst); | 3804 | const pl_ty = self.typeOfIndex(inst); |
| 3804 | const opt_mcv = try self.resolveInst(ty_op.operand); | 3805 | if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .none; |
| 3805 | | 3806 | |
| | 3807 | const opt_mcv = try self.resolveInst(ty_op.operand); |
| 3806 | if (self.reuseOperand(inst, ty_op.operand, 0, opt_mcv)) { | 3808 | if (self.reuseOperand(inst, ty_op.operand, 0, opt_mcv)) { |
| 3807 | switch (opt_mcv) { | 3809 | switch (opt_mcv) { |
| 3808 | .register => |reg| try self.truncateRegister(pl_ty, reg), | 3810 | .register => |reg| try self.truncateRegister(pl_ty, reg), |
| ... | @@ -11521,10 +11523,13 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal | ... | @@ -11521,10 +11523,13 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal |
| 11521 | .undef => {}, | 11523 | .undef => {}, |
| 11522 | .immediate => |imm| switch (abi_size) { | 11524 | .immediate => |imm| switch (abi_size) { |
| 11523 | 1, 2, 4 => { | 11525 | 1, 2, 4 => { |
| 11524 | const immediate = if (ty.isSignedInt(mod)) | 11526 | const immediate = switch (if (ty.isAbiInt(mod)) |
| 11525 | Immediate.s(@truncate(@as(i64, @bitCast(imm)))) | 11527 | ty.intInfo(mod).signedness |
| 11526 | else | 11528 | else |
| 11527 | Immediate.u(@as(u32, @intCast(imm))); | 11529 | .unsigned) { |
| | 11530 | .signed => Immediate.s(@truncate(@as(i64, @bitCast(imm)))), |
| | 11531 | .unsigned => Immediate.u(@as(u32, @intCast(imm))), |
| | 11532 | }; |
| 11528 | try self.asmMemoryImmediate( | 11533 | try self.asmMemoryImmediate( |
| 11529 | .{ ._, .mov }, | 11534 | .{ ._, .mov }, |
| 11530 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = base, .disp = disp }), | 11535 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = base, .disp = disp }), |
| ... | @@ -11586,19 +11591,35 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal | ... | @@ -11586,19 +11591,35 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal |
| 11586 | .{ .base = base, .disp = disp + @as(i32, @intCast(src_reg_i * 8)) }, | 11591 | .{ .base = base, .disp = disp + @as(i32, @intCast(src_reg_i * 8)) }, |
| 11587 | ), registerAlias(src_reg, part_size)); | 11592 | ), registerAlias(src_reg, part_size)); |
| 11588 | }, | 11593 | }, |
| 11589 | .register_overflow => |ro| { | 11594 | .register_overflow => |ro| switch (ty.zigTypeTag(mod)) { |
| 11590 | try self.genSetMem( | 11595 | .Struct => { |
| 11591 | base, | 11596 | try self.genSetMem( |
| 11592 | disp + @as(i32, @intCast(ty.structFieldOffset(0, mod))), | 11597 | base, |
| 11593 | ty.structFieldType(0, mod), | 11598 | disp + @as(i32, @intCast(ty.structFieldOffset(0, mod))), |
| 11594 | .{ .register = ro.reg }, | 11599 | ty.structFieldType(0, mod), |
| 11595 | ); | 11600 | .{ .register = ro.reg }, |
| 11596 | try self.genSetMem( | 11601 | ); |
| 11597 | base, | 11602 | try self.genSetMem( |
| 11598 | disp + @as(i32, @intCast(ty.structFieldOffset(1, mod))), | 11603 | base, |
| 11599 | ty.structFieldType(1, mod), | 11604 | disp + @as(i32, @intCast(ty.structFieldOffset(1, mod))), |
| 11600 | .{ .eflags = ro.eflags }, | 11605 | ty.structFieldType(1, mod), |
| 11601 | ); | 11606 | .{ .eflags = ro.eflags }, |
| | 11607 | ); |
| | 11608 | }, |
| | 11609 | .Optional => { |
| | 11610 | assert(!ty.optionalReprIsPayload(mod)); |
| | 11611 | const child_ty = ty.optionalChild(mod); |
| | 11612 | try self.genSetMem(base, disp, child_ty, .{ .register = ro.reg }); |
| | 11613 | try self.genSetMem( |
| | 11614 | base, |
| | 11615 | disp + @as(i32, @intCast(child_ty.abiSize(mod))), |
| | 11616 | Type.bool, |
| | 11617 | .{ .eflags = ro.eflags }, |
| | 11618 | ); |
| | 11619 | }, |
| | 11620 | else => return self.fail("TODO implement genSetMem for {s} of {}", .{ |
| | 11621 | @tagName(src_mcv), ty.fmt(mod), |
| | 11622 | }), |
| 11602 | }, | 11623 | }, |
| 11603 | .register_offset, | 11624 | .register_offset, |
| 11604 | .memory, | 11625 | .memory, |