mirror of
https://github.com/ziglang/zig.git
synced 2026-02-14 05:20:34 +00:00
x86_64: rewrite scalar @subWithOverflow
This commit is contained in:
parent
80068b6e59
commit
55ce756868
@ -2418,7 +2418,7 @@ fn genBodyBlock(self: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
|
||||
}
|
||||
|
||||
fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
|
||||
@setEvalBranchQuota(14_100);
|
||||
@setEvalBranchQuota(14_200);
|
||||
const pt = cg.pt;
|
||||
const zcu = pt.zcu;
|
||||
const ip = &zcu.intern_pool;
|
||||
@ -2459,7 +2459,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
|
||||
.mul_sat => try cg.airMulSat(inst),
|
||||
.shl_sat => try cg.airShlSat(inst),
|
||||
|
||||
.sub_with_overflow => try cg.airAddSubWithOverflow(inst),
|
||||
.mul_with_overflow => try cg.airMulWithOverflow(inst),
|
||||
.shl_with_overflow => try cg.airShlWithOverflow(inst),
|
||||
|
||||
@ -28500,8 +28499,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
|
||||
.{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
|
||||
.{ ._, ._, .mov, .tmp1q, .memad(.src0q, .add_size, -16), ._, ._ },
|
||||
.{ ._, ._, .adc, .tmp1q, .memad(.src1q, .add_size, -16), ._, ._ },
|
||||
.{ ._, ._, .mov, .memad(.dst0q, .add_src0_size, -16), .tmp1q, ._, ._ },
|
||||
.{ ._, ._o, .set, .mema(.dst0b, .add_src0_size), ._, ._, ._ },
|
||||
.{ ._, ._, .mov, .memad(.dst0q, .add_src0_size, -16), .tmp1q, ._, ._ },
|
||||
.{ ._, ._r, .sa, .tmp1q, .ui(63), ._, ._ },
|
||||
.{ ._, ._, .mov, .memad(.dst0q, .add_src0_size, -8), .tmp1q, ._, ._ },
|
||||
} },
|
||||
@ -28869,6 +28868,912 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
|
||||
try res[0].withOverflow(&res[1], cg);
|
||||
try res[0].finish(inst, &.{ bin_op.lhs, bin_op.rhs }, &ops, cg);
|
||||
},
|
||||
.sub_with_overflow => |air_tag| if (use_old) try cg.airAddSubWithOverflow(inst) else fallback: {
|
||||
const ty_pl = air_datas[@intFromEnum(inst)].ty_pl;
|
||||
const bin_op = cg.air.extraData(Air.Bin, ty_pl.payload).data;
|
||||
if (cg.typeOf(bin_op.lhs).isVector(zcu)) break :fallback try cg.airAddSubWithOverflow(inst);
|
||||
var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs });
|
||||
var res: [2]Temp = undefined;
|
||||
cg.select(&res, &.{ ty_pl.ty.toType(), .u1 }, &ops, comptime &.{ .{
|
||||
.src_constraints = .{ .{ .exact_signed_int = 8 }, .{ .exact_signed_int = 8 }, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mut_gpr, .imm8, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .mem, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .to_gpr, .none } },
|
||||
},
|
||||
.dst_temps = .{ .{ .ref = .src0 }, .{ .cc = .o } },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .sub, .dst0b, .src1b, ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.src_constraints = .{ .{ .exact_unsigned_int = 8 }, .{ .exact_unsigned_int = 8 }, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mut_gpr, .imm8, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .mem, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .to_gpr, .none } },
|
||||
},
|
||||
.dst_temps = .{ .{ .ref = .src0 }, .{ .cc = .c } },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .sub, .dst0b, .src1b, ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.src_constraints = .{ .{ .signed_int = .byte }, .{ .signed_int = .byte }, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mut_gpr, .imm8, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .mem, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .to_gpr, .none } },
|
||||
},
|
||||
.extra_temps = .{
|
||||
.{ .type = .i8, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } },
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
},
|
||||
.dst_temps = .{ .{ .ref = .src0 }, .{ .cc = .po } },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .sub, .dst0b, .src1b, ._, ._ },
|
||||
.{ ._, ._, .mov, .tmp0d, .dst0d, ._, ._ },
|
||||
.{ ._, ._l, .sa, .dst0b, .uia(8, .src0, .sub_bit_size), ._, ._ },
|
||||
.{ ._, ._r, .sa, .dst0b, .uia(8, .src0, .sub_bit_size), ._, ._ },
|
||||
.{ ._, ._, .@"test", .tmp0b, .sia(-1 << 7, .src0, .sub_smin), ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.src_constraints = .{ .{ .unsigned_int = .byte }, .{ .unsigned_int = .byte }, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mut_gpr, .imm8, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .mem, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .immut_gpr, .none } },
|
||||
},
|
||||
.dst_temps = .{ .{ .ref = .src0 }, .{ .rc = .general_purpose } },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .xor, .dst1d, .dst1d, ._, ._ },
|
||||
.{ ._, ._, .sub, .dst0b, .src1b, ._, ._ },
|
||||
.{ ._, ._c, .set, .dst1b, ._, ._, ._ },
|
||||
.{ ._, ._, .@"and", .dst0b, .ua(.src0, .add_umax), ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.src_constraints = .{ .{ .unsigned_int = .byte }, .{ .unsigned_int = .byte }, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mut_gpr, .to_mut_gpr, .none } },
|
||||
},
|
||||
.dst_temps = .{ .{ .ref = .src0 }, .{ .ref = .src1 } },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .sub, .dst0b, .src1b, ._, ._ },
|
||||
.{ ._, ._c, .set, .dst1b, ._, ._, ._ },
|
||||
.{ ._, ._, .@"and", .dst0b, .ua(.src0, .add_umax), ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.src_constraints = .{ .{ .exact_signed_int = 16 }, .{ .exact_signed_int = 16 }, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mut_gpr, .imm16, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .mem, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .to_gpr, .none } },
|
||||
},
|
||||
.dst_temps = .{ .{ .ref = .src0 }, .{ .cc = .o } },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .sub, .dst0w, .src1w, ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.src_constraints = .{ .{ .exact_unsigned_int = 16 }, .{ .exact_unsigned_int = 16 }, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mut_gpr, .imm8, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .mem, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .to_gpr, .none } },
|
||||
},
|
||||
.dst_temps = .{ .{ .ref = .src0 }, .{ .cc = .c } },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .sub, .dst0w, .src1w, ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.src_constraints = .{ .{ .signed_int = .word }, .{ .signed_int = .word }, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mut_gpr, .imm16, .none } },
|
||||
},
|
||||
.extra_temps = .{
|
||||
.{ .type = .i32, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } },
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
},
|
||||
.dst_temps = .{ .{ .ref = .src0 }, .{ .cc = .o } },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .sub, .dst0w, .src1w, ._, ._ },
|
||||
.{ ._, ._l, .ro, .dst0d, .uia(32, .src0, .sub_bit_size), ._, ._ },
|
||||
.{ ._, ._, .mov, .tmp0d, .dst0d, ._, ._ },
|
||||
.{ ._, ._r, .sa, .dst0d, .uia(32, .src0, .sub_bit_size), ._, ._ },
|
||||
.{ ._, ._r, .ro, .tmp0d, .ui(1), ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.src_constraints = .{ .{ .signed_int = .word }, .{ .signed_int = .word }, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mut_gpr, .mem, .none } },
|
||||
},
|
||||
.extra_temps = .{
|
||||
.{ .type = .i32, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } },
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
},
|
||||
.dst_temps = .{ .{ .ref = .src0 }, .{ .cc = .o } },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .sub, .dst0w, .src1w, ._, ._ },
|
||||
.{ ._, ._l, .ro, .dst0d, .uia(32, .src0, .sub_bit_size), ._, ._ },
|
||||
.{ ._, ._, .mov, .tmp0d, .dst0d, ._, ._ },
|
||||
.{ ._, ._r, .sa, .dst0d, .uia(32, .src0, .sub_bit_size), ._, ._ },
|
||||
.{ ._, ._r, .ro, .tmp0d, .ui(1), ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .fast_imm16, null, null, null },
|
||||
.src_constraints = .{ .{ .unsigned_int = .word }, .{ .unsigned_int = .word }, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mut_gpr, .imm16, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .mem, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .immut_gpr, .none } },
|
||||
},
|
||||
.dst_temps = .{ .{ .ref = .src0 }, .{ .rc = .general_purpose } },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .xor, .dst1d, .dst1d, ._, ._ },
|
||||
.{ ._, ._, .sub, .dst0w, .src1w, ._, ._ },
|
||||
.{ ._, ._c, .set, .dst1b, ._, ._, ._ },
|
||||
.{ ._, ._, .@"and", .dst0w, .ua(.src0, .add_umax), ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .fast_imm16, null, null, null },
|
||||
.src_constraints = .{ .{ .unsigned_int = .word }, .{ .unsigned_int = .word }, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mut_gpr, .to_mut_gpr, .none } },
|
||||
},
|
||||
.dst_temps = .{ .{ .ref = .src0 }, .{ .ref = .src1 } },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .sub, .dst0w, .src1w, ._, ._ },
|
||||
.{ ._, ._c, .set, .dst1b, ._, ._, ._ },
|
||||
.{ ._, ._, .@"and", .dst0w, .ua(.src0, .add_umax), ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.src_constraints = .{ .{ .unsigned_int = .word }, .{ .unsigned_int = .word }, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mut_gpr, .imm16, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .mem, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .immut_gpr, .none } },
|
||||
},
|
||||
.dst_temps = .{ .{ .ref = .src0 }, .{ .rc = .general_purpose } },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .xor, .dst1d, .dst1d, ._, ._ },
|
||||
.{ ._, ._, .sub, .dst0w, .src1w, ._, ._ },
|
||||
.{ ._, ._c, .set, .dst1b, ._, ._, ._ },
|
||||
.{ ._, ._, .@"and", .dst0d, .ua(.src0, .add_umax), ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.src_constraints = .{ .{ .unsigned_int = .word }, .{ .unsigned_int = .word }, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mut_gpr, .to_mut_gpr, .none } },
|
||||
},
|
||||
.dst_temps = .{ .{ .ref = .src0 }, .{ .ref = .src1 } },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .sub, .dst0w, .src1w, ._, ._ },
|
||||
.{ ._, ._c, .set, .dst1b, ._, ._, ._ },
|
||||
.{ ._, ._, .@"and", .dst0d, .ua(.src0, .add_umax), ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.src_constraints = .{ .{ .exact_signed_int = 32 }, .{ .exact_signed_int = 32 }, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mut_gpr, .imm32, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .mem, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .to_gpr, .none } },
|
||||
},
|
||||
.dst_temps = .{ .{ .ref = .src0 }, .{ .cc = .o } },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .sub, .dst0d, .src1d, ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.src_constraints = .{ .{ .exact_unsigned_int = 32 }, .{ .exact_unsigned_int = 32 }, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mut_gpr, .imm32, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .mem, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .to_gpr, .none } },
|
||||
},
|
||||
.dst_temps = .{ .{ .ref = .src0 }, .{ .cc = .c } },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .sub, .dst0d, .src1d, ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .bmi2, null, null, null },
|
||||
.src_constraints = .{ .{ .exact_signed_int = 31 }, .{ .exact_signed_int = 31 }, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mut_gpr, .imm32, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .mem, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .to_gpr, .none } },
|
||||
},
|
||||
.extra_temps = .{
|
||||
.{ .type = .u8, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } },
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
},
|
||||
.dst_temps = .{ .{ .ref = .src0 }, .{ .cc = .o } },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .sub, .dst0d, .src1d, ._, ._ },
|
||||
.{ ._, ._, .mov, .tmp0d, .ui(1), ._, ._ },
|
||||
.{ ._, ._, .add, .dst0d, .dst0d, ._, ._ },
|
||||
.{ ._, ._rx, .sa, .dst0d, .dst0d, .tmp0d, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.src_constraints = .{ .{ .signed_int = .dword }, .{ .signed_int = .dword }, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mut_gpr, .imm32, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .mem, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .to_gpr, .none } },
|
||||
},
|
||||
.extra_temps = .{
|
||||
.{ .type = .i32, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } },
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
},
|
||||
.dst_temps = .{ .{ .ref = .src0 }, .{ .cc = .o } },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .sub, .dst0d, .src1d, ._, ._ },
|
||||
.{ ._, ._l, .ro, .dst0d, .uia(32, .src0, .sub_bit_size), ._, ._ },
|
||||
.{ ._, ._, .mov, .tmp0d, .dst0d, ._, ._ },
|
||||
.{ ._, ._r, .sa, .dst0d, .uia(32, .src0, .sub_bit_size), ._, ._ },
|
||||
.{ ._, ._r, .ro, .tmp0d, .ui(1), ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.src_constraints = .{ .{ .unsigned_int = .dword }, .{ .unsigned_int = .dword }, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mut_gpr, .imm32, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .mem, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .immut_gpr, .none } },
|
||||
},
|
||||
.dst_temps = .{ .{ .ref = .src0 }, .{ .rc = .general_purpose } },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .xor, .dst1d, .dst1d, ._, ._ },
|
||||
.{ ._, ._, .sub, .dst0d, .src1d, ._, ._ },
|
||||
.{ ._, ._c, .set, .dst1b, ._, ._, ._ },
|
||||
.{ ._, ._, .@"and", .dst0d, .ua(.src0, .add_umax), ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.src_constraints = .{ .{ .unsigned_int = .dword }, .{ .unsigned_int = .dword }, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mut_gpr, .to_mut_gpr, .none } },
|
||||
},
|
||||
.dst_temps = .{ .{ .ref = .src0 }, .{ .ref = .src1 } },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .sub, .dst0d, .src1d, ._, ._ },
|
||||
.{ ._, ._c, .set, .dst1b, ._, ._, ._ },
|
||||
.{ ._, ._, .@"and", .dst0d, .ua(.src0, .add_umax), ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .@"64bit", null, null, null },
|
||||
.src_constraints = .{ .{ .exact_signed_int = 64 }, .{ .exact_signed_int = 64 }, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mut_gpr, .simm32, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .mem, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .to_gpr, .none } },
|
||||
},
|
||||
.dst_temps = .{ .{ .ref = .src0 }, .{ .cc = .o } },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .sub, .dst0q, .src1q, ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .@"64bit", null, null, null },
|
||||
.src_constraints = .{ .{ .exact_unsigned_int = 64 }, .{ .exact_unsigned_int = 64 }, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mut_gpr, .simm32, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .mem, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .to_gpr, .none } },
|
||||
},
|
||||
.dst_temps = .{ .{ .ref = .src0 }, .{ .cc = .c } },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .sub, .dst0q, .src1q, ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .@"64bit", .bmi2, null, null },
|
||||
.src_constraints = .{ .{ .exact_signed_int = 63 }, .{ .exact_signed_int = 63 }, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mut_gpr, .simm32, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .mem, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .to_gpr, .none } },
|
||||
},
|
||||
.extra_temps = .{
|
||||
.{ .type = .u8, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } },
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
},
|
||||
.dst_temps = .{ .{ .ref = .src0 }, .{ .cc = .o } },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .sub, .dst0q, .src1q, ._, ._ },
|
||||
.{ ._, ._, .mov, .tmp0d, .ui(1), ._, ._ },
|
||||
.{ ._, ._, .add, .dst0q, .dst0q, ._, ._ },
|
||||
.{ ._, ._rx, .sa, .dst0q, .dst0q, .tmp0q, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .@"64bit", null, null, null },
|
||||
.src_constraints = .{ .{ .signed_int = .qword }, .{ .signed_int = .qword }, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mut_gpr, .simm32, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .mem, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .to_gpr, .none } },
|
||||
},
|
||||
.extra_temps = .{
|
||||
.{ .type = .i64, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } },
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
},
|
||||
.dst_temps = .{ .{ .ref = .src0 }, .{ .cc = .o } },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .sub, .dst0q, .src1q, ._, ._ },
|
||||
.{ ._, ._l, .ro, .dst0q, .uia(64, .src0, .sub_bit_size), ._, ._ },
|
||||
.{ ._, ._, .mov, .tmp0q, .dst0q, ._, ._ },
|
||||
.{ ._, ._r, .sa, .dst0q, .uia(64, .src0, .sub_bit_size), ._, ._ },
|
||||
.{ ._, ._r, .ro, .tmp0q, .ui(1), ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .@"64bit", .bmi2, null, null },
|
||||
.src_constraints = .{ .{ .unsigned_int = .qword }, .{ .unsigned_int = .qword }, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mut_gpr, .simm32, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .mem, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .immut_gpr, .none } },
|
||||
},
|
||||
.extra_temps = .{
|
||||
.{ .type = .u8, .kind = .{ .rc = .general_purpose } },
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
},
|
||||
.dst_temps = .{ .{ .ref = .src0 }, .{ .rc = .general_purpose } },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .xor, .dst1d, .dst1d, ._, ._ },
|
||||
.{ ._, ._, .mov, .tmp0d, .ua(.src0, .add_bit_size), ._, ._ },
|
||||
.{ ._, ._, .sub, .dst0q, .src1q, ._, ._ },
|
||||
.{ ._, ._c, .set, .dst1b, ._, ._, ._ },
|
||||
.{ ._, ._, .bzhi, .dst0q, .dst0q, .tmp0q, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .@"64bit", .bmi2, null, null },
|
||||
.src_constraints = .{ .{ .unsigned_int = .qword }, .{ .unsigned_int = .qword }, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mut_gpr, .to_mut_gpr, .none } },
|
||||
},
|
||||
.extra_temps = .{
|
||||
.{ .type = .u8, .kind = .{ .rc = .general_purpose } },
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
},
|
||||
.dst_temps = .{ .{ .ref = .src0 }, .{ .ref = .src1 } },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .mov, .tmp0d, .ua(.src0, .add_bit_size), ._, ._ },
|
||||
.{ ._, ._, .sub, .dst0q, .src1q, ._, ._ },
|
||||
.{ ._, ._c, .set, .dst1b, ._, ._, ._ },
|
||||
.{ ._, ._, .bzhi, .dst0q, .dst0q, .tmp0q, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .@"64bit", null, null, null },
|
||||
.src_constraints = .{ .{ .unsigned_int = .qword }, .{ .unsigned_int = .qword }, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mut_gpr, .simm32, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .mem, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .immut_gpr, .none } },
|
||||
},
|
||||
.dst_temps = .{ .{ .rc = .general_purpose }, .{ .rc = .general_purpose } },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .xor, .dst1d, .dst1d, ._, ._ },
|
||||
.{ ._, ._, .mov, .dst0q, .ua(.src0, .add_umax), ._, ._ },
|
||||
.{ ._, ._, .sub, .src0q, .src1q, ._, ._ },
|
||||
.{ ._, ._c, .set, .dst1b, ._, ._, ._ },
|
||||
.{ ._, ._, .@"and", .dst0q, .src0q, ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .@"64bit", null, null, null },
|
||||
.src_constraints = .{ .{ .unsigned_int = .qword }, .{ .unsigned_int = .qword }, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mut_gpr, .to_mut_gpr, .none } },
|
||||
},
|
||||
.dst_temps = .{ .{ .rc = .general_purpose }, .{ .ref = .src1 } },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .mov, .dst0q, .ua(.src0, .add_umax), ._, ._ },
|
||||
.{ ._, ._, .sub, .src0q, .src1q, ._, ._ },
|
||||
.{ ._, ._c, .set, .dst1b, ._, ._, ._ },
|
||||
.{ ._, ._, .@"and", .dst0q, .src0q, ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .@"64bit", null, null, null },
|
||||
.src_constraints = .{
|
||||
.{ .exact_remainder_signed_int = .{ .of = .xword, .is = .qword } },
|
||||
.{ .exact_remainder_signed_int = .{ .of = .xword, .is = .qword } },
|
||||
.any,
|
||||
},
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mem, .to_mem, .none } },
|
||||
},
|
||||
.extra_temps = .{
|
||||
.{ .type = .isize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
},
|
||||
.dst_temps = .{ .mem, .none },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .mov, .tmp0p, .sia(2, .src0, .sub_size_div_8), ._, ._ },
|
||||
.{ ._, ._c, .cl, ._, ._, ._, ._ },
|
||||
.{ .@"0:", ._, .mov, .tmp1q, .memsiad(.src0q, .@"8", .tmp0, .add_size, -16), ._, ._ },
|
||||
.{ ._, ._, .sbb, .tmp1q, .memsiad(.src1q, .@"8", .tmp0, .add_size, -16), ._, ._ },
|
||||
.{ ._, ._, .mov, .memsiad(.dst0q, .@"8", .tmp0, .add_src0_size, -16), .tmp1q, ._, ._ },
|
||||
.{ ._, ._c, .in, .tmp0p, ._, ._, ._ },
|
||||
.{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
|
||||
.{ ._, ._, .mov, .tmp1q, .memad(.src0q, .add_size, -16), ._, ._ },
|
||||
.{ ._, ._, .sbb, .tmp1q, .memad(.src1q, .add_size, -16), ._, ._ },
|
||||
.{ ._, ._o, .set, .mema(.dst0b, .add_src0_size), ._, ._, ._ },
|
||||
.{ ._, ._, .mov, .memad(.dst0q, .add_src0_size, -16), .tmp1q, ._, ._ },
|
||||
.{ ._, ._r, .sa, .tmp1q, .ui(63), ._, ._ },
|
||||
.{ ._, ._, .mov, .memad(.dst0q, .add_src0_size, -8), .tmp1q, ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .@"64bit", null, null, null },
|
||||
.src_constraints = .{
|
||||
.{ .exact_remainder_unsigned_int = .{ .of = .xword, .is = .qword } },
|
||||
.{ .exact_remainder_unsigned_int = .{ .of = .xword, .is = .qword } },
|
||||
.any,
|
||||
},
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mem, .to_mem, .none } },
|
||||
},
|
||||
.extra_temps = .{
|
||||
.{ .type = .isize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
},
|
||||
.dst_temps = .{ .mem, .{ .cc = .c } },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .mov, .tmp0p, .sia(1, .src0, .sub_size_div_8), ._, ._ },
|
||||
.{ ._, ._c, .cl, ._, ._, ._, ._ },
|
||||
.{ .@"0:", ._, .mov, .tmp1q, .memsiad(.src0q, .@"8", .tmp0, .add_size, -8), ._, ._ },
|
||||
.{ ._, ._, .sbb, .tmp1q, .memsiad(.src1q, .@"8", .tmp0, .add_size, -8), ._, ._ },
|
||||
.{ ._, ._, .mov, .memsiad(.dst0q, .@"8", .tmp0, .add_src0_size, -8), .tmp1q, ._, ._ },
|
||||
.{ ._, ._c, .in, .tmp0p, ._, ._, ._ },
|
||||
.{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
|
||||
.{ ._, ._, .mov, .memad(.dst0q, .add_src0_size, -8), .ui(0), ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .@"64bit", null, null, null },
|
||||
.src_constraints = .{
|
||||
.{ .exact_remainder_signed_int = .{ .of = .xword, .is = .xword } },
|
||||
.{ .exact_remainder_signed_int = .{ .of = .xword, .is = .xword } },
|
||||
.any,
|
||||
},
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mem, .to_mem, .none } },
|
||||
},
|
||||
.extra_temps = .{
|
||||
.{ .type = .isize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
},
|
||||
.dst_temps = .{ .mem, .{ .cc = .o } },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .mov, .tmp0p, .sia(1, .src0, .sub_size_div_8), ._, ._ },
|
||||
.{ ._, ._c, .cl, ._, ._, ._, ._ },
|
||||
.{ .@"0:", ._, .mov, .tmp1q, .memsiad(.src0q, .@"8", .tmp0, .add_size, -8), ._, ._ },
|
||||
.{ ._, ._, .sbb, .tmp1q, .memsiad(.src1q, .@"8", .tmp0, .add_size, -8), ._, ._ },
|
||||
.{ ._, ._, .mov, .memsiad(.dst0q, .@"8", .tmp0, .add_src0_size, -8), .tmp1q, ._, ._ },
|
||||
.{ ._, ._c, .in, .tmp0p, ._, ._, ._ },
|
||||
.{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
|
||||
.{ ._, ._, .mov, .tmp1q, .memad(.src0q, .add_size, -8), ._, ._ },
|
||||
.{ ._, ._, .sbb, .tmp1q, .memad(.src1q, .add_size, -8), ._, ._ },
|
||||
.{ ._, ._, .mov, .memad(.dst0q, .add_src0_size, -8), .tmp1q, ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .@"64bit", null, null, null },
|
||||
.src_constraints = .{
|
||||
.{ .exact_remainder_unsigned_int = .{ .of = .xword, .is = .xword } },
|
||||
.{ .exact_remainder_unsigned_int = .{ .of = .xword, .is = .xword } },
|
||||
.any,
|
||||
},
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mem, .to_mem, .none } },
|
||||
},
|
||||
.extra_temps = .{
|
||||
.{ .type = .isize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
},
|
||||
.dst_temps = .{ .mem, .{ .cc = .c } },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size_div_8), ._, ._ },
|
||||
.{ ._, ._c, .cl, ._, ._, ._, ._ },
|
||||
.{ .@"0:", ._, .mov, .tmp1q, .memsia(.src0q, .@"8", .tmp0, .add_size), ._, ._ },
|
||||
.{ ._, ._, .sbb, .tmp1q, .memsia(.src1q, .@"8", .tmp0, .add_size), ._, ._ },
|
||||
.{ ._, ._, .mov, .memsia(.dst0q, .@"8", .tmp0, .add_src0_size), .tmp1q, ._, ._ },
|
||||
.{ ._, ._c, .in, .tmp0p, ._, ._, ._ },
|
||||
.{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .@"64bit", null, null, null },
|
||||
.src_constraints = .{
|
||||
.{ .remainder_signed_int = .{ .of = .xword, .is = .qword } },
|
||||
.{ .remainder_signed_int = .{ .of = .xword, .is = .qword } },
|
||||
.any,
|
||||
},
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mem, .to_mem, .none } },
|
||||
},
|
||||
.extra_temps = .{
|
||||
.{ .type = .isize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
},
|
||||
.dst_temps = .{ .mem, .{ .cc = .o } },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .mov, .tmp0p, .sia(2, .src0, .sub_size_div_8), ._, ._ },
|
||||
.{ ._, ._c, .cl, ._, ._, ._, ._ },
|
||||
.{ .@"0:", ._, .mov, .tmp1q, .memsiad(.src0q, .@"8", .tmp0, .add_size, -16), ._, ._ },
|
||||
.{ ._, ._, .sbb, .tmp1q, .memsiad(.src1q, .@"8", .tmp0, .add_size, -16), ._, ._ },
|
||||
.{ ._, ._, .mov, .memsiad(.dst0q, .@"8", .tmp0, .add_src0_size, -16), .tmp1q, ._, ._ },
|
||||
.{ ._, ._c, .in, .tmp0p, ._, ._, ._ },
|
||||
.{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
|
||||
.{ ._, ._, .mov, .tmp1q, .memad(.src0q, .add_size, -16), ._, ._ },
|
||||
.{ ._, ._, .sbb, .tmp1q, .memad(.src1q, .add_size, -16), ._, ._ },
|
||||
.{ ._, ._l, .ro, .tmp1q, .uia(64, .src0, .sub_bit_size_rem_64), ._, ._ },
|
||||
.{ ._, ._, .mov, .tmp0q, .tmp1q, ._, ._ },
|
||||
.{ ._, ._r, .sa, .tmp1q, .uia(64, .src0, .sub_bit_size_rem_64), ._, ._ },
|
||||
.{ ._, ._, .mov, .memad(.dst0q, .add_src0_size, -16), .tmp1q, ._, ._ },
|
||||
.{ ._, ._r, .sa, .tmp1q, .ui(63), ._, ._ },
|
||||
.{ ._, ._r, .ro, .tmp0q, .ui(1), ._, ._ },
|
||||
.{ ._, ._, .mov, .memad(.dst0q, .add_src0_size, -8), .tmp1q, ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .@"64bit", .bmi2, null, null },
|
||||
.src_constraints = .{
|
||||
.{ .remainder_unsigned_int = .{ .of = .xword, .is = .qword } },
|
||||
.{ .remainder_unsigned_int = .{ .of = .xword, .is = .qword } },
|
||||
.any,
|
||||
},
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mem, .to_mem, .none } },
|
||||
},
|
||||
.extra_temps = .{
|
||||
.{ .type = .isize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
},
|
||||
.dst_temps = .{ .mem, .none },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .mov, .tmp0p, .sia(2, .src0, .sub_size_div_8), ._, ._ },
|
||||
.{ ._, ._c, .cl, ._, ._, ._, ._ },
|
||||
.{ .@"0:", ._, .mov, .tmp1q, .memsiad(.src0q, .@"8", .tmp0, .add_size, -16), ._, ._ },
|
||||
.{ ._, ._, .sbb, .tmp1q, .memsiad(.src1q, .@"8", .tmp0, .add_size, -16), ._, ._ },
|
||||
.{ ._, ._, .mov, .memsiad(.dst0q, .@"8", .tmp0, .add_src0_size, -16), .tmp1q, ._, ._ },
|
||||
.{ ._, ._c, .in, .tmp0p, ._, ._, ._ },
|
||||
.{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
|
||||
.{ ._, ._, .mov, .tmp1q, .memad(.src0q, .add_size, -16), ._, ._ },
|
||||
.{ ._, ._, .mov, .tmp0d, .ua(.src0, .add_bit_size_rem_64), ._, ._ },
|
||||
.{ ._, ._, .sbb, .tmp1q, .memad(.src1q, .add_size, -16), ._, ._ },
|
||||
.{ ._, ._c, .set, .mema(.dst0b, .add_src0_size), ._, ._, ._ },
|
||||
.{ ._, ._, .bzhi, .tmp0q, .tmp1q, .tmp0q, ._ },
|
||||
.{ ._, ._, .mov, .memad(.dst0q, .add_src0_size, -8), .ui(0), ._, ._ },
|
||||
.{ ._, ._, .mov, .memad(.dst0q, .add_src0_size, -16), .tmp0q, ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .@"64bit", null, null, null },
|
||||
.src_constraints = .{
|
||||
.{ .remainder_unsigned_int = .{ .of = .xword, .is = .qword } },
|
||||
.{ .remainder_unsigned_int = .{ .of = .xword, .is = .qword } },
|
||||
.any,
|
||||
},
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mem, .to_mem, .none } },
|
||||
},
|
||||
.extra_temps = .{
|
||||
.{ .type = .isize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
},
|
||||
.dst_temps = .{ .mem, .none },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .mov, .tmp0p, .sia(2, .src0, .sub_size_div_8), ._, ._ },
|
||||
.{ ._, ._c, .cl, ._, ._, ._, ._ },
|
||||
.{ .@"0:", ._, .mov, .tmp1q, .memsiad(.src0q, .@"8", .tmp0, .add_size, -16), ._, ._ },
|
||||
.{ ._, ._, .sbb, .tmp1q, .memsiad(.src1q, .@"8", .tmp0, .add_size, -16), ._, ._ },
|
||||
.{ ._, ._, .mov, .memsiad(.dst0q, .@"8", .tmp0, .add_src0_size, -16), .tmp1q, ._, ._ },
|
||||
.{ ._, ._c, .in, .tmp0p, ._, ._, ._ },
|
||||
.{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
|
||||
.{ ._, ._, .mov, .tmp1q, .memad(.src0q, .add_size, -16), ._, ._ },
|
||||
.{ ._, ._, .mov, .tmp0q, .ua(.src0, .add_umax), ._, ._ },
|
||||
.{ ._, ._, .sbb, .tmp1q, .memad(.src1q, .add_size, -16), ._, ._ },
|
||||
.{ ._, ._c, .set, .mema(.dst0b, .add_src0_size), ._, ._, ._ },
|
||||
.{ ._, ._, .@"and", .tmp0q, .tmp1q, ._, ._ },
|
||||
.{ ._, ._, .mov, .memad(.dst0q, .add_src0_size, -8), .ui(0), ._, ._ },
|
||||
.{ ._, ._, .mov, .memad(.dst0q, .add_src0_size, -16), .tmp0q, ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .@"64bit", null, null, null },
|
||||
.src_constraints = .{
|
||||
.{ .remainder_signed_int = .{ .of = .xword, .is = .xword } },
|
||||
.{ .remainder_signed_int = .{ .of = .xword, .is = .xword } },
|
||||
.any,
|
||||
},
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mem, .to_mem, .none } },
|
||||
},
|
||||
.extra_temps = .{
|
||||
.{ .type = .isize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
},
|
||||
.dst_temps = .{ .mem, .{ .cc = .o } },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .mov, .tmp0p, .sia(1, .src0, .sub_size_div_8), ._, ._ },
|
||||
.{ ._, ._c, .cl, ._, ._, ._, ._ },
|
||||
.{ .@"0:", ._, .mov, .tmp1q, .memsiad(.src0q, .@"8", .tmp0, .add_size, -8), ._, ._ },
|
||||
.{ ._, ._, .sbb, .tmp1q, .memsiad(.src1q, .@"8", .tmp0, .add_size, -8), ._, ._ },
|
||||
.{ ._, ._, .mov, .memsiad(.dst0q, .@"8", .tmp0, .add_src0_size, -8), .tmp1q, ._, ._ },
|
||||
.{ ._, ._c, .in, .tmp0p, ._, ._, ._ },
|
||||
.{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
|
||||
.{ ._, ._, .mov, .tmp1q, .memad(.src0q, .add_size, -8), ._, ._ },
|
||||
.{ ._, ._, .sbb, .tmp1q, .memad(.src1q, .add_size, -8), ._, ._ },
|
||||
.{ ._, ._l, .ro, .tmp1q, .uia(64, .src0, .sub_bit_size_rem_64), ._, ._ },
|
||||
.{ ._, ._, .mov, .tmp0q, .tmp1q, ._, ._ },
|
||||
.{ ._, ._r, .sa, .tmp1q, .uia(64, .src0, .sub_bit_size_rem_64), ._, ._ },
|
||||
.{ ._, ._r, .ro, .tmp0q, .ui(1), ._, ._ },
|
||||
.{ ._, ._, .mov, .memad(.dst0q, .add_src0_size, -8), .tmp1q, ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .@"64bit", .bmi2, null, null },
|
||||
.src_constraints = .{
|
||||
.{ .remainder_unsigned_int = .{ .of = .xword, .is = .xword } },
|
||||
.{ .remainder_unsigned_int = .{ .of = .xword, .is = .xword } },
|
||||
.any,
|
||||
},
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mem, .to_mem, .none } },
|
||||
},
|
||||
.extra_temps = .{
|
||||
.{ .type = .isize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
},
|
||||
.dst_temps = .{ .mem, .none },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .mov, .tmp0p, .sia(1, .src0, .sub_size_div_8), ._, ._ },
|
||||
.{ ._, ._c, .cl, ._, ._, ._, ._ },
|
||||
.{ .@"0:", ._, .mov, .tmp1q, .memsiad(.src0q, .@"8", .tmp0, .add_size, -8), ._, ._ },
|
||||
.{ ._, ._, .sbb, .tmp1q, .memsiad(.src1q, .@"8", .tmp0, .add_size, -8), ._, ._ },
|
||||
.{ ._, ._, .mov, .memsiad(.dst0q, .@"8", .tmp0, .add_src0_size, -8), .tmp1q, ._, ._ },
|
||||
.{ ._, ._c, .in, .tmp0p, ._, ._, ._ },
|
||||
.{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
|
||||
.{ ._, ._, .mov, .tmp1q, .memad(.src0q, .add_size, -8), ._, ._ },
|
||||
.{ ._, ._, .mov, .tmp0d, .ua(.src0, .add_bit_size_rem_64), ._, ._ },
|
||||
.{ ._, ._, .sbb, .tmp1q, .memad(.src1q, .add_size, -8), ._, ._ },
|
||||
.{ ._, ._c, .set, .mema(.dst0b, .add_src0_size), ._, ._, ._ },
|
||||
.{ ._, ._, .bzhi, .tmp0q, .tmp1q, .tmp0q, ._ },
|
||||
.{ ._, ._, .mov, .memad(.dst0q, .add_src0_size, -8), .tmp0q, ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .@"64bit", null, null, null },
|
||||
.src_constraints = .{
|
||||
.{ .remainder_unsigned_int = .{ .of = .xword, .is = .xword } },
|
||||
.{ .remainder_unsigned_int = .{ .of = .xword, .is = .xword } },
|
||||
.any,
|
||||
},
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mem, .to_mem, .none } },
|
||||
},
|
||||
.extra_temps = .{
|
||||
.{ .type = .isize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
},
|
||||
.dst_temps = .{ .mem, .none },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .mov, .tmp0p, .sia(1, .src0, .sub_size_div_8), ._, ._ },
|
||||
.{ ._, ._c, .cl, ._, ._, ._, ._ },
|
||||
.{ .@"0:", ._, .mov, .tmp1q, .memsiad(.src0q, .@"8", .tmp0, .add_size, -8), ._, ._ },
|
||||
.{ ._, ._, .sbb, .tmp1q, .memsiad(.src1q, .@"8", .tmp0, .add_size, -8), ._, ._ },
|
||||
.{ ._, ._, .mov, .memsiad(.dst0q, .@"8", .tmp0, .add_src0_size, -8), .tmp1q, ._, ._ },
|
||||
.{ ._, ._c, .in, .tmp0p, ._, ._, ._ },
|
||||
.{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
|
||||
.{ ._, ._, .mov, .tmp1q, .memad(.src0q, .add_size, -8), ._, ._ },
|
||||
.{ ._, ._, .mov, .tmp0q, .ua(.src0, .add_umax), ._, ._ },
|
||||
.{ ._, ._, .sbb, .tmp1q, .memad(.src1q, .add_size, -8), ._, ._ },
|
||||
.{ ._, ._c, .set, .mema(.dst0b, .add_src0_size), ._, ._, ._ },
|
||||
.{ ._, ._, .@"and", .tmp0q, .tmp1q, ._, ._ },
|
||||
.{ ._, ._, .mov, .memad(.dst0q, .add_src0_size, -8), .tmp0q, ._, ._ },
|
||||
} },
|
||||
} }) catch |err| switch (err) {
|
||||
error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{
|
||||
@tagName(air_tag),
|
||||
ty_pl.ty.toType().fmt(pt),
|
||||
ops[0].tracking(cg),
|
||||
ops[1].tracking(cg),
|
||||
}),
|
||||
else => |e| return e,
|
||||
};
|
||||
try res[0].withOverflow(&res[1], cg);
|
||||
try res[0].finish(inst, &.{ bin_op.lhs, bin_op.rhs }, &ops, cg);
|
||||
},
|
||||
.alloc => if (use_old) try cg.airAlloc(inst) else {
|
||||
const ty = air_datas[@intFromEnum(inst)].ty;
|
||||
const slot = try cg.tempInit(ty, .{ .lea_frame = .{
|
||||
@ -111270,6 +112175,7 @@ const Select = struct {
|
||||
mut_mem,
|
||||
to_mut_mem,
|
||||
gpr,
|
||||
immut_gpr,
|
||||
to_gpr,
|
||||
mut_gpr,
|
||||
to_mut_gpr,
|
||||
@ -111329,6 +112235,11 @@ const Select = struct {
|
||||
.register_offset => |reg_off| reg_off.reg.class() == .general_purpose and reg_off.off == 0,
|
||||
else => false,
|
||||
},
|
||||
.immut_gpr => !temp.isMut(cg) and temp.typeOf(cg).abiSize(cg.pt.zcu) <= 8 and switch (temp.tracking(cg).short) {
|
||||
.register => |reg| reg.class() == .general_purpose,
|
||||
.register_offset => |reg_off| reg_off.reg.class() == .general_purpose and reg_off.off == 0,
|
||||
else => false,
|
||||
},
|
||||
.mut_gpr => temp.isMut(cg) and temp.typeOf(cg).abiSize(cg.pt.zcu) <= 8 and switch (temp.tracking(cg).short) {
|
||||
.register => |reg| reg.class() == .general_purpose,
|
||||
.register_offset => |reg_off| reg_off.reg.class() == .general_purpose and reg_off.off == 0,
|
||||
@ -111415,7 +112326,7 @@ const Select = struct {
|
||||
.to_param_gpr_pair => |param_spec| try temp.toRegPair(abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.index..][0..2].*, cg),
|
||||
.to_ret_gpr => |ret_spec| try temp.toReg(abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.index], cg),
|
||||
.to_ret_gpr_pair => |ret_spec| try temp.toRegPair(abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.index..][0..2].*, cg),
|
||||
.gpr, .to_gpr => try temp.toRegClass(false, .general_purpose, cg),
|
||||
.gpr, .immut_gpr, .to_gpr => try temp.toRegClass(false, .general_purpose, cg),
|
||||
.mut_gpr, .to_mut_gpr => try temp.toRegClass(true, .general_purpose, cg),
|
||||
.x87, .to_x87 => try temp.toRegClass(false, .x87, cg),
|
||||
.mut_x87, .to_mut_x87 => try temp.toRegClass(true, .x87, cg),
|
||||
|
||||
@ -5284,15 +5284,14 @@ test addWrap {
|
||||
|
||||
inline fn subUnsafe(comptime Type: type, lhs: Type, rhs: Type) AddOneBit(Type) {
|
||||
@setRuntimeSafety(false);
|
||||
switch (@typeInfo(Scalar(Type))) {
|
||||
return switch (@typeInfo(Scalar(Type))) {
|
||||
else => @compileError(@typeName(Type)),
|
||||
.int => |int| switch (int.signedness) {
|
||||
.signed => {},
|
||||
.unsigned => return @as(AddOneBit(Type), @max(lhs, rhs)) - @min(lhs, rhs),
|
||||
.signed => @as(AddOneBit(Type), lhs) - rhs,
|
||||
.unsigned => @as(AddOneBit(Type), @max(lhs, rhs)) - @min(lhs, rhs),
|
||||
},
|
||||
.float => {},
|
||||
}
|
||||
return @as(AddOneBit(Type), lhs) - rhs;
|
||||
.float => lhs - rhs,
|
||||
};
|
||||
}
|
||||
test subUnsafe {
|
||||
const test_sub_unsafe = binary(subUnsafe, .{});
|
||||
@ -5302,6 +5301,24 @@ test subUnsafe {
|
||||
try test_sub_unsafe.testFloatVectors();
|
||||
}
|
||||
|
||||
inline fn subSafe(comptime Type: type, lhs: Type, rhs: Type) AddOneBit(Type) {
|
||||
@setRuntimeSafety(true);
|
||||
return switch (@typeInfo(Scalar(Type))) {
|
||||
else => @compileError(@typeName(Type)),
|
||||
.int => |int| switch (int.signedness) {
|
||||
.signed => @as(AddOneBit(Type), lhs) - rhs,
|
||||
.unsigned => @as(AddOneBit(Type), @max(lhs, rhs)) - @min(lhs, rhs),
|
||||
},
|
||||
.float => lhs - rhs,
|
||||
};
|
||||
}
|
||||
test subSafe {
|
||||
const test_sub_safe = binary(subSafe, .{});
|
||||
try test_sub_safe.testInts();
|
||||
try test_sub_safe.testFloats();
|
||||
try test_sub_safe.testFloatVectors();
|
||||
}
|
||||
|
||||
inline fn subWrap(comptime Type: type, lhs: Type, rhs: Type) Type {
|
||||
return lhs -% rhs;
|
||||
}
|
||||
@ -5435,6 +5452,14 @@ test addWithOverflow {
|
||||
try test_add_with_overflow.testInts();
|
||||
}
|
||||
|
||||
inline fn subWithOverflow(comptime Type: type, lhs: Type, rhs: Type) struct { Type, u1 } {
|
||||
return @subWithOverflow(lhs, rhs);
|
||||
}
|
||||
test subWithOverflow {
|
||||
const test_sub_with_overflow = binary(subWithOverflow, .{});
|
||||
try test_sub_with_overflow.testInts();
|
||||
}
|
||||
|
||||
inline fn equal(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs == rhs) {
|
||||
return lhs == rhs;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user