Beispiel #1
0
LLValue* DtoBinFloatsEquals(Loc loc, DValue* lhs, DValue* rhs, TOK op)
{
    LLValue* res = 0;
#if DMDV2
    if (op == TOKequal) {
        res = gIR->ir->CreateFCmpOEQ(lhs->getRVal(), rhs->getRVal(), "tmp");
    } else if (op == TOKnotequal) {
        res = gIR->ir->CreateFCmpUNE(lhs->getRVal(), rhs->getRVal(), "tmp");
    } else {
        llvm::ICmpInst::Predicate cmpop;
        if (op == TOKidentity)
            cmpop = llvm::ICmpInst::ICMP_EQ;
        else
            cmpop = llvm::ICmpInst::ICMP_NE;

        LLValue* sz = DtoConstSize_t(getTypeStoreSize(DtoType(lhs->getType())));
        LLValue* val = DtoMemCmp(makeLValue(loc, lhs), makeLValue(loc, rhs), sz);
        res = gIR->ir->CreateICmp(cmpop, val, LLConstantInt::get(val->getType(), 0, false), "tmp");
    }
#else
    LLValue* lv = lhs->getRVal();
    LLValue* rv = rhs->getRVal();
    res = (op == TOKidentity || op == TOKequal) ?
                gIR->ir->CreateFCmpOEQ(lv, rv, "tmp") :
                gIR->ir->CreateFCmpUNE(lv, rv, "tmp");

#endif
    assert(res);
    return res;
}
Beispiel #2
0
LLValue *DtoBinFloatsEquals(Loc &loc, DValue *lhs, DValue *rhs, TOK op) {
  LLValue *res = nullptr;
  if (op == TOKequal || op == TOKnotequal) {
    LLValue *l = DtoRVal(lhs);
    LLValue *r = DtoRVal(rhs);
    res = (op == TOKequal ? gIR->ir->CreateFCmpOEQ(l, r)
                          : gIR->ir->CreateFCmpUNE(l, r));
    if (lhs->type->toBasetype()->ty == Tvector) {
      res = mergeVectorEquals(res, op);
    }
  } else {
    const auto cmpop =
        op == TOKidentity ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE;
    LLValue *sz = DtoConstSize_t(getTypeStoreSize(DtoType(lhs->type)));
    LLValue *val = DtoMemCmp(makeLValue(loc, lhs), makeLValue(loc, rhs), sz);
    res = gIR->ir->CreateICmp(cmpop, val,
                              LLConstantInt::get(val->getType(), 0, false));
  }
  assert(res);
  return res;
}
Beispiel #3
0
void DtoAggrCopy(LLValue* dst, LLValue* src)
{
    uint64_t n = getTypeStoreSize(dst->getType()->getContainedType(0));
    DtoMemCpy(dst, src, DtoConstSize_t(n));
}
Beispiel #4
0
void DtoAggrZeroInit(LLValue* v)
{
    uint64_t n = getTypeStoreSize(v->getType()->getContainedType(0));
    DtoMemSetZero(v, DtoConstSize_t(n));
}
Beispiel #5
0
void DtoMemCpy(LLValue *dst, LLValue *src, bool withPadding, unsigned align) {
  LLType *pointee = dst->getType()->getContainedType(0);
  uint64_t n =
      withPadding ? getTypeAllocSize(pointee) : getTypeStoreSize(pointee);
  DtoMemCpy(dst, src, DtoConstSize_t(n), align);
}
Beispiel #6
0
void DtoMemSetZero(LLValue *dst, unsigned align) {
  uint64_t n = getTypeStoreSize(dst->getType()->getContainedType(0));
  DtoMemSetZero(dst, DtoConstSize_t(n), align);
}
Beispiel #7
0
void TypeInfoStructDeclaration::llvmDefine()
{
    Logger::println("TypeInfoStructDeclaration::llvmDefine() %s", toChars());
    LOG_SCOPE;

    // make sure struct is resolved
    assert(tinfo->ty == Tstruct);
    TypeStruct *tc = static_cast<TypeStruct *>(tinfo);
    StructDeclaration *sd = tc->sym;

    // can't emit typeinfo for forward declarations
    if (sd->sizeok != 1)
    {
        sd->error("cannot emit TypeInfo for forward declaration");
        fatal();
    }

    sd->codegen(Type::sir);
    IrStruct* irstruct = sd->ir.irStruct;

    RTTIBuilder b(Type::typeinfostruct);

    // char[] name
    b.push_string(sd->toPrettyChars());

    // void[] init
    // never emit a null array, even for zero initialized typeinfo
    // the size() method uses this array!
    size_t init_size = getTypeStoreSize(tc->irtype->getType());
    b.push_void_array(init_size, irstruct->getInitSymbol());

    // toX functions ground work
    static TypeFunction *tftohash;
    static TypeFunction *tftostring;

    if (!tftohash)
    {
        Scope sc;
        tftohash = new TypeFunction(NULL, Type::thash_t, 0, LINKd);
#if DMDV2
        tftohash ->mod = MODconst;
#endif
        tftohash = static_cast<TypeFunction *>(tftohash->semantic(0, &sc));

#if DMDV2
        Type *retType = Type::tchar->invariantOf()->arrayOf();
#else
        Type *retType = Type::tchar->arrayOf();
#endif
        tftostring = new TypeFunction(NULL, retType, 0, LINKd);
        tftostring = static_cast<TypeFunction *>(tftostring->semantic(0, &sc));
    }

    // this one takes a parameter, so we need to build a new one each time
    // to get the right type. can we avoid this?
    TypeFunction *tfcmpptr;
    {
        Scope sc;
        Parameters *arguments = new Parameters;
#if STRUCTTHISREF
        // arg type is ref const T
        Parameter *arg = new Parameter(STCref, tc->constOf(), NULL, NULL);
#else
        // arg type is const T*
        Parameter *arg = new Parameter(STCin, tc->pointerTo(), NULL, NULL);
#endif
        arguments->push(arg);
        tfcmpptr = new TypeFunction(arguments, Type::tint32, 0, LINKd);
#if DMDV2
        tfcmpptr->mod = MODconst;
#endif
        tfcmpptr = static_cast<TypeFunction *>(tfcmpptr->semantic(0, &sc));
    }

    // well use this module for all overload lookups
    Module *gm = getModule();

    // toHash
    FuncDeclaration* fd = find_method_overload(sd, Id::tohash, tftohash, gm);
    b.push_funcptr(fd);

    // opEquals
#if DMDV2
    fd = sd->xeq;
#else
    fd = find_method_overload(sd, Id::eq, tfcmpptr, gm);
#endif
    b.push_funcptr(fd);

    // opCmp
    fd = find_method_overload(sd, Id::cmp, tfcmpptr, gm);
    b.push_funcptr(fd);

    // toString
    fd = find_method_overload(sd, Id::tostring, tftostring, gm);
    b.push_funcptr(fd);

    // uint m_flags;
    unsigned hasptrs = tc->hasPointers() ? 1 : 0;
    b.push_uint(hasptrs);

#if DMDV2

    ClassDeclaration* tscd = Type::typeinfostruct;

    assert((!global.params.is64bit && tscd->fields.dim == 11) ||
           (global.params.is64bit && tscd->fields.dim == 13));

    //void function(void*)                    xdtor;
    b.push_funcptr(sd->dtor);

    //void function(void*)                    xpostblit;
    FuncDeclaration *xpostblit = sd->postblit;
    if (xpostblit && sd->postblit->storage_class & STCdisable)
        xpostblit = 0;
    b.push_funcptr(xpostblit);

    //uint m_align;
    b.push_uint(tc->alignsize());

    if (global.params.is64bit)
    {
        // TypeInfo m_arg1;
        // TypeInfo m_arg2;
        TypeTuple *tup = tc->toArgTypes();
        assert(tup->arguments->dim <= 2);
        for (unsigned i = 0; i < 2; i++)
        {
            if (i < tup->arguments->dim)
            {
                Type *targ = static_cast<Parameter *>(tup->arguments->data[i])->type;
                targ = targ->merge();
                b.push_typeinfo(targ);
            }
            else
                b.push_null(Type::typeinfo->type);
        }
    }

    // immutable(void)* m_RTInfo;
    // The cases where getRTInfo is null are not quite here, but the code is
    // modelled after what DMD does.
    if (sd->getRTInfo)
        b.push(sd->getRTInfo->toConstElem(gIR));
    else if (!tc->hasPointers())
        b.push_size_as_vp(0);       // no pointers
    else
        b.push_size_as_vp(1);       // has pointers

#endif

    // finish
    b.finalize(ir.irGlobal);
}