#![allow(non_camel_case_types, unused_imports)]
use crate::codegen::{MachineBasicBlock, MachineFunction, MachineInstr, MachineOperand, VirtReg};
use crate::opcode::Opcode;
use crate::value::Value;
use crate::x86::x86_instr_info::X86Opcode;
use crate::x86::x86_register_info::*;
use crate::x86::x86_subtarget::X86Subtarget;
use std::collections::HashMap;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum Avx10Version {
V1,
V2,
}
impl Avx10Version {
pub fn as_u32(self) -> u32 {
match self {
Avx10Version::V1 => 1,
Avx10Version::V2 => 2,
}
}
pub fn has_512bit(self) -> bool {
true }
pub fn is_v2(self) -> bool {
matches!(self, Avx10Version::V2)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Avx10Features {
pub version: Avx10Version,
pub has_512bit: bool,
pub has_tcmm_fp16: bool,
pub has_tdpp_bf16: bool,
pub has_mps: bool,
pub has_converged_avx512: bool,
pub has_rounding_control: bool,
pub has_bf16: bool,
pub has_fp16: bool,
pub has_vnni: bool,
pub has_ifma: bool,
pub has_vbmi: bool,
pub has_bitalg: bool,
pub has_vpopcntdq: bool,
pub has_gfni: bool,
pub has_vaes: bool,
pub has_vpclmulqdq: bool,
}
impl Default for Avx10Features {
fn default() -> Self {
Self {
version: Avx10Version::V1,
has_512bit: false,
has_tcmm_fp16: false,
has_tdpp_bf16: false,
has_mps: false,
has_converged_avx512: true,
has_rounding_control: false,
has_bf16: false,
has_fp16: false,
has_vnni: false,
has_ifma: false,
has_vbmi: false,
has_bitalg: false,
has_vpopcntdq: false,
has_gfni: false,
has_vaes: false,
has_vpclmulqdq: false,
}
}
}
impl Avx10Features {
pub fn avx10_1_full() -> Self {
Self {
version: Avx10Version::V1,
has_512bit: true,
has_converged_avx512: true,
has_rounding_control: true,
has_bf16: true,
has_fp16: true,
has_vnni: true,
has_ifma: true,
has_vbmi: true,
has_bitalg: true,
has_vpopcntdq: true,
has_gfni: true,
has_vaes: true,
has_vpclmulqdq: true,
..Default::default()
}
}
pub fn avx10_2_full() -> Self {
let mut f = Self::avx10_1_full();
f.version = Avx10Version::V2;
f.has_tcmm_fp16 = true;
f.has_tdpp_bf16 = true;
f.has_mps = true;
f
}
pub fn avx10_e_core() -> Self {
let mut f = Self::avx10_1_full();
f.has_512bit = false;
f
}
pub fn has_feature(&self, feature: &str) -> bool {
match feature {
"avx512f" | "avx512cd" | "avx512bw" | "avx512dq" | "avx512vl" => {
self.has_converged_avx512
}
"avx512er" | "avx512pf" => self.has_rounding_control,
"avx512bf16" => self.has_bf16,
"avx512fp16" => self.has_fp16,
"avx512vnni" => self.has_vnni,
"avx512ifma" => self.has_ifma,
"avx512vbmi" | "avx512vbmi2" => self.has_vbmi,
"avx512bitalg" => self.has_bitalg,
"avx512vpopcntdq" => self.has_vpopcntdq,
"avx512gfni" => self.has_gfni,
"avx512vaes" => self.has_vaes,
"avx512vpclmulqdq" => self.has_vpclmulqdq,
"avx10_tcmm_fp16" => self.has_tcmm_fp16,
"avx10_tdpp_bf16" => self.has_tdpp_bf16,
"avx10_mps" => self.has_mps,
_ => false,
}
}
}
#[derive(Debug, Clone)]
pub struct Avx10VersionReport {
pub version: u32,
pub sub_version: u32,
pub supports_512bit: bool,
pub max_vector_bit_width: u32,
pub converged_features: Avx10Features,
pub raw_cpuid: [u32; 4],
}
impl Avx10VersionReport {
pub fn detect(version: Avx10Version, features: &Avx10Features) -> Self {
Avx10VersionReport {
version: version.as_u32(),
sub_version: 0,
supports_512bit: features.has_512bit,
max_vector_bit_width: if features.has_512bit { 512 } else { 256 },
converged_features: *features,
raw_cpuid: [0; 4],
}
}
pub fn report(&self) -> String {
format!(
"AVX10 version: {}.{}\n Max vector width: {} bits\n 512-bit: {}\n AVX10.2: {}",
self.version,
self.sub_version,
self.max_vector_bit_width,
self.supports_512bit,
self.converged_features.version.is_v2()
)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Avx10IselOpcode {
VAddPS512,
VAddPD512,
VSubPS512,
VSubPD512,
VMulPS512,
VMulPD512,
VDivPS512,
VDivPD512,
VPAddD512,
VPAddQ512,
VPSubD512,
VPSubQ512,
VPMulD512,
VPMulQ512,
VPAndD512,
VPAndQ512,
VPOrD512,
VPOrQ512,
VPXorD512,
VPXorQ512,
VPCmpD512,
VPCmpQ512,
VPCmpUD512,
VPCmpUQ512,
VAddPS512Mask,
VAddPD512Mask,
VSubPS512Mask,
VSubPD512Mask,
VMulPS512Mask,
VMulPD512Mask,
VPermD512,
VPermQ512,
VPermPS512,
VPermPD512,
VShufF32X4,
VShufF64X2,
VShufI32X4,
VShufI64X2,
VBlendMPS512,
VBlendMPD512,
VPBlendMD512,
VPBlendMQ512,
VBroadcastSS512,
VBroadcastSD512,
VBroadcastF32X4,
VBroadcastF64X2,
VBroadcastI32X4,
VBroadcastI64X2,
VExtractF32X4,
VExtractF64X2,
VExtractI32X4,
VExtractI64X2,
VInsertF32X4,
VInsertF64X2,
VInsertI32X4,
VInsertI64X2,
VPCompressD512,
VPCompressQ512,
VPExpandD512,
VPExpandQ512,
VPGatherDD512,
VPGatherDQ512,
VPGatherQD512,
VPGatherQQ512,
VPScatterDD512,
VPScatterDQ512,
VPScatterQD512,
VPScatterQQ512,
VPAddB512,
VPAddW512,
VPSubB512,
VPSubW512,
VPMulW512,
VPMulHW512,
VPMulHUW512,
VPMulHRSW512,
VPAndB512,
VPAndW512,
VPOrB512,
VPOrW512,
VPXorB512,
VPXorW512,
VPAddSB512,
VPAddSW512,
VPAddUSB512,
VPAddUSW512,
VPSubSB512,
VPSubSW512,
VPSubUSB512,
VPSubUSW512,
VPMinSB512,
VPMinSW512,
VPMaxSB512,
VPMaxSW512,
VPMinUB512,
VPMinUW512,
VPMaxUB512,
VPMaxUW512,
VPSllW512,
VPSllD512,
VPSllQ512,
VPSrlW512,
VPSrlD512,
VPSrlQ512,
VPSraW512,
VPSraD512,
VPSraQ512,
VPMovB2M512,
VPMovW2M512,
VPMovD2M512,
VPMovQ2M512,
VPMovM2B512,
VPMovM2W512,
VPMovM2D512,
VPMovM2Q512,
VAddPH512,
VSubPH512,
VMulPH512,
VDivPH512,
VFmaddPH512,
VFnmaddPH512,
VFmsubPH512,
VFnmsubPH512,
VMaxPH512,
VMinPH512,
VCvtPH2PS512,
VCvtPS2PH512,
VGetExpPH512,
VGetMantPH512,
VRndScalePH512,
VReducePH512,
VRSqrtPH512,
VRcpPH512,
VSqrtPH512,
VDPBF16PS512,
VCvtNE2PS2BF16_512,
VCvtNEEBF162PS512,
VFnmaddBF16512,
VFmsubBF16512,
VFmaddBF16512,
VPDpBusd512,
VPDpBussd512,
VPDpWssd512,
VPDpWssds512,
VPDpBusds512,
VPDpWssd512_v2,
VPDpBf16Ps512,
VPMadd52LUQ512,
VPMadd52HUQ512,
VPermB512,
VPermW512,
VPermI2B512,
VPermI2W512,
VPMultishiftQB512,
VPExpandB512,
VPExpandW512,
VPCompressB512,
VPCompressW512,
TCMMRLFP16x,
TCMMILFP16x,
TCMMRLFP16x_512,
TCMMILFP16x_512,
TDPPxBF16x,
TDPPxBF16x_512,
VMPSMulW512,
VMPSMulD512,
VMPSAddW512,
VMPSAddD512,
VMPSSubW512,
VMPSSubD512,
VFmaddCPH512,
VFmsubCPH512,
VPMaddCWD512,
VPMaddCSWD512,
VAddPS512_RN,
VAddPD512_RN,
VMulPS512_RN,
VMulPD512_RN,
VFmaddPS512_RN,
VFmaddPD512_RN,
VAddPS512_RU,
VAddPD512_RU,
VMulPS512_RU,
VMulPD512_RU,
VFmaddPS512_RU,
VFmaddPD512_RU,
VAddPS512_RD,
VAddPD512_RD,
VMulPS512_RD,
VMulPD512_RD,
VFmaddPS512_RD,
VFmaddPD512_RD,
VAddPS512_RZ,
VAddPD512_RZ,
VMulPS512_RZ,
VMulPD512_RZ,
VFmaddPS512_RZ,
VFmaddPD512_RZ,
VAddPS512_SAE,
VAddPD512_SAE,
VMulPS512_SAE,
VMulPD512_SAE,
VFmaddPS512_SAE,
VFmaddPD512_SAE,
VAddPS256,
VAddPD256,
VSubPS256,
VSubPD256,
VMulPS256,
VMulPD256,
VDivPS256,
VDivPD256,
VPAddD256,
VPAddQ256,
VPSubD256,
VPSubQ256,
VPMulD256,
VPMulQ256,
VPAndD256,
VPAndQ256,
VPOrD256,
VPOrQ256,
VPXorD256,
VPXorQ256,
VAddPH256,
VSubPH256,
VMulPH256,
VFmaddPH256,
}
pub fn avx10_isel_to_x86_opcode(op: Avx10IselOpcode) -> X86Opcode {
match op {
Avx10IselOpcode::VAddPS512 | Avx10IselOpcode::VAddPS256 => X86Opcode::VADDPS,
Avx10IselOpcode::VAddPD512 | Avx10IselOpcode::VAddPD256 => X86Opcode::VADDPD,
Avx10IselOpcode::VSubPS512 | Avx10IselOpcode::VSubPS256 => X86Opcode::VSUBPS,
Avx10IselOpcode::VSubPD512 | Avx10IselOpcode::VSubPD256 => X86Opcode::VSUBPD,
Avx10IselOpcode::VMulPS512 | Avx10IselOpcode::VMulPS256 => X86Opcode::VMULPS,
Avx10IselOpcode::VMulPD512 | Avx10IselOpcode::VMulPD256 => X86Opcode::VMULPD,
Avx10IselOpcode::VDivPS512 | Avx10IselOpcode::VDivPS256 => X86Opcode::VDIVPS,
Avx10IselOpcode::VDivPD512 | Avx10IselOpcode::VDivPD256 => X86Opcode::VDIVPD,
Avx10IselOpcode::VPAddD512 => X86Opcode::VADDPS, Avx10IselOpcode::VPAddQ512 => X86Opcode::VADDPD,
Avx10IselOpcode::VPSubD512 => X86Opcode::VSUBPS,
Avx10IselOpcode::VPSubQ512 => X86Opcode::VSUBPD,
Avx10IselOpcode::VPMulD512 => X86Opcode::VMULPS,
Avx10IselOpcode::VPMulQ512 => X86Opcode::VMULPD,
Avx10IselOpcode::VPAndD512 => X86Opcode::VANDPS,
Avx10IselOpcode::VPAndQ512 => X86Opcode::VANDPD,
Avx10IselOpcode::VPOrD512 => X86Opcode::VORPS,
Avx10IselOpcode::VPOrQ512 => X86Opcode::VORPD,
Avx10IselOpcode::VPXorD512 => X86Opcode::VXORPS,
Avx10IselOpcode::VPXorQ512 => X86Opcode::VXORPD,
Avx10IselOpcode::VAddPS512Mask
| Avx10IselOpcode::VAddPS512_RN
| Avx10IselOpcode::VAddPS512_RU
| Avx10IselOpcode::VAddPS512_RD
| Avx10IselOpcode::VAddPS512_RZ
| Avx10IselOpcode::VAddPS512_SAE => X86Opcode::VADDPS,
Avx10IselOpcode::VAddPD512Mask
| Avx10IselOpcode::VAddPD512_RN
| Avx10IselOpcode::VAddPD512_RU
| Avx10IselOpcode::VAddPD512_RD
| Avx10IselOpcode::VAddPD512_RZ
| Avx10IselOpcode::VAddPD512_SAE => X86Opcode::VADDPD,
Avx10IselOpcode::VMulPS512Mask
| Avx10IselOpcode::VMulPS512_RN
| Avx10IselOpcode::VMulPS512_RU
| Avx10IselOpcode::VMulPS512_RD
| Avx10IselOpcode::VMulPS512_RZ
| Avx10IselOpcode::VMulPS512_SAE => X86Opcode::VMULPS,
Avx10IselOpcode::VMulPD512Mask
| Avx10IselOpcode::VMulPD512_RN
| Avx10IselOpcode::VMulPD512_RU
| Avx10IselOpcode::VMulPD512_RD
| Avx10IselOpcode::VMulPD512_RZ
| Avx10IselOpcode::VMulPD512_SAE => X86Opcode::VMULPD,
Avx10IselOpcode::VSubPS512Mask => X86Opcode::VSUBPS,
Avx10IselOpcode::VSubPD512Mask => X86Opcode::VSUBPD,
Avx10IselOpcode::VPermD512 => X86Opcode::VPERMQ,
Avx10IselOpcode::VPermQ512 => X86Opcode::VPERMQ,
Avx10IselOpcode::VPermPS512 => X86Opcode::VPERMILPS,
Avx10IselOpcode::VPermPD512 => X86Opcode::VPERMPD,
Avx10IselOpcode::VShufF32X4 | Avx10IselOpcode::VShufI32X4 => X86Opcode::SHUFPS,
Avx10IselOpcode::VShufF64X2 | Avx10IselOpcode::VShufI64X2 => X86Opcode::SHUFPD,
Avx10IselOpcode::VBlendMPS512 => X86Opcode::BLENDPS,
Avx10IselOpcode::VBlendMPD512 => X86Opcode::BLENDPD,
Avx10IselOpcode::VPBlendMD512 => X86Opcode::BLENDPS,
Avx10IselOpcode::VPBlendMQ512 => X86Opcode::BLENDPD,
Avx10IselOpcode::VBroadcastSS512 => X86Opcode::VBROADCASTSS,
Avx10IselOpcode::VBroadcastSD512 => X86Opcode::VBROADCASTSD,
Avx10IselOpcode::VBroadcastF32X4 => X86Opcode::VBROADCASTSS,
Avx10IselOpcode::VBroadcastF64X2 => X86Opcode::VBROADCASTSD,
Avx10IselOpcode::VBroadcastI32X4 => X86Opcode::VPBROADCASTD,
Avx10IselOpcode::VBroadcastI64X2 => X86Opcode::VPBROADCASTQ,
Avx10IselOpcode::VExtractF32X4 | Avx10IselOpcode::VExtractI32X4 => X86Opcode::EXTRACTPS,
Avx10IselOpcode::VExtractF64X2 | Avx10IselOpcode::VExtractI64X2 => X86Opcode::EXTRACTPS,
Avx10IselOpcode::VInsertF32X4 | Avx10IselOpcode::VInsertI32X4 => X86Opcode::INSERTPS,
Avx10IselOpcode::VInsertF64X2 | Avx10IselOpcode::VInsertI64X2 => X86Opcode::INSERTPS,
Avx10IselOpcode::VPGatherDD512 => X86Opcode::VPGATHERDD,
Avx10IselOpcode::VPGatherDQ512 => X86Opcode::VPGATHERDQ,
Avx10IselOpcode::VPGatherQD512 => X86Opcode::VPGATHERQD,
Avx10IselOpcode::VPGatherQQ512 => X86Opcode::VPGATHERQQ,
Avx10IselOpcode::VPAddB512 => X86Opcode::VADDPS,
Avx10IselOpcode::VPAddW512 => X86Opcode::VADDPS,
Avx10IselOpcode::VPSubB512 => X86Opcode::VSUBPS,
Avx10IselOpcode::VPSubW512 => X86Opcode::VSUBPS,
Avx10IselOpcode::VPMulW512 => X86Opcode::VMULPS,
Avx10IselOpcode::VPMulHW512 => X86Opcode::VMULPS,
Avx10IselOpcode::VPMulHUW512 => X86Opcode::VMULPS,
Avx10IselOpcode::VPMulHRSW512 => X86Opcode::VMULPS,
Avx10IselOpcode::VPAndB512 => X86Opcode::VANDPS,
Avx10IselOpcode::VPAndW512 => X86Opcode::VANDPS,
Avx10IselOpcode::VPOrB512 => X86Opcode::VORPS,
Avx10IselOpcode::VPOrW512 => X86Opcode::VORPS,
Avx10IselOpcode::VPXorB512 => X86Opcode::VXORPS,
Avx10IselOpcode::VPXorW512 => X86Opcode::VXORPS,
Avx10IselOpcode::VPAddSB512
| Avx10IselOpcode::VPAddSW512
| Avx10IselOpcode::VPAddUSB512
| Avx10IselOpcode::VPAddUSW512 => X86Opcode::VADDPS,
Avx10IselOpcode::VPSubSB512
| Avx10IselOpcode::VPSubSW512
| Avx10IselOpcode::VPSubUSB512
| Avx10IselOpcode::VPSubUSW512 => X86Opcode::VSUBPS,
Avx10IselOpcode::VPMinSB512
| Avx10IselOpcode::VPMinSW512
| Avx10IselOpcode::VPMinUB512
| Avx10IselOpcode::VPMinUW512 => X86Opcode::MINSS,
Avx10IselOpcode::VPMaxSB512
| Avx10IselOpcode::VPMaxSW512
| Avx10IselOpcode::VPMaxUB512
| Avx10IselOpcode::VPMaxUW512 => X86Opcode::MAXSS,
Avx10IselOpcode::VPSllW512 | Avx10IselOpcode::VPSllD512 | Avx10IselOpcode::VPSllQ512 => {
X86Opcode::SHL
}
Avx10IselOpcode::VPSrlW512 | Avx10IselOpcode::VPSrlD512 | Avx10IselOpcode::VPSrlQ512 => {
X86Opcode::SHR
}
Avx10IselOpcode::VPSraW512 | Avx10IselOpcode::VPSraD512 | Avx10IselOpcode::VPSraQ512 => {
X86Opcode::SAR
}
Avx10IselOpcode::VAddPH512 | Avx10IselOpcode::VAddPH256 => X86Opcode::VADDPS,
Avx10IselOpcode::VSubPH512 | Avx10IselOpcode::VSubPH256 => X86Opcode::VSUBPS,
Avx10IselOpcode::VMulPH512 | Avx10IselOpcode::VMulPH256 => X86Opcode::VMULPS,
Avx10IselOpcode::VDivPH512 => X86Opcode::VDIVPS,
Avx10IselOpcode::VFmaddPH512
| Avx10IselOpcode::VFmaddPH256
| Avx10IselOpcode::VFmaddPS512_RN
| Avx10IselOpcode::VFmaddPS512_RU
| Avx10IselOpcode::VFmaddPS512_RD
| Avx10IselOpcode::VFmaddPS512_RZ
| Avx10IselOpcode::VFmaddPS512_SAE => X86Opcode::VFMADD231PS,
Avx10IselOpcode::VFnmaddPH512 => X86Opcode::VFMADD231PS,
Avx10IselOpcode::VFmsubPH512 => X86Opcode::VFMSUB231PS,
Avx10IselOpcode::VFnmsubPH512 => X86Opcode::VFNMSUB231PS,
Avx10IselOpcode::VFmaddPD512_RN
| Avx10IselOpcode::VFmaddPD512_RU
| Avx10IselOpcode::VFmaddPD512_RD
| Avx10IselOpcode::VFmaddPD512_RZ
| Avx10IselOpcode::VFmaddPD512_SAE => X86Opcode::VFMADD231PD,
Avx10IselOpcode::VMaxPH512 => X86Opcode::MAXSS,
Avx10IselOpcode::VMinPH512 => X86Opcode::MINSS,
Avx10IselOpcode::VCvtPH2PS512 => X86Opcode::CVTSS2SD,
Avx10IselOpcode::VCvtPS2PH512 => X86Opcode::CVTSD2SS,
Avx10IselOpcode::VGetExpPH512 => X86Opcode::SQRTSS,
Avx10IselOpcode::VGetMantPH512 => X86Opcode::SQRTSS,
Avx10IselOpcode::VRndScalePH512 => X86Opcode::SQRTSS,
Avx10IselOpcode::VReducePH512 => X86Opcode::SQRTSS,
Avx10IselOpcode::VRSqrtPH512 => X86Opcode::RSQRTPS,
Avx10IselOpcode::VRcpPH512 => X86Opcode::RCPPS,
Avx10IselOpcode::VSqrtPH512 => X86Opcode::SQRTPS,
Avx10IselOpcode::VDPBF16PS512 | Avx10IselOpcode::VPDpBf16Ps512 => X86Opcode::MULPS,
Avx10IselOpcode::VCvtNE2PS2BF16_512 => X86Opcode::CVTPS2DQ,
Avx10IselOpcode::VCvtNEEBF162PS512 => X86Opcode::CVTDQ2PS,
Avx10IselOpcode::VFnmaddBF16512
| Avx10IselOpcode::VFmsubBF16512
| Avx10IselOpcode::VFmaddBF16512 => X86Opcode::VFMADD231PS,
Avx10IselOpcode::VPDpBusd512
| Avx10IselOpcode::VPDpBussd512
| Avx10IselOpcode::VPDpWssd512
| Avx10IselOpcode::VPDpWssds512
| Avx10IselOpcode::VPDpBusds512
| Avx10IselOpcode::VPDpWssd512_v2 => X86Opcode::MULPS,
Avx10IselOpcode::VPMadd52LUQ512 | Avx10IselOpcode::VPMadd52HUQ512 => X86Opcode::MULPS,
Avx10IselOpcode::VPermB512 | Avx10IselOpcode::VPermI2B512 => X86Opcode::PSHUFD,
Avx10IselOpcode::VPermW512 | Avx10IselOpcode::VPermI2W512 => X86Opcode::PSHUFD,
Avx10IselOpcode::VPMultishiftQB512 => X86Opcode::AND,
Avx10IselOpcode::VPExpandB512 | Avx10IselOpcode::VPExpandW512 => X86Opcode::AND,
Avx10IselOpcode::VPCompressB512 | Avx10IselOpcode::VPCompressW512 => X86Opcode::AND,
Avx10IselOpcode::VPCompressD512 | Avx10IselOpcode::VPCompressQ512 => X86Opcode::AND,
Avx10IselOpcode::VPExpandD512 | Avx10IselOpcode::VPExpandQ512 => X86Opcode::AND,
Avx10IselOpcode::VPMovB2M512
| Avx10IselOpcode::VPMovW2M512
| Avx10IselOpcode::VPMovD2M512
| Avx10IselOpcode::VPMovQ2M512 => X86Opcode::MOV,
Avx10IselOpcode::VPMovM2B512
| Avx10IselOpcode::VPMovM2W512
| Avx10IselOpcode::VPMovM2D512
| Avx10IselOpcode::VPMovM2Q512 => X86Opcode::MOV,
Avx10IselOpcode::TCMMRLFP16x
| Avx10IselOpcode::TCMMILFP16x
| Avx10IselOpcode::TCMMRLFP16x_512
| Avx10IselOpcode::TCMMILFP16x_512 => X86Opcode::VFMADD231PS,
Avx10IselOpcode::TDPPxBF16x | Avx10IselOpcode::TDPPxBF16x_512 => X86Opcode::VMULPS,
Avx10IselOpcode::VMPSMulW512 | Avx10IselOpcode::VMPSMulD512 => X86Opcode::VMULPS,
Avx10IselOpcode::VMPSAddW512 | Avx10IselOpcode::VMPSAddD512 => X86Opcode::VADDPS,
Avx10IselOpcode::VMPSSubW512 | Avx10IselOpcode::VMPSSubD512 => X86Opcode::VSUBPS,
Avx10IselOpcode::VFmaddCPH512 => X86Opcode::VFMADD231PS,
Avx10IselOpcode::VFmsubCPH512 => X86Opcode::VFMSUB231PS,
Avx10IselOpcode::VPMaddCWD512 | Avx10IselOpcode::VPMaddCSWD512 => X86Opcode::MULPS,
Avx10IselOpcode::VAddPS256 => X86Opcode::VADDPS,
Avx10IselOpcode::VAddPD256 => X86Opcode::VADDPD,
Avx10IselOpcode::VSubPS256 => X86Opcode::VSUBPS,
Avx10IselOpcode::VSubPD256 => X86Opcode::VSUBPD,
Avx10IselOpcode::VMulPS256 => X86Opcode::VMULPS,
Avx10IselOpcode::VMulPD256 => X86Opcode::VMULPD,
Avx10IselOpcode::VDivPS256 => X86Opcode::VDIVPS,
Avx10IselOpcode::VDivPD256 => X86Opcode::VDIVPD,
Avx10IselOpcode::VPAddD256 => X86Opcode::VADDPS,
Avx10IselOpcode::VPAddQ256 => X86Opcode::VADDPD,
Avx10IselOpcode::VPSubD256 => X86Opcode::VSUBPS,
Avx10IselOpcode::VPSubQ256 => X86Opcode::VSUBPD,
Avx10IselOpcode::VPMulD256 => X86Opcode::VMULPS,
Avx10IselOpcode::VPMulQ256 => X86Opcode::VMULPD,
Avx10IselOpcode::VPAndD256 => X86Opcode::VANDPS,
Avx10IselOpcode::VPAndQ256 => X86Opcode::VANDPD,
Avx10IselOpcode::VPOrD256 => X86Opcode::VORPS,
Avx10IselOpcode::VPOrQ256 => X86Opcode::VORPD,
Avx10IselOpcode::VPXorD256 => X86Opcode::VXORPS,
Avx10IselOpcode::VPXorQ256 => X86Opcode::VXORPD,
Avx10IselOpcode::VSubPH256 => X86Opcode::VSUBPS,
Avx10IselOpcode::VPCmpD512
| Avx10IselOpcode::VPCmpQ512
| Avx10IselOpcode::VPCmpUD512
| Avx10IselOpcode::VPCmpUQ512 => X86Opcode::CMP,
Avx10IselOpcode::VPScatterDD512
| Avx10IselOpcode::VPScatterDQ512
| Avx10IselOpcode::VPScatterQD512
| Avx10IselOpcode::VPScatterQQ512 => X86Opcode::MOV,
}
}
#[derive(Debug, Clone)]
pub struct Avx10IselPattern {
pub ir_opcode: Opcode,
pub description: &'static str,
pub result_opcode: Avx10IselOpcode,
pub priority: u32,
pub num_src_operands: u8,
pub is_512bit: bool,
pub is_masked: bool,
pub required_feature: Option<&'static str>,
pub min_avx10_version: Avx10Version,
pub rounding_mode: Option<Avx10RoundingMode>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Avx10RoundingMode {
RN,
RD,
RU,
RZ,
SAE,
}
impl Avx10RoundingMode {
pub fn encode(self) -> u8 {
match self {
Avx10RoundingMode::RN => 0b00,
Avx10RoundingMode::RD => 0b01,
Avx10RoundingMode::RU => 0b10,
Avx10RoundingMode::RZ => 0b11,
Avx10RoundingMode::SAE => 0b00, }
}
}
pub struct Avx10IselTable {
pub patterns: Vec<Avx10IselPattern>,
pub total_patterns: usize,
pub patterns_512bit: usize,
pub patterns_256bit: usize,
pub patterns_masked: usize,
pub patterns_avx10_2: usize,
pub patterns_rounding: usize,
}
pub fn avx10_isel_table() -> Vec<Avx10IselPattern> {
let mut table = Vec::new();
table.push(Avx10IselPattern {
ir_opcode: Opcode::FAdd,
description: "vaddps zmm, zmm, zmm — AVX10 512-bit packed SP add",
result_opcode: Avx10IselOpcode::VAddPS512,
priority: 100,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::FAdd,
description: "vaddpd zmm, zmm, zmm — AVX10 512-bit packed DP add",
result_opcode: Avx10IselOpcode::VAddPD512,
priority: 101,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::FSub,
description: "vsubps zmm, zmm, zmm — AVX10 512-bit packed SP sub",
result_opcode: Avx10IselOpcode::VSubPS512,
priority: 100,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::FSub,
description: "vsubpd zmm, zmm, zmm — AVX10 512-bit packed DP sub",
result_opcode: Avx10IselOpcode::VSubPD512,
priority: 101,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::FMul,
description: "vmulps zmm, zmm, zmm — AVX10 512-bit packed SP mul",
result_opcode: Avx10IselOpcode::VMulPS512,
priority: 100,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::FMul,
description: "vmulpd zmm, zmm, zmm — AVX10 512-bit packed DP mul",
result_opcode: Avx10IselOpcode::VMulPD512,
priority: 101,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::FDiv,
description: "vdivps zmm, zmm, zmm — AVX10 512-bit packed SP div",
result_opcode: Avx10IselOpcode::VDivPS512,
priority: 100,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::FDiv,
description: "vdivpd zmm, zmm, zmm — AVX10 512-bit packed DP div",
result_opcode: Avx10IselOpcode::VDivPD512,
priority: 101,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::FAdd,
description: "vaddps zmm{k1}, zmm, zmm — AVX10 512-bit masked SP add",
result_opcode: Avx10IselOpcode::VAddPS512Mask,
priority: 200,
num_src_operands: 3,
is_512bit: true,
is_masked: true,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::FAdd,
description: "vaddpd zmm{k1}, zmm, zmm — AVX10 512-bit masked DP add",
result_opcode: Avx10IselOpcode::VAddPD512Mask,
priority: 201,
num_src_operands: 3,
is_512bit: true,
is_masked: true,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::FSub,
description: "vsubps zmm{k1}, zmm, zmm — AVX10 512-bit masked SP sub",
result_opcode: Avx10IselOpcode::VSubPS512Mask,
priority: 200,
num_src_operands: 3,
is_512bit: true,
is_masked: true,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::FSub,
description: "vsubpd zmm{k1}, zmm, zmm — AVX10 512-bit masked DP sub",
result_opcode: Avx10IselOpcode::VSubPD512Mask,
priority: 201,
num_src_operands: 3,
is_512bit: true,
is_masked: true,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::FMul,
description: "vmulps zmm{k1}, zmm, zmm — AVX10 512-bit masked SP mul",
result_opcode: Avx10IselOpcode::VMulPS512Mask,
priority: 200,
num_src_operands: 3,
is_512bit: true,
is_masked: true,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::FMul,
description: "vmulpd zmm{k1}, zmm, zmm — AVX10 512-bit masked DP mul",
result_opcode: Avx10IselOpcode::VMulPD512Mask,
priority: 201,
num_src_operands: 3,
is_512bit: true,
is_masked: true,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Add,
description: "vpaddd zmm, zmm, zmm — AVX10 512-bit packed int32 add",
result_opcode: Avx10IselOpcode::VPAddD512,
priority: 100,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Add,
description: "vpaddq zmm, zmm, zmm — AVX10 512-bit packed int64 add",
result_opcode: Avx10IselOpcode::VPAddQ512,
priority: 101,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Sub,
description: "vpsubd zmm, zmm, zmm — AVX10 512-bit packed int32 sub",
result_opcode: Avx10IselOpcode::VPSubD512,
priority: 100,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Sub,
description: "vpsubq zmm, zmm, zmm — AVX10 512-bit packed int64 sub",
result_opcode: Avx10IselOpcode::VPSubQ512,
priority: 101,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Mul,
description: "vpmulld zmm, zmm, zmm — AVX10 512-bit packed int32 mul",
result_opcode: Avx10IselOpcode::VPMulD512,
priority: 100,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Mul,
description: "vpmullq zmm, zmm, zmm — AVX10 512-bit packed int64 mul",
result_opcode: Avx10IselOpcode::VPMulQ512,
priority: 101,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::And,
description: "vpandd zmm, zmm, zmm — AVX10 512-bit packed int32 and",
result_opcode: Avx10IselOpcode::VPAndD512,
priority: 100,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Or,
description: "vpord zmm, zmm, zmm — AVX10 512-bit packed int32 or",
result_opcode: Avx10IselOpcode::VPOrD512,
priority: 100,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Xor,
description: "vpxord zmm, zmm, zmm — AVX10 512-bit packed int32 xor",
result_opcode: Avx10IselOpcode::VPXorD512,
priority: 100,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Add,
description: "vpaddb zmm, zmm, zmm — AVX10 512-bit packed int8 add",
result_opcode: Avx10IselOpcode::VPAddB512,
priority: 110,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_bw"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Add,
description: "vpaddw zmm, zmm, zmm — AVX10 512-bit packed int16 add",
result_opcode: Avx10IselOpcode::VPAddW512,
priority: 111,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_bw"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Sub,
description: "vpsubb zmm, zmm, zmm — AVX10 512-bit packed int8 sub",
result_opcode: Avx10IselOpcode::VPSubB512,
priority: 110,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_bw"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Sub,
description: "vpsubw zmm, zmm, zmm — AVX10 512-bit packed int16 sub",
result_opcode: Avx10IselOpcode::VPSubW512,
priority: 111,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_bw"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Add,
description: "vpaddsb zmm, zmm, zmm — AVX10 512-bit saturating signed int8 add",
result_opcode: Avx10IselOpcode::VPAddSB512,
priority: 120,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_bw"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Add,
description: "vpaddsw zmm, zmm, zmm — AVX10 512-bit saturating signed int16 add",
result_opcode: Avx10IselOpcode::VPAddSW512,
priority: 121,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_bw"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Add,
description: "vpaddusb zmm, zmm, zmm — AVX10 512-bit saturating unsigned int8 add",
result_opcode: Avx10IselOpcode::VPAddUSB512,
priority: 122,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_bw"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Add,
description: "vpaddusw zmm, zmm, zmm — AVX10 512-bit saturating unsigned int16 add",
result_opcode: Avx10IselOpcode::VPAddUSW512,
priority: 123,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_bw"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Sub,
description: "vpsubsb zmm, zmm, zmm — AVX10 512-bit saturating signed int8 sub",
result_opcode: Avx10IselOpcode::VPSubSB512,
priority: 120,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_bw"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Sub,
description: "vpsubsw zmm, zmm, zmm — AVX10 512-bit saturating signed int16 sub",
result_opcode: Avx10IselOpcode::VPSubSW512,
priority: 121,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_bw"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Sub,
description: "vpsubusb zmm, zmm, zmm — AVX10 512-bit saturating unsigned int8 sub",
result_opcode: Avx10IselOpcode::VPSubUSB512,
priority: 122,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_bw"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Sub,
description: "vpsubusw zmm, zmm, zmm — AVX10 512-bit saturating unsigned int16 sub",
result_opcode: Avx10IselOpcode::VPSubUSW512,
priority: 123,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_bw"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::ICmp,
description: "vpminsb zmm, zmm, zmm — AVX10 512-bit signed int8 min",
result_opcode: Avx10IselOpcode::VPMinSB512,
priority: 130,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_bw"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::ICmp,
description: "vpmaxsb zmm, zmm, zmm — AVX10 512-bit signed int8 max",
result_opcode: Avx10IselOpcode::VPMaxSB512,
priority: 131,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_bw"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::ICmp,
description: "vpminub zmm, zmm, zmm — AVX10 512-bit unsigned int8 min",
result_opcode: Avx10IselOpcode::VPMinUB512,
priority: 132,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_bw"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::ICmp,
description: "vpmaxub zmm, zmm, zmm — AVX10 512-bit unsigned int8 max",
result_opcode: Avx10IselOpcode::VPMaxUB512,
priority: 133,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_bw"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::ICmp,
description: "vpminsw zmm, zmm, zmm — AVX10 512-bit signed int16 min",
result_opcode: Avx10IselOpcode::VPMinSW512,
priority: 134,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_bw"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::ICmp,
description: "vpmaxsw zmm, zmm, zmm — AVX10 512-bit signed int16 max",
result_opcode: Avx10IselOpcode::VPMaxSW512,
priority: 135,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_bw"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::ICmp,
description: "vpminuw zmm, zmm, zmm — AVX10 512-bit unsigned int16 min",
result_opcode: Avx10IselOpcode::VPMinUW512,
priority: 136,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_bw"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::ICmp,
description: "vpmaxuw zmm, zmm, zmm — AVX10 512-bit unsigned int16 max",
result_opcode: Avx10IselOpcode::VPMaxUW512,
priority: 137,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_bw"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::ShuffleVector,
description: "vpermq zmm, zmm, imm8 — AVX10 512-bit qword permute",
result_opcode: Avx10IselOpcode::VPermQ512,
priority: 100,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::ShuffleVector,
description: "vpermd zmm, zmm, zmm — AVX10 512-bit dword permute",
result_opcode: Avx10IselOpcode::VPermD512,
priority: 101,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::ShuffleVector,
description: "vshuff32x4 zmm, zmm, zmm, imm8 — AVX10 512-bit shuffle f32x4",
result_opcode: Avx10IselOpcode::VShufF32X4,
priority: 102,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::ShuffleVector,
description: "vshuff64x2 zmm, zmm, zmm, imm8 — AVX10 512-bit shuffle f64x2",
result_opcode: Avx10IselOpcode::VShufF64X2,
priority: 103,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::ShuffleVector,
description: "vshufi32x4 zmm, zmm, zmm, imm8 — AVX10 512-bit shuffle i32x4",
result_opcode: Avx10IselOpcode::VShufI32X4,
priority: 104,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::ShuffleVector,
description: "vshufi64x2 zmm, zmm, zmm, imm8 — AVX10 512-bit shuffle i64x2",
result_opcode: Avx10IselOpcode::VShufI64X2,
priority: 105,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Select,
description: "vblendmps zmm{k1}, zmm, zmm — AVX10 512-bit masked blend PS",
result_opcode: Avx10IselOpcode::VBlendMPS512,
priority: 100,
num_src_operands: 3,
is_512bit: true,
is_masked: true,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Select,
description: "vblendmpd zmm{k1}, zmm, zmm — AVX10 512-bit masked blend PD",
result_opcode: Avx10IselOpcode::VBlendMPD512,
priority: 101,
num_src_operands: 3,
is_512bit: true,
is_masked: true,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Select,
description: "vpblendmd zmm{k1}, zmm, zmm — AVX10 512-bit masked blend D",
result_opcode: Avx10IselOpcode::VPBlendMD512,
priority: 102,
num_src_operands: 3,
is_512bit: true,
is_masked: true,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Select,
description: "vpblendmq zmm{k1}, zmm, zmm — AVX10 512-bit masked blend Q",
result_opcode: Avx10IselOpcode::VPBlendMQ512,
priority: 103,
num_src_operands: 3,
is_512bit: true,
is_masked: true,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::InsertElement,
description: "vbroadcastss zmm, xmm — AVX10 512-bit broadcast float32",
result_opcode: Avx10IselOpcode::VBroadcastSS512,
priority: 100,
num_src_operands: 1,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::InsertElement,
description: "vbroadcastsd zmm, xmm — AVX10 512-bit broadcast float64",
result_opcode: Avx10IselOpcode::VBroadcastSD512,
priority: 101,
num_src_operands: 1,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::InsertElement,
description: "vbroadcasti32x4 zmm, mem128 — AVX10 512-bit broadcast 4×i32",
result_opcode: Avx10IselOpcode::VBroadcastI32X4,
priority: 102,
num_src_operands: 1,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::InsertElement,
description: "vbroadcasti64x2 zmm, mem128 — AVX10 512-bit broadcast 2×i64",
result_opcode: Avx10IselOpcode::VBroadcastI64X2,
priority: 103,
num_src_operands: 1,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::ExtractElement,
description: "vextractf32x4 xmm, zmm, imm8 — AVX10 extract 128-bit float32 from 512-bit",
result_opcode: Avx10IselOpcode::VExtractF32X4,
priority: 100,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::ExtractElement,
description: "vextractf64x2 xmm, zmm, imm8 — AVX10 extract 128-bit float64 from 512-bit",
result_opcode: Avx10IselOpcode::VExtractF64X2,
priority: 101,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::ExtractElement,
description: "vextracti32x4 xmm, zmm, imm8 — AVX10 extract 128-bit int32 from 512-bit",
result_opcode: Avx10IselOpcode::VExtractI32X4,
priority: 102,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::InsertElement,
description: "vinsertf32x4 zmm, zmm, xmm, imm8 — AVX10 insert 128-bit float32 into 512-bit",
result_opcode: Avx10IselOpcode::VInsertF32X4,
priority: 104,
num_src_operands: 3,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::InsertElement,
description: "vinsertf64x2 zmm, zmm, xmm, imm8 — AVX10 insert 128-bit float64 into 512-bit",
result_opcode: Avx10IselOpcode::VInsertF64X2,
priority: 105,
num_src_operands: 3,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Load,
description: "vpgatherdd zmm, [base+zmm*scale] — AVX10 512-bit gather dword to dword",
result_opcode: Avx10IselOpcode::VPGatherDD512,
priority: 100,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Load,
description: "vpgatherdq zmm, [base+ymm*scale] — AVX10 512-bit gather dword to qword",
result_opcode: Avx10IselOpcode::VPGatherDQ512,
priority: 101,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Load,
description: "vpgatherqd xmm, [base+zmm*scale] — AVX10 512-bit gather qword to dword",
result_opcode: Avx10IselOpcode::VPGatherQD512,
priority: 102,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Load,
description: "vpgatherqq zmm, [base+zmm*scale] — AVX10 512-bit gather qword to qword",
result_opcode: Avx10IselOpcode::VPGatherQQ512,
priority: 103,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Store,
description: "vpscatterdd [base+zmm*scale], zmm — AVX10 512-bit scatter dword",
result_opcode: Avx10IselOpcode::VPScatterDD512,
priority: 100,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Store,
description: "vpscatterdq [base+ymm*scale], zmm — AVX10 512-bit scatter dword to qword ptr",
result_opcode: Avx10IselOpcode::VPScatterDQ512,
priority: 101,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Store,
description: "vpscatterqd [base+zmm*scale], xmm — AVX10 512-bit scatter qword ptr to dword",
result_opcode: Avx10IselOpcode::VPScatterQD512,
priority: 102,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Store,
description: "vpscatterqq [base+zmm*scale], zmm — AVX10 512-bit scatter qword to qword ptr",
result_opcode: Avx10IselOpcode::VPScatterQQ512,
priority: 103,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::FAdd,
description: "vaddph zmm, zmm, zmm — AVX10 FP16 512-bit packed add",
result_opcode: Avx10IselOpcode::VAddPH512,
priority: 150,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_fp16"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::FSub,
description: "vsubph zmm, zmm, zmm — AVX10 FP16 512-bit packed sub",
result_opcode: Avx10IselOpcode::VSubPH512,
priority: 150,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_fp16"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::FMul,
description: "vmulph zmm, zmm, zmm — AVX10 FP16 512-bit packed mul",
result_opcode: Avx10IselOpcode::VMulPH512,
priority: 150,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_fp16"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::FDiv,
description: "vdivph zmm, zmm, zmm — AVX10 FP16 512-bit packed div",
result_opcode: Avx10IselOpcode::VDivPH512,
priority: 150,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_fp16"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::FAdd,
description: "vfmadd231ph zmm, zmm, zmm — AVX10 FP16 FMA",
result_opcode: Avx10IselOpcode::VFmaddPH512,
priority: 151,
num_src_operands: 3,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_fp16"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::FAdd,
description: "vfnmadd231ph zmm, zmm, zmm — AVX10 FP16 negated FMA",
result_opcode: Avx10IselOpcode::VFnmaddPH512,
priority: 152,
num_src_operands: 3,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_fp16"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::FAdd,
description: "vfmsub231ph zmm, zmm, zmm — AVX10 FP16 FMS",
result_opcode: Avx10IselOpcode::VFmsubPH512,
priority: 153,
num_src_operands: 3,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_fp16"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::FAdd,
description: "vfnmsub231ph zmm, zmm, zmm — AVX10 FP16 negated FMS",
result_opcode: Avx10IselOpcode::VFnmsubPH512,
priority: 154,
num_src_operands: 3,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_fp16"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Mul,
description: "vdpbf16ps zmm, zmm, zmm — AVX10 BF16 dot product",
result_opcode: Avx10IselOpcode::VDPBF16PS512,
priority: 160,
num_src_operands: 3,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_bf16"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::FPTrunc,
description: "vcvtne2ps2bf16 zmm, zmm, zmm — AVX10 convert 2×FP32 to BF16",
result_opcode: Avx10IselOpcode::VCvtNE2PS2BF16_512,
priority: 161,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_bf16"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Add,
description: "vpdpbusd zmm, zmm, zmm — AVX10 VNNI u8×s8→s32 dot product",
result_opcode: Avx10IselOpcode::VPDpBusd512,
priority: 170,
num_src_operands: 3,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_vnni"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Add,
description: "vpdpbussd zmm, zmm, zmm — AVX10 VNNI s8×s8→s32 dot product",
result_opcode: Avx10IselOpcode::VPDpBussd512,
priority: 171,
num_src_operands: 3,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_vnni"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Add,
description: "vpdpwssd zmm, zmm, zmm — AVX10 VNNI u16×s16→s32 dot product",
result_opcode: Avx10IselOpcode::VPDpWssd512,
priority: 172,
num_src_operands: 3,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_vnni"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Add,
description: "vpdpwssds zmm, zmm, zmm — AVX10 VNNI s16×s16→s32+s32 dot product",
result_opcode: Avx10IselOpcode::VPDpWssds512,
priority: 173,
num_src_operands: 3,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_vnni"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::FAdd,
description: "tcmmlfp16ps — AVX10.2 real-part complex FP16 matrix multiply",
result_opcode: Avx10IselOpcode::TCMMRLFP16x,
priority: 200,
num_src_operands: 3,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_2_tcmm_fp16"),
min_avx10_version: Avx10Version::V2,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::FAdd,
description: "tcmmilfp16ps — AVX10.2 imaginary-part complex FP16 matrix multiply",
result_opcode: Avx10IselOpcode::TCMMILFP16x,
priority: 201,
num_src_operands: 3,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_2_tcmm_fp16"),
min_avx10_version: Avx10Version::V2,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::FAdd,
description: "tdppbf16ps — AVX10.2 tile dot product with BF16 accumulation",
result_opcode: Avx10IselOpcode::TDPPxBF16x,
priority: 200,
num_src_operands: 3,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_2_tdpp_bf16"),
min_avx10_version: Avx10Version::V2,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Mul,
description: "vmpsmulvw — AVX10.2 MPS multiply vector word",
result_opcode: Avx10IselOpcode::VMPSMulW512,
priority: 200,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_2_mps"),
min_avx10_version: Avx10Version::V2,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Mul,
description: "vmpsmulvd — AVX10.2 MPS multiply vector dword",
result_opcode: Avx10IselOpcode::VMPSMulD512,
priority: 201,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_2_mps"),
min_avx10_version: Avx10Version::V2,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Add,
description: "vmpsaddvw — AVX10.2 MPS add vector word",
result_opcode: Avx10IselOpcode::VMPSAddW512,
priority: 202,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_2_mps"),
min_avx10_version: Avx10Version::V2,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Add,
description: "vmpsaddvd — AVX10.2 MPS add vector dword",
result_opcode: Avx10IselOpcode::VMPSAddD512,
priority: 203,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_2_mps"),
min_avx10_version: Avx10Version::V2,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::FAdd,
description: "vaddps ymm, ymm, ymm — AVX10 256-bit packed SP add (mandatory)",
result_opcode: Avx10IselOpcode::VAddPS256,
priority: 50,
num_src_operands: 2,
is_512bit: false,
is_masked: false,
required_feature: Some("avx10"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::FAdd,
description: "vaddpd ymm, ymm, ymm — AVX10 256-bit packed DP add (mandatory)",
result_opcode: Avx10IselOpcode::VAddPD256,
priority: 51,
num_src_operands: 2,
is_512bit: false,
is_masked: false,
required_feature: Some("avx10"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::FSub,
description: "vsubps ymm, ymm, ymm — AVX10 256-bit packed SP sub (mandatory)",
result_opcode: Avx10IselOpcode::VSubPS256,
priority: 50,
num_src_operands: 2,
is_512bit: false,
is_masked: false,
required_feature: Some("avx10"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::FSub,
description: "vsubpd ymm, ymm, ymm — AVX10 256-bit packed DP sub (mandatory)",
result_opcode: Avx10IselOpcode::VSubPD256,
priority: 51,
num_src_operands: 2,
is_512bit: false,
is_masked: false,
required_feature: Some("avx10"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::FMul,
description: "vmulps ymm, ymm, ymm — AVX10 256-bit packed SP mul (mandatory)",
result_opcode: Avx10IselOpcode::VMulPS256,
priority: 50,
num_src_operands: 2,
is_512bit: false,
is_masked: false,
required_feature: Some("avx10"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::FMul,
description: "vmulpd ymm, ymm, ymm — AVX10 256-bit packed DP mul (mandatory)",
result_opcode: Avx10IselOpcode::VMulPD256,
priority: 51,
num_src_operands: 2,
is_512bit: false,
is_masked: false,
required_feature: Some("avx10"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Add,
description: "vpaddd ymm, ymm, ymm — AVX10 256-bit packed int32 add (mandatory)",
result_opcode: Avx10IselOpcode::VPAddD256,
priority: 50,
num_src_operands: 2,
is_512bit: false,
is_masked: false,
required_feature: Some("avx10"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
table.push(Avx10IselPattern {
ir_opcode: Opcode::Add,
description: "vpaddq ymm, ymm, ymm — AVX10 256-bit packed int64 add (mandatory)",
result_opcode: Avx10IselOpcode::VPAddQ256,
priority: 51,
num_src_operands: 2,
is_512bit: false,
is_masked: false,
required_feature: Some("avx10"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
});
for (op, rounding, desc_suffix, prio_base) in &[
(
Avx10IselOpcode::VAddPS512_RN,
Avx10RoundingMode::RN,
"RN",
300u32,
),
(
Avx10IselOpcode::VAddPS512_RU,
Avx10RoundingMode::RU,
"RU",
301,
),
(
Avx10IselOpcode::VAddPS512_RD,
Avx10RoundingMode::RD,
"RD",
302,
),
(
Avx10IselOpcode::VAddPS512_RZ,
Avx10RoundingMode::RZ,
"RZ",
303,
),
(
Avx10IselOpcode::VAddPS512_SAE,
Avx10RoundingMode::SAE,
"SAE",
304,
),
(
Avx10IselOpcode::VAddPD512_RN,
Avx10RoundingMode::RN,
"RN",
305,
),
(
Avx10IselOpcode::VAddPD512_RU,
Avx10RoundingMode::RU,
"RU",
306,
),
(
Avx10IselOpcode::VAddPD512_RD,
Avx10RoundingMode::RD,
"RD",
307,
),
(
Avx10IselOpcode::VAddPD512_RZ,
Avx10RoundingMode::RZ,
"RZ",
308,
),
(
Avx10IselOpcode::VAddPD512_SAE,
Avx10RoundingMode::SAE,
"SAE",
309,
),
(
Avx10IselOpcode::VMulPS512_RN,
Avx10RoundingMode::RN,
"RN",
310,
),
(
Avx10IselOpcode::VMulPS512_RU,
Avx10RoundingMode::RU,
"RU",
311,
),
(
Avx10IselOpcode::VMulPS512_RD,
Avx10RoundingMode::RD,
"RD",
312,
),
(
Avx10IselOpcode::VMulPS512_RZ,
Avx10RoundingMode::RZ,
"RZ",
313,
),
(
Avx10IselOpcode::VMulPS512_SAE,
Avx10RoundingMode::SAE,
"SAE",
314,
),
(
Avx10IselOpcode::VMulPD512_RN,
Avx10RoundingMode::RN,
"RN",
315,
),
(
Avx10IselOpcode::VMulPD512_RU,
Avx10RoundingMode::RU,
"RU",
316,
),
(
Avx10IselOpcode::VMulPD512_RD,
Avx10RoundingMode::RD,
"RD",
317,
),
(
Avx10IselOpcode::VMulPD512_RZ,
Avx10RoundingMode::RZ,
"RZ",
318,
),
(
Avx10IselOpcode::VMulPD512_SAE,
Avx10RoundingMode::SAE,
"SAE",
319,
),
(
Avx10IselOpcode::VFmaddPS512_RN,
Avx10RoundingMode::RN,
"RN",
320,
),
(
Avx10IselOpcode::VFmaddPS512_RU,
Avx10RoundingMode::RU,
"RU",
321,
),
(
Avx10IselOpcode::VFmaddPS512_RD,
Avx10RoundingMode::RD,
"RD",
322,
),
(
Avx10IselOpcode::VFmaddPS512_RZ,
Avx10RoundingMode::RZ,
"RZ",
323,
),
(
Avx10IselOpcode::VFmaddPS512_SAE,
Avx10RoundingMode::SAE,
"SAE",
324,
),
] {
table.push(Avx10IselPattern {
ir_opcode: Opcode::FAdd,
description: "AVX10 512-bit FP arithmetic with embedded rounding",
result_opcode: *op,
priority: *prio_base,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512_er"),
min_avx10_version: Avx10Version::V1,
rounding_mode: Some(*rounding),
});
}
table
}
pub fn build_avx10_isel_table() -> Avx10IselTable {
let patterns = avx10_isel_table();
let total = patterns.len();
let p512 = patterns.iter().filter(|p| p.is_512bit).count();
let p256 = patterns.iter().filter(|p| !p.is_512bit).count();
let pmasked = patterns.iter().filter(|p| p.is_masked).count();
let pavx102 = patterns
.iter()
.filter(|p| p.min_avx10_version.is_v2())
.count();
let pround = patterns
.iter()
.filter(|p| p.rounding_mode.is_some())
.count();
Avx10IselTable {
patterns,
total_patterns: total,
patterns_512bit: p512,
patterns_256bit: p256,
patterns_masked: pmasked,
patterns_avx10_2: pavx102,
patterns_rounding: pround,
}
}
pub struct Avx10IselEngine {
pub table: Avx10IselTable,
pub features: Avx10Features,
pub vreg_map: HashMap<usize, VirtReg>,
}
impl Avx10IselEngine {
pub fn new(features: Avx10Features) -> Self {
let table = build_avx10_isel_table();
Self {
table,
features,
vreg_map: HashMap::new(),
}
}
pub fn is_pattern_applicable(&self, pattern: &Avx10IselPattern) -> bool {
if pattern.min_avx10_version > self.features.version {
return false;
}
if pattern.is_512bit && !self.features.has_512bit {
return false;
}
if let Some(feat) = pattern.required_feature {
if !self.features.has_feature(feat) {
return false;
}
}
true
}
pub fn select_pattern(&self, ir_opcodes: &[Opcode]) -> Option<&Avx10IselPattern> {
let mut best: Option<&Avx10IselPattern> = None;
for p in &self.table.patterns {
if ir_opcodes.contains(&p.ir_opcode) && self.is_pattern_applicable(p) {
match best {
None => best = Some(p),
Some(b) if p.priority < b.priority => best = Some(p),
_ => {}
}
}
}
best
}
pub fn emit_instr(
&self,
pattern: &Avx10IselPattern,
dest: VirtReg,
srcs: &[VirtReg],
) -> MachineInstr {
let x86_op = avx10_isel_to_x86_opcode(pattern.result_opcode);
let mut mi = MachineInstr::new(x86_op as u32);
mi.def = Some(dest);
mi.push_reg(dest);
for &s in srcs {
mi.push_reg(s);
}
mi
}
pub fn stats(&self) -> String {
format!(
"AVX10 ISel: {} patterns (512-bit: {}, 256-bit: {}, masked: {}, AVX10.2: {}, rounding: {})",
self.table.total_patterns,
self.table.patterns_512bit,
self.table.patterns_256bit,
self.table.patterns_masked,
self.table.patterns_avx10_2,
self.table.patterns_rounding,
)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ApxFeatures {
pub has_rex2: bool,
pub has_ndd: bool,
pub has_push2_pop2: bool,
pub has_ccmp_ctest: bool,
pub has_zero_upper: bool,
pub egpr_count: u8,
}
impl Default for ApxFeatures {
fn default() -> Self {
Self {
has_rex2: false,
has_ndd: false,
has_push2_pop2: false,
has_ccmp_ctest: false,
has_zero_upper: false,
egpr_count: 16,
}
}
}
impl ApxFeatures {
pub fn apx_full() -> Self {
Self {
has_rex2: true,
has_ndd: true,
has_push2_pop2: true,
has_ccmp_ctest: true,
has_zero_upper: true,
egpr_count: 32,
}
}
pub fn has_egpr(&self) -> bool {
self.has_rex2 && self.egpr_count > 16
}
pub fn gpr_range(&self) -> (u8, u8) {
if self.has_egpr() {
(0, 32)
} else {
(0, 16)
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ApxIselOpcode {
AddNDD,
SubNDD,
AndNDD,
OrNDD,
XorNDD,
AdcNDD,
SbbNDD,
IMulNDD,
ShlNDD,
ShrNDD,
SarNDD,
RolNDD,
RorNDD,
NegNDD,
NotNDD,
IncNDD,
DecNDD,
PUSH2,
POP2,
CCMP,
CTEST,
AddZU,
SubZU,
IMulZU,
MovZU,
MulZU,
MovEGPR,
AddEGPR,
SubEGPR,
LeaEGPR,
}
pub fn apx_isel_to_x86_opcode(op: ApxIselOpcode) -> X86Opcode {
match op {
ApxIselOpcode::AddNDD | ApxIselOpcode::AddZU | ApxIselOpcode::AddEGPR => X86Opcode::ADD,
ApxIselOpcode::SubNDD | ApxIselOpcode::SubZU | ApxIselOpcode::SubEGPR => X86Opcode::SUB,
ApxIselOpcode::AndNDD => X86Opcode::AND,
ApxIselOpcode::OrNDD => X86Opcode::OR,
ApxIselOpcode::XorNDD => X86Opcode::XOR,
ApxIselOpcode::AdcNDD => X86Opcode::ADC,
ApxIselOpcode::SbbNDD => X86Opcode::SBB,
ApxIselOpcode::IMulNDD | ApxIselOpcode::MulZU | ApxIselOpcode::IMulZU => X86Opcode::IMUL,
ApxIselOpcode::ShlNDD => X86Opcode::SHL,
ApxIselOpcode::ShrNDD => X86Opcode::SHR,
ApxIselOpcode::SarNDD => X86Opcode::SAR,
ApxIselOpcode::RolNDD => X86Opcode::ROL,
ApxIselOpcode::RorNDD => X86Opcode::ROR,
ApxIselOpcode::NegNDD => X86Opcode::NEG,
ApxIselOpcode::NotNDD => X86Opcode::NOT,
ApxIselOpcode::IncNDD => X86Opcode::INC,
ApxIselOpcode::DecNDD => X86Opcode::DEC,
ApxIselOpcode::PUSH2 => X86Opcode::PUSH,
ApxIselOpcode::POP2 => X86Opcode::POP,
ApxIselOpcode::CCMP => X86Opcode::CMP,
ApxIselOpcode::CTEST => X86Opcode::TEST,
ApxIselOpcode::MovZU | ApxIselOpcode::MovEGPR => X86Opcode::MOV,
ApxIselOpcode::LeaEGPR => X86Opcode::LEA,
}
}
#[derive(Debug, Clone)]
pub struct ApxIselPattern {
pub ir_opcode: Opcode,
pub description: &'static str,
pub result_opcode: ApxIselOpcode,
pub priority: u32,
pub num_src_operands: u8,
pub required_feature: Option<&'static str>,
pub prefer_egpr: bool,
}
pub struct ApxIselTable {
pub patterns: Vec<ApxIselPattern>,
pub total_patterns: usize,
pub ndd_patterns: usize,
pub push2_pop2_patterns: usize,
pub ccmp_ctest_patterns: usize,
pub zu_patterns: usize,
}
pub fn apx_isel_table() -> Vec<ApxIselPattern> {
let mut table = Vec::new();
table.push(ApxIselPattern {
ir_opcode: Opcode::Add,
description: "add ndd, src1, src2 — APX NDD 3-operand add",
result_opcode: ApxIselOpcode::AddNDD,
priority: 100,
num_src_operands: 3,
required_feature: Some("apx_ndd"),
prefer_egpr: false,
});
table.push(ApxIselPattern {
ir_opcode: Opcode::Sub,
description: "sub ndd, src1, src2 — APX NDD 3-operand sub",
result_opcode: ApxIselOpcode::SubNDD,
priority: 100,
num_src_operands: 3,
required_feature: Some("apx_ndd"),
prefer_egpr: false,
});
table.push(ApxIselPattern {
ir_opcode: Opcode::And,
description: "and ndd, src1, src2 — APX NDD 3-operand and",
result_opcode: ApxIselOpcode::AndNDD,
priority: 100,
num_src_operands: 3,
required_feature: Some("apx_ndd"),
prefer_egpr: false,
});
table.push(ApxIselPattern {
ir_opcode: Opcode::Or,
description: "or ndd, src1, src2 — APX NDD 3-operand or",
result_opcode: ApxIselOpcode::OrNDD,
priority: 100,
num_src_operands: 3,
required_feature: Some("apx_ndd"),
prefer_egpr: false,
});
table.push(ApxIselPattern {
ir_opcode: Opcode::Xor,
description: "xor ndd, src1, src2 — APX NDD 3-operand xor",
result_opcode: ApxIselOpcode::XorNDD,
priority: 100,
num_src_operands: 3,
required_feature: Some("apx_ndd"),
prefer_egpr: false,
});
table.push(ApxIselPattern {
ir_opcode: Opcode::Mul,
description: "imul ndd, src1, src2 — APX NDD 3-operand signed mul",
result_opcode: ApxIselOpcode::IMulNDD,
priority: 100,
num_src_operands: 3,
required_feature: Some("apx_ndd"),
prefer_egpr: false,
});
table.push(ApxIselPattern {
ir_opcode: Opcode::Shl,
description: "shl ndd, src1, src2 — APX NDD 3-operand shift left",
result_opcode: ApxIselOpcode::ShlNDD,
priority: 100,
num_src_operands: 3,
required_feature: Some("apx_ndd"),
prefer_egpr: false,
});
table.push(ApxIselPattern {
ir_opcode: Opcode::LShr,
description: "shr ndd, src1, src2 — APX NDD 3-operand logical shift right",
result_opcode: ApxIselOpcode::ShrNDD,
priority: 100,
num_src_operands: 3,
required_feature: Some("apx_ndd"),
prefer_egpr: false,
});
table.push(ApxIselPattern {
ir_opcode: Opcode::AShr,
description: "sar ndd, src1, src2 — APX NDD 3-operand arithmetic shift right",
result_opcode: ApxIselOpcode::SarNDD,
priority: 100,
num_src_operands: 3,
required_feature: Some("apx_ndd"),
prefer_egpr: false,
});
table.push(ApxIselPattern {
ir_opcode: Opcode::Sub,
description: "neg ndd, src — APX NDD 2-operand neg",
result_opcode: ApxIselOpcode::NegNDD,
priority: 101,
num_src_operands: 2,
required_feature: Some("apx_ndd"),
prefer_egpr: false,
});
table.push(ApxIselPattern {
ir_opcode: Opcode::Xor,
description: "not ndd, src — APX NDD 2-operand not",
result_opcode: ApxIselOpcode::NotNDD,
priority: 101,
num_src_operands: 2,
required_feature: Some("apx_ndd"),
prefer_egpr: false,
});
table.push(ApxIselPattern {
ir_opcode: Opcode::Add,
description: "inc ndd, src — APX NDD 2-operand inc",
result_opcode: ApxIselOpcode::IncNDD,
priority: 102,
num_src_operands: 2,
required_feature: Some("apx_ndd"),
prefer_egpr: false,
});
table.push(ApxIselPattern {
ir_opcode: Opcode::Sub,
description: "dec ndd, src — APX NDD 2-operand dec",
result_opcode: ApxIselOpcode::DecNDD,
priority: 102,
num_src_operands: 2,
required_feature: Some("apx_ndd"),
prefer_egpr: false,
});
table.push(ApxIselPattern {
ir_opcode: Opcode::Call,
description: "push2 r1, r2 — APX push two GPRs for function prologue",
result_opcode: ApxIselOpcode::PUSH2,
priority: 200,
num_src_operands: 2,
required_feature: Some("apx_push2_pop2"),
prefer_egpr: false,
});
table.push(ApxIselPattern {
ir_opcode: Opcode::Ret,
description: "pop2 r1, r2 — APX pop two GPRs for function epilogue",
result_opcode: ApxIselOpcode::POP2,
priority: 200,
num_src_operands: 2,
required_feature: Some("apx_push2_pop2"),
prefer_egpr: false,
});
table.push(ApxIselPattern {
ir_opcode: Opcode::ICmp,
description: "ccmp src1, src2, cond — APX conditional compare",
result_opcode: ApxIselOpcode::CCMP,
priority: 300,
num_src_operands: 3,
required_feature: Some("apx_ccmp_ctest"),
prefer_egpr: false,
});
table.push(ApxIselPattern {
ir_opcode: Opcode::And,
description: "ctest src1, src2, cond — APX conditional test",
result_opcode: ApxIselOpcode::CTEST,
priority: 300,
num_src_operands: 3,
required_feature: Some("apx_ccmp_ctest"),
prefer_egpr: false,
});
table.push(ApxIselPattern {
ir_opcode: Opcode::Add,
description: "addzu ndd, src1, src2 — APX add with zero upper 32 bits",
result_opcode: ApxIselOpcode::AddZU,
priority: 400,
num_src_operands: 3,
required_feature: Some("apx_zu"),
prefer_egpr: false,
});
table.push(ApxIselPattern {
ir_opcode: Opcode::Sub,
description: "subzu ndd, src1, src2 — APX sub with zero upper 32 bits",
result_opcode: ApxIselOpcode::SubZU,
priority: 400,
num_src_operands: 3,
required_feature: Some("apx_zu"),
prefer_egpr: false,
});
table.push(ApxIselPattern {
ir_opcode: Opcode::Mul,
description: "imulzu ndd, src1, src2 — APX mul with zero upper 32 bits",
result_opcode: ApxIselOpcode::IMulZU,
priority: 400,
num_src_operands: 3,
required_feature: Some("apx_zu"),
prefer_egpr: false,
});
table.push(ApxIselPattern {
ir_opcode: Opcode::Add,
description: "add r_dst(EGPR), r_src1, r_src2 — APX EGPR add",
result_opcode: ApxIselOpcode::AddEGPR,
priority: 500,
num_src_operands: 3,
required_feature: Some("apx_rex2"),
prefer_egpr: true,
});
table.push(ApxIselPattern {
ir_opcode: Opcode::Sub,
description: "sub r_dst(EGPR), r_src1, r_src2 — APX EGPR sub",
result_opcode: ApxIselOpcode::SubEGPR,
priority: 500,
num_src_operands: 3,
required_feature: Some("apx_rex2"),
prefer_egpr: true,
});
table.push(ApxIselPattern {
ir_opcode: Opcode::Load,
description: "mov r_dst(EGPR), [mem] — APX EGPR load",
result_opcode: ApxIselOpcode::MovEGPR,
priority: 500,
num_src_operands: 2,
required_feature: Some("apx_rex2"),
prefer_egpr: true,
});
table.push(ApxIselPattern {
ir_opcode: Opcode::Store,
description: "mov [mem], r_src(EGPR) — APX EGPR store",
result_opcode: ApxIselOpcode::MovEGPR,
priority: 501,
num_src_operands: 2,
required_feature: Some("apx_rex2"),
prefer_egpr: true,
});
table.push(ApxIselPattern {
ir_opcode: Opcode::GetElementPtr,
description: "lea r_dst(EGPR), [base+index*scale+disp] — APX EGPR LEA",
result_opcode: ApxIselOpcode::LeaEGPR,
priority: 500,
num_src_operands: 3,
required_feature: Some("apx_rex2"),
prefer_egpr: true,
});
table
}
pub fn build_apx_isel_table() -> ApxIselTable {
let patterns = apx_isel_table();
let total = patterns.len();
let ndd = patterns
.iter()
.filter(|p| matches!(p.required_feature, Some("apx_ndd")))
.count();
let push2 = patterns
.iter()
.filter(|p| matches!(p.required_feature, Some("apx_push2_pop2")))
.count();
let ccmp = patterns
.iter()
.filter(|p| matches!(p.required_feature, Some("apx_ccmp_ctest")))
.count();
let zu = patterns
.iter()
.filter(|p| matches!(p.required_feature, Some("apx_zu")))
.count();
ApxIselTable {
patterns,
total_patterns: total,
ndd_patterns: ndd,
push2_pop2_patterns: push2,
ccmp_ctest_patterns: ccmp,
zu_patterns: zu,
}
}
pub struct ApxIselEngine {
pub table: ApxIselTable,
pub features: ApxFeatures,
pub vreg_map: HashMap<usize, VirtReg>,
}
impl ApxIselEngine {
pub fn new(features: ApxFeatures) -> Self {
let table = build_apx_isel_table();
Self {
table,
features,
vreg_map: HashMap::new(),
}
}
pub fn is_pattern_applicable(&self, pattern: &ApxIselPattern) -> bool {
match pattern.required_feature {
Some("apx_ndd") if !self.features.has_ndd => false,
Some("apx_push2_pop2") if !self.features.has_push2_pop2 => false,
Some("apx_ccmp_ctest") if !self.features.has_ccmp_ctest => false,
Some("apx_zu") if !self.features.has_zero_upper => false,
Some("apx_rex2") if !self.features.has_rex2 => false,
_ => true,
}
}
pub fn select_pattern(&self, ir_opcodes: &[Opcode]) -> Option<&ApxIselPattern> {
let mut best: Option<&ApxIselPattern> = None;
for p in &self.table.patterns {
if ir_opcodes.contains(&p.ir_opcode) && self.is_pattern_applicable(p) {
match best {
None => best = Some(p),
Some(b) if p.priority < b.priority => best = Some(p),
_ => {}
}
}
}
best
}
pub fn emit_instr(
&self,
pattern: &ApxIselPattern,
dest: VirtReg,
srcs: &[VirtReg],
) -> MachineInstr {
let x86_op = apx_isel_to_x86_opcode(pattern.result_opcode);
let mut mi = MachineInstr::new(x86_op as u32);
mi.def = Some(dest);
mi.push_reg(dest);
for &s in srcs {
mi.push_reg(s);
}
mi
}
pub fn stats(&self) -> String {
format!(
"APX ISel: {} patterns (NDD: {}, PUSH2/POP2: {}, CCMP/CTEST: {}, ZU: {})",
self.table.total_patterns,
self.table.ndd_patterns,
self.table.push2_pop2_patterns,
self.table.ccmp_ctest_patterns,
self.table.zu_patterns,
)
}
}
pub struct Avx10ApxCombinedISel {
pub avx10_engine: Avx10IselEngine,
pub apx_engine: ApxIselEngine,
}
impl Avx10ApxCombinedISel {
pub fn new(avx10_features: Avx10Features, apx_features: ApxFeatures) -> Self {
Self {
avx10_engine: Avx10IselEngine::new(avx10_features),
apx_engine: ApxIselEngine::new(apx_features),
}
}
pub fn select_combined(&self, ir_opcode: Opcode) -> Option<(String, MachineInstr)> {
let opcodes = &[ir_opcode];
if let Some(pat) = self.apx_engine.select_pattern(opcodes) {
let mi = self.apx_engine.emit_instr(pat, 0, &[]);
return Some((format!("APX: {}", pat.description), mi));
}
if let Some(pat) = self.avx10_engine.select_pattern(opcodes) {
let mi = self.avx10_engine.emit_instr(pat, 0, &[]);
return Some((format!("AVX10: {}", pat.description), mi));
}
None
}
pub fn combined_stats(&self) -> String {
format!(
"Combined ISel:\n {}\n {}\n Total: {} patterns",
self.avx10_engine.stats(),
self.apx_engine.stats(),
self.avx10_engine.table.total_patterns + self.apx_engine.table.total_patterns,
)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_avx10_version_ordering() {
assert!(Avx10Version::V2 > Avx10Version::V1);
assert_eq!(Avx10Version::V1.as_u32(), 1);
assert_eq!(Avx10Version::V2.as_u32(), 2);
}
#[test]
fn test_avx10_features_default() {
let f = Avx10Features::default();
assert_eq!(f.version, Avx10Version::V1);
assert!(!f.has_512bit);
}
#[test]
fn test_avx10_features_full() {
let f = Avx10Features::avx10_2_full();
assert_eq!(f.version, Avx10Version::V2);
assert!(f.has_512bit);
assert!(f.has_tcmm_fp16);
assert!(f.has_tdpp_bf16);
assert!(f.has_mps);
}
#[test]
fn test_avx10_e_core() {
let f = Avx10Features::avx10_e_core();
assert!(!f.has_512bit);
assert!(f.has_converged_avx512);
}
#[test]
fn test_avx10_feature_query() {
let f = Avx10Features::avx10_1_full();
assert!(f.has_feature("avx512f"));
assert!(f.has_feature("avx512bf16"));
assert!(!f.has_feature("avx10_tcmm_fp16"));
}
#[test]
fn test_avx10_version_report() {
let f = Avx10Features::avx10_1_full();
let report = Avx10VersionReport::detect(Avx10Version::V1, &f);
assert_eq!(report.version, 1);
assert_eq!(report.max_vector_bit_width, 512);
}
#[test]
fn test_apx_features_default() {
let f = ApxFeatures::default();
assert!(!f.has_rex2);
assert_eq!(f.egpr_count, 16);
}
#[test]
fn test_apx_features_full() {
let f = ApxFeatures::apx_full();
assert!(f.has_rex2);
assert!(f.has_egpr());
assert_eq!(f.egpr_count, 32);
}
#[test]
fn test_apx_gpr_range() {
let f_default = ApxFeatures::default();
assert_eq!(f_default.gpr_range(), (0, 16));
let f_full = ApxFeatures::apx_full();
assert_eq!(f_full.gpr_range(), (0, 32));
}
#[test]
fn test_avx10_isel_table_builds() {
let table = build_avx10_isel_table();
assert!(table.total_patterns > 50);
assert!(table.patterns_512bit > 0);
assert!(table.patterns_256bit > 0);
}
#[test]
fn test_apx_isel_table_builds() {
let table = build_apx_isel_table();
assert!(table.total_patterns > 10);
assert!(table.ndd_patterns > 0);
}
#[test]
fn test_avx10_isel_engine_select() {
let engine = Avx10IselEngine::new(Avx10Features::avx10_1_full());
let pat = engine.select_pattern(&[Opcode::FAdd]);
assert!(pat.is_some());
assert!(pat.unwrap().is_512bit);
}
#[test]
fn test_avx10_isel_engine_e_core_select() {
let engine = Avx10IselEngine::new(Avx10Features::avx10_e_core());
let pat = engine.select_pattern(&[Opcode::FAdd]);
assert!(pat.is_some());
assert!(!pat.unwrap().is_512bit);
}
#[test]
fn test_apx_isel_engine_select() {
let engine = ApxIselEngine::new(ApxFeatures::apx_full());
let pat = engine.select_pattern(&[Opcode::Add]);
assert!(pat.is_some());
assert!(pat.unwrap().priority < 500);
}
#[test]
fn test_combined_isel() {
let combined =
Avx10ApxCombinedISel::new(Avx10Features::avx10_1_full(), ApxFeatures::apx_full());
let result = combined.select_combined(Opcode::Add);
assert!(result.is_some());
assert!(result.unwrap().0.contains("APX"));
let result = combined.select_combined(Opcode::FAdd);
assert!(result.is_some());
assert!(result.unwrap().0.contains("AVX10"));
}
#[test]
fn test_avx10_isel_opcode_conversion() {
assert_eq!(
avx10_isel_to_x86_opcode(Avx10IselOpcode::VAddPS512),
X86Opcode::VADDPS
);
assert_eq!(
avx10_isel_to_x86_opcode(Avx10IselOpcode::VAddPD256),
X86Opcode::VADDPD
);
assert_eq!(
avx10_isel_to_x86_opcode(Avx10IselOpcode::VPSubD512),
X86Opcode::VSUBPS
);
}
#[test]
fn test_apx_isel_opcode_conversion() {
assert_eq!(
apx_isel_to_x86_opcode(ApxIselOpcode::AddNDD),
X86Opcode::ADD
);
assert_eq!(
apx_isel_to_x86_opcode(ApxIselOpcode::PUSH2),
X86Opcode::PUSH
);
assert_eq!(apx_isel_to_x86_opcode(ApxIselOpcode::CCMP), X86Opcode::CMP);
}
#[test]
fn test_rounding_mode_encode() {
assert_eq!(Avx10RoundingMode::RN.encode(), 0b00);
assert_eq!(Avx10RoundingMode::RD.encode(), 0b01);
assert_eq!(Avx10RoundingMode::RU.encode(), 0b10);
assert_eq!(Avx10RoundingMode::RZ.encode(), 0b11);
}
#[test]
fn test_avx10_isel_pattern_applicability() {
let engine = Avx10IselEngine::new(Avx10Features::avx10_e_core());
let pat512 = Avx10IselPattern {
ir_opcode: Opcode::FAdd,
description: "test",
result_opcode: Avx10IselOpcode::VAddPS512,
priority: 100,
num_src_operands: 2,
is_512bit: true,
is_masked: false,
required_feature: Some("avx10_512"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
};
assert!(!engine.is_pattern_applicable(&pat512));
let pat256 = Avx10IselPattern {
ir_opcode: Opcode::FAdd,
description: "test",
result_opcode: Avx10IselOpcode::VAddPS256,
priority: 50,
num_src_operands: 2,
is_512bit: false,
is_masked: false,
required_feature: Some("avx10"),
min_avx10_version: Avx10Version::V1,
rounding_mode: None,
};
assert!(engine.is_pattern_applicable(&pat256));
}
#[test]
fn test_apx_isel_pattern_applicability() {
let engine = ApxIselEngine::new(ApxFeatures::default());
let ndd_pat = ApxIselPattern {
ir_opcode: Opcode::Add,
description: "test",
result_opcode: ApxIselOpcode::AddNDD,
priority: 100,
num_src_operands: 3,
required_feature: Some("apx_ndd"),
prefer_egpr: false,
};
assert!(!engine.is_pattern_applicable(&ndd_pat));
let engine_full = ApxIselEngine::new(ApxFeatures::apx_full());
assert!(engine_full.is_pattern_applicable(&ndd_pat));
}
}