# HG changeset patch # User Tomas Lindquist Olsen # Date 1217606398 -7200 # Node ID cc40db549aea9bb7be6b3fd8e22448e63640fcef # Parent f2b5f86348efc20499a8aa536f242c0b68df4e4a 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. diff -r f2b5f86348ef -r cc40db549aea dmd/attrib.c --- 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()); } } diff -r f2b5f86348ef -r cc40db549aea dmd/cond.c --- 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", diff -r f2b5f86348ef -r cc40db549aea dmd/declaration.h --- 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 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 LabelMap; diff -r f2b5f86348ef -r cc40db549aea dmd/id.c --- 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"); diff -r f2b5f86348ef -r cc40db549aea dmd/id.h --- 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; diff -r f2b5f86348ef -r cc40db549aea dmd/idgen.c --- 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" }, diff -r f2b5f86348ef -r cc40db549aea dmd/mars.c --- 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); diff -r f2b5f86348ef -r cc40db549aea dmd/mars.h --- 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 }; diff -r f2b5f86348ef -r cc40db549aea dmd/mtype.c --- 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; } diff -r f2b5f86348ef -r cc40db549aea dmd/mtype.h --- 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; diff -r f2b5f86348ef -r cc40db549aea gen/complex.cpp --- 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 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()) { diff -r f2b5f86348ef -r cc40db549aea gen/d-asm-i386.h --- 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: diff -r f2b5f86348ef -r cc40db549aea gen/enums.h --- 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 }; diff -r f2b5f86348ef -r cc40db549aea gen/functions.cpp --- 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 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; illvmInternal == 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(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(fn); - assert(func); - assert(func->isIntrinsic()); fdecl->ir.irFunc->func = func; return func; } @@ -330,36 +318,43 @@ std::vector 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(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); +} diff -r f2b5f86348ef -r cc40db549aea gen/llvm.h --- 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 diff -r f2b5f86348ef -r cc40db549aea gen/llvmhelpers.cpp --- 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()); diff -r f2b5f86348ef -r cc40db549aea gen/runtime.cpp --- 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); diff -r f2b5f86348ef -r cc40db549aea gen/tocall.cpp --- 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(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); diff -r f2b5f86348ef -r cc40db549aea gen/toir.cpp --- 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); } diff -r f2b5f86348ef -r cc40db549aea gen/tollvm.cpp --- 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); } ////////////////////////////////////////////////////////////////////////////////////////// diff -r f2b5f86348ef -r cc40db549aea gen/tollvm.h --- 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); diff -r f2b5f86348ef -r cc40db549aea import/llvmdc/cstdarg.di --- 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); diff -r f2b5f86348ef -r cc40db549aea import/llvmdc/intrinsics.di --- 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); diff -r f2b5f86348ef -r cc40db549aea llvmdc-tango --- 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] diff -r f2b5f86348ef -r cc40db549aea llvmdc.kdevelop --- 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 @@ tango-llvmdc/patches/proposals/integrated_locks/lib/compiler/dmd/monitor.c tango-llvmdc/patches/proposals/integrated_locks/lib/compiler/gdc tango-llvmdc/patches/proposals/integrated_locks/lib/compiler/gdc/monitor.c + runtime/build.sh + runtime/internal + runtime/internal/critical.c + runtime/internal/mars.h + runtime/internal/monitor.c make diff -r f2b5f86348ef -r cc40db549aea runtime/llvmdc.diff --- 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 @@ * +∞ +∞ 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) diff -r f2b5f86348ef -r cc40db549aea tests/mini/intrinsics.d --- 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); } } diff -r f2b5f86348ef -r cc40db549aea tests/mini/marray3.d --- 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); } diff -r f2b5f86348ef -r cc40db549aea tests/mini/packed1.d --- /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 diff -r f2b5f86348ef -r cc40db549aea tests/mini/real1.d --- /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); +} diff -r f2b5f86348ef -r cc40db549aea tests/mini/sextzext.d --- /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; +} diff -r f2b5f86348ef -r cc40db549aea tests/mini/vararg6.d --- 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);