Index: src/rt/adi.d
===================================================================
--- src/rt/adi.d	(revision 433)
+++ src/rt/adi.d	(working copy)
@@ -276,13 +276,12 @@
 
     int[] a = new int[5];
     int[] b;
-    size_t i;
 
-    for (i = 0; i < 5; i++)
+    for (auto i = 0; i < 5; i++)
         a[i] = i;
     b = a.reverse;
     assert(b is a);
-    for (i = 0; i < 5; i++)
+    for (auto i = 0; i < 5; i++)
         assert(a[i] == 4 - i);
 
     struct X20
@@ -294,13 +293,13 @@
     X20[] c = new X20[5];
     X20[] d;
 
-    for (i = 0; i < 5; i++)
+    for (auto i = 0; i < 5; i++)
     {   c[i].a = i;
         c[i].e = 10;
     }
     d = c.reverse;
     assert(d is c);
-    for (i = 0; i < 5; i++)
+    for (auto i = 0; i < 5; i++)
     {
         assert(c[i].a == 4 - i);
         assert(c[i].e == 10);
Index: src/rt/lifetime.d
===================================================================
--- src/rt/lifetime.d	(revision 435)
+++ src/rt/lifetime.d	(working copy)
@@ -801,21 +801,15 @@
  */
 void[] _d_newarrayOpT(alias op)(TypeInfo ti, size_t ndims, va_list q)
 {
-    void[] result;
-
     debug(PRINTF) printf("_d_newarrayOpT(ndims = %d)\n", ndims);
     if (ndims == 0)
-        result = null;
+        return null;
     else
     {
         void[] foo(TypeInfo ti, va_list ap, size_t ndims)
         {
-            version(X86)
-                auto dim = va_arg!(size_t)(ap);
-            else version(X86_64)
-                static assert(false, "not implemented");
-            else
-                static assert(false, "platform not supported");
+            size_t dim;
+            va_arg(ap, dim);
 
             debug(PRINTF) printf("foo(ti = %p, ti.next = %p, dim = %d, ndims = %d\n", ti, ti.next, dim, ndims);
             if (ndims == 1)
@@ -831,9 +825,19 @@
                 __setArrayAllocLength(info, allocsize, isshared);
                 auto p = __arrayStart(info)[0 .. dim];
 
+                version(X86)
+                {
+                    va_list ap2;
+                    va_copy(ap2, ap);
+                }
                 for (size_t i = 0; i < dim; i++)
                 {
-                    (cast(void[]*)p.ptr)[i] = foo(ti.next, ap, ndims - 1);
+                    version(X86_64)
+                    {
+                        __va_list argsave = *cast(__va_list*)ap;
+                        va_list ap2 = &argsave;
+                    }
+                    (cast(void[]*)p.ptr)[i] = foo(ti.next, ap2, ndims - 1);
                 }
                 return p;
             }
@@ -847,13 +851,15 @@
             {
                 printf("index %d: %ul\n", i, va_arg!(size_t)(q2));
             }
+            va_end(q2);
         }
 
-        result = foo(ti, q, ndims);
+        auto result = foo(ti, q, ndims);
         debug(PRINTF) printf("result = %llx\n", result);
         va_end(q);
+
+        return result;
     }
-    return result;    
 }
 
 
@@ -885,7 +891,7 @@
  */
 extern (C) void[] _d_newarraymiT(TypeInfo ti, size_t ndims, ...)
 {
-    debug(PRINTF) printf("_d_newarraymT(ndims = %d)\n", ndims);
+    debug(PRINTF) printf("_d_newarraymiT(ndims = %d)\n", ndims);
     
     if (ndims == 0)
         return null;
@@ -1617,7 +1623,7 @@
     }
     else
     {
-        static assert(false, "unknown version");
+        static assert(false, "platform not supported");
     }
 }
 
@@ -1781,8 +1787,7 @@
         for (auto i = 0; i < n; i++)
         {
             byte[] b;
-            pragma(msg, "broken");
-            //va_arg(ap, b);
+            va_arg(ap, b);
             length += b.length;
         }
         va_end(ap);
@@ -1818,8 +1823,7 @@
         for (auto i = 0; i < n; i++)
         {
             byte[] b;
-            pragma(msg, "broken");
-            //va_arg(ap2, b);
+            va_arg(ap2, b);
             if (b.length)
             {
                 memcpy(a + j, b.ptr, b.length * size);
Index: src/core/stdc/stdarg.d
===================================================================
--- src/core/stdc/stdarg.d	(revision 433)
+++ src/core/stdc/stdarg.d	(working copy)
@@ -1,12 +1,14 @@
 /**
- * D header file for C99.
- *
- * Copyright: Copyright Sean Kelly 2005 - 2009.
- * License:   <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
- * Authors:   Sean Kelly
- * Standards: ISO/IEC 9899:1999 (E)
- *
- *          Copyright Sean Kelly 2005 - 2009.
+ * C's &lt;stdarg.h&gt;
+ * This is for use with extern(C) variable argument lists.
+ * Authors: Hauke Duden and Walter Bright, Digital Mars, http://www.digitalmars.com
+ * License: Public Domain
+ * Source: $(PHOBOSSRC std/c/_stdarg.d)
+ * Macros:
+ *      WIKI=Phobos/StdCStdarg
+ */
+
+/*          Copyright Digital Mars 2000 - 2009.
  * Distributed under the Boost Software License, Version 1.0.
  *    (See accompanying file LICENSE_1_0.txt or copy at
  *          http://www.boost.org/LICENSE_1_0.txt)
@@ -17,33 +19,322 @@
 
 version( X86 )
 {
+    /*********************
+     * The argument pointer type.
+     */
     alias void* va_list;
 
-    template va_start( T )
+    /**********
+     * Initialize ap.
+     * For 32 bit code, parmn should be the last named parameter.
+     * For 64 bit code, parmn should be __va_argsave.
+     */
+    void va_start(T)(out va_list ap, ref T parmn)
     {
-        void va_start( out va_list ap, ref T parmn )
+        ap = cast(va_list)( cast(void*) &parmn + ( ( T.sizeof + int.sizeof - 1 ) & ~( int.sizeof - 1 ) ) );
+    }
+
+    /************
+     * Retrieve and return the next value that is type T.
+     * Should use the other va_arg instead, as this won't work for 64 bit code.
+     */
+    T va_arg(T)(ref va_list ap)
+    {
+        T arg = *cast(T*) ap;
+        ap = cast(va_list)( cast(void*) ap + ( ( T.sizeof + int.sizeof - 1 ) & ~( int.sizeof - 1 ) ) );
+        return arg;
+    }
+
+    /************
+     * Retrieve and return the next value that is type T.
+     * This is the preferred version.
+     */
+    void va_arg(T)(ref va_list ap, ref T parmn)
+    {
+        parmn = *cast(T*)ap;
+        ap = cast(va_list)(cast(void*)ap + ((T.sizeof + int.sizeof - 1) & ~(int.sizeof - 1)));
+    }
+
+    /*************
+     * Retrieve and store through parmn the next value that is of TypeInfo ti.
+     * Used when the static type is not known.
+     */
+    void va_arg()(ref va_list ap, TypeInfo ti, void* parmn)
+    {
+        // Wait until everyone updates to get TypeInfo.talign()
+        //auto talign = ti.talign();
+        //auto p = cast(void*)(cast(size_t)ap + talign - 1) & ~(talign - 1);
+        auto p = ap;
+        auto tsize = ti.tsize();
+        ap = cast(void*)(cast(size_t)p + ((tsize + size_t.sizeof - 1) & ~(size_t.sizeof - 1)));
+        parmn[0..tsize] = p[0..tsize];
+    }
+
+    /***********************
+     * End use of ap.
+     */
+    void va_end(va_list ap)
+    {
+    }
+
+    void va_copy(out va_list dest, va_list src)
+    {
+        dest = src;
+    }
+}
+else version (X86_64)
+{
+    // Layout of this struct must match __gnuc_va_list for C ABI compatibility
+    struct __va_list
+    {
+        uint offset_regs = 6 * 8;            // no regs
+        uint offset_fpregs = 6 * 8 + 8 * 16; // no fp regs
+        void* stack_args;
+        void* reg_args;
+    }
+
+    struct __va_argsave_t
+    {
+        size_t[6] regs;   // RDI,RSI,RDX,RCX,R8,R9
+        real[8] fpregs;   // XMM0..XMM7
+        __va_list va;
+    }
+
+    /*
+     * Making it an array of 1 causes va_list to be passed as a pointer in
+     * function argument lists
+     */
+    alias void* va_list;
+
+    void va_start(T)(out va_list ap, ref T parmn)
+    {
+        ap = &parmn.va;
+    }
+
+    T va_arg(T)(va_list ap)
+    {   T a;
+        va_arg(ap, a);
+        return a;
+    }
+
+    void va_arg(T)(va_list apx, ref T parmn)
+    {
+        __va_list* ap = cast(__va_list*)apx;
+        static if (is(T U == __argTypes))
         {
-            ap = cast(va_list)( cast(void*) &parmn + ( ( T.sizeof + int.sizeof - 1 ) & ~( int.sizeof - 1 ) ) );
+            static if (U.length == 0 || T.sizeof > 16 || U[0].sizeof > 8)
+            {   // Always passed in memory
+                // The arg may have more strict alignment than the stack
+                auto p = (cast(size_t)ap.stack_args + T.alignof - 1) & ~(T.alignof - 1);
+                ap.stack_args = cast(void*)(p + ((T.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1)));
+                parmn = *cast(T*)p;
+            }
+            else static if (U.length == 1)
+            {   // Arg is passed in one register
+                alias U[0] T1;
+                static if (is(T1 == double) || is(T1 == float))
+                {   // Passed in XMM register
+                    if (ap.offset_fpregs < (6 * 8 + 16 * 8))
+                    {
+                        parmn = *cast(T*)(ap.reg_args + ap.offset_fpregs);
+                        ap.offset_fpregs += 16;
+                    }
+                    else
+                    {
+                        parmn = *cast(T*)ap.stack_args;
+                        ap.stack_args += (T1.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1);
+                    }
+                }
+                else
+                {   // Passed in regular register
+                    if (ap.offset_regs < 6 * 8 && T.sizeof <= 8)
+                    {
+                        parmn = *cast(T*)(ap.reg_args + ap.offset_regs);
+                        ap.offset_regs += 8;
+                    }
+                    else
+                    {
+                        auto p = (cast(size_t)ap.stack_args + T.alignof - 1) & ~(T.alignof - 1);
+                        ap.stack_args = cast(void*)(p + ((T.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1)));
+                        parmn = *cast(T*)p;
+                    }
+                }
+            }
+            else static if (U.length == 2)
+            {   // Arg is passed in two registers
+                alias U[0] T1;
+                alias U[1] T2;
+
+                static if (is(T1 == double) || is(T1 == float))
+                {
+                    if (ap.offset_fpregs < (6 * 8 + 16 * 8))
+                    {
+                        *cast(T1*)&parmn = *cast(T1*)(ap.reg_args + ap.offset_fpregs);
+                        ap.offset_fpregs += 16;
+                    }
+                    else
+                    {
+                        *cast(T1*)&parmn = *cast(T1*)ap.stack_args;
+                        ap.stack_args += (T1.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1);
+                    }
+                }
+                else
+                {
+                    if (ap.offset_regs < 6 * 8 && T1.sizeof <= 8)
+                    {
+                        *cast(T1*)&parmn = *cast(T1*)(ap.reg_args + ap.offset_regs);
+                        ap.offset_regs += 8;
+                    }
+                    else
+                    {
+                        *cast(T1*)&parmn = *cast(T1*)ap.stack_args;
+                        ap.stack_args += 8;
+                    }
+                }
+
+                auto p = cast(void*)&parmn + 8;
+                static if (is(T2 == double) || is(T2 == float))
+                {
+                    if (ap.offset_fpregs < (6 * 8 + 16 * 8))
+                    {
+                        *cast(T2*)p = *cast(T2*)(ap.reg_args + ap.offset_fpregs);
+                        ap.offset_fpregs += 16;
+                    }
+                    else
+                    {
+                        *cast(T2*)p = *cast(T2*)ap.stack_args;
+                        ap.stack_args += (T2.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1);
+                    }
+                }
+                else
+                {
+                    void* a = void;
+                    if (ap.offset_regs < 6 * 8 && T2.sizeof <= 8)
+                    {
+                        a = ap.reg_args + ap.offset_regs;
+                        ap.offset_regs += 8;
+                    }
+                    else
+                    {
+                        a = ap.stack_args;
+                        ap.stack_args += 8;
+                    }
+                    // Be careful not to go past the size of the actual argument
+                    const sz2 = T.sizeof - 8;
+                    p[0..sz2] = a[0..sz2];
+                }
+            }
+            else
+            {
+                static assert(0);
+            }
         }
+        else
+        {
+            static assert(0, "not a valid argument type for va_arg");
+        }
     }
 
-    template va_arg( T )
+    void va_arg()(va_list apx, TypeInfo ti, void* parmn)
     {
-        T va_arg( ref va_list ap )
+        __va_list* ap = cast(__va_list*)apx;
+        TypeInfo arg1, arg2;
+        if (!ti.argTypes(arg1, arg2))
         {
-            T arg = *cast(T*) ap;
-            ap = cast(va_list)( cast(void*) ap + ( ( T.sizeof + int.sizeof - 1 ) & ~( int.sizeof - 1 ) ) );
-            return arg;
+            if (arg1 && arg1.tsize() <= 8)
+            {   // Arg is passed in one register
+                auto tsize = arg1.tsize();
+                void* p;
+                auto s = arg1.toString();
+                if (s == "double" || s == "float")
+                {   // Passed in XMM register
+                    if (ap.offset_fpregs < (6 * 8 + 16 * 8))
+                    {
+                        p = ap.reg_args + ap.offset_fpregs;
+                        ap.offset_fpregs += 16;
+                    }
+                    else
+                    {
+                        p = ap.stack_args;
+                        ap.stack_args += (tsize + size_t.sizeof - 1) & ~(size_t.sizeof - 1);
+                    }
+                }
+                else
+                {   // Passed in regular register
+                    if (ap.offset_regs < 6 * 8)
+                    {
+                        p = ap.reg_args + ap.offset_regs;
+                        ap.offset_regs += 8;
+                    }
+                    else
+                    {
+                        p = ap.stack_args;
+                        ap.stack_args += 8;
+                    }
+                }
+                parmn[0..tsize] = p[0..tsize];
+
+                if (arg2)
+                {
+                    parmn += 8;
+                    tsize = arg2.tsize();
+                    s = arg2.toString();
+                    if (s == "double" || s == "float")
+                    {   // Passed in XMM register
+                        if (ap.offset_fpregs < (6 * 8 + 16 * 8))
+                        {
+                            p = ap.reg_args + ap.offset_fpregs;
+                            ap.offset_fpregs += 16;
+                        }
+                        else
+                        {
+                            p = ap.stack_args;
+                            ap.stack_args += (tsize + size_t.sizeof - 1) & ~(size_t.sizeof - 1);
+                        }
+                    }
+                    else
+                    {   // Passed in regular register
+                        if (ap.offset_regs < 6 * 8)
+                        {
+                            p = ap.reg_args + ap.offset_regs;
+                            ap.offset_regs += 8;
+                        }
+                        else
+                        {
+                            p = ap.stack_args;
+                            ap.stack_args += 8;
+                        }
+                    }
+                    tsize = ti.tsize() - 8;
+                    parmn[0..tsize] = p[0..tsize];
+                }
+            }
+            else
+            {   // Always passed in memory
+                // The arg may have more strict alignment than the stack
+                auto talign = ti.talign();
+                auto tsize = ti.tsize();
+                auto p = cast(void*)((cast(size_t)ap.stack_args + talign - 1) & ~(talign - 1));
+                ap.stack_args = cast(void*)(cast(size_t)p + ((tsize + size_t.sizeof - 1) & ~(size_t.sizeof - 1)));
+                parmn[0..tsize] = p[0..tsize];
+            }
         }
+        else
+        {
+            assert(0, "not a valid argument type for va_arg");
+        }
     }
 
-    void va_end( va_list ap )
+    void va_end(va_list ap)
     {
-
     }
 
-    void va_copy( out va_list dest, va_list src )
+    void va_copy(out va_list dest, va_list src)
     {
         dest = src;
     }
 }
+else
+{
+    static assert(0, "Unsupported platform");
+}
Index: src/core/vararg.d
===================================================================
--- src/core/vararg.d	(revision 433)
+++ src/core/vararg.d	(working copy)
@@ -16,7 +16,6 @@
  */
 module core.vararg;
 
-
 version( X86 )
 {
     /**
@@ -24,7 +23,6 @@
      */
     alias void* va_list;
 
-
     /**
      * This function initializes the supplied argument pointer for subsequent
      * use by va_arg and va_end.
@@ -68,10 +66,8 @@
      */
     void va_end( va_list ap )
     {
-
     }
 
-
     /**
      * This function copied the argument pointer src to dst.
      *
@@ -84,3 +80,8 @@
         dst = src;
     }
 }
+else
+{
+    public import core.stdc.stdarg;
+}
+
