authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-02-18 07:49:38-05:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-02-18 09:47:44-05:00
log7d70d7b215b1c388ee4c555ddd13839d7161d5de
tree98e03629c6a558294855a22c5d8127f246441c5b
parentebea56d279ecb09fa829881ee49bb070b6c4d833

x86_64: rewrite scalar `@popCount`


2 files changed, 904 insertions(+), 2 deletions(-)

src/arch/x86_64/CodeGen.zig+896-2
......@@ -2418,7 +2418,7 @@ fn genBodyBlock(self: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
24182418}
24192419
24202420fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2421 @setEvalBranchQuota(12_700);
2421 @setEvalBranchQuota(12_900);
24222422 const pt = cg.pt;
24232423 const zcu = pt.zcu;
24242424 const ip = &zcu.intern_pool;
......@@ -2475,7 +2475,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
24752475
24762476 .bitcast => try cg.airBitCast(inst),
24772477
2478 .popcount => try cg.airPopCount(inst),
24792478 .bit_reverse => try cg.airBitReverse(inst),
24802479 .splat => try cg.airSplat(inst),
24812480 .select => try cg.airSelect(inst),
......@@ -30480,6 +30479,895 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3048030479 };
3048130480 try res[0].finish(inst, &.{ty_op.operand}, &ops, cg);
3048230481 },
30482 .popcount => |air_tag| if (use_old) try cg.airPopCount(inst) else fallback: {
30483 const ty_op = air_datas[@intFromEnum(inst)].ty_op;
30484 if (ty_op.ty.toType().isVector(zcu)) break :fallback try cg.airPopCount(inst);
30485 var ops = try cg.tempsFromOperands(inst, .{ty_op.operand});
30486 var res: [1]Temp = undefined;
30487 cg.select(&res, &.{ty_op.ty.toType()}, &ops, comptime &.{ .{
30488 .src_constraints = .{ .{ .exact_signed_int = 1 }, .any, .any },
30489 .patterns = &.{
30490 .{ .src = .{ .mut_mem, .none, .none } },
30491 .{ .src = .{ .to_mut_gpr, .none, .none } },
30492 },
30493 .dst_temps = .{ .{ .ref = .src0 }, .unused },
30494 .clobbers = .{ .eflags = true },
30495 .each = .{ .once = &.{
30496 .{ ._, ._, .neg, .dst0b, ._, ._, ._ },
30497 } },
30498 }, .{
30499 .src_constraints = .{ .{ .exact_unsigned_int = 1 }, .any, .any },
30500 .patterns = &.{
30501 .{ .src = .{ .mut_mem, .none, .none } },
30502 .{ .src = .{ .to_mut_gpr, .none, .none } },
30503 },
30504 .dst_temps = .{ .{ .ref = .src0 }, .unused },
30505 .each = .{ .once = &.{} },
30506 }, .{
30507 .required_features = .{ .popcnt, null, null, null },
30508 .src_constraints = .{ .{ .unsigned_or_exact_int = .byte }, .any, .any },
30509 .patterns = &.{
30510 .{ .src = .{ .mem, .none, .none } },
30511 .{ .src = .{ .to_gpr, .none, .none } },
30512 },
30513 .dst_temps = .{ .{ .rc = .general_purpose }, .unused },
30514 .clobbers = .{ .eflags = true },
30515 .each = .{ .once = &.{
30516 .{ ._, ._, .movzx, .dst0d, .src0b, ._, ._ },
30517 .{ ._, ._, .popcnt, .dst0d, .dst0d, ._, ._ },
30518 } },
30519 }, .{
30520 .required_features = .{ .popcnt, null, null, null },
30521 .src_constraints = .{ .{ .unsigned_or_exact_int = .word }, .any, .any },
30522 .patterns = &.{
30523 .{ .src = .{ .mem, .none, .none } },
30524 .{ .src = .{ .to_gpr, .none, .none } },
30525 },
30526 .dst_temps = .{ .{ .rc = .general_purpose }, .unused },
30527 .clobbers = .{ .eflags = true },
30528 .each = .{ .once = &.{
30529 .{ ._, ._, .xor, .dst0d, .dst0d, ._, ._ },
30530 .{ ._, ._, .popcnt, .dst0w, .src0w, ._, ._ },
30531 } },
30532 }, .{
30533 .required_features = .{ .popcnt, null, null, null },
30534 .src_constraints = .{ .{ .unsigned_or_exact_int = .dword }, .any, .any },
30535 .patterns = &.{
30536 .{ .src = .{ .mut_gpr, .none, .none } },
30537 },
30538 .dst_temps = .{ .{ .ref = .src0 }, .unused },
30539 .clobbers = .{ .eflags = true },
30540 .each = .{ .once = &.{
30541 .{ ._, ._, .popcnt, .dst0d, .src0d, ._, ._ },
30542 } },
30543 }, .{
30544 .required_features = .{ .popcnt, .false_deps_popcnt, null, null },
30545 .src_constraints = .{ .{ .unsigned_or_exact_int = .dword }, .any, .any },
30546 .patterns = &.{
30547 .{ .src = .{ .mem, .none, .none } },
30548 .{ .src = .{ .to_gpr, .none, .none } },
30549 },
30550 .dst_temps = .{ .{ .rc = .general_purpose }, .unused },
30551 .clobbers = .{ .eflags = true },
30552 .each = .{ .once = &.{
30553 .{ ._, ._, .xor, .dst0d, .dst0d, ._, ._ },
30554 .{ ._, ._, .popcnt, .dst0d, .src0d, ._, ._ },
30555 } },
30556 }, .{
30557 .required_features = .{ .popcnt, null, null, null },
30558 .src_constraints = .{ .{ .unsigned_or_exact_int = .dword }, .any, .any },
30559 .patterns = &.{
30560 .{ .src = .{ .mem, .none, .none } },
30561 .{ .src = .{ .to_gpr, .none, .none } },
30562 },
30563 .dst_temps = .{ .{ .mut_rc = .{ .ref = .src0, .rc = .general_purpose } }, .unused },
30564 .clobbers = .{ .eflags = true },
30565 .each = .{ .once = &.{
30566 .{ ._, ._, .popcnt, .dst0d, .src0d, ._, ._ },
30567 } },
30568 }, .{
30569 .required_features = .{ .popcnt, null, null, null },
30570 .src_constraints = .{ .{ .signed_int = .dword }, .any, .any },
30571 .patterns = &.{
30572 .{ .src = .{ .to_mut_gpr, .none, .none } },
30573 },
30574 .dst_temps = .{ .{ .ref = .src0 }, .unused },
30575 .clobbers = .{ .eflags = true },
30576 .each = .{ .once = &.{
30577 .{ ._, ._l, .sh, .src0d, .uia(32, .src0, .sub_bit_size), ._, ._ },
30578 .{ ._, ._, .popcnt, .dst0d, .src0d, ._, ._ },
30579 } },
30580 }, .{
30581 .required_features = .{ .@"64bit", .popcnt, null, null },
30582 .src_constraints = .{ .{ .unsigned_or_exact_int = .qword }, .any, .any },
30583 .patterns = &.{
30584 .{ .src = .{ .mut_gpr, .none, .none } },
30585 },
30586 .dst_temps = .{ .{ .ref = .src0 }, .unused },
30587 .clobbers = .{ .eflags = true },
30588 .each = .{ .once = &.{
30589 .{ ._, ._, .popcnt, .dst0q, .src0q, ._, ._ },
30590 } },
30591 }, .{
30592 .required_features = .{ .@"64bit", .popcnt, .false_deps_popcnt, null },
30593 .src_constraints = .{ .{ .unsigned_or_exact_int = .qword }, .any, .any },
30594 .patterns = &.{
30595 .{ .src = .{ .mem, .none, .none } },
30596 .{ .src = .{ .to_gpr, .none, .none } },
30597 },
30598 .dst_temps = .{ .{ .rc = .general_purpose }, .unused },
30599 .clobbers = .{ .eflags = true },
30600 .each = .{ .once = &.{
30601 .{ ._, ._, .xor, .dst0d, .dst0d, ._, ._ },
30602 .{ ._, ._, .popcnt, .dst0q, .src0q, ._, ._ },
30603 } },
30604 }, .{
30605 .required_features = .{ .@"64bit", .popcnt, null, null },
30606 .src_constraints = .{ .{ .unsigned_or_exact_int = .qword }, .any, .any },
30607 .patterns = &.{
30608 .{ .src = .{ .mem, .none, .none } },
30609 .{ .src = .{ .to_gpr, .none, .none } },
30610 },
30611 .dst_temps = .{ .{ .mut_rc = .{ .ref = .src0, .rc = .general_purpose } }, .unused },
30612 .clobbers = .{ .eflags = true },
30613 .each = .{ .once = &.{
30614 .{ ._, ._, .popcnt, .dst0q, .src0q, ._, ._ },
30615 } },
30616 }, .{
30617 .required_features = .{ .@"64bit", .popcnt, null, null },
30618 .src_constraints = .{ .{ .signed_int = .qword }, .any, .any },
30619 .patterns = &.{
30620 .{ .src = .{ .to_mut_gpr, .none, .none } },
30621 },
30622 .dst_temps = .{ .{ .ref = .src0 }, .unused },
30623 .clobbers = .{ .eflags = true },
30624 .each = .{ .once = &.{
30625 .{ ._, ._l, .sh, .src0q, .uia(64, .src0, .sub_bit_size), ._, ._ },
30626 .{ ._, ._, .popcnt, .dst0q, .src0q, ._, ._ },
30627 } },
30628 }, .{
30629 .src_constraints = .{ .{ .unsigned_or_exact_int = .byte }, .any, .any },
30630 .patterns = &.{
30631 .{ .src = .{ .to_mut_gpr, .none, .none } },
30632 },
30633 .extra_temps = .{
30634 .{ .type = .u8, .kind = .{ .rc = .general_purpose } },
30635 .unused,
30636 .unused,
30637 .unused,
30638 .unused,
30639 .unused,
30640 .unused,
30641 .unused,
30642 .unused,
30643 .unused,
30644 .unused,
30645 },
30646 .dst_temps = .{ .{ .ref = .src0 }, .unused },
30647 .clobbers = .{ .eflags = true },
30648 .each = .{ .once = &.{
30649 .{ ._, ._, .mov, .tmp0d, .src0d, ._, ._ },
30650 .{ ._, ._r, .sh, .src0b, .ui(1), ._, ._ },
30651 .{ ._, ._, .@"and", .src0b, .ui(0x55), ._, ._ },
30652 .{ ._, ._, .sub, .tmp0b, .src0b, ._, ._ },
30653 .{ ._, ._, .mov, .dst0d, .tmp0d, ._, ._ },
30654 .{ ._, ._r, .sh, .tmp0d, .ui(2), ._, ._ },
30655 .{ ._, ._, .@"and", .dst0b, .ui(0x33), ._, ._ },
30656 .{ ._, ._, .@"and", .tmp0b, .ui(0x33), ._, ._ },
30657 .{ ._, ._, .add, .dst0b, .tmp0b, ._, ._ },
30658 .{ ._, ._, .mov, .tmp0d, .dst0d, ._, ._ },
30659 .{ ._, ._r, .sh, .dst0b, .ui(4), ._, ._ },
30660 .{ ._, ._, .@"and", .tmp0b, .ui(0x0f), ._, ._ },
30661 .{ ._, ._, .add, .dst0b, .tmp0b, ._, ._ },
30662 } },
30663 }, .{
30664 .src_constraints = .{ .{ .signed_int = .byte }, .any, .any },
30665 .patterns = &.{
30666 .{ .src = .{ .to_mut_gpr, .none, .none } },
30667 },
30668 .extra_temps = .{
30669 .{ .type = .u8, .kind = .{ .rc = .general_purpose } },
30670 .unused,
30671 .unused,
30672 .unused,
30673 .unused,
30674 .unused,
30675 .unused,
30676 .unused,
30677 .unused,
30678 .unused,
30679 .unused,
30680 },
30681 .dst_temps = .{ .{ .ref = .src0 }, .unused },
30682 .clobbers = .{ .eflags = true },
30683 .each = .{ .once = &.{
30684 .{ ._, ._l, .sh, .src0b, .uia(8, .src0, .sub_bit_size), ._, ._ },
30685 .{ ._, ._, .mov, .tmp0d, .src0d, ._, ._ },
30686 .{ ._, ._r, .sh, .src0b, .ui(1), ._, ._ },
30687 .{ ._, ._, .@"and", .src0b, .ui(0x55), ._, ._ },
30688 .{ ._, ._, .sub, .tmp0b, .src0b, ._, ._ },
30689 .{ ._, ._, .mov, .dst0d, .tmp0d, ._, ._ },
30690 .{ ._, ._r, .sh, .tmp0d, .ui(2), ._, ._ },
30691 .{ ._, ._, .@"and", .dst0b, .ui(0x33), ._, ._ },
30692 .{ ._, ._, .@"and", .tmp0b, .ui(0x33), ._, ._ },
30693 .{ ._, ._, .add, .dst0b, .tmp0b, ._, ._ },
30694 .{ ._, ._, .mov, .tmp0d, .dst0d, ._, ._ },
30695 .{ ._, ._r, .sh, .dst0b, .ui(4), ._, ._ },
30696 .{ ._, ._, .@"and", .tmp0b, .ui(0x0f), ._, ._ },
30697 .{ ._, ._, .add, .dst0b, .tmp0b, ._, ._ },
30698 } },
30699 }, .{
30700 .required_features = .{ .fast_imm16, null, null, null },
30701 .src_constraints = .{ .{ .unsigned_or_exact_int = .word }, .any, .any },
30702 .patterns = &.{
30703 .{ .src = .{ .to_mut_gpr, .none, .none } },
30704 },
30705 .extra_temps = .{
30706 .{ .type = .u16, .kind = .{ .rc = .general_purpose } },
30707 .unused,
30708 .unused,
30709 .unused,
30710 .unused,
30711 .unused,
30712 .unused,
30713 .unused,
30714 .unused,
30715 .unused,
30716 .unused,
30717 },
30718 .dst_temps = .{ .{ .ref = .src0 }, .unused },
30719 .clobbers = .{ .eflags = true },
30720 .each = .{ .once = &.{
30721 .{ ._, ._, .mov, .tmp0d, .src0d, ._, ._ },
30722 .{ ._, ._r, .sh, .src0d, .ui(1), ._, ._ },
30723 .{ ._, ._, .@"and", .src0w, .ui(0x5555), ._, ._ },
30724 .{ ._, ._, .sub, .tmp0d, .src0d, ._, ._ },
30725 .{ ._, ._, .mov, .dst0d, .tmp0d, ._, ._ },
30726 .{ ._, ._r, .sh, .tmp0d, .ui(2), ._, ._ },
30727 .{ ._, ._, .@"and", .dst0w, .ui(0x3333), ._, ._ },
30728 .{ ._, ._, .@"and", .tmp0w, .ui(0x3333), ._, ._ },
30729 .{ ._, ._, .lea, .dst0d, .leai(.dst0, .tmp0), ._, ._ },
30730 .{ ._, ._, .mov, .tmp0d, .dst0d, ._, ._ },
30731 .{ ._, ._r, .sh, .dst0d, .ui(4), ._, ._ },
30732 .{ ._, ._, .@"and", .tmp0w, .ui(0x0f0f), ._, ._ },
30733 .{ ._, ._, .@"and", .dst0w, .ui(0x0f0f), ._, ._ },
30734 .{ ._, ._, .lea, .tmp0d, .leai(.tmp0, .dst0), ._, ._ },
30735 .{ ._, ._, .mov, .dst0d, .tmp0d, ._, ._ },
30736 .{ ._, ._r, .sh, .tmp0d, .ui(8), ._, ._ },
30737 .{ ._, ._, .add, .dst0b, .tmp0b, ._, ._ },
30738 } },
30739 }, .{
30740 .required_features = .{ .fast_imm16, null, null, null },
30741 .src_constraints = .{ .{ .signed_int = .word }, .any, .any },
30742 .patterns = &.{
30743 .{ .src = .{ .to_mut_gpr, .none, .none } },
30744 },
30745 .extra_temps = .{
30746 .{ .type = .u16, .kind = .{ .rc = .general_purpose } },
30747 .unused,
30748 .unused,
30749 .unused,
30750 .unused,
30751 .unused,
30752 .unused,
30753 .unused,
30754 .unused,
30755 .unused,
30756 .unused,
30757 },
30758 .dst_temps = .{ .{ .ref = .src0 }, .unused },
30759 .clobbers = .{ .eflags = true },
30760 .each = .{ .once = &.{
30761 .{ ._, ._l, .sh, .src0d, .uia(16, .src0, .sub_bit_size), ._, ._ },
30762 .{ ._, ._, .mov, .tmp0d, .src0d, ._, ._ },
30763 .{ ._, ._r, .sh, .src0d, .ui(1), ._, ._ },
30764 .{ ._, ._, .@"and", .src0w, .ui(0x5555), ._, ._ },
30765 .{ ._, ._, .sub, .tmp0d, .src0d, ._, ._ },
30766 .{ ._, ._, .mov, .dst0d, .tmp0d, ._, ._ },
30767 .{ ._, ._r, .sh, .tmp0d, .ui(2), ._, ._ },
30768 .{ ._, ._, .@"and", .dst0w, .ui(0x3333), ._, ._ },
30769 .{ ._, ._, .@"and", .tmp0w, .ui(0x3333), ._, ._ },
30770 .{ ._, ._, .lea, .dst0d, .leai(.dst0, .tmp0), ._, ._ },
30771 .{ ._, ._, .mov, .tmp0d, .dst0d, ._, ._ },
30772 .{ ._, ._r, .sh, .dst0d, .ui(4), ._, ._ },
30773 .{ ._, ._, .@"and", .tmp0w, .ui(0x0f0f), ._, ._ },
30774 .{ ._, ._, .@"and", .dst0w, .ui(0x0f0f), ._, ._ },
30775 .{ ._, ._, .lea, .tmp0d, .leai(.tmp0, .dst0), ._, ._ },
30776 .{ ._, ._, .mov, .dst0d, .tmp0d, ._, ._ },
30777 .{ ._, ._r, .sh, .tmp0d, .ui(8), ._, ._ },
30778 .{ ._, ._, .add, .dst0b, .tmp0b, ._, ._ },
30779 } },
30780 }, .{
30781 .src_constraints = .{ .{ .unsigned_or_exact_int = .word }, .any, .any },
30782 .patterns = &.{
30783 .{ .src = .{ .to_mut_gpr, .none, .none } },
30784 },
30785 .extra_temps = .{
30786 .{ .type = .u16, .kind = .{ .rc = .general_purpose } },
30787 .unused,
30788 .unused,
30789 .unused,
30790 .unused,
30791 .unused,
30792 .unused,
30793 .unused,
30794 .unused,
30795 .unused,
30796 .unused,
30797 },
30798 .dst_temps = .{ .{ .ref = .src0 }, .unused },
30799 .clobbers = .{ .eflags = true },
30800 .each = .{ .once = &.{
30801 .{ ._, ._, .mov, .tmp0d, .src0d, ._, ._ },
30802 .{ ._, ._r, .sh, .src0d, .ui(1), ._, ._ },
30803 .{ ._, ._, .@"and", .src0d, .ui(0x5555), ._, ._ },
30804 .{ ._, ._, .sub, .tmp0d, .src0d, ._, ._ },
30805 .{ ._, ._, .mov, .dst0d, .tmp0d, ._, ._ },
30806 .{ ._, ._r, .sh, .tmp0d, .ui(2), ._, ._ },
30807 .{ ._, ._, .@"and", .dst0d, .ui(0x3333), ._, ._ },
30808 .{ ._, ._, .@"and", .tmp0d, .ui(0x3333), ._, ._ },
30809 .{ ._, ._, .lea, .dst0d, .leai(.dst0, .tmp0), ._, ._ },
30810 .{ ._, ._, .mov, .tmp0d, .dst0d, ._, ._ },
30811 .{ ._, ._r, .sh, .dst0d, .ui(4), ._, ._ },
30812 .{ ._, ._, .@"and", .tmp0d, .ui(0x0f0f), ._, ._ },
30813 .{ ._, ._, .@"and", .dst0d, .ui(0x0f0f), ._, ._ },
30814 .{ ._, ._, .lea, .tmp0d, .leai(.tmp0, .dst0), ._, ._ },
30815 .{ ._, ._, .mov, .dst0d, .tmp0d, ._, ._ },
30816 .{ ._, ._r, .sh, .tmp0d, .ui(8), ._, ._ },
30817 .{ ._, ._, .add, .dst0b, .tmp0b, ._, ._ },
30818 } },
30819 }, .{
30820 .src_constraints = .{ .{ .signed_int = .word }, .any, .any },
30821 .patterns = &.{
30822 .{ .src = .{ .to_mut_gpr, .none, .none } },
30823 },
30824 .extra_temps = .{
30825 .{ .type = .u16, .kind = .{ .rc = .general_purpose } },
30826 .unused,
30827 .unused,
30828 .unused,
30829 .unused,
30830 .unused,
30831 .unused,
30832 .unused,
30833 .unused,
30834 .unused,
30835 .unused,
30836 },
30837 .dst_temps = .{ .{ .ref = .src0 }, .unused },
30838 .clobbers = .{ .eflags = true },
30839 .each = .{ .once = &.{
30840 .{ ._, ._l, .sh, .src0d, .uia(16, .src0, .sub_bit_size), ._, ._ },
30841 .{ ._, ._, .mov, .tmp0d, .src0d, ._, ._ },
30842 .{ ._, ._r, .sh, .src0d, .ui(1), ._, ._ },
30843 .{ ._, ._, .@"and", .src0d, .ui(0x5555), ._, ._ },
30844 .{ ._, ._, .sub, .tmp0d, .src0d, ._, ._ },
30845 .{ ._, ._, .mov, .dst0d, .tmp0d, ._, ._ },
30846 .{ ._, ._r, .sh, .tmp0d, .ui(2), ._, ._ },
30847 .{ ._, ._, .@"and", .dst0d, .ui(0x3333), ._, ._ },
30848 .{ ._, ._, .@"and", .tmp0d, .ui(0x3333), ._, ._ },
30849 .{ ._, ._, .lea, .dst0d, .leai(.dst0, .tmp0), ._, ._ },
30850 .{ ._, ._, .mov, .tmp0d, .dst0d, ._, ._ },
30851 .{ ._, ._r, .sh, .dst0d, .ui(4), ._, ._ },
30852 .{ ._, ._, .@"and", .tmp0d, .ui(0x0f0f), ._, ._ },
30853 .{ ._, ._, .@"and", .dst0d, .ui(0x0f0f), ._, ._ },
30854 .{ ._, ._, .lea, .tmp0d, .leai(.tmp0, .dst0), ._, ._ },
30855 .{ ._, ._, .mov, .dst0d, .tmp0d, ._, ._ },
30856 .{ ._, ._r, .sh, .tmp0d, .ui(8), ._, ._ },
30857 .{ ._, ._, .add, .dst0b, .tmp0b, ._, ._ },
30858 } },
30859 }, .{
30860 .src_constraints = .{ .{ .unsigned_or_exact_int = .dword }, .any, .any },
30861 .patterns = &.{
30862 .{ .src = .{ .to_mut_gpr, .none, .none } },
30863 },
30864 .extra_temps = .{
30865 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
30866 .unused,
30867 .unused,
30868 .unused,
30869 .unused,
30870 .unused,
30871 .unused,
30872 .unused,
30873 .unused,
30874 .unused,
30875 .unused,
30876 },
30877 .dst_temps = .{ .{ .ref = .src0 }, .unused },
30878 .clobbers = .{ .eflags = true },
30879 .each = .{ .once = &.{
30880 .{ ._, ._, .mov, .tmp0d, .src0d, ._, ._ },
30881 .{ ._, ._r, .sh, .src0d, .ui(1), ._, ._ },
30882 .{ ._, ._, .@"and", .src0d, .ui(0x55555555), ._, ._ },
30883 .{ ._, ._, .sub, .tmp0d, .src0d, ._, ._ },
30884 .{ ._, ._, .mov, .dst0d, .tmp0d, ._, ._ },
30885 .{ ._, ._r, .sh, .tmp0d, .ui(2), ._, ._ },
30886 .{ ._, ._, .@"and", .dst0d, .ui(0x33333333), ._, ._ },
30887 .{ ._, ._, .@"and", .tmp0d, .ui(0x33333333), ._, ._ },
30888 .{ ._, ._, .lea, .dst0d, .leai(.dst0, .tmp0), ._, ._ },
30889 .{ ._, ._, .mov, .tmp0d, .dst0d, ._, ._ },
30890 .{ ._, ._r, .sh, .dst0d, .ui(4), ._, ._ },
30891 .{ ._, ._, .@"and", .tmp0d, .ui(0x0f0f0f0f), ._, ._ },
30892 .{ ._, ._, .@"and", .dst0d, .ui(0x0f0f0f0f), ._, ._ },
30893 .{ ._, ._, .lea, .tmp0d, .leai(.tmp0, .dst0), ._, ._ },
30894 .{ ._, .i_, .mul, .dst0d, .tmp0d, .ui(0x01010101), ._ },
30895 .{ ._, ._r, .sh, .dst0d, .ui(32 - 8), ._, ._ },
30896 } },
30897 }, .{
30898 .src_constraints = .{ .{ .signed_int = .dword }, .any, .any },
30899 .patterns = &.{
30900 .{ .src = .{ .to_mut_gpr, .none, .none } },
30901 },
30902 .extra_temps = .{
30903 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
30904 .unused,
30905 .unused,
30906 .unused,
30907 .unused,
30908 .unused,
30909 .unused,
30910 .unused,
30911 .unused,
30912 .unused,
30913 .unused,
30914 },
30915 .dst_temps = .{ .{ .ref = .src0 }, .unused },
30916 .clobbers = .{ .eflags = true },
30917 .each = .{ .once = &.{
30918 .{ ._, ._l, .sh, .src0d, .uia(32, .src0, .sub_bit_size), ._, ._ },
30919 .{ ._, ._, .mov, .tmp0d, .src0d, ._, ._ },
30920 .{ ._, ._r, .sh, .src0d, .ui(1), ._, ._ },
30921 .{ ._, ._, .@"and", .src0d, .ui(0x55555555), ._, ._ },
30922 .{ ._, ._, .sub, .tmp0d, .src0d, ._, ._ },
30923 .{ ._, ._, .mov, .dst0d, .tmp0d, ._, ._ },
30924 .{ ._, ._r, .sh, .tmp0d, .ui(2), ._, ._ },
30925 .{ ._, ._, .@"and", .dst0d, .ui(0x33333333), ._, ._ },
30926 .{ ._, ._, .@"and", .tmp0d, .ui(0x33333333), ._, ._ },
30927 .{ ._, ._, .lea, .dst0d, .leai(.dst0, .tmp0), ._, ._ },
30928 .{ ._, ._, .mov, .tmp0d, .dst0d, ._, ._ },
30929 .{ ._, ._r, .sh, .dst0d, .ui(4), ._, ._ },
30930 .{ ._, ._, .@"and", .tmp0d, .ui(0x0f0f0f0f), ._, ._ },
30931 .{ ._, ._, .@"and", .dst0d, .ui(0x0f0f0f0f), ._, ._ },
30932 .{ ._, ._, .lea, .tmp0d, .leai(.tmp0, .dst0), ._, ._ },
30933 .{ ._, .i_, .mul, .dst0d, .tmp0d, .ui(0x01010101), ._ },
30934 .{ ._, ._r, .sh, .dst0d, .ui(32 - 8), ._, ._ },
30935 } },
30936 }, .{
30937 .required_features = .{ .@"64bit", null, null, null },
30938 .src_constraints = .{ .{ .unsigned_or_exact_int = .qword }, .any, .any },
30939 .patterns = &.{
30940 .{ .src = .{ .to_mut_gpr, .none, .none } },
30941 },
30942 .extra_temps = .{
30943 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
30944 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
30945 .unused,
30946 .unused,
30947 .unused,
30948 .unused,
30949 .unused,
30950 .unused,
30951 .unused,
30952 .unused,
30953 .unused,
30954 },
30955 .dst_temps = .{ .{ .ref = .src0 }, .unused },
30956 .clobbers = .{ .eflags = true },
30957 .each = .{ .once = &.{
30958 .{ ._, ._, .mov, .tmp0q, .src0q, ._, ._ },
30959 .{ ._, ._r, .sh, .src0q, .ui(1), ._, ._ },
30960 .{ ._, ._, .mov, .tmp1q, .uia(0x55555555, .none, .repeat), ._, ._ },
30961 .{ ._, ._, .@"and", .src0q, .tmp1q, ._, ._ },
30962 .{ ._, ._, .sub, .tmp0q, .src0q, ._, ._ },
30963 .{ ._, ._, .mov, .dst0q, .tmp0q, ._, ._ },
30964 .{ ._, ._r, .sh, .tmp0q, .ui(2), ._, ._ },
30965 .{ ._, ._, .mov, .tmp1q, .uia(0x33333333, .none, .repeat), ._, ._ },
30966 .{ ._, ._, .@"and", .dst0q, .tmp1q, ._, ._ },
30967 .{ ._, ._, .@"and", .tmp0q, .tmp1q, ._, ._ },
30968 .{ ._, ._, .lea, .dst0q, .leai(.dst0, .tmp0), ._, ._ },
30969 .{ ._, ._, .mov, .tmp0q, .dst0q, ._, ._ },
30970 .{ ._, ._r, .sh, .dst0q, .ui(4), ._, ._ },
30971 .{ ._, ._, .mov, .tmp1q, .uia(0x0f0f0f0f, .none, .repeat), ._, ._ },
30972 .{ ._, ._, .@"and", .tmp0q, .tmp1q, ._, ._ },
30973 .{ ._, ._, .@"and", .dst0q, .tmp1q, ._, ._ },
30974 .{ ._, ._, .lea, .dst0q, .leai(.dst0, .tmp0), ._, ._ },
30975 .{ ._, ._, .mov, .tmp1q, .uia(0x01010101, .none, .repeat), ._, ._ },
30976 .{ ._, .i_, .mul, .dst0q, .tmp1q, ._, ._ },
30977 .{ ._, ._r, .sh, .dst0q, .ui(64 - 8), ._, ._ },
30978 } },
30979 }, .{
30980 .required_features = .{ .@"64bit", null, null, null },
30981 .src_constraints = .{ .{ .signed_int = .qword }, .any, .any },
30982 .patterns = &.{
30983 .{ .src = .{ .to_mut_gpr, .none, .none } },
30984 },
30985 .extra_temps = .{
30986 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
30987 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
30988 .unused,
30989 .unused,
30990 .unused,
30991 .unused,
30992 .unused,
30993 .unused,
30994 .unused,
30995 .unused,
30996 .unused,
30997 },
30998 .dst_temps = .{ .{ .ref = .src0 }, .unused },
30999 .clobbers = .{ .eflags = true },
31000 .each = .{ .once = &.{
31001 .{ ._, ._l, .sh, .src0q, .uia(64, .src0, .sub_bit_size), ._, ._ },
31002 .{ ._, ._, .mov, .tmp0q, .src0q, ._, ._ },
31003 .{ ._, ._r, .sh, .src0q, .ui(1), ._, ._ },
31004 .{ ._, ._, .mov, .tmp1q, .uia(0x55555555, .none, .repeat), ._, ._ },
31005 .{ ._, ._, .@"and", .src0q, .tmp1q, ._, ._ },
31006 .{ ._, ._, .sub, .tmp0q, .src0q, ._, ._ },
31007 .{ ._, ._, .mov, .dst0q, .tmp0q, ._, ._ },
31008 .{ ._, ._r, .sh, .tmp0q, .ui(2), ._, ._ },
31009 .{ ._, ._, .mov, .tmp1q, .uia(0x33333333, .none, .repeat), ._, ._ },
31010 .{ ._, ._, .@"and", .dst0q, .tmp1q, ._, ._ },
31011 .{ ._, ._, .@"and", .tmp0q, .tmp1q, ._, ._ },
31012 .{ ._, ._, .lea, .dst0q, .leai(.dst0, .tmp0), ._, ._ },
31013 .{ ._, ._, .mov, .tmp0q, .dst0q, ._, ._ },
31014 .{ ._, ._r, .sh, .dst0q, .ui(4), ._, ._ },
31015 .{ ._, ._, .mov, .tmp1q, .uia(0x0f0f0f0f, .none, .repeat), ._, ._ },
31016 .{ ._, ._, .@"and", .tmp0q, .tmp1q, ._, ._ },
31017 .{ ._, ._, .@"and", .dst0q, .tmp1q, ._, ._ },
31018 .{ ._, ._, .lea, .dst0q, .leai(.dst0, .tmp0), ._, ._ },
31019 .{ ._, ._, .mov, .tmp1q, .uia(0x01010101, .none, .repeat), ._, ._ },
31020 .{ ._, .i_, .mul, .dst0q, .tmp1q, ._, ._ },
31021 .{ ._, ._r, .sh, .dst0q, .ui(64 - 8), ._, ._ },
31022 } },
31023 }, .{
31024 .required_features = .{ .@"64bit", .popcnt, .false_deps_popcnt, null },
31025 .src_constraints = .{ .{ .unsigned_or_exact_remainder_int = .{ .of = .xword, .is = .xword } }, .any, .any },
31026 .patterns = &.{
31027 .{ .src = .{ .to_mem, .none, .none } },
31028 },
31029 .extra_temps = .{
31030 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
31031 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
31032 .unused,
31033 .unused,
31034 .unused,
31035 .unused,
31036 .unused,
31037 .unused,
31038 .unused,
31039 .unused,
31040 .unused,
31041 },
31042 .dst_temps = .{ .{ .rc = .general_purpose }, .unused },
31043 .clobbers = .{ .eflags = true },
31044 .each = .{ .once = &.{
31045 .{ ._, ._, .mov, .tmp0d, .sia(-8, .src0, .add_size), ._, ._ },
31046 .{ ._, ._, .xor, .dst0d, .dst0d, ._, ._ },
31047 .{ .@"0:", ._, .xor, .tmp1d, .tmp1d, ._, ._ },
31048 .{ ._, ._, .popcnt, .tmp1q, .memi(.src0q, .tmp0), ._, ._ },
31049 .{ ._, ._, .lea, .dst0d, .leai(.dst0, .tmp1), ._, ._ },
31050 .{ ._, ._, .sub, .tmp0d, .si(8), ._, ._ },
31051 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
31052 } },
31053 }, .{
31054 .required_features = .{ .@"64bit", .popcnt, null, null },
31055 .src_constraints = .{ .{ .unsigned_or_exact_remainder_int = .{ .of = .xword, .is = .xword } }, .any, .any },
31056 .patterns = &.{
31057 .{ .src = .{ .to_mem, .none, .none } },
31058 },
31059 .extra_temps = .{
31060 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
31061 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
31062 .unused,
31063 .unused,
31064 .unused,
31065 .unused,
31066 .unused,
31067 .unused,
31068 .unused,
31069 .unused,
31070 .unused,
31071 },
31072 .dst_temps = .{ .{ .rc = .general_purpose }, .unused },
31073 .clobbers = .{ .eflags = true },
31074 .each = .{ .once = &.{
31075 .{ ._, ._, .mov, .tmp0d, .sia(-8, .src0, .add_size), ._, ._ },
31076 .{ ._, ._, .xor, .dst0d, .dst0d, ._, ._ },
31077 .{ .@"0:", ._, .popcnt, .tmp1q, .memi(.src0q, .tmp0), ._, ._ },
31078 .{ ._, ._, .lea, .dst0d, .leai(.dst0, .tmp1), ._, ._ },
31079 .{ ._, ._, .sub, .tmp0d, .si(8), ._, ._ },
31080 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
31081 } },
31082 }, .{
31083 .required_features = .{ .@"64bit", .popcnt, .false_deps_popcnt, null },
31084 .src_constraints = .{ .{ .remainder_signed_int = .{ .of = .xword, .is = .qword } }, .any, .any },
31085 .patterns = &.{
31086 .{ .src = .{ .to_mem, .none, .none } },
31087 },
31088 .extra_temps = .{
31089 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
31090 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
31091 .unused,
31092 .unused,
31093 .unused,
31094 .unused,
31095 .unused,
31096 .unused,
31097 .unused,
31098 .unused,
31099 .unused,
31100 },
31101 .dst_temps = .{ .{ .rc = .general_purpose }, .unused },
31102 .clobbers = .{ .eflags = true },
31103 .each = .{ .once = &.{
31104 .{ ._, ._, .mov, .dst0q, .memad(.src0q, .add_size, -16), ._, ._ },
31105 .{ ._, ._, .mov, .tmp0d, .sia(-24, .src0, .add_size), ._, ._ },
31106 .{ ._, ._l, .sh, .dst0q, .uia(64, .src0, .sub_bit_size_rem_64), ._, ._ },
31107 .{ ._, ._, .popcnt, .dst0q, .dst0q, ._, ._ },
31108 .{ .@"0:", ._, .xor, .tmp1d, .tmp1d, ._, ._ },
31109 .{ ._, ._, .popcnt, .tmp1q, .memi(.src0q, .tmp0), ._, ._ },
31110 .{ ._, ._, .lea, .dst0d, .leai(.dst0, .tmp1), ._, ._ },
31111 .{ ._, ._, .sub, .tmp0d, .si(8), ._, ._ },
31112 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
31113 } },
31114 }, .{
31115 .required_features = .{ .@"64bit", .popcnt, null, null },
31116 .src_constraints = .{ .{ .remainder_signed_int = .{ .of = .xword, .is = .qword } }, .any, .any },
31117 .patterns = &.{
31118 .{ .src = .{ .to_mem, .none, .none } },
31119 },
31120 .extra_temps = .{
31121 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
31122 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
31123 .unused,
31124 .unused,
31125 .unused,
31126 .unused,
31127 .unused,
31128 .unused,
31129 .unused,
31130 .unused,
31131 .unused,
31132 },
31133 .dst_temps = .{ .{ .rc = .general_purpose }, .unused },
31134 .clobbers = .{ .eflags = true },
31135 .each = .{ .once = &.{
31136 .{ ._, ._, .mov, .dst0q, .memad(.src0q, .add_size, -16), ._, ._ },
31137 .{ ._, ._, .mov, .tmp0d, .sia(-24, .src0, .add_size), ._, ._ },
31138 .{ ._, ._l, .sh, .dst0q, .uia(64, .src0, .sub_bit_size_rem_64), ._, ._ },
31139 .{ ._, ._, .popcnt, .dst0q, .dst0q, ._, ._ },
31140 .{ .@"0:", ._, .popcnt, .tmp1q, .memi(.src0q, .tmp0), ._, ._ },
31141 .{ ._, ._, .lea, .dst0d, .leai(.dst0, .tmp1), ._, ._ },
31142 .{ ._, ._, .sub, .tmp0d, .si(8), ._, ._ },
31143 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
31144 } },
31145 }, .{
31146 .required_features = .{ .@"64bit", .popcnt, .false_deps_popcnt, null },
31147 .src_constraints = .{ .{ .remainder_signed_int = .{ .of = .xword, .is = .xword } }, .any, .any },
31148 .patterns = &.{
31149 .{ .src = .{ .to_mem, .none, .none } },
31150 },
31151 .extra_temps = .{
31152 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
31153 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
31154 .unused,
31155 .unused,
31156 .unused,
31157 .unused,
31158 .unused,
31159 .unused,
31160 .unused,
31161 .unused,
31162 .unused,
31163 },
31164 .dst_temps = .{ .{ .rc = .general_purpose }, .unused },
31165 .clobbers = .{ .eflags = true },
31166 .each = .{ .once = &.{
31167 .{ ._, ._, .mov, .dst0q, .memad(.src0q, .add_size, -8), ._, ._ },
31168 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_size), ._, ._ },
31169 .{ ._, ._l, .sh, .dst0q, .uia(64, .src0, .sub_bit_size_rem_64), ._, ._ },
31170 .{ ._, ._, .popcnt, .dst0q, .dst0q, ._, ._ },
31171 .{ .@"0:", ._, .xor, .tmp1d, .tmp1d, ._, ._ },
31172 .{ ._, ._, .popcnt, .tmp1q, .memi(.src0q, .tmp0), ._, ._ },
31173 .{ ._, ._, .lea, .dst0d, .leai(.dst0, .tmp1), ._, ._ },
31174 .{ ._, ._, .sub, .tmp0d, .si(8), ._, ._ },
31175 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
31176 } },
31177 }, .{
31178 .required_features = .{ .@"64bit", .popcnt, null, null },
31179 .src_constraints = .{ .{ .remainder_signed_int = .{ .of = .xword, .is = .xword } }, .any, .any },
31180 .patterns = &.{
31181 .{ .src = .{ .to_mem, .none, .none } },
31182 },
31183 .extra_temps = .{
31184 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
31185 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
31186 .unused,
31187 .unused,
31188 .unused,
31189 .unused,
31190 .unused,
31191 .unused,
31192 .unused,
31193 .unused,
31194 .unused,
31195 },
31196 .dst_temps = .{ .{ .rc = .general_purpose }, .unused },
31197 .clobbers = .{ .eflags = true },
31198 .each = .{ .once = &.{
31199 .{ ._, ._, .mov, .dst0q, .memad(.src0q, .add_size, -8), ._, ._ },
31200 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_size), ._, ._ },
31201 .{ ._, ._l, .sh, .dst0q, .uia(64, .src0, .sub_bit_size_rem_64), ._, ._ },
31202 .{ ._, ._, .popcnt, .dst0q, .dst0q, ._, ._ },
31203 .{ .@"0:", ._, .popcnt, .tmp1q, .memi(.src0q, .tmp0), ._, ._ },
31204 .{ ._, ._, .lea, .dst0d, .leai(.dst0, .tmp1), ._, ._ },
31205 .{ ._, ._, .sub, .tmp0d, .si(8), ._, ._ },
31206 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
31207 } },
31208 }, .{
31209 .required_features = .{ .@"64bit", null, null, null },
31210 .src_constraints = .{ .{ .unsigned_or_exact_remainder_int = .{ .of = .xword, .is = .xword } }, .any, .any },
31211 .patterns = &.{
31212 .{ .src = .{ .to_mem, .none, .none } },
31213 },
31214 .extra_temps = .{
31215 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
31216 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
31217 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
31218 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
31219 .unused,
31220 .unused,
31221 .unused,
31222 .unused,
31223 .unused,
31224 .unused,
31225 .unused,
31226 },
31227 .dst_temps = .{ .{ .rc = .general_purpose }, .unused },
31228 .clobbers = .{ .eflags = true },
31229 .each = .{ .once = &.{
31230 .{ ._, ._, .mov, .tmp0d, .sia(-8, .src0, .add_size), ._, ._ },
31231 .{ ._, ._, .xor, .dst0d, .dst0d, ._, ._ },
31232 .{ .@"0:", ._, .mov, .tmp1q, .memi(.src0q, .tmp0), ._, ._ },
31233 .{ ._, ._, .mov, .tmp2q, .tmp1q, ._, ._ },
31234 .{ ._, ._r, .sh, .tmp1q, .ui(1), ._, ._ },
31235 .{ ._, ._, .mov, .tmp3q, .uia(0x55555555, .none, .repeat), ._, ._ },
31236 .{ ._, ._, .@"and", .tmp1q, .tmp3q, ._, ._ },
31237 .{ ._, ._, .sub, .tmp2q, .tmp1q, ._, ._ },
31238 .{ ._, ._, .mov, .tmp1q, .tmp2q, ._, ._ },
31239 .{ ._, ._r, .sh, .tmp2q, .ui(2), ._, ._ },
31240 .{ ._, ._, .mov, .tmp3q, .uia(0x33333333, .none, .repeat), ._, ._ },
31241 .{ ._, ._, .@"and", .tmp1q, .tmp3q, ._, ._ },
31242 .{ ._, ._, .@"and", .tmp2q, .tmp3q, ._, ._ },
31243 .{ ._, ._, .lea, .tmp1q, .leai(.tmp1, .tmp2), ._, ._ },
31244 .{ ._, ._, .mov, .tmp2q, .tmp1q, ._, ._ },
31245 .{ ._, ._r, .sh, .tmp1q, .ui(4), ._, ._ },
31246 .{ ._, ._, .mov, .tmp3q, .uia(0x0f0f0f0f, .none, .repeat), ._, ._ },
31247 .{ ._, ._, .@"and", .tmp2q, .tmp3q, ._, ._ },
31248 .{ ._, ._, .@"and", .tmp1q, .tmp3q, ._, ._ },
31249 .{ ._, ._, .lea, .tmp1q, .leai(.tmp1, .tmp2), ._, ._ },
31250 .{ ._, ._, .mov, .tmp3q, .uia(0x01010101, .none, .repeat), ._, ._ },
31251 .{ ._, .i_, .mul, .tmp1q, .tmp3q, ._, ._ },
31252 .{ ._, ._r, .sh, .tmp1q, .ui(64 - 8), ._, ._ },
31253 .{ ._, ._, .lea, .dst0d, .leai(.dst0, .tmp1), ._, ._ },
31254 .{ ._, ._, .sub, .tmp0d, .si(8), ._, ._ },
31255 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
31256 } },
31257 }, .{
31258 .required_features = .{ .@"64bit", null, null, null },
31259 .src_constraints = .{ .{ .remainder_signed_int = .{ .of = .xword, .is = .qword } }, .any, .any },
31260 .patterns = &.{
31261 .{ .src = .{ .to_mem, .none, .none } },
31262 },
31263 .extra_temps = .{
31264 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
31265 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
31266 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
31267 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
31268 .unused,
31269 .unused,
31270 .unused,
31271 .unused,
31272 .unused,
31273 .unused,
31274 .unused,
31275 },
31276 .dst_temps = .{ .{ .rc = .general_purpose }, .unused },
31277 .clobbers = .{ .eflags = true },
31278 .each = .{ .once = &.{
31279 .{ ._, ._, .mov, .tmp1q, .memad(.src0q, .add_size, -16), ._, ._ },
31280 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_size), ._, ._ },
31281 .{ ._, ._l, .sh, .tmp1q, .uia(64, .src0, .sub_bit_size_rem_64), ._, ._ },
31282 .{ ._, ._, .xor, .dst0d, .dst0d, ._, ._ },
31283 .{ ._, ._mp, .j, .@"1f", ._, ._, ._ },
31284 .{ .@"0:", ._, .mov, .tmp1q, .memi(.src0q, .tmp0), ._, ._ },
31285 .{ .@"1:", ._, .mov, .tmp2q, .tmp1q, ._, ._ },
31286 .{ ._, ._r, .sh, .tmp1q, .ui(1), ._, ._ },
31287 .{ ._, ._, .mov, .tmp3q, .uia(0x55555555, .none, .repeat), ._, ._ },
31288 .{ ._, ._, .@"and", .tmp1q, .tmp3q, ._, ._ },
31289 .{ ._, ._, .sub, .tmp2q, .tmp1q, ._, ._ },
31290 .{ ._, ._, .mov, .tmp1q, .tmp2q, ._, ._ },
31291 .{ ._, ._r, .sh, .tmp2q, .ui(2), ._, ._ },
31292 .{ ._, ._, .mov, .tmp3q, .uia(0x33333333, .none, .repeat), ._, ._ },
31293 .{ ._, ._, .@"and", .tmp1q, .tmp3q, ._, ._ },
31294 .{ ._, ._, .@"and", .tmp2q, .tmp3q, ._, ._ },
31295 .{ ._, ._, .lea, .tmp1q, .leai(.tmp1, .tmp2), ._, ._ },
31296 .{ ._, ._, .mov, .tmp2q, .tmp1q, ._, ._ },
31297 .{ ._, ._r, .sh, .tmp1q, .ui(4), ._, ._ },
31298 .{ ._, ._, .mov, .tmp3q, .uia(0x0f0f0f0f, .none, .repeat), ._, ._ },
31299 .{ ._, ._, .@"and", .tmp2q, .tmp3q, ._, ._ },
31300 .{ ._, ._, .@"and", .tmp1q, .tmp3q, ._, ._ },
31301 .{ ._, ._, .lea, .tmp1q, .leai(.tmp1, .tmp2), ._, ._ },
31302 .{ ._, ._, .mov, .tmp3q, .uia(0x01010101, .none, .repeat), ._, ._ },
31303 .{ ._, .i_, .mul, .tmp1q, .tmp3q, ._, ._ },
31304 .{ ._, ._r, .sh, .tmp1q, .ui(64 - 8), ._, ._ },
31305 .{ ._, ._, .lea, .dst0d, .leai(.dst0, .tmp1), ._, ._ },
31306 .{ ._, ._, .sub, .tmp0d, .si(8), ._, ._ },
31307 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
31308 } },
31309 }, .{
31310 .required_features = .{ .@"64bit", null, null, null },
31311 .src_constraints = .{ .{ .remainder_signed_int = .{ .of = .xword, .is = .xword } }, .any, .any },
31312 .patterns = &.{
31313 .{ .src = .{ .to_mem, .none, .none } },
31314 },
31315 .extra_temps = .{
31316 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
31317 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
31318 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
31319 .{ .type = .u64, .kind = .{ .rc = .general_purpose } },
31320 .unused,
31321 .unused,
31322 .unused,
31323 .unused,
31324 .unused,
31325 .unused,
31326 .unused,
31327 },
31328 .dst_temps = .{ .{ .rc = .general_purpose }, .unused },
31329 .clobbers = .{ .eflags = true },
31330 .each = .{ .once = &.{
31331 .{ ._, ._, .mov, .tmp1q, .memad(.src0q, .add_size, -8), ._, ._ },
31332 .{ ._, ._, .mov, .tmp0d, .sia(-8, .src0, .add_size), ._, ._ },
31333 .{ ._, ._l, .sh, .tmp1q, .uia(64, .src0, .sub_bit_size_rem_64), ._, ._ },
31334 .{ ._, ._, .xor, .dst0d, .dst0d, ._, ._ },
31335 .{ ._, ._mp, .j, .@"1f", ._, ._, ._ },
31336 .{ .@"0:", ._, .mov, .tmp1q, .memi(.src0q, .tmp0), ._, ._ },
31337 .{ .@"1:", ._, .mov, .tmp2q, .tmp1q, ._, ._ },
31338 .{ ._, ._r, .sh, .tmp1q, .ui(1), ._, ._ },
31339 .{ ._, ._, .mov, .tmp3q, .uia(0x55555555, .none, .repeat), ._, ._ },
31340 .{ ._, ._, .@"and", .tmp1q, .tmp3q, ._, ._ },
31341 .{ ._, ._, .sub, .tmp2q, .tmp1q, ._, ._ },
31342 .{ ._, ._, .mov, .tmp1q, .tmp2q, ._, ._ },
31343 .{ ._, ._r, .sh, .tmp2q, .ui(2), ._, ._ },
31344 .{ ._, ._, .mov, .tmp3q, .uia(0x33333333, .none, .repeat), ._, ._ },
31345 .{ ._, ._, .@"and", .tmp1q, .tmp3q, ._, ._ },
31346 .{ ._, ._, .@"and", .tmp2q, .tmp3q, ._, ._ },
31347 .{ ._, ._, .lea, .tmp1q, .leai(.tmp1, .tmp2), ._, ._ },
31348 .{ ._, ._, .mov, .tmp2q, .tmp1q, ._, ._ },
31349 .{ ._, ._r, .sh, .tmp1q, .ui(4), ._, ._ },
31350 .{ ._, ._, .mov, .tmp3q, .uia(0x0f0f0f0f, .none, .repeat), ._, ._ },
31351 .{ ._, ._, .@"and", .tmp2q, .tmp3q, ._, ._ },
31352 .{ ._, ._, .@"and", .tmp1q, .tmp3q, ._, ._ },
31353 .{ ._, ._, .lea, .tmp1q, .leai(.tmp1, .tmp2), ._, ._ },
31354 .{ ._, ._, .mov, .tmp3q, .uia(0x01010101, .none, .repeat), ._, ._ },
31355 .{ ._, .i_, .mul, .tmp1q, .tmp3q, ._, ._ },
31356 .{ ._, ._r, .sh, .tmp1q, .ui(64 - 8), ._, ._ },
31357 .{ ._, ._, .lea, .dst0d, .leai(.dst0, .tmp1), ._, ._ },
31358 .{ ._, ._, .sub, .tmp0d, .si(8), ._, ._ },
31359 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
31360 } },
31361 } }) catch |err| switch (err) {
31362 error.SelectFailed => return cg.fail("failed to select {s} {} {}", .{
31363 @tagName(air_tag),
31364 cg.typeOf(ty_op.operand).fmt(pt),
31365 ops[0].tracking(cg),
31366 }),
31367 else => |e| return e,
31368 };
31369 try res[0].finish(inst, &.{ty_op.operand}, &ops, cg);
31370 },
3048331371 .byte_swap => |air_tag| if (use_old) try cg.airByteSwap(inst) else fallback: {
3048431372 const ty_op = air_datas[@intFromEnum(inst)].ty_op;
3048531373 if (ty_op.ty.toType().isVector(zcu)) break :fallback try cg.airByteSwap(inst);
......@@ -100339,6 +101227,7 @@ const Select = struct {
100339101227 smin,
100340101228 smax,
100341101229 umax,
101230 repeat,
100342101231 },
100343101232 op: enum(u2) { mul, div, div_8_down, rem_8_mul },
100344101233 rhs: Memory.Scale,
......@@ -100399,6 +101288,7 @@ const Select = struct {
100399101288 const add_elem_limbs: Adjust = .{ .sign = .pos, .lhs = .elem_limbs, .op = .mul, .rhs = .@"1" };
100400101289 const add_smin: Adjust = .{ .sign = .pos, .lhs = .smin, .op = .mul, .rhs = .@"1" };
100401101290 const add_umax: Adjust = .{ .sign = .pos, .lhs = .umax, .op = .mul, .rhs = .@"1" };
101291 const repeat: Adjust = .{ .sign = .pos, .lhs = .repeat, .op = .mul, .rhs = .@"1" };
100402101292 };
100403101293 const Ref = enum(u5) {
100404101294 tmp0,
......@@ -101107,6 +101997,10 @@ const Select = struct {
101107101997 .umax => @bitCast(@as(UnsignedImm, std.math.maxInt(UnsignedImm)) >> @truncate(
101108101998 -%op.flags.base.ref.typeOf(s).scalarType(s.cg.pt.zcu).bitSize(s.cg.pt.zcu),
101109101999 )),
102000 .repeat => switch (SignedImm) {
102001 else => unreachable,
102002 i64 => return @as(i64, op.imm) << 32 | @as(u32, @bitCast(op.imm)),
102003 },
101110102004 };
101111102005 const rhs = op.flags.adjust.rhs.toLog2();
101112102006 const op_res = op_res: switch (op.flags.adjust.op) {
test/behavior/x86_64/math.zig+8
......@@ -19281,6 +19281,14 @@ test ctz {
1928119281 try test_ctz.testInts();
1928219282}
1928319283
19284inline fn popCount(comptime Type: type, rhs: Type) @TypeOf(@popCount(rhs)) {
19285 return @popCount(rhs);
19286}
19287test popCount {
19288 const test_pop_count = unary(popCount, .{});
19289 try test_pop_count.testInts();
19290}
19291
1928419292inline fn byteSwap(comptime Type: type, rhs: Type) RoundBitsUp(Type, 8) {
1928519293 return @byteSwap(@as(RoundBitsUp(Type, 8), rhs));
1928619294}