diff --git a/cranelift/codegen/src/ir/libcall.rs b/cranelift/codegen/src/ir/libcall.rs index 6734258ed7..e6b2d539d0 100644 --- a/cranelift/codegen/src/ir/libcall.rs +++ b/cranelift/codegen/src/ir/libcall.rs @@ -1,7 +1,7 @@ //! Naming well-known routines in the runtime library. use crate::{ - ir::{types, AbiParam, ExternalName, FuncRef, Function, Signature}, + ir::{types, AbiParam, ExternalName, FuncRef, Function, Signature, Type}, isa::CallConv, }; use core::fmt; @@ -119,7 +119,7 @@ impl LibCall { } /// Get a [Signature] for the function targeted by this [LibCall]. - pub fn signature(&self, call_conv: CallConv) -> Signature { + pub fn signature(&self, call_conv: CallConv, pointer_type: Type) -> Signature { use types::*; let mut sig = Signature::new(call_conv); @@ -140,13 +140,32 @@ impl LibCall { sig.params.push(AbiParam::new(ty)); sig.returns.push(AbiParam::new(ty)); } - LibCall::Probestack - | LibCall::Memcpy - | LibCall::Memset - | LibCall::Memmove - | LibCall::Memcmp - | LibCall::ElfTlsGetAddr - | LibCall::ElfTlsGetOffset => unimplemented!(), + LibCall::Memcpy | LibCall::Memmove => { + // void* memcpy(void *dest, const void *src, size_t count); + // void* memmove(void* dest, const void* src, size_t count); + sig.params.push(AbiParam::new(pointer_type)); + sig.params.push(AbiParam::new(pointer_type)); + sig.params.push(AbiParam::new(pointer_type)); + sig.returns.push(AbiParam::new(pointer_type)); + } + LibCall::Memset => { + // void *memset(void *dest, int ch, size_t count); + sig.params.push(AbiParam::new(pointer_type)); + sig.params.push(AbiParam::new(I32)); + sig.params.push(AbiParam::new(pointer_type)); + sig.returns.push(AbiParam::new(pointer_type)); + } + LibCall::Memcmp => { + // void* memcpy(void *dest, const void *src, size_t count); + sig.params.push(AbiParam::new(pointer_type)); + sig.params.push(AbiParam::new(pointer_type)); + sig.params.push(AbiParam::new(pointer_type)); + sig.returns.push(AbiParam::new(I32)) + } + + LibCall::Probestack | LibCall::ElfTlsGetAddr | LibCall::ElfTlsGetOffset => { + unimplemented!() + } } sig diff --git a/cranelift/codegen/src/isa/x64/lower.rs b/cranelift/codegen/src/isa/x64/lower.rs index bd3b6e8dcd..d40eaecdc4 100644 --- a/cranelift/codegen/src/isa/x64/lower.rs +++ b/cranelift/codegen/src/isa/x64/lower.rs @@ -150,7 +150,7 @@ fn emit_vm_call( // TODO avoid recreating signatures for every single Libcall function. let call_conv = CallConv::for_libcall(flags, CallConv::triple_default(triple)); - let sig = libcall.signature(call_conv); + let sig = libcall.signature(call_conv, types::I64); let caller_conv = ctx.abi().call_conv(ctx.sigs()); if !ctx.sigs().have_abi_sig_for_signature(&sig) { diff --git a/cranelift/codegen/src/isa/x64/lower/isle.rs b/cranelift/codegen/src/isa/x64/lower/isle.rs index 1ca927ec31..bf328b5268 100644 --- a/cranelift/codegen/src/isa/x64/lower/isle.rs +++ b/cranelift/codegen/src/isa/x64/lower/isle.rs @@ -629,7 +629,7 @@ impl Context for IsleContext<'_, '_, MInst, X64Backend> { fn libcall_1(&mut self, libcall: &LibCall, a: Reg) -> Reg { let call_conv = self.lower_ctx.abi().call_conv(self.lower_ctx.sigs()); - let ret_ty = libcall.signature(call_conv).returns[0].value_type; + let ret_ty = libcall.signature(call_conv, I64).returns[0].value_type; let output_reg = self.lower_ctx.alloc_tmp(ret_ty).only_reg().unwrap(); emit_vm_call( @@ -647,7 +647,7 @@ impl Context for IsleContext<'_, '_, MInst, X64Backend> { fn libcall_3(&mut self, libcall: &LibCall, a: Reg, b: Reg, c: Reg) -> Reg { let call_conv = self.lower_ctx.abi().call_conv(self.lower_ctx.sigs()); - let ret_ty = libcall.signature(call_conv).returns[0].value_type; + let ret_ty = libcall.signature(call_conv, I64).returns[0].value_type; let output_reg = self.lower_ctx.alloc_tmp(ret_ty).only_reg().unwrap(); emit_vm_call( diff --git a/cranelift/frontend/src/frontend.rs b/cranelift/frontend/src/frontend.rs index ecef10ba76..631f6ba8cb 100644 --- a/cranelift/frontend/src/frontend.rs +++ b/cranelift/frontend/src/frontend.rs @@ -753,6 +753,7 @@ impl<'a> FunctionBuilder<'a> { s.params.push(AbiParam::new(pointer_type)); s.params.push(AbiParam::new(pointer_type)); s.params.push(AbiParam::new(pointer_type)); + s.returns.push(AbiParam::new(pointer_type)); self.import_signature(s) }; @@ -853,6 +854,7 @@ impl<'a> FunctionBuilder<'a> { s.params.push(AbiParam::new(pointer_type)); s.params.push(AbiParam::new(types::I32)); s.params.push(AbiParam::new(pointer_type)); + s.returns.push(AbiParam::new(pointer_type)); self.import_signature(s) }; @@ -949,6 +951,7 @@ impl<'a> FunctionBuilder<'a> { s.params.push(AbiParam::new(pointer_type)); s.params.push(AbiParam::new(pointer_type)); s.params.push(AbiParam::new(pointer_type)); + s.returns.push(AbiParam::new(pointer_type)); self.import_signature(s) }; @@ -1283,15 +1286,15 @@ mod tests { check( &func, "function %sample() -> i32 system_v { - sig0 = (i64, i64, i64) system_v + sig0 = (i64, i64, i64) -> i64 system_v fn0 = %Memcpy sig0 block0: + v4 = iconst.i64 0 + v1 -> v4 v3 = iconst.i64 0 - v1 -> v3 - v2 = iconst.i64 0 - v0 -> v2 - call fn0(v1, v0, v1) ; v1 = 0, v0 = 0, v1 = 0 + v0 -> v3 + v2 = call fn0(v1, v0, v1) ; v1 = 0, v0 = 0, v1 = 0 return v1 ; v1 = 0 } ", @@ -1393,16 +1396,16 @@ block0: check( &func, "function %sample() -> i32 system_v { - sig0 = (i64, i64, i64) system_v + sig0 = (i64, i64, i64) -> i64 system_v fn0 = %Memcpy sig0 block0: + v5 = iconst.i64 0 + v1 -> v5 v4 = iconst.i64 0 - v1 -> v4 - v3 = iconst.i64 0 - v0 -> v3 + v0 -> v4 v2 = iconst.i64 8192 - call fn0(v1, v0, v2) ; v1 = 0, v0 = 0, v2 = 8192 + v3 = call fn0(v1, v0, v2) ; v1 = 0, v0 = 0, v2 = 8192 return v1 ; v1 = 0 } ", @@ -1478,16 +1481,16 @@ block0: check( &func, "function %sample() -> i32 system_v { - sig0 = (i64, i32, i64) system_v + sig0 = (i64, i32, i64) -> i64 system_v fn0 = %Memset sig0 block0: - v4 = iconst.i64 0 - v0 -> v4 + v5 = iconst.i64 0 + v0 -> v5 v1 = iconst.i8 1 v2 = iconst.i64 8192 v3 = uextend.i32 v1 ; v1 = 1 - call fn0(v0, v3, v2) ; v0 = 0, v2 = 8192 + v4 = call fn0(v0, v3, v2) ; v0 = 0, v2 = 8192 return v0 ; v0 = 0 } ", diff --git a/cranelift/fuzzgen/src/function_generator.rs b/cranelift/fuzzgen/src/function_generator.rs index 52f89db231..a6e28b73b8 100644 --- a/cranelift/fuzzgen/src/function_generator.rs +++ b/cranelift/fuzzgen/src/function_generator.rs @@ -1863,7 +1863,11 @@ where .libcalls .iter() .map(|libcall| { - let signature = libcall.signature(lib_callconv); + let pointer_type = Type::int_with_byte_size( + self.target_triple.pointer_width().unwrap().bytes().into(), + ) + .unwrap(); + let signature = libcall.signature(lib_callconv, pointer_type); let name = ExternalName::LibCall(*libcall); (name, signature) }) diff --git a/cranelift/interpreter/src/state.rs b/cranelift/interpreter/src/state.rs index 6e01d4b943..5c5d7a685b 100644 --- a/cranelift/interpreter/src/state.rs +++ b/cranelift/interpreter/src/state.rs @@ -5,8 +5,8 @@ use crate::frame::Frame; use crate::interpreter::LibCallHandler; use cranelift_codegen::data_value::DataValue; use cranelift_codegen::ir::{ - ExternalName, FuncRef, Function, GlobalValue, LibCall, MemFlags, Signature, StackSlot, Type, - Value, + types, ExternalName, FuncRef, Function, GlobalValue, LibCall, MemFlags, Signature, StackSlot, + Type, Value, }; use cranelift_codegen::isa::CallConv; use smallvec::SmallVec; @@ -96,7 +96,8 @@ impl<'a> InterpreterFunctionRef<'a> { match self { InterpreterFunctionRef::Function(f) => f.stencil.signature.clone(), // CallConv here is sort of irrelevant, since we don't use it for anything - InterpreterFunctionRef::LibCall(lc) => lc.signature(CallConv::SystemV), + // FIXME handle non-64bit systems + InterpreterFunctionRef::LibCall(lc) => lc.signature(CallConv::SystemV, types::I64), } } }