return StackReference(m_offsetFromTop);
}
- // FIXME: ARM64 needs an API take a list of register to push and pop to use strp and ldrp when possible.
- StackReference push(JSC::MacroAssembler::RegisterID registerID)
+ Vector<StackReference> push(const Vector<JSC::MacroAssembler::RegisterID>& registerIDs)
{
RELEASE_ASSERT(!m_hasFunctionCallPadding);
+ unsigned registerCount = registerIDs.size();
+ Vector<StackReference> stackReferences;
+ stackReferences.reserveInitialCapacity(registerCount);
#if CPU(ARM64)
- m_assembler.m_assembler.str<64>(registerID, JSC::ARM64Registers::sp, JSC::PreIndex(-16));
+ for (unsigned i = 0; i < registerCount - 1; i += 2) {
+ m_assembler.pushPair(registerIDs[i + 1], registerIDs[i]);
+ m_offsetFromTop += stackUnitInBytes;
+ stackReferences.append(StackReference(m_offsetFromTop - stackUnitInBytes / 2));
+ stackReferences.append(StackReference(m_offsetFromTop));
+ }
+ if (registerCount % 2) {
+ m_assembler.pushToSave(registerIDs[registerCount - 1]);
+ m_offsetFromTop += stackUnitInBytes;
+ stackReferences.append(StackReference(m_offsetFromTop));
+ }
#else
- m_assembler.push(registerID);
+ for (auto registerID : registerIDs) {
+ m_assembler.pushToSave(registerID);
+ m_offsetFromTop += stackUnitInBytes;
+ stackReferences.append(StackReference(m_offsetFromTop));
+ }
#endif
+ return stackReferences;
+ }
+
+ StackReference push(JSC::MacroAssembler::RegisterID registerID)
+ {
+ RELEASE_ASSERT(!m_hasFunctionCallPadding);
+ m_assembler.pushToSave(registerID);
m_offsetFromTop += stackUnitInBytes;
return StackReference(m_offsetFromTop);
}
- void pop(StackReference stackReference, JSC::MacroAssembler::RegisterID registerID)
+ void pop(const Vector<StackReference>& stackReferences, const Vector<JSC::MacroAssembler::RegisterID>& registerIDs)
{
- RELEASE_ASSERT(stackReference == m_offsetFromTop);
RELEASE_ASSERT(!m_hasFunctionCallPadding);
- ASSERT(m_offsetFromTop > 0);
- m_offsetFromTop -= stackUnitInBytes;
+
+ unsigned registerCount = registerIDs.size();
+ RELEASE_ASSERT(stackReferences.size() == registerCount);
#if CPU(ARM64)
- m_assembler.m_assembler.ldr<64>(registerID, JSC::ARM64Registers::sp, JSC::PostIndex(16));
+ ASSERT(m_offsetFromTop >= stackUnitInBytes * registerCount);
+ unsigned registerCountOdd = registerCount % 2;
+ if (registerCountOdd) {
+ RELEASE_ASSERT(stackReferences[registerCount - 1] == m_offsetFromTop);
+ RELEASE_ASSERT(m_offsetFromTop >= stackUnitInBytes);
+ m_offsetFromTop -= stackUnitInBytes;
+ m_assembler.popToRestore(registerIDs[registerCount - 1]);
+ }
+ for (unsigned i = registerCount - registerCountOdd; i > 0; i -= 2) {
+ RELEASE_ASSERT(stackReferences[i - 1] == m_offsetFromTop);
+ RELEASE_ASSERT(stackReferences[i - 2] == m_offsetFromTop - stackUnitInBytes / 2);
+ RELEASE_ASSERT(m_offsetFromTop >= stackUnitInBytes);
+ m_offsetFromTop -= stackUnitInBytes;
+ m_assembler.popPair(registerIDs[i - 1], registerIDs[i - 2]);
+ }
#else
- m_assembler.pop(registerID);
+ ASSERT(m_offsetFromTop >= stackUnitInBytes * registerCount);
+ for (unsigned i = registerCount; i > 0; --i) {
+ RELEASE_ASSERT(stackReferences[i - 1] == m_offsetFromTop);
+ RELEASE_ASSERT(m_offsetFromTop >= stackUnitInBytes);
+ m_offsetFromTop -= stackUnitInBytes;
+ m_assembler.popToRestore(registerIDs[i - 1]);
+ }
#endif
}
+
+ void pop(StackReference stackReference, JSC::MacroAssembler::RegisterID registerID)
+ {
+ RELEASE_ASSERT(stackReference == m_offsetFromTop);
+ RELEASE_ASSERT(!m_hasFunctionCallPadding);
+ RELEASE_ASSERT(m_offsetFromTop >= stackUnitInBytes);
+ m_offsetFromTop -= stackUnitInBytes;
+ m_assembler.popToRestore(registerID);
+ }
void popAndDiscard(StackReference stackReference)
{