From 7e7441a5f8ed1375c7de842d0ca05f2b1fabd838 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Mon, 14 Jul 2008 17:22:43 +0200 Subject: [PATCH] [svn r380] Improve complex number support. --- gen/complex.cpp | 67 ++++++++++++++++++++++++++++----------------- gen/dvalue.h | 24 +++++++--------- gen/llvmhelpers.cpp | 9 ++++-- gen/toir.cpp | 4 +-- 4 files changed, 61 insertions(+), 43 deletions(-) diff --git a/gen/complex.cpp b/gen/complex.cpp index 361c3b7e..f755cf23 100644 --- a/gen/complex.cpp +++ b/gen/complex.cpp @@ -104,7 +104,6 @@ LLValue* DtoImagPart(DValue* val) 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 @@ DValue* DtoComplex(Type* to, DValue* val) 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 if (t->isintegral()) { + return new DComplexValue(to, DtoCastInt(val, baserety)->getRVal(), LLConstant::getNullValue(DtoType(baseimty))); } - else assert(0); } @@ -149,7 +155,7 @@ void DtoComplexSet(LLValue* c, LLValue* re, LLValue* im) 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 @@ void DtoGetComplexParts(DValue* c, LLValue*& re, LLValue*& im) } } +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* DtoComplexAdd(Type* type, DValue* lhs, DValue* rhs) 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* DtoComplexSub(Type* type, DValue* lhs, DValue* rhs) 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* DtoComplexMul(Type* type, DValue* lhs, DValue* rhs) 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* DtoComplexDiv(Type* type, DValue* lhs, DValue* rhs) 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 @@ LLValue* DtoComplexEquals(TOK op, DValue* lhs, DValue* rhs) { 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 @@ DValue* DtoCastComplex(DValue* val, Type* _to) // 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 --git a/gen/dvalue.h b/gen/dvalue.h index 9924185e..8755997d 100644 --- a/gen/dvalue.h +++ b/gen/dvalue.h @@ -169,24 +169,20 @@ struct DFuncValue : DValue // 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 --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index e19409db..c59436a8 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -671,6 +671,9 @@ DValue* DtoCastInt(DValue* val, Type* _to) 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 @@ DValue* DtoCastFloat(DValue* val, Type* to) 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 --git a/gen/toir.cpp b/gen/toir.cpp index f073604f..4e1f6632 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -1257,7 +1257,7 @@ DValue* CastExp::toElem(IRState* p) } 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 @@ DValue* PtrExp::toElem(IRState* p) 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)); } //////////////////////////////////////////////////////////////////////////////////////////