# HG changeset patch # User ChristianK # Date 1216048963 -7200 # Node ID 926f65e39246fe845702ed8561442f9a3266ccf1 # Parent 051f5b550d9c3ffbd84184d75febe0befa0af6d4 [svn r380] Improve complex number support. diff -r 051f5b550d9c -r 926f65e39246 gen/complex.cpp --- a/gen/complex.cpp Mon Jul 14 12:39:23 2008 +0200 +++ b/gen/complex.cpp Mon Jul 14 17:22:43 2008 +0200 @@ -104,7 +104,6 @@ DValue* DtoComplex(Type* to, DValue* val) { Type* t = DtoDType(val->getType()); - TY ty = t->ty; if (val->isComplex() || t->iscomplex()) { return DtoCastComplex(val, to); @@ -112,22 +111,29 @@ const LLType* base = DtoComplexBaseType(to); - LLConstant* undef = llvm::UndefValue::get(base); - LLConstant* zero; - if (ty == Tfloat32 || ty == Timaginary32 || ty == Tcomplex32) - zero = LLConstant::getNullValue(DtoType(Type::tfloat32)); // llvm::ConstantFP::get(llvm::APFloat(0.0f)); - else if (ty == Tfloat64 || ty == Timaginary64 || ty == Tcomplex64) - zero = LLConstant::getNullValue(DtoType(Type::tfloat64)); - else if (ty == Tfloat80 || ty == Timaginary80 || ty == Tcomplex80) - zero = LLConstant::getNullValue(DtoType((global.params.useFP80)?Type::tfloat80:Type::tfloat64)); + Type* baserety; + Type* baseimty; + TY ty = to->ty; + if (ty == Tcomplex32) { + baserety = Type::tfloat32; + baseimty = Type::timaginary32; + } else if (ty == Tcomplex64) { + 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; + } if (t->isimaginary()) { - return new DComplexValue(to, zero, val->getRVal()); + return new DComplexValue(to, LLConstant::getNullValue(DtoType(baserety)), DtoCastFloat(val, baseimty)->getRVal()); } else if (t->isfloating()) { - return new DComplexValue(to, val->getRVal(), zero); + return new DComplexValue(to, DtoCastFloat(val, baserety)->getRVal(), LLConstant::getNullValue(DtoType(baseimty))); } - else + else if (t->isintegral()) { + return new DComplexValue(to, DtoCastInt(val, baserety)->getRVal(), LLConstant::getNullValue(DtoType(baseimty))); + } assert(0); } @@ -149,7 +155,7 @@ void DtoGetComplexParts(DValue* c, LLValue*& re, LLValue*& im) { - // lhs values + // get LLValues if (DComplexValue* cx = c->isComplex()) { re = cx->re; im = cx->im; @@ -160,12 +166,23 @@ } } +DValue* resolveLR(DValue* val, bool getlval) +{ + if (DLRValue* lr = val->isLRValue()) { + if (getlval) + return lr->lvalue; + else + return lr->rvalue; + } + return val; +} + ////////////////////////////////////////////////////////////////////////////////////////// DValue* DtoComplexAdd(Type* type, DValue* lhs, DValue* rhs) { - lhs = DtoComplex(type, lhs); - rhs = DtoComplex(type, rhs); + lhs = DtoComplex(type, resolveLR(lhs, true)); + rhs = DtoComplex(type, resolveLR(rhs, false)); llvm::Value *a, *b, *c, *d, *re, *im; @@ -185,8 +202,8 @@ DValue* DtoComplexSub(Type* type, DValue* lhs, DValue* rhs) { - lhs = DtoComplex(type, lhs); - rhs = DtoComplex(type, rhs); + lhs = DtoComplex(type, resolveLR(lhs, true)); + rhs = DtoComplex(type, resolveLR(rhs, false)); llvm::Value *a, *b, *c, *d, *re, *im; @@ -206,8 +223,8 @@ DValue* DtoComplexMul(Type* type, DValue* lhs, DValue* rhs) { - lhs = DtoComplex(type, lhs); - rhs = DtoComplex(type, rhs); + lhs = DtoComplex(type, resolveLR(lhs, true)); + rhs = DtoComplex(type, resolveLR(rhs, false)); llvm::Value *a, *b, *c, *d; @@ -233,8 +250,8 @@ DValue* DtoComplexDiv(Type* type, DValue* lhs, DValue* rhs) { - lhs = DtoComplex(type, lhs); - rhs = DtoComplex(type, rhs); + lhs = DtoComplex(type, resolveLR(lhs, true)); + rhs = DtoComplex(type, resolveLR(rhs, false)); llvm::Value *a, *b, *c, *d; @@ -266,7 +283,7 @@ DValue* DtoComplexNeg(Type* type, DValue* val) { - val = DtoComplex(type, val); + val = DtoComplex(type, resolveLR(val, false)); llvm::Value *a, *b, *re, *im; @@ -286,8 +303,8 @@ { Type* type = lhs->getType(); - lhs = DtoComplex(type, lhs); - rhs = DtoComplex(type, rhs); + lhs = DtoComplex(type, resolveLR(lhs, false)); + rhs = DtoComplex(type, resolveLR(rhs, false)); llvm::Value *a, *b, *c, *d; @@ -342,7 +359,7 @@ // so we need to give it storage, or fix the system that handles this stuff (DLRValue) LLValue* mem = new llvm::AllocaInst(DtoType(_to), "castcomplextmp", gIR->topallocapoint()); DtoComplexSet(mem, re, im); - return new DLRValue(val->getType(), val->getRVal(), _to, mem); + return new DLRValue(val, new DImValue(_to, mem)); } else if (to->isimaginary()) { if (val->isComplex()) diff -r 051f5b550d9c -r 926f65e39246 gen/dvalue.h --- a/gen/dvalue.h Mon Jul 14 12:39:23 2008 +0200 +++ b/gen/dvalue.h Mon Jul 14 17:22:43 2008 +0200 @@ -169,24 +169,20 @@ // l-value and r-value pair d-value struct DLRValue : DValue { - Type* ltype; - LLValue* lval; - Type* rtype; - LLValue* rval; + DValue* lvalue; + DValue* rvalue; - DLRValue(Type* lt, LLValue* l, Type* rt, LLValue* r) { - ltype = lt; - lval = l; - rtype = rt; - rval = r; + DLRValue(DValue* lval, DValue* rval) { + lvalue = lval; + rvalue = rval; } - virtual bool isLVal() { return lval; } - virtual LLValue* getLVal() { assert(lval); return lval; } - virtual LLValue* getRVal() { assert(rval); return rval; } + virtual bool isLVal() { return true; } + virtual LLValue* getLVal() { return lvalue->isLVal() ? lvalue->getLVal() : lvalue->getRVal(); } + virtual LLValue* getRVal() { return rvalue->getRVal(); } - Type* getLType() { return ltype; } - Type* getRType() { return rtype; } + Type* getLType() { return lvalue->getType(); } + Type* getRType() { return rvalue->getType(); } virtual Type* getType() { return getRType(); } virtual DLRValue* isLRValue() { return this; } }; diff -r 051f5b550d9c -r 926f65e39246 gen/llvmhelpers.cpp --- a/gen/llvmhelpers.cpp Mon Jul 14 12:39:23 2008 +0200 +++ b/gen/llvmhelpers.cpp Mon Jul 14 17:22:43 2008 +0200 @@ -671,6 +671,9 @@ rval = DtoBitCast(rval, tolltype); } } + else if (to->iscomplex()) { + return DtoComplex(to, val); + } else if (to->isfloating()) { if (from->isunsigned()) { rval = new llvm::UIToFPInst(rval, tolltype, "tmp", gIR->scopebb()); @@ -733,13 +736,15 @@ LLValue* rval; if (totype->iscomplex()) { - assert(0); - //return new DImValue(to, DtoComplex(to, val)); + return DtoComplex(to, val); } else if (totype->isfloating()) { if ((fromtype->ty == Tfloat80 || fromtype->ty == Tfloat64) && (totype->ty == Tfloat80 || totype->ty == Tfloat64)) { rval = val->getRVal(); } + else if ((fromtype->ty == Timaginary80 || fromtype->ty == Timaginary64) && (totype->ty == Timaginary80 || totype->ty == Timaginary64)) { + rval = val->getRVal(); + } else if (fromsz < tosz) { rval = new llvm::FPExtInst(val->getRVal(), tolltype, "tmp", gIR->scopebb()); } diff -r 051f5b550d9c -r 926f65e39246 gen/toir.cpp --- a/gen/toir.cpp Mon Jul 14 12:39:23 2008 +0200 +++ b/gen/toir.cpp Mon Jul 14 17:22:43 2008 +0200 @@ -1257,7 +1257,7 @@ } else if(u->isLVal()) - return new DLRValue(e1->type, u->getLVal(), to, v->getRVal()); + return new DLRValue(u, v); else return v; @@ -1315,7 +1315,7 @@ LLValue* v = lv; if (DtoCanLoad(v)) v = DtoLoad(v); - return new DLRValue(type, lv, type, v); + return new DLRValue(new DVarValue(type, lv, true), new DImValue(type, v)); } //////////////////////////////////////////////////////////////////////////////////////////