changeset 359:926f65e39246 trunk

[svn r380] Improve complex number support.
author ChristianK
date Mon, 14 Jul 2008 17:22:43 +0200
parents 051f5b550d9c
children 9c9544fd769d
files gen/complex.cpp gen/dvalue.h gen/llvmhelpers.cpp gen/toir.cpp
diffstat 4 files changed, 61 insertions(+), 43 deletions(-) [+]
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())
--- 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; }
 };
--- 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());
         }
--- 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));
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////