Mercurial > projects > ldc
diff gen/tollvm.cpp @ 107:3efbcc81ba45 trunk
[svn r111] Fixed most problems with complex number support and added typeinfo for them.
Added typeinfo ti_C.
Did some changes to the way expressions that have both lvalue and rvalue LLVM values are handled.
author | lindquist |
---|---|
date | Tue, 20 Nov 2007 00:02:35 +0100 |
parents | 5b5194b25f33 |
children | 288fe1029e1f |
line wrap: on
line diff
--- a/gen/tollvm.cpp Mon Nov 19 06:01:48 2007 +0100 +++ b/gen/tollvm.cpp Tue Nov 20 00:02:35 2007 +0100 @@ -689,6 +689,10 @@ retval = new llvm::AllocaInst(DtoType(realtype), "tmpparam", gIR->topallocapoint()); DtoSetArray(retval, DtoArrayLen(sv), DtoArrayPtr(sv)); } + else if (DComplexValue* cv = arg->isComplex()) { + retval = new llvm::AllocaInst(DtoType(realtype), "tmpparam", gIR->topallocapoint()); + DtoComplexSet(retval, cv->re, cv->im); + } else { retval = arg->getRVal(); } @@ -719,6 +723,14 @@ allocaInst = new llvm::AllocaInst(pty->getElementType(), "tmpparam", gIR->topallocapoint()); } } + else if (realtype->iscomplex()) { + if (arg->isComplex()) { + allocaInst = new llvm::AllocaInst(realtypell, "tmpparam", gIR->topallocapoint()); + } + else { + allocaInst = new llvm::AllocaInst(pty->getElementType(), "tmpparam", gIR->topallocapoint()); + } + } else assert(0); @@ -736,6 +748,9 @@ if (sl->len) Logger::cout() << "len = " << *sl->len << '\n'; assert(0); } + else if (DComplexValue* cl = arg->isComplex()) { + assert(0 && "complex in the wrong place"); + } else { retval = arg->getRVal(); } @@ -895,19 +910,27 @@ } else if (t->iscomplex()) { assert(!lhs->isComplex()); - if (DComplexValue* cx = rhs->isComplex()) { - DtoComplexSet(lhs->getRVal(), cx->re, cx->im); + + llvm::Value* dst; + if (DLRValue* lr = lhs->isLRValue()) { + dst = lr->getLVal(); + rhs = DtoCastComplex(rhs, lr->getLType()); } else { - DtoComplexAssign(lhs->getRVal(), rhs->getRVal()); + dst = lhs->getRVal(); } + + if (DComplexValue* cx = rhs->isComplex()) + DtoComplexSet(dst, cx->re, cx->im); + else + DtoComplexAssign(dst, rhs->getRVal()); } else { llvm::Value* r = rhs->getRVal(); llvm::Value* l = lhs->getLVal(); Logger::cout() << "assign\nlhs: " << *l << "rhs: " << *r << '\n'; const llvm::Type* lit = l->getType()->getContainedType(0); - if (r->getType() != lit) { + if (r->getType() != lit) { // :( r = DtoBitCast(r, lit); Logger::cout() << "really assign\nlhs: " << *l << "rhs: " << *r << '\n'; } @@ -982,6 +1005,7 @@ rval = new llvm::PtrToIntInst(val->getRVal(), tolltype, "tmp", gIR->scopebb()); } else { + Logger::println("invalid cast from '%s' to '%s'", val->getType()->toChars(), to->toChars()); assert(0); } @@ -1040,16 +1064,48 @@ DValue* DtoCastComplex(DValue* val, Type* _to) { Type* to = DtoDType(_to); - llvm::Value* v = val->getRVal(); + Type* vty = val->getType(); if (to->iscomplex()) { - assert(0); + if (vty->size() == to->size()) + return val; + + llvm::Value *re, *im; + DtoGetComplexParts(val, re, im); + const llvm::Type* toty = DtoComplexBaseType(to); + + if (to->size() < vty->size()) { + re = gIR->ir->CreateFPTrunc(re, toty, "tmp"); + im = gIR->ir->CreateFPTrunc(im, toty, "tmp"); + } + else if (to->size() > vty->size()) { + re = gIR->ir->CreateFPExt(re, toty, "tmp"); + im = gIR->ir->CreateFPExt(im, toty, "tmp"); + } + else { + return val; + } + + if (val->isComplex()) + return new DComplexValue(_to, re, im); + + // unfortunately at this point, the cast value can show up as the lvalue for += and similar expressions. + // so we need to give it storage, or fix the system that handles this stuff (DLRValue) + llvm::Value* mem = new llvm::AllocaInst(DtoType(_to), "castcomplextmp", gIR->topallocapoint()); + DtoComplexSet(mem, re, im); + return new DLRValue(val->getType(), val->getRVal(), _to, mem); } else if (to->isimaginary()) { - DImValue* im = new DImValue(to, gIR->ir->CreateExtractElement(v, DtoConstUint(1), "im")); + if (val->isComplex()) + return new DImValue(to, val->isComplex()->im); + llvm::Value* v = val->getRVal(); + DImValue* im = new DImValue(to, DtoLoad(DtoGEPi(v,0,1,"tmp"))); return DtoCastFloat(im, to); } else if (to->isfloating()) { - DImValue* re = new DImValue(to, gIR->ir->CreateExtractElement(v, DtoConstUint(0), "re")); + if (val->isComplex()) + return new DImValue(to, val->isComplex()->re); + llvm::Value* v = val->getRVal(); + DImValue* re = new DImValue(to, DtoLoad(DtoGEPi(v,0,0,"tmp"))); return DtoCastFloat(re, to); } else