diff gen/toir.cpp @ 104:4d1e9eb001e0 trunk

[svn r108] Now basic suppport for complex types. =,+,-,*,/ are supported.
author lindquist
date Mon, 19 Nov 2007 02:58:58 +0100
parents 027b8d8b71ec
children 3efbcc81ba45
line wrap: on
line diff
--- a/gen/toir.cpp	Sun Nov 18 08:25:07 2007 +0100
+++ b/gen/toir.cpp	Mon Nov 19 02:58:58 2007 +0100
@@ -28,7 +28,7 @@
 #include "gen/structs.h"
 #include "gen/classes.h"
 #include "gen/typeinf.h"
-
+#include "gen/complex.h"
 #include "gen/dvalue.h"
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -291,13 +291,7 @@
     Logger::print("RealExp::toConstElem: %s | %s\n", toChars(), type->toChars());
     LOG_SCOPE;
     Type* t = DtoDType(type);
-    const llvm::Type* fty = DtoType(t);
-    if (t->ty == Tfloat32 || t->ty == Timaginary32)
-        return llvm::ConstantFP::get(fty,float(value));
-    else if (t->ty == Tfloat64 || t->ty == Timaginary64 || t->ty == Tfloat80 || t->ty == Timaginary80)
-        return llvm::ConstantFP::get(fty,double(value));
-    assert(0);
-    return NULL;
+    return DtoConstFP(t, value);
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -334,7 +328,18 @@
 {
     Logger::print("ComplexExp::toElem(): %s | %s\n", toChars(), type->toChars());
     LOG_SCOPE;
-    assert(0 && "no complex yet");
+    llvm::Constant* c = toConstElem(p);
+
+    if (c->isNullValue()) {
+        Type* t = DtoDType(type);
+        if (t->ty == Tcomplex32)
+            c = DtoConstFP(Type::tfloat32, 0);
+        else
+            c = DtoConstFP(Type::tfloat64, 0);
+        return new DComplexValue(type, c, c);
+    }
+
+    return new DComplexValue(type, c->getOperand(0), c->getOperand(1));
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -343,7 +348,7 @@
 {
     Logger::print("ComplexExp::toConstElem(): %s | %s\n", toChars(), type->toChars());
     LOG_SCOPE;
-    assert(0 && "no complex yet");
+    return DtoConstComplex(type, value.re, value.im);
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -484,164 +489,6 @@
     }
 
     return l;
-
-    /*
-    if (l->type == DValue::ARRAYLEN)
-    {
-        DtoResizeDynArray(l->mem, r->getValue());
-        delete r;
-        delete l;
-        return 0;
-    }
-
-    Type* e1type = DtoDType(e1->type);
-    Type* e2type = DtoDType(e2->type);
-    TY e1ty = e1type->ty;
-    TY e2ty = e2type->ty;
-
-    DValue* e = new DValue(this);
-    e->type = DValue::VAR;
-
-    // struct
-    if (e1ty == Tstruct) {
-        e->mem = l->mem;
-        // struct + struct
-        if (e2ty == Tstruct) {
-            // struct literals do the assignment themselvs (in place)
-            if (!r->inplace) {
-                DtoStructCopy(l->mem,r->getValue());
-            }
-            else {
-                e->inplace = true;
-            }
-        }
-        // struct + const int
-        else if (e2type->isintegral()){
-            IntegerExp* iexp = (IntegerExp*)e2;
-            assert(iexp->value == 0 && "Only integral struct initializer allowed is zero");
-            DtoStructZeroInit(l->mem);
-        }
-        // :x
-        else
-        assert(0 && "struct = unknown");
-    }
-    else if (e1ty == Tsarray) {
-        assert(0 && "static array not supported");
-    }
-    else if (e1ty == Tarray) {
-        if (e2type->isscalar() || e2type->ty == Tclass){
-            if (l->type == DValue::SLICE) {
-                DtoArrayInit(l->mem, l->arg, r->getValue());
-            }
-            else {
-                DtoArrayInit(l->mem, r->getValue());
-            }
-        }
-        else if (e2ty == Tarray) {
-            //new llvm::StoreInst(r->val,l->val,p->scopebb());
-            if (r->type == DValue::NUL) {
-                llvm::Constant* c = llvm::cast<llvm::Constant>(r->val);
-                assert(c->isNullValue());
-                DtoNullArray(l->mem);
-                e->mem = l->mem;
-            }
-            else if (r->type == DValue::SLICE) {
-                if (l->type == DValue::SLICE) {
-                    DtoArrayCopy(l,r);
-                    e->type = DValue::SLICE;
-                    e->mem = l->mem;
-                    e->arg = l->arg;
-                }
-                else {
-                    DtoSetArray(l->mem,r->arg,r->mem);
-                    e->mem = l->mem;
-                }
-            }
-            else {
-                // new expressions write directly to the array reference
-                // so do string literals
-                e->mem = l->mem;
-                if (!r->inplace) {
-                    assert(r->mem);
-                    DtoArrayAssign(l->mem, r->mem);
-                }
-                else {
-                    e->inplace = true;
-                }
-            }
-        }
-        else
-        assert(0);
-    }
-    else if (e1ty == Tpointer) {
-        e->mem = l->mem;
-        if (e2ty == Tpointer) {
-            llvm::Value* v = r->field ? r->mem : r->getValue();
-            Logger::cout() << "*=*: " << *v << ", " << *l->mem << '\n';
-            new llvm::StoreInst(v, l->mem, p->scopebb());
-        }
-        else
-        assert(0);
-    }
-    else if (e1ty == Tclass) {
-        if (e2ty == Tclass) {
-            llvm::Value* tmp = r->getValue();
-            Logger::cout() << "tmp: " << *tmp << " ||| " << *l->mem << '\n';
-            // assignment to this in constructor special case
-            if (l->isthis) {
-                FuncDeclaration* fdecl = p->func().decl;
-                // respecify the this param
-                if (!llvm::isa<llvm::AllocaInst>(fdecl->llvmThisVar))
-                    fdecl->llvmThisVar = new llvm::AllocaInst(tmp->getType(), "newthis", p->topallocapoint());
-                new llvm::StoreInst(tmp, fdecl->llvmThisVar, p->scopebb());
-                e->mem = fdecl->llvmThisVar;
-            }
-            // regular class ref -> class ref assignment
-            else {
-                new llvm::StoreInst(tmp, l->mem, p->scopebb());
-                e->mem = l->mem;
-            }
-        }
-        else
-        assert(0);
-    }
-    else if (e1ty == Tdelegate) {
-        Logger::println("Assigning to delegate");
-        if (e2ty == Tdelegate) {
-            if (r->type == DValue::NUL) {
-                llvm::Constant* c = llvm::cast<llvm::Constant>(r->val);
-                if (c->isNullValue()) {
-                    DtoNullDelegate(l->mem);
-                    e->mem = l->mem;
-                }
-                else
-                assert(0);
-            }
-            else if (r->inplace) {
-                // do nothing
-                e->inplace = true;
-                e->mem = l->mem;
-            }
-            else {
-                DtoDelegateCopy(l->mem, r->getValue());
-                e->mem = l->mem;
-            }
-        }
-        else
-        assert(0);
-    }
-    // !struct && !array && !pointer && !class
-    else {
-        Logger::cout() << *l->mem << '\n';
-        new llvm::StoreInst(r->getValue(),l->mem,p->scopebb());
-        e->mem = l->mem;
-    }
-
-    delete r;
-    delete l;
-
-    return e;
-    */
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -682,8 +529,14 @@
             llvm::Value* v = new llvm::GetElementPtrInst(l->getRVal(), r->getRVal(), "tmp", p->scopebb());
             return new DImValue(type, v);
         }
+        else if (t->iscomplex()) {
+            return DtoComplexAdd(type, l, r);
+        }
         assert(0);
     }
+    else if (t->iscomplex()) {
+        return DtoComplexAdd(type, l, r);
+    }
     else {
         return DtoBinAdd(l,r);
     }
@@ -701,39 +554,22 @@
     DValue* r = e2->toElem(p);
     p->exps.pop_back();
 
+    Type* t = DtoDType(type);
+
     DValue* res;
     if (DtoDType(e1->type)->ty == Tpointer) {
         llvm::Value* gep = new llvm::GetElementPtrInst(l->getRVal(),r->getRVal(),"tmp",p->scopebb());
         res = new DImValue(type, gep);
     }
+    else if (t->iscomplex()) {
+        res = DtoComplexAdd(type, l, r);
+    }
     else {
         res = DtoBinAdd(l,r);
     }
     DtoAssign(l, res);
 
     return l;
-
-    /*
-
-    Type* e1type = DtoDType(e1->type);
-
-    DValue* e = new DValue(this);
-    llvm::Value* val = 0;
-    if (e1type->ty == Tpointer) {
-        val = e->mem = new llvm::GetElementPtrInst(l->getValue(),r->getValue(),"tmp",p->scopebb());
-    }
-    else {
-        val = e->val = llvm::BinaryOperator::createAdd(l->getValue(),r->getValue(),"tmp",p->scopebb());
-    }
-
-    assert(l->mem);
-    new llvm::StoreInst(val,l->mem,p->scopebb());
-    e->type = DValue::VAR;
-
-    delete l;
-    delete r;
-    return e;
-    */
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -746,6 +582,8 @@
     DValue* l = e1->toElem(p);
     DValue* r = e2->toElem(p);
 
+    Type* t = DtoDType(type);
+
     if (DtoDType(e1->type)->ty == Tpointer) {
         llvm::Value* lv = l->getRVal();
         llvm::Value* rv = r->getRVal();
@@ -759,34 +597,12 @@
             diff = p->ir->CreateIntToPtr(diff, DtoType(type));
         return new DImValue(type, diff);
     }
+    else if (t->iscomplex()) {
+        return DtoComplexSub(type, l, r);
+    }
     else {
         return DtoBinSub(l,r);
     }
-
-    /*
-    llvm::Value* left = l->getValue();
-    if (isaPointer(left->getType()))
-        left = new llvm::PtrToIntInst(left,DtoSize_t(),"tmp",p->scopebb());
-
-    llvm::Value* right = r->getValue();
-    if (isaPointer(right->getType()))
-        right = new llvm::PtrToIntInst(right,DtoSize_t(),"tmp",p->scopebb());
-
-    e->val = llvm::BinaryOperator::createSub(left,right,"tmp",p->scopebb());
-    e->type = DValue::VAL;
-
-    const llvm::Type* totype = DtoType(type);
-    if (e->val->getType() != totype) {
-        assert(0);
-        assert(isaPointer(e->val->getType()));
-        assert(llvm::isa<llvm::IntegerType>(totype));
-        e->val = new llvm::IntToPtrInst(e->val,totype,"tmp",p->scopebb());
-    }
-
-    delete l;
-    delete r;
-    return e;
-    */
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -799,6 +615,8 @@
     DValue* l = e1->toElem(p);
     DValue* r = e2->toElem(p);
 
+    Type* t = DtoDType(type);
+
     DValue* res;
     if (DtoDType(e1->type)->ty == Tpointer) {
         llvm::Value* tmp = r->getRVal();
@@ -807,212 +625,113 @@
         tmp = new llvm::GetElementPtrInst(l->getRVal(),tmp,"tmp",p->scopebb());
         res = new DImValue(type, tmp);
     }
+    else if (t->iscomplex()) {
+        res = DtoComplexSub(type, l, r);
+    }
     else {
         res = DtoBinSub(l,r);
     }
     DtoAssign(l, res);
 
     return l;
-
-    /*
-
-    Type* e1type = DtoDType(e1->type);
-
-    llvm::Value* tmp = 0;
-    if (e1type->ty == Tpointer) {
-        tmp = r->getValue();
-        llvm::Value* zero = llvm::ConstantInt::get(tmp->getType(),0,false);
-        tmp = llvm::BinaryOperator::createSub(zero,tmp,"tmp",p->scopebb());
-        tmp = new llvm::GetElementPtrInst(l->getValue(),tmp,"tmp",p->scopebb());
-    }
-    else {
-        tmp = llvm::BinaryOperator::createSub(l->getValue(),r->getValue(),"tmp",p->scopebb());
-    }
-
-    assert(l->mem);
-    new llvm::StoreInst(tmp, l->mem, p->scopebb());
-
-    delete l;
-    delete r;
-
-    DValue* e = new DValue(this);
-    e->val = tmp;
-    e->type = DValue::VAR;
-    return e;
-    */
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
 DValue* MulExp::toElem(IRState* p)
 {
-    Logger::print("MulExp::toElem: %s\n", toChars());
+    Logger::print("MulExp::toElem: %s | %s\n", toChars(), type->toChars());
     LOG_SCOPE;
 
     DValue* l = e1->toElem(p);
     DValue* r = e2->toElem(p);
 
-    return DtoBinMul(l,r);
-    /*
-    if (l->dvalue && r->dvalue) {
-        Logger::println("DVALUE PATH");
-        e->dvalue = DtoBinMul(l->dvalue, r->dvalue);
-        e->val = e->dvalue->getRVal();
+    if (type->iscomplex()) {
+        return DtoComplexMul(type, l, r);
     }
-    else {
-        llvm::Value* vl = l->getValue();
-        llvm::Value* vr = r->getValue();
-        Logger::cout() << "mul: " << *vl << ", " << *vr << '\n';
-        e->val = llvm::BinaryOperator::createMul(vl,vr,"tmp",p->scopebb());
-        e->dvalue = new DImValue(type, e->val);
-    }
-    e->type = DValue::VAL;
-    delete l;
-    delete r;
-    return e;
-    */
+
+    return DtoBinMul(l,r);
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
 DValue* MulAssignExp::toElem(IRState* p)
 {
-    Logger::print("MulAssignExp::toElem: %s\n", toChars());
+    Logger::print("MulAssignExp::toElem: %s | %s\n", toChars(), type->toChars());
     LOG_SCOPE;
 
     DValue* l = e1->toElem(p);
     DValue* r = e2->toElem(p);
 
-    DValue* res = DtoBinMul(l,r);
+    DValue* res;
+    if (type->iscomplex()) {
+        res = DtoComplexMul(type, l, r);
+    }
+    else {
+        res = DtoBinMul(l,r);
+    }
     DtoAssign(l, res);
 
     return l;
-
-    /*
-    llvm::Value* vl = l->getValue();
-    llvm::Value* vr = r->getValue();
-    Logger::cout() << "mulassign: " << *vl << ", " << *vr << '\n';
-    llvm::Value* tmp = llvm::BinaryOperator::createMul(vl,vr,"tmp",p->scopebb());
-
-    assert(l->mem);
-    new llvm::StoreInst(tmp,l->mem,p->scopebb());
-
-    delete l;
-    delete r;
-
-    DValue* e = new DValue(this);
-    e->val = tmp;
-    e->type = DValue::VAR;
-    return e;
-    */
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
 DValue* DivExp::toElem(IRState* p)
 {
-    Logger::print("DivExp::toElem: %s\n", toChars());
+    Logger::print("DivExp::toElem: %s | %s\n", toChars(), type->toChars());
     LOG_SCOPE;
 
     DValue* l = e1->toElem(p);
     DValue* r = e2->toElem(p);
 
+    if (type->iscomplex()) {
+        return DtoComplexDiv(type, l, r);
+    }
+
     return DtoBinDiv(l, r);
-    /*
-
-    Type* t = DtoDType(type);
-
-    if (t->isunsigned())
-        e->val = llvm::BinaryOperator::createUDiv(l->getValue(),r->getValue(),"tmp",p->scopebb());
-    else if (t->isintegral())
-        e->val = llvm::BinaryOperator::createSDiv(l->getValue(),r->getValue(),"tmp",p->scopebb());
-    else if (t->isfloating())
-        e->val = llvm::BinaryOperator::createFDiv(l->getValue(),r->getValue(),"tmp",p->scopebb());
-    else
-        assert(0);
-    e->type = DValue::VAL;
-    delete l;
-    delete r;
-    return e;
-    */
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
 DValue* DivAssignExp::toElem(IRState* p)
 {
-    Logger::print("DivAssignExp::toElem: %s\n", toChars());
+    Logger::print("DivAssignExp::toElem: %s | %s\n", toChars(), type->toChars());
     LOG_SCOPE;
 
     DValue* l = e1->toElem(p);
     DValue* r = e2->toElem(p);
 
-    DValue* res = DtoBinDiv(l,r);
+    DValue* res;
+    if (type->iscomplex()) {
+        res = DtoComplexDiv(type, l, r);
+    }
+    else {
+        res = DtoBinDiv(l,r);
+    }
     DtoAssign(l, res);
 
     return l;
-
-    /*
-
-    Type* t = DtoDType(type);
-
-    llvm::Value* tmp;
-    if (t->isunsigned())
-        tmp = llvm::BinaryOperator::createUDiv(l->getValue(),r->getValue(),"tmp",p->scopebb());
-    else if (t->isintegral())
-        tmp = llvm::BinaryOperator::createSDiv(l->getValue(),r->getValue(),"tmp",p->scopebb());
-    else if (t->isfloating())
-        tmp = llvm::BinaryOperator::createFDiv(l->getValue(),r->getValue(),"tmp",p->scopebb());
-    else
-        assert(0);
-
-    assert(l->mem);
-    new llvm::StoreInst(tmp,l->mem,p->scopebb());
-
-    delete l;
-    delete r;
-
-    DValue* e = new DValue(this);
-    e->val = tmp;
-    e->type = DValue::VAR;
-    return e;
-    */
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
 DValue* ModExp::toElem(IRState* p)
 {
-    Logger::print("ModExp::toElem: %s\n", toChars());
+    Logger::print("ModExp::toElem: %s | %s\n", toChars(), type->toChars());
     LOG_SCOPE;
 
     DValue* l = e1->toElem(p);
     DValue* r = e2->toElem(p);
 
     return DtoBinRem(l, r);
-    /*
-    Type* t = DtoDType(type);
-
-    if (t->isunsigned())
-        e->val = llvm::BinaryOperator::createURem(l->getValue(),r->getValue(),"tmp",p->scopebb());
-    else if (t->isintegral())
-        e->val = llvm::BinaryOperator::createSRem(l->getValue(),r->getValue(),"tmp",p->scopebb());
-    else if (t->isfloating())
-        e->val = llvm::BinaryOperator::createFRem(l->getValue(),r->getValue(),"tmp",p->scopebb());
-    else
-        assert(0);
-    e->type = DValue::VAL;
-    delete l;
-    delete r;
-    return e;
-    */
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
 DValue* ModAssignExp::toElem(IRState* p)
 {
-    Logger::print("ModAssignExp::toElem: %s\n", toChars());
+    Logger::print("ModAssignExp::toElem: %s | %s\n", toChars(), type->toChars());
     LOG_SCOPE;
 
     DValue* l = e1->toElem(p);
@@ -1022,39 +741,13 @@
     DtoAssign(l, res);
 
     return l;
-
-    /*
-
-    Type* t = DtoDType(type);
-
-    llvm::Value* tmp;
-    if (t->isunsigned())
-        tmp = llvm::BinaryOperator::createURem(l->getValue(),r->getValue(),"tmp",p->scopebb());
-    else if (t->isintegral())
-        tmp = llvm::BinaryOperator::createSRem(l->getValue(),r->getValue(),"tmp",p->scopebb());
-    else if (t->isfloating())
-        tmp = llvm::BinaryOperator::createFRem(l->getValue(),r->getValue(),"tmp",p->scopebb());
-    else
-        assert(0);
-
-    assert(l->mem);
-    new llvm::StoreInst(tmp,l->mem,p->scopebb());
-
-    delete l;
-    delete r;
-
-    DValue* e = new DValue(this);
-    e->val = tmp;
-    e->type = DValue::VAR;
-    return e;
-    */
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
 DValue* CallExp::toElem(IRState* p)
 {
-    Logger::print("CallExp::toElem: %s\n", toChars());
+    Logger::print("CallExp::toElem: %s | %s\n", toChars(), type->toChars());
     LOG_SCOPE;
 
     DValue* fn = e1->toElem(p);
@@ -1880,6 +1573,11 @@
         }
         eval = new llvm::ICmpInst(cmpop, l->getRVal(), r->getRVal(), "tmp", p->scopebb());
     }
+    else if (t->iscomplex())
+    {
+        Logger::println("complex");
+        eval = DtoComplexEquals(op, l, r);
+    }
     else if (t->isfloating())
     {
         Logger::println("floating");
@@ -2439,9 +2137,9 @@
     if (t->isintegral())
         zero = llvm::ConstantInt::get(val->getType(), 0, true);
     else if (t->isfloating()) {
-        if (t->ty == Tfloat32)
+        if (t->ty == Tfloat32 || t->ty == Timaginary32)
             zero = llvm::ConstantFP::get(val->getType(), float(0));
-        else if (t->ty == Tfloat64 || t->ty == Tfloat80)
+        else if (t->ty == Tfloat64 || t->ty == Tfloat80 || t->ty == Timaginary64 || t->ty == Timaginary80)
             zero = llvm::ConstantFP::get(val->getType(), double(0));
         else
         assert(0);