about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMadhav Madhusoodanan <madhavmadhusoodanan@gmail.com>2025-05-25 23:52:56 +0530
committerAmanieu d'Antras <amanieu@gmail.com>2025-05-27 23:27:38 +0000
commitd8469bea64c29fabe2d8e022cadf3af18ed0c2cf (patch)
treeee8ab07d35c15de5a631992673e6e1587aedc588
parent54e277cdd58d6ceed114d5fca92405ec6f68d213 (diff)
downloadrust-d8469bea64c29fabe2d8e022cadf3af18ed0c2cf.tar.gz
rust-d8469bea64c29fabe2d8e022cadf3af18ed0c2cf.zip
fix: moved common code (that required no architecture-specific
modifications) outside the IntrinsicDefinition trait
-rw-r--r--library/stdarch/crates/intrinsic-test/src/arm/intrinsic.rs53
-rw-r--r--library/stdarch/crates/intrinsic-test/src/common/gen_c.rs104
-rw-r--r--library/stdarch/crates/intrinsic-test/src/common/gen_rust.rs110
-rw-r--r--library/stdarch/crates/intrinsic-test/src/common/intrinsic.rs225
-rw-r--r--library/stdarch/crates/intrinsic-test/src/common/write_file.rs19
5 files changed, 243 insertions, 268 deletions
diff --git a/library/stdarch/crates/intrinsic-test/src/arm/intrinsic.rs b/library/stdarch/crates/intrinsic-test/src/arm/intrinsic.rs
index e3b0fbbce93..773dabf4d75 100644
--- a/library/stdarch/crates/intrinsic-test/src/arm/intrinsic.rs
+++ b/library/stdarch/crates/intrinsic-test/src/arm/intrinsic.rs
@@ -92,57 +92,4 @@ impl IntrinsicDefinition<ArmIntrinsicType> for Intrinsic<ArmIntrinsicType> {
             close = if self.results.is_simd() { ")" } else { "" },
         )
     }
-
-    fn generate_loop_c(
-        &self,
-        indentation: Indentation,
-        additional: &str,
-        passes: u32,
-        _target: &str,
-    ) -> String {
-        let body_indentation = indentation.nested();
-        format!(
-            "{indentation}for (int i=0; i<{passes}; i++) {{\n\
-                {loaded_args}\
-                {body_indentation}auto __return_value = {intrinsic_call}({args});\n\
-                {print_result}\n\
-            {indentation}}}",
-            loaded_args = self.arguments.load_values_c(body_indentation),
-            intrinsic_call = self.name,
-            args = self.arguments.as_call_param_c(),
-            print_result = self.print_result_c(body_indentation, additional)
-        )
-    }
-
-    fn generate_loop_rust(
-        &self,
-        indentation: Indentation,
-        additional: &str,
-        passes: u32,
-    ) -> String {
-        let constraints = self.arguments.as_constraint_parameters_rust();
-        let constraints = if !constraints.is_empty() {
-            format!("::<{constraints}>")
-        } else {
-            constraints
-        };
-
-        let return_value = self.format_f16_return_value();
-        let indentation2 = indentation.nested();
-        let indentation3 = indentation2.nested();
-
-        format!(
-            "{indentation}for i in 0..{passes} {{\n\
-                {indentation2}unsafe {{\n\
-                    {loaded_args}\
-                    {indentation3}let __return_value = {intrinsic_call}{const}({args});\n\
-                    {indentation3}println!(\"Result {additional}-{{}}: {{:?}}\", i + 1, {return_value});\n\
-                {indentation2}}}\n\
-            {indentation}}}",
-            loaded_args = self.arguments.load_values_rust(indentation3),
-            intrinsic_call = self.name,
-            const = constraints,
-            args = self.arguments.as_call_param_rust(),
-        )
-    }
 }
diff --git a/library/stdarch/crates/intrinsic-test/src/common/gen_c.rs b/library/stdarch/crates/intrinsic-test/src/common/gen_c.rs
index a2a4115da62..6f91d676dc5 100644
--- a/library/stdarch/crates/intrinsic-test/src/common/gen_c.rs
+++ b/library/stdarch/crates/intrinsic-test/src/common/gen_c.rs
@@ -3,6 +3,14 @@ use rayon::prelude::*;
 use std::collections::BTreeMap;
 use std::process::Command;
 
+use super::argument::Argument;
+use super::indentation::Indentation;
+use super::intrinsic::IntrinsicDefinition;
+use super::intrinsic_helpers::IntrinsicTypeDefinition;
+
+// The number of times each intrinsic will be called.
+const PASSES: u32 = 20;
+
 pub fn generate_c_program(
     notices: &str,
     header_files: &[&str],
@@ -89,3 +97,99 @@ pub fn create_c_filenames(identifiers: &Vec<String>) -> BTreeMap<&String, String
         })
         .collect::<BTreeMap<&String, String>>()
 }
+
+pub fn generate_loop_c<T: IntrinsicTypeDefinition + Sized>(
+    intrinsic: &dyn IntrinsicDefinition<T>,
+    indentation: Indentation,
+    additional: &str,
+    passes: u32,
+    _target: &str,
+) -> String {
+    let body_indentation = indentation.nested();
+    format!(
+        "{indentation}for (int i=0; i<{passes}; i++) {{\n\
+            {loaded_args}\
+            {body_indentation}auto __return_value = {intrinsic_call}({args});\n\
+            {print_result}\n\
+        {indentation}}}",
+        loaded_args = intrinsic.arguments().load_values_c(body_indentation),
+        intrinsic_call = intrinsic.name(),
+        args = intrinsic.arguments().as_call_param_c(),
+        print_result = intrinsic.print_result_c(body_indentation, additional)
+    )
+}
+
+pub fn gen_code_c<T: IntrinsicTypeDefinition>(
+    intrinsic: &dyn IntrinsicDefinition<T>,
+    indentation: Indentation,
+    constraints: &[&Argument<T>],
+    name: String,
+    target: &str,
+) -> String {
+    if let Some((current, constraints)) = constraints.split_last() {
+        let range = current
+            .constraint
+            .iter()
+            .map(|c| c.to_range())
+            .flat_map(|r| r.into_iter());
+
+        let body_indentation = indentation.nested();
+        range
+            .map(|i| {
+                format!(
+                    "{indentation}{{\n\
+                        {body_indentation}{ty} {name} = {val};\n\
+                        {pass}\n\
+                    {indentation}}}",
+                    name = current.name,
+                    ty = current.ty.c_type(),
+                    val = i,
+                    pass = gen_code_c(
+                        intrinsic,
+                        body_indentation,
+                        constraints,
+                        format!("{name}-{i}"),
+                        target,
+                    )
+                )
+            })
+            .join("\n")
+    } else {
+        generate_loop_c(intrinsic, indentation, &name, PASSES, target)
+    }
+}
+
+pub fn gen_c_program<T: IntrinsicTypeDefinition>(
+    intrinsic: &dyn IntrinsicDefinition<T>,
+    header_files: &[&str],
+    target: &str,
+    c_target: &str,
+    notices: &str,
+    arch_specific_definitions: &[&str],
+) -> String {
+    let arguments = intrinsic.arguments();
+    let constraints = arguments
+        .iter()
+        .filter(|&i| i.has_constraint())
+        .collect_vec();
+
+    let indentation = Indentation::default();
+    generate_c_program(
+        notices,
+        header_files,
+        c_target,
+        arch_specific_definitions,
+        intrinsic
+            .arguments()
+            .gen_arglists_c(indentation, PASSES)
+            .as_str(),
+        gen_code_c(
+            intrinsic,
+            indentation.nested(),
+            constraints.as_slice(),
+            Default::default(),
+            target,
+        )
+        .as_str(),
+    )
+}
diff --git a/library/stdarch/crates/intrinsic-test/src/common/gen_rust.rs b/library/stdarch/crates/intrinsic-test/src/common/gen_rust.rs
index 260ff1b010d..06380b2c43e 100644
--- a/library/stdarch/crates/intrinsic-test/src/common/gen_rust.rs
+++ b/library/stdarch/crates/intrinsic-test/src/common/gen_rust.rs
@@ -5,6 +5,14 @@ use std::fs::File;
 use std::io::Write;
 use std::process::Command;
 
+use super::argument::Argument;
+use super::indentation::Indentation;
+use super::intrinsic::{IntrinsicDefinition, format_f16_return_value};
+use super::intrinsic_helpers::IntrinsicTypeDefinition;
+
+// The number of times each intrinsic will be called.
+const PASSES: u32 = 20;
+
 pub fn generate_rust_program(
     notices: &str,
     definitions: &str,
@@ -129,3 +137,105 @@ pub fn create_rust_filenames(identifiers: &Vec<String>) -> BTreeMap<&String, Str
         })
         .collect::<BTreeMap<&String, String>>()
 }
+
+pub fn generate_loop_rust<T: IntrinsicTypeDefinition>(
+    intrinsic: &dyn IntrinsicDefinition<T>,
+    indentation: Indentation,
+    additional: &str,
+    passes: u32,
+) -> String {
+    let constraints = intrinsic.arguments().as_constraint_parameters_rust();
+    let constraints = if !constraints.is_empty() {
+        format!("::<{constraints}>")
+    } else {
+        constraints
+    };
+
+    let return_value = format_f16_return_value(intrinsic);
+    let indentation2 = indentation.nested();
+    let indentation3 = indentation2.nested();
+    format!(
+        "{indentation}for i in 0..{passes} {{\n\
+            {indentation2}unsafe {{\n\
+                {loaded_args}\
+                {indentation3}let __return_value = {intrinsic_call}{const}({args});\n\
+                {indentation3}println!(\"Result {additional}-{{}}: {{:?}}\", i + 1, {return_value});\n\
+            {indentation2}}}\n\
+        {indentation}}}",
+        loaded_args = intrinsic.arguments().load_values_rust(indentation3),
+        intrinsic_call = intrinsic.name(),
+        const = constraints,
+        args = intrinsic.arguments().as_call_param_rust(),
+    )
+}
+
+pub fn gen_code_rust<T: IntrinsicTypeDefinition>(
+    intrinsic: &dyn IntrinsicDefinition<T>,
+    indentation: Indentation,
+    constraints: &[&Argument<T>],
+    name: String,
+) -> String {
+    if let Some((current, constraints)) = constraints.split_last() {
+        let range = current
+            .constraint
+            .iter()
+            .map(|c| c.to_range())
+            .flat_map(|r| r.into_iter());
+
+        let body_indentation = indentation.nested();
+        range
+            .map(|i| {
+                format!(
+                    "{indentation}{{\n\
+                        {body_indentation}const {name}: {ty} = {val};\n\
+                        {pass}\n\
+                    {indentation}}}",
+                    name = current.name,
+                    ty = current.ty.rust_type(),
+                    val = i,
+                    pass = gen_code_rust(
+                        intrinsic,
+                        body_indentation,
+                        constraints,
+                        format!("{name}-{i}")
+                    )
+                )
+            })
+            .join("\n")
+    } else {
+        generate_loop_rust(intrinsic, indentation, &name, PASSES)
+    }
+}
+
+pub fn gen_rust_program<T: IntrinsicTypeDefinition>(
+    intrinsic: &dyn IntrinsicDefinition<T>,
+    target: &str,
+    notice: &str,
+    definitions: &str,
+    cfg: &str,
+) -> String {
+    let arguments = intrinsic.arguments();
+    let constraints = arguments
+        .iter()
+        .filter(|i| i.has_constraint())
+        .collect_vec();
+
+    let indentation = Indentation::default();
+    generate_rust_program(
+        notice,
+        definitions,
+        cfg,
+        target,
+        intrinsic
+            .arguments()
+            .gen_arglists_rust(indentation.nested(), PASSES)
+            .as_str(),
+        gen_code_rust(
+            intrinsic,
+            indentation.nested(),
+            &constraints,
+            Default::default(),
+        )
+        .as_str(),
+    )
+}
diff --git a/library/stdarch/crates/intrinsic-test/src/common/intrinsic.rs b/library/stdarch/crates/intrinsic-test/src/common/intrinsic.rs
index 9a2bf74a63d..61891e7c97d 100644
--- a/library/stdarch/crates/intrinsic-test/src/common/intrinsic.rs
+++ b/library/stdarch/crates/intrinsic-test/src/common/intrinsic.rs
@@ -1,15 +1,7 @@
+use super::intrinsic_helpers::TypeKind;
 use crate::common::argument::ArgumentList;
 use crate::common::indentation::Indentation;
 use crate::common::intrinsic_helpers::IntrinsicTypeDefinition;
-use itertools::Itertools;
-
-use super::argument::Argument;
-use super::gen_c::generate_c_program;
-use super::gen_rust::generate_rust_program;
-use super::intrinsic_helpers::TypeKind;
-
-// The number of times each intrinsic will be called.
-const PASSES: u32 = 20;
 
 /// An intrinsic
 #[derive(Debug, PartialEq, Clone)]
@@ -41,205 +33,20 @@ where
     /// rust debug output format for the return type. The generated line assumes
     /// there is an int i in scope which is the current pass number.
     fn print_result_c(&self, _indentation: Indentation, _additional: &str) -> String;
+}
 
-    fn format_f16_return_value(&self) -> String {
-        // the `intrinsic-test` crate compares the output of C and Rust intrinsics. Currently, It uses
-        // a string representation of the output value to compare. In C, f16 values are currently printed
-        // as hexadecimal integers. Since https://github.com/rust-lang/rust/pull/127013, rust does print
-        // them as decimal floating point values. To keep the intrinsics tests working, for now, format
-        // vectors containing f16 values like C prints them.
-        let return_value = match self.results().kind() {
-            TypeKind::Float if self.results().inner_size() == 16 => "debug_f16(__return_value)",
-            _ => "format_args!(\"{__return_value:.150?}\")",
-        };
-
-        String::from(return_value)
-    }
-
-    fn generate_loop_c(
-        &self,
-        indentation: Indentation,
-        additional: &str,
-        passes: u32,
-        _target: &str,
-    ) -> String {
-        let body_indentation = indentation.nested();
-        format!(
-            "{indentation}for (int i=0; i<{passes}; i++) {{\n\
-                {loaded_args}\
-                {body_indentation}auto __return_value = {intrinsic_call}({args});\n\
-                {print_result}\n\
-            {indentation}}}",
-            loaded_args = self.arguments().load_values_c(body_indentation),
-            intrinsic_call = self.name(),
-            args = self.arguments().as_call_param_c(),
-            print_result = self.print_result_c(body_indentation, additional)
-        )
-    }
-
-    fn generate_loop_rust(
-        &self,
-        indentation: Indentation,
-        additional: &str,
-        passes: u32,
-    ) -> String {
-        let constraints = self.arguments().as_constraint_parameters_rust();
-        let constraints = if !constraints.is_empty() {
-            format!("::<{constraints}>")
-        } else {
-            constraints
-        };
-
-        let indentation2 = indentation.nested();
-        let indentation3 = indentation2.nested();
-        format!(
-            "{indentation}for i in 0..{passes} {{\n\
-                {indentation2}unsafe {{\n\
-                    {loaded_args}\
-                    {indentation3}let __return_value = {intrinsic_call}{const}({args});\n\
-                    {indentation3}println!(\"Result {additional}-{{}}: {{:.150?}}\", i + 1, __return_value);\n\
-                {indentation2}}}\n\
-            {indentation}}}",
-            loaded_args = self.arguments().load_values_rust(indentation3),
-            intrinsic_call = self.name(),
-            const = constraints,
-            args = self.arguments().as_call_param_rust(),
-        )
-    }
-
-    fn gen_code_c(
-        &self,
-        indentation: Indentation,
-        constraints: &[&Argument<T>],
-        name: String,
-        target: &str,
-    ) -> String {
-        if let Some((current, constraints)) = constraints.split_last() {
-            let range = current
-                .constraint
-                .iter()
-                .map(|c| c.to_range())
-                .flat_map(|r| r.into_iter());
-
-            let body_indentation = indentation.nested();
-            range
-                .map(|i| {
-                    format!(
-                        "{indentation}{{\n\
-                            {body_indentation}{ty} {name} = {val};\n\
-                            {pass}\n\
-                        {indentation}}}",
-                        name = current.name,
-                        ty = current.ty.c_type(),
-                        val = i,
-                        pass = self.gen_code_c(
-                            body_indentation,
-                            constraints,
-                            format!("{name}-{i}"),
-                            target,
-                        )
-                    )
-                })
-                .join("\n")
-        } else {
-            self.generate_loop_c(indentation, &name, PASSES, target)
-        }
-    }
-
-    fn generate_c_program(
-        &self,
-        header_files: &[&str],
-        target: &str,
-        c_target: &str,
-        notices: &str,
-        arch_specific_definitions: &[&str],
-    ) -> String {
-        let arguments = self.arguments();
-        let constraints = arguments
-            .iter()
-            .filter(|&i| i.has_constraint())
-            .collect_vec();
-
-        let indentation = Indentation::default();
-        generate_c_program(
-            notices,
-            header_files,
-            c_target,
-            arch_specific_definitions,
-            self.arguments()
-                .gen_arglists_c(indentation, PASSES)
-                .as_str(),
-            self.gen_code_c(
-                indentation.nested(),
-                constraints.as_slice(),
-                Default::default(),
-                target,
-            )
-            .as_str(),
-        )
-    }
-
-    fn gen_code_rust(
-        &self,
-        indentation: Indentation,
-        constraints: &[&Argument<T>],
-        name: String,
-    ) -> String {
-        if let Some((current, constraints)) = constraints.split_last() {
-            let range = current
-                .constraint
-                .iter()
-                .map(|c| c.to_range())
-                .flat_map(|r| r.into_iter());
-
-            let body_indentation = indentation.nested();
-            range
-                .map(|i| {
-                    format!(
-                        "{indentation}{{\n\
-                            {body_indentation}const {name}: {ty} = {val};\n\
-                            {pass}\n\
-                        {indentation}}}",
-                        name = current.name,
-                        ty = current.ty.rust_type(),
-                        val = i,
-                        pass = self.gen_code_rust(
-                            body_indentation,
-                            constraints,
-                            format!("{name}-{i}")
-                        )
-                    )
-                })
-                .join("\n")
-        } else {
-            self.generate_loop_rust(indentation, &name, PASSES)
-        }
-    }
-
-    fn generate_rust_program(
-        &self,
-        target: &str,
-        notice: &str,
-        definitions: &str,
-        cfg: &str,
-    ) -> String {
-        let arguments = self.arguments();
-        let constraints = arguments
-            .iter()
-            .filter(|i| i.has_constraint())
-            .collect_vec();
-
-        let indentation = Indentation::default();
-        generate_rust_program(
-            notice,
-            definitions,
-            cfg,
-            target,
-            self.arguments()
-                .gen_arglists_rust(indentation.nested(), PASSES)
-                .as_str(),
-            self.gen_code_rust(indentation.nested(), &constraints, Default::default())
-                .as_str(),
-        )
-    }
+pub fn format_f16_return_value<T: IntrinsicTypeDefinition>(
+    intrinsic: &dyn IntrinsicDefinition<T>,
+) -> String {
+    // the `intrinsic-test` crate compares the output of C and Rust intrinsics. Currently, It uses
+    // a string representation of the output value to compare. In C, f16 values are currently printed
+    // as hexadecimal integers. Since https://github.com/rust-lang/rust/pull/127013, rust does print
+    // them as decimal floating point values. To keep the intrinsics tests working, for now, format
+    // vectors containing f16 values like C prints them.
+    let return_value = match intrinsic.results().kind() {
+        TypeKind::Float if intrinsic.results().inner_size() == 16 => "debug_f16(__return_value)",
+        _ => "format_args!(\"{__return_value:.150?}\")",
+    };
+
+    String::from(return_value)
 }
diff --git a/library/stdarch/crates/intrinsic-test/src/common/write_file.rs b/library/stdarch/crates/intrinsic-test/src/common/write_file.rs
index 88644fa7de1..503b9e82304 100644
--- a/library/stdarch/crates/intrinsic-test/src/common/write_file.rs
+++ b/library/stdarch/crates/intrinsic-test/src/common/write_file.rs
@@ -1,6 +1,7 @@
+use super::gen_c::gen_c_program;
+use super::gen_rust::{create_rust_filenames, gen_rust_program};
 use super::intrinsic_helpers::IntrinsicTypeDefinition;
 use crate::common::gen_c::create_c_filenames;
-use crate::common::gen_rust::create_rust_filenames;
 use crate::common::intrinsic::IntrinsicDefinition;
 use crate::common::write_file;
 
@@ -18,9 +19,15 @@ pub fn write_c_testfiles<T: IntrinsicTypeDefinition + Sized>(
         .collect::<Vec<_>>();
     let filename_mapping = create_c_filenames(&intrinsics_name_list);
 
-    intrinsics.iter().for_each(|i| {
-        let c_code =
-            i.generate_c_program(headers, target, c_target, notice, arch_specific_definitions);
+    intrinsics.iter().for_each(|&i| {
+        let c_code = gen_c_program(
+            i,
+            headers,
+            target,
+            c_target,
+            notice,
+            arch_specific_definitions,
+        );
         match filename_mapping.get(&i.name()) {
             Some(filename) => write_file(filename, c_code),
             None => {}
@@ -43,8 +50,8 @@ pub fn write_rust_testfiles<T: IntrinsicTypeDefinition>(
         .collect::<Vec<_>>();
     let filename_mapping = create_rust_filenames(&intrinsics_name_list);
 
-    intrinsics.iter().for_each(|i| {
-        let rust_code = i.generate_rust_program(rust_target, notice, definitions, cfg);
+    intrinsics.iter().for_each(|&i| {
+        let rust_code = gen_rust_program(i, rust_target, notice, definitions, cfg);
         match filename_mapping.get(&i.name()) {
             Some(filename) => write_file(filename, rust_code),
             None => {}