diff --git a/cranelift/codegen/src/isa/x64/inst.isle b/cranelift/codegen/src/isa/x64/inst.isle index c523f35dcf..c2ff730561 100644 --- a/cranelift/codegen/src/isa/x64/inst.isle +++ b/cranelift/codegen/src/isa/x64/inst.isle @@ -281,7 +281,8 @@ (XmmMinMaxSeq (size OperandSize) (is_min bool) (lhs Xmm) - (rhs_dst WritableXmm)) + (rhs Xmm) + (dst WritableXmm)) ;; Float comparisons/tests: cmp (b w l q) (reg addr imm) reg. (XmmCmpRmR (op SseOpcode) @@ -2430,6 +2431,71 @@ (_ Unit (emit (MInst.UnaryRmR size (UnaryRmROpcode.Popcnt) src dst)))) dst)) +;; Helper for creating `xmm_min_max_seq` psuedo-instructions. +(decl xmm_min_max_seq (Type bool Xmm Xmm) Xmm) +(rule (xmm_min_max_seq ty is_min lhs rhs) + (let ((dst WritableXmm (temp_writable_xmm)) + (size OperandSize (operand_size_of_type_32_64 ty)) + (_ Unit (emit (MInst.XmmMinMaxSeq size is_min lhs rhs dst)))) + dst)) + +;; Helper for creating `minss` instructions. +(decl minss (Xmm Xmm) Xmm) +(rule (minss x y) + (let ((dst WritableXmm (temp_writable_xmm)) + (_ Unit (emit (MInst.XmmRmR (SseOpcode.Minss) x y dst)))) + dst)) + +;; Helper for creating `minsd` instructions. +(decl minsd (Xmm Xmm) Xmm) +(rule (minsd x y) + (let ((dst WritableXmm (temp_writable_xmm)) + (_ Unit (emit (MInst.XmmRmR (SseOpcode.Minsd) x y dst)))) + dst)) + + +;; Helper for creating `minps` instructions. +(decl minps (Xmm Xmm) Xmm) +(rule (minps x y) + (let ((dst WritableXmm (temp_writable_xmm)) + (_ Unit (emit (MInst.XmmRmR (SseOpcode.Minps) x y dst)))) + dst)) + +;; Helper for creating `minpd` instructions. +(decl minpd (Xmm Xmm) Xmm) +(rule (minpd x y) + (let ((dst WritableXmm (temp_writable_xmm)) + (_ Unit (emit (MInst.XmmRmR (SseOpcode.Minpd) x y dst)))) + dst)) + +;; Helper for creating `maxss` instructions. +(decl maxss (Xmm Xmm) Xmm) +(rule (maxss x y) + (let ((dst WritableXmm (temp_writable_xmm)) + (_ Unit (emit (MInst.XmmRmR (SseOpcode.Maxss) x y dst)))) + dst)) + +;; Helper for creating `maxsd` instructions. +(decl maxsd (Xmm Xmm) Xmm) +(rule (maxsd x y) + (let ((dst WritableXmm (temp_writable_xmm)) + (_ Unit (emit (MInst.XmmRmR (SseOpcode.Maxsd) x y dst)))) + dst)) + +;; Helper for creating `maxps` instructions. +(decl maxps (Xmm Xmm) Xmm) +(rule (maxps x y) + (let ((dst WritableXmm (temp_writable_xmm)) + (_ Unit (emit (MInst.XmmRmR (SseOpcode.Maxps) x y dst)))) + dst)) + +;; Helper for creating `maxpd` instructions. +(decl maxpd (Xmm Xmm) Xmm) +(rule (maxpd x y) + (let ((dst WritableXmm (temp_writable_xmm)) + (_ Unit (emit (MInst.XmmRmR (SseOpcode.Maxpd) x y dst)))) + dst)) + ;;;; Automatic conversions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (convert Gpr InstOutput output_gpr) diff --git a/cranelift/codegen/src/isa/x64/inst/emit.rs b/cranelift/codegen/src/isa/x64/inst/emit.rs index 7177109d36..2ff056625c 100644 --- a/cranelift/codegen/src/isa/x64/inst/emit.rs +++ b/cranelift/codegen/src/isa/x64/inst/emit.rs @@ -1696,8 +1696,11 @@ pub(crate) fn emit( size, is_min, lhs, - rhs_dst, + rhs, + dst, } => { + debug_assert_eq!(*rhs, dst.to_reg()); + // Generates the following sequence: // cmpss/cmpsd %lhs, %rhs_dst // jnz do_min_max @@ -1747,8 +1750,7 @@ pub(crate) fn emit( _ => unreachable!(), }; - let inst = - Inst::xmm_cmp_rm_r(cmp_op, RegMem::reg(lhs.to_reg()), rhs_dst.to_reg().to_reg()); + let inst = Inst::xmm_cmp_rm_r(cmp_op, RegMem::reg(lhs.to_reg()), dst.to_reg().to_reg()); inst.emit(sink, info, state); one_way_jmp(sink, CC::NZ, do_min_max); @@ -1758,7 +1760,7 @@ pub(crate) fn emit( // and negative zero. These instructions merge the sign bits in that // case, and are no-ops otherwise. let op = if *is_min { or_op } else { and_op }; - let inst = Inst::xmm_rm_r(op, RegMem::reg(lhs.to_reg()), rhs_dst.to_writable_reg()); + let inst = Inst::xmm_rm_r(op, RegMem::reg(lhs.to_reg()), dst.to_writable_reg()); inst.emit(sink, info, state); let inst = Inst::jmp_known(done); @@ -1768,17 +1770,13 @@ pub(crate) fn emit( // read-only operand: perform an addition between the two operands, which has the // desired NaN propagation effects. sink.bind_label(propagate_nan); - let inst = Inst::xmm_rm_r(add_op, RegMem::reg(lhs.to_reg()), rhs_dst.to_writable_reg()); + let inst = Inst::xmm_rm_r(add_op, RegMem::reg(lhs.to_reg()), dst.to_writable_reg()); inst.emit(sink, info, state); one_way_jmp(sink, CC::P, done); sink.bind_label(do_min_max); - let inst = Inst::xmm_rm_r( - min_max_op, - RegMem::reg(lhs.to_reg()), - rhs_dst.to_writable_reg(), - ); + let inst = Inst::xmm_rm_r(min_max_op, RegMem::reg(lhs.to_reg()), dst.to_writable_reg()); inst.emit(sink, info, state); sink.bind_label(done); diff --git a/cranelift/codegen/src/isa/x64/inst/mod.rs b/cranelift/codegen/src/isa/x64/inst/mod.rs index 3e4ada4553..9bf0fe2f04 100644 --- a/cranelift/codegen/src/isa/x64/inst/mod.rs +++ b/cranelift/codegen/src/isa/x64/inst/mod.rs @@ -450,20 +450,24 @@ impl Inst { } } + #[allow(dead_code)] pub(crate) fn xmm_min_max_seq( size: OperandSize, is_min: bool, lhs: Reg, - rhs_dst: Writable, + rhs: Reg, + dst: Writable, ) -> Inst { debug_assert!(size.is_one_of(&[OperandSize::Size32, OperandSize::Size64])); debug_assert_eq!(lhs.get_class(), RegClass::V128); - debug_assert_eq!(rhs_dst.to_reg().get_class(), RegClass::V128); + debug_assert_eq!(rhs.get_class(), RegClass::V128); + debug_assert_eq!(dst.to_reg().get_class(), RegClass::V128); Inst::XmmMinMaxSeq { size, is_min, lhs: Xmm::new(lhs).unwrap(), - rhs_dst: WritableXmm::from_writable_reg(rhs_dst).unwrap(), + rhs: Xmm::new(rhs).unwrap(), + dst: WritableXmm::from_writable_reg(dst).unwrap(), } } @@ -900,6 +904,18 @@ impl Inst { } insts.push(self); } + Inst::XmmMinMaxSeq { rhs, dst, .. } => { + if *rhs != dst.to_reg() { + debug_assert!(rhs.is_virtual()); + insts.push(Self::gen_move( + dst.to_writable_reg(), + rhs.to_reg(), + types::I8X16, + )); + *rhs = dst.to_reg(); + } + insts.push(self); + } Inst::Cmove { size, alternative, @@ -1330,11 +1346,12 @@ impl PrettyPrint for Inst { Inst::XmmMinMaxSeq { lhs, - rhs_dst, + rhs, + dst, is_min, size, } => format!( - "{} {}, {}", + "{} {}, {}, {}", ljustify2( if *is_min { "xmm min seq ".to_string() @@ -1344,7 +1361,8 @@ impl PrettyPrint for Inst { format!("f{}", size.to_bits()) ), show_ireg_sized(lhs.to_reg(), mb_rru, 8), - show_ireg_sized(rhs_dst.to_reg().to_reg(), mb_rru, 8), + show_ireg_sized(rhs.to_reg(), mb_rru, 8), + show_ireg_sized(dst.to_reg().to_reg(), mb_rru, 8), ), Inst::XmmRmRImm { @@ -1924,9 +1942,10 @@ fn x64_get_regs(inst: &Inst, collector: &mut RegUsageCollector) { } Inst::XmmUninitializedValue { dst } => collector.add_def(dst.to_writable_reg()), Inst::XmmLoadConst { dst, .. } => collector.add_def(*dst), - Inst::XmmMinMaxSeq { lhs, rhs_dst, .. } => { + Inst::XmmMinMaxSeq { lhs, rhs, dst, .. } => { + debug_assert_eq!(*rhs, dst.to_reg()); collector.add_use(lhs.to_reg()); - collector.add_mod(rhs_dst.to_writable_reg()); + collector.add_mod(dst.to_writable_reg()); } Inst::XmmRmiReg { src1, src2, dst, .. @@ -2352,11 +2371,14 @@ pub(crate) fn x64_map_regs(inst: &mut Inst, mapper: &RM) { } Inst::XmmMinMaxSeq { ref mut lhs, - ref mut rhs_dst, + ref mut rhs, + ref mut dst, .. } => { + debug_assert_eq!(*rhs, dst.to_reg()); lhs.map_use(mapper); - rhs_dst.map_mod(mapper); + dst.map_mod(mapper); + *rhs = dst.to_reg(); } Inst::XmmMovRM { ref mut src, diff --git a/cranelift/codegen/src/isa/x64/lower.isle b/cranelift/codegen/src/isa/x64/lower.isle index 6c60b52597..d082fda8ef 100644 --- a/cranelift/codegen/src/isa/x64/lower.isle +++ b/cranelift/codegen/src/isa/x64/lower.isle @@ -2059,3 +2059,194 @@ (divps x y)) (rule (lower (has_type $F64X2 (fdiv x y))) (divpd x y)) + +;; Rules for `fmin` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(rule (lower (has_type $F32 (fmin x y))) + (xmm_min_max_seq $F32 $true x y)) +(rule (lower (has_type $F64 (fmin x y))) + (xmm_min_max_seq $F64 $true x y)) + +;; Vector-typed version. We don't use single pseudoinstructions as +;; above, because we don't need to generate a mini-CFG. Instead, we +;; perform a branchless series of operations. +;; +;; We cannot simply use native min instructions (minps, minpd) because +;; NaN handling is different per CLIF semantics than on +;; x86. Specifically, if an argument is NaN, or the arguments are both +;; zero but of opposite signs, then the x86 instruction always +;; produces the second argument. However, per CLIF semantics, we +;; require that fmin(NaN, _) = fmin(_, NaN) = NaN, and fmin(+0, -0) = +;; fmin(-0, +0) = -0. + +(rule (lower (has_type $F32X4 (fmin x y))) + ;; Compute min(x, y) and min(y, x) with native + ;; instructions. These will differ in one of the edge cases + ;; above that we have to handle properly. (Conversely, if they + ;; don't differ, then the native instruction's answer is the + ;; right one per CLIF semantics.) + (let ((min1 Xmm (minps x y)) + (min2 Xmm (minps y x)) + ;; Compute the OR of the two. Note that NaNs have an + ;; exponent field of all-ones (0xFF for F32), so if either + ;; result is a NaN, this OR will be. And if either is a + ;; zero (which has an exponent of 0 and mantissa of 0), + ;; this captures a sign-bit of 1 (negative) if either + ;; input is negative. + ;; + ;; In the case where we don't have a +/-0 mismatch or + ;; NaNs, then `min1` and `min2` are equal and `min_or` is + ;; the correct minimum. + (min_or Xmm (orps min1 min2)) + ;; "compare unordered" produces a true mask (all ones) in + ;; a given lane if the min is a NaN. We use this to + ;; generate a mask to ensure quiet NaNs. + (is_nan_mask Xmm (cmpps min_or min2 (FcmpImm.Unordered))) + ;; OR in the NaN mask. + (min_or_2 Xmm (orps min_or is_nan_mask)) + ;; Shift the NaN mask down so that it covers just the + ;; fraction below the NaN signalling bit; we'll use this + ;; to mask off non-canonical NaN payloads. + ;; + ;; All-ones for NaN, shifted down to leave 10 top bits (1 + ;; sign, 8 exponent, 1 QNaN bit that must remain set) + ;; cleared. + (nan_fraction_mask Xmm (psrld is_nan_mask (RegMemImm.Imm 10))) + ;; Do a NAND, so that we retain every bit not set in + ;; `nan_fraction_mask`. This mask will be all zeroes (so + ;; we retain every bit) in non-NaN cases, and will have + ;; ones (so we clear those bits) in NaN-payload bits + ;; otherwise. + (final Xmm (andnps nan_fraction_mask min_or_2))) + final)) + +;; Likewise for F64 lanes, except that the right-shift is by 13 bits +;; (1 sign, 11 exponent, 1 QNaN bit). +(rule (lower (has_type $F64X2 (fmin x y))) + (let ((min1 Xmm (minpd x y)) + (min2 Xmm (minpd y x)) + (min_or Xmm (orpd min1 min2)) + (is_nan_mask Xmm (cmppd min1 min2 (FcmpImm.Unordered))) + (min_or_2 Xmm (orpd min_or is_nan_mask)) + (nan_fraction_mask Xmm (psrlq is_nan_mask (RegMemImm.Imm 13))) + (final Xmm (andnpd nan_fraction_mask min_or_2))) + final)) + +;; Rules for `fmax` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(rule (lower (has_type $F32 (fmax x y))) + (xmm_min_max_seq $F32 $false x y)) +(rule (lower (has_type $F64 (fmax x y))) + (xmm_min_max_seq $F64 $false x y)) + +;; The vector version of fmax here is a dual to the fmin sequence +;; above, almost, with a few differences. + +(rule (lower (has_type $F32X4 (fmax x y))) + ;; Compute max(x, y) and max(y, x) with native + ;; instructions. These will differ in one of the edge cases + ;; above that we have to handle properly. (Conversely, if they + ;; don't differ, then the native instruction's answer is the + ;; right one per CLIF semantics.) + (let ((max1 Xmm (maxps x y)) + (max2 Xmm (maxps y x)) + ;; Compute the XOR of the two maxima. In the case + ;; where we don't have a +/-0 mismatch or NaNs, then + ;; `min1` and `min2` are equal and this XOR is zero. + (max_xor Xmm (xorps max1 max2)) + ;; OR the XOR into one of the original maxima. If they are + ;; equal, this does nothing. If max2 was NaN, its exponent + ;; bits were all-ones, so the xor's exponent bits were the + ;; complement of max1, and the OR of max1 and max_xor has + ;; an all-ones exponent (is a NaN). If max1 was NaN, then + ;; its exponent bits were already all-ones, so the OR will + ;; be a NaN as well. + (max_blended_nan Xmm (orps max1 max_xor)) + ;; Subtract the XOR. This ensures that if we had +0 and + ;; -0, we end up with +0. + (max_blended_nan_positive Xmm (subps max_blended_nan max_xor)) + ;; "compare unordered" produces a true mask (all ones) in + ;; a given lane if the min is a NaN. We use this to + ;; generate a mask to ensure quiet NaNs. + (is_nan_mask Xmm (cmpps max_blended_nan max_blended_nan (FcmpImm.Unordered))) + ;; Shift the NaN mask down so that it covers just the + ;; fraction below the NaN signalling bit; we'll use this + ;; to mask off non-canonical NaN payloads. + ;; + ;; All-ones for NaN, shifted down to leave 10 top bits (1 + ;; sign, 8 exponent, 1 QNaN bit that must remain set) + ;; cleared. + (nan_fraction_mask Xmm (psrld is_nan_mask (RegMemImm.Imm 10))) + ;; Do a NAND, so that we retain every bit not set in + ;; `nan_fraction_mask`. This mask will be all zeroes (so + ;; we retain every bit) in non-NaN cases, and will have + ;; ones (so we clear those bits) in NaN-payload bits + ;; otherwise. + (final Xmm (andnps nan_fraction_mask max_blended_nan_positive))) + final)) + +(rule (lower (has_type $F64X2 (fmax x y))) + ;; Compute max(x, y) and max(y, x) with native + ;; instructions. These will differ in one of the edge cases + ;; above that we have to handle properly. (Conversely, if they + ;; don't differ, then the native instruction's answer is the + ;; right one per CLIF semantics.) + (let ((max1 Xmm (maxpd x y)) + (max2 Xmm (maxpd y x)) + ;; Compute the XOR of the two maxima. In the case + ;; where we don't have a +/-0 mismatch or NaNs, then + ;; `min1` and `min2` are equal and this XOR is zero. + (max_xor Xmm (xorpd max1 max2)) + ;; OR the XOR into one of the original maxima. If they are + ;; equal, this does nothing. If max2 was NaN, its exponent + ;; bits were all-ones, so the xor's exponent bits were the + ;; complement of max1, and the OR of max1 and max_xor has + ;; an all-ones exponent (is a NaN). If max1 was NaN, then + ;; its exponent bits were already all-ones, so the OR will + ;; be a NaN as well. + (max_blended_nan Xmm (orpd max1 max_xor)) + ;; Subtract the XOR. This ensures that if we had +0 and + ;; -0, we end up with +0. + (max_blended_nan_positive Xmm (subpd max_blended_nan max_xor)) + ;; `cmpps` with predicate index `3` is `cmpunordps`, or + ;; "compare unordered": it produces a true mask (all ones) + ;; in a given lane if the min is a NaN. We use this to + ;; generate a mask to ensure quiet NaNs. + (is_nan_mask Xmm (cmppd max_blended_nan max_blended_nan (FcmpImm.Unordered))) + ;; Shift the NaN mask down so that it covers just the + ;; fraction below the NaN signalling bit; we'll use this + ;; to mask off non-canonical NaN payloads. + ;; + ;; All-ones for NaN, shifted down to leave 13 top bits (1 + ;; sign, 11 exponent, 1 QNaN bit that must remain set) + ;; cleared. + (nan_fraction_mask Xmm (psrlq is_nan_mask (RegMemImm.Imm 13))) + ;; Do a NAND, so that we retain every bit not set in + ;; `nan_fraction_mask`. This mask will be all zeroes (so + ;; we retain every bit) in non-NaN cases, and will have + ;; ones (so we clear those bits) in NaN-payload bits + ;; otherwise. + (final Xmm (andnpd nan_fraction_mask max_blended_nan_positive))) + final)) + +;; Rules for `fmin_pseudo` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(rule (lower (has_type $F32 (fmin_pseudo x y))) + (minss y x)) +(rule (lower (has_type $F64 (fmin_pseudo x y))) + (minsd y x)) +(rule (lower (has_type $F32X4 (fmin_pseudo x y))) + (minps y x)) +(rule (lower (has_type $F64X2 (fmin_pseudo x y))) + (minpd y x)) + +;; Rules for `fmax_pseudo` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(rule (lower (has_type $F32 (fmax_pseudo x y))) + (maxss y x)) +(rule (lower (has_type $F64 (fmax_pseudo x y))) + (maxsd y x)) +(rule (lower (has_type $F32X4 (fmax_pseudo x y))) + (maxps y x)) +(rule (lower (has_type $F64X2 (fmax_pseudo x y))) + (maxpd y x)) diff --git a/cranelift/codegen/src/isa/x64/lower.rs b/cranelift/codegen/src/isa/x64/lower.rs index 0095ed0dc1..39adcf85c4 100644 --- a/cranelift/codegen/src/isa/x64/lower.rs +++ b/cranelift/codegen/src/isa/x64/lower.rs @@ -910,7 +910,11 @@ fn lower_insn_to_regs>( | Opcode::Fadd | Opcode::Fsub | Opcode::Fmul - | Opcode::Fdiv => implemented_in_isle(ctx), + | Opcode::Fdiv + | Opcode::Fmin + | Opcode::Fmax + | Opcode::FminPseudo + | Opcode::FmaxPseudo => implemented_in_isle(ctx), Opcode::Icmp => { let condcode = ctx.data(insn).cond_code().unwrap(); @@ -1278,235 +1282,6 @@ fn lower_insn_to_regs>( }; } - Opcode::Fmin | Opcode::Fmax => { - let lhs = put_input_in_reg(ctx, inputs[0]); - let rhs = put_input_in_reg(ctx, inputs[1]); - let dst = get_output_reg(ctx, outputs[0]).only_reg().unwrap(); - let is_min = op == Opcode::Fmin; - let output_ty = ty.unwrap(); - ctx.emit(Inst::gen_move(dst, rhs, output_ty)); - if !output_ty.is_vector() { - let op_size = match output_ty { - types::F32 => OperandSize::Size32, - types::F64 => OperandSize::Size64, - _ => panic!("unexpected type {:?} for fmin/fmax", output_ty), - }; - ctx.emit(Inst::xmm_min_max_seq(op_size, is_min, lhs, dst)); - } else { - // X64's implementation of floating point min and floating point max does not - // propagate NaNs and +0's in a way that is friendly to the SIMD spec. For the - // scalar approach we use jumps to handle cases where NaN and +0 propagation is - // not consistent with what is needed. However for packed floating point min and - // floating point max we implement a different approach to avoid the sequence - // of jumps that would be required on a per lane basis. Because we do not need to - // lower labels and jumps but do need ctx for creating temporaries we implement - // the lowering here in lower.rs instead of emit.rs as is done in the case for scalars. - // The outline of approach is as follows: - // - // First we preform the Min/Max in both directions. This is because in the - // case of an operand's lane containing a NaN or in the case of the lanes of the - // two operands containing 0 but with mismatched signs, x64 will return the second - // operand regardless of its contents. So in order to make sure we capture NaNs and - // normalize NaNs and 0 values we capture the operation in both directions and merge the - // results. Then we normalize the results through operations that create a mask for the - // lanes containing NaNs, we use that mask to adjust NaNs to quite NaNs and normalize - // 0s. - // - // The following sequence is generated for min: - // - // movap{s,d} %lhs, %tmp - // minp{s,d} %dst, %tmp - // minp,{s,d} %lhs, %dst - // orp{s,d} %dst, %tmp - // cmpp{s,d} %tmp, %dst, $3 - // orps{s,d} %dst, %tmp - // psrl{s,d} {$10, $13}, %dst - // andnp{s,d} %tmp, %dst - // - // and for max the sequence is: - // - // movap{s,d} %lhs, %tmp - // minp{s,d} %dst, %tmp - // minp,{s,d} %lhs, %dst - // xorp{s,d} %tmp, %dst - // orp{s,d} %dst, %tmp - // subp{s,d} %dst, %tmp - // cmpp{s,d} %tmp, %dst, $3 - // psrl{s,d} {$10, $13}, %dst - // andnp{s,d} %tmp, %dst - - if is_min { - let (mov_op, min_op, or_op, cmp_op, shift_op, shift_by, andn_op) = - match output_ty { - types::F32X4 => ( - SseOpcode::Movaps, - SseOpcode::Minps, - SseOpcode::Orps, - SseOpcode::Cmpps, - SseOpcode::Psrld, - 10, - SseOpcode::Andnps, - ), - types::F64X2 => ( - SseOpcode::Movapd, - SseOpcode::Minpd, - SseOpcode::Orpd, - SseOpcode::Cmppd, - SseOpcode::Psrlq, - 13, - SseOpcode::Andnpd, - ), - _ => unimplemented!("unsupported op type {:?}", output_ty), - }; - - // Copy lhs into tmp - let tmp_xmm1 = ctx.alloc_tmp(output_ty).only_reg().unwrap(); - ctx.emit(Inst::xmm_mov(mov_op, RegMem::reg(lhs), tmp_xmm1)); - - // Perform min in reverse direction - ctx.emit(Inst::xmm_rm_r(min_op, RegMem::from(dst), tmp_xmm1)); - - // Perform min in original direction - ctx.emit(Inst::xmm_rm_r(min_op, RegMem::reg(lhs), dst)); - - // X64 handles propagation of -0's and Nans differently between left and right - // operands. After doing the min in both directions, this OR will - // guarrentee capture of -0's and Nan in our tmp register - ctx.emit(Inst::xmm_rm_r(or_op, RegMem::from(dst), tmp_xmm1)); - - // Compare unordered to create mask for lanes containing NaNs and then use - // that mask to saturate the NaN containing lanes in the tmp register with 1s. - // TODO: Would a check for NaN and then a jump be better here in the - // common case than continuing on to normalize NaNs that might not exist? - let cond = FcmpImm::from(FloatCC::Unordered); - ctx.emit(Inst::xmm_rm_r_imm( - cmp_op, - RegMem::reg(tmp_xmm1.to_reg()), - dst, - cond.encode(), - OperandSize::Size32, - )); - ctx.emit(Inst::xmm_rm_r(or_op, RegMem::reg(dst.to_reg()), tmp_xmm1)); - - // The dst register holds a mask for lanes containing NaNs. - // We take that mask and shift in preparation for creating a different mask - // to normalize NaNs (create a quite NaN) by zeroing out the appropriate - // number of least signficant bits. We shift right each lane by 10 bits - // (1 sign + 8 exp. + 1 MSB sig.) for F32X4 and by 13 bits (1 sign + - // 11 exp. + 1 MSB sig.) for F64X2. - ctx.emit(Inst::xmm_rmi_reg(shift_op, RegMemImm::imm(shift_by), dst)); - - // Finally we do a nand with the tmp register to produce the final results - // in the dst. - ctx.emit(Inst::xmm_rm_r(andn_op, RegMem::reg(tmp_xmm1.to_reg()), dst)); - } else { - let ( - mov_op, - max_op, - xor_op, - or_op, - sub_op, - cmp_op, - shift_op, - shift_by, - andn_op, - ) = match output_ty { - types::F32X4 => ( - SseOpcode::Movaps, - SseOpcode::Maxps, - SseOpcode::Xorps, - SseOpcode::Orps, - SseOpcode::Subps, - SseOpcode::Cmpps, - SseOpcode::Psrld, - 10, - SseOpcode::Andnps, - ), - types::F64X2 => ( - SseOpcode::Movapd, - SseOpcode::Maxpd, - SseOpcode::Xorpd, - SseOpcode::Orpd, - SseOpcode::Subpd, - SseOpcode::Cmppd, - SseOpcode::Psrlq, - 13, - SseOpcode::Andnpd, - ), - _ => unimplemented!("unsupported op type {:?}", output_ty), - }; - - // Copy lhs into tmp. - let tmp_xmm1 = ctx.alloc_tmp(types::F32).only_reg().unwrap(); - ctx.emit(Inst::xmm_mov(mov_op, RegMem::reg(lhs), tmp_xmm1)); - - // Perform max in reverse direction. - ctx.emit(Inst::xmm_rm_r(max_op, RegMem::reg(dst.to_reg()), tmp_xmm1)); - - // Perform max in original direction. - ctx.emit(Inst::xmm_rm_r(max_op, RegMem::reg(lhs), dst)); - - // Get the difference between the two results and store in tmp. - // Max uses a different approach than min to account for potential - // discrepancies with plus/minus 0. - ctx.emit(Inst::xmm_rm_r(xor_op, RegMem::reg(tmp_xmm1.to_reg()), dst)); - - // X64 handles propagation of -0's and Nans differently between left and right - // operands. After doing the max in both directions, this OR will - // guarentee capture of 0's and Nan in our tmp register. - ctx.emit(Inst::xmm_rm_r(or_op, RegMem::reg(dst.to_reg()), tmp_xmm1)); - - // Capture NaNs and sign discrepancies. - ctx.emit(Inst::xmm_rm_r(sub_op, RegMem::reg(dst.to_reg()), tmp_xmm1)); - - // Compare unordered to create mask for lanes containing NaNs and then use - // that mask to saturate the NaN containing lanes in the tmp register with 1s. - let cond = FcmpImm::from(FloatCC::Unordered); - ctx.emit(Inst::xmm_rm_r_imm( - cmp_op, - RegMem::reg(tmp_xmm1.to_reg()), - dst, - cond.encode(), - OperandSize::Size32, - )); - - // The dst register holds a mask for lanes containing NaNs. - // We take that mask and shift in preparation for creating a different mask - // to normalize NaNs (create a quite NaN) by zeroing out the appropriate - // number of least signficant bits. We shift right each lane by 10 bits - // (1 sign + 8 exp. + 1 MSB sig.) for F32X4 and by 13 bits (1 sign + - // 11 exp. + 1 MSB sig.) for F64X2. - ctx.emit(Inst::xmm_rmi_reg(shift_op, RegMemImm::imm(shift_by), dst)); - - // Finally we do a nand with the tmp register to produce the final results - // in the dst. - ctx.emit(Inst::xmm_rm_r(andn_op, RegMem::reg(tmp_xmm1.to_reg()), dst)); - } - } - } - - Opcode::FminPseudo | Opcode::FmaxPseudo => { - // We can't guarantee the RHS (if a load) is 128-bit aligned, so we - // must avoid merging a load here. - let lhs = RegMem::reg(put_input_in_reg(ctx, inputs[0])); - let rhs = put_input_in_reg(ctx, inputs[1]); - let dst = get_output_reg(ctx, outputs[0]).only_reg().unwrap(); - let ty = ty.unwrap(); - ctx.emit(Inst::gen_move(dst, rhs, ty)); - let sse_opcode = match (ty, op) { - (types::F32, Opcode::FminPseudo) => SseOpcode::Minss, - (types::F32, Opcode::FmaxPseudo) => SseOpcode::Maxss, - (types::F64, Opcode::FminPseudo) => SseOpcode::Minsd, - (types::F64, Opcode::FmaxPseudo) => SseOpcode::Maxsd, - (types::F32X4, Opcode::FminPseudo) => SseOpcode::Minps, - (types::F32X4, Opcode::FmaxPseudo) => SseOpcode::Maxps, - (types::F64X2, Opcode::FminPseudo) => SseOpcode::Minpd, - (types::F64X2, Opcode::FmaxPseudo) => SseOpcode::Maxpd, - _ => unimplemented!("unsupported type {} for {}", ty, op), - }; - ctx.emit(Inst::xmm_rm_r(sse_opcode, lhs, dst)); - } - Opcode::Sqrt => { // We can't guarantee the RHS (if a load) is 128-bit aligned, so we // must avoid merging a load here. diff --git a/cranelift/codegen/src/isa/x64/lower/isle/generated_code.manifest b/cranelift/codegen/src/isa/x64/lower/isle/generated_code.manifest index 42e4b978a1..b1f03e50d8 100644 --- a/cranelift/codegen/src/isa/x64/lower/isle/generated_code.manifest +++ b/cranelift/codegen/src/isa/x64/lower/isle/generated_code.manifest @@ -1,4 +1,4 @@ src/clif.isle 9ea75a6f790b5c03 src/prelude.isle b2bc986bcbbbb77 -src/isa/x64/inst.isle 9a8a3babd8257100 -src/isa/x64/lower.isle f0f4af691241209e +src/isa/x64/inst.isle 40f495d3ca5ae547 +src/isa/x64/lower.isle faa2a07bba48a813 diff --git a/cranelift/codegen/src/isa/x64/lower/isle/generated_code.rs b/cranelift/codegen/src/isa/x64/lower/isle/generated_code.rs index 8132cea9ea..b409fad5c4 100644 --- a/cranelift/codegen/src/isa/x64/lower/isle/generated_code.rs +++ b/cranelift/codegen/src/isa/x64/lower/isle/generated_code.rs @@ -396,7 +396,8 @@ pub enum MInst { size: OperandSize, is_min: bool, lhs: Xmm, - rhs_dst: WritableXmm, + rhs: Xmm, + dst: WritableXmm, }, XmmCmpRmR { op: SseOpcode, @@ -500,7 +501,7 @@ pub enum MInst { }, } -/// Internal type ExtendKind: defined at src/isa/x64/inst.isle line 1119. +/// Internal type ExtendKind: defined at src/isa/x64/inst.isle line 1120. #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub enum ExtendKind { Sign, @@ -754,22 +755,22 @@ pub fn constructor_operand_size_bits(ctx: &mut C, arg0: &OperandSize let pattern0_0 = arg0; match pattern0_0 { &OperandSize::Size8 => { - // Rule at src/isa/x64/inst.isle line 509. + // Rule at src/isa/x64/inst.isle line 510. let expr0_0: u16 = 8; return Some(expr0_0); } &OperandSize::Size16 => { - // Rule at src/isa/x64/inst.isle line 510. + // Rule at src/isa/x64/inst.isle line 511. let expr0_0: u16 = 16; return Some(expr0_0); } &OperandSize::Size32 => { - // Rule at src/isa/x64/inst.isle line 511. + // Rule at src/isa/x64/inst.isle line 512. let expr0_0: u16 = 32; return Some(expr0_0); } &OperandSize::Size64 => { - // Rule at src/isa/x64/inst.isle line 512. + // Rule at src/isa/x64/inst.isle line 513. let expr0_0: u16 = 64; return Some(expr0_0); } @@ -781,7 +782,7 @@ pub fn constructor_operand_size_bits(ctx: &mut C, arg0: &OperandSize // Generated as internal constructor for term reg_to_gpr_mem_imm. pub fn constructor_reg_to_gpr_mem_imm(ctx: &mut C, arg0: Reg) -> Option { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 949. + // Rule at src/isa/x64/inst.isle line 950. let expr0_0 = C::gpr_new(ctx, pattern0_0); let expr1_0 = C::gpr_to_gpr_mem_imm(ctx, expr0_0); return Some(expr1_0); @@ -790,7 +791,7 @@ pub fn constructor_reg_to_gpr_mem_imm(ctx: &mut C, arg0: Reg) -> Opt // Generated as internal constructor for term put_in_gpr. pub fn constructor_put_in_gpr(ctx: &mut C, arg0: Value) -> Option { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 956. + // Rule at src/isa/x64/inst.isle line 957. let expr0_0 = C::put_in_reg(ctx, pattern0_0); let expr1_0 = C::gpr_new(ctx, expr0_0); return Some(expr1_0); @@ -799,7 +800,7 @@ pub fn constructor_put_in_gpr(ctx: &mut C, arg0: Value) -> Option(ctx: &mut C, arg0: Value) -> Option { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 963. + // Rule at src/isa/x64/inst.isle line 964. let expr0_0 = C::put_in_reg_mem(ctx, pattern0_0); let expr1_0 = C::reg_mem_to_gpr_mem(ctx, &expr0_0); return Some(expr1_0); @@ -808,7 +809,7 @@ pub fn constructor_put_in_gpr_mem(ctx: &mut C, arg0: Value) -> Optio // Generated as internal constructor for term put_in_gpr_mem_imm. pub fn constructor_put_in_gpr_mem_imm(ctx: &mut C, arg0: Value) -> Option { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 970. + // Rule at src/isa/x64/inst.isle line 971. let expr0_0 = C::put_in_reg_mem_imm(ctx, pattern0_0); let expr1_0 = C::gpr_mem_imm_new(ctx, &expr0_0); return Some(expr1_0); @@ -817,7 +818,7 @@ pub fn constructor_put_in_gpr_mem_imm(ctx: &mut C, arg0: Value) -> O // Generated as internal constructor for term put_in_xmm. pub fn constructor_put_in_xmm(ctx: &mut C, arg0: Value) -> Option { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 977. + // Rule at src/isa/x64/inst.isle line 978. let expr0_0 = C::put_in_reg(ctx, pattern0_0); let expr1_0 = C::xmm_new(ctx, expr0_0); return Some(expr1_0); @@ -826,7 +827,7 @@ pub fn constructor_put_in_xmm(ctx: &mut C, arg0: Value) -> Option(ctx: &mut C, arg0: Value) -> Option { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 984. + // Rule at src/isa/x64/inst.isle line 985. let expr0_0 = C::put_in_reg_mem(ctx, pattern0_0); let expr1_0 = C::reg_mem_to_xmm_mem(ctx, &expr0_0); return Some(expr1_0); @@ -835,7 +836,7 @@ pub fn constructor_put_in_xmm_mem(ctx: &mut C, arg0: Value) -> Optio // Generated as internal constructor for term put_in_xmm_mem_imm. pub fn constructor_put_in_xmm_mem_imm(ctx: &mut C, arg0: Value) -> Option { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 991. + // Rule at src/isa/x64/inst.isle line 992. let expr0_0 = C::put_in_reg_mem_imm(ctx, pattern0_0); let expr1_0 = C::xmm_mem_imm_new(ctx, &expr0_0); return Some(expr1_0); @@ -844,7 +845,7 @@ pub fn constructor_put_in_xmm_mem_imm(ctx: &mut C, arg0: Value) -> O // Generated as internal constructor for term output_gpr. pub fn constructor_output_gpr(ctx: &mut C, arg0: Gpr) -> Option { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 996. + // Rule at src/isa/x64/inst.isle line 997. let expr0_0 = C::gpr_to_reg(ctx, pattern0_0); let expr1_0 = constructor_output_reg(ctx, expr0_0)?; return Some(expr1_0); @@ -854,7 +855,7 @@ pub fn constructor_output_gpr(ctx: &mut C, arg0: Gpr) -> Option(ctx: &mut C, arg0: Gpr, arg1: Gpr) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1001. + // Rule at src/isa/x64/inst.isle line 1002. let expr0_0 = C::gpr_to_reg(ctx, pattern0_0); let expr1_0 = C::gpr_to_reg(ctx, pattern1_0); let expr2_0 = C::value_regs(ctx, expr0_0, expr1_0); @@ -864,7 +865,7 @@ pub fn constructor_value_gprs(ctx: &mut C, arg0: Gpr, arg1: Gpr) -> // Generated as internal constructor for term output_xmm. pub fn constructor_output_xmm(ctx: &mut C, arg0: Xmm) -> Option { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 1006. + // Rule at src/isa/x64/inst.isle line 1007. let expr0_0 = C::xmm_to_reg(ctx, pattern0_0); let expr1_0 = constructor_output_reg(ctx, expr0_0)?; return Some(expr1_0); @@ -878,7 +879,7 @@ pub fn constructor_value_regs_get_gpr( ) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1013. + // Rule at src/isa/x64/inst.isle line 1014. let expr0_0 = C::value_regs_get(ctx, pattern0_0, pattern1_0); let expr1_0 = C::gpr_new(ctx, expr0_0); return Some(expr1_0); @@ -887,7 +888,7 @@ pub fn constructor_value_regs_get_gpr( // Generated as internal constructor for term lo_gpr. pub fn constructor_lo_gpr(ctx: &mut C, arg0: Value) -> Option { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 1026. + // Rule at src/isa/x64/inst.isle line 1027. let expr0_0 = constructor_lo_reg(ctx, pattern0_0)?; let expr1_0 = C::gpr_new(ctx, expr0_0); return Some(expr1_0); @@ -899,7 +900,7 @@ pub fn constructor_sink_load_to_gpr_mem_imm( arg0: &SinkableLoad, ) -> Option { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 1109. + // Rule at src/isa/x64/inst.isle line 1110. let expr0_0 = C::sink_load(ctx, pattern0_0); let expr1_0 = C::gpr_mem_imm_new(ctx, &expr0_0); return Some(expr1_0); @@ -917,12 +918,12 @@ pub fn constructor_extend_to_gpr( let pattern2_0 = arg1; if pattern2_0 == pattern1_0 { let pattern4_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1131. + // Rule at src/isa/x64/inst.isle line 1132. let expr0_0 = constructor_put_in_gpr(ctx, pattern0_0)?; return Some(expr0_0); } let pattern3_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1134. + // Rule at src/isa/x64/inst.isle line 1135. let expr0_0 = C::ty_bits_u16(ctx, pattern1_0); let expr1_0 = C::operand_size_of_type_32_64(ctx, pattern2_0); let expr2_0 = constructor_operand_size_bits(ctx, &expr1_0)?; @@ -946,7 +947,7 @@ pub fn constructor_extend( let pattern2_0 = arg1; let pattern3_0 = arg2; let pattern4_0 = arg3; - // Rule at src/isa/x64/inst.isle line 1154. + // Rule at src/isa/x64/inst.isle line 1155. let expr0_0 = constructor_movsx(ctx, pattern2_0, pattern3_0, pattern4_0)?; return Some(expr0_0); } @@ -954,7 +955,7 @@ pub fn constructor_extend( let pattern2_0 = arg1; let pattern3_0 = arg2; let pattern4_0 = arg3; - // Rule at src/isa/x64/inst.isle line 1150. + // Rule at src/isa/x64/inst.isle line 1151. let expr0_0 = constructor_movzx(ctx, pattern2_0, pattern3_0, pattern4_0)?; return Some(expr0_0); } @@ -967,17 +968,17 @@ pub fn constructor_extend( pub fn constructor_sse_xor_op(ctx: &mut C, arg0: Type) -> Option { let pattern0_0 = arg0; if pattern0_0 == F32X4 { - // Rule at src/isa/x64/inst.isle line 1161. + // Rule at src/isa/x64/inst.isle line 1162. let expr0_0 = SseOpcode::Xorps; return Some(expr0_0); } if pattern0_0 == F64X2 { - // Rule at src/isa/x64/inst.isle line 1162. + // Rule at src/isa/x64/inst.isle line 1163. let expr0_0 = SseOpcode::Xorpd; return Some(expr0_0); } if let Some((pattern1_0, pattern1_1)) = C::multi_lane(ctx, pattern0_0) { - // Rule at src/isa/x64/inst.isle line 1163. + // Rule at src/isa/x64/inst.isle line 1164. let expr0_0 = SseOpcode::Pxor; return Some(expr0_0); } @@ -994,7 +995,7 @@ pub fn constructor_sse_xor( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1167. + // Rule at src/isa/x64/inst.isle line 1168. let expr0_0 = constructor_sse_xor_op(ctx, pattern0_0)?; let expr1_0 = constructor_xmm_rm_r(ctx, pattern0_0, &expr0_0, pattern1_0, pattern2_0)?; return Some(expr1_0); @@ -1004,40 +1005,40 @@ pub fn constructor_sse_xor( pub fn constructor_sse_cmp_op(ctx: &mut C, arg0: Type) -> Option { let pattern0_0 = arg0; if pattern0_0 == F32X4 { - // Rule at src/isa/x64/inst.isle line 1176. + // Rule at src/isa/x64/inst.isle line 1177. let expr0_0 = SseOpcode::Cmpps; return Some(expr0_0); } if pattern0_0 == F64X2 { - // Rule at src/isa/x64/inst.isle line 1177. + // Rule at src/isa/x64/inst.isle line 1178. let expr0_0 = SseOpcode::Cmppd; return Some(expr0_0); } if let Some((pattern1_0, pattern1_1)) = C::multi_lane(ctx, pattern0_0) { if pattern1_0 == 8 { if pattern1_1 == 16 { - // Rule at src/isa/x64/inst.isle line 1172. + // Rule at src/isa/x64/inst.isle line 1173. let expr0_0 = SseOpcode::Pcmpeqb; return Some(expr0_0); } } if pattern1_0 == 16 { if pattern1_1 == 8 { - // Rule at src/isa/x64/inst.isle line 1173. + // Rule at src/isa/x64/inst.isle line 1174. let expr0_0 = SseOpcode::Pcmpeqw; return Some(expr0_0); } } if pattern1_0 == 32 { if pattern1_1 == 4 { - // Rule at src/isa/x64/inst.isle line 1174. + // Rule at src/isa/x64/inst.isle line 1175. let expr0_0 = SseOpcode::Pcmpeqd; return Some(expr0_0); } } if pattern1_0 == 64 { if pattern1_1 == 2 { - // Rule at src/isa/x64/inst.isle line 1175. + // Rule at src/isa/x64/inst.isle line 1176. let expr0_0 = SseOpcode::Pcmpeqq; return Some(expr0_0); } @@ -1049,7 +1050,7 @@ pub fn constructor_sse_cmp_op(ctx: &mut C, arg0: Type) -> Option(ctx: &mut C, arg0: Type) -> Option { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 1191. + // Rule at src/isa/x64/inst.isle line 1192. let expr0_0 = C::temp_writable_xmm(ctx); let expr1_0: Type = I32X4; let expr2_0 = constructor_sse_cmp_op(ctx, expr1_0)?; @@ -1074,7 +1075,7 @@ pub fn constructor_make_i64x2_from_lanes( ) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1201. + // Rule at src/isa/x64/inst.isle line 1202. let expr0_0 = C::temp_writable_xmm(ctx); let expr1_0 = C::writable_xmm_to_reg(ctx, expr0_0); let expr2_0 = MInst::XmmUninitializedValue { dst: expr0_0 }; @@ -1116,12 +1117,12 @@ pub fn constructor_mov_rmi_to_xmm(ctx: &mut C, arg0: &RegMemImm) -> let pattern0_0 = arg0; match pattern0_0 { &RegMemImm::Imm { simm32: pattern1_0 } => { - // Rule at src/isa/x64/inst.isle line 1222. + // Rule at src/isa/x64/inst.isle line 1223. let expr0_0 = C::xmm_mem_imm_new(ctx, pattern0_0); return Some(expr0_0); } &RegMemImm::Reg { reg: pattern1_0 } => { - // Rule at src/isa/x64/inst.isle line 1223. + // Rule at src/isa/x64/inst.isle line 1224. let expr0_0 = SseOpcode::Movd; let expr1_0 = C::reg_to_gpr_mem(ctx, pattern1_0); let expr2_0 = OperandSize::Size32; @@ -1132,7 +1133,7 @@ pub fn constructor_mov_rmi_to_xmm(ctx: &mut C, arg0: &RegMemImm) -> &RegMemImm::Mem { addr: ref pattern1_0, } => { - // Rule at src/isa/x64/inst.isle line 1221. + // Rule at src/isa/x64/inst.isle line 1222. let expr0_0 = C::xmm_mem_imm_new(ctx, pattern0_0); return Some(expr0_0); } @@ -1152,7 +1153,7 @@ pub fn constructor_x64_load( if pattern0_0 == I64 { let pattern2_0 = arg1; let pattern3_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1238. + // Rule at src/isa/x64/inst.isle line 1239. let expr0_0 = C::temp_writable_gpr(ctx); let expr1_0 = MInst::Mov64MR { src: pattern2_0.clone(), @@ -1165,7 +1166,7 @@ pub fn constructor_x64_load( if pattern0_0 == F32 { let pattern2_0 = arg1; let pattern3_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1243. + // Rule at src/isa/x64/inst.isle line 1244. let expr0_0 = SseOpcode::Movss; let expr1_0 = constructor_synthetic_amode_to_xmm_mem(ctx, pattern2_0)?; let expr2_0 = constructor_xmm_unary_rm_r(ctx, &expr0_0, &expr1_0)?; @@ -1175,7 +1176,7 @@ pub fn constructor_x64_load( if pattern0_0 == F64 { let pattern2_0 = arg1; let pattern3_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1247. + // Rule at src/isa/x64/inst.isle line 1248. let expr0_0 = SseOpcode::Movsd; let expr1_0 = constructor_synthetic_amode_to_xmm_mem(ctx, pattern2_0)?; let expr2_0 = constructor_xmm_unary_rm_r(ctx, &expr0_0, &expr1_0)?; @@ -1185,7 +1186,7 @@ pub fn constructor_x64_load( if pattern0_0 == F32X4 { let pattern2_0 = arg1; let pattern3_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1251. + // Rule at src/isa/x64/inst.isle line 1252. let expr0_0 = SseOpcode::Movups; let expr1_0 = constructor_synthetic_amode_to_xmm_mem(ctx, pattern2_0)?; let expr2_0 = constructor_xmm_unary_rm_r(ctx, &expr0_0, &expr1_0)?; @@ -1195,7 +1196,7 @@ pub fn constructor_x64_load( if pattern0_0 == F64X2 { let pattern2_0 = arg1; let pattern3_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1255. + // Rule at src/isa/x64/inst.isle line 1256. let expr0_0 = SseOpcode::Movupd; let expr1_0 = constructor_synthetic_amode_to_xmm_mem(ctx, pattern2_0)?; let expr2_0 = constructor_xmm_unary_rm_r(ctx, &expr0_0, &expr1_0)?; @@ -1205,7 +1206,7 @@ pub fn constructor_x64_load( if let Some((pattern1_0, pattern1_1)) = C::multi_lane(ctx, pattern0_0) { let pattern2_0 = arg1; let pattern3_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1259. + // Rule at src/isa/x64/inst.isle line 1260. let expr0_0 = SseOpcode::Movdqu; let expr1_0 = constructor_synthetic_amode_to_xmm_mem(ctx, pattern2_0)?; let expr2_0 = constructor_xmm_unary_rm_r(ctx, &expr0_0, &expr1_0)?; @@ -1216,7 +1217,7 @@ pub fn constructor_x64_load( let pattern2_0 = arg1; let pattern3_0 = arg2; if let &ExtKind::SignExtend = pattern3_0 { - // Rule at src/isa/x64/inst.isle line 1233. + // Rule at src/isa/x64/inst.isle line 1234. let expr0_0 = C::ty_bytes(ctx, pattern1_0); let expr1_0: u16 = 8; let expr2_0 = C::ext_mode(ctx, expr0_0, expr1_0); @@ -1237,7 +1238,7 @@ pub fn constructor_xmm_load_const( ) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1265. + // Rule at src/isa/x64/inst.isle line 1266. let expr0_0 = C::temp_writable_xmm(ctx); let expr1_0 = C::writable_xmm_to_reg(ctx, expr0_0); let expr2_0 = MInst::XmmLoadConst { @@ -1262,7 +1263,7 @@ pub fn constructor_alu_rmi_r( let pattern1_0 = arg1; let pattern2_0 = arg2; let pattern3_0 = arg3; - // Rule at src/isa/x64/inst.isle line 1278. + // Rule at src/isa/x64/inst.isle line 1279. let expr0_0 = C::temp_writable_gpr(ctx); let expr1_0 = C::operand_size_of_type_32_64(ctx, pattern0_0); let expr2_0 = MInst::AluRmiR { @@ -1287,7 +1288,7 @@ pub fn constructor_add( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1286. + // Rule at src/isa/x64/inst.isle line 1287. let expr0_0 = AluRmiROpcode::Add; let expr1_0 = constructor_alu_rmi_r(ctx, pattern0_0, &expr0_0, pattern1_0, pattern2_0)?; return Some(expr1_0); @@ -1303,7 +1304,7 @@ pub fn constructor_add_with_flags_paired( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1294. + // Rule at src/isa/x64/inst.isle line 1295. let expr0_0 = C::temp_writable_gpr(ctx); let expr1_0 = C::operand_size_of_type_32_64(ctx, pattern0_0); let expr2_0 = AluRmiROpcode::Add; @@ -1332,7 +1333,7 @@ pub fn constructor_adc_paired( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1306. + // Rule at src/isa/x64/inst.isle line 1307. let expr0_0 = C::temp_writable_gpr(ctx); let expr1_0 = C::operand_size_of_type_32_64(ctx, pattern0_0); let expr2_0 = AluRmiROpcode::Adc; @@ -1361,7 +1362,7 @@ pub fn constructor_sub( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1318. + // Rule at src/isa/x64/inst.isle line 1319. let expr0_0 = AluRmiROpcode::Sub; let expr1_0 = constructor_alu_rmi_r(ctx, pattern0_0, &expr0_0, pattern1_0, pattern2_0)?; return Some(expr1_0); @@ -1377,7 +1378,7 @@ pub fn constructor_sub_with_flags_paired( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1326. + // Rule at src/isa/x64/inst.isle line 1327. let expr0_0 = C::temp_writable_gpr(ctx); let expr1_0 = C::operand_size_of_type_32_64(ctx, pattern0_0); let expr2_0 = AluRmiROpcode::Sub; @@ -1406,7 +1407,7 @@ pub fn constructor_sbb_paired( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1338. + // Rule at src/isa/x64/inst.isle line 1339. let expr0_0 = C::temp_writable_gpr(ctx); let expr1_0 = C::operand_size_of_type_32_64(ctx, pattern0_0); let expr2_0 = AluRmiROpcode::Sbb; @@ -1435,7 +1436,7 @@ pub fn constructor_mul( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1350. + // Rule at src/isa/x64/inst.isle line 1351. let expr0_0 = AluRmiROpcode::Mul; let expr1_0 = constructor_alu_rmi_r(ctx, pattern0_0, &expr0_0, pattern1_0, pattern2_0)?; return Some(expr1_0); @@ -1451,7 +1452,7 @@ pub fn constructor_x64_and( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1358. + // Rule at src/isa/x64/inst.isle line 1359. let expr0_0 = AluRmiROpcode::And; let expr1_0 = constructor_alu_rmi_r(ctx, pattern0_0, &expr0_0, pattern1_0, pattern2_0)?; return Some(expr1_0); @@ -1467,7 +1468,7 @@ pub fn constructor_or( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1366. + // Rule at src/isa/x64/inst.isle line 1367. let expr0_0 = AluRmiROpcode::Or; let expr1_0 = constructor_alu_rmi_r(ctx, pattern0_0, &expr0_0, pattern1_0, pattern2_0)?; return Some(expr1_0); @@ -1483,7 +1484,7 @@ pub fn constructor_xor( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1374. + // Rule at src/isa/x64/inst.isle line 1375. let expr0_0 = AluRmiROpcode::Xor; let expr1_0 = constructor_alu_rmi_r(ctx, pattern0_0, &expr0_0, pattern1_0, pattern2_0)?; return Some(expr1_0); @@ -1495,7 +1496,7 @@ pub fn constructor_imm(ctx: &mut C, arg0: Type, arg1: u64) -> Option if pattern0_0 == I64 { let pattern2_0 = arg1; if let Some(pattern3_0) = C::nonzero_u64_fits_in_u32(ctx, pattern2_0) { - // Rule at src/isa/x64/inst.isle line 1414. + // Rule at src/isa/x64/inst.isle line 1415. let expr0_0 = C::temp_writable_gpr(ctx); let expr1_0 = OperandSize::Size32; let expr2_0 = MInst::Imm { @@ -1511,7 +1512,7 @@ pub fn constructor_imm(ctx: &mut C, arg0: Type, arg1: u64) -> Option if pattern0_0 == F32 { let pattern2_0 = arg1; if pattern2_0 == 0 { - // Rule at src/isa/x64/inst.isle line 1443. + // Rule at src/isa/x64/inst.isle line 1444. let expr0_0 = C::temp_writable_xmm(ctx); let expr1_0 = C::writable_xmm_to_xmm(ctx, expr0_0); let expr2_0 = SseOpcode::Xorps; @@ -1526,7 +1527,7 @@ pub fn constructor_imm(ctx: &mut C, arg0: Type, arg1: u64) -> Option let expr6_0 = C::xmm_to_reg(ctx, expr1_0); return Some(expr6_0); } - // Rule at src/isa/x64/inst.isle line 1391. + // Rule at src/isa/x64/inst.isle line 1392. let expr0_0 = SseOpcode::Movd; let expr1_0: Type = I32; let expr2_0 = constructor_imm(ctx, expr1_0, pattern2_0)?; @@ -1539,7 +1540,7 @@ pub fn constructor_imm(ctx: &mut C, arg0: Type, arg1: u64) -> Option if pattern0_0 == F64 { let pattern2_0 = arg1; if pattern2_0 == 0 { - // Rule at src/isa/x64/inst.isle line 1455. + // Rule at src/isa/x64/inst.isle line 1456. let expr0_0 = C::temp_writable_xmm(ctx); let expr1_0 = C::writable_xmm_to_xmm(ctx, expr0_0); let expr2_0 = SseOpcode::Xorpd; @@ -1554,7 +1555,7 @@ pub fn constructor_imm(ctx: &mut C, arg0: Type, arg1: u64) -> Option let expr6_0 = C::xmm_to_reg(ctx, expr1_0); return Some(expr6_0); } - // Rule at src/isa/x64/inst.isle line 1397. + // Rule at src/isa/x64/inst.isle line 1398. let expr0_0 = SseOpcode::Movq; let expr1_0: Type = I64; let expr2_0 = constructor_imm(ctx, expr1_0, pattern2_0)?; @@ -1567,7 +1568,7 @@ pub fn constructor_imm(ctx: &mut C, arg0: Type, arg1: u64) -> Option if let Some((pattern1_0, pattern1_1)) = C::multi_lane(ctx, pattern0_0) { let pattern2_0 = arg1; if pattern2_0 == 0 { - // Rule at src/isa/x64/inst.isle line 1433. + // Rule at src/isa/x64/inst.isle line 1434. let expr0_0 = C::temp_writable_xmm(ctx); let expr1_0 = C::writable_xmm_to_xmm(ctx, expr0_0); let expr2_0 = constructor_sse_xor_op(ctx, pattern0_0)?; @@ -1586,7 +1587,7 @@ pub fn constructor_imm(ctx: &mut C, arg0: Type, arg1: u64) -> Option if let Some(pattern1_0) = C::fits_in_64(ctx, pattern0_0) { let pattern2_0 = arg1; if pattern2_0 == 0 { - // Rule at src/isa/x64/inst.isle line 1420. + // Rule at src/isa/x64/inst.isle line 1421. let expr0_0 = C::temp_writable_gpr(ctx); let expr1_0 = C::writable_gpr_to_gpr(ctx, expr0_0); let expr2_0 = C::operand_size_of_type_32_64(ctx, pattern1_0); @@ -1603,7 +1604,7 @@ pub fn constructor_imm(ctx: &mut C, arg0: Type, arg1: u64) -> Option let expr7_0 = C::gpr_to_reg(ctx, expr1_0); return Some(expr7_0); } - // Rule at src/isa/x64/inst.isle line 1384. + // Rule at src/isa/x64/inst.isle line 1385. let expr0_0 = C::temp_writable_gpr(ctx); let expr1_0 = C::operand_size_of_type_32_64(ctx, pattern1_0); let expr2_0 = MInst::Imm { @@ -1622,7 +1623,7 @@ pub fn constructor_imm(ctx: &mut C, arg0: Type, arg1: u64) -> Option pub fn constructor_imm_i64(ctx: &mut C, arg0: Type, arg1: i64) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1406. + // Rule at src/isa/x64/inst.isle line 1407. let expr0_0 = C::i64_as_u64(ctx, pattern1_0); let expr1_0 = constructor_imm(ctx, pattern0_0, expr0_0)?; return Some(expr1_0); @@ -1640,7 +1641,7 @@ pub fn constructor_shift_r( let pattern1_0 = arg1; let pattern2_0 = arg2; let pattern3_0 = arg3; - // Rule at src/isa/x64/inst.isle line 1468. + // Rule at src/isa/x64/inst.isle line 1469. let expr0_0 = C::temp_writable_gpr(ctx); let expr1_0 = C::raw_operand_size_of_type(ctx, pattern0_0); let expr2_0 = MInst::ShiftR { @@ -1665,7 +1666,7 @@ pub fn constructor_x64_rotl( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1478. + // Rule at src/isa/x64/inst.isle line 1479. let expr0_0 = ShiftKind::RotateLeft; let expr1_0 = constructor_shift_r(ctx, pattern0_0, &expr0_0, pattern1_0, pattern2_0)?; return Some(expr1_0); @@ -1681,7 +1682,7 @@ pub fn constructor_x64_rotr( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1483. + // Rule at src/isa/x64/inst.isle line 1484. let expr0_0 = ShiftKind::RotateRight; let expr1_0 = constructor_shift_r(ctx, pattern0_0, &expr0_0, pattern1_0, pattern2_0)?; return Some(expr1_0); @@ -1697,7 +1698,7 @@ pub fn constructor_shl( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1488. + // Rule at src/isa/x64/inst.isle line 1489. let expr0_0 = ShiftKind::ShiftLeft; let expr1_0 = constructor_shift_r(ctx, pattern0_0, &expr0_0, pattern1_0, pattern2_0)?; return Some(expr1_0); @@ -1713,7 +1714,7 @@ pub fn constructor_shr( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1493. + // Rule at src/isa/x64/inst.isle line 1494. let expr0_0 = ShiftKind::ShiftRightLogical; let expr1_0 = constructor_shift_r(ctx, pattern0_0, &expr0_0, pattern1_0, pattern2_0)?; return Some(expr1_0); @@ -1729,7 +1730,7 @@ pub fn constructor_sar( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1498. + // Rule at src/isa/x64/inst.isle line 1499. let expr0_0 = ShiftKind::ShiftRightArithmetic; let expr1_0 = constructor_shift_r(ctx, pattern0_0, &expr0_0, pattern1_0, pattern2_0)?; return Some(expr1_0); @@ -1747,7 +1748,7 @@ pub fn constructor_cmp_rmi_r( let pattern1_0 = arg1; let pattern2_0 = arg2; let pattern3_0 = arg3; - // Rule at src/isa/x64/inst.isle line 1503. + // Rule at src/isa/x64/inst.isle line 1504. let expr0_0 = MInst::CmpRmiR { size: pattern0_0.clone(), opcode: pattern1_0.clone(), @@ -1768,7 +1769,7 @@ pub fn constructor_cmp( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1512. + // Rule at src/isa/x64/inst.isle line 1513. let expr0_0 = CmpOpcode::Cmp; let expr1_0 = constructor_cmp_rmi_r(ctx, pattern0_0, &expr0_0, pattern1_0, pattern2_0)?; return Some(expr1_0); @@ -1784,7 +1785,7 @@ pub fn constructor_cmp_imm( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1517. + // Rule at src/isa/x64/inst.isle line 1518. let expr0_0 = CmpOpcode::Cmp; let expr1_0 = RegMemImm::Imm { simm32: pattern1_0 }; let expr2_0 = C::gpr_mem_imm_new(ctx, &expr1_0); @@ -1802,7 +1803,7 @@ pub fn constructor_xmm_cmp_rm_r( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1522. + // Rule at src/isa/x64/inst.isle line 1523. let expr0_0 = MInst::XmmCmpRmR { op: pattern0_0.clone(), src: pattern1_0.clone(), @@ -1822,7 +1823,7 @@ pub fn constructor_fpcmp( let pattern1_0 = C::value_type(ctx, pattern0_0); if pattern1_0 == F32 { let pattern3_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1529. + // Rule at src/isa/x64/inst.isle line 1530. let expr0_0 = SseOpcode::Ucomiss; let expr1_0 = constructor_put_in_xmm_mem(ctx, pattern0_0)?; let expr2_0 = constructor_put_in_xmm(ctx, pattern3_0)?; @@ -1831,7 +1832,7 @@ pub fn constructor_fpcmp( } if pattern1_0 == F64 { let pattern3_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1531. + // Rule at src/isa/x64/inst.isle line 1532. let expr0_0 = SseOpcode::Ucomisd; let expr1_0 = constructor_put_in_xmm_mem(ctx, pattern0_0)?; let expr2_0 = constructor_put_in_xmm(ctx, pattern3_0)?; @@ -1851,7 +1852,7 @@ pub fn constructor_test( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1536. + // Rule at src/isa/x64/inst.isle line 1537. let expr0_0 = CmpOpcode::Test; let expr1_0 = constructor_cmp_rmi_r(ctx, pattern0_0, &expr0_0, pattern1_0, pattern2_0)?; return Some(expr1_0); @@ -1869,7 +1870,7 @@ pub fn constructor_cmove( let pattern1_0 = arg1; let pattern2_0 = arg2; let pattern3_0 = arg3; - // Rule at src/isa/x64/inst.isle line 1543. + // Rule at src/isa/x64/inst.isle line 1544. let expr0_0 = C::temp_writable_gpr(ctx); let expr1_0 = C::operand_size_of_type_32_64(ctx, pattern0_0); let expr2_0 = MInst::Cmove { @@ -1899,7 +1900,7 @@ pub fn constructor_cmove_xmm( let pattern1_0 = arg1; let pattern2_0 = arg2; let pattern3_0 = arg3; - // Rule at src/isa/x64/inst.isle line 1551. + // Rule at src/isa/x64/inst.isle line 1552. let expr0_0 = C::temp_writable_xmm(ctx); let expr1_0 = C::operand_size_of_type_32_64(ctx, pattern0_0); let expr2_0 = MInst::XmmCmove { @@ -1930,7 +1931,7 @@ pub fn constructor_cmove_from_values( let pattern2_0 = arg1; let pattern3_0 = arg2; let pattern4_0 = arg3; - // Rule at src/isa/x64/inst.isle line 1562. + // Rule at src/isa/x64/inst.isle line 1563. let expr0_0 = C::put_in_regs(ctx, pattern3_0); let expr1_0 = C::put_in_regs(ctx, pattern4_0); let expr2_0 = C::temp_writable_gpr(ctx); @@ -1975,7 +1976,7 @@ pub fn constructor_cmove_from_values( let pattern3_0 = arg1; let pattern4_0 = arg2; let pattern5_0 = arg3; - // Rule at src/isa/x64/inst.isle line 1586. + // Rule at src/isa/x64/inst.isle line 1587. let expr0_0 = constructor_put_in_xmm_mem(ctx, pattern4_0)?; let expr1_0 = constructor_put_in_xmm(ctx, pattern5_0)?; let expr2_0 = constructor_cmove_xmm(ctx, pattern2_0, pattern3_0, &expr0_0, expr1_0)?; @@ -1987,7 +1988,7 @@ pub fn constructor_cmove_from_values( let pattern3_0 = arg1; let pattern4_0 = arg2; let pattern5_0 = arg3; - // Rule at src/isa/x64/inst.isle line 1583. + // Rule at src/isa/x64/inst.isle line 1584. let expr0_0 = constructor_put_in_gpr_mem(ctx, pattern4_0)?; let expr1_0 = constructor_put_in_gpr(ctx, pattern5_0)?; let expr2_0 = constructor_cmove(ctx, pattern2_0, pattern3_0, &expr0_0, expr1_0)?; @@ -2011,7 +2012,7 @@ pub fn constructor_cmove_or( let pattern2_0 = arg2; let pattern3_0 = arg3; let pattern4_0 = arg4; - // Rule at src/isa/x64/inst.isle line 1593. + // Rule at src/isa/x64/inst.isle line 1594. let expr0_0 = C::temp_writable_gpr(ctx); let expr1_0 = C::temp_writable_gpr(ctx); let expr2_0 = C::operand_size_of_type_32_64(ctx, pattern0_0); @@ -2053,7 +2054,7 @@ pub fn constructor_cmove_or_xmm( let pattern2_0 = arg2; let pattern3_0 = arg3; let pattern4_0 = arg4; - // Rule at src/isa/x64/inst.isle line 1605. + // Rule at src/isa/x64/inst.isle line 1606. let expr0_0 = C::temp_writable_xmm(ctx); let expr1_0 = C::temp_writable_xmm(ctx); let expr2_0 = C::operand_size_of_type_32_64(ctx, pattern0_0); @@ -2096,7 +2097,7 @@ pub fn constructor_cmove_or_from_values( let pattern3_0 = arg2; let pattern4_0 = arg3; let pattern5_0 = arg4; - // Rule at src/isa/x64/inst.isle line 1620. + // Rule at src/isa/x64/inst.isle line 1621. let expr0_0 = C::put_in_regs(ctx, pattern4_0); let expr1_0 = C::put_in_regs(ctx, pattern5_0); let expr2_0 = C::temp_writable_gpr(ctx); @@ -2168,7 +2169,7 @@ pub fn constructor_cmove_or_from_values( let pattern4_0 = arg2; let pattern5_0 = arg3; let pattern6_0 = arg4; - // Rule at src/isa/x64/inst.isle line 1642. + // Rule at src/isa/x64/inst.isle line 1643. let expr0_0 = constructor_put_in_xmm_mem(ctx, pattern5_0)?; let expr1_0 = constructor_put_in_xmm(ctx, pattern6_0)?; let expr2_0 = constructor_cmove_or_xmm( @@ -2183,7 +2184,7 @@ pub fn constructor_cmove_or_from_values( let pattern4_0 = arg2; let pattern5_0 = arg3; let pattern6_0 = arg4; - // Rule at src/isa/x64/inst.isle line 1639. + // Rule at src/isa/x64/inst.isle line 1640. let expr0_0 = constructor_put_in_gpr_mem(ctx, pattern5_0)?; let expr1_0 = constructor_put_in_gpr(ctx, pattern6_0)?; let expr2_0 = @@ -2197,7 +2198,7 @@ pub fn constructor_cmove_or_from_values( // Generated as internal constructor for term setcc. pub fn constructor_setcc(ctx: &mut C, arg0: &CC) -> Option { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 1647. + // Rule at src/isa/x64/inst.isle line 1648. let expr0_0 = C::temp_writable_gpr(ctx); let expr1_0 = MInst::Setcc { cc: pattern0_0.clone(), @@ -2221,7 +2222,7 @@ pub fn constructor_movzx( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1655. + // Rule at src/isa/x64/inst.isle line 1656. let expr0_0 = C::temp_writable_gpr(ctx); let expr1_0 = MInst::MovzxRmR { ext_mode: pattern1_0.clone(), @@ -2243,7 +2244,7 @@ pub fn constructor_movsx( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1662. + // Rule at src/isa/x64/inst.isle line 1663. let expr0_0 = C::temp_writable_gpr(ctx); let expr1_0 = MInst::MovsxRmR { ext_mode: pattern1_0.clone(), @@ -2267,7 +2268,7 @@ pub fn constructor_xmm_rm_r( let pattern1_0 = arg1; let pattern2_0 = arg2; let pattern3_0 = arg3; - // Rule at src/isa/x64/inst.isle line 1669. + // Rule at src/isa/x64/inst.isle line 1670. let expr0_0 = C::temp_writable_xmm(ctx); let expr1_0 = MInst::XmmRmR { op: pattern1_0.clone(), @@ -2284,7 +2285,7 @@ pub fn constructor_xmm_rm_r( pub fn constructor_paddb(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1676. + // Rule at src/isa/x64/inst.isle line 1677. let expr0_0: Type = I8X16; let expr1_0 = SseOpcode::Paddb; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2295,7 +2296,7 @@ pub fn constructor_paddb(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> O pub fn constructor_paddw(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1681. + // Rule at src/isa/x64/inst.isle line 1682. let expr0_0: Type = I16X8; let expr1_0 = SseOpcode::Paddw; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2306,7 +2307,7 @@ pub fn constructor_paddw(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> O pub fn constructor_paddd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1686. + // Rule at src/isa/x64/inst.isle line 1687. let expr0_0: Type = I32X4; let expr1_0 = SseOpcode::Paddd; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2317,7 +2318,7 @@ pub fn constructor_paddd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> O pub fn constructor_paddq(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1691. + // Rule at src/isa/x64/inst.isle line 1692. let expr0_0: Type = I64X2; let expr1_0 = SseOpcode::Paddq; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2328,7 +2329,7 @@ pub fn constructor_paddq(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> O pub fn constructor_paddsb(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1696. + // Rule at src/isa/x64/inst.isle line 1697. let expr0_0: Type = I8X16; let expr1_0 = SseOpcode::Paddsb; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2339,7 +2340,7 @@ pub fn constructor_paddsb(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> pub fn constructor_paddsw(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1701. + // Rule at src/isa/x64/inst.isle line 1702. let expr0_0: Type = I16X8; let expr1_0 = SseOpcode::Paddsw; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2350,7 +2351,7 @@ pub fn constructor_paddsw(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> pub fn constructor_paddusb(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1706. + // Rule at src/isa/x64/inst.isle line 1707. let expr0_0: Type = I8X16; let expr1_0 = SseOpcode::Paddusb; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2361,7 +2362,7 @@ pub fn constructor_paddusb(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> pub fn constructor_paddusw(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1711. + // Rule at src/isa/x64/inst.isle line 1712. let expr0_0: Type = I16X8; let expr1_0 = SseOpcode::Paddusw; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2372,7 +2373,7 @@ pub fn constructor_paddusw(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> pub fn constructor_psubb(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1716. + // Rule at src/isa/x64/inst.isle line 1717. let expr0_0: Type = I8X16; let expr1_0 = SseOpcode::Psubb; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2383,7 +2384,7 @@ pub fn constructor_psubb(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> O pub fn constructor_psubw(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1721. + // Rule at src/isa/x64/inst.isle line 1722. let expr0_0: Type = I16X8; let expr1_0 = SseOpcode::Psubw; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2394,7 +2395,7 @@ pub fn constructor_psubw(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> O pub fn constructor_psubd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1726. + // Rule at src/isa/x64/inst.isle line 1727. let expr0_0: Type = I32X4; let expr1_0 = SseOpcode::Psubd; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2405,7 +2406,7 @@ pub fn constructor_psubd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> O pub fn constructor_psubq(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1731. + // Rule at src/isa/x64/inst.isle line 1732. let expr0_0: Type = I64X2; let expr1_0 = SseOpcode::Psubq; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2416,7 +2417,7 @@ pub fn constructor_psubq(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> O pub fn constructor_psubsb(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1736. + // Rule at src/isa/x64/inst.isle line 1737. let expr0_0: Type = I8X16; let expr1_0 = SseOpcode::Psubsb; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2427,7 +2428,7 @@ pub fn constructor_psubsb(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> pub fn constructor_psubsw(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1741. + // Rule at src/isa/x64/inst.isle line 1742. let expr0_0: Type = I16X8; let expr1_0 = SseOpcode::Psubsw; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2438,7 +2439,7 @@ pub fn constructor_psubsw(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> pub fn constructor_psubusb(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1746. + // Rule at src/isa/x64/inst.isle line 1747. let expr0_0: Type = I8X16; let expr1_0 = SseOpcode::Psubusb; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2449,7 +2450,7 @@ pub fn constructor_psubusb(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> pub fn constructor_psubusw(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1751. + // Rule at src/isa/x64/inst.isle line 1752. let expr0_0: Type = I16X8; let expr1_0 = SseOpcode::Psubusw; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2460,7 +2461,7 @@ pub fn constructor_psubusw(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> pub fn constructor_pavgb(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1756. + // Rule at src/isa/x64/inst.isle line 1757. let expr0_0: Type = I8X16; let expr1_0 = SseOpcode::Pavgb; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2471,7 +2472,7 @@ pub fn constructor_pavgb(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> O pub fn constructor_pavgw(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1761. + // Rule at src/isa/x64/inst.isle line 1762. let expr0_0: Type = I16X8; let expr1_0 = SseOpcode::Pavgw; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2482,7 +2483,7 @@ pub fn constructor_pavgw(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> O pub fn constructor_pand(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1766. + // Rule at src/isa/x64/inst.isle line 1767. let expr0_0: Type = F32X4; let expr1_0 = SseOpcode::Pand; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2493,7 +2494,7 @@ pub fn constructor_pand(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Op pub fn constructor_andps(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1771. + // Rule at src/isa/x64/inst.isle line 1772. let expr0_0: Type = F32X4; let expr1_0 = SseOpcode::Andps; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2504,7 +2505,7 @@ pub fn constructor_andps(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> O pub fn constructor_andpd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1776. + // Rule at src/isa/x64/inst.isle line 1777. let expr0_0: Type = F64X2; let expr1_0 = SseOpcode::Andpd; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2515,7 +2516,7 @@ pub fn constructor_andpd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> O pub fn constructor_por(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1781. + // Rule at src/isa/x64/inst.isle line 1782. let expr0_0: Type = F32X4; let expr1_0 = SseOpcode::Por; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2526,7 +2527,7 @@ pub fn constructor_por(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Opt pub fn constructor_orps(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1786. + // Rule at src/isa/x64/inst.isle line 1787. let expr0_0: Type = F32X4; let expr1_0 = SseOpcode::Orps; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2537,7 +2538,7 @@ pub fn constructor_orps(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Op pub fn constructor_orpd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1791. + // Rule at src/isa/x64/inst.isle line 1792. let expr0_0: Type = F64X2; let expr1_0 = SseOpcode::Orpd; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2548,7 +2549,7 @@ pub fn constructor_orpd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Op pub fn constructor_pxor(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1796. + // Rule at src/isa/x64/inst.isle line 1797. let expr0_0: Type = I8X16; let expr1_0 = SseOpcode::Pxor; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2559,7 +2560,7 @@ pub fn constructor_pxor(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Op pub fn constructor_xorps(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1801. + // Rule at src/isa/x64/inst.isle line 1802. let expr0_0: Type = F32X4; let expr1_0 = SseOpcode::Xorps; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2570,7 +2571,7 @@ pub fn constructor_xorps(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> O pub fn constructor_xorpd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1806. + // Rule at src/isa/x64/inst.isle line 1807. let expr0_0: Type = F64X2; let expr1_0 = SseOpcode::Xorpd; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2581,7 +2582,7 @@ pub fn constructor_xorpd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> O pub fn constructor_pmullw(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1811. + // Rule at src/isa/x64/inst.isle line 1812. let expr0_0: Type = I16X8; let expr1_0 = SseOpcode::Pmullw; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2592,7 +2593,7 @@ pub fn constructor_pmullw(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> pub fn constructor_pmulld(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1816. + // Rule at src/isa/x64/inst.isle line 1817. let expr0_0: Type = I16X8; let expr1_0 = SseOpcode::Pmulld; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2603,7 +2604,7 @@ pub fn constructor_pmulld(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> pub fn constructor_pmulhw(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1821. + // Rule at src/isa/x64/inst.isle line 1822. let expr0_0: Type = I16X8; let expr1_0 = SseOpcode::Pmulhw; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2614,7 +2615,7 @@ pub fn constructor_pmulhw(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> pub fn constructor_pmulhuw(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1826. + // Rule at src/isa/x64/inst.isle line 1827. let expr0_0: Type = I16X8; let expr1_0 = SseOpcode::Pmulhuw; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2625,7 +2626,7 @@ pub fn constructor_pmulhuw(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> pub fn constructor_pmuldq(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1831. + // Rule at src/isa/x64/inst.isle line 1832. let expr0_0: Type = I16X8; let expr1_0 = SseOpcode::Pmuldq; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2636,7 +2637,7 @@ pub fn constructor_pmuldq(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> pub fn constructor_pmuludq(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1836. + // Rule at src/isa/x64/inst.isle line 1837. let expr0_0: Type = I64X2; let expr1_0 = SseOpcode::Pmuludq; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2647,7 +2648,7 @@ pub fn constructor_pmuludq(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> pub fn constructor_punpckhwd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1841. + // Rule at src/isa/x64/inst.isle line 1842. let expr0_0: Type = I16X8; let expr1_0 = SseOpcode::Punpckhwd; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2658,7 +2659,7 @@ pub fn constructor_punpckhwd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) pub fn constructor_punpcklwd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1846. + // Rule at src/isa/x64/inst.isle line 1847. let expr0_0: Type = I16X8; let expr1_0 = SseOpcode::Punpcklwd; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2669,7 +2670,7 @@ pub fn constructor_punpcklwd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) pub fn constructor_andnps(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1851. + // Rule at src/isa/x64/inst.isle line 1852. let expr0_0: Type = F32X4; let expr1_0 = SseOpcode::Andnps; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2680,7 +2681,7 @@ pub fn constructor_andnps(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> pub fn constructor_andnpd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1856. + // Rule at src/isa/x64/inst.isle line 1857. let expr0_0: Type = F64X2; let expr1_0 = SseOpcode::Andnpd; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2691,7 +2692,7 @@ pub fn constructor_andnpd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> pub fn constructor_pandn(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1861. + // Rule at src/isa/x64/inst.isle line 1862. let expr0_0: Type = F64X2; let expr1_0 = SseOpcode::Pandn; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2702,7 +2703,7 @@ pub fn constructor_pandn(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> O pub fn constructor_addss(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1866. + // Rule at src/isa/x64/inst.isle line 1867. let expr0_0: Type = F32; let expr1_0 = SseOpcode::Addss; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2713,7 +2714,7 @@ pub fn constructor_addss(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> O pub fn constructor_addsd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1871. + // Rule at src/isa/x64/inst.isle line 1872. let expr0_0: Type = F64; let expr1_0 = SseOpcode::Addsd; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2724,7 +2725,7 @@ pub fn constructor_addsd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> O pub fn constructor_addps(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1876. + // Rule at src/isa/x64/inst.isle line 1877. let expr0_0: Type = F32; let expr1_0 = SseOpcode::Addps; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2735,7 +2736,7 @@ pub fn constructor_addps(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> O pub fn constructor_addpd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1881. + // Rule at src/isa/x64/inst.isle line 1882. let expr0_0: Type = F32; let expr1_0 = SseOpcode::Addpd; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2746,7 +2747,7 @@ pub fn constructor_addpd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> O pub fn constructor_subss(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1886. + // Rule at src/isa/x64/inst.isle line 1887. let expr0_0: Type = F32; let expr1_0 = SseOpcode::Subss; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2757,7 +2758,7 @@ pub fn constructor_subss(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> O pub fn constructor_subsd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1891. + // Rule at src/isa/x64/inst.isle line 1892. let expr0_0: Type = F64; let expr1_0 = SseOpcode::Subsd; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2768,7 +2769,7 @@ pub fn constructor_subsd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> O pub fn constructor_subps(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1896. + // Rule at src/isa/x64/inst.isle line 1897. let expr0_0: Type = F32; let expr1_0 = SseOpcode::Subps; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2779,7 +2780,7 @@ pub fn constructor_subps(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> O pub fn constructor_subpd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1901. + // Rule at src/isa/x64/inst.isle line 1902. let expr0_0: Type = F32; let expr1_0 = SseOpcode::Subpd; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2790,7 +2791,7 @@ pub fn constructor_subpd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> O pub fn constructor_mulss(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1906. + // Rule at src/isa/x64/inst.isle line 1907. let expr0_0: Type = F32; let expr1_0 = SseOpcode::Mulss; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2801,7 +2802,7 @@ pub fn constructor_mulss(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> O pub fn constructor_mulsd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1911. + // Rule at src/isa/x64/inst.isle line 1912. let expr0_0: Type = F64; let expr1_0 = SseOpcode::Mulsd; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2812,7 +2813,7 @@ pub fn constructor_mulsd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> O pub fn constructor_mulps(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1916. + // Rule at src/isa/x64/inst.isle line 1917. let expr0_0: Type = F32; let expr1_0 = SseOpcode::Mulps; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2823,7 +2824,7 @@ pub fn constructor_mulps(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> O pub fn constructor_mulpd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1921. + // Rule at src/isa/x64/inst.isle line 1922. let expr0_0: Type = F32; let expr1_0 = SseOpcode::Mulpd; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2834,7 +2835,7 @@ pub fn constructor_mulpd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> O pub fn constructor_divss(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1926. + // Rule at src/isa/x64/inst.isle line 1927. let expr0_0: Type = F32; let expr1_0 = SseOpcode::Divss; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2845,7 +2846,7 @@ pub fn constructor_divss(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> O pub fn constructor_divsd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1931. + // Rule at src/isa/x64/inst.isle line 1932. let expr0_0: Type = F64; let expr1_0 = SseOpcode::Divsd; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2856,7 +2857,7 @@ pub fn constructor_divsd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> O pub fn constructor_divps(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1936. + // Rule at src/isa/x64/inst.isle line 1937. let expr0_0: Type = F32; let expr1_0 = SseOpcode::Divps; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2867,7 +2868,7 @@ pub fn constructor_divps(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> O pub fn constructor_divpd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1941. + // Rule at src/isa/x64/inst.isle line 1942. let expr0_0: Type = F32; let expr1_0 = SseOpcode::Divpd; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2878,17 +2879,17 @@ pub fn constructor_divpd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> O pub fn constructor_sse_blend_op(ctx: &mut C, arg0: Type) -> Option { let pattern0_0 = arg0; if pattern0_0 == F32X4 { - // Rule at src/isa/x64/inst.isle line 1945. + // Rule at src/isa/x64/inst.isle line 1946. let expr0_0 = SseOpcode::Blendvps; return Some(expr0_0); } if pattern0_0 == F64X2 { - // Rule at src/isa/x64/inst.isle line 1946. + // Rule at src/isa/x64/inst.isle line 1947. let expr0_0 = SseOpcode::Blendvpd; return Some(expr0_0); } if let Some((pattern1_0, pattern1_1)) = C::multi_lane(ctx, pattern0_0) { - // Rule at src/isa/x64/inst.isle line 1947. + // Rule at src/isa/x64/inst.isle line 1948. let expr0_0 = SseOpcode::Pblendvb; return Some(expr0_0); } @@ -2899,17 +2900,17 @@ pub fn constructor_sse_blend_op(ctx: &mut C, arg0: Type) -> Option(ctx: &mut C, arg0: Type) -> Option { let pattern0_0 = arg0; if pattern0_0 == F32X4 { - // Rule at src/isa/x64/inst.isle line 1950. + // Rule at src/isa/x64/inst.isle line 1951. let expr0_0 = SseOpcode::Movaps; return Some(expr0_0); } if pattern0_0 == F64X2 { - // Rule at src/isa/x64/inst.isle line 1951. + // Rule at src/isa/x64/inst.isle line 1952. let expr0_0 = SseOpcode::Movapd; return Some(expr0_0); } if let Some((pattern1_0, pattern1_1)) = C::multi_lane(ctx, pattern0_0) { - // Rule at src/isa/x64/inst.isle line 1952. + // Rule at src/isa/x64/inst.isle line 1953. let expr0_0 = SseOpcode::Movdqa; return Some(expr0_0); } @@ -2928,7 +2929,7 @@ pub fn constructor_sse_blend( let pattern1_0 = arg1; let pattern2_0 = arg2; let pattern3_0 = arg3; - // Rule at src/isa/x64/inst.isle line 1956. + // Rule at src/isa/x64/inst.isle line 1957. let expr0_0 = C::xmm0(ctx); let expr1_0 = constructor_sse_mov_op(ctx, pattern0_0)?; let expr2_0 = MInst::XmmUnaryRmR { @@ -2952,7 +2953,7 @@ pub fn constructor_blendvpd( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1970. + // Rule at src/isa/x64/inst.isle line 1971. let expr0_0 = C::xmm0(ctx); let expr1_0 = SseOpcode::Movapd; let expr2_0 = C::xmm_to_xmm_mem(ctx, pattern2_0); @@ -2972,7 +2973,7 @@ pub fn constructor_blendvpd( pub fn constructor_movsd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1984. + // Rule at src/isa/x64/inst.isle line 1985. let expr0_0: Type = I8X16; let expr1_0 = SseOpcode::Movsd; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2983,7 +2984,7 @@ pub fn constructor_movsd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> O pub fn constructor_movlhps(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1989. + // Rule at src/isa/x64/inst.isle line 1990. let expr0_0: Type = I8X16; let expr1_0 = SseOpcode::Movlhps; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -2994,7 +2995,7 @@ pub fn constructor_movlhps(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> pub fn constructor_pmaxsb(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1994. + // Rule at src/isa/x64/inst.isle line 1995. let expr0_0: Type = I8X16; let expr1_0 = SseOpcode::Pmaxsb; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -3005,7 +3006,7 @@ pub fn constructor_pmaxsb(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> pub fn constructor_pmaxsw(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1999. + // Rule at src/isa/x64/inst.isle line 2000. let expr0_0: Type = I8X16; let expr1_0 = SseOpcode::Pmaxsw; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -3016,7 +3017,7 @@ pub fn constructor_pmaxsw(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> pub fn constructor_pmaxsd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 2004. + // Rule at src/isa/x64/inst.isle line 2005. let expr0_0: Type = I8X16; let expr1_0 = SseOpcode::Pmaxsd; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -3027,7 +3028,7 @@ pub fn constructor_pmaxsd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> pub fn constructor_pminsb(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 2009. + // Rule at src/isa/x64/inst.isle line 2010. let expr0_0: Type = I8X16; let expr1_0 = SseOpcode::Pminsb; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -3038,7 +3039,7 @@ pub fn constructor_pminsb(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> pub fn constructor_pminsw(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 2014. + // Rule at src/isa/x64/inst.isle line 2015. let expr0_0: Type = I8X16; let expr1_0 = SseOpcode::Pminsw; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -3049,7 +3050,7 @@ pub fn constructor_pminsw(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> pub fn constructor_pminsd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 2019. + // Rule at src/isa/x64/inst.isle line 2020. let expr0_0: Type = I8X16; let expr1_0 = SseOpcode::Pminsd; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -3060,7 +3061,7 @@ pub fn constructor_pminsd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> pub fn constructor_pmaxub(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 2024. + // Rule at src/isa/x64/inst.isle line 2025. let expr0_0: Type = I8X16; let expr1_0 = SseOpcode::Pmaxub; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -3071,7 +3072,7 @@ pub fn constructor_pmaxub(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> pub fn constructor_pmaxuw(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 2029. + // Rule at src/isa/x64/inst.isle line 2030. let expr0_0: Type = I8X16; let expr1_0 = SseOpcode::Pmaxuw; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -3082,7 +3083,7 @@ pub fn constructor_pmaxuw(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> pub fn constructor_pmaxud(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 2034. + // Rule at src/isa/x64/inst.isle line 2035. let expr0_0: Type = I8X16; let expr1_0 = SseOpcode::Pmaxud; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -3093,7 +3094,7 @@ pub fn constructor_pmaxud(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> pub fn constructor_pminub(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 2039. + // Rule at src/isa/x64/inst.isle line 2040. let expr0_0: Type = I8X16; let expr1_0 = SseOpcode::Pminub; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -3104,7 +3105,7 @@ pub fn constructor_pminub(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> pub fn constructor_pminuw(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 2044. + // Rule at src/isa/x64/inst.isle line 2045. let expr0_0: Type = I8X16; let expr1_0 = SseOpcode::Pminuw; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -3115,7 +3116,7 @@ pub fn constructor_pminuw(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> pub fn constructor_pminud(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 2049. + // Rule at src/isa/x64/inst.isle line 2050. let expr0_0: Type = I8X16; let expr1_0 = SseOpcode::Pminud; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -3126,7 +3127,7 @@ pub fn constructor_pminud(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> pub fn constructor_punpcklbw(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 2054. + // Rule at src/isa/x64/inst.isle line 2055. let expr0_0: Type = I8X16; let expr1_0 = SseOpcode::Punpcklbw; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -3137,7 +3138,7 @@ pub fn constructor_punpcklbw(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) pub fn constructor_punpckhbw(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 2059. + // Rule at src/isa/x64/inst.isle line 2060. let expr0_0: Type = I8X16; let expr1_0 = SseOpcode::Punpckhbw; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -3148,7 +3149,7 @@ pub fn constructor_punpckhbw(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) pub fn constructor_packsswb(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 2064. + // Rule at src/isa/x64/inst.isle line 2065. let expr0_0: Type = I8X16; let expr1_0 = SseOpcode::Packsswb; let expr2_0 = constructor_xmm_rm_r(ctx, expr0_0, &expr1_0, pattern0_0, pattern1_0)?; @@ -3169,7 +3170,7 @@ pub fn constructor_xmm_rm_r_imm( let pattern2_0 = arg2; let pattern3_0 = arg3; let pattern4_0 = arg4; - // Rule at src/isa/x64/inst.isle line 2069. + // Rule at src/isa/x64/inst.isle line 2070. let expr0_0 = C::temp_writable_xmm(ctx); let expr1_0 = C::writable_xmm_to_reg(ctx, expr0_0); let expr2_0 = MInst::XmmRmRImm { @@ -3197,7 +3198,7 @@ pub fn constructor_palignr( let pattern1_0 = arg1; let pattern2_0 = arg2; let pattern3_0 = arg3; - // Rule at src/isa/x64/inst.isle line 2081. + // Rule at src/isa/x64/inst.isle line 2082. let expr0_0 = SseOpcode::Palignr; let expr1_0 = C::xmm_to_reg(ctx, pattern0_0); let expr2_0 = C::xmm_mem_to_reg_mem(ctx, pattern1_0); @@ -3216,7 +3217,7 @@ pub fn constructor_cmpps( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 2090. + // Rule at src/isa/x64/inst.isle line 2091. let expr0_0 = SseOpcode::Cmpps; let expr1_0 = C::xmm_to_reg(ctx, pattern0_0); let expr2_0 = C::xmm_mem_to_reg_mem(ctx, pattern1_0); @@ -3236,7 +3237,7 @@ pub fn constructor_pinsrb( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 2099. + // Rule at src/isa/x64/inst.isle line 2100. let expr0_0 = SseOpcode::Pinsrb; let expr1_0 = C::xmm_to_reg(ctx, pattern0_0); let expr2_0 = C::gpr_mem_to_reg_mem(ctx, pattern1_0); @@ -3255,7 +3256,7 @@ pub fn constructor_pinsrw( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 2108. + // Rule at src/isa/x64/inst.isle line 2109. let expr0_0 = SseOpcode::Pinsrw; let expr1_0 = C::xmm_to_reg(ctx, pattern0_0); let expr2_0 = C::gpr_mem_to_reg_mem(ctx, pattern1_0); @@ -3276,7 +3277,7 @@ pub fn constructor_pinsrd( let pattern1_0 = arg1; let pattern2_0 = arg2; let pattern3_0 = arg3; - // Rule at src/isa/x64/inst.isle line 2117. + // Rule at src/isa/x64/inst.isle line 2118. let expr0_0 = SseOpcode::Pinsrd; let expr1_0 = C::xmm_to_reg(ctx, pattern0_0); let expr2_0 = C::gpr_mem_to_reg_mem(ctx, pattern1_0); @@ -3289,7 +3290,7 @@ pub fn constructor_pinsrd( pub fn constructor_pmaddwd(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 2126. + // Rule at src/isa/x64/inst.isle line 2127. let expr0_0 = C::temp_writable_xmm(ctx); let expr1_0 = SseOpcode::Pmaddwd; let expr2_0 = MInst::XmmRmR { @@ -3313,7 +3314,7 @@ pub fn constructor_insertps( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 2136. + // Rule at src/isa/x64/inst.isle line 2137. let expr0_0 = SseOpcode::Insertps; let expr1_0 = C::xmm_to_reg(ctx, pattern0_0); let expr2_0 = C::xmm_mem_to_reg_mem(ctx, pattern1_0); @@ -3332,7 +3333,7 @@ pub fn constructor_pshufd( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 2145. + // Rule at src/isa/x64/inst.isle line 2146. let expr0_0 = C::temp_writable_xmm(ctx); let expr1_0 = SseOpcode::Pshufd; let expr2_0 = constructor_writable_xmm_to_r_reg(ctx, expr0_0)?; @@ -3355,7 +3356,7 @@ pub fn constructor_pshufd( pub fn constructor_pshufb(ctx: &mut C, arg0: Xmm, arg1: &XmmMem) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 2157. + // Rule at src/isa/x64/inst.isle line 2158. let expr0_0 = C::temp_writable_xmm(ctx); let expr1_0 = SseOpcode::Pshufb; let expr2_0 = MInst::XmmRmR { @@ -3377,7 +3378,7 @@ pub fn constructor_xmm_unary_rm_r( ) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 2167. + // Rule at src/isa/x64/inst.isle line 2168. let expr0_0 = C::temp_writable_xmm(ctx); let expr1_0 = MInst::XmmUnaryRmR { op: pattern0_0.clone(), @@ -3392,7 +3393,7 @@ pub fn constructor_xmm_unary_rm_r( // Generated as internal constructor for term pmovsxbw. pub fn constructor_pmovsxbw(ctx: &mut C, arg0: &XmmMem) -> Option { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 2174. + // Rule at src/isa/x64/inst.isle line 2175. let expr0_0 = SseOpcode::Pmovsxbw; let expr1_0 = constructor_xmm_unary_rm_r(ctx, &expr0_0, pattern0_0)?; return Some(expr1_0); @@ -3401,7 +3402,7 @@ pub fn constructor_pmovsxbw(ctx: &mut C, arg0: &XmmMem) -> Option(ctx: &mut C, arg0: &XmmMem) -> Option { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 2179. + // Rule at src/isa/x64/inst.isle line 2180. let expr0_0 = SseOpcode::Pmovzxbw; let expr1_0 = constructor_xmm_unary_rm_r(ctx, &expr0_0, pattern0_0)?; return Some(expr1_0); @@ -3410,7 +3411,7 @@ pub fn constructor_pmovzxbw(ctx: &mut C, arg0: &XmmMem) -> Option(ctx: &mut C, arg0: &XmmMem) -> Option { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 2184. + // Rule at src/isa/x64/inst.isle line 2185. let expr0_0 = SseOpcode::Pabsb; let expr1_0 = constructor_xmm_unary_rm_r(ctx, &expr0_0, pattern0_0)?; return Some(expr1_0); @@ -3419,7 +3420,7 @@ pub fn constructor_pabsb(ctx: &mut C, arg0: &XmmMem) -> Option // Generated as internal constructor for term pabsw. pub fn constructor_pabsw(ctx: &mut C, arg0: &XmmMem) -> Option { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 2189. + // Rule at src/isa/x64/inst.isle line 2190. let expr0_0 = SseOpcode::Pabsw; let expr1_0 = constructor_xmm_unary_rm_r(ctx, &expr0_0, pattern0_0)?; return Some(expr1_0); @@ -3428,7 +3429,7 @@ pub fn constructor_pabsw(ctx: &mut C, arg0: &XmmMem) -> Option // Generated as internal constructor for term pabsd. pub fn constructor_pabsd(ctx: &mut C, arg0: &XmmMem) -> Option { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 2194. + // Rule at src/isa/x64/inst.isle line 2195. let expr0_0 = SseOpcode::Pabsd; let expr1_0 = constructor_xmm_unary_rm_r(ctx, &expr0_0, pattern0_0)?; return Some(expr1_0); @@ -3442,7 +3443,7 @@ pub fn constructor_xmm_unary_rm_r_evex( ) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 2199. + // Rule at src/isa/x64/inst.isle line 2200. let expr0_0 = C::temp_writable_xmm(ctx); let expr1_0 = MInst::XmmUnaryRmREvex { op: pattern0_0.clone(), @@ -3457,7 +3458,7 @@ pub fn constructor_xmm_unary_rm_r_evex( // Generated as internal constructor for term vpabsq. pub fn constructor_vpabsq(ctx: &mut C, arg0: &XmmMem) -> Option { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 2206. + // Rule at src/isa/x64/inst.isle line 2207. let expr0_0 = Avx512Opcode::Vpabsq; let expr1_0 = constructor_xmm_unary_rm_r_evex(ctx, &expr0_0, pattern0_0)?; return Some(expr1_0); @@ -3466,7 +3467,7 @@ pub fn constructor_vpabsq(ctx: &mut C, arg0: &XmmMem) -> Option // Generated as internal constructor for term vpopcntb. pub fn constructor_vpopcntb(ctx: &mut C, arg0: &XmmMem) -> Option { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 2211. + // Rule at src/isa/x64/inst.isle line 2212. let expr0_0 = Avx512Opcode::Vpopcntb; let expr1_0 = constructor_xmm_unary_rm_r_evex(ctx, &expr0_0, pattern0_0)?; return Some(expr1_0); @@ -3482,7 +3483,7 @@ pub fn constructor_xmm_rm_r_evex( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 2216. + // Rule at src/isa/x64/inst.isle line 2217. let expr0_0 = C::temp_writable_xmm(ctx); let expr1_0 = MInst::XmmRmREvex { op: pattern0_0.clone(), @@ -3499,7 +3500,7 @@ pub fn constructor_xmm_rm_r_evex( pub fn constructor_vpmullq(ctx: &mut C, arg0: &XmmMem, arg1: Xmm) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 2228. + // Rule at src/isa/x64/inst.isle line 2229. let expr0_0 = Avx512Opcode::Vpmullq; let expr1_0 = constructor_xmm_rm_r_evex(ctx, &expr0_0, pattern0_0, pattern1_0)?; return Some(expr1_0); @@ -3517,7 +3518,7 @@ pub fn constructor_mul_hi( let pattern1_0 = arg1; let pattern2_0 = arg2; let pattern3_0 = arg3; - // Rule at src/isa/x64/inst.isle line 2237. + // Rule at src/isa/x64/inst.isle line 2238. let expr0_0 = C::temp_writable_gpr(ctx); let expr1_0 = C::temp_writable_gpr(ctx); let expr2_0 = C::operand_size_of_type_32_64(ctx, pattern0_0); @@ -3546,7 +3547,7 @@ pub fn constructor_mulhi_u( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 2252. + // Rule at src/isa/x64/inst.isle line 2253. let expr0_0: bool = false; let expr1_0 = constructor_mul_hi(ctx, pattern0_0, expr0_0, pattern1_0, pattern2_0)?; return Some(expr1_0); @@ -3562,7 +3563,7 @@ pub fn constructor_xmm_rmi_xmm( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 2257. + // Rule at src/isa/x64/inst.isle line 2258. let expr0_0 = C::temp_writable_xmm(ctx); let expr1_0 = MInst::XmmRmiReg { opcode: pattern0_0.clone(), @@ -3579,7 +3580,7 @@ pub fn constructor_xmm_rmi_xmm( pub fn constructor_psllw(ctx: &mut C, arg0: Xmm, arg1: &XmmMemImm) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 2267. + // Rule at src/isa/x64/inst.isle line 2268. let expr0_0 = SseOpcode::Psllw; let expr1_0 = constructor_xmm_rmi_xmm(ctx, &expr0_0, pattern0_0, pattern1_0)?; return Some(expr1_0); @@ -3589,7 +3590,7 @@ pub fn constructor_psllw(ctx: &mut C, arg0: Xmm, arg1: &XmmMemImm) - pub fn constructor_pslld(ctx: &mut C, arg0: Xmm, arg1: &XmmMemImm) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 2272. + // Rule at src/isa/x64/inst.isle line 2273. let expr0_0 = SseOpcode::Pslld; let expr1_0 = constructor_xmm_rmi_xmm(ctx, &expr0_0, pattern0_0, pattern1_0)?; return Some(expr1_0); @@ -3599,7 +3600,7 @@ pub fn constructor_pslld(ctx: &mut C, arg0: Xmm, arg1: &XmmMemImm) - pub fn constructor_psllq(ctx: &mut C, arg0: Xmm, arg1: &XmmMemImm) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 2277. + // Rule at src/isa/x64/inst.isle line 2278. let expr0_0 = SseOpcode::Psllq; let expr1_0 = constructor_xmm_rmi_xmm(ctx, &expr0_0, pattern0_0, pattern1_0)?; return Some(expr1_0); @@ -3609,7 +3610,7 @@ pub fn constructor_psllq(ctx: &mut C, arg0: Xmm, arg1: &XmmMemImm) - pub fn constructor_psrlw(ctx: &mut C, arg0: Xmm, arg1: &XmmMemImm) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 2282. + // Rule at src/isa/x64/inst.isle line 2283. let expr0_0 = SseOpcode::Psrlw; let expr1_0 = constructor_xmm_rmi_xmm(ctx, &expr0_0, pattern0_0, pattern1_0)?; return Some(expr1_0); @@ -3619,7 +3620,7 @@ pub fn constructor_psrlw(ctx: &mut C, arg0: Xmm, arg1: &XmmMemImm) - pub fn constructor_psrld(ctx: &mut C, arg0: Xmm, arg1: &XmmMemImm) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 2287. + // Rule at src/isa/x64/inst.isle line 2288. let expr0_0 = SseOpcode::Psrld; let expr1_0 = constructor_xmm_rmi_xmm(ctx, &expr0_0, pattern0_0, pattern1_0)?; return Some(expr1_0); @@ -3629,7 +3630,7 @@ pub fn constructor_psrld(ctx: &mut C, arg0: Xmm, arg1: &XmmMemImm) - pub fn constructor_psrlq(ctx: &mut C, arg0: Xmm, arg1: &XmmMemImm) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 2292. + // Rule at src/isa/x64/inst.isle line 2293. let expr0_0 = SseOpcode::Psrlq; let expr1_0 = constructor_xmm_rmi_xmm(ctx, &expr0_0, pattern0_0, pattern1_0)?; return Some(expr1_0); @@ -3639,7 +3640,7 @@ pub fn constructor_psrlq(ctx: &mut C, arg0: Xmm, arg1: &XmmMemImm) - pub fn constructor_psraw(ctx: &mut C, arg0: Xmm, arg1: &XmmMemImm) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 2297. + // Rule at src/isa/x64/inst.isle line 2298. let expr0_0 = SseOpcode::Psraw; let expr1_0 = constructor_xmm_rmi_xmm(ctx, &expr0_0, pattern0_0, pattern1_0)?; return Some(expr1_0); @@ -3649,7 +3650,7 @@ pub fn constructor_psraw(ctx: &mut C, arg0: Xmm, arg1: &XmmMemImm) - pub fn constructor_psrad(ctx: &mut C, arg0: Xmm, arg1: &XmmMemImm) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 2302. + // Rule at src/isa/x64/inst.isle line 2303. let expr0_0 = SseOpcode::Psrad; let expr1_0 = constructor_xmm_rmi_xmm(ctx, &expr0_0, pattern0_0, pattern1_0)?; return Some(expr1_0); @@ -3660,7 +3661,7 @@ pub fn constructor_pextrd(ctx: &mut C, arg0: Type, arg1: Xmm, arg2: let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 2307. + // Rule at src/isa/x64/inst.isle line 2308. let expr0_0 = C::temp_writable_gpr(ctx); let expr1_0 = SseOpcode::Pextrd; let expr2_0 = constructor_writable_gpr_to_r_reg(ctx, expr0_0)?; @@ -3693,7 +3694,7 @@ pub fn constructor_cmppd( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 2323. + // Rule at src/isa/x64/inst.isle line 2324. let expr0_0 = SseOpcode::Cmppd; let expr1_0 = C::xmm_to_reg(ctx, pattern0_0); let expr2_0 = C::xmm_mem_to_reg_mem(ctx, pattern1_0); @@ -3713,7 +3714,7 @@ pub fn constructor_gpr_to_xmm( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 2332. + // Rule at src/isa/x64/inst.isle line 2333. let expr0_0 = C::temp_writable_xmm(ctx); let expr1_0 = MInst::GprToXmm { op: pattern0_0.clone(), @@ -3730,7 +3731,7 @@ pub fn constructor_gpr_to_xmm( pub fn constructor_not(ctx: &mut C, arg0: Type, arg1: Gpr) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 2339. + // Rule at src/isa/x64/inst.isle line 2340. let expr0_0 = C::temp_writable_gpr(ctx); let expr1_0 = C::operand_size_of_type_32_64(ctx, pattern0_0); let expr2_0 = MInst::Not { @@ -3747,7 +3748,7 @@ pub fn constructor_not(ctx: &mut C, arg0: Type, arg1: Gpr) -> Option pub fn constructor_neg(ctx: &mut C, arg0: Type, arg1: Gpr) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 2347. + // Rule at src/isa/x64/inst.isle line 2348. let expr0_0 = C::temp_writable_gpr(ctx); let expr1_0 = C::operand_size_of_type_32_64(ctx, pattern0_0); let expr2_0 = MInst::Neg { @@ -3763,7 +3764,7 @@ pub fn constructor_neg(ctx: &mut C, arg0: Type, arg1: Gpr) -> Option // Generated as internal constructor for term lea. pub fn constructor_lea(ctx: &mut C, arg0: &SyntheticAmode) -> Option { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 2354. + // Rule at src/isa/x64/inst.isle line 2355. let expr0_0 = C::temp_writable_gpr(ctx); let expr1_0 = MInst::LoadEffectiveAddress { addr: pattern0_0.clone(), @@ -3777,7 +3778,7 @@ pub fn constructor_lea(ctx: &mut C, arg0: &SyntheticAmode) -> Option // Generated as internal constructor for term ud2. pub fn constructor_ud2(ctx: &mut C, arg0: &TrapCode) -> Option { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 2361. + // Rule at src/isa/x64/inst.isle line 2362. let expr0_0 = MInst::Ud2 { trap_code: pattern0_0.clone(), }; @@ -3787,7 +3788,7 @@ pub fn constructor_ud2(ctx: &mut C, arg0: &TrapCode) -> Option(ctx: &mut C) -> Option { - // Rule at src/isa/x64/inst.isle line 2366. + // Rule at src/isa/x64/inst.isle line 2367. let expr0_0 = MInst::Hlt; let expr1_0 = SideEffectNoResult::Inst { inst: expr0_0 }; return Some(expr1_0); @@ -3797,7 +3798,7 @@ pub fn constructor_hlt(ctx: &mut C) -> Option { pub fn constructor_lzcnt(ctx: &mut C, arg0: Type, arg1: Gpr) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 2371. + // Rule at src/isa/x64/inst.isle line 2372. let expr0_0 = C::temp_writable_gpr(ctx); let expr1_0 = C::operand_size_of_type_32_64(ctx, pattern0_0); let expr2_0 = UnaryRmROpcode::Lzcnt; @@ -3817,7 +3818,7 @@ pub fn constructor_lzcnt(ctx: &mut C, arg0: Type, arg1: Gpr) -> Opti pub fn constructor_tzcnt(ctx: &mut C, arg0: Type, arg1: Gpr) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 2379. + // Rule at src/isa/x64/inst.isle line 2380. let expr0_0 = C::temp_writable_gpr(ctx); let expr1_0 = C::operand_size_of_type_32_64(ctx, pattern0_0); let expr2_0 = UnaryRmROpcode::Tzcnt; @@ -3837,7 +3838,7 @@ pub fn constructor_tzcnt(ctx: &mut C, arg0: Type, arg1: Gpr) -> Opti pub fn constructor_bsr(ctx: &mut C, arg0: Type, arg1: Gpr) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 2387. + // Rule at src/isa/x64/inst.isle line 2388. let expr0_0 = C::temp_writable_gpr(ctx); let expr1_0 = C::operand_size_of_type_32_64(ctx, pattern0_0); let expr2_0 = UnaryRmROpcode::Bsr; @@ -3866,7 +3867,7 @@ pub fn constructor_bsr_or_else( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 2396. + // Rule at src/isa/x64/inst.isle line 2397. let expr0_0 = constructor_bsr(ctx, pattern0_0, pattern1_0)?; let expr1_0 = constructor_produces_flags_get_reg(ctx, &expr0_0)?; let expr2_0 = C::gpr_new(ctx, expr1_0); @@ -3883,7 +3884,7 @@ pub fn constructor_bsr_or_else( pub fn constructor_bsf(ctx: &mut C, arg0: Type, arg1: Gpr) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 2407. + // Rule at src/isa/x64/inst.isle line 2408. let expr0_0 = C::temp_writable_gpr(ctx); let expr1_0 = C::operand_size_of_type_32_64(ctx, pattern0_0); let expr2_0 = UnaryRmROpcode::Bsf; @@ -3912,7 +3913,7 @@ pub fn constructor_bsf_or_else( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 2416. + // Rule at src/isa/x64/inst.isle line 2417. let expr0_0 = constructor_bsf(ctx, pattern0_0, pattern1_0)?; let expr1_0 = constructor_produces_flags_get_reg(ctx, &expr0_0)?; let expr2_0 = C::gpr_new(ctx, expr1_0); @@ -3929,7 +3930,7 @@ pub fn constructor_bsf_or_else( pub fn constructor_x64_popcnt(ctx: &mut C, arg0: Type, arg1: Gpr) -> Option { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 2427. + // Rule at src/isa/x64/inst.isle line 2428. let expr0_0 = C::temp_writable_gpr(ctx); let expr1_0 = C::operand_size_of_type_32_64(ctx, pattern0_0); let expr2_0 = UnaryRmROpcode::Popcnt; @@ -3945,10 +3946,189 @@ pub fn constructor_x64_popcnt(ctx: &mut C, arg0: Type, arg1: Gpr) -> return Some(expr6_0); } +// Generated as internal constructor for term xmm_min_max_seq. +pub fn constructor_xmm_min_max_seq( + ctx: &mut C, + arg0: Type, + arg1: bool, + arg2: Xmm, + arg3: Xmm, +) -> Option { + let pattern0_0 = arg0; + let pattern1_0 = arg1; + let pattern2_0 = arg2; + let pattern3_0 = arg3; + // Rule at src/isa/x64/inst.isle line 2436. + let expr0_0 = C::temp_writable_xmm(ctx); + let expr1_0 = C::operand_size_of_type_32_64(ctx, pattern0_0); + let expr2_0 = MInst::XmmMinMaxSeq { + size: expr1_0, + is_min: pattern1_0, + lhs: pattern2_0, + rhs: pattern3_0, + dst: expr0_0, + }; + let expr3_0 = C::emit(ctx, &expr2_0); + let expr4_0 = C::writable_xmm_to_xmm(ctx, expr0_0); + return Some(expr4_0); +} + +// Generated as internal constructor for term minss. +pub fn constructor_minss(ctx: &mut C, arg0: Xmm, arg1: Xmm) -> Option { + let pattern0_0 = arg0; + let pattern1_0 = arg1; + // Rule at src/isa/x64/inst.isle line 2444. + let expr0_0 = C::temp_writable_xmm(ctx); + let expr1_0 = SseOpcode::Minss; + let expr2_0 = C::xmm_to_xmm_mem(ctx, pattern1_0); + let expr3_0 = MInst::XmmRmR { + op: expr1_0, + src1: pattern0_0, + src2: expr2_0, + dst: expr0_0, + }; + let expr4_0 = C::emit(ctx, &expr3_0); + let expr5_0 = C::writable_xmm_to_xmm(ctx, expr0_0); + return Some(expr5_0); +} + +// Generated as internal constructor for term minsd. +pub fn constructor_minsd(ctx: &mut C, arg0: Xmm, arg1: Xmm) -> Option { + let pattern0_0 = arg0; + let pattern1_0 = arg1; + // Rule at src/isa/x64/inst.isle line 2451. + let expr0_0 = C::temp_writable_xmm(ctx); + let expr1_0 = SseOpcode::Minsd; + let expr2_0 = C::xmm_to_xmm_mem(ctx, pattern1_0); + let expr3_0 = MInst::XmmRmR { + op: expr1_0, + src1: pattern0_0, + src2: expr2_0, + dst: expr0_0, + }; + let expr4_0 = C::emit(ctx, &expr3_0); + let expr5_0 = C::writable_xmm_to_xmm(ctx, expr0_0); + return Some(expr5_0); +} + +// Generated as internal constructor for term minps. +pub fn constructor_minps(ctx: &mut C, arg0: Xmm, arg1: Xmm) -> Option { + let pattern0_0 = arg0; + let pattern1_0 = arg1; + // Rule at src/isa/x64/inst.isle line 2459. + let expr0_0 = C::temp_writable_xmm(ctx); + let expr1_0 = SseOpcode::Minps; + let expr2_0 = C::xmm_to_xmm_mem(ctx, pattern1_0); + let expr3_0 = MInst::XmmRmR { + op: expr1_0, + src1: pattern0_0, + src2: expr2_0, + dst: expr0_0, + }; + let expr4_0 = C::emit(ctx, &expr3_0); + let expr5_0 = C::writable_xmm_to_xmm(ctx, expr0_0); + return Some(expr5_0); +} + +// Generated as internal constructor for term minpd. +pub fn constructor_minpd(ctx: &mut C, arg0: Xmm, arg1: Xmm) -> Option { + let pattern0_0 = arg0; + let pattern1_0 = arg1; + // Rule at src/isa/x64/inst.isle line 2466. + let expr0_0 = C::temp_writable_xmm(ctx); + let expr1_0 = SseOpcode::Minpd; + let expr2_0 = C::xmm_to_xmm_mem(ctx, pattern1_0); + let expr3_0 = MInst::XmmRmR { + op: expr1_0, + src1: pattern0_0, + src2: expr2_0, + dst: expr0_0, + }; + let expr4_0 = C::emit(ctx, &expr3_0); + let expr5_0 = C::writable_xmm_to_xmm(ctx, expr0_0); + return Some(expr5_0); +} + +// Generated as internal constructor for term maxss. +pub fn constructor_maxss(ctx: &mut C, arg0: Xmm, arg1: Xmm) -> Option { + let pattern0_0 = arg0; + let pattern1_0 = arg1; + // Rule at src/isa/x64/inst.isle line 2473. + let expr0_0 = C::temp_writable_xmm(ctx); + let expr1_0 = SseOpcode::Maxss; + let expr2_0 = C::xmm_to_xmm_mem(ctx, pattern1_0); + let expr3_0 = MInst::XmmRmR { + op: expr1_0, + src1: pattern0_0, + src2: expr2_0, + dst: expr0_0, + }; + let expr4_0 = C::emit(ctx, &expr3_0); + let expr5_0 = C::writable_xmm_to_xmm(ctx, expr0_0); + return Some(expr5_0); +} + +// Generated as internal constructor for term maxsd. +pub fn constructor_maxsd(ctx: &mut C, arg0: Xmm, arg1: Xmm) -> Option { + let pattern0_0 = arg0; + let pattern1_0 = arg1; + // Rule at src/isa/x64/inst.isle line 2480. + let expr0_0 = C::temp_writable_xmm(ctx); + let expr1_0 = SseOpcode::Maxsd; + let expr2_0 = C::xmm_to_xmm_mem(ctx, pattern1_0); + let expr3_0 = MInst::XmmRmR { + op: expr1_0, + src1: pattern0_0, + src2: expr2_0, + dst: expr0_0, + }; + let expr4_0 = C::emit(ctx, &expr3_0); + let expr5_0 = C::writable_xmm_to_xmm(ctx, expr0_0); + return Some(expr5_0); +} + +// Generated as internal constructor for term maxps. +pub fn constructor_maxps(ctx: &mut C, arg0: Xmm, arg1: Xmm) -> Option { + let pattern0_0 = arg0; + let pattern1_0 = arg1; + // Rule at src/isa/x64/inst.isle line 2487. + let expr0_0 = C::temp_writable_xmm(ctx); + let expr1_0 = SseOpcode::Maxps; + let expr2_0 = C::xmm_to_xmm_mem(ctx, pattern1_0); + let expr3_0 = MInst::XmmRmR { + op: expr1_0, + src1: pattern0_0, + src2: expr2_0, + dst: expr0_0, + }; + let expr4_0 = C::emit(ctx, &expr3_0); + let expr5_0 = C::writable_xmm_to_xmm(ctx, expr0_0); + return Some(expr5_0); +} + +// Generated as internal constructor for term maxpd. +pub fn constructor_maxpd(ctx: &mut C, arg0: Xmm, arg1: Xmm) -> Option { + let pattern0_0 = arg0; + let pattern1_0 = arg1; + // Rule at src/isa/x64/inst.isle line 2494. + let expr0_0 = C::temp_writable_xmm(ctx); + let expr1_0 = SseOpcode::Maxpd; + let expr2_0 = C::xmm_to_xmm_mem(ctx, pattern1_0); + let expr3_0 = MInst::XmmRmR { + op: expr1_0, + src1: pattern0_0, + src2: expr2_0, + dst: expr0_0, + }; + let expr4_0 = C::emit(ctx, &expr3_0); + let expr5_0 = C::writable_xmm_to_xmm(ctx, expr0_0); + return Some(expr5_0); +} + // Generated as internal constructor for term reg_to_xmm_mem. pub fn constructor_reg_to_xmm_mem(ctx: &mut C, arg0: Reg) -> Option { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 2483. + // Rule at src/isa/x64/inst.isle line 2549. let expr0_0 = C::xmm_new(ctx, pattern0_0); let expr1_0 = C::xmm_to_xmm_mem(ctx, expr0_0); return Some(expr1_0); @@ -3957,7 +4137,7 @@ pub fn constructor_reg_to_xmm_mem(ctx: &mut C, arg0: Reg) -> Option< // Generated as internal constructor for term xmm_to_reg_mem. pub fn constructor_xmm_to_reg_mem(ctx: &mut C, arg0: Reg) -> Option { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 2486. + // Rule at src/isa/x64/inst.isle line 2552. let expr0_0 = C::xmm_new(ctx, pattern0_0); let expr1_0 = C::xmm_to_reg(ctx, expr0_0); let expr2_0 = RegMem::Reg { reg: expr1_0 }; @@ -3971,7 +4151,7 @@ pub fn constructor_writable_gpr_to_r_reg( arg0: WritableGpr, ) -> Option { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 2490. + // Rule at src/isa/x64/inst.isle line 2556. let expr0_0 = C::writable_gpr_to_reg(ctx, pattern0_0); let expr1_0 = C::writable_reg_to_reg(ctx, expr0_0); return Some(expr1_0); @@ -3983,7 +4163,7 @@ pub fn constructor_writable_gpr_to_gpr_mem( arg0: WritableGpr, ) -> Option { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 2493. + // Rule at src/isa/x64/inst.isle line 2559. let expr0_0 = C::writable_gpr_to_gpr(ctx, pattern0_0); let expr1_0 = C::gpr_to_gpr_mem(ctx, expr0_0); return Some(expr1_0); @@ -3995,7 +4175,7 @@ pub fn constructor_writable_gpr_to_value_regs( arg0: WritableGpr, ) -> Option { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 2496. + // Rule at src/isa/x64/inst.isle line 2562. let expr0_0 = constructor_writable_gpr_to_r_reg(ctx, pattern0_0)?; let expr1_0 = C::value_reg(ctx, expr0_0); return Some(expr1_0); @@ -4007,7 +4187,7 @@ pub fn constructor_writable_xmm_to_r_reg( arg0: WritableXmm, ) -> Option { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 2499. + // Rule at src/isa/x64/inst.isle line 2565. let expr0_0 = C::writable_xmm_to_reg(ctx, pattern0_0); let expr1_0 = C::writable_reg_to_reg(ctx, expr0_0); return Some(expr1_0); @@ -4019,7 +4199,7 @@ pub fn constructor_writable_xmm_to_xmm_mem( arg0: WritableXmm, ) -> Option { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 2502. + // Rule at src/isa/x64/inst.isle line 2568. let expr0_0 = C::writable_xmm_to_xmm(ctx, pattern0_0); let expr1_0 = C::xmm_to_xmm_mem(ctx, expr0_0); return Some(expr1_0); @@ -4031,7 +4211,7 @@ pub fn constructor_writable_xmm_to_value_regs( arg0: WritableXmm, ) -> Option { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 2505. + // Rule at src/isa/x64/inst.isle line 2571. let expr0_0 = constructor_writable_xmm_to_r_reg(ctx, pattern0_0)?; let expr1_0 = C::value_reg(ctx, expr0_0); return Some(expr1_0); @@ -4043,7 +4223,7 @@ pub fn constructor_synthetic_amode_to_gpr_mem( arg0: &SyntheticAmode, ) -> Option { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 2509. + // Rule at src/isa/x64/inst.isle line 2575. let expr0_0 = C::synthetic_amode_to_reg_mem(ctx, pattern0_0); let expr1_0 = C::reg_mem_to_gpr_mem(ctx, &expr0_0); return Some(expr1_0); @@ -4055,7 +4235,7 @@ pub fn constructor_synthetic_amode_to_xmm_mem( arg0: &SyntheticAmode, ) -> Option { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 2512. + // Rule at src/isa/x64/inst.isle line 2578. let expr0_0 = C::synthetic_amode_to_reg_mem(ctx, pattern0_0); let expr1_0 = C::reg_mem_to_xmm_mem(ctx, &expr0_0); return Some(expr1_0); @@ -5080,6 +5260,48 @@ pub fn constructor_lower(ctx: &mut C, arg0: Inst) -> Option { + let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, pattern5_1); + // Rule at src/isa/x64/lower.isle line 2065. + let expr0_0: Type = F32; + let expr1_0: bool = true; + let expr2_0 = constructor_put_in_xmm(ctx, pattern7_0)?; + let expr3_0 = constructor_put_in_xmm(ctx, pattern7_1)?; + let expr4_0 = + constructor_xmm_min_max_seq(ctx, expr0_0, expr1_0, expr2_0, expr3_0)?; + let expr5_0 = constructor_output_xmm(ctx, expr4_0)?; + return Some(expr5_0); + } + &Opcode::FminPseudo => { + let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, pattern5_1); + // Rule at src/isa/x64/lower.isle line 2234. + let expr0_0 = constructor_put_in_xmm(ctx, pattern7_1)?; + let expr1_0 = constructor_put_in_xmm(ctx, pattern7_0)?; + let expr2_0 = constructor_minss(ctx, expr0_0, expr1_0)?; + let expr3_0 = constructor_output_xmm(ctx, expr2_0)?; + return Some(expr3_0); + } + &Opcode::Fmax => { + let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, pattern5_1); + // Rule at src/isa/x64/lower.isle line 2137. + let expr0_0: Type = F32; + let expr1_0: bool = false; + let expr2_0 = constructor_put_in_xmm(ctx, pattern7_0)?; + let expr3_0 = constructor_put_in_xmm(ctx, pattern7_1)?; + let expr4_0 = + constructor_xmm_min_max_seq(ctx, expr0_0, expr1_0, expr2_0, expr3_0)?; + let expr5_0 = constructor_output_xmm(ctx, expr4_0)?; + return Some(expr5_0); + } + &Opcode::FmaxPseudo => { + let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, pattern5_1); + // Rule at src/isa/x64/lower.isle line 2245. + let expr0_0 = constructor_put_in_xmm(ctx, pattern7_1)?; + let expr1_0 = constructor_put_in_xmm(ctx, pattern7_0)?; + let expr2_0 = constructor_maxss(ctx, expr0_0, expr1_0)?; + let expr3_0 = constructor_output_xmm(ctx, expr2_0)?; + return Some(expr3_0); + } _ => {} } } @@ -5128,6 +5350,48 @@ pub fn constructor_lower(ctx: &mut C, arg0: Inst) -> Option { + let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, pattern5_1); + // Rule at src/isa/x64/lower.isle line 2067. + let expr0_0: Type = F64; + let expr1_0: bool = true; + let expr2_0 = constructor_put_in_xmm(ctx, pattern7_0)?; + let expr3_0 = constructor_put_in_xmm(ctx, pattern7_1)?; + let expr4_0 = + constructor_xmm_min_max_seq(ctx, expr0_0, expr1_0, expr2_0, expr3_0)?; + let expr5_0 = constructor_output_xmm(ctx, expr4_0)?; + return Some(expr5_0); + } + &Opcode::FminPseudo => { + let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, pattern5_1); + // Rule at src/isa/x64/lower.isle line 2236. + let expr0_0 = constructor_put_in_xmm(ctx, pattern7_1)?; + let expr1_0 = constructor_put_in_xmm(ctx, pattern7_0)?; + let expr2_0 = constructor_minsd(ctx, expr0_0, expr1_0)?; + let expr3_0 = constructor_output_xmm(ctx, expr2_0)?; + return Some(expr3_0); + } + &Opcode::Fmax => { + let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, pattern5_1); + // Rule at src/isa/x64/lower.isle line 2139. + let expr0_0: Type = F64; + let expr1_0: bool = false; + let expr2_0 = constructor_put_in_xmm(ctx, pattern7_0)?; + let expr3_0 = constructor_put_in_xmm(ctx, pattern7_1)?; + let expr4_0 = + constructor_xmm_min_max_seq(ctx, expr0_0, expr1_0, expr2_0, expr3_0)?; + let expr5_0 = constructor_output_xmm(ctx, expr4_0)?; + return Some(expr5_0); + } + &Opcode::FmaxPseudo => { + let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, pattern5_1); + // Rule at src/isa/x64/lower.isle line 2247. + let expr0_0 = constructor_put_in_xmm(ctx, pattern7_1)?; + let expr1_0 = constructor_put_in_xmm(ctx, pattern7_0)?; + let expr2_0 = constructor_maxsd(ctx, expr0_0, expr1_0)?; + let expr3_0 = constructor_output_xmm(ctx, expr2_0)?; + return Some(expr3_0); + } _ => {} } } @@ -5650,6 +5914,76 @@ pub fn constructor_lower(ctx: &mut C, arg0: Inst) -> Option { + let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, pattern5_1); + // Rule at src/isa/x64/lower.isle line 2082. + let expr0_0 = constructor_put_in_xmm(ctx, pattern7_0)?; + let expr1_0 = constructor_put_in_xmm(ctx, pattern7_1)?; + let expr2_0 = constructor_minps(ctx, expr0_0, expr1_0)?; + let expr3_0 = constructor_put_in_xmm(ctx, pattern7_1)?; + let expr4_0 = constructor_put_in_xmm(ctx, pattern7_0)?; + let expr5_0 = constructor_minps(ctx, expr3_0, expr4_0)?; + let expr6_0 = C::xmm_to_xmm_mem(ctx, expr5_0); + let expr7_0 = constructor_orps(ctx, expr2_0, &expr6_0)?; + let expr8_0 = C::xmm_to_xmm_mem(ctx, expr5_0); + let expr9_0 = FcmpImm::Unordered; + let expr10_0 = constructor_cmpps(ctx, expr7_0, &expr8_0, &expr9_0)?; + let expr11_0 = C::xmm_to_xmm_mem(ctx, expr10_0); + let expr12_0 = constructor_orps(ctx, expr7_0, &expr11_0)?; + let expr13_0: u32 = 10; + let expr14_0 = RegMemImm::Imm { simm32: expr13_0 }; + let expr15_0 = constructor_mov_rmi_to_xmm(ctx, &expr14_0)?; + let expr16_0 = constructor_psrld(ctx, expr10_0, &expr15_0)?; + let expr17_0 = C::xmm_to_xmm_mem(ctx, expr12_0); + let expr18_0 = constructor_andnps(ctx, expr16_0, &expr17_0)?; + let expr19_0 = constructor_output_xmm(ctx, expr18_0)?; + return Some(expr19_0); + } + &Opcode::FminPseudo => { + let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, pattern5_1); + // Rule at src/isa/x64/lower.isle line 2238. + let expr0_0 = constructor_put_in_xmm(ctx, pattern7_1)?; + let expr1_0 = constructor_put_in_xmm(ctx, pattern7_0)?; + let expr2_0 = constructor_minps(ctx, expr0_0, expr1_0)?; + let expr3_0 = constructor_output_xmm(ctx, expr2_0)?; + return Some(expr3_0); + } + &Opcode::Fmax => { + let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, pattern5_1); + // Rule at src/isa/x64/lower.isle line 2145. + let expr0_0 = constructor_put_in_xmm(ctx, pattern7_0)?; + let expr1_0 = constructor_put_in_xmm(ctx, pattern7_1)?; + let expr2_0 = constructor_maxps(ctx, expr0_0, expr1_0)?; + let expr3_0 = constructor_put_in_xmm(ctx, pattern7_1)?; + let expr4_0 = constructor_put_in_xmm(ctx, pattern7_0)?; + let expr5_0 = constructor_maxps(ctx, expr3_0, expr4_0)?; + let expr6_0 = C::xmm_to_xmm_mem(ctx, expr5_0); + let expr7_0 = constructor_xorps(ctx, expr2_0, &expr6_0)?; + let expr8_0 = C::xmm_to_xmm_mem(ctx, expr7_0); + let expr9_0 = constructor_orps(ctx, expr2_0, &expr8_0)?; + let expr10_0 = C::xmm_to_xmm_mem(ctx, expr7_0); + let expr11_0 = constructor_subps(ctx, expr9_0, &expr10_0)?; + let expr12_0 = C::xmm_to_xmm_mem(ctx, expr9_0); + let expr13_0 = FcmpImm::Unordered; + let expr14_0 = constructor_cmpps(ctx, expr9_0, &expr12_0, &expr13_0)?; + let expr15_0: u32 = 10; + let expr16_0 = RegMemImm::Imm { simm32: expr15_0 }; + let expr17_0 = constructor_mov_rmi_to_xmm(ctx, &expr16_0)?; + let expr18_0 = constructor_psrld(ctx, expr14_0, &expr17_0)?; + let expr19_0 = C::xmm_to_xmm_mem(ctx, expr11_0); + let expr20_0 = constructor_andnps(ctx, expr18_0, &expr19_0)?; + let expr21_0 = constructor_output_xmm(ctx, expr20_0)?; + return Some(expr21_0); + } + &Opcode::FmaxPseudo => { + let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, pattern5_1); + // Rule at src/isa/x64/lower.isle line 2249. + let expr0_0 = constructor_put_in_xmm(ctx, pattern7_1)?; + let expr1_0 = constructor_put_in_xmm(ctx, pattern7_0)?; + let expr2_0 = constructor_maxps(ctx, expr0_0, expr1_0)?; + let expr3_0 = constructor_output_xmm(ctx, expr2_0)?; + return Some(expr3_0); + } _ => {} } } @@ -5719,6 +6053,76 @@ pub fn constructor_lower(ctx: &mut C, arg0: Inst) -> Option { + let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, pattern5_1); + // Rule at src/isa/x64/lower.isle line 2125. + let expr0_0 = constructor_put_in_xmm(ctx, pattern7_0)?; + let expr1_0 = constructor_put_in_xmm(ctx, pattern7_1)?; + let expr2_0 = constructor_minpd(ctx, expr0_0, expr1_0)?; + let expr3_0 = constructor_put_in_xmm(ctx, pattern7_1)?; + let expr4_0 = constructor_put_in_xmm(ctx, pattern7_0)?; + let expr5_0 = constructor_minpd(ctx, expr3_0, expr4_0)?; + let expr6_0 = C::xmm_to_xmm_mem(ctx, expr5_0); + let expr7_0 = constructor_orpd(ctx, expr2_0, &expr6_0)?; + let expr8_0 = C::xmm_to_xmm_mem(ctx, expr5_0); + let expr9_0 = FcmpImm::Unordered; + let expr10_0 = constructor_cmppd(ctx, expr2_0, &expr8_0, &expr9_0)?; + let expr11_0 = C::xmm_to_xmm_mem(ctx, expr10_0); + let expr12_0 = constructor_orpd(ctx, expr7_0, &expr11_0)?; + let expr13_0: u32 = 13; + let expr14_0 = RegMemImm::Imm { simm32: expr13_0 }; + let expr15_0 = constructor_mov_rmi_to_xmm(ctx, &expr14_0)?; + let expr16_0 = constructor_psrlq(ctx, expr10_0, &expr15_0)?; + let expr17_0 = C::xmm_to_xmm_mem(ctx, expr12_0); + let expr18_0 = constructor_andnpd(ctx, expr16_0, &expr17_0)?; + let expr19_0 = constructor_output_xmm(ctx, expr18_0)?; + return Some(expr19_0); + } + &Opcode::FminPseudo => { + let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, pattern5_1); + // Rule at src/isa/x64/lower.isle line 2240. + let expr0_0 = constructor_put_in_xmm(ctx, pattern7_1)?; + let expr1_0 = constructor_put_in_xmm(ctx, pattern7_0)?; + let expr2_0 = constructor_minpd(ctx, expr0_0, expr1_0)?; + let expr3_0 = constructor_output_xmm(ctx, expr2_0)?; + return Some(expr3_0); + } + &Opcode::Fmax => { + let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, pattern5_1); + // Rule at src/isa/x64/lower.isle line 2188. + let expr0_0 = constructor_put_in_xmm(ctx, pattern7_0)?; + let expr1_0 = constructor_put_in_xmm(ctx, pattern7_1)?; + let expr2_0 = constructor_maxpd(ctx, expr0_0, expr1_0)?; + let expr3_0 = constructor_put_in_xmm(ctx, pattern7_1)?; + let expr4_0 = constructor_put_in_xmm(ctx, pattern7_0)?; + let expr5_0 = constructor_maxpd(ctx, expr3_0, expr4_0)?; + let expr6_0 = C::xmm_to_xmm_mem(ctx, expr5_0); + let expr7_0 = constructor_xorpd(ctx, expr2_0, &expr6_0)?; + let expr8_0 = C::xmm_to_xmm_mem(ctx, expr7_0); + let expr9_0 = constructor_orpd(ctx, expr2_0, &expr8_0)?; + let expr10_0 = C::xmm_to_xmm_mem(ctx, expr7_0); + let expr11_0 = constructor_subpd(ctx, expr9_0, &expr10_0)?; + let expr12_0 = C::xmm_to_xmm_mem(ctx, expr9_0); + let expr13_0 = FcmpImm::Unordered; + let expr14_0 = constructor_cmppd(ctx, expr9_0, &expr12_0, &expr13_0)?; + let expr15_0: u32 = 13; + let expr16_0 = RegMemImm::Imm { simm32: expr15_0 }; + let expr17_0 = constructor_mov_rmi_to_xmm(ctx, &expr16_0)?; + let expr18_0 = constructor_psrlq(ctx, expr14_0, &expr17_0)?; + let expr19_0 = C::xmm_to_xmm_mem(ctx, expr11_0); + let expr20_0 = constructor_andnpd(ctx, expr18_0, &expr19_0)?; + let expr21_0 = constructor_output_xmm(ctx, expr20_0)?; + return Some(expr21_0); + } + &Opcode::FmaxPseudo => { + let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, pattern5_1); + // Rule at src/isa/x64/lower.isle line 2251. + let expr0_0 = constructor_put_in_xmm(ctx, pattern7_1)?; + let expr1_0 = constructor_put_in_xmm(ctx, pattern7_0)?; + let expr2_0 = constructor_maxpd(ctx, expr0_0, expr1_0)?; + let expr3_0 = constructor_output_xmm(ctx, expr2_0)?; + return Some(expr3_0); + } _ => {} } }