diff --git a/Cargo.lock b/Cargo.lock index 8d7d237b6e..63fdb07c47 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -433,6 +433,7 @@ dependencies = [ "memmap", "num_cpus", "region", + "target-lexicon", ] [[package]] diff --git a/cranelift/filetests/Cargo.toml b/cranelift/filetests/Cargo.toml index 35b46b87c8..3bf3090507 100644 --- a/cranelift/filetests/Cargo.toml +++ b/cranelift/filetests/Cargo.toml @@ -22,3 +22,4 @@ memmap = "0.7.0" num_cpus = "1.8.0" region = "2.1.2" byteorder = { version = "1.3.2", default-features = false } +target-lexicon = "0.10" diff --git a/cranelift/filetests/src/lib.rs b/cranelift/filetests/src/lib.rs index 0d3b12e458..0fee249f12 100644 --- a/cranelift/filetests/src/lib.rs +++ b/cranelift/filetests/src/lib.rs @@ -56,6 +56,7 @@ mod test_shrink; mod test_simple_gvn; mod test_simple_preopt; mod test_unwind; +mod test_vcode; mod test_verifier; /// The result of running the test in a file. @@ -134,6 +135,7 @@ fn new_subtest(parsed: &TestCommand) -> subtest::SubtestResult test_run::subtest(parsed), "shrink" => test_shrink::subtest(parsed), "simple-gvn" => test_simple_gvn::subtest(parsed), + "vcode" => test_vcode::subtest(parsed), "verifier" => test_verifier::subtest(parsed), "preopt" => test_preopt::subtest(parsed), "safepoint" => test_safepoint::subtest(parsed), diff --git a/cranelift/filetests/src/test_vcode.rs b/cranelift/filetests/src/test_vcode.rs new file mode 100644 index 0000000000..f97aef47ea --- /dev/null +++ b/cranelift/filetests/src/test_vcode.rs @@ -0,0 +1,71 @@ +use crate::subtest::{run_filecheck, Context, SubTest, SubtestResult}; +use cranelift_codegen::ir::Function; +use cranelift_codegen::isa::lookup; +use cranelift_codegen::settings; +use cranelift_codegen::Context as CodegenContext; +use cranelift_reader::{TestCommand, TestOption}; +use target_lexicon::Triple; + +use log::info; +use std::borrow::Cow; +use std::str::FromStr; +use std::string::String; + +struct TestVCode { + arch: String, +} + +pub fn subtest(parsed: &TestCommand) -> SubtestResult> { + assert_eq!(parsed.command, "vcode"); + + let mut arch = "arm64".to_string(); + for option in &parsed.options { + match option { + TestOption::Value(k, v) if k == &"arch" => { + arch = v.to_string(); + } + _ => {} + } + } + + Ok(Box::new(TestVCode { arch })) +} + +impl SubTest for TestVCode { + fn name(&self) -> &'static str { + "vcode" + } + + fn is_mutating(&self) -> bool { + true + } + + fn needs_isa(&self) -> bool { + false + } + + fn run(&self, func: Cow, context: &Context) -> SubtestResult<()> { + let func = func.into_owned(); + + let triple = + Triple::from_str(&self.arch).map_err(|_| format!("Unknown arch: '{}'", self.arch))?; + + let mut isa = lookup(triple) + .map_err(|_| format!("Could not look up backend for arch '{}'", self.arch))? + .finish(settings::Flags::new(settings::builder())); + + let mut codectx = CodegenContext::for_function(func); + codectx.set_disasm(true); + + codectx + .compile(&mut *isa) + .map_err(|e| format!("Could not compile with arch '{}': {:?}", self.arch, e))?; + + let result = codectx.mach_compile_result.take().unwrap(); + let text = result.disasm.unwrap(); + + info!("text input to filecheck is:\n{}\n", text); + + run_filecheck(&text, context) + } +}