view runtime/llvmdc.diff @ 540:9312024a7053

Gah, missed something still. I'll test properly next time ;)
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Sun, 24 Aug 2008 17:13:40 +0200
parents 795e972e17ce
children 52ab8f3130d9
line wrap: on
line source

Index: object.di
===================================================================
--- object.di	(revision 3899)
+++ 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/unittest.sh
===================================================================
--- lib/unittest.sh	(revision 3899)
+++ 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
+  llvmdc: Builds unittests for llvmdc
 
   <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
             ;;
+        llvmdc)
+            LLVMDC=1
+            ;;
         *)
             usage
             ;;
@@ -132,10 +136,11 @@
     shift
 done
 
-if [ ! "$DMD" -a ! "$GDC" ]
+if [ ! "$DMD" -a ! "$GDC" -a ! "$LLVMDC" ]
 then
     DMD=1
     GDC=1
+    LLVMDC=1
 fi
 
 if [ "$DMD" = "1" ]
@@ -146,4 +151,7 @@
 then
     compile gdc runUnitTest_gdc
 fi
-
+if [ "$LLVMDC" = "1" ]
+then
+    compile llvmdc runUnitTest_llvmdc
+fi
Index: lib/common/tango/core/BitManip.d
===================================================================
--- lib/common/tango/core/BitManip.d	(revision 3899)
+++ lib/common/tango/core/BitManip.d	(working copy)
@@ -171,6 +171,10 @@
      */
     uint outpl( uint port_address, uint value );
 }
+else version( LLVMDC )
+{
+    public import llvmdc.bitmanip;
+}
 else
 {
     public import std.intrinsic;
Index: lib/common/tango/core/Thread.d
===================================================================
--- lib/common/tango/core/Thread.d	(revision 3899)
+++ lib/common/tango/core/Thread.d	(working copy)
@@ -244,8 +244,29 @@
         }
         body
         {
-            version( D_InlineAsm_X86 )
+            version( LLVMDC)
             {
+                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;
@@ -297,8 +318,12 @@
                 }
             }
 
-            version( D_InlineAsm_X86 )
+            version( LLVMDC)
             {
+                // nothing to pop
+            }
+            else version( D_InlineAsm_X86 )
+            {
                 asm
                 {
                     popad;
Index: lib/gc/basic/gcx.d
===================================================================
--- lib/gc/basic/gcx.d	(revision 3899)
+++ lib/gc/basic/gcx.d	(working copy)
@@ -2178,6 +2178,28 @@
             __builtin_unwind_init();
             sp = & sp;
         }
+        else version(LLVMDC)
+        {
+            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(LLVMDC)
+        {
+            // nothing to do
+        }
         else
         {
         asm
Index: lib/gc/basic/gcbits.d
===================================================================
--- lib/gc/basic/gcbits.d	(revision 3899)
+++ lib/gc/basic/gcbits.d	(working copy)
@@ -39,6 +39,10 @@
 {
     // use the unoptimized version
 }
+else version(LLVMDC)
+{
+    // ditto
+}
 else version (D_InlineAsm_X86)
 {
     version = Asm86;
Index: tango/text/convert/Layout.d
===================================================================
--- tango/text/convert/Layout.d	(revision 3899)
+++ tango/text/convert/Layout.d	(working copy)
@@ -47,6 +47,12 @@
         alias void* Arg;
         alias va_list ArgList;
         }
+else version(LLVMDC)
+        {
+        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 (LLVMDC)
                         {
                         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/core/Vararg.d
===================================================================
--- tango/core/Vararg.d	(revision 3899)
+++ tango/core/Vararg.d	(working copy)
@@ -15,6 +15,10 @@
 {
     public import std.stdarg;
 }
+else version( LLVMDC )
+{
+    public import llvmdc.vararg;
+}
 else
 {
     /**
Index: tango/core/Atomic.d
===================================================================
--- tango/core/Atomic.d	(revision 3899)
+++ tango/core/Atomic.d	(working copy)
@@ -270,6 +270,161 @@
 
 
 ////////////////////////////////////////////////////////////////////////////////
+// LLVMDC Atomics Implementation
+////////////////////////////////////////////////////////////////////////////////
+
+
+else version( LLVMDC )
+{
+    import llvmdc.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
+            {
+                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))
+            {
+                return cast(T)llvm_atomic_load_add!(size_t)(cast(size_t*)&val, 1);
+            }
+            else
+            {
+                return llvm_atomic_load_add!(T)(&val, cast(T)1);
+            }
+        }
+    }
+    
+    
+    ////////////////////////////////////////////////////////////////////////////
+    // 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))
+            {
+                return cast(T)llvm_atomic_load_sub!(size_t)(cast(size_t*)&val, 1);
+            }
+            else
+            {
+                return llvm_atomic_load_sub!(T)(&val, cast(T)1);
+            }
+        }
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
 // x86 Atomic Function Implementation
 ////////////////////////////////////////////////////////////////////////////////
 
Index: tango/math/Math.d
===================================================================
--- tango/math/Math.d	(revision 3899)
+++ tango/math/Math.d	(working copy)
@@ -76,6 +76,14 @@
         version = DigitalMars_D_InlineAsm_X86;
     }
 }
+else version(LLVMDC)
+{
+    import llvmdc.intrinsics;
+    version(X86)
+    {
+        version = LLVMDC_X86;
+    }
+}
 
 /*
  * Constants
@@ -298,6 +306,24 @@
  * Bugs:
  *  Results are undefined if |x| >= $(POWER 2,64).
  */
+version(LLVMDC)
+{
+    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(LLVMDC)
+{
+    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(LLVMDC) {
+        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(LLVMDC)
+{
+    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(LLVMDC_X86)
+    {
+        return llvm_pow_f80(x, y);
+    }
+    else
+    {
+        return tango.stdc.math.powl(x, y);
+    }
 }
 
 debug(UnitTest) {
Index: tango/math/internal/BignumX86.d
===================================================================
--- tango/math/internal/BignumX86.d	(revision 3899)
+++ tango/math/internal/BignumX86.d	(working copy)
@@ -50,6 +50,8 @@
 private:
 version(GNU) {
     // GDC is a filthy liar. It can't actually do inline asm.
+} else version(LLVMDC) {
+    // I guess the same goes for llvmdc to some extent :(
 } else version(D_InlineAsm_X86) {
 /* Duplicate string s, with n times, substituting index for '@'.
  *
Index: tango/math/internal/BiguintCore.d
===================================================================
--- tango/math/internal/BiguintCore.d	(revision 3899)
+++ tango/math/internal/BiguintCore.d	(working copy)
@@ -12,7 +12,10 @@
 } else version(GNU) {
     // GDC lies about its X86 support
 private import tango.math.internal.BignumNoAsm;    
-} else version(D_InlineAsm_X86) { 
+} else version(LLVMDC) {
+    // I guess llvmdc does too :(
+private import tango.math.internal.BignumNoAsm;    
+} else version(D_InlineAsm_X86) {
 private import tango.math.internal.BignumX86;
 } else {
 private import tango.math.internal.BignumNoAsm;
Index: tango/stdc/stdlib.d
===================================================================
--- tango/stdc/stdlib.d	(revision 3899)
+++ tango/stdc/stdlib.d	(working copy)
@@ -94,6 +94,11 @@
 {
     void* alloca(size_t size);
 }
+else version( LLVMDC )
+{
+    pragma(alloca)
+        void* alloca(size_t size);
+}
 else version( GNU )
 {
     private import gcc.builtins;
Index: tango/stdc/stdarg.d
===================================================================
--- tango/stdc/stdarg.d	(revision 3899)
+++ tango/stdc/stdarg.d	(working copy)
@@ -13,6 +13,10 @@
 {
     public import std.c.stdarg;
 }
+else version( LLVMDC )
+{
+    public import llvmdc.cstdarg;
+}
 else
 {
     alias void* va_list;