Skip to content

Commit a84475c

Browse files
committed
Generate rust bindings and test code
1 parent e195070 commit a84475c

11 files changed

Lines changed: 342 additions & 223 deletions

File tree

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

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,11 @@ use json_parser::get_neon_intrinsics;
1313

1414
pub struct ArmArchitectureTest {
1515
intrinsics: Vec<Intrinsic<ArmIntrinsicType>>,
16-
cli_options: ProcessedCli,
1716
}
1817

1918
impl SupportedArchitectureTest for ArmArchitectureTest {
2019
type IntrinsicImpl = ArmIntrinsicType;
2120

22-
fn cli_options(&self) -> &ProcessedCli {
23-
&self.cli_options
24-
}
25-
2621
fn intrinsics(&self) -> &[Intrinsic<ArmIntrinsicType>] {
2722
&self.intrinsics
2823
}
@@ -34,6 +29,10 @@ impl SupportedArchitectureTest for ArmArchitectureTest {
3429
const PLATFORM_RUST_DEFINITIONS: &str = config::PLATFORM_RUST_DEFINITIONS;
3530
const PLATFORM_RUST_CFGS: &str = config::PLATFORM_RUST_CFGS;
3631

32+
fn arch_flags(&self) -> Vec<&str> {
33+
vec!["-march=armv8.6a+crypto+crc+dotprod+fp16"]
34+
}
35+
3736
fn create(cli_options: ProcessedCli) -> Self {
3837
let a32 = cli_options.target.starts_with("armv7");
3938
let mut intrinsics = get_neon_intrinsics(&cli_options.filename, &cli_options.target)
@@ -60,9 +59,6 @@ impl SupportedArchitectureTest for ArmArchitectureTest {
6059
.take(sample_size)
6160
.collect::<Vec<_>>();
6261

63-
Self {
64-
intrinsics,
65-
cli_options,
66-
}
62+
Self { intrinsics }
6763
}
6864
}

crates/intrinsic-test/src/arm/types.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ impl IntrinsicTypeDefinition for ArmIntrinsicType {
66
fn c_type(&self) -> String {
77
let prefix = self.kind.c_prefix();
88

9-
if let (Some(bit_len), simd_len, vec_len) = (self.bit_len, self.simd_len, self.vec_len) {
10-
match (simd_len, vec_len) {
9+
if let Some(bit_len) = self.bit_len {
10+
match (self.simd_len, self.vec_len) {
1111
(None, None) => format!("{prefix}{bit_len}_t"),
1212
(Some(simd), None) => format!("{prefix}{bit_len}x{simd}_t"),
1313
(Some(simd), Some(vec)) => format!("{prefix}{bit_len}x{simd}x{vec}_t"),
@@ -18,6 +18,22 @@ impl IntrinsicTypeDefinition for ArmIntrinsicType {
1818
}
1919
}
2020

21+
fn rust_type(&self) -> String {
22+
let rust_prefix = self.kind.rust_prefix();
23+
let c_prefix = self.kind.c_prefix();
24+
25+
if let Some(bit_len) = self.bit_len {
26+
match (self.simd_len, self.vec_len) {
27+
(None, None) => format!("{rust_prefix}{bit_len}"),
28+
(Some(simd), None) => format!("{c_prefix}{bit_len}x{simd}_t"),
29+
(Some(simd), Some(vec)) => format!("{c_prefix}{bit_len}x{simd}x{vec}_t"),
30+
(None, Some(_)) => todo!("{self:#?}"), // Likely an invalid case
31+
}
32+
} else {
33+
todo!("{self:#?}")
34+
}
35+
}
36+
2137
/// Determines the load function for this type.
2238
fn get_load_function(&self) -> String {
2339
if let IntrinsicType {

crates/intrinsic-test/src/common/argument.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,15 @@ where
9494
.to_string()
9595
}
9696

97+
pub fn as_non_imm_arglist_rust(&self) -> String {
98+
self.iter()
99+
.filter(|arg| !arg.has_constraint())
100+
.format_with(", ", |arg, fmt| {
101+
fmt(&format_args!("{}: {}", arg.name, arg.ty.rust_type()))
102+
})
103+
.to_string()
104+
}
105+
97106
pub fn as_call_params_c(&self, imm_args: &[i64]) -> String {
98107
let mut imm_args = imm_args.iter();
99108
self.iter()
@@ -113,7 +122,6 @@ where
113122
self.iter()
114123
.filter(|a| !a.has_constraint())
115124
.map(|arg| arg.generate_name() + " as _")
116-
.collect::<Vec<String>>()
117125
.join(", ")
118126
}
119127

crates/intrinsic-test/src/common/gen_c.rs

Lines changed: 19 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,9 @@
11
use itertools::Itertools;
22

3-
use crate::common::constraint::Constraint;
43
use crate::common::intrinsic::Intrinsic;
54

65
use super::intrinsic_helpers::IntrinsicTypeDefinition;
76

8-
fn generate_c_wrapper<'a, T: IntrinsicTypeDefinition + 'a>(
9-
w: &mut impl std::io::Write,
10-
intrinsic: &Intrinsic<T>,
11-
constraints: &mut (impl Iterator<Item = &'a Constraint> + Clone),
12-
imm_values: &mut Vec<i64>,
13-
) -> std::io::Result<()> {
14-
if let Some(current) = constraints.next() {
15-
for i in current.iter() {
16-
imm_values.push(i);
17-
generate_c_wrapper(w, intrinsic, &mut constraints.clone(), imm_values)?;
18-
imm_values.pop();
19-
}
20-
} else {
21-
writeln!(
22-
w,
23-
"
24-
{return_ty} {name}_wrapper{imm_arglist}({arglist}) {{
25-
return {name}({params});
26-
}}",
27-
return_ty = intrinsic.results.c_type(),
28-
name = intrinsic.name,
29-
imm_arglist = imm_values
30-
.iter()
31-
.format_with("", |i, fmt| fmt(&format_args!("_{i}"))),
32-
arglist = intrinsic.arguments.as_non_imm_arglist_c(),
33-
params = intrinsic.arguments.as_call_params_c(&imm_values)
34-
)?;
35-
}
36-
Ok(())
37-
}
38-
39-
fn create_c_wrapper<T: IntrinsicTypeDefinition>(
40-
w: &mut impl std::io::Write,
41-
intrinsic: &Intrinsic<T>,
42-
) -> std::io::Result<()> {
43-
generate_c_wrapper(
44-
w,
45-
intrinsic,
46-
&mut intrinsic
47-
.arguments
48-
.iter()
49-
.filter_map(|arg| arg.constraint.as_ref()),
50-
&mut Vec::new(),
51-
)
52-
}
53-
547
pub fn write_wrapper_c<T: IntrinsicTypeDefinition>(
558
w: &mut impl std::io::Write,
569
notice: &str,
@@ -59,12 +12,30 @@ pub fn write_wrapper_c<T: IntrinsicTypeDefinition>(
5912
) -> std::io::Result<()> {
6013
write!(w, "{notice}")?;
6114

15+
writeln!(w, "#include <stdint.h>")?;
16+
writeln!(w, "#include <stddef.h>")?;
17+
6218
for header in platform_headers {
6319
writeln!(w, "#include <{header}>")?;
6420
}
6521

6622
for intrinsic in intrinsics {
67-
create_c_wrapper(w, intrinsic)?;
23+
intrinsic.iter_specializations(|imm_values| {
24+
writeln!(
25+
w,
26+
"
27+
{return_ty} {name}_wrapper{imm_arglist}({arglist}) {{
28+
return {name}({params});
29+
}}",
30+
return_ty = intrinsic.results.c_type(),
31+
name = intrinsic.name,
32+
imm_arglist = imm_values
33+
.iter()
34+
.format_with("", |i, fmt| fmt(&format_args!("_{i}"))),
35+
arglist = intrinsic.arguments.as_non_imm_arglist_c(),
36+
params = intrinsic.arguments.as_call_params_c(&imm_values)
37+
)
38+
})?;
6839
}
6940

7041
Ok(())

0 commit comments

Comments
 (0)