diff --git a/crates/intrinsic-test/src/arm/argument.rs b/crates/intrinsic-test/src/arm/argument.rs new file mode 100644 index 0000000000..db5501e5d2 --- /dev/null +++ b/crates/intrinsic-test/src/arm/argument.rs @@ -0,0 +1,12 @@ +use crate::arm::intrinsic::ArmIntrinsicType; +use crate::common::argument::Argument; + +impl Argument { + pub fn type_and_name_from_c(arg: &str) -> (&str, &str) { + let split_index = arg + .rfind([' ', '*']) + .expect("Couldn't split type and argname"); + + (arg[..split_index + 1].trim_end(), &arg[split_index + 1..]) + } +} diff --git a/crates/intrinsic-test/src/arm/json_parser.rs b/crates/intrinsic-test/src/arm/json_parser.rs index 58d366c86a..53ef86a268 100644 --- a/crates/intrinsic-test/src/arm/json_parser.rs +++ b/crates/intrinsic-test/src/arm/json_parser.rs @@ -79,20 +79,25 @@ fn json_to_intrinsic( ) -> Result, Box> { let name = intr.name.replace(['[', ']'], ""); - let results = ArmIntrinsicType::from_c(&intr.return_type.value, target)?; + let mut results = ArmIntrinsicType::from_c(&intr.return_type.value)?; + results.set_metadata("target", target); let args = intr .arguments .into_iter() .enumerate() .map(|(i, arg)| { - let arg_name = Argument::::type_and_name_from_c(&arg).1; + let (type_name, arg_name) = Argument::::type_and_name_from_c(&arg); let metadata = intr.args_prep.as_mut(); let metadata = metadata.and_then(|a| a.remove(arg_name)); let arg_prep: Option = metadata.and_then(|a| a.try_into().ok()); let constraint: Option = arg_prep.and_then(|a| a.try_into().ok()); + let mut ty = ArmIntrinsicType::from_c(type_name) + .unwrap_or_else(|_| panic!("Failed to parse argument '{arg}'")); + ty.set_metadata("target", target); - let mut arg = Argument::::from_c(i, &arg, target, constraint); + let mut arg = + Argument::::new(i, String::from(arg_name), ty, constraint); // The JSON doesn't list immediates as const let IntrinsicType { diff --git a/crates/intrinsic-test/src/arm/mod.rs b/crates/intrinsic-test/src/arm/mod.rs index 5d0320c4cd..d5ab4aedf7 100644 --- a/crates/intrinsic-test/src/arm/mod.rs +++ b/crates/intrinsic-test/src/arm/mod.rs @@ -1,10 +1,11 @@ +mod argument; mod compile; mod config; mod intrinsic; mod json_parser; mod types; -use std::fs::File; +use std::fs::{self, File}; use rayon::prelude::*; @@ -69,9 +70,10 @@ impl SupportedArchitectureTest for ArmArchitectureTest { let (chunk_size, chunk_count) = chunk_info(self.intrinsics.len()); - let cpp_compiler = compile::build_cpp_compilation(&self.cli_options).unwrap(); + let cpp_compiler_wrapped = compile::build_cpp_compilation(&self.cli_options); let notice = &build_notices("// "); + fs::create_dir_all("c_programs").unwrap(); self.intrinsics .par_chunks(chunk_size) .enumerate() @@ -81,9 +83,11 @@ impl SupportedArchitectureTest for ArmArchitectureTest { write_mod_cpp(&mut file, notice, c_target, platform_headers, chunk).unwrap(); // compile this cpp file into a .o file - let output = cpp_compiler - .compile_object_file(&format!("mod_{i}.cpp"), &format!("mod_{i}.o"))?; - assert!(output.status.success(), "{output:?}"); + if let Some(cpp_compiler) = cpp_compiler_wrapped.as_ref() { + let output = cpp_compiler + .compile_object_file(&format!("mod_{i}.cpp"), &format!("mod_{i}.o"))?; + assert!(output.status.success(), "{output:?}"); + } Ok(()) }) @@ -99,21 +103,25 @@ impl SupportedArchitectureTest for ArmArchitectureTest { ) .unwrap(); - // compile this cpp file into a .o file - info!("compiling main.cpp"); - let output = cpp_compiler - .compile_object_file("main.cpp", "intrinsic-test-programs.o") - .unwrap(); - assert!(output.status.success(), "{output:?}"); - - let object_files = (0..chunk_count) - .map(|i| format!("mod_{i}.o")) - .chain(["intrinsic-test-programs.o".to_owned()]); - - let output = cpp_compiler - .link_executable(object_files, "intrinsic-test-programs") - .unwrap(); - assert!(output.status.success(), "{output:?}"); + // This is done because `cpp_compiler_wrapped` is None when + // the --generate-only flag is passed + if let Some(cpp_compiler) = cpp_compiler_wrapped.as_ref() { + // compile this cpp file into a .o file + info!("compiling main.cpp"); + let output = cpp_compiler + .compile_object_file("main.cpp", "intrinsic-test-programs.o") + .unwrap(); + assert!(output.status.success(), "{output:?}"); + + let object_files = (0..chunk_count) + .map(|i| format!("mod_{i}.o")) + .chain(["intrinsic-test-programs.o".to_owned()]); + + let output = cpp_compiler + .link_executable(object_files, "intrinsic-test-programs") + .unwrap(); + assert!(output.status.success(), "{output:?}"); + } true } diff --git a/crates/intrinsic-test/src/arm/types.rs b/crates/intrinsic-test/src/arm/types.rs index c06e9355c4..229a74b4e8 100644 --- a/crates/intrinsic-test/src/arm/types.rs +++ b/crates/intrinsic-test/src/arm/types.rs @@ -1,3 +1,5 @@ +use std::collections::HashMap; + use super::intrinsic::ArmIntrinsicType; use crate::common::cli::Language; use crate::common::intrinsic_helpers::{IntrinsicType, IntrinsicTypeDefinition, Sign, TypeKind}; @@ -40,7 +42,7 @@ impl IntrinsicTypeDefinition for ArmIntrinsicType { bit_len: Some(bl), simd_len, vec_len, - target, + metadata, .. } = &self.0 { @@ -50,7 +52,8 @@ impl IntrinsicTypeDefinition for ArmIntrinsicType { "" }; - let choose_workaround = language == Language::C && target.contains("v7"); + let choose_workaround = language == Language::C + && metadata.get("target").is_some_and(|val| val.contains("v7")); format!( "vld{len}{quad}_{type}{size}", type = match k { @@ -102,15 +105,16 @@ impl IntrinsicTypeDefinition for ArmIntrinsicType { } } - fn from_c(s: &str, target: &str) -> Result { + fn from_c(s: &str) -> Result { const CONST_STR: &str = "const"; + let metadata: HashMap = HashMap::new(); if let Some(s) = s.strip_suffix('*') { let (s, constant) = match s.trim().strip_suffix(CONST_STR) { Some(stripped) => (stripped, true), None => (s, false), }; let s = s.trim_end(); - let temp_return = ArmIntrinsicType::from_c(s, target); + let temp_return = ArmIntrinsicType::from_c(s); temp_return.map(|mut op| { op.ptr = true; op.ptr_constant = constant; @@ -151,7 +155,7 @@ impl IntrinsicTypeDefinition for ArmIntrinsicType { bit_len: Some(bit_len), simd_len, vec_len, - target: target.to_string(), + metadata, })) } else { let kind = start.parse::()?; @@ -167,7 +171,7 @@ impl IntrinsicTypeDefinition for ArmIntrinsicType { bit_len, simd_len: None, vec_len: None, - target: target.to_string(), + metadata, })) } } diff --git a/crates/intrinsic-test/src/common/argument.rs b/crates/intrinsic-test/src/common/argument.rs index 1550cbd97f..f38515e40a 100644 --- a/crates/intrinsic-test/src/common/argument.rs +++ b/crates/intrinsic-test/src/common/argument.rs @@ -20,6 +20,15 @@ impl Argument where T: IntrinsicTypeDefinition, { + pub fn new(pos: usize, name: String, ty: T, constraint: Option) -> Self { + Argument { + pos, + name, + ty, + constraint, + } + } + pub fn to_c_type(&self) -> String { self.ty.c_type() } @@ -36,14 +45,6 @@ where self.constraint.is_some() } - pub fn type_and_name_from_c(arg: &str) -> (&str, &str) { - let split_index = arg - .rfind([' ', '*']) - .expect("Couldn't split type and argname"); - - (arg[..split_index + 1].trim_end(), &arg[split_index + 1..]) - } - /// The binding keyword (e.g. "const" or "let") for the array of possible test inputs. fn rust_vals_array_binding(&self) -> impl std::fmt::Display { if self.ty.is_rust_vals_array_const() { @@ -62,25 +63,6 @@ where } } - pub fn from_c( - pos: usize, - arg: &str, - target: &str, - constraint: Option, - ) -> Argument { - let (ty, var_name) = Self::type_and_name_from_c(arg); - - let ty = - T::from_c(ty, target).unwrap_or_else(|_| panic!("Failed to parse argument '{arg}'")); - - Argument { - pos, - name: String::from(var_name), - ty: ty, - constraint, - } - } - fn as_call_param_c(&self) -> String { self.ty.as_call_param_c(&self.name) } diff --git a/crates/intrinsic-test/src/common/gen_rust.rs b/crates/intrinsic-test/src/common/gen_rust.rs index 60bb577a80..acc18cfb92 100644 --- a/crates/intrinsic-test/src/common/gen_rust.rs +++ b/crates/intrinsic-test/src/common/gen_rust.rs @@ -130,6 +130,12 @@ pub fn compile_rust_programs(toolchain: Option<&str>, target: &str, linker: Opti /* If there has been a linker explicitly set from the command line then * we want to set it via setting it in the RUSTFLAGS*/ + // This is done because `toolchain` is None when + // the --generate-only flag is passed + if toolchain.is_none() { + return true; + } + trace!("Building cargo command"); let mut cargo_command = Command::new("cargo"); @@ -138,10 +144,8 @@ pub fn compile_rust_programs(toolchain: Option<&str>, target: &str, linker: Opti // Do not use the target directory of the workspace please. cargo_command.env("CARGO_TARGET_DIR", "target"); - if let Some(toolchain) = toolchain - && !toolchain.is_empty() - { - cargo_command.arg(toolchain); + if toolchain.is_some_and(|val| !val.is_empty()) { + cargo_command.arg(toolchain.unwrap()); } cargo_command.args(["build", "--target", target, "--release"]); diff --git a/crates/intrinsic-test/src/common/intrinsic_helpers.rs b/crates/intrinsic-test/src/common/intrinsic_helpers.rs index b53047b2d3..ef7c4d016b 100644 --- a/crates/intrinsic-test/src/common/intrinsic_helpers.rs +++ b/crates/intrinsic-test/src/common/intrinsic_helpers.rs @@ -1,3 +1,4 @@ +use std::collections::HashMap; use std::fmt; use std::ops::Deref; use std::str::FromStr; @@ -121,7 +122,7 @@ pub struct IntrinsicType { /// A value of `None` can be assumed to be 1 though. pub vec_len: Option, - pub target: String, + pub metadata: HashMap, } impl IntrinsicType { @@ -153,6 +154,10 @@ impl IntrinsicType { self.ptr } + pub fn set_metadata(&mut self, key: &str, value: &str) { + self.metadata.insert(key.to_string(), value.to_string()); + } + pub fn c_scalar_type(&self) -> String { match self.kind() { TypeKind::Char(_) => String::from("char"), @@ -322,7 +327,7 @@ pub trait IntrinsicTypeDefinition: Deref { fn get_lane_function(&self) -> String; /// can be implemented in an `impl` block - fn from_c(_s: &str, _target: &str) -> Result + fn from_c(_s: &str) -> Result where Self: Sized;