| ... | ... | @@ -920,9 +920,6 @@ fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue { |
| 920 | 920 | const mod = self.bin_file.options.module.?; |
| 921 | 921 | return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)}); |
| 922 | 922 | }; |
| 923 | | const abi_align = elem_ty.abiAlignment(self.target.*); |
| 924 | | if (abi_align > self.stack_align) |
| 925 | | self.stack_align = abi_align; |
| 926 | 923 | |
| 927 | 924 | if (reg_ok) { |
| 928 | 925 | switch (elem_ty.zigTypeTag()) { |
| ... | ... | @@ -951,6 +948,10 @@ fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue { |
| 951 | 948 | }, |
| 952 | 949 | } |
| 953 | 950 | } |
| 951 | |
| 952 | const abi_align = elem_ty.abiAlignment(self.target.*); |
| 953 | if (abi_align > self.stack_align) |
| 954 | self.stack_align = abi_align; |
| 954 | 955 | const stack_offset = try self.allocMem(inst, abi_size, abi_align); |
| 955 | 956 | return MCValue{ .stack_offset = @intCast(i32, stack_offset) }; |
| 956 | 957 | } |
| ... | ... | @@ -990,7 +991,7 @@ fn revertState(self: *Self, state: State) void { |
| 990 | 991 | |
| 991 | 992 | pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void { |
| 992 | 993 | const stack_mcv = try self.allocRegOrMem(inst, false); |
| 993 | | log.debug("spilling {d} to stack mcv {any}", .{ inst, stack_mcv }); |
| 994 | log.debug("spilling %{d} to stack mcv {any}", .{ inst, stack_mcv }); |
| 994 | 995 | const reg_mcv = self.getResolvedInstValue(inst); |
| 995 | 996 | switch (reg_mcv) { |
| 996 | 997 | .register => |other| { |
| ... | ... | @@ -1016,7 +1017,7 @@ pub fn spillEflagsIfOccupied(self: *Self) !void { |
| 1016 | 1017 | }; |
| 1017 | 1018 | |
| 1018 | 1019 | try self.setRegOrMem(self.air.typeOfIndex(inst_to_save), new_mcv, mcv); |
| 1019 | | log.debug("spilling {d} to mcv {any}", .{ inst_to_save, new_mcv }); |
| 1020 | log.debug("spilling %{d} to mcv {any}", .{ inst_to_save, new_mcv }); |
| 1020 | 1021 | |
| 1021 | 1022 | const branch = &self.branch_stack.items[self.branch_stack.items.len - 1]; |
| 1022 | 1023 | try branch.inst_table.put(self.gpa, inst_to_save, new_mcv); |
| ... | ... | @@ -2114,6 +2115,7 @@ fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void { |
| 2114 | 2115 | }; |
| 2115 | 2116 | break :result dst_mcv; |
| 2116 | 2117 | }; |
| 2118 | log.debug("airSliceLen(%{d}): {}", .{ inst, result }); |
| 2117 | 2119 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 2118 | 2120 | } |
| 2119 | 2121 | |
| ... | ... | @@ -2641,6 +2643,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo |
| 2641 | 2643 | fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 2642 | 2644 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 2643 | 2645 | const elem_ty = self.air.typeOfIndex(inst); |
| 2646 | const elem_size = elem_ty.abiSize(self.target.*); |
| 2644 | 2647 | const result: MCValue = result: { |
| 2645 | 2648 | if (!elem_ty.hasRuntimeBitsIgnoreComptime()) |
| 2646 | 2649 | break :result MCValue.none; |
| ... | ... | @@ -2651,13 +2654,14 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 2651 | 2654 | break :result MCValue.dead; |
| 2652 | 2655 | |
| 2653 | 2656 | const dst_mcv: MCValue = blk: { |
| 2654 | | if (self.reuseOperand(inst, ty_op.operand, 0, ptr)) { |
| 2657 | if (elem_size <= 8 and self.reuseOperand(inst, ty_op.operand, 0, ptr)) { |
| 2655 | 2658 | // The MCValue that holds the pointer can be re-used as the value. |
| 2656 | 2659 | break :blk ptr; |
| 2657 | 2660 | } else { |
| 2658 | 2661 | break :blk try self.allocRegOrMem(inst, true); |
| 2659 | 2662 | } |
| 2660 | 2663 | }; |
| 2664 | log.debug("airLoad(%{d}): {} <- {}", .{ inst, dst_mcv, ptr }); |
| 2661 | 2665 | try self.load(dst_mcv, ptr, self.air.typeOf(ty_op.operand)); |
| 2662 | 2666 | break :result dst_mcv; |
| 2663 | 2667 | }; |
| ... | ... | @@ -2728,10 +2732,12 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 2728 | 2732 | |
| 2729 | 2733 | switch (value) { |
| 2730 | 2734 | .none => unreachable, |
| 2731 | | .undef => unreachable, |
| 2732 | 2735 | .dead => unreachable, |
| 2733 | 2736 | .unreach => unreachable, |
| 2734 | 2737 | .eflags => unreachable, |
| 2738 | .undef => { |
| 2739 | try self.genSetReg(value_ty, reg, value); |
| 2740 | }, |
| 2735 | 2741 | .immediate => |imm| { |
| 2736 | 2742 | switch (abi_size) { |
| 2737 | 2743 | 1, 2, 4 => { |
| ... | ... | @@ -2773,6 +2779,30 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 2773 | 2779 | .register => |src_reg| { |
| 2774 | 2780 | try self.genInlineMemcpyRegisterRegister(value_ty, reg, src_reg, 0); |
| 2775 | 2781 | }, |
| 2782 | .register_overflow => |ro| { |
| 2783 | const ro_reg_lock = self.register_manager.lockReg(ro.reg); |
| 2784 | defer if (ro_reg_lock) |lock| self.register_manager.unlockReg(lock); |
| 2785 | |
| 2786 | const wrapped_ty = value_ty.structFieldType(0); |
| 2787 | try self.genInlineMemcpyRegisterRegister(wrapped_ty, reg, ro.reg, 0); |
| 2788 | |
| 2789 | const overflow_bit_ty = value_ty.structFieldType(1); |
| 2790 | const overflow_bit_offset = value_ty.structFieldOffset(1, self.target.*); |
| 2791 | const tmp_reg = try self.register_manager.allocReg(null, gp); |
| 2792 | _ = try self.addInst(.{ |
| 2793 | .tag = .cond_set_byte, |
| 2794 | .ops = Mir.Inst.Ops.encode(.{ |
| 2795 | .reg1 = tmp_reg.to8(), |
| 2796 | }), |
| 2797 | .data = .{ .cc = ro.eflags }, |
| 2798 | }); |
| 2799 | try self.genInlineMemcpyRegisterRegister( |
| 2800 | overflow_bit_ty, |
| 2801 | reg, |
| 2802 | tmp_reg, |
| 2803 | -@intCast(i32, overflow_bit_offset), |
| 2804 | ); |
| 2805 | }, |
| 2776 | 2806 | .linker_load, |
| 2777 | 2807 | .memory, |
| 2778 | 2808 | .stack_offset, |
| ... | ... | @@ -2787,8 +2817,9 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 2787 | 2817 | .dest_stack_base = reg.to64(), |
| 2788 | 2818 | }); |
| 2789 | 2819 | }, |
| 2790 | | else => |other| { |
| 2791 | | return self.fail("TODO implement set pointee with {}", .{other}); |
| 2820 | .ptr_stack_offset => { |
| 2821 | const tmp_reg = try self.copyToTmpRegister(value_ty, value); |
| 2822 | return self.store(ptr, .{ .register = tmp_reg }, ptr_ty, value_ty); |
| 2792 | 2823 | }, |
| 2793 | 2824 | } |
| 2794 | 2825 | }, |
| ... | ... | @@ -2902,6 +2933,7 @@ fn airStore(self: *Self, inst: Air.Inst.Index) !void { |
| 2902 | 2933 | const ptr_ty = self.air.typeOf(bin_op.lhs); |
| 2903 | 2934 | const value = try self.resolveInst(bin_op.rhs); |
| 2904 | 2935 | const value_ty = self.air.typeOf(bin_op.rhs); |
| 2936 | log.debug("airStore(%{d}): {} <- {}", .{ inst, ptr, value }); |
| 2905 | 2937 | try self.store(ptr, value, ptr_ty, value_ty); |
| 2906 | 2938 | return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 2907 | 2939 | } |
| ... | ... | @@ -6321,7 +6353,22 @@ fn airPtrToInt(self: *Self, inst: Air.Inst.Index) !void { |
| 6321 | 6353 | |
| 6322 | 6354 | fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { |
| 6323 | 6355 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 6324 | | const result = try self.resolveInst(ty_op.operand); |
| 6356 | const result = if (self.liveness.isUnused(inst)) .dead else result: { |
| 6357 | const operand = try self.resolveInst(ty_op.operand); |
| 6358 | if (self.reuseOperand(inst, ty_op.operand, 0, operand)) break :result operand; |
| 6359 | |
| 6360 | const operand_lock = switch (operand) { |
| 6361 | .register => |reg| self.register_manager.lockReg(reg), |
| 6362 | .register_overflow => |ro| self.register_manager.lockReg(ro.reg), |
| 6363 | else => null, |
| 6364 | }; |
| 6365 | defer if (operand_lock) |lock| self.register_manager.unlockReg(lock); |
| 6366 | |
| 6367 | const dest = try self.allocRegOrMem(inst, true); |
| 6368 | try self.setRegOrMem(self.air.typeOfIndex(inst), dest, operand); |
| 6369 | break :result dest; |
| 6370 | }; |
| 6371 | log.debug("airBitCast(%{d}): {}", .{ inst, result }); |
| 6325 | 6372 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 6326 | 6373 | } |
| 6327 | 6374 | |