| ... | @@ -2986,6 +2986,7 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2986,6 +2986,7 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { |
| 2986 | .{ ._r, .sa }, | 2986 | .{ ._r, .sa }, |
| 2987 | Type.isize, | 2987 | Type.isize, |
| 2988 | extend_mcv, | 2988 | extend_mcv, |
| | 2989 | Type.u8, |
| 2989 | .{ .immediate = 63 }, | 2990 | .{ .immediate = 63 }, |
| 2990 | ); | 2991 | ); |
| 2991 | break :extend extend_mcv; | 2992 | break :extend extend_mcv; |
| ... | @@ -3500,10 +3501,22 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3500,10 +3501,22 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { |
| 3500 | const reg_extra_bits = self.regExtraBits(ty); | 3501 | const reg_extra_bits = self.regExtraBits(ty); |
| 3501 | const cc: Condition = if (ty.isSignedInt(mod)) cc: { | 3502 | const cc: Condition = if (ty.isSignedInt(mod)) cc: { |
| 3502 | if (reg_extra_bits > 0) { | 3503 | if (reg_extra_bits > 0) { |
| 3503 | try self.genShiftBinOpMir(.{ ._l, .sa }, ty, dst_mcv, .{ .immediate = reg_extra_bits }); | 3504 | try self.genShiftBinOpMir( |
| | 3505 | .{ ._l, .sa }, |
| | 3506 | ty, |
| | 3507 | dst_mcv, |
| | 3508 | Type.u8, |
| | 3509 | .{ .immediate = reg_extra_bits }, |
| | 3510 | ); |
| 3504 | } | 3511 | } |
| 3505 | try self.genSetReg(limit_reg, ty, dst_mcv, .{}); | 3512 | try self.genSetReg(limit_reg, ty, dst_mcv, .{}); |
| 3506 | try self.genShiftBinOpMir(.{ ._r, .sa }, ty, limit_mcv, .{ .immediate = reg_bits - 1 }); | 3513 | try self.genShiftBinOpMir( |
| | 3514 | .{ ._r, .sa }, |
| | 3515 | ty, |
| | 3516 | limit_mcv, |
| | 3517 | Type.u8, |
| | 3518 | .{ .immediate = reg_bits - 1 }, |
| | 3519 | ); |
| 3507 | try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, .{ | 3520 | try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, .{ |
| 3508 | .immediate = (@as(u64, 1) << @intCast(reg_bits - 1)) - 1, | 3521 | .immediate = (@as(u64, 1) << @intCast(reg_bits - 1)) - 1, |
| 3509 | }); | 3522 | }); |
| ... | @@ -3517,6 +3530,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3517,6 +3530,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { |
| 3517 | .{ ._l, .sa }, | 3530 | .{ ._l, .sa }, |
| 3518 | ty, | 3531 | ty, |
| 3519 | shifted_rhs_mcv, | 3532 | shifted_rhs_mcv, |
| | 3533 | Type.u8, |
| 3520 | .{ .immediate = reg_extra_bits }, | 3534 | .{ .immediate = reg_extra_bits }, |
| 3521 | ); | 3535 | ); |
| 3522 | try self.genBinOpMir(.{ ._, .add }, ty, dst_mcv, shifted_rhs_mcv); | 3536 | try self.genBinOpMir(.{ ._, .add }, ty, dst_mcv, shifted_rhs_mcv); |
| ... | @@ -3542,9 +3556,13 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3542,9 +3556,13 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { |
| 3542 | registerAlias(limit_reg, cmov_abi_size), | 3556 | registerAlias(limit_reg, cmov_abi_size), |
| 3543 | ); | 3557 | ); |
| 3544 | | 3558 | |
| 3545 | if (reg_extra_bits > 0 and ty.isSignedInt(mod)) { | 3559 | if (reg_extra_bits > 0 and ty.isSignedInt(mod)) try self.genShiftBinOpMir( |
| 3546 | try self.genShiftBinOpMir(.{ ._r, .sa }, ty, dst_mcv, .{ .immediate = reg_extra_bits }); | 3560 | .{ ._r, .sa }, |
| 3547 | } | 3561 | ty, |
| | 3562 | dst_mcv, |
| | 3563 | Type.u8, |
| | 3564 | .{ .immediate = reg_extra_bits }, |
| | 3565 | ); |
| 3548 | | 3566 | |
| 3549 | return self.finishAir(inst, dst_mcv, .{ bin_op.lhs, bin_op.rhs, .none }); | 3567 | return self.finishAir(inst, dst_mcv, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 3550 | } | 3568 | } |
| ... | @@ -3583,10 +3601,22 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3583,10 +3601,22 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void { |
| 3583 | const reg_extra_bits = self.regExtraBits(ty); | 3601 | const reg_extra_bits = self.regExtraBits(ty); |
| 3584 | const cc: Condition = if (ty.isSignedInt(mod)) cc: { | 3602 | const cc: Condition = if (ty.isSignedInt(mod)) cc: { |
| 3585 | if (reg_extra_bits > 0) { | 3603 | if (reg_extra_bits > 0) { |
| 3586 | try self.genShiftBinOpMir(.{ ._l, .sa }, ty, dst_mcv, .{ .immediate = reg_extra_bits }); | 3604 | try self.genShiftBinOpMir( |
| | 3605 | .{ ._l, .sa }, |
| | 3606 | ty, |
| | 3607 | dst_mcv, |
| | 3608 | Type.u8, |
| | 3609 | .{ .immediate = reg_extra_bits }, |
| | 3610 | ); |
| 3587 | } | 3611 | } |
| 3588 | try self.genSetReg(limit_reg, ty, dst_mcv, .{}); | 3612 | try self.genSetReg(limit_reg, ty, dst_mcv, .{}); |
| 3589 | try self.genShiftBinOpMir(.{ ._r, .sa }, ty, limit_mcv, .{ .immediate = reg_bits - 1 }); | 3613 | try self.genShiftBinOpMir( |
| | 3614 | .{ ._r, .sa }, |
| | 3615 | ty, |
| | 3616 | limit_mcv, |
| | 3617 | Type.u8, |
| | 3618 | .{ .immediate = reg_bits - 1 }, |
| | 3619 | ); |
| 3590 | try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, .{ | 3620 | try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, .{ |
| 3591 | .immediate = (@as(u64, 1) << @intCast(reg_bits - 1)) - 1, | 3621 | .immediate = (@as(u64, 1) << @intCast(reg_bits - 1)) - 1, |
| 3592 | }); | 3622 | }); |
| ... | @@ -3600,6 +3630,7 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3600,6 +3630,7 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void { |
| 3600 | .{ ._l, .sa }, | 3630 | .{ ._l, .sa }, |
| 3601 | ty, | 3631 | ty, |
| 3602 | shifted_rhs_mcv, | 3632 | shifted_rhs_mcv, |
| | 3633 | Type.u8, |
| 3603 | .{ .immediate = reg_extra_bits }, | 3634 | .{ .immediate = reg_extra_bits }, |
| 3604 | ); | 3635 | ); |
| 3605 | try self.genBinOpMir(.{ ._, .sub }, ty, dst_mcv, shifted_rhs_mcv); | 3636 | try self.genBinOpMir(.{ ._, .sub }, ty, dst_mcv, shifted_rhs_mcv); |
| ... | @@ -3618,9 +3649,13 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3618,9 +3649,13 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void { |
| 3618 | registerAlias(limit_reg, cmov_abi_size), | 3649 | registerAlias(limit_reg, cmov_abi_size), |
| 3619 | ); | 3650 | ); |
| 3620 | | 3651 | |
| 3621 | if (reg_extra_bits > 0 and ty.isSignedInt(mod)) { | 3652 | if (reg_extra_bits > 0 and ty.isSignedInt(mod)) try self.genShiftBinOpMir( |
| 3622 | try self.genShiftBinOpMir(.{ ._r, .sa }, ty, dst_mcv, .{ .immediate = reg_extra_bits }); | 3653 | .{ ._r, .sa }, |
| 3623 | } | 3654 | ty, |
| | 3655 | dst_mcv, |
| | 3656 | Type.u8, |
| | 3657 | .{ .immediate = reg_extra_bits }, |
| | 3658 | ); |
| 3624 | | 3659 | |
| 3625 | return self.finishAir(inst, dst_mcv, .{ bin_op.lhs, bin_op.rhs, .none }); | 3660 | return self.finishAir(inst, dst_mcv, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 3626 | } | 3661 | } |
| ... | @@ -3741,7 +3776,13 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3741,7 +3776,13 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void { |
| 3741 | const cc: Condition = if (ty.isSignedInt(mod)) cc: { | 3776 | const cc: Condition = if (ty.isSignedInt(mod)) cc: { |
| 3742 | try self.genSetReg(limit_reg, ty, lhs_mcv, .{}); | 3777 | try self.genSetReg(limit_reg, ty, lhs_mcv, .{}); |
| 3743 | try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, rhs_mcv); | 3778 | try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, rhs_mcv); |
| 3744 | try self.genShiftBinOpMir(.{ ._r, .sa }, ty, limit_mcv, .{ .immediate = reg_bits - 1 }); | 3779 | try self.genShiftBinOpMir( |
| | 3780 | .{ ._r, .sa }, |
| | 3781 | ty, |
| | 3782 | limit_mcv, |
| | 3783 | Type.u8, |
| | 3784 | .{ .immediate = reg_bits - 1 }, |
| | 3785 | ); |
| 3745 | try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, .{ | 3786 | try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, .{ |
| 3746 | .immediate = (@as(u64, 1) << @intCast(reg_bits - 1)) - 1, | 3787 | .immediate = (@as(u64, 1) << @intCast(reg_bits - 1)) - 1, |
| 3747 | }); | 3788 | }); |
| ... | @@ -4029,6 +4070,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4029,6 +4070,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4029 | .size = .qword, | 4070 | .size = .qword, |
| 4030 | .index = temp_regs[0].to64(), | 4071 | .index = temp_regs[0].to64(), |
| 4031 | .scale = .@"8", | 4072 | .scale = .@"8", |
| | 4073 | .disp = rhs_mcv.load_frame.off, |
| 4032 | } }, | 4074 | } }, |
| 4033 | }); | 4075 | }); |
| 4034 | try self.asmRegisterRegister(.{ ._, .@"test" }, temp_regs[1].to64(), temp_regs[1].to64()); | 4076 | try self.asmRegisterRegister(.{ ._, .@"test" }, temp_regs[1].to64(), temp_regs[1].to64()); |
| ... | @@ -4047,7 +4089,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4047,7 +4089,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4047 | .size = .qword, | 4089 | .size = .qword, |
| 4048 | .index = temp_regs[3].to64(), | 4090 | .index = temp_regs[3].to64(), |
| 4049 | .scale = .@"8", | 4091 | .scale = .@"8", |
| 4050 | .disp = @intCast(tuple_ty.structFieldOffset(0, mod)), | 4092 | .disp = dst_mcv.load_frame.off + |
| | 4093 | @as(i32, @intCast(tuple_ty.structFieldOffset(0, mod))), |
| 4051 | } }, | 4094 | } }, |
| 4052 | }, .rdx); | 4095 | }, .rdx); |
| 4053 | try self.asmSetccRegister(.c, .cl); | 4096 | try self.asmSetccRegister(.c, .cl); |
| ... | @@ -4058,6 +4101,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4058,6 +4101,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4058 | .size = .qword, | 4101 | .size = .qword, |
| 4059 | .index = temp_regs[2].to64(), | 4102 | .index = temp_regs[2].to64(), |
| 4060 | .scale = .@"8", | 4103 | .scale = .@"8", |
| | 4104 | .disp = lhs_mcv.load_frame.off, |
| 4061 | } }, | 4105 | } }, |
| 4062 | }); | 4106 | }); |
| 4063 | try self.asmRegister(.{ ._, .mul }, temp_regs[1].to64()); | 4107 | try self.asmRegister(.{ ._, .mul }, temp_regs[1].to64()); |
| ... | @@ -4069,7 +4113,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4069,7 +4113,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4069 | .size = .qword, | 4113 | .size = .qword, |
| 4070 | .index = temp_regs[3].to64(), | 4114 | .index = temp_regs[3].to64(), |
| 4071 | .scale = .@"8", | 4115 | .scale = .@"8", |
| 4072 | .disp = @intCast(tuple_ty.structFieldOffset(0, mod)), | 4116 | .disp = dst_mcv.load_frame.off + |
| | 4117 | @as(i32, @intCast(tuple_ty.structFieldOffset(0, mod))), |
| 4073 | } }, | 4118 | } }, |
| 4074 | }, .rax); | 4119 | }, .rax); |
| 4075 | try self.asmSetccRegister(.c, .ch); | 4120 | try self.asmSetccRegister(.c, .ch); |
| ... | @@ -4108,7 +4153,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4108,7 +4153,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4108 | .size = .qword, | 4153 | .size = .qword, |
| 4109 | .index = temp_regs[2].to64(), | 4154 | .index = temp_regs[2].to64(), |
| 4110 | .scale = .@"8", | 4155 | .scale = .@"8", |
| 4111 | .disp = -8, | 4156 | .disp = lhs_mcv.load_frame.off - 8, |
| 4112 | } }, | 4157 | } }, |
| 4113 | }, Immediate.u(0)); | 4158 | }, Immediate.u(0)); |
| 4114 | _ = try self.asmJccReloc(.z, overflow_loop); | 4159 | _ = try self.asmJccReloc(.z, overflow_loop); |
| ... | @@ -4117,7 +4162,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4117,7 +4162,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4117 | .base = .{ .frame = dst_mcv.load_frame.index }, | 4162 | .base = .{ .frame = dst_mcv.load_frame.index }, |
| 4118 | .mod = .{ .rm = .{ | 4163 | .mod = .{ .rm = .{ |
| 4119 | .size = .byte, | 4164 | .size = .byte, |
| 4120 | .disp = @intCast(tuple_ty.structFieldOffset(1, mod)), | 4165 | .disp = dst_mcv.load_frame.off + |
| | 4166 | @as(i32, @intCast(tuple_ty.structFieldOffset(1, mod))), |
| 4121 | } }, | 4167 | } }, |
| 4122 | }, Immediate.u(1)); | 4168 | }, Immediate.u(1)); |
| 4123 | self.performReloc(no_overflow); | 4169 | self.performReloc(no_overflow); |
| ... | @@ -4863,6 +4909,7 @@ fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4863,6 +4909,7 @@ fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { |
| 4863 | .{ ._r, .sh }, | 4909 | .{ ._r, .sh }, |
| 4864 | err_union_ty, | 4910 | err_union_ty, |
| 4865 | result, | 4911 | result, |
| | 4912 | Type.u8, |
| 4866 | .{ .immediate = @as(u6, @intCast(err_off * 8)) }, | 4913 | .{ .immediate = @as(u6, @intCast(err_off * 8)) }, |
| 4867 | ) else try self.truncateRegister(Type.anyerror, result.register); | 4914 | ) else try self.truncateRegister(Type.anyerror, result.register); |
| 4868 | break :result result; | 4915 | break :result result; |
| ... | @@ -5020,6 +5067,7 @@ fn genUnwrapErrUnionPayloadMir( | ... | @@ -5020,6 +5067,7 @@ fn genUnwrapErrUnionPayloadMir( |
| 5020 | .{ ._r, .sh }, | 5067 | .{ ._r, .sh }, |
| 5021 | err_union_ty, | 5068 | err_union_ty, |
| 5022 | result_mcv, | 5069 | result_mcv, |
| | 5070 | Type.u8, |
| 5023 | .{ .immediate = @as(u6, @intCast(payload_off * 8)) }, | 5071 | .{ .immediate = @as(u6, @intCast(payload_off * 8)) }, |
| 5024 | ) else try self.truncateRegister(payload_ty, result_mcv.register); | 5072 | ) else try self.truncateRegister(payload_ty, result_mcv.register); |
| 5025 | break :result if (payload_in_gp) | 5073 | break :result if (payload_in_gp) |
| ... | @@ -5642,7 +5690,10 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5642,7 +5690,10 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void { |
| 5642 | }); | 5690 | }); |
| 5643 | } | 5691 | } |
| 5644 | | 5692 | |
| 5645 | return self.fail("TODO implement get_union_tag for ABI larger than 8 bytes and operand {}", .{operand}); | 5693 | return self.fail( |
| | 5694 | "TODO implement get_union_tag for ABI larger than 8 bytes and operand {}", |
| | 5695 | .{operand}, |
| | 5696 | ); |
| 5646 | }, | 5697 | }, |
| 5647 | .register => { | 5698 | .register => { |
| 5648 | const shift: u6 = if (layout.tag_align.compare(.lt, layout.payload_align)) | 5699 | const shift: u6 = if (layout.tag_align.compare(.lt, layout.payload_align)) |
| ... | @@ -5650,7 +5701,13 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5650,7 +5701,13 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void { |
| 5650 | else | 5701 | else |
| 5651 | 0; | 5702 | 0; |
| 5652 | const result = try self.copyToRegisterWithInstTracking(inst, union_ty, operand); | 5703 | const result = try self.copyToRegisterWithInstTracking(inst, union_ty, operand); |
| 5653 | try self.genShiftBinOpMir(.{ ._r, .sh }, Type.usize, result, .{ .immediate = shift }); | 5704 | try self.genShiftBinOpMir( |
| | 5705 | .{ ._r, .sh }, |
| | 5706 | Type.usize, |
| | 5707 | result, |
| | 5708 | Type.u8, |
| | 5709 | .{ .immediate = shift }, |
| | 5710 | ); |
| 5654 | break :blk MCValue{ | 5711 | break :blk MCValue{ |
| 5655 | .register = registerAlias(result.register, @intCast(layout.tag_size)), | 5712 | .register = registerAlias(result.register, @intCast(layout.tag_size)), |
| 5656 | }; | 5713 | }; |
| ... | @@ -6199,7 +6256,7 @@ fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6199,7 +6256,7 @@ fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void { |
| 6199 | if (extra_bits > 0) try self.genShiftBinOpMir(switch (signedness) { | 6256 | if (extra_bits > 0) try self.genShiftBinOpMir(switch (signedness) { |
| 6200 | .signed => .{ ._r, .sa }, | 6257 | .signed => .{ ._r, .sa }, |
| 6201 | .unsigned => .{ ._r, .sh }, | 6258 | .unsigned => .{ ._r, .sh }, |
| 6202 | }, src_ty, dst_mcv, .{ .immediate = extra_bits }); | 6259 | }, src_ty, dst_mcv, Type.u8, .{ .immediate = extra_bits }); |
| 6203 | | 6260 | |
| 6204 | return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none }); | 6261 | return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none }); |
| 6205 | } | 6262 | } |
| ... | @@ -6321,7 +6378,7 @@ fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6321,7 +6378,7 @@ fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void { |
| 6321 | if (extra_bits > 0) try self.genShiftBinOpMir(switch (signedness) { | 6378 | if (extra_bits > 0) try self.genShiftBinOpMir(switch (signedness) { |
| 6322 | .signed => .{ ._r, .sa }, | 6379 | .signed => .{ ._r, .sa }, |
| 6323 | .unsigned => .{ ._r, .sh }, | 6380 | .unsigned => .{ ._r, .sh }, |
| 6324 | }, src_ty, dst_mcv, .{ .immediate = extra_bits }); | 6381 | }, src_ty, dst_mcv, Type.u8, .{ .immediate = extra_bits }); |
| 6325 | | 6382 | |
| 6326 | return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none }); | 6383 | return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none }); |
| 6327 | } | 6384 | } |
| ... | @@ -6710,6 +6767,7 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6710,6 +6767,7 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { |
| 6710 | .size = .qword, | 6767 | .size = .qword, |
| 6711 | .index = tmp_regs[0].to64(), | 6768 | .index = tmp_regs[0].to64(), |
| 6712 | .scale = .@"8", | 6769 | .scale = .@"8", |
| | 6770 | .disp = dst_mcv.load_frame.off, |
| 6713 | } }, | 6771 | } }, |
| 6714 | }); | 6772 | }); |
| 6715 | try self.asmSetccRegister(.c, tmp_regs[1].to8()); | 6773 | try self.asmSetccRegister(.c, tmp_regs[1].to8()); |
| ... | @@ -6719,6 +6777,7 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6719,6 +6777,7 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { |
| 6719 | .size = .qword, | 6777 | .size = .qword, |
| 6720 | .index = tmp_regs[0].to64(), | 6778 | .index = tmp_regs[0].to64(), |
| 6721 | .scale = .@"8", | 6779 | .scale = .@"8", |
| | 6780 | .disp = dst_mcv.load_frame.off, |
| 6722 | } }, | 6781 | } }, |
| 6723 | }, tmp_regs[2].to64()); | 6782 | }, tmp_regs[2].to64()); |
| 6724 | | 6783 | |
| ... | @@ -7303,12 +7362,14 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In | ... | @@ -7303,12 +7362,14 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In |
| 7303 | .{ ._l, .sh }, | 7362 | .{ ._l, .sh }, |
| 7304 | limb_ty, | 7363 | limb_ty, |
| 7305 | tmp_mcv, | 7364 | tmp_mcv, |
| | 7365 | Type.u8, |
| 7306 | .{ .immediate = src_bit_off }, | 7366 | .{ .immediate = src_bit_off }, |
| 7307 | ), | 7367 | ), |
| 7308 | 1 => try self.genShiftBinOpMir( | 7368 | 1 => try self.genShiftBinOpMir( |
| 7309 | .{ ._r, .sh }, | 7369 | .{ ._r, .sh }, |
| 7310 | limb_ty, | 7370 | limb_ty, |
| 7311 | tmp_mcv, | 7371 | tmp_mcv, |
| | 7372 | Type.u8, |
| 7312 | .{ .immediate = limb_abi_bits - src_bit_off }, | 7373 | .{ .immediate = limb_abi_bits - src_bit_off }, |
| 7313 | ), | 7374 | ), |
| 7314 | else => unreachable, | 7375 | else => unreachable, |
| ... | @@ -7497,6 +7558,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -7497,6 +7558,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 7497 | .{ ._r, .sh }, | 7558 | .{ ._r, .sh }, |
| 7498 | Type.usize, | 7559 | Type.usize, |
| 7499 | dst_mcv, | 7560 | dst_mcv, |
| | 7561 | Type.u8, |
| 7500 | .{ .immediate = field_off }, | 7562 | .{ .immediate = field_off }, |
| 7501 | ); | 7563 | ); |
| 7502 | } | 7564 | } |
| ... | @@ -7540,6 +7602,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -7540,6 +7602,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 7540 | .{ ._r, .sh }, | 7602 | .{ ._r, .sh }, |
| 7541 | Type.u128, | 7603 | Type.u128, |
| 7542 | dst_mcv, | 7604 | dst_mcv, |
| | 7605 | Type.u8, |
| 7543 | .{ .immediate = field_off }, | 7606 | .{ .immediate = field_off }, |
| 7544 | ); | 7607 | ); |
| 7545 | } | 7608 | } |
| ... | @@ -7576,6 +7639,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -7576,6 +7639,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 7576 | .{ ._r, .sh }, | 7639 | .{ ._r, .sh }, |
| 7577 | Type.usize, | 7640 | Type.usize, |
| 7578 | dst_mcv, | 7641 | dst_mcv, |
| | 7642 | Type.u8, |
| 7579 | .{ .immediate = field_off % 64 }, | 7643 | .{ .immediate = field_off % 64 }, |
| 7580 | ); | 7644 | ); |
| 7581 | } | 7645 | } |
| ... | @@ -7890,117 +7954,350 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MC | ... | @@ -7890,117 +7954,350 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MC |
| 7890 | fn genShiftBinOpMir( | 7954 | fn genShiftBinOpMir( |
| 7891 | self: *Self, | 7955 | self: *Self, |
| 7892 | tag: Mir.Inst.FixedTag, | 7956 | tag: Mir.Inst.FixedTag, |
| 7893 | ty: Type, | 7957 | lhs_ty: Type, |
| 7894 | lhs_mcv: MCValue, | 7958 | lhs_mcv: MCValue, |
| 7895 | shift_mcv: MCValue, | 7959 | rhs_ty: Type, |
| | 7960 | rhs_mcv: MCValue, |
| 7896 | ) !void { | 7961 | ) !void { |
| 7897 | const mod = self.bin_file.comp.module.?; | 7962 | const mod = self.bin_file.comp.module.?; |
| 7898 | const rhs_mcv: MCValue = rhs: { | 7963 | const abi_size: u32 = @intCast(lhs_ty.abiSize(mod)); |
| 7899 | switch (shift_mcv) { | 7964 | const shift_abi_size: u32 = @intCast(rhs_ty.abiSize(mod)); |
| 7900 | .immediate => |imm| switch (imm) { | 7965 | try self.spillEflagsIfOccupied(); |
| | 7966 | |
| | 7967 | if (abi_size > 16) { |
| | 7968 | const limbs_len = math.divCeil(u32, abi_size, 8) catch unreachable; |
| | 7969 | assert(shift_abi_size >= 1 and shift_abi_size <= 2); |
| | 7970 | |
| | 7971 | const rcx_lock: ?RegisterLock = switch (rhs_mcv) { |
| | 7972 | .immediate => |shift_imm| switch (shift_imm) { |
| 7901 | 0 => return, | 7973 | 0 => return, |
| 7902 | else => break :rhs shift_mcv, | 7974 | else => null, |
| 7903 | }, | 7975 | }, |
| 7904 | .register => |shift_reg| if (shift_reg == .rcx) break :rhs shift_mcv, | 7976 | else => lock: { |
| 7905 | else => {}, | 7977 | if (switch (rhs_mcv) { |
| 7906 | } | 7978 | .register => |rhs_reg| rhs_reg.id() != Register.rcx.id(), |
| 7907 | self.register_manager.getRegAssumeFree(.rcx, null); | 7979 | else => true, |
| 7908 | try self.genSetReg(.cl, Type.u8, shift_mcv, .{}); | 7980 | }) { |
| 7909 | break :rhs .{ .register = .rcx }; | 7981 | self.register_manager.getRegAssumeFree(.rcx, null); |
| 7910 | }; | 7982 | try self.genSetReg(.rcx, rhs_ty, rhs_mcv, .{}); |
| | 7983 | } |
| | 7984 | break :lock self.register_manager.lockReg(.rcx); |
| | 7985 | }, |
| | 7986 | }; |
| | 7987 | defer if (rcx_lock) |lock| self.register_manager.unlockReg(lock); |
| 7911 | | 7988 | |
| 7912 | const abi_size: u32 = @intCast(ty.abiSize(mod)); | 7989 | const temp_regs = try self.register_manager.allocRegs(4, .{null} ** 4, abi.RegisterClass.gp); |
| 7913 | if (abi_size <= 8) { | 7990 | const temp_locks = self.register_manager.lockRegs(4, temp_regs); |
| 7914 | switch (lhs_mcv) { | 7991 | defer for (temp_locks) |temp_lock| if (temp_lock) |lock| self.register_manager.unlockReg(lock); |
| 7915 | .register => |lhs_reg| switch (rhs_mcv) { | 7992 | |
| 7916 | .immediate => |rhs_imm| try self.asmRegisterImmediate( | 7993 | switch (tag[0]) { |
| 7917 | tag, | 7994 | ._l => { |
| 7918 | registerAlias(lhs_reg, abi_size), | 7995 | try self.asmRegisterImmediate(.{ ._, .mov }, temp_regs[1].to32(), Immediate.u(limbs_len - 1)); |
| 7919 | Immediate.u(rhs_imm), | 7996 | switch (rhs_mcv) { |
| 7920 | ), | 7997 | .immediate => |shift_imm| try self.asmRegisterImmediate( |
| 7921 | .register => |rhs_reg| try self.asmRegisterRegister( | 7998 | .{ ._, .mov }, |
| 7922 | tag, | 7999 | temp_regs[0].to32(), |
| 7923 | registerAlias(lhs_reg, abi_size), | 8000 | Immediate.u(limbs_len - (shift_imm >> 6) - 1), |
| 7924 | registerAlias(rhs_reg, 1), | 8001 | ), |
| 7925 | ), | 8002 | else => { |
| 7926 | else => return self.fail("TODO genShiftBinOpMir between {s} and {s}", .{ | 8003 | try self.asmRegisterRegister( |
| 7927 | @tagName(lhs_mcv), | 8004 | .{ ._, .movzx }, |
| 7928 | @tagName(rhs_mcv), | 8005 | temp_regs[2].to32(), |
| 7929 | }), | 8006 | registerAlias(.rcx, shift_abi_size), |
| | 8007 | ); |
| | 8008 | try self.asmRegisterImmediate( |
| | 8009 | .{ ._, .@"and" }, |
| | 8010 | .cl, |
| | 8011 | Immediate.u(std.math.maxInt(u6)), |
| | 8012 | ); |
| | 8013 | try self.asmRegisterImmediate( |
| | 8014 | .{ ._r, .sh }, |
| | 8015 | temp_regs[2].to32(), |
| | 8016 | Immediate.u(6), |
| | 8017 | ); |
| | 8018 | try self.asmRegisterRegister( |
| | 8019 | .{ ._, .mov }, |
| | 8020 | temp_regs[0].to32(), |
| | 8021 | temp_regs[1].to32(), |
| | 8022 | ); |
| | 8023 | try self.asmRegisterRegister( |
| | 8024 | .{ ._, .sub }, |
| | 8025 | temp_regs[0].to32(), |
| | 8026 | temp_regs[2].to32(), |
| | 8027 | ); |
| | 8028 | }, |
| | 8029 | } |
| 7930 | }, | 8030 | }, |
| 7931 | .memory, .indirect, .load_frame => { | 8031 | ._r => { |
| 7932 | const lhs_mem: Memory = switch (lhs_mcv) { | 8032 | try self.asmRegisterRegister(.{ ._, .xor }, temp_regs[1].to32(), temp_regs[1].to32()); |
| 7933 | .memory => |addr| .{ | 8033 | switch (rhs_mcv) { |
| 7934 | .base = .{ .reg = .ds }, | 8034 | .immediate => |shift_imm| try self.asmRegisterImmediate( |
| 7935 | .mod = .{ .rm = .{ | 8035 | .{ ._, .mov }, |
| 7936 | .size = Memory.Size.fromSize(abi_size), | 8036 | temp_regs[0].to32(), |
| 7937 | .disp = math.cast(i32, @as(i64, @bitCast(addr))) orelse | 8037 | Immediate.u(shift_imm >> 6), |
| 7938 | return self.fail("TODO genShiftBinOpMir between {s} and {s}", .{ | 8038 | ), |
| 7939 | @tagName(lhs_mcv), | 8039 | else => { |
| 7940 | @tagName(rhs_mcv), | 8040 | try self.asmRegisterRegister( |
| 7941 | }), | 8041 | .{ ._, .movzx }, |
| 7942 | } }, | 8042 | temp_regs[0].to32(), |
| | 8043 | registerAlias(.rcx, shift_abi_size), |
| | 8044 | ); |
| | 8045 | try self.asmRegisterImmediate( |
| | 8046 | .{ ._, .@"and" }, |
| | 8047 | .cl, |
| | 8048 | Immediate.u(std.math.maxInt(u6)), |
| | 8049 | ); |
| | 8050 | try self.asmRegisterImmediate( |
| | 8051 | .{ ._r, .sh }, |
| | 8052 | temp_regs[0].to32(), |
| | 8053 | Immediate.u(6), |
| | 8054 | ); |
| 7943 | }, | 8055 | }, |
| 7944 | .indirect => |reg_off| .{ | 8056 | } |
| 7945 | .base = .{ .reg = reg_off.reg }, | 8057 | }, |
| 7946 | .mod = .{ .rm = .{ | 8058 | else => unreachable, |
| 7947 | .size = Memory.Size.fromSize(abi_size), | 8059 | } |
| 7948 | .disp = reg_off.off, | 8060 | |
| 7949 | } }, | 8061 | const slow_inc_dec = self.hasFeature(.slow_incdec); |
| | 8062 | if (switch (rhs_mcv) { |
| | 8063 | .immediate => |shift_imm| shift_imm >> 6 < limbs_len - 1, |
| | 8064 | else => true, |
| | 8065 | }) { |
| | 8066 | try self.asmRegisterMemory(.{ ._, .mov }, temp_regs[2].to64(), .{ |
| | 8067 | .base = .{ .frame = lhs_mcv.load_frame.index }, |
| | 8068 | .mod = .{ .rm = .{ |
| | 8069 | .size = .qword, |
| | 8070 | .index = temp_regs[0].to64(), |
| | 8071 | .scale = .@"8", |
| | 8072 | .disp = lhs_mcv.load_frame.off, |
| | 8073 | } }, |
| | 8074 | }); |
| | 8075 | const skip = switch (rhs_mcv) { |
| | 8076 | .immediate => undefined, |
| | 8077 | else => switch (tag[0]) { |
| | 8078 | ._l => try self.asmJccReloc(.z, undefined), |
| | 8079 | ._r => skip: { |
| | 8080 | try self.asmRegisterImmediate( |
| | 8081 | .{ ._, .cmp }, |
| | 8082 | temp_regs[0].to32(), |
| | 8083 | Immediate.u(limbs_len - 1), |
| | 8084 | ); |
| | 8085 | break :skip try self.asmJccReloc(.nb, undefined); |
| 7950 | }, | 8086 | }, |
| 7951 | .load_frame => |frame_addr| .{ | 8087 | else => unreachable, |
| 7952 | .base = .{ .frame = frame_addr.index }, | 8088 | }, |
| 7953 | .mod = .{ .rm = .{ | 8089 | }; |
| 7954 | .size = Memory.Size.fromSize(abi_size), | 8090 | const loop: Mir.Inst.Index = @intCast(self.mir_instructions.len); |
| 7955 | .disp = frame_addr.off, | 8091 | try self.asmRegisterMemory(.{ ._, .mov }, temp_regs[3].to64(), .{ |
| 7956 | } }, | 8092 | .base = .{ .frame = lhs_mcv.load_frame.index }, |
| | 8093 | .mod = .{ .rm = .{ |
| | 8094 | .size = .qword, |
| | 8095 | .index = temp_regs[0].to64(), |
| | 8096 | .scale = .@"8", |
| | 8097 | .disp = switch (tag[0]) { |
| | 8098 | ._l => lhs_mcv.load_frame.off - 8, |
| | 8099 | ._r => lhs_mcv.load_frame.off + 8, |
| | 8100 | else => unreachable, |
| 7957 | }, | 8101 | }, |
| | 8102 | } }, |
| | 8103 | }); |
| | 8104 | switch (rhs_mcv) { |
| | 8105 | .immediate => |shift_imm| try self.asmRegisterRegisterImmediate( |
| | 8106 | .{ switch (tag[0]) { |
| | 8107 | ._l => ._ld, |
| | 8108 | ._r => ._rd, |
| | 8109 | else => unreachable, |
| | 8110 | }, .sh }, |
| | 8111 | temp_regs[2].to64(), |
| | 8112 | temp_regs[3].to64(), |
| | 8113 | Immediate.u(shift_imm & std.math.maxInt(u6)), |
| | 8114 | ), |
| | 8115 | else => try self.asmRegisterRegisterRegister(.{ switch (tag[0]) { |
| | 8116 | ._l => ._ld, |
| | 8117 | ._r => ._rd, |
| 7958 | else => unreachable, | 8118 | else => unreachable, |
| 7959 | }; | 8119 | }, .sh }, temp_regs[2].to64(), temp_regs[3].to64(), .cl), |
| 7960 | switch (rhs_mcv) { | 8120 | } |
| 7961 | .immediate => |rhs_imm| try self.asmMemoryImmediate( | 8121 | try self.asmMemoryRegister(.{ ._, .mov }, .{ |
| 7962 | tag, | 8122 | .base = .{ .frame = lhs_mcv.load_frame.index }, |
| 7963 | lhs_mem, | 8123 | .mod = .{ .rm = .{ |
| 7964 | Immediate.u(rhs_imm), | 8124 | .size = .qword, |
| 7965 | ), | 8125 | .index = temp_regs[1].to64(), |
| 7966 | .register => |rhs_reg| try self.asmMemoryRegister( | 8126 | .scale = .@"8", |
| 7967 | tag, | 8127 | .disp = lhs_mcv.load_frame.off, |
| 7968 | lhs_mem, | 8128 | } }, |
| 7969 | registerAlias(rhs_reg, 1), | 8129 | }, temp_regs[2].to64()); |
| 7970 | ), | 8130 | try self.asmRegisterRegister(.{ ._, .mov }, temp_regs[2].to64(), temp_regs[3].to64()); |
| 7971 | else => return self.fail("TODO genShiftBinOpMir between {s} and {s}", .{ | 8131 | switch (tag[0]) { |
| 7972 | @tagName(lhs_mcv), | 8132 | ._l => { |
| 7973 | @tagName(rhs_mcv), | 8133 | if (slow_inc_dec) { |
| 7974 | }), | 8134 | try self.asmRegisterImmediate(.{ ._, .sub }, temp_regs[1].to32(), Immediate.u(1)); |
| 7975 | } | 8135 | try self.asmRegisterImmediate(.{ ._, .sub }, temp_regs[0].to32(), Immediate.u(1)); |
| | 8136 | } else { |
| | 8137 | try self.asmRegister(.{ ._, .dec }, temp_regs[1].to32()); |
| | 8138 | try self.asmRegister(.{ ._, .dec }, temp_regs[0].to32()); |
| | 8139 | } |
| | 8140 | _ = try self.asmJccReloc(.nz, loop); |
| | 8141 | }, |
| | 8142 | ._r => { |
| | 8143 | if (slow_inc_dec) { |
| | 8144 | try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[1].to32(), Immediate.u(1)); |
| | 8145 | try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[0].to32(), Immediate.u(1)); |
| | 8146 | } else { |
| | 8147 | try self.asmRegister(.{ ._, .inc }, temp_regs[1].to32()); |
| | 8148 | try self.asmRegister(.{ ._, .inc }, temp_regs[0].to32()); |
| | 8149 | } |
| | 8150 | try self.asmRegisterImmediate( |
| | 8151 | .{ ._, .cmp }, |
| | 8152 | temp_regs[0].to32(), |
| | 8153 | Immediate.u(limbs_len - 1), |
| | 8154 | ); |
| | 8155 | _ = try self.asmJccReloc(.b, loop); |
| | 8156 | }, |
| | 8157 | else => unreachable, |
| | 8158 | } |
| | 8159 | switch (rhs_mcv) { |
| | 8160 | .immediate => {}, |
| | 8161 | else => self.performReloc(skip), |
| | 8162 | } |
| | 8163 | } |
| | 8164 | switch (rhs_mcv) { |
| | 8165 | .immediate => |shift_imm| try self.asmRegisterImmediate( |
| | 8166 | tag, |
| | 8167 | temp_regs[2].to64(), |
| | 8168 | Immediate.u(shift_imm & std.math.maxInt(u6)), |
| | 8169 | ), |
| | 8170 | else => try self.asmRegisterRegister(tag, temp_regs[2].to64(), .cl), |
| | 8171 | } |
| | 8172 | try self.asmMemoryRegister(.{ ._, .mov }, .{ |
| | 8173 | .base = .{ .frame = lhs_mcv.load_frame.index }, |
| | 8174 | .mod = .{ .rm = .{ |
| | 8175 | .size = .qword, |
| | 8176 | .index = temp_regs[1].to64(), |
| | 8177 | .scale = .@"8", |
| | 8178 | .disp = lhs_mcv.load_frame.off, |
| | 8179 | } }, |
| | 8180 | }, temp_regs[2].to64()); |
| | 8181 | if (tag[0] == ._r and tag[1] == .sa) try self.asmRegisterImmediate( |
| | 8182 | tag, |
| | 8183 | temp_regs[2].to64(), |
| | 8184 | Immediate.u(63), |
| | 8185 | ); |
| | 8186 | if (switch (rhs_mcv) { |
| | 8187 | .immediate => |shift_imm| shift_imm >> 6 > 0, |
| | 8188 | else => true, |
| | 8189 | }) { |
| | 8190 | const skip = switch (rhs_mcv) { |
| | 8191 | .immediate => undefined, |
| | 8192 | else => switch (tag[0]) { |
| | 8193 | ._l => skip: { |
| | 8194 | try self.asmRegisterRegister( |
| | 8195 | .{ ._, .@"test" }, |
| | 8196 | temp_regs[1].to32(), |
| | 8197 | temp_regs[1].to32(), |
| | 8198 | ); |
| | 8199 | break :skip try self.asmJccReloc(.z, undefined); |
| | 8200 | }, |
| | 8201 | ._r => skip: { |
| | 8202 | try self.asmRegisterImmediate( |
| | 8203 | .{ ._, .cmp }, |
| | 8204 | temp_regs[1].to32(), |
| | 8205 | Immediate.u(limbs_len - 1), |
| | 8206 | ); |
| | 8207 | break :skip try self.asmJccReloc(.nb, undefined); |
| | 8208 | }, |
| | 8209 | else => unreachable, |
| | 8210 | }, |
| | 8211 | }; |
| | 8212 | const loop: Mir.Inst.Index = @intCast(self.mir_instructions.len); |
| | 8213 | switch (tag[0]) { |
| | 8214 | ._l => if (slow_inc_dec) { |
| | 8215 | try self.asmRegisterImmediate(.{ ._, .sub }, temp_regs[1].to32(), Immediate.u(1)); |
| | 8216 | } else { |
| | 8217 | try self.asmRegister(.{ ._, .dec }, temp_regs[1].to32()); |
| | 8218 | }, |
| | 8219 | ._r => if (slow_inc_dec) { |
| | 8220 | try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[1].to32(), Immediate.u(1)); |
| | 8221 | } else { |
| | 8222 | try self.asmRegister(.{ ._, .inc }, temp_regs[1].to32()); |
| | 8223 | }, |
| | 8224 | else => unreachable, |
| | 8225 | } |
| | 8226 | if (tag[0] == ._r and tag[1] == .sa) try self.asmMemoryRegister(.{ ._, .mov }, .{ |
| | 8227 | .base = .{ .frame = lhs_mcv.load_frame.index }, |
| | 8228 | .mod = .{ .rm = .{ |
| | 8229 | .size = .qword, |
| | 8230 | .index = temp_regs[1].to64(), |
| | 8231 | .scale = .@"8", |
| | 8232 | .disp = lhs_mcv.load_frame.off, |
| | 8233 | } }, |
| | 8234 | }, temp_regs[2].to64()) else try self.asmMemoryImmediate(.{ ._, .mov }, .{ |
| | 8235 | .base = .{ .frame = lhs_mcv.load_frame.index }, |
| | 8236 | .mod = .{ .rm = .{ |
| | 8237 | .size = .qword, |
| | 8238 | .index = temp_regs[1].to64(), |
| | 8239 | .scale = .@"8", |
| | 8240 | .disp = lhs_mcv.load_frame.off, |
| | 8241 | } }, |
| | 8242 | }, Immediate.u(0)); |
| | 8243 | switch (tag[0]) { |
| | 8244 | ._l => _ = try self.asmJccReloc(.nz, loop), |
| | 8245 | ._r => { |
| | 8246 | try self.asmRegisterImmediate( |
| | 8247 | .{ ._, .cmp }, |
| | 8248 | temp_regs[1].to32(), |
| | 8249 | Immediate.u(limbs_len - 1), |
| | 8250 | ); |
| | 8251 | _ = try self.asmJccReloc(.b, loop); |
| | 8252 | }, |
| | 8253 | else => unreachable, |
| | 8254 | } |
| | 8255 | switch (rhs_mcv) { |
| | 8256 | .immediate => {}, |
| | 8257 | else => self.performReloc(skip), |
| | 8258 | } |
| | 8259 | } |
| | 8260 | return; |
| | 8261 | } |
| | 8262 | |
| | 8263 | assert(shift_abi_size == 1); |
| | 8264 | const shift_mcv: MCValue = shift: { |
| | 8265 | switch (rhs_mcv) { |
| | 8266 | .immediate => |shift_imm| switch (shift_imm) { |
| | 8267 | 0 => return, |
| | 8268 | else => break :shift rhs_mcv, |
| 7976 | }, | 8269 | }, |
| 7977 | else => return self.fail("TODO genShiftBinOpMir between {s} and {s}", .{ | 8270 | .register => |rhs_reg| if (rhs_reg.id() == Register.rcx.id()) |
| 7978 | @tagName(lhs_mcv), | 8271 | break :shift rhs_mcv, |
| 7979 | @tagName(rhs_mcv), | 8272 | else => {}, |
| 7980 | }), | | |
| 7981 | } | 8273 | } |
| 7982 | } else if (abi_size <= 16) { | 8274 | self.register_manager.getRegAssumeFree(.rcx, null); |
| | 8275 | try self.genSetReg(.cl, rhs_ty, rhs_mcv, .{}); |
| | 8276 | break :shift .{ .register = .rcx }; |
| | 8277 | }; |
| | 8278 | if (abi_size > 8) { |
| 7983 | const info: struct { indices: [2]u31, double_tag: Mir.Inst.FixedTag } = switch (tag[0]) { | 8279 | const info: struct { indices: [2]u31, double_tag: Mir.Inst.FixedTag } = switch (tag[0]) { |
| 7984 | ._l => .{ .indices = .{ 0, 1 }, .double_tag = .{ ._ld, .sh } }, | 8280 | ._l => .{ .indices = .{ 0, 1 }, .double_tag = .{ ._ld, .sh } }, |
| 7985 | ._r => .{ .indices = .{ 1, 0 }, .double_tag = .{ ._rd, .sh } }, | 8281 | ._r => .{ .indices = .{ 1, 0 }, .double_tag = .{ ._rd, .sh } }, |
| 7986 | else => unreachable, | 8282 | else => unreachable, |
| 7987 | }; | 8283 | }; |
| 7988 | switch (lhs_mcv) { | 8284 | switch (lhs_mcv) { |
| 7989 | .register_pair => |lhs_regs| switch (rhs_mcv) { | 8285 | .register_pair => |lhs_regs| switch (shift_mcv) { |
| 7990 | .immediate => |rhs_imm| if (rhs_imm > 0 and rhs_imm < 64) { | 8286 | .immediate => |shift_imm| if (shift_imm > 0 and shift_imm < 64) { |
| 7991 | try self.asmRegisterRegisterImmediate( | 8287 | try self.asmRegisterRegisterImmediate( |
| 7992 | info.double_tag, | 8288 | info.double_tag, |
| 7993 | lhs_regs[info.indices[1]], | 8289 | lhs_regs[info.indices[1]], |
| 7994 | lhs_regs[info.indices[0]], | 8290 | lhs_regs[info.indices[0]], |
| 7995 | Immediate.u(rhs_imm), | 8291 | Immediate.u(shift_imm), |
| 7996 | ); | 8292 | ); |
| 7997 | try self.asmRegisterImmediate( | 8293 | try self.asmRegisterImmediate( |
| 7998 | tag, | 8294 | tag, |
| 7999 | lhs_regs[info.indices[0]], | 8295 | lhs_regs[info.indices[0]], |
| 8000 | Immediate.u(rhs_imm), | 8296 | Immediate.u(shift_imm), |
| 8001 | ); | 8297 | ); |
| | 8298 | return; |
| 8002 | } else { | 8299 | } else { |
| 8003 | assert(rhs_imm < 128); | 8300 | assert(shift_imm < 128); |
| 8004 | try self.asmRegisterRegister( | 8301 | try self.asmRegisterRegister( |
| 8005 | .{ ._, .mov }, | 8302 | .{ ._, .mov }, |
| 8006 | lhs_regs[info.indices[1]], | 8303 | lhs_regs[info.indices[1]], |
| ... | @@ -8015,13 +8312,14 @@ fn genShiftBinOpMir( | ... | @@ -8015,13 +8312,14 @@ fn genShiftBinOpMir( |
| 8015 | lhs_regs[info.indices[0]], | 8312 | lhs_regs[info.indices[0]], |
| 8016 | lhs_regs[info.indices[0]], | 8313 | lhs_regs[info.indices[0]], |
| 8017 | ); | 8314 | ); |
| 8018 | if (rhs_imm > 64) try self.asmRegisterImmediate( | 8315 | if (shift_imm > 64) try self.asmRegisterImmediate( |
| 8019 | tag, | 8316 | tag, |
| 8020 | lhs_regs[info.indices[1]], | 8317 | lhs_regs[info.indices[1]], |
| 8021 | Immediate.u(rhs_imm - 64), | 8318 | Immediate.u(shift_imm - 64), |
| 8022 | ); | 8319 | ); |
| | 8320 | return; |
| 8023 | }, | 8321 | }, |
| 8024 | .register => |rhs_reg| { | 8322 | .register => |shift_reg| { |
| 8025 | const tmp_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); | 8323 | const tmp_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); |
| 8026 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | 8324 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 8027 | defer self.register_manager.unlockReg(tmp_lock); | 8325 | defer self.register_manager.unlockReg(tmp_lock); |
| ... | @@ -8038,16 +8336,16 @@ fn genShiftBinOpMir( | ... | @@ -8038,16 +8336,16 @@ fn genShiftBinOpMir( |
| 8038 | info.double_tag, | 8336 | info.double_tag, |
| 8039 | lhs_regs[info.indices[1]], | 8337 | lhs_regs[info.indices[1]], |
| 8040 | lhs_regs[info.indices[0]], | 8338 | lhs_regs[info.indices[0]], |
| 8041 | registerAlias(rhs_reg, 1), | 8339 | registerAlias(shift_reg, 1), |
| 8042 | ); | 8340 | ); |
| 8043 | try self.asmRegisterRegister( | 8341 | try self.asmRegisterRegister( |
| 8044 | tag, | 8342 | tag, |
| 8045 | lhs_regs[info.indices[0]], | 8343 | lhs_regs[info.indices[0]], |
| 8046 | registerAlias(rhs_reg, 1), | 8344 | registerAlias(shift_reg, 1), |
| 8047 | ); | 8345 | ); |
| 8048 | try self.asmRegisterImmediate( | 8346 | try self.asmRegisterImmediate( |
| 8049 | .{ ._, .cmp }, | 8347 | .{ ._, .cmp }, |
| 8050 | registerAlias(rhs_reg, 1), | 8348 | registerAlias(shift_reg, 1), |
| 8051 | Immediate.u(64), | 8349 | Immediate.u(64), |
| 8052 | ); | 8350 | ); |
| 8053 | try self.asmCmovccRegisterRegister( | 8351 | try self.asmCmovccRegisterRegister( |
| ... | @@ -8056,19 +8354,17 @@ fn genShiftBinOpMir( | ... | @@ -8056,19 +8354,17 @@ fn genShiftBinOpMir( |
| 8056 | lhs_regs[info.indices[0]], | 8354 | lhs_regs[info.indices[0]], |
| 8057 | ); | 8355 | ); |
| 8058 | try self.asmCmovccRegisterRegister(.ae, lhs_regs[info.indices[0]], tmp_reg); | 8356 | try self.asmCmovccRegisterRegister(.ae, lhs_regs[info.indices[0]], tmp_reg); |
| | 8357 | return; |
| 8059 | }, | 8358 | }, |
| 8060 | else => return self.fail("TODO genShiftBinOpMir between {s} and {s}", .{ | 8359 | else => {}, |
| 8061 | @tagName(lhs_mcv), | | |
| 8062 | @tagName(rhs_mcv), | | |
| 8063 | }), | | |
| 8064 | }, | 8360 | }, |
| 8065 | .load_frame => |dst_frame_addr| { | 8361 | .load_frame => |dst_frame_addr| { |
| 8066 | const tmp_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); | 8362 | const tmp_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); |
| 8067 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | 8363 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 8068 | defer self.register_manager.unlockReg(tmp_lock); | 8364 | defer self.register_manager.unlockReg(tmp_lock); |
| 8069 | | 8365 | |
| 8070 | switch (rhs_mcv) { | 8366 | switch (shift_mcv) { |
| 8071 | .immediate => |rhs_imm| if (rhs_imm > 0 and rhs_imm < 64) { | 8367 | .immediate => |shift_imm| if (shift_imm > 0 and shift_imm < 64) { |
| 8072 | try self.asmRegisterMemory( | 8368 | try self.asmRegisterMemory( |
| 8073 | .{ ._, .mov }, | 8369 | .{ ._, .mov }, |
| 8074 | tmp_reg, | 8370 | tmp_reg, |
| ... | @@ -8090,7 +8386,7 @@ fn genShiftBinOpMir( | ... | @@ -8090,7 +8386,7 @@ fn genShiftBinOpMir( |
| 8090 | } }, | 8386 | } }, |
| 8091 | }, | 8387 | }, |
| 8092 | tmp_reg, | 8388 | tmp_reg, |
| 8093 | Immediate.u(rhs_imm), | 8389 | Immediate.u(shift_imm), |
| 8094 | ); | 8390 | ); |
| 8095 | try self.asmMemoryImmediate( | 8391 | try self.asmMemoryImmediate( |
| 8096 | tag, | 8392 | tag, |
| ... | @@ -8101,10 +8397,11 @@ fn genShiftBinOpMir( | ... | @@ -8101,10 +8397,11 @@ fn genShiftBinOpMir( |
| 8101 | .disp = dst_frame_addr.off + info.indices[0] * 8, | 8397 | .disp = dst_frame_addr.off + info.indices[0] * 8, |
| 8102 | } }, | 8398 | } }, |
| 8103 | }, | 8399 | }, |
| 8104 | Immediate.u(rhs_imm), | 8400 | Immediate.u(shift_imm), |
| 8105 | ); | 8401 | ); |
| | 8402 | return; |
| 8106 | } else { | 8403 | } else { |
| 8107 | assert(rhs_imm < 128); | 8404 | assert(shift_imm < 128); |
| 8108 | try self.asmRegisterMemory( | 8405 | try self.asmRegisterMemory( |
| 8109 | .{ ._, .mov }, | 8406 | .{ ._, .mov }, |
| 8110 | tmp_reg, | 8407 | tmp_reg, |
| ... | @@ -8116,10 +8413,10 @@ fn genShiftBinOpMir( | ... | @@ -8116,10 +8413,10 @@ fn genShiftBinOpMir( |
| 8116 | } }, | 8413 | } }, |
| 8117 | }, | 8414 | }, |
| 8118 | ); | 8415 | ); |
| 8119 | if (rhs_imm > 64) try self.asmRegisterImmediate( | 8416 | if (shift_imm > 64) try self.asmRegisterImmediate( |
| 8120 | tag, | 8417 | tag, |
| 8121 | tmp_reg, | 8418 | tmp_reg, |
| 8122 | Immediate.u(rhs_imm - 64), | 8419 | Immediate.u(shift_imm - 64), |
| 8123 | ); | 8420 | ); |
| 8124 | try self.asmMemoryRegister( | 8421 | try self.asmMemoryRegister( |
| 8125 | .{ ._, .mov }, | 8422 | .{ ._, .mov }, |
| ... | @@ -8156,8 +8453,9 @@ fn genShiftBinOpMir( | ... | @@ -8156,8 +8453,9 @@ fn genShiftBinOpMir( |
| 8156 | tmp_reg, | 8453 | tmp_reg, |
| 8157 | ); | 8454 | ); |
| 8158 | } | 8455 | } |
| | 8456 | return; |
| 8159 | }, | 8457 | }, |
| 8160 | .register => |rhs_reg| { | 8458 | .register => |shift_reg| { |
| 8161 | const first_reg = | 8459 | const first_reg = |
| 8162 | try self.register_manager.allocReg(null, abi.RegisterClass.gp); | 8460 | try self.register_manager.allocReg(null, abi.RegisterClass.gp); |
| 8163 | const first_lock = self.register_manager.lockRegAssumeUnused(first_reg); | 8461 | const first_lock = self.register_manager.lockRegAssumeUnused(first_reg); |
| ... | @@ -8202,12 +8500,12 @@ fn genShiftBinOpMir( | ... | @@ -8202,12 +8500,12 @@ fn genShiftBinOpMir( |
| 8202 | info.double_tag, | 8500 | info.double_tag, |
| 8203 | second_reg, | 8501 | second_reg, |
| 8204 | first_reg, | 8502 | first_reg, |
| 8205 | registerAlias(rhs_reg, 1), | 8503 | registerAlias(shift_reg, 1), |
| 8206 | ); | 8504 | ); |
| 8207 | try self.asmRegisterRegister(tag, first_reg, registerAlias(rhs_reg, 1)); | 8505 | try self.asmRegisterRegister(tag, first_reg, registerAlias(shift_reg, 1)); |
| 8208 | try self.asmRegisterImmediate( | 8506 | try self.asmRegisterImmediate( |
| 8209 | .{ ._, .cmp }, | 8507 | .{ ._, .cmp }, |
| 8210 | registerAlias(rhs_reg, 1), | 8508 | registerAlias(shift_reg, 1), |
| 8211 | Immediate.u(64), | 8509 | Immediate.u(64), |
| 8212 | ); | 8510 | ); |
| 8213 | try self.asmCmovccRegisterRegister(.ae, second_reg, first_reg); | 8511 | try self.asmCmovccRegisterRegister(.ae, second_reg, first_reg); |
| ... | @@ -8234,21 +8532,75 @@ fn genShiftBinOpMir( | ... | @@ -8234,21 +8532,75 @@ fn genShiftBinOpMir( |
| 8234 | }, | 8532 | }, |
| 8235 | first_reg, | 8533 | first_reg, |
| 8236 | ); | 8534 | ); |
| | 8535 | return; |
| 8237 | }, | 8536 | }, |
| 8238 | else => return self.fail("TODO genShiftBinOpMir between {s} and {s}", .{ | 8537 | else => {}, |
| 8239 | @tagName(lhs_mcv), | | |
| 8240 | @tagName(rhs_mcv), | | |
| 8241 | }), | | |
| 8242 | } | 8538 | } |
| 8243 | }, | 8539 | }, |
| 8244 | else => return self.fail("TODO genShiftBinOpMir between {s} and {s}", .{ | 8540 | else => {}, |
| 8245 | @tagName(lhs_mcv), | | |
| 8246 | @tagName(rhs_mcv), | | |
| 8247 | }), | | |
| 8248 | } | 8541 | } |
| 8249 | } else return self.fail("TODO genShiftBinOpMir between {s} and {s}", .{ | 8542 | } else switch (lhs_mcv) { |
| | 8543 | .register => |lhs_reg| switch (shift_mcv) { |
| | 8544 | .immediate => |shift_imm| return self.asmRegisterImmediate( |
| | 8545 | tag, |
| | 8546 | registerAlias(lhs_reg, abi_size), |
| | 8547 | Immediate.u(shift_imm), |
| | 8548 | ), |
| | 8549 | .register => |shift_reg| return self.asmRegisterRegister( |
| | 8550 | tag, |
| | 8551 | registerAlias(lhs_reg, abi_size), |
| | 8552 | registerAlias(shift_reg, 1), |
| | 8553 | ), |
| | 8554 | else => {}, |
| | 8555 | }, |
| | 8556 | .memory, .indirect, .load_frame => { |
| | 8557 | const lhs_mem: Memory = switch (lhs_mcv) { |
| | 8558 | .memory => |addr| .{ |
| | 8559 | .base = .{ .reg = .ds }, |
| | 8560 | .mod = .{ .rm = .{ |
| | 8561 | .size = Memory.Size.fromSize(abi_size), |
| | 8562 | .disp = math.cast(i32, @as(i64, @bitCast(addr))) orelse |
| | 8563 | return self.fail("TODO genShiftBinOpMir between {s} and {s}", .{ |
| | 8564 | @tagName(lhs_mcv), |
| | 8565 | @tagName(shift_mcv), |
| | 8566 | }), |
| | 8567 | } }, |
| | 8568 | }, |
| | 8569 | .indirect => |reg_off| .{ |
| | 8570 | .base = .{ .reg = reg_off.reg }, |
| | 8571 | .mod = .{ .rm = .{ |
| | 8572 | .size = Memory.Size.fromSize(abi_size), |
| | 8573 | .disp = reg_off.off, |
| | 8574 | } }, |
| | 8575 | }, |
| | 8576 | .load_frame => |frame_addr| .{ |
| | 8577 | .base = .{ .frame = frame_addr.index }, |
| | 8578 | .mod = .{ .rm = .{ |
| | 8579 | .size = Memory.Size.fromSize(abi_size), |
| | 8580 | .disp = frame_addr.off, |
| | 8581 | } }, |
| | 8582 | }, |
| | 8583 | else => unreachable, |
| | 8584 | }; |
| | 8585 | switch (shift_mcv) { |
| | 8586 | .immediate => |shift_imm| return self.asmMemoryImmediate( |
| | 8587 | tag, |
| | 8588 | lhs_mem, |
| | 8589 | Immediate.u(shift_imm), |
| | 8590 | ), |
| | 8591 | .register => |shift_reg| return self.asmMemoryRegister( |
| | 8592 | tag, |
| | 8593 | lhs_mem, |
| | 8594 | registerAlias(shift_reg, 1), |
| | 8595 | ), |
| | 8596 | else => {}, |
| | 8597 | } |
| | 8598 | }, |
| | 8599 | else => {}, |
| | 8600 | } |
| | 8601 | return self.fail("TODO genShiftBinOpMir between {s} and {s}", .{ |
| 8250 | @tagName(lhs_mcv), | 8602 | @tagName(lhs_mcv), |
| 8251 | @tagName(rhs_mcv), | 8603 | @tagName(shift_mcv), |
| 8252 | }); | 8604 | }); |
| 8253 | } | 8605 | } |
| 8254 | | 8606 | |
| ... | @@ -8269,14 +8621,6 @@ fn genShiftBinOp( | ... | @@ -8269,14 +8621,6 @@ fn genShiftBinOp( |
| 8269 | lhs_ty.fmt(mod), | 8621 | lhs_ty.fmt(mod), |
| 8270 | }); | 8622 | }); |
| 8271 | | 8623 | |
| 8272 | try self.spillEflagsIfOccupied(); | | |
| 8273 | | | |
| 8274 | const lhs_abi_size = lhs_ty.abiSize(mod); | | |
| 8275 | if (lhs_abi_size > 16) return self.fail("TODO implement genShiftBinOp for {}", .{ | | |
| 8276 | lhs_ty.fmt(mod), | | |
| 8277 | }); | | |
| 8278 | assert(rhs_ty.abiSize(mod) == 1); | | |
| 8279 | | | |
| 8280 | try self.register_manager.getReg(.rcx, null); | 8624 | try self.register_manager.getReg(.rcx, null); |
| 8281 | const rcx_lock = self.register_manager.lockReg(.rcx); | 8625 | const rcx_lock = self.register_manager.lockReg(.rcx); |
| 8282 | defer if (rcx_lock) |lock| self.register_manager.unlockReg(lock); | 8626 | defer if (rcx_lock) |lock| self.register_manager.unlockReg(lock); |
| ... | @@ -8314,7 +8658,7 @@ fn genShiftBinOp( | ... | @@ -8314,7 +8658,7 @@ fn genShiftBinOp( |
| 8314 | .unsigned => .{ ._r, .sh }, | 8658 | .unsigned => .{ ._r, .sh }, |
| 8315 | }, | 8659 | }, |
| 8316 | else => unreachable, | 8660 | else => unreachable, |
| 8317 | }, lhs_ty, dst_mcv, rhs_mcv); | 8661 | }, lhs_ty, dst_mcv, rhs_ty, rhs_mcv); |
| 8318 | return dst_mcv; | 8662 | return dst_mcv; |
| 8319 | } | 8663 | } |
| 8320 | | 8664 | |
| ... | @@ -8446,6 +8790,7 @@ fn genMulDivBinOp( | ... | @@ -8446,6 +8790,7 @@ fn genMulDivBinOp( |
| 8446 | .size = .qword, | 8790 | .size = .qword, |
| 8447 | .index = temp_regs[0].to64(), | 8791 | .index = temp_regs[0].to64(), |
| 8448 | .scale = .@"8", | 8792 | .scale = .@"8", |
| | 8793 | .disp = rhs_mcv.load_frame.off, |
| 8449 | } }, | 8794 | } }, |
| 8450 | }); | 8795 | }); |
| 8451 | try self.asmRegisterRegister(.{ ._, .@"test" }, temp_regs[1].to64(), temp_regs[1].to64()); | 8796 | try self.asmRegisterRegister(.{ ._, .@"test" }, temp_regs[1].to64(), temp_regs[1].to64()); |
| ... | @@ -8464,6 +8809,7 @@ fn genMulDivBinOp( | ... | @@ -8464,6 +8809,7 @@ fn genMulDivBinOp( |
| 8464 | .size = .qword, | 8809 | .size = .qword, |
| 8465 | .index = temp_regs[3].to64(), | 8810 | .index = temp_regs[3].to64(), |
| 8466 | .scale = .@"8", | 8811 | .scale = .@"8", |
| | 8812 | .disp = dst_mcv.load_frame.off, |
| 8467 | } }, | 8813 | } }, |
| 8468 | }, .rdx); | 8814 | }, .rdx); |
| 8469 | try self.asmSetccRegister(.c, .cl); | 8815 | try self.asmSetccRegister(.c, .cl); |
| ... | @@ -8474,6 +8820,7 @@ fn genMulDivBinOp( | ... | @@ -8474,6 +8820,7 @@ fn genMulDivBinOp( |
| 8474 | .size = .qword, | 8820 | .size = .qword, |
| 8475 | .index = temp_regs[2].to64(), | 8821 | .index = temp_regs[2].to64(), |
| 8476 | .scale = .@"8", | 8822 | .scale = .@"8", |
| | 8823 | .disp = lhs_mcv.load_frame.off, |
| 8477 | } }, | 8824 | } }, |
| 8478 | }); | 8825 | }); |
| 8479 | try self.asmRegister(.{ ._, .mul }, temp_regs[1].to64()); | 8826 | try self.asmRegister(.{ ._, .mul }, temp_regs[1].to64()); |
| ... | @@ -8485,6 +8832,7 @@ fn genMulDivBinOp( | ... | @@ -8485,6 +8832,7 @@ fn genMulDivBinOp( |
| 8485 | .size = .qword, | 8832 | .size = .qword, |
| 8486 | .index = temp_regs[3].to64(), | 8833 | .index = temp_regs[3].to64(), |
| 8487 | .scale = .@"8", | 8834 | .scale = .@"8", |
| | 8835 | .disp = dst_mcv.load_frame.off, |
| 8488 | } }, | 8836 | } }, |
| 8489 | }, .rax); | 8837 | }, .rax); |
| 8490 | try self.asmSetccRegister(.c, .ch); | 8838 | try self.asmSetccRegister(.c, .ch); |
| ... | @@ -8757,6 +9105,7 @@ fn genBinOp( | ... | @@ -8757,6 +9105,7 @@ fn genBinOp( |
| 8757 | .div_float, | 9105 | .div_float, |
| 8758 | .div_trunc, | 9106 | .div_trunc, |
| 8759 | .div_floor, | 9107 | .div_floor, |
| | 9108 | .div_exact, |
| 8760 | => std.fmt.bufPrint(&callee_buf, "__{s}{c}f3", .{ | 9109 | => std.fmt.bufPrint(&callee_buf, "__{s}{c}f3", .{ |
| 8761 | @tagName(air_tag)[0..3], | 9110 | @tagName(air_tag)[0..3], |
| 8762 | floatCompilerRtAbiName(float_bits), | 9111 | floatCompilerRtAbiName(float_bits), |
| ... | @@ -8910,7 +9259,7 @@ fn genBinOp( | ... | @@ -8910,7 +9259,7 @@ fn genBinOp( |
| 8910 | else => false, | 9259 | else => false, |
| 8911 | .Float => true, | 9260 | .Float => true, |
| 8912 | .Vector => switch (lhs_ty.childType(mod).toIntern()) { | 9261 | .Vector => switch (lhs_ty.childType(mod).toIntern()) { |
| 8913 | .bool_type => false, | 9262 | .bool_type, .u1_type => false, |
| 8914 | else => true, | 9263 | else => true, |
| 8915 | }, | 9264 | }, |
| 8916 | }; | 9265 | }; |
| ... | @@ -12443,6 +12792,7 @@ fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, eu_ty: Type, eu_mcv: MCValue) | ... | @@ -12443,6 +12792,7 @@ fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, eu_ty: Type, eu_mcv: MCValue) |
| 12443 | .{ ._r, .sh }, | 12792 | .{ ._r, .sh }, |
| 12444 | eu_ty, | 12793 | eu_ty, |
| 12445 | .{ .register = tmp_reg }, | 12794 | .{ .register = tmp_reg }, |
| | 12795 | Type.u8, |
| 12446 | .{ .immediate = @as(u6, @intCast(err_off * 8)) }, | 12796 | .{ .immediate = @as(u6, @intCast(err_off * 8)) }, |
| 12447 | ); | 12797 | ); |
| 12448 | } else { | 12798 | } else { |
| ... | @@ -16174,6 +16524,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -16174,6 +16524,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 16174 | .{ ._l, .sh }, | 16524 | .{ ._l, .sh }, |
| 16175 | elem_ty, | 16525 | elem_ty, |
| 16176 | .{ .register = elem_reg }, | 16526 | .{ .register = elem_reg }, |
| | 16527 | Type.u8, |
| 16177 | .{ .immediate = elem_bit_off }, | 16528 | .{ .immediate = elem_bit_off }, |
| 16178 | ); | 16529 | ); |
| 16179 | try self.genBinOpMir( | 16530 | try self.genBinOpMir( |
| ... | @@ -16191,6 +16542,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -16191,6 +16542,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 16191 | .{ ._r, .sh }, | 16542 | .{ ._r, .sh }, |
| 16192 | elem_ty, | 16543 | elem_ty, |
| 16193 | .{ .register = reg }, | 16544 | .{ .register = reg }, |
| | 16545 | Type.u8, |
| 16194 | .{ .immediate = elem_abi_bits - elem_bit_off }, | 16546 | .{ .immediate = elem_abi_bits - elem_bit_off }, |
| 16195 | ); | 16547 | ); |
| 16196 | try self.genBinOpMir( | 16548 | try self.genBinOpMir( |
| ... | @@ -17294,12 +17646,14 @@ fn truncateRegister(self: *Self, ty: Type, reg: Register) !void { | ... | @@ -17294,12 +17646,14 @@ fn truncateRegister(self: *Self, ty: Type, reg: Register) !void { |
| 17294 | .{ ._l, .sa }, | 17646 | .{ ._l, .sa }, |
| 17295 | Type.isize, | 17647 | Type.isize, |
| 17296 | .{ .register = reg }, | 17648 | .{ .register = reg }, |
| | 17649 | Type.u8, |
| 17297 | .{ .immediate = shift }, | 17650 | .{ .immediate = shift }, |
| 17298 | ); | 17651 | ); |
| 17299 | try self.genShiftBinOpMir( | 17652 | try self.genShiftBinOpMir( |
| 17300 | .{ ._r, .sa }, | 17653 | .{ ._r, .sa }, |
| 17301 | Type.isize, | 17654 | Type.isize, |
| 17302 | .{ .register = reg }, | 17655 | .{ .register = reg }, |
| | 17656 | Type.u8, |
| 17303 | .{ .immediate = shift }, | 17657 | .{ .immediate = shift }, |
| 17304 | ); | 17658 | ); |
| 17305 | }, | 17659 | }, |