Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cranelift/filetests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@ serde = { workspace = true }
serde_derive = { workspace = true }
cranelift.workspace = true
smallvec = { workspace = true }
pulley-interpreter = { workspace = true, features = ["disas", "std"] }
pulley-interpreter = { workspace = true, features = ["disas", "std", "interp"] }
4 changes: 4 additions & 0 deletions cranelift/filetests/filetests/runtests/br.clif
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ target s390x
target x86_64
target riscv64
target riscv64 has_c has_zcb
target pulley32
target pulley32be
target pulley64
target pulley64be

function %jump() -> i8 {
block0:
Expand Down
4 changes: 4 additions & 0 deletions cranelift/filetests/filetests/runtests/brif.clif
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ target s390x
target x86_64
target riscv64
target riscv64 has_c has_zcb
target pulley32
target pulley32be
target pulley64
target pulley64be

function %brif_value(i8) -> i64 {
block0(v0: i8):
Expand Down
42 changes: 39 additions & 3 deletions cranelift/filetests/src/function_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@ use cranelift_jit::{JITBuilder, JITModule};
use cranelift_module::{FuncId, Linkage, Module, ModuleError};
use cranelift_native::builder_with_options;
use cranelift_reader::TestFile;
use pulley_interpreter::interp as pulley;
use std::cmp::max;
use std::collections::hash_map::Entry;
use std::collections::HashMap;
use std::ptr::NonNull;
use target_lexicon::Architecture;
use thiserror::Error;

const TESTFILE_NAMESPACE: u32 = 0;
Expand Down Expand Up @@ -370,12 +373,45 @@ impl<'a> Trampoline<'a> {
let function_ptr = self.module.get_finalized_function(self.func_id);
let trampoline_ptr = self.module.get_finalized_function(self.trampoline_id);

let callable_trampoline: fn(*const u8, *mut u128) -> () =
unsafe { mem::transmute(trampoline_ptr) };
callable_trampoline(function_ptr, arguments_address);
unsafe {
self.call_raw(trampoline_ptr, function_ptr, arguments_address);
}

values.collect_returns(&self.func_signature)
}

unsafe fn call_raw(
&self,
trampoline_ptr: *const u8,
function_ptr: *const u8,
arguments_address: *mut u128,
) {
match self.module.isa().triple().architecture {
// For the pulley target this is pulley bytecode, not machine code,
// so run the interpreter.
Architecture::Pulley32
| Architecture::Pulley64
| Architecture::Pulley32be
| Architecture::Pulley64be => {
let mut state = pulley::Vm::new();
state.call(
NonNull::new(trampoline_ptr.cast_mut()).unwrap(),
&[
pulley::XRegVal::new_ptr(function_ptr.cast_mut()).into(),
pulley::XRegVal::new_ptr(arguments_address).into(),
],
[],
);
}

// Other targets natively execute this machine code.
_ => {
let callable_trampoline: fn(*const u8, *mut u128) -> () =
unsafe { mem::transmute(trampoline_ptr) };
callable_trampoline(function_ptr, arguments_address);
}
}
}
}

/// Compilation Error when compiling a function.
Expand Down
44 changes: 39 additions & 5 deletions cranelift/filetests/src/test_run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,23 @@ fn is_isa_compatible(
let requested_arch = requested.triple().architecture;

match (host_arch, requested_arch) {
// If the host matches the requested target, then that's all good.
(host, requested) if host == requested => {}

// Allow minor differences in risc-v targets.
(Architecture::Riscv64(_), Architecture::Riscv64(_)) => {}

// Any host can run pulley so long as the pointer width and endianness
// match.
(
_,
Architecture::Pulley32
| Architecture::Pulley64
| Architecture::Pulley32be
| Architecture::Pulley64be,
) if host.triple().pointer_width() == requested.triple().pointer_width()
&& host.triple().endianness() == requested.triple().endianness() => {}

_ => {
return Err(format!(
"skipped {file_path}: host can't run {requested_arch:?} programs"
Expand All @@ -72,6 +87,10 @@ fn is_isa_compatible(
// we can't natively support on the host.
let requested_flags = requested.isa_flags();
for req_value in requested_flags {
// pointer_width for pulley already validated above
if req_value.name == "pointer_width" {
continue;
}
let requested = match req_value.as_bool() {
Some(requested) => requested,
None => unimplemented!("ISA flag {} of kind {:?}", req_value.name, req_value.kind()),
Expand Down Expand Up @@ -116,11 +135,26 @@ fn compile_testfile(
flags: &Flags,
isa: &dyn TargetIsa,
) -> anyhow::Result<CompiledTestFile> {
// We can't use the requested ISA directly since it does not contain info
// about the operating system / calling convention / etc..
//
// Copy the requested ISA flags into the host ISA and use that.
let isa = build_host_isa(false, flags.clone(), isa.isa_flags());
let isa = match isa.triple().architecture {
// Convert `&dyn TargetIsa` to `OwnedTargetIsa` by re-making the ISA and
// applying pulley flags/etc.
Architecture::Pulley32
| Architecture::Pulley64
| Architecture::Pulley32be
| Architecture::Pulley64be => {
let mut builder = cranelift_codegen::isa::lookup(isa.triple().clone())?;
for value in isa.isa_flags() {
builder.set(value.name, &value.value_string()).unwrap();
}
builder.finish(flags.clone())?
}

// We can't use the requested ISA directly since it does not contain info
// about the operating system / calling convention / etc..
//
// Copy the requested ISA flags into the host ISA and use that.
_ => build_host_isa(false, flags.clone(), isa.isa_flags()),
};

let mut tfc = TestFileCompiler::new(isa);
tfc.add_testfile(testfile)?;
Expand Down