Use the target-lexicon crate.
This switches from a custom list of architectures to use the target-lexicon crate. - "set is_64bit=1; isa x86" is replaced with "target x86_64", and similar for other architectures, and the `is_64bit` flag is removed entirely. - The `is_compressed` flag is removed too; it's no longer being used to control REX prefixes on x86-64, ARM and Thumb are separate architectures in target-lexicon, and we can figure out how to select RISC-V compressed encodings when we're ready.
This commit is contained in:
@@ -9,7 +9,8 @@ use cretonne_codegen::{binemit, ir};
|
||||
use cretonne_reader::parse_test;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use utils::{parse_sets_and_isa, read_to_string};
|
||||
use target_lexicon::Architecture;
|
||||
use utils::{parse_sets_and_triple, read_to_string};
|
||||
|
||||
struct PrintRelocs {
|
||||
flag_print: bool,
|
||||
@@ -64,7 +65,7 @@ pub fn run(
|
||||
flag_set: &[String],
|
||||
flag_isa: &str,
|
||||
) -> Result<(), String> {
|
||||
let parsed = parse_sets_and_isa(flag_set, flag_isa)?;
|
||||
let parsed = parse_sets_and_triple(flag_set, flag_isa)?;
|
||||
|
||||
for filename in files {
|
||||
let path = Path::new(&filename);
|
||||
@@ -136,23 +137,28 @@ fn handle_module(
|
||||
}
|
||||
|
||||
fn get_disassembler(isa: &TargetIsa) -> Result<Capstone, String> {
|
||||
let cs = match isa.name() {
|
||||
"riscv" => return Err(String::from("No disassembler for RiscV")),
|
||||
"x86" => {
|
||||
if isa.flags().is_64bit() {
|
||||
Capstone::new()
|
||||
.x86()
|
||||
.mode(arch::x86::ArchMode::Mode64)
|
||||
.build()
|
||||
} else {
|
||||
Capstone::new()
|
||||
.x86()
|
||||
.mode(arch::x86::ArchMode::Mode32)
|
||||
.build()
|
||||
}
|
||||
let cs = match isa.triple().architecture {
|
||||
Architecture::Riscv32 | Architecture::Riscv64 => {
|
||||
return Err(String::from("No disassembler for RiscV"))
|
||||
}
|
||||
"arm32" => Capstone::new().arm().mode(arch::arm::ArchMode::Arm).build(),
|
||||
"arm64" => Capstone::new()
|
||||
Architecture::I386 | Architecture::I586 | Architecture::I686 => Capstone::new()
|
||||
.x86()
|
||||
.mode(arch::x86::ArchMode::Mode32)
|
||||
.build(),
|
||||
Architecture::X86_64 => Capstone::new()
|
||||
.x86()
|
||||
.mode(arch::x86::ArchMode::Mode64)
|
||||
.build(),
|
||||
Architecture::Arm
|
||||
| Architecture::Armv4t
|
||||
| Architecture::Armv5te
|
||||
| Architecture::Armv7
|
||||
| Architecture::Armv7s => Capstone::new().arm().mode(arch::arm::ArchMode::Arm).build(),
|
||||
Architecture::Thumbv6m | Architecture::Thumbv7em | Architecture::Thumbv7m => Capstone::new(
|
||||
).arm()
|
||||
.mode(arch::arm::ArchMode::Thumb)
|
||||
.build(),
|
||||
Architecture::Aarch64 => Capstone::new()
|
||||
.arm64()
|
||||
.mode(arch::arm64::ArchMode::Arm)
|
||||
.build(),
|
||||
|
||||
@@ -27,6 +27,7 @@ cfg_if! {
|
||||
mod wasm;
|
||||
}
|
||||
}
|
||||
extern crate target_lexicon;
|
||||
|
||||
use cretonne_codegen::{timing, VERSION};
|
||||
use docopt::Docopt;
|
||||
@@ -47,8 +48,8 @@ Usage:
|
||||
cton-util cat <file>...
|
||||
cton-util filecheck [-v] <file>
|
||||
cton-util print-cfg <file>...
|
||||
cton-util compile [-vpT] [--set <set>]... [--isa <isa>] <file>...
|
||||
cton-util wasm [-ctvpTs] [--set <set>]... [--isa <isa>] <file>...
|
||||
cton-util compile [-vpT] [--set <set>]... [--target <triple>] <file>...
|
||||
cton-util wasm [-ctvpTs] [--set <set>]... [--target <triple>] <file>...
|
||||
cton-util --help | --version
|
||||
|
||||
Options:
|
||||
@@ -64,7 +65,8 @@ Options:
|
||||
-p, --print print the resulting Cretonne IR
|
||||
-h, --help print this help message
|
||||
--set=<set> configure Cretonne settings
|
||||
--isa=<isa> specify the Cretonne ISA
|
||||
--target=<triple>
|
||||
specify the Cretonne target
|
||||
--version print the Cretonne version
|
||||
|
||||
";
|
||||
@@ -83,7 +85,7 @@ struct Args {
|
||||
flag_print: bool,
|
||||
flag_verbose: bool,
|
||||
flag_set: Vec<String>,
|
||||
flag_isa: String,
|
||||
flag_target: String,
|
||||
flag_time_passes: bool,
|
||||
flag_print_size: bool,
|
||||
}
|
||||
@@ -116,7 +118,7 @@ fn cton_util() -> CommandResult {
|
||||
args.arg_file,
|
||||
args.flag_print,
|
||||
&args.flag_set,
|
||||
&args.flag_isa,
|
||||
&args.flag_target,
|
||||
)
|
||||
} else if args.cmd_wasm {
|
||||
#[cfg(feature = "wasm")]
|
||||
@@ -127,7 +129,7 @@ fn cton_util() -> CommandResult {
|
||||
args.flag_check_translation,
|
||||
args.flag_print,
|
||||
&args.flag_set,
|
||||
&args.flag_isa,
|
||||
&args.flag_target,
|
||||
args.flag_print_size,
|
||||
);
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@ use cretonne_reader::{parse_options, Location};
|
||||
use std::fs::File;
|
||||
use std::io::{self, Read};
|
||||
use std::path::Path;
|
||||
use std::str::FromStr;
|
||||
use target_lexicon::Triple;
|
||||
|
||||
/// Read an entire file into a string.
|
||||
pub fn read_to_string<P: AsRef<Path>>(path: P) -> io::Result<String> {
|
||||
@@ -40,8 +42,11 @@ impl OwnedFlagsOrIsa {
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse "set" and "isa" commands.
|
||||
pub fn parse_sets_and_isa(flag_set: &[String], flag_isa: &str) -> Result<OwnedFlagsOrIsa, String> {
|
||||
/// Parse "set" and "triple" commands.
|
||||
pub fn parse_sets_and_triple(
|
||||
flag_set: &[String],
|
||||
flag_triple: &str,
|
||||
) -> Result<OwnedFlagsOrIsa, String> {
|
||||
let mut flag_builder = settings::builder();
|
||||
parse_options(
|
||||
flag_set.iter().map(|x| x.as_str()),
|
||||
@@ -49,12 +54,21 @@ pub fn parse_sets_and_isa(flag_set: &[String], flag_isa: &str) -> Result<OwnedFl
|
||||
&Location { line_number: 0 },
|
||||
).map_err(|err| err.to_string())?;
|
||||
|
||||
let mut words = flag_isa.trim().split_whitespace();
|
||||
// Look for `isa foo`.
|
||||
if let Some(isa_name) = words.next() {
|
||||
let mut 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 mut words = flag_triple.trim().split_whitespace();
|
||||
// Look for `target foo`.
|
||||
if let Some(triple_name) = words.next() {
|
||||
let triple = match Triple::from_str(triple_name) {
|
||||
Ok(triple) => triple,
|
||||
Err(parse_error) => return Err(format!("{}", parse_error)),
|
||||
};
|
||||
let mut isa_builder = isa::lookup(triple).map_err(|err| match err {
|
||||
isa::LookupError::SupportDisabled => {
|
||||
format!("support for triple '{}' is disabled", triple_name)
|
||||
}
|
||||
isa::LookupError::Unsupported => format!(
|
||||
"support for triple '{}' is not implemented yet",
|
||||
triple_name
|
||||
),
|
||||
})?;
|
||||
// Apply the ISA-specific settings to `isa_builder`.
|
||||
parse_options(words, &mut isa_builder, &Location { line_number: 0 })
|
||||
|
||||
@@ -12,7 +12,7 @@ use std::error::Error;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use term;
|
||||
use utils::{parse_sets_and_isa, read_to_end};
|
||||
use utils::{parse_sets_and_triple, read_to_end};
|
||||
use wabt::wat2wasm;
|
||||
|
||||
macro_rules! vprintln {
|
||||
@@ -38,10 +38,10 @@ pub fn run(
|
||||
flag_check_translation: bool,
|
||||
flag_print: bool,
|
||||
flag_set: &[String],
|
||||
flag_isa: &str,
|
||||
flag_triple: &str,
|
||||
flag_print_size: bool,
|
||||
) -> Result<(), String> {
|
||||
let parsed = parse_sets_and_isa(flag_set, flag_isa)?;
|
||||
let parsed = parse_sets_and_triple(flag_set, flag_triple)?;
|
||||
|
||||
for filename in files {
|
||||
let path = Path::new(&filename);
|
||||
@@ -79,9 +79,7 @@ fn handle_module(
|
||||
vprint!(flag_verbose, "Translating... ");
|
||||
terminal.reset().unwrap();
|
||||
|
||||
let mut data = read_to_end(path.clone()).map_err(|err| {
|
||||
String::from(err.description())
|
||||
})?;
|
||||
let mut data = read_to_end(path.clone()).map_err(|err| String::from(err.description()))?;
|
||||
|
||||
if !data.starts_with(&[b'\0', b'a', b's', b'm']) {
|
||||
data = match wat2wasm(&data) {
|
||||
@@ -90,10 +88,9 @@ fn handle_module(
|
||||
};
|
||||
}
|
||||
|
||||
let mut dummy_environ = DummyEnvironment::with_flags(fisa.flags.clone());
|
||||
translate_module(&data, &mut dummy_environ).map_err(
|
||||
|e| e.to_string(),
|
||||
)?;
|
||||
let mut dummy_environ =
|
||||
DummyEnvironment::with_triple_flags(fisa.isa.unwrap().triple().clone(), fisa.flags.clone());
|
||||
translate_module(&data, &mut dummy_environ).map_err(|e| e.to_string())?;
|
||||
|
||||
terminal.fg(term::color::GREEN).unwrap();
|
||||
vprintln!(flag_verbose, "ok");
|
||||
@@ -142,24 +139,22 @@ fn handle_module(
|
||||
let mut context = Context::new();
|
||||
context.func = func.clone();
|
||||
if flag_check_translation {
|
||||
context.verify(fisa).map_err(|err| {
|
||||
pretty_verifier_error(&context.func, fisa.isa, &err)
|
||||
})?;
|
||||
context
|
||||
.verify(fisa)
|
||||
.map_err(|err| pretty_verifier_error(&context.func, fisa.isa, &err))?;
|
||||
} else if let Some(isa) = fisa.isa {
|
||||
let compiled_size = context.compile(isa).map_err(|err| {
|
||||
pretty_error(&context.func, fisa.isa, err)
|
||||
})?;
|
||||
let compiled_size = context
|
||||
.compile(isa)
|
||||
.map_err(|err| pretty_error(&context.func, fisa.isa, err))?;
|
||||
if flag_print_size {
|
||||
println!(
|
||||
"Function #{} code size: {} bytes",
|
||||
func_index,
|
||||
compiled_size
|
||||
func_index, compiled_size
|
||||
);
|
||||
total_module_code_size += compiled_size;
|
||||
println!(
|
||||
"Function #{} bytecode size: {} bytes",
|
||||
func_index,
|
||||
dummy_environ.func_bytecode_sizes[def_index]
|
||||
func_index, dummy_environ.func_bytecode_sizes[def_index]
|
||||
);
|
||||
}
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user