Mercurial > projects > ldc
diff gen/complex.cpp @ 359:926f65e39246 trunk
[svn r380] Improve complex number support.
author | ChristianK |
---|---|
date | Mon, 14 Jul 2008 17:22:43 +0200 |
parents | 4aa2b6753059 |
children | 8014dbd24605 |
line wrap: on
line diff
--- 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())