From c47bfbcc3233a6e82a64a8a775248cc4ffbf3642 Mon Sep 17 00:00:00 2001 From: Alexey Prokhin Date: Wed, 15 Dec 2010 20:30:38 +0300 Subject: [PATCH] Implemented mod operator for complex numbers --- gen/complex.cpp | 22 ++++++++++++++++++++++ gen/complex.h | 1 + gen/toir.cpp | 4 ++++ 3 files changed, 27 insertions(+) diff --git a/gen/complex.cpp b/gen/complex.cpp index 652a3992..35faf991 100644 --- a/gen/complex.cpp +++ b/gen/complex.cpp @@ -359,6 +359,28 @@ DValue* DtoComplexDiv(Loc& loc, Type* type, DValue* lhs, DValue* rhs) ////////////////////////////////////////////////////////////////////////////////////////// +DValue* DtoComplexRem(Loc& loc, Type* type, DValue* lhs, DValue* rhs) +{ + llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im, *divisor; + + // lhs values + DtoGetComplexParts(loc, type, lhs, lhs_re, lhs_im); + // rhs values + DtoGetComplexParts(loc, type, rhs, rhs_re, rhs_im); + + // Divisor can be real or imaginary but not complex + assert((rhs_re != 0) ^ (rhs_im != 0)); + + divisor = rhs_re ? rhs_re : rhs_im; + res_re = lhs_re ? gIR->ir->CreateFRem(lhs_re, divisor, "tmp") : lhs_re; + res_im = lhs_re ? gIR->ir->CreateFRem(lhs_im, divisor, "tmp") : lhs_im; + + LLValue* res = DtoAggrPair(DtoType(type), res_re, res_im); + return new DImValue(type, res); +} + +////////////////////////////////////////////////////////////////////////////////////////// + DValue* DtoComplexNeg(Loc& loc, Type* type, DValue* val) { llvm::Value *a, *b, *re, *im; diff --git a/gen/complex.h b/gen/complex.h index e835cdb5..d939a00d 100644 --- a/gen/complex.h +++ b/gen/complex.h @@ -20,6 +20,7 @@ DValue* DtoComplexAdd(Loc& loc, Type* type, DValue* lhs, DValue* rhs); DValue* DtoComplexSub(Loc& loc, Type* type, DValue* lhs, DValue* rhs); DValue* DtoComplexMul(Loc& loc, Type* type, DValue* lhs, DValue* rhs); DValue* DtoComplexDiv(Loc& loc, Type* type, DValue* lhs, DValue* rhs); +DValue* DtoComplexRem(Loc& loc, Type* type, DValue* lhs, DValue* rhs); DValue* DtoComplexNeg(Loc& loc, Type* type, DValue* val); LLValue* DtoComplexEquals(Loc& loc, TOK op, DValue* lhs, DValue* rhs); diff --git a/gen/toir.cpp b/gen/toir.cpp index 3b8f5473..c3330433 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -767,6 +767,10 @@ DValue* ModExp::toElem(IRState* p) errorOnIllegalArrayOp(this, e1, e2); + if (type->iscomplex()) { + return DtoComplexRem(loc, type, l, r); + } + return DtoBinRem(type, l, r); }