diff --git a/lib/llvm/src/operations.rs b/lib/llvm/src/operations.rs index b7e6c12..ab2afdc 100644 --- a/lib/llvm/src/operations.rs +++ b/lib/llvm/src/operations.rs @@ -858,7 +858,13 @@ fn translate_mem_intrinsic( // start optimizing these libcalls. let args = [dst_arg, src_arg, len_arg]; - let funcname = strings.get_extname(name); + let libcall = match name { + "memcpy" => ir::LibCall::Memcpy, + "memmove" => ir::LibCall::Memmove, + "memset" => ir::LibCall::Memset, + _ => panic!("not handled {}", name) + }; + // TODO: Translate the calling convention. let mut sig = ir::Signature::new(CallConv::SystemV); sig.params.resize(3, ir::AbiParam::new(pointer_type)); @@ -868,7 +874,7 @@ fn translate_mem_intrinsic( sig.returns.resize(1, ir::AbiParam::new(pointer_type)); let signature = ctx.builder.import_signature(sig); let data = ir::ExtFuncData { - name: funcname, + name: ir::ExternalName::LibCall(libcall), signature, colocated: false, // TODO: Set the colocated flag based on the visibility. }; diff --git a/lib/llvm/src/string_table.rs b/lib/llvm/src/string_table.rs index dcbc1a2..679be7f 100644 --- a/lib/llvm/src/string_table.rs +++ b/lib/llvm/src/string_table.rs @@ -26,6 +26,14 @@ impl StringTable { .0 .as_str() } + ir::ExternalName::LibCall(libcall) => { + match libcall { + ir::LibCall::Memcpy => "memcpy", + ir::LibCall::Memmove => "memmove", + ir::LibCall::Memset => "memset", + _ => panic!("unhandled LibCall {}", libcall), + } + } _ => panic!("non-user names not yet implemented"), } } diff --git a/lib/llvm/src/translate.rs b/lib/llvm/src/translate.rs index 2e82ef9..945008d 100644 --- a/lib/llvm/src/translate.rs +++ b/lib/llvm/src/translate.rs @@ -103,14 +103,22 @@ pub fn translate_module( // Collect externally referenced symbols for the module. for func_ref in func.il.dfg.ext_funcs.keys() { let name = &func.il.dfg.ext_funcs[func_ref].name; - // If this function is defined inside the module, don't list it - // as an import. - let c_str = ffi::CString::new(result.strings.get_str(name)) - .map_err(|err| err.description().to_string())?; - let llvm_str = c_str.as_ptr(); - let llvm_func = unsafe { LLVMGetNamedFunction(llvm_mod, llvm_str) }; - if llvm_func.is_null() || unsafe { LLVMIsDeclaration(llvm_func) } != 0 { - result.imports.push((name.clone(), SymbolKind::Function)); + match name { + ir::ExternalName::User{..} => { + // If this function is defined inside the module, don't list it + // as an import. + let c_str = ffi::CString::new(result.strings.get_str(name)) + .map_err(|err| err.description().to_string())?; + let llvm_str = c_str.as_ptr(); + let llvm_func = unsafe { LLVMGetNamedFunction(llvm_mod, llvm_str) }; + if llvm_func.is_null() || unsafe { LLVMIsDeclaration(llvm_func) } != 0 { + result.imports.push((name.clone(), SymbolKind::Function)); + } + } + ir::ExternalName::LibCall{..} => { + result.imports.push((name.clone(), SymbolKind::Function)); + } + _ => panic!("unhandled: {}", name) } } for global_var in func.il.global_values.keys() {