diff --git a/Cargo.lock b/Cargo.lock index bd11682..5576e10 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -687,6 +687,7 @@ dependencies = [ "regex", "revive-builtins", "revive-common", + "revive-extensions", "revive-linker", "revive-stdlib", "semver 1.0.22", @@ -1349,7 +1350,7 @@ dependencies = [ [[package]] name = "polkavm" version = "0.9.3" -source = "git+https://github.com/koute/polkavm.git#4ca06cc1b7cb435b2b92e81e30c2eb0e988f563e" +source = "git+https://github.com/koute/polkavm.git?branch=master_byteswap#8b8050bd58be30c6001925b5b2785bc9c98cca4e" dependencies = [ "libc", "log", @@ -1361,7 +1362,7 @@ dependencies = [ [[package]] name = "polkavm-assembler" version = "0.9.0" -source = "git+https://github.com/koute/polkavm.git#4ca06cc1b7cb435b2b92e81e30c2eb0e988f563e" +source = "git+https://github.com/koute/polkavm.git?branch=master_byteswap#8b8050bd58be30c6001925b5b2785bc9c98cca4e" dependencies = [ "log", ] @@ -1369,7 +1370,7 @@ dependencies = [ [[package]] name = "polkavm-common" version = "0.9.0" -source = "git+https://github.com/koute/polkavm.git#4ca06cc1b7cb435b2b92e81e30c2eb0e988f563e" +source = "git+https://github.com/koute/polkavm.git?branch=master_byteswap#8b8050bd58be30c6001925b5b2785bc9c98cca4e" dependencies = [ "log", ] @@ -1377,7 +1378,7 @@ dependencies = [ [[package]] name = "polkavm-linker" version = "0.9.2" -source = "git+https://github.com/koute/polkavm.git#4ca06cc1b7cb435b2b92e81e30c2eb0e988f563e" +source = "git+https://github.com/koute/polkavm.git?branch=master_byteswap#8b8050bd58be30c6001925b5b2785bc9c98cca4e" dependencies = [ "gimli", "hashbrown 0.14.3", @@ -1391,7 +1392,7 @@ dependencies = [ [[package]] name = "polkavm-linux-raw" version = "0.9.0" -source = "git+https://github.com/koute/polkavm.git#4ca06cc1b7cb435b2b92e81e30c2eb0e988f563e" +source = "git+https://github.com/koute/polkavm.git?branch=master_byteswap#8b8050bd58be30c6001925b5b2785bc9c98cca4e" [[package]] name = "ppv-lite86" diff --git a/Cargo.toml b/Cargo.toml index 902f9e2..9f3daae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,9 +27,9 @@ path-slash = "0.2" rayon = "1.8" structopt = { version = "0.3", default-features = false } rand = "0.8" -polkavm-common = { git = "https://github.com/koute/polkavm.git" } -polkavm-linker = { git = "https://github.com/koute/polkavm.git" } -polkavm = { git = "https://github.com/koute/polkavm.git" } +polkavm-common = { branch = "master_byteswap", git = "https://github.com/koute/polkavm.git" } +polkavm-linker = { branch = "master_byteswap", git = "https://github.com/koute/polkavm.git" } +polkavm = { branch = "master_byteswap", git = "https://github.com/koute/polkavm.git" } alloy-primitives = "0.6" alloy-sol-types = "0.6" env_logger = { version = "0.10.0", default-features = false } diff --git a/crates/extensions/build.rs b/crates/extensions/build.rs index c7b657a..3788c03 100644 --- a/crates/extensions/build.rs +++ b/crates/extensions/build.rs @@ -5,7 +5,7 @@ fn compile(source_path: &str, output_path: &str) { .args([ "-O3", "-filetype=asm", - "-mattr=+zbb,+e", + "-mattr=+zbb,+e,+m", source_path, "-o", output_path, diff --git a/crates/llvm-context/Cargo.toml b/crates/llvm-context/Cargo.toml index a740dc2..cbf0b58 100644 --- a/crates/llvm-context/Cargo.toml +++ b/crates/llvm-context/Cargo.toml @@ -33,3 +33,4 @@ pallet-contracts-pvm-llapi = { path = "../pallet-contracts-pvm-llapi" } revive-linker = { path = "../linker" } revive-builtins = { path = "../builtins" } revive-stdlib = { path = "../stdlib" } +revive-extensions = { path = "../extensions" } diff --git a/crates/llvm-context/src/eravm/context/mod.rs b/crates/llvm-context/src/eravm/context/mod.rs index e76d3d6..75e72ec 100644 --- a/crates/llvm-context/src/eravm/context/mod.rs +++ b/crates/llvm-context/src/eravm/context/mod.rs @@ -122,6 +122,31 @@ where /// The PolkaVM minimum stack size. const POLKAVM_STACK_SIZE: u32 = 0x4000; + /// Link in the extensions module. + fn link_extensions_module( + llvm: &'ctx inkwell::context::Context, + module: &inkwell::module::Module<'ctx>, + ) { + module + .link_in_module(revive_extensions::module(llvm, "revive_extensions").unwrap()) + .expect("the extensions module should be linkable"); + + let i256_type = llvm.custom_width_int_type(revive_common::BIT_LENGTH_FIELD as u32); + let bswap = module.add_function( + "__bswap", + i256_type.fn_type(&[i256_type.into()], false), + Some(inkwell::module::Linkage::External), + ); + bswap.add_attribute( + inkwell::attributes::AttributeLoc::Function, + llvm.create_enum_attribute(Attribute::AlwaysInline as u32, 0), + ); + bswap.add_attribute( + inkwell::attributes::AttributeLoc::Function, + llvm.create_enum_attribute(Attribute::WillReturn as u32, 0), + ); + } + /// Link in the stdlib module. fn link_stdlib_module( llvm: &'ctx inkwell::context::Context, @@ -203,6 +228,7 @@ where debug_config: Option, ) -> Self { Self::link_stdlib_module(llvm, &module); + Self::link_extensions_module(llvm, &module); Self::link_polkavm_guest_module(llvm, &module); Self::set_polkavm_stack_size(llvm, &module, Self::POLKAVM_STACK_SIZE); Self::set_module_flags(llvm, &module); @@ -703,7 +729,7 @@ where .set_alignment(revive_common::BYTE_LENGTH_BYTE as u32) .expect("Alignment is valid"); - Ok(self.build_byte_swap(value)) + self.build_byte_swap(value) } AddressSpace::TransientStorage => todo!(), AddressSpace::Storage => { @@ -761,13 +787,13 @@ where // TODO check return value self.build_load(storage_value_pointer, "storage_value_load") - .map(|value| self.build_byte_swap(value)) + .and_then(|value| self.build_byte_swap(value)) } AddressSpace::Code | AddressSpace::HeapAuxiliary => todo!(), - AddressSpace::Generic => Ok(self.build_byte_swap(self.build_load( + AddressSpace::Generic => self.build_byte_swap(self.build_load( pointer.address_space_cast(self, AddressSpace::Stack, &format!("{}_cast", name))?, name, - )?)), + )?), AddressSpace::Stack => { let value = self .builder() @@ -811,7 +837,7 @@ where let value = value.as_basic_value_enum(); let value = match value.get_type().into_int_type().get_bit_width() as usize { - revive_common::BIT_LENGTH_FIELD => self.build_byte_swap(value), + revive_common::BIT_LENGTH_FIELD => self.build_byte_swap(value)?, revive_common::BIT_LENGTH_BYTE => value, _ => unreachable!("Only word and byte sized values can be stored on EVM heap"), }; @@ -834,7 +860,7 @@ where self.build_alloca(storage_key_value.get_type(), "storage_key"); let storage_value_value = self - .build_byte_swap(value.as_basic_value_enum()) + .build_byte_swap(value.as_basic_value_enum())? .into_int_value(); let storage_value_pointer = self.build_alloca(storage_value_value.get_type(), "storage_value"); @@ -871,7 +897,7 @@ where AddressSpace::Code | AddressSpace::HeapAuxiliary => {} AddressSpace::Generic => self.build_store( pointer.address_space_cast(self, AddressSpace::Stack, "cast")?, - self.build_byte_swap(value.as_basic_value_enum()), + self.build_byte_swap(value.as_basic_value_enum())?, )?, AddressSpace::Stack => { let instruction = self.builder.build_store(pointer.value, value).unwrap(); @@ -888,9 +914,23 @@ where pub fn build_byte_swap( &self, value: inkwell::values::BasicValueEnum<'ctx>, - ) -> inkwell::values::BasicValueEnum<'ctx> { - self.build_call(self.intrinsics().byte_swap, &[value], "call_byte_swap") - .expect("byte_swap should return a value") + ) -> anyhow::Result> { + //return Ok(self + // .build_call(self.intrinsics().byte_swap, &[value], "call_byte_swap") + // .expect("__bswap should return a value")); + + let function = self + .module() + .get_function("__bswap") + .expect("should be declared"); + + Ok(self + .builder() + .build_direct_call(function, &[value.into()], "call_byte_swap")? + .try_as_basic_value() + .left() + .expect("__bswap should return a value") + .into()) } /// diff --git a/crates/llvm-context/src/eravm/evm/calldata.rs b/crates/llvm-context/src/eravm/evm/calldata.rs index 8a75a92..7fc3f7f 100644 --- a/crates/llvm-context/src/eravm/evm/calldata.rs +++ b/crates/llvm-context/src/eravm/evm/calldata.rs @@ -30,7 +30,7 @@ where ); context .build_load(offset, "calldata_value") - .map(|value| context.build_byte_swap(value)) + .and_then(|value| context.build_byte_swap(value)) } /// diff --git a/crates/llvm-context/src/eravm/evm/crypto.rs b/crates/llvm-context/src/eravm/evm/crypto.rs index c301ef3..ab7a657 100644 --- a/crates/llvm-context/src/eravm/evm/crypto.rs +++ b/crates/llvm-context/src/eravm/evm/crypto.rs @@ -47,5 +47,5 @@ where "call_seal_hash_keccak_256", )?; - Ok(context.build_byte_swap(context.build_load(output_pointer, "sha3_output")?)) + context.build_byte_swap(context.build_load(output_pointer, "sha3_output")?) }