summaryrefslogtreecommitdiffstats
path: root/library/stdarch/crates/intrinsic-test/src/intrinsic.rs
diff options
context:
space:
mode:
Diffstat (limited to 'library/stdarch/crates/intrinsic-test/src/intrinsic.rs')
-rw-r--r--library/stdarch/crates/intrinsic-test/src/intrinsic.rs125
1 files changed, 125 insertions, 0 deletions
diff --git a/library/stdarch/crates/intrinsic-test/src/intrinsic.rs b/library/stdarch/crates/intrinsic-test/src/intrinsic.rs
new file mode 100644
index 000000000..2b7130440
--- /dev/null
+++ b/library/stdarch/crates/intrinsic-test/src/intrinsic.rs
@@ -0,0 +1,125 @@
+use crate::types::{IntrinsicType, TypeKind};
+
+use super::argument::ArgumentList;
+
+/// An intrinsic
+#[derive(Debug, PartialEq, Clone)]
+pub struct Intrinsic {
+ /// The function name of this intrinsic.
+ pub name: String,
+
+ /// Any arguments for this intrinsic.
+ pub arguments: ArgumentList,
+
+ /// The return type of this intrinsic.
+ pub results: IntrinsicType,
+
+ /// Whether this intrinsic is only available on A64.
+ pub a64_only: bool,
+}
+
+impl Intrinsic {
+ /// Generates a std::cout for the intrinsics results that will match the
+ /// rust debug output format for the return type.
+ pub fn print_result_c(&self, index: usize, additional: &str) -> String {
+ let lanes = if self.results.num_vectors() > 1 {
+ (0..self.results.num_vectors())
+ .map(|vector| {
+ format!(
+ r#""{ty}(" << {lanes} << ")""#,
+ ty = self.results.c_single_vector_type(),
+ lanes = (0..self.results.num_lanes())
+ .map(move |idx| -> std::string::String {
+ format!(
+ "{cast}{lane_fn}(__return_value.val[{vector}], {lane})",
+ cast = self.results.c_promotion(),
+ lane_fn = self.results.get_lane_function(),
+ lane = idx,
+ vector = vector,
+ )
+ })
+ .collect::<Vec<_>>()
+ .join(r#" << ", " << "#)
+ )
+ })
+ .collect::<Vec<_>>()
+ .join(r#" << ", " << "#)
+ } else if self.results.num_lanes() > 1 {
+ (0..self.results.num_lanes())
+ .map(|idx| -> std::string::String {
+ format!(
+ "{cast}{lane_fn}(__return_value, {lane})",
+ cast = self.results.c_promotion(),
+ lane_fn = self.results.get_lane_function(),
+ lane = idx
+ )
+ })
+ .collect::<Vec<_>>()
+ .join(r#" << ", " << "#)
+ } else {
+ format!(
+ "{promote}cast<{cast}>(__return_value)",
+ cast = match self.results.kind() {
+ 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::Poly => format!("poly{}_t", self.results.inner_size()),
+ ty => todo!("print_result_c - Unknown type: {:#?}", ty),
+ },
+ promote = self.results.c_promotion(),
+ )
+ };
+
+ format!(
+ r#"std::cout << "Result {additional}-{idx}: {ty}" << std::fixed << std::setprecision(150) << {lanes} << "{close}" << std::endl;"#,
+ ty = if self.results.is_simd() {
+ format!("{}(", self.results.c_type())
+ } else {
+ String::from("")
+ },
+ close = if self.results.is_simd() { ")" } else { "" },
+ lanes = lanes,
+ additional = additional,
+ idx = index,
+ )
+ }
+
+ pub fn generate_pass_rust(&self, index: usize, additional: &str) -> String {
+ let constraints = self.arguments.as_constraint_parameters_rust();
+ let constraints = if !constraints.is_empty() {
+ format!("::<{}>", constraints)
+ } else {
+ constraints
+ };
+
+ format!(
+ r#"
+ unsafe {{
+ {initialized_args}
+ let res = {intrinsic_call}{const}({args});
+ println!("Result {additional}-{idx}: {{:.150?}}", res);
+ }}"#,
+ initialized_args = self.arguments.init_random_values_rust(index),
+ intrinsic_call = self.name,
+ args = self.arguments.as_call_param_rust(),
+ additional = additional,
+ idx = index,
+ const = constraints,
+ )
+ }
+
+ pub fn generate_pass_c(&self, index: usize, additional: &str) -> String {
+ format!(
+ r#" {{
+ {initialized_args}
+ auto __return_value = {intrinsic_call}({args});
+ {print_result}
+ }}"#,
+ initialized_args = self.arguments.init_random_values_c(index),
+ intrinsic_call = self.name,
+ args = self.arguments.as_call_param_c(),
+ print_result = self.print_result_c(index, additional)
+ )
+ }
+}