Bug 1019831: Add an optional simdSet parameter to {Push,Pop}RegsInMask; r=sunfish

--HG--
extra : rebase_source : 4f0fc89cafe86497ea9efdb6101fdf9e27ca5921
This commit is contained in:
Benjamin Bouvier 2014-08-07 17:58:48 +02:00
parent 7b824bf050
commit 4f03b8bd59
4 changed files with 53 additions and 10 deletions

View File

@ -497,17 +497,26 @@ class MacroAssembler : public MacroAssemblerSpecific
return extractObject(source, scratch);
}
void PushRegsInMask(RegisterSet set);
void PushRegsInMask(RegisterSet set, FloatRegisterSet simdSet);
void PushRegsInMask(RegisterSet set) {
PushRegsInMask(set, FloatRegisterSet());
}
void PushRegsInMask(GeneralRegisterSet set) {
PushRegsInMask(RegisterSet(set, FloatRegisterSet()));
}
void PopRegsInMask(RegisterSet set) {
PopRegsInMaskIgnore(set, RegisterSet());
}
void PopRegsInMask(RegisterSet set, FloatRegisterSet simdSet) {
PopRegsInMaskIgnore(set, RegisterSet(), simdSet);
}
void PopRegsInMask(GeneralRegisterSet set) {
PopRegsInMask(RegisterSet(set, FloatRegisterSet()));
}
void PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore);
void PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore, FloatRegisterSet simdSet);
void PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore) {
PopRegsInMaskIgnore(set, ignore, FloatRegisterSet());
}
void branchIfFunctionHasNoScript(Register fun, Label *label) {
// 16-bit loads are slow and unaligned 32-bit loads may be too so

View File

@ -351,6 +351,11 @@ class TypedRegisterSet
static inline TypedRegisterSet Not(const TypedRegisterSet &in) {
return TypedRegisterSet(~in.bits_ & T::Codes::AllocatableMask);
}
static inline TypedRegisterSet Subtract(const TypedRegisterSet &lhs,
const TypedRegisterSet &rhs)
{
return TypedRegisterSet(lhs.bits_ & ~rhs.bits_);
}
static inline TypedRegisterSet VolatileNot(const TypedRegisterSet &in) {
const SetType allocatableVolatile =
T::Codes::AllocatableMask & T::Codes::VolatileMask;

View File

@ -1873,8 +1873,9 @@ MacroAssemblerARMCompat::freeStack(Register amount)
}
void
MacroAssembler::PushRegsInMask(RegisterSet set)
MacroAssembler::PushRegsInMask(RegisterSet set, FloatRegisterSet simdSet)
{
JS_ASSERT(!SupportsSimd && simdSet.size() == 0);
int32_t diffF = set.fpus().getPushSizeInBytes();
int32_t diffG = set.gprs().size() * sizeof(intptr_t);
@ -1901,8 +1902,9 @@ MacroAssembler::PushRegsInMask(RegisterSet set)
}
void
MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore)
MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore, FloatRegisterSet simdSet)
{
JS_ASSERT(!SupportsSimd && simdSet.size() == 0);
int32_t diffG = set.gprs().size() * sizeof(intptr_t);
int32_t diffF = set.fpus().getPushSizeInBytes();
const int32_t reservedG = diffG;

View File

@ -13,9 +13,13 @@ using namespace js;
using namespace js::jit;
void
MacroAssembler::PushRegsInMask(RegisterSet set)
MacroAssembler::PushRegsInMask(RegisterSet set, FloatRegisterSet simdSet)
{
int32_t diffF = set.fpus().size() * sizeof(double);
FloatRegisterSet doubleSet(FloatRegisterSet::Subtract(set.fpus(), simdSet));
JS_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
@ -27,27 +31,50 @@ MacroAssembler::PushRegsInMask(RegisterSet set)
JS_ASSERT(diffG == 0);
reserveStack(diffF);
for (FloatRegisterBackwardIterator iter(set.fpus()); iter.more(); iter++) {
for (FloatRegisterBackwardIterator iter(doubleSet); iter.more(); iter++) {
diffF -= sizeof(double);
numDouble -= 1;
storeDouble(*iter, Address(StackPointer, diffF));
}
JS_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));
}
JS_ASSERT(numSimd == 0);
JS_ASSERT(diffF == 0);
}
void
MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore)
MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore, FloatRegisterSet simdSet)
{
FloatRegisterSet doubleSet(FloatRegisterSet::Subtract(set.fpus(), simdSet));
JS_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 = set.fpus().size() * sizeof(double);
int32_t diffF = numDouble * sizeof(double) + numSimd * Simd128DataSize;
const int32_t reservedG = diffG;
const int32_t reservedF = diffF;
for (FloatRegisterBackwardIterator iter(set.fpus()); iter.more(); iter++) {
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);
}
JS_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);
JS_ASSERT(numDouble == 0);
JS_ASSERT(diffF == 0);
// On x86, use pop to pop the integer registers, if we're not going to