diff gen/tollvm.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 855adfdb8d38
children 5b5194b25f33
line wrap: on
line diff
--- a/gen/tollvm.cpp	Sun Nov 18 08:25:07 2007 +0100
+++ b/gen/tollvm.cpp	Mon Nov 19 02:58:58 2007 +0100
@@ -18,11 +18,13 @@
 #include "gen/structs.h"
 #include "gen/classes.h"
 #include "gen/typeinf.h"
+#include "gen/complex.h"
 
 bool DtoIsPassedByRef(Type* type)
 {
-    TY t = DtoDType(type)->ty;
-    return (t == Tstruct || t == Tarray || t == Tdelegate || t == Tsarray);
+    Type* typ = DtoDType(type);
+    TY t = typ->ty;
+    return (t == Tstruct || t == Tarray || t == Tdelegate || t == Tsarray || typ->iscomplex());
 }
 
 Type* DtoDType(Type* t)
@@ -72,10 +74,9 @@
 
     // complex
     case Tcomplex32:
-        return DtoComplexType(llvm::Type::FloatTy);
     case Tcomplex64:
     case Tcomplex80:
-        return DtoComplexType(llvm::Type::DoubleTy);
+        return DtoComplexType(t);
 
     // pointers
     case Tpointer: {
@@ -196,16 +197,6 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
-const llvm::StructType* DtoComplexType(const llvm::Type* base)
-{
-    std::vector<const llvm::Type*> types;
-    types.push_back(base);
-    types.push_back(base);
-    return llvm::StructType::get(types);
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
 static llvm::Function* LLVM_DeclareMemIntrinsic(const char* name, int bits, bool set=false)
 {
     assert(bits == 32 || bits == 64);
@@ -902,6 +893,15 @@
             DtoStore(rhs->getRVal(), lhs->getLVal());
         }
     }
+    else if (t->iscomplex()) {
+        assert(!lhs->isComplex());
+        if (DComplexValue* cx = rhs->isComplex()) {
+            DtoComplexSet(lhs->getRVal(), cx->re, cx->im);
+        }
+        else {
+            DtoComplexAssign(lhs->getRVal(), rhs->getRVal());
+        }
+    }
     else {
         llvm::Value* r = rhs->getRVal();
         llvm::Value* l = lhs->getLVal();
@@ -990,6 +990,9 @@
 
 DValue* DtoCastFloat(DValue* val, Type* to)
 {
+    if (val->getType() == to)
+        return val;
+
     const llvm::Type* tolltype = DtoType(to);
 
     Type* totype = DtoDType(to);
@@ -1001,7 +1004,11 @@
 
     llvm::Value* rval;
 
-    if (totype->isfloating()) {
+    if (totype->iscomplex()) {
+        assert(0);
+        //return new DImValue(to, DtoComplex(to, val));
+    }
+    else if (totype->isfloating()) {
         if ((fromtype->ty == Tfloat80 || fromtype->ty == Tfloat64) && (totype->ty == Tfloat80 || totype->ty == Tfloat64)) {
             rval = val->getRVal();
         }
@@ -1030,6 +1037,25 @@
     return new DImValue(to, rval);
 }
 
+DValue* DtoCastComplex(DValue* val, Type* _to)
+{
+    Type* to = DtoDType(_to);
+    llvm::Value* v = val->getRVal();
+    if (to->iscomplex()) {
+        assert(0);
+    }
+    else if (to->isimaginary()) {
+        DImValue* im = new DImValue(to, gIR->ir->CreateExtractElement(v, DtoConstUint(1), "im"));
+        return DtoCastFloat(im, to);
+    }
+    else if (to->isfloating()) {
+        DImValue* re = new DImValue(to, gIR->ir->CreateExtractElement(v, DtoConstUint(0), "re"));
+        return DtoCastFloat(re, to);
+    }
+    else
+    assert(0);
+}
+
 DValue* DtoCastClass(DValue* val, Type* _to)
 {
     const llvm::Type* tolltype = DtoType(_to);
@@ -1045,6 +1071,9 @@
     if (fromtype->isintegral()) {
         return DtoCastInt(val, to);
     }
+    else if (fromtype->iscomplex()) {
+        return DtoCastComplex(val, to);
+    }
     else if (fromtype->isfloating()) {
         return DtoCastFloat(val, to);
     }
@@ -1081,6 +1110,16 @@
     return llvm::ConstantInt::get(llvm::Type::Int1Ty, b, false);
 }
 
+llvm::ConstantFP* DtoConstFP(Type* t, long double value)
+{
+    TY ty = DtoDType(t)->ty;
+    if (ty == Tfloat32 || ty == Timaginary32)
+        return llvm::ConstantFP::get(llvm::Type::FloatTy, float(value));
+    else if (ty == Tfloat64 || ty == Timaginary64 || ty == Tfloat80 || ty == Timaginary80)
+        return llvm::ConstantFP::get(llvm::Type::DoubleTy, double(value));
+}
+
+
 //////////////////////////////////////////////////////////////////////////////////////////
 
 llvm::Constant* DtoConstString(const char* str)
@@ -1165,6 +1204,8 @@
     return false;
 }
 
+//////////////////////////////////////////////////////////////////////////////////////////
+
 llvm::Value* DtoBitCast(llvm::Value* v, const llvm::Type* t)
 {
     if (v->getType() == t)
@@ -1172,6 +1213,8 @@
     return gIR->ir->CreateBitCast(v, t, "tmp");
 }
 
+//////////////////////////////////////////////////////////////////////////////////////////
+
 const llvm::PointerType* isaPointer(llvm::Value* v)
 {
     return llvm::dyn_cast<llvm::PointerType>(v->getType());