mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-11 18:33:14 +01:00
[svn r380] Improve complex number support.
This commit is contained in:
@@ -104,7 +104,6 @@ LLValue* DtoImagPart(DValue* val)
|
||||
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 @@ DValue* DtoComplex(Type* to, DValue* val)
|
||||
|
||||
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 if (t->isintegral()) {
|
||||
return new DComplexValue(to, DtoCastInt(val, baserety)->getRVal(), LLConstant::getNullValue(DtoType(baseimty)));
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
}
|
||||
|
||||
@@ -149,7 +155,7 @@ void DtoComplexSet(LLValue* c, LLValue* re, LLValue* im)
|
||||
|
||||
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 @@ void DtoGetComplexParts(DValue* c, LLValue*& re, LLValue*& im)
|
||||
}
|
||||
}
|
||||
|
||||
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* DtoComplexAdd(Type* type, DValue* lhs, DValue* rhs)
|
||||
|
||||
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* DtoComplexSub(Type* type, DValue* lhs, DValue* rhs)
|
||||
|
||||
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* DtoComplexMul(Type* type, DValue* lhs, DValue* rhs)
|
||||
|
||||
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* DtoComplexDiv(Type* type, DValue* lhs, DValue* rhs)
|
||||
|
||||
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 @@ LLValue* DtoComplexEquals(TOK op, DValue* lhs, DValue* rhs)
|
||||
{
|
||||
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 @@ DValue* DtoCastComplex(DValue* val, Type* _to)
|
||||
// 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())
|
||||
|
||||
24
gen/dvalue.h
24
gen/dvalue.h
@@ -169,24 +169,20 @@ struct DFuncValue : DValue
|
||||
// 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; }
|
||||
};
|
||||
|
||||
@@ -671,6 +671,9 @@ DValue* DtoCastInt(DValue* val, Type* _to)
|
||||
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 @@ DValue* DtoCastFloat(DValue* val, Type* to)
|
||||
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());
|
||||
}
|
||||
|
||||
@@ -1257,7 +1257,7 @@ DValue* CastExp::toElem(IRState* p)
|
||||
}
|
||||
|
||||
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 @@ DValue* PtrExp::toElem(IRState* p)
|
||||
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));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Reference in New Issue
Block a user