Skip to content

Adding the x86 part of behavioural testing for std::arch intrinsics #1814

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 15 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions crates/intrinsic-test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@ pretty_env_logger = "0.5.0"
rayon = "1.5.0"
diff = "0.1.12"
itertools = "0.14.0"
quick-xml = { version = "0.37.5", features = ["serialize", "overlapped-lists"] }
serde-xml-rs = "0.8.0"
12 changes: 9 additions & 3 deletions crates/intrinsic-test/src/arm/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::common::argument::ArgumentList;
use crate::common::indentation::Indentation;
use crate::common::intrinsic::{Intrinsic, IntrinsicDefinition};
use crate::common::intrinsic_helpers::{IntrinsicType, IntrinsicTypeDefinition, TypeKind};
use std::ops::Deref;
use std::ops::{Deref, DerefMut};

#[derive(Debug, Clone, PartialEq)]
pub struct ArmIntrinsicType(pub IntrinsicType);
Expand All @@ -15,6 +15,12 @@ impl Deref for ArmIntrinsicType {
}
}

impl DerefMut for ArmIntrinsicType {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}

impl IntrinsicDefinition<ArmIntrinsicType> for Intrinsic<ArmIntrinsicType> {
fn arguments(&self) -> ArgumentList<ArmIntrinsicType> {
self.arguments.clone()
Expand Down Expand Up @@ -73,8 +79,8 @@ impl IntrinsicDefinition<ArmIntrinsicType> for Intrinsic<ArmIntrinsicType> {
TypeKind::Float if self.results().inner_size() == 16 => "float16_t".to_string(),
TypeKind::Float if self.results().inner_size() == 32 => "float".to_string(),
TypeKind::Float if self.results().inner_size() == 64 => "double".to_string(),
TypeKind::Int => format!("int{}_t", self.results().inner_size()),
TypeKind::UInt => format!("uint{}_t", self.results().inner_size()),
TypeKind::Int(true) => format!("int{}_t", self.results().inner_size()),
TypeKind::Int(false) => format!("uint{}_t", self.results().inner_size()),
TypeKind::Poly => format!("poly{}_t", self.results().inner_size()),
ty => todo!("print_result_c - Unknown type: {:#?}", ty),
},
Expand Down
10 changes: 6 additions & 4 deletions crates/intrinsic-test/src/arm/json_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ fn json_to_intrinsic(
) -> Result<Intrinsic<ArmIntrinsicType>, Box<dyn std::error::Error>> {
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".to_string(), target.to_string());
let args = intr
.arguments
.into_iter()
Expand All @@ -92,7 +92,9 @@ fn json_to_intrinsic(
let arg_prep: Option<ArgPrep> = metadata.and_then(|a| a.try_into().ok());
let constraint: Option<Constraint> = arg_prep.and_then(|a| a.try_into().ok());

let mut arg = Argument::<ArmIntrinsicType>::from_c(i, &arg, target, constraint);
let mut arg = Argument::<ArmIntrinsicType>::from_c(i, &arg, constraint);
arg.ty
.set_metadata("target".to_string(), target.to_string());

// The JSON doesn't list immediates as const
let IntrinsicType {
Expand All @@ -110,7 +112,7 @@ fn json_to_intrinsic(
Ok(Intrinsic {
name,
arguments,
results: *results,
results: results,
arch_tags: intr.architectures,
})
}
Expand Down
45 changes: 25 additions & 20 deletions crates/intrinsic-test/src/arm/types.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::collections::HashMap;

use super::intrinsic::ArmIntrinsicType;
use crate::common::cli::Language;
use crate::common::intrinsic_helpers::{IntrinsicType, IntrinsicTypeDefinition, TypeKind};
Expand Down Expand Up @@ -59,7 +61,7 @@ impl IntrinsicTypeDefinition for ArmIntrinsicType {
bit_len: Some(bl),
simd_len,
vec_len,
target,
metadata,
..
} = &self.0
{
Expand All @@ -69,12 +71,16 @@ impl IntrinsicTypeDefinition for ArmIntrinsicType {
""
};

let choose_workaround = language == Language::C && target.contains("v7");
let choose_workaround = language == Language::C
&& metadata
.get("target")
.filter(|value| value.contains("v7"))
.is_some();
format!(
"vld{len}{quad}_{type}{size}",
type = match k {
TypeKind::UInt => "u",
TypeKind::Int => "s",
TypeKind::Int(false) => "u",
TypeKind::Int(true) => "s",
TypeKind::Float => "f",
// The ACLE doesn't support 64-bit polynomial loads on Armv7
// if armv7 and bl == 64, use "s", else "p"
Expand Down Expand Up @@ -107,8 +113,8 @@ impl IntrinsicTypeDefinition for ArmIntrinsicType {
format!(
"vget{quad}_lane_{type}{size}",
type = match k {
TypeKind::UInt => "u",
TypeKind::Int => "s",
TypeKind::Int(false) => "u",
TypeKind::Int(true) => "s",
TypeKind::Float => "f",
TypeKind::Poly => "p",
x => todo!("get_load_function TypeKind: {:#?}", x),
Expand All @@ -121,20 +127,19 @@ impl IntrinsicTypeDefinition for ArmIntrinsicType {
}
}

fn from_c(s: &str, target: &str) -> Result<Box<Self>, String> {
fn from_c(s: &str) -> Result<Self, String> {
const CONST_STR: &str = "const";
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);
temp_return.map(|mut op| {
let edited = op.as_mut();
edited.0.ptr = true;
edited.0.ptr_constant = constant;
op
let temp_return = ArmIntrinsicType::from_c(s);
temp_return.and_then(|mut op| {
op.ptr = true;
op.ptr_constant = constant;
Ok(op)
})
} else {
// [const ]TYPE[{bitlen}[x{simdlen}[x{vec_len}]]][_t]
Expand Down Expand Up @@ -163,32 +168,32 @@ impl IntrinsicTypeDefinition for ArmIntrinsicType {
),
None => None,
};
Ok(Box::new(ArmIntrinsicType(IntrinsicType {
Ok(ArmIntrinsicType(IntrinsicType {
ptr: false,
ptr_constant: false,
constant,
kind: arg_kind,
bit_len: Some(bit_len),
simd_len,
vec_len,
target: target.to_string(),
})))
metadata: HashMap::new(),
}))
} else {
let kind = start.parse::<TypeKind>()?;
let bit_len = match kind {
TypeKind::Int => Some(32),
TypeKind::Int(_) => Some(32),
_ => None,
};
Ok(Box::new(ArmIntrinsicType(IntrinsicType {
Ok(ArmIntrinsicType(IntrinsicType {
ptr: false,
ptr_constant: false,
constant,
kind: start.parse::<TypeKind>()?,
bit_len,
simd_len: None,
vec_len: None,
target: target.to_string(),
})))
metadata: HashMap::new(),
}))
}
}
}
Expand Down
21 changes: 12 additions & 9 deletions crates/intrinsic-test/src/common/argument.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@ impl<T> Argument<T>
where
T: IntrinsicTypeDefinition,
{
pub fn new(pos: usize, name: String, ty: T, constraint: Option<Constraint>) -> Self {
Argument {
pos,
name,
ty,
constraint,
}
}

pub fn to_c_type(&self) -> String {
self.ty.c_type()
}
Expand Down Expand Up @@ -62,21 +71,15 @@ where
}
}

pub fn from_c(
pos: usize,
arg: &str,
target: &str,
constraint: Option<Constraint>,
) -> Argument<T> {
pub fn from_c(pos: usize, arg: &str, constraint: Option<Constraint>) -> Argument<T> {
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}'"));
let ty = T::from_c(ty).unwrap_or_else(|_| panic!("Failed to parse argument '{arg}'"));

Argument {
pos,
name: String::from(var_name),
ty: *ty,
ty: ty,
constraint,
}
}
Expand Down
3 changes: 1 addition & 2 deletions crates/intrinsic-test/src/common/gen_c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ pub fn generate_c_test_loop<T: IntrinsicTypeDefinition + Sized>(
indentation: Indentation,
additional: &str,
passes: u32,
_target: &str,
) -> String {
let body_indentation = indentation.nested();
format!(
Expand Down Expand Up @@ -157,7 +156,7 @@ pub fn generate_c_constraint_blocks<T: IntrinsicTypeDefinition>(
})
.join("\n")
} else {
generate_c_test_loop(intrinsic, indentation, &name, PASSES, target)
generate_c_test_loop(intrinsic, indentation, &name, PASSES)
}
}

Expand Down
Loading