changeset 445:cc40db549aea

Changed the handling of variadic intrinsics a bit. Removed the -fp80 option and made real be 80bit floats on X86, this is what the D spec really says it should be and fixes a bunch of issues. Changed the handling of parameter attributes to a bit more generalized approach. Added sext/zext attributes for byte/short/ubyte/ushort parameters, fixes #60 . Parameter attribs now properly set for intrinsic calls if necessary. Made the tango.math.Math patch less intrusive. Fixed/added some mini tests.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Fri, 01 Aug 2008 17:59:58 +0200
parents f2b5f86348ef
children 7a67dedbf933
files dmd/attrib.c dmd/cond.c dmd/declaration.h dmd/id.c dmd/id.h dmd/idgen.c dmd/mars.c dmd/mars.h dmd/mtype.c dmd/mtype.h gen/complex.cpp gen/d-asm-i386.h gen/enums.h gen/functions.cpp gen/llvm.h gen/llvmhelpers.cpp gen/runtime.cpp gen/tocall.cpp gen/toir.cpp gen/tollvm.cpp gen/tollvm.h import/llvmdc/cstdarg.di import/llvmdc/intrinsics.di llvmdc-tango llvmdc.kdevelop runtime/llvmdc.diff tests/mini/intrinsics.d tests/mini/marray3.d tests/mini/packed1.d tests/mini/real1.d tests/mini/sextzext.d tests/mini/vararg6.d
diffstat 32 files changed, 418 insertions(+), 532 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/attrib.c	Fri Aug 01 01:12:33 2008 +0200
+++ b/dmd/attrib.c	Fri Aug 01 17:59:58 2008 +0200
@@ -831,7 +831,7 @@
 // LLVMDC
 #if IN_LLVM
 
-    // pragma(intrinsic, dotExpS) { funcdecl(s) }
+    // pragma(intrinsic, string) { funcdecl(s) }
     else if (ident == Id::intrinsic)
     {
         Expression* expr = (Expression *)args->data[0];
@@ -844,19 +844,6 @@
         llvm_internal = LLVMintrinsic;
     }
 
-    // pragma(va_intrinsic, dotExpS) { funcdecl(s) }
-    else if (ident == Id::va_intrinsic)
-    {
-        Expression* expr = (Expression *)args->data[0];
-        expr = expr->semantic(sc);
-        if (!args || args->dim != 1 || !parseStringExp(expr, arg1str))
-        {
-             error("pragma va_intrinsic requires exactly 1 string literal parameter");
-             fatal();
-        }
-        llvm_internal = LLVMva_intrinsic;
-    }
-
     // pragma(notypeinfo) { typedecl(s) }
     else if (ident == Id::no_typeinfo)
     {
@@ -880,7 +867,7 @@
     }
 
     // pragma(alloca) { funcdecl(s) }
-    else if (ident == Id::alloca)
+    else if (ident == Id::Alloca)
     {
         if (args && args->dim > 0)
         {
@@ -891,7 +878,7 @@
     }
 
     // pragma(va_start) { templdecl(s) }
-    else if (ident == Id::va_start)
+    else if (ident == Id::vastart)
     {
         if (args && args->dim > 0)
         {
@@ -901,8 +888,30 @@
         llvm_internal = LLVMva_start;
     }
 
+    // pragma(va_copy) { funcdecl(s) }
+    else if (ident == Id::vacopy)
+    {
+        if (args && args->dim > 0)
+        {
+             error("pragma va_copy takes no parameters");
+             fatal();
+        }
+        llvm_internal = LLVMva_copy;
+    }
+
+    // pragma(va_end) { funcdecl(s) }
+    else if (ident == Id::vaend)
+    {
+        if (args && args->dim > 0)
+        {
+             error("pragma va_end takes no parameters");
+             fatal();
+        }
+        llvm_internal = LLVMva_end;
+    }
+
     // pragma(va_arg) { templdecl(s) }
-    else if (ident == Id::va_arg)
+    else if (ident == Id::vaarg)
     {
         if (args && args->dim > 0)
         {
@@ -959,13 +968,12 @@
         {
         if (s->llvmInternal)
         {
-            error("multiple LLVMDC specific pragmas not allowed not affect the same declaration (%s at '%s')", s->toChars(), s->loc.toChars());
+            error("multiple LLVMDC specific pragmas not allowed not affect the same declaration ('%s' at '%s')", s->toChars(), s->loc.toChars());
             fatal();
         }
         switch(llvm_internal)
         {
         case LLVMintrinsic:
-        case LLVMva_intrinsic:
             if (FuncDeclaration* fd = s->isFuncDeclaration())
             {
                 fd->llvmInternal = llvm_internal;
@@ -973,7 +981,7 @@
             }
             else
             {
-                error("intrinsic pragmas are only allowed to affect function declarations");
+                error("the intrinsic pragma is only allowed on function declarations");
                 fatal();
             }
             break;
@@ -984,24 +992,37 @@
             {
                 if (td->parameters->dim != 1)
                 {
-                    error("the %s pragma template must have exactly one template parameter", ident->toChars());
+                    error("the '%s' pragma template must have exactly one template parameter", ident->toChars());
                     fatal();
                 }
                 else if (!td->onemember)
                 {
-                    error("the %s pragma template must have exactly one member", ident->toChars());
+                    error("the '%s' pragma template must have exactly one member", ident->toChars());
                     fatal();
                 }
                 else if (td->overnext || td->overroot)
                 {
-                    error("the %s pragma template must not be overloaded", ident->toChars());
+                    error("the '%s' pragma template must not be overloaded", ident->toChars());
                     fatal();
                 }
                 td->llvmInternal = llvm_internal;
             }
             else
             {
-                error("the %s pragma is only allowed on template declarations", ident->toChars());
+                error("the '%s' pragma is only allowed on template declarations", ident->toChars());
+                fatal();
+            }
+            break;
+
+        case LLVMva_copy:
+        case LLVMva_end:
+            if (FuncDeclaration* fd = s->isFuncDeclaration())
+            {
+                fd->llvmInternal = llvm_internal;
+            }
+            else
+            {
+                error("the '%s' pragma is only allowed on function declarations", ident->toChars());
                 fatal();
             }
             break;
@@ -1017,13 +1038,13 @@
             }
             else
             {
-                error("the %s pragma must only be used on function declarations of type 'void* function(uint nbytes)'", ident->toChars());
+                error("the '%s' pragma must only be used on function declarations of type 'void* function(uint nbytes)'", ident->toChars());
                 fatal();
             }
             break;
 
         default:
-            warning("LLVMDC specific pragma %s not yet implemented, ignoring", ident->toChars());
+            warning("the LLVMDC specific pragma '%s' is not yet implemented, ignoring", ident->toChars());
         }
         }
 
--- a/dmd/cond.c	Fri Aug 01 01:12:33 2008 +0200
+++ b/dmd/cond.c	Fri Aug 01 17:59:58 2008 +0200
@@ -127,8 +127,7 @@
 {
     static char* reserved[] =
     {
-	"DigitalMars", "LLVM", "LLVMDC",
-    "LLVM64", "LLVM_X86_FP80",
+	"DigitalMars", "LLVM", "LLVMDC", "LLVM64",
     "X86", "X86_64", "PPC", "PPC64",
 	"Windows", "Win32", "Win64",
 	"linux",
--- a/dmd/declaration.h	Fri Aug 01 01:12:33 2008 +0200
+++ b/dmd/declaration.h	Fri Aug 01 17:59:58 2008 +0200
@@ -642,6 +642,9 @@
     std::set<VarDeclaration*> nestedVars;
     std::string intrinsicName;
 
+    bool isIntrinsic();
+    bool isVaIntrinsic();
+
     // we keep our own table of label statements as LabelDsymbolS
     // don't always carry their corresponding statement along ...
     typedef std::map<const char*, LabelStatement*> LabelMap;
--- a/dmd/id.c	Fri Aug 01 01:12:33 2008 +0200
+++ b/dmd/id.c	Fri Aug 01 17:59:58 2008 +0200
@@ -171,9 +171,11 @@
 Identifier *Id::va_intrinsic;
 Identifier *Id::no_typeinfo;
 Identifier *Id::no_moduleinfo;
-Identifier *Id::alloca;
-Identifier *Id::va_start;
-Identifier *Id::va_arg;
+Identifier *Id::Alloca;
+Identifier *Id::vastart;
+Identifier *Id::vacopy;
+Identifier *Id::vaend;
+Identifier *Id::vaarg;
 Identifier *Id::tohash;
 Identifier *Id::tostring;
 Identifier *Id::main;
@@ -350,9 +352,11 @@
     va_intrinsic = Lexer::idPool("va_intrinsic");
     no_typeinfo = Lexer::idPool("no_typeinfo");
     no_moduleinfo = Lexer::idPool("no_moduleinfo");
-    alloca = Lexer::idPool("alloca");
-    va_start = Lexer::idPool("va_start");
-    va_arg = Lexer::idPool("va_arg");
+    Alloca = Lexer::idPool("alloca");
+    vastart = Lexer::idPool("va_start");
+    vacopy = Lexer::idPool("va_copy");
+    vaend = Lexer::idPool("va_end");
+    vaarg = Lexer::idPool("va_arg");
     tohash = Lexer::idPool("toHash");
     tostring = Lexer::idPool("toString");
     main = Lexer::idPool("main");
--- a/dmd/id.h	Fri Aug 01 01:12:33 2008 +0200
+++ b/dmd/id.h	Fri Aug 01 17:59:58 2008 +0200
@@ -173,9 +173,11 @@
     static Identifier *va_intrinsic;
     static Identifier *no_typeinfo;
     static Identifier *no_moduleinfo;
-    static Identifier *alloca;
-    static Identifier *va_start;
-    static Identifier *va_arg;
+    static Identifier *Alloca;
+    static Identifier *vastart;
+    static Identifier *vacopy;
+    static Identifier *vaend;
+    static Identifier *vaarg;
     static Identifier *tohash;
     static Identifier *tostring;
     static Identifier *main;
--- a/dmd/idgen.c	Fri Aug 01 01:12:33 2008 +0200
+++ b/dmd/idgen.c	Fri Aug 01 17:59:58 2008 +0200
@@ -218,9 +218,11 @@
     { "va_intrinsic" },
     { "no_typeinfo" },
     { "no_moduleinfo" },
-    { "alloca" },
-    { "va_start" },
-    { "va_arg" },
+    { "Alloca", "alloca" },
+    { "vastart", "va_start" },
+    { "vacopy", "va_copy" },
+    { "vaend", "va_end" },
+    { "vaarg", "va_arg" },
 
     // For toHash/toString
     { "tohash", "toHash" },
--- a/dmd/mars.c	Fri Aug 01 01:12:33 2008 +0200
+++ b/dmd/mars.c	Fri Aug 01 17:59:58 2008 +0200
@@ -178,7 +178,6 @@
   -debuglib=name    set symbolic debug library to name\n\
   -defaultlib=name  set default library to name\n\
   -dis           disassemble module after compiling\n\
-  -fp80          enable 80bit reals on x86 32bit (EXPERIMENTAL)\n\
   -g             add symbolic debug info\n\
   -gc            add symbolic debug info, pretend to be C\n\
   -H             generate 'header' file\n\
@@ -407,8 +406,6 @@
             global.params.disassemble = 1;
         else if (strcmp(p + 1, "annotate") == 0)
             global.params.llvmAnnotate = 1;
-        else if (strcmp(p + 1, "fp80") == 0)
-            global.params.useFP80 = 1;
         else if (strcmp(p + 1, "noasm") == 0)
             global.params.useInlineAsm = 0;
 	    else if (p[1] == 'o')
@@ -697,20 +694,20 @@
         findDefaultTarget();
     }
 
-    bool is_x86 = false;
     if (strcmp(global.params.llvmArch,"x86")==0) {
         VersionCondition::addPredefinedGlobalIdent("X86");
-        //VersionCondition::addPredefinedGlobalIdent("LLVM_InlineAsm_X86");
         global.params.isLE = true;
         global.params.is64bit = false;
         global.params.cpu = ARCHx86;
         tt_arch = "i686";
         data_layout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-f80:32:32-v64:64:64-v128:128:128-a0:0:64";
-        is_x86 = true;
+        if (global.params.useInlineAsm) {
+            VersionCondition::addPredefinedGlobalIdent("D_InlineAsm");
+            VersionCondition::addPredefinedGlobalIdent("D_InlineAsm_X86");
+        }
     }
     else if (strcmp(global.params.llvmArch,"x86-64")==0) {
         VersionCondition::addPredefinedGlobalIdent("X86_64");
-        //VersionCondition::addPredefinedGlobalIdent("LLVM_InlineAsm_X86_64");
         global.params.isLE = true;
         global.params.is64bit = true;
         global.params.cpu = ARCHx86_64;
@@ -752,18 +749,6 @@
         VersionCondition::addPredefinedGlobalIdent("LLVM64");
     }
 
-    if (global.params.useFP80) {
-        if (!is_x86) {
-            error("the -fp80 option is only valid for the x86 32bit architecture");
-            fatal();
-        }
-        VersionCondition::addPredefinedGlobalIdent("LLVM_X86_FP80");
-    }
-    if (is_x86 && global.params.useInlineAsm) {
-        VersionCondition::addPredefinedGlobalIdent("D_InlineAsm");
-        VersionCondition::addPredefinedGlobalIdent("D_InlineAsm_X86");
-    }
-
     assert(tt_arch != 0);
     assert(tt_os != 0);
     assert(data_layout != 0);
--- a/dmd/mars.h	Fri Aug 01 01:12:33 2008 +0200
+++ b/dmd/mars.h	Fri Aug 01 17:59:58 2008 +0200
@@ -135,7 +135,6 @@
     char llvmInline;
     char llvmAnnotate;
     char *runtimePath;
-    char useFP80;
     char useInlineAsm;
     char fqnPaths; // use fully qualified object names
 };
--- a/dmd/mtype.c	Fri Aug 01 01:12:33 2008 +0200
+++ b/dmd/mtype.c	Fri Aug 01 17:59:58 2008 +0200
@@ -252,7 +252,7 @@
     }
 
     // set real size and padding
-    if (global.params.useFP80)
+    if (global.params.cpu == ARCHx86)
     {
     REALSIZE = 12;
     REALPAD = 2;
@@ -2653,6 +2653,7 @@
     this->inuse = 0;
     this->llvmRetInPtr = false;
     this->llvmUsesThis = false;
+    this->llvmRetAttrs = 0;
 }
 
 Type *TypeFunction::syntaxCopy()
@@ -2662,6 +2663,7 @@
     TypeFunction *t = new TypeFunction(params, treturn, varargs, linkage);
     t->llvmRetInPtr = llvmRetInPtr;
     t->llvmUsesThis = llvmUsesThis;
+    t->llvmRetAttrs = llvmRetAttrs;
     return t;
 }
 
@@ -5235,7 +5237,7 @@
     this->ident = ident;
     this->storageClass = storageClass;
     this->defaultArg = defaultArg;
-    this->llvmByVal = false;
+    this->llvmAttrs = 0;
 }
 
 Argument *Argument::syntaxCopy()
@@ -5244,7 +5246,7 @@
 		type ? type->syntaxCopy() : NULL,
 		ident,
 		defaultArg ? defaultArg->syntaxCopy() : NULL);
-    a->llvmByVal = llvmByVal;
+    a->llvmAttrs = llvmAttrs;
     return a;
 }
 
--- a/dmd/mtype.h	Fri Aug 01 01:12:33 2008 +0200
+++ b/dmd/mtype.h	Fri Aug 01 17:59:58 2008 +0200
@@ -443,6 +443,7 @@
 
     bool llvmRetInPtr;
     bool llvmUsesThis;
+    unsigned llvmRetAttrs;
 };
 
 struct TypeDelegate : Type
@@ -701,7 +702,7 @@
     static Argument *getNth(Arguments *arguments, size_t nth, size_t *pn = NULL);
 
     // LLVMDC
-    bool llvmByVal;
+    unsigned llvmAttrs;
 };
 
 extern int PTRSIZE;
--- a/gen/complex.cpp	Fri Aug 01 01:12:33 2008 +0200
+++ b/gen/complex.cpp	Fri Aug 01 17:59:58 2008 +0200
@@ -35,7 +35,10 @@
         return LLType::DoubleTy;
     }
     else if (ty == Tcomplex80) {
-        return (global.params.useFP80) ? LLType::X86_FP80Ty : LLType::DoubleTy;
+        if (global.params.cpu == ARCHx86)
+            return LLType::X86_FP80Ty;
+        else
+            return LLType::DoubleTy;
     }
     else {
         assert(0);
@@ -73,7 +76,7 @@
         base = Type::tfloat64;
     }
     else if (ty == Tcomplex80) {
-        base = (global.params.useFP80) ? Type::tfloat80 : Type::tfloat64;
+        base = Type::tfloat80;
     }
 
     std::vector<LLConstant*> inits;
@@ -121,8 +124,8 @@
         baserety = Type::tfloat64;
         baseimty = Type::timaginary64;
     } else if (ty == Tcomplex80) {
-        baserety = global.params.useFP80 ? Type::tfloat80 : Type::tfloat64;
-        baseimty = global.params.useFP80 ? Type::timaginary80 : Type::timaginary64;
+        baserety = Type::tfloat80;
+        baseimty = Type::timaginary80;
     }
 
     if (t->isimaginary()) {
--- a/gen/d-asm-i386.h	Fri Aug 01 01:12:33 2008 +0200
+++ b/gen/d-asm-i386.h	Fri Aug 01 17:59:58 2008 +0200
@@ -2396,10 +2396,7 @@
 	case TOKfloat64v:
 	case TOKfloat80v:
 	    // %% need different types?
-        if (global.params.useFP80)
-	       e = new RealExp(stmt->loc, token->float80value, Type::tfloat80);
-        else
-            e = new RealExp(stmt->loc, token->float80value, Type::tfloat64);
+        e = new RealExp(stmt->loc, token->float80value, Type::tfloat80);
 	    nextToken();
 	    break;
 	case TOKidentifier:
--- a/gen/enums.h	Fri Aug 01 01:12:33 2008 +0200
+++ b/gen/enums.h	Fri Aug 01 17:59:58 2008 +0200
@@ -2,10 +2,11 @@
 {
     LLVMnone,
     LLVMintrinsic,
-    LLVMva_intrinsic,
     LLVMno_typeinfo,
     LLVMno_moduleinfo,
     LLVMalloca,
     LLVMva_start,
+    LLVMva_copy,
+    LLVMva_end,
     LLVMva_arg
 };
--- a/gen/functions.cpp	Fri Aug 01 01:12:33 2008 +0200
+++ b/gen/functions.cpp	Fri Aug 01 17:59:58 2008 +0200
@@ -1,5 +1,6 @@
 #include "gen/llvm.h"
 #include "llvm/Support/CFG.h"
+#include "llvm/Intrinsics.h"
 
 #include "mtype.h"
 #include "aggregate.h"
@@ -62,7 +63,6 @@
     }
     else{
         assert(rt);
-        Type* rtfin = DtoDType(rt);
         if (DtoIsReturnedInArg(rt)) {
             rettype = getPtrToType(DtoType(rt));
             actualRettype = LLType::VoidTy;
@@ -72,6 +72,11 @@
             rettype = DtoType(rt);
             actualRettype = rettype;
         }
+
+        if (unsigned ea = DtoShouldExtend(rt))
+        {
+            f->llvmRetAttrs |= ea;
+        }
     }
 
     if (retinptr) {
@@ -103,8 +108,6 @@
 
     size_t n = Argument::dim(f->parameters);
 
-    int nbyval = 0;
-
     for (int i=0; i < n; ++i) {
         Argument* arg = Argument::getNth(f->parameters, i);
         // ensure scalar
@@ -117,7 +120,8 @@
         if (isaStruct(at)) {
             Logger::println("struct param");
             paramvec.push_back(getPtrToType(at));
-            arg->llvmByVal = !refOrOut;
+            if (!refOrOut)
+                arg->llvmAttrs |= llvm::ParamAttr::ByVal;
         }
         else if (isaArray(at)) {
             // static array are passed by reference
@@ -137,6 +141,10 @@
             }
             else {
                 Logger::println("in param");
+                if (unsigned ea = DtoShouldExtend(argT))
+                {
+                    arg->llvmAttrs |= ea;
+                }
             }
             paramvec.push_back(at);
         }
@@ -151,9 +159,6 @@
             Logger::cout() << "lazy updated to: " << *at << '\n';
             paramvec.back() = at;
         }
-
-        if (arg->llvmByVal)
-            nbyval++;
     }
 
     //warning("set %d byval args for type: %s", nbyval, f->toChars());
@@ -180,27 +185,17 @@
     }
 
     TypeFunction* f = (TypeFunction*)fdecl->type;
-    assert(f != 0);
-
-    const llvm::PointerType* i8pty = getPtrToType(LLType::Int8Ty);
-    std::vector<const LLType*> args;
+    const llvm::FunctionType* fty = 0;
 
-    if (fdecl->llvmInternal == LLVMva_start) {
-        args.push_back(i8pty);
-    }
-    else if (fdecl->llvmInternal == LLVMva_intrinsic) {
-        size_t n = Argument::dim(f->parameters);
-        for (size_t i=0; i<n; ++i) {
-            args.push_back(i8pty);
-        }
-    }
-    else
-    assert(0);
-
-    const llvm::FunctionType* fty = llvm::FunctionType::get(LLType::VoidTy, args, false);
+    if (fdecl->llvmInternal == LLVMva_start)
+        fty = GET_INTRINSIC_DECL(vastart)->getFunctionType();
+    else if (fdecl->llvmInternal == LLVMva_copy)
+        fty = GET_INTRINSIC_DECL(vacopy)->getFunctionType();
+    else if (fdecl->llvmInternal == LLVMva_end)
+        fty = GET_INTRINSIC_DECL(vaend)->getFunctionType();
+    assert(fty);
 
     f->ir.type = new llvm::PATypeHolder(fty);
-
     return fty;
 }
 
@@ -208,14 +203,13 @@
 
 const llvm::FunctionType* DtoFunctionType(FuncDeclaration* fdecl)
 {
-    if ((fdecl->llvmInternal == LLVMva_start) || (fdecl->llvmInternal == LLVMva_intrinsic)) {
+    // handle for C vararg intrinsics
+    if (fdecl->isVaIntrinsic())
         return DtoVaFunctionType(fdecl);
-    }
 
     // type has already been resolved
-    if (fdecl->type->ir.type != 0) {
+    if (fdecl->type->ir.type != 0)
         return llvm::cast<llvm::FunctionType>(fdecl->type->ir.type->get());
-    }
 
     const LLType* thisty = NULL;
     if (fdecl->needThis()) {
@@ -246,22 +240,16 @@
 {
     TypeFunction* f = (TypeFunction*)DtoDType(fdecl->type);
     const llvm::FunctionType* fty = DtoVaFunctionType(fdecl);
-    LLConstant* fn = 0;
+    llvm::Function* func = 0;
 
-    if (fdecl->llvmInternal == LLVMva_start) {
-        fn = gIR->module->getOrInsertFunction("llvm.va_start", fty);
-        assert(fn);
-    }
-    else if (fdecl->llvmInternal == LLVMva_intrinsic) {
-        fn = gIR->module->getOrInsertFunction(fdecl->intrinsicName, fty);
-        assert(fn);
-    }
-    else
-    assert(0);
+    if (fdecl->llvmInternal == LLVMva_start)
+        func = GET_INTRINSIC_DECL(vastart);
+    else if (fdecl->llvmInternal == LLVMva_copy)
+        func = GET_INTRINSIC_DECL(vacopy);
+    else if (fdecl->llvmInternal == LLVMva_end)
+        func = GET_INTRINSIC_DECL(vaend);
+    assert(func);
 
-    llvm::Function* func = llvm::dyn_cast<llvm::Function>(fn);
-    assert(func);
-    assert(func->isIntrinsic());
     fdecl->ir.irFunc->func = func;
     return func;
 }
@@ -330,36 +318,43 @@
     std::vector<llvm::ParamAttrsWithIndex> attrs;
     int k = 0;
 
-    int nbyval = 0;
+    llvm::ParamAttrsWithIndex PAWI;
 
+    // set zext/sext attr on return value if necessary
+    if (f->next->isintegral() && f->next->size() < PTRSIZE)
+    {
+        PAWI.Index = 0;
+        if (f->next->isunsigned())
+            PAWI.Attrs = llvm::ParamAttr::ZExt;
+        else
+            PAWI.Attrs = llvm::ParamAttr::SExt;
+        attrs.push_back(PAWI);
+    }
+
+    // set byval attrs on implicit main arg
     if (fdecl->isMain() && Argument::dim(f->parameters) == 0)
     {
-        llvm::ParamAttrsWithIndex PAWI;
         PAWI.Index = llidx;
         PAWI.Attrs = llvm::ParamAttr::ByVal;
         attrs.push_back(PAWI);
         llidx++;
-        nbyval++;
     }
 
+    // set attrs on the rest of the arguments
     for (; llidx <= funcNumArgs && f->parameters->dim > k; ++llidx,++k)
     {
         Argument* fnarg = (Argument*)f->parameters->data[k];
         assert(fnarg);
-        if (fnarg->llvmByVal)
-        {
-            llvm::ParamAttrsWithIndex PAWI;
-            PAWI.Index = llidx;
-            PAWI.Attrs = llvm::ParamAttr::ByVal;
+
+        PAWI.Index = llidx;
+        PAWI.Attrs = fnarg->llvmAttrs;
+
+        if (PAWI.Attrs)
             attrs.push_back(PAWI);
-            nbyval++;
-        }
     }
 
-    if (nbyval) {
-        llvm::PAListPtr palist = llvm::PAListPtr::get(attrs.begin(), attrs.end());
-        func->setParamAttrs(palist);
-    }
+    llvm::PAListPtr palist = llvm::PAListPtr::get(attrs.begin(), attrs.end());
+    func->setParamAttrs(palist);
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -412,9 +407,8 @@
         mangled_name = fdecl->mangle();
 
     llvm::Function* vafunc = 0;
-    if ((fdecl->llvmInternal == LLVMva_start) || (fdecl->llvmInternal == LLVMva_intrinsic)) {
+    if (fdecl->isVaIntrinsic())
         vafunc = DtoDeclareVaFunction(fdecl);
-    }
 
     // construct function
     const llvm::FunctionType* functype = DtoFunctionType(fdecl);
@@ -437,7 +431,7 @@
     assert(llvm::isa<llvm::FunctionType>(f->ir.type->get()));
 
     // parameter attributes
-    if (f->parameters) {
+    if (f->parameters && !fdecl->isIntrinsic()) {
         set_param_attrs(f, func, fdecl);
     }
 
@@ -812,3 +806,15 @@
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
+
+bool FuncDeclaration::isIntrinsic()
+{
+    return (llvmInternal == LLVMintrinsic || isVaIntrinsic());
+}
+
+bool FuncDeclaration::isVaIntrinsic()
+{
+    return (llvmInternal == LLVMva_start ||
+            llvmInternal == LLVMva_copy ||
+            llvmInternal == LLVMva_end);
+}
--- a/gen/llvm.h	Fri Aug 01 01:12:33 2008 +0200
+++ b/gen/llvm.h	Fri Aug 01 17:59:58 2008 +0200
@@ -10,6 +10,7 @@
 #include "llvm/Function.h"
 #include "llvm/Module.h"
 #include "llvm/Value.h"
+#include "llvm/ParameterAttributes.h"
 
 #include "llvm/Target/TargetData.h"
 
@@ -37,9 +38,12 @@
 #define LLConstantStruct llvm::ConstantStruct
 #define LLConstantArray llvm::ConstantArray
 #define LLConstantInt llvm::ConstantInt
+#define LLConstantFP llvm::ConstantFP
 
 #define LLPATypeHolder llvm::PATypeHolder
 
 #define LLSmallVector llvm::SmallVector
 
+#define APFloat llvm::APFloat
+
 #endif // GEN_LLVM_H
--- a/gen/llvmhelpers.cpp	Fri Aug 01 01:12:33 2008 +0200
+++ b/gen/llvmhelpers.cpp	Fri Aug 01 17:59:58 2008 +0200
@@ -779,11 +779,9 @@
         return DtoComplex(loc, to, val);
     }
     else if (totype->isfloating()) {
-        if ((fromtype->ty == Tfloat80 || fromtype->ty == Tfloat64) && (totype->ty == Tfloat80 || totype->ty == Tfloat64)) {
+        if (fromsz == tosz) {
             rval = val->getRVal();
-        }
-        else if ((fromtype->ty == Timaginary80 || fromtype->ty == Timaginary64) && (totype->ty == Timaginary80 || totype->ty == Timaginary64)) {
-            rval = val->getRVal();
+            assert(rval->getType() == tolltype);
         }
         else if (fromsz < tosz) {
             rval = new llvm::FPExtInst(val->getRVal(), tolltype, "tmp", gIR->scopebb());
--- a/gen/runtime.cpp	Fri Aug 01 01:12:33 2008 +0200
+++ b/gen/runtime.cpp	Fri Aug 01 17:59:58 2008 +0200
@@ -165,7 +165,11 @@
     const LLType* longTy = LLType::Int64Ty;
     const LLType* floatTy = LLType::FloatTy;
     const LLType* doubleTy = LLType::DoubleTy;
-    const LLType* realTy = (global.params.useFP80) ? LLType::X86_FP80Ty : LLType::DoubleTy;
+    const LLType* realTy;
+    if (global.params.cpu == ARCHx86)
+        realTy = LLType::X86_FP80Ty;
+    else
+        realTy = LLType::DoubleTy;
     const LLType* sizeTy = DtoSize_t();
     const LLType* voidPtrTy = rt_ptr(byteTy);
     const LLType* stringTy = rt_array(byteTy);
--- a/gen/tocall.cpp	Fri Aug 01 01:12:33 2008 +0200
+++ b/gen/tocall.cpp	Fri Aug 01 17:59:58 2008 +0200
@@ -173,8 +173,8 @@
         DValue* argval = DtoArgument(fnarg, (Expression*)arguments->data[i]);
         args.push_back(argval->getRVal());
 
-        if (fnarg->llvmByVal)
-            palist = palist.addAttr(argidx, llvm::ParamAttr::ByVal);
+        if (fnarg->llvmAttrs)
+            palist = palist.addAttr(argidx, fnarg->llvmAttrs);
 
         ++argidx;
     }
@@ -189,8 +189,8 @@
     // get func value if any
     DFuncValue* dfnval = fnval->isFunc();
 
-    // handle special va_copy / va_end intrinsics
-    bool va_intrinsic = (dfnval && dfnval->func && (dfnval->func->llvmInternal == LLVMva_intrinsic));
+    // handle special vararg intrinsics
+    bool va_intrinsic = (dfnval && dfnval->func && dfnval->func->isVaIntrinsic());
 
     // get function type info
     TypeFunction* tf = DtoTypeFunction(fnval);
@@ -263,6 +263,9 @@
     // handle the rest of the arguments based on param passing style
     llvm::PAListPtr palist;
 
+    if (tf->llvmRetAttrs)
+        palist = palist.addAttr(0, tf->llvmRetAttrs);
+
     // variadic instrinsics need some custom casts
     if (va_intrinsic)
     {
@@ -293,10 +296,13 @@
             Argument* fnarg = Argument::getNth(tf->parameters, i);
             DValue* argval = DtoArgument(fnarg, (Expression*)arguments->data[i]);
             LLValue* arg = argval->getRVal();
-            if (fnarg && arg->getType() != callableTy->getParamType(j))
-                arg = DtoBitCast(arg, callableTy->getParamType(j));
-            if (fnarg && fnarg->llvmByVal)
-                palist = palist.addAttr(j+1, llvm::ParamAttr::ByVal);
+            if (fnarg)
+            {
+                if (arg->getType() != callableTy->getParamType(j))
+                    arg = DtoBitCast(arg, callableTy->getParamType(j));
+                if (fnarg->llvmAttrs)
+                    palist = palist.addAttr(j+1, fnarg->llvmAttrs);
+            }
             ++argiter;
             args.push_back(arg);
         }
@@ -327,21 +333,17 @@
     if (retllval->getType()->isAbstract())
         retllval = DtoBitCast(retllval, getPtrToType(DtoType(resulttype)), "retval");
 
-    // set calling convention
+    // set calling convention and parameter attributes
     if (dfnval && dfnval->func)
     {
-        int li = dfnval->func->llvmInternal;
-        if (li != LLVMintrinsic && li != LLVMva_start && li != LLVMva_intrinsic)
-        {
+        LLFunction* llfunc = llvm::dyn_cast<LLFunction>(dfnval->val);
+        if (llfunc && llfunc->isIntrinsic())
+            palist = llvm::Intrinsic::getParamAttrs((llvm::Intrinsic::ID)llfunc->getIntrinsicID());
+        else
             call->setCallingConv(callconv);
-        }
     }
     else
-    {
         call->setCallingConv(callconv);
-    }
-
-    // param attrs
     call->setParamAttrs(palist);
 
     return new DImValue(resulttype, retllval, false);
--- a/gen/toir.cpp	Fri Aug 01 01:12:33 2008 +0200
+++ b/gen/toir.cpp	Fri Aug 01 17:59:58 2008 +0200
@@ -288,8 +288,12 @@
         Type* t = DtoDType(type);
         if (t->ty == Tcomplex32)
             c = DtoConstFP(Type::tfloat32, 0);
+        else if (t->ty == Tcomplex64)
+            c = DtoConstFP(Type::tfloat64, 0);
+        else if (t->ty == Tcomplex80)
+            c = DtoConstFP(Type::tfloat80, 0);
         else
-            c = DtoConstFP(Type::tfloat64, 0);
+            assert(0);
         return new DComplexValue(type, c, c);
     }
 
--- a/gen/tollvm.cpp	Fri Aug 01 01:12:33 2008 +0200
+++ b/gen/tollvm.cpp	Fri Aug 01 17:59:58 2008 +0200
@@ -35,6 +35,25 @@
     return (t == Tstruct || t == Tarray || t == Tdelegate || t == Tsarray || typ->iscomplex());
 }
 
+unsigned DtoShouldExtend(Type* type)
+{
+    type = type->toBasetype();
+    if (type->isintegral())
+    {
+        switch(type->ty)
+        {
+        case Tint8:
+        case Tint16:
+            return llvm::ParamAttr::SExt;
+
+        case Tuns8:
+        case Tuns16:
+            return llvm::ParamAttr::ZExt;
+        }
+    }
+    return llvm::ParamAttr::None;
+}
+
 Type* DtoDType(Type* t)
 {
     if (t->ty == Ttypedef) {
@@ -79,7 +98,10 @@
         return LLType::DoubleTy;
     case Tfloat80:
     case Timaginary80:
-        return (global.params.useFP80) ? LLType::X86_FP80Ty : LLType::DoubleTy;
+        if (global.params.cpu == ARCHx86)
+            return LLType::X86_FP80Ty;
+        else
+            return LLType::DoubleTy;
 
     // complex
     case Tcomplex32:
@@ -485,11 +507,9 @@
 
 llvm::ConstantFP* DtoConstFP(Type* t, long double value)
 {
-    TY ty = DtoDType(t)->ty;
-    if (ty == Tfloat32 || ty == Timaginary32)
-        return llvm::ConstantFP::get(llvm::APFloat(float(value)));
-    else if (ty == Tfloat64 || ty == Timaginary64 || ty == Tfloat80 || ty == Timaginary80)
-        return llvm::ConstantFP::get(llvm::APFloat(double(value)));
+    const LLType* llty = DtoType(t);
+    assert(llty->isFloatingPoint());
+    return LLConstantFP::get(llty, value);
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
--- a/gen/tollvm.h	Fri Aug 01 01:12:33 2008 +0200
+++ b/gen/tollvm.h	Fri Aug 01 17:59:58 2008 +0200
@@ -21,6 +21,8 @@
 // returns if the type should be returned in a hidden pointer arguement
 bool DtoIsReturnedInArg(Type* type);
 
+unsigned DtoShouldExtend(Type* type);
+
 // resolve typedefs to their real type.
 // TODO should probably be removed in favor of DMD's Type::toBasetype
 Type* DtoDType(Type* t);
--- a/import/llvmdc/cstdarg.di	Fri Aug 01 01:12:33 2008 +0200
+++ b/import/llvmdc/cstdarg.di	Fri Aug 01 17:59:58 2008 +0200
@@ -22,8 +22,8 @@
 pragma(va_arg)
     T va_arg(T)(va_list ap);
 
-pragma(va_intrinsic, "llvm.va_end")
+pragma(va_end)
     void va_end(va_list args);
 
-pragma(va_intrinsic, "llvm.va_copy")
+pragma(va_copy)
     void va_copy(va_list dst, va_list src);
--- a/import/llvmdc/intrinsics.di	Fri Aug 01 01:12:33 2008 +0200
+++ b/import/llvmdc/intrinsics.di	Fri Aug 01 17:59:58 2008 +0200
@@ -106,7 +106,7 @@
     float llvm_sqrt_f32(float val);
 pragma(intrinsic, "llvm.sqrt.f64")
     double llvm_sqrt_f64(double val);
-version(LLVM_X86_FP80)
+version(X86)
 {
 pragma(intrinsic, "llvm.sqrt.f80")
     real llvm_sqrt_f80(real val);
@@ -119,7 +119,7 @@
     float llvm_sin_f32(float val);
 pragma(intrinsic, "llvm.sin.f64")
     double llvm_sin_f64(double val);
-version(LLVM_X86_FP80)
+version(X86)
 {
 pragma(intrinsic, "llvm.sin.f80")
     real llvm_sin_f80(real val);
@@ -132,7 +132,7 @@
     float llvm_cos_f32(float val);
 pragma(intrinsic, "llvm.cos.f64")
     double llvm_cos_f64(double val);
-version(LLVM_X86_FP80)
+version(X86)
 {
 pragma(intrinsic, "llvm.cos.f80")
     real llvm_cos_f80(real val);
@@ -146,7 +146,7 @@
 
 pragma(intrinsic, "llvm.powi.f64")
     double llvm_powi_f64(double val, int power);
-version(LLVM_X86_FP80)
+version(X86)
 {
 pragma(intrinsic, "llvm.powi.f80")
     real llvm_powi_f80(real val, int power);
@@ -160,7 +160,7 @@
 
 pragma(intrinsic, "llvm.pow.f64")
     double llvm_pow_f64(double val, double power);
-version(LLVM_X86_FP80)
+version(X86)
 {
 pragma(intrinsic, "llvm.pow.f80")
     real llvm_pow_f80(real val, real power);
--- a/llvmdc-tango	Fri Aug 01 01:12:33 2008 +0200
+++ b/llvmdc-tango	Fri Aug 01 17:59:58 2008 +0200
@@ -29,7 +29,6 @@
 testversion=LittleEndian
 testversion=BigEndian
 testversion=LLVM64
-textversion=LLVM_X86_FP80
 
 
 [compile]
--- a/llvmdc.kdevelop	Fri Aug 01 01:12:33 2008 +0200
+++ b/llvmdc.kdevelop	Fri Aug 01 17:59:58 2008 +0200
@@ -406,6 +406,11 @@
       <path>tango-llvmdc/patches/proposals/integrated_locks/lib/compiler/dmd/monitor.c</path>
       <path>tango-llvmdc/patches/proposals/integrated_locks/lib/compiler/gdc</path>
       <path>tango-llvmdc/patches/proposals/integrated_locks/lib/compiler/gdc/monitor.c</path>
+      <path>runtime/build.sh</path>
+      <path>runtime/internal</path>
+      <path>runtime/internal/critical.c</path>
+      <path>runtime/internal/mars.h</path>
+      <path>runtime/internal/monitor.c</path>
     </blacklist>
     <build>
       <buildtool>make</buildtool>
--- a/runtime/llvmdc.diff	Fri Aug 01 01:12:33 2008 +0200
+++ b/runtime/llvmdc.diff	Fri Aug 01 17:59:58 2008 +0200
@@ -209,96 +209,47 @@
 ===================================================================
 --- tango/math/Math.d	(revision 3831)
 +++ tango/math/Math.d	(working copy)
-@@ -76,7 +76,77 @@
+@@ -76,6 +76,14 @@
          version = DigitalMars_D_InlineAsm_X86;
      }
  }
 +else version(LLVMDC)
 +{
-+    private
-+    {
- 
-+    pragma(intrinsic, "llvm.sqrt.f32")
-+        float sqrt(float);
-+    pragma(intrinsic, "llvm.sqrt.f64")
-+        double sqrt(double);
-+
-+    version(LLVM_X86_FP80)
++    import llvmdc.intrinsics;
++    version(X86)
 +    {
-+        alias tango.stdc.math.tanl llvm_tan;
-+        alias tango.stdc.math.acosl llvm_acos;
-+        alias tango.stdc.math.asinl llvm_asin;
-+        alias tango.stdc.math.atanl llvm_atan;
-+        alias tango.stdc.math.atan2l llvm_atan2;
-+        alias tango.stdc.math.coshl llvm_cosh;
-+        alias tango.stdc.math.sinhl llvm_sinh;
-+        alias tango.stdc.math.tanhl llvm_tanh;
-+        alias tango.stdc.math.cbrtl llvm_cbrt;
-+        alias tango.stdc.math.expl llvm_exp;
-+        alias tango.stdc.math.expm1l llvm_expm1;
-+        alias tango.stdc.math.exp2l llvm_exp2;
-+        alias tango.stdc.math.logl llvm_log;
-+        alias tango.stdc.math.log1pl llvm_log1p;
-+        alias tango.stdc.math.log2l llvm_log2;
-+        alias tango.stdc.math.log10l llvm_log10;
-+        alias tango.stdc.math.powl llvm_pow;
-+        alias tango.stdc.math.lrintl llvm_lrint;
-+        alias tango.stdc.math.llrintl llvm_llrint;
-+
-+        pragma(intrinsic, "llvm.cos.f80")
-+            real cos(real);
-+        pragma(intrinsic, "llvm.sin.f80")
-+            real sin(real);
-+        pragma(intrinsic, "llvm.sqrt.f80")
-+            real sqrt(real);
-+    }
-+    else
-+    {
-+        alias tango.stdc.math.tan llvm_tan;
-+        alias tango.stdc.math.acos llvm_acos;
-+        alias tango.stdc.math.asin llvm_asin;
-+        alias tango.stdc.math.atan llvm_atan;
-+        alias tango.stdc.math.atan2 llvm_atan2;
-+        alias tango.stdc.math.cosh llvm_cosh;
-+        alias tango.stdc.math.sinh llvm_sinh;
-+        alias tango.stdc.math.tanh llvm_tanh;
-+        alias tango.stdc.math.cbrt llvm_cbrt;
-+        alias tango.stdc.math.exp llvm_exp;
-+        alias tango.stdc.math.expm1 llvm_expm1;
-+        alias tango.stdc.math.exp2 llvm_exp2;
-+        alias tango.stdc.math.log llvm_log;
-+        alias tango.stdc.math.log1p llvm_log1p;
-+        alias tango.stdc.math.log2 llvm_log2;
-+        alias tango.stdc.math.log10 llvm_log10;
-+        alias tango.stdc.math.pow llvm_pow;
-+        alias tango.stdc.math.lrint llvm_lrint;
-+        alias tango.stdc.math.llrint llvm_llrint;
-+
-+        pragma(intrinsic, "llvm.cos.f64")
-+            real cos(real);
-+        pragma(intrinsic, "llvm.sin.f64")
-+            real sin(real);
-+        pragma(intrinsic, "llvm.sqrt.f64")
-+            real sqrt(real);
-+    }
++        version = LLVMDC_X86;
 +    }
 +}
-+
+ 
  /*
   * Constants
-  */
-@@ -298,6 +368,10 @@
+@@ -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 +387,7 @@
+@@ -313,6 +339,7 @@
          return tango.stdc.math.cosl(x);
      }
  }
@@ -306,18 +257,32 @@
  
  debug(UnitTest) {
  unittest {
-@@ -333,6 +408,10 @@
+@@ -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 +427,7 @@
+@@ -348,6 +393,7 @@
          return tango.stdc.math.sinl(x);
      }
  }
@@ -325,283 +290,62 @@
  
  debug(UnitTest) {
  unittest {
-@@ -374,6 +454,9 @@
+@@ -374,7 +420,11 @@
  {
      version (GNU) {
          return tanl(x);
+-    } else {
 +    }
 +    else version(LLVMDC) {
-+        return llvm_tan(x);
-     } else {
++        return tango.stdc.math.tanl(x);
++    }
++    else {
      asm
      {
-@@ -576,7 +659,14 @@
-  */
- real acos(real x)
- {
--    return tango.stdc.math.acosl(x);
-+    version(LLVMDC)
-+    {
-+        return llvm_acos(x);
-+    }
-+    else
-+    {
-+        return tango.stdc.math.acosl(x);
-+    }
- }
- 
- debug(UnitTest) {
-@@ -599,7 +689,14 @@
-  */
- real asin(real x)
- {
--    return tango.stdc.math.asinl(x);
-+    version(LLVMDC)
-+    {
-+        return llvm_asin(x);
-+    }
-+    else
-+    {
-+        return tango.stdc.math.asinl(x);
-+    }
- }
- 
- debug(UnitTest) {
-@@ -621,7 +718,14 @@
-  */
- real atan(real x)
- {
--    return tango.stdc.math.atanl(x);
-+    version(LLVMDC)
-+    {
-+        return llvm_atan(x);
-+    }
-+    else
-+    {
-+        return tango.stdc.math.atanl(x);
-+    }
- }
- 
- debug(UnitTest) {
-@@ -658,7 +762,14 @@
-  */
- real atan2(real y, real x)
- {
--    return tango.stdc.math.atan2l(y,x);
-+    version(LLVMDC)
-+    {
-+        return llvm_atan2(y,x);
-+    }
-+    else
-+    {
-+        return tango.stdc.math.atan2l(y,x);
-+    }
- }
- 
- debug(UnitTest) {
-@@ -707,7 +818,14 @@
-  */
- real cosh(real x)
- {
--    return tango.stdc.math.coshl(x);
-+    version(LLVMDC)
-+    {
-+        return llvm_cosh(x);
-+    }
-+    else
-+    {
-+        return tango.stdc.math.coshl(x);
-+    }
- }
- 
- debug(UnitTest) {
-@@ -728,7 +846,14 @@
-  */
- real sinh(real x)
- {
--    return tango.stdc.math.sinhl(x);
-+    version(LLVMDC)
-+    {
-+        return llvm_sinh(x);
-+    }
-+    else
-+    {
-+        return tango.stdc.math.sinhl(x);
-+    }
- }
- 
- debug(UnitTest) {
-@@ -749,7 +874,14 @@
-  */
- real tanh(real x)
- {
--    return tango.stdc.math.tanhl(x);
-+    version(LLVMDC)
-+    {
-+        return llvm_tanh(x);
-+    }
-+    else
-+    {
-+        return tango.stdc.math.tanhl(x);
-+    }
- }
- 
- debug(UnitTest) {
-@@ -947,6 +1079,10 @@
+         fld x[EBP]      ; // load theta
+@@ -947,6 +997,25 @@
   *  <tr> <td> +&infin; <td> +&infin; <td> no
   *  )
   */
 +version(LLVMDC)
-+{}
-+else
 +{
- float sqrt(float x) /* intrinsic */
- {
-     version(D_InlineAsm_X86)
-@@ -994,6 +1130,7 @@
-         return tango.stdc.math.sqrtl(x);
-     }
- }
-+}
- 
- /** ditto */
- creal sqrt(creal z)
-@@ -1045,7 +1182,14 @@
-  */
- real cbrt(real x)
- {
--    return tango.stdc.math.cbrtl(x);
-+    version(LLVMDC)
-+    {
-+        return llvm_cbrt(x);
-+    }
-+    else
++    alias llvm_sqrt_f32 sqrt;
++    alias llvm_sqrt_f64 sqrt;
++    version(X86)
 +    {
-+        return tango.stdc.math.cbrtl(x);
-+    }
- }
- 
- 
-@@ -1067,7 +1211,14 @@
-  */
- real exp(real x)
- {
--    return tango.stdc.math.expl(x);
-+    version(LLVMDC)
-+    {
-+        return llvm_exp(x);
-+    }
-+    else
-+    {
-+        return tango.stdc.math.expl(x);
-+    }
- }
- 
- debug(UnitTest) {
-@@ -1093,7 +1244,14 @@
-  */
- real expm1(real x)
- {
--    return tango.stdc.math.expm1l(x);
-+    version(LLVMDC)
-+    {
-+        return llvm_expm1(x);
++        alias llvm_sqrt_f80 sqrt;
 +    }
 +    else
 +    {
-+        return tango.stdc.math.expm1l(x);
-+    }
- }
- 
- debug(UnitTest) {
-@@ -1115,7 +1273,14 @@
-  */
- real exp2(real x)
- {
--    return tango.stdc.math.exp2l(x);
-+    version(LLVMDC)
-+    {
-+        return llvm_exp2(x);
++        real sqrt(real x)
++        {
++            return tango.stdc.math.sqrtl(x);
++        }
 +    }
-+    else
-+    {
-+        return tango.stdc.math.exp2l(x);
-+    }
- }
- 
- debug(UnitTest) {
-@@ -1141,7 +1306,14 @@
-  */
- real log(real x)
++}
++else
++{
++
+ float sqrt(float x) /* intrinsic */
  {
--    return tango.stdc.math.logl(x);
-+    version(LLVMDC)
-+    {
-+        return llvm_log(x);
-+    }
-+    else
-+    {
-+        return tango.stdc.math.logl(x);
-+    }
+     version(D_InlineAsm_X86)
+@@ -995,6 +1064,8 @@
+     }
  }
  
- debug(UnitTest) {
-@@ -1167,7 +1339,14 @@
-  */
- real log1p(real x)
- {
--    return tango.stdc.math.log1pl(x);
-+    version(LLVMDC)
-+    {
-+        return llvm_log1p(x);
-+    }
-+    else
-+    {
-+        return tango.stdc.math.log1pl(x);
-+    }
- }
- 
- debug(UnitTest) {
-@@ -1190,7 +1369,14 @@
-  */
- real log2(real x)
++}
++
+ /** ditto */
+ creal sqrt(creal z)
  {
--    return tango.stdc.math.log2l(x);
-+    version(LLVMDC)
-+    {
-+        return llvm_log2(x);
-+    }
-+    else
-+    {
-+        return tango.stdc.math.log2l(x);
-+    }
- }
- 
- debug(UnitTest) {
-@@ -1212,7 +1398,14 @@
-  */
- real log10(real x)
- {
--    return tango.stdc.math.log10l(x);
-+    version(LLVMDC)
-+    {
-+        return llvm_log10(x);
-+    }
-+    else
-+    {
-+        return tango.stdc.math.log10l(x);
-+    }
- }
- 
- debug(UnitTest) {
-@@ -1477,7 +1670,14 @@
+@@ -1477,7 +1548,14 @@
          }
      }
      }
 -    return tango.stdc.math.powl(x, y);
-+    version(LLVMDC)
++    version(LLVMDC_X86)
 +    {
-+        return llvm_pow(x, y);
++        return llvm_pow_f80(x, y);
 +    }
 +    else
 +    {
@@ -610,28 +354,6 @@
  }
  
  debug(UnitTest) {
-@@ -1823,6 +2023,10 @@
-         }
-         return n;
-     }
-+    else version(LLVMDC)
-+    {
-+        return llvm_lrint(x);
-+    }
-     else
-     {
-         return tango.stdc.math.lrintl(x);
-@@ -1842,6 +2046,10 @@
-         }
-         return n;
-     }
-+    else version(LLVMDC)
-+    {
-+        return llvm_llrint(x);
-+    }
-     else
-     {
-         return tango.stdc.math.llrintl(x);
 Index: tango/stdc/stdlib.d
 ===================================================================
 --- tango/stdc/stdlib.d	(revision 3831)
--- a/tests/mini/intrinsics.d	Fri Aug 01 01:12:33 2008 +0200
+++ b/tests/mini/intrinsics.d	Fri Aug 01 17:59:58 2008 +0200
@@ -23,7 +23,7 @@
     printf("Enter real: ");
     //scanf("%lf", &d);
     r = 3.2311167891231231234754764576;
-    version(LLVM_X86_FP80)
+    version(X86)
     {
         real sr = llvm_sqrt_f80(r);
         printf("sqrt(%llf) = %llf\n", r, sr);
@@ -31,6 +31,6 @@
     else
     {
         real sr = llvm_sqrt_f64(r);
-        printf("sqrt(%lf) = %lf\n", r, sr);
+        printf("sqrt(%f) = %lf\n", r, sr);
     }
 }
--- a/tests/mini/marray3.d	Fri Aug 01 01:12:33 2008 +0200
+++ b/tests/mini/marray3.d	Fri Aug 01 17:59:58 2008 +0200
@@ -14,10 +14,10 @@
     assert(ma[1][1].length == 3);
     assert(ma[1][2].length == 3);
     assert(ma[1][3].length == 3);
-    ma[0][3][1] = 32;
-    ma[1][2][2] = 123;
-    ma[0][0][3] = 55;
-    assert(ma[0][3][1] == 32);
-    assert(ma[1][2][2] == 123);
-    assert(ma[0][0][3] == 55);
+    ma[0][3][0] = 32;
+    ma[1][2][1] = 123;
+    ma[0][0][2] = 55;
+    assert(ma[0][3][0] == 32);
+    assert(ma[1][2][1] == 123);
+    assert(ma[0][0][2] == 55);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/mini/packed1.d	Fri Aug 01 17:59:58 2008 +0200
@@ -0,0 +1,24 @@
+module mini.packed1;
+
+extern(C) int printf(char*, ...);
+
+align(1)
+struct PackedStruct
+{
+    ubyte ub;
+    float f;
+    long l;
+    short s;
+    ubyte ub2;
+    short s2;
+}
+
+void main()
+{
+    PackedStruct[2] a = void;
+    void* begin = a.ptr;
+    void* end = &a[1];
+    ptrdiff_t sz = end - begin;
+    printf("size = 18 = %u = %u\n", PackedStruct.sizeof, sz);
+    assert(sz == 18);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/mini/real1.d	Fri Aug 01 17:59:58 2008 +0200
@@ -0,0 +1,14 @@
+module mini.real1;
+
+extern(C)
+{
+real tanl(real x);
+int printf(char*, ...);
+}
+
+void main()
+{
+    real ans = tanl(0.785398163398);
+    printf("%llf\n", ans);
+    assert(ans > 0.999 && ans < 1.001);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/mini/sextzext.d	Fri Aug 01 17:59:58 2008 +0200
@@ -0,0 +1,68 @@
+module mini.sextzext;
+
+void main()
+{
+    byte sb  = sextreturn1();
+    short ss = sextreturn2();
+    assert(ss == -2);
+    assert(sb == -2);
+    assert(sextparam1(-42) == -42);
+    assert(sextparam2(-42) == -42);
+
+    ubyte ub  = zextreturn1();
+    ushort us = zextreturn2();
+    assert(ub == 2);
+    assert(us == 2);
+    assert(zextparam1(42) == 42);
+    assert(zextparam2(42) == 42);
+
+    assert(getchar() == 'a');
+    assert(passchar('z') == 'z');
+
+}
+
+byte sextreturn1()
+{
+    return -2;
+}
+short sextreturn2()
+{
+    return -2;
+}
+
+ubyte zextreturn1()
+{
+    return 2;
+}
+ushort zextreturn2()
+{
+    return 2;
+}
+
+byte sextparam1(byte b)
+{
+    return b;
+}
+short sextparam2(short s)
+{
+    return s;
+}
+
+ubyte zextparam1(ubyte b)
+{
+    return b;
+}
+ushort zextparam2(ushort s)
+{
+    return s;
+}
+
+char getchar()
+{
+    return 'a';
+}
+
+char passchar(char ch)
+{
+    return ch;
+}
--- a/tests/mini/vararg6.d	Fri Aug 01 01:12:33 2008 +0200
+++ b/tests/mini/vararg6.d	Fri Aug 01 17:59:58 2008 +0200
@@ -142,13 +142,8 @@
         printf("%f", *cast(float*)arg);
     else if (ti == typeid(double))
         printf("%f", *cast(double*)arg);
-    else if (ti == typeid(real)) // FIXME: 80bit?
-    {
-        version(LLVM_X86_FP80)
-            printf("%llf", *cast(real*)arg);
-        else
-            printf("%f", *cast(real*)arg);
-    }
+    else if (ti == typeid(real))
+        printf("%llf", *cast(real*)arg);
 
     else if (ti == typeid(char))
         printf("%.*s", 1, arg);