view runtime/ldc.diff @ 842:e66c627c177e

Update tango patch for newest tango.
author Christian Kamm <kamm incasoftware de>
date Mon, 08 Dec 2008 17:09:13 +0100
parents 43178a913a28
children 0ffa92f4ac99
line wrap: on
line source
Index: lib/unittest.sh
===================================================================
--- lib/unittest.sh	(revision 4150)
+++ 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/common/tango/core/BitManip.d
===================================================================
--- lib/common/tango/core/BitManip.d	(revision 4150)
+++ 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 4150)
+++ lib/common/tango/core/Thread.d	(working copy)
@@ -273,8 +273,50 @@
         }
         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 version (X86_64)
+                {
+                    ulong rax,rbx,rcx,rdx,rbp,rsi,rdi,rsp,r10,r11,r12,r13,r14,r15;
+                    asm
+                    {
+                        movq rax[RBP], RAX        ;
+                        movq rbx[RBP], RBX        ;
+                        movq rcx[RBP], RCX        ;
+                        movq rdx[RBP], RDX        ;
+                        movq rbp[RBP], RBP        ;
+                        movq rsi[RBP], RSI        ;
+                        movq rdi[RBP], RDI        ;
+                        movq rsp[RBP], RSP        ;
+                        movq r10[RBP], R10        ;
+                        movq r11[RBP], R11        ;
+                        movq r12[RBP], R12        ;
+                        movq r13[RBP], R13        ;
+                        movq r14[RBP], R14        ;
+                        movq r15[RBP], R15        ;
+                    }
+                }
+                else
+                {
+                    static assert( false, "Architecture not supported." );
+                }
+            }
+            else version( D_InlineAsm_X86 )
+            {
                 asm
                 {
                     pushad;
@@ -330,8 +372,12 @@
                 }
             }
 
-            version( D_InlineAsm_X86 )
+            version( LDC)
             {
+                // nothing to pop
+            }
+            else version( D_InlineAsm_X86 )
+            {
                 asm
                 {
                     popad;
@@ -2347,6 +2393,18 @@
         version( Posix )
             version = AsmPPC_Posix;
     }
+    version( LLVM_InlineAsm_X86 ) 
+    {
+        version( Win32 )
+            version = LLVM_AsmX86_Win32;
+        else version( Posix )
+            version = LLVM_AsmX86_Posix;
+    }
+    else version( LLVM_InlineAsm_X86_64 )
+    {
+        version( Posix )
+            version = LLVM_AsmX86_64_Posix;
+    }
 
     version( Posix )
     {
@@ -2357,6 +2415,10 @@
         version( AsmX86_Win32 ) {} else
         version( AsmX86_Posix ) {} else
         version( AsmPPC_Posix ) {} else
+        version( LLVM_AsmX86_Win32 ) {} else
+        version( LLVM_AsmX86_Posix ) {} else
+//TODO: Enable when x86-64 Posix supports fibers
+//        version( LLVM_AsmX86_64_Posix ) {} else
         {
             // NOTE: The ucontext implementation requires architecture specific
             //       data definitions to operate so testing for it must be done
@@ -2510,6 +2572,28 @@
                 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;
+            }
+        }
+/+
+        version( LLVM_AsmX86_64_Posix )
+        {
+            //TODO: Fiber implementation here
+        }
++/
         else static if( is( ucontext_t ) )
         {
             Fiber   cfib = Fiber.getThis();
@@ -2522,7 +2606,7 @@
     }
 }
 
-
+extern(C) int printf(char*, ...);
 ////////////////////////////////////////////////////////////////////////////////
 // Fiber
 ////////////////////////////////////////////////////////////////////////////////
@@ -3255,6 +3339,22 @@
             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
+        }
+//TODO: Implement x86-64 fibers
+/+
+        else version( LLVM_AsmX86_Posix )
+        {
+        }
++/
         else version( AsmPPC_Posix )
         {
             version( StackGrowsDown )
Index: lib/gc/basic/gcx.d
===================================================================
--- lib/gc/basic/gcx.d	(revision 4150)
+++ 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,49 @@
             __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 version (X86_64)
+            {
+                ulong rax,rbx,rcx,rdx,rbp,rsi,rdi,rsp,r10,r11,r12,r13,r14,r15;
+                asm
+                {
+                    movq rax[RBP], RAX      ;
+                    movq rbx[RBP], RBX      ;
+                    movq rcx[RBP], RCX      ;
+                    movq rdx[RBP], RDX      ;
+                    movq rbp[RBP], RBP      ;
+                    movq rsi[RBP], RSI      ;
+                    movq rdi[RBP], RDI      ;
+                    movq rsp[RBP], RSP      ;
+                    movq r10[RBP], R10      ;
+                    movq r11[RBP], R11      ;
+                    movq r12[RBP], R12      ;
+                    movq r13[RBP], R13      ;
+                    movq r14[RBP], R14      ;
+                    movq r15[RBP], R15      ;
+                }
+            }
+            else
+            {
+                static assert( false, "Architecture not supported." );
+            }
+        }
         else
         {
         asm
@@ -2191,6 +2234,10 @@
         {
             // nothing to do
         }
+        else version(LDC)
+        {
+            // nothing to do
+        }
         else
         {
         asm
Index: lib/gc/basic/gcbits.d
===================================================================
--- lib/gc/basic/gcbits.d	(revision 4150)
+++ 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 4150)
+++ 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 4150)
+++ 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;
@@ -295,7 +301,7 @@
                         foreach (i, arg; arguments)
                                 {
                                 arglist[i] = args;
-                                args += (arg.tsize + int.sizeof - 1) & ~ (int.sizeof - 1);
+                                args += (arg.tsize + size_t.sizeof - 1) & ~ (size_t.sizeof - 1);
                                 }
                         }
                 return parse (formatStr, arguments, arglist, sink);
Index: tango/net/cluster/CacheInvalidator.d
===================================================================
--- tango/net/cluster/CacheInvalidator.d	(revision 4150)
+++ 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 4150)
+++ 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 4150)
+++ tango/core/sync/Semaphore.d	(working copy)
@@ -384,7 +384,8 @@
             {
                 synchronized( synComplete )
                 {
-                    if( numComplete == numConsumers )
+                    // if( numComplete == numConsumers )
+                    if( numComplete == numToProduce )
                         break;
                 }
                 Thread.yield();
@@ -392,9 +393,9 @@
 
             synchronized( synComplete )
             {
-                assert( numComplete == numConsumers );
+                assert( numComplete == numToProduce );
+                // assert( numComplete == numConsumers );
             }
-
             synchronized( synConsumed )
             {
                 assert( numConsumed == numToProduce );
@@ -455,7 +456,8 @@
 
     unittest
     {
+        version(darwin){}else{
         testWait();
-        testWaitTimeout();
+        testWaitTimeout();}
     }
 }
Index: tango/core/sync/Condition.d
===================================================================
--- tango/core/sync/Condition.d	(revision 4150)
+++ 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 4150)
+++ 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
 ////////////////////////////////////////////////////////////////////////////////
 
Index: tango/math/IEEE.d
===================================================================
--- tango/math/IEEE.d	(revision 4150)
+++ tango/math/IEEE.d	(working copy)
@@ -1554,7 +1554,12 @@
         return (bitsdiff == 0 && !((pa[F.EXPPOS_SHORT] ^ pb[F.EXPPOS_SHORT])& F.EXPMASK)) ? 1 : 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 4150)
+++ 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> +&infin; <td> +&infin; <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 4150)
+++ 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 4150)
+++ 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 4150)
+++ 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;