Mercurial > projects > ldc
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());