diff --git a/lib/compiler-llvm/src/abi/aarch64_systemv.rs b/lib/compiler-llvm/src/abi/aarch64_systemv.rs index c4a5fc36ebb..329d4ea8cad 100644 --- a/lib/compiler-llvm/src/abi/aarch64_systemv.rs +++ b/lib/compiler-llvm/src/abi/aarch64_systemv.rs @@ -11,6 +11,8 @@ use inkwell::{ use wasmer_compiler::CompileError; use wasmer_types::{FunctionType as FuncSig, Type}; +use std::convert::TryInto; + /// Implementation of the [`Abi`] trait for the Aarch64 ABI on Linux. pub struct Aarch64SystemV {} @@ -47,19 +49,41 @@ impl Abi for Aarch64SystemV { let param_types = std::iter::once(Ok(intrinsics.ctx_ptr_ty.as_basic_type_enum())).chain(user_param_types); + let vmctx_attributes = |i: u32| { + vec![ + ( + context.create_enum_attribute(Attribute::get_named_enum_kind_id("nofree"), 0), + AttributeLoc::Param(i), + ), + ( + context.create_enum_attribute(Attribute::get_named_enum_kind_id("nonnull"), 0), + AttributeLoc::Param(i), + ), + ( + context.create_enum_attribute( + Attribute::get_named_enum_kind_id("align"), + std::mem::align_of::() + .try_into() + .unwrap(), + ), + AttributeLoc::Param(i), + ), + ] + }; + Ok(match sig.results() { [] => ( intrinsics .void_ty .fn_type(¶m_types.collect::, _>>()?, false), - vec![], + vmctx_attributes(0), ), [_] => { let single_value = sig.results()[0]; ( type_to_llvm(intrinsics, single_value)? .fn_type(¶m_types.collect::, _>>()?, false), - vec![], + vmctx_attributes(0), ) } [Type::F32, Type::F32] => { @@ -68,7 +92,7 @@ impl Abi for Aarch64SystemV { context .struct_type(&[f32_ty, f32_ty], false) .fn_type(¶m_types.collect::, _>>()?, false), - vec![], + vmctx_attributes(0), ) } [Type::F64, Type::F64] => { @@ -77,7 +101,7 @@ impl Abi for Aarch64SystemV { context .struct_type(&[f64_ty, f64_ty], false) .fn_type(¶m_types.collect::, _>>()?, false), - vec![], + vmctx_attributes(0), ) } [Type::F32, Type::F32, Type::F32] => { @@ -86,7 +110,7 @@ impl Abi for Aarch64SystemV { context .struct_type(&[f32_ty, f32_ty, f32_ty], false) .fn_type(¶m_types.collect::, _>>()?, false), - vec![], + vmctx_attributes(0), ) } [Type::F32, Type::F32, Type::F32, Type::F32] => { @@ -95,7 +119,7 @@ impl Abi for Aarch64SystemV { context .struct_type(&[f32_ty, f32_ty, f32_ty, f32_ty], false) .fn_type(¶m_types.collect::, _>>()?, false), - vec![], + vmctx_attributes(0), ) } _ => { @@ -115,7 +139,7 @@ impl Abi for Aarch64SystemV { intrinsics .i64_ty .fn_type(¶m_types.collect::, _>>()?, false), - vec![], + vmctx_attributes(0), ), [32, 64] | [64, 32] @@ -128,7 +152,7 @@ impl Abi for Aarch64SystemV { .i64_ty .array_type(2) .fn_type(¶m_types.collect::, _>>()?, false), - vec![], + vmctx_attributes(0), ), _ => { let basic_types: Vec<_> = sig @@ -144,17 +168,20 @@ impl Abi for Aarch64SystemV { let param_types = std::iter::once(Ok(sret.as_basic_type_enum())).chain(param_types); + let mut attributes = vec![( + context.create_enum_attribute( + Attribute::get_named_enum_kind_id("sret"), + 0, + ), + AttributeLoc::Param(0), + )]; + attributes.append(&mut vmctx_attributes(1)); + ( intrinsics .void_ty .fn_type(¶m_types.collect::, _>>()?, false), - vec![( - context.create_enum_attribute( - Attribute::get_named_enum_kind_id("sret"), - 0, - ), - AttributeLoc::Param(0), - )], + attributes, ) } } @@ -393,17 +420,18 @@ impl Abi for Aarch64SystemV { }) .collect::, _>>()?; - Ok(!matches!(func_sig_returns_bitwidths.as_slice(), - [] - | [_] - | [32, 32] - | [32, 64] - | [64, 32] - | [64, 64] - | [32, 32, 32] - | [32, 32, 64] - | [64, 32, 32] - | [32, 32, 32, 32])) + Ok(!matches!( + func_sig_returns_bitwidths.as_slice(), + [] | [_] + | [32, 32] + | [32, 64] + | [64, 32] + | [64, 64] + | [32, 32, 32] + | [32, 32, 64] + | [64, 32, 32] + | [32, 32, 32, 32] + )) } fn pack_values_for_register_return<'ctx>( diff --git a/lib/compiler-llvm/src/abi/x86_64_systemv.rs b/lib/compiler-llvm/src/abi/x86_64_systemv.rs index a6fd67622c7..799d20056e9 100644 --- a/lib/compiler-llvm/src/abi/x86_64_systemv.rs +++ b/lib/compiler-llvm/src/abi/x86_64_systemv.rs @@ -14,6 +14,8 @@ use inkwell::{ use wasmer_compiler::CompileError; use wasmer_types::{FunctionType as FuncSig, Type}; +use std::convert::TryInto; + /// Implementation of the [`Abi`] trait for the AMD64 SystemV ABI. pub struct X86_64SystemV {} @@ -50,6 +52,29 @@ impl Abi for X86_64SystemV { let param_types = std::iter::once(Ok(intrinsics.ctx_ptr_ty.as_basic_type_enum())).chain(user_param_types); + // TODO: figure out how many bytes long vmctx is, and mark it dereferenceable. (no need to mark it nonnull once we do this.) + let vmctx_attributes = |i: u32| { + vec![ + ( + context.create_enum_attribute(Attribute::get_named_enum_kind_id("nofree"), 0), + AttributeLoc::Param(i), + ), + ( + context.create_enum_attribute(Attribute::get_named_enum_kind_id("nonnull"), 0), + AttributeLoc::Param(i), + ), + ( + context.create_enum_attribute( + Attribute::get_named_enum_kind_id("align"), + std::mem::align_of::() + .try_into() + .unwrap(), + ), + AttributeLoc::Param(i), + ), + ] + }; + let sig_returns_bitwidths = sig .results() .iter() @@ -67,14 +92,14 @@ impl Abi for X86_64SystemV { intrinsics .void_ty .fn_type(¶m_types.collect::, _>>()?, false), - vec![], + vmctx_attributes(0), ), [_] => { let single_value = sig.results()[0]; ( type_to_llvm(intrinsics, single_value)? .fn_type(¶m_types.collect::, _>>()?, false), - vec![], + vmctx_attributes(0), ) } [32, 64] | [64, 32] | [64, 64] => { @@ -88,7 +113,7 @@ impl Abi for X86_64SystemV { context .struct_type(&basic_types, false) .fn_type(¶m_types.collect::, _>>()?, false), - vec![], + vmctx_attributes(0), ) } [32, 32] if sig.results()[0] == Type::F32 && sig.results()[1] == Type::F32 => ( @@ -96,13 +121,13 @@ impl Abi for X86_64SystemV { .f32_ty .vec_type(2) .fn_type(¶m_types.collect::, _>>()?, false), - vec![], + vmctx_attributes(0), ), [32, 32] => ( intrinsics .i64_ty .fn_type(¶m_types.collect::, _>>()?, false), - vec![], + vmctx_attributes(0), ), [32, 32, _] if sig.results()[0] == Type::F32 && sig.results()[1] == Type::F32 => ( context @@ -114,7 +139,7 @@ impl Abi for X86_64SystemV { false, ) .fn_type(¶m_types.collect::, _>>()?, false), - vec![], + vmctx_attributes(0), ), [32, 32, _] => ( context @@ -126,7 +151,7 @@ impl Abi for X86_64SystemV { false, ) .fn_type(¶m_types.collect::, _>>()?, false), - vec![], + vmctx_attributes(0), ), [64, 32, 32] if sig.results()[1] == Type::F32 && sig.results()[2] == Type::F32 => ( context @@ -138,7 +163,7 @@ impl Abi for X86_64SystemV { false, ) .fn_type(¶m_types.collect::, _>>()?, false), - vec![], + vmctx_attributes(0), ), [64, 32, 32] => ( context @@ -150,7 +175,7 @@ impl Abi for X86_64SystemV { false, ) .fn_type(¶m_types.collect::, _>>()?, false), - vec![], + vmctx_attributes(0), ), [32, 32, 32, 32] => ( context @@ -170,7 +195,7 @@ impl Abi for X86_64SystemV { false, ) .fn_type(¶m_types.collect::, _>>()?, false), - vec![], + vmctx_attributes(0), ), _ => { let basic_types: Vec<_> = sig @@ -185,14 +210,17 @@ impl Abi for X86_64SystemV { let param_types = std::iter::once(Ok(sret.as_basic_type_enum())).chain(param_types); + let mut attributes = vec![( + context.create_enum_attribute(Attribute::get_named_enum_kind_id("sret"), 0), + AttributeLoc::Param(0), + )]; + attributes.append(&mut vmctx_attributes(1)); + ( intrinsics .void_ty .fn_type(¶m_types.collect::, _>>()?, false), - vec![( - context.create_enum_attribute(Attribute::get_named_enum_kind_id("sret"), 0), - AttributeLoc::Param(0), - )], + attributes, ) } }) @@ -447,17 +475,18 @@ impl Abi for X86_64SystemV { }) .collect::, _>>()?; - Ok(!matches!(func_sig_returns_bitwidths.as_slice(), - [] - | [_] - | [32, 32] - | [32, 64] - | [64, 32] - | [64, 64] - | [32, 32, 32] - | [32, 32, 64] - | [64, 32, 32] - | [32, 32, 32, 32])) + Ok(!matches!( + func_sig_returns_bitwidths.as_slice(), + [] | [_] + | [32, 32] + | [32, 64] + | [64, 32] + | [64, 64] + | [32, 32, 32] + | [32, 32, 64] + | [64, 32, 32] + | [32, 32, 32, 32] + )) } fn pack_values_for_register_return<'ctx>( diff --git a/lib/compiler-llvm/src/translator/code.rs b/lib/compiler-llvm/src/translator/code.rs index 8e2c617c4f4..674f58507e1 100644 --- a/lib/compiler-llvm/src/translator/code.rs +++ b/lib/compiler-llvm/src/translator/code.rs @@ -111,9 +111,6 @@ impl FuncTranslator { func.add_attribute(*attr_loc, *attr); } - // TODO: mark vmctx align 16 - // TODO: figure out how many bytes long vmctx is, and mark it dereferenceable. (no need to mark it nonnull once we do this.) - // TODO: mark vmctx nofree func.add_attribute(AttributeLoc::Function, intrinsics.stack_probe); func.set_personality_function(intrinsics.personality); func.as_global_value().set_section(FUNCTION_SECTION);