Skip to content

Commit

Permalink
proper ABI implementation support for ccall, and start work on the sa…
Browse files Browse the repository at this point in the history
…me for cfunction
  • Loading branch information
vtjnash committed Mar 9, 2015
1 parent 468cb71 commit 9053bff
Show file tree
Hide file tree
Showing 24 changed files with 1,645 additions and 349 deletions.
1 change: 1 addition & 0 deletions LICENSE.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ The following components of Julia's standard library have separate licenses:
Julia builds the following libraries by default, but does not use them itself:

- [RMATH](https://www.r-project.org/Licenses/)
- [LDC](https://github.com/ldc-developers/ldc/blob/master/LICENSE)


Julia's build process uses the following external tools:
Expand Down
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ julia-deps: git-submodules | $(DIRS) $(build_datarootdir)/julia/base $(build_da
julia-base: julia-deps
@$(MAKE) $(QUIET_MAKE) -C base

julia-libccalltest:
@$(MAKE) $(QUIET_MAKE) -C test libccalltest

julia-src-%: julia-deps
@$(MAKE) $(QUIET_MAKE) -C src libjulia-$*

Expand All @@ -78,7 +81,7 @@ julia-ui-%: julia-src-%
julia-sysimg-% : julia-ui-% julia-base
@$(MAKE) $(QUIET_MAKE) LD_LIBRARY_PATH=$(build_libdir):$(LD_LIBRARY_PATH) JULIA_EXECUTABLE="$(JULIA_EXECUTABLE_$*)" $(build_private_libdir)/sys.$(SHLIB_EXT)

julia-debug julia-release : julia-% : julia-symlink-% julia-sysimg-%
julia-debug julia-release : julia-% : julia-symlink-% julia-sysimg-% julia-libccalltest

debug release : % : julia-%

Expand Down Expand Up @@ -455,6 +458,7 @@ clean: | $(CLEAN_TARGETS)
@$(MAKE) -C doc clean
@$(MAKE) -C src clean
@$(MAKE) -C ui clean
@$(MAKE) -C test clean
@rm -f julia
@rm -f *~ *# *.tar.gz
@rm -f $(build_bindir)/stringreplace \
Expand Down
7 changes: 4 additions & 3 deletions base/boot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,10 @@ export
Box, Function, IntrinsicFunction, LambdaStaticData, Method, MethodTable,
Module, Symbol, Task, Array, GenSym,
# numeric types
Bool, FloatingPoint, Float16, Float32, Float64, Number, Integer, Int, Int8, Int16,
Int32, Int64, Int128, Ref, Ptr, Real, Signed, UInt, UInt8, UInt16, UInt32,
UInt64, UInt128, Unsigned,
Real, Complex, Number, Integer, Bool, Ref, Ptr,
FloatingPoint, Float16, Float32, Float64,
Signed, Int, Int8, Int16, Int32, Int64, Int128,
Unsigned, UInt, UInt8, UInt16, UInt32, UInt64, UInt128,
# string types
Char, ASCIIString, ByteString, DirectIndexString, AbstractString, UTF8String,
# errors
Expand Down
5 changes: 5 additions & 0 deletions base/reflection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -215,3 +215,8 @@ function function_module(f, types)
end
m[1].func.code.module
end

#

type_alignment(x::DataType) = ccall(:jl_get_alignment,Csize_t,(Any,),x)
field_offset(x::DataType,idx) = ccall(:jl_get_field_offset,Csize_t,(Any,Int32),x,idx)
3 changes: 0 additions & 3 deletions base/special/erf.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
@unix_only if WORD_SIZE == 64
# TODO: complex return only on 64-bit for now
for f in (:erf, :erfc, :erfcx, :erfi, :Dawson)
fname = (f === :Dawson) ? :dawson : f
@eval begin
Expand All @@ -8,7 +6,6 @@ for f in (:erf, :erfc, :erfcx, :erfi, :Dawson)
($fname)(z::Complex) = ($fname)(Complex128(z))
end
end
end
for f in (:erfcx, :erfi, :Dawson)
fname = (f === :Dawson) ? :dawson : f
@eval begin
Expand Down
38 changes: 38 additions & 0 deletions src/abi_llvm.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//===-- abi_llvm.cpp - LLVM Target ABI description --------------*- C++ -*-===https://
//
// LDC – the LLVM D compiler
//
// This file is distributed under the BSD-style LDC license. See the LICENSE
// file for details.
//
//===----------------------------------------------------------------------===https://
//
// This ABI implementation does whatever LLVM decides is fine.
// It can be useful when first porting Julia to a new platform
// (until a platform-specific implementation can be developed).
//
//===----------------------------------------------------------------------===https://


typedef bool AbiState;
AbiState default_abi_state = 0;

bool use_sret(AbiState *state,jl_value_t *ty)
{
return false;
}

void needPassByRef(AbiState *state,jl_value_t *ty, bool *byRef, bool *inReg)
{
return;
}

Type *preferred_llvm_type(jl_value_t *ty, bool isret)
{
return NULL;
}

bool need_private_copy(jl_value_t *ty, bool byRef)
{
return false;
}
68 changes: 68 additions & 0 deletions src/abi_win64.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
//===-- abi_win64.cpp - Windows x86_64 ABI description ----------*- C++ -*-===https://
//
// LDC – the LLVM D compiler
//
// This file is distributed under the BSD-style LDC license. See the LICENSE
// file for details.
//
//===----------------------------------------------------------------------===https://
//
// The ABI implementation used for 64 bit x86 (i.e. x86_64/AMD64/x64) targets
// on Windows.
//
//===----------------------------------------------------------------------===https://


// Windows only uses the first four registers of either
struct AbiState {
unsigned char int_regs, sse_regs;
};

const AbiState default_abi_state = {4,4};


bool use_sret(AbiState *state,jl_value_t *ty)
{
if(!jl_is_datatype(ty) || jl_is_abstracttype(ty) || jl_is_cpointer_type(ty) || jl_is_array_type(ty))
return false;
size_t size = jl_datatype_size(ty);
bool sret = !(size == 1 || size == 2 || size == 4 || size == 8); // || jl_is_sse(ty) if every implemented
if(sret)
state->int_regs--;
return sret;
}

void needPassByRef(AbiState *state,jl_value_t *ty, bool *byRef, bool *inReg, bool *byRefAttr)
{
if(!jl_is_datatype(ty) || jl_is_abstracttype(ty) || jl_is_cpointer_type(ty) || jl_is_array_type(ty))
return;
if ((jl_datatype_t*)ty == jl_float32_type || (jl_datatype_t*)ty == jl_float64_type) {
state->sse_regs--;
return;
}
size_t size = jl_datatype_size(ty);
*byRef = !(size == 1 || size == 2 || size == 4 || size == 8); // but not sse types
*byRefAttr = *byRef;
if(state->int_regs > 0) {
state->int_regs--; //Windows passes these by pointer
//*inReg = true;
}
}

Type *preferred_llvm_type(jl_value_t *ty, bool isret)
{
if(!jl_is_datatype(ty) || jl_is_abstracttype(ty) || jl_is_cpointer_type(ty) || jl_is_array_type(ty))
return NULL;
if(jl_is_bitstype(ty))
return NULL;
size_t size = jl_datatype_size(ty);
if (size == 1 || size == 2 || size == 4 || size == 8)
return T_int64;
return NULL;
}

// Windows needs all types pased byRef to be passed in caller allocated memory
bool need_private_copy(jl_value_t *ty, bool byRef)
{
return byRef;
}
61 changes: 61 additions & 0 deletions src/abi_x86.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//===-- abi_x86.cpp - x86 ABI description -----------------------*- C++ -*-===https://
//
// LDC – the LLVM D compiler
//
// This file is distributed under the BSD-style LDC license. See the LICENSE
// file for details.
//
//===----------------------------------------------------------------------===https://
//
// The ABI implementation used for 32 bit x86 targets.
//
//===----------------------------------------------------------------------===https://


typedef bool AbiState;
AbiState default_abi_state = 0;

inline bool is_complex64(jl_value_t *ty)
{
return jl_subtype(ty,(jl_value_t*)jl_complex_type,0) && jl_tparam0(ty) == (jl_value_t*)jl_float32_type;
}

inline bool is_complex128(jl_value_t *ty)
{
return jl_subtype(ty,(jl_value_t*)jl_complex_type,0) && jl_tparam0(ty) == (jl_value_t*)jl_float64_type;
}

bool use_sret(AbiState *state,jl_value_t *ty)
{
if(!jl_is_datatype(ty) || jl_is_abstracttype(ty) || jl_is_bitstype(ty) || jl_is_cpointer_type(ty) || jl_is_array_type(ty))
return false;
if(is_complex64(ty))
return false;
return jl_is_structtype(ty);
}

void needPassByRef(AbiState *state,jl_value_t *ty, bool *byRef, bool *inReg, bool *byRefAttr)
{
if(!jl_is_datatype(ty) || jl_is_abstracttype(ty) || jl_is_bitstype(ty) || jl_is_cpointer_type(ty) || jl_is_array_type(ty))
return;
if(jl_is_structtype(ty) && !need_destructure_argument(ty))
*byRef = true;
*byRefAttr = *byRef;
}

Type *preferred_llvm_type(jl_value_t *ty, bool isret)
{
if(!isret)
return NULL;
if(!jl_is_datatype(ty) || jl_is_abstracttype(ty) || jl_is_bitstype(ty) || jl_is_cpointer_type(ty) || jl_is_array_type(ty))
return NULL;
// special case Complex{Float32} as a return type
if(jl_subtype(ty,(jl_value_t*)jl_complex_type,0) && jl_tparam0(ty) == (jl_value_t*)jl_float32_type)
return T_int64;
return NULL;
}

bool need_private_copy(jl_value_t *ty, bool byRef)
{
return false;
}
Loading

0 comments on commit 9053bff

Please sign in to comment.