mirror of
https://github.com/Noratrieb/intringen.git
synced 2026-01-14 22:05:02 +01:00
generate tests
This commit is contained in:
parent
8f49c199cc
commit
1dcfb83114
9 changed files with 268 additions and 41 deletions
|
|
@ -9,4 +9,5 @@ edition = "2021"
|
|||
eyre = "0.6.11"
|
||||
heck = "0.4.1"
|
||||
logos = "0.13.0"
|
||||
rand = { version = "0.8.5", features = ["small_rng"] }
|
||||
strong-xml = "0.6.3"
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ use crate::{
|
|||
Intrinsic,
|
||||
};
|
||||
use eyre::{bail, Context, OptionExt, Result};
|
||||
use rand::{rngs::SmallRng, Rng, SeedableRng};
|
||||
|
||||
pub fn generate(intrinsics: &[Intrinsic]) -> Result<()> {
|
||||
println!("impl<C: super::Core> Intrinsics for C {{}}");
|
||||
|
|
@ -14,7 +15,9 @@ pub fn generate(intrinsics: &[Intrinsic]) -> Result<()> {
|
|||
println!("}}");
|
||||
|
||||
println!();
|
||||
generate_soft_arch_module(intrinsics).context("generating soft_arch module")?;
|
||||
generate_soft_arch_module(intrinsics).wrap_err("generating soft_arch module")?;
|
||||
|
||||
generate_test_module(intrinsics).wrap_err("generating test module")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -33,6 +36,21 @@ fn generate_soft_arch_module(intrinsics: &[Intrinsic]) -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn generate_test_module(intrinsics: &[Intrinsic]) -> Result<()> {
|
||||
println!("#[cfg(all(test, target_arch = \"x86_64\"))]");
|
||||
println!("pub mod tests {{");
|
||||
println!(" use super::super::compare_test_helper::hard_soft_same_128;");
|
||||
let rng = &mut SmallRng::seed_from_u64(44);
|
||||
|
||||
for intr in intrinsics {
|
||||
generate_intr_test(intr, rng)
|
||||
.wrap_err_with(|| format!("generating soft_arch `{}`", intr.name))?;
|
||||
}
|
||||
|
||||
println!("}}");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn generate_intr(intr: &Intrinsic) -> Result<(), eyre::Error> {
|
||||
eprintln!("generating {}...", intr.name);
|
||||
let signature = signature(intr)?;
|
||||
|
|
@ -53,6 +71,20 @@ fn generate_intr_soft_arch_wrap(intr: &Intrinsic) -> Result<(), eyre::Error> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn generate_intr_test(intr: &Intrinsic, rng: &mut SmallRng) -> Result<(), eyre::Error> {
|
||||
eprintln!("generating test {}...", intr.name);
|
||||
println!(" #[test]");
|
||||
let name = &intr.name;
|
||||
println!(" fn {name}() {{");
|
||||
// TODO: non-128
|
||||
println!(" hard_soft_same_128! {{");
|
||||
let body = generate_body_test(intr, rng).wrap_err("generating body")?;
|
||||
println!("{}", indent(&body, 12));
|
||||
println!(" }}");
|
||||
println!(" }}");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn generate_body_soft_arch(intr: &Intrinsic) -> Result<String> {
|
||||
let mut rust_stmts = Vec::<String>::new();
|
||||
|
||||
|
|
@ -74,6 +106,47 @@ fn generate_body_soft_arch(intr: &Intrinsic) -> Result<String> {
|
|||
Ok(rust_stmts.join("\n"))
|
||||
}
|
||||
|
||||
fn generate_body_test(intr: &Intrinsic, rng: &mut SmallRng) -> Result<String> {
|
||||
let mut rust_stmts = Vec::<String>::new();
|
||||
|
||||
let args = intr
|
||||
.parameter
|
||||
.iter()
|
||||
.map(|param| -> Result<&str> {
|
||||
let name = param.varname.as_deref().unwrap();
|
||||
let ty = map_type_to_rust(param.r#type.as_deref().unwrap());
|
||||
|
||||
rust_stmts.push(format!("let {name} = {};", random_value(ty, rng)?));
|
||||
Ok(name)
|
||||
})
|
||||
.collect::<Result<Vec<_>>>()
|
||||
.wrap_err("preparing arguments")?
|
||||
.join(", ");
|
||||
|
||||
let name = &intr.name;
|
||||
rust_stmts.push(format!("{name}({args})"));
|
||||
|
||||
Ok(rust_stmts.join("\n"))
|
||||
}
|
||||
|
||||
fn random_value(ty: &str, rng: &mut SmallRng) -> Result<String> {
|
||||
Ok(match ty {
|
||||
"i16" => rng.gen::<i16>().to_string(),
|
||||
"__m128i" => format!(
|
||||
"_mm_setr_epi16({}, {}, {}, {}, {}, {}, {}, {})",
|
||||
rng.gen::<i16>().to_string(),
|
||||
rng.gen::<i16>().to_string(),
|
||||
rng.gen::<i16>().to_string(),
|
||||
rng.gen::<i16>().to_string(),
|
||||
rng.gen::<i16>().to_string(),
|
||||
rng.gen::<i16>().to_string(),
|
||||
rng.gen::<i16>().to_string(),
|
||||
rng.gen::<i16>().to_string(),
|
||||
),
|
||||
_ => bail!("unknown type: {ty}"),
|
||||
})
|
||||
}
|
||||
|
||||
fn indent(input: &str, indent: usize) -> String {
|
||||
let replace = format!("\n{}", " ".repeat(indent));
|
||||
let mut s = " ".repeat(indent);
|
||||
|
|
@ -98,6 +171,7 @@ impl VariableType {
|
|||
_ => bail!("unknown type: {ty}"),
|
||||
};
|
||||
let (is_signed, elem_width) = match etype {
|
||||
"SI8" => (true, 8),
|
||||
"SI16" => (true, 16),
|
||||
"UI8" => (false, 8),
|
||||
"UI16" => (false, 16),
|
||||
|
|
|
|||
|
|
@ -86,4 +86,4 @@ fn main() -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
const INTRINSICS_GENERATE: &[&str] = &["_mm_packus_epi16", "_mm_setr_epi16"];
|
||||
const INTRINSICS_GENERATE: &[&str] = &["_mm_packus_epi16", "_mm_packs_epi16", "_mm_setr_epi16"];
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use eyre::{bail, ContextCompat, OptionExt, Result};
|
||||
use eyre::{bail, OptionExt, Result};
|
||||
use logos::Logos;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[allow(dead_code)]
|
||||
pub(crate) enum Stmt {
|
||||
FnDef,
|
||||
Assign {
|
||||
|
|
@ -16,6 +17,7 @@ pub(crate) enum Stmt {
|
|||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[allow(dead_code)]
|
||||
pub(crate) enum Expr {
|
||||
Int(u64),
|
||||
Ident(String),
|
||||
|
|
@ -133,7 +135,7 @@ fn parse_expr_call(parser: &mut Parser) -> Result<Expr> {
|
|||
loop {
|
||||
if parser.eat(Token::ParenOpen) {
|
||||
let arg = parse_expr(parser)?;
|
||||
parser.expect(Token::ParenClose);
|
||||
parser.expect(Token::ParenClose)?;
|
||||
let Expr::Ident(ident) = lhs else {
|
||||
panic!("lhs of function must be ident");
|
||||
};
|
||||
|
|
@ -145,7 +147,7 @@ fn parse_expr_call(parser: &mut Parser) -> Result<Expr> {
|
|||
}
|
||||
if parser.eat(Token::BracketOpen) {
|
||||
let arg = parse_expr(parser)?;
|
||||
parser.expect(Token::BracketClose);
|
||||
parser.expect(Token::BracketClose)?;
|
||||
lhs = Expr::Index {
|
||||
lhs: Box::new(lhs),
|
||||
idx: Box::new(arg),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue