| ... | @@ -537,7 +537,7 @@ const InstTracking = struct { | ... | @@ -537,7 +537,7 @@ const InstTracking = struct { |
| 537 | else => unreachable, | 537 | else => unreachable, |
| 538 | } | 538 | } |
| 539 | tracking_log.debug("spill %{d} from {} to {}", .{ inst, self.short, self.long }); | 539 | tracking_log.debug("spill %{d} from {} to {}", .{ inst, self.short, self.long }); |
| 540 | try function.genCopy(function.typeOfIndex(inst), self.long, self.short); | 540 | try function.genCopy(function.typeOfIndex(inst), self.long, self.short, .{}); |
| 541 | } | 541 | } |
| 542 | | 542 | |
| 543 | fn reuseFrame(self: *InstTracking) void { | 543 | fn reuseFrame(self: *InstTracking) void { |
| ... | @@ -637,8 +637,8 @@ const InstTracking = struct { | ... | @@ -637,8 +637,8 @@ const InstTracking = struct { |
| 637 | ) !void { | 637 | ) !void { |
| 638 | const ty = function.typeOfIndex(inst); | 638 | const ty = function.typeOfIndex(inst); |
| 639 | if ((self.long == .none or self.long == .reserved_frame) and target.long == .load_frame) | 639 | if ((self.long == .none or self.long == .reserved_frame) and target.long == .load_frame) |
| 640 | try function.genCopy(ty, target.long, self.short); | 640 | try function.genCopy(ty, target.long, self.short, .{}); |
| 641 | try function.genCopy(ty, target.short, self.short); | 641 | try function.genCopy(ty, target.short, self.short, .{}); |
| 642 | } | 642 | } |
| 643 | | 643 | |
| 644 | fn trackMaterialize(self: *InstTracking, inst: Air.Inst.Index, target: InstTracking) void { | 644 | fn trackMaterialize(self: *InstTracking, inst: Air.Inst.Index, target: InstTracking) void { |
| ... | @@ -1717,6 +1717,7 @@ fn gen(self: *Self) InnerError!void { | ... | @@ -1717,6 +1717,7 @@ fn gen(self: *Self) InnerError!void { |
| 1717 | 0, | 1717 | 0, |
| 1718 | Type.usize, | 1718 | Type.usize, |
| 1719 | self.ret_mcv.long.address().offset(-self.ret_mcv.short.indirect.off), | 1719 | self.ret_mcv.long.address().offset(-self.ret_mcv.short.indirect.off), |
| | 1720 | .{}, |
| 1720 | ); | 1721 | ); |
| 1721 | self.ret_mcv.long = .{ .load_frame = .{ .index = frame_index } }; | 1722 | self.ret_mcv.long = .{ .load_frame = .{ .index = frame_index } }; |
| 1722 | tracking_log.debug("spill {} to {}", .{ self.ret_mcv.long, frame_index }); | 1723 | tracking_log.debug("spill {} to {}", .{ self.ret_mcv.long, frame_index }); |
| ... | @@ -1740,6 +1741,7 @@ fn gen(self: *Self) InnerError!void { | ... | @@ -1740,6 +1741,7 @@ fn gen(self: *Self) InnerError!void { |
| 1740 | @intCast(reg_i * 8), | 1741 | @intCast(reg_i * 8), |
| 1741 | Type.usize, | 1742 | Type.usize, |
| 1742 | .{ .register = reg }, | 1743 | .{ .register = reg }, |
| | 1744 | .{}, |
| 1743 | ); | 1745 | ); |
| 1744 | | 1746 | |
| 1745 | try self.asmRegisterImmediate(.{ ._, .cmp }, .al, Immediate.u(info.fp_count)); | 1747 | try self.asmRegisterImmediate(.{ ._, .cmp }, .al, Immediate.u(info.fp_count)); |
| ... | @@ -1752,6 +1754,7 @@ fn gen(self: *Self) InnerError!void { | ... | @@ -1752,6 +1754,7 @@ fn gen(self: *Self) InnerError!void { |
| 1752 | @intCast(abi.SysV.c_abi_int_param_regs.len * 8 + reg_i * 16), | 1754 | @intCast(abi.SysV.c_abi_int_param_regs.len * 8 + reg_i * 16), |
| 1753 | vec_2_f64, | 1755 | vec_2_f64, |
| 1754 | .{ .register = reg }, | 1756 | .{ .register = reg }, |
| | 1757 | .{}, |
| 1755 | ); | 1758 | ); |
| 1756 | | 1759 | |
| 1757 | try self.performReloc(skip_sse_reloc); | 1760 | try self.performReloc(skip_sse_reloc); |
| ... | @@ -2006,8 +2009,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -2006,8 +2009,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 2006 | .load => try self.airLoad(inst), | 2009 | .load => try self.airLoad(inst), |
| 2007 | .loop => try self.airLoop(inst), | 2010 | .loop => try self.airLoop(inst), |
| 2008 | .int_from_ptr => try self.airIntFromPtr(inst), | 2011 | .int_from_ptr => try self.airIntFromPtr(inst), |
| 2009 | .ret => try self.airRet(inst), | 2012 | .ret => try self.airRet(inst, false), |
| 2010 | .ret_safe => try self.airRet(inst), // TODO | 2013 | .ret_safe => try self.airRet(inst, true), |
| 2011 | .ret_load => try self.airRetLoad(inst), | 2014 | .ret_load => try self.airRetLoad(inst), |
| 2012 | .store => try self.airStore(inst, false), | 2015 | .store => try self.airStore(inst, false), |
| 2013 | .store_safe => try self.airStore(inst, true), | 2016 | .store_safe => try self.airStore(inst, true), |
| ... | @@ -2209,8 +2212,15 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void { | ... | @@ -2209,8 +2212,15 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void { |
| 2209 | 0, | 2212 | 0, |
| 2210 | Type.usize, | 2213 | Type.usize, |
| 2211 | .{ .register_offset = .{ .reg = data_reg, .off = data_off } }, | 2214 | .{ .register_offset = .{ .reg = data_reg, .off = data_off } }, |
| | 2215 | .{}, |
| | 2216 | ); |
| | 2217 | try self.genSetMem( |
| | 2218 | .{ .reg = ret_reg }, |
| | 2219 | 8, |
| | 2220 | Type.usize, |
| | 2221 | .{ .immediate = tag_name.len }, |
| | 2222 | .{}, |
| 2212 | ); | 2223 | ); |
| 2213 | try self.genSetMem(.{ .reg = ret_reg }, 8, Type.usize, .{ .immediate = tag_name.len }); | | |
| 2214 | | 2224 | |
| 2215 | exitlude_jump_reloc.* = try self.asmJmpReloc(undefined); | 2225 | exitlude_jump_reloc.* = try self.asmJmpReloc(undefined); |
| 2216 | try self.performReloc(skip_reloc); | 2226 | try self.performReloc(skip_reloc); |
| ... | @@ -2651,7 +2661,7 @@ pub fn spillRegisters(self: *Self, comptime registers: []const Register) !void { | ... | @@ -2651,7 +2661,7 @@ pub fn spillRegisters(self: *Self, comptime registers: []const Register) !void { |
| 2651 | /// This can have a side effect of spilling instructions to the stack to free up a register. | 2661 | /// This can have a side effect of spilling instructions to the stack to free up a register. |
| 2652 | fn copyToTmpRegister(self: *Self, ty: Type, mcv: MCValue) !Register { | 2662 | fn copyToTmpRegister(self: *Self, ty: Type, mcv: MCValue) !Register { |
| 2653 | const reg = try self.register_manager.allocReg(null, self.regClassForType(ty)); | 2663 | const reg = try self.register_manager.allocReg(null, self.regClassForType(ty)); |
| 2654 | try self.genSetReg(reg, ty, mcv); | 2664 | try self.genSetReg(reg, ty, mcv, .{}); |
| 2655 | return reg; | 2665 | return reg; |
| 2656 | } | 2666 | } |
| 2657 | | 2667 | |
| ... | @@ -2666,7 +2676,7 @@ fn copyToRegisterWithInstTracking( | ... | @@ -2666,7 +2676,7 @@ fn copyToRegisterWithInstTracking( |
| 2666 | mcv: MCValue, | 2676 | mcv: MCValue, |
| 2667 | ) !MCValue { | 2677 | ) !MCValue { |
| 2668 | const reg: Register = try self.register_manager.allocReg(reg_owner, self.regClassForType(ty)); | 2678 | const reg: Register = try self.register_manager.allocReg(reg_owner, self.regClassForType(ty)); |
| 2669 | try self.genSetReg(reg, ty, mcv); | 2679 | try self.genSetReg(reg, ty, mcv, .{}); |
| 2670 | return MCValue{ .register = reg }; | 2680 | return MCValue{ .register = reg }; |
| 2671 | } | 2681 | } |
| 2672 | | 2682 | |
| ... | @@ -2919,7 +2929,7 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2919,7 +2929,7 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { |
| 2919 | math.divCeil(u32, src_storage_bits, 64) catch unreachable and | 2929 | math.divCeil(u32, src_storage_bits, 64) catch unreachable and |
| 2920 | self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) src_mcv else dst: { | 2930 | self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) src_mcv else dst: { |
| 2921 | const dst_mcv = try self.allocRegOrMem(inst, true); | 2931 | const dst_mcv = try self.allocRegOrMem(inst, true); |
| 2922 | try self.genCopy(min_ty, dst_mcv, src_mcv); | 2932 | try self.genCopy(min_ty, dst_mcv, src_mcv, .{}); |
| 2923 | break :dst dst_mcv; | 2933 | break :dst dst_mcv; |
| 2924 | }; | 2934 | }; |
| 2925 | | 2935 | |
| ... | @@ -2954,7 +2964,7 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2954,7 +2964,7 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { |
| 2954 | if (high_bits > 0) { | 2964 | if (high_bits > 0) { |
| 2955 | try self.truncateRegister(src_ty, high_reg); | 2965 | try self.truncateRegister(src_ty, high_reg); |
| 2956 | const high_ty = if (dst_int_info.bits >= 64) Type.usize else dst_ty; | 2966 | const high_ty = if (dst_int_info.bits >= 64) Type.usize else dst_ty; |
| 2957 | try self.genCopy(high_ty, high_mcv, .{ .register = high_reg }); | 2967 | try self.genCopy(high_ty, high_mcv, .{ .register = high_reg }, .{}); |
| 2958 | } | 2968 | } |
| 2959 | | 2969 | |
| 2960 | if (dst_limbs_len > src_limbs_len) try self.genInlineMemset( | 2970 | if (dst_limbs_len > src_limbs_len) try self.genInlineMemset( |
| ... | @@ -2973,6 +2983,7 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2973,6 +2983,7 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { |
| 2973 | .unsigned => .{ .immediate = 0 }, | 2983 | .unsigned => .{ .immediate = 0 }, |
| 2974 | }, | 2984 | }, |
| 2975 | .{ .immediate = (dst_limbs_len - src_limbs_len) * 8 }, | 2985 | .{ .immediate = (dst_limbs_len - src_limbs_len) * 8 }, |
| | 2986 | .{}, |
| 2976 | ); | 2987 | ); |
| 2977 | | 2988 | |
| 2978 | break :result dst_mcv; | 2989 | break :result dst_mcv; |
| ... | @@ -3006,7 +3017,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3006,7 +3017,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { |
| 3006 | const dst_locks = self.register_manager.lockRegsAssumeUnused(2, dst_regs); | 3017 | const dst_locks = self.register_manager.lockRegsAssumeUnused(2, dst_regs); |
| 3007 | defer for (dst_locks) |lock| self.register_manager.unlockReg(lock); | 3018 | defer for (dst_locks) |lock| self.register_manager.unlockReg(lock); |
| 3008 | | 3019 | |
| 3009 | try self.genCopy(dst_ty, dst_mcv, src_mcv); | 3020 | try self.genCopy(dst_ty, dst_mcv, src_mcv, .{}); |
| 3010 | break :dst dst_mcv; | 3021 | break :dst dst_mcv; |
| 3011 | } else try self.allocRegOrMem(inst, true); | 3022 | } else try self.allocRegOrMem(inst, true); |
| 3012 | | 3023 | |
| ... | @@ -3082,11 +3093,15 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3082,11 +3093,15 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { |
| 3082 | // when truncating a `u16` to `u5`, for example, those top 3 bits in the result | 3093 | // when truncating a `u16` to `u5`, for example, those top 3 bits in the result |
| 3083 | // have to be removed. this only happens if the dst if not a power-of-two size. | 3094 | // have to be removed. this only happens if the dst if not a power-of-two size. |
| 3084 | if (dst_abi_size <= 8) { | 3095 | if (dst_abi_size <= 8) { |
| 3085 | if (self.regExtraBits(dst_ty) > 0) try self.truncateRegister(dst_ty, dst_mcv.register.to64()); | 3096 | if (self.regExtraBits(dst_ty) > 0) { |
| | 3097 | try self.truncateRegister(dst_ty, dst_mcv.register.to64()); |
| | 3098 | } |
| 3086 | } else if (dst_abi_size <= 16) { | 3099 | } else if (dst_abi_size <= 16) { |
| 3087 | const dst_info = dst_ty.intInfo(mod); | 3100 | const dst_info = dst_ty.intInfo(mod); |
| 3088 | const high_ty = try mod.intType(dst_info.signedness, dst_info.bits - 64); | 3101 | const high_ty = try mod.intType(dst_info.signedness, dst_info.bits - 64); |
| 3089 | if (self.regExtraBits(high_ty) > 0) try self.truncateRegister(high_ty, dst_mcv.register_pair[1].to64()); | 3102 | if (self.regExtraBits(high_ty) > 0) { |
| | 3103 | try self.truncateRegister(high_ty, dst_mcv.register_pair[1].to64()); |
| | 3104 | } |
| 3090 | } | 3105 | } |
| 3091 | | 3106 | |
| 3092 | break :result dst_mcv; | 3107 | break :result dst_mcv; |
| ... | @@ -3116,7 +3131,7 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3116,7 +3131,7 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void { |
| 3116 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(slice_ty, mod)); | 3131 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(slice_ty, mod)); |
| 3117 | | 3132 | |
| 3118 | const ptr_ty = self.typeOf(bin_op.lhs); | 3133 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 3119 | try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, .{ .air_ref = bin_op.lhs }); | 3134 | try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, .{ .air_ref = bin_op.lhs }, .{}); |
| 3120 | | 3135 | |
| 3121 | const len_ty = self.typeOf(bin_op.rhs); | 3136 | const len_ty = self.typeOf(bin_op.rhs); |
| 3122 | try self.genSetMem( | 3137 | try self.genSetMem( |
| ... | @@ -3124,6 +3139,7 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3124,6 +3139,7 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void { |
| 3124 | @intCast(ptr_ty.abiSize(mod)), | 3139 | @intCast(ptr_ty.abiSize(mod)), |
| 3125 | len_ty, | 3140 | len_ty, |
| 3126 | .{ .air_ref = bin_op.rhs }, | 3141 | .{ .air_ref = bin_op.rhs }, |
| | 3142 | .{}, |
| 3127 | ); | 3143 | ); |
| 3128 | | 3144 | |
| 3129 | const result = MCValue{ .load_frame = .{ .index = frame_index } }; | 3145 | const result = MCValue{ .load_frame = .{ .index = frame_index } }; |
| ... | @@ -3161,9 +3177,9 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void { | ... | @@ -3161,9 +3177,9 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void { |
| 3161 | | 3177 | |
| 3162 | const hi_ty = try mod.intType(.unsigned, @intCast((dst_ty.bitSize(mod) - 1) % 64 + 1)); | 3178 | const hi_ty = try mod.intType(.unsigned, @intCast((dst_ty.bitSize(mod) - 1) % 64 + 1)); |
| 3163 | const hi_mcv = dst_mcv.address().offset(@intCast(bit_size / 64 * 8)).deref(); | 3179 | const hi_mcv = dst_mcv.address().offset(@intCast(bit_size / 64 * 8)).deref(); |
| 3164 | try self.genSetReg(tmp_reg, hi_ty, hi_mcv); | 3180 | try self.genSetReg(tmp_reg, hi_ty, hi_mcv, .{}); |
| 3165 | try self.truncateRegister(dst_ty, tmp_reg); | 3181 | try self.truncateRegister(dst_ty, tmp_reg); |
| 3166 | try self.genCopy(hi_ty, hi_mcv, .{ .register = tmp_reg }); | 3182 | try self.genCopy(hi_ty, hi_mcv, .{ .register = tmp_reg }, .{}); |
| 3167 | } | 3183 | } |
| 3168 | } | 3184 | } |
| 3169 | } | 3185 | } |
| ... | @@ -3476,7 +3492,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3476,7 +3492,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { |
| 3476 | if (reg_extra_bits > 0) { | 3492 | if (reg_extra_bits > 0) { |
| 3477 | try self.genShiftBinOpMir(.{ ._l, .sa }, ty, dst_mcv, .{ .immediate = reg_extra_bits }); | 3493 | try self.genShiftBinOpMir(.{ ._l, .sa }, ty, dst_mcv, .{ .immediate = reg_extra_bits }); |
| 3478 | } | 3494 | } |
| 3479 | try self.genSetReg(limit_reg, ty, dst_mcv); | 3495 | try self.genSetReg(limit_reg, ty, dst_mcv, .{}); |
| 3480 | try self.genShiftBinOpMir(.{ ._r, .sa }, ty, limit_mcv, .{ .immediate = reg_bits - 1 }); | 3496 | try self.genShiftBinOpMir(.{ ._r, .sa }, ty, limit_mcv, .{ .immediate = reg_bits - 1 }); |
| 3481 | try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, .{ | 3497 | try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, .{ |
| 3482 | .immediate = (@as(u64, 1) << @intCast(reg_bits - 1)) - 1, | 3498 | .immediate = (@as(u64, 1) << @intCast(reg_bits - 1)) - 1, |
| ... | @@ -3499,7 +3515,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3499,7 +3515,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { |
| 3499 | } else cc: { | 3515 | } else cc: { |
| 3500 | try self.genSetReg(limit_reg, ty, .{ | 3516 | try self.genSetReg(limit_reg, ty, .{ |
| 3501 | .immediate = @as(u64, math.maxInt(u64)) >> @intCast(64 - ty.bitSize(mod)), | 3517 | .immediate = @as(u64, math.maxInt(u64)) >> @intCast(64 - ty.bitSize(mod)), |
| 3502 | }); | 3518 | }, .{}); |
| 3503 | | 3519 | |
| 3504 | try self.genBinOpMir(.{ ._, .add }, ty, dst_mcv, rhs_mcv); | 3520 | try self.genBinOpMir(.{ ._, .add }, ty, dst_mcv, rhs_mcv); |
| 3505 | if (reg_extra_bits > 0) { | 3521 | if (reg_extra_bits > 0) { |
| ... | @@ -3559,7 +3575,7 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3559,7 +3575,7 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void { |
| 3559 | if (reg_extra_bits > 0) { | 3575 | if (reg_extra_bits > 0) { |
| 3560 | try self.genShiftBinOpMir(.{ ._l, .sa }, ty, dst_mcv, .{ .immediate = reg_extra_bits }); | 3576 | try self.genShiftBinOpMir(.{ ._l, .sa }, ty, dst_mcv, .{ .immediate = reg_extra_bits }); |
| 3561 | } | 3577 | } |
| 3562 | try self.genSetReg(limit_reg, ty, dst_mcv); | 3578 | try self.genSetReg(limit_reg, ty, dst_mcv, .{}); |
| 3563 | try self.genShiftBinOpMir(.{ ._r, .sa }, ty, limit_mcv, .{ .immediate = reg_bits - 1 }); | 3579 | try self.genShiftBinOpMir(.{ ._r, .sa }, ty, limit_mcv, .{ .immediate = reg_bits - 1 }); |
| 3564 | try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, .{ | 3580 | try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, .{ |
| 3565 | .immediate = (@as(u64, 1) << @intCast(reg_bits - 1)) - 1, | 3581 | .immediate = (@as(u64, 1) << @intCast(reg_bits - 1)) - 1, |
| ... | @@ -3580,7 +3596,7 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3580,7 +3596,7 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void { |
| 3580 | } else try self.genBinOpMir(.{ ._, .sub }, ty, dst_mcv, rhs_mcv); | 3596 | } else try self.genBinOpMir(.{ ._, .sub }, ty, dst_mcv, rhs_mcv); |
| 3581 | break :cc .o; | 3597 | break :cc .o; |
| 3582 | } else cc: { | 3598 | } else cc: { |
| 3583 | try self.genSetReg(limit_reg, ty, .{ .immediate = 0 }); | 3599 | try self.genSetReg(limit_reg, ty, .{ .immediate = 0 }, .{}); |
| 3584 | try self.genBinOpMir(.{ ._, .sub }, ty, dst_mcv, rhs_mcv); | 3600 | try self.genBinOpMir(.{ ._, .sub }, ty, dst_mcv, rhs_mcv); |
| 3585 | break :cc .c; | 3601 | break :cc .c; |
| 3586 | }; | 3602 | }; |
| ... | @@ -3713,7 +3729,7 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3713,7 +3729,7 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void { |
| 3713 | | 3729 | |
| 3714 | const reg_bits = self.regBitSize(ty); | 3730 | const reg_bits = self.regBitSize(ty); |
| 3715 | const cc: Condition = if (ty.isSignedInt(mod)) cc: { | 3731 | const cc: Condition = if (ty.isSignedInt(mod)) cc: { |
| 3716 | try self.genSetReg(limit_reg, ty, lhs_mcv); | 3732 | try self.genSetReg(limit_reg, ty, lhs_mcv, .{}); |
| 3717 | try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, rhs_mcv); | 3733 | try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, rhs_mcv); |
| 3718 | try self.genShiftBinOpMir(.{ ._r, .sa }, ty, limit_mcv, .{ .immediate = reg_bits - 1 }); | 3734 | try self.genShiftBinOpMir(.{ ._r, .sa }, ty, limit_mcv, .{ .immediate = reg_bits - 1 }); |
| 3719 | try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, .{ | 3735 | try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, .{ |
| ... | @@ -3723,7 +3739,7 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3723,7 +3739,7 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void { |
| 3723 | } else cc: { | 3739 | } else cc: { |
| 3724 | try self.genSetReg(limit_reg, ty, .{ | 3740 | try self.genSetReg(limit_reg, ty, .{ |
| 3725 | .immediate = @as(u64, math.maxInt(u64)) >> @intCast(64 - reg_bits), | 3741 | .immediate = @as(u64, math.maxInt(u64)) >> @intCast(64 - reg_bits), |
| 3726 | }); | 3742 | }, .{}); |
| 3727 | break :cc .c; | 3743 | break :cc .c; |
| 3728 | }; | 3744 | }; |
| 3729 | | 3745 | |
| ... | @@ -3779,12 +3795,14 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3779,12 +3795,14 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 3779 | @intCast(tuple_ty.structFieldOffset(1, mod)), | 3795 | @intCast(tuple_ty.structFieldOffset(1, mod)), |
| 3780 | Type.u1, | 3796 | Type.u1, |
| 3781 | .{ .eflags = cc }, | 3797 | .{ .eflags = cc }, |
| | 3798 | .{}, |
| 3782 | ); | 3799 | ); |
| 3783 | try self.genSetMem( | 3800 | try self.genSetMem( |
| 3784 | .{ .frame = frame_index }, | 3801 | .{ .frame = frame_index }, |
| 3785 | @intCast(tuple_ty.structFieldOffset(0, mod)), | 3802 | @intCast(tuple_ty.structFieldOffset(0, mod)), |
| 3786 | ty, | 3803 | ty, |
| 3787 | partial_mcv, | 3804 | partial_mcv, |
| | 3805 | .{}, |
| 3788 | ); | 3806 | ); |
| 3789 | break :result .{ .load_frame = .{ .index = frame_index } }; | 3807 | break :result .{ .load_frame = .{ .index = frame_index } }; |
| 3790 | } | 3808 | } |
| ... | @@ -3852,12 +3870,14 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3852,12 +3870,14 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 3852 | @intCast(tuple_ty.structFieldOffset(1, mod)), | 3870 | @intCast(tuple_ty.structFieldOffset(1, mod)), |
| 3853 | tuple_ty.structFieldType(1, mod), | 3871 | tuple_ty.structFieldType(1, mod), |
| 3854 | .{ .eflags = cc }, | 3872 | .{ .eflags = cc }, |
| | 3873 | .{}, |
| 3855 | ); | 3874 | ); |
| 3856 | try self.genSetMem( | 3875 | try self.genSetMem( |
| 3857 | .{ .frame = frame_index }, | 3876 | .{ .frame = frame_index }, |
| 3858 | @intCast(tuple_ty.structFieldOffset(0, mod)), | 3877 | @intCast(tuple_ty.structFieldOffset(0, mod)), |
| 3859 | tuple_ty.structFieldType(0, mod), | 3878 | tuple_ty.structFieldType(0, mod), |
| 3860 | partial_mcv, | 3879 | partial_mcv, |
| | 3880 | .{}, |
| 3861 | ); | 3881 | ); |
| 3862 | break :result .{ .load_frame = .{ .index = frame_index } }; | 3882 | break :result .{ .load_frame = .{ .index = frame_index } }; |
| 3863 | } | 3883 | } |
| ... | @@ -3912,7 +3932,7 @@ fn genSetFrameTruncatedOverflowCompare( | ... | @@ -3912,7 +3932,7 @@ fn genSetFrameTruncatedOverflowCompare( |
| 3912 | src_mcv.address().offset(int_info.bits / 64 * 8).deref() | 3932 | src_mcv.address().offset(int_info.bits / 64 * 8).deref() |
| 3913 | else | 3933 | else |
| 3914 | src_mcv; | 3934 | src_mcv; |
| 3915 | try self.genSetReg(scratch_reg, limb_ty, hi_limb_mcv); | 3935 | try self.genSetReg(scratch_reg, limb_ty, hi_limb_mcv, .{}); |
| 3916 | try self.truncateRegister(hi_ty, scratch_reg); | 3936 | try self.truncateRegister(hi_ty, scratch_reg); |
| 3917 | try self.genBinOpMir(.{ ._, .cmp }, limb_ty, .{ .register = scratch_reg }, hi_limb_mcv); | 3937 | try self.genBinOpMir(.{ ._, .cmp }, limb_ty, .{ .register = scratch_reg }, hi_limb_mcv); |
| 3918 | | 3938 | |
| ... | @@ -3928,18 +3948,26 @@ fn genSetFrameTruncatedOverflowCompare( | ... | @@ -3928,18 +3948,26 @@ fn genSetFrameTruncatedOverflowCompare( |
| 3928 | } | 3948 | } |
| 3929 | | 3949 | |
| 3930 | const payload_off: i32 = @intCast(tuple_ty.structFieldOffset(0, mod)); | 3950 | const payload_off: i32 = @intCast(tuple_ty.structFieldOffset(0, mod)); |
| 3931 | if (hi_limb_off > 0) try self.genSetMem(.{ .frame = frame_index }, payload_off, rest_ty, src_mcv); | 3951 | if (hi_limb_off > 0) try self.genSetMem( |
| | 3952 | .{ .frame = frame_index }, |
| | 3953 | payload_off, |
| | 3954 | rest_ty, |
| | 3955 | src_mcv, |
| | 3956 | .{}, |
| | 3957 | ); |
| 3932 | try self.genSetMem( | 3958 | try self.genSetMem( |
| 3933 | .{ .frame = frame_index }, | 3959 | .{ .frame = frame_index }, |
| 3934 | payload_off + hi_limb_off, | 3960 | payload_off + hi_limb_off, |
| 3935 | limb_ty, | 3961 | limb_ty, |
| 3936 | .{ .register = scratch_reg }, | 3962 | .{ .register = scratch_reg }, |
| | 3963 | .{}, |
| 3937 | ); | 3964 | ); |
| 3938 | try self.genSetMem( | 3965 | try self.genSetMem( |
| 3939 | .{ .frame = frame_index }, | 3966 | .{ .frame = frame_index }, |
| 3940 | @intCast(tuple_ty.structFieldOffset(1, mod)), | 3967 | @intCast(tuple_ty.structFieldOffset(1, mod)), |
| 3941 | tuple_ty.structFieldType(1, mod), | 3968 | tuple_ty.structFieldType(1, mod), |
| 3942 | if (overflow_cc) |_| .{ .register = overflow_reg.to8() } else .{ .eflags = .ne }, | 3969 | if (overflow_cc) |_| .{ .register = overflow_reg.to8() } else .{ .eflags = .ne }, |
| | 3970 | .{}, |
| 3943 | ); | 3971 | ); |
| 3944 | } | 3972 | } |
| 3945 | | 3973 | |
| ... | @@ -3967,6 +3995,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3967,6 +3995,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 3967 | dst_mcv.address(), | 3995 | dst_mcv.address(), |
| 3968 | .{ .immediate = 0 }, | 3996 | .{ .immediate = 0 }, |
| 3969 | .{ .immediate = tuple_ty.abiSize(mod) }, | 3997 | .{ .immediate = tuple_ty.abiSize(mod) }, |
| | 3998 | .{}, |
| 3970 | ); | 3999 | ); |
| 3971 | const lhs_mcv = try self.resolveInst(bin_op.lhs); | 4000 | const lhs_mcv = try self.resolveInst(bin_op.lhs); |
| 3972 | const rhs_mcv = try self.resolveInst(bin_op.rhs); | 4001 | const rhs_mcv = try self.resolveInst(bin_op.rhs); |
| ... | @@ -4122,6 +4151,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4122,6 +4151,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4122 | @intCast(tuple_ty.structFieldOffset(0, mod)), | 4151 | @intCast(tuple_ty.structFieldOffset(0, mod)), |
| 4123 | tuple_ty.structFieldType(0, mod), | 4152 | tuple_ty.structFieldType(0, mod), |
| 4124 | result, | 4153 | result, |
| | 4154 | .{}, |
| 4125 | ); | 4155 | ); |
| 4126 | try self.asmMemoryImmediate( | 4156 | try self.asmMemoryImmediate( |
| 4127 | .{ ._, .cmp }, | 4157 | .{ ._, .cmp }, |
| ... | @@ -4133,6 +4163,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4133,6 +4163,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4133 | @intCast(tuple_ty.structFieldOffset(1, mod)), | 4163 | @intCast(tuple_ty.structFieldOffset(1, mod)), |
| 4134 | tuple_ty.structFieldType(1, mod), | 4164 | tuple_ty.structFieldType(1, mod), |
| 4135 | .{ .eflags = .ne }, | 4165 | .{ .eflags = .ne }, |
| | 4166 | .{}, |
| 4136 | ); | 4167 | ); |
| 4137 | try self.freeValue(overflow); | 4168 | try self.freeValue(overflow); |
| 4138 | break :result dst_mcv; | 4169 | break :result dst_mcv; |
| ... | @@ -4244,12 +4275,14 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4244,12 +4275,14 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4244 | @intCast(tuple_ty.structFieldOffset(0, mod)), | 4275 | @intCast(tuple_ty.structFieldOffset(0, mod)), |
| 4245 | tuple_ty.structFieldType(0, mod), | 4276 | tuple_ty.structFieldType(0, mod), |
| 4246 | .{ .register_pair = .{ .rax, .rdx } }, | 4277 | .{ .register_pair = .{ .rax, .rdx } }, |
| | 4278 | .{}, |
| 4247 | ); | 4279 | ); |
| 4248 | try self.genSetMem( | 4280 | try self.genSetMem( |
| 4249 | .{ .frame = dst_mcv.load_frame.index }, | 4281 | .{ .frame = dst_mcv.load_frame.index }, |
| 4250 | @intCast(tuple_ty.structFieldOffset(1, mod)), | 4282 | @intCast(tuple_ty.structFieldOffset(1, mod)), |
| 4251 | tuple_ty.structFieldType(1, mod), | 4283 | tuple_ty.structFieldType(1, mod), |
| 4252 | .{ .register = tmp_regs[1] }, | 4284 | .{ .register = tmp_regs[1] }, |
| | 4285 | .{}, |
| 4253 | ); | 4286 | ); |
| 4254 | break :result dst_mcv; | 4287 | break :result dst_mcv; |
| 4255 | }, | 4288 | }, |
| ... | @@ -4297,12 +4330,14 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4297,12 +4330,14 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4297 | @intCast(tuple_ty.structFieldOffset(0, mod)), | 4330 | @intCast(tuple_ty.structFieldOffset(0, mod)), |
| 4298 | tuple_ty.structFieldType(0, mod), | 4331 | tuple_ty.structFieldType(0, mod), |
| 4299 | partial_mcv, | 4332 | partial_mcv, |
| | 4333 | .{}, |
| 4300 | ); | 4334 | ); |
| 4301 | try self.genSetMem( | 4335 | try self.genSetMem( |
| 4302 | .{ .frame = frame_index }, | 4336 | .{ .frame = frame_index }, |
| 4303 | @intCast(tuple_ty.structFieldOffset(1, mod)), | 4337 | @intCast(tuple_ty.structFieldOffset(1, mod)), |
| 4304 | tuple_ty.structFieldType(1, mod), | 4338 | tuple_ty.structFieldType(1, mod), |
| 4305 | .{ .immediate = 0 }, // cc being set is impossible | 4339 | .{ .immediate = 0 }, // cc being set is impossible |
| | 4340 | .{}, |
| 4306 | ); | 4341 | ); |
| 4307 | } else try self.genSetFrameTruncatedOverflowCompare( | 4342 | } else try self.genSetFrameTruncatedOverflowCompare( |
| 4308 | tuple_ty, | 4343 | tuple_ty, |
| ... | @@ -4330,7 +4365,7 @@ fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue | ... | @@ -4330,7 +4365,7 @@ fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue |
| 4330 | return self.fail("TODO implement genIntMulDivOpMir for ABI size larger than 8", .{}); | 4365 | return self.fail("TODO implement genIntMulDivOpMir for ABI size larger than 8", .{}); |
| 4331 | } | 4366 | } |
| 4332 | | 4367 | |
| 4333 | try self.genSetReg(.rax, ty, lhs); | 4368 | try self.genSetReg(.rax, ty, lhs, .{}); |
| 4334 | switch (tag[1]) { | 4369 | switch (tag[1]) { |
| 4335 | else => unreachable, | 4370 | else => unreachable, |
| 4336 | .mul => {}, | 4371 | .mul => {}, |
| ... | @@ -4459,6 +4494,7 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4459,6 +4494,7 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 4459 | tmp_reg, | 4494 | tmp_reg, |
| 4460 | tmp_ty, | 4495 | tmp_ty, |
| 4461 | .{ .load_frame = .{ .index = frame_addr.index, .off = off } }, | 4496 | .{ .load_frame = .{ .index = frame_addr.index, .off = off } }, |
| | 4497 | .{}, |
| 4462 | ); | 4498 | ); |
| 4463 | try self.truncateRegister(lhs_ty, tmp_reg); | 4499 | try self.truncateRegister(lhs_ty, tmp_reg); |
| 4464 | try self.genSetMem( | 4500 | try self.genSetMem( |
| ... | @@ -4466,6 +4502,7 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4466,6 +4502,7 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 4466 | off, | 4502 | off, |
| 4467 | tmp_ty, | 4503 | tmp_ty, |
| 4468 | .{ .register = tmp_reg }, | 4504 | .{ .register = tmp_reg }, |
| | 4505 | .{}, |
| 4469 | ); | 4506 | ); |
| 4470 | }, | 4507 | }, |
| 4471 | else => {}, | 4508 | else => {}, |
| ... | @@ -4726,7 +4763,7 @@ fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4726,7 +4763,7 @@ fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 4726 | try self.genCopy(pl_ty, pl_mcv, switch (opt_mcv) { | 4763 | try self.genCopy(pl_ty, pl_mcv, switch (opt_mcv) { |
| 4727 | else => opt_mcv, | 4764 | else => opt_mcv, |
| 4728 | .register_overflow => |ro| .{ .register = ro.reg }, | 4765 | .register_overflow => |ro| .{ .register = ro.reg }, |
| 4729 | }); | 4766 | }, .{}); |
| 4730 | break :result pl_mcv; | 4767 | break :result pl_mcv; |
| 4731 | }; | 4768 | }; |
| 4732 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 4769 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| ... | @@ -4773,7 +4810,13 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4773,7 +4810,13 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { |
| 4773 | | 4810 | |
| 4774 | const pl_ty = dst_ty.childType(mod); | 4811 | const pl_ty = dst_ty.childType(mod); |
| 4775 | const pl_abi_size: i32 = @intCast(pl_ty.abiSize(mod)); | 4812 | const pl_abi_size: i32 = @intCast(pl_ty.abiSize(mod)); |
| 4776 | try self.genSetMem(.{ .reg = dst_mcv.getReg().? }, pl_abi_size, Type.bool, .{ .immediate = 1 }); | 4813 | try self.genSetMem( |
| | 4814 | .{ .reg = dst_mcv.getReg().? }, |
| | 4815 | pl_abi_size, |
| | 4816 | Type.bool, |
| | 4817 | .{ .immediate = 1 }, |
| | 4818 | .{}, |
| | 4819 | ); |
| 4777 | break :result if (self.liveness.isUnused(inst)) .unreach else dst_mcv; | 4820 | break :result if (self.liveness.isUnused(inst)) .unreach else dst_mcv; |
| 4778 | }; | 4821 | }; |
| 4779 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 4822 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| ... | @@ -5039,7 +5082,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5039,7 +5082,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { |
| 5039 | defer if (pl_lock) |lock| self.register_manager.unlockReg(lock); | 5082 | defer if (pl_lock) |lock| self.register_manager.unlockReg(lock); |
| 5040 | | 5083 | |
| 5041 | const opt_mcv = try self.allocRegOrMem(inst, true); | 5084 | const opt_mcv = try self.allocRegOrMem(inst, true); |
| 5042 | try self.genCopy(pl_ty, opt_mcv, pl_mcv); | 5085 | try self.genCopy(pl_ty, opt_mcv, pl_mcv, .{}); |
| 5043 | | 5086 | |
| 5044 | if (!same_repr) { | 5087 | if (!same_repr) { |
| 5045 | const pl_abi_size: i32 = @intCast(pl_ty.abiSize(mod)); | 5088 | const pl_abi_size: i32 = @intCast(pl_ty.abiSize(mod)); |
| ... | @@ -5089,8 +5132,8 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5089,8 +5132,8 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 5089 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(eu_ty, mod)); | 5132 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(eu_ty, mod)); |
| 5090 | const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, mod)); | 5133 | const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, mod)); |
| 5091 | const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, mod)); | 5134 | const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, mod)); |
| 5092 | try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, operand); | 5135 | try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, operand, .{}); |
| 5093 | try self.genSetMem(.{ .frame = frame_index }, err_off, err_ty, .{ .immediate = 0 }); | 5136 | try self.genSetMem(.{ .frame = frame_index }, err_off, err_ty, .{ .immediate = 0 }, .{}); |
| 5094 | break :result .{ .load_frame = .{ .index = frame_index } }; | 5137 | break :result .{ .load_frame = .{ .index = frame_index } }; |
| 5095 | }; | 5138 | }; |
| 5096 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 5139 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| ... | @@ -5111,9 +5154,9 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5111,9 +5154,9 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { |
| 5111 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(eu_ty, mod)); | 5154 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(eu_ty, mod)); |
| 5112 | const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, mod)); | 5155 | const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, mod)); |
| 5113 | const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, mod)); | 5156 | const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, mod)); |
| 5114 | try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, .undef); | 5157 | try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, .undef, .{}); |
| 5115 | const operand = try self.resolveInst(ty_op.operand); | 5158 | const operand = try self.resolveInst(ty_op.operand); |
| 5116 | try self.genSetMem(.{ .frame = frame_index }, err_off, err_ty, operand); | 5159 | try self.genSetMem(.{ .frame = frame_index }, err_off, err_ty, operand, .{}); |
| 5117 | break :result .{ .load_frame = .{ .index = frame_index } }; | 5160 | break :result .{ .load_frame = .{ .index = frame_index } }; |
| 5118 | }; | 5161 | }; |
| 5119 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 5162 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| ... | @@ -5127,7 +5170,7 @@ fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5127,7 +5170,7 @@ fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void { |
| 5127 | | 5170 | |
| 5128 | const dst_mcv = try self.allocRegOrMem(inst, true); | 5171 | const dst_mcv = try self.allocRegOrMem(inst, true); |
| 5129 | const dst_ty = self.typeOfIndex(inst); | 5172 | const dst_ty = self.typeOfIndex(inst); |
| 5130 | try self.genCopy(dst_ty, dst_mcv, src_mcv); | 5173 | try self.genCopy(dst_ty, dst_mcv, src_mcv, .{}); |
| 5131 | break :result dst_mcv; | 5174 | break :result dst_mcv; |
| 5132 | }; | 5175 | }; |
| 5133 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 5176 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| ... | @@ -5147,7 +5190,7 @@ fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5147,7 +5190,7 @@ fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void { |
| 5147 | if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) break :result len_mcv; | 5190 | if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) break :result len_mcv; |
| 5148 | | 5191 | |
| 5149 | const dst_mcv = try self.allocRegOrMem(inst, true); | 5192 | const dst_mcv = try self.allocRegOrMem(inst, true); |
| 5150 | try self.genCopy(Type.usize, dst_mcv, len_mcv); | 5193 | try self.genCopy(Type.usize, dst_mcv, len_mcv, .{}); |
| 5151 | break :result dst_mcv; | 5194 | break :result dst_mcv; |
| 5152 | }, | 5195 | }, |
| 5153 | else => return self.fail("TODO implement slice_len for {}", .{src_mcv}), | 5196 | else => return self.fail("TODO implement slice_len for {}", .{src_mcv}), |
| ... | @@ -5211,7 +5254,7 @@ fn elemOffset(self: *Self, index_ty: Type, index: MCValue, elem_size: u64) !Regi | ... | @@ -5211,7 +5254,7 @@ fn elemOffset(self: *Self, index_ty: Type, index: MCValue, elem_size: u64) !Regi |
| 5211 | // Optimisation: if index MCValue is an immediate, we can multiply in `comptime` | 5254 | // Optimisation: if index MCValue is an immediate, we can multiply in `comptime` |
| 5212 | // and set the register directly to the scaled offset as an immediate. | 5255 | // and set the register directly to the scaled offset as an immediate. |
| 5213 | const reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); | 5256 | const reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); |
| 5214 | try self.genSetReg(reg, index_ty, .{ .immediate = imm * elem_size }); | 5257 | try self.genSetReg(reg, index_ty, .{ .immediate = imm * elem_size }, .{}); |
| 5215 | break :blk reg; | 5258 | break :blk reg; |
| 5216 | }, | 5259 | }, |
| 5217 | else => { | 5260 | else => { |
| ... | @@ -5251,7 +5294,7 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue { | ... | @@ -5251,7 +5294,7 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue { |
| 5251 | defer self.register_manager.unlockReg(offset_reg_lock); | 5294 | defer self.register_manager.unlockReg(offset_reg_lock); |
| 5252 | | 5295 | |
| 5253 | const addr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); | 5296 | const addr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); |
| 5254 | try self.genSetReg(addr_reg, Type.usize, slice_mcv); | 5297 | try self.genSetReg(addr_reg, Type.usize, slice_mcv, .{}); |
| 5255 | // TODO we could allocate register here, but need to expect addr register and potentially | 5298 | // TODO we could allocate register here, but need to expect addr register and potentially |
| 5256 | // offset register. | 5299 | // offset register. |
| 5257 | try self.genBinOpMir(.{ ._, .add }, slice_ptr_field_type, .{ .register = addr_reg }, .{ | 5300 | try self.genBinOpMir(.{ ._, .add }, slice_ptr_field_type, .{ .register = addr_reg }, .{ |
| ... | @@ -5353,7 +5396,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5353,7 +5396,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5353 | switch (array_mcv) { | 5396 | switch (array_mcv) { |
| 5354 | .register => { | 5397 | .register => { |
| 5355 | const frame_index = try self.allocFrameIndex(FrameAlloc.initType(array_ty, mod)); | 5398 | const frame_index = try self.allocFrameIndex(FrameAlloc.initType(array_ty, mod)); |
| 5356 | try self.genSetMem(.{ .frame = frame_index }, 0, array_ty, array_mcv); | 5399 | try self.genSetMem(.{ .frame = frame_index }, 0, array_ty, array_mcv, .{}); |
| 5357 | try self.asmRegisterMemory( | 5400 | try self.asmRegisterMemory( |
| 5358 | .{ ._, .lea }, | 5401 | .{ ._, .lea }, |
| 5359 | addr_reg, | 5402 | addr_reg, |
| ... | @@ -5373,7 +5416,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5373,7 +5416,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5373 | .load_direct, | 5416 | .load_direct, |
| 5374 | .load_got, | 5417 | .load_got, |
| 5375 | .load_tlv, | 5418 | .load_tlv, |
| 5376 | => try self.genSetReg(addr_reg, Type.usize, array_mcv.address()), | 5419 | => try self.genSetReg(addr_reg, Type.usize, array_mcv.address(), .{}), |
| 5377 | .lea_symbol, .lea_direct, .lea_tlv => unreachable, | 5420 | .lea_symbol, .lea_direct, .lea_tlv => unreachable, |
| 5378 | else => return self.fail("TODO airArrayElemVal_val for {s} of {}", .{ | 5421 | else => return self.fail("TODO airArrayElemVal_val for {s} of {}", .{ |
| 5379 | @tagName(array_mcv), array_ty.fmt(mod), | 5422 | @tagName(array_mcv), array_ty.fmt(mod), |
| ... | @@ -5393,7 +5436,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5393,7 +5436,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5393 | .{ .register = addr_reg }, | 5436 | .{ .register = addr_reg }, |
| 5394 | .{ .register = offset_reg }, | 5437 | .{ .register = offset_reg }, |
| 5395 | ); | 5438 | ); |
| 5396 | try self.genCopy(elem_ty, dst_mcv, .{ .indirect = .{ .reg = addr_reg } }); | 5439 | try self.genCopy(elem_ty, dst_mcv, .{ .indirect = .{ .reg = addr_reg } }, .{}); |
| 5397 | break :result dst_mcv; | 5440 | break :result dst_mcv; |
| 5398 | }; | 5441 | }; |
| 5399 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); | 5442 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); |
| ... | @@ -5533,7 +5576,7 @@ fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5533,7 +5576,7 @@ fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void { |
| 5533 | } else ptr; | 5576 | } else ptr; |
| 5534 | | 5577 | |
| 5535 | const ptr_tag_ty = try mod.adjustPtrTypeChild(ptr_union_ty, tag_ty); | 5578 | const ptr_tag_ty = try mod.adjustPtrTypeChild(ptr_union_ty, tag_ty); |
| 5536 | try self.store(ptr_tag_ty, adjusted_ptr, tag); | 5579 | try self.store(ptr_tag_ty, adjusted_ptr, tag, .{}); |
| 5537 | | 5580 | |
| 5538 | return self.finishAir(inst, .none, .{ bin_op.lhs, bin_op.rhs, .none }); | 5581 | return self.finishAir(inst, .none, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 5539 | } | 5582 | } |
| ... | @@ -5743,7 +5786,7 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5743,7 +5786,7 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void { |
| 5743 | registerAlias(dst_reg, cmov_abi_size), | 5786 | registerAlias(dst_reg, cmov_abi_size), |
| 5744 | ); | 5787 | ); |
| 5745 | | 5788 | |
| 5746 | try self.genSetReg(dst_reg, dst_ty, .{ .immediate = src_bits - 1 }); | 5789 | try self.genSetReg(dst_reg, dst_ty, .{ .immediate = src_bits - 1 }, .{}); |
| 5747 | try self.genBinOpMir(.{ ._, .sub }, dst_ty, dst_mcv, .{ .register = imm_reg }); | 5790 | try self.genBinOpMir(.{ ._, .sub }, dst_ty, dst_mcv, .{ .register = imm_reg }); |
| 5748 | } | 5791 | } |
| 5749 | break :result dst_mcv; | 5792 | break :result dst_mcv; |
| ... | @@ -5798,7 +5841,7 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5798,7 +5841,7 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void { |
| 5798 | const tmp_mcv = tmp: { | 5841 | const tmp_mcv = tmp: { |
| 5799 | if (src_mcv.isImmediate() or self.liveness.operandDies(inst, 0)) | 5842 | if (src_mcv.isImmediate() or self.liveness.operandDies(inst, 0)) |
| 5800 | break :tmp src_mcv; | 5843 | break :tmp src_mcv; |
| 5801 | try self.genSetReg(dst_reg, wide_ty, src_mcv); | 5844 | try self.genSetReg(dst_reg, wide_ty, src_mcv, .{}); |
| 5802 | break :tmp dst_mcv; | 5845 | break :tmp dst_mcv; |
| 5803 | }; | 5846 | }; |
| 5804 | try self.genBinOpMir( | 5847 | try self.genBinOpMir( |
| ... | @@ -5826,7 +5869,7 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5826,7 +5869,7 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void { |
| 5826 | else | 5869 | else |
| 5827 | .{ .register = mat_src_mcv.register_pair[1] }; | 5870 | .{ .register = mat_src_mcv.register_pair[1] }; |
| 5828 | const masked_mcv = if (src_bits < 128) masked: { | 5871 | const masked_mcv = if (src_bits < 128) masked: { |
| 5829 | try self.genCopy(Type.u64, dst_mcv, hi_mat_src_mcv); | 5872 | try self.genCopy(Type.u64, dst_mcv, hi_mat_src_mcv, .{}); |
| 5830 | try self.genBinOpMir( | 5873 | try self.genBinOpMir( |
| 5831 | .{ ._, .@"or" }, | 5874 | .{ ._, .@"or" }, |
| 5832 | Type.u64, | 5875 | Type.u64, |
| ... | @@ -5941,7 +5984,7 @@ fn genPopCount( | ... | @@ -5941,7 +5984,7 @@ fn genPopCount( |
| 5941 | if (src_abi_size > 1) src_ty else Type.u32, | 5984 | if (src_abi_size > 1) src_ty else Type.u32, |
| 5942 | .{ .register = dst_reg }, | 5985 | .{ .register = dst_reg }, |
| 5943 | if (src_abi_size > 1) src_mcv else src: { | 5986 | if (src_abi_size > 1) src_mcv else src: { |
| 5944 | if (!dst_contains_src) try self.genSetReg(dst_reg, src_ty, src_mcv); | 5987 | if (!dst_contains_src) try self.genSetReg(dst_reg, src_ty, src_mcv, .{}); |
| 5945 | try self.truncateRegister(try src_ty.toUnsigned(mod), dst_reg); | 5988 | try self.truncateRegister(try src_ty.toUnsigned(mod), dst_reg); |
| 5946 | break :src .{ .register = dst_reg }; | 5989 | break :src .{ .register = dst_reg }; |
| 5947 | }, | 5990 | }, |
| ... | @@ -5964,7 +6007,7 @@ fn genPopCount( | ... | @@ -5964,7 +6007,7 @@ fn genPopCount( |
| 5964 | else | 6007 | else |
| 5965 | undefined; | 6008 | undefined; |
| 5966 | | 6009 | |
| 5967 | if (!dst_contains_src) try self.genSetReg(dst, src_ty, src_mcv); | 6010 | if (!dst_contains_src) try self.genSetReg(dst, src_ty, src_mcv, .{}); |
| 5968 | // dst = operand | 6011 | // dst = operand |
| 5969 | try self.asmRegisterRegister(.{ ._, .mov }, tmp, dst); | 6012 | try self.asmRegisterRegister(.{ ._, .mov }, tmp, dst); |
| 5970 | // tmp = operand | 6013 | // tmp = operand |
| ... | @@ -6102,7 +6145,7 @@ fn genByteSwap( | ... | @@ -6102,7 +6145,7 @@ fn genByteSwap( |
| 6102 | const dst_lock = self.register_manager.lockRegAssumeUnused(dst_mcv.register); | 6145 | const dst_lock = self.register_manager.lockRegAssumeUnused(dst_mcv.register); |
| 6103 | defer self.register_manager.unlockReg(dst_lock); | 6146 | defer self.register_manager.unlockReg(dst_lock); |
| 6104 | | 6147 | |
| 6105 | try self.genSetReg(dst_reg, src_ty, src_mcv); | 6148 | try self.genSetReg(dst_reg, src_ty, src_mcv, .{}); |
| 6106 | switch (abi_size) { | 6149 | switch (abi_size) { |
| 6107 | else => unreachable, | 6150 | else => unreachable, |
| 6108 | 2 => try self.genBinOpMir(.{ ._l, .ro }, src_ty, dst_mcv, .{ .immediate = 8 }), | 6151 | 2 => try self.genBinOpMir(.{ ._l, .ro }, src_ty, dst_mcv, .{ .immediate = 8 }), |
| ... | @@ -6275,7 +6318,7 @@ fn floatSign(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, ty: Type) | ... | @@ -6275,7 +6318,7 @@ fn floatSign(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, ty: Type) |
| 6275 | if (!std.meta.eql(src_mcv, dst_mcv) or !self.reuseOperand(inst, operand, 0, src_mcv)) | 6318 | if (!std.meta.eql(src_mcv, dst_mcv) or !self.reuseOperand(inst, operand, 0, src_mcv)) |
| 6276 | try self.register_manager.getReg(.st0, inst); | 6319 | try self.register_manager.getReg(.st0, inst); |
| 6277 | | 6320 | |
| 6278 | try self.genCopy(ty, dst_mcv, src_mcv); | 6321 | try self.genCopy(ty, dst_mcv, src_mcv, .{}); |
| 6279 | switch (tag) { | 6322 | switch (tag) { |
| 6280 | .neg => try self.asmOpOnly(.{ .f_, .chs }), | 6323 | .neg => try self.asmOpOnly(.{ .f_, .chs }), |
| 6281 | .abs => try self.asmOpOnly(.{ .f_, .abs }), | 6324 | .abs => try self.asmOpOnly(.{ .f_, .abs }), |
| ... | @@ -6492,7 +6535,7 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: Ro | ... | @@ -6492,7 +6535,7 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: Ro |
| 6492 | const mod = self.bin_file.comp.module.?; | 6535 | const mod = self.bin_file.comp.module.?; |
| 6493 | const mir_tag = self.getRoundTag(ty) orelse { | 6536 | const mir_tag = self.getRoundTag(ty) orelse { |
| 6494 | const result = try self.genRoundLibcall(ty, src_mcv, mode); | 6537 | const result = try self.genRoundLibcall(ty, src_mcv, mode); |
| 6495 | return self.genSetReg(dst_reg, ty, result); | 6538 | return self.genSetReg(dst_reg, ty, result, .{}); |
| 6496 | }; | 6539 | }; |
| 6497 | const abi_size: u32 = @intCast(ty.abiSize(mod)); | 6540 | const abi_size: u32 = @intCast(ty.abiSize(mod)); |
| 6498 | const dst_alias = registerAlias(dst_reg, abi_size); | 6541 | const dst_alias = registerAlias(dst_reg, abi_size); |
| ... | @@ -6583,7 +6626,7 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6583,7 +6626,7 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { |
| 6583 | const dst_locks = self.register_manager.lockRegsAssumeUnused(2, dst_regs); | 6626 | const dst_locks = self.register_manager.lockRegsAssumeUnused(2, dst_regs); |
| 6584 | defer for (dst_locks) |lock| self.register_manager.unlockReg(lock); | 6627 | defer for (dst_locks) |lock| self.register_manager.unlockReg(lock); |
| 6585 | | 6628 | |
| 6586 | try self.genCopy(ty, dst_mcv, src_mcv); | 6629 | try self.genCopy(ty, dst_mcv, src_mcv, .{}); |
| 6587 | break :dst dst_mcv; | 6630 | break :dst dst_mcv; |
| 6588 | }; | 6631 | }; |
| 6589 | const dst_regs = dst_mcv.register_pair; | 6632 | const dst_regs = dst_mcv.register_pair; |
| ... | @@ -6940,9 +6983,9 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn | ... | @@ -6940,9 +6983,9 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn |
| 6940 | defer self.register_manager.unlockReg(tmp_lock); | 6983 | defer self.register_manager.unlockReg(tmp_lock); |
| 6941 | | 6984 | |
| 6942 | const hi_mcv = dst_mcv.address().offset(@intCast(val_bit_size / 64 * 8)).deref(); | 6985 | const hi_mcv = dst_mcv.address().offset(@intCast(val_bit_size / 64 * 8)).deref(); |
| 6943 | try self.genSetReg(tmp_reg, Type.usize, hi_mcv); | 6986 | try self.genSetReg(tmp_reg, Type.usize, hi_mcv, .{}); |
| 6944 | try self.truncateRegister(val_ty, tmp_reg); | 6987 | try self.truncateRegister(val_ty, tmp_reg); |
| 6945 | try self.genCopy(Type.usize, hi_mcv, .{ .register = tmp_reg }); | 6988 | try self.genCopy(Type.usize, hi_mcv, .{ .register = tmp_reg }, .{}); |
| 6946 | } | 6989 | } |
| 6947 | } | 6990 | } |
| 6948 | return; | 6991 | return; |
| ... | @@ -7011,7 +7054,7 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn | ... | @@ -7011,7 +7054,7 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn |
| 7011 | } | 7054 | } |
| 7012 | | 7055 | |
| 7013 | if (val_extra_bits > 0) try self.truncateRegister(val_ty, dst_reg); | 7056 | if (val_extra_bits > 0) try self.truncateRegister(val_ty, dst_reg); |
| 7014 | try self.genCopy(val_ty, dst_mcv, .{ .register = dst_reg }); | 7057 | try self.genCopy(val_ty, dst_mcv, .{ .register = dst_reg }, .{}); |
| 7015 | } | 7058 | } |
| 7016 | | 7059 | |
| 7017 | fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerError!void { | 7060 | fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerError!void { |
| ... | @@ -7036,7 +7079,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerErro | ... | @@ -7036,7 +7079,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerErro |
| 7036 | .lea_got, | 7079 | .lea_got, |
| 7037 | .lea_tlv, | 7080 | .lea_tlv, |
| 7038 | .lea_frame, | 7081 | .lea_frame, |
| 7039 | => try self.genCopy(dst_ty, dst_mcv, ptr_mcv.deref()), | 7082 | => try self.genCopy(dst_ty, dst_mcv, ptr_mcv.deref(), .{}), |
| 7040 | .memory, | 7083 | .memory, |
| 7041 | .indirect, | 7084 | .indirect, |
| 7042 | .load_symbol, | 7085 | .load_symbol, |
| ... | @@ -7049,7 +7092,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerErro | ... | @@ -7049,7 +7092,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerErro |
| 7049 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); | 7092 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 7050 | defer self.register_manager.unlockReg(addr_lock); | 7093 | defer self.register_manager.unlockReg(addr_lock); |
| 7051 | | 7094 | |
| 7052 | try self.genCopy(dst_ty, dst_mcv, .{ .indirect = .{ .reg = addr_reg } }); | 7095 | try self.genCopy(dst_ty, dst_mcv, .{ .indirect = .{ .reg = addr_reg } }, .{}); |
| 7053 | }, | 7096 | }, |
| 7054 | .air_ref => |ptr_ref| try self.load(dst_mcv, ptr_ty, try self.resolveInst(ptr_ref)), | 7097 | .air_ref => |ptr_ref| try self.load(dst_mcv, ptr_ty, try self.resolveInst(ptr_ref)), |
| 7055 | } | 7098 | } |
| ... | @@ -7105,6 +7148,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -7105,6 +7148,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 7105 | if (elem_size <= 8) elem_ty else Type.usize, | 7148 | if (elem_size <= 8) elem_ty else Type.usize, |
| 7106 | high_mcv, | 7149 | high_mcv, |
| 7107 | .{ .register = high_reg }, | 7150 | .{ .register = high_reg }, |
| | 7151 | .{}, |
| 7108 | ); | 7152 | ); |
| 7109 | } | 7153 | } |
| 7110 | break :result dst_mcv; | 7154 | break :result dst_mcv; |
| ... | @@ -7167,7 +7211,7 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In | ... | @@ -7167,7 +7211,7 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In |
| 7167 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | 7211 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 7168 | defer self.register_manager.unlockReg(tmp_lock); | 7212 | defer self.register_manager.unlockReg(tmp_lock); |
| 7169 | | 7213 | |
| 7170 | try self.genSetReg(tmp_reg, limb_ty, src_mcv); | 7214 | try self.genSetReg(tmp_reg, limb_ty, src_mcv, .{}); |
| 7171 | switch (limb_i) { | 7215 | switch (limb_i) { |
| 7172 | 0 => try self.genShiftBinOpMir( | 7216 | 0 => try self.genShiftBinOpMir( |
| 7173 | .{ ._l, .sh }, | 7217 | .{ ._l, .sh }, |
| ... | @@ -7198,7 +7242,7 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In | ... | @@ -7198,7 +7242,7 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In |
| 7198 | try self.genSetReg(tmp_reg, limb_ty, switch (limb_i) { | 7242 | try self.genSetReg(tmp_reg, limb_ty, switch (limb_i) { |
| 7199 | 0 => src_mcv, | 7243 | 0 => src_mcv, |
| 7200 | else => src_mcv.address().offset(limb_i * limb_abi_size).deref(), | 7244 | else => src_mcv.address().offset(limb_i * limb_abi_size).deref(), |
| 7201 | }); | 7245 | }, .{}); |
| 7202 | try self.genBinOpMir(.{ ._, .@"and" }, limb_ty, tmp_mcv, .{ .immediate = part_mask }); | 7246 | try self.genBinOpMir(.{ ._, .@"and" }, limb_ty, tmp_mcv, .{ .immediate = part_mask }); |
| 7203 | try self.asmMemoryRegister( | 7247 | try self.asmMemoryRegister( |
| 7204 | .{ ._, .@"or" }, | 7248 | .{ ._, .@"or" }, |
| ... | @@ -7209,7 +7253,13 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In | ... | @@ -7209,7 +7253,13 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In |
| 7209 | } | 7253 | } |
| 7210 | } | 7254 | } |
| 7211 | | 7255 | |
| 7212 | fn store(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerError!void { | 7256 | fn store( |
| | 7257 | self: *Self, |
| | 7258 | ptr_ty: Type, |
| | 7259 | ptr_mcv: MCValue, |
| | 7260 | src_mcv: MCValue, |
| | 7261 | opts: CopyOptions, |
| | 7262 | ) InnerError!void { |
| 7213 | const mod = self.bin_file.comp.module.?; | 7263 | const mod = self.bin_file.comp.module.?; |
| 7214 | const src_ty = ptr_ty.childType(mod); | 7264 | const src_ty = ptr_ty.childType(mod); |
| 7215 | if (!src_ty.hasRuntimeBitsIgnoreComptime(mod)) return; | 7265 | if (!src_ty.hasRuntimeBitsIgnoreComptime(mod)) return; |
| ... | @@ -7231,7 +7281,7 @@ fn store(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerErr | ... | @@ -7231,7 +7281,7 @@ fn store(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerErr |
| 7231 | .lea_got, | 7281 | .lea_got, |
| 7232 | .lea_tlv, | 7282 | .lea_tlv, |
| 7233 | .lea_frame, | 7283 | .lea_frame, |
| 7234 | => try self.genCopy(src_ty, ptr_mcv.deref(), src_mcv), | 7284 | => try self.genCopy(src_ty, ptr_mcv.deref(), src_mcv, opts), |
| 7235 | .memory, | 7285 | .memory, |
| 7236 | .indirect, | 7286 | .indirect, |
| 7237 | .load_symbol, | 7287 | .load_symbol, |
| ... | @@ -7244,9 +7294,9 @@ fn store(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerErr | ... | @@ -7244,9 +7294,9 @@ fn store(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerErr |
| 7244 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); | 7294 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 7245 | defer self.register_manager.unlockReg(addr_lock); | 7295 | defer self.register_manager.unlockReg(addr_lock); |
| 7246 | | 7296 | |
| 7247 | try self.genCopy(src_ty, .{ .indirect = .{ .reg = addr_reg } }, src_mcv); | 7297 | try self.genCopy(src_ty, .{ .indirect = .{ .reg = addr_reg } }, src_mcv, opts); |
| 7248 | }, | 7298 | }, |
| 7249 | .air_ref => |ptr_ref| try self.store(ptr_ty, try self.resolveInst(ptr_ref), src_mcv), | 7299 | .air_ref => |ptr_ref| try self.store(ptr_ty, try self.resolveInst(ptr_ref), src_mcv, opts), |
| 7250 | } | 7300 | } |
| 7251 | } | 7301 | } |
| 7252 | | 7302 | |
| ... | @@ -7269,7 +7319,7 @@ fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void { | ... | @@ -7269,7 +7319,7 @@ fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void { |
| 7269 | if (ptr_info.flags.vector_index != .none or ptr_info.packed_offset.host_size > 0) { | 7319 | if (ptr_info.flags.vector_index != .none or ptr_info.packed_offset.host_size > 0) { |
| 7270 | try self.packedStore(ptr_ty, ptr_mcv, src_mcv); | 7320 | try self.packedStore(ptr_ty, ptr_mcv, src_mcv); |
| 7271 | } else { | 7321 | } else { |
| 7272 | try self.store(ptr_ty, ptr_mcv, src_mcv); | 7322 | try self.store(ptr_ty, ptr_mcv, src_mcv, .{ .safety = safety }); |
| 7273 | } | 7323 | } |
| 7274 | } | 7324 | } |
| 7275 | return self.finishAir(inst, .none, .{ bin_op.lhs, bin_op.rhs, .none }); | 7325 | return self.finishAir(inst, .none, .{ bin_op.lhs, bin_op.rhs, .none }); |
| ... | @@ -7389,7 +7439,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -7389,7 +7439,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 7389 | const dst_locks = self.register_manager.lockRegsAssumeUnused(2, dst_regs); | 7439 | const dst_locks = self.register_manager.lockRegsAssumeUnused(2, dst_regs); |
| 7390 | defer for (dst_locks) |lock| self.register_manager.unlockReg(lock); | 7440 | defer for (dst_locks) |lock| self.register_manager.unlockReg(lock); |
| 7391 | | 7441 | |
| 7392 | try self.genCopy(container_ty, .{ .register_pair = dst_regs }, src_mcv); | 7442 | try self.genCopy(container_ty, .{ .register_pair = dst_regs }, src_mcv, .{}); |
| 7393 | break :dst dst_regs; | 7443 | break :dst dst_regs; |
| 7394 | }; | 7444 | }; |
| 7395 | const dst_mcv = MCValue{ .register_pair = dst_regs }; | 7445 | const dst_mcv = MCValue{ .register_pair = dst_regs }; |
| ... | @@ -7493,7 +7543,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -7493,7 +7543,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 7493 | const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); | 7543 | const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); |
| 7494 | defer self.register_manager.unlockReg(dst_lock); | 7544 | defer self.register_manager.unlockReg(dst_lock); |
| 7495 | | 7545 | |
| 7496 | try self.genCopy(int_ty, dst_mcv, off_mcv); | 7546 | try self.genCopy(int_ty, dst_mcv, off_mcv, .{}); |
| 7497 | if (self.regExtraBits(field_ty) > 0) try self.truncateRegister(int_ty, dst_reg); | 7547 | if (self.regExtraBits(field_ty) > 0) try self.truncateRegister(int_ty, dst_reg); |
| 7498 | break :result if (field_is_gp) | 7548 | break :result if (field_is_gp) |
| 7499 | dst_mcv | 7549 | dst_mcv |
| ... | @@ -7507,7 +7557,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -7507,7 +7557,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 7507 | off_mcv | 7557 | off_mcv |
| 7508 | else dst: { | 7558 | else dst: { |
| 7509 | const dst_mcv = try self.allocRegOrMem(inst, true); | 7559 | const dst_mcv = try self.allocRegOrMem(inst, true); |
| 7510 | try self.genCopy(field_ty, dst_mcv, off_mcv); | 7560 | try self.genCopy(field_ty, dst_mcv, off_mcv, .{}); |
| 7511 | break :dst dst_mcv; | 7561 | break :dst dst_mcv; |
| 7512 | }; | 7562 | }; |
| 7513 | if (field_abi_size * 8 > field_bit_size and dst_mcv.isMemory()) { | 7563 | if (field_abi_size * 8 > field_bit_size and dst_mcv.isMemory()) { |
| ... | @@ -7517,9 +7567,9 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -7517,9 +7567,9 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 7517 | | 7567 | |
| 7518 | const hi_mcv = | 7568 | const hi_mcv = |
| 7519 | dst_mcv.address().offset(@intCast(field_bit_size / 64 * 8)).deref(); | 7569 | dst_mcv.address().offset(@intCast(field_bit_size / 64 * 8)).deref(); |
| 7520 | try self.genSetReg(tmp_reg, Type.usize, hi_mcv); | 7570 | try self.genSetReg(tmp_reg, Type.usize, hi_mcv, .{}); |
| 7521 | try self.truncateRegister(field_ty, tmp_reg); | 7571 | try self.truncateRegister(field_ty, tmp_reg); |
| 7522 | try self.genCopy(Type.usize, hi_mcv, .{ .register = tmp_reg }); | 7572 | try self.genCopy(Type.usize, hi_mcv, .{ .register = tmp_reg }, .{}); |
| 7523 | } | 7573 | } |
| 7524 | break :result dst_mcv; | 7574 | break :result dst_mcv; |
| 7525 | } | 7575 | } |
| ... | @@ -7650,7 +7700,7 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air: | ... | @@ -7650,7 +7700,7 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air: |
| 7650 | if (maybe_inst) |inst| if (self.reuseOperand(inst, src_air, 0, src_mcv)) break :dst src_mcv; | 7700 | if (maybe_inst) |inst| if (self.reuseOperand(inst, src_air, 0, src_mcv)) break :dst src_mcv; |
| 7651 | | 7701 | |
| 7652 | const dst_mcv = try self.allocRegOrMemAdvanced(src_ty, maybe_inst, true); | 7702 | const dst_mcv = try self.allocRegOrMemAdvanced(src_ty, maybe_inst, true); |
| 7653 | try self.genCopy(src_ty, dst_mcv, src_mcv); | 7703 | try self.genCopy(src_ty, dst_mcv, src_mcv, .{}); |
| 7654 | break :dst dst_mcv; | 7704 | break :dst dst_mcv; |
| 7655 | }; | 7705 | }; |
| 7656 | const dst_lock = switch (dst_mcv) { | 7706 | const dst_lock = switch (dst_mcv) { |
| ... | @@ -7697,9 +7747,9 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air: | ... | @@ -7697,9 +7747,9 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air: |
| 7697 | defer self.register_manager.unlockReg(tmp_lock); | 7747 | defer self.register_manager.unlockReg(tmp_lock); |
| 7698 | | 7748 | |
| 7699 | const hi_mcv = dst_mcv.address().offset(@intCast(bit_size / 64 * 8)).deref(); | 7749 | const hi_mcv = dst_mcv.address().offset(@intCast(bit_size / 64 * 8)).deref(); |
| 7700 | try self.genSetReg(tmp_reg, Type.usize, hi_mcv); | 7750 | try self.genSetReg(tmp_reg, Type.usize, hi_mcv, .{}); |
| 7701 | try self.truncateRegister(src_ty, tmp_reg); | 7751 | try self.truncateRegister(src_ty, tmp_reg); |
| 7702 | try self.genCopy(Type.usize, hi_mcv, .{ .register = tmp_reg }); | 7752 | try self.genCopy(Type.usize, hi_mcv, .{ .register = tmp_reg }, .{}); |
| 7703 | } | 7753 | } |
| 7704 | } | 7754 | } |
| 7705 | }, | 7755 | }, |
| ... | @@ -7736,7 +7786,7 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MC | ... | @@ -7736,7 +7786,7 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MC |
| 7736 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); | 7786 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 7737 | defer self.register_manager.unlockReg(addr_reg_lock); | 7787 | defer self.register_manager.unlockReg(addr_reg_lock); |
| 7738 | | 7788 | |
| 7739 | try self.genSetReg(addr_reg, Type.usize, dst_mcv.address()); | 7789 | try self.genSetReg(addr_reg, Type.usize, dst_mcv.address(), .{}); |
| 7740 | try self.asmMemory(mir_tag, .{ .base = .{ .reg = addr_reg }, .mod = .{ .rm = .{ | 7790 | try self.asmMemory(mir_tag, .{ .base = .{ .reg = addr_reg }, .mod = .{ .rm = .{ |
| 7741 | .size = Memory.Size.fromSize(abi_size), | 7791 | .size = Memory.Size.fromSize(abi_size), |
| 7742 | } } }); | 7792 | } } }); |
| ... | @@ -7767,7 +7817,7 @@ fn genShiftBinOpMir( | ... | @@ -7767,7 +7817,7 @@ fn genShiftBinOpMir( |
| 7767 | else => {}, | 7817 | else => {}, |
| 7768 | } | 7818 | } |
| 7769 | self.register_manager.getRegAssumeFree(.rcx, null); | 7819 | self.register_manager.getRegAssumeFree(.rcx, null); |
| 7770 | try self.genSetReg(.cl, Type.u8, shift_mcv); | 7820 | try self.genSetReg(.cl, Type.u8, shift_mcv, .{}); |
| 7771 | break :rhs .{ .register = .rcx }; | 7821 | break :rhs .{ .register = .rcx }; |
| 7772 | }; | 7822 | }; |
| 7773 | | 7823 | |
| ... | @@ -8161,7 +8211,7 @@ fn genShiftBinOp( | ... | @@ -8161,7 +8211,7 @@ fn genShiftBinOp( |
| 8161 | if (self.reuseOperand(inst, bin_op.lhs, 0, lhs_mcv)) break :dst lhs_mcv; | 8211 | if (self.reuseOperand(inst, bin_op.lhs, 0, lhs_mcv)) break :dst lhs_mcv; |
| 8162 | } | 8212 | } |
| 8163 | const dst_mcv = try self.allocRegOrMemAdvanced(lhs_ty, maybe_inst, true); | 8213 | const dst_mcv = try self.allocRegOrMemAdvanced(lhs_ty, maybe_inst, true); |
| 8164 | try self.genCopy(lhs_ty, dst_mcv, lhs_mcv); | 8214 | try self.genCopy(lhs_ty, dst_mcv, lhs_mcv, .{}); |
| 8165 | break :dst dst_mcv; | 8215 | break :dst dst_mcv; |
| 8166 | }; | 8216 | }; |
| 8167 | | 8217 | |
| ... | @@ -8290,6 +8340,7 @@ fn genMulDivBinOp( | ... | @@ -8290,6 +8340,7 @@ fn genMulDivBinOp( |
| 8290 | dst_mcv.address(), | 8340 | dst_mcv.address(), |
| 8291 | .{ .immediate = 0 }, | 8341 | .{ .immediate = 0 }, |
| 8292 | .{ .immediate = src_abi_size }, | 8342 | .{ .immediate = src_abi_size }, |
| | 8343 | .{}, |
| 8293 | ); | 8344 | ); |
| 8294 | | 8345 | |
| 8295 | const temp_regs = try self.register_manager.allocRegs( | 8346 | const temp_regs = try self.register_manager.allocRegs( |
| ... | @@ -8891,7 +8942,7 @@ fn genBinOp( | ... | @@ -8891,7 +8942,7 @@ fn genBinOp( |
| 8891 | if (sse_op and lhs_mcv.isRegister() and self.hasFeature(.avx)) | 8942 | if (sse_op and lhs_mcv.isRegister() and self.hasFeature(.avx)) |
| 8892 | copied_to_dst = false | 8943 | copied_to_dst = false |
| 8893 | else | 8944 | else |
| 8894 | try self.genCopy(lhs_ty, dst_mcv, lhs_mcv); | 8945 | try self.genCopy(lhs_ty, dst_mcv, lhs_mcv, .{}); |
| 8895 | rhs_mcv = try self.resolveInst(ordered_air[1]); | 8946 | rhs_mcv = try self.resolveInst(ordered_air[1]); |
| 8896 | break :dst dst_mcv; | 8947 | break :dst dst_mcv; |
| 8897 | }; | 8948 | }; |
| ... | @@ -8906,7 +8957,7 @@ fn genBinOp( | ... | @@ -8906,7 +8957,7 @@ fn genBinOp( |
| 8906 | const src_mcv: MCValue = if (maybe_mask_reg) |mask_reg| | 8957 | const src_mcv: MCValue = if (maybe_mask_reg) |mask_reg| |
| 8907 | if (self.hasFeature(.avx) and unmat_src_mcv.isRegister() and maybe_inst != null and | 8958 | if (self.hasFeature(.avx) and unmat_src_mcv.isRegister() and maybe_inst != null and |
| 8908 | self.liveness.operandDies(maybe_inst.?, if (flipped) 0 else 1)) unmat_src_mcv else src: { | 8959 | self.liveness.operandDies(maybe_inst.?, if (flipped) 0 else 1)) unmat_src_mcv else src: { |
| 8909 | try self.genSetReg(mask_reg, rhs_ty, unmat_src_mcv); | 8960 | try self.genSetReg(mask_reg, rhs_ty, unmat_src_mcv, .{}); |
| 8910 | break :src .{ .register = mask_reg }; | 8961 | break :src .{ .register = mask_reg }; |
| 8911 | } | 8962 | } |
| 8912 | else | 8963 | else |
| ... | @@ -8981,7 +9032,7 @@ fn genBinOp( | ... | @@ -8981,7 +9032,7 @@ fn genBinOp( |
| 8981 | defer for (dst_regs_locks) |dst_lock| if (dst_lock) |lock| | 9032 | defer for (dst_regs_locks) |dst_lock| if (dst_lock) |lock| |
| 8982 | self.register_manager.unlockReg(lock); | 9033 | self.register_manager.unlockReg(lock); |
| 8983 | | 9034 | |
| 8984 | try self.genCopy(lhs_ty, .{ .register_pair = dst_regs }, dst_mcv); | 9035 | try self.genCopy(lhs_ty, .{ .register_pair = dst_regs }, dst_mcv, .{}); |
| 8985 | break :dst dst_regs; | 9036 | break :dst dst_regs; |
| 8986 | }, | 9037 | }, |
| 8987 | }; | 9038 | }; |
| ... | @@ -9036,7 +9087,7 @@ fn genBinOp( | ... | @@ -9036,7 +9087,7 @@ fn genBinOp( |
| 9036 | try self.asmCmovccRegisterRegister(cc, dst_regs[0], src_mcv.register_pair[0]); | 9087 | try self.asmCmovccRegisterRegister(cc, dst_regs[0], src_mcv.register_pair[0]); |
| 9037 | try self.asmCmovccRegisterRegister(cc, dst_regs[1], src_mcv.register_pair[1]); | 9088 | try self.asmCmovccRegisterRegister(cc, dst_regs[1], src_mcv.register_pair[1]); |
| 9038 | } | 9089 | } |
| 9039 | try self.genCopy(lhs_ty, dst_mcv, .{ .register_pair = dst_regs }); | 9090 | try self.genCopy(lhs_ty, dst_mcv, .{ .register_pair = dst_regs }, .{}); |
| 9040 | } else { | 9091 | } else { |
| 9041 | const mat_src_mcv: MCValue = if (switch (resolved_src_mcv) { | 9092 | const mat_src_mcv: MCValue = if (switch (resolved_src_mcv) { |
| 9042 | .immediate, | 9093 | .immediate, |
| ... | @@ -9146,7 +9197,7 @@ fn genBinOp( | ... | @@ -9146,7 +9197,7 @@ fn genBinOp( |
| 9146 | }, | 9197 | }, |
| 9147 | ), | 9198 | ), |
| 9148 | } | 9199 | } |
| 9149 | try self.genCopy(lhs_ty, dst_mcv, .{ .register = tmp_reg }); | 9200 | try self.genCopy(lhs_ty, dst_mcv, .{ .register = tmp_reg }, .{}); |
| 9150 | } | 9201 | } |
| 9151 | }, | 9202 | }, |
| 9152 | | 9203 | |
| ... | @@ -10519,7 +10570,7 @@ fn genBinOpMir( | ... | @@ -10519,7 +10570,7 @@ fn genBinOpMir( |
| 10519 | const dst_addr_lock = self.register_manager.lockRegAssumeUnused(dst_addr_reg); | 10570 | const dst_addr_lock = self.register_manager.lockRegAssumeUnused(dst_addr_reg); |
| 10520 | errdefer self.register_manager.unlockReg(dst_addr_lock); | 10571 | errdefer self.register_manager.unlockReg(dst_addr_lock); |
| 10521 | | 10572 | |
| 10522 | try self.genSetReg(dst_addr_reg, Type.usize, dst_mcv.address()); | 10573 | try self.genSetReg(dst_addr_reg, Type.usize, dst_mcv.address(), .{}); |
| 10523 | break :dst .{ .addr_reg = dst_addr_reg, .addr_lock = dst_addr_lock }; | 10574 | break :dst .{ .addr_reg = dst_addr_reg, .addr_lock = dst_addr_lock }; |
| 10524 | }, | 10575 | }, |
| 10525 | .load_frame => null, | 10576 | .load_frame => null, |
| ... | @@ -10566,7 +10617,7 @@ fn genBinOpMir( | ... | @@ -10566,7 +10617,7 @@ fn genBinOpMir( |
| 10566 | const src_addr_lock = self.register_manager.lockRegAssumeUnused(src_addr_reg); | 10617 | const src_addr_lock = self.register_manager.lockRegAssumeUnused(src_addr_reg); |
| 10567 | errdefer self.register_manager.unlockReg(src_addr_lock); | 10618 | errdefer self.register_manager.unlockReg(src_addr_lock); |
| 10568 | | 10619 | |
| 10569 | try self.genSetReg(src_addr_reg, Type.usize, resolved_src_mcv.address()); | 10620 | try self.genSetReg(src_addr_reg, Type.usize, resolved_src_mcv.address(), .{}); |
| 10570 | break :src .{ .addr_reg = src_addr_reg, .addr_lock = src_addr_lock }; | 10621 | break :src .{ .addr_reg = src_addr_reg, .addr_lock = src_addr_lock }; |
| 10571 | }, | 10622 | }, |
| 10572 | }; | 10623 | }; |
| ... | @@ -10867,7 +10918,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M | ... | @@ -10867,7 +10918,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 10867 | defer self.register_manager.unlockReg(tmp_lock); | 10918 | defer self.register_manager.unlockReg(tmp_lock); |
| 10868 | | 10919 | |
| 10869 | try self.genIntMulComplexOpMir(dst_ty, tmp_mcv, src_mcv); | 10920 | try self.genIntMulComplexOpMir(dst_ty, tmp_mcv, src_mcv); |
| 10870 | try self.genCopy(dst_ty, dst_mcv, tmp_mcv); | 10921 | try self.genCopy(dst_ty, dst_mcv, tmp_mcv, .{}); |
| 10871 | }, | 10922 | }, |
| 10872 | } | 10923 | } |
| 10873 | } | 10924 | } |
| ... | @@ -10890,7 +10941,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -10890,7 +10941,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { |
| 10890 | .indirect => |reg_off| dst: { | 10941 | .indirect => |reg_off| dst: { |
| 10891 | self.register_manager.getRegAssumeFree(reg_off.reg, inst); | 10942 | self.register_manager.getRegAssumeFree(reg_off.reg, inst); |
| 10892 | const dst_mcv = try self.allocRegOrMem(inst, false); | 10943 | const dst_mcv = try self.allocRegOrMem(inst, false); |
| 10893 | try self.genCopy(arg_ty, dst_mcv, src_mcv); | 10944 | try self.genCopy(arg_ty, dst_mcv, src_mcv, .{}); |
| 10894 | break :dst dst_mcv; | 10945 | break :dst dst_mcv; |
| 10895 | }, | 10946 | }, |
| 10896 | else => return self.fail("TODO implement arg for {}", .{src_mcv}), | 10947 | else => return self.fail("TODO implement arg for {}", .{src_mcv}), |
| ... | @@ -10998,13 +11049,13 @@ fn airBreakpoint(self: *Self) !void { | ... | @@ -10998,13 +11049,13 @@ fn airBreakpoint(self: *Self) !void { |
| 10998 | | 11049 | |
| 10999 | fn airRetAddr(self: *Self, inst: Air.Inst.Index) !void { | 11050 | fn airRetAddr(self: *Self, inst: Air.Inst.Index) !void { |
| 11000 | const dst_mcv = try self.allocRegOrMem(inst, true); | 11051 | const dst_mcv = try self.allocRegOrMem(inst, true); |
| 11001 | try self.genCopy(Type.usize, dst_mcv, .{ .load_frame = .{ .index = .ret_addr } }); | 11052 | try self.genCopy(Type.usize, dst_mcv, .{ .load_frame = .{ .index = .ret_addr } }, .{}); |
| 11002 | return self.finishAir(inst, dst_mcv, .{ .none, .none, .none }); | 11053 | return self.finishAir(inst, dst_mcv, .{ .none, .none, .none }); |
| 11003 | } | 11054 | } |
| 11004 | | 11055 | |
| 11005 | fn airFrameAddress(self: *Self, inst: Air.Inst.Index) !void { | 11056 | fn airFrameAddress(self: *Self, inst: Air.Inst.Index) !void { |
| 11006 | const dst_mcv = try self.allocRegOrMem(inst, true); | 11057 | const dst_mcv = try self.allocRegOrMem(inst, true); |
| 11007 | try self.genCopy(Type.usize, dst_mcv, .{ .lea_frame = .{ .index = .base_ptr } }); | 11058 | try self.genCopy(Type.usize, dst_mcv, .{ .lea_frame = .{ .index = .base_ptr } }, .{}); |
| 11008 | return self.finishAir(inst, dst_mcv, .{ .none, .none, .none }); | 11059 | return self.finishAir(inst, dst_mcv, .{ .none, .none, .none }); |
| 11009 | } | 11060 | } |
| 11010 | | 11061 | |
| ... | @@ -11143,12 +11194,12 @@ fn genCall(self: *Self, info: union(enum) { | ... | @@ -11143,12 +11194,12 @@ fn genCall(self: *Self, info: union(enum) { |
| 11143 | }, | 11194 | }, |
| 11144 | .indirect => |reg_off| { | 11195 | .indirect => |reg_off| { |
| 11145 | frame_index.* = try self.allocFrameIndex(FrameAlloc.initType(arg_ty, mod)); | 11196 | frame_index.* = try self.allocFrameIndex(FrameAlloc.initType(arg_ty, mod)); |
| 11146 | try self.genSetMem(.{ .frame = frame_index.* }, 0, arg_ty, src_arg); | 11197 | try self.genSetMem(.{ .frame = frame_index.* }, 0, arg_ty, src_arg, .{}); |
| 11147 | try self.register_manager.getReg(reg_off.reg, null); | 11198 | try self.register_manager.getReg(reg_off.reg, null); |
| 11148 | try reg_locks.append(self.register_manager.lockReg(reg_off.reg)); | 11199 | try reg_locks.append(self.register_manager.lockReg(reg_off.reg)); |
| 11149 | }, | 11200 | }, |
| 11150 | .load_frame => { | 11201 | .load_frame => { |
| 11151 | try self.genCopy(arg_ty, dst_arg, src_arg); | 11202 | try self.genCopy(arg_ty, dst_arg, src_arg, .{}); |
| 11152 | try self.freeValue(src_arg); | 11203 | try self.freeValue(src_arg); |
| 11153 | }, | 11204 | }, |
| 11154 | else => unreachable, | 11205 | else => unreachable, |
| ... | @@ -11162,7 +11213,7 @@ fn genCall(self: *Self, info: union(enum) { | ... | @@ -11162,7 +11213,7 @@ fn genCall(self: *Self, info: union(enum) { |
| 11162 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(ret_ty, mod)); | 11213 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(ret_ty, mod)); |
| 11163 | try self.genSetReg(reg_off.reg, Type.usize, .{ | 11214 | try self.genSetReg(reg_off.reg, Type.usize, .{ |
| 11164 | .lea_frame = .{ .index = frame_index, .off = -reg_off.off }, | 11215 | .lea_frame = .{ .index = frame_index, .off = -reg_off.off }, |
| 11165 | }); | 11216 | }, .{}); |
| 11166 | call_info.return_value.short = .{ .load_frame = .{ .index = frame_index } }; | 11217 | call_info.return_value.short = .{ .load_frame = .{ .index = frame_index } }; |
| 11167 | try reg_locks.append(self.register_manager.lockReg(reg_off.reg)); | 11218 | try reg_locks.append(self.register_manager.lockReg(reg_off.reg)); |
| 11168 | }, | 11219 | }, |
| ... | @@ -11177,20 +11228,21 @@ fn genCall(self: *Self, info: union(enum) { | ... | @@ -11177,20 +11228,21 @@ fn genCall(self: *Self, info: union(enum) { |
| 11177 | registerAlias(dst_reg, @intCast(arg_ty.abiSize(mod))), | 11228 | registerAlias(dst_reg, @intCast(arg_ty.abiSize(mod))), |
| 11178 | arg_ty, | 11229 | arg_ty, |
| 11179 | src_arg, | 11230 | src_arg, |
| | 11231 | .{}, |
| 11180 | ), | 11232 | ), |
| 11181 | .C, .SysV, .Win64 => { | 11233 | .C, .SysV, .Win64 => { |
| 11182 | const promoted_ty = self.promoteInt(arg_ty); | 11234 | const promoted_ty = self.promoteInt(arg_ty); |
| 11183 | const promoted_abi_size: u32 = @intCast(promoted_ty.abiSize(mod)); | 11235 | const promoted_abi_size: u32 = @intCast(promoted_ty.abiSize(mod)); |
| 11184 | const dst_alias = registerAlias(dst_reg, promoted_abi_size); | 11236 | const dst_alias = registerAlias(dst_reg, promoted_abi_size); |
| 11185 | try self.genSetReg(dst_alias, promoted_ty, src_arg); | 11237 | try self.genSetReg(dst_alias, promoted_ty, src_arg, .{}); |
| 11186 | if (promoted_ty.toIntern() != arg_ty.toIntern()) | 11238 | if (promoted_ty.toIntern() != arg_ty.toIntern()) |
| 11187 | try self.truncateRegister(arg_ty, dst_alias); | 11239 | try self.truncateRegister(arg_ty, dst_alias); |
| 11188 | }, | 11240 | }, |
| 11189 | }, | 11241 | }, |
| 11190 | .register_pair => try self.genCopy(arg_ty, dst_arg, src_arg), | 11242 | .register_pair => try self.genCopy(arg_ty, dst_arg, src_arg, .{}), |
| 11191 | .indirect => |reg_off| try self.genSetReg(reg_off.reg, Type.usize, .{ | 11243 | .indirect => |reg_off| try self.genSetReg(reg_off.reg, Type.usize, .{ |
| 11192 | .lea_frame = .{ .index = frame_index, .off = -reg_off.off }, | 11244 | .lea_frame = .{ .index = frame_index, .off = -reg_off.off }, |
| 11193 | }), | 11245 | }, .{}), |
| 11194 | else => unreachable, | 11246 | else => unreachable, |
| 11195 | }; | 11247 | }; |
| 11196 | | 11248 | |
| ... | @@ -11231,6 +11283,7 @@ fn genCall(self: *Self, info: union(enum) { | ... | @@ -11231,6 +11283,7 @@ fn genCall(self: *Self, info: union(enum) { |
| 11231 | callee_reg, | 11283 | callee_reg, |
| 11232 | Type.usize, | 11284 | Type.usize, |
| 11233 | .{ .load_symbol = .{ .sym = sym.esym_index } }, | 11285 | .{ .load_symbol = .{ .sym = sym.esym_index } }, |
| | 11286 | .{}, |
| 11234 | ); | 11287 | ); |
| 11235 | try self.asmRegister(.{ ._, .call }, callee_reg); | 11288 | try self.asmRegister(.{ ._, .call }, callee_reg); |
| 11236 | } else try self.asmMemory(.{ ._, .call }, .{ | 11289 | } else try self.asmMemory(.{ ._, .call }, .{ |
| ... | @@ -11243,12 +11296,17 @@ fn genCall(self: *Self, info: union(enum) { | ... | @@ -11243,12 +11296,17 @@ fn genCall(self: *Self, info: union(enum) { |
| 11243 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { | 11296 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { |
| 11244 | const atom = try coff_file.getOrCreateAtomForDecl(func.owner_decl); | 11297 | const atom = try coff_file.getOrCreateAtomForDecl(func.owner_decl); |
| 11245 | const sym_index = coff_file.getAtom(atom).getSymbolIndex().?; | 11298 | const sym_index = coff_file.getAtom(atom).getSymbolIndex().?; |
| 11246 | try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index }); | 11299 | try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index }, .{}); |
| 11247 | try self.asmRegister(.{ ._, .call }, .rax); | 11300 | try self.asmRegister(.{ ._, .call }, .rax); |
| 11248 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { | 11301 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { |
| 11249 | const sym_index = try macho_file.getZigObject().?.getOrCreateMetadataForDecl(macho_file, func.owner_decl); | 11302 | const sym_index = try macho_file.getZigObject().?.getOrCreateMetadataForDecl(macho_file, func.owner_decl); |
| 11250 | const sym = macho_file.getSymbol(sym_index); | 11303 | const sym = macho_file.getSymbol(sym_index); |
| 11251 | try self.genSetReg(.rax, Type.usize, .{ .load_symbol = .{ .sym = sym.nlist_idx } }); | 11304 | try self.genSetReg( |
| | 11305 | .rax, |
| | 11306 | Type.usize, |
| | 11307 | .{ .load_symbol = .{ .sym = sym.nlist_idx } }, |
| | 11308 | .{}, |
| | 11309 | ); |
| 11252 | try self.asmRegister(.{ ._, .call }, .rax); | 11310 | try self.asmRegister(.{ ._, .call }, .rax); |
| 11253 | } else if (self.bin_file.cast(link.File.Plan9)) |p9| { | 11311 | } else if (self.bin_file.cast(link.File.Plan9)) |p9| { |
| 11254 | const atom_index = try p9.seeDecl(func.owner_decl); | 11312 | const atom_index = try p9.seeDecl(func.owner_decl); |
| ... | @@ -11273,7 +11331,7 @@ fn genCall(self: *Self, info: union(enum) { | ... | @@ -11273,7 +11331,7 @@ fn genCall(self: *Self, info: union(enum) { |
| 11273 | } | 11331 | } |
| 11274 | } else { | 11332 | } else { |
| 11275 | assert(self.typeOf(callee).zigTypeTag(mod) == .Pointer); | 11333 | assert(self.typeOf(callee).zigTypeTag(mod) == .Pointer); |
| 11276 | try self.genSetReg(.rax, Type.usize, .{ .air_ref = callee }); | 11334 | try self.genSetReg(.rax, Type.usize, .{ .air_ref = callee }, .{}); |
| 11277 | try self.asmRegister(.{ ._, .call }, .rax); | 11335 | try self.asmRegister(.{ ._, .call }, .rax); |
| 11278 | }, | 11336 | }, |
| 11279 | .lib => |lib| try self.genExternSymbolRef(.call, lib.lib, lib.callee), | 11337 | .lib => |lib| try self.genExternSymbolRef(.call, lib.lib, lib.callee), |
| ... | @@ -11281,7 +11339,7 @@ fn genCall(self: *Self, info: union(enum) { | ... | @@ -11281,7 +11339,7 @@ fn genCall(self: *Self, info: union(enum) { |
| 11281 | return call_info.return_value.short; | 11339 | return call_info.return_value.short; |
| 11282 | } | 11340 | } |
| 11283 | | 11341 | |
| 11284 | fn airRet(self: *Self, inst: Air.Inst.Index) !void { | 11342 | fn airRet(self: *Self, inst: Air.Inst.Index, safety: bool) !void { |
| 11285 | const mod = self.bin_file.comp.module.?; | 11343 | const mod = self.bin_file.comp.module.?; |
| 11286 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 11344 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 11287 | | 11345 | |
| ... | @@ -11290,14 +11348,20 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -11290,14 +11348,20 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void { |
| 11290 | .none => {}, | 11348 | .none => {}, |
| 11291 | .register, | 11349 | .register, |
| 11292 | .register_pair, | 11350 | .register_pair, |
| 11293 | => try self.genCopy(ret_ty, self.ret_mcv.short, .{ .air_ref = un_op }), | 11351 | => try self.genCopy(ret_ty, self.ret_mcv.short, .{ .air_ref = un_op }, .{ .safety = safety }), |
| 11294 | .indirect => |reg_off| { | 11352 | .indirect => |reg_off| { |
| 11295 | try self.register_manager.getReg(reg_off.reg, null); | 11353 | try self.register_manager.getReg(reg_off.reg, null); |
| 11296 | const lock = self.register_manager.lockRegAssumeUnused(reg_off.reg); | 11354 | const lock = self.register_manager.lockRegAssumeUnused(reg_off.reg); |
| 11297 | defer self.register_manager.unlockReg(lock); | 11355 | defer self.register_manager.unlockReg(lock); |
| 11298 | | 11356 | |
| 11299 | try self.genSetReg(reg_off.reg, Type.usize, self.ret_mcv.long); | 11357 | try self.genSetReg(reg_off.reg, Type.usize, self.ret_mcv.long, .{}); |
| 11300 | try self.genSetMem(.{ .reg = reg_off.reg }, reg_off.off, ret_ty, .{ .air_ref = un_op }); | 11358 | try self.genSetMem( |
| | 11359 | .{ .reg = reg_off.reg }, |
| | 11360 | reg_off.off, |
| | 11361 | ret_ty, |
| | 11362 | .{ .air_ref = un_op }, |
| | 11363 | .{ .safety = safety }, |
| | 11364 | ); |
| 11301 | }, | 11365 | }, |
| 11302 | else => unreachable, | 11366 | else => unreachable, |
| 11303 | } | 11367 | } |
| ... | @@ -11318,7 +11382,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -11318,7 +11382,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 11318 | switch (self.ret_mcv.short) { | 11382 | switch (self.ret_mcv.short) { |
| 11319 | .none => {}, | 11383 | .none => {}, |
| 11320 | .register, .register_pair => try self.load(self.ret_mcv.short, ptr_ty, ptr), | 11384 | .register, .register_pair => try self.load(self.ret_mcv.short, ptr_ty, ptr), |
| 11321 | .indirect => |reg_off| try self.genSetReg(reg_off.reg, ptr_ty, ptr), | 11385 | .indirect => |reg_off| try self.genSetReg(reg_off.reg, ptr_ty, ptr, .{}), |
| 11322 | else => unreachable, | 11386 | else => unreachable, |
| 11323 | } | 11387 | } |
| 11324 | self.ret_mcv.liveOut(self, inst); | 11388 | self.ret_mcv.liveOut(self, inst); |
| ... | @@ -11423,7 +11487,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { | ... | @@ -11423,7 +11487,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 11423 | const dst_mcv = if (unmat_dst_mcv.isRegister() or | 11487 | const dst_mcv = if (unmat_dst_mcv.isRegister() or |
| 11424 | (abi_size <= 8 and unmat_dst_mcv.isMemory())) unmat_dst_mcv else dst: { | 11488 | (abi_size <= 8 and unmat_dst_mcv.isMemory())) unmat_dst_mcv else dst: { |
| 11425 | const dst_mcv = try self.allocTempRegOrMem(ty, true); | 11489 | const dst_mcv = try self.allocTempRegOrMem(ty, true); |
| 11426 | try self.genCopy(ty, dst_mcv, unmat_dst_mcv); | 11490 | try self.genCopy(ty, dst_mcv, unmat_dst_mcv, .{}); |
| 11427 | break :dst dst_mcv; | 11491 | break :dst dst_mcv; |
| 11428 | }; | 11492 | }; |
| 11429 | const dst_lock = | 11493 | const dst_lock = |
| ... | @@ -11494,6 +11558,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { | ... | @@ -11494,6 +11558,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 11494 | dst_addr_reg, | 11558 | dst_addr_reg, |
| 11495 | Type.usize, | 11559 | Type.usize, |
| 11496 | resolved_dst_mcv.address(), | 11560 | resolved_dst_mcv.address(), |
| | 11561 | .{}, |
| 11497 | ); | 11562 | ); |
| 11498 | break :dst .{ | 11563 | break :dst .{ |
| 11499 | .addr_reg = dst_addr_reg, | 11564 | .addr_reg = dst_addr_reg, |
| ... | @@ -11553,6 +11618,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { | ... | @@ -11553,6 +11618,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 11553 | src_addr_reg, | 11618 | src_addr_reg, |
| 11554 | Type.usize, | 11619 | Type.usize, |
| 11555 | resolved_src_mcv.address(), | 11620 | resolved_src_mcv.address(), |
| | 11621 | .{}, |
| 11556 | ); | 11622 | ); |
| 11557 | break :src .{ | 11623 | break :src .{ |
| 11558 | .addr_reg = src_addr_reg, | 11624 | .addr_reg = src_addr_reg, |
| ... | @@ -11594,7 +11660,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { | ... | @@ -11594,7 +11660,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 11594 | .off = frame_addr.off + off, | 11660 | .off = frame_addr.off + off, |
| 11595 | } }, | 11661 | } }, |
| 11596 | else => unreachable, | 11662 | else => unreachable, |
| 11597 | }); | 11663 | }, .{}); |
| 11598 | | 11664 | |
| 11599 | try self.genBinOpMir( | 11665 | try self.genBinOpMir( |
| 11600 | .{ ._, .xor }, | 11666 | .{ ._, .xor }, |
| ... | @@ -12000,7 +12066,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC | ... | @@ -12000,7 +12066,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC |
| 12000 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); | 12066 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 12001 | defer self.register_manager.unlockReg(addr_reg_lock); | 12067 | defer self.register_manager.unlockReg(addr_reg_lock); |
| 12002 | | 12068 | |
| 12003 | try self.genSetReg(addr_reg, Type.usize, opt_mcv.address()); | 12069 | try self.genSetReg(addr_reg, Type.usize, opt_mcv.address(), .{}); |
| 12004 | const some_abi_size: u32 = @intCast(some_info.ty.abiSize(mod)); | 12070 | const some_abi_size: u32 = @intCast(some_info.ty.abiSize(mod)); |
| 12005 | try self.asmMemoryImmediate( | 12071 | try self.asmMemoryImmediate( |
| 12006 | .{ ._, .cmp }, | 12072 | .{ ._, .cmp }, |
| ... | @@ -12440,7 +12506,7 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -12440,7 +12506,7 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void { |
| 12440 | try self.getValue(block_tracking.short, br.block_inst); | 12506 | try self.getValue(block_tracking.short, br.block_inst); |
| 12441 | break :dst block_tracking.short; | 12507 | break :dst block_tracking.short; |
| 12442 | }; | 12508 | }; |
| 12443 | try self.genCopy(block_ty, dst_mcv, try self.resolveInst(br.operand)); | 12509 | try self.genCopy(block_ty, dst_mcv, try self.resolveInst(br.operand), .{}); |
| 12444 | break :result dst_mcv; | 12510 | break :result dst_mcv; |
| 12445 | }; | 12511 | }; |
| 12446 | | 12512 | |
| ... | @@ -12604,7 +12670,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -12604,7 +12670,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 12604 | rc.isSet(RegisterManager.indexOfRegIntoTracked(input_mcv.getReg().?).?)) | 12670 | rc.isSet(RegisterManager.indexOfRegIntoTracked(input_mcv.getReg().?).?)) |
| 12605 | break :arg input_mcv; | 12671 | break :arg input_mcv; |
| 12606 | const reg = try self.register_manager.allocReg(null, rc); | 12672 | const reg = try self.register_manager.allocReg(null, rc); |
| 12607 | try self.genSetReg(reg, ty, input_mcv); | 12673 | try self.genSetReg(reg, ty, input_mcv, .{}); |
| 12608 | break :arg .{ .register = registerAlias(reg, @intCast(ty.abiSize(mod))) }; | 12674 | break :arg .{ .register = registerAlias(reg, @intCast(ty.abiSize(mod))) }; |
| 12609 | } else if (mem.eql(u8, constraint, "i") or mem.eql(u8, constraint, "n")) | 12675 | } else if (mem.eql(u8, constraint, "i") or mem.eql(u8, constraint, "n")) |
| 12610 | switch (input_mcv) { | 12676 | switch (input_mcv) { |
| ... | @@ -12621,16 +12687,16 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -12621,16 +12687,16 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 12621 | .load_symbol, .load_direct, .load_got, .load_tlv => {}, | 12687 | .load_symbol, .load_direct, .load_got, .load_tlv => {}, |
| 12622 | else => { | 12688 | else => { |
| 12623 | const temp_mcv = try self.allocTempRegOrMem(ty, false); | 12689 | const temp_mcv = try self.allocTempRegOrMem(ty, false); |
| 12624 | try self.genCopy(ty, temp_mcv, input_mcv); | 12690 | try self.genCopy(ty, temp_mcv, input_mcv, .{}); |
| 12625 | break :arg temp_mcv; | 12691 | break :arg temp_mcv; |
| 12626 | }, | 12692 | }, |
| 12627 | } | 12693 | } |
| 12628 | const addr_reg = self.register_manager.tryAllocReg(null, abi.RegisterClass.gp) orelse { | 12694 | const addr_reg = self.register_manager.tryAllocReg(null, abi.RegisterClass.gp) orelse { |
| 12629 | const temp_mcv = try self.allocTempRegOrMem(ty, false); | 12695 | const temp_mcv = try self.allocTempRegOrMem(ty, false); |
| 12630 | try self.genCopy(ty, temp_mcv, input_mcv); | 12696 | try self.genCopy(ty, temp_mcv, input_mcv, .{}); |
| 12631 | break :arg temp_mcv; | 12697 | break :arg temp_mcv; |
| 12632 | }; | 12698 | }; |
| 12633 | try self.genSetReg(addr_reg, Type.usize, input_mcv.address()); | 12699 | try self.genSetReg(addr_reg, Type.usize, input_mcv.address(), .{}); |
| 12634 | break :arg .{ .indirect = .{ .reg = addr_reg } }; | 12700 | break :arg .{ .indirect = .{ .reg = addr_reg } }; |
| 12635 | } else if (mem.eql(u8, constraint, "g") or | 12701 | } else if (mem.eql(u8, constraint, "g") or |
| 12636 | mem.eql(u8, constraint, "rm") or mem.eql(u8, constraint, "mr") or | 12702 | mem.eql(u8, constraint, "rm") or mem.eql(u8, constraint, "mr") or |
| ... | @@ -12643,7 +12709,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -12643,7 +12709,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 12643 | else => {}, | 12709 | else => {}, |
| 12644 | } | 12710 | } |
| 12645 | const temp_mcv = try self.allocTempRegOrMem(ty, true); | 12711 | const temp_mcv = try self.allocTempRegOrMem(ty, true); |
| 12646 | try self.genCopy(ty, temp_mcv, input_mcv); | 12712 | try self.genCopy(ty, temp_mcv, input_mcv, .{}); |
| 12647 | break :arg temp_mcv; | 12713 | break :arg temp_mcv; |
| 12648 | } else if (mem.eql(u8, constraint, "X")) | 12714 | } else if (mem.eql(u8, constraint, "X")) |
| 12649 | input_mcv | 12715 | input_mcv |
| ... | @@ -12651,7 +12717,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -12651,7 +12717,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 12651 | const reg = parseRegName(constraint["{".len .. constraint.len - "}".len]) orelse | 12717 | const reg = parseRegName(constraint["{".len .. constraint.len - "}".len]) orelse |
| 12652 | return self.fail("invalid register constraint: '{s}'", .{constraint}); | 12718 | return self.fail("invalid register constraint: '{s}'", .{constraint}); |
| 12653 | try self.register_manager.getReg(reg, null); | 12719 | try self.register_manager.getReg(reg, null); |
| 12654 | try self.genSetReg(reg, ty, input_mcv); | 12720 | try self.genSetReg(reg, ty, input_mcv, .{}); |
| 12655 | break :arg .{ .register = reg }; | 12721 | break :arg .{ .register = reg }; |
| 12656 | } else if (constraint.len == 1 and std.ascii.isDigit(constraint[0])) arg: { | 12722 | } else if (constraint.len == 1 and std.ascii.isDigit(constraint[0])) arg: { |
| 12657 | const index = std.fmt.charToDigit(constraint[0], 10) catch unreachable; | 12723 | const index = std.fmt.charToDigit(constraint[0], 10) catch unreachable; |
| ... | @@ -13105,7 +13171,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -13105,7 +13171,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 13105 | if (output == .none) continue; | 13171 | if (output == .none) continue; |
| 13106 | if (arg_mcv != .register) continue; | 13172 | if (arg_mcv != .register) continue; |
| 13107 | if (constraint.len == 2 and std.ascii.isDigit(constraint[1])) continue; | 13173 | if (constraint.len == 2 and std.ascii.isDigit(constraint[1])) continue; |
| 13108 | try self.store(self.typeOf(output), .{ .air_ref = output }, arg_mcv); | 13174 | try self.store(self.typeOf(output), .{ .air_ref = output }, arg_mcv, .{}); |
| 13109 | } | 13175 | } |
| 13110 | | 13176 | |
| 13111 | simple: { | 13177 | simple: { |
| ... | @@ -13477,7 +13543,11 @@ fn moveStrategy(self: *Self, ty: Type, class: Register.Class, aligned: bool) !Mo | ... | @@ -13477,7 +13543,11 @@ fn moveStrategy(self: *Self, ty: Type, class: Register.Class, aligned: bool) !Mo |
| 13477 | return self.fail("TODO moveStrategy for {}", .{ty.fmt(mod)}); | 13543 | return self.fail("TODO moveStrategy for {}", .{ty.fmt(mod)}); |
| 13478 | } | 13544 | } |
| 13479 | | 13545 | |
| 13480 | fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError!void { | 13546 | const CopyOptions = struct { |
| | 13547 | safety: bool = false, |
| | 13548 | }; |
| | 13549 | |
| | 13550 | fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: CopyOptions) InnerError!void { |
| 13481 | const mod = self.bin_file.comp.module.?; | 13551 | const mod = self.bin_file.comp.module.?; |
| 13482 | | 13552 | |
| 13483 | const src_lock = if (src_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null; | 13553 | const src_lock = if (src_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null; |
| ... | @@ -13499,7 +13569,7 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError | ... | @@ -13499,7 +13569,7 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError |
| 13499 | .reserved_frame, | 13569 | .reserved_frame, |
| 13500 | .air_ref, | 13570 | .air_ref, |
| 13501 | => unreachable, // unmodifiable destination | 13571 | => unreachable, // unmodifiable destination |
| 13502 | .register => |reg| try self.genSetReg(reg, ty, src_mcv), | 13572 | .register => |reg| try self.genSetReg(reg, ty, src_mcv, opts), |
| 13503 | .register_offset => |dst_reg_off| try self.genSetReg(dst_reg_off.reg, ty, switch (src_mcv) { | 13573 | .register_offset => |dst_reg_off| try self.genSetReg(dst_reg_off.reg, ty, switch (src_mcv) { |
| 13504 | .none, | 13574 | .none, |
| 13505 | .unreach, | 13575 | .unreach, |
| ... | @@ -13517,7 +13587,7 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError | ... | @@ -13517,7 +13587,7 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError |
| 13517 | .reg = try self.copyToTmpRegister(ty, src_mcv), | 13587 | .reg = try self.copyToTmpRegister(ty, src_mcv), |
| 13518 | .off = -dst_reg_off.off, | 13588 | .off = -dst_reg_off.off, |
| 13519 | } }, | 13589 | } }, |
| 13520 | }), | 13590 | }, opts), |
| 13521 | .register_pair => |dst_regs| { | 13591 | .register_pair => |dst_regs| { |
| 13522 | const src_info: ?struct { addr_reg: Register, addr_lock: RegisterLock } = switch (src_mcv) { | 13592 | const src_info: ?struct { addr_reg: Register, addr_lock: RegisterLock } = switch (src_mcv) { |
| 13523 | .register_pair, .memory, .indirect, .load_frame => null, | 13593 | .register_pair, .memory, .indirect, .load_frame => null, |
| ... | @@ -13527,10 +13597,15 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError | ... | @@ -13527,10 +13597,15 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError |
| 13527 | const src_addr_lock = self.register_manager.lockRegAssumeUnused(src_addr_reg); | 13597 | const src_addr_lock = self.register_manager.lockRegAssumeUnused(src_addr_reg); |
| 13528 | errdefer self.register_manager.unlockReg(src_addr_lock); | 13598 | errdefer self.register_manager.unlockReg(src_addr_lock); |
| 13529 | | 13599 | |
| 13530 | try self.genSetReg(src_addr_reg, Type.usize, src_mcv.address()); | 13600 | try self.genSetReg(src_addr_reg, Type.usize, src_mcv.address(), opts); |
| 13531 | break :src .{ .addr_reg = src_addr_reg, .addr_lock = src_addr_lock }; | 13601 | break :src .{ .addr_reg = src_addr_reg, .addr_lock = src_addr_lock }; |
| 13532 | }, | 13602 | }, |
| 13533 | .air_ref => |src_ref| return self.genCopy(ty, dst_mcv, try self.resolveInst(src_ref)), | 13603 | .air_ref => |src_ref| return self.genCopy( |
| | 13604 | ty, |
| | 13605 | dst_mcv, |
| | 13606 | try self.resolveInst(src_ref), |
| | 13607 | opts, |
| | 13608 | ), |
| 13534 | else => return self.fail("TODO implement genCopy for {s} of {}", .{ | 13609 | else => return self.fail("TODO implement genCopy for {s} of {}", .{ |
| 13535 | @tagName(src_mcv), ty.fmt(mod), | 13610 | @tagName(src_mcv), ty.fmt(mod), |
| 13536 | }), | 13611 | }), |
| ... | @@ -13547,15 +13622,21 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError | ... | @@ -13547,15 +13622,21 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError |
| 13547 | .off = part_disp, | 13622 | .off = part_disp, |
| 13548 | } }, | 13623 | } }, |
| 13549 | else => unreachable, | 13624 | else => unreachable, |
| 13550 | }); | 13625 | }, opts); |
| 13551 | part_disp += @intCast(dst_ty.abiSize(mod)); | 13626 | part_disp += @intCast(dst_ty.abiSize(mod)); |
| 13552 | } | 13627 | } |
| 13553 | }, | 13628 | }, |
| 13554 | .indirect => |reg_off| try self.genSetMem(.{ .reg = reg_off.reg }, reg_off.off, ty, src_mcv), | 13629 | .indirect => |reg_off| try self.genSetMem( |
| | 13630 | .{ .reg = reg_off.reg }, |
| | 13631 | reg_off.off, |
| | 13632 | ty, |
| | 13633 | src_mcv, |
| | 13634 | opts, |
| | 13635 | ), |
| 13555 | .memory, .load_symbol, .load_direct, .load_got, .load_tlv => { | 13636 | .memory, .load_symbol, .load_direct, .load_got, .load_tlv => { |
| 13556 | switch (dst_mcv) { | 13637 | switch (dst_mcv) { |
| 13557 | .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr| | 13638 | .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr| |
| 13558 | return self.genSetMem(.{ .reg = .ds }, small_addr, ty, src_mcv), | 13639 | return self.genSetMem(.{ .reg = .ds }, small_addr, ty, src_mcv, opts), |
| 13559 | .load_symbol, .load_direct, .load_got, .load_tlv => {}, | 13640 | .load_symbol, .load_direct, .load_got, .load_tlv => {}, |
| 13560 | else => unreachable, | 13641 | else => unreachable, |
| 13561 | } | 13642 | } |
| ... | @@ -13564,18 +13645,25 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError | ... | @@ -13564,18 +13645,25 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError |
| 13564 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); | 13645 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 13565 | defer self.register_manager.unlockReg(addr_lock); | 13646 | defer self.register_manager.unlockReg(addr_lock); |
| 13566 | | 13647 | |
| 13567 | try self.genSetMem(.{ .reg = addr_reg }, 0, ty, src_mcv); | 13648 | try self.genSetMem(.{ .reg = addr_reg }, 0, ty, src_mcv, opts); |
| 13568 | }, | 13649 | }, |
| 13569 | .load_frame => |frame_addr| try self.genSetMem( | 13650 | .load_frame => |frame_addr| try self.genSetMem( |
| 13570 | .{ .frame = frame_addr.index }, | 13651 | .{ .frame = frame_addr.index }, |
| 13571 | frame_addr.off, | 13652 | frame_addr.off, |
| 13572 | ty, | 13653 | ty, |
| 13573 | src_mcv, | 13654 | src_mcv, |
| | 13655 | opts, |
| 13574 | ), | 13656 | ), |
| 13575 | } | 13657 | } |
| 13576 | } | 13658 | } |
| 13577 | | 13659 | |
| 13578 | fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerError!void { | 13660 | fn genSetReg( |
| | 13661 | self: *Self, |
| | 13662 | dst_reg: Register, |
| | 13663 | ty: Type, |
| | 13664 | src_mcv: MCValue, |
| | 13665 | opts: CopyOptions, |
| | 13666 | ) InnerError!void { |
| 13579 | const mod = self.bin_file.comp.module.?; | 13667 | const mod = self.bin_file.comp.module.?; |
| 13580 | const abi_size: u32 = @intCast(ty.abiSize(mod)); | 13668 | const abi_size: u32 = @intCast(ty.abiSize(mod)); |
| 13581 | if (ty.bitSize(mod) > dst_reg.bitSize()) | 13669 | if (ty.bitSize(mod) > dst_reg.bitSize()) |
| ... | @@ -13587,7 +13675,27 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr | ... | @@ -13587,7 +13675,27 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 13587 | .register_overflow, | 13675 | .register_overflow, |
| 13588 | .reserved_frame, | 13676 | .reserved_frame, |
| 13589 | => unreachable, | 13677 | => unreachable, |
| 13590 | .undef => {}, | 13678 | .undef => if (opts.safety) switch (dst_reg.class()) { |
| | 13679 | .general_purpose => switch (abi_size) { |
| | 13680 | 1 => try self.asmRegisterImmediate(.{ ._, .mov }, dst_reg.to8(), Immediate.u(0xAA)), |
| | 13681 | 2 => try self.asmRegisterImmediate(.{ ._, .mov }, dst_reg.to16(), Immediate.u(0xAAAA)), |
| | 13682 | 3...4 => try self.asmRegisterImmediate( |
| | 13683 | .{ ._, .mov }, |
| | 13684 | dst_reg.to32(), |
| | 13685 | Immediate.s(@as(i32, @bitCast(@as(u32, 0xAAAAAAAA)))), |
| | 13686 | ), |
| | 13687 | 5...8 => try self.asmRegisterImmediate( |
| | 13688 | .{ ._, .mov }, |
| | 13689 | dst_reg.to64(), |
| | 13690 | Immediate.u(0xAAAAAAAAAAAAAAAA), |
| | 13691 | ), |
| | 13692 | else => unreachable, |
| | 13693 | }, |
| | 13694 | .segment, .x87, .mmx, .sse => try self.genSetReg(dst_reg, ty, try self.genTypedValue(.{ |
| | 13695 | .ty = ty, |
| | 13696 | .val = try mod.undefValue(ty), |
| | 13697 | }), opts), |
| | 13698 | }, |
| 13591 | .eflags => |cc| try self.asmSetccRegister(cc, dst_reg.to8()), | 13699 | .eflags => |cc| try self.asmSetccRegister(cc, dst_reg.to8()), |
| 13592 | .immediate => |imm| { | 13700 | .immediate => |imm| { |
| 13593 | if (imm == 0) { | 13701 | if (imm == 0) { |
| ... | @@ -13672,6 +13780,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr | ... | @@ -13672,6 +13780,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 13672 | dst_reg, | 13780 | dst_reg, |
| 13673 | ty, | 13781 | ty, |
| 13674 | .{ .register = try self.copyToTmpRegister(ty, src_mcv) }, | 13782 | .{ .register = try self.copyToTmpRegister(ty, src_mcv) }, |
| | 13783 | opts, |
| 13675 | ), | 13784 | ), |
| 13676 | .x87, .mmx => unreachable, | 13785 | .x87, .mmx => unreachable, |
| 13677 | .sse => try self.asmRegisterRegister( | 13786 | .sse => try self.asmRegisterRegister( |
| ... | @@ -13701,14 +13810,14 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr | ... | @@ -13701,14 +13810,14 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 13701 | ), | 13810 | ), |
| 13702 | }, | 13811 | }, |
| 13703 | }, | 13812 | }, |
| 13704 | .register_pair => |src_regs| try self.genSetReg(dst_reg, ty, .{ .register = src_regs[0] }), | 13813 | .register_pair => |src_regs| try self.genSetReg(dst_reg, ty, .{ .register = src_regs[0] }, opts), |
| 13705 | .register_offset, | 13814 | .register_offset, |
| 13706 | .indirect, | 13815 | .indirect, |
| 13707 | .load_frame, | 13816 | .load_frame, |
| 13708 | .lea_frame, | 13817 | .lea_frame, |
| 13709 | => try @as(MoveStrategy, switch (src_mcv) { | 13818 | => try @as(MoveStrategy, switch (src_mcv) { |
| 13710 | .register_offset => |reg_off| switch (reg_off.off) { | 13819 | .register_offset => |reg_off| switch (reg_off.off) { |
| 13711 | 0 => return self.genSetReg(dst_reg, ty, .{ .register = reg_off.reg }), | 13820 | 0 => return self.genSetReg(dst_reg, ty, .{ .register = reg_off.reg }, opts), |
| 13712 | else => .{ .move = .{ ._, .lea } }, | 13821 | else => .{ .move = .{ ._, .lea } }, |
| 13713 | }, | 13822 | }, |
| 13714 | .indirect => try self.moveStrategy(ty, dst_reg.class(), false), | 13823 | .indirect => try self.moveStrategy(ty, dst_reg.class(), false), |
| ... | @@ -13852,11 +13961,18 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr | ... | @@ -13852,11 +13961,18 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 13852 | }); | 13961 | }); |
| 13853 | }, | 13962 | }, |
| 13854 | .lea_tlv => unreachable, // TODO: remove this | 13963 | .lea_tlv => unreachable, // TODO: remove this |
| 13855 | .air_ref => |src_ref| try self.genSetReg(dst_reg, ty, try self.resolveInst(src_ref)), | 13964 | .air_ref => |src_ref| try self.genSetReg(dst_reg, ty, try self.resolveInst(src_ref), opts), |
| 13856 | } | 13965 | } |
| 13857 | } | 13966 | } |
| 13858 | | 13967 | |
| 13859 | fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCValue) InnerError!void { | 13968 | fn genSetMem( |
| | 13969 | self: *Self, |
| | 13970 | base: Memory.Base, |
| | 13971 | disp: i32, |
| | 13972 | ty: Type, |
| | 13973 | src_mcv: MCValue, |
| | 13974 | opts: CopyOptions, |
| | 13975 | ) InnerError!void { |
| 13860 | const mod = self.bin_file.comp.module.?; | 13976 | const mod = self.bin_file.comp.module.?; |
| 13861 | const abi_size: u32 = @intCast(ty.abiSize(mod)); | 13977 | const abi_size: u32 = @intCast(ty.abiSize(mod)); |
| 13862 | const dst_ptr_mcv: MCValue = switch (base) { | 13978 | const dst_ptr_mcv: MCValue = switch (base) { |
| ... | @@ -13867,10 +13983,11 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal | ... | @@ -13867,10 +13983,11 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal |
| 13867 | }; | 13983 | }; |
| 13868 | switch (src_mcv) { | 13984 | switch (src_mcv) { |
| 13869 | .none, .unreach, .dead, .reserved_frame => unreachable, | 13985 | .none, .unreach, .dead, .reserved_frame => unreachable, |
| 13870 | .undef => try self.genInlineMemset( | 13986 | .undef => if (opts.safety) try self.genInlineMemset( |
| 13871 | dst_ptr_mcv, | 13987 | dst_ptr_mcv, |
| 13872 | .{ .immediate = 0xaa }, | 13988 | src_mcv, |
| 13873 | .{ .immediate = abi_size }, | 13989 | .{ .immediate = abi_size }, |
| | 13990 | opts, |
| 13874 | ), | 13991 | ), |
| 13875 | .immediate => |imm| switch (abi_size) { | 13992 | .immediate => |imm| switch (abi_size) { |
| 13876 | 1, 2, 4 => { | 13993 | 1, 2, 4 => { |
| ... | @@ -13951,7 +14068,7 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal | ... | @@ -13951,7 +14068,7 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal |
| 13951 | } } }, | 14068 | } } }, |
| 13952 | src_alias, | 14069 | src_alias, |
| 13953 | ); | 14070 | ); |
| 13954 | try self.genSetMem(base, disp, ty, frame_mcv); | 14071 | try self.genSetMem(base, disp, ty, frame_mcv, opts); |
| 13955 | try self.freeValue(frame_mcv); | 14072 | try self.freeValue(frame_mcv); |
| 13956 | } else try (try self.moveStrategy(ty, src_alias.class(), switch (base) { | 14073 | } else try (try self.moveStrategy(ty, src_alias.class(), switch (base) { |
| 13957 | .none => ty.abiAlignment(mod).check(@as(u32, @bitCast(disp))), | 14074 | .none => ty.abiAlignment(mod).check(@as(u32, @bitCast(disp))), |
| ... | @@ -13975,7 +14092,7 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal | ... | @@ -13975,7 +14092,7 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal |
| 13975 | .register_pair => |src_regs| { | 14092 | .register_pair => |src_regs| { |
| 13976 | var part_disp: i32 = disp; | 14093 | var part_disp: i32 = disp; |
| 13977 | for (try self.splitType(ty), src_regs) |src_ty, src_reg| { | 14094 | for (try self.splitType(ty), src_regs) |src_ty, src_reg| { |
| 13978 | try self.genSetMem(base, part_disp, src_ty, .{ .register = src_reg }); | 14095 | try self.genSetMem(base, part_disp, src_ty, .{ .register = src_reg }, opts); |
| 13979 | part_disp += @intCast(src_ty.abiSize(mod)); | 14096 | part_disp += @intCast(src_ty.abiSize(mod)); |
| 13980 | } | 14097 | } |
| 13981 | }, | 14098 | }, |
| ... | @@ -13986,23 +14103,26 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal | ... | @@ -13986,23 +14103,26 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal |
| 13986 | disp + @as(i32, @intCast(ty.structFieldOffset(0, mod))), | 14103 | disp + @as(i32, @intCast(ty.structFieldOffset(0, mod))), |
| 13987 | ty.structFieldType(0, mod), | 14104 | ty.structFieldType(0, mod), |
| 13988 | .{ .register = ro.reg }, | 14105 | .{ .register = ro.reg }, |
| | 14106 | opts, |
| 13989 | ); | 14107 | ); |
| 13990 | try self.genSetMem( | 14108 | try self.genSetMem( |
| 13991 | base, | 14109 | base, |
| 13992 | disp + @as(i32, @intCast(ty.structFieldOffset(1, mod))), | 14110 | disp + @as(i32, @intCast(ty.structFieldOffset(1, mod))), |
| 13993 | ty.structFieldType(1, mod), | 14111 | ty.structFieldType(1, mod), |
| 13994 | .{ .eflags = ro.eflags }, | 14112 | .{ .eflags = ro.eflags }, |
| | 14113 | opts, |
| 13995 | ); | 14114 | ); |
| 13996 | }, | 14115 | }, |
| 13997 | .Optional => { | 14116 | .Optional => { |
| 13998 | assert(!ty.optionalReprIsPayload(mod)); | 14117 | assert(!ty.optionalReprIsPayload(mod)); |
| 13999 | const child_ty = ty.optionalChild(mod); | 14118 | const child_ty = ty.optionalChild(mod); |
| 14000 | try self.genSetMem(base, disp, child_ty, .{ .register = ro.reg }); | 14119 | try self.genSetMem(base, disp, child_ty, .{ .register = ro.reg }, opts); |
| 14001 | try self.genSetMem( | 14120 | try self.genSetMem( |
| 14002 | base, | 14121 | base, |
| 14003 | disp + @as(i32, @intCast(child_ty.abiSize(mod))), | 14122 | disp + @as(i32, @intCast(child_ty.abiSize(mod))), |
| 14004 | Type.bool, | 14123 | Type.bool, |
| 14005 | .{ .eflags = ro.eflags }, | 14124 | .{ .eflags = ro.eflags }, |
| | 14125 | opts, |
| 14006 | ); | 14126 | ); |
| 14007 | }, | 14127 | }, |
| 14008 | else => return self.fail("TODO implement genSetMem for {s} of {}", .{ | 14128 | else => return self.fail("TODO implement genSetMem for {s} of {}", .{ |
| ... | @@ -14029,27 +14149,37 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal | ... | @@ -14029,27 +14149,37 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal |
| 14029 | const src_lock = self.register_manager.lockRegAssumeUnused(src_reg); | 14149 | const src_lock = self.register_manager.lockRegAssumeUnused(src_reg); |
| 14030 | defer self.register_manager.unlockReg(src_lock); | 14150 | defer self.register_manager.unlockReg(src_lock); |
| 14031 | | 14151 | |
| 14032 | try self.genSetMem(base, disp, ty, .{ .register = src_reg }); | 14152 | try self.genSetMem(base, disp, ty, .{ .register = src_reg }, opts); |
| 14033 | }, | 14153 | }, |
| 14034 | else => try self.genInlineMemcpy(dst_ptr_mcv, src_mcv.address(), .{ .immediate = abi_size }), | 14154 | else => try self.genInlineMemcpy( |
| | 14155 | dst_ptr_mcv, |
| | 14156 | src_mcv.address(), |
| | 14157 | .{ .immediate = abi_size }, |
| | 14158 | ), |
| 14035 | }, | 14159 | }, |
| 14036 | .air_ref => |src_ref| try self.genSetMem(base, disp, ty, try self.resolveInst(src_ref)), | 14160 | .air_ref => |src_ref| try self.genSetMem(base, disp, ty, try self.resolveInst(src_ref), opts), |
| 14037 | } | 14161 | } |
| 14038 | } | 14162 | } |
| 14039 | | 14163 | |
| 14040 | fn genInlineMemcpy(self: *Self, dst_ptr: MCValue, src_ptr: MCValue, len: MCValue) InnerError!void { | 14164 | fn genInlineMemcpy(self: *Self, dst_ptr: MCValue, src_ptr: MCValue, len: MCValue) InnerError!void { |
| 14041 | try self.spillRegisters(&.{ .rsi, .rdi, .rcx }); | 14165 | try self.spillRegisters(&.{ .rsi, .rdi, .rcx }); |
| 14042 | try self.genSetReg(.rsi, Type.usize, src_ptr); | 14166 | try self.genSetReg(.rsi, Type.usize, src_ptr, .{}); |
| 14043 | try self.genSetReg(.rdi, Type.usize, dst_ptr); | 14167 | try self.genSetReg(.rdi, Type.usize, dst_ptr, .{}); |
| 14044 | try self.genSetReg(.rcx, Type.usize, len); | 14168 | try self.genSetReg(.rcx, Type.usize, len, .{}); |
| 14045 | try self.asmOpOnly(.{ .@"rep _sb", .mov }); | 14169 | try self.asmOpOnly(.{ .@"rep _sb", .mov }); |
| 14046 | } | 14170 | } |
| 14047 | | 14171 | |
| 14048 | fn genInlineMemset(self: *Self, dst_ptr: MCValue, value: MCValue, len: MCValue) InnerError!void { | 14172 | fn genInlineMemset( |
| | 14173 | self: *Self, |
| | 14174 | dst_ptr: MCValue, |
| | 14175 | value: MCValue, |
| | 14176 | len: MCValue, |
| | 14177 | opts: CopyOptions, |
| | 14178 | ) InnerError!void { |
| 14049 | try self.spillRegisters(&.{ .rdi, .al, .rcx }); | 14179 | try self.spillRegisters(&.{ .rdi, .al, .rcx }); |
| 14050 | try self.genSetReg(.rdi, Type.usize, dst_ptr); | 14180 | try self.genSetReg(.rdi, Type.usize, dst_ptr, .{}); |
| 14051 | try self.genSetReg(.al, Type.u8, value); | 14181 | try self.genSetReg(.al, Type.u8, value, opts); |
| 14052 | try self.genSetReg(.rcx, Type.usize, len); | 14182 | try self.genSetReg(.rcx, Type.usize, len, .{}); |
| 14053 | try self.asmOpOnly(.{ .@"rep _sb", .sto }); | 14183 | try self.asmOpOnly(.{ .@"rep _sb", .sto }); |
| 14054 | } | 14184 | } |
| 14055 | | 14185 | |
| ... | @@ -14113,10 +14243,10 @@ fn genLazySymbolRef( | ... | @@ -14113,10 +14243,10 @@ fn genLazySymbolRef( |
| 14113 | switch (tag) { | 14243 | switch (tag) { |
| 14114 | .lea, .call => try self.genSetReg(reg, Type.usize, .{ | 14244 | .lea, .call => try self.genSetReg(reg, Type.usize, .{ |
| 14115 | .load_symbol = .{ .sym = sym.esym_index }, | 14245 | .load_symbol = .{ .sym = sym.esym_index }, |
| 14116 | }), | 14246 | }, .{}), |
| 14117 | .mov => try self.genSetReg(reg, Type.usize, .{ | 14247 | .mov => try self.genSetReg(reg, Type.usize, .{ |
| 14118 | .load_symbol = .{ .sym = sym.esym_index }, | 14248 | .load_symbol = .{ .sym = sym.esym_index }, |
| 14119 | }), | 14249 | }, .{}), |
| 14120 | else => unreachable, | 14250 | else => unreachable, |
| 14121 | } | 14251 | } |
| 14122 | switch (tag) { | 14252 | switch (tag) { |
| ... | @@ -14173,8 +14303,8 @@ fn genLazySymbolRef( | ... | @@ -14173,8 +14303,8 @@ fn genLazySymbolRef( |
| 14173 | return self.fail("{s} creating lazy symbol", .{@errorName(err)}); | 14303 | return self.fail("{s} creating lazy symbol", .{@errorName(err)}); |
| 14174 | const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?; | 14304 | const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?; |
| 14175 | switch (tag) { | 14305 | switch (tag) { |
| 14176 | .lea, .call => try self.genSetReg(reg, Type.usize, .{ .lea_got = sym_index }), | 14306 | .lea, .call => try self.genSetReg(reg, Type.usize, .{ .lea_got = sym_index }, .{}), |
| 14177 | .mov => try self.genSetReg(reg, Type.usize, .{ .load_got = sym_index }), | 14307 | .mov => try self.genSetReg(reg, Type.usize, .{ .load_got = sym_index }, .{}), |
| 14178 | else => unreachable, | 14308 | else => unreachable, |
| 14179 | } | 14309 | } |
| 14180 | switch (tag) { | 14310 | switch (tag) { |
| ... | @@ -14187,8 +14317,13 @@ fn genLazySymbolRef( | ... | @@ -14187,8 +14317,13 @@ fn genLazySymbolRef( |
| 14187 | return self.fail("{s} creating lazy symbol", .{@errorName(err)}); | 14317 | return self.fail("{s} creating lazy symbol", .{@errorName(err)}); |
| 14188 | const sym = macho_file.getSymbol(sym_index); | 14318 | const sym = macho_file.getSymbol(sym_index); |
| 14189 | switch (tag) { | 14319 | switch (tag) { |
| 14190 | .lea, .call => try self.genSetReg(reg, Type.usize, .{ .load_symbol = .{ .sym = sym.nlist_idx } }), | 14320 | .lea, .call => try self.genSetReg( |
| 14191 | .mov => try self.genSetReg(reg, Type.usize, .{ .load_symbol = .{ .sym = sym.nlist_idx } }), | 14321 | reg, |
| | 14322 | Type.usize, |
| | 14323 | .{ .load_symbol = .{ .sym = sym.nlist_idx } }, |
| | 14324 | .{}, |
| | 14325 | ), |
| | 14326 | .mov => try self.genSetReg(reg, Type.usize, .{ .load_symbol = .{ .sym = sym.nlist_idx } }, .{}), |
| 14192 | else => unreachable, | 14327 | else => unreachable, |
| 14193 | } | 14328 | } |
| 14194 | switch (tag) { | 14329 | switch (tag) { |
| ... | @@ -14210,7 +14345,7 @@ fn airIntFromPtr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -14210,7 +14345,7 @@ fn airIntFromPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 14210 | | 14345 | |
| 14211 | const dst_mcv = try self.allocRegOrMem(inst, true); | 14346 | const dst_mcv = try self.allocRegOrMem(inst, true); |
| 14212 | const dst_ty = self.typeOfIndex(inst); | 14347 | const dst_ty = self.typeOfIndex(inst); |
| 14213 | try self.genCopy(dst_ty, dst_mcv, src_mcv); | 14348 | try self.genCopy(dst_ty, dst_mcv, src_mcv, .{}); |
| 14214 | break :result dst_mcv; | 14349 | break :result dst_mcv; |
| 14215 | }; | 14350 | }; |
| 14216 | return self.finishAir(inst, result, .{ un_op, .none, .none }); | 14351 | return self.finishAir(inst, result, .{ un_op, .none, .none }); |
| ... | @@ -14237,7 +14372,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -14237,7 +14372,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { |
| 14237 | .lt => dst_ty, | 14372 | .lt => dst_ty, |
| 14238 | .eq => if (!dst_mcv.isMemory() or src_mcv.isMemory()) dst_ty else src_ty, | 14373 | .eq => if (!dst_mcv.isMemory() or src_mcv.isMemory()) dst_ty else src_ty, |
| 14239 | .gt => src_ty, | 14374 | .gt => src_ty, |
| 14240 | }, dst_mcv, src_mcv); | 14375 | }, dst_mcv, src_mcv, .{}); |
| 14241 | break :dst dst_mcv; | 14376 | break :dst dst_mcv; |
| 14242 | }; | 14377 | }; |
| 14243 | | 14378 | |
| ... | @@ -14268,6 +14403,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -14268,6 +14403,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { |
| 14268 | if (abi_size <= 8) dst_ty else Type.usize, | 14403 | if (abi_size <= 8) dst_ty else Type.usize, |
| 14269 | high_mcv, | 14404 | high_mcv, |
| 14270 | .{ .register = high_reg }, | 14405 | .{ .register = high_reg }, |
| | 14406 | .{}, |
| 14271 | ); | 14407 | ); |
| 14272 | break :result dst_mcv; | 14408 | break :result dst_mcv; |
| 14273 | }; | 14409 | }; |
| ... | @@ -14285,12 +14421,13 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -14285,12 +14421,13 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { |
| 14285 | const array_len = array_ty.arrayLen(mod); | 14421 | const array_len = array_ty.arrayLen(mod); |
| 14286 | | 14422 | |
| 14287 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(slice_ty, mod)); | 14423 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(slice_ty, mod)); |
| 14288 | try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, ptr); | 14424 | try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, ptr, .{}); |
| 14289 | try self.genSetMem( | 14425 | try self.genSetMem( |
| 14290 | .{ .frame = frame_index }, | 14426 | .{ .frame = frame_index }, |
| 14291 | @intCast(ptr_ty.abiSize(mod)), | 14427 | @intCast(ptr_ty.abiSize(mod)), |
| 14292 | Type.usize, | 14428 | Type.usize, |
| 14293 | .{ .immediate = array_len }, | 14429 | .{ .immediate = array_len }, |
| | 14430 | .{}, |
| 14294 | ); | 14431 | ); |
| 14295 | | 14432 | |
| 14296 | const result = MCValue{ .load_frame = .{ .index = frame_index } }; | 14433 | const result = MCValue{ .load_frame = .{ .index = frame_index } }; |
| ... | @@ -14470,9 +14607,9 @@ fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -14470,9 +14607,9 @@ fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void { |
| 14470 | if (exp_addr_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null; | 14607 | if (exp_addr_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null; |
| 14471 | defer if (exp_addr_lock) |lock| self.register_manager.unlockReg(lock); | 14608 | defer if (exp_addr_lock) |lock| self.register_manager.unlockReg(lock); |
| 14472 | | 14609 | |
| 14473 | try self.genSetReg(.rax, Type.usize, exp_addr_mcv.deref()); | 14610 | try self.genSetReg(.rax, Type.usize, exp_addr_mcv.deref(), .{}); |
| 14474 | try self.genSetReg(.rdx, Type.usize, exp_addr_mcv.offset(8).deref()); | 14611 | try self.genSetReg(.rdx, Type.usize, exp_addr_mcv.offset(8).deref(), .{}); |
| 14475 | } else try self.genSetReg(.rax, val_ty, exp_mcv); | 14612 | } else try self.genSetReg(.rax, val_ty, exp_mcv, .{}); |
| 14476 | | 14613 | |
| 14477 | const new_mcv = try self.resolveInst(extra.new_value); | 14614 | const new_mcv = try self.resolveInst(extra.new_value); |
| 14478 | const new_reg = if (val_abi_size > 8) new: { | 14615 | const new_reg = if (val_abi_size > 8) new: { |
| ... | @@ -14484,8 +14621,8 @@ fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -14484,8 +14621,8 @@ fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void { |
| 14484 | if (new_addr_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null; | 14621 | if (new_addr_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null; |
| 14485 | defer if (new_addr_lock) |lock| self.register_manager.unlockReg(lock); | 14622 | defer if (new_addr_lock) |lock| self.register_manager.unlockReg(lock); |
| 14486 | | 14623 | |
| 14487 | try self.genSetReg(.rbx, Type.usize, new_addr_mcv.deref()); | 14624 | try self.genSetReg(.rbx, Type.usize, new_addr_mcv.deref(), .{}); |
| 14488 | try self.genSetReg(.rcx, Type.usize, new_addr_mcv.offset(8).deref()); | 14625 | try self.genSetReg(.rcx, Type.usize, new_addr_mcv.offset(8).deref(), .{}); |
| 14489 | break :new null; | 14626 | break :new null; |
| 14490 | } else try self.copyToTmpRegister(val_ty, new_mcv); | 14627 | } else try self.copyToTmpRegister(val_ty, new_mcv); |
| 14491 | const new_lock = if (new_reg) |reg| self.register_manager.lockRegAssumeUnused(reg) else null; | 14628 | const new_lock = if (new_reg) |reg| self.register_manager.lockRegAssumeUnused(reg) else null; |
| ... | @@ -14526,9 +14663,9 @@ fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -14526,9 +14663,9 @@ fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void { |
| 14526 | } | 14663 | } |
| 14527 | | 14664 | |
| 14528 | const dst_mcv = try self.allocRegOrMem(inst, false); | 14665 | const dst_mcv = try self.allocRegOrMem(inst, false); |
| 14529 | try self.genCopy(Type.usize, dst_mcv, .{ .register = .rax }); | 14666 | try self.genCopy(Type.usize, dst_mcv, .{ .register = .rax }, .{}); |
| 14530 | try self.genCopy(Type.usize, dst_mcv.address().offset(8).deref(), .{ .register = .rdx }); | 14667 | try self.genCopy(Type.usize, dst_mcv.address().offset(8).deref(), .{ .register = .rdx }, .{}); |
| 14531 | try self.genCopy(Type.bool, dst_mcv.address().offset(16).deref(), .{ .eflags = .ne }); | 14668 | try self.genCopy(Type.bool, dst_mcv.address().offset(16).deref(), .{ .eflags = .ne }, .{}); |
| 14532 | break :result dst_mcv; | 14669 | break :result dst_mcv; |
| 14533 | }; | 14670 | }; |
| 14534 | return self.finishAir(inst, result, .{ extra.ptr, extra.expected_value, extra.new_value }); | 14671 | return self.finishAir(inst, result, .{ extra.ptr, extra.expected_value, extra.new_value }); |
| ... | @@ -14612,7 +14749,7 @@ fn atomicOp( | ... | @@ -14612,7 +14749,7 @@ fn atomicOp( |
| 14612 | const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); | 14749 | const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); |
| 14613 | defer self.register_manager.unlockReg(dst_lock); | 14750 | defer self.register_manager.unlockReg(dst_lock); |
| 14614 | | 14751 | |
| 14615 | try self.genSetReg(dst_reg, val_ty, val_mcv); | 14752 | try self.genSetReg(dst_reg, val_ty, val_mcv, .{}); |
| 14616 | if (rmw_op == std.builtin.AtomicRmwOp.Sub and tag == .xadd) { | 14753 | if (rmw_op == std.builtin.AtomicRmwOp.Sub and tag == .xadd) { |
| 14617 | try self.genUnOpMir(.{ ._, .neg }, val_ty, dst_mcv); | 14754 | try self.genUnOpMir(.{ ._, .neg }, val_ty, dst_mcv); |
| 14618 | } | 14755 | } |
| ... | @@ -14645,7 +14782,7 @@ fn atomicOp( | ... | @@ -14645,7 +14782,7 @@ fn atomicOp( |
| 14645 | try self.asmRegisterMemory(.{ ._, .mov }, registerAlias(.rax, val_abi_size), ptr_mem); | 14782 | try self.asmRegisterMemory(.{ ._, .mov }, registerAlias(.rax, val_abi_size), ptr_mem); |
| 14646 | const loop: Mir.Inst.Index = @intCast(self.mir_instructions.len); | 14783 | const loop: Mir.Inst.Index = @intCast(self.mir_instructions.len); |
| 14647 | if (!use_sse and rmw_op orelse .Xchg != .Xchg) { | 14784 | if (!use_sse and rmw_op orelse .Xchg != .Xchg) { |
| 14648 | try self.genSetReg(tmp_reg, val_ty, .{ .register = .rax }); | 14785 | try self.genSetReg(tmp_reg, val_ty, .{ .register = .rax }, .{}); |
| 14649 | } | 14786 | } |
| 14650 | if (rmw_op) |op| if (use_sse) { | 14787 | if (rmw_op) |op| if (use_sse) { |
| 14651 | const mir_tag = @as(?Mir.Inst.FixedTag, switch (op) { | 14788 | const mir_tag = @as(?Mir.Inst.FixedTag, switch (op) { |
| ... | @@ -14673,7 +14810,7 @@ fn atomicOp( | ... | @@ -14673,7 +14810,7 @@ fn atomicOp( |
| 14673 | }) orelse return self.fail("TODO implement atomicOp of {s} for {}", .{ | 14810 | }) orelse return self.fail("TODO implement atomicOp of {s} for {}", .{ |
| 14674 | @tagName(op), val_ty.fmt(mod), | 14811 | @tagName(op), val_ty.fmt(mod), |
| 14675 | }); | 14812 | }); |
| 14676 | try self.genSetReg(sse_reg, val_ty, .{ .register = .rax }); | 14813 | try self.genSetReg(sse_reg, val_ty, .{ .register = .rax }, .{}); |
| 14677 | switch (mir_tag[0]) { | 14814 | switch (mir_tag[0]) { |
| 14678 | .v_ss, .v_sd => if (val_mcv.isMemory()) try self.asmRegisterRegisterMemory( | 14815 | .v_ss, .v_sd => if (val_mcv.isMemory()) try self.asmRegisterRegisterMemory( |
| 14679 | mir_tag, | 14816 | mir_tag, |
| ... | @@ -14703,9 +14840,9 @@ fn atomicOp( | ... | @@ -14703,9 +14840,9 @@ fn atomicOp( |
| 14703 | ), | 14840 | ), |
| 14704 | else => unreachable, | 14841 | else => unreachable, |
| 14705 | } | 14842 | } |
| 14706 | try self.genSetReg(tmp_reg, val_ty, .{ .register = sse_reg }); | 14843 | try self.genSetReg(tmp_reg, val_ty, .{ .register = sse_reg }, .{}); |
| 14707 | } else switch (op) { | 14844 | } else switch (op) { |
| 14708 | .Xchg => try self.genSetReg(tmp_reg, val_ty, val_mcv), | 14845 | .Xchg => try self.genSetReg(tmp_reg, val_ty, val_mcv, .{}), |
| 14709 | .Add => try self.genBinOpMir(.{ ._, .add }, val_ty, tmp_mcv, val_mcv), | 14846 | .Add => try self.genBinOpMir(.{ ._, .add }, val_ty, tmp_mcv, val_mcv), |
| 14710 | .Sub => try self.genBinOpMir(.{ ._, .sub }, val_ty, tmp_mcv, val_mcv), | 14847 | .Sub => try self.genBinOpMir(.{ ._, .sub }, val_ty, tmp_mcv, val_mcv), |
| 14711 | .And => try self.genBinOpMir(.{ ._, .@"and" }, val_ty, tmp_mcv, val_mcv), | 14848 | .And => try self.genBinOpMir(.{ ._, .@"and" }, val_ty, tmp_mcv, val_mcv), |
| ... | @@ -14995,7 +15132,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { | ... | @@ -14995,7 +15132,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { |
| 14995 | }; | 15132 | }; |
| 14996 | defer if (len_lock) |lock| self.register_manager.unlockReg(lock); | 15133 | defer if (len_lock) |lock| self.register_manager.unlockReg(lock); |
| 14997 | | 15134 | |
| 14998 | try self.genInlineMemset(ptr, src_val, len); | 15135 | try self.genInlineMemset(ptr, src_val, len, .{ .safety = safety }); |
| 14999 | break :result; | 15136 | break :result; |
| 15000 | } | 15137 | } |
| 15001 | | 15138 | |
| ... | @@ -15017,11 +15154,11 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { | ... | @@ -15017,11 +15154,11 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { |
| 15017 | const len_lock = self.register_manager.lockRegAssumeUnused(len_reg); | 15154 | const len_lock = self.register_manager.lockRegAssumeUnused(len_reg); |
| 15018 | defer self.register_manager.unlockReg(len_lock); | 15155 | defer self.register_manager.unlockReg(len_lock); |
| 15019 | | 15156 | |
| 15020 | try self.genSetReg(len_reg, Type.usize, len); | 15157 | try self.genSetReg(len_reg, Type.usize, len, .{}); |
| 15021 | try self.asmRegisterRegister(.{ ._, .@"test" }, len_reg, len_reg); | 15158 | try self.asmRegisterRegister(.{ ._, .@"test" }, len_reg, len_reg); |
| 15022 | | 15159 | |
| 15023 | const skip_reloc = try self.asmJccReloc(.z, undefined); | 15160 | const skip_reloc = try self.asmJccReloc(.z, undefined); |
| 15024 | try self.store(slice_ptr_ty, ptr, src_val); | 15161 | try self.store(slice_ptr_ty, ptr, src_val, .{ .safety = safety }); |
| 15025 | | 15162 | |
| 15026 | const second_elem_ptr_reg = | 15163 | const second_elem_ptr_reg = |
| 15027 | try self.register_manager.allocReg(null, abi.RegisterClass.gp); | 15164 | try self.register_manager.allocReg(null, abi.RegisterClass.gp); |
| ... | @@ -15033,7 +15170,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { | ... | @@ -15033,7 +15170,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { |
| 15033 | try self.genSetReg(second_elem_ptr_reg, Type.usize, .{ .register_offset = .{ | 15170 | try self.genSetReg(second_elem_ptr_reg, Type.usize, .{ .register_offset = .{ |
| 15034 | .reg = try self.copyToTmpRegister(Type.usize, ptr), | 15171 | .reg = try self.copyToTmpRegister(Type.usize, ptr), |
| 15035 | .off = elem_abi_size, | 15172 | .off = elem_abi_size, |
| 15036 | } }); | 15173 | } }, .{}); |
| 15037 | | 15174 | |
| 15038 | try self.genBinOpMir(.{ ._, .sub }, Type.usize, len_mcv, .{ .immediate = 1 }); | 15175 | try self.genBinOpMir(.{ ._, .sub }, Type.usize, len_mcv, .{ .immediate = 1 }); |
| 15039 | try self.asmRegisterRegisterImmediate( | 15176 | try self.asmRegisterRegisterImmediate( |
| ... | @@ -15052,7 +15189,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { | ... | @@ -15052,7 +15189,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { |
| 15052 | const len = dst_ptr_ty.childType(mod).arrayLen(mod); | 15189 | const len = dst_ptr_ty.childType(mod).arrayLen(mod); |
| 15053 | | 15190 | |
| 15054 | assert(len != 0); // prevented by Sema | 15191 | assert(len != 0); // prevented by Sema |
| 15055 | try self.store(elem_ptr_ty, dst_ptr, src_val); | 15192 | try self.store(elem_ptr_ty, dst_ptr, src_val, .{ .safety = safety }); |
| 15056 | | 15193 | |
| 15057 | const second_elem_ptr_reg = | 15194 | const second_elem_ptr_reg = |
| 15058 | try self.register_manager.allocReg(null, abi.RegisterClass.gp); | 15195 | try self.register_manager.allocReg(null, abi.RegisterClass.gp); |
| ... | @@ -15064,7 +15201,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { | ... | @@ -15064,7 +15201,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { |
| 15064 | try self.genSetReg(second_elem_ptr_reg, Type.usize, .{ .register_offset = .{ | 15201 | try self.genSetReg(second_elem_ptr_reg, Type.usize, .{ .register_offset = .{ |
| 15065 | .reg = try self.copyToTmpRegister(Type.usize, dst_ptr), | 15202 | .reg = try self.copyToTmpRegister(Type.usize, dst_ptr), |
| 15066 | .off = elem_abi_size, | 15203 | .off = elem_abi_size, |
| 15067 | } }); | 15204 | } }, .{}); |
| 15068 | | 15205 | |
| 15069 | const bytes_to_copy: MCValue = .{ .immediate = elem_abi_size * (len - 1) }; | 15206 | const bytes_to_copy: MCValue = .{ .immediate = elem_abi_size * (len - 1) }; |
| 15070 | try self.genInlineMemcpy(second_elem_ptr_mcv, dst_ptr, bytes_to_copy); | 15207 | try self.genInlineMemcpy(second_elem_ptr_mcv, dst_ptr, bytes_to_copy); |
| ... | @@ -15158,10 +15295,10 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -15158,10 +15295,10 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void { |
| 15158 | const param_regs = abi.getCAbiIntParamRegs(resolved_cc); | 15295 | const param_regs = abi.getCAbiIntParamRegs(resolved_cc); |
| 15159 | | 15296 | |
| 15160 | const dst_mcv = try self.allocRegOrMem(inst, false); | 15297 | const dst_mcv = try self.allocRegOrMem(inst, false); |
| 15161 | try self.genSetReg(param_regs[0], Type.usize, dst_mcv.address()); | 15298 | try self.genSetReg(param_regs[0], Type.usize, dst_mcv.address(), .{}); |
| 15162 | | 15299 | |
| 15163 | const operand = try self.resolveInst(un_op); | 15300 | const operand = try self.resolveInst(un_op); |
| 15164 | try self.genSetReg(param_regs[1], enum_ty, operand); | 15301 | try self.genSetReg(param_regs[1], enum_ty, operand, .{}); |
| 15165 | | 15302 | |
| 15166 | try self.genLazySymbolRef( | 15303 | try self.genLazySymbolRef( |
| 15167 | .call, | 15304 | .call, |
| ... | @@ -15291,11 +15428,12 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -15291,11 +15428,12 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void { |
| 15291 | const reg_locks = self.register_manager.lockRegsAssumeUnused(2, regs); | 15428 | const reg_locks = self.register_manager.lockRegsAssumeUnused(2, regs); |
| 15292 | defer for (reg_locks) |lock| self.register_manager.unlockReg(lock); | 15429 | defer for (reg_locks) |lock| self.register_manager.unlockReg(lock); |
| 15293 | | 15430 | |
| 15294 | try self.genSetReg(regs[1], vector_ty, .{ .immediate = 0 }); | 15431 | try self.genSetReg(regs[1], vector_ty, .{ .immediate = 0 }, .{}); |
| 15295 | try self.genSetReg( | 15432 | try self.genSetReg( |
| 15296 | regs[1], | 15433 | regs[1], |
| 15297 | vector_ty, | 15434 | vector_ty, |
| 15298 | .{ .immediate = @as(u64, math.maxInt(u64)) >> @intCast(64 - vector_len) }, | 15435 | .{ .immediate = @as(u64, math.maxInt(u64)) >> @intCast(64 - vector_len) }, |
| | 15436 | .{}, |
| 15299 | ); | 15437 | ); |
| 15300 | const src_mcv = try self.resolveInst(ty_op.operand); | 15438 | const src_mcv = try self.resolveInst(ty_op.operand); |
| 15301 | const abi_size = @max(math.divCeil(u32, vector_len, 8) catch unreachable, 4); | 15439 | const abi_size = @max(math.divCeil(u32, vector_len, 8) catch unreachable, 4); |
| ... | @@ -15360,7 +15498,7 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -15360,7 +15498,7 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void { |
| 15360 | try src_mcv.mem(self, self.memSize(scalar_ty)), | 15498 | try src_mcv.mem(self, self.memSize(scalar_ty)), |
| 15361 | ) else { | 15499 | ) else { |
| 15362 | if (mir_tag[0] == .vp_i128) break :avx2; | 15500 | if (mir_tag[0] == .vp_i128) break :avx2; |
| 15363 | try self.genSetReg(dst_reg, scalar_ty, src_mcv); | 15501 | try self.genSetReg(dst_reg, scalar_ty, src_mcv, .{}); |
| 15364 | try self.asmRegisterRegister( | 15502 | try self.asmRegisterRegister( |
| 15365 | mir_tag, | 15503 | mir_tag, |
| 15366 | registerAlias(dst_reg, @intCast(vector_ty.abiSize(mod))), | 15504 | registerAlias(dst_reg, @intCast(vector_ty.abiSize(mod))), |
| ... | @@ -15373,7 +15511,7 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -15373,7 +15511,7 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void { |
| 15373 | const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); | 15511 | const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); |
| 15374 | defer self.register_manager.unlockReg(dst_lock); | 15512 | defer self.register_manager.unlockReg(dst_lock); |
| 15375 | | 15513 | |
| 15376 | try self.genSetReg(dst_reg, scalar_ty, .{ .air_ref = ty_op.operand }); | 15514 | try self.genSetReg(dst_reg, scalar_ty, .{ .air_ref = ty_op.operand }, .{}); |
| 15377 | if (vector_len == 1) break :result .{ .register = dst_reg }; | 15515 | if (vector_len == 1) break :result .{ .register = dst_reg }; |
| 15378 | | 15516 | |
| 15379 | const dst_alias = registerAlias(dst_reg, @intCast(vector_ty.abiSize(mod))); | 15517 | const dst_alias = registerAlias(dst_reg, @intCast(vector_ty.abiSize(mod))); |
| ... | @@ -15423,7 +15561,7 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -15423,7 +15561,7 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void { |
| 15423 | const src_mcv = try self.resolveInst(ty_op.operand); | 15561 | const src_mcv = try self.resolveInst(ty_op.operand); |
| 15424 | if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) break :result src_mcv; | 15562 | if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) break :result src_mcv; |
| 15425 | const dst_reg = try self.register_manager.allocReg(inst, dst_rc); | 15563 | const dst_reg = try self.register_manager.allocReg(inst, dst_rc); |
| 15426 | try self.genSetReg(dst_reg, scalar_ty, src_mcv); | 15564 | try self.genSetReg(dst_reg, scalar_ty, src_mcv, .{}); |
| 15427 | break :result .{ .register = dst_reg }; | 15565 | break :result .{ .register = dst_reg }; |
| 15428 | }, | 15566 | }, |
| 15429 | 2...4 => { | 15567 | 2...4 => { |
| ... | @@ -15506,7 +15644,7 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -15506,7 +15644,7 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void { |
| 15506 | const src_mcv = try self.resolveInst(ty_op.operand); | 15644 | const src_mcv = try self.resolveInst(ty_op.operand); |
| 15507 | if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) break :result src_mcv; | 15645 | if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) break :result src_mcv; |
| 15508 | const dst_reg = try self.register_manager.allocReg(inst, dst_rc); | 15646 | const dst_reg = try self.register_manager.allocReg(inst, dst_rc); |
| 15509 | try self.genSetReg(dst_reg, scalar_ty, src_mcv); | 15647 | try self.genSetReg(dst_reg, scalar_ty, src_mcv, .{}); |
| 15510 | break :result .{ .register = dst_reg }; | 15648 | break :result .{ .register = dst_reg }; |
| 15511 | }, | 15649 | }, |
| 15512 | 2 => { | 15650 | 2 => { |
| ... | @@ -15575,7 +15713,7 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -15575,7 +15713,7 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void { |
| 15575 | const src_mcv = try self.resolveInst(ty_op.operand); | 15713 | const src_mcv = try self.resolveInst(ty_op.operand); |
| 15576 | if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) break :result src_mcv; | 15714 | if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) break :result src_mcv; |
| 15577 | const dst_reg = try self.register_manager.allocReg(inst, dst_rc); | 15715 | const dst_reg = try self.register_manager.allocReg(inst, dst_rc); |
| 15578 | try self.genSetReg(dst_reg, scalar_ty, src_mcv); | 15716 | try self.genSetReg(dst_reg, scalar_ty, src_mcv, .{}); |
| 15579 | break :result .{ .register = dst_reg }; | 15717 | break :result .{ .register = dst_reg }; |
| 15580 | }, | 15718 | }, |
| 15581 | 2 => if (self.hasFeature(.avx)) { | 15719 | 2 => if (self.hasFeature(.avx)) { |
| ... | @@ -15699,6 +15837,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -15699,6 +15837,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 15699 | .{ .lea_frame = .{ .index = frame_index } }, | 15837 | .{ .lea_frame = .{ .index = frame_index } }, |
| 15700 | .{ .immediate = 0 }, | 15838 | .{ .immediate = 0 }, |
| 15701 | .{ .immediate = result_ty.abiSize(mod) }, | 15839 | .{ .immediate = result_ty.abiSize(mod) }, |
| | 15840 | .{}, |
| 15702 | ); | 15841 | ); |
| 15703 | for (elements, 0..) |elem, elem_i_usize| { | 15842 | for (elements, 0..) |elem, elem_i_usize| { |
| 15704 | const elem_i: u32 = @intCast(elem_i_usize); | 15843 | const elem_i: u32 = @intCast(elem_i_usize); |
| ... | @@ -15783,7 +15922,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -15783,7 +15922,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 15783 | .load_tlv => |sym_index| MCValue{ .lea_tlv = sym_index }, | 15922 | .load_tlv => |sym_index| MCValue{ .lea_tlv = sym_index }, |
| 15784 | else => elem_mcv, | 15923 | else => elem_mcv, |
| 15785 | }; | 15924 | }; |
| 15786 | try self.genSetMem(.{ .frame = frame_index }, elem_off, elem_ty, mat_elem_mcv); | 15925 | try self.genSetMem(.{ .frame = frame_index }, elem_off, elem_ty, mat_elem_mcv, .{}); |
| 15787 | } | 15926 | } |
| 15788 | break :result .{ .load_frame = .{ .index = frame_index } }; | 15927 | break :result .{ .load_frame = .{ .index = frame_index } }; |
| 15789 | }, | 15928 | }, |
| ... | @@ -15831,13 +15970,20 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -15831,13 +15970,20 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 15831 | else => elem_mcv, | 15970 | else => elem_mcv, |
| 15832 | }; | 15971 | }; |
| 15833 | const elem_off: i32 = @intCast(elem_size * elem_i); | 15972 | const elem_off: i32 = @intCast(elem_size * elem_i); |
| 15834 | try self.genSetMem(.{ .frame = frame_index }, elem_off, elem_ty, mat_elem_mcv); | 15973 | try self.genSetMem( |
| | 15974 | .{ .frame = frame_index }, |
| | 15975 | elem_off, |
| | 15976 | elem_ty, |
| | 15977 | mat_elem_mcv, |
| | 15978 | .{}, |
| | 15979 | ); |
| 15835 | } | 15980 | } |
| 15836 | if (result_ty.sentinel(mod)) |sentinel| try self.genSetMem( | 15981 | if (result_ty.sentinel(mod)) |sentinel| try self.genSetMem( |
| 15837 | .{ .frame = frame_index }, | 15982 | .{ .frame = frame_index }, |
| 15838 | @intCast(elem_size * elements.len), | 15983 | @intCast(elem_size * elements.len), |
| 15839 | elem_ty, | 15984 | elem_ty, |
| 15840 | try self.genTypedValue(.{ .ty = elem_ty, .val = sentinel }), | 15985 | try self.genTypedValue(.{ .ty = elem_ty, .val = sentinel }), |
| | 15986 | .{}, |
| 15841 | ); | 15987 | ); |
| 15842 | break :result .{ .load_frame = .{ .index = frame_index } }; | 15988 | break :result .{ .load_frame = .{ .index = frame_index } }; |
| 15843 | } | 15989 | } |
| ... | @@ -15872,7 +16018,7 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -15872,7 +16018,7 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void { |
| 15872 | self.reuseOperand(inst, extra.init, 0, src_mcv)) break :result src_mcv; | 16018 | self.reuseOperand(inst, extra.init, 0, src_mcv)) break :result src_mcv; |
| 15873 | | 16019 | |
| 15874 | const dst_mcv = try self.allocRegOrMem(inst, true); | 16020 | const dst_mcv = try self.allocRegOrMem(inst, true); |
| 15875 | try self.genCopy(src_ty, dst_mcv, src_mcv); | 16021 | try self.genCopy(src_ty, dst_mcv, src_mcv, .{}); |
| 15876 | break :result dst_mcv; | 16022 | break :result dst_mcv; |
| 15877 | } | 16023 | } |
| 15878 | | 16024 | |
| ... | @@ -15889,13 +16035,18 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -15889,13 +16035,18 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void { |
| 15889 | @intCast(layout.payload_size) | 16035 | @intCast(layout.payload_size) |
| 15890 | else | 16036 | else |
| 15891 | 0; | 16037 | 0; |
| 15892 | try self.genCopy(tag_ty, dst_mcv.address().offset(tag_off).deref(), .{ .immediate = tag_int }); | 16038 | try self.genCopy( |
| | 16039 | tag_ty, |
| | 16040 | dst_mcv.address().offset(tag_off).deref(), |
| | 16041 | .{ .immediate = tag_int }, |
| | 16042 | .{}, |
| | 16043 | ); |
| 15893 | | 16044 | |
| 15894 | const pl_off: i32 = if (layout.tag_align.compare(.lt, layout.payload_align)) | 16045 | const pl_off: i32 = if (layout.tag_align.compare(.lt, layout.payload_align)) |
| 15895 | 0 | 16046 | 0 |
| 15896 | else | 16047 | else |
| 15897 | @intCast(layout.tag_size); | 16048 | @intCast(layout.tag_size); |
| 15898 | try self.genCopy(src_ty, dst_mcv.address().offset(pl_off).deref(), src_mcv); | 16049 | try self.genCopy(src_ty, dst_mcv.address().offset(pl_off).deref(), src_mcv, .{}); |
| 15899 | | 16050 | |
| 15900 | break :result dst_mcv; | 16051 | break :result dst_mcv; |
| 15901 | }; | 16052 | }; |
| ... | @@ -16093,6 +16244,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -16093,6 +16244,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { |
| 16093 | field_off, | 16244 | field_off, |
| 16094 | Type.c_uint, | 16245 | Type.c_uint, |
| 16095 | .{ .immediate = info.gp_count * 8 }, | 16246 | .{ .immediate = info.gp_count * 8 }, |
| | 16247 | .{}, |
| 16096 | ); | 16248 | ); |
| 16097 | field_off += @intCast(Type.c_uint.abiSize(mod)); | 16249 | field_off += @intCast(Type.c_uint.abiSize(mod)); |
| 16098 | // fp_offset: c_uint, | 16250 | // fp_offset: c_uint, |
| ... | @@ -16101,6 +16253,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -16101,6 +16253,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { |
| 16101 | field_off, | 16253 | field_off, |
| 16102 | Type.c_uint, | 16254 | Type.c_uint, |
| 16103 | .{ .immediate = abi.SysV.c_abi_int_param_regs.len * 8 + info.fp_count * 16 }, | 16255 | .{ .immediate = abi.SysV.c_abi_int_param_regs.len * 8 + info.fp_count * 16 }, |
| | 16256 | .{}, |
| 16104 | ); | 16257 | ); |
| 16105 | field_off += @intCast(Type.c_uint.abiSize(mod)); | 16258 | field_off += @intCast(Type.c_uint.abiSize(mod)); |
| 16106 | // overflow_arg_area: *anyopaque, | 16259 | // overflow_arg_area: *anyopaque, |
| ... | @@ -16109,6 +16262,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -16109,6 +16262,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { |
| 16109 | field_off, | 16262 | field_off, |
| 16110 | ptr_anyopaque_ty, | 16263 | ptr_anyopaque_ty, |
| 16111 | .{ .lea_frame = info.overflow_arg_area }, | 16264 | .{ .lea_frame = info.overflow_arg_area }, |
| | 16265 | .{}, |
| 16112 | ); | 16266 | ); |
| 16113 | field_off += @intCast(ptr_anyopaque_ty.abiSize(mod)); | 16267 | field_off += @intCast(ptr_anyopaque_ty.abiSize(mod)); |
| 16114 | // reg_save_area: *anyopaque, | 16268 | // reg_save_area: *anyopaque, |
| ... | @@ -16117,6 +16271,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -16117,6 +16271,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { |
| 16117 | field_off, | 16271 | field_off, |
| 16118 | ptr_anyopaque_ty, | 16272 | ptr_anyopaque_ty, |
| 16119 | .{ .lea_frame = info.reg_save_area }, | 16273 | .{ .lea_frame = info.reg_save_area }, |
| | 16274 | .{}, |
| 16120 | ); | 16275 | ); |
| 16121 | field_off += @intCast(ptr_anyopaque_ty.abiSize(mod)); | 16276 | field_off += @intCast(ptr_anyopaque_ty.abiSize(mod)); |
| 16122 | break :result .{ .load_frame = .{ .index = dst_fi } }; | 16277 | break :result .{ .load_frame = .{ .index = dst_fi } }; |
| ... | @@ -16171,13 +16326,13 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -16171,13 +16326,13 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { |
| 16171 | .integer => { | 16326 | .integer => { |
| 16172 | assert(classes.len == 1); | 16327 | assert(classes.len == 1); |
| 16173 | | 16328 | |
| 16174 | try self.genSetReg(offset_reg, Type.c_uint, gp_offset); | 16329 | try self.genSetReg(offset_reg, Type.c_uint, gp_offset, .{}); |
| 16175 | try self.asmRegisterImmediate(.{ ._, .cmp }, offset_reg, Immediate.u( | 16330 | try self.asmRegisterImmediate(.{ ._, .cmp }, offset_reg, Immediate.u( |
| 16176 | abi.SysV.c_abi_int_param_regs.len * 8, | 16331 | abi.SysV.c_abi_int_param_regs.len * 8, |
| 16177 | )); | 16332 | )); |
| 16178 | const mem_reloc = try self.asmJccReloc(.ae, undefined); | 16333 | const mem_reloc = try self.asmJccReloc(.ae, undefined); |
| 16179 | | 16334 | |
| 16180 | try self.genSetReg(addr_reg, ptr_anyopaque_ty, reg_save_area); | 16335 | try self.genSetReg(addr_reg, ptr_anyopaque_ty, reg_save_area, .{}); |
| 16181 | if (!unused) try self.asmRegisterMemory(.{ ._, .lea }, addr_reg, .{ | 16336 | if (!unused) try self.asmRegisterMemory(.{ ._, .lea }, addr_reg, .{ |
| 16182 | .base = .{ .reg = addr_reg }, | 16337 | .base = .{ .reg = addr_reg }, |
| 16183 | .mod = .{ .rm = .{ | 16338 | .mod = .{ .rm = .{ |
| ... | @@ -16192,11 +16347,11 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -16192,11 +16347,11 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { |
| 16192 | .disp = 8, | 16347 | .disp = 8, |
| 16193 | } }, | 16348 | } }, |
| 16194 | }); | 16349 | }); |
| 16195 | try self.genCopy(Type.c_uint, gp_offset, .{ .register = offset_reg }); | 16350 | try self.genCopy(Type.c_uint, gp_offset, .{ .register = offset_reg }, .{}); |
| 16196 | const done_reloc = try self.asmJmpReloc(undefined); | 16351 | const done_reloc = try self.asmJmpReloc(undefined); |
| 16197 | | 16352 | |
| 16198 | try self.performReloc(mem_reloc); | 16353 | try self.performReloc(mem_reloc); |
| 16199 | try self.genSetReg(addr_reg, ptr_anyopaque_ty, overflow_arg_area); | 16354 | try self.genSetReg(addr_reg, ptr_anyopaque_ty, overflow_arg_area, .{}); |
| 16200 | try self.asmRegisterMemory(.{ ._, .lea }, offset_reg.to64(), .{ | 16355 | try self.asmRegisterMemory(.{ ._, .lea }, offset_reg.to64(), .{ |
| 16201 | .base = .{ .reg = addr_reg }, | 16356 | .base = .{ .reg = addr_reg }, |
| 16202 | .mod = .{ .rm = .{ | 16357 | .mod = .{ .rm = .{ |
| ... | @@ -16208,23 +16363,24 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -16208,23 +16363,24 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { |
| 16208 | ptr_anyopaque_ty, | 16363 | ptr_anyopaque_ty, |
| 16209 | overflow_arg_area, | 16364 | overflow_arg_area, |
| 16210 | .{ .register = offset_reg.to64() }, | 16365 | .{ .register = offset_reg.to64() }, |
| | 16366 | .{}, |
| 16211 | ); | 16367 | ); |
| 16212 | | 16368 | |
| 16213 | try self.performReloc(done_reloc); | 16369 | try self.performReloc(done_reloc); |
| 16214 | if (!unused) try self.genCopy(promote_ty, promote_mcv, .{ | 16370 | if (!unused) try self.genCopy(promote_ty, promote_mcv, .{ |
| 16215 | .indirect = .{ .reg = addr_reg }, | 16371 | .indirect = .{ .reg = addr_reg }, |
| 16216 | }); | 16372 | }, .{}); |
| 16217 | }, | 16373 | }, |
| 16218 | .sse => { | 16374 | .sse => { |
| 16219 | assert(classes.len == 1); | 16375 | assert(classes.len == 1); |
| 16220 | | 16376 | |
| 16221 | try self.genSetReg(offset_reg, Type.c_uint, fp_offset); | 16377 | try self.genSetReg(offset_reg, Type.c_uint, fp_offset, .{}); |
| 16222 | try self.asmRegisterImmediate(.{ ._, .cmp }, offset_reg, Immediate.u( | 16378 | try self.asmRegisterImmediate(.{ ._, .cmp }, offset_reg, Immediate.u( |
| 16223 | abi.SysV.c_abi_int_param_regs.len * 8 + abi.SysV.c_abi_sse_param_regs.len * 16, | 16379 | abi.SysV.c_abi_int_param_regs.len * 8 + abi.SysV.c_abi_sse_param_regs.len * 16, |
| 16224 | )); | 16380 | )); |
| 16225 | const mem_reloc = try self.asmJccReloc(.ae, undefined); | 16381 | const mem_reloc = try self.asmJccReloc(.ae, undefined); |
| 16226 | | 16382 | |
| 16227 | try self.genSetReg(addr_reg, ptr_anyopaque_ty, reg_save_area); | 16383 | try self.genSetReg(addr_reg, ptr_anyopaque_ty, reg_save_area, .{}); |
| 16228 | if (!unused) try self.asmRegisterMemory(.{ ._, .lea }, addr_reg, .{ | 16384 | if (!unused) try self.asmRegisterMemory(.{ ._, .lea }, addr_reg, .{ |
| 16229 | .base = .{ .reg = addr_reg }, | 16385 | .base = .{ .reg = addr_reg }, |
| 16230 | .mod = .{ .rm = .{ | 16386 | .mod = .{ .rm = .{ |
| ... | @@ -16239,11 +16395,11 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -16239,11 +16395,11 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { |
| 16239 | .disp = 16, | 16395 | .disp = 16, |
| 16240 | } }, | 16396 | } }, |
| 16241 | }); | 16397 | }); |
| 16242 | try self.genCopy(Type.c_uint, fp_offset, .{ .register = offset_reg }); | 16398 | try self.genCopy(Type.c_uint, fp_offset, .{ .register = offset_reg }, .{}); |
| 16243 | const done_reloc = try self.asmJmpReloc(undefined); | 16399 | const done_reloc = try self.asmJmpReloc(undefined); |
| 16244 | | 16400 | |
| 16245 | try self.performReloc(mem_reloc); | 16401 | try self.performReloc(mem_reloc); |
| 16246 | try self.genSetReg(addr_reg, ptr_anyopaque_ty, overflow_arg_area); | 16402 | try self.genSetReg(addr_reg, ptr_anyopaque_ty, overflow_arg_area, .{}); |
| 16247 | try self.asmRegisterMemory(.{ ._, .lea }, offset_reg.to64(), .{ | 16403 | try self.asmRegisterMemory(.{ ._, .lea }, offset_reg.to64(), .{ |
| 16248 | .base = .{ .reg = addr_reg }, | 16404 | .base = .{ .reg = addr_reg }, |
| 16249 | .mod = .{ .rm = .{ | 16405 | .mod = .{ .rm = .{ |
| ... | @@ -16255,12 +16411,13 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -16255,12 +16411,13 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { |
| 16255 | ptr_anyopaque_ty, | 16411 | ptr_anyopaque_ty, |
| 16256 | overflow_arg_area, | 16412 | overflow_arg_area, |
| 16257 | .{ .register = offset_reg.to64() }, | 16413 | .{ .register = offset_reg.to64() }, |
| | 16414 | .{}, |
| 16258 | ); | 16415 | ); |
| 16259 | | 16416 | |
| 16260 | try self.performReloc(done_reloc); | 16417 | try self.performReloc(done_reloc); |
| 16261 | if (!unused) try self.genCopy(promote_ty, promote_mcv, .{ | 16418 | if (!unused) try self.genCopy(promote_ty, promote_mcv, .{ |
| 16262 | .indirect = .{ .reg = addr_reg }, | 16419 | .indirect = .{ .reg = addr_reg }, |
| 16263 | }); | 16420 | }, .{}); |
| 16264 | }, | 16421 | }, |
| 16265 | .memory => { | 16422 | .memory => { |
| 16266 | assert(classes.len == 1); | 16423 | assert(classes.len == 1); |
| ... | @@ -16276,7 +16433,7 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -16276,7 +16433,7 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { |
| 16276 | | 16433 | |
| 16277 | if (!promote_ty.isRuntimeFloat()) { | 16434 | if (!promote_ty.isRuntimeFloat()) { |
| 16278 | const dst_mcv = try self.allocRegOrMem(inst, true); | 16435 | const dst_mcv = try self.allocRegOrMem(inst, true); |
| 16279 | try self.genCopy(ty, dst_mcv, promote_mcv); | 16436 | try self.genCopy(ty, dst_mcv, promote_mcv, .{}); |
| 16280 | break :result dst_mcv; | 16437 | break :result dst_mcv; |
| 16281 | } | 16438 | } |
| 16282 | | 16439 | |
| ... | @@ -16367,6 +16524,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue { | ... | @@ -16367,6 +16524,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue { |
| 16367 | 0, | 16524 | 0, |
| 16368 | Type.usize, | 16525 | Type.usize, |
| 16369 | .{ .lea_symbol = .{ .sym = tlv_sym } }, | 16526 | .{ .lea_symbol = .{ .sym = tlv_sym } }, |
| | 16527 | .{}, |
| 16370 | ); | 16528 | ); |
| 16371 | break :init .{ .load_frame = .{ .index = frame_index } }; | 16529 | break :init .{ .load_frame = .{ .index = frame_index } }; |
| 16372 | }, | 16530 | }, |