authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-02-13 16:25:41-05:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-02-15 03:45:21-05:00
logf6bcc9dbcbd22083ce58c34179cb050abf3377fc
tree81df291665031b43c73abb2fb2d17c941e9e637e
parent8c48376d64391aba5edd0e2c8219537554cf2819

x86_64: rewrite scalar and vector int `@rem`


4 files changed, 694 insertions(+), 19 deletions(-)

src/arch/x86_64/CodeGen.zig+669-2
......@@ -11648,12 +11648,679 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
1164811648 };
1164911649 try res[0].finish(inst, &.{ bin_op.lhs, bin_op.rhs }, &ops, cg);
1165011650 },
11651 .rem, .rem_optimized => |air_tag| if (use_old) try cg.airMulDivBinOp(inst, .rem) else fallback: {
11651 .rem, .rem_optimized => |air_tag| if (use_old) try cg.airMulDivBinOp(inst, .rem) else {
1165211652 const bin_op = air_datas[@intFromEnum(inst)].bin_op;
11653 if (cg.floatBits(cg.typeOf(bin_op.lhs).scalarType(zcu)) == null) break :fallback try cg.airMulDivBinOp(inst, .rem);
1165411653 var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs });
1165511654 var res: [1]Temp = undefined;
1165611655 cg.select(&res, &.{cg.typeOf(bin_op.lhs)}, &ops, comptime &.{ .{
11656 .src_constraints = .{ .{ .signed_int = .byte }, .{ .signed_int = .byte }, .any },
11657 .patterns = &.{
11658 .{ .src = .{ .mem, .mem, .none } },
11659 .{ .src = .{ .to_gpr, .mem, .none } },
11660 .{ .src = .{ .mem, .to_gpr, .none } },
11661 .{ .src = .{ .to_gpr, .to_gpr, .none } },
11662 },
11663 .dst_temps = .{ .{ .reg = .ah }, .unused },
11664 .clobbers = .{ .eflags = true },
11665 .each = .{ .once = &.{
11666 .{ ._, ._, .movsx, .dst0d, .src0b, ._, ._ },
11667 .{ ._, .i_, .div, .src1b, ._, ._, ._ },
11668 } },
11669 }, .{
11670 .src_constraints = .{ .{ .unsigned_int = .byte }, .{ .unsigned_int = .byte }, .any },
11671 .patterns = &.{
11672 .{ .src = .{ .mem, .mem, .none } },
11673 .{ .src = .{ .to_gpr, .mem, .none } },
11674 .{ .src = .{ .mem, .to_gpr, .none } },
11675 .{ .src = .{ .to_gpr, .to_gpr, .none } },
11676 },
11677 .dst_temps = .{ .{ .reg = .ah }, .unused },
11678 .clobbers = .{ .eflags = true },
11679 .each = .{ .once = &.{
11680 .{ ._, ._, .movzx, .dst0d, .src0b, ._, ._ },
11681 .{ ._, ._, .div, .src1b, ._, ._, ._ },
11682 } },
11683 }, .{
11684 .src_constraints = .{ .{ .signed_int = .word }, .{ .signed_int = .word }, .any },
11685 .patterns = &.{
11686 .{ .src = .{ .{ .to_reg = .ax }, .mem, .none } },
11687 .{ .src = .{ .{ .to_reg = .ax }, .to_gpr, .none } },
11688 },
11689 .dst_temps = .{ .{ .reg = .dx }, .unused },
11690 .clobbers = .{ .eflags = true },
11691 .each = .{ .once = &.{
11692 .{ ._, ._, .cwd, ._, ._, ._, ._ },
11693 .{ ._, .i_, .div, .src1w, ._, ._, ._ },
11694 } },
11695 }, .{
11696 .src_constraints = .{ .{ .unsigned_int = .word }, .{ .unsigned_int = .word }, .any },
11697 .patterns = &.{
11698 .{ .src = .{ .{ .to_reg = .ax }, .mem, .none } },
11699 .{ .src = .{ .{ .to_reg = .ax }, .to_gpr, .none } },
11700 },
11701 .dst_temps = .{ .{ .reg = .dx }, .unused },
11702 .clobbers = .{ .eflags = true },
11703 .each = .{ .once = &.{
11704 .{ ._, ._, .xor, .dst0d, .dst0d, ._, ._ },
11705 .{ ._, ._, .div, .src1w, ._, ._, ._ },
11706 } },
11707 }, .{
11708 .src_constraints = .{ .{ .signed_int = .dword }, .{ .signed_int = .dword }, .any },
11709 .patterns = &.{
11710 .{ .src = .{ .{ .to_reg = .eax }, .mem, .none } },
11711 .{ .src = .{ .{ .to_reg = .eax }, .to_gpr, .none } },
11712 },
11713 .dst_temps = .{ .{ .reg = .edx }, .unused },
11714 .clobbers = .{ .eflags = true },
11715 .each = .{ .once = &.{
11716 .{ ._, ._, .cdq, ._, ._, ._, ._ },
11717 .{ ._, .i_, .div, .src1d, ._, ._, ._ },
11718 } },
11719 }, .{
11720 .src_constraints = .{ .{ .unsigned_int = .dword }, .{ .unsigned_int = .dword }, .any },
11721 .patterns = &.{
11722 .{ .src = .{ .{ .to_reg = .eax }, .mem, .none } },
11723 .{ .src = .{ .{ .to_reg = .eax }, .to_gpr, .none } },
11724 },
11725 .dst_temps = .{ .{ .reg = .edx }, .unused },
11726 .clobbers = .{ .eflags = true },
11727 .each = .{ .once = &.{
11728 .{ ._, ._, .xor, .dst0d, .dst0d, ._, ._ },
11729 .{ ._, ._, .div, .src1d, ._, ._, ._ },
11730 } },
11731 }, .{
11732 .required_features = .{ .@"64bit", null, null, null },
11733 .src_constraints = .{ .{ .signed_int = .qword }, .{ .signed_int = .qword }, .any },
11734 .patterns = &.{
11735 .{ .src = .{ .{ .to_reg = .rax }, .mem, .none } },
11736 .{ .src = .{ .{ .to_reg = .rax }, .to_gpr, .none } },
11737 },
11738 .dst_temps = .{ .{ .reg = .rdx }, .unused },
11739 .clobbers = .{ .eflags = true },
11740 .each = .{ .once = &.{
11741 .{ ._, ._, .cqo, ._, ._, ._, ._ },
11742 .{ ._, .i_, .div, .src1q, ._, ._, ._ },
11743 } },
11744 }, .{
11745 .required_features = .{ .@"64bit", null, null, null },
11746 .src_constraints = .{ .{ .unsigned_int = .qword }, .{ .unsigned_int = .qword }, .any },
11747 .patterns = &.{
11748 .{ .src = .{ .{ .to_reg = .rax }, .mem, .none } },
11749 .{ .src = .{ .{ .to_reg = .rax }, .to_gpr, .none } },
11750 },
11751 .dst_temps = .{ .{ .reg = .rdx }, .unused },
11752 .clobbers = .{ .eflags = true },
11753 .each = .{ .once = &.{
11754 .{ ._, ._, .xor, .dst0q, .dst0q, ._, ._ },
11755 .{ ._, ._, .div, .src1q, ._, ._, ._ },
11756 } },
11757 }, .{
11758 .required_features = .{ .@"64bit", null, null, null },
11759 .src_constraints = .{ .{ .signed_int = .xword }, .{ .signed_int = .xword }, .any },
11760 .patterns = &.{
11761 .{ .src = .{
11762 .{ .to_param_gpr_pair = .{ .cc = .ccc, .index = 0 } },
11763 .{ .to_param_gpr_pair = .{ .cc = .ccc, .index = 2 } },
11764 .none,
11765 } },
11766 },
11767 .call_frame = .{ .alignment = .@"16" },
11768 .extra_temps = .{
11769 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modti3" } } },
11770 .unused,
11771 .unused,
11772 .unused,
11773 .unused,
11774 .unused,
11775 .unused,
11776 .unused,
11777 .unused,
11778 },
11779 .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .index = 0 } }, .unused },
11780 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
11781 .each = .{ .once = &.{
11782 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
11783 } },
11784 }, .{
11785 .required_features = .{ .@"64bit", null, null, null },
11786 .src_constraints = .{ .{ .unsigned_int = .xword }, .{ .unsigned_int = .xword }, .any },
11787 .patterns = &.{
11788 .{ .src = .{
11789 .{ .to_param_gpr_pair = .{ .cc = .ccc, .index = 0 } },
11790 .{ .to_param_gpr_pair = .{ .cc = .ccc, .index = 2 } },
11791 .none,
11792 } },
11793 },
11794 .call_frame = .{ .alignment = .@"16" },
11795 .extra_temps = .{
11796 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__umodti3" } } },
11797 .unused,
11798 .unused,
11799 .unused,
11800 .unused,
11801 .unused,
11802 .unused,
11803 .unused,
11804 .unused,
11805 },
11806 .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .index = 0 } }, .unused },
11807 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
11808 .each = .{ .once = &.{
11809 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
11810 } },
11811 }, .{
11812 .required_features = .{ .@"64bit", null, null, null },
11813 .src_constraints = .{
11814 .{ .remainder_signed_int = .{ .of = .dword, .is = .dword } },
11815 .{ .remainder_signed_int = .{ .of = .dword, .is = .dword } },
11816 .any,
11817 },
11818 .patterns = &.{
11819 .{ .src = .{ .to_mut_mem, .to_mut_mem, .none } },
11820 },
11821 .call_frame = .{ .alignment = .@"16" },
11822 .extra_temps = .{
11823 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } },
11824 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } },
11825 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } },
11826 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } },
11827 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modei4" } } },
11828 .unused,
11829 .unused,
11830 .unused,
11831 .unused,
11832 },
11833 .dst_temps = .{ .mem, .unused },
11834 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
11835 .each = .{ .once = &.{
11836 .{ ._, ._, .lea, .tmp0p, .mem(.dst0), ._, ._ },
11837 .{ ._, ._, .lea, .tmp1p, .mem(.src0), ._, ._ },
11838 .{ ._, ._, .lea, .tmp2p, .mem(.src1), ._, ._ },
11839 .{ ._, ._, .mov, .tmp3d, .sa(.src0, .add_8_size), ._, ._ },
11840 .{ ._, ._, .call, .tmp4d, ._, ._, ._ },
11841 } },
11842 }, .{
11843 .required_features = .{ .@"64bit", null, null, null },
11844 .src_constraints = .{
11845 .{ .remainder_unsigned_int = .{ .of = .dword, .is = .dword } },
11846 .{ .remainder_unsigned_int = .{ .of = .dword, .is = .dword } },
11847 .any,
11848 },
11849 .patterns = &.{
11850 .{ .src = .{ .to_mem, .to_mem, .none } },
11851 },
11852 .call_frame = .{ .alignment = .@"16" },
11853 .extra_temps = .{
11854 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } },
11855 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } },
11856 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } },
11857 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } },
11858 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__umodei4" } } },
11859 .unused,
11860 .unused,
11861 .unused,
11862 .unused,
11863 },
11864 .dst_temps = .{ .mem, .unused },
11865 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
11866 .each = .{ .once = &.{
11867 .{ ._, ._, .lea, .tmp0p, .mem(.dst0), ._, ._ },
11868 .{ ._, ._, .lea, .tmp1p, .mem(.src0), ._, ._ },
11869 .{ ._, ._, .lea, .tmp2p, .mem(.src1), ._, ._ },
11870 .{ ._, ._, .mov, .tmp3d, .sa(.src0, .add_8_size), ._, ._ },
11871 .{ ._, ._, .call, .tmp4d, ._, ._, ._ },
11872 } },
11873 }, .{
11874 .required_features = .{ .slow_incdec, null, null, null },
11875 .src_constraints = .{
11876 .{ .multiple_scalar_signed_int = .{ .of = .byte, .is = .byte } },
11877 .{ .multiple_scalar_signed_int = .{ .of = .byte, .is = .byte } },
11878 .any,
11879 },
11880 .patterns = &.{
11881 .{ .src = .{ .to_mem, .to_mem, .none } },
11882 },
11883 .extra_temps = .{
11884 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
11885 .{ .type = .i8, .kind = .{ .reg = .ah } },
11886 .unused,
11887 .unused,
11888 .unused,
11889 .unused,
11890 .unused,
11891 .unused,
11892 .unused,
11893 },
11894 .dst_temps = .{ .mem, .unused },
11895 .clobbers = .{ .eflags = true },
11896 .each = .{ .once = &.{
11897 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
11898 .{ .@"0:", ._, .movsx, .tmp1d, .memia(.src0b, .tmp0, .add_unaligned_size), ._, ._ },
11899 .{ ._, .i_, .div, .memia(.src1b, .tmp0, .add_unaligned_size), ._, ._, ._ },
11900 .{ ._, ._, .mov, .memia(.dst0b, .tmp0, .add_unaligned_size), .tmp1b, ._, ._ },
11901 .{ ._, ._, .add, .tmp0p, .si(1), ._, ._ },
11902 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
11903 } },
11904 }, .{
11905 .src_constraints = .{
11906 .{ .multiple_scalar_signed_int = .{ .of = .byte, .is = .byte } },
11907 .{ .multiple_scalar_signed_int = .{ .of = .byte, .is = .byte } },
11908 .any,
11909 },
11910 .patterns = &.{
11911 .{ .src = .{ .to_mem, .to_mem, .none } },
11912 },
11913 .extra_temps = .{
11914 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
11915 .{ .type = .i8, .kind = .{ .reg = .ah } },
11916 .unused,
11917 .unused,
11918 .unused,
11919 .unused,
11920 .unused,
11921 .unused,
11922 .unused,
11923 },
11924 .dst_temps = .{ .mem, .unused },
11925 .clobbers = .{ .eflags = true },
11926 .each = .{ .once = &.{
11927 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
11928 .{ .@"0:", ._, .movsx, .tmp1d, .memia(.src0b, .tmp0, .add_unaligned_size), ._, ._ },
11929 .{ ._, .i_, .div, .memia(.src1b, .tmp0, .add_unaligned_size), ._, ._, ._ },
11930 .{ ._, ._, .mov, .memia(.dst0b, .tmp0, .add_unaligned_size), .tmp1b, ._, ._ },
11931 .{ ._, ._c, .in, .tmp0p, ._, ._, ._ },
11932 .{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
11933 } },
11934 }, .{
11935 .required_features = .{ .slow_incdec, null, null, null },
11936 .src_constraints = .{
11937 .{ .multiple_scalar_unsigned_int = .{ .of = .byte, .is = .byte } },
11938 .{ .multiple_scalar_unsigned_int = .{ .of = .byte, .is = .byte } },
11939 .any,
11940 },
11941 .patterns = &.{
11942 .{ .src = .{ .to_mem, .to_mem, .none } },
11943 },
11944 .extra_temps = .{
11945 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
11946 .{ .type = .u8, .kind = .{ .reg = .ah } },
11947 .unused,
11948 .unused,
11949 .unused,
11950 .unused,
11951 .unused,
11952 .unused,
11953 .unused,
11954 },
11955 .dst_temps = .{ .mem, .unused },
11956 .clobbers = .{ .eflags = true },
11957 .each = .{ .once = &.{
11958 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
11959 .{ .@"0:", ._, .movzx, .tmp1d, .memia(.src0b, .tmp0, .add_unaligned_size), ._, ._ },
11960 .{ ._, ._, .div, .memia(.src1b, .tmp0, .add_unaligned_size), ._, ._, ._ },
11961 .{ ._, ._, .mov, .memia(.dst0b, .tmp0, .add_unaligned_size), .tmp1b, ._, ._ },
11962 .{ ._, ._, .add, .tmp0p, .si(1), ._, ._ },
11963 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
11964 } },
11965 }, .{
11966 .src_constraints = .{
11967 .{ .multiple_scalar_unsigned_int = .{ .of = .byte, .is = .byte } },
11968 .{ .multiple_scalar_unsigned_int = .{ .of = .byte, .is = .byte } },
11969 .any,
11970 },
11971 .patterns = &.{
11972 .{ .src = .{ .to_mem, .to_mem, .none } },
11973 },
11974 .extra_temps = .{
11975 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
11976 .{ .type = .u8, .kind = .{ .reg = .ah } },
11977 .unused,
11978 .unused,
11979 .unused,
11980 .unused,
11981 .unused,
11982 .unused,
11983 .unused,
11984 },
11985 .dst_temps = .{ .mem, .unused },
11986 .clobbers = .{ .eflags = true },
11987 .each = .{ .once = &.{
11988 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
11989 .{ .@"0:", ._, .movzx, .tmp1d, .memia(.src0b, .tmp0, .add_unaligned_size), ._, ._ },
11990 .{ ._, ._, .div, .memia(.src1b, .tmp0, .add_unaligned_size), ._, ._, ._ },
11991 .{ ._, ._, .mov, .memia(.dst0b, .tmp0, .add_unaligned_size), .tmp1b, ._, ._ },
11992 .{ ._, ._c, .in, .tmp0p, ._, ._, ._ },
11993 .{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
11994 } },
11995 }, .{
11996 .src_constraints = .{
11997 .{ .multiple_scalar_signed_int = .{ .of = .word, .is = .word } },
11998 .{ .multiple_scalar_signed_int = .{ .of = .word, .is = .word } },
11999 .any,
12000 },
12001 .patterns = &.{
12002 .{ .src = .{ .to_mem, .to_mem, .none } },
12003 },
12004 .extra_temps = .{
12005 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
12006 .{ .type = .i16, .kind = .{ .reg = .ax } },
12007 .{ .type = .i16, .kind = .{ .reg = .dx } },
12008 .unused,
12009 .unused,
12010 .unused,
12011 .unused,
12012 .unused,
12013 .unused,
12014 },
12015 .dst_temps = .{ .mem, .unused },
12016 .clobbers = .{ .eflags = true },
12017 .each = .{ .once = &.{
12018 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
12019 .{ .@"0:", ._, .movsx, .tmp1d, .memia(.src0w, .tmp0, .add_unaligned_size), ._, ._ },
12020 .{ ._, ._, .cwd, ._, ._, ._, ._ },
12021 .{ ._, .i_, .div, .memia(.src1w, .tmp0, .add_unaligned_size), ._, ._, ._ },
12022 .{ ._, ._, .mov, .memia(.dst0w, .tmp0, .add_unaligned_size), .tmp2w, ._, ._ },
12023 .{ ._, ._, .add, .tmp0p, .si(2), ._, ._ },
12024 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
12025 } },
12026 }, .{
12027 .src_constraints = .{
12028 .{ .multiple_scalar_unsigned_int = .{ .of = .word, .is = .word } },
12029 .{ .multiple_scalar_unsigned_int = .{ .of = .word, .is = .word } },
12030 .any,
12031 },
12032 .patterns = &.{
12033 .{ .src = .{ .to_mem, .to_mem, .none } },
12034 },
12035 .extra_temps = .{
12036 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
12037 .{ .type = .u16, .kind = .{ .reg = .ax } },
12038 .{ .type = .u16, .kind = .{ .reg = .dx } },
12039 .unused,
12040 .unused,
12041 .unused,
12042 .unused,
12043 .unused,
12044 .unused,
12045 },
12046 .dst_temps = .{ .mem, .unused },
12047 .clobbers = .{ .eflags = true },
12048 .each = .{ .once = &.{
12049 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
12050 .{ .@"0:", ._, .movzx, .tmp1d, .memia(.src0w, .tmp0, .add_unaligned_size), ._, ._ },
12051 .{ ._, ._, .xor, .tmp2d, .tmp2d, ._, ._ },
12052 .{ ._, ._, .div, .memia(.src1w, .tmp0, .add_unaligned_size), ._, ._, ._ },
12053 .{ ._, ._, .mov, .memia(.dst0w, .tmp0, .add_unaligned_size), .tmp2w, ._, ._ },
12054 .{ ._, ._, .add, .tmp0p, .si(2), ._, ._ },
12055 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
12056 } },
12057 }, .{
12058 .src_constraints = .{
12059 .{ .multiple_scalar_signed_int = .{ .of = .dword, .is = .dword } },
12060 .{ .multiple_scalar_signed_int = .{ .of = .dword, .is = .dword } },
12061 .any,
12062 },
12063 .patterns = &.{
12064 .{ .src = .{ .to_mem, .to_mem, .none } },
12065 },
12066 .extra_temps = .{
12067 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
12068 .{ .type = .i32, .kind = .{ .reg = .eax } },
12069 .{ .type = .i32, .kind = .{ .reg = .edx } },
12070 .unused,
12071 .unused,
12072 .unused,
12073 .unused,
12074 .unused,
12075 .unused,
12076 },
12077 .dst_temps = .{ .mem, .unused },
12078 .clobbers = .{ .eflags = true },
12079 .each = .{ .once = &.{
12080 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
12081 .{ .@"0:", ._, .mov, .tmp1d, .memia(.src0d, .tmp0, .add_unaligned_size), ._, ._ },
12082 .{ ._, ._, .cdq, ._, ._, ._, ._ },
12083 .{ ._, .i_, .div, .memia(.src1d, .tmp0, .add_unaligned_size), ._, ._, ._ },
12084 .{ ._, ._, .mov, .memia(.dst0d, .tmp0, .add_unaligned_size), .tmp2d, ._, ._ },
12085 .{ ._, ._, .add, .tmp0p, .si(4), ._, ._ },
12086 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
12087 } },
12088 }, .{
12089 .src_constraints = .{
12090 .{ .multiple_scalar_unsigned_int = .{ .of = .dword, .is = .dword } },
12091 .{ .multiple_scalar_unsigned_int = .{ .of = .dword, .is = .dword } },
12092 .any,
12093 },
12094 .patterns = &.{
12095 .{ .src = .{ .to_mem, .to_mem, .none } },
12096 },
12097 .extra_temps = .{
12098 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
12099 .{ .type = .u32, .kind = .{ .reg = .eax } },
12100 .{ .type = .u32, .kind = .{ .reg = .edx } },
12101 .unused,
12102 .unused,
12103 .unused,
12104 .unused,
12105 .unused,
12106 .unused,
12107 },
12108 .dst_temps = .{ .mem, .unused },
12109 .clobbers = .{ .eflags = true },
12110 .each = .{ .once = &.{
12111 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
12112 .{ .@"0:", ._, .mov, .tmp1d, .memia(.src0d, .tmp0, .add_unaligned_size), ._, ._ },
12113 .{ ._, ._, .xor, .tmp2d, .tmp2d, ._, ._ },
12114 .{ ._, ._, .div, .memia(.src1d, .tmp0, .add_unaligned_size), ._, ._, ._ },
12115 .{ ._, ._, .mov, .memia(.dst0d, .tmp0, .add_unaligned_size), .tmp2d, ._, ._ },
12116 .{ ._, ._, .add, .tmp0p, .si(4), ._, ._ },
12117 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
12118 } },
12119 }, .{
12120 .required_features = .{ .@"64bit", null, null, null },
12121 .src_constraints = .{
12122 .{ .multiple_scalar_signed_int = .{ .of = .qword, .is = .qword } },
12123 .{ .multiple_scalar_signed_int = .{ .of = .qword, .is = .qword } },
12124 .any,
12125 },
12126 .patterns = &.{
12127 .{ .src = .{ .to_mem, .to_mem, .none } },
12128 },
12129 .extra_temps = .{
12130 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
12131 .{ .type = .i64, .kind = .{ .reg = .rax } },
12132 .{ .type = .i64, .kind = .{ .reg = .rdx } },
12133 .unused,
12134 .unused,
12135 .unused,
12136 .unused,
12137 .unused,
12138 .unused,
12139 },
12140 .dst_temps = .{ .mem, .unused },
12141 .clobbers = .{ .eflags = true },
12142 .each = .{ .once = &.{
12143 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
12144 .{ .@"0:", ._, .mov, .tmp1q, .memia(.src0q, .tmp0, .add_unaligned_size), ._, ._ },
12145 .{ ._, ._, .cqo, ._, ._, ._, ._ },
12146 .{ ._, .i_, .div, .memia(.src1q, .tmp0, .add_unaligned_size), ._, ._, ._ },
12147 .{ ._, ._, .mov, .memia(.dst0q, .tmp0, .add_unaligned_size), .tmp2q, ._, ._ },
12148 .{ ._, ._, .add, .tmp0p, .si(8), ._, ._ },
12149 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
12150 } },
12151 }, .{
12152 .required_features = .{ .@"64bit", null, null, null },
12153 .src_constraints = .{
12154 .{ .multiple_scalar_unsigned_int = .{ .of = .qword, .is = .qword } },
12155 .{ .multiple_scalar_unsigned_int = .{ .of = .qword, .is = .qword } },
12156 .any,
12157 },
12158 .patterns = &.{
12159 .{ .src = .{ .to_mem, .to_mem, .none } },
12160 },
12161 .extra_temps = .{
12162 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
12163 .{ .type = .u64, .kind = .{ .reg = .rax } },
12164 .{ .type = .u64, .kind = .{ .reg = .rdx } },
12165 .unused,
12166 .unused,
12167 .unused,
12168 .unused,
12169 .unused,
12170 .unused,
12171 },
12172 .dst_temps = .{ .mem, .unused },
12173 .clobbers = .{ .eflags = true },
12174 .each = .{ .once = &.{
12175 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
12176 .{ .@"0:", ._, .mov, .tmp1q, .memia(.src0q, .tmp0, .add_unaligned_size), ._, ._ },
12177 .{ ._, ._, .xor, .tmp2d, .tmp2d, ._, ._ },
12178 .{ ._, ._, .div, .memia(.src1q, .tmp0, .add_unaligned_size), ._, ._, ._ },
12179 .{ ._, ._, .mov, .memia(.dst0q, .tmp0, .add_unaligned_size), .tmp2q, ._, ._ },
12180 .{ ._, ._, .add, .tmp0p, .si(8), ._, ._ },
12181 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
12182 } },
12183 }, .{
12184 .required_features = .{ .@"64bit", null, null, null },
12185 .src_constraints = .{
12186 .{ .multiple_scalar_signed_int = .{ .of = .xword, .is = .xword } },
12187 .{ .multiple_scalar_signed_int = .{ .of = .xword, .is = .xword } },
12188 .any,
12189 },
12190 .patterns = &.{
12191 .{ .src = .{ .to_mem, .to_mem, .none } },
12192 },
12193 .call_frame = .{ .alignment = .@"16" },
12194 .extra_temps = .{
12195 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
12196 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } },
12197 .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } },
12198 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } },
12199 .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } },
12200 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modti3" } } },
12201 .{ .type = .u64, .kind = .{ .ret_gpr = .{ .cc = .ccc, .index = 0 } } },
12202 .unused,
12203 .unused,
12204 },
12205 .dst_temps = .{ .mem, .unused },
12206 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
12207 .each = .{ .once = &.{
12208 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
12209 .{ .@"0:", ._, .mov, .tmp1q, .memia(.src0q, .tmp0, .add_unaligned_size), ._, ._ },
12210 .{ ._, ._, .mov, .tmp2q, .memiad(.src0q, .tmp0, .add_unaligned_size, 8), ._, ._ },
12211 .{ ._, ._, .mov, .tmp3q, .memia(.src1q, .tmp0, .add_unaligned_size), ._, ._ },
12212 .{ ._, ._, .mov, .tmp4q, .memiad(.src1q, .tmp0, .add_unaligned_size, 8), ._, ._ },
12213 .{ ._, ._, .call, .tmp5d, ._, ._, ._ },
12214 .{ ._, ._, .mov, .memia(.dst0q, .tmp0, .add_unaligned_size), .tmp6q, ._, ._ },
12215 .{ ._, ._, .mov, .memiad(.dst0q, .tmp0, .add_unaligned_size, 8), .tmp3q, ._, ._ },
12216 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
12217 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
12218 } },
12219 }, .{
12220 .required_features = .{ .@"64bit", null, null, null },
12221 .src_constraints = .{
12222 .{ .multiple_scalar_unsigned_int = .{ .of = .xword, .is = .xword } },
12223 .{ .multiple_scalar_unsigned_int = .{ .of = .xword, .is = .xword } },
12224 .any,
12225 },
12226 .patterns = &.{
12227 .{ .src = .{ .to_mem, .to_mem, .none } },
12228 },
12229 .call_frame = .{ .alignment = .@"16" },
12230 .extra_temps = .{
12231 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
12232 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } },
12233 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } },
12234 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } },
12235 .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } },
12236 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__umodti3" } } },
12237 .{ .type = .u64, .kind = .{ .ret_gpr = .{ .cc = .ccc, .index = 0 } } },
12238 .unused,
12239 .unused,
12240 },
12241 .dst_temps = .{ .mem, .unused },
12242 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
12243 .each = .{ .once = &.{
12244 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
12245 .{ .@"0:", ._, .mov, .tmp1q, .memia(.src0q, .tmp0, .add_unaligned_size), ._, ._ },
12246 .{ ._, ._, .mov, .tmp2q, .memiad(.src0q, .tmp0, .add_unaligned_size, 8), ._, ._ },
12247 .{ ._, ._, .mov, .tmp3q, .memia(.src1q, .tmp0, .add_unaligned_size), ._, ._ },
12248 .{ ._, ._, .mov, .tmp4q, .memiad(.src1q, .tmp0, .add_unaligned_size, 8), ._, ._ },
12249 .{ ._, ._, .call, .tmp5d, ._, ._, ._ },
12250 .{ ._, ._, .mov, .memia(.dst0q, .tmp0, .add_unaligned_size), .tmp6q, ._, ._ },
12251 .{ ._, ._, .mov, .memiad(.dst0q, .tmp0, .add_unaligned_size, 8), .tmp3q, ._, ._ },
12252 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
12253 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
12254 } },
12255 }, .{
12256 .required_features = .{ .@"64bit", null, null, null },
12257 .src_constraints = .{
12258 .{ .scalar_remainder_signed_int = .{ .of = .dword, .is = .dword } },
12259 .{ .scalar_remainder_signed_int = .{ .of = .dword, .is = .dword } },
12260 .any,
12261 },
12262 .patterns = &.{
12263 .{ .src = .{ .to_mut_mem, .to_mut_mem, .none } },
12264 },
12265 .call_frame = .{ .alignment = .@"16" },
12266 .extra_temps = .{
12267 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
12268 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } },
12269 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } },
12270 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } },
12271 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } },
12272 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modei4" } } },
12273 .unused,
12274 .unused,
12275 .unused,
12276 },
12277 .dst_temps = .{ .mem, .unused },
12278 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
12279 .each = .{ .once = &.{
12280 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
12281 .{ .@"0:", ._, .lea, .tmp1p, .memia(.dst0, .tmp0, .add_unaligned_size), ._, ._ },
12282 .{ ._, ._, .lea, .tmp2p, .memia(.src0, .tmp0, .add_unaligned_size), ._, ._ },
12283 .{ ._, ._, .lea, .tmp3p, .memia(.src1, .tmp0, .add_unaligned_size), ._, ._ },
12284 .{ ._, ._, .mov, .tmp4d, .sa(.src0, .add_8_elem_size), ._, ._ },
12285 .{ ._, ._, .call, .tmp5d, ._, ._, ._ },
12286 .{ ._, ._, .add, .tmp0p, .sa(.src0, .add_elem_size), ._, ._ },
12287 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
12288 } },
12289 }, .{
12290 .required_features = .{ .@"64bit", null, null, null },
12291 .src_constraints = .{
12292 .{ .scalar_remainder_unsigned_int = .{ .of = .dword, .is = .dword } },
12293 .{ .scalar_remainder_unsigned_int = .{ .of = .dword, .is = .dword } },
12294 .any,
12295 },
12296 .patterns = &.{
12297 .{ .src = .{ .to_mut_mem, .to_mut_mem, .none } },
12298 },
12299 .call_frame = .{ .alignment = .@"16" },
12300 .extra_temps = .{
12301 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
12302 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } },
12303 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } },
12304 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } },
12305 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } },
12306 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__umodei4" } } },
12307 .unused,
12308 .unused,
12309 .unused,
12310 },
12311 .dst_temps = .{ .mem, .unused },
12312 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
12313 .each = .{ .once = &.{
12314 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
12315 .{ .@"0:", ._, .lea, .tmp1p, .memia(.dst0, .tmp0, .add_unaligned_size), ._, ._ },
12316 .{ ._, ._, .lea, .tmp2p, .memia(.src0, .tmp0, .add_unaligned_size), ._, ._ },
12317 .{ ._, ._, .lea, .tmp3p, .memia(.src1, .tmp0, .add_unaligned_size), ._, ._ },
12318 .{ ._, ._, .mov, .tmp4d, .sa(.src0, .add_8_elem_size), ._, ._ },
12319 .{ ._, ._, .call, .tmp5d, ._, ._, ._ },
12320 .{ ._, ._, .add, .tmp0p, .sa(.src0, .add_elem_size), ._, ._ },
12321 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
12322 } },
12323 }, .{
1165712324 .required_features = .{ .sse, null, null, null },
1165812325 .src_constraints = .{
1165912326 .{ .scalar_float = .{ .of = .word, .is = .word } },
test/behavior/math.zig+1-1
......@@ -527,7 +527,7 @@ fn testIntDivision() !void {
527527 try expect(mod(i64, -14, 12) == 10);
528528 try expect(mod(i16, -2, 12) == 10);
529529 try expect(mod(i16, -118, 12) == 2);
530 try expect(mod(i8, -2, 12) == 10); // TODO: fails in x86_64
530 try expect(mod(i8, -2, 12) == 10);
531531
532532 try expect(rem(i64, -118, 12) == -10);
533533 try expect(rem(i32, 10, 12) == 10);
test/behavior/x86_64/math.zig+23-15
......@@ -19079,25 +19079,33 @@ test divFloor {
1907919079// workaround https://github.com/ziglang/zig/issues/22748
1908019080// TODO: @TypeOf(@rem(lhs, rhs))
1908119081inline fn rem(comptime Type: type, lhs: Type, rhs: Type) Type {
19082 if (@inComptime()) {
19083 // workaround https://github.com/ziglang/zig/issues/22748
19084 switch (@typeInfo(Type)) {
19085 else => return if (rhs != 0) @rem(lhs, rhs) else nan(Type),
19086 .vector => |info| {
19087 var res: Type = undefined;
19088 inline for (0..info.len) |i| res[i] = if (rhs[i] != 0) @rem(lhs[i], rhs[i]) else nan(Scalar(Type));
19089 return res;
19090 },
19091 }
19082 switch (@typeInfo(Scalar(Type))) {
19083 else => @compileError(@typeName(Type)),
19084 .int => return @rem(lhs, rhs),
19085 .float => {
19086 if (@inComptime()) {
19087 // workaround https://github.com/ziglang/zig/issues/22748
19088 switch (@typeInfo(Type)) {
19089 else => return if (rhs != 0) @rem(lhs, rhs) else nan(Type),
19090 .vector => |info| {
19091 var res: Type = undefined;
19092 inline for (0..info.len) |i| res[i] = if (rhs[i] != 0) @rem(lhs[i], rhs[i]) else nan(Scalar(Type));
19093 return res;
19094 },
19095 }
19096 }
19097 // workaround https://github.com/ziglang/zig/issues/22748
19098 // TODO: return @rem(lhs, rhs);
19099 var rt_rhs = rhs;
19100 _ = &rt_rhs;
19101 return @rem(lhs, rt_rhs);
19102 },
1909219103 }
19093 // workaround https://github.com/ziglang/zig/issues/22748
19094 // TODO: return @rem(lhs, rhs);
19095 var rt_rhs = rhs;
19096 _ = &rt_rhs;
19097 return @rem(lhs, rt_rhs);
1909819104}
1909919105test rem {
1910019106 const test_rem = binary(rem, .{});
19107 try test_rem.testInts();
19108 try test_rem.testIntVectors();
1910119109 try test_rem.testFloats();
1910219110 try test_rem.testFloatVectors();
1910319111}
test/cases/safety/exact division failure - vectors.zig +1-1
......@@ -19,5 +19,5 @@ fn divExact(a: @Vector(4, i32), b: @Vector(4, i32)) @Vector(4, i32) {
1919 return @divExact(a, b);
2020}
2121// run
22// backend=llvm
22// backend=stage2,llvm
2323// target=native