예제 #1
0
파일: complex.cpp 프로젝트: NilsBossung/ldc
DValue* DtoComplex(Loc& loc, Type* to, DValue* val)
{
    LLType* complexTy = DtoType(to);

    Type* baserety;
    Type* baseimty;
    switch (to->toBasetype()->ty) {
    default: llvm_unreachable("Unexpected complex floating point type");
    case Tcomplex32:
        baserety = Type::tfloat32;
        baseimty = Type::timaginary32;
        break;
    case Tcomplex64:
        baserety = Type::tfloat64;
        baseimty = Type::timaginary64;
        break;
    case Tcomplex80:
        baserety = Type::tfloat80;
        baseimty = Type::timaginary80;
        break;
    }

    LLValue *re, *im;
    DtoGetComplexParts(loc, to, val, re, im);

    if(!re)
        re = LLConstant::getNullValue(DtoType(baserety));
    if(!im)
        im = LLConstant::getNullValue(DtoType(baseimty));

    LLValue* res = DtoAggrPair(complexTy, re, im);

    return new DImValue(to, res);
}
예제 #2
0
파일: tollvm.cpp 프로젝트: FrankLIKE/ldc
LLValue* DtoAggrPairSwap(LLValue* aggr)
{
    Logger::println("swapping aggr pair");
    LLValue* r = gIR->ir->CreateExtractValue(aggr, 0);
    LLValue* i = gIR->ir->CreateExtractValue(aggr, 1);
    return DtoAggrPair(i, r, "swapped");
}
예제 #3
0
파일: complex.cpp 프로젝트: Doeme/ldc
DValue *DtoComplexAdd(Loc &loc, Type *type, DValue *lhs, DValue *rhs) {
  llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im;

  // lhs values
  DtoGetComplexParts(loc, type, lhs, lhs_re, lhs_im);
  // rhs values
  DtoGetComplexParts(loc, type, rhs, rhs_re, rhs_im);

  // add up
  if (lhs_re && rhs_re) {
    res_re = gIR->ir->CreateFAdd(lhs_re, rhs_re);
  } else if (lhs_re) {
    res_re = lhs_re;
  } else { // either rhs_re or no re at all (then use any)
    res_re = rhs_re;
  }

  if (lhs_im && rhs_im) {
    res_im = gIR->ir->CreateFAdd(lhs_im, rhs_im);
  } else if (lhs_im) {
    res_im = lhs_im;
  } else { // either rhs_im or no im at all (then use any)
    res_im = rhs_im;
  }

  LLValue *res = DtoAggrPair(DtoType(type), res_re, res_im);
  return new DImValue(type, res);
}
예제 #4
0
파일: complex.cpp 프로젝트: NilsBossung/ldc
DValue* DtoCastComplex(Loc& loc, DValue* val, Type* _to)
{
    Type* to = _to->toBasetype();
    Type* vty = val->getType()->toBasetype();
    if (to->iscomplex()) {
        if (vty->size() == to->size())
            return val;

        llvm::Value *re, *im;
        DtoGetComplexParts(loc, val->getType(), val, re, im);
        LLType* toty = DtoComplexBaseType(to);

        if (to->size() < vty->size()) {
            re = gIR->ir->CreateFPTrunc(re, toty, "tmp");
            im = gIR->ir->CreateFPTrunc(im, toty, "tmp");
        }
        else {
            re = gIR->ir->CreateFPExt(re, toty, "tmp");
            im = gIR->ir->CreateFPExt(im, toty, "tmp");
        }

        LLValue* pair = DtoAggrPair(DtoType(_to), re, im);
        return new DImValue(_to, pair);
    }
    else if (to->isimaginary()) {
        // FIXME: this loads both values, even when we only need one
        LLValue* v = val->getRVal();
        LLValue* impart = gIR->ir->CreateExtractValue(v, 1, ".im_part");
        Type *extractty;
        switch (vty->ty) {
        default: llvm_unreachable("Unexpected complex floating point type");
        case Tcomplex32: extractty = Type::timaginary32; break;
        case Tcomplex64: extractty = Type::timaginary64; break;
        case Tcomplex80: extractty = Type::timaginary80; break;
        }
        DImValue* im = new DImValue(extractty, impart);
        return DtoCastFloat(loc, im, to);
    }
    else if (to->ty == Tbool) {
        return new DImValue(_to, DtoComplexEquals(loc, TOKnotequal, val, DtoNullValue(vty)));
    }
    else if (to->isfloating() || to->isintegral()) {
        // FIXME: this loads both values, even when we only need one
        LLValue* v = val->getRVal();
        LLValue* repart = gIR->ir->CreateExtractValue(v, 0, ".re_part");
        Type *extractty;
        switch (vty->ty) {
        default: llvm_unreachable("Unexpected complex floating point type");
        case Tcomplex32: extractty = Type::tfloat32; break;
        case Tcomplex64: extractty = Type::tfloat64; break;
        case Tcomplex80: extractty = Type::tfloat80; break;
        }
        DImValue* re = new DImValue(extractty, repart);
        return DtoCastFloat(loc, re, to);
    }
    else {
        error(loc, "Don't know how to cast %s to %s", vty->toChars(), to->toChars());
        fatal();
    }
}
예제 #5
0
파일: complex.cpp 프로젝트: NilsBossung/ldc
DValue* DtoComplexSub(Loc& loc, Type* type, DValue* lhs, DValue* rhs)
{
    llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im;

    // lhs values
    DtoGetComplexParts(loc, type, lhs, lhs_re, lhs_im);
    // rhs values
    DtoGetComplexParts(loc, type, rhs, rhs_re, rhs_im);

    // add up
    if(lhs_re && rhs_re)
        res_re = gIR->ir->CreateFSub(lhs_re, rhs_re, "tmp");
    else if(lhs_re)
        res_re = lhs_re;
    else // either rhs_re or no re at all (then use any)
        res_re = gIR->ir->CreateFNeg(rhs_re, "neg");

    if(lhs_im && rhs_im)
        res_im = gIR->ir->CreateFSub(lhs_im, rhs_im, "tmp");
    else if(lhs_im)
        res_im = lhs_im;
    else // either rhs_im or no im at all (then use any)
        res_im = gIR->ir->CreateFNeg(rhs_im, "neg");

    LLValue* res = DtoAggrPair(DtoType(type), res_re, res_im);
    return new DImValue(type, res);
}
예제 #6
0
파일: tollvm.cpp 프로젝트: sgraf812/ldc
LLValue* DtoAggrPair(LLValue* V1, LLValue* V2, const char* name)
{
    llvm::SmallVector<LLType*, 2> types;
    types.push_back(V1->getType());
    types.push_back(V2->getType());
    LLType* t = LLStructType::get(gIR->context(), types);
    return DtoAggrPair(t, V1, V2, name);
}
예제 #7
0
파일: complex.cpp 프로젝트: Doeme/ldc
DValue *DtoComplexNeg(Loc &loc, Type *type, DValue *val) {
  llvm::Value *a, *b, *re, *im;

  // values
  DtoGetComplexParts(loc, type, val, a, b);

  // neg up
  assert(a && b);
  re = gIR->ir->CreateFNeg(a);
  im = gIR->ir->CreateFNeg(b);

  LLValue *res = DtoAggrPair(DtoType(type), re, im);
  return new DImValue(type, res);
}
예제 #8
0
파일: complex.cpp 프로젝트: Doeme/ldc
DValue *DtoComplexMul(Loc &loc, Type *type, DValue *lhs, DValue *rhs) {
  llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im;

  // lhs values
  DtoGetComplexParts(loc, type, lhs, lhs_re, lhs_im);
  // rhs values
  DtoGetComplexParts(loc, type, rhs, rhs_re, rhs_im);

  // mul up
  llvm::Value *rere = nullptr;
  llvm::Value *reim = nullptr;
  llvm::Value *imre = nullptr;
  llvm::Value *imim = nullptr;

  if (lhs_re && rhs_re) {
    rere = gIR->ir->CreateFMul(lhs_re, rhs_re, "rere_mul");
  }
  if (lhs_re && rhs_im) {
    reim = gIR->ir->CreateFMul(lhs_re, rhs_im, "reim_mul");
  }
  if (lhs_im && rhs_re) {
    imre = gIR->ir->CreateFMul(lhs_im, rhs_re, "imre_mul");
  }
  if (lhs_im && rhs_im) {
    imim = gIR->ir->CreateFMul(lhs_im, rhs_im, "imim_mul");
  }

  if (rere && imim) {
    res_re = gIR->ir->CreateFSub(rere, imim, "rere_imim_sub");
  } else if (rere) {
    res_re = rere;
  } else if (imim) {
    res_re = gIR->ir->CreateFNeg(imim, "imim_neg");
  } else {
    res_re = lhs_re ? rhs_re : lhs_re; // null!
  }

  if (reim && imre) {
    res_im = gIR->ir->CreateFAdd(reim, imre, "reim_imre_add");
  } else if (reim) {
    res_im = reim;
  } else if (imre) {
    res_im = imre;
  } else {
    res_im = lhs_re ? rhs_im : lhs_re; // null!
  }

  LLValue *res = DtoAggrPair(DtoType(type), res_re, res_im);
  return new DImValue(type, res);
}
예제 #9
0
파일: abi-x86.cpp 프로젝트: alexrp/ldc
    // i64 -> {float,float}
    LLValue* get(Type*, DValue* dv)
    {
        LLValue* in = dv->getRVal();

        // extract real part
        LLValue* rpart = gIR->ir->CreateTrunc(in, LLType::getInt32Ty(gIR->context()));
        rpart = gIR->ir->CreateBitCast(rpart, LLType::getFloatTy(gIR->context()), ".re");

        // extract imag part
        LLValue* ipart = gIR->ir->CreateLShr(in, LLConstantInt::get(LLType::getInt64Ty(gIR->context()), 32, false));
        ipart = gIR->ir->CreateTrunc(ipart, LLType::getInt32Ty(gIR->context()));
        ipart = gIR->ir->CreateBitCast(ipart, LLType::getFloatTy(gIR->context()), ".im");

        // return {float,float} aggr pair with same bits
        return DtoAggrPair(rpart, ipart, ".final_cfloat");
    }
예제 #10
0
파일: complex.cpp 프로젝트: Doeme/ldc
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) : lhs_re;
  res_im = lhs_re ? gIR->ir->CreateFRem(lhs_im, divisor) : lhs_im;

  LLValue *res = DtoAggrPair(DtoType(type), res_re, res_im);
  return new DImValue(type, res);
}
예제 #11
0
파일: tollvm.cpp 프로젝트: mleise/ldc
LLValue* DtoAggrPair(LLValue* V1, LLValue* V2, const char* name)
{
    LLType *types[] = {  V1->getType(), V2->getType() };
    LLType *t = LLStructType::get(gIR->context(), types, false);
    return DtoAggrPair(t, V1, V2, name);
}
예제 #12
0
파일: dvalue.cpp 프로젝트: kinke/ldc
DSliceValue::DSliceValue(Type *t, LLValue *length, LLValue *ptr)
    : DValue(t, DtoAggrPair(length, ptr)) {}
예제 #13
0
파일: complex.cpp 프로젝트: NilsBossung/ldc
DValue* DtoComplexDiv(Loc& loc, Type* type, DValue* lhs, DValue* rhs)
{
    llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im;

    // lhs values
    DtoGetComplexParts(loc, type, lhs, lhs_re, lhs_im);
    // rhs values
    DtoGetComplexParts(loc, type, rhs, rhs_re, rhs_im);

    // if divisor is only real, division is simple
    if(rhs_re && !rhs_im) {
        if(lhs_re)
            res_re = gIR->ir->CreateFDiv(lhs_re, rhs_re, "re_divby_re");
        else
            res_re = lhs_re;
        if(lhs_im)
            res_im = gIR->ir->CreateFDiv(lhs_im, rhs_re, "im_divby_re");
        else
            res_im = lhs_im;
    }
    // if divisor is only imaginary, division is simple too
    else if(!rhs_re && rhs_im) {
        if(lhs_re)
            res_im = gIR->ir->CreateFNeg(gIR->ir->CreateFDiv(lhs_re, rhs_im, "re_divby_im"), "neg");
        else
            res_im = lhs_re;
        if(lhs_im)
            res_re = gIR->ir->CreateFDiv(lhs_im, rhs_im, "im_divby_im");
        else
            res_re = lhs_im;
    }
    // full division
    else {
        llvm::Value *tmp1, *tmp2, *denom;

        if(lhs_re && lhs_im) {
            tmp1 = gIR->ir->CreateFMul(lhs_re, rhs_re, "rere");
            tmp2 = gIR->ir->CreateFMul(lhs_im, rhs_im, "imim");
            res_re = gIR->ir->CreateFAdd(tmp1, tmp2, "rere_plus_imim");

            tmp1 = gIR->ir->CreateFMul(lhs_re, rhs_im, "reim");
            tmp2 = gIR->ir->CreateFMul(lhs_im, rhs_re, "imre");
            res_im = gIR->ir->CreateFSub(tmp2, tmp1, "imre_sub_reim");
        }
        else if(lhs_re) {
            res_re = gIR->ir->CreateFMul(lhs_re, rhs_re, "rere");

            res_im = gIR->ir->CreateFMul(lhs_re, rhs_im, "reim");
            res_im = gIR->ir->CreateFNeg(res_im);
        }
        else if(lhs_im) {
            res_re = gIR->ir->CreateFMul(lhs_im, rhs_im, "imim");
            res_im = gIR->ir->CreateFMul(lhs_im, rhs_re, "imre");
        }
        else
            assert(0 && "lhs has neither real nor imaginary part");

        tmp1 = gIR->ir->CreateFMul(rhs_re, rhs_re, "rhs_resq");
        tmp2 = gIR->ir->CreateFMul(rhs_im, rhs_im, "rhs_imsq");
        denom = gIR->ir->CreateFAdd(tmp1, tmp2, "denom");

        res_re = gIR->ir->CreateFDiv(res_re, denom, "res_re");
        res_im = gIR->ir->CreateFDiv(res_im, denom, "res_im");
    }

    LLValue* res = DtoAggrPair(DtoType(type), res_re, res_im);
    return new DImValue(type, res);
}
예제 #14
0
파일: dvalue.cpp 프로젝트: dansanduleac/ldc
LLValue* DSliceValue::getRVal()
{
    assert(len);
    assert(ptr);
    return DtoAggrPair(len, ptr);
}