blob: 96ac3ca7856cdbc1a6e38d7dab4826734c4e31b5 [file] [log] [blame]
mod argument;
mod format;
mod functions;
mod intrinsic;
mod json_parser;
mod types;
use crate::common::cli::ProcessedCli;
use crate::common::supporting_test::SupportedArchitectureTest;
use functions::{build_c, build_rust, compare_outputs};
use intrinsic::Intrinsic;
use json_parser::get_neon_intrinsics;
use types::TypeKind;
fn build_notices(line_prefix: &str) -> String {
format!(
"\
{line_prefix}This is a transient test file, not intended for distribution. Some aspects of the
{line_prefix}test are derived from a JSON specification, published under the same license as the
{line_prefix}`intrinsic-test` crate.\n
"
)
}
pub struct ArmTestProcessor {
intrinsics: Vec<Intrinsic>,
notices: String,
cli_options: ProcessedCli,
}
impl SupportedArchitectureTest for ArmTestProcessor {
fn create(cli_options: ProcessedCli) -> Self {
let a32 = cli_options.target.contains("v7");
let mut intrinsics =
get_neon_intrinsics(&cli_options.filename).expect("Error parsing input file");
intrinsics.sort_by(|a, b| a.name.cmp(&b.name));
let mut intrinsics = intrinsics
.into_iter()
// Not sure how we would compare intrinsic that returns void.
.filter(|i| i.results.kind() != TypeKind::Void)
.filter(|i| i.results.kind() != TypeKind::BFloat)
.filter(|i| !i.arguments.iter().any(|a| a.ty.kind() == TypeKind::BFloat))
// Skip pointers for now, we would probably need to look at the return
// type to work out how many elements we need to point to.
.filter(|i| !i.arguments.iter().any(|a| a.is_ptr()))
.filter(|i| !i.arguments.iter().any(|a| a.ty.inner_size() == 128))
.filter(|i| !cli_options.skip.contains(&i.name))
.filter(|i| !(a32 && i.a64_only))
.collect::<Vec<_>>();
intrinsics.dedup();
let notices = build_notices("// ");
Self {
intrinsics: intrinsics,
notices: notices,
cli_options: cli_options,
}
}
fn build_c_file(&self) -> bool {
build_c(
&self.notices,
&self.intrinsics,
self.cli_options.cpp_compiler.as_deref(),
&self.cli_options.target,
self.cli_options.cxx_toolchain_dir.as_deref(),
)
}
fn build_rust_file(&self) -> bool {
build_rust(
&self.notices,
&self.intrinsics,
self.cli_options.toolchain.as_deref(),
&self.cli_options.target,
self.cli_options.linker.as_deref(),
)
}
fn compare_outputs(&self) -> bool {
if let Some(ref toolchain) = self.cli_options.toolchain {
compare_outputs(
&self.intrinsics,
toolchain,
&self.cli_options.c_runner,
&self.cli_options.target,
)
} else {
true
}
}
}