diff --git a/crates/assert-instr-macro/Cargo.toml b/crates/assert-instr-macro/Cargo.toml
index 4ad654e695..881c8109c1 100644
--- a/crates/assert-instr-macro/Cargo.toml
+++ b/crates/assert-instr-macro/Cargo.toml
@@ -11,4 +11,4 @@ test = false
[dependencies]
proc-macro2 = "1.0"
quote = "1.0"
-syn = { version = "1.0", features = ["full"] }
+syn = { version = "2.0", features = ["full"] }
diff --git a/crates/assert-instr-macro/src/lib.rs b/crates/assert-instr-macro/src/lib.rs
index dfda3b48bf..c9de43943f 100644
--- a/crates/assert-instr-macro/src/lib.rs
+++ b/crates/assert-instr-macro/src/lib.rs
@@ -38,7 +38,7 @@ pub fn assert_instr(
let maybe_allow_deprecated = if func
.attrs
.iter()
- .any(|attr| attr.path.is_ident("deprecated"))
+ .any(|attr| attr.path().is_ident("deprecated"))
{
quote! { #[allow(deprecated)] }
} else {
@@ -117,7 +117,7 @@ pub fn assert_instr(
.attrs
.iter()
.filter(|attr| {
- attr.path
+ attr.path()
.segments
.first()
.expect("attr.path.segments.first() failed")
diff --git a/crates/intrinsic-test/Cargo.toml b/crates/intrinsic-test/Cargo.toml
index d977dd659b..c7a18f77f5 100644
--- a/crates/intrinsic-test/Cargo.toml
+++ b/crates/intrinsic-test/Cargo.toml
@@ -12,10 +12,10 @@ lazy_static = "1.4.0"
serde = { version = "1", features = ["derive"] }
serde_json = "1.0"
csv = "1.1"
-clap = "2.33.3"
+clap = { version = "4.4", features = ["derive"] }
regex = "1.4.2"
log = "0.4.11"
-pretty_env_logger = "0.4.0"
+pretty_env_logger = "0.5.0"
rayon = "1.5.0"
diff = "0.1.12"
-itertools = "0.10.1"
+itertools = "0.11.0"
diff --git a/crates/intrinsic-test/README.md b/crates/intrinsic-test/README.md
index 8a8ddab404..2b3f0c75a2 100644
--- a/crates/intrinsic-test/README.md
+++ b/crates/intrinsic-test/README.md
@@ -4,15 +4,17 @@ each produces the same result from random inputs.
# Usage
```
USAGE:
- intrinsic-test [OPTIONS]
+ intrinsic-test [FLAGS] [OPTIONS]
FLAGS:
+ --a32 Run tests for A32 instrinsics instead of A64
-h, --help Prints help information
-V, --version Prints version information
OPTIONS:
--cppcompiler The C++ compiler to use for compiling the c++ code [default: clang++]
--runner Run the C programs under emulation with this command
+ --skip Filename for a list of intrinsics to skip (one per line)
--toolchain The rust toolchain to use for building the rust code
ARGS:
diff --git a/crates/intrinsic-test/src/json_parser.rs b/crates/intrinsic-test/src/json_parser.rs
index bc6fa4a9ed..8b3c7869c6 100644
--- a/crates/intrinsic-test/src/json_parser.rs
+++ b/crates/intrinsic-test/src/json_parser.rs
@@ -1,4 +1,5 @@
use std::collections::HashMap;
+use std::path::Path;
use serde::Deserialize;
@@ -41,7 +42,7 @@ struct JsonIntrinsic {
architectures: Vec,
}
-pub fn get_neon_intrinsics(filename: &str) -> Result, Box> {
+pub fn get_neon_intrinsics(filename: &Path) -> Result, Box> {
let file = std::fs::File::open(filename)?;
let reader = std::io::BufReader::new(file);
let json: Vec = serde_json::from_reader(reader).expect("Couldn't parse JSON");
diff --git a/crates/intrinsic-test/src/main.rs b/crates/intrinsic-test/src/main.rs
index 76d2da3abf..15bc021c75 100644
--- a/crates/intrinsic-test/src/main.rs
+++ b/crates/intrinsic-test/src/main.rs
@@ -4,9 +4,9 @@ extern crate log;
use std::fs::File;
use std::io::Write;
+use std::path::PathBuf;
use std::process::Command;
-use clap::{App, Arg};
use intrinsic::Intrinsic;
use itertools::Itertools;
use rayon::prelude::*;
@@ -320,58 +320,47 @@ path = "{intrinsic}/main.rs""#,
}
}
+/// Intrinsic test tool
+#[derive(clap::Parser)]
+#[command(
+ name = "Intrinsic test tool",
+ about = "Generates Rust and C programs for intrinsics and compares the output"
+)]
+struct Cli {
+ /// The input file containing the intrinsics
+ input: PathBuf,
+
+ /// The rust toolchain to use for building the rust code
+ #[arg(long)]
+ toolchain: Option,
+
+ /// The C++ compiler to use for compiling the c++ code
+ #[arg(long, default_value_t = String::from("clang++"))]
+ cppcompiler: String,
+
+ /// Run the C programs under emulation with this command
+ #[arg(long)]
+ runner: Option,
+
+ /// Filename for a list of intrinsics to skip (one per line)
+ #[arg(long)]
+ skip: Option,
+
+ /// Run tests for A32 instrinsics instead of A64
+ #[arg(long)]
+ a32: bool,
+}
+
fn main() {
pretty_env_logger::init();
- let matches = App::new("Intrinsic test tool")
- .about("Generates Rust and C programs for intrinsics and compares the output")
- .arg(
- Arg::with_name("INPUT")
- .help("The input file containing the intrinsics")
- .required(true)
- .index(1),
- )
- .arg(
- Arg::with_name("TOOLCHAIN")
- .takes_value(true)
- .long("toolchain")
- .help("The rust toolchain to use for building the rust code"),
- )
- .arg(
- Arg::with_name("CPPCOMPILER")
- .takes_value(true)
- .default_value("clang++")
- .long("cppcompiler")
- .help("The C++ compiler to use for compiling the c++ code"),
- )
- .arg(
- Arg::with_name("RUNNER")
- .takes_value(true)
- .long("runner")
- .help("Run the C programs under emulation with this command"),
- )
- .arg(
- Arg::with_name("SKIP")
- .takes_value(true)
- .long("skip")
- .help("Filename for a list of intrinsics to skip (one per line)"),
- )
- .arg(
- Arg::with_name("A32")
- .takes_value(false)
- .long("a32")
- .help("Run tests for A32 instrinsics instead of A64"),
- )
- .get_matches();
-
- let filename = matches.value_of("INPUT").unwrap();
- let toolchain = matches
- .value_of("TOOLCHAIN")
- .map_or("".into(), |t| format!("+{t}"));
+ let args: Cli = clap::Parser::parse();
- let cpp_compiler = matches.value_of("CPPCOMPILER").unwrap();
- let c_runner = matches.value_of("RUNNER").unwrap_or("");
- let skip = if let Some(filename) = matches.value_of("SKIP") {
+ let filename = args.input;
+ let toolchain = args.toolchain.map_or_else(String::new, |t| format!("+{t}"));
+ let cpp_compiler = args.cppcompiler;
+ let c_runner = args.runner.unwrap_or_else(String::new);
+ let skip = if let Some(filename) = args.skip {
let data = std::fs::read_to_string(&filename).expect("Failed to open file");
data.lines()
.map(str::trim)
@@ -381,8 +370,8 @@ fn main() {
} else {
Default::default()
};
- let a32 = matches.is_present("A32");
- let mut intrinsics = get_neon_intrinsics(filename).expect("Error parsing input file");
+ let a32 = args.a32;
+ let mut intrinsics = get_neon_intrinsics(&filename).expect("Error parsing input file");
intrinsics.sort_by(|a, b| a.name.cmp(&b.name));
@@ -409,7 +398,7 @@ fn main() {
let notices = build_notices("// ");
- if !build_c(¬ices, &intrinsics, cpp_compiler, a32) {
+ if !build_c(¬ices, &intrinsics, &cpp_compiler, a32) {
std::process::exit(2);
}
diff --git a/crates/stdarch-test/Cargo.toml b/crates/stdarch-test/Cargo.toml
index 3a2130d4e2..3682fcd7ed 100644
--- a/crates/stdarch-test/Cargo.toml
+++ b/crates/stdarch-test/Cargo.toml
@@ -20,7 +20,7 @@ cc = "1.0"
# time, and we want to make updates to this explicit rather than automatically
# picking up updates which might break CI with new instruction names.
[target.'cfg(target_arch = "wasm32")'.dependencies]
-wasmprinter = "=0.2.53"
+wasmprinter = "=0.2.67"
[features]
default = []
diff --git a/crates/stdarch-verify/Cargo.toml b/crates/stdarch-verify/Cargo.toml
index 10ae90074d..515f05138a 100644
--- a/crates/stdarch-verify/Cargo.toml
+++ b/crates/stdarch-verify/Cargo.toml
@@ -7,7 +7,7 @@ edition = "2021"
[dependencies]
proc-macro2 = "1.0"
quote = "1.0"
-syn = { version = "1.0", features = ["full"] }
+syn = { version = "2.0", features = ["full"] }
[lib]
proc-macro = true
@@ -15,5 +15,5 @@ test = false
[dev-dependencies]
serde = { version = "1.0", features = ['derive'] }
-serde-xml-rs = "0.3"
+serde-xml-rs = "0.6"
serde_json = "1.0.96"
diff --git a/crates/stdarch-verify/src/lib.rs b/crates/stdarch-verify/src/lib.rs
index a9bf89f707..3f9eb3bf9b 100644
--- a/crates/stdarch-verify/src/lib.rs
+++ b/crates/stdarch-verify/src/lib.rs
@@ -7,6 +7,7 @@ extern crate syn;
use proc_macro::TokenStream;
use std::{fs::File, io::Read, path::Path};
use syn::ext::IdentExt;
+use syn::parse::Parser as _;
#[proc_macro]
pub fn x86_functions(input: TokenStream) -> TokenStream {
@@ -416,7 +417,7 @@ fn walk(root: &Path, files: &mut Vec<(syn::File, String)>) {
fn find_instrs(attrs: &[syn::Attribute]) -> Vec {
struct AssertInstr {
- instr: String,
+ instr: Option,
}
// A small custom parser to parse out the instruction in `assert_instr`.
@@ -424,15 +425,21 @@ fn find_instrs(attrs: &[syn::Attribute]) -> Vec {
// TODO: should probably just reuse `Invoc` from the `assert-instr-macro`
// crate.
impl syn::parse::Parse for AssertInstr {
- fn parse(content: syn::parse::ParseStream<'_>) -> syn::Result {
- let input;
- parenthesized!(input in content);
- let _ = input.parse::()?;
- let _ = input.parse::()?;
- let ident = input.parse::()?;
- if ident != "assert_instr" {
- return Err(input.error("expected `assert_instr`"));
+ fn parse(input: syn::parse::ParseStream<'_>) -> syn::Result {
+ let _ = input.parse::().unwrap();
+ let _ = input.parse::().unwrap();
+
+ match input.parse::() {
+ Ok(ident) if ident == "assert_instr" => {}
+ _ => {
+ while !input.is_empty() {
+ // consume everything
+ drop(input.parse::());
+ }
+ return Ok(Self { instr: None });
+ }
}
+
let instrs;
parenthesized!(instrs in input);
@@ -452,18 +459,24 @@ fn find_instrs(attrs: &[syn::Attribute]) -> Vec {
return Err(input.error("failed to parse instruction"));
}
}
- Ok(Self { instr })
+ Ok(Self { instr: Some(instr) })
}
}
attrs
.iter()
- .filter(|a| a.path.is_ident("cfg_attr"))
.filter_map(|a| {
- syn::parse2::(a.tokens.clone())
- .ok()
- .map(|a| a.instr)
+ if let syn::Meta::List(ref l) = a.meta {
+ if l.path.is_ident("cfg_attr") {
+ Some(l)
+ } else {
+ None
+ }
+ } else {
+ None
+ }
})
+ .filter_map(|l| syn::parse2::(l.tokens.clone()).unwrap().instr)
.collect()
}
@@ -471,19 +484,26 @@ fn find_target_feature(attrs: &[syn::Attribute]) -> Option {
attrs
.iter()
.flat_map(|a| {
- if let Ok(syn::Meta::List(i)) = a.parse_meta() {
- if i.path.is_ident("target_feature") {
- return i.nested;
+ if let syn::Meta::List(ref l) = a.meta {
+ if l.path.is_ident("target_feature") {
+ if let Ok(l) =
+ syn::punctuated::Punctuated::::parse_terminated
+ .parse2(l.tokens.clone())
+ {
+ return l;
+ }
}
}
syn::punctuated::Punctuated::new()
})
- .filter_map(|nested| match nested {
- syn::NestedMeta::Meta(m) => Some(m),
- syn::NestedMeta::Lit(_) => None,
- })
.find_map(|m| match m {
- syn::Meta::NameValue(ref i) if i.path.is_ident("enable") => Some(i.clone().lit),
+ syn::Meta::NameValue(i) if i.path.is_ident("enable") => {
+ if let syn::Expr::Lit(lit) = i.value {
+ Some(lit.lit)
+ } else {
+ None
+ }
+ }
_ => None,
})
}
@@ -491,9 +511,16 @@ fn find_target_feature(attrs: &[syn::Attribute]) -> Option {
fn find_required_const(name: &str, attrs: &[syn::Attribute]) -> Vec {
attrs
.iter()
- .flat_map(|a| {
- if a.path.segments[0].ident == name {
- syn::parse::(a.tokens.clone().into())
+ .filter_map(|a| {
+ if let syn::Meta::List(ref l) = a.meta {
+ Some(l)
+ } else {
+ None
+ }
+ })
+ .flat_map(|l| {
+ if l.path.segments[0].ident == name {
+ syn::parse2::(l.tokens.clone())
.unwrap()
.args
} else {
@@ -509,10 +536,7 @@ struct RustcArgsRequiredConst {
impl syn::parse::Parse for RustcArgsRequiredConst {
fn parse(input: syn::parse::ParseStream<'_>) -> syn::Result {
- let content;
- parenthesized!(content in input);
- let list =
- syn::punctuated::Punctuated::::parse_terminated(&content)?;
+ let list = syn::punctuated::Punctuated::::parse_terminated(&input)?;
Ok(Self {
args: list
.into_iter()
diff --git a/examples/Cargo.toml b/examples/Cargo.toml
index 38f497fa61..d9034dd803 100644
--- a/examples/Cargo.toml
+++ b/examples/Cargo.toml
@@ -13,8 +13,8 @@ default-run = "hex"
[dependencies]
core_arch = { path = "../crates/core_arch" }
std_detect = { path = "../crates/std_detect" }
-quickcheck = "0.9"
-rand = "0.7"
+quickcheck = "1.0"
+rand = "0.8"
[[bin]]
name = "hex"