Skip to content

Commit e79129a

Browse files
chore: update x86 module, removed intrinsicDefinition trait, formatting
updates
1 parent 1a07650 commit e79129a

File tree

6 files changed

+115
-238
lines changed

6 files changed

+115
-238
lines changed

Cargo.lock

Lines changed: 2 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/intrinsic-test/src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ fn main() {
2020
| "armv7-unknown-linux-gnueabihf"
2121
| "aarch64_be-unknown-linux-gnu" => run(ArmArchitectureTest::create(processed_cli_options)),
2222

23+
"x86_64-unknown-linux-gnu" => run(X86ArchitectureTest::create(processed_cli_options)),
2324
_ => std::process::exit(0),
2425
}
2526
}

crates/intrinsic-test/src/x86/config.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
1-
pub fn build_notices(line_prefix: &str) -> String {
2-
format!(
3-
"\
4-
{line_prefix}This is a transient test file, not intended for distribution. Some aspects of the
5-
{line_prefix}test are derived from an XML specification, published under the same license as the
6-
{line_prefix}`intrinsic-test` crate.\n
7-
"
8-
)
9-
}
1+
pub const NOTICE: &str = "\
2+
// This is a transient test file, not intended for distribution. Some aspects of the
3+
// test are derived from an XML specification, published under the same license as the
4+
// `intrinsic-test` crate.\n";
105

116
// Format f16 values (and vectors containing them) in a way that is consistent with C.
127
pub const F16_FORMATTING_DEF: &str = r#"
Lines changed: 1 addition & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
use crate::common::argument::ArgumentList;
2-
use crate::common::indentation::Indentation;
3-
use crate::common::intrinsic::{Intrinsic, IntrinsicDefinition};
4-
use crate::common::intrinsic_helpers::{IntrinsicType, IntrinsicTypeDefinition, TypeKind};
1+
use crate::common::intrinsic_helpers::IntrinsicType;
52
use crate::x86::xml_parser::Parameter;
63
use std::ops::{Deref, DerefMut};
74

@@ -24,88 +21,3 @@ impl DerefMut for X86IntrinsicType {
2421
&mut self.data
2522
}
2623
}
27-
28-
impl IntrinsicDefinition<X86IntrinsicType> for Intrinsic<X86IntrinsicType> {
29-
fn arguments(&self) -> ArgumentList<X86IntrinsicType> {
30-
self.arguments.clone()
31-
}
32-
33-
fn results(&self) -> X86IntrinsicType {
34-
self.results.clone()
35-
}
36-
37-
fn name(&self) -> String {
38-
self.name.clone()
39-
}
40-
41-
/// Generates a std::cout for the intrinsics results that will match the
42-
/// rust debug output format for the return type. The generated line assumes
43-
/// there is an int i in scope which is the current pass number.
44-
fn print_result_c(&self, indentation: Indentation, additional: &str) -> String {
45-
let lanes = if self.results().num_vectors() > 1 {
46-
(0..self.results().num_vectors())
47-
.map(|vector| {
48-
format!(
49-
r#""{ty}(" << {lanes} << ")""#,
50-
ty = self.results().c_single_vector_type(),
51-
lanes = (0..self.results().num_lanes())
52-
.map(move |idx| -> std::string::String {
53-
format!(
54-
"{cast}{lane_fn}(__return_value.val[{vector}], {lane})",
55-
cast = self.results().c_promotion(),
56-
lane_fn = self.results().get_lane_function(),
57-
lane = idx,
58-
vector = vector,
59-
)
60-
})
61-
.collect::<Vec<_>>()
62-
.join(r#" << ", " << "#)
63-
)
64-
})
65-
.collect::<Vec<_>>()
66-
.join(r#" << ", " << "#)
67-
} else if self.results().num_lanes() > 1 {
68-
(0..self.results().num_lanes())
69-
.map(|idx| -> std::string::String {
70-
format!(
71-
"{cast}{lane_fn}(__return_value, {lane})",
72-
cast = self.results().c_promotion(),
73-
lane_fn = self.results().get_lane_function(),
74-
lane = idx
75-
)
76-
})
77-
.collect::<Vec<_>>()
78-
.join(r#" << ", " << "#)
79-
} else {
80-
format!(
81-
"{promote}cast<{cast}>(__return_value)",
82-
cast = match self.results.kind() {
83-
TypeKind::Void => "void".to_string(),
84-
TypeKind::Float if self.results().inner_size() == 64 => "double".to_string(),
85-
TypeKind::Float if self.results().inner_size() == 32 => "float".to_string(),
86-
TypeKind::Mask => format!("__mmask{}", self.results.bit_len.expect(format!("self: {:#?}", self).as_str())),
87-
TypeKind::Vector => format!("__m{}i", self.results.bit_len.expect(format!("self: {:#?}", self).as_str())),
88-
// TypeKind::Float if self.results().inner_size() == 16 => "float16_t".to_string(),
89-
// TypeKind::Int(true) if self.results().inner_size() == 64 => "long".to_string(),
90-
// TypeKind::Int(false) if self.results().inner_size() == 64 => "unsigned long".to_string(),
91-
// TypeKind::Int(true) if self.results().inner_size() == 32 => "int".to_string(),
92-
// TypeKind::Int(false) if self.results().inner_size() == 32 => "unsigned int".to_string(),
93-
// TypeKind::Int(true) if self.results().inner_size() == 16 => "short".to_string(),
94-
// TypeKind::Int(false) if self.results().inner_size() == 16 => "unsigned short".to_string(),
95-
_ => self.results.c_scalar_type(),
96-
},
97-
promote = self.results().c_promotion(),
98-
)
99-
};
100-
101-
format!(
102-
r#"{indentation}std::cout << "Result {additional}-" << i+1 << ": {ty}" << std::fixed << std::setprecision(150) << {lanes} << "{close}" << std::endl;"#,
103-
ty = if self.results().is_simd() {
104-
format!("{}(", self.results().c_type())
105-
} else {
106-
String::from("")
107-
},
108-
close = if self.results.is_simd() { ")" } else { "" },
109-
)
110-
}
111-
}

crates/intrinsic-test/src/x86/mod.rs

Lines changed: 29 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,12 @@ mod intrinsic;
55
mod types;
66
mod xml_parser;
77

8-
use rayon::prelude::*;
9-
use std::fs::{self, File};
10-
8+
use crate::common::SupportedArchitectureTest;
119
use crate::common::cli::ProcessedCli;
1210
use crate::common::compare::compare_outputs;
13-
use crate::common::gen_c::{write_main_cpp, write_mod_cpp};
14-
use crate::common::gen_rust::{
15-
compile_rust_programs, write_bin_cargo_toml, write_lib_cargo_toml, write_lib_rs, write_main_rs,
16-
};
17-
use crate::common::intrinsic::{Intrinsic, IntrinsicDefinition};
11+
use crate::common::compile_c::CppCompilation;
12+
use crate::common::intrinsic::Intrinsic;
1813
use crate::common::intrinsic_helpers::TypeKind;
19-
use crate::common::{SupportedArchitectureTest, chunk_info};
20-
use crate::x86::config::{F16_FORMATTING_DEF, LANE_FUNCTION_HELPERS, X86_CONFIGURATIONS};
21-
use config::build_notices;
2214
use intrinsic::X86IntrinsicType;
2315
use xml_parser::get_xml_intrinsics;
2416

@@ -28,7 +20,30 @@ pub struct X86ArchitectureTest {
2820
}
2921

3022
impl SupportedArchitectureTest for X86ArchitectureTest {
31-
fn create(cli_options: ProcessedCli) -> Box<Self> {
23+
type IntrinsicImpl = X86IntrinsicType;
24+
25+
fn cli_options(&self) -> &ProcessedCli {
26+
&self.cli_options
27+
}
28+
29+
fn intrinsics(&self) -> &[Intrinsic<X86IntrinsicType>] {
30+
&self.intrinsics
31+
}
32+
33+
fn cpp_compilation(&self) -> Option<CppCompilation> {
34+
compile::build_cpp_compilation(&self.cli_options)
35+
}
36+
37+
const NOTICE: &str = config::NOTICE;
38+
39+
const PLATFORM_C_HEADERS: &[&str] = &["immintrin.h"];
40+
const PLATFORM_C_DEFINITIONS: &str = config::LANE_FUNCTION_HELPERS;
41+
const PLATFORM_C_FORWARD_DECLARATIONS: &str = "";
42+
43+
const PLATFORM_RUST_DEFINITIONS: &str = config::F16_FORMATTING_DEF;
44+
const PLATFORM_RUST_CFGS: &str = config::X86_CONFIGURATIONS;
45+
46+
fn create(cli_options: ProcessedCli) -> Self {
3247
let intrinsics =
3348
get_xml_intrinsics(&cli_options.filename).expect("Error parsing input file");
3449

@@ -37,7 +52,7 @@ impl SupportedArchitectureTest for X86ArchitectureTest {
3752
// Not sure how we would compare intrinsic that returns void.
3853
.filter(|i| i.results.kind() != TypeKind::Void)
3954
.filter(|i| i.results.kind() != TypeKind::BFloat)
40-
.filter(|i| i.arguments().args.len() > 0)
55+
.filter(|i| i.arguments.args.len() > 0)
4156
.filter(|i| !i.arguments.iter().any(|a| a.ty.kind() == TypeKind::BFloat))
4257
// Skip pointers for now, we would probably need to look at the return
4358
// type to work out how many elements we need to point to.
@@ -47,132 +62,10 @@ impl SupportedArchitectureTest for X86ArchitectureTest {
4762
.collect::<Vec<_>>();
4863

4964
intrinsics.sort_by(|a, b| a.name.cmp(&b.name));
50-
Box::new(Self {
65+
Self {
5166
intrinsics: intrinsics,
5267
cli_options: cli_options,
53-
})
54-
}
55-
56-
fn build_c_file(&self) -> bool {
57-
let c_target = "x86_64";
58-
let platform_headers = &["immintrin.h"];
59-
60-
let (chunk_size, chunk_count) = chunk_info(self.intrinsics.len());
61-
62-
let cpp_compiler_wrapped = compile::build_cpp_compilation(&self.cli_options);
63-
64-
let notice = &build_notices("// ");
65-
fs::create_dir_all("c_programs").unwrap();
66-
self.intrinsics
67-
.par_chunks(chunk_size)
68-
.enumerate()
69-
.map(|(i, chunk)| {
70-
let c_filename = format!("c_programs/mod_{i}.cpp");
71-
let mut file = File::create(&c_filename).unwrap();
72-
write_mod_cpp(&mut file, notice, c_target, platform_headers, chunk).unwrap();
73-
74-
// compile this cpp file into a .o file.
75-
//
76-
// This is done because `cpp_compiler_wrapped` is None when
77-
// the --generate-only flag is passed
78-
if let Some(cpp_compiler) = cpp_compiler_wrapped.as_ref() {
79-
let output = cpp_compiler
80-
.compile_object_file(&format!("mod_{i}.cpp"), &format!("mod_{i}.o"))?;
81-
assert!(output.status.success(), "{output:?}");
82-
}
83-
84-
Ok(())
85-
})
86-
.collect::<Result<(), std::io::Error>>()
87-
.unwrap();
88-
89-
let mut file = File::create("c_programs/main.cpp").unwrap();
90-
write_main_cpp(
91-
&mut file,
92-
c_target,
93-
"\n",
94-
self.intrinsics.iter().map(|i| i.name.as_str()),
95-
)
96-
.unwrap();
97-
98-
// This is done because `cpp_compiler_wrapped` is None when
99-
// the --generate-only flag is passed
100-
if let Some(cpp_compiler) = cpp_compiler_wrapped.as_ref() {
101-
// compile this cpp file into a .o file
102-
info!("compiling main.cpp");
103-
let output = cpp_compiler
104-
.compile_object_file("main.cpp", "intrinsic-test-programs.o")
105-
.unwrap();
106-
assert!(output.status.success(), "{output:?}");
107-
108-
let object_files = (0..chunk_count)
109-
.map(|i| format!("mod_{i}.o"))
110-
.chain(["intrinsic-test-programs.o".to_owned()]);
111-
112-
let output = cpp_compiler
113-
.link_executable(object_files, "intrinsic-test-programs")
114-
.unwrap();
115-
assert!(output.status.success(), "{output:?}");
11668
}
117-
118-
true
119-
}
120-
121-
fn build_rust_file(&self) -> bool {
122-
std::fs::create_dir_all("rust_programs/src").unwrap();
123-
124-
let architecture = if self.cli_options.target.contains("v7") {
125-
"arm"
126-
} else {
127-
"aarch64"
128-
};
129-
130-
let (chunk_size, chunk_count) = chunk_info(self.intrinsics.len());
131-
132-
let mut cargo = File::create("rust_programs/Cargo.toml").unwrap();
133-
write_bin_cargo_toml(&mut cargo, chunk_count).unwrap();
134-
135-
let mut main_rs = File::create("rust_programs/src/main.rs").unwrap();
136-
write_main_rs(
137-
&mut main_rs,
138-
chunk_count,
139-
X86_CONFIGURATIONS,
140-
LANE_FUNCTION_HELPERS,
141-
self.intrinsics.iter().map(|i| i.name.as_str()),
142-
)
143-
.unwrap();
144-
145-
let target = &self.cli_options.target;
146-
let toolchain = self.cli_options.toolchain.as_deref();
147-
let linker = self.cli_options.linker.as_deref();
148-
149-
let notice = &build_notices("// ");
150-
self.intrinsics
151-
.par_chunks(chunk_size)
152-
.enumerate()
153-
.map(|(i, chunk)| {
154-
std::fs::create_dir_all(format!("rust_programs/mod_{i}/src"))?;
155-
156-
let rust_filename = format!("rust_programs/mod_{i}/src/lib.rs");
157-
trace!("generating `{rust_filename}`");
158-
let mut file = File::create(rust_filename)?;
159-
160-
let cfg = X86_CONFIGURATIONS;
161-
let definitions = F16_FORMATTING_DEF;
162-
write_lib_rs(&mut file, architecture, notice, cfg, definitions, chunk)?;
163-
164-
let toml_filename = format!("rust_programs/mod_{i}/Cargo.toml");
165-
trace!("generating `{toml_filename}`");
166-
let mut file = File::create(toml_filename).unwrap();
167-
168-
write_lib_cargo_toml(&mut file, &format!("mod_{i}"))?;
169-
170-
Ok(())
171-
})
172-
.collect::<Result<(), std::io::Error>>()
173-
.unwrap();
174-
175-
compile_rust_programs(toolchain, target, linker)
17669
}
17770

17871
fn compare_outputs(&self) -> bool {

0 commit comments

Comments
 (0)