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); }
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); }
uint32_t FloatRegister::GetPushSizeInBytes(const FloatRegisterSet& s) { return s.size() * sizeof(double); }
uint32_t FloatRegister::GetSizeInBytes(const FloatRegisterSet& s) { uint32_t ret = s.size() * sizeof(double); return ret; }