This commit is contained in:
T0b1
2023-04-18 12:21:54 +02:00
commit 0bb8f5c3be
14 changed files with 4993 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/target

7
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,7 @@
{
"editor.formatOnSave": true,
"[rust]": {
"editor.defaultFormatter": "rust-lang.rust-analyzer"
},
"rust-analyzer.cargo.allFeatures": true
}

1579
1 Normal file

File diff suppressed because it is too large Load Diff

550
Cargo.lock generated Normal file
View File

@@ -0,0 +1,550 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "ahash"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f"
dependencies = [
"cfg-if",
"once_cell",
"version_check",
]
[[package]]
name = "aho-corasick"
version = "0.7.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
dependencies = [
"memchr",
]
[[package]]
name = "anyhow"
version = "1.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6"
[[package]]
name = "arbitrary"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2d098ff73c1ca148721f37baad5ea6a465a13f9573aba8641fbbbae8164a54e"
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
]
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bumpalo"
version = "3.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cranelift"
version = "0.96.0"
dependencies = [
"cranelift-codegen",
"cranelift-frontend",
]
[[package]]
name = "cranelift-bforest"
version = "0.96.0"
dependencies = [
"cranelift-entity",
]
[[package]]
name = "cranelift-codegen"
version = "0.96.0"
dependencies = [
"bumpalo",
"cranelift-bforest",
"cranelift-codegen-meta",
"cranelift-codegen-shared",
"cranelift-control",
"cranelift-entity",
"cranelift-isle",
"gimli",
"hashbrown 0.13.2",
"log",
"regalloc2",
"smallvec",
"target-lexicon",
]
[[package]]
name = "cranelift-codegen-meta"
version = "0.96.0"
dependencies = [
"cranelift-codegen-shared",
]
[[package]]
name = "cranelift-codegen-shared"
version = "0.96.0"
[[package]]
name = "cranelift-control"
version = "0.96.0"
dependencies = [
"arbitrary",
]
[[package]]
name = "cranelift-entity"
version = "0.96.0"
[[package]]
name = "cranelift-frontend"
version = "0.96.0"
dependencies = [
"cranelift-codegen",
"log",
"smallvec",
"target-lexicon",
]
[[package]]
name = "cranelift-isle"
version = "0.96.0"
[[package]]
name = "cranelift-jit"
version = "0.96.0"
dependencies = [
"anyhow",
"cranelift-codegen",
"cranelift-control",
"cranelift-entity",
"cranelift-module",
"cranelift-native",
"libc",
"log",
"memmap2",
"region",
"target-lexicon",
"wasmtime-jit-icache-coherence",
"windows-sys",
]
[[package]]
name = "cranelift-module"
version = "0.96.0"
dependencies = [
"anyhow",
"cranelift-codegen",
"cranelift-control",
]
[[package]]
name = "cranelift-native"
version = "0.96.0"
dependencies = [
"cranelift-codegen",
"libc",
"target-lexicon",
]
[[package]]
name = "cranelift-reader"
version = "0.96.0"
dependencies = [
"anyhow",
"cranelift-codegen",
"smallvec",
"target-lexicon",
]
[[package]]
name = "cranelift_test"
version = "0.1.0"
dependencies = [
"cranelift",
"cranelift-frontend",
"cranelift-jit",
"cranelift-module",
"cranelift-native",
"cranelift-reader",
"iced-x86",
"pretty_env_logger",
"regalloc2",
"target-lexicon",
]
[[package]]
name = "env_logger"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
dependencies = [
"atty",
"humantime",
"log",
"regex",
"termcolor",
]
[[package]]
name = "fallible-iterator"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
[[package]]
name = "gimli"
version = "0.27.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4"
dependencies = [
"fallible-iterator",
"indexmap",
"stable_deref_trait",
]
[[package]]
name = "hashbrown"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]]
name = "hashbrown"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e"
dependencies = [
"ahash",
]
[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
[[package]]
name = "humantime"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
dependencies = [
"quick-error",
]
[[package]]
name = "iced-x86"
version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "158f5204401d08f91d19176112146d75e99b3cf745092e268fa7be33e09adcec"
dependencies = [
"lazy_static",
"static_assertions",
]
[[package]]
name = "indexmap"
version = "1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
dependencies = [
"autocfg",
"hashbrown 0.12.3",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.135"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68783febc7782c6c5cb401fbda4de5a9898be1762314da0bb2c10ced61f18b0c"
[[package]]
name = "log"
version = "0.4.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
dependencies = [
"cfg-if",
]
[[package]]
name = "mach"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa"
dependencies = [
"libc",
]
[[package]]
name = "memchr"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "memmap2"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "723e3ebdcdc5c023db1df315364573789f8857c11b631a2fdfad7c00f5c046b4"
dependencies = [
"libc",
]
[[package]]
name = "once_cell"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
[[package]]
name = "pretty_env_logger"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "926d36b9553851b8b0005f1275891b392ee4d2d833852c417ed025477350fb9d"
dependencies = [
"env_logger",
"log",
]
[[package]]
name = "quick-error"
version = "1.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
[[package]]
name = "regalloc2"
version = "0.6.1"
dependencies = [
"hashbrown 0.13.2",
"log",
"rustc-hash",
"slice-group-by",
"smallvec",
]
[[package]]
name = "regex"
version = "1.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
[[package]]
name = "region"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877e54ea2adcd70d80e9179344c97f93ef0dffd6b03e1f4529e6e83ab2fa9ae0"
dependencies = [
"bitflags",
"libc",
"mach",
"winapi",
]
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "slice-group-by"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03b634d87b960ab1a38c4fe143b508576f075e7c978bfad18217645ebfdfa2ec"
[[package]]
name = "smallvec"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
[[package]]
name = "stable_deref_trait"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "target-lexicon"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c02424087780c9b71cc96799eaeddff35af2bc513278cda5c99fc1f5d026d3c1"
[[package]]
name = "termcolor"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
dependencies = [
"winapi-util",
]
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "wasmtime-jit-icache-coherence"
version = "9.0.0"
dependencies = [
"cfg-if",
"libc",
"windows-sys",
]
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
dependencies = [
"winapi",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
version = "0.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
[[package]]
name = "windows_aarch64_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
[[package]]
name = "windows_i686_gnu"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
[[package]]
name = "windows_i686_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
[[package]]
name = "windows_x86_64_gnu"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
[[package]]
name = "windows_x86_64_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"

19
Cargo.toml Normal file
View File

@@ -0,0 +1,19 @@
[package]
name = "cranelift_test"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
cranelift = { path = "../wasmtime/cranelift/umbrella" }
cranelift-module = { path = "../wasmtime/cranelift/module" }
cranelift-jit = { path = "../wasmtime/cranelift/jit", features = ["selinux-fix"] }
cranelift-frontend = { path = "../wasmtime/cranelift/frontend" }
target-lexicon = "0.12.4"
cranelift-native = { path = "../wasmtime/cranelift/native" }
cranelift-reader = { path = "../wasmtime/cranelift/reader" }
regalloc2 = { path = "../regalloc2", features = ["trace-log"] }
pretty_env_logger = "0.4.0"
iced-x86 = "1.17.0"

652
src/main.rs Normal file
View File

@@ -0,0 +1,652 @@
use cranelift::codegen::ir::{function, BlockCall, FuncRef, InstructionData, Opcode, ValueList};
use cranelift::codegen::isa;
use cranelift::codegen::settings::{self, Configurable};
use cranelift::prelude::*;
use cranelift_frontend::FunctionBuilderContext;
use cranelift_jit::{JITBuilder, JITModule};
use cranelift_module::{DataDescription, FuncId, Linkage, Module};
extern "C" fn extern_fn(test: u64) -> i64 {
test as i64 - 40
}
fn main() {
pretty_env_logger::init();
let mut shared_builder = settings::builder();
for setting in shared_builder.iter() {
println!("{:?}", setting);
}
shared_builder
.set("use_colocated_libcalls", "false")
.unwrap();
shared_builder.set("is_pic", "true").unwrap();
shared_builder
.set("preserve_frame_pointers", "true")
.unwrap();
shared_builder.set("opt_level", "speed").unwrap();
shared_builder.set("enable_verifier", "true").unwrap();
shared_builder
.set("enable_llvm_abi_extensions", "true")
.unwrap();
let shared_flags = settings::Flags::new(shared_builder);
println!("ISA:");
let isa = {
let isa_builder = cranelift_native::builder_with_options(false).unwrap_or_else(|msg| {
panic!("host machine is not supported: {}", msg);
});
for setting in isa_builder.iter() {
println!("{:?}", setting);
}
isa_builder.finish(shared_flags).unwrap()
};
let mut builder = JITBuilder::with_isa(isa, cranelift_module::default_libcall_names());
builder.symbol("extern_fn", (extern_fn as *const ()) as *const u8);
let mut module = JITModule::new(builder);
let txt = std::fs::read_to_string(std::env::args().nth(1).unwrap()).unwrap();
let fns = cranelift_reader::parse_functions(&txt).unwrap();
println!("Len: {}", fns.len());
println!("Function:\n{}", fns[0].display());
let mut ctx = module.make_context();
for func_idx in 0..fns.len() {
ctx.set_disasm(true);
println!("Compiling Func {} ('{}')", func_idx, fns[func_idx].name);
ctx.func = fns[func_idx].clone();
let func = module
.declare_function(
&format!("test_func{}", func_idx),
Linkage::Export,
&ctx.func.signature,
)
.unwrap();
module.define_function(func, &mut ctx).unwrap();
println!(
"Disasm:\n{}",
ctx.compiled_code().unwrap().vcode.as_ref().unwrap()
);
if true {
println!("Asm2:");
use iced_x86::Formatter;
let bytes = ctx.compiled_code().unwrap().code_buffer();
let mut decoder = iced_x86::Decoder::new(64, bytes, iced_x86::DecoderOptions::NONE);
// Formatters: Masm*, Nasm*, Gas* (AT&T) and Intel* (XED).
// For fastest code, see `SpecializedFormatter` which is ~3.3x faster. Use it if formatting
// speed is more important than being able to re-assemble formatted instructions.
let mut formatter = iced_x86::NasmFormatter::new();
// Change some options, there are many more
formatter.options_mut().set_digit_separator("`");
formatter.options_mut().set_first_operand_char_index(10);
// String implements FormatterOutput
let mut output = String::new();
// Initialize this outside the loop because decode_out() writes to every field
let mut instruction = iced_x86::Instruction::default();
// The decoder also implements Iterator/IntoIterator so you could use a for loop:
// for instruction in &mut decoder { /* ... */ }
// or collect():
// let instructions: Vec<_> = decoder.into_iter().collect();
// but can_decode()/decode_out() is a little faster:
while decoder.can_decode() {
// There's also a decode() method that returns an instruction but that also
// means it copies an instruction (40 bytes):
// instruction = decoder.decode();
decoder.decode_out(&mut instruction);
// Format the instruction ("disassemble" it)
output.clear();
formatter.format(&instruction, &mut output);
// Eg. "00007FFAC46ACDB2 488DAC2400FFFFFF lea rbp,[rsp-100h]"
print!("{:08X} ", instruction.ip());
let start_index = instruction.ip() as usize;
let instr_bytes = &bytes[start_index..start_index + instruction.len()];
for b in instr_bytes.iter() {
print!("{:02X}", b);
}
if instr_bytes.len() < 10 {
for _ in 0..10 - instr_bytes.len() {
print!(" ");
}
}
println!(" {}", output);
}
}
module.clear_context(&mut ctx);
}
}
/*fn main() {
let mut shared_builder = settings::builder();
for setting in shared_builder.iter() {
println!("{:?}", setting);
}
shared_builder
.set("use_colocated_libcalls", "false")
.unwrap();
shared_builder.set("is_pic", "true").unwrap();
shared_builder
.set("preserve_frame_pointers", "true")
.unwrap();
shared_builder.set("opt_level", "speed").unwrap();
shared_builder.set("enable_verifier", "true").unwrap();
shared_builder
.set("enable_llvm_abi_extensions", "true")
.unwrap();
let shared_flags = settings::Flags::new(shared_builder);
println!("ISA:");
let isa = {
let isa_builder = cranelift_native::builder().unwrap_or_else(|msg| {
panic!("host machine is not supported: {}", msg);
});
for setting in isa_builder.iter() {
println!("{:?}", setting);
}
isa_builder.finish(shared_flags).unwrap()
};
let mut builder = JITBuilder::with_isa(isa, cranelift_module::default_libcall_names());
builder.symbol("extern_fn", (extern_fn as *const ()) as *const u8);
let mut module = JITModule::new(builder);
let mut extern_sig = Signature::new(isa::CallConv::SystemV);
extern_sig.params.push(AbiParam::new(types::I64));
extern_sig.returns.push(AbiParam::new(types::I64));
//extern_sig.params.push(AbiParam::new(types::I64));
//extern_sig.params.push(AbiParam::new(types::I64));
//extern_sig.params.push(AbiParam::new(types::I64));
//extern_sig.params.push(AbiParam::new(types::I64));
//extern_sig.params.push(AbiParam::new(types::I128));
let extern_id = module
.declare_function("extern_fn", Linkage::Import, &extern_sig)
.unwrap();
let mut ctx = module.make_context();
let mut data_ctx = DataDescription::new();
ctx.set_disasm(true);
let fn_ref = module.declare_func_in_func(extern_id, &mut ctx.func);
ctx.func.signature.params.push(AbiParam::new(types::I64));
ctx.func.signature.params.push(AbiParam::new(types::I64));
ctx.func.signature.returns.push(AbiParam::new(types::I64));
//ctx.func.signature.returns.push(AbiParam::new(types::B1));
test1(&mut ctx, fn_ref);
// test2(&mut ctx);
//test3(&mut ctx, fn_ref);
//ctx.cfg.compute(&ctx.func);
//ctx.domtree.compute(&ctx.func, &ctx.cfg);
/*let mut builder_ctx = FunctionBuilderContext::new();
let mut func_builder = FunctionBuilder::new(&mut ctx.func, &mut builder_ctx);
let entry_block = func_builder.create_block();
let block1 = func_builder.create_block();
let block2 = func_builder.create_block();
func_builder.append_block_params_for_function_params(entry_block);
func_builder.switch_to_block(entry_block);
func_builder.seal_block(entry_block);
let param0 = func_builder.block_params(entry_block)[0];
let param1 = func_builder.block_params(entry_block)[1];
func_builder.ins().brnz(param1, block1, &[param0]);
func_builder.ins().jump(block2, &[param0]);
func_builder.seal_block(block1);
func_builder.seal_block(block2);
func_builder.switch_to_block(block1);
func_builder.append_block_param(block1, types::I64);
let const50 = func_builder.ins().iconst(types::I64, 50);
let call = func_builder.ins().call(fn_ref, &[const50]);
let call_res = func_builder.inst_results(call)[0];
let param0 = func_builder.block_params(block1)[0];
let add_val = func_builder.ins().iadd(param0, call_res);
func_builder.ins().return_(&[add_val]);
func_builder.switch_to_block(block2);
func_builder.append_block_param(block2, types::I64);
let param0 = func_builder.block_params(block2)[0];
let test_val = func_builder.ins().iconst(types::I64, 10);
let test_val2 = func_builder.ins().iconst(types::I64, -20);
let test2_val = func_builder.ins().iadd(test_val, test_val2);
let sub_val = func_builder.ins().iadd(param0, test2_val);
func_builder.ins().return_(&[sub_val]);
func_builder.finalize();*/
/*ctx.verify(module.isa()).unwrap();
let mut errors = cranelift::codegen::verifier::VerifierErrors::default();
cranelift::codegen::verifier::verify_context(
&ctx.func,
&ctx.cfg,
&ctx.domtree,
module.isa(),
&mut errors,
)
.unwrap();*/
// TODO: umbra should not need this since it does constant folding by itself
//cranelift_preopt::optimize(&mut ctx, module.isa()).unwrap();
//ctx.dce(module.isa()).unwrap();
//ctx.verify(module.isa()).unwrap();
println!("Function: {}", ctx.func.display());
let func = module
.declare_function("test_func", Linkage::Export, &ctx.func.signature)
.unwrap();
module.define_function(func, &mut ctx).unwrap();
println!(
"Disasm:\n{}",
ctx.compiled_code().unwrap().vcode.as_ref().unwrap()
);
if true {
println!("Asm2:");
use iced_x86::Formatter;
let bytes = ctx.compiled_code().unwrap().code_buffer();
let mut decoder = iced_x86::Decoder::new(64, bytes, iced_x86::DecoderOptions::NONE);
// Formatters: Masm*, Nasm*, Gas* (AT&T) and Intel* (XED).
// For fastest code, see `SpecializedFormatter` which is ~3.3x faster. Use it if formatting
// speed is more important than being able to re-assemble formatted instructions.
let mut formatter = iced_x86::NasmFormatter::new();
// Change some options, there are many more
formatter.options_mut().set_digit_separator("`");
formatter.options_mut().set_first_operand_char_index(10);
// String implements FormatterOutput
let mut output = String::new();
// Initialize this outside the loop because decode_out() writes to every field
let mut instruction = iced_x86::Instruction::default();
// The decoder also implements Iterator/IntoIterator so you could use a for loop:
// for instruction in &mut decoder { /* ... */ }
// or collect():
// let instructions: Vec<_> = decoder.into_iter().collect();
// but can_decode()/decode_out() is a little faster:
while decoder.can_decode() {
// There's also a decode() method that returns an instruction but that also
// means it copies an instruction (40 bytes):
// instruction = decoder.decode();
decoder.decode_out(&mut instruction);
// Format the instruction ("disassemble" it)
output.clear();
formatter.format(&instruction, &mut output);
// Eg. "00007FFAC46ACDB2 488DAC2400FFFFFF lea rbp,[rsp-100h]"
print!("{:08X} ", instruction.ip());
let start_index = instruction.ip() as usize;
let instr_bytes = &bytes[start_index..start_index + instruction.len()];
for b in instr_bytes.iter() {
print!("{:02X}", b);
}
if instr_bytes.len() < 10 {
for _ in 0..10 - instr_bytes.len() {
print!(" ");
}
}
println!(" {}", output);
}
}
module.clear_context(&mut ctx);
module.finalize_definitions();
println!("Timing Info: {}", codegen::timing::take_current());
let code = module.get_finalized_function(func) as *const ();
// run_test1(code);
//run_test2(code);
}
fn test1(ctx: &mut codegen::Context, fn_ref: FuncRef) {
let entry_block = {
let b = ctx.func.dfg.make_block();
ctx.func.layout.append_block(b);
ctx.func.dfg.append_block_param(b, types::I64);
ctx.func.dfg.append_block_param(b, types::I64);
b
};
let block1 = {
let b = ctx.func.dfg.make_block();
ctx.func.layout.append_block(b);
ctx.func.dfg.append_block_param(b, types::I64);
b
};
let block2 = {
let b = ctx.func.dfg.make_block();
ctx.func.layout.append_block(b);
ctx.func.dfg.append_block_param(b, types::I64);
b
};
let mut tmp_val = Value::from_u32(0);
// create entry block
{
let param0 = ctx.func.dfg.block_params(entry_block)[0];
let param1 = ctx.func.dfg.block_params(entry_block)[1];
let const50 = {
// TODO: when taking immediates that are smaller than 64bit we need to call InstructionData::sign_extend_immediates to get them sign_extended to 64bit
let inst = ctx.func.dfg.make_inst(InstructionData::UnaryImm {
opcode: Opcode::Iconst,
imm: 50.into(),
});
ctx.func.dfg.make_inst_results(inst, types::I64);
ctx.func.layout.append_inst(inst, entry_block);
ctx.func.dfg.first_result(inst)
};
tmp_val = const50;
let block1_call = ctx.func.dfg.block_call(block1, &[param0]);
let block2_call = ctx.func.dfg.block_call(block2, &[param0]);
let inst = ctx.func.dfg.make_inst(InstructionData::Brif {
opcode: Opcode::Brif,
arg: param1,
blocks: [block1_call, block2_call],
});
ctx.func.layout.append_inst(inst, entry_block);
}
// block1
{
let param0 = ctx.func.dfg.block_params(block1)[0];
let const50 = {
// TODO: when taking immediates that are smaller than 64bit we need to call InstructionData::sign_extend_immediates to get them sign_extended to 64bit
let inst = ctx.func.dfg.make_inst(InstructionData::UnaryImm {
opcode: Opcode::Iconst,
imm: 50.into(),
});
ctx.func.dfg.make_inst_results(inst, types::I64);
ctx.func.layout.append_inst(inst, block1);
ctx.func.dfg.first_result(inst)
};
let call_res = {
let mut vlist = ValueList::default();
{
let pool = &mut ctx.func.dfg.value_lists;
vlist.push(const50, pool);
}
let inst = ctx.func.dfg.make_inst(InstructionData::Call {
opcode: Opcode::Call,
args: vlist,
func_ref: fn_ref,
});
ctx.func.dfg.make_inst_results(inst, types::I64);
ctx.func.layout.append_inst(inst, block1);
ctx.func.dfg.first_result(inst)
};
let add_val = {
let inst = ctx.func.dfg.make_inst(InstructionData::Binary {
opcode: Opcode::Iadd,
args: [param0, call_res],
});
ctx.func.dfg.make_inst_results(inst, types::I64);
ctx.func.layout.append_inst(inst, block1);
ctx.func.dfg.first_result(inst)
};
{
let mut vlist = ValueList::default();
{
let pool = &mut ctx.func.dfg.value_lists;
vlist.push(add_val, pool);
}
let inst = ctx.func.dfg.make_inst(InstructionData::MultiAry {
opcode: Opcode::Return,
args: vlist,
});
ctx.func.layout.append_inst(inst, block1);
}
}
// block2
{
/*
let test_val = func_builder.ins().iconst(types::I64, 10);
let test_val2 = func_builder.ins().iconst(types::I64, -20);
let test2_val = func_builder.ins().iadd(test_val, test_val2);
let sub_val = func_builder.ins().iadd(param0, test2_val);
func_builder.ins().return_(&[sub_val]); */
let param0 = ctx.func.dfg.block_params(block2)[0];
let test_val = {
let inst = ctx.func.dfg.make_inst(InstructionData::UnaryImm {
opcode: Opcode::Iconst,
imm: 10.into(),
});
ctx.func.dfg.make_inst_results(inst, types::I64);
ctx.func.layout.append_inst(inst, block2);
ctx.func.dfg.first_result(inst)
};
let test_val2 = {
let inst = ctx.func.dfg.make_inst(InstructionData::UnaryImm {
opcode: Opcode::Iconst,
imm: (-20 as i64).into(),
});
ctx.func.dfg.make_inst_results(inst, types::I64);
ctx.func.layout.append_inst(inst, block2);
ctx.func.dfg.first_result(inst)
};
/*let test2_val = {
let inst = ctx.func.dfg.make_inst(InstructionData::Binary {
opcode: Opcode::Iadd,
args: [test_val, test_val2],
});
ctx.func.dfg.make_inst_results(inst, types::I64);
ctx.func.layout.append_inst(inst, block2);
ctx.func.dfg.first_result(inst)
};*/
let test2_val = {
let inst = ctx.func.dfg.make_inst(InstructionData::BinaryImm64 {
opcode: Opcode::IaddImm,
arg: test_val,
imm: (-20 as i64).into(),
});
ctx.func.dfg.make_inst_results(inst, types::I64);
ctx.func.layout.append_inst(inst, block2);
ctx.func.dfg.first_result(inst)
};
//let test2_val = tmp_val;
let sub_val = {
let inst = ctx.func.dfg.make_inst(InstructionData::Binary {
opcode: Opcode::Iadd,
args: [param0, test2_val],
});
ctx.func.dfg.make_inst_results(inst, types::I64);
ctx.func.layout.append_inst(inst, block2);
ctx.func.dfg.first_result(inst)
};
{
let mut vlist = ValueList::default();
{
let pool = &mut ctx.func.dfg.value_lists;
vlist.push(sub_val, pool);
}
let inst = ctx.func.dfg.make_inst(InstructionData::MultiAry {
opcode: Opcode::Return,
args: vlist,
});
ctx.func.layout.append_inst(inst, block2);
}
}
}
fn run_test1(code: *const ()) {
let ptr: extern "C" fn(u64, u64) -> u64 = unsafe { std::mem::transmute(code) };
println!("Res1: {}", (ptr)(10, 0));
println!("Res2: {}", (ptr)(10, 1));
}*/
/*fn test2(ctx: &mut codegen::Context) {
let entry_block = {
let b = ctx.func.dfg.make_block();
ctx.func.layout.append_block(b);
ctx.func.dfg.append_block_param(b, types::I64);
ctx.func.dfg.append_block_param(b, types::I64);
b
};
let param0 = ctx.func.dfg.block_params(entry_block)[0];
let c = {
let inst = ctx.func.dfg.make_inst(InstructionData::UnaryImm {
opcode: Opcode::Iconst,
imm: 1.into(),
});
ctx.func.dfg.make_inst_results(inst, types::I64);
ctx.func.layout.append_inst(inst, entry_block);
ctx.func.dfg.first_result(inst)
};
let res = {
let inst = ctx.func.dfg.make_inst(InstructionData::Binary {
opcode: Opcode::Band,
args: [c, param0],
});
ctx.func.dfg.make_inst_results(inst, types::I64);
ctx.func.layout.append_inst(inst, entry_block);
ctx.func.dfg.first_result(inst)
};
/*let nc = {
let inst = ctx.func.dfg.make_inst(InstructionData::Unary {
opcode: Opcode::Bnot,
arg: c,
});
ctx.func.dfg.make_inst_results(inst, types::I64);
ctx.func.layout.append_inst(inst, entry_block);
ctx.func.dfg.first_result(inst)
};
let res = {
let inst = ctx.func.dfg.make_inst(InstructionData::Binary {
opcode: Opcode::Band,
args: [nc, param0],
});
ctx.func.dfg.make_inst_results(inst, types::I64);
ctx.func.layout.append_inst(inst, entry_block);
ctx.func.dfg.first_result(inst)
};*/
{
let mut vlist = ValueList::default();
{
let pool = &mut ctx.func.dfg.value_lists;
vlist.push(res, pool);
}
let inst = ctx.func.dfg.make_inst(InstructionData::MultiAry {
opcode: Opcode::Return,
args: vlist,
});
ctx.func.layout.append_inst(inst, entry_block);
}
}
fn run_test2(code: *const ()) {
let ptr: extern "C" fn(u64, u64) -> u64 = unsafe { std::mem::transmute(code) };
println!("Res1: {}", (ptr)(3, 1));
}
*/
/*fn test3(ctx: &mut codegen::Context, fn_ref: FuncRef) {
let ty_use = types::I32;
ctx.func.signature.params.push(AbiParam::new(ty_use).uext());
ctx.func.signature.params.push(AbiParam::new(ty_use));
ctx.func.signature.returns.push(AbiParam::new(ty_use));
let entry_block = {
let b = ctx.func.dfg.make_block();
ctx.func.layout.append_block(b);
ctx.func.dfg.append_block_param(b, ty_use);
ctx.func.dfg.append_block_param(b, ty_use);
b
};
let param0 = ctx.func.dfg.block_params(entry_block)[0];
let param1 = ctx.func.dfg.block_params(entry_block)[1];
/*let d128 = {
let inst = ctx.func.dfg.make_inst(InstructionData::UnaryImm {
opcode: Opcode::Iconst,
imm: 0.into(),
});
ctx.func.dfg.make_inst_results(inst, types::I64);
ctx.func.layout.append_inst(inst, entry_block);
let v = ctx.func.dfg.first_result(inst);
let inst = ctx.func.dfg.make_inst(InstructionData::Unary {
opcode: Opcode::Uextend,
arg: v,
});
ctx.func.dfg.make_inst_results(inst, types::I128);
ctx.func.layout.append_inst(inst, entry_block);
let v = ctx.func.dfg.first_result(inst);
v
};
{
let mut vlist = ValueList::default();
{
let pool = &mut ctx.func.dfg.value_lists;
vlist.push(param0, pool);
vlist.push(param0, pool);
vlist.push(param0, pool);
vlist.push(param0, pool);
vlist.push(param0, pool);
vlist.push(d128, pool);
}
let inst = ctx.func.dfg.make_inst(InstructionData::Call {
opcode: Opcode::Call,
args: vlist,
func_ref: fn_ref,
});
ctx.func.layout.append_inst(inst, entry_block);
};*/
let c = {
let inst = ctx.func.dfg.make_inst(InstructionData::UnaryImm {
opcode: Opcode::Iconst,
imm: 1.into(),
});
ctx.func.dfg.make_inst_results(inst, ty_use);
ctx.func.layout.append_inst(inst, entry_block);
ctx.func.dfg.first_result(inst)
};
let res = {
let inst = ctx.func.dfg.make_inst(InstructionData::Binary {
opcode: Opcode::Iadd,
args: [param0, c],
});
ctx.func.dfg.make_inst_results(inst, ty_use);
ctx.func.layout.append_inst(inst, entry_block);
ctx.func.dfg.first_result(inst)
};
{
let mut vlist = ValueList::default();
{
let pool = &mut ctx.func.dfg.value_lists;
vlist.push(res, pool);
}
let inst = ctx.func.dfg.make_inst(InstructionData::MultiAry {
opcode: Opcode::Return,
args: vlist,
});
ctx.func.layout.append_inst(inst, entry_block);
}
}*/

19
tests/alias.clif Normal file
View File

@@ -0,0 +1,19 @@
function %alias(i8) -> i8 {
block0(v0: i8):
v1 -> v0
return v1
}
function %double_alias(i8) -> i8 {
block0(v0: i8):
v1 -> v0
v2 -> v1
return v2
}
function %alias_inst() -> i8 {
block0:
v0 = iconst.i8 10
v1 -> v0
return v1
}

11
tests/bad_br.clif Normal file
View File

@@ -0,0 +1,11 @@
function u0:2(i32) -> i32 system_v {
block0(v0: i32):
v1 = iconst.i32 1
v2 = iconst.i32 2
v3 = iconst.i32 3
v4 = iconst.i32 4
br_table v0, block1(v4), [block1(v1), block1(v2), block1(v2), block1(v3)] ; v4 = 4, v1 = 1, v2 = 2, v2 = 2, v3 = 3
block1(v5: i32):
return v5
}

View File

@@ -0,0 +1,46 @@
function u0:4(i64 vmctx, i64, r64, i64) wasmtime_system_v {
gv0 = vmctx
gv1 = load.i64 notrap aligned readonly gv0+8
gv2 = load.i64 notrap aligned gv1
gv3 = vmctx
sig0 = (i64 vmctx, i64) wasmtime_system_v
sig1 = (i64 vmctx, i64, i32) -> i32 wasmtime_system_v
sig2 = (i64 vmctx, i64, i32, i64) wasmtime_system_v
sig3 = (i64 vmctx, i64, i32, i64, i32, f32, f64, r64, i64) wasmtime_system_v
fn0 = u0:0 sig0
fn1 = u0:1 sig1
fn2 = u0:2 sig2
fn3 = u0:3 sig3
stack_limit = gv2
block0(v0: i64, v1: i64, v2: r64, v3: i64):
v4 -> v0
v8 -> v0
v15 -> v0
v23 -> v0
v5 = load.i64 notrap aligned v0+72
v6 = load.i64 notrap aligned v0+80
call_indirect sig0, v5(v6, v0)
v9 = load.i64 notrap aligned v0+88
v10 = load.i64 notrap aligned v0+96
v7 = iconst.i32 0
v11 = call_indirect sig1, v9(v10, v0, v7) ; v7 = 0
v16 = load.i64 notrap aligned v0+104
v17 = load.i64 notrap aligned v0+112
v12 = iconst.i32 1
v13 = iadd v11, v12 ; v12 = 1
v14 = iconst.i64 3
call_indirect sig2, v16(v17, v0, v13, v14) ; v14 = 3
v24 = load.i64 notrap aligned v0+120
v25 = load.i64 notrap aligned v0+128
v18 = iconst.i32 100
v19 = iconst.i64 200
v20 = iconst.i32 300
v21 = f32const 0x1.900000p8
v22 = f64const 0x1.f400000000000p8
call_indirect sig3, v24(v25, v0, v18, v19, v20, v21, v22, v2, v3) ; v18 = 100, v19 = 200, v20 = 300, v21 = 0x1.900000p8, v22 = 0x1.f400000000000p8
jump block1
block1:
return
}

View File

@@ -0,0 +1,9 @@
function u0:3(i64, i64) system_v {
sig0 = (i8) -> i8 system_v
block0(v0: i64, v1: i64):
v2 = load.i8 notrap aligned v1
v3 = call_indirect sig0, v0(v2)
store notrap aligned v3, v1
return
}

21
tests/fibonacci.clif Normal file
View File

@@ -0,0 +1,21 @@
function %fibonacci(i32) -> i32 {
block0(v0: i32):
v1 = icmp_imm ule v0, 2
v2 = iconst.i32 1
; handle base case, n <= 2
brif v1, block3(v2), block1(v0, v2)
block1(v4: i32, v5:i32):
v6 = iconst.i32 1
v7 = iadd_imm v4, -2
jump block2(v7, v5, v6)
block2(v10: i32, v11: i32, v12: i32): ; params: n, fib(n-1), fib(n-2)
v13 = iadd v11, v12
v14 = iadd_imm v10, -1
v15 = icmp_imm eq v14, 0
brif v15, block3(v13), block2(v14, v13, v11)
block3(v20: i32): ; early return and end of loop
return v20
}

21
tests/simple.clif Normal file
View File

@@ -0,0 +1,21 @@
function u0:0(i64, i64) -> i64 system_v {
sig0 = (i64) -> i64 system_v
fn0 = u0:0 sig0
block0(v0: i64, v1: i64):
v4 = iconst.i64 50
brif v1, block1(v0), block2(v0)
block1(v2: i64):
v5 = iconst.i64 50
v6 = call fn0(v5) ; v5 = 50
v7 = iadd v2, v6
return v7
block2(v3: i64):
v8 = iconst.i64 10
v9 = iconst.i64 -20
v10 = iadd_imm v8, -20 ; v8 = 10
v11 = iadd v3, v10
return v11
}

8
tests/test.clif Normal file
View File

@@ -0,0 +1,8 @@
function u0:4(i64, i64) system_v {
sig0 = () -> i8 system_v
block0(v0: i64, v1: i64):
v2 = call_indirect sig0, v0()
store notrap aligned v2, v1
return
}

2050
tmp_out.txt Normal file

File diff suppressed because it is too large Load Diff