mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-12 02:43:14 +01:00
899 lines
24 KiB
Diff
899 lines
24 KiB
Diff
Index: object.di
|
|
===================================================================
|
|
--- object.di (revision 4002)
|
|
+++ object.di (working copy)
|
|
@@ -150,6 +150,9 @@
|
|
void function() dtor;
|
|
void function() unitTest;
|
|
|
|
+ void* xgetMembers;
|
|
+ void function() ictor;
|
|
+
|
|
static int opApply( int delegate( inout ModuleInfo ) );
|
|
}
|
|
|
|
Index: lib/common/tango/core/BitManip.d
|
|
===================================================================
|
|
--- lib/common/tango/core/BitManip.d (revision 4002)
|
|
+++ lib/common/tango/core/BitManip.d (working copy)
|
|
@@ -171,6 +171,10 @@
|
|
*/
|
|
uint outpl( uint port_address, uint value );
|
|
}
|
|
+else version( LDC )
|
|
+{
|
|
+ public import ldc.bitmanip;
|
|
+}
|
|
else
|
|
{
|
|
public import std.intrinsic;
|
|
Index: lib/common/tango/core/Thread.d
|
|
===================================================================
|
|
--- lib/common/tango/core/Thread.d (revision 4002)
|
|
+++ lib/common/tango/core/Thread.d (working copy)
|
|
@@ -235,6 +235,7 @@
|
|
// used to track the number of suspended threads
|
|
//
|
|
sem_t suspendCount;
|
|
+ sem_t* suspendCountPtr;
|
|
|
|
|
|
extern (C) void thread_suspendHandler( int sig )
|
|
@@ -244,8 +245,29 @@
|
|
}
|
|
body
|
|
{
|
|
- version( D_InlineAsm_X86 )
|
|
+ version( LDC)
|
|
{
|
|
+ version(X86)
|
|
+ {
|
|
+ uint eax,ecx,edx,ebx,ebp,esi,edi;
|
|
+ asm
|
|
+ {
|
|
+ mov eax[EBP], EAX ;
|
|
+ mov ecx[EBP], ECX ;
|
|
+ mov edx[EBP], EDX ;
|
|
+ mov ebx[EBP], EBX ;
|
|
+ mov ebp[EBP], EBP ;
|
|
+ mov esi[EBP], ESI ;
|
|
+ mov edi[EBP], EDI ;
|
|
+ }
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ static assert( false, "Architecture not supported." );
|
|
+ }
|
|
+ }
|
|
+ else version( D_InlineAsm_X86 )
|
|
+ {
|
|
asm
|
|
{
|
|
pushad;
|
|
@@ -286,7 +308,7 @@
|
|
status = sigdelset( &sigres, SIGUSR2 );
|
|
assert( status == 0 );
|
|
|
|
- status = sem_post( &suspendCount );
|
|
+ status = sem_post( suspendCountPtr );
|
|
assert( status == 0 );
|
|
|
|
sigsuspend( &sigres );
|
|
@@ -297,8 +319,12 @@
|
|
}
|
|
}
|
|
|
|
- version( D_InlineAsm_X86 )
|
|
+ version( LDC)
|
|
{
|
|
+ // nothing to pop
|
|
+ }
|
|
+ else version( D_InlineAsm_X86 )
|
|
+ {
|
|
asm
|
|
{
|
|
popad;
|
|
@@ -1572,8 +1598,14 @@
|
|
status = sigaction( SIGUSR2, &sigusr2, null );
|
|
assert( status == 0 );
|
|
|
|
- status = sem_init( &suspendCount, 0, 0 );
|
|
- assert( status == 0 );
|
|
+ version(darwin){
|
|
+ suspendCountPtr = sem_open( "/thread_init/sem\0".ptr, 0 );
|
|
+ assert( suspendCountPtr !is null );
|
|
+ }else {
|
|
+ status=sem_init(&suspendCount,0,0);
|
|
+ suspendCountPtr=&suspendCount;
|
|
+ assert(status==0);
|
|
+ }
|
|
|
|
status = pthread_key_create( &Thread.sm_this, null );
|
|
assert( status == 0 );
|
|
@@ -1781,7 +1813,7 @@
|
|
// to simply loop on sem_wait at the end, but I'm not
|
|
// convinced that this would be much faster than the
|
|
// current approach.
|
|
- sem_wait( &suspendCount );
|
|
+ sem_wait( suspendCountPtr );
|
|
}
|
|
else if( !t.m_lock )
|
|
{
|
|
@@ -2286,6 +2318,13 @@
|
|
version = AsmPPC_Posix;
|
|
}
|
|
|
|
+ version( LLVM_InlineAsm_X86 )
|
|
+ {
|
|
+ version( Win32 )
|
|
+ version = LLVM_AsmX86_Win32;
|
|
+ else version( Posix )
|
|
+ version = LLVM_AsmX86_Posix;
|
|
+ }
|
|
|
|
version( Posix )
|
|
{
|
|
@@ -2296,6 +2328,8 @@
|
|
version( AsmX86_Win32 ) {} else
|
|
version( AsmX86_Posix ) {} else
|
|
version( AsmPPC_Posix ) {} else
|
|
+ version( LLVM_AsmX86_Win32 ) {} else
|
|
+ version( LLVM_AsmX86_Posix ) {} else
|
|
{
|
|
// NOTE: The ucontext implementation requires architecture specific
|
|
// data definitions to operate so testing for it must be done
|
|
@@ -2306,10 +2340,10 @@
|
|
import tango.stdc.posix.ucontext;
|
|
}
|
|
}
|
|
-
|
|
- const size_t PAGESIZE;
|
|
}
|
|
|
|
+// this can't be private since it's used as default argument to a public function
|
|
+const size_t PAGESIZE;
|
|
|
|
static this()
|
|
{
|
|
@@ -2336,7 +2370,7 @@
|
|
}
|
|
}
|
|
|
|
-
|
|
+extern(C) int printf(char*, ...);
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Fiber Entry Point and Context Switch
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
@@ -2450,6 +2484,22 @@
|
|
ret;
|
|
}
|
|
}
|
|
+ else version( LLVM_AsmX86_Posix )
|
|
+ {
|
|
+ asm
|
|
+ {
|
|
+ // clobber registers to save
|
|
+ inc EBX;
|
|
+ inc ESI;
|
|
+ inc EDI;
|
|
+
|
|
+ // store oldp again with more accurate address
|
|
+ mov EAX, oldp;
|
|
+ mov [EAX], ESP;
|
|
+ // load newp to begin context switch
|
|
+ mov ESP, newp;
|
|
+ }
|
|
+ }
|
|
else static if( is( ucontext_t ) )
|
|
{
|
|
Fiber cfib = Fiber.getThis();
|
|
@@ -3115,6 +3165,16 @@
|
|
push( 0x00000000 ); // ESI
|
|
push( 0x00000000 ); // EDI
|
|
}
|
|
+ else version( LLVM_AsmX86_Posix )
|
|
+ {
|
|
+ push( cast(size_t) &fiber_entryPoint ); // EIP
|
|
+ push( 0x00000000 ); // newp
|
|
+ push( 0x00000000 ); // oldp
|
|
+ push( 0x00000000 ); // EBP
|
|
+ push( 0x00000000 ); // EBX
|
|
+ push( 0x00000000 ); // ESI
|
|
+ push( 0x00000000 ); // EDI
|
|
+ }
|
|
else version( AsmPPC_Posix )
|
|
{
|
|
version( StackGrowsDown )
|
|
Index: lib/unittest.sh
|
|
===================================================================
|
|
--- lib/unittest.sh (revision 4002)
|
|
+++ lib/unittest.sh (working copy)
|
|
@@ -18,8 +18,9 @@
|
|
--help: This message
|
|
--run-all: Reports result instead of breaking. Do not use this if you want to
|
|
run unittest runner through a debugger.
|
|
- dmd: Builds unittests for dmd
|
|
- gdc: Builds unittests for gdc
|
|
+ dmd: Builds unittests for dmd
|
|
+ gdc: Builds unittests for gdc
|
|
+ ldc: Builds unittests for ldc
|
|
|
|
<none>: Builds unittests for all known compilers.'
|
|
exit 0
|
|
@@ -86,7 +87,7 @@
|
|
void main() {}
|
|
EOF
|
|
|
|
- rebuild -w -d -g -L-ldl -L-lz -L-lbz2 -debug=UnitTest -debug -full -clean -unittest \
|
|
+ rebuild -w -d -L-ldl -L-lz -L-lbz2 -debug=UnitTest -debug -full -clean -unittest \
|
|
-version=UnitTest $EXE.d tango/core/*.d tango/core/sync/*.d tango/io/digest/*.d \
|
|
tango/io/model/*.d tango/io/protocol/*.d tango/io/selector/*.d tango/io/*.d \
|
|
tango/io/vfs/*.d tango/io/vfs/model/*.d \
|
|
@@ -125,6 +126,9 @@
|
|
gdc)
|
|
GDC=1
|
|
;;
|
|
+ ldc)
|
|
+ LDC=1
|
|
+ ;;
|
|
*)
|
|
usage
|
|
;;
|
|
@@ -132,10 +136,11 @@
|
|
shift
|
|
done
|
|
|
|
-if [ ! "$DMD" -a ! "$GDC" ]
|
|
+if [ ! "$DMD" -a ! "$GDC" -a ! "$LDC" ]
|
|
then
|
|
DMD=1
|
|
GDC=1
|
|
+ LDC=1
|
|
fi
|
|
|
|
if [ "$DMD" = "1" ]
|
|
@@ -146,4 +151,7 @@
|
|
then
|
|
compile gdc runUnitTest_gdc
|
|
fi
|
|
-
|
|
+if [ "$LDC" = "1" ]
|
|
+then
|
|
+ compile ldc runUnitTest_ldc
|
|
+fi
|
|
Index: lib/gc/basic/gcx.d
|
|
===================================================================
|
|
--- lib/gc/basic/gcx.d (revision 4002)
|
|
+++ lib/gc/basic/gcx.d (working copy)
|
|
@@ -65,6 +65,13 @@
|
|
}
|
|
|
|
|
|
+struct BlkInfo
|
|
+{
|
|
+ void* base;
|
|
+ size_t size;
|
|
+ uint attr;
|
|
+}
|
|
+
|
|
private
|
|
{
|
|
enum BlkAttr : uint
|
|
@@ -75,13 +82,6 @@
|
|
ALL_BITS = 0b1111_1111
|
|
}
|
|
|
|
- struct BlkInfo
|
|
- {
|
|
- void* base;
|
|
- size_t size;
|
|
- uint attr;
|
|
- }
|
|
-
|
|
extern (C) void* rt_stackBottom();
|
|
extern (C) void* rt_stackTop();
|
|
|
|
@@ -2178,6 +2178,28 @@
|
|
__builtin_unwind_init();
|
|
sp = & sp;
|
|
}
|
|
+ else version(LDC)
|
|
+ {
|
|
+ version(X86)
|
|
+ {
|
|
+ uint eax,ecx,edx,ebx,ebp,esi,edi;
|
|
+ asm
|
|
+ {
|
|
+ mov eax[EBP], EAX ;
|
|
+ mov ecx[EBP], ECX ;
|
|
+ mov edx[EBP], EDX ;
|
|
+ mov ebx[EBP], EBX ;
|
|
+ mov ebp[EBP], EBP ;
|
|
+ mov esi[EBP], ESI ;
|
|
+ mov edi[EBP], EDI ;
|
|
+ mov sp[EBP],ESP ;
|
|
+ }
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ static assert( false, "Architecture not supported." );
|
|
+ }
|
|
+ }
|
|
else
|
|
{
|
|
asm
|
|
@@ -2191,6 +2213,10 @@
|
|
{
|
|
// nothing to do
|
|
}
|
|
+ else version(LDC)
|
|
+ {
|
|
+ // nothing to do
|
|
+ }
|
|
else
|
|
{
|
|
asm
|
|
Index: lib/gc/basic/gcbits.d
|
|
===================================================================
|
|
--- lib/gc/basic/gcbits.d (revision 4002)
|
|
+++ lib/gc/basic/gcbits.d (working copy)
|
|
@@ -39,6 +39,10 @@
|
|
{
|
|
// use the unoptimized version
|
|
}
|
|
+else version(LDC)
|
|
+{
|
|
+ // ditto
|
|
+}
|
|
else version (D_InlineAsm_X86)
|
|
{
|
|
version = Asm86;
|
|
Index: lib/build-tango.sh
|
|
===================================================================
|
|
--- lib/build-tango.sh (revision 4002)
|
|
+++ lib/build-tango.sh (working copy)
|
|
@@ -23,7 +23,7 @@
|
|
--debug: Will enable debug info
|
|
--warn: Will enable warnings
|
|
--verbose: Increase verbosity
|
|
- <identifier> is one of {dmd, gdc, mac} and will build libtango.a,
|
|
+ <identifier> is one of {dmd, gdc, ldc, mac} and will build libtango.a,
|
|
libgtango.a or universal Mac binaries respectively
|
|
|
|
The script must be called from within lib/ and the resulting
|
|
@@ -105,7 +105,7 @@
|
|
if filter $OBJNAME
|
|
then
|
|
if [ $VERBOSE == 1 ]; then echo "[$DC] $FILENAME"; fi
|
|
- $DC $WARN -c $INLINE $DEBUG $RELEASE -version=Posix -version=Tango -of$OBJNAME $FILENAME
|
|
+ $DC $WARN -c $INLINE $DEBUG $RELEASE -version=Tango -of$OBJNAME $FILENAME
|
|
if [ "$?" != 0 ]
|
|
then
|
|
return 1;
|
|
@@ -189,6 +189,9 @@
|
|
gdc)
|
|
build gdmd libgtango.a libgphobos.a
|
|
;;
|
|
+ ldc)
|
|
+ build ldc libtango-user-ldc.a build-tango.sh
|
|
+ ;;
|
|
mac)
|
|
# build Universal Binary version of the Tango library
|
|
build powerpc-apple-darwin8-gdmd libgtango.a.ppc libgphobos.a.ppc
|
|
Index: tango/text/convert/Layout.d
|
|
===================================================================
|
|
--- tango/text/convert/Layout.d (revision 4002)
|
|
+++ tango/text/convert/Layout.d (working copy)
|
|
@@ -47,6 +47,12 @@
|
|
alias void* Arg;
|
|
alias va_list ArgList;
|
|
}
|
|
+else version(LDC)
|
|
+ {
|
|
+ private import tango.core.Vararg;
|
|
+ alias void* Arg;
|
|
+ alias va_list ArgList;
|
|
+ }
|
|
else
|
|
{
|
|
alias void* Arg;
|
|
@@ -197,9 +203,18 @@
|
|
assert (formatStr, "null format specifier");
|
|
assert (arguments.length < 64, "too many args in Layout.convert");
|
|
|
|
- version (GNU)
|
|
+ version (LDC)
|
|
{
|
|
Arg[64] arglist = void;
|
|
+ foreach (i, arg; arguments)
|
|
+ {
|
|
+ arglist[i] = args;
|
|
+ args += (arg.tsize + size_t.sizeof - 1) & ~ (size_t.sizeof - 1);
|
|
+ }
|
|
+ }
|
|
+ else version (GNU)
|
|
+ {
|
|
+ Arg[64] arglist = void;
|
|
int[64] intargs = void;
|
|
byte[64] byteargs = void;
|
|
long[64] longargs = void;
|
|
Index: tango/net/cluster/CacheInvalidator.d
|
|
===================================================================
|
|
--- tango/net/cluster/CacheInvalidator.d (revision 4002)
|
|
+++ tango/net/cluster/CacheInvalidator.d (working copy)
|
|
@@ -79,7 +79,7 @@
|
|
|
|
*******************************************************************************/
|
|
|
|
-private class InvalidatorPayload : NetworkMessage
|
|
+package class InvalidatorPayload : NetworkMessage
|
|
{
|
|
private char[] key_;
|
|
|
|
Index: tango/core/Vararg.d
|
|
===================================================================
|
|
--- tango/core/Vararg.d (revision 4002)
|
|
+++ tango/core/Vararg.d (working copy)
|
|
@@ -15,6 +15,10 @@
|
|
{
|
|
public import std.stdarg;
|
|
}
|
|
+else version( LDC )
|
|
+{
|
|
+ public import ldc.vararg;
|
|
+}
|
|
else
|
|
{
|
|
/**
|
|
Index: tango/core/sync/Semaphore.d
|
|
===================================================================
|
|
--- tango/core/sync/Semaphore.d (revision 3979)
|
|
+++ tango/core/sync/Semaphore.d (working copy)
|
|
@@ -329,7 +329,8 @@
|
|
{
|
|
synchronized( synComplete )
|
|
{
|
|
- if( numComplete == numConsumers )
|
|
+ // if( numComplete == numConsumers )
|
|
+ if( numComplete == numToProduce )
|
|
break;
|
|
}
|
|
Thread.yield();
|
|
@@ -337,9 +338,9 @@
|
|
|
|
synchronized( synComplete )
|
|
{
|
|
- assert( numComplete == numConsumers );
|
|
+ assert( numComplete == numToProduce );
|
|
+ // assert( numComplete == numConsumers );
|
|
}
|
|
-
|
|
synchronized( synConsumed )
|
|
{
|
|
assert( numConsumed == numToProduce );
|
|
@@ -400,7 +401,8 @@
|
|
|
|
unittest
|
|
{
|
|
+ version(darwin){}else{
|
|
testWait();
|
|
- testWaitTimeout();
|
|
+ testWaitTimeout();}
|
|
}
|
|
}
|
|
Index: tango/core/sync/Condition.d
|
|
===================================================================
|
|
--- tango/core/sync/Condition.d (revision 3979)
|
|
+++ tango/core/sync/Condition.d (working copy)
|
|
@@ -553,8 +553,11 @@
|
|
|
|
unittest
|
|
{
|
|
+ version(darwin){}
|
|
+ else{
|
|
testNotify();
|
|
testNotifyAll();
|
|
testWaitTimeout();
|
|
+ }
|
|
}
|
|
}
|
|
Index: tango/core/Atomic.d
|
|
===================================================================
|
|
--- tango/core/Atomic.d (revision 4002)
|
|
+++ tango/core/Atomic.d (working copy)
|
|
@@ -270,6 +270,167 @@
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
+// LDC Atomics Implementation
|
|
+////////////////////////////////////////////////////////////////////////////////
|
|
+
|
|
+
|
|
+else version( LDC )
|
|
+{
|
|
+ import ldc.intrinsics;
|
|
+
|
|
+
|
|
+ ////////////////////////////////////////////////////////////////////////////
|
|
+ // Atomic Load
|
|
+ ////////////////////////////////////////////////////////////////////////////
|
|
+
|
|
+
|
|
+ template atomicLoad( msync ms = msync.seq, T )
|
|
+ {
|
|
+ T atomicLoad(ref T val)
|
|
+ {
|
|
+ llvm_memory_barrier(
|
|
+ ms == msync.hlb || ms == msync.acq || ms == msync.seq,
|
|
+ ms == msync.hsb || ms == msync.acq || ms == msync.seq,
|
|
+ ms == msync.slb || ms == msync.rel || ms == msync.seq,
|
|
+ ms == msync.ssb || ms == msync.rel || ms == msync.seq,
|
|
+ false);
|
|
+ static if (isPointerType!(T))
|
|
+ {
|
|
+ return cast(T)llvm_atomic_load_add!(size_t)(cast(size_t*)&val, 0);
|
|
+ }
|
|
+ else static if (is(T == bool))
|
|
+ {
|
|
+ return llvm_atomic_load_add!(ubyte)(cast(ubyte*)&val, cast(ubyte)0) ? 1 : 0;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ return llvm_atomic_load_add!(T)(&val, cast(T)0);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+
|
|
+ ////////////////////////////////////////////////////////////////////////////
|
|
+ // Atomic Store
|
|
+ ////////////////////////////////////////////////////////////////////////////
|
|
+
|
|
+
|
|
+ template atomicStore( msync ms = msync.seq, T )
|
|
+ {
|
|
+ void atomicStore( ref T val, T newval )
|
|
+ {
|
|
+ llvm_memory_barrier(
|
|
+ ms == msync.hlb || ms == msync.acq || ms == msync.seq,
|
|
+ ms == msync.hsb || ms == msync.acq || ms == msync.seq,
|
|
+ ms == msync.slb || ms == msync.rel || ms == msync.seq,
|
|
+ ms == msync.ssb || ms == msync.rel || ms == msync.seq,
|
|
+ false);
|
|
+ static if (isPointerType!(T))
|
|
+ {
|
|
+ llvm_atomic_swap!(size_t)(cast(size_t*)&val, cast(size_t)newval);
|
|
+ }
|
|
+ else static if (is(T == bool))
|
|
+ {
|
|
+ llvm_atomic_swap!(ubyte)(cast(ubyte*)&val, newval?1:0);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ llvm_atomic_swap!(T)(&val, newval);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+
|
|
+ ////////////////////////////////////////////////////////////////////////////
|
|
+ // Atomic Store If
|
|
+ ////////////////////////////////////////////////////////////////////////////
|
|
+
|
|
+
|
|
+ template atomicStoreIf( msync ms = msync.seq, T )
|
|
+ {
|
|
+ bool atomicStoreIf( ref T val, T newval, T equalTo )
|
|
+ {
|
|
+ llvm_memory_barrier(
|
|
+ ms == msync.hlb || ms == msync.acq || ms == msync.seq,
|
|
+ ms == msync.hsb || ms == msync.acq || ms == msync.seq,
|
|
+ ms == msync.slb || ms == msync.rel || ms == msync.seq,
|
|
+ ms == msync.ssb || ms == msync.rel || ms == msync.seq,
|
|
+ false);
|
|
+ T oldval = void;
|
|
+ static if (isPointerType!(T))
|
|
+ {
|
|
+ oldval = cast(T)llvm_atomic_cmp_swap!(size_t)(cast(size_t*)&val, cast(size_t)equalTo, cast(size_t)newval);
|
|
+ }
|
|
+ else static if (is(T == bool))
|
|
+ {
|
|
+ oldval = llvm_atomic_cmp_swap!(ubyte)(cast(ubyte*)&val, equalTo?1:0, newval?1:0)?0:1;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ oldval = llvm_atomic_cmp_swap!(T)(&val, equalTo, newval);
|
|
+ }
|
|
+ return oldval == equalTo;
|
|
+ }
|
|
+ }
|
|
+
|
|
+
|
|
+ ////////////////////////////////////////////////////////////////////////////
|
|
+ // Atomic Increment
|
|
+ ////////////////////////////////////////////////////////////////////////////
|
|
+
|
|
+
|
|
+ template atomicIncrement( msync ms = msync.seq, T )
|
|
+ {
|
|
+ //
|
|
+ // NOTE: This operation is only valid for integer or pointer types
|
|
+ //
|
|
+ static assert( isValidNumericType!(T) );
|
|
+
|
|
+
|
|
+ T atomicIncrement( ref T val )
|
|
+ {
|
|
+ static if (isPointerType!(T))
|
|
+ {
|
|
+ llvm_atomic_load_add!(size_t)(cast(size_t*)&val, 1);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ llvm_atomic_load_add!(T)(&val, cast(T)1);
|
|
+ }
|
|
+ return val;
|
|
+ }
|
|
+ }
|
|
+
|
|
+
|
|
+ ////////////////////////////////////////////////////////////////////////////
|
|
+ // Atomic Decrement
|
|
+ ////////////////////////////////////////////////////////////////////////////
|
|
+
|
|
+
|
|
+ template atomicDecrement( msync ms = msync.seq, T )
|
|
+ {
|
|
+ //
|
|
+ // NOTE: This operation is only valid for integer or pointer types
|
|
+ //
|
|
+ static assert( isValidNumericType!(T) );
|
|
+
|
|
+
|
|
+ T atomicDecrement( ref T val )
|
|
+ {
|
|
+ static if (isPointerType!(T))
|
|
+ {
|
|
+ llvm_atomic_load_sub!(size_t)(cast(size_t*)&val, 1);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ llvm_atomic_load_sub!(T)(&val, cast(T)1);
|
|
+ }
|
|
+ return val;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+////////////////////////////////////////////////////////////////////////////////
|
|
// x86 Atomic Function Implementation
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
@@ -282,9 +598,9 @@
|
|
{
|
|
pragma( msg, "tango.core.Atomic: using IA-32 inline asm" );
|
|
}
|
|
-
|
|
+ version(darwin){}
|
|
+ else { version = Has64BitCAS; }
|
|
version = Has32BitOps;
|
|
- version = Has64BitCAS;
|
|
}
|
|
version( X86_64 )
|
|
{
|
|
Index: tango/math/IEEE.d
|
|
===================================================================
|
|
--- tango/math/IEEE.d (revision 3979)
|
|
+++ tango/math/IEEE.d (working copy)
|
|
@@ -1543,7 +1543,12 @@
|
|
else return 0;
|
|
}
|
|
} else {
|
|
- assert(0, "Unsupported");
|
|
+ static if (is(X==real)){
|
|
+ static assert(0, X.stringof~" unsupported by feqrel");
|
|
+ } else {
|
|
+ int res=feqrel(cast(real)x,cast(real)y);
|
|
+ return ((res>X.mant_dig)?X.mant_dig:res);
|
|
+ }
|
|
}
|
|
}
|
|
|
|
Index: tango/math/Math.d
|
|
===================================================================
|
|
--- tango/math/Math.d (revision 4002)
|
|
+++ tango/math/Math.d (working copy)
|
|
@@ -76,6 +76,14 @@
|
|
version = DigitalMars_D_InlineAsm_X86;
|
|
}
|
|
}
|
|
+else version(LDC)
|
|
+{
|
|
+ import ldc.intrinsics;
|
|
+ version(X86)
|
|
+ {
|
|
+ version = LDC_X86;
|
|
+ }
|
|
+}
|
|
|
|
/*
|
|
* Constants
|
|
@@ -298,6 +306,24 @@
|
|
* Bugs:
|
|
* Results are undefined if |x| >= $(POWER 2,64).
|
|
*/
|
|
+version(LDC)
|
|
+{
|
|
+ alias llvm_cos_f32 cos;
|
|
+ alias llvm_cos_f64 cos;
|
|
+ version(X86)
|
|
+ {
|
|
+ alias llvm_cos_f80 cos;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ real cos(real x)
|
|
+ {
|
|
+ return tango.stdc.math.cosl(x);
|
|
+ }
|
|
+ }
|
|
+}
|
|
+else
|
|
+{
|
|
real cos(real x) /* intrinsic */
|
|
{
|
|
version(D_InlineAsm_X86)
|
|
@@ -313,6 +339,7 @@
|
|
return tango.stdc.math.cosl(x);
|
|
}
|
|
}
|
|
+}
|
|
|
|
debug(UnitTest) {
|
|
unittest {
|
|
@@ -333,6 +360,24 @@
|
|
* Bugs:
|
|
* Results are undefined if |x| >= $(POWER 2,64).
|
|
*/
|
|
+version(LDC)
|
|
+{
|
|
+ alias llvm_sin_f32 sin;
|
|
+ alias llvm_sin_f64 sin;
|
|
+ version(X86)
|
|
+ {
|
|
+ alias llvm_sin_f80 sin;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ real sin(real x)
|
|
+ {
|
|
+ return tango.stdc.math.sinl(x);
|
|
+ }
|
|
+ }
|
|
+}
|
|
+else
|
|
+{
|
|
real sin(real x) /* intrinsic */
|
|
{
|
|
version(D_InlineAsm_X86)
|
|
@@ -348,6 +393,7 @@
|
|
return tango.stdc.math.sinl(x);
|
|
}
|
|
}
|
|
+}
|
|
|
|
debug(UnitTest) {
|
|
unittest {
|
|
@@ -374,7 +420,11 @@
|
|
{
|
|
version (GNU) {
|
|
return tanl(x);
|
|
- } else {
|
|
+ }
|
|
+ else version(LDC) {
|
|
+ return tango.stdc.math.tanl(x);
|
|
+ }
|
|
+ else {
|
|
asm
|
|
{
|
|
fld x[EBP] ; // load theta
|
|
@@ -947,6 +997,25 @@
|
|
* <tr> <td> +∞ <td> +∞ <td> no
|
|
* )
|
|
*/
|
|
+version(LDC)
|
|
+{
|
|
+ alias llvm_sqrt_f32 sqrt;
|
|
+ alias llvm_sqrt_f64 sqrt;
|
|
+ version(X86)
|
|
+ {
|
|
+ alias llvm_sqrt_f80 sqrt;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ real sqrt(real x)
|
|
+ {
|
|
+ return tango.stdc.math.sqrtl(x);
|
|
+ }
|
|
+ }
|
|
+}
|
|
+else
|
|
+{
|
|
+
|
|
float sqrt(float x) /* intrinsic */
|
|
{
|
|
version(D_InlineAsm_X86)
|
|
@@ -995,6 +1064,8 @@
|
|
}
|
|
}
|
|
|
|
+}
|
|
+
|
|
/** ditto */
|
|
creal sqrt(creal z)
|
|
{
|
|
@@ -1477,7 +1548,14 @@
|
|
}
|
|
}
|
|
}
|
|
- return tango.stdc.math.powl(x, y);
|
|
+ version(LDC_X86)
|
|
+ {
|
|
+ return llvm_pow_f80(x, y);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ return tango.stdc.math.powl(x, y);
|
|
+ }
|
|
}
|
|
|
|
debug(UnitTest) {
|
|
Index: tango/stdc/posix/sys/types.d
|
|
===================================================================
|
|
--- tango/stdc/posix/sys/types.d (revision 3979)
|
|
+++ tango/stdc/posix/sys/types.d (working copy)
|
|
@@ -422,7 +422,11 @@
|
|
}
|
|
else version( darwin )
|
|
{
|
|
- struct pthread_spinlock_t;
|
|
+ version (LDC)
|
|
+ alias void* pthread_spinlock_t;
|
|
+
|
|
+ else
|
|
+ struct pthread_spinlock_t;
|
|
}
|
|
else version( freebsd )
|
|
{
|
|
Index: tango/stdc/stdlib.d
|
|
===================================================================
|
|
--- tango/stdc/stdlib.d (revision 4002)
|
|
+++ tango/stdc/stdlib.d (working copy)
|
|
@@ -94,6 +94,11 @@
|
|
{
|
|
void* alloca(size_t size);
|
|
}
|
|
+else version( LDC )
|
|
+{
|
|
+ pragma(alloca)
|
|
+ void* alloca(size_t size);
|
|
+}
|
|
else version( GNU )
|
|
{
|
|
private import gcc.builtins;
|
|
Index: tango/stdc/stdarg.d
|
|
===================================================================
|
|
--- tango/stdc/stdarg.d (revision 4002)
|
|
+++ tango/stdc/stdarg.d (working copy)
|
|
@@ -13,6 +13,10 @@
|
|
{
|
|
public import std.c.stdarg;
|
|
}
|
|
+else version( LDC )
|
|
+{
|
|
+ public import ldc.cstdarg;
|
|
+}
|
|
else
|
|
{
|
|
alias void* va_list;
|