diff --git a/cranelift/codegen/src/isa/aarch64/lower/isle/generated_code.manifest b/cranelift/codegen/src/isa/aarch64/lower/isle/generated_code.manifest index ec93bcbed6f7..1e38a6cc6359 100644 --- a/cranelift/codegen/src/isa/aarch64/lower/isle/generated_code.manifest +++ b/cranelift/codegen/src/isa/aarch64/lower/isle/generated_code.manifest @@ -1,4 +1,4 @@ src/clif.isle f176ef3bba99365 -src/prelude.isle d95510fad2e2473c +src/prelude.isle 7b911d3b894ae17 src/isa/aarch64/inst.isle 5fa80451697b084f src/isa/aarch64/lower.isle 2d2e1e076a0c8a23 diff --git a/cranelift/codegen/src/isa/aarch64/lower/isle/generated_code.rs b/cranelift/codegen/src/isa/aarch64/lower/isle/generated_code.rs index 347e4764cfac..ca4f68a59833 100644 --- a/cranelift/codegen/src/isa/aarch64/lower/isle/generated_code.rs +++ b/cranelift/codegen/src/isa/aarch64/lower/isle/generated_code.rs @@ -34,6 +34,7 @@ pub trait Context { fn u32_as_u64(&mut self, arg0: u32) -> u64; fn ty_bits(&mut self, arg0: Type) -> u8; fn ty_bits_u16(&mut self, arg0: Type) -> u16; + fn ty_bytes(&mut self, arg0: Type) -> u16; fn lane_type(&mut self, arg0: Type) -> Type; fn fits_in_16(&mut self, arg0: Type) -> Option<Type>; fn fits_in_32(&mut self, arg0: Type) -> Option<Type>; @@ -91,13 +92,13 @@ pub trait Context { fn rotr_opposite_amount(&mut self, arg0: Type, arg1: ImmShift) -> ImmShift; } -/// Internal type ProducesFlags: defined at src/prelude.isle line 273. +/// Internal type ProducesFlags: defined at src/prelude.isle line 277. #[derive(Clone, Debug)] pub enum ProducesFlags { ProducesFlags { inst: MInst, result: Reg }, } -/// Internal type ConsumesFlags: defined at src/prelude.isle line 276. +/// Internal type ConsumesFlags: defined at src/prelude.isle line 280. #[derive(Clone, Debug)] pub enum ConsumesFlags { ConsumesFlags { inst: MInst, result: Reg }, @@ -1011,7 +1012,7 @@ pub fn constructor_with_flags<C: Context>( result: pattern3_1, } = pattern2_0 { - // Rule at src/prelude.isle line 286. + // Rule at src/prelude.isle line 290. let expr0_0 = C::emit(ctx, &pattern1_0); let expr1_0 = C::emit(ctx, &pattern3_0); let expr2_0 = C::value_regs(ctx, pattern1_1, pattern3_1); @@ -1039,7 +1040,7 @@ pub fn constructor_with_flags_1<C: Context>( result: pattern3_1, } = pattern2_0 { - // Rule at src/prelude.isle line 294. + // Rule at src/prelude.isle line 298. let expr0_0 = C::emit(ctx, &pattern1_0); let expr1_0 = C::emit(ctx, &pattern3_0); return Some(pattern3_1); @@ -1073,7 +1074,7 @@ pub fn constructor_with_flags_2<C: Context>( result: pattern5_1, } = pattern4_0 { - // Rule at src/prelude.isle line 304. + // Rule at src/prelude.isle line 308. let expr0_0 = C::emit(ctx, &pattern1_0); let expr1_0 = C::emit(ctx, &pattern5_0); let expr2_0 = C::emit(ctx, &pattern3_0); diff --git a/cranelift/codegen/src/isa/x64/inst.isle b/cranelift/codegen/src/isa/x64/inst.isle index 9be471a7e288..d7ad48e2db1f 100644 --- a/cranelift/codegen/src/isa/x64/inst.isle +++ b/cranelift/codegen/src/isa/x64/inst.isle @@ -54,6 +54,8 @@ (MovsxRmR (ext_mode ExtMode) (src RegMem) (dst WritableReg)) + (Mov64MR (src SyntheticAmode) + (dst WritableReg)) (Cmove (size OperandSize) (cc CC) (consequent RegMem) @@ -70,6 +72,8 @@ (Not (size OperandSize) (src Reg) (dst WritableReg)) + (LoadEffectiveAddress (addr SyntheticAmode) + (dst WritableReg)) )) (type OperandSize extern @@ -318,6 +322,17 @@ (type SyntheticAmode extern (enum)) +(decl synthetic_amode_to_reg_mem (SyntheticAmode) RegMem) +(extern constructor synthetic_amode_to_reg_mem synthetic_amode_to_reg_mem) + +(type Amode extern (enum)) + +(decl amode_imm_reg_reg_shift (u32 Reg Reg u8) Amode) +(extern constructor amode_imm_reg_reg_shift amode_imm_reg_reg_shift) + +(decl amode_to_synthetic_amode (Amode) SyntheticAmode) +(extern constructor amode_to_synthetic_amode amode_to_synthetic_amode) + (type ShiftKind extern (enum ShiftLeft ShiftRightLogical @@ -438,6 +453,11 @@ ;;;; Helpers for Sign/Zero Extending ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(type ExtKind extern + (enum None + SignExtend + ZeroExtend)) + (type ExtendKind (enum Sign Zero)) (type ExtMode extern (enum BL BQ WL WQ LQ)) @@ -549,6 +569,40 @@ (RegMem.Reg r) (OperandSize.Size32)))) +;;;; Helpers for Emitting Loads ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; Load a value into a register. +(decl x64_load (Type SyntheticAmode ExtKind) Reg) + +(rule (x64_load (fits_in_32 ty) addr (ExtKind.SignExtend)) + (movsx ty + (ext_mode (ty_bytes ty) 8) + (synthetic_amode_to_reg_mem addr))) + +(rule (x64_load $I64 addr _ext_kind) + (let ((dst WritableReg (temp_writable_reg $I64)) + (_ Unit (emit (MInst.Mov64MR addr dst)))) + (writable_reg_to_reg dst))) + +(rule (x64_load $F32 addr _ext_kind) + (xmm_unary_rm_r (SseOpcode.Movss) + (synthetic_amode_to_reg_mem addr))) + +(rule (x64_load $F64 addr _ext_kind) + (xmm_unary_rm_r (SseOpcode.Movsd) + (synthetic_amode_to_reg_mem addr))) + +(rule (x64_load $F32X4 addr _ext_kind) + (xmm_unary_rm_r (SseOpcode.Movups) + (synthetic_amode_to_reg_mem addr))) + +(rule (x64_load $F64X2 addr _ext_kind) + (xmm_unary_rm_r (SseOpcode.Movupd) + (synthetic_amode_to_reg_mem addr))) + +(rule (x64_load (multi_lane _bits _lanes) addr _ext_kind) + (xmm_unary_rm_r (SseOpcode.Movdqu) + (synthetic_amode_to_reg_mem addr))) ;;;; Instruction Constructors ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; @@ -1236,6 +1290,16 @@ dst)))) (writable_reg_to_reg dst))) +;; Helper for creating `psllw` instructions. +(decl psllw (Reg RegMemImm) Reg) +(rule (psllw src1 src2) + (xmm_rmi_reg (SseOpcode.Psllw) src1 src2)) + +;; Helper for creating `pslld` instructions. +(decl pslld (Reg RegMemImm) Reg) +(rule (pslld src1 src2) + (xmm_rmi_reg (SseOpcode.Pslld) src1 src2)) + ;; Helper for creating `psllq` instructions. (decl psllq (Reg RegMemImm) Reg) (rule (psllq src1 src2) @@ -1353,3 +1417,9 @@ (size OperandSize (operand_size_of_type_32_64 ty)) (_ Unit (emit (MInst.Not size src dst)))) (writable_reg_to_reg dst))) + +(decl lea (SyntheticAmode) Reg) +(rule (lea addr) + (let ((dst WritableReg (temp_writable_reg $I64)) + (_ Unit (emit (MInst.LoadEffectiveAddress addr dst)))) + (writable_reg_to_reg dst))) diff --git a/cranelift/codegen/src/isa/x64/inst/mod.rs b/cranelift/codegen/src/isa/x64/inst/mod.rs index 7dfb5d7304e9..e8d958f7387a 100644 --- a/cranelift/codegen/src/isa/x64/inst/mod.rs +++ b/cranelift/codegen/src/isa/x64/inst/mod.rs @@ -3053,6 +3053,12 @@ impl MachInst for Inst { } fn gen_move(dst_reg: Writable<Reg>, src_reg: Reg, ty: Type) -> Inst { + log::trace!( + "Inst::gen_move {:?} -> {:?} (type: {:?})", + src_reg, + dst_reg.to_reg(), + ty + ); let rc_dst = dst_reg.to_reg().get_class(); let rc_src = src_reg.get_class(); // If this isn't true, we have gone way off the rails. diff --git a/cranelift/codegen/src/isa/x64/lower.isle b/cranelift/codegen/src/isa/x64/lower.isle index fe6c6e2bc370..2ea073684528 100644 --- a/cranelift/codegen/src/isa/x64/lower.isle +++ b/cranelift/codegen/src/isa/x64/lower.isle @@ -571,6 +571,67 @@ (let ((amt_ Reg (lo_reg amt))) (shl_i128 (put_in_regs src) amt_))) +;; SSE. + +;; Since the x86 instruction set does not have any 8x16 shift instructions (even +;; in higher feature sets like AVX), we lower the `ishl.i8x16` to a sequence of +;; instructions. The basic idea, whether the amount to shift by is an immediate +;; or not, is to use a 16x8 shift and then mask off the incorrect bits to 0s. +(rule (lower (has_type $I8X16 (ishl src amt))) + (let ((src_ Reg (put_in_reg src)) + (amt_gpr RegMemImm (put_in_reg_mem_imm amt)) + (amt_xmm RegMemImm (reg_mem_imm_to_xmm amt_gpr)) + ;; Shift `src` using 16x8. Unfortunately, a 16x8 shift will only be + ;; correct for half of the lanes; the others must be fixed up with + ;; the mask below. + (unmasked Reg (psllw src_ amt_xmm)) + (mask_addr SyntheticAmode (ishl_i8x16_mask amt_gpr)) + (mask Reg (x64_load $I8X16 mask_addr (ExtKind.None)))) + (value_reg (sse_and $I8X16 unmasked (RegMem.Reg mask))))) + +;; Get the address of the mask to use when fixing up the lanes that weren't +;; correctly generated by the 16x8 shift. +(decl ishl_i8x16_mask (RegMemImm) SyntheticAmode) + +;; When the shift amount is known, we can statically (i.e. at compile time) +;; determine the mask to use and only emit that. +(rule (ishl_i8x16_mask (RegMemImm.Imm amt)) + (ishl_i8x16_mask_for_const amt)) + +;; Otherwise, we must emit the entire mask table and dynamically (i.e. at run +;; time) find the correct mask offset in the table. We do this use `lea` to find +;; the base address of the mask table and then complex addressing to offset to +;; the right mask: `base_address + amt << 4` +(rule (ishl_i8x16_mask (RegMemImm.Reg amt)) + (let ((mask_table SyntheticAmode (ishl_i8x16_mask_table)) + (base_mask_addr Reg (lea mask_table)) + (mask_offset Reg (shl $I64 amt (Imm8Reg.Imm8 4)))) + (amode_to_synthetic_amode (amode_imm_reg_reg_shift 0 + base_mask_addr + mask_offset + 0)))) +(rule (ishl_i8x16_mask (RegMemImm.Mem amt)) + (ishl_i8x16_mask (RegMemImm.Reg (x64_load $I64 amt (ExtKind.None))))) + +;; Get the address of the mask for a constant 8x16 shift amount. +(decl ishl_i8x16_mask_for_const (u32) SyntheticAmode) +(extern constructor ishl_i8x16_mask_for_const ishl_i8x16_mask_for_const) + +;; Get the address of the mask table for a dynamic 8x16 shift amount. +(decl ishl_i8x16_mask_table () SyntheticAmode) +(extern constructor ishl_i8x16_mask_table ishl_i8x16_mask_table) + +;; 16x8, 32x4, and 64x2 shifts can each use a single instruction. +(rule (lower (has_type $I16X8 (ishl src amt))) + (value_reg (psllw (put_in_reg src) + (reg_mem_imm_to_xmm (put_in_reg_mem_imm amt))))) +(rule (lower (has_type $I32X4 (ishl src amt))) + (value_reg (pslld (put_in_reg src) + (reg_mem_imm_to_xmm (put_in_reg_mem_imm amt))))) +(rule (lower (has_type $I64X2 (ishl src amt))) + (value_reg (psllq (put_in_reg src) + (reg_mem_imm_to_xmm (put_in_reg_mem_imm amt))))) + ;;;; Rules for `ushr` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; `i64` and smaller. diff --git a/cranelift/codegen/src/isa/x64/lower.rs b/cranelift/codegen/src/isa/x64/lower.rs index 6fd6a995b912..0f150318fb64 100644 --- a/cranelift/codegen/src/isa/x64/lower.rs +++ b/cranelift/codegen/src/isa/x64/lower.rs @@ -1539,9 +1539,10 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>( | Opcode::Bnot | Opcode::Bitselect | Opcode::Vselect - | Opcode::Sshr => implemented_in_isle(ctx), + | Opcode::Sshr + | Opcode::Ishl => implemented_in_isle(ctx), - Opcode::Ishl | Opcode::Ushr | Opcode::Rotl | Opcode::Rotr => { + Opcode::Ushr | Opcode::Rotl | Opcode::Rotr => { let dst_ty = ctx.output_ty(insn, 0); debug_assert_eq!(ctx.input_ty(insn, 0), dst_ty); @@ -1557,7 +1558,6 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>( // This implementation uses the last two encoding methods. let (size, lhs) = match dst_ty { types::I8 | types::I16 => match op { - Opcode::Ishl => (OperandSize::Size32, put_input_in_reg(ctx, inputs[0])), Opcode::Ushr => ( OperandSize::Size32, extend_input_to_reg(ctx, inputs[0], ExtSpec::ZeroExtendTo32), @@ -1589,7 +1589,6 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>( let dst = get_output_reg(ctx, outputs[0]).only_reg().unwrap(); let shift_kind = match op { - Opcode::Ishl => ShiftKind::ShiftLeft, Opcode::Ushr => ShiftKind::ShiftRightLogical, Opcode::Rotl => ShiftKind::RotateLeft, Opcode::Rotr => ShiftKind::RotateRight, @@ -1608,7 +1607,7 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>( let dst = get_output_reg(ctx, outputs[0]); match op { - Opcode::Ishl | Opcode::Ushr | Opcode::Rotl => { + Opcode::Ushr | Opcode::Rotl => { implemented_in_isle(ctx); } Opcode::Rotr => { @@ -1643,7 +1642,7 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>( } _ => unreachable!(), } - } else if dst_ty == types::I8X16 && (op == Opcode::Ishl || op == Opcode::Ushr) { + } else if dst_ty == types::I8X16 && op == Opcode::Ushr { // Since the x86 instruction set does not have any 8x16 shift instructions (even in higher feature sets // like AVX), we lower the `ishl.i8x16` and `ushr.i8x16` to a sequence of instructions. The basic idea, // whether the `shift_by` amount is an immediate or not, is to use a 16x8 shift and then mask off the @@ -1671,7 +1670,6 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>( // Shift `src` using 16x8. Unfortunately, a 16x8 shift will only be correct for half of the lanes; // the others must be fixed up with the mask below. let shift_opcode = match op { - Opcode::Ishl => SseOpcode::Psllw, Opcode::Ushr => SseOpcode::Psrlw, _ => unimplemented!("{} is not implemented for type {}", op, dst_ty), }; @@ -1695,20 +1693,8 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>( 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, ]; - const SHL_MASKS: [u8; 128] = [ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, - 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, - 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xf8, 0xf8, 0xf8, 0xf8, - 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf0, - 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, - 0xf0, 0xf0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, - 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, - 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - ]; + let mask = match op { - Opcode::Ishl => &SHL_MASKS, Opcode::Ushr => &USHR_MASKS, _ => unimplemented!("{} is not implemented for type {}", op, dst_ty), }; @@ -1775,17 +1761,14 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>( let dst = get_output_reg(ctx, outputs[0]).only_reg().unwrap(); let sse_op = match dst_ty { types::I16X8 => match op { - Opcode::Ishl => SseOpcode::Psllw, Opcode::Ushr => SseOpcode::Psrlw, _ => unimplemented!("{} is not implemented for type {}", op, dst_ty), }, types::I32X4 => match op { - Opcode::Ishl => SseOpcode::Pslld, Opcode::Ushr => SseOpcode::Psrld, _ => unimplemented!("{} is not implemented for type {}", op, dst_ty), }, types::I64X2 => match op { - Opcode::Ishl => SseOpcode::Psllq, Opcode::Ushr => SseOpcode::Psrlq, _ => unimplemented!("{} is not implemented for type {}", op, dst_ty), }, diff --git a/cranelift/codegen/src/isa/x64/lower/isle.rs b/cranelift/codegen/src/isa/x64/lower/isle.rs index 18260e802086..17b64fcb72c8 100644 --- a/cranelift/codegen/src/isa/x64/lower/isle.rs +++ b/cranelift/codegen/src/isa/x64/lower/isle.rs @@ -7,19 +7,19 @@ mod generated_code; use super::{ is_mergeable_load, lower_to_amode, AluRmiROpcode, Inst as MInst, OperandSize, Reg, RegMemImm, }; -use crate::isa::x64::inst::args::SyntheticAmode; -use crate::isa::x64::inst::regs; -use crate::isa::x64::settings::Flags; -use crate::machinst::isle::*; use crate::{ ir::{immediates::*, types::*, Inst, InstructionData, Opcode, TrapCode, Value, ValueList}, - isa::x64::inst::{ - args::{ - Avx512Opcode, CmpOpcode, ExtMode, FcmpImm, Imm8Reg, RegMem, ShiftKind, SseOpcode, CC, + isa::x64::{ + inst::{ + args::{ + Amode, Avx512Opcode, CmpOpcode, ExtKind, ExtMode, FcmpImm, Imm8Reg, RegMem, + ShiftKind, SseOpcode, SyntheticAmode, CC, + }, + regs, x64_map_regs, }, - x64_map_regs, + settings::Flags, }, - machinst::{InsnInput, InsnOutput, LowerCtx}, + machinst::{isle::*, InsnInput, InsnOutput, LowerCtx, VCodeConstantData}, }; use std::convert::TryFrom; @@ -248,8 +248,59 @@ where fn xmm0(&mut self) -> WritableReg { WritableReg::from_reg(regs::xmm0()) } + + #[inline] + fn synthetic_amode_to_reg_mem(&mut self, addr: &SyntheticAmode) -> RegMem { + RegMem::mem(addr.clone()) + } + + #[inline] + fn amode_imm_reg_reg_shift(&mut self, simm32: u32, base: Reg, index: Reg, shift: u8) -> Amode { + Amode::imm_reg_reg_shift(simm32, base, index, shift) + } + + #[inline] + fn amode_to_synthetic_amode(&mut self, amode: &Amode) -> SyntheticAmode { + amode.clone().into() + } + + fn ishl_i8x16_mask_for_const(&mut self, amt: u32) -> SyntheticAmode { + // When the shift amount is known, we can statically (i.e. at compile + // time) determine the mask to use and only emit that. + debug_assert!(amt < 8); + let mask_offset = amt as usize * 16; + let mask_constant = self.lower_ctx.use_constant(VCodeConstantData::WellKnown( + &I8X16_SHL_MASKS[mask_offset..mask_offset + 16], + )); + SyntheticAmode::ConstantOffset(mask_constant) + } + + fn ishl_i8x16_mask_table(&mut self) -> SyntheticAmode { + let mask_table = self + .lower_ctx + .use_constant(VCodeConstantData::WellKnown(&I8X16_SHL_MASKS)); + SyntheticAmode::ConstantOffset(mask_table) + } } +// Since x64 doesn't have 8x16 shifts and we must use a 16x8 shift instead, we +// need to fix up the bits that migrate from one half of the lane to the +// other. Each 16-byte mask is indexed by the shift amount: e.g. if we shift +// right by 0 (no movement), we want to retain all the bits so we mask with +// `0xff`; if we shift right by 1, we want to retain all bits except the MSB so +// we mask with `0x7f`; etc. +#[rustfmt::skip] // Preserve 16 bytes (i.e. one mask) per row. +const I8X16_SHL_MASKS: [u8; 128] = [ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, + 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, + 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, + 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, +]; + #[inline] fn to_simm32(constant: i64) -> Option<RegMemImm> { if constant == ((constant << 32) >> 32) { 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 b65d211bdae5..1cfc6d633d54 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 f176ef3bba99365 -src/prelude.isle d95510fad2e2473c -src/isa/x64/inst.isle c16462cc359dd466 -src/isa/x64/lower.isle 9f761598e3949e8e +src/prelude.isle 7b911d3b894ae17 +src/isa/x64/inst.isle dbfa857f7f2c5d9f +src/isa/x64/lower.isle 5a737854091e1189 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 6323b91e177d..011a6b271faa 100644 --- a/cranelift/codegen/src/isa/x64/lower/isle/generated_code.rs +++ b/cranelift/codegen/src/isa/x64/lower/isle/generated_code.rs @@ -34,6 +34,7 @@ pub trait Context { fn u32_as_u64(&mut self, arg0: u32) -> u64; fn ty_bits(&mut self, arg0: Type) -> u8; fn ty_bits_u16(&mut self, arg0: Type) -> u16; + fn ty_bytes(&mut self, arg0: Type) -> u16; fn lane_type(&mut self, arg0: Type) -> Type; fn fits_in_16(&mut self, arg0: Type) -> Option<Type>; fn fits_in_32(&mut self, arg0: Type) -> Option<Type>; @@ -63,6 +64,9 @@ pub trait Context { fn raw_operand_size_of_type(&mut self, arg0: Type) -> OperandSize; fn put_in_reg_mem_imm(&mut self, arg0: Value) -> RegMemImm; fn put_in_reg_mem(&mut self, arg0: Value) -> RegMem; + fn synthetic_amode_to_reg_mem(&mut self, arg0: &SyntheticAmode) -> RegMem; + fn amode_imm_reg_reg_shift(&mut self, arg0: u32, arg1: Reg, arg2: Reg, arg3: u8) -> Amode; + fn amode_to_synthetic_amode(&mut self, arg0: &Amode) -> SyntheticAmode; fn put_masked_in_imm8_reg(&mut self, arg0: Value, arg1: Type) -> Imm8Reg; fn encode_fcmp_imm(&mut self, arg0: &FcmpImm) -> u8; fn xmm0(&mut self) -> WritableReg; @@ -78,22 +82,24 @@ pub trait Context { fn ext_mode(&mut self, arg0: u16, arg1: u16) -> ExtMode; fn emit(&mut self, arg0: &MInst) -> Unit; fn nonzero_u64_fits_in_u32(&mut self, arg0: u64) -> Option<u64>; + fn ishl_i8x16_mask_for_const(&mut self, arg0: u32) -> SyntheticAmode; + fn ishl_i8x16_mask_table(&mut self) -> SyntheticAmode; fn sse_insertps_lane_imm(&mut self, arg0: u8) -> u8; } -/// Internal type ProducesFlags: defined at src/prelude.isle line 273. +/// Internal type ProducesFlags: defined at src/prelude.isle line 277. #[derive(Clone, Debug)] pub enum ProducesFlags { ProducesFlags { inst: MInst, result: Reg }, } -/// Internal type ConsumesFlags: defined at src/prelude.isle line 276. +/// Internal type ConsumesFlags: defined at src/prelude.isle line 280. #[derive(Clone, Debug)] pub enum ConsumesFlags { ConsumesFlags { inst: MInst, result: Reg }, } -/// Internal type ExtendKind: defined at src/isa/x64/inst.isle line 441. +/// Internal type ExtendKind: defined at src/isa/x64/inst.isle line 461. #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum ExtendKind { Sign, @@ -137,7 +143,7 @@ pub fn constructor_with_flags<C: Context>( result: pattern3_1, } = pattern2_0 { - // Rule at src/prelude.isle line 286. + // Rule at src/prelude.isle line 290. let expr0_0 = C::emit(ctx, &pattern1_0); let expr1_0 = C::emit(ctx, &pattern3_0); let expr2_0 = C::value_regs(ctx, pattern1_1, pattern3_1); @@ -165,7 +171,7 @@ pub fn constructor_with_flags_1<C: Context>( result: pattern3_1, } = pattern2_0 { - // Rule at src/prelude.isle line 294. + // Rule at src/prelude.isle line 298. let expr0_0 = C::emit(ctx, &pattern1_0); let expr1_0 = C::emit(ctx, &pattern3_0); return Some(pattern3_1); @@ -199,7 +205,7 @@ pub fn constructor_with_flags_2<C: Context>( result: pattern5_1, } = pattern4_0 { - // Rule at src/prelude.isle line 304. + // Rule at src/prelude.isle line 308. let expr0_0 = C::emit(ctx, &pattern1_0); let expr1_0 = C::emit(ctx, &pattern5_0); let expr2_0 = C::emit(ctx, &pattern3_0); @@ -216,22 +222,22 @@ pub fn constructor_operand_size_bits<C: Context>(ctx: &mut C, arg0: &OperandSize let pattern0_0 = arg0; match pattern0_0 { &OperandSize::Size8 => { - // Rule at src/isa/x64/inst.isle line 91. + // Rule at src/isa/x64/inst.isle line 95. let expr0_0: u16 = 8; return Some(expr0_0); } &OperandSize::Size16 => { - // Rule at src/isa/x64/inst.isle line 92. + // Rule at src/isa/x64/inst.isle line 96. let expr0_0: u16 = 16; return Some(expr0_0); } &OperandSize::Size32 => { - // Rule at src/isa/x64/inst.isle line 93. + // Rule at src/isa/x64/inst.isle line 97. let expr0_0: u16 = 32; return Some(expr0_0); } &OperandSize::Size64 => { - // Rule at src/isa/x64/inst.isle line 94. + // Rule at src/isa/x64/inst.isle line 98. let expr0_0: u16 = 64; return Some(expr0_0); } @@ -252,12 +258,12 @@ pub fn constructor_extend_to_reg<C: Context>( let pattern2_0 = arg1; if pattern2_0 == pattern1_0 { let pattern4_0 = arg2; - // Rule at src/isa/x64/inst.isle line 453. + // Rule at src/isa/x64/inst.isle line 473. let expr0_0 = C::put_in_reg(ctx, pattern0_0); return Some(expr0_0); } let pattern3_0 = arg2; - // Rule at src/isa/x64/inst.isle line 456. + // Rule at src/isa/x64/inst.isle line 476. 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)?; @@ -281,7 +287,7 @@ pub fn constructor_extend<C: Context>( let pattern2_0 = arg1; let pattern3_0 = arg2; let pattern4_0 = arg3; - // Rule at src/isa/x64/inst.isle line 476. + // Rule at src/isa/x64/inst.isle line 496. let expr0_0 = constructor_movsx(ctx, pattern2_0, pattern3_0, pattern4_0)?; return Some(expr0_0); } @@ -289,7 +295,7 @@ pub fn constructor_extend<C: Context>( let pattern2_0 = arg1; let pattern3_0 = arg2; let pattern4_0 = arg3; - // Rule at src/isa/x64/inst.isle line 472. + // Rule at src/isa/x64/inst.isle line 492. let expr0_0 = constructor_movzx(ctx, pattern2_0, pattern3_0, pattern4_0)?; return Some(expr0_0); } @@ -302,17 +308,17 @@ pub fn constructor_extend<C: Context>( pub fn constructor_sse_xor_op<C: Context>(ctx: &mut C, arg0: Type) -> Option<SseOpcode> { let pattern0_0 = arg0; if pattern0_0 == F32X4 { - // Rule at src/isa/x64/inst.isle line 483. + // Rule at src/isa/x64/inst.isle line 503. let expr0_0 = SseOpcode::Xorps; return Some(expr0_0); } if pattern0_0 == F64X2 { - // Rule at src/isa/x64/inst.isle line 484. + // Rule at src/isa/x64/inst.isle line 504. 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 485. + // Rule at src/isa/x64/inst.isle line 505. let expr0_0 = SseOpcode::Pxor; return Some(expr0_0); } @@ -329,7 +335,7 @@ pub fn constructor_sse_xor<C: Context>( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 489. + // Rule at src/isa/x64/inst.isle line 509. 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); @@ -339,40 +345,40 @@ pub fn constructor_sse_xor<C: Context>( pub fn constructor_sse_cmp_op<C: Context>(ctx: &mut C, arg0: Type) -> Option<SseOpcode> { let pattern0_0 = arg0; if pattern0_0 == F32X4 { - // Rule at src/isa/x64/inst.isle line 498. + // Rule at src/isa/x64/inst.isle line 518. let expr0_0 = SseOpcode::Cmpps; return Some(expr0_0); } if pattern0_0 == F64X2 { - // Rule at src/isa/x64/inst.isle line 499. + // Rule at src/isa/x64/inst.isle line 519. 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 494. + // Rule at src/isa/x64/inst.isle line 514. 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 495. + // Rule at src/isa/x64/inst.isle line 515. 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 496. + // Rule at src/isa/x64/inst.isle line 516. 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 497. + // Rule at src/isa/x64/inst.isle line 517. let expr0_0 = SseOpcode::Pcmpeqq; return Some(expr0_0); } @@ -384,7 +390,7 @@ pub fn constructor_sse_cmp_op<C: Context>(ctx: &mut C, arg0: Type) -> Option<Sse // Generated as internal constructor for term vector_all_ones. pub fn constructor_vector_all_ones<C: Context>(ctx: &mut C, arg0: Type) -> Option<Reg> { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 513. + // Rule at src/isa/x64/inst.isle line 533. let expr0_0 = C::temp_writable_reg(ctx, pattern0_0); let expr1_0 = C::writable_reg_to_reg(ctx, expr0_0); let expr2_0: Type = I32X4; @@ -408,7 +414,7 @@ pub fn constructor_make_i64x2_from_lanes<C: Context>( ) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 524. + // Rule at src/isa/x64/inst.isle line 544. let expr0_0: Type = I64X2; let expr1_0 = C::temp_writable_reg(ctx, expr0_0); let expr2_0 = C::writable_reg_to_reg(ctx, expr1_0); @@ -449,11 +455,11 @@ pub fn constructor_reg_mem_imm_to_xmm<C: Context>( let pattern0_0 = arg0; match pattern0_0 { &RegMemImm::Imm { simm32: pattern1_0 } => { - // Rule at src/isa/x64/inst.isle line 545. + // Rule at src/isa/x64/inst.isle line 565. return Some(pattern0_0.clone()); } &RegMemImm::Reg { reg: pattern1_0 } => { - // Rule at src/isa/x64/inst.isle line 546. + // Rule at src/isa/x64/inst.isle line 566. let expr0_0: Type = I8X16; let expr1_0 = SseOpcode::Movd; let expr2_0 = RegMem::Reg { reg: pattern1_0 }; @@ -465,7 +471,7 @@ pub fn constructor_reg_mem_imm_to_xmm<C: Context>( &RegMemImm::Mem { addr: ref pattern1_0, } => { - // Rule at src/isa/x64/inst.isle line 544. + // Rule at src/isa/x64/inst.isle line 564. return Some(pattern0_0.clone()); } _ => {} @@ -473,6 +479,89 @@ pub fn constructor_reg_mem_imm_to_xmm<C: Context>( return None; } +// Generated as internal constructor for term x64_load. +pub fn constructor_x64_load<C: Context>( + ctx: &mut C, + arg0: Type, + arg1: &SyntheticAmode, + arg2: &ExtKind, +) -> Option<Reg> { + let pattern0_0 = arg0; + if pattern0_0 == I64 { + let pattern2_0 = arg1; + let pattern3_0 = arg2; + // Rule at src/isa/x64/inst.isle line 582. + let expr0_0: Type = I64; + let expr1_0 = C::temp_writable_reg(ctx, expr0_0); + let expr2_0 = MInst::Mov64MR { + src: pattern2_0.clone(), + dst: expr1_0, + }; + let expr3_0 = C::emit(ctx, &expr2_0); + let expr4_0 = C::writable_reg_to_reg(ctx, expr1_0); + return Some(expr4_0); + } + if pattern0_0 == F32 { + let pattern2_0 = arg1; + let pattern3_0 = arg2; + // Rule at src/isa/x64/inst.isle line 587. + let expr0_0 = SseOpcode::Movss; + let expr1_0 = C::synthetic_amode_to_reg_mem(ctx, pattern2_0); + let expr2_0 = constructor_xmm_unary_rm_r(ctx, &expr0_0, &expr1_0)?; + return Some(expr2_0); + } + if pattern0_0 == F64 { + let pattern2_0 = arg1; + let pattern3_0 = arg2; + // Rule at src/isa/x64/inst.isle line 591. + let expr0_0 = SseOpcode::Movsd; + let expr1_0 = C::synthetic_amode_to_reg_mem(ctx, pattern2_0); + let expr2_0 = constructor_xmm_unary_rm_r(ctx, &expr0_0, &expr1_0)?; + return Some(expr2_0); + } + if pattern0_0 == F32X4 { + let pattern2_0 = arg1; + let pattern3_0 = arg2; + // Rule at src/isa/x64/inst.isle line 595. + let expr0_0 = SseOpcode::Movups; + let expr1_0 = C::synthetic_amode_to_reg_mem(ctx, pattern2_0); + let expr2_0 = constructor_xmm_unary_rm_r(ctx, &expr0_0, &expr1_0)?; + return Some(expr2_0); + } + if pattern0_0 == F64X2 { + let pattern2_0 = arg1; + let pattern3_0 = arg2; + // Rule at src/isa/x64/inst.isle line 599. + let expr0_0 = SseOpcode::Movupd; + let expr1_0 = C::synthetic_amode_to_reg_mem(ctx, pattern2_0); + let expr2_0 = constructor_xmm_unary_rm_r(ctx, &expr0_0, &expr1_0)?; + return Some(expr2_0); + } + 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 603. + let expr0_0 = SseOpcode::Movdqu; + let expr1_0 = C::synthetic_amode_to_reg_mem(ctx, pattern2_0); + let expr2_0 = constructor_xmm_unary_rm_r(ctx, &expr0_0, &expr1_0)?; + return Some(expr2_0); + } + if let Some(pattern1_0) = C::fits_in_32(ctx, pattern0_0) { + let pattern2_0 = arg1; + let pattern3_0 = arg2; + if let &ExtKind::SignExtend = pattern3_0 { + // Rule at src/isa/x64/inst.isle line 577. + 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); + let expr3_0 = C::synthetic_amode_to_reg_mem(ctx, pattern2_0); + let expr4_0 = constructor_movsx(ctx, pattern1_0, &expr2_0, &expr3_0)?; + return Some(expr4_0); + } + } + return None; +} + // Generated as internal constructor for term alu_rmi_r. pub fn constructor_alu_rmi_r<C: Context>( ctx: &mut C, @@ -485,7 +574,7 @@ pub fn constructor_alu_rmi_r<C: Context>( let pattern1_0 = arg1; let pattern2_0 = arg2; let pattern3_0 = arg3; - // Rule at src/isa/x64/inst.isle line 568. + // Rule at src/isa/x64/inst.isle line 622. let expr0_0 = C::temp_writable_reg(ctx, pattern0_0); let expr1_0 = C::operand_size_of_type_32_64(ctx, pattern0_0); let expr2_0 = MInst::AluRmiR { @@ -510,7 +599,7 @@ pub fn constructor_add<C: Context>( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 576. + // Rule at src/isa/x64/inst.isle line 630. 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); @@ -526,7 +615,7 @@ pub fn constructor_add_with_flags<C: Context>( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 584. + // Rule at src/isa/x64/inst.isle line 638. let expr0_0 = C::temp_writable_reg(ctx, pattern0_0); let expr1_0 = C::operand_size_of_type_32_64(ctx, pattern0_0); let expr2_0 = AluRmiROpcode::Add; @@ -555,7 +644,7 @@ pub fn constructor_adc<C: Context>( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 595. + // Rule at src/isa/x64/inst.isle line 649. let expr0_0 = C::temp_writable_reg(ctx, pattern0_0); let expr1_0 = C::operand_size_of_type_32_64(ctx, pattern0_0); let expr2_0 = AluRmiROpcode::Adc; @@ -584,7 +673,7 @@ pub fn constructor_sub<C: Context>( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 606. + // Rule at src/isa/x64/inst.isle line 660. 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); @@ -600,7 +689,7 @@ pub fn constructor_sub_with_flags<C: Context>( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 614. + // Rule at src/isa/x64/inst.isle line 668. let expr0_0 = C::temp_writable_reg(ctx, pattern0_0); let expr1_0 = C::operand_size_of_type_32_64(ctx, pattern0_0); let expr2_0 = AluRmiROpcode::Sub; @@ -629,7 +718,7 @@ pub fn constructor_sbb<C: Context>( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 625. + // Rule at src/isa/x64/inst.isle line 679. let expr0_0 = C::temp_writable_reg(ctx, pattern0_0); let expr1_0 = C::operand_size_of_type_32_64(ctx, pattern0_0); let expr2_0 = AluRmiROpcode::Sbb; @@ -658,7 +747,7 @@ pub fn constructor_mul<C: Context>( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 636. + // Rule at src/isa/x64/inst.isle line 690. 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); @@ -674,7 +763,7 @@ pub fn constructor_m_and<C: Context>( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 647. + // Rule at src/isa/x64/inst.isle line 701. 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); @@ -690,7 +779,7 @@ pub fn constructor_or<C: Context>( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 655. + // Rule at src/isa/x64/inst.isle line 709. 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); @@ -706,7 +795,7 @@ pub fn constructor_xor<C: Context>( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 663. + // Rule at src/isa/x64/inst.isle line 717. 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); @@ -718,7 +807,7 @@ pub fn constructor_imm<C: Context>(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 692. + // Rule at src/isa/x64/inst.isle line 746. let expr0_0: Type = I64; let expr1_0 = C::temp_writable_reg(ctx, expr0_0); let expr2_0 = OperandSize::Size32; @@ -735,7 +824,7 @@ pub fn constructor_imm<C: Context>(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 721. + // Rule at src/isa/x64/inst.isle line 775. let expr0_0: Type = F32; let expr1_0 = C::temp_writable_reg(ctx, expr0_0); let expr2_0 = C::writable_reg_to_reg(ctx, expr1_0); @@ -750,7 +839,7 @@ pub fn constructor_imm<C: Context>(ctx: &mut C, arg0: Type, arg1: u64) -> Option let expr6_0 = C::emit(ctx, &expr5_0); return Some(expr2_0); } - // Rule at src/isa/x64/inst.isle line 680. + // Rule at src/isa/x64/inst.isle line 734. let expr0_0: Type = F32; let expr1_0 = SseOpcode::Movd; let expr2_0: Type = I32; @@ -763,7 +852,7 @@ pub fn constructor_imm<C: Context>(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 733. + // Rule at src/isa/x64/inst.isle line 787. let expr0_0: Type = F64; let expr1_0 = C::temp_writable_reg(ctx, expr0_0); let expr2_0 = C::writable_reg_to_reg(ctx, expr1_0); @@ -778,7 +867,7 @@ pub fn constructor_imm<C: Context>(ctx: &mut C, arg0: Type, arg1: u64) -> Option let expr6_0 = C::emit(ctx, &expr5_0); return Some(expr2_0); } - // Rule at src/isa/x64/inst.isle line 684. + // Rule at src/isa/x64/inst.isle line 738. let expr0_0: Type = F64; let expr1_0 = SseOpcode::Movq; let expr2_0: Type = I64; @@ -791,7 +880,7 @@ pub fn constructor_imm<C: Context>(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 711. + // Rule at src/isa/x64/inst.isle line 765. let expr0_0 = C::temp_writable_reg(ctx, pattern0_0); let expr1_0 = C::writable_reg_to_reg(ctx, expr0_0); let expr2_0 = constructor_sse_xor_op(ctx, pattern0_0)?; @@ -808,7 +897,7 @@ pub fn constructor_imm<C: Context>(ctx: &mut C, arg0: Type, arg1: u64) -> Option } let pattern1_0 = arg1; if pattern1_0 == 0 { - // Rule at src/isa/x64/inst.isle line 698. + // Rule at src/isa/x64/inst.isle line 752. let expr0_0 = C::temp_writable_reg(ctx, pattern0_0); let expr1_0 = C::writable_reg_to_reg(ctx, expr0_0); let expr2_0 = C::operand_size_of_type_32_64(ctx, pattern0_0); @@ -824,7 +913,7 @@ pub fn constructor_imm<C: Context>(ctx: &mut C, arg0: Type, arg1: u64) -> Option let expr6_0 = C::emit(ctx, &expr5_0); return Some(expr1_0); } - // Rule at src/isa/x64/inst.isle line 673. + // Rule at src/isa/x64/inst.isle line 727. let expr0_0 = C::temp_writable_reg(ctx, pattern0_0); let expr1_0 = C::operand_size_of_type_32_64(ctx, pattern0_0); let expr2_0 = MInst::Imm { @@ -849,7 +938,7 @@ pub fn constructor_shift_r<C: Context>( let pattern1_0 = arg1; let pattern2_0 = arg2; let pattern3_0 = arg3; - // Rule at src/isa/x64/inst.isle line 746. + // Rule at src/isa/x64/inst.isle line 800. let expr0_0 = C::temp_writable_reg(ctx, pattern0_0); let expr1_0 = C::raw_operand_size_of_type(ctx, pattern0_0); let expr2_0 = MInst::ShiftR { @@ -874,7 +963,7 @@ pub fn constructor_m_rotl<C: Context>( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 757. + // Rule at src/isa/x64/inst.isle line 811. let expr0_0 = ShiftKind::RotateLeft; let expr1_0 = constructor_shift_r(ctx, pattern0_0, &expr0_0, pattern1_0, pattern2_0)?; return Some(expr1_0); @@ -890,7 +979,7 @@ pub fn constructor_shl<C: Context>( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 762. + // Rule at src/isa/x64/inst.isle line 816. let expr0_0 = ShiftKind::ShiftLeft; let expr1_0 = constructor_shift_r(ctx, pattern0_0, &expr0_0, pattern1_0, pattern2_0)?; return Some(expr1_0); @@ -906,7 +995,7 @@ pub fn constructor_shr<C: Context>( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 767. + // Rule at src/isa/x64/inst.isle line 821. let expr0_0 = ShiftKind::ShiftRightLogical; let expr1_0 = constructor_shift_r(ctx, pattern0_0, &expr0_0, pattern1_0, pattern2_0)?; return Some(expr1_0); @@ -922,7 +1011,7 @@ pub fn constructor_sar<C: Context>( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 772. + // Rule at src/isa/x64/inst.isle line 826. let expr0_0 = ShiftKind::ShiftRightArithmetic; let expr1_0 = constructor_shift_r(ctx, pattern0_0, &expr0_0, pattern1_0, pattern2_0)?; return Some(expr1_0); @@ -940,7 +1029,7 @@ pub fn constructor_cmp_rmi_r<C: Context>( let pattern1_0 = arg1; let pattern2_0 = arg2; let pattern3_0 = arg3; - // Rule at src/isa/x64/inst.isle line 777. + // Rule at src/isa/x64/inst.isle line 831. let expr0_0 = MInst::CmpRmiR { size: pattern0_0.clone(), opcode: pattern1_0.clone(), @@ -965,7 +1054,7 @@ pub fn constructor_cmp<C: Context>( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 786. + // Rule at src/isa/x64/inst.isle line 840. 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); @@ -981,7 +1070,7 @@ pub fn constructor_test<C: Context>( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 791. + // Rule at src/isa/x64/inst.isle line 845. 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); @@ -999,7 +1088,7 @@ pub fn constructor_cmove<C: Context>( let pattern1_0 = arg1; let pattern2_0 = arg2; let pattern3_0 = arg3; - // Rule at src/isa/x64/inst.isle line 796. + // Rule at src/isa/x64/inst.isle line 850. let expr0_0 = C::temp_writable_reg(ctx, pattern0_0); let expr1_0 = C::operand_size_of_type_32_64(ctx, pattern0_0); let expr2_0 = MInst::Cmove { @@ -1027,7 +1116,7 @@ pub fn constructor_movzx<C: Context>( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 804. + // Rule at src/isa/x64/inst.isle line 858. let expr0_0 = C::temp_writable_reg(ctx, pattern0_0); let expr1_0 = MInst::MovzxRmR { ext_mode: pattern1_0.clone(), @@ -1049,7 +1138,7 @@ pub fn constructor_movsx<C: Context>( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 811. + // Rule at src/isa/x64/inst.isle line 865. let expr0_0 = C::temp_writable_reg(ctx, pattern0_0); let expr1_0 = MInst::MovsxRmR { ext_mode: pattern1_0.clone(), @@ -1073,7 +1162,7 @@ pub fn constructor_xmm_rm_r<C: Context>( let pattern1_0 = arg1; let pattern2_0 = arg2; let pattern3_0 = arg3; - // Rule at src/isa/x64/inst.isle line 818. + // Rule at src/isa/x64/inst.isle line 872. let expr0_0 = C::temp_writable_reg(ctx, pattern0_0); let expr1_0 = MInst::XmmRmR { op: pattern1_0.clone(), @@ -1090,7 +1179,7 @@ pub fn constructor_xmm_rm_r<C: Context>( pub fn constructor_paddb<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 825. + // Rule at src/isa/x64/inst.isle line 879. 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)?; @@ -1101,7 +1190,7 @@ pub fn constructor_paddb<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> O pub fn constructor_paddw<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 830. + // Rule at src/isa/x64/inst.isle line 884. 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)?; @@ -1112,7 +1201,7 @@ pub fn constructor_paddw<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> O pub fn constructor_paddd<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 835. + // Rule at src/isa/x64/inst.isle line 889. 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)?; @@ -1123,7 +1212,7 @@ pub fn constructor_paddd<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> O pub fn constructor_paddq<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 840. + // Rule at src/isa/x64/inst.isle line 894. 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)?; @@ -1134,7 +1223,7 @@ pub fn constructor_paddq<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> O pub fn constructor_paddsb<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 845. + // Rule at src/isa/x64/inst.isle line 899. 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)?; @@ -1145,7 +1234,7 @@ pub fn constructor_paddsb<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> pub fn constructor_paddsw<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 850. + // Rule at src/isa/x64/inst.isle line 904. 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)?; @@ -1156,7 +1245,7 @@ pub fn constructor_paddsw<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> pub fn constructor_paddusb<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 855. + // Rule at src/isa/x64/inst.isle line 909. 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)?; @@ -1167,7 +1256,7 @@ pub fn constructor_paddusb<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> pub fn constructor_paddusw<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 860. + // Rule at src/isa/x64/inst.isle line 914. 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)?; @@ -1178,7 +1267,7 @@ pub fn constructor_paddusw<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> pub fn constructor_psubb<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 865. + // Rule at src/isa/x64/inst.isle line 919. 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)?; @@ -1189,7 +1278,7 @@ pub fn constructor_psubb<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> O pub fn constructor_psubw<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 870. + // Rule at src/isa/x64/inst.isle line 924. 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)?; @@ -1200,7 +1289,7 @@ pub fn constructor_psubw<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> O pub fn constructor_psubd<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 875. + // Rule at src/isa/x64/inst.isle line 929. 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)?; @@ -1211,7 +1300,7 @@ pub fn constructor_psubd<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> O pub fn constructor_psubq<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 880. + // Rule at src/isa/x64/inst.isle line 934. 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)?; @@ -1222,7 +1311,7 @@ pub fn constructor_psubq<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> O pub fn constructor_psubsb<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 885. + // Rule at src/isa/x64/inst.isle line 939. 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)?; @@ -1233,7 +1322,7 @@ pub fn constructor_psubsb<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> pub fn constructor_psubsw<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 890. + // Rule at src/isa/x64/inst.isle line 944. 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)?; @@ -1244,7 +1333,7 @@ pub fn constructor_psubsw<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> pub fn constructor_psubusb<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 895. + // Rule at src/isa/x64/inst.isle line 949. 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)?; @@ -1255,7 +1344,7 @@ pub fn constructor_psubusb<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> pub fn constructor_psubusw<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 900. + // Rule at src/isa/x64/inst.isle line 954. 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)?; @@ -1266,7 +1355,7 @@ pub fn constructor_psubusw<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> pub fn constructor_pavgb<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 905. + // Rule at src/isa/x64/inst.isle line 959. 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)?; @@ -1277,7 +1366,7 @@ pub fn constructor_pavgb<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> O pub fn constructor_pavgw<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 910. + // Rule at src/isa/x64/inst.isle line 964. 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)?; @@ -1288,7 +1377,7 @@ pub fn constructor_pavgw<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> O pub fn constructor_pand<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 915. + // Rule at src/isa/x64/inst.isle line 969. 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)?; @@ -1299,7 +1388,7 @@ pub fn constructor_pand<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Op pub fn constructor_andps<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 920. + // Rule at src/isa/x64/inst.isle line 974. 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)?; @@ -1310,7 +1399,7 @@ pub fn constructor_andps<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> O pub fn constructor_andpd<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 925. + // Rule at src/isa/x64/inst.isle line 979. 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)?; @@ -1321,7 +1410,7 @@ pub fn constructor_andpd<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> O pub fn constructor_por<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 930. + // Rule at src/isa/x64/inst.isle line 984. 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)?; @@ -1332,7 +1421,7 @@ pub fn constructor_por<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Opt pub fn constructor_orps<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 935. + // Rule at src/isa/x64/inst.isle line 989. 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)?; @@ -1343,7 +1432,7 @@ pub fn constructor_orps<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Op pub fn constructor_orpd<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 940. + // Rule at src/isa/x64/inst.isle line 994. 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)?; @@ -1354,7 +1443,7 @@ pub fn constructor_orpd<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Op pub fn constructor_pxor<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 945. + // Rule at src/isa/x64/inst.isle line 999. 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)?; @@ -1365,7 +1454,7 @@ pub fn constructor_pxor<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Op pub fn constructor_xorps<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 950. + // Rule at src/isa/x64/inst.isle line 1004. 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)?; @@ -1376,7 +1465,7 @@ pub fn constructor_xorps<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> O pub fn constructor_xorpd<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 955. + // Rule at src/isa/x64/inst.isle line 1009. 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)?; @@ -1387,7 +1476,7 @@ pub fn constructor_xorpd<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> O pub fn constructor_pmullw<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 960. + // Rule at src/isa/x64/inst.isle line 1014. 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)?; @@ -1398,7 +1487,7 @@ pub fn constructor_pmullw<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> pub fn constructor_pmulld<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 965. + // Rule at src/isa/x64/inst.isle line 1019. 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)?; @@ -1409,7 +1498,7 @@ pub fn constructor_pmulld<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> pub fn constructor_pmulhw<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 970. + // Rule at src/isa/x64/inst.isle line 1024. 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)?; @@ -1420,7 +1509,7 @@ pub fn constructor_pmulhw<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> pub fn constructor_pmulhuw<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 975. + // Rule at src/isa/x64/inst.isle line 1029. 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)?; @@ -1431,7 +1520,7 @@ pub fn constructor_pmulhuw<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> pub fn constructor_pmuldq<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 980. + // Rule at src/isa/x64/inst.isle line 1034. 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)?; @@ -1442,7 +1531,7 @@ pub fn constructor_pmuldq<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> pub fn constructor_pmuludq<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 985. + // Rule at src/isa/x64/inst.isle line 1039. 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)?; @@ -1453,7 +1542,7 @@ pub fn constructor_pmuludq<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> pub fn constructor_punpckhwd<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 990. + // Rule at src/isa/x64/inst.isle line 1044. 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)?; @@ -1464,7 +1553,7 @@ pub fn constructor_punpckhwd<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) pub fn constructor_punpcklwd<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 995. + // Rule at src/isa/x64/inst.isle line 1049. 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)?; @@ -1475,7 +1564,7 @@ pub fn constructor_punpcklwd<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) pub fn constructor_andnps<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1000. + // Rule at src/isa/x64/inst.isle line 1054. 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)?; @@ -1486,7 +1575,7 @@ pub fn constructor_andnps<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> pub fn constructor_andnpd<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1005. + // Rule at src/isa/x64/inst.isle line 1059. 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)?; @@ -1497,7 +1586,7 @@ pub fn constructor_andnpd<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> pub fn constructor_pandn<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1010. + // Rule at src/isa/x64/inst.isle line 1064. 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)?; @@ -1508,17 +1597,17 @@ pub fn constructor_pandn<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> O pub fn constructor_sse_blend_op<C: Context>(ctx: &mut C, arg0: Type) -> Option<SseOpcode> { let pattern0_0 = arg0; if pattern0_0 == F32X4 { - // Rule at src/isa/x64/inst.isle line 1014. + // Rule at src/isa/x64/inst.isle line 1068. let expr0_0 = SseOpcode::Blendvps; return Some(expr0_0); } if pattern0_0 == F64X2 { - // Rule at src/isa/x64/inst.isle line 1015. + // Rule at src/isa/x64/inst.isle line 1069. 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 1016. + // Rule at src/isa/x64/inst.isle line 1070. let expr0_0 = SseOpcode::Pblendvb; return Some(expr0_0); } @@ -1529,17 +1618,17 @@ pub fn constructor_sse_blend_op<C: Context>(ctx: &mut C, arg0: Type) -> Option<S pub fn constructor_sse_mov_op<C: Context>(ctx: &mut C, arg0: Type) -> Option<SseOpcode> { let pattern0_0 = arg0; if pattern0_0 == F32X4 { - // Rule at src/isa/x64/inst.isle line 1019. + // Rule at src/isa/x64/inst.isle line 1073. let expr0_0 = SseOpcode::Movaps; return Some(expr0_0); } if pattern0_0 == F64X2 { - // Rule at src/isa/x64/inst.isle line 1020. + // Rule at src/isa/x64/inst.isle line 1074. 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 1021. + // Rule at src/isa/x64/inst.isle line 1075. let expr0_0 = SseOpcode::Movdqa; return Some(expr0_0); } @@ -1558,7 +1647,7 @@ pub fn constructor_sse_blend<C: Context>( let pattern1_0 = arg1; let pattern2_0 = arg2; let pattern3_0 = arg3; - // Rule at src/isa/x64/inst.isle line 1025. + // Rule at src/isa/x64/inst.isle line 1079. let expr0_0 = C::xmm0(ctx); let expr1_0 = constructor_sse_mov_op(ctx, pattern0_0)?; let expr2_0 = MInst::XmmUnaryRmR { @@ -1582,7 +1671,7 @@ pub fn constructor_blendvpd<C: Context>( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1037. + // Rule at src/isa/x64/inst.isle line 1091. let expr0_0 = C::xmm0(ctx); let expr1_0 = SseOpcode::Movapd; let expr2_0 = RegMem::Reg { reg: pattern2_0 }; @@ -1602,7 +1691,7 @@ pub fn constructor_blendvpd<C: Context>( pub fn constructor_movsd<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1049. + // Rule at src/isa/x64/inst.isle line 1103. 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)?; @@ -1613,7 +1702,7 @@ pub fn constructor_movsd<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> O pub fn constructor_movlhps<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1054. + // Rule at src/isa/x64/inst.isle line 1108. 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)?; @@ -1624,7 +1713,7 @@ pub fn constructor_movlhps<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> pub fn constructor_pmaxsb<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1059. + // Rule at src/isa/x64/inst.isle line 1113. 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)?; @@ -1635,7 +1724,7 @@ pub fn constructor_pmaxsb<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> pub fn constructor_pmaxsw<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1064. + // Rule at src/isa/x64/inst.isle line 1118. 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)?; @@ -1646,7 +1735,7 @@ pub fn constructor_pmaxsw<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> pub fn constructor_pmaxsd<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1069. + // Rule at src/isa/x64/inst.isle line 1123. 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)?; @@ -1657,7 +1746,7 @@ pub fn constructor_pmaxsd<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> pub fn constructor_pminsb<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1074. + // Rule at src/isa/x64/inst.isle line 1128. 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)?; @@ -1668,7 +1757,7 @@ pub fn constructor_pminsb<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> pub fn constructor_pminsw<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1079. + // Rule at src/isa/x64/inst.isle line 1133. 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)?; @@ -1679,7 +1768,7 @@ pub fn constructor_pminsw<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> pub fn constructor_pminsd<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1084. + // Rule at src/isa/x64/inst.isle line 1138. 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)?; @@ -1690,7 +1779,7 @@ pub fn constructor_pminsd<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> pub fn constructor_pmaxub<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1089. + // Rule at src/isa/x64/inst.isle line 1143. 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)?; @@ -1701,7 +1790,7 @@ pub fn constructor_pmaxub<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> pub fn constructor_pmaxuw<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1094. + // Rule at src/isa/x64/inst.isle line 1148. 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)?; @@ -1712,7 +1801,7 @@ pub fn constructor_pmaxuw<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> pub fn constructor_pmaxud<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1099. + // Rule at src/isa/x64/inst.isle line 1153. 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)?; @@ -1723,7 +1812,7 @@ pub fn constructor_pmaxud<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> pub fn constructor_pminub<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1104. + // Rule at src/isa/x64/inst.isle line 1158. 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)?; @@ -1734,7 +1823,7 @@ pub fn constructor_pminub<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> pub fn constructor_pminuw<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1109. + // Rule at src/isa/x64/inst.isle line 1163. 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)?; @@ -1745,7 +1834,7 @@ pub fn constructor_pminuw<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> pub fn constructor_pminud<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1114. + // Rule at src/isa/x64/inst.isle line 1168. 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)?; @@ -1756,7 +1845,7 @@ pub fn constructor_pminud<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> pub fn constructor_punpcklbw<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1119. + // Rule at src/isa/x64/inst.isle line 1173. 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)?; @@ -1767,7 +1856,7 @@ pub fn constructor_punpcklbw<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) pub fn constructor_punpckhbw<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1124. + // Rule at src/isa/x64/inst.isle line 1178. 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)?; @@ -1778,7 +1867,7 @@ pub fn constructor_punpckhbw<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) pub fn constructor_packsswb<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1129. + // Rule at src/isa/x64/inst.isle line 1183. 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)?; @@ -1799,7 +1888,7 @@ pub fn constructor_xmm_rm_r_imm<C: Context>( let pattern2_0 = arg2; let pattern3_0 = arg3; let pattern4_0 = arg4; - // Rule at src/isa/x64/inst.isle line 1134. + // Rule at src/isa/x64/inst.isle line 1188. let expr0_0: Type = I8X16; let expr1_0 = C::temp_writable_reg(ctx, expr0_0); let expr2_0 = MInst::XmmRmRImm { @@ -1827,7 +1916,7 @@ pub fn constructor_palignr<C: Context>( let pattern1_0 = arg1; let pattern2_0 = arg2; let pattern3_0 = arg3; - // Rule at src/isa/x64/inst.isle line 1146. + // Rule at src/isa/x64/inst.isle line 1200. let expr0_0 = SseOpcode::Palignr; let expr1_0 = constructor_xmm_rm_r_imm( ctx, &expr0_0, pattern0_0, pattern1_0, pattern2_0, pattern3_0, @@ -1845,7 +1934,7 @@ pub fn constructor_pshufd<C: Context>( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1155. + // Rule at src/isa/x64/inst.isle line 1209. let expr0_0: Type = I8X16; let expr1_0 = C::temp_writable_reg(ctx, expr0_0); let expr2_0 = C::writable_reg_to_reg(ctx, expr1_0); @@ -1870,7 +1959,7 @@ pub fn constructor_xmm_unary_rm_r<C: Context>( ) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1168. + // Rule at src/isa/x64/inst.isle line 1222. let expr0_0: Type = I8X16; let expr1_0 = C::temp_writable_reg(ctx, expr0_0); let expr2_0 = MInst::XmmUnaryRmR { @@ -1886,7 +1975,7 @@ pub fn constructor_xmm_unary_rm_r<C: Context>( // Generated as internal constructor for term pmovsxbw. pub fn constructor_pmovsxbw<C: Context>(ctx: &mut C, arg0: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 1175. + // Rule at src/isa/x64/inst.isle line 1229. let expr0_0 = SseOpcode::Pmovsxbw; let expr1_0 = constructor_xmm_unary_rm_r(ctx, &expr0_0, pattern0_0)?; return Some(expr1_0); @@ -1895,7 +1984,7 @@ pub fn constructor_pmovsxbw<C: Context>(ctx: &mut C, arg0: &RegMem) -> Option<Re // Generated as internal constructor for term pmovzxbw. pub fn constructor_pmovzxbw<C: Context>(ctx: &mut C, arg0: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 1180. + // Rule at src/isa/x64/inst.isle line 1234. let expr0_0 = SseOpcode::Pmovzxbw; let expr1_0 = constructor_xmm_unary_rm_r(ctx, &expr0_0, pattern0_0)?; return Some(expr1_0); @@ -1904,7 +1993,7 @@ pub fn constructor_pmovzxbw<C: Context>(ctx: &mut C, arg0: &RegMem) -> Option<Re // Generated as internal constructor for term pabsb. pub fn constructor_pabsb<C: Context>(ctx: &mut C, arg0: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 1185. + // Rule at src/isa/x64/inst.isle line 1239. let expr0_0 = SseOpcode::Pabsb; let expr1_0 = constructor_xmm_unary_rm_r(ctx, &expr0_0, pattern0_0)?; return Some(expr1_0); @@ -1913,7 +2002,7 @@ pub fn constructor_pabsb<C: Context>(ctx: &mut C, arg0: &RegMem) -> Option<Reg> // Generated as internal constructor for term pabsw. pub fn constructor_pabsw<C: Context>(ctx: &mut C, arg0: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 1190. + // Rule at src/isa/x64/inst.isle line 1244. let expr0_0 = SseOpcode::Pabsw; let expr1_0 = constructor_xmm_unary_rm_r(ctx, &expr0_0, pattern0_0)?; return Some(expr1_0); @@ -1922,7 +2011,7 @@ pub fn constructor_pabsw<C: Context>(ctx: &mut C, arg0: &RegMem) -> Option<Reg> // Generated as internal constructor for term pabsd. pub fn constructor_pabsd<C: Context>(ctx: &mut C, arg0: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 1195. + // Rule at src/isa/x64/inst.isle line 1249. let expr0_0 = SseOpcode::Pabsd; let expr1_0 = constructor_xmm_unary_rm_r(ctx, &expr0_0, pattern0_0)?; return Some(expr1_0); @@ -1936,7 +2025,7 @@ pub fn constructor_xmm_unary_rm_r_evex<C: Context>( ) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1200. + // Rule at src/isa/x64/inst.isle line 1254. let expr0_0: Type = I8X16; let expr1_0 = C::temp_writable_reg(ctx, expr0_0); let expr2_0 = MInst::XmmUnaryRmREvex { @@ -1952,7 +2041,7 @@ pub fn constructor_xmm_unary_rm_r_evex<C: Context>( // Generated as internal constructor for term vpabsq. pub fn constructor_vpabsq<C: Context>(ctx: &mut C, arg0: &RegMem) -> Option<Reg> { let pattern0_0 = arg0; - // Rule at src/isa/x64/inst.isle line 1207. + // Rule at src/isa/x64/inst.isle line 1261. let expr0_0 = Avx512Opcode::Vpabsq; let expr1_0 = constructor_xmm_unary_rm_r_evex(ctx, &expr0_0, pattern0_0)?; return Some(expr1_0); @@ -1968,7 +2057,7 @@ pub fn constructor_xmm_rm_r_evex<C: Context>( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1212. + // Rule at src/isa/x64/inst.isle line 1266. let expr0_0: Type = I8X16; let expr1_0 = C::temp_writable_reg(ctx, expr0_0); let expr2_0 = MInst::XmmRmREvex { @@ -1986,7 +2075,7 @@ pub fn constructor_xmm_rm_r_evex<C: Context>( pub fn constructor_vpmullq<C: Context>(ctx: &mut C, arg0: &RegMem, arg1: Reg) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1224. + // Rule at src/isa/x64/inst.isle line 1278. let expr0_0 = Avx512Opcode::Vpmullq; let expr1_0 = constructor_xmm_rm_r_evex(ctx, &expr0_0, pattern0_0, pattern1_0)?; return Some(expr1_0); @@ -2002,7 +2091,7 @@ pub fn constructor_xmm_rmi_reg<C: Context>( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1231. + // Rule at src/isa/x64/inst.isle line 1285. let expr0_0: Type = I8X16; let expr1_0 = C::temp_writable_reg(ctx, expr0_0); let expr2_0 = MInst::XmmRmiReg { @@ -2016,11 +2105,31 @@ pub fn constructor_xmm_rmi_reg<C: Context>( return Some(expr4_0); } +// Generated as internal constructor for term psllw. +pub fn constructor_psllw<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMemImm) -> Option<Reg> { + let pattern0_0 = arg0; + let pattern1_0 = arg1; + // Rule at src/isa/x64/inst.isle line 1295. + let expr0_0 = SseOpcode::Psllw; + let expr1_0 = constructor_xmm_rmi_reg(ctx, &expr0_0, pattern0_0, pattern1_0)?; + return Some(expr1_0); +} + +// Generated as internal constructor for term pslld. +pub fn constructor_pslld<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMemImm) -> Option<Reg> { + let pattern0_0 = arg0; + let pattern1_0 = arg1; + // Rule at src/isa/x64/inst.isle line 1300. + let expr0_0 = SseOpcode::Pslld; + let expr1_0 = constructor_xmm_rmi_reg(ctx, &expr0_0, pattern0_0, pattern1_0)?; + return Some(expr1_0); +} + // Generated as internal constructor for term psllq. pub fn constructor_psllq<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMemImm) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1241. + // Rule at src/isa/x64/inst.isle line 1305. let expr0_0 = SseOpcode::Psllq; let expr1_0 = constructor_xmm_rmi_reg(ctx, &expr0_0, pattern0_0, pattern1_0)?; return Some(expr1_0); @@ -2030,7 +2139,7 @@ pub fn constructor_psllq<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMemImm) - pub fn constructor_psrld<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMemImm) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1246. + // Rule at src/isa/x64/inst.isle line 1310. let expr0_0 = SseOpcode::Psrld; let expr1_0 = constructor_xmm_rmi_reg(ctx, &expr0_0, pattern0_0, pattern1_0)?; return Some(expr1_0); @@ -2040,7 +2149,7 @@ pub fn constructor_psrld<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMemImm) - pub fn constructor_psrlq<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMemImm) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1251. + // Rule at src/isa/x64/inst.isle line 1315. let expr0_0 = SseOpcode::Psrlq; let expr1_0 = constructor_xmm_rmi_reg(ctx, &expr0_0, pattern0_0, pattern1_0)?; return Some(expr1_0); @@ -2050,7 +2159,7 @@ pub fn constructor_psrlq<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMemImm) - pub fn constructor_psraw<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMemImm) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1256. + // Rule at src/isa/x64/inst.isle line 1320. let expr0_0 = SseOpcode::Psraw; let expr1_0 = constructor_xmm_rmi_reg(ctx, &expr0_0, pattern0_0, pattern1_0)?; return Some(expr1_0); @@ -2060,7 +2169,7 @@ pub fn constructor_psraw<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMemImm) - pub fn constructor_psrad<C: Context>(ctx: &mut C, arg0: Reg, arg1: &RegMemImm) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1261. + // Rule at src/isa/x64/inst.isle line 1325. let expr0_0 = SseOpcode::Psrad; let expr1_0 = constructor_xmm_rmi_reg(ctx, &expr0_0, pattern0_0, pattern1_0)?; return Some(expr1_0); @@ -2078,7 +2187,7 @@ pub fn constructor_mul_hi<C: Context>( let pattern1_0 = arg1; let pattern2_0 = arg2; let pattern3_0 = arg3; - // Rule at src/isa/x64/inst.isle line 1268. + // Rule at src/isa/x64/inst.isle line 1332. let expr0_0 = C::temp_writable_reg(ctx, pattern0_0); let expr1_0 = C::temp_writable_reg(ctx, pattern0_0); let expr2_0 = C::operand_size_of_type_32_64(ctx, pattern0_0); @@ -2107,7 +2216,7 @@ pub fn constructor_mulhi_u<C: Context>( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1284. + // Rule at src/isa/x64/inst.isle line 1348. let expr0_0: bool = false; let expr1_0 = constructor_mul_hi(ctx, pattern0_0, expr0_0, pattern1_0, pattern2_0)?; return Some(expr1_0); @@ -2123,7 +2232,7 @@ pub fn constructor_cmpps<C: Context>( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1289. + // Rule at src/isa/x64/inst.isle line 1353. let expr0_0 = SseOpcode::Cmpps; let expr1_0 = C::encode_fcmp_imm(ctx, pattern2_0); let expr2_0 = OperandSize::Size32; @@ -2142,7 +2251,7 @@ pub fn constructor_cmppd<C: Context>( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1302. + // Rule at src/isa/x64/inst.isle line 1366. let expr0_0 = SseOpcode::Cmppd; let expr1_0 = C::encode_fcmp_imm(ctx, pattern2_0); let expr2_0 = OperandSize::Size32; @@ -2163,7 +2272,7 @@ pub fn constructor_gpr_to_xmm<C: Context>( let pattern1_0 = arg1; let pattern2_0 = arg2; let pattern3_0 = arg3; - // Rule at src/isa/x64/inst.isle line 1311. + // Rule at src/isa/x64/inst.isle line 1375. let expr0_0 = C::temp_writable_reg(ctx, pattern0_0); let expr1_0 = MInst::GprToXmm { op: pattern1_0.clone(), @@ -2186,7 +2295,7 @@ pub fn constructor_pinsrb<C: Context>( 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 1382. let expr0_0 = SseOpcode::Pinsrb; let expr1_0 = OperandSize::Size32; let expr2_0 = @@ -2204,7 +2313,7 @@ pub fn constructor_pinsrw<C: Context>( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1323. + // Rule at src/isa/x64/inst.isle line 1387. let expr0_0 = SseOpcode::Pinsrw; let expr1_0 = OperandSize::Size32; let expr2_0 = @@ -2224,7 +2333,7 @@ pub fn constructor_pinsrd<C: Context>( let pattern1_0 = arg1; let pattern2_0 = arg2; let pattern3_0 = arg3; - // Rule at src/isa/x64/inst.isle line 1328. + // Rule at src/isa/x64/inst.isle line 1392. let expr0_0 = SseOpcode::Pinsrd; let expr1_0 = constructor_xmm_rm_r_imm( ctx, &expr0_0, pattern0_0, pattern1_0, pattern2_0, pattern3_0, @@ -2242,7 +2351,7 @@ pub fn constructor_insertps<C: Context>( let pattern0_0 = arg0; let pattern1_0 = arg1; let pattern2_0 = arg2; - // Rule at src/isa/x64/inst.isle line 1333. + // Rule at src/isa/x64/inst.isle line 1397. let expr0_0 = SseOpcode::Insertps; let expr1_0 = OperandSize::Size32; let expr2_0 = @@ -2255,7 +2364,7 @@ pub fn constructor_pextrd<C: Context>(ctx: &mut C, arg0: Type, arg1: Reg, arg2: 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 1402. let expr0_0 = C::temp_writable_reg(ctx, pattern0_0); let expr1_0 = C::writable_reg_to_reg(ctx, expr0_0); let expr2_0 = SseOpcode::Pextrd; @@ -2278,7 +2387,7 @@ pub fn constructor_pextrd<C: Context>(ctx: &mut C, arg0: Type, arg1: Reg, arg2: pub fn constructor_not<C: Context>(ctx: &mut C, arg0: Type, arg1: Reg) -> Option<Reg> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/inst.isle line 1351. + // Rule at src/isa/x64/inst.isle line 1415. let expr0_0 = C::temp_writable_reg(ctx, pattern0_0); let expr1_0 = C::operand_size_of_type_32_64(ctx, pattern0_0); let expr2_0 = MInst::Not { @@ -2291,6 +2400,21 @@ pub fn constructor_not<C: Context>(ctx: &mut C, arg0: Type, arg1: Reg) -> Option return Some(expr4_0); } +// Generated as internal constructor for term lea. +pub fn constructor_lea<C: Context>(ctx: &mut C, arg0: &SyntheticAmode) -> Option<Reg> { + let pattern0_0 = arg0; + // Rule at src/isa/x64/inst.isle line 1422. + let expr0_0: Type = I64; + let expr1_0 = C::temp_writable_reg(ctx, expr0_0); + let expr2_0 = MInst::LoadEffectiveAddress { + addr: pattern0_0.clone(), + dst: expr1_0, + }; + let expr3_0 = C::emit(ctx, &expr2_0); + let expr4_0 = C::writable_reg_to_reg(ctx, expr1_0); + return Some(expr4_0); +} + // Generated as internal constructor for term lower. pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueRegs> { let pattern0_0 = arg0; @@ -2331,7 +2455,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg let (pattern4_0, pattern4_1) = C::unpack_value_array_2(ctx, &pattern2_1); let pattern5_0 = C::value_type(ctx, pattern4_0); let pattern6_0 = C::u8_from_uimm8(ctx, pattern2_2); - // Rule at src/isa/x64/lower.isle line 1160. + // Rule at src/isa/x64/lower.isle line 1221. let expr0_0 = C::put_in_reg(ctx, pattern4_0); let expr1_0 = C::put_in_reg_mem(ctx, pattern4_1); let expr2_0 = @@ -2437,7 +2561,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg arg: pattern5_1, } => { if let &Opcode::Bnot = &pattern5_0 { - // Rule at src/isa/x64/lower.isle line 1127. + // Rule at src/isa/x64/lower.isle line 1188. let expr0_0 = constructor_i128_not(ctx, pattern5_1)?; return Some(expr0_0); } @@ -2520,7 +2644,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg &Opcode::Imul => { let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1); - // Rule at src/isa/x64/lower.isle line 815. + // Rule at src/isa/x64/lower.isle line 876. let expr0_0 = C::put_in_regs(ctx, pattern7_0); let expr1_0: usize = 0; let expr2_0 = C::value_regs_get(ctx, expr0_0, expr1_0); @@ -2611,7 +2735,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg &Opcode::Rotl => { let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1); - // Rule at src/isa/x64/lower.isle line 748. + // Rule at src/isa/x64/lower.isle line 809. let expr0_0 = C::put_in_regs(ctx, pattern7_0); let expr1_0 = constructor_lo_reg(ctx, pattern7_1)?; let expr2_0 = constructor_shl_i128(ctx, expr0_0, expr1_0)?; @@ -2637,7 +2761,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg &Opcode::Ushr => { let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1); - // Rule at src/isa/x64/lower.isle line 607. + // Rule at src/isa/x64/lower.isle line 668. let expr0_0 = constructor_lo_reg(ctx, pattern7_1)?; let expr1_0 = C::put_in_regs(ctx, pattern7_0); let expr2_0 = constructor_shr_i128(ctx, expr1_0, expr0_0)?; @@ -2646,7 +2770,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg &Opcode::Sshr => { let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1); - // Rule at src/isa/x64/lower.isle line 649. + // Rule at src/isa/x64/lower.isle line 710. let expr0_0 = constructor_lo_reg(ctx, pattern7_1)?; let expr1_0 = C::put_in_regs(ctx, pattern7_0); let expr2_0 = constructor_sar_i128(ctx, expr1_0, expr0_0)?; @@ -2660,7 +2784,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg arg: pattern5_1, } => { if let &Opcode::Bnot = &pattern5_0 { - // Rule at src/isa/x64/lower.isle line 1124. + // Rule at src/isa/x64/lower.isle line 1185. let expr0_0 = constructor_i128_not(ctx, pattern5_1)?; return Some(expr0_0); } @@ -2705,7 +2829,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg &Opcode::Imin => { let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1); - // Rule at src/isa/x64/lower.isle line 1228. + // Rule at src/isa/x64/lower.isle line 1289. let expr0_0 = C::put_in_reg(ctx, pattern7_0); let expr1_0 = C::put_in_reg_mem(ctx, pattern7_1); let expr2_0 = constructor_pminsb(ctx, expr0_0, &expr1_0)?; @@ -2715,7 +2839,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg &Opcode::Umin => { let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1); - // Rule at src/isa/x64/lower.isle line 1250. + // Rule at src/isa/x64/lower.isle line 1311. let expr0_0 = C::put_in_reg(ctx, pattern7_0); let expr1_0 = C::put_in_reg_mem(ctx, pattern7_1); let expr2_0 = constructor_pminub(ctx, expr0_0, &expr1_0)?; @@ -2725,7 +2849,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg &Opcode::Imax => { let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1); - // Rule at src/isa/x64/lower.isle line 1217. + // Rule at src/isa/x64/lower.isle line 1278. let expr0_0 = C::put_in_reg(ctx, pattern7_0); let expr1_0 = C::put_in_reg_mem(ctx, pattern7_1); let expr2_0 = constructor_pmaxsb(ctx, expr0_0, &expr1_0)?; @@ -2735,18 +2859,36 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg &Opcode::Umax => { let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1); - // Rule at src/isa/x64/lower.isle line 1239. + // Rule at src/isa/x64/lower.isle line 1300. let expr0_0 = C::put_in_reg(ctx, pattern7_0); let expr1_0 = C::put_in_reg_mem(ctx, pattern7_1); let expr2_0 = constructor_pmaxub(ctx, expr0_0, &expr1_0)?; let expr3_0 = C::value_reg(ctx, expr2_0); return Some(expr3_0); } + &Opcode::Ishl => { + let (pattern7_0, pattern7_1) = + C::unpack_value_array_2(ctx, &pattern5_1); + // Rule at src/isa/x64/lower.isle line 580. + let expr0_0 = C::put_in_reg(ctx, pattern7_0); + let expr1_0 = C::put_in_reg_mem_imm(ctx, pattern7_1); + let expr2_0 = constructor_reg_mem_imm_to_xmm(ctx, &expr1_0)?; + let expr3_0 = constructor_psllw(ctx, expr0_0, &expr2_0)?; + let expr4_0 = constructor_ishl_i8x16_mask(ctx, &expr1_0)?; + let expr5_0: Type = I8X16; + let expr6_0 = ExtKind::None; + let expr7_0 = constructor_x64_load(ctx, expr5_0, &expr4_0, &expr6_0)?; + let expr8_0: Type = I8X16; + let expr9_0 = RegMem::Reg { reg: expr7_0 }; + let expr10_0 = constructor_sse_and(ctx, expr8_0, expr3_0, &expr9_0)?; + let expr11_0 = C::value_reg(ctx, expr10_0); + return Some(expr11_0); + } &Opcode::Sshr => { let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1); let pattern8_0 = C::value_type(ctx, pattern7_1); - // Rule at src/isa/x64/lower.isle line 670. + // Rule at src/isa/x64/lower.isle line 731. let expr0_0 = C::put_in_reg(ctx, pattern7_0); let expr1_0 = RegMem::Reg { reg: expr0_0 }; let expr2_0 = constructor_punpcklbw(ctx, expr0_0, &expr1_0)?; @@ -2770,7 +2912,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg arg: pattern5_1, } => { if let &Opcode::Iabs = &pattern5_0 { - // Rule at src/isa/x64/lower.isle line 1070. + // Rule at src/isa/x64/lower.isle line 1131. let expr0_0 = C::put_in_reg_mem(ctx, pattern5_1); let expr1_0 = constructor_pabsb(ctx, &expr0_0)?; let expr2_0 = C::value_reg(ctx, expr1_0); @@ -2791,7 +2933,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg &Opcode::Imin => { let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1); - // Rule at src/isa/x64/lower.isle line 1231. + // Rule at src/isa/x64/lower.isle line 1292. let expr0_0 = C::put_in_reg(ctx, pattern7_0); let expr1_0 = C::put_in_reg_mem(ctx, pattern7_1); let expr2_0 = constructor_pminsw(ctx, expr0_0, &expr1_0)?; @@ -2801,7 +2943,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg &Opcode::Umin => { let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1); - // Rule at src/isa/x64/lower.isle line 1253. + // Rule at src/isa/x64/lower.isle line 1314. let expr0_0 = C::put_in_reg(ctx, pattern7_0); let expr1_0 = C::put_in_reg_mem(ctx, pattern7_1); let expr2_0 = constructor_pminuw(ctx, expr0_0, &expr1_0)?; @@ -2811,7 +2953,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg &Opcode::Imax => { let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1); - // Rule at src/isa/x64/lower.isle line 1220. + // Rule at src/isa/x64/lower.isle line 1281. let expr0_0 = C::put_in_reg(ctx, pattern7_0); let expr1_0 = C::put_in_reg_mem(ctx, pattern7_1); let expr2_0 = constructor_pmaxsw(ctx, expr0_0, &expr1_0)?; @@ -2821,17 +2963,28 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg &Opcode::Umax => { let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1); - // Rule at src/isa/x64/lower.isle line 1242. + // Rule at src/isa/x64/lower.isle line 1303. let expr0_0 = C::put_in_reg(ctx, pattern7_0); let expr1_0 = C::put_in_reg_mem(ctx, pattern7_1); let expr2_0 = constructor_pmaxuw(ctx, expr0_0, &expr1_0)?; let expr3_0 = C::value_reg(ctx, expr2_0); return Some(expr3_0); } + &Opcode::Ishl => { + let (pattern7_0, pattern7_1) = + C::unpack_value_array_2(ctx, &pattern5_1); + // Rule at src/isa/x64/lower.isle line 625. + let expr0_0 = C::put_in_reg(ctx, pattern7_0); + let expr1_0 = C::put_in_reg_mem_imm(ctx, pattern7_1); + let expr2_0 = constructor_reg_mem_imm_to_xmm(ctx, &expr1_0)?; + let expr3_0 = constructor_psllw(ctx, expr0_0, &expr2_0)?; + let expr4_0 = C::value_reg(ctx, expr3_0); + return Some(expr4_0); + } &Opcode::Sshr => { let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1); - // Rule at src/isa/x64/lower.isle line 692. + // Rule at src/isa/x64/lower.isle line 753. let expr0_0 = C::put_in_reg(ctx, pattern7_0); let expr1_0 = C::put_in_reg_mem_imm(ctx, pattern7_1); let expr2_0 = constructor_reg_mem_imm_to_xmm(ctx, &expr1_0)?; @@ -2847,7 +3000,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg arg: pattern5_1, } => { if let &Opcode::Iabs = &pattern5_0 { - // Rule at src/isa/x64/lower.isle line 1073. + // Rule at src/isa/x64/lower.isle line 1134. let expr0_0 = C::put_in_reg_mem(ctx, pattern5_1); let expr1_0 = constructor_pabsw(ctx, &expr0_0)?; let expr2_0 = C::value_reg(ctx, expr1_0); @@ -2868,7 +3021,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg &Opcode::Imin => { let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1); - // Rule at src/isa/x64/lower.isle line 1234. + // Rule at src/isa/x64/lower.isle line 1295. let expr0_0 = C::put_in_reg(ctx, pattern7_0); let expr1_0 = C::put_in_reg_mem(ctx, pattern7_1); let expr2_0 = constructor_pminsd(ctx, expr0_0, &expr1_0)?; @@ -2878,7 +3031,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg &Opcode::Umin => { let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1); - // Rule at src/isa/x64/lower.isle line 1256. + // Rule at src/isa/x64/lower.isle line 1317. let expr0_0 = C::put_in_reg(ctx, pattern7_0); let expr1_0 = C::put_in_reg_mem(ctx, pattern7_1); let expr2_0 = constructor_pminud(ctx, expr0_0, &expr1_0)?; @@ -2888,7 +3041,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg &Opcode::Imax => { let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1); - // Rule at src/isa/x64/lower.isle line 1223. + // Rule at src/isa/x64/lower.isle line 1284. let expr0_0 = C::put_in_reg(ctx, pattern7_0); let expr1_0 = C::put_in_reg_mem(ctx, pattern7_1); let expr2_0 = constructor_pmaxsd(ctx, expr0_0, &expr1_0)?; @@ -2898,17 +3051,28 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg &Opcode::Umax => { let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1); - // Rule at src/isa/x64/lower.isle line 1245. + // Rule at src/isa/x64/lower.isle line 1306. let expr0_0 = C::put_in_reg(ctx, pattern7_0); let expr1_0 = C::put_in_reg_mem(ctx, pattern7_1); let expr2_0 = constructor_pmaxud(ctx, expr0_0, &expr1_0)?; let expr3_0 = C::value_reg(ctx, expr2_0); return Some(expr3_0); } + &Opcode::Ishl => { + let (pattern7_0, pattern7_1) = + C::unpack_value_array_2(ctx, &pattern5_1); + // Rule at src/isa/x64/lower.isle line 628. + let expr0_0 = C::put_in_reg(ctx, pattern7_0); + let expr1_0 = C::put_in_reg_mem_imm(ctx, pattern7_1); + let expr2_0 = constructor_reg_mem_imm_to_xmm(ctx, &expr1_0)?; + let expr3_0 = constructor_pslld(ctx, expr0_0, &expr2_0)?; + let expr4_0 = C::value_reg(ctx, expr3_0); + return Some(expr4_0); + } &Opcode::Sshr => { let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1); - // Rule at src/isa/x64/lower.isle line 695. + // Rule at src/isa/x64/lower.isle line 756. let expr0_0 = C::put_in_reg(ctx, pattern7_0); let expr1_0 = C::put_in_reg_mem_imm(ctx, pattern7_1); let expr2_0 = constructor_reg_mem_imm_to_xmm(ctx, &expr1_0)?; @@ -2924,7 +3088,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg arg: pattern5_1, } => { if let &Opcode::Iabs = &pattern5_0 { - // Rule at src/isa/x64/lower.isle line 1076. + // Rule at src/isa/x64/lower.isle line 1137. let expr0_0 = C::put_in_reg_mem(ctx, pattern5_1); let expr1_0 = constructor_pabsd(ctx, &expr0_0)?; let expr2_0 = C::value_reg(ctx, expr1_0); @@ -2941,28 +3105,43 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg opcode: ref pattern5_0, args: ref pattern5_1, } => { - if let &Opcode::Sshr = &pattern5_0 { - let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1); - // Rule at src/isa/x64/lower.isle line 707. - let expr0_0 = C::put_in_reg(ctx, pattern7_0); - let expr1_0: Type = I64; - let expr2_0: u8 = 0; - let expr3_0 = constructor_pextrd(ctx, expr1_0, expr0_0, expr2_0)?; - let expr4_0: Type = I64; - let expr5_0: u8 = 1; - let expr6_0 = constructor_pextrd(ctx, expr4_0, expr0_0, expr5_0)?; - let expr7_0: Type = I64; - let expr8_0 = C::put_masked_in_imm8_reg(ctx, pattern7_1, expr7_0); - let expr9_0: Type = I64; - let expr10_0 = constructor_sar(ctx, expr9_0, expr3_0, &expr8_0)?; - let expr11_0: Type = I64; - let expr12_0 = constructor_sar(ctx, expr11_0, expr6_0, &expr8_0)?; - let expr13_0 = RegMem::Reg { reg: expr10_0 }; - let expr14_0 = RegMem::Reg { reg: expr12_0 }; - let expr15_0 = - constructor_make_i64x2_from_lanes(ctx, &expr13_0, &expr14_0)?; - let expr16_0 = C::value_reg(ctx, expr15_0); - return Some(expr16_0); + match &pattern5_0 { + &Opcode::Ishl => { + let (pattern7_0, pattern7_1) = + C::unpack_value_array_2(ctx, &pattern5_1); + // Rule at src/isa/x64/lower.isle line 631. + let expr0_0 = C::put_in_reg(ctx, pattern7_0); + let expr1_0 = C::put_in_reg_mem_imm(ctx, pattern7_1); + let expr2_0 = constructor_reg_mem_imm_to_xmm(ctx, &expr1_0)?; + let expr3_0 = constructor_psllq(ctx, expr0_0, &expr2_0)?; + let expr4_0 = C::value_reg(ctx, expr3_0); + return Some(expr4_0); + } + &Opcode::Sshr => { + let (pattern7_0, pattern7_1) = + C::unpack_value_array_2(ctx, &pattern5_1); + // Rule at src/isa/x64/lower.isle line 768. + let expr0_0 = C::put_in_reg(ctx, pattern7_0); + let expr1_0: Type = I64; + let expr2_0: u8 = 0; + let expr3_0 = constructor_pextrd(ctx, expr1_0, expr0_0, expr2_0)?; + let expr4_0: Type = I64; + let expr5_0: u8 = 1; + let expr6_0 = constructor_pextrd(ctx, expr4_0, expr0_0, expr5_0)?; + let expr7_0: Type = I64; + let expr8_0 = C::put_masked_in_imm8_reg(ctx, pattern7_1, expr7_0); + let expr9_0: Type = I64; + let expr10_0 = constructor_sar(ctx, expr9_0, expr3_0, &expr8_0)?; + let expr11_0: Type = I64; + let expr12_0 = constructor_sar(ctx, expr11_0, expr6_0, &expr8_0)?; + let expr13_0 = RegMem::Reg { reg: expr10_0 }; + let expr14_0 = RegMem::Reg { reg: expr12_0 }; + let expr15_0 = + constructor_make_i64x2_from_lanes(ctx, &expr13_0, &expr14_0)?; + let expr16_0 = C::value_reg(ctx, expr15_0); + return Some(expr16_0); + } + _ => {} } } &InstructionData::Unary { @@ -2970,7 +3149,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg arg: pattern5_1, } => { if let &Opcode::Iabs = &pattern5_0 { - // Rule at src/isa/x64/lower.isle line 1090. + // Rule at src/isa/x64/lower.isle line 1151. let expr0_0 = C::put_in_reg(ctx, pattern5_1); let expr1_0: Type = I64X2; let expr2_0: u64 = 0; @@ -2994,7 +3173,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg } = &pattern4_0 { if let &Opcode::Fabs = &pattern5_0 { - // Rule at src/isa/x64/lower.isle line 1098. + // Rule at src/isa/x64/lower.isle line 1159. let expr0_0 = C::put_in_reg(ctx, pattern5_1); let expr1_0: Type = F32X4; let expr2_0 = constructor_vector_all_ones(ctx, expr1_0)?; @@ -3016,7 +3195,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg } = &pattern4_0 { if let &Opcode::Fabs = &pattern5_0 { - // Rule at src/isa/x64/lower.isle line 1103. + // Rule at src/isa/x64/lower.isle line 1164. let expr0_0 = C::put_in_reg(ctx, pattern5_1); let expr1_0: Type = F64X2; let expr2_0 = constructor_vector_all_ones(ctx, expr1_0)?; @@ -3049,7 +3228,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg } => { if let &Opcode::BandNot = &pattern4_0 { let (pattern6_0, pattern6_1) = C::unpack_value_array_2(ctx, &pattern4_1); - // Rule at src/isa/x64/lower.isle line 1063. + // Rule at src/isa/x64/lower.isle line 1124. let expr0_0 = C::put_in_reg(ctx, pattern6_1); let expr1_0 = C::put_in_reg_mem(ctx, pattern6_0); let expr2_0 = constructor_sse_and_not(ctx, pattern2_0, expr0_0, &expr1_0)?; @@ -3073,7 +3252,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg if let &Opcode::Imul = &pattern9_0 { let (pattern11_0, pattern11_1) = C::unpack_value_array_2(ctx, &pattern9_1); - // Rule at src/isa/x64/lower.isle line 850. + // Rule at src/isa/x64/lower.isle line 911. let expr0_0 = C::put_in_reg_mem(ctx, pattern11_0); let expr1_0 = C::put_in_reg(ctx, pattern11_1); let expr2_0 = constructor_vpmullq(ctx, &expr0_0, expr1_0)?; @@ -3094,7 +3273,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg } = &pattern6_0 { if let &Opcode::Iabs = &pattern7_0 { - // Rule at src/isa/x64/lower.isle line 1080. + // Rule at src/isa/x64/lower.isle line 1141. let expr0_0 = C::put_in_reg_mem(ctx, pattern7_1); let expr1_0 = constructor_vpabsq(ctx, &expr0_0)?; let expr2_0 = C::value_reg(ctx, expr1_0); @@ -3117,7 +3296,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg &Opcode::AvgRound => { let (pattern9_0, pattern9_1) = C::unpack_value_array_2(ctx, &pattern7_1); - // Rule at src/isa/x64/lower.isle line 758. + // Rule at src/isa/x64/lower.isle line 819. let expr0_0 = C::put_in_reg(ctx, pattern9_0); let expr1_0 = C::put_in_reg_mem(ctx, pattern9_1); let expr2_0 = constructor_pavgb(ctx, expr0_0, &expr1_0)?; @@ -3201,7 +3380,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg &Opcode::AvgRound => { let (pattern9_0, pattern9_1) = C::unpack_value_array_2(ctx, &pattern7_1); - // Rule at src/isa/x64/lower.isle line 762. + // Rule at src/isa/x64/lower.isle line 823. let expr0_0 = C::put_in_reg(ctx, pattern9_0); let expr1_0 = C::put_in_reg_mem(ctx, pattern9_1); let expr2_0 = constructor_pavgw(ctx, expr0_0, &expr1_0)?; @@ -3314,7 +3493,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg if pattern23_0 == 8 { if pattern23_1 == 16 { - // Rule at src/isa/x64/lower.isle line 938. + // Rule at src/isa/x64/lower.isle line 999. let expr0_0 = C::put_in_reg_mem(ctx, pattern12_1); let expr1_0 = constructor_pmovsxbw(ctx, &expr0_0)?; let expr2_0 = C::put_in_reg_mem(ctx, pattern20_1); @@ -3372,7 +3551,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg if pattern23_0 == 8 { if pattern23_1 == 16 { - // Rule at src/isa/x64/lower.isle line 898. + // Rule at src/isa/x64/lower.isle line 959. let expr0_0 = C::put_in_reg(ctx, pattern12_1); let expr1_0 = RegMem::Reg { reg: expr0_0, @@ -3448,7 +3627,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg if pattern23_0 == 8 { if pattern23_1 == 16 { - // Rule at src/isa/x64/lower.isle line 1014. + // Rule at src/isa/x64/lower.isle line 1075. let expr0_0 = C::put_in_reg_mem(ctx, pattern12_1); let expr1_0 = constructor_pmovzxbw(ctx, &expr0_0)?; let expr2_0 = C::put_in_reg_mem(ctx, pattern20_1); @@ -3506,7 +3685,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg if pattern23_0 == 8 { if pattern23_1 == 16 { - // Rule at src/isa/x64/lower.isle line 974. + // Rule at src/isa/x64/lower.isle line 1035. let expr0_0 = C::put_in_reg(ctx, pattern12_1); let expr1_0 = RegMem::Reg { reg: expr0_0, @@ -3551,7 +3730,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg } } } - // Rule at src/isa/x64/lower.isle line 842. + // Rule at src/isa/x64/lower.isle line 903. let expr0_0 = C::put_in_reg(ctx, pattern9_0); let expr1_0 = C::put_in_reg_mem(ctx, pattern9_1); let expr2_0 = constructor_pmullw(ctx, expr0_0, &expr1_0)?; @@ -3638,7 +3817,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg if pattern23_0 == 16 { if pattern23_1 == 8 { - // Rule at src/isa/x64/lower.isle line 948. + // Rule at src/isa/x64/lower.isle line 1009. let expr0_0 = C::put_in_reg(ctx, pattern12_1); let expr1_0 = C::put_in_reg(ctx, pattern20_1); let expr2_0 = RegMem::Reg { @@ -3702,7 +3881,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg if pattern23_0 == 16 { if pattern23_1 == 8 { - // Rule at src/isa/x64/lower.isle line 912. + // Rule at src/isa/x64/lower.isle line 973. let expr0_0 = C::put_in_reg(ctx, pattern12_1); let expr1_0 = C::put_in_reg(ctx, pattern20_1); let expr2_0 = RegMem::Reg { @@ -3766,7 +3945,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg if pattern23_0 == 16 { if pattern23_1 == 8 { - // Rule at src/isa/x64/lower.isle line 1024. + // Rule at src/isa/x64/lower.isle line 1085. let expr0_0 = C::put_in_reg(ctx, pattern12_1); let expr1_0 = C::put_in_reg(ctx, pattern20_1); let expr2_0 = RegMem::Reg { @@ -3830,7 +4009,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg if pattern23_0 == 16 { if pattern23_1 == 8 { - // Rule at src/isa/x64/lower.isle line 988. + // Rule at src/isa/x64/lower.isle line 1049. let expr0_0 = C::put_in_reg(ctx, pattern12_1); let expr1_0 = C::put_in_reg(ctx, pattern20_1); let expr2_0 = RegMem::Reg { @@ -3863,7 +4042,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg } } } - // Rule at src/isa/x64/lower.isle line 845. + // Rule at src/isa/x64/lower.isle line 906. let expr0_0 = C::put_in_reg(ctx, pattern9_0); let expr1_0 = C::put_in_reg_mem(ctx, pattern9_1); let expr2_0 = constructor_pmulld(ctx, expr0_0, &expr1_0)?; @@ -3950,7 +4129,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg if pattern23_0 == 32 { if pattern23_1 == 4 { - // Rule at src/isa/x64/lower.isle line 960. + // Rule at src/isa/x64/lower.isle line 1021. let expr0_0 = C::put_in_reg_mem(ctx, pattern12_1); let expr1_0: u8 = 80; let expr2_0 = OperandSize::Size32; @@ -4012,7 +4191,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg if pattern23_0 == 32 { if pattern23_1 == 4 { - // Rule at src/isa/x64/lower.isle line 924. + // Rule at src/isa/x64/lower.isle line 985. let expr0_0 = C::put_in_reg_mem(ctx, pattern12_1); let expr1_0: u8 = 250; let expr2_0 = OperandSize::Size32; @@ -4074,7 +4253,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg if pattern23_0 == 32 { if pattern23_1 == 4 { - // Rule at src/isa/x64/lower.isle line 1036. + // Rule at src/isa/x64/lower.isle line 1097. let expr0_0 = C::put_in_reg_mem(ctx, pattern12_1); let expr1_0: u8 = 80; let expr2_0 = OperandSize::Size32; @@ -4136,7 +4315,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg if pattern23_0 == 32 { if pattern23_1 == 4 { - // Rule at src/isa/x64/lower.isle line 1000. + // Rule at src/isa/x64/lower.isle line 1061. let expr0_0 = C::put_in_reg_mem(ctx, pattern12_1); let expr1_0: u8 = 250; let expr2_0 = OperandSize::Size32; @@ -4167,7 +4346,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg } } } - // Rule at src/isa/x64/lower.isle line 876. + // Rule at src/isa/x64/lower.isle line 937. let expr0_0 = C::put_in_reg(ctx, pattern9_0); let expr1_0 = C::put_in_reg(ctx, pattern9_1); let expr2_0: u32 = 32; @@ -4245,7 +4424,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg &Opcode::Bitselect => { let (pattern7_0, pattern7_1, pattern7_2) = C::unpack_value_array_3(ctx, &pattern5_1); - // Rule at src/isa/x64/lower.isle line 1137. + // Rule at src/isa/x64/lower.isle line 1198. let expr0_0 = C::put_in_reg(ctx, pattern7_0); let expr1_0 = C::put_in_reg(ctx, pattern7_1); let expr2_0 = RegMem::Reg { reg: expr0_0 }; @@ -4261,7 +4440,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg &Opcode::Vselect => { let (pattern7_0, pattern7_1, pattern7_2) = C::unpack_value_array_3(ctx, &pattern5_1); - // Rule at src/isa/x64/lower.isle line 1151. + // Rule at src/isa/x64/lower.isle line 1212. let expr0_0 = C::put_in_reg_mem(ctx, pattern7_0); let expr1_0 = C::put_in_reg_mem(ctx, pattern7_1); let expr2_0 = C::put_in_reg(ctx, pattern7_2); @@ -4279,7 +4458,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg arg: pattern5_1, } => { if let &Opcode::Bnot = &pattern5_0 { - // Rule at src/isa/x64/lower.isle line 1132. + // Rule at src/isa/x64/lower.isle line 1193. let expr0_0 = C::put_in_reg(ctx, pattern5_1); let expr1_0 = constructor_vector_all_ones(ctx, pattern2_0)?; let expr2_0 = RegMem::Reg { reg: expr1_0 }; @@ -4406,7 +4585,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1); if let Some(pattern8_0) = C::simm32_from_value(ctx, pattern7_0) { - // Rule at src/isa/x64/lower.isle line 782. + // Rule at src/isa/x64/lower.isle line 843. let expr0_0 = C::put_in_reg(ctx, pattern7_1); let expr1_0 = constructor_mul(ctx, pattern3_0, expr0_0, &pattern8_0)?; @@ -4414,7 +4593,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg return Some(expr2_0); } if let Some(pattern8_0) = C::sinkable_load(ctx, pattern7_0) { - // Rule at src/isa/x64/lower.isle line 794. + // Rule at src/isa/x64/lower.isle line 855. let expr0_0 = C::put_in_reg(ctx, pattern7_1); let expr1_0 = C::sink_load(ctx, &pattern8_0); let expr2_0 = constructor_mul(ctx, pattern3_0, expr0_0, &expr1_0)?; @@ -4422,7 +4601,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg return Some(expr3_0); } if let Some(pattern8_0) = C::simm32_from_value(ctx, pattern7_1) { - // Rule at src/isa/x64/lower.isle line 778. + // Rule at src/isa/x64/lower.isle line 839. let expr0_0 = C::put_in_reg(ctx, pattern7_0); let expr1_0 = constructor_mul(ctx, pattern3_0, expr0_0, &pattern8_0)?; @@ -4430,14 +4609,14 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg return Some(expr2_0); } if let Some(pattern8_0) = C::sinkable_load(ctx, pattern7_1) { - // Rule at src/isa/x64/lower.isle line 788. + // Rule at src/isa/x64/lower.isle line 849. let expr0_0 = C::put_in_reg(ctx, pattern7_0); let expr1_0 = C::sink_load(ctx, &pattern8_0); let expr2_0 = constructor_mul(ctx, pattern3_0, expr0_0, &expr1_0)?; let expr3_0 = C::value_reg(ctx, expr2_0); return Some(expr3_0); } - // Rule at src/isa/x64/lower.isle line 771. + // Rule at src/isa/x64/lower.isle line 832. let expr0_0 = C::put_in_reg(ctx, pattern7_0); let expr1_0 = C::put_in_reg(ctx, pattern7_1); let expr2_0 = RegMemImm::Reg { reg: expr1_0 }; @@ -4647,7 +4826,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg &Opcode::Ushr => { let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1); - // Rule at src/isa/x64/lower.isle line 578. + // Rule at src/isa/x64/lower.isle line 639. let expr0_0 = ExtendKind::Zero; let expr1_0 = constructor_extend_to_reg(ctx, pattern7_0, pattern3_0, &expr0_0)?; @@ -4659,7 +4838,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg &Opcode::Sshr => { let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1); - // Rule at src/isa/x64/lower.isle line 617. + // Rule at src/isa/x64/lower.isle line 678. let expr0_0 = ExtendKind::Sign; let expr1_0 = constructor_extend_to_reg(ctx, pattern7_0, pattern3_0, &expr0_0)?; @@ -4676,7 +4855,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg arg: pattern5_1, } => { if let &Opcode::Bnot = &pattern5_0 { - // Rule at src/isa/x64/lower.isle line 1111. + // Rule at src/isa/x64/lower.isle line 1172. let expr0_0 = C::put_in_reg(ctx, pattern5_1); let expr1_0 = constructor_not(ctx, pattern3_0, expr0_0)?; let expr2_0 = C::value_reg(ctx, expr1_0); @@ -4720,7 +4899,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg { if let &Opcode::Iconst = &pattern10_0 { let pattern12_0 = C::u64_from_imm64(ctx, pattern10_1); - // Rule at src/isa/x64/lower.isle line 740. + // Rule at src/isa/x64/lower.isle line 801. let expr0_0 = C::put_in_reg(ctx, pattern7_0); let expr1_0 = C::const_to_type_masked_imm8(ctx, pattern12_0, pattern3_0); @@ -4731,7 +4910,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg } } } - // Rule at src/isa/x64/lower.isle line 734. + // Rule at src/isa/x64/lower.isle line 795. let expr0_0 = constructor_lo_reg(ctx, pattern7_1)?; let expr1_0 = C::put_in_reg(ctx, pattern7_0); let expr2_0 = Imm8Reg::Reg { reg: expr0_0 }; @@ -4759,7 +4938,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg { if let &Opcode::Iconst = &pattern10_0 { let pattern12_0 = C::u64_from_imm64(ctx, pattern10_1); - // Rule at src/isa/x64/lower.isle line 725. + // Rule at src/isa/x64/lower.isle line 786. let expr0_0 = C::put_in_reg(ctx, pattern7_0); let expr1_0 = C::const_to_type_masked_imm8(ctx, pattern12_0, pattern3_0); @@ -4770,7 +4949,7 @@ pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueReg } } } - // Rule at src/isa/x64/lower.isle line 721. + // Rule at src/isa/x64/lower.isle line 782. let expr0_0: Type = I32; let expr1_0 = ExtendKind::Zero; let expr2_0 = constructor_extend_to_reg(ctx, pattern7_1, expr0_0, &expr1_0)?; @@ -4936,6 +5115,48 @@ pub fn constructor_shl_i128<C: Context>( return Some(expr46_0); } +// Generated as internal constructor for term ishl_i8x16_mask. +pub fn constructor_ishl_i8x16_mask<C: Context>( + ctx: &mut C, + arg0: &RegMemImm, +) -> Option<SyntheticAmode> { + let pattern0_0 = arg0; + match pattern0_0 { + &RegMemImm::Imm { simm32: pattern1_0 } => { + // Rule at src/isa/x64/lower.isle line 598. + let expr0_0 = C::ishl_i8x16_mask_for_const(ctx, pattern1_0); + return Some(expr0_0); + } + &RegMemImm::Reg { reg: pattern1_0 } => { + // Rule at src/isa/x64/lower.isle line 605. + let expr0_0 = C::ishl_i8x16_mask_table(ctx); + let expr1_0 = constructor_lea(ctx, &expr0_0)?; + let expr2_0: Type = I64; + let expr3_0: u8 = 4; + let expr4_0 = Imm8Reg::Imm8 { imm: expr3_0 }; + let expr5_0 = constructor_shl(ctx, expr2_0, pattern1_0, &expr4_0)?; + let expr6_0: u32 = 0; + let expr7_0: u8 = 0; + let expr8_0 = C::amode_imm_reg_reg_shift(ctx, expr6_0, expr1_0, expr5_0, expr7_0); + let expr9_0 = C::amode_to_synthetic_amode(ctx, &expr8_0); + return Some(expr9_0); + } + &RegMemImm::Mem { + addr: ref pattern1_0, + } => { + // Rule at src/isa/x64/lower.isle line 613. + let expr0_0: Type = I64; + let expr1_0 = ExtKind::None; + let expr2_0 = constructor_x64_load(ctx, expr0_0, &pattern1_0, &expr1_0)?; + let expr3_0 = RegMemImm::Reg { reg: expr2_0 }; + let expr4_0 = constructor_ishl_i8x16_mask(ctx, &expr3_0)?; + return Some(expr4_0); + } + _ => {} + } + return None; +} + // Generated as internal constructor for term shr_i128. pub fn constructor_shr_i128<C: Context>( ctx: &mut C, @@ -4944,7 +5165,7 @@ pub fn constructor_shr_i128<C: Context>( ) -> Option<ValueRegs> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/lower.isle line 585. + // Rule at src/isa/x64/lower.isle line 646. let expr0_0: usize = 0; let expr1_0 = C::value_regs_get(ctx, pattern0_0, expr0_0); let expr2_0: usize = 1; @@ -5006,7 +5227,7 @@ pub fn constructor_sar_i128<C: Context>( ) -> Option<ValueRegs> { let pattern0_0 = arg0; let pattern1_0 = arg1; - // Rule at src/isa/x64/lower.isle line 624. + // Rule at src/isa/x64/lower.isle line 685. let expr0_0: usize = 0; let expr1_0 = C::value_regs_get(ctx, pattern0_0, expr0_0); let expr2_0: usize = 1; @@ -5071,14 +5292,14 @@ pub fn constructor_sshr_i8x16_bigger_shift<C: Context>( let pattern1_0 = arg1; match pattern1_0 { &RegMemImm::Imm { simm32: pattern2_0 } => { - // Rule at src/isa/x64/lower.isle line 683. + // Rule at src/isa/x64/lower.isle line 744. let expr0_0: u32 = 8; let expr1_0 = C::u32_add(ctx, pattern2_0, expr0_0); let expr2_0 = RegMemImm::Imm { simm32: expr1_0 }; return Some(expr2_0); } &RegMemImm::Reg { reg: pattern2_0 } => { - // Rule at src/isa/x64/lower.isle line 685. + // Rule at src/isa/x64/lower.isle line 746. let expr0_0: u32 = 8; let expr1_0 = RegMemImm::Imm { simm32: expr0_0 }; let expr2_0 = constructor_add(ctx, pattern0_0, pattern2_0, &expr1_0)?; @@ -5089,7 +5310,7 @@ pub fn constructor_sshr_i8x16_bigger_shift<C: Context>( &RegMemImm::Mem { addr: ref pattern2_0, } => { - // Rule at src/isa/x64/lower.isle line 687. + // Rule at src/isa/x64/lower.isle line 748. let expr0_0: u64 = 8; let expr1_0 = constructor_imm(ctx, pattern0_0, expr0_0)?; let expr2_0 = constructor_add(ctx, pattern0_0, expr1_0, pattern1_0)?; @@ -5113,21 +5334,21 @@ pub fn constructor_sse_and_not<C: Context>( if pattern0_0 == F32X4 { let pattern2_0 = arg1; let pattern3_0 = arg2; - // Rule at src/isa/x64/lower.isle line 1052. + // Rule at src/isa/x64/lower.isle line 1113. let expr0_0 = constructor_andnps(ctx, pattern2_0, pattern3_0)?; return Some(expr0_0); } if pattern0_0 == F64X2 { let pattern2_0 = arg1; let pattern3_0 = arg2; - // Rule at src/isa/x64/lower.isle line 1053. + // Rule at src/isa/x64/lower.isle line 1114. let expr0_0 = constructor_andnpd(ctx, pattern2_0, pattern3_0)?; return Some(expr0_0); } 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/lower.isle line 1054. + // Rule at src/isa/x64/lower.isle line 1115. let expr0_0 = constructor_pandn(ctx, pattern2_0, pattern3_0)?; return Some(expr0_0); } @@ -5137,7 +5358,7 @@ pub fn constructor_sse_and_not<C: Context>( // Generated as internal constructor for term i128_not. pub fn constructor_i128_not<C: Context>(ctx: &mut C, arg0: Value) -> Option<ValueRegs> { let pattern0_0 = arg0; - // Rule at src/isa/x64/lower.isle line 1117. + // Rule at src/isa/x64/lower.isle line 1178. let expr0_0 = C::put_in_regs(ctx, pattern0_0); let expr1_0: usize = 0; let expr2_0 = C::value_regs_get(ctx, expr0_0, expr1_0); @@ -5164,7 +5385,7 @@ pub fn constructor_vec_insert_lane<C: Context>( let pattern2_0 = arg1; let pattern3_0 = arg2; let pattern4_0 = arg3; - // Rule at src/isa/x64/lower.isle line 1171. + // Rule at src/isa/x64/lower.isle line 1232. let expr0_0 = constructor_pinsrb(ctx, pattern2_0, pattern3_0, pattern4_0)?; return Some(expr0_0); } @@ -5172,7 +5393,7 @@ pub fn constructor_vec_insert_lane<C: Context>( let pattern2_0 = arg1; let pattern3_0 = arg2; let pattern4_0 = arg3; - // Rule at src/isa/x64/lower.isle line 1174. + // Rule at src/isa/x64/lower.isle line 1235. let expr0_0 = constructor_pinsrw(ctx, pattern2_0, pattern3_0, pattern4_0)?; return Some(expr0_0); } @@ -5180,7 +5401,7 @@ pub fn constructor_vec_insert_lane<C: Context>( let pattern2_0 = arg1; let pattern3_0 = arg2; let pattern4_0 = arg3; - // Rule at src/isa/x64/lower.isle line 1177. + // Rule at src/isa/x64/lower.isle line 1238. let expr0_0 = OperandSize::Size32; let expr1_0 = constructor_pinsrd(ctx, pattern2_0, pattern3_0, pattern4_0, &expr0_0)?; return Some(expr1_0); @@ -5189,7 +5410,7 @@ pub fn constructor_vec_insert_lane<C: Context>( let pattern2_0 = arg1; let pattern3_0 = arg2; let pattern4_0 = arg3; - // Rule at src/isa/x64/lower.isle line 1180. + // Rule at src/isa/x64/lower.isle line 1241. let expr0_0 = OperandSize::Size64; let expr1_0 = constructor_pinsrd(ctx, pattern2_0, pattern3_0, pattern4_0, &expr0_0)?; return Some(expr1_0); @@ -5198,7 +5419,7 @@ pub fn constructor_vec_insert_lane<C: Context>( let pattern2_0 = arg1; let pattern3_0 = arg2; let pattern4_0 = arg3; - // Rule at src/isa/x64/lower.isle line 1183. + // Rule at src/isa/x64/lower.isle line 1244. let expr0_0 = C::sse_insertps_lane_imm(ctx, pattern4_0); let expr1_0 = constructor_insertps(ctx, pattern2_0, pattern3_0, expr0_0)?; return Some(expr1_0); @@ -5209,7 +5430,7 @@ pub fn constructor_vec_insert_lane<C: Context>( if let &RegMem::Reg { reg: pattern4_0 } = pattern3_0 { let pattern5_0 = arg3; if pattern5_0 == 0 { - // Rule at src/isa/x64/lower.isle line 1204. + // Rule at src/isa/x64/lower.isle line 1265. let expr0_0 = RegMem::Reg { reg: pattern4_0 }; let expr1_0 = constructor_movsd(ctx, pattern2_0, &expr0_0)?; return Some(expr1_0); @@ -5217,7 +5438,7 @@ pub fn constructor_vec_insert_lane<C: Context>( } let pattern4_0 = arg3; if pattern4_0 == 0 { - // Rule at src/isa/x64/lower.isle line 1205. + // Rule at src/isa/x64/lower.isle line 1266. let expr0_0 = SseOpcode::Movsd; let expr1_0 = constructor_xmm_unary_rm_r(ctx, &expr0_0, pattern3_0)?; let expr2_0 = RegMem::Reg { reg: expr1_0 }; @@ -5225,7 +5446,7 @@ pub fn constructor_vec_insert_lane<C: Context>( return Some(expr3_0); } if pattern4_0 == 1 { - // Rule at src/isa/x64/lower.isle line 1213. + // Rule at src/isa/x64/lower.isle line 1274. let expr0_0 = constructor_movlhps(ctx, pattern2_0, pattern3_0)?; return Some(expr0_0); } diff --git a/cranelift/codegen/src/machinst/isle.rs b/cranelift/codegen/src/machinst/isle.rs index 9763819a36d1..95541b057d57 100644 --- a/cranelift/codegen/src/machinst/isle.rs +++ b/cranelift/codegen/src/machinst/isle.rs @@ -100,6 +100,11 @@ macro_rules! isle_prelude_methods { ty.bits() } + #[inline] + fn ty_bytes(&mut self, ty: Type) -> u16 { + u16::try_from(ty.bytes()).unwrap() + } + fn fits_in_16(&mut self, ty: Type) -> Option<Type> { if ty.bits() <= 16 { Some(ty) diff --git a/cranelift/codegen/src/prelude.isle b/cranelift/codegen/src/prelude.isle index 585892b17dfd..96c5740b5d84 100644 --- a/cranelift/codegen/src/prelude.isle +++ b/cranelift/codegen/src/prelude.isle @@ -152,6 +152,10 @@ (decl ty_bits_u16 (Type) u16) (extern constructor ty_bits_u16 ty_bits_u16) +;; Get the byte width of a given type. +(decl ty_bytes (Type) u16) +(extern constructor ty_bytes ty_bytes) + ;; Get the type of each lane in the given type. (decl lane_type (Type) Type) (extern constructor lane_type lane_type)