Skip to content

Commit 0956462

Browse files
authored
Merge pull request #2071 from davidtwco/sve-intrinsics
initial SVE intrinsics
2 parents cf05573 + ae9cb1c commit 0956462

23 files changed

Lines changed: 332594 additions & 33011 deletions

File tree

crates/assert-instr-macro/src/lib.rs

Lines changed: 65 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ extern crate quote;
1414

1515
use proc_macro2::TokenStream;
1616
use quote::ToTokens;
17+
use syn::spanned::Spanned;
1718

1819
#[proc_macro_attribute]
1920
pub fn assert_instr(
@@ -67,40 +68,70 @@ pub fn assert_instr(
6768
);
6869
let mut inputs = Vec::new();
6970
let mut input_vals = Vec::new();
70-
let mut const_vals = Vec::new();
71+
let mut param_vals = Vec::new();
7172
let ret = &func.sig.output;
7273
for arg in func.sig.inputs.iter() {
7374
let capture = match *arg {
74-
syn::FnArg::Typed(ref c) => c,
75+
syn::FnArg::Typed(ref c) => c.to_owned(),
7576
ref v => panic!(
7677
"arguments must not have patterns: `{:?}`",
7778
v.clone().into_token_stream()
7879
),
7980
};
80-
let ident = match *capture.pat {
81-
syn::Pat::Ident(ref i) => &i.ident,
81+
let ident = match capture.pat.as_ref() {
82+
syn::Pat::Ident(i) => &i.ident.to_owned(),
8283
_ => panic!("must have bare arguments"),
8384
};
84-
if let Some((_, tokens)) = invoc.args.iter().find(|a| *ident == a.0) {
85+
if let Some(&(_, ref tokens)) = invoc.args.iter().find(|a| *ident == a.0) {
8586
input_vals.push(quote! { #tokens });
8687
} else {
8788
inputs.push(capture);
8889
input_vals.push(quote! { #ident });
8990
}
9091
}
9192
for arg in func.sig.generics.params.iter() {
92-
let c = match *arg {
93-
syn::GenericParam::Const(ref c) => c,
93+
match *arg {
94+
syn::GenericParam::Const(ref c) => {
95+
if let Some((_, tokens)) = invoc.args.iter().find(|a| c.ident == a.0) {
96+
param_vals.push(quote! { #tokens });
97+
} else {
98+
panic!("const generics must have a value for tests");
99+
}
100+
}
101+
syn::GenericParam::Type(ref t) => {
102+
if let Some((_, tokens)) = invoc.args.iter().find(|a| t.ident == a.0)
103+
&& let syn::Expr::Path(syn::ExprPath { qself, path, .. }) = tokens
104+
{
105+
param_vals.push(syn::Token![_](tokens.span()).to_token_stream());
106+
107+
let generic_ty_value = syn::TypePath {
108+
qself: qself.clone(),
109+
path: path.clone(),
110+
};
111+
112+
// Replace any function arguments that use generic parameters with the
113+
// instantiation provided in the macro invocation.
114+
inputs.iter_mut().for_each(|arg| {
115+
update_type_path(arg.ty.as_mut(), |type_path: &mut syn::TypePath| {
116+
if let Some(syn::PathSegment {
117+
ident: last_ident, ..
118+
}) = type_path.path.segments.last_mut()
119+
{
120+
if *last_ident == t.ident {
121+
*type_path = generic_ty_value.to_owned()
122+
}
123+
}
124+
})
125+
});
126+
} else {
127+
panic!("type generics must have a type for tests");
128+
}
129+
}
94130
ref v => panic!(
95-
"only const generics are allowed: `{:?}`",
131+
"only type and const generics are allowed: `{:?}`",
96132
v.clone().into_token_stream()
97133
),
98134
};
99-
if let Some((_, tokens)) = invoc.args.iter().find(|a| c.ident == a.0) {
100-
const_vals.push(quote! { #tokens });
101-
} else {
102-
panic!("const generics must have a value for tests");
103-
}
104135
}
105136

106137
let attrs = func
@@ -138,7 +169,7 @@ pub fn assert_instr(
138169
#[unsafe(no_mangle)]
139170
#[inline(never)]
140171
pub unsafe extern #abi fn #shim_name(#(#inputs),*) #ret {
141-
#name::<#(#const_vals),*>(#(#input_vals),*)
172+
#name::<#(#param_vals),*>(#(#input_vals),*)
142173
}
143174
};
144175

@@ -222,3 +253,23 @@ where
222253
}
223254
}
224255
}
256+
257+
/// Calls `update` on type paths so that type generics can be replaced with the instantiation from
258+
/// the attribute.
259+
fn update_type_path<F>(ty: &mut syn::Type, update: F)
260+
where
261+
F: Fn(&mut syn::TypePath),
262+
{
263+
use syn::Type::*;
264+
match ty {
265+
Array(syn::TypeArray { elem, .. })
266+
| Group(syn::TypeGroup { elem, .. })
267+
| Paren(syn::TypeParen { elem, .. })
268+
| Ptr(syn::TypePtr { elem, .. })
269+
| Reference(syn::TypeReference { elem, .. })
270+
| Slice(syn::TypeSlice { elem, .. }) => update_type_path(elem.as_mut(), update),
271+
Path(path @ syn::TypePath { .. }) => update(path),
272+
Tuple(..) => panic!("tuples and generic types together are not yet supported"),
273+
_ => {}
274+
}
275+
}

crates/core_arch/src/aarch64/mod.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,20 @@ mod neon;
2525
#[stable(feature = "neon_intrinsics", since = "1.59.0")]
2626
pub use self::neon::*;
2727

28+
// The rest of `core_arch::aarch64` is available on `arm64ec` but SVE is not supported on `arm64ec`.
29+
#[cfg(any(target_arch = "aarch64", doc))]
30+
mod sve;
31+
#[cfg(any(target_arch = "aarch64", doc))]
32+
#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
33+
pub use self::sve::*;
34+
35+
// The rest of `core_arch::aarch64` is available on `arm64ec` but SVE is not supported on `arm64ec`.
36+
#[cfg(any(target_arch = "aarch64", doc))]
37+
mod sve2;
38+
#[cfg(any(target_arch = "aarch64", doc))]
39+
#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
40+
pub use self::sve2::*;
41+
2842
mod prefetch;
2943
#[unstable(feature = "stdarch_aarch64_prefetch", issue = "117217")]
3044
pub use self::prefetch::*;

0 commit comments

Comments
 (0)