diff --git a/library/stdarch/Cargo.lock b/library/stdarch/Cargo.lock index 97bdfd5368b3..26a422327187 100644 --- a/library/stdarch/Cargo.lock +++ b/library/stdarch/Cargo.lock @@ -349,6 +349,7 @@ dependencies = [ "pretty_env_logger", "quick-xml 0.37.5", "rayon", + "regex", "serde", "serde-xml-rs", "serde_json", diff --git a/library/stdarch/crates/intrinsic-test/Cargo.toml b/library/stdarch/crates/intrinsic-test/Cargo.toml index df4f7fe706f5..2c0f53897e79 100644 --- a/library/stdarch/crates/intrinsic-test/Cargo.toml +++ b/library/stdarch/crates/intrinsic-test/Cargo.toml @@ -21,3 +21,4 @@ diff = "0.1.12" itertools = "0.14.0" quick-xml = { version = "0.37.5", features = ["serialize", "overlapped-lists"] } serde-xml-rs = "0.8.0" +regex = "1.11.1" diff --git a/library/stdarch/crates/intrinsic-test/src/x86/compile.rs b/library/stdarch/crates/intrinsic-test/src/x86/compile.rs index 170e40927fb8..e8c2262b8571 100644 --- a/library/stdarch/crates/intrinsic-test/src/x86/compile.rs +++ b/library/stdarch/crates/intrinsic-test/src/x86/compile.rs @@ -32,7 +32,7 @@ pub fn build_cpp_compilation(config: &ProcessedCli) -> Option { command = command.add_extra_flag("-flax-vector-conversions"); } - let mut cpp_compiler = command.into_cpp_compilation(); + let cpp_compiler = command.into_cpp_compilation(); Some(cpp_compiler) } diff --git a/library/stdarch/crates/intrinsic-test/src/x86/intrinsic.rs b/library/stdarch/crates/intrinsic-test/src/x86/intrinsic.rs index 1dedcb59a5cc..0261a2df8520 100644 --- a/library/stdarch/crates/intrinsic-test/src/x86/intrinsic.rs +++ b/library/stdarch/crates/intrinsic-test/src/x86/intrinsic.rs @@ -2,22 +2,26 @@ use crate::common::argument::ArgumentList; use crate::common::indentation::Indentation; use crate::common::intrinsic::{Intrinsic, IntrinsicDefinition}; use crate::common::intrinsic_helpers::IntrinsicType; +use crate::x86::xml_parser::Parameter; use std::ops::{Deref, DerefMut}; #[derive(Debug, Clone, PartialEq)] -pub struct X86IntrinsicType(pub IntrinsicType); +pub struct X86IntrinsicType { + pub data: IntrinsicType, + pub param: Parameter, +} impl Deref for X86IntrinsicType { type Target = IntrinsicType; fn deref(&self) -> &Self::Target { - &self.0 + &self.data } } impl DerefMut for X86IntrinsicType { fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 + &mut self.data } } diff --git a/library/stdarch/crates/intrinsic-test/src/x86/types.rs b/library/stdarch/crates/intrinsic-test/src/x86/types.rs index e27a18237078..542d1ad3fac8 100644 --- a/library/stdarch/crates/intrinsic-test/src/x86/types.rs +++ b/library/stdarch/crates/intrinsic-test/src/x86/types.rs @@ -13,18 +13,16 @@ impl IntrinsicTypeDefinition for X86IntrinsicType { /// Gets a string containing the type in C format. /// This function assumes that this value is present in the metadata hashmap. fn c_type(&self) -> String { - self.metadata - .get("type") - .expect("Failed to extract the C typename in X86!") - .to_string() + self.param.type_data.clone() } fn c_single_vector_type(&self) -> String { // matches __m128, __m256 and similar types let re = Regex::new(r"\__m\d+\").unwrap(); - match self.metadata.get("type") { - Some(type_data) if re.is_match(type_data) => type_data.to_string(), - _ => unreachable!("Shouldn't be called on this type"), + if re.is_match(self.param.type_data.as_str()) { + self.param.type_data.clone() + } else { + unreachable!("Shouldn't be called on this type") } } @@ -94,40 +92,42 @@ impl IntrinsicTypeDefinition for X86IntrinsicType { /// Determines the load function for this type. fn get_load_function(&self, _language: Language) -> String { - if let Some(type_value) = self.metadata.get("type") { - if type_value.starts_with("__mmask") { - // no need of loads, since they work directly - // with hex constants - String::from("*") - } else if type_value.starts_with("__m") { - // the structure is like the follows: - // if "type" starts with __m{h/i/}, - // then use either _mm_set1_epi64, - // _mm256_set1_epi64 or _mm512_set1_epi64 - let type_val_filtered = type_value - .chars() - .filter(|c| c.is_numeric()) - .join("") - .replace("128", ""); - format!("_mm{type_val_filtered}_set1_epi64") - } else { - // if it is a pointer, then rely on type conversion - // If it is not any of the above type (__int, __bfloat16, unsigned short, etc) - // then typecast it. - format!("({type_value})") - } - // Look for edge cases (constexpr, literal, etc) - } else { + let type_value = self.param.type_data.clone(); + if type_value.len() == 0 { unimplemented!("the value for key 'type' is not present!"); } + if type_value.starts_with("__mmask") { + // no need of loads, since they work directly + // with hex constants + String::from("*") + } else if type_value.starts_with("__m") { + // the structure is like the follows: + // if "type" starts with __m{h/i/}, + // then use either _mm_set1_epi64, + // _mm256_set1_epi64 or _mm512_set1_epi64 + let type_val_filtered = type_value + .chars() + .filter(|c| c.is_numeric()) + .join("") + .replace("128", ""); + format!("_mm{type_val_filtered}_set1_epi64") + } else { + // if it is a pointer, then rely on type conversion + // If it is not any of the above type (__int, __bfloat16, unsigned short, etc) + // then typecast it. + format!("({type_value})") + } + // Look for edge cases (constexpr, literal, etc) } /// Determines the get lane function for this type. fn get_lane_function(&self) -> String { todo!("get_lane_function for X86IntrinsicType needs to be implemented!"); } +} - fn from_c(s: &str) -> Result { +impl X86IntrinsicType { + fn from_c(s: &str) -> Result { let mut s_copy = s.to_string(); let mut metadata: HashMap = HashMap::new(); metadata.insert("type".to_string(), s.to_string()); @@ -162,7 +162,7 @@ impl IntrinsicTypeDefinition for X86IntrinsicType { let constant = s.matches("const").next().is_some(); let ptr = s.matches("*").next().is_some(); - Ok(X86IntrinsicType(IntrinsicType { + Ok(IntrinsicType { ptr, ptr_constant, constant, @@ -170,25 +170,20 @@ impl IntrinsicTypeDefinition for X86IntrinsicType { bit_len: None, simd_len: None, vec_len: None, - metadata, - })) + }) } -} -impl X86IntrinsicType { pub fn from_param(param: &Parameter) -> Result { match Self::from_c(param.type_data.as_str()) { Err(message) => Err(message), - Ok(mut ret) => { + Ok(mut data) => { // First correct the type of the parameter using param.etype. // The assumption is that the parameter of type void may have param.type // as "__m128i", "__mmask8" and the like. - ret.set_metadata("etype".to_string(), param.etype.clone()); - ret.set_metadata("memwidth".to_string(), param.memwidth.to_string()); if !param.etype.is_empty() { match TypeKind::from_str(param.etype.as_str()) { Ok(value) => { - ret.kind = value; + data.kind = value; } Err(_) => {} }; @@ -202,9 +197,9 @@ impl X86IntrinsicType { etype_processed.retain(|c| c.is_numeric()); match str::parse::(etype_processed.as_str()) { - Ok(value) => ret.bit_len = Some(value), + Ok(value) => data.bit_len = Some(value), Err(_) => { - ret.bit_len = match ret.kind() { + data.bit_len = match data.kind() { TypeKind::Char(_) => Some(8), TypeKind::BFloat => Some(16), TypeKind::Int(_) => Some(32), @@ -222,26 +217,29 @@ impl X86IntrinsicType { { let mut type_processed = param.type_data.clone(); type_processed.retain(|c| c.is_numeric()); - ret.vec_len = match str::parse::(type_processed.as_str()) { + data.vec_len = match str::parse::(type_processed.as_str()) { // If bit_len is None, vec_len will be None. // Else vec_len will be (num_bits / bit_len). - Ok(num_bits) => ret.bit_len.and(Some(num_bits / ret.bit_len.unwrap())), + Ok(num_bits) => data.bit_len.and(Some(num_bits / data.bit_len.unwrap())), Err(_) => None, }; } // default settings for "void *" parameters // often used by intrinsics to denote memory address or so. - if ret.kind == TypeKind::Void && ret.ptr { - ret.kind = TypeKind::Int(Sign::Unsigned); - ret.bit_len = Some(8); + if data.kind == TypeKind::Void && data.ptr { + data.kind = TypeKind::Int(Sign::Unsigned); + data.bit_len = Some(8); } // if param.etype == IMM, then it is a constant. // else it stays unchanged. - ret.constant |= param.etype == "IMM"; + data.constant |= param.etype == "IMM"; - Ok(ret) + Ok(X86IntrinsicType { + data, + param: param.clone(), + }) } } // Tile types won't currently reach here, since the intrinsic that involve them diff --git a/library/stdarch/crates/intrinsic-test/src/x86/xml_parser.rs b/library/stdarch/crates/intrinsic-test/src/x86/xml_parser.rs index b26e18840d4c..0b422bddb580 100644 --- a/library/stdarch/crates/intrinsic-test/src/x86/xml_parser.rs +++ b/library/stdarch/crates/intrinsic-test/src/x86/xml_parser.rs @@ -37,7 +37,7 @@ struct XMLIntrinsic { parameters: Vec, } -#[derive(Deserialize)] +#[derive(Debug, PartialEq, Clone, Deserialize)] pub struct Parameter { #[serde(rename = "@varname")] pub var_name: String,