diff --git a/cranelift/src/cton-util.rs b/cranelift/src/cton-util.rs index e702f57ae4..fbb0603cf7 100644 --- a/cranelift/src/cton-util.rs +++ b/cranelift/src/cton-util.rs @@ -30,7 +30,7 @@ Usage: cton-util cat ... cton-util filecheck [-v] cton-util print-cfg ... - cton-util wasm [-cvo] [--enable=]... ... + cton-util wasm [-cvo] [--set ]... [--isa ] ... cton-util --help | --version Options: @@ -38,6 +38,8 @@ Options: -c, --check checks the correctness of Cretonne IL translated from WebAssembly -o, --optimize runs otpimization passes on translated WebAssembly functions -h, --help print this help message + --set= configure Cretonne settings + --isa= specify the Cretonne ISA --version print the Cretonne version "; @@ -53,7 +55,8 @@ struct Args { flag_check: bool, flag_optimize: bool, flag_verbose: bool, - flag_enable: Vec, + flag_set: Vec, + flag_isa: String, } /// A command either succeeds or fails with an error message. @@ -85,7 +88,8 @@ fn cton_util() -> CommandResult { args.flag_verbose, args.flag_optimize, args.flag_check, - args.flag_enable, + args.flag_set, + args.flag_isa, ) } else { // Debugging / shouldn't happen with proper command line handling above. diff --git a/cranelift/src/wasm.rs b/cranelift/src/wasm.rs index 73d27dac91..7ed47a2a9d 100644 --- a/cranelift/src/wasm.rs +++ b/cranelift/src/wasm.rs @@ -5,10 +5,12 @@ //! and tables, then emitting the translated code with hardcoded addresses to memory. use cton_wasm::{translate_module, DummyRuntime, WasmRuntime}; +use cton_reader::{parse_options, Location}; use std::path::PathBuf; use cretonne::Context; use cretonne::verifier; -use cretonne::settings::{self, Configurable}; +use cretonne::settings; +use cretonne::isa::{self, TargetIsa}; use std::fs::File; use std::error::Error; use std::io; @@ -50,16 +52,29 @@ pub fn run( flag_verbose: bool, flag_optimize: bool, flag_check: bool, - flag_enable: Vec, + flag_set: Vec, + flag_isa: String, ) -> Result<(), String> { let mut flag_builder = settings::builder(); - for enable in flag_enable { - flag_builder.enable(&enable).map_err(|_| { - format!("unrecognized flag: {}", enable) - })?; - } + parse_options( + flag_set.iter().map(|x| x.as_str()), + &mut flag_builder, + &Location { line_number: 0 }, + ).map_err(|err| err.to_string())?; let flags = settings::Flags::new(&flag_builder); + let mut words = flag_isa.trim().split_whitespace(); + // Look for `isa foo`. + let isa_name = match words.next() { + None => return Err(String::from("expected ISA name")), + Some(w) => w, + }; + let isa_builder = isa::lookup(isa_name).map_err(|err| match err { + isa::LookupError::Unknown => format!("unknown ISA '{}'", isa_name), + isa::LookupError::Unsupported => format!("support for ISA '{}' not enabled", isa_name), + })?; + let isa = isa_builder.finish(settings::Flags::new(&flag_builder)); + for filename in files { let path = Path::new(&filename); let name = String::from(path.as_os_str().to_string_lossy()); @@ -70,6 +85,7 @@ pub fn run( path.to_path_buf(), name, &flags, + &*isa, )?; } Ok(()) @@ -82,6 +98,7 @@ fn handle_module( path: PathBuf, name: String, flags: &settings::Flags, + isa: &TargetIsa, ) -> Result<(), String> { let mut terminal = term::stdout().unwrap(); terminal.fg(term::color::YELLOW).unwrap(); @@ -140,8 +157,8 @@ fn handle_module( vprint!(flag_verbose, "Checking... "); terminal.reset().unwrap(); for func in &translation.functions { - verifier::verify_function(func, None).map_err(|err| { - pretty_verifier_error(func, None, err) + verifier::verify_function(func, Some(isa)).map_err(|err| { + pretty_verifier_error(func, Some(isa), err) })?; } terminal.fg(term::color::GREEN).unwrap(); @@ -155,18 +172,18 @@ fn handle_module( for func in &translation.functions { let mut context = Context::new(); context.func = func.clone(); - context.verify(None).map_err(|err| { - pretty_verifier_error(&context.func, None, err) + context.verify(Some(isa)).map_err(|err| { + pretty_verifier_error(&context.func, Some(isa), err) })?; context.flowgraph(); context.compute_loop_analysis(); context.licm(); - context.verify(None).map_err(|err| { - pretty_verifier_error(&context.func, None, err) + context.verify(Some(isa)).map_err(|err| { + pretty_verifier_error(&context.func, Some(isa), err) })?; context.simple_gvn(); - context.verify(None).map_err(|err| { - pretty_verifier_error(&context.func, None, err) + context.verify(Some(isa)).map_err(|err| { + pretty_verifier_error(&context.func, Some(isa), err) })?; } terminal.fg(term::color::GREEN).unwrap(); diff --git a/lib/reader/src/error.rs b/lib/reader/src/error.rs index c49e523b72..965eba3cb8 100644 --- a/lib/reader/src/error.rs +++ b/lib/reader/src/error.rs @@ -8,7 +8,8 @@ use std::result; /// The location of a `Token` or `Error`. #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] pub struct Location { - /// Line number, starting from 1. + /// Line number. Command-line arguments are line 0 and source file + /// lines start from 1. pub line_number: usize, } @@ -23,7 +24,11 @@ pub struct Error { impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}: {}", self.location.line_number, self.message) + if self.location.line_number == 0 { + write!(f, "command-line arguments: {}", self.message) + } else { + write!(f, "{}: {}", self.location.line_number, self.message) + } } } diff --git a/lib/reader/src/lib.rs b/lib/reader/src/lib.rs index 61473afe38..06a03dd6fe 100644 --- a/lib/reader/src/lib.rs +++ b/lib/reader/src/lib.rs @@ -11,7 +11,7 @@ pub use error::{Location, Result, Error}; pub use parser::{parse_functions, parse_test}; pub use testcommand::{TestCommand, TestOption}; pub use testfile::{TestFile, Details, Comment}; -pub use isaspec::IsaSpec; +pub use isaspec::{IsaSpec, parse_options}; pub use sourcemap::SourceMap; mod error;