mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-02-05 06:23:13 +01:00
[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.
This commit is contained in:
138
gen/complex.cpp
138
gen/complex.cpp
@@ -127,8 +127,7 @@ DValue* DtoComplex(Type* to, DValue* val)
|
||||
TY ty = t->ty;
|
||||
|
||||
if (val->isComplex() || t->iscomplex()) {
|
||||
assert(DtoDType(to) == t);
|
||||
return val;
|
||||
return DtoCastComplex(val, to);
|
||||
}
|
||||
|
||||
const llvm::Type* base = DtoComplexBaseType(to);
|
||||
@@ -166,6 +165,21 @@ void DtoComplexSet(llvm::Value* c, llvm::Value* re, llvm::Value* im)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DtoGetComplexParts(DValue* c, llvm::Value*& re, llvm::Value*& im)
|
||||
{
|
||||
// lhs values
|
||||
if (DComplexValue* cx = c->isComplex()) {
|
||||
re = cx->re;
|
||||
im = cx->im;
|
||||
}
|
||||
else {
|
||||
re = DtoLoad(DtoGEPi(c->getRVal(),0,0,"tmp"));
|
||||
im = DtoLoad(DtoGEPi(c->getRVal(),0,1,"tmp"));
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DValue* DtoComplexAdd(Type* type, DValue* lhs, DValue* rhs)
|
||||
{
|
||||
lhs = DtoComplex(type, lhs);
|
||||
@@ -174,24 +188,9 @@ DValue* DtoComplexAdd(Type* type, DValue* lhs, DValue* rhs)
|
||||
llvm::Value *a, *b, *c, *d, *re, *im;
|
||||
|
||||
// lhs values
|
||||
if (DComplexValue* cx = lhs->isComplex()) {
|
||||
a = cx->re;
|
||||
b = cx->im;
|
||||
}
|
||||
else {
|
||||
a = DtoLoad(DtoGEPi(lhs->getRVal(),0,0,"tmp"));
|
||||
b = DtoLoad(DtoGEPi(lhs->getRVal(),0,1,"tmp"));
|
||||
}
|
||||
|
||||
DtoGetComplexParts(lhs, a, b);
|
||||
// rhs values
|
||||
if (DComplexValue* cx = rhs->isComplex()) {
|
||||
c = cx->re;
|
||||
d = cx->im;
|
||||
}
|
||||
else {
|
||||
c = DtoLoad(DtoGEPi(rhs->getRVal(),0,0,"tmp"));
|
||||
d = DtoLoad(DtoGEPi(rhs->getRVal(),0,1,"tmp"));
|
||||
}
|
||||
DtoGetComplexParts(rhs, c, d);
|
||||
|
||||
// add up
|
||||
re = gIR->ir->CreateAdd(a, c, "tmp");
|
||||
@@ -210,24 +209,9 @@ DValue* DtoComplexSub(Type* type, DValue* lhs, DValue* rhs)
|
||||
llvm::Value *a, *b, *c, *d, *re, *im;
|
||||
|
||||
// lhs values
|
||||
if (DComplexValue* cx = lhs->isComplex()) {
|
||||
a = cx->re;
|
||||
b = cx->im;
|
||||
}
|
||||
else {
|
||||
a = DtoLoad(DtoGEPi(lhs->getRVal(),0,0,"tmp"));
|
||||
b = DtoLoad(DtoGEPi(lhs->getRVal(),0,1,"tmp"));
|
||||
}
|
||||
|
||||
DtoGetComplexParts(lhs, a, b);
|
||||
// rhs values
|
||||
if (DComplexValue* cx = rhs->isComplex()) {
|
||||
c = cx->re;
|
||||
d = cx->im;
|
||||
}
|
||||
else {
|
||||
c = DtoLoad(DtoGEPi(rhs->getRVal(),0,0,"tmp"));
|
||||
d = DtoLoad(DtoGEPi(rhs->getRVal(),0,1,"tmp"));
|
||||
}
|
||||
DtoGetComplexParts(rhs, c, d);
|
||||
|
||||
// add up
|
||||
re = gIR->ir->CreateSub(a, c, "tmp");
|
||||
@@ -243,29 +227,14 @@ DValue* DtoComplexMul(Type* type, DValue* lhs, DValue* rhs)
|
||||
lhs = DtoComplex(type, lhs);
|
||||
rhs = DtoComplex(type, rhs);
|
||||
|
||||
llvm::Value *a, *b, *c, *d, *re, *im;
|
||||
llvm::Value *a, *b, *c, *d;
|
||||
|
||||
// lhs values
|
||||
if (DComplexValue* cx = lhs->isComplex()) {
|
||||
a = cx->re;
|
||||
b = cx->im;
|
||||
}
|
||||
else {
|
||||
a = DtoLoad(DtoGEPi(lhs->getRVal(),0,0,"tmp"));
|
||||
b = DtoLoad(DtoGEPi(lhs->getRVal(),0,1,"tmp"));
|
||||
}
|
||||
|
||||
DtoGetComplexParts(lhs, a, b);
|
||||
// rhs values
|
||||
if (DComplexValue* cx = rhs->isComplex()) {
|
||||
c = cx->re;
|
||||
d = cx->im;
|
||||
}
|
||||
else {
|
||||
c = DtoLoad(DtoGEPi(rhs->getRVal(),0,0,"tmp"));
|
||||
d = DtoLoad(DtoGEPi(rhs->getRVal(),0,1,"tmp"));
|
||||
}
|
||||
DtoGetComplexParts(rhs, c, d);
|
||||
|
||||
llvm::Value *tmp1, *tmp2;
|
||||
llvm::Value *tmp1, *tmp2, *re, *im;
|
||||
|
||||
tmp1 = gIR->ir->CreateMul(a, c, "tmp");
|
||||
tmp2 = gIR->ir->CreateMul(b, d, "tmp");
|
||||
@@ -285,29 +254,14 @@ DValue* DtoComplexDiv(Type* type, DValue* lhs, DValue* rhs)
|
||||
lhs = DtoComplex(type, lhs);
|
||||
rhs = DtoComplex(type, rhs);
|
||||
|
||||
llvm::Value *a, *b, *c, *d, *re, *im;
|
||||
llvm::Value *a, *b, *c, *d;
|
||||
|
||||
// lhs values
|
||||
if (DComplexValue* cx = lhs->isComplex()) {
|
||||
a = cx->re;
|
||||
b = cx->im;
|
||||
}
|
||||
else {
|
||||
a = DtoLoad(DtoGEPi(lhs->getRVal(),0,0,"tmp"));
|
||||
b = DtoLoad(DtoGEPi(lhs->getRVal(),0,1,"tmp"));
|
||||
}
|
||||
|
||||
DtoGetComplexParts(lhs, a, b);
|
||||
// rhs values
|
||||
if (DComplexValue* cx = rhs->isComplex()) {
|
||||
c = cx->re;
|
||||
d = cx->im;
|
||||
}
|
||||
else {
|
||||
c = DtoLoad(DtoGEPi(rhs->getRVal(),0,0,"tmp"));
|
||||
d = DtoLoad(DtoGEPi(rhs->getRVal(),0,1,"tmp"));
|
||||
}
|
||||
DtoGetComplexParts(rhs, c, d);
|
||||
|
||||
llvm::Value *tmp1, *tmp2, *denom;
|
||||
llvm::Value *tmp1, *tmp2, *denom, *re, *im;
|
||||
|
||||
tmp1 = gIR->ir->CreateMul(c, c, "tmp");
|
||||
tmp2 = gIR->ir->CreateMul(d, d, "tmp");
|
||||
@@ -330,29 +284,27 @@ DValue* DtoComplexDiv(Type* type, DValue* lhs, DValue* rhs)
|
||||
|
||||
llvm::Value* DtoComplexEquals(TOK op, DValue* lhs, DValue* rhs)
|
||||
{
|
||||
llvm::Value* lvec = lhs->getRVal();
|
||||
llvm::Value* rvec = rhs->getRVal();
|
||||
Type* type = lhs->getType();
|
||||
|
||||
lhs = DtoComplex(type, lhs);
|
||||
rhs = DtoComplex(type, rhs);
|
||||
|
||||
llvm::Value *a, *b, *c, *d;
|
||||
|
||||
// lhs values
|
||||
DtoGetComplexParts(lhs, a, b);
|
||||
// rhs values
|
||||
DtoGetComplexParts(rhs, c, d);
|
||||
|
||||
// select predicate
|
||||
llvm::FCmpInst::Predicate cmpop;
|
||||
switch(op)
|
||||
{
|
||||
case TOKequal:
|
||||
if (op == TOKequal)
|
||||
cmpop = llvm::FCmpInst::FCMP_OEQ;
|
||||
break;
|
||||
case TOKnotequal:
|
||||
else
|
||||
cmpop = llvm::FCmpInst::FCMP_UNE;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
llvm::Value* l1 = gIR->ir->CreateExtractElement(lvec, DtoConstUint(0), "re");
|
||||
llvm::Value* r1 = gIR->ir->CreateExtractElement(rvec, DtoConstUint(0), "re");
|
||||
llvm::Value* b1 = new llvm::FCmpInst(cmpop, l1, r1, "tmp", gIR->scopebb());
|
||||
|
||||
llvm::Value* l2 = gIR->ir->CreateExtractElement(lvec, DtoConstUint(1), "im");
|
||||
llvm::Value* r2 = gIR->ir->CreateExtractElement(rvec, DtoConstUint(1), "im");
|
||||
llvm::Value* b2 = new llvm::FCmpInst(cmpop, l2, r2, "tmp", gIR->scopebb());
|
||||
|
||||
// (l.re==r.re && l.im==r.im)
|
||||
llvm::Value* b1 = new llvm::FCmpInst(cmpop, a, c, "tmp", gIR->scopebb());
|
||||
llvm::Value* b2 = new llvm::FCmpInst(cmpop, b, d, "tmp", gIR->scopebb());
|
||||
return gIR->ir->CreateAnd(b1,b2,"tmp");
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ DValue* DtoComplex(Type* to, DValue* val);
|
||||
void DtoComplexAssign(llvm::Value* l, llvm::Value* r);
|
||||
void DtoComplexSet(llvm::Value* c, llvm::Value* re, llvm::Value* im);
|
||||
|
||||
void DtoGetComplexParts(DValue* c, llvm::Value*& re, llvm::Value*& im);
|
||||
|
||||
DValue* DtoComplexAdd(Type* type, DValue* lhs, DValue* rhs);
|
||||
DValue* DtoComplexSub(Type* type, DValue* lhs, DValue* rhs);
|
||||
DValue* DtoComplexMul(Type* type, DValue* lhs, DValue* rhs);
|
||||
|
||||
24
gen/dvalue.h
24
gen/dvalue.h
@@ -31,7 +31,7 @@ struct DThisValue;
|
||||
struct DFuncValue;
|
||||
struct DSliceValue;
|
||||
struct DArrayLenValue;
|
||||
struct DLValueCast;
|
||||
struct DLRValue;
|
||||
struct DComplexValue;
|
||||
|
||||
// base class for d-values
|
||||
@@ -51,8 +51,8 @@ struct DValue : Object
|
||||
virtual DSliceValue* isSlice() { return NULL; }
|
||||
virtual DFuncValue* isFunc() { return NULL; }
|
||||
virtual DArrayLenValue* isArrayLen() { return NULL; }
|
||||
virtual DLValueCast* isLValueCast() { return NULL; }
|
||||
virtual DComplexValue* isComplex() { return NULL; };
|
||||
virtual DComplexValue* isComplex() { return NULL; }
|
||||
virtual DLRValue* isLRValue() { return NULL; }
|
||||
|
||||
virtual bool inPlace() { return false; }
|
||||
|
||||
@@ -172,24 +172,28 @@ struct DFuncValue : DValue
|
||||
virtual DFuncValue* isFunc() { return this; }
|
||||
};
|
||||
|
||||
// l-value cast d-value
|
||||
struct DLValueCast : DValue
|
||||
// l-value and r-value pair d-value
|
||||
struct DLRValue : DValue
|
||||
{
|
||||
Type* type;
|
||||
Type* ltype;
|
||||
llvm::Value* lval;
|
||||
Type* rtype;
|
||||
llvm::Value* rval;
|
||||
|
||||
DLValueCast(Type* t, llvm::Value* l, llvm::Value* r) {
|
||||
type = t;
|
||||
DLRValue(Type* lt, llvm::Value* l, Type* rt, llvm::Value* r) {
|
||||
ltype = lt;
|
||||
lval = l;
|
||||
rtype = rt;
|
||||
rval = r;
|
||||
}
|
||||
|
||||
virtual llvm::Value* getLVal() { assert(lval); return lval; }
|
||||
virtual llvm::Value* getRVal() { assert(rval); return rval; }
|
||||
|
||||
virtual Type* getType() { assert(type); return type; }
|
||||
virtual DLValueCast* isLValueCast() { return this; }
|
||||
Type* getLType() { return ltype; }
|
||||
Type* getRType() { return rtype; }
|
||||
virtual Type* getType() { return getRType(); }
|
||||
virtual DLRValue* isLRValue() { return this; }
|
||||
};
|
||||
|
||||
// complex number immediate d-value (much like slice)
|
||||
|
||||
20
gen/toir.cpp
20
gen/toir.cpp
@@ -562,7 +562,7 @@ DValue* AddAssignExp::toElem(IRState* p)
|
||||
res = new DImValue(type, gep);
|
||||
}
|
||||
else if (t->iscomplex()) {
|
||||
res = DtoComplexAdd(type, l, r);
|
||||
res = DtoComplexAdd(e1->type, l, r);
|
||||
}
|
||||
else {
|
||||
res = DtoBinAdd(l,r);
|
||||
@@ -1056,17 +1056,17 @@ DValue* CastExp::toElem(IRState* p)
|
||||
DValue* u = e1->toElem(p);
|
||||
DValue* v = DtoCast(u, to);
|
||||
|
||||
if (v->isSlice())
|
||||
if (v->isSlice()) {
|
||||
assert(!gIR->topexp() || gIR->topexp()->e1 != this);
|
||||
return v;
|
||||
else if (u->isLValueCast() || (u->isVar() && u->isVar()->lval))
|
||||
return new DLValueCast(to, u->getLVal(), v->getRVal());
|
||||
else if (gIR->topexp() && gIR->topexp()->e1 == this) {
|
||||
llvm::Value* lval = u->getLVal();
|
||||
llvm::Value* rval = v->getRVal();
|
||||
Logger::cout() << "lval: " << *lval << "rval: " << *rval << '\n';
|
||||
return new DLValueCast(to, lval, rval);
|
||||
}
|
||||
|
||||
else if (u->isLRValue() || (u->isVar() && u->isVar()->lval))
|
||||
return new DLRValue(e1->type, u->getLVal(), to, v->getRVal());
|
||||
|
||||
else if (gIR->topexp() && gIR->topexp()->e1 == this)
|
||||
return new DLRValue(e1->type, u->getLVal(), to, v->getRVal());
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -1193,7 +1193,7 @@ DValue* PtrExp::toElem(IRState* p)
|
||||
llvm::Value* v = lv;
|
||||
if (DtoCanLoad(v))
|
||||
v = DtoLoad(v);
|
||||
return new DLValueCast(type, lv, v);
|
||||
return new DLRValue(e1->type, lv, type, v);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -689,6 +689,10 @@ llvm::Value* DtoArgument(const llvm::Type* paramtype, Argument* fnarg, Expressio
|
||||
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 @@ llvm::Value* DtoArgument(const llvm::Type* paramtype, Argument* fnarg, Expressio
|
||||
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 @@ llvm::Value* DtoArgument(const llvm::Type* paramtype, Argument* fnarg, Expressio
|
||||
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 @@ void DtoAssign(DValue* lhs, DValue* rhs)
|
||||
}
|
||||
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 @@ DValue* DtoCastPtr(DValue* val, Type* to)
|
||||
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* DtoCastFloat(DValue* val, Type* to)
|
||||
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
|
||||
|
||||
@@ -132,7 +132,6 @@ gen/tollvm.cpp
|
||||
gen/tollvm.h
|
||||
gen/toobj.cpp
|
||||
gen/typeinf.h
|
||||
gen/typeinfo12.d
|
||||
gen/typinf.cpp
|
||||
lphobos
|
||||
lphobos/crc32.d
|
||||
@@ -193,7 +192,10 @@ lphobos/std/uni.d
|
||||
lphobos/std/utf.d
|
||||
lphobos/typeinfo1
|
||||
lphobos/typeinfo1/ti_byte.d
|
||||
lphobos/typeinfo1/ti_cdouble.d
|
||||
lphobos/typeinfo1/ti_cfloat.d
|
||||
lphobos/typeinfo1/ti_char.d
|
||||
lphobos/typeinfo1/ti_creal.d
|
||||
lphobos/typeinfo1/ti_dchar.d
|
||||
lphobos/typeinfo1/ti_delegate.d
|
||||
lphobos/typeinfo1/ti_double.d
|
||||
@@ -213,6 +215,7 @@ lphobos/typeinfo1/ti_ushort.d
|
||||
lphobos/typeinfo1/ti_void.d
|
||||
lphobos/typeinfo1/ti_wchar.d
|
||||
lphobos/typeinfo2
|
||||
lphobos/typeinfo2/ti_AC.d
|
||||
lphobos/typeinfo2/ti_Adouble.d
|
||||
lphobos/typeinfo2/ti_Afloat.d
|
||||
lphobos/typeinfo2/ti_Ag.d
|
||||
@@ -220,6 +223,7 @@ lphobos/typeinfo2/ti_Aint.d
|
||||
lphobos/typeinfo2/ti_Along.d
|
||||
lphobos/typeinfo2/ti_Areal.d
|
||||
lphobos/typeinfo2/ti_Ashort.d
|
||||
lphobos/typeinfo2/ti_C.d
|
||||
lphobos/typeinfos1.d
|
||||
lphobos/typeinfos2.d
|
||||
runalltests.d
|
||||
@@ -304,8 +308,8 @@ test/bug62.d
|
||||
test/bug63.d
|
||||
test/bug64.d
|
||||
test/bug66.d
|
||||
test/bug69.d
|
||||
test/bug7.d
|
||||
test/bug70.d
|
||||
test/bug8.d
|
||||
test/bug9.d
|
||||
test/c.d
|
||||
|
||||
@@ -20,7 +20,7 @@ llvm-link -f -o=../lib/llvmdcore.bc `ls obj/internal.*.bc` ../lib/llvmdcore.bc o
|
||||
|
||||
|
||||
echo "compiling typeinfo 1"
|
||||
rebuild typeinfos1.d -c -oqobj -dc=llvmdc-posix || exit 1
|
||||
rebuild typeinfos1.d -c -oqobj -dc=llvmdc-posix -v || exit 1
|
||||
llvm-link -f -o=../lib/llvmdcore.bc `ls obj/typeinfo1.*.bc` ../lib/llvmdcore.bc || exit 1
|
||||
|
||||
echo "compiling typeinfo 2"
|
||||
|
||||
67
lphobos/typeinfo1/ti_cdouble.d
Normal file
67
lphobos/typeinfo1/ti_cdouble.d
Normal file
@@ -0,0 +1,67 @@
|
||||
|
||||
// cdouble
|
||||
|
||||
module std.typeinfo.ti_cdouble;
|
||||
|
||||
class TypeInfo_r : TypeInfo
|
||||
{
|
||||
char[] toString() { return "cdouble"; }
|
||||
|
||||
hash_t getHash(void *p)
|
||||
{
|
||||
return (cast(uint *)p)[0] + (cast(uint *)p)[1] +
|
||||
(cast(uint *)p)[2] + (cast(uint *)p)[3];
|
||||
}
|
||||
|
||||
static int _equals(cdouble f1, cdouble f2)
|
||||
{
|
||||
return f1 == f2;
|
||||
}
|
||||
|
||||
static int _compare(cdouble f1, cdouble f2)
|
||||
{ int result;
|
||||
|
||||
if (f1.re < f2.re)
|
||||
result = -1;
|
||||
else if (f1.re > f2.re)
|
||||
result = 1;
|
||||
else if (f1.im < f2.im)
|
||||
result = -1;
|
||||
else if (f1.im > f2.im)
|
||||
result = 1;
|
||||
else
|
||||
result = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
return _equals(*cast(cdouble *)p1, *cast(cdouble *)p2);
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
return _compare(*cast(cdouble *)p1, *cast(cdouble *)p2);
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return cdouble.sizeof;
|
||||
}
|
||||
|
||||
void swap(void *p1, void *p2)
|
||||
{
|
||||
cdouble t;
|
||||
|
||||
t = *cast(cdouble *)p1;
|
||||
*cast(cdouble *)p1 = *cast(cdouble *)p2;
|
||||
*cast(cdouble *)p2 = t;
|
||||
}
|
||||
|
||||
void[] init()
|
||||
{ static cdouble r;
|
||||
|
||||
return (cast(cdouble *)&r)[0 .. 1];
|
||||
}
|
||||
}
|
||||
|
||||
66
lphobos/typeinfo1/ti_cfloat.d
Normal file
66
lphobos/typeinfo1/ti_cfloat.d
Normal file
@@ -0,0 +1,66 @@
|
||||
|
||||
// cfloat
|
||||
|
||||
module std.typeinfo.ti_cfloat;
|
||||
|
||||
class TypeInfo_q : TypeInfo
|
||||
{
|
||||
char[] toString() { return "cfloat"; }
|
||||
|
||||
hash_t getHash(void *p)
|
||||
{
|
||||
return (cast(uint *)p)[0] + (cast(uint *)p)[1];
|
||||
}
|
||||
|
||||
static int _equals(cfloat f1, cfloat f2)
|
||||
{
|
||||
return f1 == f2;
|
||||
}
|
||||
|
||||
static int _compare(cfloat f1, cfloat f2)
|
||||
{ int result;
|
||||
|
||||
if (f1.re < f2.re)
|
||||
result = -1;
|
||||
else if (f1.re > f2.re)
|
||||
result = 1;
|
||||
else if (f1.im < f2.im)
|
||||
result = -1;
|
||||
else if (f1.im > f2.im)
|
||||
result = 1;
|
||||
else
|
||||
result = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
return _equals(*cast(cfloat *)p1, *cast(cfloat *)p2);
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
return _compare(*cast(cfloat *)p1, *cast(cfloat *)p2);
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return cfloat.sizeof;
|
||||
}
|
||||
|
||||
void swap(void *p1, void *p2)
|
||||
{
|
||||
cfloat t;
|
||||
|
||||
t = *cast(cfloat *)p1;
|
||||
*cast(cfloat *)p1 = *cast(cfloat *)p2;
|
||||
*cast(cfloat *)p2 = t;
|
||||
}
|
||||
|
||||
void[] init()
|
||||
{ static cfloat r;
|
||||
|
||||
return (cast(cfloat *)&r)[0 .. 1];
|
||||
}
|
||||
}
|
||||
|
||||
68
lphobos/typeinfo1/ti_creal.d
Normal file
68
lphobos/typeinfo1/ti_creal.d
Normal file
@@ -0,0 +1,68 @@
|
||||
|
||||
// creal
|
||||
|
||||
module std.typeinfo.ti_creal;
|
||||
|
||||
class TypeInfo_c : TypeInfo
|
||||
{
|
||||
char[] toString() { return "creal"; }
|
||||
|
||||
hash_t getHash(void *p)
|
||||
{
|
||||
return (cast(uint *)p)[0] + (cast(uint *)p)[1] +
|
||||
(cast(uint *)p)[2] + (cast(uint *)p)[3] +
|
||||
(cast(uint *)p)[4];
|
||||
}
|
||||
|
||||
static int _equals(creal f1, creal f2)
|
||||
{
|
||||
return f1 == f2;
|
||||
}
|
||||
|
||||
static int _compare(creal f1, creal f2)
|
||||
{ int result;
|
||||
|
||||
if (f1.re < f2.re)
|
||||
result = -1;
|
||||
else if (f1.re > f2.re)
|
||||
result = 1;
|
||||
else if (f1.im < f2.im)
|
||||
result = -1;
|
||||
else if (f1.im > f2.im)
|
||||
result = 1;
|
||||
else
|
||||
result = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
return _equals(*cast(creal *)p1, *cast(creal *)p2);
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
return _compare(*cast(creal *)p1, *cast(creal *)p2);
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return creal.sizeof;
|
||||
}
|
||||
|
||||
void swap(void *p1, void *p2)
|
||||
{
|
||||
creal t;
|
||||
|
||||
t = *cast(creal *)p1;
|
||||
*cast(creal *)p1 = *cast(creal *)p2;
|
||||
*cast(creal *)p2 = t;
|
||||
}
|
||||
|
||||
void[] init()
|
||||
{ static creal r;
|
||||
|
||||
return (cast(creal *)&r)[0 .. 1];
|
||||
}
|
||||
}
|
||||
|
||||
92
lphobos/typeinfo2/ti_AC.d
Normal file
92
lphobos/typeinfo2/ti_AC.d
Normal file
@@ -0,0 +1,92 @@
|
||||
module std.typeinfo.ti_AC;
|
||||
|
||||
// Object[]
|
||||
|
||||
class TypeInfo_AC : TypeInfo
|
||||
{
|
||||
hash_t getHash(void *p)
|
||||
{ Object[] s = *cast(Object[]*)p;
|
||||
hash_t hash = 0;
|
||||
|
||||
foreach (Object o; s)
|
||||
{
|
||||
if (o)
|
||||
hash += o.toHash();
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
Object[] s1 = *cast(Object[]*)p1;
|
||||
Object[] s2 = *cast(Object[]*)p2;
|
||||
|
||||
if (s1.length == s2.length)
|
||||
{
|
||||
for (size_t u = 0; u < s1.length; u++)
|
||||
{ Object o1 = s1[u];
|
||||
Object o2 = s2[u];
|
||||
|
||||
// Do not pass null's to Object.opEquals()
|
||||
if (o1 is o2 ||
|
||||
(!(o1 is null) && !(o2 is null) && o1.opEquals(o2)))
|
||||
continue;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
Object[] s1 = *cast(Object[]*)p1;
|
||||
Object[] s2 = *cast(Object[]*)p2;
|
||||
int c;
|
||||
|
||||
c = cast(int)s1.length - cast(int)s2.length;
|
||||
if (c == 0)
|
||||
{
|
||||
for (size_t u = 0; u < s1.length; u++)
|
||||
{ Object o1 = s1[u];
|
||||
Object o2 = s2[u];
|
||||
|
||||
if (o1 is o2)
|
||||
continue;
|
||||
|
||||
// Regard null references as always being "less than"
|
||||
if (o1)
|
||||
{
|
||||
if (!o2)
|
||||
{ c = 1;
|
||||
break;
|
||||
}
|
||||
c = o1.opCmp(o2);
|
||||
if (c)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{ c = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return (Object[]).sizeof;
|
||||
}
|
||||
|
||||
uint flags()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
TypeInfo next()
|
||||
{
|
||||
return typeid(Object);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,13 +2,16 @@ module typeinfos1;
|
||||
|
||||
import
|
||||
typeinfo1.ti_byte,
|
||||
typeinfo1.ti_cdouble,
|
||||
typeinfo1.ti_cfloat,
|
||||
typeinfo1.ti_char,
|
||||
typeinfo1.ti_delegate,
|
||||
typeinfo1.ti_creal,
|
||||
typeinfo1.ti_dchar,
|
||||
typeinfo1.ti_delegate,
|
||||
typeinfo1.ti_double,
|
||||
typeinfo1.ti_float,
|
||||
typeinfo1.ti_ifloat,
|
||||
typeinfo1.ti_idouble,
|
||||
typeinfo1.ti_ifloat,
|
||||
typeinfo1.ti_int,
|
||||
typeinfo1.ti_ireal,
|
||||
typeinfo1.ti_long,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
module typeinfos2;
|
||||
|
||||
import
|
||||
//typeinfo2.to_AC,
|
||||
typeinfo2.ti_Adouble,
|
||||
typeinfo2.ti_Afloat,
|
||||
typeinfo2.ti_Ag,
|
||||
|
||||
@@ -4,6 +4,6 @@ void main()
|
||||
{
|
||||
cfloat c1 = 1f + 0i;
|
||||
cfloat c2 = 0f + 0i;
|
||||
//c2 += 1f + 0i;
|
||||
c2 += 1f + 0i;
|
||||
//assert(c1 == c2);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user