void
MacroAssembler::PushRegsInMask(RegisterSet set, FloatRegisterSet simdSet)
{
    FloatRegisterSet doubleSet(FloatRegisterSet::Subtract(set.fpus(), simdSet));
    MOZ_ASSERT_IF(simdSet.empty(), doubleSet == set.fpus());
    unsigned numSimd = simdSet.size();
    unsigned numDouble = doubleSet.size();
    int32_t diffF = numDouble * sizeof(double) + numSimd * Simd128DataSize;
    int32_t diffG = set.gprs().size() * sizeof(intptr_t);

    // On x86, always use push to push the integer registers, as it's fast
    // on modern hardware and it's a small instruction.
    for (GeneralRegisterBackwardIterator iter(set.gprs()); iter.more(); iter++) {
        diffG -= sizeof(intptr_t);
        Push(*iter);
    }
    MOZ_ASSERT(diffG == 0);

    reserveStack(diffF);
    for (FloatRegisterBackwardIterator iter(doubleSet); iter.more(); iter++) {
        diffF -= sizeof(double);
        numDouble -= 1;
        storeDouble(*iter, Address(StackPointer, diffF));
    }
    MOZ_ASSERT(numDouble == 0);
    for (FloatRegisterBackwardIterator iter(simdSet); iter.more(); iter++) {
        diffF -= Simd128DataSize;
        numSimd -= 1;
        // XXX how to choose the right move type?
        storeUnalignedInt32x4(*iter, Address(StackPointer, diffF));
    }
    MOZ_ASSERT(numSimd == 0);
    MOZ_ASSERT(diffF == 0);
}
uint32_t
VFPRegister::GetPushSizeInBytes(const FloatRegisterSet& s)
{
    FloatRegisterSet ss = s.reduceSetForPush();
    uint64_t bits = ss.bits();
    uint32_t ret = mozilla::CountPopulation32(bits&0xffffffff) * sizeof(float);
    ret +=  mozilla::CountPopulation32(bits >> 32) * sizeof(double);
    return ret;
}
uint32_t
FloatRegister::GetPushSizeInBytes(const FloatRegisterSet& s)
{
    FloatRegisterSet ss = s.reduceSetForPush();
    uint64_t bits = ss.bits();
    // We are only pushing double registers.
    MOZ_ASSERT((bits & 0xffffffff) == 0);
    uint32_t ret =  mozilla::CountPopulation32(bits >> 32) * sizeof(double);
    return ret;
}
void
MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore, FloatRegisterSet simdSet)
{
    FloatRegisterSet doubleSet(FloatRegisterSet::Subtract(set.fpus(), simdSet));
    MOZ_ASSERT_IF(simdSet.empty(), doubleSet == set.fpus());
    unsigned numSimd = simdSet.size();
    unsigned numDouble = doubleSet.size();
    int32_t diffG = set.gprs().size() * sizeof(intptr_t);
    int32_t diffF = numDouble * sizeof(double) + numSimd * Simd128DataSize;
    const int32_t reservedG = diffG;
    const int32_t reservedF = diffF;

    for (FloatRegisterBackwardIterator iter(simdSet); iter.more(); iter++) {
        diffF -= Simd128DataSize;
        numSimd -= 1;
        if (!ignore.has(*iter))
            // XXX how to choose the right move type?
            loadUnalignedInt32x4(Address(StackPointer, diffF), *iter);
    }
    MOZ_ASSERT(numSimd == 0);
    for (FloatRegisterBackwardIterator iter(doubleSet); iter.more(); iter++) {
        diffF -= sizeof(double);
        numDouble -= 1;
        if (!ignore.has(*iter))
            loadDouble(Address(StackPointer, diffF), *iter);
    }
    freeStack(reservedF);
    MOZ_ASSERT(numDouble == 0);
    MOZ_ASSERT(diffF == 0);

    // On x86, use pop to pop the integer registers, if we're not going to
    // ignore any slots, as it's fast on modern hardware and it's a small
    // instruction.
    if (ignore.empty(false)) {
        for (GeneralRegisterForwardIterator iter(set.gprs()); iter.more(); iter++) {
            diffG -= sizeof(intptr_t);
            Pop(*iter);
        }
    } else {
        for (GeneralRegisterBackwardIterator iter(set.gprs()); iter.more(); iter++) {
            diffG -= sizeof(intptr_t);
            if (!ignore.has(*iter))
                loadPtr(Address(StackPointer, diffG), *iter);
        }
        freeStack(reservedG);
    }
    MOZ_ASSERT(diffG == 0);
}
Example #5
0
FloatRegisterSet
VFPRegister::ReduceSetForPush(const FloatRegisterSet &s)
{
    FloatRegisterSet mod;
    for (TypedRegisterIterator<FloatRegister> iter(s); iter.more(); iter++) {
        if ((*iter).isSingle()) {
            // Add in just this float.
            mod.addUnchecked(*iter);
        } else if ((*iter).id() < 16) {
            // A double with an overlay, add in both floats.
            mod.addUnchecked((*iter).singleOverlay(0));
            mod.addUnchecked((*iter).singleOverlay(1));
        } else {
            // Add in the lone double in the range 16-31.
            mod.addUnchecked(*iter);
        }
    }
    return mod;
}
Example #6
0
uint32_t
FloatRegister::GetPushSizeInBytes(const FloatRegisterSet& s)
{
    return s.size() * sizeof(double);
}
Example #7
0
uint32_t
FloatRegister::GetSizeInBytes(const FloatRegisterSet& s)
{
    uint32_t ret = s.size() * sizeof(double);
    return ret;
}