mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-14 07:09:50 +03:00
[svn r108] Now basic suppport for complex types. =,+,-,*,/ are supported.
This commit is contained in:
parent
6da09c01b3
commit
5e9f5034ff
11 changed files with 592 additions and 392 deletions
|
@ -3,26 +3,35 @@
|
|||
#include "declaration.h"
|
||||
|
||||
#include "gen/irstate.h"
|
||||
#include "gen/tollvm.h"
|
||||
#include "gen/dvalue.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DValue* DtoBinAdd(DValue* lhs, DValue* rhs)
|
||||
{
|
||||
llvm::Value* v = gIR->ir->CreateAdd(lhs->getRVal(), rhs->getRVal(), "tmp");
|
||||
return new DImValue( lhs->getType(), v );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DValue* DtoBinSub(DValue* lhs, DValue* rhs)
|
||||
{
|
||||
llvm::Value* v = gIR->ir->CreateSub(lhs->getRVal(), rhs->getRVal(), "tmp");
|
||||
return new DImValue( lhs->getType(), v );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DValue* DtoBinMul(DValue* lhs, DValue* rhs)
|
||||
{
|
||||
llvm::Value* v = gIR->ir->CreateMul(lhs->getRVal(), rhs->getRVal(), "tmp");
|
||||
return new DImValue( lhs->getType(), v );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DValue* DtoBinDiv(DValue* lhs, DValue* rhs)
|
||||
{
|
||||
Type* t = lhs->getType();
|
||||
|
@ -39,6 +48,8 @@ DValue* DtoBinDiv(DValue* lhs, DValue* rhs)
|
|||
return new DImValue( lhs->getType(), res );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DValue* DtoBinRem(DValue* lhs, DValue* rhs)
|
||||
{
|
||||
Type* t = lhs->getType();
|
||||
|
|
358
gen/complex.cpp
Normal file
358
gen/complex.cpp
Normal file
|
@ -0,0 +1,358 @@
|
|||
#include "gen/llvm.h"
|
||||
|
||||
#include "mtype.h"
|
||||
#include "declaration.h"
|
||||
|
||||
#include "gen/complex.h"
|
||||
#include "gen/tollvm.h"
|
||||
#include "gen/irstate.h"
|
||||
#include "gen/dvalue.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const llvm::StructType* DtoComplexType(Type* type)
|
||||
{
|
||||
Type* t = DtoDType(type);
|
||||
|
||||
const llvm::Type* base = DtoComplexBaseType(t);
|
||||
|
||||
std::vector<const llvm::Type*> types;
|
||||
types.push_back(base);
|
||||
types.push_back(base);
|
||||
|
||||
return llvm::StructType::get(types);
|
||||
}
|
||||
|
||||
const llvm::Type* DtoComplexBaseType(Type* t)
|
||||
{
|
||||
TY ty = DtoDType(t)->ty;
|
||||
const llvm::Type* base;
|
||||
if (ty == Tcomplex32) {
|
||||
return llvm::Type::FloatTy;
|
||||
}
|
||||
else if (ty == Tcomplex64 || ty == Tcomplex80) {
|
||||
return llvm::Type::DoubleTy;
|
||||
}
|
||||
else {
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::Constant* DtoConstComplex(Type* ty, llvm::Constant* re, llvm::Constant* im)
|
||||
{
|
||||
assert(0);
|
||||
const llvm::Type* base = DtoComplexBaseType(ty);
|
||||
|
||||
std::vector<llvm::Constant*> inits;
|
||||
inits.push_back(re);
|
||||
inits.push_back(im);
|
||||
|
||||
const llvm::VectorType* vt = llvm::VectorType::get(base, 2);
|
||||
return llvm::ConstantVector::get(vt, inits);
|
||||
}
|
||||
|
||||
llvm::Constant* DtoConstComplex(Type* _ty, long double re, long double im)
|
||||
{
|
||||
TY ty = DtoDType(_ty)->ty;
|
||||
|
||||
llvm::ConstantFP* fre;
|
||||
llvm::ConstantFP* fim;
|
||||
|
||||
const llvm::Type* base;
|
||||
|
||||
if (ty == Tcomplex32) {
|
||||
fre = DtoConstFP(Type::tfloat32, re);
|
||||
fim = DtoConstFP(Type::tfloat32, im);
|
||||
base = llvm::Type::FloatTy;
|
||||
}
|
||||
else if (ty == Tcomplex64 || ty == Tcomplex80) {
|
||||
fre = DtoConstFP(Type::tfloat64, re);
|
||||
fim = DtoConstFP(Type::tfloat64, im);
|
||||
base = llvm::Type::DoubleTy;
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
|
||||
std::vector<llvm::Constant*> inits;
|
||||
inits.push_back(fre);
|
||||
inits.push_back(fim);
|
||||
return llvm::ConstantStruct::get(DtoComplexType(_ty), inits);
|
||||
}
|
||||
|
||||
llvm::Constant* DtoUndefComplex(Type* _ty)
|
||||
{
|
||||
assert(0);
|
||||
TY ty = DtoDType(_ty)->ty;
|
||||
const llvm::Type* base;
|
||||
if (ty == Tcomplex32) {
|
||||
base = llvm::Type::FloatTy;
|
||||
}
|
||||
else if (ty == Tcomplex64 || ty == Tcomplex80) {
|
||||
base = llvm::Type::DoubleTy;
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
|
||||
std::vector<llvm::Constant*> inits;
|
||||
inits.push_back(llvm::UndefValue::get(base));
|
||||
inits.push_back(llvm::UndefValue::get(base));
|
||||
|
||||
const llvm::VectorType* vt = llvm::VectorType::get(base, 2);
|
||||
return llvm::ConstantVector::get(vt, inits);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::Value* DtoRealPart(DValue* val)
|
||||
{
|
||||
assert(0);
|
||||
return gIR->ir->CreateExtractElement(val->getRVal(), DtoConstUint(0), "tmp");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::Value* DtoImagPart(DValue* val)
|
||||
{
|
||||
assert(0);
|
||||
return gIR->ir->CreateExtractElement(val->getRVal(), DtoConstUint(1), "tmp");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DValue* DtoComplex(Type* to, DValue* val)
|
||||
{
|
||||
Type* t = DtoDType(val->getType());
|
||||
TY ty = t->ty;
|
||||
|
||||
if (val->isComplex() || t->iscomplex()) {
|
||||
assert(DtoDType(to) == t);
|
||||
return val;
|
||||
}
|
||||
|
||||
const llvm::Type* base = DtoComplexBaseType(to);
|
||||
|
||||
llvm::Constant* undef = llvm::UndefValue::get(base);
|
||||
llvm::Constant* zero;
|
||||
if (ty == Tfloat32 || ty == Timaginary32 || ty == Tcomplex32)
|
||||
zero = llvm::ConstantFP::get(llvm::Type::FloatTy, float(0));
|
||||
else if (ty == Tfloat64 || ty == Timaginary64 || ty == Tcomplex64 || ty == Tfloat80 || ty == Timaginary80 || ty == Tcomplex80)
|
||||
zero = llvm::ConstantFP::get(llvm::Type::DoubleTy, double(0));
|
||||
|
||||
if (t->isimaginary()) {
|
||||
return new DComplexValue(to, zero, val->getRVal());
|
||||
}
|
||||
else if (t->isfloating()) {
|
||||
return new DComplexValue(to, val->getRVal(), zero);
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DtoComplexAssign(llvm::Value* l, llvm::Value* r)
|
||||
{
|
||||
DtoStore(DtoLoad(DtoGEPi(r, 0,0, "tmp")), DtoGEPi(l,0,0,"tmp"));
|
||||
DtoStore(DtoLoad(DtoGEPi(r, 0,1, "tmp")), DtoGEPi(l,0,1,"tmp"));
|
||||
}
|
||||
|
||||
void DtoComplexSet(llvm::Value* c, llvm::Value* re, llvm::Value* im)
|
||||
{
|
||||
DtoStore(re, DtoGEPi(c,0,0,"tmp"));
|
||||
DtoStore(im, DtoGEPi(c,0,1,"tmp"));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DValue* DtoComplexAdd(Type* type, DValue* lhs, DValue* rhs)
|
||||
{
|
||||
lhs = DtoComplex(type, lhs);
|
||||
rhs = DtoComplex(type, 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"));
|
||||
}
|
||||
|
||||
// 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"));
|
||||
}
|
||||
|
||||
// add up
|
||||
re = gIR->ir->CreateAdd(a, c, "tmp");
|
||||
im = gIR->ir->CreateAdd(b, d, "tmp");
|
||||
|
||||
return new DComplexValue(type, re, im);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DValue* DtoComplexSub(Type* type, DValue* lhs, DValue* rhs)
|
||||
{
|
||||
lhs = DtoComplex(type, lhs);
|
||||
rhs = DtoComplex(type, 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"));
|
||||
}
|
||||
|
||||
// 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"));
|
||||
}
|
||||
|
||||
// add up
|
||||
re = gIR->ir->CreateSub(a, c, "tmp");
|
||||
im = gIR->ir->CreateSub(b, d, "tmp");
|
||||
|
||||
return new DComplexValue(type, re, im);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DValue* DtoComplexMul(Type* type, DValue* lhs, DValue* rhs)
|
||||
{
|
||||
lhs = DtoComplex(type, lhs);
|
||||
rhs = DtoComplex(type, 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"));
|
||||
}
|
||||
|
||||
// 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"));
|
||||
}
|
||||
|
||||
llvm::Value *tmp1, *tmp2;
|
||||
|
||||
tmp1 = gIR->ir->CreateMul(a, c, "tmp");
|
||||
tmp2 = gIR->ir->CreateMul(b, d, "tmp");
|
||||
re = gIR->ir->CreateSub(tmp1, tmp2, "tmp");
|
||||
|
||||
tmp1 = gIR->ir->CreateMul(b, c, "tmp");
|
||||
tmp2 = gIR->ir->CreateMul(a, d, "tmp");
|
||||
im = gIR->ir->CreateAdd(tmp1, tmp2, "tmp");
|
||||
|
||||
return new DComplexValue(type, re, im);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DValue* DtoComplexDiv(Type* type, DValue* lhs, DValue* rhs)
|
||||
{
|
||||
lhs = DtoComplex(type, lhs);
|
||||
rhs = DtoComplex(type, 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"));
|
||||
}
|
||||
|
||||
// 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"));
|
||||
}
|
||||
|
||||
llvm::Value *tmp1, *tmp2, *denom;
|
||||
|
||||
tmp1 = gIR->ir->CreateMul(c, c, "tmp");
|
||||
tmp2 = gIR->ir->CreateMul(d, d, "tmp");
|
||||
denom = gIR->ir->CreateAdd(tmp1, tmp2, "tmp");
|
||||
|
||||
tmp1 = gIR->ir->CreateMul(a, c, "tmp");
|
||||
tmp2 = gIR->ir->CreateMul(b, d, "tmp");
|
||||
re = gIR->ir->CreateAdd(tmp1, tmp2, "tmp");
|
||||
re = gIR->ir->CreateFDiv(re, denom, "tmp");
|
||||
|
||||
tmp1 = gIR->ir->CreateMul(b, c, "tmp");
|
||||
tmp2 = gIR->ir->CreateMul(a, d, "tmp");
|
||||
im = gIR->ir->CreateSub(tmp1, tmp2, "tmp");
|
||||
im = gIR->ir->CreateFDiv(im, denom, "tmp");
|
||||
|
||||
return new DComplexValue(type, re, im);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::Value* DtoComplexEquals(TOK op, DValue* lhs, DValue* rhs)
|
||||
{
|
||||
llvm::Value* lvec = lhs->getRVal();
|
||||
llvm::Value* rvec = rhs->getRVal();
|
||||
|
||||
llvm::FCmpInst::Predicate cmpop;
|
||||
switch(op)
|
||||
{
|
||||
case TOKequal:
|
||||
cmpop = llvm::FCmpInst::FCMP_OEQ;
|
||||
break;
|
||||
case TOKnotequal:
|
||||
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());
|
||||
|
||||
return gIR->ir->CreateAnd(b1,b2,"tmp");
|
||||
}
|
27
gen/complex.h
Normal file
27
gen/complex.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
#ifndef LLVMDC_GEN_COMPLEX_H
|
||||
#define LLVMDC_GEN_COMPLEX_H
|
||||
|
||||
const llvm::StructType* DtoComplexType(Type* t);
|
||||
const llvm::Type* DtoComplexBaseType(Type* t);
|
||||
|
||||
llvm::Constant* DtoConstComplex(Type* t, llvm::Constant* re, llvm::Constant* im);
|
||||
llvm::Constant* DtoConstComplex(Type* t, long double re, long double im);
|
||||
llvm::Constant* DtoUndefComplex(Type* _ty);
|
||||
|
||||
llvm::Constant* DtoComplexShuffleMask(unsigned a, unsigned b);
|
||||
|
||||
llvm::Value* DtoRealPart(DValue* val);
|
||||
llvm::Value* DtoImagPart(DValue* val);
|
||||
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);
|
||||
|
||||
DValue* DtoComplexAdd(Type* type, DValue* lhs, DValue* rhs);
|
||||
DValue* DtoComplexSub(Type* type, DValue* lhs, DValue* rhs);
|
||||
DValue* DtoComplexMul(Type* type, DValue* lhs, DValue* rhs);
|
||||
DValue* DtoComplexDiv(Type* type, DValue* lhs, DValue* rhs);
|
||||
|
||||
llvm::Value* DtoComplexEquals(TOK op, DValue* lhs, DValue* rhs);
|
||||
|
||||
#endif // LLVMDC_GEN_COMPLEX_H
|
19
gen/dvalue.h
19
gen/dvalue.h
|
@ -32,6 +32,7 @@ struct DFuncValue;
|
|||
struct DSliceValue;
|
||||
struct DArrayLenValue;
|
||||
struct DLValueCast;
|
||||
struct DComplexValue;
|
||||
|
||||
// base class for d-values
|
||||
struct DValue : Object
|
||||
|
@ -51,6 +52,7 @@ struct DValue : Object
|
|||
virtual DFuncValue* isFunc() { return NULL; }
|
||||
virtual DArrayLenValue* isArrayLen() { return NULL; }
|
||||
virtual DLValueCast* isLValueCast() { return NULL; }
|
||||
virtual DComplexValue* isComplex() { return NULL; };
|
||||
|
||||
virtual bool inPlace() { return false; }
|
||||
|
||||
|
@ -190,4 +192,21 @@ struct DLValueCast : DValue
|
|||
virtual DLValueCast* isLValueCast() { return this; }
|
||||
};
|
||||
|
||||
// complex number immediate d-value (much like slice)
|
||||
struct DComplexValue : DValue
|
||||
{
|
||||
Type* type;
|
||||
llvm::Value* re;
|
||||
llvm::Value* im;
|
||||
|
||||
DComplexValue(Type* t, llvm::Value* r, llvm::Value* i) {
|
||||
type = t;
|
||||
re = r;
|
||||
im = i;
|
||||
}
|
||||
|
||||
virtual Type* getType() { assert(type); return type; }
|
||||
virtual DComplexValue* isComplex() { return this; }
|
||||
};
|
||||
|
||||
#endif // LLVMDC_GEN_DVALUE_H
|
||||
|
|
446
gen/toir.cpp
446
gen/toir.cpp
|
@ -28,7 +28,7 @@
|
|||
#include "gen/structs.h"
|
||||
#include "gen/classes.h"
|
||||
#include "gen/typeinf.h"
|
||||
|
||||
#include "gen/complex.h"
|
||||
#include "gen/dvalue.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -291,13 +291,7 @@ llvm::Constant* RealExp::toConstElem(IRState* p)
|
|||
Logger::print("RealExp::toConstElem: %s | %s\n", toChars(), type->toChars());
|
||||
LOG_SCOPE;
|
||||
Type* t = DtoDType(type);
|
||||
const llvm::Type* fty = DtoType(t);
|
||||
if (t->ty == Tfloat32 || t->ty == Timaginary32)
|
||||
return llvm::ConstantFP::get(fty,float(value));
|
||||
else if (t->ty == Tfloat64 || t->ty == Timaginary64 || t->ty == Tfloat80 || t->ty == Timaginary80)
|
||||
return llvm::ConstantFP::get(fty,double(value));
|
||||
assert(0);
|
||||
return NULL;
|
||||
return DtoConstFP(t, value);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -334,7 +328,18 @@ DValue* ComplexExp::toElem(IRState* p)
|
|||
{
|
||||
Logger::print("ComplexExp::toElem(): %s | %s\n", toChars(), type->toChars());
|
||||
LOG_SCOPE;
|
||||
assert(0 && "no complex yet");
|
||||
llvm::Constant* c = toConstElem(p);
|
||||
|
||||
if (c->isNullValue()) {
|
||||
Type* t = DtoDType(type);
|
||||
if (t->ty == Tcomplex32)
|
||||
c = DtoConstFP(Type::tfloat32, 0);
|
||||
else
|
||||
c = DtoConstFP(Type::tfloat64, 0);
|
||||
return new DComplexValue(type, c, c);
|
||||
}
|
||||
|
||||
return new DComplexValue(type, c->getOperand(0), c->getOperand(1));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -343,7 +348,7 @@ llvm::Constant* ComplexExp::toConstElem(IRState* p)
|
|||
{
|
||||
Logger::print("ComplexExp::toConstElem(): %s | %s\n", toChars(), type->toChars());
|
||||
LOG_SCOPE;
|
||||
assert(0 && "no complex yet");
|
||||
return DtoConstComplex(type, value.re, value.im);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -484,164 +489,6 @@ DValue* AssignExp::toElem(IRState* p)
|
|||
}
|
||||
|
||||
return l;
|
||||
|
||||
/*
|
||||
if (l->type == DValue::ARRAYLEN)
|
||||
{
|
||||
DtoResizeDynArray(l->mem, r->getValue());
|
||||
delete r;
|
||||
delete l;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Type* e1type = DtoDType(e1->type);
|
||||
Type* e2type = DtoDType(e2->type);
|
||||
TY e1ty = e1type->ty;
|
||||
TY e2ty = e2type->ty;
|
||||
|
||||
DValue* e = new DValue(this);
|
||||
e->type = DValue::VAR;
|
||||
|
||||
// struct
|
||||
if (e1ty == Tstruct) {
|
||||
e->mem = l->mem;
|
||||
// struct + struct
|
||||
if (e2ty == Tstruct) {
|
||||
// struct literals do the assignment themselvs (in place)
|
||||
if (!r->inplace) {
|
||||
DtoStructCopy(l->mem,r->getValue());
|
||||
}
|
||||
else {
|
||||
e->inplace = true;
|
||||
}
|
||||
}
|
||||
// struct + const int
|
||||
else if (e2type->isintegral()){
|
||||
IntegerExp* iexp = (IntegerExp*)e2;
|
||||
assert(iexp->value == 0 && "Only integral struct initializer allowed is zero");
|
||||
DtoStructZeroInit(l->mem);
|
||||
}
|
||||
// :x
|
||||
else
|
||||
assert(0 && "struct = unknown");
|
||||
}
|
||||
else if (e1ty == Tsarray) {
|
||||
assert(0 && "static array not supported");
|
||||
}
|
||||
else if (e1ty == Tarray) {
|
||||
if (e2type->isscalar() || e2type->ty == Tclass){
|
||||
if (l->type == DValue::SLICE) {
|
||||
DtoArrayInit(l->mem, l->arg, r->getValue());
|
||||
}
|
||||
else {
|
||||
DtoArrayInit(l->mem, r->getValue());
|
||||
}
|
||||
}
|
||||
else if (e2ty == Tarray) {
|
||||
//new llvm::StoreInst(r->val,l->val,p->scopebb());
|
||||
if (r->type == DValue::NUL) {
|
||||
llvm::Constant* c = llvm::cast<llvm::Constant>(r->val);
|
||||
assert(c->isNullValue());
|
||||
DtoNullArray(l->mem);
|
||||
e->mem = l->mem;
|
||||
}
|
||||
else if (r->type == DValue::SLICE) {
|
||||
if (l->type == DValue::SLICE) {
|
||||
DtoArrayCopy(l,r);
|
||||
e->type = DValue::SLICE;
|
||||
e->mem = l->mem;
|
||||
e->arg = l->arg;
|
||||
}
|
||||
else {
|
||||
DtoSetArray(l->mem,r->arg,r->mem);
|
||||
e->mem = l->mem;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// new expressions write directly to the array reference
|
||||
// so do string literals
|
||||
e->mem = l->mem;
|
||||
if (!r->inplace) {
|
||||
assert(r->mem);
|
||||
DtoArrayAssign(l->mem, r->mem);
|
||||
}
|
||||
else {
|
||||
e->inplace = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
}
|
||||
else if (e1ty == Tpointer) {
|
||||
e->mem = l->mem;
|
||||
if (e2ty == Tpointer) {
|
||||
llvm::Value* v = r->field ? r->mem : r->getValue();
|
||||
Logger::cout() << "*=*: " << *v << ", " << *l->mem << '\n';
|
||||
new llvm::StoreInst(v, l->mem, p->scopebb());
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
}
|
||||
else if (e1ty == Tclass) {
|
||||
if (e2ty == Tclass) {
|
||||
llvm::Value* tmp = r->getValue();
|
||||
Logger::cout() << "tmp: " << *tmp << " ||| " << *l->mem << '\n';
|
||||
// assignment to this in constructor special case
|
||||
if (l->isthis) {
|
||||
FuncDeclaration* fdecl = p->func().decl;
|
||||
// respecify the this param
|
||||
if (!llvm::isa<llvm::AllocaInst>(fdecl->llvmThisVar))
|
||||
fdecl->llvmThisVar = new llvm::AllocaInst(tmp->getType(), "newthis", p->topallocapoint());
|
||||
new llvm::StoreInst(tmp, fdecl->llvmThisVar, p->scopebb());
|
||||
e->mem = fdecl->llvmThisVar;
|
||||
}
|
||||
// regular class ref -> class ref assignment
|
||||
else {
|
||||
new llvm::StoreInst(tmp, l->mem, p->scopebb());
|
||||
e->mem = l->mem;
|
||||
}
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
}
|
||||
else if (e1ty == Tdelegate) {
|
||||
Logger::println("Assigning to delegate");
|
||||
if (e2ty == Tdelegate) {
|
||||
if (r->type == DValue::NUL) {
|
||||
llvm::Constant* c = llvm::cast<llvm::Constant>(r->val);
|
||||
if (c->isNullValue()) {
|
||||
DtoNullDelegate(l->mem);
|
||||
e->mem = l->mem;
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
}
|
||||
else if (r->inplace) {
|
||||
// do nothing
|
||||
e->inplace = true;
|
||||
e->mem = l->mem;
|
||||
}
|
||||
else {
|
||||
DtoDelegateCopy(l->mem, r->getValue());
|
||||
e->mem = l->mem;
|
||||
}
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
}
|
||||
// !struct && !array && !pointer && !class
|
||||
else {
|
||||
Logger::cout() << *l->mem << '\n';
|
||||
new llvm::StoreInst(r->getValue(),l->mem,p->scopebb());
|
||||
e->mem = l->mem;
|
||||
}
|
||||
|
||||
delete r;
|
||||
delete l;
|
||||
|
||||
return e;
|
||||
*/
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -682,8 +529,14 @@ DValue* AddExp::toElem(IRState* p)
|
|||
llvm::Value* v = new llvm::GetElementPtrInst(l->getRVal(), r->getRVal(), "tmp", p->scopebb());
|
||||
return new DImValue(type, v);
|
||||
}
|
||||
else if (t->iscomplex()) {
|
||||
return DtoComplexAdd(type, l, r);
|
||||
}
|
||||
assert(0);
|
||||
}
|
||||
else if (t->iscomplex()) {
|
||||
return DtoComplexAdd(type, l, r);
|
||||
}
|
||||
else {
|
||||
return DtoBinAdd(l,r);
|
||||
}
|
||||
|
@ -701,39 +554,22 @@ DValue* AddAssignExp::toElem(IRState* p)
|
|||
DValue* r = e2->toElem(p);
|
||||
p->exps.pop_back();
|
||||
|
||||
Type* t = DtoDType(type);
|
||||
|
||||
DValue* res;
|
||||
if (DtoDType(e1->type)->ty == Tpointer) {
|
||||
llvm::Value* gep = new llvm::GetElementPtrInst(l->getRVal(),r->getRVal(),"tmp",p->scopebb());
|
||||
res = new DImValue(type, gep);
|
||||
}
|
||||
else if (t->iscomplex()) {
|
||||
res = DtoComplexAdd(type, l, r);
|
||||
}
|
||||
else {
|
||||
res = DtoBinAdd(l,r);
|
||||
}
|
||||
DtoAssign(l, res);
|
||||
|
||||
return l;
|
||||
|
||||
/*
|
||||
|
||||
Type* e1type = DtoDType(e1->type);
|
||||
|
||||
DValue* e = new DValue(this);
|
||||
llvm::Value* val = 0;
|
||||
if (e1type->ty == Tpointer) {
|
||||
val = e->mem = new llvm::GetElementPtrInst(l->getValue(),r->getValue(),"tmp",p->scopebb());
|
||||
}
|
||||
else {
|
||||
val = e->val = llvm::BinaryOperator::createAdd(l->getValue(),r->getValue(),"tmp",p->scopebb());
|
||||
}
|
||||
|
||||
assert(l->mem);
|
||||
new llvm::StoreInst(val,l->mem,p->scopebb());
|
||||
e->type = DValue::VAR;
|
||||
|
||||
delete l;
|
||||
delete r;
|
||||
return e;
|
||||
*/
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -746,6 +582,8 @@ DValue* MinExp::toElem(IRState* p)
|
|||
DValue* l = e1->toElem(p);
|
||||
DValue* r = e2->toElem(p);
|
||||
|
||||
Type* t = DtoDType(type);
|
||||
|
||||
if (DtoDType(e1->type)->ty == Tpointer) {
|
||||
llvm::Value* lv = l->getRVal();
|
||||
llvm::Value* rv = r->getRVal();
|
||||
|
@ -759,34 +597,12 @@ DValue* MinExp::toElem(IRState* p)
|
|||
diff = p->ir->CreateIntToPtr(diff, DtoType(type));
|
||||
return new DImValue(type, diff);
|
||||
}
|
||||
else if (t->iscomplex()) {
|
||||
return DtoComplexSub(type, l, r);
|
||||
}
|
||||
else {
|
||||
return DtoBinSub(l,r);
|
||||
}
|
||||
|
||||
/*
|
||||
llvm::Value* left = l->getValue();
|
||||
if (isaPointer(left->getType()))
|
||||
left = new llvm::PtrToIntInst(left,DtoSize_t(),"tmp",p->scopebb());
|
||||
|
||||
llvm::Value* right = r->getValue();
|
||||
if (isaPointer(right->getType()))
|
||||
right = new llvm::PtrToIntInst(right,DtoSize_t(),"tmp",p->scopebb());
|
||||
|
||||
e->val = llvm::BinaryOperator::createSub(left,right,"tmp",p->scopebb());
|
||||
e->type = DValue::VAL;
|
||||
|
||||
const llvm::Type* totype = DtoType(type);
|
||||
if (e->val->getType() != totype) {
|
||||
assert(0);
|
||||
assert(isaPointer(e->val->getType()));
|
||||
assert(llvm::isa<llvm::IntegerType>(totype));
|
||||
e->val = new llvm::IntToPtrInst(e->val,totype,"tmp",p->scopebb());
|
||||
}
|
||||
|
||||
delete l;
|
||||
delete r;
|
||||
return e;
|
||||
*/
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -799,6 +615,8 @@ DValue* MinAssignExp::toElem(IRState* p)
|
|||
DValue* l = e1->toElem(p);
|
||||
DValue* r = e2->toElem(p);
|
||||
|
||||
Type* t = DtoDType(type);
|
||||
|
||||
DValue* res;
|
||||
if (DtoDType(e1->type)->ty == Tpointer) {
|
||||
llvm::Value* tmp = r->getRVal();
|
||||
|
@ -807,212 +625,113 @@ DValue* MinAssignExp::toElem(IRState* p)
|
|||
tmp = new llvm::GetElementPtrInst(l->getRVal(),tmp,"tmp",p->scopebb());
|
||||
res = new DImValue(type, tmp);
|
||||
}
|
||||
else if (t->iscomplex()) {
|
||||
res = DtoComplexSub(type, l, r);
|
||||
}
|
||||
else {
|
||||
res = DtoBinSub(l,r);
|
||||
}
|
||||
DtoAssign(l, res);
|
||||
|
||||
return l;
|
||||
|
||||
/*
|
||||
|
||||
Type* e1type = DtoDType(e1->type);
|
||||
|
||||
llvm::Value* tmp = 0;
|
||||
if (e1type->ty == Tpointer) {
|
||||
tmp = r->getValue();
|
||||
llvm::Value* zero = llvm::ConstantInt::get(tmp->getType(),0,false);
|
||||
tmp = llvm::BinaryOperator::createSub(zero,tmp,"tmp",p->scopebb());
|
||||
tmp = new llvm::GetElementPtrInst(l->getValue(),tmp,"tmp",p->scopebb());
|
||||
}
|
||||
else {
|
||||
tmp = llvm::BinaryOperator::createSub(l->getValue(),r->getValue(),"tmp",p->scopebb());
|
||||
}
|
||||
|
||||
assert(l->mem);
|
||||
new llvm::StoreInst(tmp, l->mem, p->scopebb());
|
||||
|
||||
delete l;
|
||||
delete r;
|
||||
|
||||
DValue* e = new DValue(this);
|
||||
e->val = tmp;
|
||||
e->type = DValue::VAR;
|
||||
return e;
|
||||
*/
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DValue* MulExp::toElem(IRState* p)
|
||||
{
|
||||
Logger::print("MulExp::toElem: %s\n", toChars());
|
||||
Logger::print("MulExp::toElem: %s | %s\n", toChars(), type->toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
DValue* l = e1->toElem(p);
|
||||
DValue* r = e2->toElem(p);
|
||||
|
||||
if (type->iscomplex()) {
|
||||
return DtoComplexMul(type, l, r);
|
||||
}
|
||||
|
||||
return DtoBinMul(l,r);
|
||||
/*
|
||||
if (l->dvalue && r->dvalue) {
|
||||
Logger::println("DVALUE PATH");
|
||||
e->dvalue = DtoBinMul(l->dvalue, r->dvalue);
|
||||
e->val = e->dvalue->getRVal();
|
||||
}
|
||||
else {
|
||||
llvm::Value* vl = l->getValue();
|
||||
llvm::Value* vr = r->getValue();
|
||||
Logger::cout() << "mul: " << *vl << ", " << *vr << '\n';
|
||||
e->val = llvm::BinaryOperator::createMul(vl,vr,"tmp",p->scopebb());
|
||||
e->dvalue = new DImValue(type, e->val);
|
||||
}
|
||||
e->type = DValue::VAL;
|
||||
delete l;
|
||||
delete r;
|
||||
return e;
|
||||
*/
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DValue* MulAssignExp::toElem(IRState* p)
|
||||
{
|
||||
Logger::print("MulAssignExp::toElem: %s\n", toChars());
|
||||
Logger::print("MulAssignExp::toElem: %s | %s\n", toChars(), type->toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
DValue* l = e1->toElem(p);
|
||||
DValue* r = e2->toElem(p);
|
||||
|
||||
DValue* res = DtoBinMul(l,r);
|
||||
DValue* res;
|
||||
if (type->iscomplex()) {
|
||||
res = DtoComplexMul(type, l, r);
|
||||
}
|
||||
else {
|
||||
res = DtoBinMul(l,r);
|
||||
}
|
||||
DtoAssign(l, res);
|
||||
|
||||
return l;
|
||||
|
||||
/*
|
||||
llvm::Value* vl = l->getValue();
|
||||
llvm::Value* vr = r->getValue();
|
||||
Logger::cout() << "mulassign: " << *vl << ", " << *vr << '\n';
|
||||
llvm::Value* tmp = llvm::BinaryOperator::createMul(vl,vr,"tmp",p->scopebb());
|
||||
|
||||
assert(l->mem);
|
||||
new llvm::StoreInst(tmp,l->mem,p->scopebb());
|
||||
|
||||
delete l;
|
||||
delete r;
|
||||
|
||||
DValue* e = new DValue(this);
|
||||
e->val = tmp;
|
||||
e->type = DValue::VAR;
|
||||
return e;
|
||||
*/
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DValue* DivExp::toElem(IRState* p)
|
||||
{
|
||||
Logger::print("DivExp::toElem: %s\n", toChars());
|
||||
Logger::print("DivExp::toElem: %s | %s\n", toChars(), type->toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
DValue* l = e1->toElem(p);
|
||||
DValue* r = e2->toElem(p);
|
||||
|
||||
if (type->iscomplex()) {
|
||||
return DtoComplexDiv(type, l, r);
|
||||
}
|
||||
|
||||
return DtoBinDiv(l, r);
|
||||
/*
|
||||
|
||||
Type* t = DtoDType(type);
|
||||
|
||||
if (t->isunsigned())
|
||||
e->val = llvm::BinaryOperator::createUDiv(l->getValue(),r->getValue(),"tmp",p->scopebb());
|
||||
else if (t->isintegral())
|
||||
e->val = llvm::BinaryOperator::createSDiv(l->getValue(),r->getValue(),"tmp",p->scopebb());
|
||||
else if (t->isfloating())
|
||||
e->val = llvm::BinaryOperator::createFDiv(l->getValue(),r->getValue(),"tmp",p->scopebb());
|
||||
else
|
||||
assert(0);
|
||||
e->type = DValue::VAL;
|
||||
delete l;
|
||||
delete r;
|
||||
return e;
|
||||
*/
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DValue* DivAssignExp::toElem(IRState* p)
|
||||
{
|
||||
Logger::print("DivAssignExp::toElem: %s\n", toChars());
|
||||
Logger::print("DivAssignExp::toElem: %s | %s\n", toChars(), type->toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
DValue* l = e1->toElem(p);
|
||||
DValue* r = e2->toElem(p);
|
||||
|
||||
DValue* res = DtoBinDiv(l,r);
|
||||
DValue* res;
|
||||
if (type->iscomplex()) {
|
||||
res = DtoComplexDiv(type, l, r);
|
||||
}
|
||||
else {
|
||||
res = DtoBinDiv(l,r);
|
||||
}
|
||||
DtoAssign(l, res);
|
||||
|
||||
return l;
|
||||
|
||||
/*
|
||||
|
||||
Type* t = DtoDType(type);
|
||||
|
||||
llvm::Value* tmp;
|
||||
if (t->isunsigned())
|
||||
tmp = llvm::BinaryOperator::createUDiv(l->getValue(),r->getValue(),"tmp",p->scopebb());
|
||||
else if (t->isintegral())
|
||||
tmp = llvm::BinaryOperator::createSDiv(l->getValue(),r->getValue(),"tmp",p->scopebb());
|
||||
else if (t->isfloating())
|
||||
tmp = llvm::BinaryOperator::createFDiv(l->getValue(),r->getValue(),"tmp",p->scopebb());
|
||||
else
|
||||
assert(0);
|
||||
|
||||
assert(l->mem);
|
||||
new llvm::StoreInst(tmp,l->mem,p->scopebb());
|
||||
|
||||
delete l;
|
||||
delete r;
|
||||
|
||||
DValue* e = new DValue(this);
|
||||
e->val = tmp;
|
||||
e->type = DValue::VAR;
|
||||
return e;
|
||||
*/
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DValue* ModExp::toElem(IRState* p)
|
||||
{
|
||||
Logger::print("ModExp::toElem: %s\n", toChars());
|
||||
Logger::print("ModExp::toElem: %s | %s\n", toChars(), type->toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
DValue* l = e1->toElem(p);
|
||||
DValue* r = e2->toElem(p);
|
||||
|
||||
return DtoBinRem(l, r);
|
||||
/*
|
||||
Type* t = DtoDType(type);
|
||||
|
||||
if (t->isunsigned())
|
||||
e->val = llvm::BinaryOperator::createURem(l->getValue(),r->getValue(),"tmp",p->scopebb());
|
||||
else if (t->isintegral())
|
||||
e->val = llvm::BinaryOperator::createSRem(l->getValue(),r->getValue(),"tmp",p->scopebb());
|
||||
else if (t->isfloating())
|
||||
e->val = llvm::BinaryOperator::createFRem(l->getValue(),r->getValue(),"tmp",p->scopebb());
|
||||
else
|
||||
assert(0);
|
||||
e->type = DValue::VAL;
|
||||
delete l;
|
||||
delete r;
|
||||
return e;
|
||||
*/
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DValue* ModAssignExp::toElem(IRState* p)
|
||||
{
|
||||
Logger::print("ModAssignExp::toElem: %s\n", toChars());
|
||||
Logger::print("ModAssignExp::toElem: %s | %s\n", toChars(), type->toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
DValue* l = e1->toElem(p);
|
||||
|
@ -1022,39 +741,13 @@ DValue* ModAssignExp::toElem(IRState* p)
|
|||
DtoAssign(l, res);
|
||||
|
||||
return l;
|
||||
|
||||
/*
|
||||
|
||||
Type* t = DtoDType(type);
|
||||
|
||||
llvm::Value* tmp;
|
||||
if (t->isunsigned())
|
||||
tmp = llvm::BinaryOperator::createURem(l->getValue(),r->getValue(),"tmp",p->scopebb());
|
||||
else if (t->isintegral())
|
||||
tmp = llvm::BinaryOperator::createSRem(l->getValue(),r->getValue(),"tmp",p->scopebb());
|
||||
else if (t->isfloating())
|
||||
tmp = llvm::BinaryOperator::createFRem(l->getValue(),r->getValue(),"tmp",p->scopebb());
|
||||
else
|
||||
assert(0);
|
||||
|
||||
assert(l->mem);
|
||||
new llvm::StoreInst(tmp,l->mem,p->scopebb());
|
||||
|
||||
delete l;
|
||||
delete r;
|
||||
|
||||
DValue* e = new DValue(this);
|
||||
e->val = tmp;
|
||||
e->type = DValue::VAR;
|
||||
return e;
|
||||
*/
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DValue* CallExp::toElem(IRState* p)
|
||||
{
|
||||
Logger::print("CallExp::toElem: %s\n", toChars());
|
||||
Logger::print("CallExp::toElem: %s | %s\n", toChars(), type->toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
DValue* fn = e1->toElem(p);
|
||||
|
@ -1880,6 +1573,11 @@ DValue* EqualExp::toElem(IRState* p)
|
|||
}
|
||||
eval = new llvm::ICmpInst(cmpop, l->getRVal(), r->getRVal(), "tmp", p->scopebb());
|
||||
}
|
||||
else if (t->iscomplex())
|
||||
{
|
||||
Logger::println("complex");
|
||||
eval = DtoComplexEquals(op, l, r);
|
||||
}
|
||||
else if (t->isfloating())
|
||||
{
|
||||
Logger::println("floating");
|
||||
|
@ -2439,9 +2137,9 @@ DValue* NegExp::toElem(IRState* p)
|
|||
if (t->isintegral())
|
||||
zero = llvm::ConstantInt::get(val->getType(), 0, true);
|
||||
else if (t->isfloating()) {
|
||||
if (t->ty == Tfloat32)
|
||||
if (t->ty == Tfloat32 || t->ty == Timaginary32)
|
||||
zero = llvm::ConstantFP::get(val->getType(), float(0));
|
||||
else if (t->ty == Tfloat64 || t->ty == Tfloat80)
|
||||
else if (t->ty == Tfloat64 || t->ty == Tfloat80 || t->ty == Timaginary64 || t->ty == Timaginary80)
|
||||
zero = llvm::ConstantFP::get(val->getType(), double(0));
|
||||
else
|
||||
assert(0);
|
||||
|
|
|
@ -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 @@ const llvm::Type* DtoType(Type* t)
|
|||
|
||||
// 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* DtoDelegateType(Type* t)
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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 @@ void DtoAssign(DValue* lhs, DValue* rhs)
|
|||
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* DtoCastPtr(DValue* val, Type* to)
|
|||
|
||||
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 @@ DValue* DtoCastFloat(DValue* val, Type* to)
|
|||
|
||||
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 @@ DValue* DtoCastFloat(DValue* val, Type* to)
|
|||
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 @@ DValue* DtoCast(DValue* val, Type* to)
|
|||
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 @@ llvm::Constant* DtoConstBool(bool b)
|
|||
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 @@ bool DtoCanLoad(llvm::Value* ptr)
|
|||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::Value* DtoBitCast(llvm::Value* v, const llvm::Type* t)
|
||||
{
|
||||
if (v->getType() == t)
|
||||
|
@ -1172,6 +1213,8 @@ llvm::Value* DtoBitCast(llvm::Value* v, const llvm::Type* t)
|
|||
return gIR->ir->CreateBitCast(v, t, "tmp");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const llvm::PointerType* isaPointer(llvm::Value* v)
|
||||
{
|
||||
return llvm::dyn_cast<llvm::PointerType>(v->getType());
|
||||
|
|
|
@ -22,8 +22,6 @@ llvm::Value* DtoBoolean(llvm::Value* val);
|
|||
|
||||
const llvm::Type* DtoSize_t();
|
||||
|
||||
const llvm::StructType* DtoComplexType(const llvm::Type* base);
|
||||
|
||||
llvm::Constant* DtoConstInitializer(Type* type, Initializer* init);
|
||||
llvm::Constant* DtoConstFieldInitializer(Type* type, Initializer* init);
|
||||
DValue* DtoInitializer(Initializer* init);
|
||||
|
@ -50,6 +48,8 @@ llvm::Value* DtoNestedVariable(VarDeclaration* vd);
|
|||
llvm::ConstantInt* DtoConstSize_t(size_t);
|
||||
llvm::ConstantInt* DtoConstUint(unsigned i);
|
||||
llvm::ConstantInt* DtoConstInt(int i);
|
||||
llvm::ConstantFP* DtoConstFP(Type* t, long double value);
|
||||
|
||||
llvm::Constant* DtoConstString(const char*);
|
||||
llvm::Constant* DtoConstStringPtr(const char* str, const char* section = 0);
|
||||
llvm::Constant* DtoConstBool(bool);
|
||||
|
@ -98,6 +98,7 @@ void DtoAssign(DValue* lhs, DValue* rhs);
|
|||
DValue* DtoCastInt(DValue* val, Type* to);
|
||||
DValue* DtoCastPtr(DValue* val, Type* to);
|
||||
DValue* DtoCastFloat(DValue* val, Type* to);
|
||||
DValue* DtoCastComplex(DValue* val, Type* to);
|
||||
DValue* DtoCastClass(DValue* val, Type* to);
|
||||
DValue* DtoCast(DValue* val, Type* to);
|
||||
|
||||
|
|
|
@ -105,6 +105,8 @@ gen/arrays.h
|
|||
gen/binops.cpp
|
||||
gen/classes.cpp
|
||||
gen/classes.h
|
||||
gen/complex.cpp
|
||||
gen/complex.h
|
||||
gen/dvalue.cpp
|
||||
gen/dvalue.h
|
||||
gen/dwarftypes.cpp
|
||||
|
@ -142,6 +144,7 @@ lphobos/internal/aApply.d
|
|||
lphobos/internal/aApplyR.d
|
||||
lphobos/internal/adi.d
|
||||
lphobos/internal/arrays.d
|
||||
lphobos/internal/cmath2.d
|
||||
lphobos/internal/contract.d
|
||||
lphobos/internal/mem.d
|
||||
lphobos/internal/moduleinit.d
|
||||
|
@ -317,6 +320,8 @@ test/classinfo1.d
|
|||
test/classinfo2.d
|
||||
test/comma.d
|
||||
test/complex1.d
|
||||
test/complex2.d
|
||||
test/complex3.d
|
||||
test/cond.d
|
||||
test/cond1.d
|
||||
test/condexp.d
|
||||
|
|
|
@ -2,5 +2,20 @@ module complex1;
|
|||
|
||||
void main()
|
||||
{
|
||||
cfloat c1;
|
||||
cfloat cf1 = 3f + 0i;
|
||||
cfloat cf2 = 4f + 1i;
|
||||
cfloat cf3 = func();
|
||||
auto c1 = cf1 + cf2;
|
||||
auto c2 = cf2 - cf3;
|
||||
{
|
||||
auto c3 = cf1 * cf3;
|
||||
{
|
||||
auto c4 = cf2 / cf3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cfloat func()
|
||||
{
|
||||
return 3f + 1i;
|
||||
}
|
||||
|
|
14
test/complex2.d
Normal file
14
test/complex2.d
Normal file
|
@ -0,0 +1,14 @@
|
|||
module complex2;
|
||||
|
||||
void main()
|
||||
{
|
||||
cdouble c = 3.0 + 0i;
|
||||
cdouble d = 2.0 + 0i;
|
||||
{
|
||||
cdouble c1 = c + 3.0;
|
||||
cdouble c2 = c - 3.0i;
|
||||
}
|
||||
{
|
||||
cdouble c1 = c / 2.0;
|
||||
}
|
||||
}
|
9
test/complex3.d
Normal file
9
test/complex3.d
Normal file
|
@ -0,0 +1,9 @@
|
|||
module complex3;
|
||||
|
||||
void main()
|
||||
{
|
||||
cfloat c1 = 1f + 0i;
|
||||
cfloat c2 = 0f + 0i;
|
||||
//c2 += 1f + 0i;
|
||||
//assert(c1 == c2);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue