mirror of
https://github.com/Noratrieb/intringen.git
synced 2026-01-14 13:55:02 +01:00
rewrite codegen to syn
This commit is contained in:
parent
1dcfb83114
commit
2f60340a3b
5 changed files with 367 additions and 279 deletions
26
Cargo.lock
generated
26
Cargo.lock
generated
|
|
@ -37,8 +37,12 @@ dependencies = [
|
||||||
"eyre",
|
"eyre",
|
||||||
"heck",
|
"heck",
|
||||||
"logos",
|
"logos",
|
||||||
|
"prettyplease",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
"rand",
|
"rand",
|
||||||
"strong-xml",
|
"strong-xml",
|
||||||
|
"syn 2.0.48",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -109,7 +113,7 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"regex-syntax",
|
"regex-syntax",
|
||||||
"syn 2.0.46",
|
"syn 2.0.48",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -140,10 +144,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "prettyplease"
|
||||||
version = "1.0.74"
|
version = "0.2.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2de98502f212cfcea8d0bb305bd0f49d7ebdd75b64ba0a68f937d888f4e0d6db"
|
checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"syn 2.0.48",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.75"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "907a61bd0f64c2f29cd1cf1dc34d05176426a3f504a78010f08416ddb7b13708"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
@ -230,9 +244,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.46"
|
version = "2.0.48"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "89456b690ff72fddcecf231caedbe615c59480c93358a93dfae7fc29e3ebbf0e"
|
checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
|
||||||
|
|
@ -9,5 +9,9 @@ edition = "2021"
|
||||||
eyre = "0.6.11"
|
eyre = "0.6.11"
|
||||||
heck = "0.4.1"
|
heck = "0.4.1"
|
||||||
logos = "0.13.0"
|
logos = "0.13.0"
|
||||||
|
prettyplease = "0.2.16"
|
||||||
|
proc-macro2 = "1.0.75"
|
||||||
|
quote = "1.0.35"
|
||||||
rand = { version = "0.8.5", features = ["small_rng"] }
|
rand = { version = "0.8.5", features = ["small_rng"] }
|
||||||
strong-xml = "0.6.3"
|
strong-xml = "0.6.3"
|
||||||
|
syn = "2.0.48"
|
||||||
|
|
|
||||||
|
|
@ -5,155 +5,180 @@ use crate::{
|
||||||
use eyre::{bail, Context, OptionExt, Result};
|
use eyre::{bail, Context, OptionExt, Result};
|
||||||
use rand::{rngs::SmallRng, Rng, SeedableRng};
|
use rand::{rngs::SmallRng, Rng, SeedableRng};
|
||||||
|
|
||||||
pub fn generate(intrinsics: &[Intrinsic]) -> Result<()> {
|
pub fn generate(intrinsics: &[Intrinsic]) -> Result<syn::File> {
|
||||||
println!("impl<C: super::Core> Intrinsics for C {{}}");
|
let blanket: syn::ItemImpl = syn::parse_quote! {
|
||||||
println!("pub trait Intrinsics: super::Core {{");
|
impl<C: super::Core> Intrinsics for C {}
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut trait_def: syn::ItemTrait = syn::parse_quote! {
|
||||||
|
pub trait Intrinsics: super::Core {}
|
||||||
|
};
|
||||||
for intr in intrinsics {
|
for intr in intrinsics {
|
||||||
generate_intr(intr).wrap_err_with(|| format!("generating `{}`", intr.name))?;
|
let item = generate_intr(intr).wrap_err_with(|| format!("generating `{}`", intr.name))?;
|
||||||
|
trait_def.items.push(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("}}");
|
let soft_arch =
|
||||||
|
|
||||||
println!();
|
|
||||||
generate_soft_arch_module(intrinsics).wrap_err("generating soft_arch module")?;
|
generate_soft_arch_module(intrinsics).wrap_err("generating soft_arch module")?;
|
||||||
|
|
||||||
generate_test_module(intrinsics).wrap_err("generating test module")?;
|
let test = generate_test_module(intrinsics).wrap_err("generating test module")?;
|
||||||
|
|
||||||
Ok(())
|
let mut file: syn::File = syn::parse_quote! {};
|
||||||
|
file.items = vec![
|
||||||
|
blanket.into(),
|
||||||
|
trait_def.into(),
|
||||||
|
soft_arch.into(),
|
||||||
|
test.into(),
|
||||||
|
];
|
||||||
|
|
||||||
|
Ok(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_soft_arch_module(intrinsics: &[Intrinsic]) -> Result<()> {
|
fn generate_soft_arch_module(intrinsics: &[Intrinsic]) -> Result<syn::ItemMod> {
|
||||||
println!("pub mod soft_arch {{");
|
let mut module: syn::ItemMod = syn::parse_quote! {
|
||||||
println!(" pub use super::super::soft_arch_types::*;");
|
pub mod soft_arch {
|
||||||
println!(" use super::Intrinsics;");
|
pub use super::super::soft_arch_types::*;
|
||||||
|
use super::Intrinsics;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
for intr in intrinsics {
|
for intr in intrinsics {
|
||||||
generate_intr_soft_arch_wrap(intr)
|
let item = generate_intr_soft_arch_wrap(intr)
|
||||||
.wrap_err_with(|| format!("generating soft_arch `{}`", intr.name))?;
|
.wrap_err_with(|| format!("generating `{}`", intr.name))?;
|
||||||
|
module.content.as_mut().unwrap().1.push(item.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("}}");
|
Ok(module)
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_test_module(intrinsics: &[Intrinsic]) -> Result<()> {
|
fn generate_test_module(intrinsics: &[Intrinsic]) -> Result<syn::ItemMod> {
|
||||||
println!("#[cfg(all(test, target_arch = \"x86_64\"))]");
|
let mut module: syn::ItemMod = syn::parse_quote! {
|
||||||
println!("pub mod tests {{");
|
#[cfg(all(test, target_arch = "x86_64"))]
|
||||||
println!(" use super::super::compare_test_helper::hard_soft_same_128;");
|
pub mod tests {
|
||||||
|
use super::super::compare_test_helper::hard_soft_same_128;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let rng = &mut SmallRng::seed_from_u64(44);
|
let rng = &mut SmallRng::seed_from_u64(44);
|
||||||
|
|
||||||
for intr in intrinsics {
|
for intr in intrinsics {
|
||||||
generate_intr_test(intr, rng)
|
let item = generate_intr_test(intr, rng)
|
||||||
.wrap_err_with(|| format!("generating soft_arch `{}`", intr.name))?;
|
.wrap_err_with(|| format!("generating soft_arch `{}`", intr.name))?;
|
||||||
|
|
||||||
|
module.content.as_mut().unwrap().1.push(item.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("}}");
|
Ok(module)
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_intr(intr: &Intrinsic) -> Result<(), eyre::Error> {
|
fn generate_intr(intr: &Intrinsic) -> Result<syn::TraitItem, eyre::Error> {
|
||||||
eprintln!("generating {}...", intr.name);
|
eprintln!("generating {}...", intr.name);
|
||||||
let signature = signature(intr)?;
|
|
||||||
println!(" {signature} {{");
|
|
||||||
let body = generate_body(intr).wrap_err("generating body")?;
|
let body = generate_body(intr).wrap_err("generating body")?;
|
||||||
println!("{}", indent(&body, 8));
|
|
||||||
println!(" }}");
|
signature(intr, body)
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_intr_soft_arch_wrap(intr: &Intrinsic) -> Result<(), eyre::Error> {
|
fn generate_intr_soft_arch_wrap(intr: &Intrinsic) -> Result<syn::ItemFn, eyre::Error> {
|
||||||
eprintln!("generating soft_arch wrapper {}...", intr.name);
|
eprintln!("generating soft_arch wrapper {}...", intr.name);
|
||||||
let signature = signature_soft_arch(intr)?;
|
|
||||||
println!(" {signature} {{");
|
|
||||||
let body = generate_body_soft_arch(intr).wrap_err("generating body")?;
|
let body = generate_body_soft_arch(intr).wrap_err("generating body")?;
|
||||||
println!("{}", indent(&body, 8));
|
|
||||||
println!(" }}");
|
signature_soft_arch(intr, body)
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_intr_test(intr: &Intrinsic, rng: &mut SmallRng) -> Result<(), eyre::Error> {
|
fn generate_intr_test(intr: &Intrinsic, rng: &mut SmallRng) -> Result<syn::ItemFn, eyre::Error> {
|
||||||
eprintln!("generating test {}...", intr.name);
|
eprintln!("generating test {}...", intr.name);
|
||||||
println!(" #[test]");
|
|
||||||
let name = &intr.name;
|
let name = ident(&intr.name);
|
||||||
println!(" fn {name}() {{");
|
|
||||||
// TODO: non-128
|
|
||||||
println!(" hard_soft_same_128! {{");
|
|
||||||
let body = generate_body_test(intr, rng).wrap_err("generating body")?;
|
let body = generate_body_test(intr, rng).wrap_err("generating body")?;
|
||||||
println!("{}", indent(&body, 12));
|
|
||||||
println!(" }}");
|
Ok(syn::parse_quote! {
|
||||||
println!(" }}");
|
#[test]
|
||||||
Ok(())
|
fn #name() {
|
||||||
|
hard_soft_same_128! {
|
||||||
|
#body
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_body_soft_arch(intr: &Intrinsic) -> Result<String> {
|
fn generate_body_soft_arch(intr: &Intrinsic) -> Result<syn::Block> {
|
||||||
let mut rust_stmts = Vec::<String>::new();
|
let mut rust_stmts = Vec::<syn::Stmt>::new();
|
||||||
|
|
||||||
rust_stmts.push("let mut output = unsafe { std::mem::zeroed() };".into());
|
rust_stmts.push(syn::parse_quote! { let mut output = unsafe { std::mem::zeroed() }; });
|
||||||
|
|
||||||
let name = &intr.name;
|
let name = ident(&intr.name);
|
||||||
let args = intr
|
|
||||||
.parameter
|
|
||||||
.iter()
|
|
||||||
.map(|param| param.varname.as_deref().ok_or_eyre("parameter has no name"))
|
|
||||||
.collect::<Result<Vec<_>>>()?
|
|
||||||
.join(", ");
|
|
||||||
rust_stmts.push(format!(
|
|
||||||
"super::super::ValueCore.{name}(&mut output, {args});"
|
|
||||||
));
|
|
||||||
|
|
||||||
rust_stmts.push("output".into());
|
let args = intr.parameter.iter().map(|param| -> syn::Expr {
|
||||||
|
let name = ident_opt_s(¶m.varname).unwrap();
|
||||||
|
syn::parse_quote! { #name }
|
||||||
|
});
|
||||||
|
|
||||||
Ok(rust_stmts.join("\n"))
|
rust_stmts.push(syn::parse_quote! {
|
||||||
|
super::super::ValueCore.#name(&mut output, #(#args),*);
|
||||||
|
});
|
||||||
|
|
||||||
|
rust_stmts.push(syn::Stmt::Expr(syn::parse_quote! { output }, None));
|
||||||
|
|
||||||
|
Ok(syn::parse_quote! {
|
||||||
|
{ #(#rust_stmts)* }
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_body_test(intr: &Intrinsic, rng: &mut SmallRng) -> Result<String> {
|
fn generate_body_test(intr: &Intrinsic, rng: &mut SmallRng) -> Result<syn::Block> {
|
||||||
let mut rust_stmts = Vec::<String>::new();
|
let mut rust_stmts = Vec::<syn::Stmt>::new();
|
||||||
|
|
||||||
let args = intr
|
let args = intr
|
||||||
.parameter
|
.parameter
|
||||||
.iter()
|
.iter()
|
||||||
.map(|param| -> Result<&str> {
|
.map(|param| -> Result<syn::Expr> {
|
||||||
let name = param.varname.as_deref().unwrap();
|
let name = ident_opt_s(¶m.varname).unwrap();
|
||||||
let ty = map_type_to_rust(param.r#type.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)?));
|
let random = random_value(ty, rng)?;
|
||||||
Ok(name)
|
rust_stmts.push(syn::parse_quote! { let #name = #random; });
|
||||||
|
Ok(syn::parse_quote! { #name })
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>>>()
|
.collect::<Result<Vec<syn::Expr>>>()
|
||||||
.wrap_err("preparing arguments")?
|
.wrap_err("preparing arguments")?;
|
||||||
.join(", ");
|
|
||||||
|
|
||||||
let name = &intr.name;
|
let name = ident(&intr.name);
|
||||||
rust_stmts.push(format!("{name}({args})"));
|
rust_stmts.push(syn::Stmt::Expr(
|
||||||
|
syn::parse_quote!(#name( #(#args),* )),
|
||||||
|
None,
|
||||||
|
));
|
||||||
|
|
||||||
Ok(rust_stmts.join("\n"))
|
Ok(syn::parse_quote! {
|
||||||
|
{ #(#rust_stmts)* }
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn random_value(ty: &str, rng: &mut SmallRng) -> Result<String> {
|
fn random_value(ty: &str, rng: &mut SmallRng) -> Result<syn::Expr> {
|
||||||
|
let quotei16 = |n| {
|
||||||
|
syn::parse_quote! { #n }
|
||||||
|
};
|
||||||
Ok(match ty {
|
Ok(match ty {
|
||||||
"i16" => rng.gen::<i16>().to_string(),
|
"i16" => quotei16(rng.gen::<i16>()),
|
||||||
"__m128i" => format!(
|
"__m128i" => {
|
||||||
"_mm_setr_epi16({}, {}, {}, {}, {}, {}, {}, {})",
|
let args = [
|
||||||
rng.gen::<i16>().to_string(),
|
quotei16(rng.gen::<i16>()),
|
||||||
rng.gen::<i16>().to_string(),
|
quotei16(rng.gen::<i16>()),
|
||||||
rng.gen::<i16>().to_string(),
|
quotei16(rng.gen::<i16>()),
|
||||||
rng.gen::<i16>().to_string(),
|
quotei16(rng.gen::<i16>()),
|
||||||
rng.gen::<i16>().to_string(),
|
quotei16(rng.gen::<i16>()),
|
||||||
rng.gen::<i16>().to_string(),
|
quotei16(rng.gen::<i16>()),
|
||||||
rng.gen::<i16>().to_string(),
|
quotei16(rng.gen::<i16>()),
|
||||||
rng.gen::<i16>().to_string(),
|
quotei16(rng.gen::<i16>()),
|
||||||
),
|
];
|
||||||
|
|
||||||
|
syn::parse_quote! {
|
||||||
|
_mm_setr_epi16(#(#args),*)
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => bail!("unknown type: {ty}"),
|
_ => bail!("unknown type: {ty}"),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn indent(input: &str, indent: usize) -> String {
|
|
||||||
let replace = format!("\n{}", " ".repeat(indent));
|
|
||||||
let mut s = " ".repeat(indent);
|
|
||||||
s.push_str(&input.trim_end().replace("\n", &replace));
|
|
||||||
s
|
|
||||||
}
|
|
||||||
|
|
||||||
struct VariableType {
|
struct VariableType {
|
||||||
is_signed: bool,
|
is_signed: bool,
|
||||||
rawtype_signed: bool,
|
rawtype_signed: bool,
|
||||||
|
|
@ -192,9 +217,9 @@ impl VariableType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_body(instr: &Intrinsic) -> Result<String> {
|
fn generate_body(instr: &Intrinsic) -> Result<syn::Block> {
|
||||||
let opstmts = parse_op(instr)?;
|
let opstmts = parse_op(instr)?;
|
||||||
let mut rust_stmts = Vec::<String>::new();
|
let mut rust_stmts = Vec::<syn::Stmt>::new();
|
||||||
|
|
||||||
let type_of_ident = |ident: &str| -> Result<VariableType> {
|
let type_of_ident = |ident: &str| -> Result<VariableType> {
|
||||||
for param in &instr.parameter {
|
for param in &instr.parameter {
|
||||||
|
|
@ -222,7 +247,7 @@ fn generate_body(instr: &Intrinsic) -> Result<String> {
|
||||||
let Expr::Index { lhs, idx } = lhs else {
|
let Expr::Index { lhs, idx } = lhs else {
|
||||||
bail!("lhs of assign must be indexing");
|
bail!("lhs of assign must be indexing");
|
||||||
};
|
};
|
||||||
let Expr::Ident(ident) = *lhs else {
|
let Expr::Ident(identifier) = *lhs else {
|
||||||
bail!("lhs of indexing must be identifier");
|
bail!("lhs of indexing must be identifier");
|
||||||
};
|
};
|
||||||
let Expr::Range { left, right } = *idx else {
|
let Expr::Range { left, right } = *idx else {
|
||||||
|
|
@ -243,7 +268,7 @@ fn generate_body(instr: &Intrinsic) -> Result<String> {
|
||||||
bail!("indexing size must be power of two");
|
bail!("indexing size must be power of two");
|
||||||
}
|
}
|
||||||
|
|
||||||
let ty = type_of_ident(&ident)?;
|
let ty = type_of_ident(&identifier)?;
|
||||||
if size != ty.elem_width {
|
if size != ty.elem_width {
|
||||||
bail!(
|
bail!(
|
||||||
"unsupported not-direct element indexing, size={size}, element size={}",
|
"unsupported not-direct element indexing, size={size}, element size={}",
|
||||||
|
|
@ -254,37 +279,48 @@ fn generate_body(instr: &Intrinsic) -> Result<String> {
|
||||||
let raw = &ty.raw_type;
|
let raw = &ty.raw_type;
|
||||||
let rust_type = ty.rust_type();
|
let rust_type = ty.rust_type();
|
||||||
let lane_idx = low / ty.elem_width;
|
let lane_idx = low / ty.elem_width;
|
||||||
rust_stmts.push(format!(
|
|
||||||
"self.set_lane_{raw}_{rust_type}({ident}, {lane_idx}, {expr});"
|
let method = ident(&format!("set_lane_{raw}_{rust_type}"));
|
||||||
));
|
let identifier = ident(&identifier);
|
||||||
|
rust_stmts.push(syn::parse_quote! {
|
||||||
|
self.#method(#identifier, #lane_idx, #expr);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(rust_stmts.join("\n"))
|
Ok(syn::parse_quote! {
|
||||||
|
{ #(#rust_stmts)* }
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_expr_tmp(
|
fn generate_expr_tmp(
|
||||||
rust_stmts: &mut Vec<String>,
|
rust_stmts: &mut Vec<syn::Stmt>,
|
||||||
expr: Expr,
|
expr: Expr,
|
||||||
type_of_ident: &impl Fn(&str) -> Result<VariableType>,
|
type_of_ident: &impl Fn(&str) -> Result<VariableType>,
|
||||||
) -> Result<String> {
|
) -> Result<syn::Expr> {
|
||||||
let result = match expr {
|
let tmp = |rust_stmts: &mut Vec<syn::Stmt>, inner: syn::Expr| {
|
||||||
Expr::Int(int) => int.to_string(),
|
let stmt = syn::parse_quote! { let __tmp = #inner; };
|
||||||
Expr::Ident(ident) => {
|
rust_stmts.push(stmt);
|
||||||
let ty = type_of_ident(&ident)?;
|
syn::parse_quote! { __tmp }
|
||||||
|
};
|
||||||
|
|
||||||
|
let result: syn::Expr = match expr {
|
||||||
|
Expr::Int(int) => syn::parse_quote! { #int },
|
||||||
|
Expr::Ident(identifier) => {
|
||||||
|
let ty = type_of_ident(&identifier)?;
|
||||||
|
let identifier = ident(&identifier);
|
||||||
if ty.is_signed != ty.rawtype_signed {
|
if ty.is_signed != ty.rawtype_signed {
|
||||||
let from = &ty.raw_type;
|
let from = &ty.raw_type;
|
||||||
let to = ty.rust_type();
|
let to = ty.rust_type();
|
||||||
let stmt = format!("let __tmp = self.cast_sign_{from}_{to}({ident});");
|
let method = ident(&format!("cast_sign_{from}_{to}"));
|
||||||
rust_stmts.push(stmt);
|
tmp(rust_stmts, syn::parse_quote! { self.#method(#identifier) })
|
||||||
"__tmp".into()
|
|
||||||
} else {
|
} else {
|
||||||
ident
|
syn::parse_quote! { #identifier }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Expr::Index { lhs, idx } => {
|
Expr::Index { lhs, idx } => {
|
||||||
let Expr::Ident(ident) = *lhs else {
|
let Expr::Ident(identifier) = *lhs else {
|
||||||
bail!("lhs of indexing must be identifier");
|
bail!("lhs of indexing must be identifier");
|
||||||
};
|
};
|
||||||
let Expr::Range { left, right } = *idx else {
|
let Expr::Range { left, right } = *idx else {
|
||||||
|
|
@ -304,7 +340,7 @@ fn generate_expr_tmp(
|
||||||
bail!("indexing size must be power of two");
|
bail!("indexing size must be power of two");
|
||||||
}
|
}
|
||||||
|
|
||||||
let ty = type_of_ident(&ident)?;
|
let ty = type_of_ident(&identifier)?;
|
||||||
if size != ty.elem_width {
|
if size != ty.elem_width {
|
||||||
bail!(
|
bail!(
|
||||||
"unsupported not-direct element indexing, size={size}, element size={}",
|
"unsupported not-direct element indexing, size={size}, element size={}",
|
||||||
|
|
@ -314,21 +350,27 @@ fn generate_expr_tmp(
|
||||||
let raw = &ty.raw_type;
|
let raw = &ty.raw_type;
|
||||||
let rust_type = ty.rust_type();
|
let rust_type = ty.rust_type();
|
||||||
let lane_idx = low / ty.elem_width;
|
let lane_idx = low / ty.elem_width;
|
||||||
let stmt = format!("let __tmp = self.get_lane_{raw}_{rust_type}({ident}, {lane_idx});");
|
|
||||||
rust_stmts.push(stmt);
|
let identifier = ident(&identifier);
|
||||||
"__tmp".into()
|
let method = ident(&format!("get_lane_{raw}_{rust_type}"));
|
||||||
|
|
||||||
|
tmp(
|
||||||
|
rust_stmts,
|
||||||
|
syn::parse_quote! { self.#method(#identifier, #lane_idx) },
|
||||||
|
)
|
||||||
}
|
}
|
||||||
Expr::Range { .. } => todo!(),
|
Expr::Range { .. } => todo!(),
|
||||||
Expr::Call { function, args } => {
|
Expr::Call { function, args } => {
|
||||||
let function = heck::AsSnekCase(function);
|
let function = ident(&heck::ToSnekCase::to_snek_case(function.as_str()));
|
||||||
let args = args
|
let args = args
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|arg| generate_expr_tmp(rust_stmts, arg, type_of_ident))
|
.map(|arg| generate_expr_tmp(rust_stmts, arg, type_of_ident))
|
||||||
.collect::<Result<Vec<_>>>()?
|
.collect::<Result<Vec<syn::Expr>>>()?;
|
||||||
.join(", ");
|
|
||||||
let stmt = format!("let __tmp = self.{function}({args});");
|
tmp(
|
||||||
rust_stmts.push(stmt);
|
rust_stmts,
|
||||||
"__tmp".into()
|
syn::parse_quote! { self.#function( #(#args),* ) },
|
||||||
|
)
|
||||||
}
|
}
|
||||||
Expr::BinaryOp { .. } => todo!(),
|
Expr::BinaryOp { .. } => todo!(),
|
||||||
};
|
};
|
||||||
|
|
@ -343,49 +385,48 @@ fn parse_op(intr: &Intrinsic) -> Result<Vec<Stmt>> {
|
||||||
Ok(stmts)
|
Ok(stmts)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn signature(intr: &Intrinsic) -> Result<String> {
|
fn ident(s: &str) -> syn::Ident {
|
||||||
let name = &intr.name;
|
syn::Ident::new(s, proc_macro2::Span::call_site())
|
||||||
|
}
|
||||||
let args = intr
|
fn ident_opt_s(s: &Option<String>) -> Result<syn::Ident> {
|
||||||
.parameter
|
let s = s.as_deref().ok_or_eyre("missing")?;
|
||||||
.iter()
|
Ok(ident(s))
|
||||||
.map(|param| {
|
|
||||||
format!(
|
|
||||||
"{}: Self::{}",
|
|
||||||
param.varname.as_ref().unwrap(),
|
|
||||||
map_type_to_rust(param.r#type.as_ref().unwrap())
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.join(", ");
|
|
||||||
|
|
||||||
let ret_name = intr.ret.varname.as_ref().unwrap();
|
|
||||||
let ret_ty = map_type_to_rust(intr.ret.r#type.as_ref().unwrap());
|
|
||||||
|
|
||||||
Ok(format!(
|
|
||||||
"fn {name}(&mut self, {ret_name}: &mut Self::{ret_ty}, {args})"
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn signature_soft_arch(intr: &Intrinsic) -> Result<String> {
|
fn signature(intr: &Intrinsic, body: syn::Block) -> Result<syn::TraitItem> {
|
||||||
let name = &intr.name;
|
let name = ident(&intr.name);
|
||||||
|
|
||||||
let args = intr
|
let ret_name = ident_opt_s(&intr.ret.varname)?;
|
||||||
.parameter
|
let ret_ty = ident(map_type_to_rust(intr.ret.r#type.as_ref().unwrap()));
|
||||||
.iter()
|
|
||||||
.map(|param| {
|
|
||||||
format!(
|
|
||||||
"{}: {}",
|
|
||||||
param.varname.as_ref().unwrap(),
|
|
||||||
map_type_to_rust(param.r#type.as_ref().unwrap())
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.join(", ");
|
|
||||||
|
|
||||||
let ret_ty = map_type_to_rust(intr.ret.r#type.as_ref().unwrap());
|
let args = [
|
||||||
|
syn::parse_quote! { &mut self },
|
||||||
|
syn::parse_quote! { #ret_name: &mut Self::#ret_ty },
|
||||||
|
]
|
||||||
|
.into_iter()
|
||||||
|
.chain(intr.parameter.iter().map(|param| -> syn::FnArg {
|
||||||
|
let varname = ident_opt_s(¶m.varname).unwrap();
|
||||||
|
let ty = ident(map_type_to_rust(param.r#type.as_ref().unwrap()));
|
||||||
|
|
||||||
Ok(format!("pub fn {name}({args}) -> {ret_ty}"))
|
syn::parse_quote! { #varname: Self::#ty }
|
||||||
|
}));
|
||||||
|
|
||||||
|
Ok(syn::parse_quote! { fn #name(#(#args),*) #body })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn signature_soft_arch(intr: &Intrinsic, body: syn::Block) -> Result<syn::ItemFn> {
|
||||||
|
let name = ident(&intr.name);
|
||||||
|
|
||||||
|
let args = intr.parameter.iter().map(|param| -> syn::FnArg {
|
||||||
|
let varname = ident_opt_s(¶m.varname).unwrap();
|
||||||
|
let ty = ident(map_type_to_rust(param.r#type.as_ref().unwrap()));
|
||||||
|
|
||||||
|
syn::parse_quote! { #varname: #ty }
|
||||||
|
});
|
||||||
|
|
||||||
|
let ret_ty = ident(map_type_to_rust(intr.ret.r#type.as_ref().unwrap()));
|
||||||
|
|
||||||
|
Ok(syn::parse_quote! { pub fn #name( #(#args),* ) -> #ret_ty #body })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn map_type_to_rust(ty: &str) -> &str {
|
fn map_type_to_rust(ty: &str) -> &str {
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,9 @@ fn main() -> Result<()> {
|
||||||
|
|
||||||
eprintln!("filtered: {}", list.len());
|
eprintln!("filtered: {}", list.len());
|
||||||
|
|
||||||
generate::generate(&list).wrap_err("generating rust code")?;
|
let generated_mod = generate::generate(&list).wrap_err("generating rust code")?;
|
||||||
|
|
||||||
|
println!("{}", prettyplease::unparse(&generated_mod));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,131 +1,161 @@
|
||||||
impl<C: super::Core> Intrinsics for C {}
|
impl<C: super::Core> Intrinsics for C {}
|
||||||
pub trait Intrinsics: super::Core {
|
pub trait Intrinsics: super::Core {
|
||||||
fn _mm_setr_epi16(&mut self, dst: &mut Self::__m128i, e7: Self::i16, e6: Self::i16, e5: Self::i16, e4: Self::i16, e3: Self::i16, e2: Self::i16, e1: Self::i16, e0: Self::i16) {
|
fn _mm_setr_epi16(
|
||||||
|
&mut self,
|
||||||
|
dst: &mut Self::__m128i,
|
||||||
|
e7: Self::i16,
|
||||||
|
e6: Self::i16,
|
||||||
|
e5: Self::i16,
|
||||||
|
e4: Self::i16,
|
||||||
|
e3: Self::i16,
|
||||||
|
e2: Self::i16,
|
||||||
|
e1: Self::i16,
|
||||||
|
e0: Self::i16,
|
||||||
|
) {
|
||||||
let __tmp = self.cast_sign_i16_u16(e7);
|
let __tmp = self.cast_sign_i16_u16(e7);
|
||||||
self.set_lane___m128i_u16(dst, 0, __tmp);
|
self.set_lane___m128i_u16(dst, 0u64, __tmp);
|
||||||
let __tmp = self.cast_sign_i16_u16(e6);
|
let __tmp = self.cast_sign_i16_u16(e6);
|
||||||
self.set_lane___m128i_u16(dst, 1, __tmp);
|
self.set_lane___m128i_u16(dst, 1u64, __tmp);
|
||||||
let __tmp = self.cast_sign_i16_u16(e5);
|
let __tmp = self.cast_sign_i16_u16(e5);
|
||||||
self.set_lane___m128i_u16(dst, 2, __tmp);
|
self.set_lane___m128i_u16(dst, 2u64, __tmp);
|
||||||
let __tmp = self.cast_sign_i16_u16(e4);
|
let __tmp = self.cast_sign_i16_u16(e4);
|
||||||
self.set_lane___m128i_u16(dst, 3, __tmp);
|
self.set_lane___m128i_u16(dst, 3u64, __tmp);
|
||||||
let __tmp = self.cast_sign_i16_u16(e3);
|
let __tmp = self.cast_sign_i16_u16(e3);
|
||||||
self.set_lane___m128i_u16(dst, 4, __tmp);
|
self.set_lane___m128i_u16(dst, 4u64, __tmp);
|
||||||
let __tmp = self.cast_sign_i16_u16(e2);
|
let __tmp = self.cast_sign_i16_u16(e2);
|
||||||
self.set_lane___m128i_u16(dst, 5, __tmp);
|
self.set_lane___m128i_u16(dst, 5u64, __tmp);
|
||||||
let __tmp = self.cast_sign_i16_u16(e1);
|
let __tmp = self.cast_sign_i16_u16(e1);
|
||||||
self.set_lane___m128i_u16(dst, 6, __tmp);
|
self.set_lane___m128i_u16(dst, 6u64, __tmp);
|
||||||
let __tmp = self.cast_sign_i16_u16(e0);
|
let __tmp = self.cast_sign_i16_u16(e0);
|
||||||
self.set_lane___m128i_u16(dst, 7, __tmp);
|
self.set_lane___m128i_u16(dst, 7u64, __tmp);
|
||||||
}
|
}
|
||||||
fn _mm_packs_epi16(&mut self, dst: &mut Self::__m128i, a: Self::__m128i, b: Self::__m128i) {
|
fn _mm_packs_epi16(
|
||||||
let __tmp = self.get_lane___m128i_i16(a, 0);
|
&mut self,
|
||||||
|
dst: &mut Self::__m128i,
|
||||||
|
a: Self::__m128i,
|
||||||
|
b: Self::__m128i,
|
||||||
|
) {
|
||||||
|
let __tmp = self.get_lane___m128i_i16(a, 0u64);
|
||||||
let __tmp = self.saturate8(__tmp);
|
let __tmp = self.saturate8(__tmp);
|
||||||
self.set_lane___m128i_i8(dst, 0, __tmp);
|
self.set_lane___m128i_i8(dst, 0u64, __tmp);
|
||||||
let __tmp = self.get_lane___m128i_i16(a, 1);
|
let __tmp = self.get_lane___m128i_i16(a, 1u64);
|
||||||
let __tmp = self.saturate8(__tmp);
|
let __tmp = self.saturate8(__tmp);
|
||||||
self.set_lane___m128i_i8(dst, 1, __tmp);
|
self.set_lane___m128i_i8(dst, 1u64, __tmp);
|
||||||
let __tmp = self.get_lane___m128i_i16(a, 2);
|
let __tmp = self.get_lane___m128i_i16(a, 2u64);
|
||||||
let __tmp = self.saturate8(__tmp);
|
let __tmp = self.saturate8(__tmp);
|
||||||
self.set_lane___m128i_i8(dst, 2, __tmp);
|
self.set_lane___m128i_i8(dst, 2u64, __tmp);
|
||||||
let __tmp = self.get_lane___m128i_i16(a, 3);
|
let __tmp = self.get_lane___m128i_i16(a, 3u64);
|
||||||
let __tmp = self.saturate8(__tmp);
|
let __tmp = self.saturate8(__tmp);
|
||||||
self.set_lane___m128i_i8(dst, 3, __tmp);
|
self.set_lane___m128i_i8(dst, 3u64, __tmp);
|
||||||
let __tmp = self.get_lane___m128i_i16(a, 4);
|
let __tmp = self.get_lane___m128i_i16(a, 4u64);
|
||||||
let __tmp = self.saturate8(__tmp);
|
let __tmp = self.saturate8(__tmp);
|
||||||
self.set_lane___m128i_i8(dst, 4, __tmp);
|
self.set_lane___m128i_i8(dst, 4u64, __tmp);
|
||||||
let __tmp = self.get_lane___m128i_i16(a, 5);
|
let __tmp = self.get_lane___m128i_i16(a, 5u64);
|
||||||
let __tmp = self.saturate8(__tmp);
|
let __tmp = self.saturate8(__tmp);
|
||||||
self.set_lane___m128i_i8(dst, 5, __tmp);
|
self.set_lane___m128i_i8(dst, 5u64, __tmp);
|
||||||
let __tmp = self.get_lane___m128i_i16(a, 6);
|
let __tmp = self.get_lane___m128i_i16(a, 6u64);
|
||||||
let __tmp = self.saturate8(__tmp);
|
let __tmp = self.saturate8(__tmp);
|
||||||
self.set_lane___m128i_i8(dst, 6, __tmp);
|
self.set_lane___m128i_i8(dst, 6u64, __tmp);
|
||||||
let __tmp = self.get_lane___m128i_i16(a, 7);
|
let __tmp = self.get_lane___m128i_i16(a, 7u64);
|
||||||
let __tmp = self.saturate8(__tmp);
|
let __tmp = self.saturate8(__tmp);
|
||||||
self.set_lane___m128i_i8(dst, 7, __tmp);
|
self.set_lane___m128i_i8(dst, 7u64, __tmp);
|
||||||
let __tmp = self.get_lane___m128i_i16(b, 0);
|
let __tmp = self.get_lane___m128i_i16(b, 0u64);
|
||||||
let __tmp = self.saturate8(__tmp);
|
let __tmp = self.saturate8(__tmp);
|
||||||
self.set_lane___m128i_i8(dst, 8, __tmp);
|
self.set_lane___m128i_i8(dst, 8u64, __tmp);
|
||||||
let __tmp = self.get_lane___m128i_i16(b, 1);
|
let __tmp = self.get_lane___m128i_i16(b, 1u64);
|
||||||
let __tmp = self.saturate8(__tmp);
|
let __tmp = self.saturate8(__tmp);
|
||||||
self.set_lane___m128i_i8(dst, 9, __tmp);
|
self.set_lane___m128i_i8(dst, 9u64, __tmp);
|
||||||
let __tmp = self.get_lane___m128i_i16(b, 2);
|
let __tmp = self.get_lane___m128i_i16(b, 2u64);
|
||||||
let __tmp = self.saturate8(__tmp);
|
let __tmp = self.saturate8(__tmp);
|
||||||
self.set_lane___m128i_i8(dst, 10, __tmp);
|
self.set_lane___m128i_i8(dst, 10u64, __tmp);
|
||||||
let __tmp = self.get_lane___m128i_i16(b, 3);
|
let __tmp = self.get_lane___m128i_i16(b, 3u64);
|
||||||
let __tmp = self.saturate8(__tmp);
|
let __tmp = self.saturate8(__tmp);
|
||||||
self.set_lane___m128i_i8(dst, 11, __tmp);
|
self.set_lane___m128i_i8(dst, 11u64, __tmp);
|
||||||
let __tmp = self.get_lane___m128i_i16(b, 4);
|
let __tmp = self.get_lane___m128i_i16(b, 4u64);
|
||||||
let __tmp = self.saturate8(__tmp);
|
let __tmp = self.saturate8(__tmp);
|
||||||
self.set_lane___m128i_i8(dst, 12, __tmp);
|
self.set_lane___m128i_i8(dst, 12u64, __tmp);
|
||||||
let __tmp = self.get_lane___m128i_i16(b, 5);
|
let __tmp = self.get_lane___m128i_i16(b, 5u64);
|
||||||
let __tmp = self.saturate8(__tmp);
|
let __tmp = self.saturate8(__tmp);
|
||||||
self.set_lane___m128i_i8(dst, 13, __tmp);
|
self.set_lane___m128i_i8(dst, 13u64, __tmp);
|
||||||
let __tmp = self.get_lane___m128i_i16(b, 6);
|
let __tmp = self.get_lane___m128i_i16(b, 6u64);
|
||||||
let __tmp = self.saturate8(__tmp);
|
let __tmp = self.saturate8(__tmp);
|
||||||
self.set_lane___m128i_i8(dst, 14, __tmp);
|
self.set_lane___m128i_i8(dst, 14u64, __tmp);
|
||||||
let __tmp = self.get_lane___m128i_i16(b, 7);
|
let __tmp = self.get_lane___m128i_i16(b, 7u64);
|
||||||
let __tmp = self.saturate8(__tmp);
|
let __tmp = self.saturate8(__tmp);
|
||||||
self.set_lane___m128i_i8(dst, 15, __tmp);
|
self.set_lane___m128i_i8(dst, 15u64, __tmp);
|
||||||
}
|
}
|
||||||
fn _mm_packus_epi16(&mut self, dst: &mut Self::__m128i, a: Self::__m128i, b: Self::__m128i) {
|
fn _mm_packus_epi16(
|
||||||
let __tmp = self.get_lane___m128i_i16(a, 0);
|
&mut self,
|
||||||
|
dst: &mut Self::__m128i,
|
||||||
|
a: Self::__m128i,
|
||||||
|
b: Self::__m128i,
|
||||||
|
) {
|
||||||
|
let __tmp = self.get_lane___m128i_i16(a, 0u64);
|
||||||
let __tmp = self.saturate_u8(__tmp);
|
let __tmp = self.saturate_u8(__tmp);
|
||||||
self.set_lane___m128i_u8(dst, 0, __tmp);
|
self.set_lane___m128i_u8(dst, 0u64, __tmp);
|
||||||
let __tmp = self.get_lane___m128i_i16(a, 1);
|
let __tmp = self.get_lane___m128i_i16(a, 1u64);
|
||||||
let __tmp = self.saturate_u8(__tmp);
|
let __tmp = self.saturate_u8(__tmp);
|
||||||
self.set_lane___m128i_u8(dst, 1, __tmp);
|
self.set_lane___m128i_u8(dst, 1u64, __tmp);
|
||||||
let __tmp = self.get_lane___m128i_i16(a, 2);
|
let __tmp = self.get_lane___m128i_i16(a, 2u64);
|
||||||
let __tmp = self.saturate_u8(__tmp);
|
let __tmp = self.saturate_u8(__tmp);
|
||||||
self.set_lane___m128i_u8(dst, 2, __tmp);
|
self.set_lane___m128i_u8(dst, 2u64, __tmp);
|
||||||
let __tmp = self.get_lane___m128i_i16(a, 3);
|
let __tmp = self.get_lane___m128i_i16(a, 3u64);
|
||||||
let __tmp = self.saturate_u8(__tmp);
|
let __tmp = self.saturate_u8(__tmp);
|
||||||
self.set_lane___m128i_u8(dst, 3, __tmp);
|
self.set_lane___m128i_u8(dst, 3u64, __tmp);
|
||||||
let __tmp = self.get_lane___m128i_i16(a, 4);
|
let __tmp = self.get_lane___m128i_i16(a, 4u64);
|
||||||
let __tmp = self.saturate_u8(__tmp);
|
let __tmp = self.saturate_u8(__tmp);
|
||||||
self.set_lane___m128i_u8(dst, 4, __tmp);
|
self.set_lane___m128i_u8(dst, 4u64, __tmp);
|
||||||
let __tmp = self.get_lane___m128i_i16(a, 5);
|
let __tmp = self.get_lane___m128i_i16(a, 5u64);
|
||||||
let __tmp = self.saturate_u8(__tmp);
|
let __tmp = self.saturate_u8(__tmp);
|
||||||
self.set_lane___m128i_u8(dst, 5, __tmp);
|
self.set_lane___m128i_u8(dst, 5u64, __tmp);
|
||||||
let __tmp = self.get_lane___m128i_i16(a, 6);
|
let __tmp = self.get_lane___m128i_i16(a, 6u64);
|
||||||
let __tmp = self.saturate_u8(__tmp);
|
let __tmp = self.saturate_u8(__tmp);
|
||||||
self.set_lane___m128i_u8(dst, 6, __tmp);
|
self.set_lane___m128i_u8(dst, 6u64, __tmp);
|
||||||
let __tmp = self.get_lane___m128i_i16(a, 7);
|
let __tmp = self.get_lane___m128i_i16(a, 7u64);
|
||||||
let __tmp = self.saturate_u8(__tmp);
|
let __tmp = self.saturate_u8(__tmp);
|
||||||
self.set_lane___m128i_u8(dst, 7, __tmp);
|
self.set_lane___m128i_u8(dst, 7u64, __tmp);
|
||||||
let __tmp = self.get_lane___m128i_i16(b, 0);
|
let __tmp = self.get_lane___m128i_i16(b, 0u64);
|
||||||
let __tmp = self.saturate_u8(__tmp);
|
let __tmp = self.saturate_u8(__tmp);
|
||||||
self.set_lane___m128i_u8(dst, 8, __tmp);
|
self.set_lane___m128i_u8(dst, 8u64, __tmp);
|
||||||
let __tmp = self.get_lane___m128i_i16(b, 1);
|
let __tmp = self.get_lane___m128i_i16(b, 1u64);
|
||||||
let __tmp = self.saturate_u8(__tmp);
|
let __tmp = self.saturate_u8(__tmp);
|
||||||
self.set_lane___m128i_u8(dst, 9, __tmp);
|
self.set_lane___m128i_u8(dst, 9u64, __tmp);
|
||||||
let __tmp = self.get_lane___m128i_i16(b, 2);
|
let __tmp = self.get_lane___m128i_i16(b, 2u64);
|
||||||
let __tmp = self.saturate_u8(__tmp);
|
let __tmp = self.saturate_u8(__tmp);
|
||||||
self.set_lane___m128i_u8(dst, 10, __tmp);
|
self.set_lane___m128i_u8(dst, 10u64, __tmp);
|
||||||
let __tmp = self.get_lane___m128i_i16(b, 3);
|
let __tmp = self.get_lane___m128i_i16(b, 3u64);
|
||||||
let __tmp = self.saturate_u8(__tmp);
|
let __tmp = self.saturate_u8(__tmp);
|
||||||
self.set_lane___m128i_u8(dst, 11, __tmp);
|
self.set_lane___m128i_u8(dst, 11u64, __tmp);
|
||||||
let __tmp = self.get_lane___m128i_i16(b, 4);
|
let __tmp = self.get_lane___m128i_i16(b, 4u64);
|
||||||
let __tmp = self.saturate_u8(__tmp);
|
let __tmp = self.saturate_u8(__tmp);
|
||||||
self.set_lane___m128i_u8(dst, 12, __tmp);
|
self.set_lane___m128i_u8(dst, 12u64, __tmp);
|
||||||
let __tmp = self.get_lane___m128i_i16(b, 5);
|
let __tmp = self.get_lane___m128i_i16(b, 5u64);
|
||||||
let __tmp = self.saturate_u8(__tmp);
|
let __tmp = self.saturate_u8(__tmp);
|
||||||
self.set_lane___m128i_u8(dst, 13, __tmp);
|
self.set_lane___m128i_u8(dst, 13u64, __tmp);
|
||||||
let __tmp = self.get_lane___m128i_i16(b, 6);
|
let __tmp = self.get_lane___m128i_i16(b, 6u64);
|
||||||
let __tmp = self.saturate_u8(__tmp);
|
let __tmp = self.saturate_u8(__tmp);
|
||||||
self.set_lane___m128i_u8(dst, 14, __tmp);
|
self.set_lane___m128i_u8(dst, 14u64, __tmp);
|
||||||
let __tmp = self.get_lane___m128i_i16(b, 7);
|
let __tmp = self.get_lane___m128i_i16(b, 7u64);
|
||||||
let __tmp = self.saturate_u8(__tmp);
|
let __tmp = self.saturate_u8(__tmp);
|
||||||
self.set_lane___m128i_u8(dst, 15, __tmp);
|
self.set_lane___m128i_u8(dst, 15u64, __tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod soft_arch {
|
pub mod soft_arch {
|
||||||
pub use super::super::soft_arch_types::*;
|
pub use super::super::soft_arch_types::*;
|
||||||
use super::Intrinsics;
|
use super::Intrinsics;
|
||||||
pub fn _mm_setr_epi16(e7: i16, e6: i16, e5: i16, e4: i16, e3: i16, e2: i16, e1: i16, e0: i16) -> __m128i {
|
pub fn _mm_setr_epi16(
|
||||||
|
e7: i16,
|
||||||
|
e6: i16,
|
||||||
|
e5: i16,
|
||||||
|
e4: i16,
|
||||||
|
e3: i16,
|
||||||
|
e2: i16,
|
||||||
|
e1: i16,
|
||||||
|
e0: i16,
|
||||||
|
) -> __m128i {
|
||||||
let mut output = unsafe { std::mem::zeroed() };
|
let mut output = unsafe { std::mem::zeroed() };
|
||||||
super::super::ValueCore._mm_setr_epi16(&mut output, e7, e6, e5, e4, e3, e2, e1, e0);
|
super::super::ValueCore
|
||||||
|
._mm_setr_epi16(&mut output, e7, e6, e5, e4, e3, e2, e1, e0);
|
||||||
output
|
output
|
||||||
}
|
}
|
||||||
pub fn _mm_packs_epi16(a: __m128i, b: __m128i) -> __m128i {
|
pub fn _mm_packs_epi16(a: __m128i, b: __m128i) -> __m128i {
|
||||||
|
|
@ -145,31 +175,28 @@ pub mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn _mm_setr_epi16() {
|
fn _mm_setr_epi16() {
|
||||||
hard_soft_same_128! {
|
hard_soft_same_128! {
|
||||||
let e7 = -24391;
|
{ let e7 = - 24391i16; let e6 = 19541i16; let e5 = - 16509i16; let e4 =
|
||||||
let e6 = 19541;
|
7733i16; let e3 = - 15140i16; let e2 = 30719i16; let e1 = 16513i16; let e0 =
|
||||||
let e5 = -16509;
|
22878i16; _mm_setr_epi16(e7, e6, e5, e4, e3, e2, e1, e0) }
|
||||||
let e4 = 7733;
|
|
||||||
let e3 = -15140;
|
|
||||||
let e2 = 30719;
|
|
||||||
let e1 = 16513;
|
|
||||||
let e0 = 22878;
|
|
||||||
_mm_setr_epi16(e7, e6, e5, e4, e3, e2, e1, e0)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn _mm_packs_epi16() {
|
fn _mm_packs_epi16() {
|
||||||
hard_soft_same_128! {
|
hard_soft_same_128! {
|
||||||
let a = _mm_setr_epi16(23986, 27900, -8343, -10648, 4841, 14610, -17251, -3971);
|
{ let a = _mm_setr_epi16(23986i16, 27900i16, - 8343i16, - 10648i16, 4841i16,
|
||||||
let b = _mm_setr_epi16(22390, -23547, 15401, 15832, -14212, -1286, -18062, 22296);
|
14610i16, - 17251i16, - 3971i16); let b = _mm_setr_epi16(22390i16, -
|
||||||
_mm_packs_epi16(a, b)
|
23547i16, 15401i16, 15832i16, - 14212i16, - 1286i16, - 18062i16, 22296i16);
|
||||||
|
_mm_packs_epi16(a, b) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn _mm_packus_epi16() {
|
fn _mm_packus_epi16() {
|
||||||
hard_soft_same_128! {
|
hard_soft_same_128! {
|
||||||
let a = _mm_setr_epi16(18077, 23617, -9205, 21233, -4332, -31339, 23623, -22080);
|
{ let a = _mm_setr_epi16(18077i16, 23617i16, - 9205i16, 21233i16, - 4332i16,
|
||||||
let b = _mm_setr_epi16(-1436, -30227, 8629, 10922, -16731, -1013, -14310, 2892);
|
- 31339i16, 23623i16, - 22080i16); let b = _mm_setr_epi16(- 1436i16, -
|
||||||
_mm_packus_epi16(a, b)
|
30227i16, 8629i16, 10922i16, - 16731i16, - 1013i16, - 14310i16, 2892i16);
|
||||||
|
_mm_packus_epi16(a, b) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue