authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-06-02 01:18:21-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-06-02 22:45:15-04:00
log2543e2d97c323fb4ec04e134005267252a2c96ed
tree53809392f591e2b29e5a43dcb44085e5d2bfbe61
parentf4f4460e178d13e62cc0031ef5a51a524101b9a0

x86_64: implement integer `@divFloor` and `@mod`

Closes #24039

7 files changed, 1024 insertions(+), 214 deletions(-)

src/arch/x86_64/CodeGen.zig+987-188
......@@ -47,10 +47,11 @@ pub fn legalizeFeatures(target: *const std.Target) *const Air.Legalize.Features
4747 .scalarize_div_float_optimized = use_old,
4848 .scalarize_div_trunc = use_old,
4949 .scalarize_div_trunc_optimized = use_old,
50 .scalarize_div_floor = use_old,
50 .scalarize_div_floor = true,
5151 .scalarize_div_floor_optimized = use_old,
5252 .scalarize_div_exact = use_old,
5353 .scalarize_div_exact_optimized = use_old,
54 .scalarize_mod = true,
5455 .scalarize_max = use_old,
5556 .scalarize_min = use_old,
5657 .scalarize_add_with_overflow = true,
......@@ -690,7 +691,7 @@ const InstTracking = struct {
690691 }
691692 tracking_log.debug("spill {} from {} to {}", .{ inst, self.short, self.long });
692693 try cg.genCopy(cg.typeOfIndex(inst), self.long, self.short, .{});
693 for (self.short.getRegs()) |reg| if (reg.class() == .x87) try cg.asmRegister(.{ .f_, .free }, reg);
694 for (self.short.getRegs()) |reg| if (reg.isClass(.x87)) try cg.asmRegister(.{ .f_, .free }, reg);
694695 }
695696
696697 fn reuseFrame(self: *InstTracking) void {
......@@ -2468,7 +2469,7 @@ fn genBodyBlock(self: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
24682469}
24692470
24702471fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2471 @setEvalBranchQuota(28_600);
2472 @setEvalBranchQuota(28_700);
24722473 const pt = cg.pt;
24732474 const zcu = pt.zcu;
24742475 const ip = &zcu.intern_pool;
......@@ -35458,12 +35459,249 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3545835459 };
3545935460 try res[0].finish(inst, &.{ bin_op.lhs, bin_op.rhs }, &ops, cg);
3546035461 },
35461 .div_floor => |air_tag| if (use_old) try cg.airMulDivBinOp(inst, air_tag) else fallback: {
35462 .div_floor => |air_tag| if (use_old) try cg.airMulDivBinOp(inst, air_tag) else {
3546235463 const bin_op = air_datas[@intFromEnum(inst)].bin_op;
35463 if (cg.floatBits(cg.typeOf(bin_op.lhs).scalarType(zcu)) == null) break :fallback try cg.airMulDivBinOp(inst, air_tag);
35464 const ty = cg.typeOf(bin_op.lhs);
3546435465 var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs });
3546535466 var res: [1]Temp = undefined;
35466 cg.select(&res, &.{cg.typeOf(bin_op.lhs)}, &ops, comptime &.{ .{
35467 (if (cg.intInfo(ty)) |int_info| err: switch (int_info.signedness) {
35468 .signed => cg.select(&res, &.{ty}, &ops, comptime &.{ .{
35469 .src_constraints = .{ .{ .exact_signed_int = 1 }, .{ .exact_signed_int = 1 }, .any },
35470 .patterns = &.{
35471 .{ .src = .{ .any, .any, .none } },
35472 },
35473 .dst_temps = .{ .{ .imm = 0 }, .unused },
35474 .each = .{ .once = &.{} },
35475 }, .{
35476 .src_constraints = .{ .{ .signed_int = .byte }, .{ .signed_int = .byte }, .any },
35477 .patterns = &.{
35478 .{ .src = .{ .mem, .to_mut_gphi, .none } },
35479 .{ .src = .{ .to_gpr, .to_mut_gphi, .none } },
35480 },
35481 .dst_temps = .{ .{ .reg = .al }, .unused },
35482 .clobbers = .{ .eflags = true },
35483 .each = .{ .once = &.{
35484 .{ ._, ._, .movsx, .dst0d, .src0b, ._, ._ },
35485 .{ ._, .i_, .div, .src1b, ._, ._, ._ },
35486 .{ ._, ._, .@"and", .src1b, .sa(.src0, .add_smin), ._, ._ },
35487 .{ ._, ._, .xor, .src1b, .dst0h, ._, ._ },
35488 .{ ._, ._, .cmp, .src1b, .sia(1, .src0, .add_smin), ._, ._ },
35489 .{ ._, ._, .adc, .dst0b, .si(-1), ._, ._ },
35490 } },
35491 }, .{
35492 .required_features = .{ .fast_imm16, null, null, null },
35493 .src_constraints = .{ .{ .signed_int = .word }, .{ .signed_int = .word }, .any },
35494 .patterns = &.{
35495 .{ .src = .{ .{ .to_reg = .ax }, .to_mut_gpr, .none } },
35496 },
35497 .extra_temps = .{
35498 .{ .type = .i16, .kind = .{ .reg = .dx } },
35499 .unused,
35500 .unused,
35501 .unused,
35502 .unused,
35503 .unused,
35504 .unused,
35505 .unused,
35506 .unused,
35507 .unused,
35508 .unused,
35509 },
35510 .dst_temps = .{ .{ .ref = .src0 }, .unused },
35511 .clobbers = .{ .eflags = true },
35512 .each = .{ .once = &.{
35513 .{ ._, ._, .cwd, ._, ._, ._, ._ },
35514 .{ ._, .i_, .div, .src1w, ._, ._, ._ },
35515 .{ ._, ._, .@"and", .src1w, .sa(.src0, .add_smin), ._, ._ },
35516 .{ ._, ._, .xor, .src1d, .tmp0d, ._, ._ },
35517 .{ ._, ._, .cmp, .src1w, .sia(1, .src0, .add_smin), ._, ._ },
35518 .{ ._, ._, .adc, .dst0d, .si(-1), ._, ._ },
35519 } },
35520 }, .{
35521 .src_constraints = .{ .{ .signed_int = .word }, .{ .signed_int = .word }, .any },
35522 .patterns = &.{
35523 .{ .src = .{ .{ .to_reg = .ax }, .to_mut_gpr, .none } },
35524 },
35525 .extra_temps = .{
35526 .{ .type = .i16, .kind = .{ .reg = .dx } },
35527 .unused,
35528 .unused,
35529 .unused,
35530 .unused,
35531 .unused,
35532 .unused,
35533 .unused,
35534 .unused,
35535 .unused,
35536 .unused,
35537 },
35538 .dst_temps = .{ .{ .ref = .src0 }, .unused },
35539 .clobbers = .{ .eflags = true },
35540 .each = .{ .once = &.{
35541 .{ ._, ._, .cwd, ._, ._, ._, ._ },
35542 .{ ._, .i_, .div, .src1w, ._, ._, ._ },
35543 .{ ._, ._, .@"and", .src1d, .sa(.src0, .add_smin), ._, ._ },
35544 .{ ._, ._, .xor, .src1d, .tmp0d, ._, ._ },
35545 .{ ._, ._, .cmp, .src1w, .sia(1, .src0, .add_smin), ._, ._ },
35546 .{ ._, ._, .adc, .dst0d, .si(-1), ._, ._ },
35547 } },
35548 }, .{
35549 .src_constraints = .{ .{ .signed_int = .dword }, .{ .signed_int = .dword }, .any },
35550 .patterns = &.{
35551 .{ .src = .{ .{ .to_reg = .eax }, .to_mut_gpr, .none } },
35552 },
35553 .extra_temps = .{
35554 .{ .type = .i32, .kind = .{ .reg = .edx } },
35555 .unused,
35556 .unused,
35557 .unused,
35558 .unused,
35559 .unused,
35560 .unused,
35561 .unused,
35562 .unused,
35563 .unused,
35564 .unused,
35565 },
35566 .dst_temps = .{ .{ .ref = .src0 }, .unused },
35567 .clobbers = .{ .eflags = true },
35568 .each = .{ .once = &.{
35569 .{ ._, ._, .cdq, ._, ._, ._, ._ },
35570 .{ ._, .i_, .div, .src1d, ._, ._, ._ },
35571 .{ ._, ._, .@"and", .src1d, .sa(.src0, .add_smin), ._, ._ },
35572 .{ ._, ._, .xor, .src1d, .tmp0d, ._, ._ },
35573 .{ ._, ._, .cmp, .src1d, .sia(1, .src0, .add_smin), ._, ._ },
35574 .{ ._, ._, .adc, .dst0d, .si(-1), ._, ._ },
35575 } },
35576 }, .{
35577 .required_features = .{ .@"64bit", null, null, null },
35578 .src_constraints = .{ .{ .signed_int = .qword }, .{ .signed_int = .qword }, .any },
35579 .patterns = &.{
35580 .{ .src = .{ .{ .to_reg = .rax }, .to_mut_gpr, .none } },
35581 },
35582 .extra_temps = .{
35583 .{ .type = .i64, .kind = .{ .reg = .rdx } },
35584 .{ .type = .i64, .kind = .{ .rc = .general_purpose } },
35585 .unused,
35586 .unused,
35587 .unused,
35588 .unused,
35589 .unused,
35590 .unused,
35591 .unused,
35592 .unused,
35593 .unused,
35594 },
35595 .dst_temps = .{ .{ .ref = .src0 }, .unused },
35596 .clobbers = .{ .eflags = true },
35597 .each = .{ .once = &.{
35598 .{ ._, ._, .cqo, ._, ._, ._, ._ },
35599 .{ ._, .i_, .div, .src1q, ._, ._, ._ },
35600 .{ ._, ._, .mov, .tmp1q, .ua(.src0, .add_smin), ._, ._ },
35601 .{ ._, ._, .@"and", .src1q, .tmp1q, ._, ._ },
35602 .{ ._, ._, .xor, .src1q, .tmp0q, ._, ._ },
35603 .{ ._, ._c, .st, ._, ._, ._, ._ },
35604 .{ ._, ._, .sbb, .src1q, .tmp1q, ._, ._ },
35605 .{ ._, ._, .adc, .dst0q, .si(-1), ._, ._ },
35606 } },
35607 }, .{
35608 .required_features = .{ .@"64bit", null, null, null },
35609 .src_constraints = .{ .{ .signed_int = .xword }, .{ .signed_int = .xword }, .any },
35610 .patterns = &.{
35611 .{ .src = .{ .mem, .mem, .none } },
35612 },
35613 .call_frame = .{ .alignment = .@"16" },
35614 .extra_temps = .{
35615 .{ .type = .i128, .kind = .{ .param_gpr_pair = .{ .cc = .ccc, .at = 0 } } },
35616 .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
35617 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modti3" } } },
35618 .{ .type = .i64, .kind = .{ .rc = .general_purpose } },
35619 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divti3" } } },
35620 .unused,
35621 .unused,
35622 .unused,
35623 .unused,
35624 .unused,
35625 .unused,
35626 },
35627 .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .at = 0 } }, .unused },
35628 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
35629 .each = .{ .once = &.{
35630 .{ ._, ._, .mov, .tmp0q0, .mem(.src0q), ._, ._ },
35631 .{ ._, ._, .mov, .tmp0q1, .memd(.src0q, 8), ._, ._ },
35632 .{ ._, ._, .mov, .dst0q1, .mem(.src1q), ._, ._ },
35633 .{ ._, ._, .mov, .tmp1q, .memd(.src1q, 8), ._, ._ },
35634 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
35635 .{ ._, ._, .mov, .tmp0q0, .ua(.src0, .add_smin), ._, ._ },
35636 .{ ._, ._, .mov, .tmp1q, .memd(.src1q, 8), ._, ._ },
35637 .{ ._, ._, .mov, .tmp0q1, .tmp0q0, ._, ._ },
35638 .{ ._, ._, .@"and", .tmp0q1, .tmp1q, ._, ._ },
35639 .{ ._, ._, .xor, .tmp0q1, .dst0q1, ._, ._ },
35640 .{ ._, ._, .cmp, .dst0q0, .si(1), ._, ._ },
35641 .{ ._, ._, .sbb, .tmp0q1, .tmp0q0, ._, ._ },
35642 .{ ._, ._, .sbb, .tmp3q, .tmp3q, ._, ._ },
35643 .{ ._, ._, .mov, .tmp0q0, .mem(.src0q), ._, ._ },
35644 .{ ._, ._, .mov, .tmp0q1, .memd(.src0q, 8), ._, ._ },
35645 .{ ._, ._, .mov, .dst0q1, .mem(.src1q), ._, ._ },
35646 .{ ._, ._, .call, .tmp4d, ._, ._, ._ },
35647 .{ ._, ._c, .st, ._, ._, ._, ._ },
35648 .{ ._, ._, .sbb, .dst0q0, .tmp3q, ._, ._ },
35649 .{ ._, ._, .sbb, .dst0q1, .tmp3q, ._, ._ },
35650 } },
35651 }, .{
35652 .required_features = .{ .@"64bit", null, null, null },
35653 .src_constraints = .{
35654 .{ .remainder_signed_int = .{ .of = .dword, .is = .dword } },
35655 .{ .remainder_signed_int = .{ .of = .dword, .is = .dword } },
35656 .any,
35657 },
35658 .patterns = &.{
35659 .{ .src = .{ .to_mut_mem, .to_mut_mem, .none } },
35660 },
35661 .call_frame = .{ .alignment = .@"16" },
35662 .extra_temps = .{
35663 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } },
35664 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
35665 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
35666 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
35667 .{ .type = .i32, .kind = .{ .rc = .general_purpose } },
35668 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divei4" } } },
35669 .{ .kind = .{ .mem_of_type = .dst0 } },
35670 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modei4" } } },
35671 .unused,
35672 .unused,
35673 .unused,
35674 },
35675 .dst_temps = .{ .mem, .unused },
35676 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
35677 .each = .{ .once = &.{
35678 .{ ._, ._, .lea, .tmp0p, .mem(.dst0), ._, ._ },
35679 .{ ._, ._, .lea, .tmp1p, .mem(.src0), ._, ._ },
35680 .{ ._, ._, .lea, .tmp2p, .mem(.src1), ._, ._ },
35681 .{ ._, ._, .mov, .tmp3d, .sa(.src0, .add_bit_size), ._, ._ },
35682 .{ ._, ._, .mov, .tmp4d, .memad(.src0d, .add_size, -4), ._, ._ },
35683 .{ ._, ._, .xor, .tmp4d, .memad(.src1d, .add_size, -4), ._, ._ },
35684 .{ ._, ._, .call, .tmp5d, ._, ._, ._ },
35685 .{ ._, ._, .@"test", .tmp4d, .tmp4d, ._, ._ },
35686 .{ ._, ._ns, .j, .@"0f", ._, ._, ._ },
35687 .{ ._, ._, .lea, .tmp0p, .mem(.tmp6), ._, ._ },
35688 .{ ._, ._, .lea, .tmp1p, .mem(.src0), ._, ._ },
35689 .{ ._, ._, .lea, .tmp2p, .mem(.src1), ._, ._ },
35690 .{ ._, ._, .mov, .tmp3d, .sa(.src0, .add_bit_size), ._, ._ },
35691 .{ ._, ._, .call, .tmp7d, ._, ._, ._ },
35692 .{ ._, ._, .mov, .tmp0d, .sia(-8, .dst0, .add_size), ._, ._ },
35693 .{ .@"1:", ._, .cmp, .memi(.tmp6q, .tmp0), .si(0), ._, ._ },
35694 .{ ._, ._e, .j, .@"3f", ._, ._, ._ },
35695 .{ ._, ._, .mov, .tmp0p, .sa(.dst0, .sub_size_div_8), ._, ._ },
35696 .{ .@"2:", ._, .adc, .memsia(.dst0q, .@"8", .tmp0, .add_size), .si(-1), ._, ._ },
35697 .{ ._, ._c, .in, .tmp0p, ._, ._, ._ },
35698 .{ ._, ._nz, .j, .@"2b", ._, ._, ._ },
35699 .{ .@"3:", ._, .sub, .tmp0d, .si(8), ._, ._ },
35700 .{ ._, ._ae, .j, .@"1b", ._, ._, ._ },
35701 } },
35702 } }),
35703 .unsigned => res[0] = ops[0].divTruncInts(&ops[1], cg) catch |err| break :err err,
35704 } else cg.select(&res, &.{ty}, &ops, comptime &.{ .{
3546735705 .required_features = .{ .f16c, null, null, null },
3546835706 .src_constraints = .{
3546935707 .{ .scalar_float = .{ .of = .word, .is = .word } },
......@@ -36494,10 +36732,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3649436732 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
3649536733 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
3649636734 } },
36497 } }) catch |err| switch (err) {
36735 } })) catch |err| switch (err) {
3649836736 error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{
3649936737 @tagName(air_tag),
36500 cg.typeOf(bin_op.lhs).fmt(pt),
36738 ty.fmt(pt),
3650136739 ops[0].tracking(cg),
3650236740 ops[1].tracking(cg),
3650336741 }),
......@@ -36510,6 +36748,13 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3651036748 var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs });
3651136749 var res: [1]Temp = undefined;
3651236750 cg.select(&res, &.{cg.typeOf(bin_op.lhs)}, &ops, comptime &.{ .{
36751 .src_constraints = .{ .{ .exact_int = 1 }, .{ .exact_int = 1 }, .any },
36752 .patterns = &.{
36753 .{ .src = .{ .any, .any, .none } },
36754 },
36755 .dst_temps = .{ .{ .imm = 0 }, .unused },
36756 .each = .{ .once = &.{} },
36757 }, .{
3651336758 .src_constraints = .{ .{ .signed_int = .byte }, .{ .signed_int = .byte }, .any },
3651436759 .patterns = &.{
3651536760 .{ .src = .{ .mem, .mem, .none } },
......@@ -36616,8 +36861,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3661636861 .src_constraints = .{ .{ .signed_int = .xword }, .{ .signed_int = .xword }, .any },
3661736862 .patterns = &.{
3661836863 .{ .src = .{
36619 .{ .to_param_gpr_pair = .{ .cc = .ccc, .index = 0 } },
36620 .{ .to_param_gpr_pair = .{ .cc = .ccc, .index = 2 } },
36864 .{ .to_param_gpr_pair = .{ .cc = .ccc, .at = 0 } },
36865 .{ .to_param_gpr_pair = .{ .cc = .ccc, .at = 2 } },
3662136866 .none,
3662236867 } },
3662336868 },
......@@ -36635,7 +36880,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3663536880 .unused,
3663636881 .unused,
3663736882 },
36638 .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .index = 0 } }, .unused },
36883 .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .at = 0 } }, .unused },
3663936884 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
3664036885 .each = .{ .once = &.{
3664136886 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
......@@ -36645,8 +36890,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3664536890 .src_constraints = .{ .{ .unsigned_int = .xword }, .{ .unsigned_int = .xword }, .any },
3664636891 .patterns = &.{
3664736892 .{ .src = .{
36648 .{ .to_param_gpr_pair = .{ .cc = .ccc, .index = 0 } },
36649 .{ .to_param_gpr_pair = .{ .cc = .ccc, .index = 2 } },
36893 .{ .to_param_gpr_pair = .{ .cc = .ccc, .at = 0 } },
36894 .{ .to_param_gpr_pair = .{ .cc = .ccc, .at = 2 } },
3665036895 .none,
3665136896 } },
3665236897 },
......@@ -36664,7 +36909,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3666436909 .unused,
3666536910 .unused,
3666636911 },
36667 .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .index = 0 } }, .unused },
36912 .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .at = 0 } }, .unused },
3666836913 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
3666936914 .each = .{ .once = &.{
3667036915 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
......@@ -36681,10 +36926,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3668136926 },
3668236927 .call_frame = .{ .alignment = .@"16" },
3668336928 .extra_temps = .{
36684 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } },
36685 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } },
36686 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } },
36687 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } },
36929 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } },
36930 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
36931 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
36932 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
3668836933 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modei4" } } },
3668936934 .unused,
3669036935 .unused,
......@@ -36714,10 +36959,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3671436959 },
3671536960 .call_frame = .{ .alignment = .@"16" },
3671636961 .extra_temps = .{
36717 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } },
36718 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } },
36719 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } },
36720 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } },
36962 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } },
36963 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
36964 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
36965 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
3672136966 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__umodei4" } } },
3672236967 .unused,
3672336968 .unused,
......@@ -37078,12 +37323,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3707837323 .call_frame = .{ .alignment = .@"16" },
3707937324 .extra_temps = .{
3708037325 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
37081 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } },
37082 .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } },
37083 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } },
37084 .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } },
37326 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } },
37327 .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
37328 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
37329 .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
3708537330 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modti3" } } },
37086 .{ .type = .u64, .kind = .{ .ret_gpr = .{ .cc = .ccc, .index = 0 } } },
37331 .{ .type = .u64, .kind = .{ .ret_gpr = .{ .cc = .ccc, .at = 0 } } },
3708737332 .unused,
3708837333 .unused,
3708937334 .unused,
......@@ -37116,12 +37361,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3711637361 .call_frame = .{ .alignment = .@"16" },
3711737362 .extra_temps = .{
3711837363 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
37119 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } },
37120 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } },
37121 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } },
37122 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } },
37364 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } },
37365 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
37366 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
37367 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
3712337368 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__umodti3" } } },
37124 .{ .type = .u64, .kind = .{ .ret_gpr = .{ .cc = .ccc, .index = 0 } } },
37369 .{ .type = .u64, .kind = .{ .ret_gpr = .{ .cc = .ccc, .at = 0 } } },
3712537370 .unused,
3712637371 .unused,
3712737372 .unused,
......@@ -37154,10 +37399,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3715437399 .call_frame = .{ .alignment = .@"16" },
3715537400 .extra_temps = .{
3715637401 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
37157 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } },
37158 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } },
37159 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } },
37160 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } },
37402 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } },
37403 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
37404 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
37405 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
3716137406 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modei4" } } },
3716237407 .unused,
3716337408 .unused,
......@@ -37190,10 +37435,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3719037435 .call_frame = .{ .alignment = .@"16" },
3719137436 .extra_temps = .{
3719237437 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
37193 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } },
37194 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } },
37195 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } },
37196 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } },
37438 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } },
37439 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
37440 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
37441 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
3719737442 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__umodei4" } } },
3719837443 .unused,
3719937444 .unused,
......@@ -37987,12 +38232,498 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3798738232 };
3798838233 try res[0].finish(inst, &.{ bin_op.lhs, bin_op.rhs }, &ops, cg);
3798938234 },
37990 .mod, .mod_optimized => |air_tag| if (use_old) try cg.airMulDivBinOp(inst, .mod) else fallback: {
38235 .mod, .mod_optimized => |air_tag| if (use_old) try cg.airMulDivBinOp(inst, .mod) else {
3799138236 const bin_op = air_datas[@intFromEnum(inst)].bin_op;
37992 if (cg.floatBits(cg.typeOf(bin_op.lhs).scalarType(zcu)) == null) break :fallback try cg.airMulDivBinOp(inst, .mod);
3799338237 var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs });
3799438238 var res: [1]Temp = undefined;
3799538239 cg.select(&res, &.{cg.typeOf(bin_op.lhs)}, &ops, comptime &.{ .{
38240 .src_constraints = .{ .{ .exact_int = 1 }, .{ .exact_int = 1 }, .any },
38241 .patterns = &.{
38242 .{ .src = .{ .any, .any, .none } },
38243 },
38244 .dst_temps = .{ .{ .imm = 0 }, .unused },
38245 .each = .{ .once = &.{} },
38246 }, .{
38247 .required_features = .{ .cmov, null, null, null },
38248 .src_constraints = .{ .{ .signed_int = .byte }, .{ .signed_int = .byte }, .any },
38249 .patterns = &.{
38250 .{ .src = .{ .mem, .to_mut_gphi, .none } },
38251 .{ .src = .{ .to_gpr, .to_mut_gphi, .none } },
38252 },
38253 .extra_temps = .{
38254 .{ .type = .i8, .kind = .{ .rc = .gphi } },
38255 .unused,
38256 .unused,
38257 .unused,
38258 .unused,
38259 .unused,
38260 .unused,
38261 .unused,
38262 .unused,
38263 .unused,
38264 .unused,
38265 },
38266 .dst_temps = .{ .{ .reg = .ah }, .unused },
38267 .clobbers = .{ .eflags = true },
38268 .each = .{ .once = &.{
38269 .{ ._, ._, .movsx, .dst0d, .src0b, ._, ._ },
38270 .{ ._, .i_, .div, .src1b, ._, ._, ._ },
38271 .{ ._, ._, .mov, .tmp0d, .dst0d, ._, ._ },
38272 .{ ._, ._, .add, .tmp0h, .src1b, ._, ._ },
38273 .{ ._, ._, .@"and", .src1b, .sa(.src0, .add_smin), ._, ._ },
38274 .{ ._, ._, .xor, .src1b, .dst0h, ._, ._ },
38275 .{ ._, ._, .cmp, .src1b, .sa(.src0, .add_smin), ._, ._ },
38276 .{ ._, ._a, .cmov, .dst0d, .tmp0d, ._, ._ },
38277 } },
38278 }, .{
38279 .src_constraints = .{ .{ .signed_int = .byte }, .{ .signed_int = .byte }, .any },
38280 .patterns = &.{
38281 .{ .src = .{ .mem, .to_gphi, .none } },
38282 .{ .src = .{ .to_gpr, .to_gphi, .none } },
38283 },
38284 .extra_temps = .{
38285 .{ .type = .i8, .kind = .{ .rc = .gphi } },
38286 .unused,
38287 .unused,
38288 .unused,
38289 .unused,
38290 .unused,
38291 .unused,
38292 .unused,
38293 .unused,
38294 .unused,
38295 .unused,
38296 },
38297 .dst_temps = .{ .{ .reg = .ah }, .unused },
38298 .clobbers = .{ .eflags = true },
38299 .each = .{ .once = &.{
38300 .{ ._, ._, .movsx, .dst0d, .src0b, ._, ._ },
38301 .{ ._, .i_, .div, .src1b, ._, ._, ._ },
38302 .{ ._, ._, .mov, .tmp0d, .src1d, ._, ._ },
38303 .{ ._, ._, .@"and", .tmp0b, .sa(.src0, .add_smin), ._, ._ },
38304 .{ ._, ._, .xor, .tmp0b, .dst0h, ._, ._ },
38305 .{ ._, ._, .cmp, .tmp0b, .sa(.src0, .add_smin), ._, ._ },
38306 .{ ._, ._na, .j, .@"0f", ._, ._, ._ },
38307 .{ ._, ._, .add, .dst0h, .src1b, ._, ._ },
38308 } },
38309 }, .{
38310 .src_constraints = .{ .{ .unsigned_int = .byte }, .{ .unsigned_int = .byte }, .any },
38311 .patterns = &.{
38312 .{ .src = .{ .mem, .mem, .none } },
38313 .{ .src = .{ .to_gpr, .mem, .none } },
38314 .{ .src = .{ .mem, .to_gpr, .none } },
38315 .{ .src = .{ .to_gpr, .to_gpr, .none } },
38316 },
38317 .dst_temps = .{ .{ .reg = .ah }, .unused },
38318 .clobbers = .{ .eflags = true },
38319 .each = .{ .once = &.{
38320 .{ ._, ._, .movzx, .dst0d, .src0b, ._, ._ },
38321 .{ ._, ._, .div, .src1b, ._, ._, ._ },
38322 } },
38323 }, .{
38324 .required_features = .{ .cmov, .fast_imm16, null, null },
38325 .src_constraints = .{ .{ .signed_int = .word }, .{ .signed_int = .word }, .any },
38326 .patterns = &.{
38327 .{ .src = .{ .{ .to_reg = .ax }, .to_mut_gpr, .none } },
38328 },
38329 .dst_temps = .{ .{ .reg = .dx }, .unused },
38330 .clobbers = .{ .eflags = true },
38331 .each = .{ .once = &.{
38332 .{ ._, ._, .cwd, ._, ._, ._, ._ },
38333 .{ ._, .i_, .div, .src1w, ._, ._, ._ },
38334 .{ ._, ._, .mov, .src0d, .dst0d, ._, ._ },
38335 .{ ._, ._, .add, .src0d, .src1d, ._, ._ },
38336 .{ ._, ._, .@"and", .src1w, .sa(.src0, .add_smin), ._, ._ },
38337 .{ ._, ._, .xor, .src1d, .dst0d, ._, ._ },
38338 .{ ._, ._, .cmp, .src1w, .sa(.src0, .add_smin), ._, ._ },
38339 .{ ._, ._a, .cmov, .dst0d, .src0d, ._, ._ },
38340 } },
38341 }, .{
38342 .required_features = .{ .cmov, null, null, null },
38343 .src_constraints = .{ .{ .signed_int = .word }, .{ .signed_int = .word }, .any },
38344 .patterns = &.{
38345 .{ .src = .{ .{ .to_reg = .ax }, .to_mut_gpr, .none } },
38346 },
38347 .dst_temps = .{ .{ .reg = .dx }, .unused },
38348 .clobbers = .{ .eflags = true },
38349 .each = .{ .once = &.{
38350 .{ ._, ._, .cwd, ._, ._, ._, ._ },
38351 .{ ._, .i_, .div, .src1w, ._, ._, ._ },
38352 .{ ._, ._, .mov, .src0d, .dst0d, ._, ._ },
38353 .{ ._, ._, .add, .src0d, .src1d, ._, ._ },
38354 .{ ._, ._, .@"and", .src1d, .sa(.src0, .add_smin), ._, ._ },
38355 .{ ._, ._, .xor, .src1d, .dst0d, ._, ._ },
38356 .{ ._, ._, .cmp, .src1w, .sa(.src0, .add_smin), ._, ._ },
38357 .{ ._, ._a, .cmov, .dst0d, .src0d, ._, ._ },
38358 } },
38359 }, .{
38360 .required_features = .{ .fast_imm16, null, null, null },
38361 .src_constraints = .{ .{ .signed_int = .word }, .{ .signed_int = .word }, .any },
38362 .patterns = &.{
38363 .{ .src = .{ .{ .to_reg = .ax }, .to_gpr, .none } },
38364 },
38365 .dst_temps = .{ .{ .reg = .dx }, .unused },
38366 .clobbers = .{ .eflags = true },
38367 .each = .{ .once = &.{
38368 .{ ._, ._, .cwd, ._, ._, ._, ._ },
38369 .{ ._, .i_, .div, .src1w, ._, ._, ._ },
38370 .{ ._, ._, .mov, .src0d, .src1d, ._, ._ },
38371 .{ ._, ._, .@"and", .src0w, .sa(.src0, .add_smin), ._, ._ },
38372 .{ ._, ._, .xor, .src0d, .dst0d, ._, ._ },
38373 .{ ._, ._, .cmp, .src0w, .sa(.src0, .add_smin), ._, ._ },
38374 .{ ._, ._na, .j, .@"0f", ._, ._, ._ },
38375 .{ ._, ._, .add, .dst0d, .src1d, ._, ._ },
38376 } },
38377 }, .{
38378 .src_constraints = .{ .{ .signed_int = .word }, .{ .signed_int = .word }, .any },
38379 .patterns = &.{
38380 .{ .src = .{ .{ .to_reg = .ax }, .to_gpr, .none } },
38381 },
38382 .dst_temps = .{ .{ .reg = .dx }, .unused },
38383 .clobbers = .{ .eflags = true },
38384 .each = .{ .once = &.{
38385 .{ ._, ._, .cwd, ._, ._, ._, ._ },
38386 .{ ._, .i_, .div, .src1w, ._, ._, ._ },
38387 .{ ._, ._, .mov, .src0d, .src1d, ._, ._ },
38388 .{ ._, ._, .@"and", .src0d, .sa(.src0, .add_smin), ._, ._ },
38389 .{ ._, ._, .xor, .src0d, .dst0d, ._, ._ },
38390 .{ ._, ._, .cmp, .src0w, .sa(.src0, .add_smin), ._, ._ },
38391 .{ ._, ._na, .j, .@"0f", ._, ._, ._ },
38392 .{ ._, ._, .add, .dst0d, .src1d, ._, ._ },
38393 } },
38394 }, .{
38395 .src_constraints = .{ .{ .unsigned_int = .word }, .{ .unsigned_int = .word }, .any },
38396 .patterns = &.{
38397 .{ .src = .{ .{ .to_reg = .ax }, .mem, .none } },
38398 .{ .src = .{ .{ .to_reg = .ax }, .to_gpr, .none } },
38399 },
38400 .dst_temps = .{ .{ .reg = .dx }, .unused },
38401 .clobbers = .{ .eflags = true },
38402 .each = .{ .once = &.{
38403 .{ ._, ._, .xor, .dst0d, .dst0d, ._, ._ },
38404 .{ ._, ._, .div, .src1w, ._, ._, ._ },
38405 } },
38406 }, .{
38407 .required_features = .{ .cmov, null, null, null },
38408 .src_constraints = .{ .{ .signed_int = .dword }, .{ .signed_int = .dword }, .any },
38409 .patterns = &.{
38410 .{ .src = .{ .{ .to_reg = .eax }, .to_mut_gpr, .none } },
38411 },
38412 .dst_temps = .{ .{ .reg = .edx }, .unused },
38413 .clobbers = .{ .eflags = true },
38414 .each = .{ .once = &.{
38415 .{ ._, ._, .cdq, ._, ._, ._, ._ },
38416 .{ ._, .i_, .div, .src1d, ._, ._, ._ },
38417 .{ ._, ._, .mov, .src0d, .dst0d, ._, ._ },
38418 .{ ._, ._, .add, .src0d, .src1d, ._, ._ },
38419 .{ ._, ._, .@"and", .src1d, .sa(.src0, .add_smin), ._, ._ },
38420 .{ ._, ._, .xor, .src1d, .dst0d, ._, ._ },
38421 .{ ._, ._, .cmp, .src1d, .sa(.src0, .add_smin), ._, ._ },
38422 .{ ._, ._a, .cmov, .dst0d, .src0d, ._, ._ },
38423 } },
38424 }, .{
38425 .src_constraints = .{ .{ .signed_int = .dword }, .{ .signed_int = .dword }, .any },
38426 .patterns = &.{
38427 .{ .src = .{ .{ .to_reg = .eax }, .to_gpr, .none } },
38428 },
38429 .dst_temps = .{ .{ .reg = .edx }, .unused },
38430 .clobbers = .{ .eflags = true },
38431 .each = .{ .once = &.{
38432 .{ ._, ._, .cdq, ._, ._, ._, ._ },
38433 .{ ._, .i_, .div, .src1d, ._, ._, ._ },
38434 .{ ._, ._, .mov, .src0d, .src1d, ._, ._ },
38435 .{ ._, ._, .@"and", .src0d, .sa(.src0, .add_smin), ._, ._ },
38436 .{ ._, ._, .xor, .src0d, .dst0d, ._, ._ },
38437 .{ ._, ._, .cmp, .src0d, .sa(.src0, .add_smin), ._, ._ },
38438 .{ ._, ._na, .j, .@"0f", ._, ._, ._ },
38439 .{ ._, ._, .add, .dst0d, .src1d, ._, ._ },
38440 } },
38441 }, .{
38442 .src_constraints = .{ .{ .unsigned_int = .dword }, .{ .unsigned_int = .dword }, .any },
38443 .patterns = &.{
38444 .{ .src = .{ .{ .to_reg = .eax }, .mem, .none } },
38445 .{ .src = .{ .{ .to_reg = .eax }, .to_gpr, .none } },
38446 },
38447 .dst_temps = .{ .{ .reg = .edx }, .unused },
38448 .clobbers = .{ .eflags = true },
38449 .each = .{ .once = &.{
38450 .{ ._, ._, .xor, .dst0d, .dst0d, ._, ._ },
38451 .{ ._, ._, .div, .src1d, ._, ._, ._ },
38452 } },
38453 }, .{
38454 .required_features = .{ .@"64bit", .cmov, null, null },
38455 .src_constraints = .{ .{ .signed_int = .qword }, .{ .signed_int = .qword }, .any },
38456 .patterns = &.{
38457 .{ .src = .{ .{ .to_reg = .rax }, .to_mut_gpr, .none } },
38458 },
38459 .extra_temps = .{
38460 .{ .type = .i64, .kind = .{ .rc = .general_purpose } },
38461 .unused,
38462 .unused,
38463 .unused,
38464 .unused,
38465 .unused,
38466 .unused,
38467 .unused,
38468 .unused,
38469 .unused,
38470 .unused,
38471 },
38472 .dst_temps = .{ .{ .reg = .rdx }, .unused },
38473 .clobbers = .{ .eflags = true },
38474 .each = .{ .once = &.{
38475 .{ ._, ._, .cqo, ._, ._, ._, ._ },
38476 .{ ._, .i_, .div, .src1q, ._, ._, ._ },
38477 .{ ._, ._, .mov, .tmp0q, .ua(.src0, .add_smin), ._, ._ },
38478 .{ ._, ._, .mov, .src0q, .dst0q, ._, ._ },
38479 .{ ._, ._, .add, .src0q, .src1q, ._, ._ },
38480 .{ ._, ._, .@"and", .src1q, .tmp0q, ._, ._ },
38481 .{ ._, ._, .xor, .src1q, .dst0q, ._, ._ },
38482 .{ ._, ._, .cmp, .src1q, .tmp0q, ._, ._ },
38483 .{ ._, ._a, .cmov, .dst0q, .src0q, ._, ._ },
38484 } },
38485 }, .{
38486 .required_features = .{ .@"64bit", null, null, null },
38487 .src_constraints = .{ .{ .signed_int = .qword }, .{ .signed_int = .qword }, .any },
38488 .patterns = &.{
38489 .{ .src = .{ .{ .to_reg = .rax }, .to_gpr, .none } },
38490 },
38491 .extra_temps = .{
38492 .{ .type = .i64, .kind = .{ .rc = .general_purpose } },
38493 .unused,
38494 .unused,
38495 .unused,
38496 .unused,
38497 .unused,
38498 .unused,
38499 .unused,
38500 .unused,
38501 .unused,
38502 .unused,
38503 },
38504 .dst_temps = .{ .{ .reg = .rdx }, .unused },
38505 .clobbers = .{ .eflags = true },
38506 .each = .{ .once = &.{
38507 .{ ._, ._, .cqo, ._, ._, ._, ._ },
38508 .{ ._, .i_, .div, .src1q, ._, ._, ._ },
38509 .{ ._, ._, .mov, .tmp0q, .ua(.src0, .add_smin), ._, ._ },
38510 .{ ._, ._, .mov, .src0q, .src1q, ._, ._ },
38511 .{ ._, ._, .@"and", .src0q, .tmp0q, ._, ._ },
38512 .{ ._, ._, .xor, .src0q, .dst0q, ._, ._ },
38513 .{ ._, ._, .cmp, .src0q, .tmp0q, ._, ._ },
38514 .{ ._, ._na, .j, .@"0f", ._, ._, ._ },
38515 .{ ._, ._, .add, .dst0q, .src1q, ._, ._ },
38516 } },
38517 }, .{
38518 .required_features = .{ .@"64bit", null, null, null },
38519 .src_constraints = .{ .{ .unsigned_int = .qword }, .{ .unsigned_int = .qword }, .any },
38520 .patterns = &.{
38521 .{ .src = .{ .{ .to_reg = .rax }, .mem, .none } },
38522 .{ .src = .{ .{ .to_reg = .rax }, .to_gpr, .none } },
38523 },
38524 .dst_temps = .{ .{ .reg = .rdx }, .unused },
38525 .clobbers = .{ .eflags = true },
38526 .each = .{ .once = &.{
38527 .{ ._, ._, .xor, .dst0q, .dst0q, ._, ._ },
38528 .{ ._, ._, .div, .src1q, ._, ._, ._ },
38529 } },
38530 }, .{
38531 .required_features = .{ .@"64bit", .cmov, null, null },
38532 .src_constraints = .{ .{ .signed_int = .xword }, .{ .signed_int = .xword }, .any },
38533 .patterns = &.{
38534 .{ .src = .{ .{ .to_param_gpr_pair = .{ .cc = .ccc, .at = 0 } }, .to_mem, .none } },
38535 },
38536 .call_frame = .{ .alignment = .@"16" },
38537 .extra_temps = .{
38538 .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
38539 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modti3" } } },
38540 .{ .type = .i64, .kind = .{ .rc = .general_purpose } },
38541 .unused,
38542 .unused,
38543 .unused,
38544 .unused,
38545 .unused,
38546 .unused,
38547 .unused,
38548 .unused,
38549 },
38550 .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .at = 0 } }, .unused },
38551 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
38552 .each = .{ .once = &.{
38553 .{ ._, ._, .mov, .dst0q1, .mem(.src1q), ._, ._ },
38554 .{ ._, ._, .mov, .tmp0q, .memd(.src1q, 8), ._, ._ },
38555 .{ ._, ._, .call, .tmp1d, ._, ._, ._ },
38556 .{ ._, ._, .mov, .src0q0, .memd(.src1q, 8), ._, ._ },
38557 .{ ._, ._, .mov, .src0q1, .ua(.src0, .add_smin), ._, ._ },
38558 .{ ._, ._, .mov, .tmp0q, .src0q0, ._, ._ },
38559 .{ ._, ._, .@"and", .tmp0q, .src0q1, ._, ._ },
38560 .{ ._, ._, .xor, .tmp0q, .dst0q1, ._, ._ },
38561 .{ ._, ._, .xor, .tmp2d, .tmp2d, ._, ._ },
38562 .{ ._, ._, .cmp, .dst0q0, .si(1), ._, ._ },
38563 .{ ._, ._, .sbb, .tmp0q, .src0q1, ._, ._ },
38564 .{ ._, ._nae, .cmov, .src0q0, .tmp2q, ._, ._ },
38565 .{ ._, ._ae, .cmov, .tmp2q, .mem(.src1q), ._, ._ },
38566 .{ ._, ._, .add, .dst0q0, .tmp2q, ._, ._ },
38567 .{ ._, ._, .adc, .dst0q1, .src0q0, ._, ._ },
38568 } },
38569 }, .{
38570 .required_features = .{ .@"64bit", null, null, null },
38571 .src_constraints = .{ .{ .signed_int = .xword }, .{ .signed_int = .xword }, .any },
38572 .patterns = &.{
38573 .{ .src = .{ .{ .to_param_gpr_pair = .{ .cc = .ccc, .at = 0 } }, .to_mem, .none } },
38574 },
38575 .call_frame = .{ .alignment = .@"16" },
38576 .extra_temps = .{
38577 .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
38578 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modti3" } } },
38579 .unused,
38580 .unused,
38581 .unused,
38582 .unused,
38583 .unused,
38584 .unused,
38585 .unused,
38586 .unused,
38587 .unused,
38588 },
38589 .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .at = 0 } }, .unused },
38590 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
38591 .each = .{ .once = &.{
38592 .{ ._, ._, .mov, .dst0q1, .mem(.src1q), ._, ._ },
38593 .{ ._, ._, .mov, .tmp0q, .memd(.src1q, 8), ._, ._ },
38594 .{ ._, ._, .call, .tmp1d, ._, ._, ._ },
38595 .{ ._, ._, .mov, .src0q0, .memd(.src1q, 8), ._, ._ },
38596 .{ ._, ._, .mov, .src0q1, .ua(.src0, .add_smin), ._, ._ },
38597 .{ ._, ._, .mov, .tmp0q, .src0q0, ._, ._ },
38598 .{ ._, ._, .@"and", .tmp0q, .src0q1, ._, ._ },
38599 .{ ._, ._, .xor, .tmp0q, .dst0q1, ._, ._ },
38600 .{ ._, ._, .cmp, .dst0q0, .si(1), ._, ._ },
38601 .{ ._, ._, .sbb, .tmp0q, .src0q1, ._, ._ },
38602 .{ ._, ._nae, .j, .@"0f", ._, ._, ._ },
38603 .{ ._, ._, .add, .dst0q0, .mem(.src1q), ._, ._ },
38604 .{ ._, ._, .adc, .dst0q1, .src0q0, ._, ._ },
38605 } },
38606 }, .{
38607 .required_features = .{ .@"64bit", null, null, null },
38608 .src_constraints = .{ .{ .unsigned_int = .xword }, .{ .unsigned_int = .xword }, .any },
38609 .patterns = &.{
38610 .{ .src = .{
38611 .{ .to_param_gpr_pair = .{ .cc = .ccc, .at = 0 } },
38612 .{ .to_param_gpr_pair = .{ .cc = .ccc, .at = 2 } },
38613 .none,
38614 } },
38615 },
38616 .call_frame = .{ .alignment = .@"16" },
38617 .extra_temps = .{
38618 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__umodti3" } } },
38619 .unused,
38620 .unused,
38621 .unused,
38622 .unused,
38623 .unused,
38624 .unused,
38625 .unused,
38626 .unused,
38627 .unused,
38628 .unused,
38629 },
38630 .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .at = 0 } }, .unused },
38631 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
38632 .each = .{ .once = &.{
38633 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
38634 } },
38635 }, .{
38636 .required_features = .{ .@"64bit", null, null, null },
38637 .src_constraints = .{
38638 .{ .remainder_signed_int = .{ .of = .dword, .is = .dword } },
38639 .{ .remainder_signed_int = .{ .of = .dword, .is = .dword } },
38640 .any,
38641 },
38642 .patterns = &.{
38643 .{ .src = .{ .to_mut_mem, .to_mut_mem, .none } },
38644 },
38645 .call_frame = .{ .alignment = .@"16" },
38646 .extra_temps = .{
38647 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } },
38648 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
38649 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
38650 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
38651 .{ .type = .i64, .kind = .{ .rc = .general_purpose } },
38652 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modei4" } } },
38653 .unused,
38654 .unused,
38655 .unused,
38656 .unused,
38657 .unused,
38658 },
38659 .dst_temps = .{ .mem, .unused },
38660 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
38661 .each = .{ .once = &.{
38662 .{ ._, ._, .lea, .tmp0p, .mem(.dst0), ._, ._ },
38663 .{ ._, ._, .lea, .tmp1p, .mem(.src0), ._, ._ },
38664 .{ ._, ._, .lea, .tmp2p, .mem(.src1), ._, ._ },
38665 .{ ._, ._, .mov, .tmp3d, .sa(.src0, .add_bit_size), ._, ._ },
38666 .{ ._, ._, .mov, .tmp4q, .memad(.src1q, .add_size, -8), ._, ._ },
38667 .{ ._, ._, .call, .tmp5d, ._, ._, ._ },
38668 .{ ._, ._, .mov, .tmp0d, .sia(-3, .dst0, .add_size_div_8), ._, ._ },
38669 .{ ._, ._, .mov, .tmp1q, .ua(.src0, .add_smin), ._, ._ },
38670 .{ ._, ._, .mov, .tmp2q, .tmp4q, ._, ._ },
38671 .{ ._, ._, .@"and", .tmp2q, .tmp1q, ._, ._ },
38672 .{ ._, ._, .xor, .tmp2q, .memad(.dst0q, .add_size, -8), ._, ._ },
38673 .{ ._, ._, .cmp, .memad(.dst0q, .add_size, -16), .si(1), ._, ._ },
38674 .{ .@"0:", ._, .mov, .tmp3q, .memsi(.dst0q, .@"8", .tmp0), ._, ._ },
38675 .{ ._, ._, .sbb, .tmp3q, .si(0), ._, ._ },
38676 .{ ._, ._c, .de, .tmp0d, ._, ._, ._ },
38677 .{ ._, ._ns, .j, .@"0b", ._, ._, ._ },
38678 .{ ._, ._, .sbb, .tmp2q, .tmp1q, ._, ._ },
38679 .{ ._, ._nae, .j, .@"0f", ._, ._, ._ },
38680 .{ ._, ._, .mov, .tmp0p, .sa(.src1, .sub_size_div_8), ._, ._ },
38681 .{ ._, ._, .@"test", .tmp4q, .tmp4q, ._, ._ },
38682 .{ ._, ._ns, .j, .@"2f", ._, ._, ._ },
38683 .{ .@"1:", ._, .mov, .tmp1q, .memsia(.src1q, .@"8", .tmp0, .add_size), ._, ._ },
38684 .{ ._, ._, .sbb, .memsia(.dst0q, .@"8", .tmp0, .add_size), .tmp1q, ._, ._ },
38685 .{ ._, ._c, .in, .tmp0p, ._, ._, ._ },
38686 .{ ._, ._nz, .j, .@"1b", ._, ._, ._ },
38687 .{ ._, ._mp, .j, .@"0f", ._, ._, ._ },
38688 .{ .@"2:", ._, .mov, .tmp1q, .memsia(.src1q, .@"8", .tmp0, .add_size), ._, ._ },
38689 .{ ._, ._, .adc, .memsia(.dst0q, .@"8", .tmp0, .add_size), .tmp1q, ._, ._ },
38690 .{ ._, ._c, .in, .tmp0p, ._, ._, ._ },
38691 .{ ._, ._nz, .j, .@"2b", ._, ._, ._ },
38692 } },
38693 }, .{
38694 .required_features = .{ .@"64bit", null, null, null },
38695 .src_constraints = .{
38696 .{ .remainder_unsigned_int = .{ .of = .dword, .is = .dword } },
38697 .{ .remainder_unsigned_int = .{ .of = .dword, .is = .dword } },
38698 .any,
38699 },
38700 .patterns = &.{
38701 .{ .src = .{ .to_mem, .to_mem, .none } },
38702 },
38703 .call_frame = .{ .alignment = .@"16" },
38704 .extra_temps = .{
38705 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } },
38706 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
38707 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
38708 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
38709 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__umodei4" } } },
38710 .unused,
38711 .unused,
38712 .unused,
38713 .unused,
38714 .unused,
38715 .unused,
38716 },
38717 .dst_temps = .{ .mem, .unused },
38718 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
38719 .each = .{ .once = &.{
38720 .{ ._, ._, .lea, .tmp0p, .mem(.dst0), ._, ._ },
38721 .{ ._, ._, .lea, .tmp1p, .mem(.src0), ._, ._ },
38722 .{ ._, ._, .lea, .tmp2p, .mem(.src1), ._, ._ },
38723 .{ ._, ._, .mov, .tmp3d, .sa(.src0, .add_bit_size), ._, ._ },
38724 .{ ._, ._, .call, .tmp4d, ._, ._, ._ },
38725 } },
38726 }, .{
3799638727 .required_features = .{ .f16c, .fast_imm16, null, null },
3799738728 .src_constraints = .{
3799838729 .{ .scalar_float = .{ .of = .word, .is = .word } },
......@@ -160281,9 +161012,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
160281161012 inline .memcpy, .memmove => |symbol| comptime &.{.{
160282161013 .patterns = &.{
160283161014 .{ .src = .{
160284 .{ .to_param_gpr = .{ .cc = .ccc, .index = 0 } },
160285 .{ .to_param_gpr = .{ .cc = .ccc, .index = 1 } },
160286 .{ .to_param_gpr = .{ .cc = .ccc, .index = 2 } },
161015 .{ .to_param_gpr = .{ .cc = .ccc, .at = 0 } },
161016 .{ .to_param_gpr = .{ .cc = .ccc, .at = 1 } },
161017 .{ .to_param_gpr = .{ .cc = .ccc, .at = 2 } },
160287161018 } },
160288161019 },
160289161020 .call_frame = .{ .alignment = .@"16" },
......@@ -160333,7 +161064,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
160333161064 .required_features = .{ .avx, null, null, null },
160334161065 .src_constraints = .{ .{ .int = .gpr }, .any, .any },
160335161066 .patterns = &.{
160336 .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .index = 0 } }, .none, .none } },
161067 .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .at = 0 } }, .none, .none } },
160337161068 },
160338161069 .call_frame = .{ .alignment = .@"32" },
160339161070 .extra_temps = .{
......@@ -160359,7 +161090,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
160359161090 .required_features = .{ .sse, null, null, null },
160360161091 .src_constraints = .{ .{ .int = .gpr }, .any, .any },
160361161092 .patterns = &.{
160362 .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .index = 0 } }, .none, .none } },
161093 .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .at = 0 } }, .none, .none } },
160363161094 },
160364161095 .call_frame = .{ .alignment = .@"16" },
160365161096 .extra_temps = .{
......@@ -160384,7 +161115,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
160384161115 }, .{
160385161116 .src_constraints = .{ .{ .int = .gpr }, .any, .any },
160386161117 .patterns = &.{
160387 .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .index = 0 } }, .none, .none } },
161118 .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .at = 0 } }, .none, .none } },
160388161119 },
160389161120 .call_frame = .{ .alignment = .@"8" },
160390161121 .extra_temps = .{
......@@ -160424,7 +161155,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
160424161155 .required_features = .{ .avx, null, null, null },
160425161156 .src_constraints = .{ .{ .int = .gpr }, .any, .any },
160426161157 .patterns = &.{
160427 .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .index = 0 } }, .none, .none } },
161158 .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .at = 0 } }, .none, .none } },
160428161159 },
160429161160 .call_frame = .{ .alignment = .@"32" },
160430161161 .extra_temps = .{
......@@ -160440,7 +161171,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
160440161171 .unused,
160441161172 .unused,
160442161173 },
160443 .dst_temps = .{ .{ .ret_gpr = .{ .cc = .zigcc, .index = 1 } }, .unused },
161174 .dst_temps = .{ .{ .ret_gpr = .{ .cc = .zigcc, .at = 1 } }, .unused },
160444161175 .clobbers = .{ .eflags = true, .caller_preserved = .zigcc },
160445161176 .each = .{ .once = &.{
160446161177 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
......@@ -160449,7 +161180,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
160449161180 .required_features = .{ .sse, null, null, null },
160450161181 .src_constraints = .{ .{ .int = .gpr }, .any, .any },
160451161182 .patterns = &.{
160452 .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .index = 0 } }, .none, .none } },
161183 .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .at = 0 } }, .none, .none } },
160453161184 },
160454161185 .call_frame = .{ .alignment = .@"16" },
160455161186 .extra_temps = .{
......@@ -160465,7 +161196,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
160465161196 .unused,
160466161197 .unused,
160467161198 },
160468 .dst_temps = .{ .{ .ret_gpr = .{ .cc = .zigcc, .index = 1 } }, .unused },
161199 .dst_temps = .{ .{ .ret_gpr = .{ .cc = .zigcc, .at = 1 } }, .unused },
160469161200 .clobbers = .{ .eflags = true, .caller_preserved = .zigcc },
160470161201 .each = .{ .once = &.{
160471161202 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
......@@ -160473,7 +161204,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
160473161204 }, .{
160474161205 .src_constraints = .{ .{ .int = .gpr }, .any, .any },
160475161206 .patterns = &.{
160476 .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .index = 0 } }, .none, .none } },
161207 .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .at = 0 } }, .none, .none } },
160477161208 },
160478161209 .call_frame = .{ .alignment = .@"8" },
160479161210 .extra_temps = .{
......@@ -160489,7 +161220,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
160489161220 .unused,
160490161221 .unused,
160491161222 },
160492 .dst_temps = .{ .{ .ret_gpr = .{ .cc = .zigcc, .index = 1 } }, .unused },
161223 .dst_temps = .{ .{ .ret_gpr = .{ .cc = .zigcc, .at = 1 } }, .unused },
160493161224 .clobbers = .{ .eflags = true, .caller_preserved = .zigcc },
160494161225 .each = .{ .once = &.{
160495161226 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
......@@ -160621,7 +161352,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
160621161352 .required_features = .{ .avx, null, null, null },
160622161353 .src_constraints = .{ .{ .int = .gpr }, .any, .any },
160623161354 .patterns = &.{
160624 .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .index = 0 } }, .none, .none } },
161355 .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .at = 0 } }, .none, .none } },
160625161356 },
160626161357 .call_frame = .{ .alignment = .@"32" },
160627161358 .extra_temps = .{
......@@ -160647,7 +161378,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
160647161378 .required_features = .{ .sse, null, null, null },
160648161379 .src_constraints = .{ .{ .int = .gpr }, .any, .any },
160649161380 .patterns = &.{
160650 .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .index = 0 } }, .none, .none } },
161381 .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .at = 0 } }, .none, .none } },
160651161382 },
160652161383 .call_frame = .{ .alignment = .@"16" },
160653161384 .extra_temps = .{
......@@ -160672,7 +161403,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
160672161403 }, .{
160673161404 .src_constraints = .{ .{ .int = .gpr }, .any, .any },
160674161405 .patterns = &.{
160675 .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .index = 0 } }, .none, .none } },
161406 .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .at = 0 } }, .none, .none } },
160676161407 },
160677161408 .call_frame = .{ .alignment = .@"8" },
160678161409 .extra_temps = .{
......@@ -162921,7 +163652,7 @@ fn getValueIfFree(self: *CodeGen, value: MCValue, inst: ?Air.Inst.Index) void {
162921163652
162922163653fn freeReg(self: *CodeGen, reg: Register) !void {
162923163654 self.register_manager.freeReg(reg);
162924 if (reg.class() == .x87) try self.asmRegister(.{ .f_, .free }, reg);
163655 if (reg.isClass(.x87)) try self.asmRegister(.{ .f_, .free }, reg);
162925163656}
162926163657
162927163658fn freeValue(self: *CodeGen, value: MCValue) !void {
......@@ -163840,7 +164571,7 @@ fn airIntCast(self: *CodeGen, inst: Air.Inst.Index) !void {
163840164571 else => src_int_info.bits,
163841164572 };
163842164573
163843 const dst_mcv = if ((if (src_mcv.getReg()) |src_reg| src_reg.class() == .general_purpose else src_abi_size > 8) and
164574 const dst_mcv = if ((if (src_mcv.getReg()) |src_reg| src_reg.isClass(.general_purpose) else src_abi_size > 8) and
163844164575 dst_int_info.bits <= src_storage_bits and
163845164576 std.math.divCeil(u16, dst_int_info.bits, 64) catch unreachable ==
163846164577 std.math.divCeil(u32, src_storage_bits, 64) catch unreachable and
......@@ -163921,7 +164652,7 @@ fn airTrunc(self: *CodeGen, inst: Air.Inst.Index) !void {
163921164652 if (src_mcv.getReg()) |reg| self.register_manager.lockRegAssumeUnused(reg) else null;
163922164653 defer if (src_lock) |lock| self.register_manager.unlockReg(lock);
163923164654
163924 const dst_mcv = if (src_mcv.isRegister() and src_mcv.getReg().?.class() == self.regClassForType(dst_ty) and
164655 const dst_mcv = if (src_mcv.isRegister() and src_mcv.getReg().?.isClass(self.regClassForType(dst_ty)) and
163925164656 self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
163926164657 src_mcv
163927164658 else if (dst_abi_size <= 8)
......@@ -176332,7 +177063,11 @@ fn genSetReg(
176332177063 ),
176333177064 },
176334177065 .ip, .cr, .dr => unreachable,
176335 },
177066 } else if ((dst_reg.class() == .gphi) != (src_reg.class() == .gphi)) try self.asmRegisterRegister(
177067 .{ ._, .mov },
177068 dst_reg.to8(),
177069 src_reg.to8(),
177070 ),
176336177071 inline .register_pair,
176337177072 .register_triple,
176338177073 .register_quadruple,
......@@ -176452,7 +177187,7 @@ fn genSetReg(
176452177187 });
176453177188 },
176454177189 .register_mask => |src_reg_mask| {
176455 assert(src_reg_mask.reg.class() == .sse);
177190 assert(src_reg_mask.reg.isClass(.sse));
176456177191 const has_avx = self.hasFeature(.avx);
176457177192 const bits_reg = switch (dst_reg.class()) {
176458177193 .general_purpose => dst_reg,
......@@ -177055,7 +177790,7 @@ fn airBitCast(self: *CodeGen, inst: Air.Inst.Index) !void {
177055177790 defer if (src_lock) |lock| self.register_manager.unlockReg(lock);
177056177791
177057177792 const dst_mcv = if (src_mcv != .register_mask and
177058 (if (src_mcv.getReg()) |src_reg| src_reg.class() == .general_purpose else true) and
177793 (if (src_mcv.getReg()) |src_reg| src_reg.isClass(.general_purpose) else true) and
177059177794 dst_rc.supersetOf(src_rc) and dst_ty.abiSize(zcu) <= src_ty.abiSize(zcu) and
177060177795 dst_ty.abiAlignment(zcu).order(src_ty.abiAlignment(zcu)).compare(.lte) and
177061177796 self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) src_mcv else dst: {
......@@ -179909,7 +180644,7 @@ fn airReduce(self: *CodeGen, inst: Air.Inst.Index) !void {
179909180644 const operand_reg = registerAlias(operand_reg: {
179910180645 if (operand_mcv.isRegister()) {
179911180646 const operand_reg = operand_mcv.getReg().?;
179912 if (operand_reg.class() == .general_purpose) break :operand_reg operand_reg;
180647 if (operand_reg.isClass(.general_purpose)) break :operand_reg operand_reg;
179913180648 }
179914180649 break :operand_reg try self.copyToTmpRegister(operand_ty, operand_mcv);
179915180650 }, abi_size);
......@@ -180779,12 +181514,12 @@ fn resolveCallingConventionValues(
180779181514 ret_tracking_i += 1;
180780181515 }
180781181516 },
180782 .sseup => assert(ret_tracking[ret_tracking_i - 1].short.register.class() == .sse),
181517 .sseup => assert(ret_tracking[ret_tracking_i - 1].short.register.isClass(.sse)),
180783181518 .x87 => {
180784181519 ret_tracking[ret_tracking_i] = .init(.{ .register = abi.getCAbiX87ReturnRegs(cc)[0] });
180785181520 ret_tracking_i += 1;
180786181521 },
180787 .x87up => assert(ret_tracking[ret_tracking_i - 1].short.register.class() == .x87),
181522 .x87up => assert(ret_tracking[ret_tracking_i - 1].short.register.isClass(.x87)),
180788181523 .complex_x87 => {
180789181524 ret_tracking[ret_tracking_i] = .init(.{ .register_pair = abi.getCAbiX87ReturnRegs(cc)[0..2].* });
180790181525 ret_tracking_i += 1;
......@@ -180871,7 +181606,7 @@ fn resolveCallingConventionValues(
180871181606 arg_mcv_i += 1;
180872181607 }
180873181608 },
180874 .sseup => assert(arg_mcv[arg_mcv_i - 1].register.class() == .sse),
181609 .sseup => assert(arg_mcv[arg_mcv_i - 1].register.isClass(.sse)),
180875181610 .x87, .x87up, .complex_x87, .memory, .win_i128 => switch (cc) {
180876181611 .x86_64_sysv => switch (class) {
180877181612 .x87, .x87up, .complex_x87, .memory => break,
......@@ -181864,8 +182599,8 @@ const Temp = struct {
181864182599 const val = temp.tracking(cg).short;
181865182600 if (!mut or temp.isMut(cg)) switch (val) {
181866182601 else => {},
181867 .register => |reg| if (reg.class() == rc) return false,
181868 .register_offset => |reg_off| if (reg_off.reg.class() == rc and reg_off.off == 0) return false,
182602 .register => |reg| if (reg.isClass(rc)) return false,
182603 .register_offset => |reg_off| if (reg_off.off == 0 and reg_off.reg.isClass(rc)) return false,
181869182604 };
181870182605 const ty = temp.typeOf(cg);
181871182606 const new_temp_index = cg.next_temp_index;
......@@ -185888,6 +186623,21 @@ const Temp = struct {
185888186623 var ops: [2]Temp = .{ lhs.*, rhs.* };
185889186624 var res: [1]Temp = undefined;
185890186625 try cg.select(&res, &.{lhs.typeOf(cg)}, &ops, comptime &.{ .{
186626 .src_constraints = .{ .{ .exact_signed_int = 1 }, .{ .exact_signed_int = 1 }, .any },
186627 .patterns = &.{
186628 .{ .src = .{ .any, .any, .none } },
186629 },
186630 .dst_temps = .{ .{ .imm = 0 }, .unused },
186631 .each = .{ .once = &.{} },
186632 }, .{
186633 .src_constraints = .{ .{ .exact_unsigned_int = 1 }, .{ .exact_unsigned_int = 1 }, .any },
186634 .patterns = &.{
186635 .{ .src = .{ .mut_mem, .any, .none } },
186636 .{ .src = .{ .to_mut_gpr, .any, .none } },
186637 },
186638 .dst_temps = .{ .{ .ref = .src0 }, .unused },
186639 .each = .{ .once = &.{} },
186640 }, .{
185891186641 .src_constraints = .{ .{ .signed_int = .byte }, .{ .signed_int = .byte }, .any },
185892186642 .patterns = &.{
185893186643 .{ .src = .{ .mem, .mem, .none } },
......@@ -186072,8 +186822,8 @@ const Temp = struct {
186072186822 .src_constraints = .{ .{ .signed_int = .xword }, .{ .signed_int = .xword }, .any },
186073186823 .patterns = &.{
186074186824 .{ .src = .{
186075 .{ .to_param_gpr_pair = .{ .cc = .ccc, .index = 0 } },
186076 .{ .to_param_gpr_pair = .{ .cc = .ccc, .index = 2 } },
186825 .{ .to_param_gpr_pair = .{ .cc = .ccc, .at = 0 } },
186826 .{ .to_param_gpr_pair = .{ .cc = .ccc, .at = 2 } },
186077186827 .none,
186078186828 } },
186079186829 },
......@@ -186091,7 +186841,7 @@ const Temp = struct {
186091186841 .unused,
186092186842 .unused,
186093186843 },
186094 .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .index = 0 } }, .unused },
186844 .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .at = 0 } }, .unused },
186095186845 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
186096186846 .each = .{ .once = &.{
186097186847 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
......@@ -186101,8 +186851,8 @@ const Temp = struct {
186101186851 .src_constraints = .{ .{ .unsigned_int = .xword }, .{ .unsigned_int = .xword }, .any },
186102186852 .patterns = &.{
186103186853 .{ .src = .{
186104 .{ .to_param_gpr_pair = .{ .cc = .ccc, .index = 0 } },
186105 .{ .to_param_gpr_pair = .{ .cc = .ccc, .index = 2 } },
186854 .{ .to_param_gpr_pair = .{ .cc = .ccc, .at = 0 } },
186855 .{ .to_param_gpr_pair = .{ .cc = .ccc, .at = 2 } },
186106186856 .none,
186107186857 } },
186108186858 },
......@@ -186120,7 +186870,7 @@ const Temp = struct {
186120186870 .unused,
186121186871 .unused,
186122186872 },
186123 .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .index = 0 } }, .unused },
186873 .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .at = 0 } }, .unused },
186124186874 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
186125186875 .each = .{ .once = &.{
186126186876 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
......@@ -186137,10 +186887,10 @@ const Temp = struct {
186137186887 },
186138186888 .call_frame = .{ .alignment = .@"16" },
186139186889 .extra_temps = .{
186140 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } },
186141 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } },
186142 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } },
186143 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } },
186890 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } },
186891 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
186892 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
186893 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
186144186894 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divei4" } } },
186145186895 .unused,
186146186896 .unused,
......@@ -186170,10 +186920,10 @@ const Temp = struct {
186170186920 },
186171186921 .call_frame = .{ .alignment = .@"16" },
186172186922 .extra_temps = .{
186173 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } },
186174 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } },
186175 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } },
186176 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } },
186923 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } },
186924 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
186925 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
186926 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
186177186927 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__udivei4" } } },
186178186928 .unused,
186179186929 .unused,
......@@ -186534,12 +187284,12 @@ const Temp = struct {
186534187284 .call_frame = .{ .alignment = .@"16" },
186535187285 .extra_temps = .{
186536187286 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
186537 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } },
186538 .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } },
186539 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } },
186540 .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } },
187287 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } },
187288 .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
187289 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
187290 .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
186541187291 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divti3" } } },
186542 .{ .type = .u64, .kind = .{ .ret_gpr = .{ .cc = .ccc, .index = 0 } } },
187292 .{ .type = .u64, .kind = .{ .ret_gpr = .{ .cc = .ccc, .at = 0 } } },
186543187293 .unused,
186544187294 .unused,
186545187295 .unused,
......@@ -186572,12 +187322,12 @@ const Temp = struct {
186572187322 .call_frame = .{ .alignment = .@"16" },
186573187323 .extra_temps = .{
186574187324 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
186575 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } },
186576 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } },
186577 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } },
186578 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } },
187325 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } },
187326 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
187327 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
187328 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
186579187329 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__udivti3" } } },
186580 .{ .type = .u64, .kind = .{ .ret_gpr = .{ .cc = .ccc, .index = 0 } } },
187330 .{ .type = .u64, .kind = .{ .ret_gpr = .{ .cc = .ccc, .at = 0 } } },
186581187331 .unused,
186582187332 .unused,
186583187333 .unused,
......@@ -186610,10 +187360,10 @@ const Temp = struct {
186610187360 .call_frame = .{ .alignment = .@"16" },
186611187361 .extra_temps = .{
186612187362 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
186613 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } },
186614 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } },
186615 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } },
186616 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } },
187363 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } },
187364 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
187365 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
187366 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
186617187367 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divei4" } } },
186618187368 .unused,
186619187369 .unused,
......@@ -186646,10 +187396,10 @@ const Temp = struct {
186646187396 .call_frame = .{ .alignment = .@"16" },
186647187397 .extra_temps = .{
186648187398 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
186649 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } },
186650 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } },
186651 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } },
186652 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } },
187399 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } },
187400 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
187401 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
187402 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
186653187403 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__udivei4" } } },
186654187404 .unused,
186655187405 .unused,
......@@ -187117,8 +187867,7 @@ const Select = struct {
187117187867 }
187118187868
187119187869 fn lowerReg(s: *const Select, reg: Register) Register {
187120 if (reg.class() != .x87) return reg;
187121 return @enumFromInt(@intFromEnum(Register.st0) + (@as(u3, @intCast(reg.enc())) -% s.top));
187870 return if (reg.isClass(.x87)) @enumFromInt(@intFromEnum(Register.st0) + (@as(u3, @intCast(reg.enc())) -% s.top)) else reg;
187122187871 }
187123187872
187124187873 const Case = struct {
......@@ -187505,6 +188254,8 @@ const Select = struct {
187505188254 to_gpr,
187506188255 mut_gpr,
187507188256 to_mut_gpr,
188257 to_gphi,
188258 to_mut_gphi,
187508188259 x87,
187509188260 to_x87,
187510188261 mut_x87,
......@@ -187581,84 +188332,84 @@ const Select = struct {
187581188332 .mut_mem => temp.isMut(cg) and temp.tracking(cg).short.isMemory(),
187582188333 .to_reg, .to_reg_pair, .to_param_gpr, .to_param_gpr_pair, .to_ret_gpr, .to_ret_gpr_pair => true,
187583188334 .gpr => temp.typeOf(cg).abiSize(cg.pt.zcu) <= 8 and switch (temp.tracking(cg).short) {
187584 .register => |reg| reg.class() == .general_purpose,
187585 .register_offset => |reg_off| reg_off.reg.class() == .general_purpose and reg_off.off == 0,
188335 .register => |reg| reg.isClass(.general_purpose),
188336 .register_offset => |reg_off| reg_off.reg.isClass(.general_purpose) and reg_off.off == 0,
187586188337 else => false,
187587188338 },
187588188339 .immut_gpr => !temp.isMut(cg) and temp.typeOf(cg).abiSize(cg.pt.zcu) <= 8 and switch (temp.tracking(cg).short) {
187589 .register => |reg| reg.class() == .general_purpose,
187590 .register_offset => |reg_off| reg_off.reg.class() == .general_purpose and reg_off.off == 0,
188340 .register => |reg| reg.isClass(.general_purpose),
188341 .register_offset => |reg_off| reg_off.reg.isClass(.general_purpose) and reg_off.off == 0,
187591188342 else => false,
187592188343 },
187593188344 .mut_gpr => temp.isMut(cg) and temp.typeOf(cg).abiSize(cg.pt.zcu) <= 8 and switch (temp.tracking(cg).short) {
187594 .register => |reg| reg.class() == .general_purpose,
187595 .register_offset => |reg_off| reg_off.reg.class() == .general_purpose and reg_off.off == 0,
188345 .register => |reg| reg.isClass(.general_purpose),
188346 .register_offset => |reg_off| reg_off.reg.isClass(.general_purpose) and reg_off.off == 0,
187596188347 else => false,
187597188348 },
187598 .to_gpr, .to_mut_gpr => temp.typeOf(cg).abiSize(cg.pt.zcu) <= 8,
188349 .to_gpr, .to_mut_gpr, .to_gphi, .to_mut_gphi => temp.typeOf(cg).abiSize(cg.pt.zcu) <= 8,
187599188350 .x87 => switch (temp.tracking(cg).short) {
187600 .register => |reg| reg.class() == .x87,
187601 .register_offset => |reg_off| reg_off.reg.class() == .x87 and reg_off.off == 0,
188351 .register => |reg| reg.isClass(.x87),
188352 .register_offset => |reg_off| reg_off.reg.isClass(.x87) and reg_off.off == 0,
187602188353 else => false,
187603188354 },
187604188355 .mut_x87 => temp.isMut(cg) and switch (temp.tracking(cg).short) {
187605 .register => |reg| reg.class() == .x87,
187606 .register_offset => |reg_off| reg_off.reg.class() == .x87 and reg_off.off == 0,
188356 .register => |reg| reg.isClass(.x87),
188357 .register_offset => |reg_off| reg_off.reg.isClass(.x87) and reg_off.off == 0,
187607188358 else => false,
187608188359 },
187609188360 .to_x87, .to_mut_x87 => true,
187610188361 .mmx => switch (temp.tracking(cg).short) {
187611 .register => |reg| reg.class() == .mmx,
187612 .register_offset => |reg_off| reg_off.reg.class() == .mmx and reg_off.off == 0,
188362 .register => |reg| reg.isClass(.mmx),
188363 .register_offset => |reg_off| reg_off.reg.isClass(.mmx) and reg_off.off == 0,
187613188364 else => false,
187614188365 },
187615188366 .mut_mmx => temp.isMut(cg) and switch (temp.tracking(cg).short) {
187616 .register => |reg| reg.class() == .mmx,
187617 .register_offset => |reg_off| reg_off.reg.class() == .mmx and reg_off.off == 0,
188367 .register => |reg| reg.isClass(.mmx),
188368 .register_offset => |reg_off| reg_off.reg.isClass(.mmx) and reg_off.off == 0,
187618188369 else => false,
187619188370 },
187620188371 .to_mmx, .to_mut_mmx => true,
187621188372 .mm => temp.typeOf(cg).abiSize(cg.pt.zcu) == 8 and switch (temp.tracking(cg).short) {
187622 .register => |reg| reg.class() == .mmx,
187623 .register_offset => |reg_off| reg_off.reg.class() == .mmx and reg_off.off == 0,
188373 .register => |reg| reg.isClass(.mmx),
188374 .register_offset => |reg_off| reg_off.reg.isClass(.mmx) and reg_off.off == 0,
187624188375 else => false,
187625188376 },
187626188377 .mut_mm => temp.isMut(cg) and temp.typeOf(cg).abiSize(cg.pt.zcu) == 8 and switch (temp.tracking(cg).short) {
187627 .register => |reg| reg.class() == .mmx,
187628 .register_offset => |reg_off| reg_off.reg.class() == .mmx and reg_off.off == 0,
188378 .register => |reg| reg.isClass(.mmx),
188379 .register_offset => |reg_off| reg_off.reg.isClass(.mmx) and reg_off.off == 0,
187629188380 else => false,
187630188381 },
187631188382 .to_mm, .to_mut_mm => temp.typeOf(cg).abiSize(cg.pt.zcu) == 8,
187632188383 .sse => switch (temp.tracking(cg).short) {
187633 .register => |reg| reg.class() == .sse,
187634 .register_offset => |reg_off| reg_off.reg.class() == .sse and reg_off.off == 0,
188384 .register => |reg| reg.isClass(.sse),
188385 .register_offset => |reg_off| reg_off.reg.isClass(.sse) and reg_off.off == 0,
187635188386 else => false,
187636188387 },
187637188388 .mut_sse => temp.isMut(cg) and switch (temp.tracking(cg).short) {
187638 .register => |reg| reg.class() == .sse,
187639 .register_offset => |reg_off| reg_off.reg.class() == .sse and reg_off.off == 0,
188389 .register => |reg| reg.isClass(.sse),
188390 .register_offset => |reg_off| reg_off.reg.isClass(.sse) and reg_off.off == 0,
187640188391 else => false,
187641188392 },
187642188393 .to_sse, .to_mut_sse => true,
187643188394 .xmm => temp.typeOf(cg).abiSize(cg.pt.zcu) == 16 and switch (temp.tracking(cg).short) {
187644 .register => |reg| reg.class() == .sse,
187645 .register_offset => |reg_off| reg_off.reg.class() == .sse and reg_off.off == 0,
188395 .register => |reg| reg.isClass(.sse),
188396 .register_offset => |reg_off| reg_off.reg.isClass(.sse) and reg_off.off == 0,
187646188397 else => false,
187647188398 },
187648188399 .mut_xmm => temp.isMut(cg) and temp.typeOf(cg).abiSize(cg.pt.zcu) == 16 and switch (temp.tracking(cg).short) {
187649 .register => |reg| reg.class() == .sse,
187650 .register_offset => |reg_off| reg_off.reg.class() == .sse and reg_off.off == 0,
188400 .register => |reg| reg.isClass(.sse),
188401 .register_offset => |reg_off| reg_off.reg.isClass(.sse) and reg_off.off == 0,
187651188402 else => false,
187652188403 },
187653188404 .to_xmm, .to_mut_xmm => temp.typeOf(cg).abiSize(cg.pt.zcu) == 16,
187654188405 .ymm => temp.typeOf(cg).abiSize(cg.pt.zcu) == 32 and switch (temp.tracking(cg).short) {
187655 .register => |reg| reg.class() == .sse,
187656 .register_offset => |reg_off| reg_off.reg.class() == .sse and reg_off.off == 0,
188406 .register => |reg| reg.isClass(.sse),
188407 .register_offset => |reg_off| reg_off.reg.isClass(.sse) and reg_off.off == 0,
187657188408 else => false,
187658188409 },
187659188410 .mut_ymm => temp.isMut(cg) and temp.typeOf(cg).abiSize(cg.pt.zcu) == 32 and switch (temp.tracking(cg).short) {
187660 .register => |reg| reg.class() == .sse,
187661 .register_offset => |reg_off| reg_off.reg.class() == .sse and reg_off.off == 0,
188411 .register => |reg| reg.isClass(.sse),
188412 .register_offset => |reg_off| reg_off.reg.isClass(.sse) and reg_off.off == 0,
187662188413 else => false,
187663188414 },
187664188415 .to_ymm, .to_mut_ymm => temp.typeOf(cg).abiSize(cg.pt.zcu) == 32,
......@@ -187684,12 +188435,14 @@ const Select = struct {
187684188435 .mut_mem, .to_mut_mem => try temp.toBase(true, cg),
187685188436 .to_reg => |reg| try temp.toReg(reg, cg),
187686188437 .to_reg_pair => |regs| try temp.toRegPair(regs, cg),
187687 .to_param_gpr => |param_spec| try temp.toReg(abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.index], cg),
187688 .to_param_gpr_pair => |param_spec| try temp.toRegPair(abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.index..][0..2].*, cg),
187689 .to_ret_gpr => |ret_spec| try temp.toReg(abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.index], cg),
187690 .to_ret_gpr_pair => |ret_spec| try temp.toRegPair(abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.index..][0..2].*, cg),
188438 .to_param_gpr => |param_spec| try temp.toReg(abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.at], cg),
188439 .to_param_gpr_pair => |param_spec| try temp.toRegPair(abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.at..][0..2].*, cg),
188440 .to_ret_gpr => |ret_spec| try temp.toReg(abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.at], cg),
188441 .to_ret_gpr_pair => |ret_spec| try temp.toRegPair(abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.at..][0..2].*, cg),
187691188442 .gpr, .immut_gpr, .to_gpr => try temp.toRegClass(false, .general_purpose, cg),
187692188443 .mut_gpr, .to_mut_gpr => try temp.toRegClass(true, .general_purpose, cg),
188444 .to_gphi => try temp.toRegClass(false, .gphi, cg),
188445 .to_mut_gphi => try temp.toRegClass(true, .gphi, cg),
187693188446 .x87, .to_x87 => try temp.toRegClass(false, .x87, cg),
187694188447 .mut_x87, .to_mut_x87 => try temp.toRegClass(true, .x87, cg),
187695188448 .mmx, .to_mmx, .mm, .to_mm => try temp.toRegClass(false, .mmx, cg),
......@@ -187761,7 +188514,7 @@ const Select = struct {
187761188514
187762188515 const CallConvRegSpec = struct {
187763188516 cc: Case.CallConv,
187764 index: u2,
188517 at: u2,
187765188518
187766188519 fn tag(spec: CallConvRegSpec, cg: *const CodeGen) std.builtin.CallingConvention.Tag {
187767188520 return switch (spec.cc) {
......@@ -187778,10 +188531,10 @@ const Select = struct {
187778188531 else => return reg_locks,
187779188532 .reg => |reg| .{ reg, .none },
187780188533 .reg_pair => |regs| regs,
187781 .param_gpr => |param_spec| abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.index..][0..1].* ++ .{.none},
187782 .param_gpr_pair => |param_spec| abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.index..][0..2].*,
187783 .ret_gpr => |ret_spec| abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.index..][0..1].* ++ .{.none},
187784 .ret_gpr_pair => |ret_spec| abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.index..][0..2].*,
188534 .param_gpr => |param_spec| abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.at..][0..1].* ++ .{.none},
188535 .param_gpr_pair => |param_spec| abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.at..][0..2].*,
188536 .ret_gpr => |ret_spec| abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.at..][0..1].* ++ .{.none},
188537 .ret_gpr_pair => |ret_spec| abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.at..][0..2].*,
187785188538 };
187786188539 for (regs, &reg_locks) |reg, *reg_lock| {
187787188540 if (reg == .none) continue;
......@@ -187791,13 +188544,6 @@ const Select = struct {
187791188544 }
187792188545 return reg_locks;
187793188546 }
187794
187795 fn finish(kind: Kind, temp: Temp, cg: *CodeGen) void {
187796 switch (kind) {
187797 else => {},
187798 inline .rc_mask, .mut_rc_mask, .ref_mask => |mask| temp.asMask(mask.info, cg),
187799 }
187800 }
187801188547 };
187802188548
187803188549 fn create(spec: TempSpec, s: *const Select) InnerError!struct { Temp, bool } {
......@@ -187822,24 +188568,24 @@ const Select = struct {
187822188568 .reg => |reg| .{ try cg.tempInit(spec.type, .{ .register = reg }), true },
187823188569 .reg_pair => |regs| .{ try cg.tempInit(spec.type, .{ .register_pair = regs }), true },
187824188570 .param_gpr => |param_spec| .{ try cg.tempInit(spec.type, .{
187825 .register = abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.index],
188571 .register = abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.at],
187826188572 }), true },
187827188573 .param_gpr_pair => |param_spec| .{ try cg.tempInit(spec.type, .{
187828 .register_pair = abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.index..][0..2].*,
188574 .register_pair = abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.at..][0..2].*,
187829188575 }), true },
187830188576 .ret_gpr => |ret_spec| .{ try cg.tempInit(spec.type, .{
187831 .register = abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.index],
188577 .register = abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.at],
187832188578 }), true },
187833188579 .ret_gpr_pair => |ret_spec| .{ try cg.tempInit(spec.type, .{
187834 .register_pair = abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.index..][0..2].*,
188580 .register_pair = abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.at..][0..2].*,
187835188581 }), true },
187836188582 .rc => |rc| .{ try cg.tempAllocReg(spec.type, regSetForRegClass(rc)), true },
187837188583 .rc_pair => |rc| .{ try cg.tempAllocRegPair(spec.type, regSetForRegClass(rc)), true },
187838188584 .mut_rc => |ref_rc| {
187839188585 const temp = ref_rc.ref.tempOf(s);
187840188586 if (temp.isMut(cg)) switch (temp.tracking(cg).short) {
187841 .register => |reg| if (reg.class() == ref_rc.rc) return .{ temp, false },
187842 .register_offset => |reg_off| if (reg_off.off == 0 and reg_off.reg.class() == ref_rc.rc) return .{ temp, false },
188587 .register => |reg| if (reg.isClass(ref_rc.rc)) return .{ temp, false },
188588 .register_offset => |reg_off| if (reg_off.off == 0 and reg_off.reg.isClass(ref_rc.rc)) return .{ temp, false },
187843188589 else => {},
187844188590 };
187845188591 return .{ try cg.tempAllocReg(spec.type, regSetForRegClass(ref_rc.rc)), true };
......@@ -187849,8 +188595,8 @@ const Select = struct {
187849188595 .mut_rc_mask => |ref_rc_mask| {
187850188596 const temp = ref_rc_mask.ref.tempOf(s);
187851188597 if (temp.isMut(cg)) switch (temp.tracking(cg).short) {
187852 .register => |reg| if (reg.class() == ref_rc_mask.rc) return .{ temp, false },
187853 .register_offset => |reg_off| if (reg_off.off == 0 and reg_off.reg.class() == ref_rc_mask.rc) return .{ temp, false },
188598 .register => |reg| if (reg.isClass(ref_rc_mask.rc)) return .{ temp, false },
188599 .register_offset => |reg_off| if (reg_off.off == 0 and reg_off.reg.isClass(ref_rc_mask.rc)) return .{ temp, false },
187854188600 else => {},
187855188601 };
187856188602 return .{ try cg.tempAllocReg(spec.type, regSetForRegClass(ref_rc_mask.rc)), true };
......@@ -188228,6 +188974,14 @@ const Select = struct {
188228188974 } }), true },
188229188975 };
188230188976 }
188977
188978 fn finish(spec: TempSpec, temp: *Temp, cg: *CodeGen) InnerError!void {
188979 switch (spec.kind) {
188980 else => {},
188981 inline .rc_mask, .mut_rc_mask, .ref_mask => |mask| temp.asMask(mask.info, cg),
188982 }
188983 cg.temp_type[@intFromEnum(temp.unwrap(cg).temp)] = spec.type;
188984 }
188231188985 };
188232188986
188233188987 const Instruction = struct {
......@@ -188255,8 +189009,7 @@ const Select = struct {
188255189009
188256189010 const Tag = enum(u3) {
188257189011 none,
188258 backward_label,
188259 forward_label,
189012 label,
188260189013 ref,
188261189014 simm,
188262189015 uimm,
......@@ -188626,16 +189379,16 @@ const Select = struct {
188626189379
188627189380 const @"_": Select.Operand = .{ .flags = .{ .tag = .none } };
188628189381
188629 const @"0b": Select.Operand = .{ .flags = .{ .tag = .backward_label, .base = .{ .ref = .tmp0, .size = .none } } };
188630 const @"0f": Select.Operand = .{ .flags = .{ .tag = .forward_label, .base = .{ .ref = .tmp0, .size = .none } } };
188631 const @"1b": Select.Operand = .{ .flags = .{ .tag = .backward_label, .base = .{ .ref = .tmp1, .size = .none } } };
188632 const @"1f": Select.Operand = .{ .flags = .{ .tag = .forward_label, .base = .{ .ref = .tmp1, .size = .none } } };
188633 const @"2b": Select.Operand = .{ .flags = .{ .tag = .backward_label, .base = .{ .ref = .tmp2, .size = .none } } };
188634 const @"2f": Select.Operand = .{ .flags = .{ .tag = .forward_label, .base = .{ .ref = .tmp2, .size = .none } } };
188635 const @"3b": Select.Operand = .{ .flags = .{ .tag = .backward_label, .base = .{ .ref = .tmp3, .size = .none } } };
188636 const @"3f": Select.Operand = .{ .flags = .{ .tag = .forward_label, .base = .{ .ref = .tmp3, .size = .none } } };
188637 const @"4b": Select.Operand = .{ .flags = .{ .tag = .backward_label, .base = .{ .ref = .tmp4, .size = .none } } };
188638 const @"4f": Select.Operand = .{ .flags = .{ .tag = .forward_label, .base = .{ .ref = .tmp4, .size = .none } } };
189382 const @"0b": Select.Operand = .{ .flags = .{ .tag = .label }, .imm = ~@as(i32, 0) };
189383 const @"0f": Select.Operand = .{ .flags = .{ .tag = .label }, .imm = @as(i32, 0) };
189384 const @"1b": Select.Operand = .{ .flags = .{ .tag = .label }, .imm = ~@as(i32, 1) };
189385 const @"1f": Select.Operand = .{ .flags = .{ .tag = .label }, .imm = @as(i32, 1) };
189386 const @"2b": Select.Operand = .{ .flags = .{ .tag = .label }, .imm = ~@as(i32, 2) };
189387 const @"2f": Select.Operand = .{ .flags = .{ .tag = .label }, .imm = @as(i32, 2) };
189388 const @"3b": Select.Operand = .{ .flags = .{ .tag = .label }, .imm = ~@as(i32, 3) };
189389 const @"3f": Select.Operand = .{ .flags = .{ .tag = .label }, .imm = @as(i32, 3) };
189390 const @"4b": Select.Operand = .{ .flags = .{ .tag = .label }, .imm = ~@as(i32, 4) };
189391 const @"4f": Select.Operand = .{ .flags = .{ .tag = .label }, .imm = @as(i32, 4) };
188639189392
188640189393 const tmp0l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp0l } };
188641189394 const tmp0h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp0h } };
......@@ -188648,6 +189401,8 @@ const Select = struct {
188648189401 const tmp0t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp0t } };
188649189402 const tmp0x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp0x } };
188650189403 const tmp0y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp0y } };
189404 const tmp0q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp0q }, .imm = 1 };
189405 const tmp0q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp0q }, .imm = 2 };
188651189406
188652189407 const tmp1l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp1l } };
188653189408 const tmp1h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp1h } };
......@@ -188660,6 +189415,8 @@ const Select = struct {
188660189415 const tmp1t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp1t } };
188661189416 const tmp1x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp1x } };
188662189417 const tmp1y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp1y } };
189418 const tmp1q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp1q }, .imm = 1 };
189419 const tmp1q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp1q }, .imm = 2 };
188663189420
188664189421 const tmp2l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp2l } };
188665189422 const tmp2h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp2h } };
......@@ -188672,6 +189429,8 @@ const Select = struct {
188672189429 const tmp2t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp2t } };
188673189430 const tmp2x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp2x } };
188674189431 const tmp2y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp2y } };
189432 const tmp2q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp2q }, .imm = 1 };
189433 const tmp2q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp2q }, .imm = 2 };
188675189434
188676189435 const tmp3l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp3l } };
188677189436 const tmp3h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp3h } };
......@@ -188684,6 +189443,8 @@ const Select = struct {
188684189443 const tmp3t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp3t } };
188685189444 const tmp3x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp3x } };
188686189445 const tmp3y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp3y } };
189446 const tmp3q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp3q }, .imm = 1 };
189447 const tmp3q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp3q }, .imm = 2 };
188687189448
188688189449 const tmp4l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp4l } };
188689189450 const tmp4h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp4h } };
......@@ -188696,6 +189457,8 @@ const Select = struct {
188696189457 const tmp4t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp4t } };
188697189458 const tmp4x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp4x } };
188698189459 const tmp4y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp4y } };
189460 const tmp4q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp4q }, .imm = 1 };
189461 const tmp4q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp4q }, .imm = 2 };
188699189462
188700189463 const tmp5l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp5l } };
188701189464 const tmp5h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp5h } };
......@@ -188708,6 +189471,8 @@ const Select = struct {
188708189471 const tmp5t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp5t } };
188709189472 const tmp5x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp5x } };
188710189473 const tmp5y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp5y } };
189474 const tmp5q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp5q }, .imm = 1 };
189475 const tmp5q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp5q }, .imm = 2 };
188711189476
188712189477 const tmp6l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp6l } };
188713189478 const tmp6h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp6h } };
......@@ -188720,6 +189485,8 @@ const Select = struct {
188720189485 const tmp6t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp6t } };
188721189486 const tmp6x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp6x } };
188722189487 const tmp6y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp6y } };
189488 const tmp6q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp6q }, .imm = 1 };
189489 const tmp6q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp6q }, .imm = 2 };
188723189490
188724189491 const tmp7l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp7l } };
188725189492 const tmp7h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp7h } };
......@@ -188732,6 +189499,8 @@ const Select = struct {
188732189499 const tmp7t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp7t } };
188733189500 const tmp7x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp7x } };
188734189501 const tmp7y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp7y } };
189502 const tmp7q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp7q }, .imm = 1 };
189503 const tmp7q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp7q }, .imm = 2 };
188735189504
188736189505 const tmp8l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp8l } };
188737189506 const tmp8h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp8h } };
......@@ -188744,6 +189513,8 @@ const Select = struct {
188744189513 const tmp8t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp8t } };
188745189514 const tmp8x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp8x } };
188746189515 const tmp8y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp8y } };
189516 const tmp8q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp8q }, .imm = 1 };
189517 const tmp8q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp8q }, .imm = 2 };
188747189518
188748189519 const tmp9l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp9l } };
188749189520 const tmp9h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp9h } };
......@@ -188756,6 +189527,8 @@ const Select = struct {
188756189527 const tmp9t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp9t } };
188757189528 const tmp9x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp9x } };
188758189529 const tmp9y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp9y } };
189530 const tmp9q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp9q }, .imm = 1 };
189531 const tmp9q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp9q }, .imm = 2 };
188759189532
188760189533 const tmp10l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp10l } };
188761189534 const tmp10h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp10h } };
......@@ -188768,6 +189541,8 @@ const Select = struct {
188768189541 const tmp10t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp10t } };
188769189542 const tmp10x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp10x } };
188770189543 const tmp10y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp10y } };
189544 const tmp10q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp10q }, .imm = 1 };
189545 const tmp10q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp10q }, .imm = 2 };
188771189546
188772189547 const dst0l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst0l } };
188773189548 const dst0h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst0h } };
......@@ -188780,6 +189555,8 @@ const Select = struct {
188780189555 const dst0t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst0t } };
188781189556 const dst0x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst0x } };
188782189557 const dst0y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst0y } };
189558 const dst0q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst0q }, .imm = 1 };
189559 const dst0q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst0q }, .imm = 2 };
188783189560
188784189561 const dst1l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst1l } };
188785189562 const dst1h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst1h } };
......@@ -188792,6 +189569,8 @@ const Select = struct {
188792189569 const dst1t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst1t } };
188793189570 const dst1x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst1x } };
188794189571 const dst1y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst1y } };
189572 const dst1q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst1q }, .imm = 1 };
189573 const dst1q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst1q }, .imm = 2 };
188795189574
188796189575 const src0l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src0l } };
188797189576 const src0h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src0h } };
......@@ -188804,6 +189583,8 @@ const Select = struct {
188804189583 const src0t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src0t } };
188805189584 const src0x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src0x } };
188806189585 const src0y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src0y } };
189586 const src0q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src0q }, .imm = 1 };
189587 const src0q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src0q }, .imm = 2 };
188807189588
188808189589 const src1l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src1l } };
188809189590 const src1h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src1h } };
......@@ -188816,6 +189597,8 @@ const Select = struct {
188816189597 const src1t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src1t } };
188817189598 const src1x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src1x } };
188818189599 const src1y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src1y } };
189600 const src1q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src1q }, .imm = 1 };
189601 const src1q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src1q }, .imm = 2 };
188819189602
188820189603 const src2l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src2l } };
188821189604 const src2h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src2h } };
......@@ -188828,6 +189611,8 @@ const Select = struct {
188828189611 const src2t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src2t } };
188829189612 const src2x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src2x } };
188830189613 const src2y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src2y } };
189614 const src2q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src2q }, .imm = 1 };
189615 const src2q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src2q }, .imm = 2 };
188831189616
188832189617 fn si(imm: i32) Select.Operand {
188833189618 return .{ .flags = .{ .tag = .simm }, .imm = imm };
......@@ -189207,24 +189992,41 @@ const Select = struct {
189207189992 fn lower(op: Select.Operand, s: *Select) InnerError!CodeGen.Operand {
189208189993 return switch (op.flags.tag) {
189209189994 .none => .none,
189210 .backward_label => .{ .inst = s.labels[@intFromEnum(op.flags.base.ref)].backward.? },
189211 .forward_label => for (&s.labels[@intFromEnum(op.flags.base.ref)].forward) |*label| {
189995 .label => if (op.imm < 0)
189996 .{ .inst = s.labels[@intCast(~op.imm)].backward.? }
189997 else for (&s.labels[@intCast(op.imm)].forward) |*label| {
189212189998 if (label.*) |_| continue;
189213189999 label.* = @intCast(s.cg.mir_instructions.len);
189214190000 break .{ .inst = undefined };
189215190001 } else unreachable,
189216 .ref => switch (op.flags.base.ref.valueOf(s)) {
189217 .immediate => |imm| .{ .imm = switch (op.flags.base.size) {
189218 .byte => if (std.math.cast(i8, @as(i64, @bitCast(imm)))) |simm| .s(simm) else .u(@as(u8, @intCast(imm))),
189219 .word => if (std.math.cast(i16, @as(i64, @bitCast(imm)))) |simm| .s(simm) else .u(@as(u16, @intCast(imm))),
189220 .dword => if (std.math.cast(i32, @as(i64, @bitCast(imm)))) |simm| .s(simm) else .u(@as(u32, @intCast(imm))),
189221 .qword => if (std.math.cast(i32, @as(i64, @bitCast(imm)))) |simm| .s(simm) else .u(imm),
189222 else => unreachable,
189223 } },
189224 else => |mcv| .{ .mem = try mcv.mem(s.cg, .{ .size = op.flags.base.size }) },
189225 .register => |reg| .{ .reg = s.lowerReg(reg.toSize(op.flags.base.size, s.cg.target)) },
189226 .register_mask => |reg_mask| .{ .reg = s.lowerReg(reg_mask.reg.toSize(op.flags.base.size, s.cg.target)) },
189227 .lea_symbol => |sym_off| .{ .imm = .rel(sym_off) },
190002 .ref => switch (op.imm) {
190003 else => unreachable,
190004 0 => switch (op.flags.base.ref.valueOf(s)) {
190005 .none, .unreach, .dead, .undef => unreachable,
190006 .immediate => |imm| .{ .imm = switch (op.flags.base.size) {
190007 .byte => if (std.math.cast(i8, @as(i64, @bitCast(imm)))) |simm| .s(simm) else .u(@as(u8, @intCast(imm))),
190008 .word => if (std.math.cast(i16, @as(i64, @bitCast(imm)))) |simm| .s(simm) else .u(@as(u16, @intCast(imm))),
190009 .dword => if (std.math.cast(i32, @as(i64, @bitCast(imm)))) |simm| .s(simm) else .u(@as(u32, @intCast(imm))),
190010 .qword => if (std.math.cast(i32, @as(i64, @bitCast(imm)))) |simm| .s(simm) else .u(imm),
190011 else => unreachable,
190012 } },
190013 .eflags => unreachable,
190014 .register => |reg| .{ .reg = s.lowerReg(reg.toSize(op.flags.base.size, s.cg.target)) },
190015 .register_pair, .register_triple, .register_quadruple, .register_offset, .register_overflow => unreachable,
190016 .register_mask => |reg_mask| .{ .reg = s.lowerReg(reg_mask.reg.toSize(op.flags.base.size, s.cg.target)) },
190017 else => |mcv| .{ .mem = try mcv.mem(s.cg, .{ .size = op.flags.base.size }) },
190018 .lea_symbol => |sym_off| .{ .imm = .rel(sym_off) },
190019 .load_direct, .lea_direct, .load_got, .lea_got, .lea_frame, .elementwise_args, .reserved_frame, .air_ref => unreachable,
190020 },
190021 1...2 => |imm| switch (op.flags.base.ref.valueOf(s)) {
190022 inline .register_pair, .register_triple, .register_quadruple => |regs| .{
190023 .reg = s.lowerReg(regs[@intCast(imm - 1)].toSize(op.flags.base.size, s.cg.target)),
190024 },
190025 else => |mcv| .{ .mem = try mcv.mem(s.cg, .{
190026 .size = op.flags.base.size,
190027 .disp = @as(i32, @intCast(@divExact(op.flags.base.size.bitSize(s.cg.target), 8))) * (imm - 1),
190028 }) },
190029 },
189228190030 },
189229190031 .simm => .{ .imm = .s(op.adjustedImm(i32, s)) },
189230190032 .uimm => .{ .imm = .u(@bitCast(op.adjustedImm(i64, s))) },
......@@ -189392,11 +190194,8 @@ fn select(
189392190194 },
189393190195 }
189394190196 }
189395 for (case.dst_temps[0..dst_temps.len], dst_temps, dst_tys) |tmp_kind, dst_temp, dst_ty| {
189396 tmp_kind.finish(dst_temp, cg);
189397 cg.temp_type[@intFromEnum(dst_temp.unwrap(cg).temp)] = dst_ty;
189398 }
189399190197 for (tmp_owned, s_tmp_temps) |owned, temp| if (owned) try temp.die(cg);
190198 for (dst_tys, case.dst_temps[0..dst_temps.len], dst_temps) |dst_ty, dst_kind, *dst_temp| try Select.TempSpec.finish(.{ .type = dst_ty, .kind = dst_kind }, dst_temp, cg);
189400190199 return;
189401190200 }
189402190201 }
src/arch/x86_64/abi.zig+4-4
......@@ -575,22 +575,22 @@ const RegisterBitSet = RegisterManager.RegisterBitSet;
575575pub const RegisterClass = struct {
576576 pub const gp: RegisterBitSet = blk: {
577577 var set = RegisterBitSet.initEmpty();
578 for (allocatable_regs, 0..) |reg, index| if (reg.class() == .general_purpose) set.set(index);
578 for (allocatable_regs, 0..) |reg, index| if (reg.isClass(.general_purpose)) set.set(index);
579579 break :blk set;
580580 };
581581 pub const gphi: RegisterBitSet = blk: {
582582 var set = RegisterBitSet.initEmpty();
583 for (allocatable_regs, 0..) |reg, index| if (reg.hasHi8()) set.set(index);
583 for (allocatable_regs, 0..) |reg, index| if (reg.isClass(.gphi)) set.set(index);
584584 break :blk set;
585585 };
586586 pub const x87: RegisterBitSet = blk: {
587587 var set = RegisterBitSet.initEmpty();
588 for (allocatable_regs, 0..) |reg, index| if (reg.class() == .x87) set.set(index);
588 for (allocatable_regs, 0..) |reg, index| if (reg.isClass(.x87)) set.set(index);
589589 break :blk set;
590590 };
591591 pub const sse: RegisterBitSet = blk: {
592592 var set = RegisterBitSet.initEmpty();
593 for (allocatable_regs, 0..) |reg, index| if (reg.class() == .sse) set.set(index);
593 for (allocatable_regs, 0..) |reg, index| if (reg.isClass(.sse)) set.set(index);
594594 break :blk set;
595595 };
596596};
src/arch/x86_64/bits.zig+20-13
......@@ -429,6 +429,16 @@ pub const Register = enum(u8) {
429429 };
430430 }
431431
432 pub inline fn isClass(reg: Register, rc: Class) bool {
433 switch (rc) {
434 else => return reg.class() == rc,
435 .gphi => {
436 const reg_id = reg.id();
437 return (reg_id >= comptime Register.ah.id()) and reg_id <= comptime Register.bh.id();
438 },
439 }
440 }
441
432442 pub fn id(reg: Register) u7 {
433443 const base = switch (@intFromEnum(reg)) {
434444 // zig fmt: off
......@@ -615,22 +625,17 @@ pub const Register = enum(u8) {
615625 }
616626
617627 pub fn toHi8(reg: Register) Register {
618 assert(reg.hasHi8());
628 assert(reg.isClass(.gphi));
619629 return @enumFromInt(@intFromEnum(reg) - reg.gpBase() + @intFromEnum(Register.ah));
620630 }
621631
622 pub fn hasHi8(reg: Register) bool {
623 const reg_id = reg.id();
624 return (reg_id >= comptime Register.ah.id()) and reg_id <= comptime Register.bh.id();
625 }
626
627632 pub fn to80(reg: Register) Register {
628 assert(reg.class() == .x87);
633 assert(reg.isClass(.x87));
629634 return reg;
630635 }
631636
632637 fn sseBase(reg: Register) u8 {
633 assert(reg.class() == .sse);
638 assert(reg.isClass(.sse));
634639 return switch (@intFromEnum(reg)) {
635640 @intFromEnum(Register.zmm0)...@intFromEnum(Register.zmm31) => @intFromEnum(Register.zmm0),
636641 @intFromEnum(Register.ymm0)...@intFromEnum(Register.ymm31) => @intFromEnum(Register.ymm0),
......@@ -694,11 +699,13 @@ test "Register enc - different classes" {
694699}
695700
696701test "Register classes" {
697 try expect(Register.r11.class() == .general_purpose);
698 try expect(Register.ymm11.class() == .sse);
699 try expect(Register.mm3.class() == .mmx);
700 try expect(Register.st3.class() == .x87);
701 try expect(Register.fs.class() == .segment);
702 try expect(Register.r11.isClass(.general_purpose));
703 try expect(Register.rdx.isClass(.gphi));
704 try expect(!Register.dil.isClass(.gphi));
705 try expect(Register.ymm11.isClass(.sse));
706 try expect(Register.mm3.isClass(.mmx));
707 try expect(Register.st3.isClass(.x87));
708 try expect(Register.fs.isClass(.segment));
702709}
703710
704711pub const FrameIndex = enum(u32) {
src/arch/x86_64/encoder.zig+6-6
......@@ -111,7 +111,7 @@ pub const Instruction = struct {
111111 };
112112
113113 pub fn initMoffs(reg: Register, offset: u64) Memory {
114 assert(reg.class() == .segment);
114 assert(reg.isClass(.segment));
115115 return .{ .moffs = .{ .seg = reg, .offset = offset } };
116116 }
117117
......@@ -139,7 +139,7 @@ pub const Instruction = struct {
139139 .rip => false,
140140 .sib => |s| switch (s.base) {
141141 .none, .frame, .table, .reloc, .rip_inst => false,
142 .reg => |reg| reg.class() == .segment,
142 .reg => |reg| reg.isClass(.segment),
143143 },
144144 };
145145 }
......@@ -199,7 +199,7 @@ pub const Instruction = struct {
199199 pub fn isSegmentRegister(op: Operand) bool {
200200 return switch (op) {
201201 .none => unreachable,
202 .reg => |reg| reg.class() == .segment,
202 .reg => |reg| reg.isClass(.segment),
203203 .mem => |mem| mem.isSegmentRegister(),
204204 .imm => unreachable,
205205 .bytes => unreachable,
......@@ -776,7 +776,7 @@ pub const LegacyPrefixes = packed struct {
776776 padding: u5 = 0,
777777
778778 pub fn setSegmentOverride(self: *LegacyPrefixes, reg: Register) void {
779 assert(reg.class() == .segment);
779 assert(reg.isClass(.segment));
780780 switch (reg) {
781781 .cs => self.prefix_2e = true,
782782 .ss => self.prefix_36 = true,
......@@ -2457,7 +2457,7 @@ const Assembler = struct {
24572457 .general_purpose, .segment => {
24582458 const tok = try as.expect(.string);
24592459 const base = registerFromString(as.source(tok)) orelse return error.InvalidMemoryOperand;
2460 if (base.class() != cond) return error.InvalidMemoryOperand;
2460 if (!base.isClass(cond)) return error.InvalidMemoryOperand;
24612461 res.base = base;
24622462 },
24632463 .rip => {
......@@ -2498,7 +2498,7 @@ const Assembler = struct {
24982498 error.Overflow => {
24992499 if (is_neg) return err;
25002500 if (res.base) |base| {
2501 if (base.class() != .segment) return err;
2501 if (!base.isClass(.segment)) return err;
25022502 }
25032503 const offset = try std.fmt.parseInt(u64, as.source(tok), 0);
25042504 res.offset = offset;
test/behavior/math.zig+1-1
......@@ -1893,13 +1893,13 @@ test "float divide by zero" {
18931893
18941894test "partially-runtime integer vector division would be illegal if vector elements were reordered" {
18951895 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1896 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
18971896 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
18981897 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
18991898 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
19001899 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
19011900 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
19021901 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .hexagon) return error.SkipZigTest;
1902 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
19031903
19041904 var lhs: @Vector(2, i8) = .{ -128, 5 };
19051905 const rhs: @Vector(2, i8) = .{ 1, -1 };
test/behavior/vector.zig+1-1
......@@ -559,12 +559,12 @@ test "vector comparison operators" {
559559
560560test "vector division operators" {
561561 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
562 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
563562 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
564563 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
565564 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
566565 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
567566 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
567 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
568568
569569 const S = struct {
570570 fn doTheTestDiv(comptime T: type, x: @Vector(4, T), y: @Vector(4, T)) !void {
test/behavior/x86_64/binary.zig+5-1
......@@ -5181,6 +5181,8 @@ inline fn divFloor(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(@divFloor(
51815181}
51825182test divFloor {
51835183 const test_div_floor = binary(divFloor, .{ .compare = .approx_int });
5184 try test_div_floor.testInts();
5185 try test_div_floor.testIntVectors();
51845186 try test_div_floor.testFloats();
51855187 try test_div_floor.testFloatVectors();
51865188}
......@@ -5198,7 +5200,7 @@ test rem {
51985200
51995201inline fn mod(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(@mod(lhs, rhs)) {
52005202 // workaround llvm backend bugs
5201 if (@inComptime()) {
5203 if (@inComptime() and @typeInfo(Scalar(Type)) == .float) {
52025204 const scalarMod = struct {
52035205 fn scalarMod(scalar_lhs: Scalar(Type), scalar_rhs: Scalar(Type)) Scalar(Type) {
52045206 const scalar_rem = @rem(scalar_lhs, scalar_rhs);
......@@ -5218,6 +5220,8 @@ inline fn mod(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(@mod(lhs, rhs))
52185220}
52195221test mod {
52205222 const test_mod = binary(mod, .{});
5223 try test_mod.testInts();
5224 try test_mod.testIntVectors();
52215225 try test_mod.testFloats();
52225226 try test_mod.testFloatVectors();
52235227}