rewrite codegen to syn

This commit is contained in:
nora 2024-01-05 23:48:53 +01:00
parent 1dcfb83114
commit 2f60340a3b
5 changed files with 367 additions and 279 deletions

26
Cargo.lock generated
View file

@ -37,8 +37,12 @@ dependencies = [
"eyre",
"heck",
"logos",
"prettyplease",
"proc-macro2",
"quote",
"rand",
"strong-xml",
"syn 2.0.48",
]
[[package]]
@ -109,7 +113,7 @@ dependencies = [
"proc-macro2",
"quote",
"regex-syntax",
"syn 2.0.46",
"syn 2.0.48",
]
[[package]]
@ -140,10 +144,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "proc-macro2"
version = "1.0.74"
name = "prettyplease"
version = "0.2.16"
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 = [
"unicode-ident",
]
@ -230,9 +244,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.46"
version = "2.0.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89456b690ff72fddcecf231caedbe615c59480c93358a93dfae7fc29e3ebbf0e"
checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f"
dependencies = [
"proc-macro2",
"quote",

View file

@ -9,5 +9,9 @@ edition = "2021"
eyre = "0.6.11"
heck = "0.4.1"
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"] }
strong-xml = "0.6.3"
syn = "2.0.48"

View file

@ -5,155 +5,180 @@ use crate::{
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 {{}}");
println!("pub trait Intrinsics: super::Core {{");
pub fn generate(intrinsics: &[Intrinsic]) -> Result<syn::File> {
let blanket: syn::ItemImpl = syn::parse_quote! {
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 {
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!("}}");
println!();
let soft_arch =
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<()> {
println!("pub mod soft_arch {{");
println!(" pub use super::super::soft_arch_types::*;");
println!(" use super::Intrinsics;");
fn generate_soft_arch_module(intrinsics: &[Intrinsic]) -> Result<syn::ItemMod> {
let mut module: syn::ItemMod = syn::parse_quote! {
pub mod soft_arch {
pub use super::super::soft_arch_types::*;
use super::Intrinsics;
}
};
for intr in intrinsics {
generate_intr_soft_arch_wrap(intr)
.wrap_err_with(|| format!("generating soft_arch `{}`", intr.name))?;
let item = generate_intr_soft_arch_wrap(intr)
.wrap_err_with(|| format!("generating `{}`", intr.name))?;
module.content.as_mut().unwrap().1.push(item.into());
}
println!("}}");
Ok(())
Ok(module)
}
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;");
fn generate_test_module(intrinsics: &[Intrinsic]) -> Result<syn::ItemMod> {
let mut module: syn::ItemMod = syn::parse_quote! {
#[cfg(all(test, target_arch = "x86_64"))]
pub mod tests {
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)
let item = generate_intr_test(intr, rng)
.wrap_err_with(|| format!("generating soft_arch `{}`", intr.name))?;
module.content.as_mut().unwrap().1.push(item.into());
}
println!("}}");
Ok(())
Ok(module)
}
fn generate_intr(intr: &Intrinsic) -> Result<(), eyre::Error> {
fn generate_intr(intr: &Intrinsic) -> Result<syn::TraitItem, eyre::Error> {
eprintln!("generating {}...", intr.name);
let signature = signature(intr)?;
println!(" {signature} {{");
let body = generate_body(intr).wrap_err("generating body")?;
println!("{}", indent(&body, 8));
println!(" }}");
Ok(())
signature(intr, body)
}
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);
let signature = signature_soft_arch(intr)?;
println!(" {signature} {{");
let body = generate_body_soft_arch(intr).wrap_err("generating body")?;
println!("{}", indent(&body, 8));
println!(" }}");
Ok(())
signature_soft_arch(intr, body)
}
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);
println!(" #[test]");
let name = &intr.name;
println!(" fn {name}() {{");
// TODO: non-128
println!(" hard_soft_same_128! {{");
let name = ident(&intr.name);
let body = generate_body_test(intr, rng).wrap_err("generating body")?;
println!("{}", indent(&body, 12));
println!(" }}");
println!(" }}");
Ok(())
Ok(syn::parse_quote! {
#[test]
fn #name() {
hard_soft_same_128! {
#body
}
}
})
}
fn generate_body_soft_arch(intr: &Intrinsic) -> Result<String> {
let mut rust_stmts = Vec::<String>::new();
fn generate_body_soft_arch(intr: &Intrinsic) -> Result<syn::Block> {
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 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});"
));
let name = ident(&intr.name);
rust_stmts.push("output".into());
let args = intr.parameter.iter().map(|param| -> syn::Expr {
let name = ident_opt_s(&param.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> {
let mut rust_stmts = Vec::<String>::new();
fn generate_body_test(intr: &Intrinsic, rng: &mut SmallRng) -> Result<syn::Block> {
let mut rust_stmts = Vec::<syn::Stmt>::new();
let args = intr
.parameter
.iter()
.map(|param| -> Result<&str> {
let name = param.varname.as_deref().unwrap();
.map(|param| -> Result<syn::Expr> {
let name = ident_opt_s(&param.varname).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)
let random = random_value(ty, rng)?;
rust_stmts.push(syn::parse_quote! { let #name = #random; });
Ok(syn::parse_quote! { #name })
})
.collect::<Result<Vec<_>>>()
.wrap_err("preparing arguments")?
.join(", ");
.collect::<Result<Vec<syn::Expr>>>()
.wrap_err("preparing arguments")?;
let name = &intr.name;
rust_stmts.push(format!("{name}({args})"));
let name = ident(&intr.name);
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 {
"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(),
),
"i16" => quotei16(rng.gen::<i16>()),
"__m128i" => {
let args = [
quotei16(rng.gen::<i16>()),
quotei16(rng.gen::<i16>()),
quotei16(rng.gen::<i16>()),
quotei16(rng.gen::<i16>()),
quotei16(rng.gen::<i16>()),
quotei16(rng.gen::<i16>()),
quotei16(rng.gen::<i16>()),
quotei16(rng.gen::<i16>()),
];
syn::parse_quote! {
_mm_setr_epi16(#(#args),*)
}
}
_ => 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 {
is_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 mut rust_stmts = Vec::<String>::new();
let mut rust_stmts = Vec::<syn::Stmt>::new();
let type_of_ident = |ident: &str| -> Result<VariableType> {
for param in &instr.parameter {
@ -222,7 +247,7 @@ fn generate_body(instr: &Intrinsic) -> Result<String> {
let Expr::Index { lhs, idx } = lhs else {
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");
};
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");
}
let ty = type_of_ident(&ident)?;
let ty = type_of_ident(&identifier)?;
if size != ty.elem_width {
bail!(
"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 rust_type = ty.rust_type();
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!(),
}
}
Ok(rust_stmts.join("\n"))
Ok(syn::parse_quote! {
{ #(#rust_stmts)* }
})
}
fn generate_expr_tmp(
rust_stmts: &mut Vec<String>,
rust_stmts: &mut Vec<syn::Stmt>,
expr: Expr,
type_of_ident: &impl Fn(&str) -> Result<VariableType>,
) -> Result<String> {
let result = match expr {
Expr::Int(int) => int.to_string(),
Expr::Ident(ident) => {
let ty = type_of_ident(&ident)?;
) -> Result<syn::Expr> {
let tmp = |rust_stmts: &mut Vec<syn::Stmt>, inner: syn::Expr| {
let stmt = syn::parse_quote! { let __tmp = #inner; };
rust_stmts.push(stmt);
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 {
let from = &ty.raw_type;
let to = ty.rust_type();
let stmt = format!("let __tmp = self.cast_sign_{from}_{to}({ident});");
rust_stmts.push(stmt);
"__tmp".into()
let method = ident(&format!("cast_sign_{from}_{to}"));
tmp(rust_stmts, syn::parse_quote! { self.#method(#identifier) })
} else {
ident
syn::parse_quote! { #identifier }
}
}
Expr::Index { lhs, idx } => {
let Expr::Ident(ident) = *lhs else {
let Expr::Ident(identifier) = *lhs else {
bail!("lhs of indexing must be identifier");
};
let Expr::Range { left, right } = *idx else {
@ -304,7 +340,7 @@ fn generate_expr_tmp(
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 {
bail!(
"unsupported not-direct element indexing, size={size}, element size={}",
@ -314,21 +350,27 @@ fn generate_expr_tmp(
let raw = &ty.raw_type;
let rust_type = ty.rust_type();
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);
"__tmp".into()
let identifier = ident(&identifier);
let method = ident(&format!("get_lane_{raw}_{rust_type}"));
tmp(
rust_stmts,
syn::parse_quote! { self.#method(#identifier, #lane_idx) },
)
}
Expr::Range { .. } => todo!(),
Expr::Call { function, args } => {
let function = heck::AsSnekCase(function);
let function = ident(&heck::ToSnekCase::to_snek_case(function.as_str()));
let args = args
.into_iter()
.map(|arg| generate_expr_tmp(rust_stmts, arg, type_of_ident))
.collect::<Result<Vec<_>>>()?
.join(", ");
let stmt = format!("let __tmp = self.{function}({args});");
rust_stmts.push(stmt);
"__tmp".into()
.collect::<Result<Vec<syn::Expr>>>()?;
tmp(
rust_stmts,
syn::parse_quote! { self.#function( #(#args),* ) },
)
}
Expr::BinaryOp { .. } => todo!(),
};
@ -343,49 +385,48 @@ fn parse_op(intr: &Intrinsic) -> Result<Vec<Stmt>> {
Ok(stmts)
}
fn signature(intr: &Intrinsic) -> Result<String> {
let name = &intr.name;
let args = intr
.parameter
.iter()
.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 ident(s: &str) -> syn::Ident {
syn::Ident::new(s, proc_macro2::Span::call_site())
}
fn ident_opt_s(s: &Option<String>) -> Result<syn::Ident> {
let s = s.as_deref().ok_or_eyre("missing")?;
Ok(ident(s))
}
fn signature_soft_arch(intr: &Intrinsic) -> Result<String> {
let name = &intr.name;
fn signature(intr: &Intrinsic, body: syn::Block) -> Result<syn::TraitItem> {
let name = ident(&intr.name);
let args = intr
.parameter
.iter()
.map(|param| {
format!(
"{}: {}",
param.varname.as_ref().unwrap(),
map_type_to_rust(param.r#type.as_ref().unwrap())
)
})
.collect::<Vec<_>>()
.join(", ");
let ret_name = ident_opt_s(&intr.ret.varname)?;
let ret_ty = ident(map_type_to_rust(intr.ret.r#type.as_ref().unwrap()));
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(&param.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(&param.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 {

View file

@ -81,7 +81,9 @@ fn main() -> Result<()> {
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(())
}

View file

@ -1,131 +1,161 @@
impl<C: super::Core> Intrinsics for C {}
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);
self.set_lane___m128i_u16(dst, 0, __tmp);
self.set_lane___m128i_u16(dst, 0u64, __tmp);
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);
self.set_lane___m128i_u16(dst, 2, __tmp);
self.set_lane___m128i_u16(dst, 2u64, __tmp);
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);
self.set_lane___m128i_u16(dst, 4, __tmp);
self.set_lane___m128i_u16(dst, 4u64, __tmp);
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);
self.set_lane___m128i_u16(dst, 6, __tmp);
self.set_lane___m128i_u16(dst, 6u64, __tmp);
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) {
let __tmp = self.get_lane___m128i_i16(a, 0);
fn _mm_packs_epi16(
&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);
self.set_lane___m128i_i8(dst, 0, __tmp);
let __tmp = self.get_lane___m128i_i16(a, 1);
self.set_lane___m128i_i8(dst, 0u64, __tmp);
let __tmp = self.get_lane___m128i_i16(a, 1u64);
let __tmp = self.saturate8(__tmp);
self.set_lane___m128i_i8(dst, 1, __tmp);
let __tmp = self.get_lane___m128i_i16(a, 2);
self.set_lane___m128i_i8(dst, 1u64, __tmp);
let __tmp = self.get_lane___m128i_i16(a, 2u64);
let __tmp = self.saturate8(__tmp);
self.set_lane___m128i_i8(dst, 2, __tmp);
let __tmp = self.get_lane___m128i_i16(a, 3);
self.set_lane___m128i_i8(dst, 2u64, __tmp);
let __tmp = self.get_lane___m128i_i16(a, 3u64);
let __tmp = self.saturate8(__tmp);
self.set_lane___m128i_i8(dst, 3, __tmp);
let __tmp = self.get_lane___m128i_i16(a, 4);
self.set_lane___m128i_i8(dst, 3u64, __tmp);
let __tmp = self.get_lane___m128i_i16(a, 4u64);
let __tmp = self.saturate8(__tmp);
self.set_lane___m128i_i8(dst, 4, __tmp);
let __tmp = self.get_lane___m128i_i16(a, 5);
self.set_lane___m128i_i8(dst, 4u64, __tmp);
let __tmp = self.get_lane___m128i_i16(a, 5u64);
let __tmp = self.saturate8(__tmp);
self.set_lane___m128i_i8(dst, 5, __tmp);
let __tmp = self.get_lane___m128i_i16(a, 6);
self.set_lane___m128i_i8(dst, 5u64, __tmp);
let __tmp = self.get_lane___m128i_i16(a, 6u64);
let __tmp = self.saturate8(__tmp);
self.set_lane___m128i_i8(dst, 6, __tmp);
let __tmp = self.get_lane___m128i_i16(a, 7);
self.set_lane___m128i_i8(dst, 6u64, __tmp);
let __tmp = self.get_lane___m128i_i16(a, 7u64);
let __tmp = self.saturate8(__tmp);
self.set_lane___m128i_i8(dst, 7, __tmp);
let __tmp = self.get_lane___m128i_i16(b, 0);
self.set_lane___m128i_i8(dst, 7u64, __tmp);
let __tmp = self.get_lane___m128i_i16(b, 0u64);
let __tmp = self.saturate8(__tmp);
self.set_lane___m128i_i8(dst, 8, __tmp);
let __tmp = self.get_lane___m128i_i16(b, 1);
self.set_lane___m128i_i8(dst, 8u64, __tmp);
let __tmp = self.get_lane___m128i_i16(b, 1u64);
let __tmp = self.saturate8(__tmp);
self.set_lane___m128i_i8(dst, 9, __tmp);
let __tmp = self.get_lane___m128i_i16(b, 2);
self.set_lane___m128i_i8(dst, 9u64, __tmp);
let __tmp = self.get_lane___m128i_i16(b, 2u64);
let __tmp = self.saturate8(__tmp);
self.set_lane___m128i_i8(dst, 10, __tmp);
let __tmp = self.get_lane___m128i_i16(b, 3);
self.set_lane___m128i_i8(dst, 10u64, __tmp);
let __tmp = self.get_lane___m128i_i16(b, 3u64);
let __tmp = self.saturate8(__tmp);
self.set_lane___m128i_i8(dst, 11, __tmp);
let __tmp = self.get_lane___m128i_i16(b, 4);
self.set_lane___m128i_i8(dst, 11u64, __tmp);
let __tmp = self.get_lane___m128i_i16(b, 4u64);
let __tmp = self.saturate8(__tmp);
self.set_lane___m128i_i8(dst, 12, __tmp);
let __tmp = self.get_lane___m128i_i16(b, 5);
self.set_lane___m128i_i8(dst, 12u64, __tmp);
let __tmp = self.get_lane___m128i_i16(b, 5u64);
let __tmp = self.saturate8(__tmp);
self.set_lane___m128i_i8(dst, 13, __tmp);
let __tmp = self.get_lane___m128i_i16(b, 6);
self.set_lane___m128i_i8(dst, 13u64, __tmp);
let __tmp = self.get_lane___m128i_i16(b, 6u64);
let __tmp = self.saturate8(__tmp);
self.set_lane___m128i_i8(dst, 14, __tmp);
let __tmp = self.get_lane___m128i_i16(b, 7);
self.set_lane___m128i_i8(dst, 14u64, __tmp);
let __tmp = self.get_lane___m128i_i16(b, 7u64);
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) {
let __tmp = self.get_lane___m128i_i16(a, 0);
fn _mm_packus_epi16(
&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);
self.set_lane___m128i_u8(dst, 0, __tmp);
let __tmp = self.get_lane___m128i_i16(a, 1);
self.set_lane___m128i_u8(dst, 0u64, __tmp);
let __tmp = self.get_lane___m128i_i16(a, 1u64);
let __tmp = self.saturate_u8(__tmp);
self.set_lane___m128i_u8(dst, 1, __tmp);
let __tmp = self.get_lane___m128i_i16(a, 2);
self.set_lane___m128i_u8(dst, 1u64, __tmp);
let __tmp = self.get_lane___m128i_i16(a, 2u64);
let __tmp = self.saturate_u8(__tmp);
self.set_lane___m128i_u8(dst, 2, __tmp);
let __tmp = self.get_lane___m128i_i16(a, 3);
self.set_lane___m128i_u8(dst, 2u64, __tmp);
let __tmp = self.get_lane___m128i_i16(a, 3u64);
let __tmp = self.saturate_u8(__tmp);
self.set_lane___m128i_u8(dst, 3, __tmp);
let __tmp = self.get_lane___m128i_i16(a, 4);
self.set_lane___m128i_u8(dst, 3u64, __tmp);
let __tmp = self.get_lane___m128i_i16(a, 4u64);
let __tmp = self.saturate_u8(__tmp);
self.set_lane___m128i_u8(dst, 4, __tmp);
let __tmp = self.get_lane___m128i_i16(a, 5);
self.set_lane___m128i_u8(dst, 4u64, __tmp);
let __tmp = self.get_lane___m128i_i16(a, 5u64);
let __tmp = self.saturate_u8(__tmp);
self.set_lane___m128i_u8(dst, 5, __tmp);
let __tmp = self.get_lane___m128i_i16(a, 6);
self.set_lane___m128i_u8(dst, 5u64, __tmp);
let __tmp = self.get_lane___m128i_i16(a, 6u64);
let __tmp = self.saturate_u8(__tmp);
self.set_lane___m128i_u8(dst, 6, __tmp);
let __tmp = self.get_lane___m128i_i16(a, 7);
self.set_lane___m128i_u8(dst, 6u64, __tmp);
let __tmp = self.get_lane___m128i_i16(a, 7u64);
let __tmp = self.saturate_u8(__tmp);
self.set_lane___m128i_u8(dst, 7, __tmp);
let __tmp = self.get_lane___m128i_i16(b, 0);
self.set_lane___m128i_u8(dst, 7u64, __tmp);
let __tmp = self.get_lane___m128i_i16(b, 0u64);
let __tmp = self.saturate_u8(__tmp);
self.set_lane___m128i_u8(dst, 8, __tmp);
let __tmp = self.get_lane___m128i_i16(b, 1);
self.set_lane___m128i_u8(dst, 8u64, __tmp);
let __tmp = self.get_lane___m128i_i16(b, 1u64);
let __tmp = self.saturate_u8(__tmp);
self.set_lane___m128i_u8(dst, 9, __tmp);
let __tmp = self.get_lane___m128i_i16(b, 2);
self.set_lane___m128i_u8(dst, 9u64, __tmp);
let __tmp = self.get_lane___m128i_i16(b, 2u64);
let __tmp = self.saturate_u8(__tmp);
self.set_lane___m128i_u8(dst, 10, __tmp);
let __tmp = self.get_lane___m128i_i16(b, 3);
self.set_lane___m128i_u8(dst, 10u64, __tmp);
let __tmp = self.get_lane___m128i_i16(b, 3u64);
let __tmp = self.saturate_u8(__tmp);
self.set_lane___m128i_u8(dst, 11, __tmp);
let __tmp = self.get_lane___m128i_i16(b, 4);
self.set_lane___m128i_u8(dst, 11u64, __tmp);
let __tmp = self.get_lane___m128i_i16(b, 4u64);
let __tmp = self.saturate_u8(__tmp);
self.set_lane___m128i_u8(dst, 12, __tmp);
let __tmp = self.get_lane___m128i_i16(b, 5);
self.set_lane___m128i_u8(dst, 12u64, __tmp);
let __tmp = self.get_lane___m128i_i16(b, 5u64);
let __tmp = self.saturate_u8(__tmp);
self.set_lane___m128i_u8(dst, 13, __tmp);
let __tmp = self.get_lane___m128i_i16(b, 6);
self.set_lane___m128i_u8(dst, 13u64, __tmp);
let __tmp = self.get_lane___m128i_i16(b, 6u64);
let __tmp = self.saturate_u8(__tmp);
self.set_lane___m128i_u8(dst, 14, __tmp);
let __tmp = self.get_lane___m128i_i16(b, 7);
self.set_lane___m128i_u8(dst, 14u64, __tmp);
let __tmp = self.get_lane___m128i_i16(b, 7u64);
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 use super::super::soft_arch_types::*;
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() };
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
}
pub fn _mm_packs_epi16(a: __m128i, b: __m128i) -> __m128i {
@ -145,31 +175,28 @@ pub mod tests {
#[test]
fn _mm_setr_epi16() {
hard_soft_same_128! {
let e7 = -24391;
let e6 = 19541;
let e5 = -16509;
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)
{ let e7 = - 24391i16; let e6 = 19541i16; let e5 = - 16509i16; let e4 =
7733i16; let e3 = - 15140i16; let e2 = 30719i16; let e1 = 16513i16; let e0 =
22878i16; _mm_setr_epi16(e7, e6, e5, e4, e3, e2, e1, e0) }
}
}
#[test]
fn _mm_packs_epi16() {
hard_soft_same_128! {
let a = _mm_setr_epi16(23986, 27900, -8343, -10648, 4841, 14610, -17251, -3971);
let b = _mm_setr_epi16(22390, -23547, 15401, 15832, -14212, -1286, -18062, 22296);
_mm_packs_epi16(a, b)
{ let a = _mm_setr_epi16(23986i16, 27900i16, - 8343i16, - 10648i16, 4841i16,
14610i16, - 17251i16, - 3971i16); let b = _mm_setr_epi16(22390i16, -
23547i16, 15401i16, 15832i16, - 14212i16, - 1286i16, - 18062i16, 22296i16);
_mm_packs_epi16(a, b) }
}
}
#[test]
fn _mm_packus_epi16() {
hard_soft_same_128! {
let a = _mm_setr_epi16(18077, 23617, -9205, 21233, -4332, -31339, 23623, -22080);
let b = _mm_setr_epi16(-1436, -30227, 8629, 10922, -16731, -1013, -14310, 2892);
_mm_packus_epi16(a, b)
{ let a = _mm_setr_epi16(18077i16, 23617i16, - 9205i16, 21233i16, - 4332i16,
- 31339i16, 23623i16, - 22080i16); let b = _mm_setr_epi16(- 1436i16, -
30227i16, 8629i16, 10922i16, - 16731i16, - 1013i16, - 14310i16, 2892i16);
_mm_packus_epi16(a, b) }
}
}
}