Title: [294794] trunk/Source/_javascript_Core
Revision
294794
Author
commit-qu...@webkit.org
Date
2022-05-25 06:32:59 -0700 (Wed, 25 May 2022)

Log Message

[JSC][ARMv7] Support callee save FPRs

Patch by Geza Lore <gl...@igalia.com> on 2022-05-25
https://bugs.webkit.org/show_bug.cgi?id=240376

Reviewed by Yusuke Suzuki.

ARMv7 FPRs d8-d15 (also referenced as s16-s32 and q4-q7) are callee save
in the host ABI, but currently JSC is unaware of this. This does not
currently cause problems as they are not used, but will be used by the
Wasm JITs.

In preparation for the 32-bit ports of the Wasm JITs, this patch:
- Teaches JSC about callee save FPRs on ARMv7. d8-d15 are host ABI
  callee save, but only d8-d14 are VM callee save, i.e.: we treat d15
  as a volatile register in JIT code. This is so we can use d15 as a
  macro assembler scratch register.
- Changes offlineasm and MacroAssemblerARMv7 to use d15 as the FP
  scratch register. We do this so we can use the full range of d0-d7
  as temporary, and in particular as Wasm argument/return registers.
- To achieve the above, we need to modify RegisterAtOffsetList as GPRs
  and FPRs have different sizes on JSVALUE32_64 platforms
- Adds the ARMv7 specific registers to
  RegisterSet::macroScratchRegisters()

* assembler/ARMv7Registers.h:
* assembler/MacroAssemblerARMv7.h:
* b3/air/AirCode.cpp:
(JSC::B3::Air::Code::calleeSaveRegisterAtOffsetList const):
(JSC::B3::Air::Code::dump const):
* b3/testb3_7.cpp:
(testInfiniteLoopDoesntCauseBadHoisting):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters):
(JSC::CodeBlock::calleeSaveSpaceAsVirtualRegisters):
(JSC::roundCalleeSaveSpaceAsVirtualRegisters): Deleted.
* bytecode/ValueRecovery.h:
(JSC::ValueRecovery::calleeSaveGPRDisplacedInJSStack):
(JSC::ValueRecovery::calleeSaveRegDisplacedInJSStack): Deleted.
* dfg/DFGOSREntry.cpp:
(JSC::DFG::prepareOSREntry):
* dfg/DFGOSRExitCompilerCommon.cpp:
(JSC::DFG::calleeSaveSlot):
* ftl/FTLOSRExitCompiler.cpp:
(JSC::FTL::compileStub):
* interpreter/Interpreter.cpp:
(JSC::UnwindFunctor::copyCalleeSavesToEntryFrameCalleeSavesBuffer const):
* jit/AssemblyHelpers.cpp:
(JSC::AssemblyHelpers::restoreCalleeSavesFromEntryFrameCalleeSavesBuffer):
(JSC::AssemblyHelpers::restoreCalleeSavesFromVMEntryFrameCalleeSavesBufferImpl):
(JSC::AssemblyHelpers::copyCalleeSavesToEntryFrameCalleeSavesBufferImpl):
(JSC::AssemblyHelpers::emitSave):
(JSC::AssemblyHelpers::emitRestore):
(JSC::AssemblyHelpers::emitSaveCalleeSavesFor):
(JSC::AssemblyHelpers::emitRestoreCalleeSavesFor):
(JSC::AssemblyHelpers::copyLLIntBaselineCalleeSavesFromFrameOrRegisterToEntryFrameCalleeSavesBuffer):
(JSC::AssemblyHelpers::emitSaveOrCopyLLIntBaselineCalleeSavesFor):
* jit/CallFrameShuffleData.cpp:
(JSC::CallFrameShuffleData::setupCalleeSaveRegisters):
* jit/CallFrameShuffler.h:
(JSC::CallFrameShuffler::snapshot const):
* jit/CallFrameShuffler32_64.cpp:
(JSC::CallFrameShuffler::emitDisplace):
* jit/FPRInfo.h:
* jit/GPRInfo.h:
* jit/RegisterAtOffsetList.cpp:
(JSC::RegisterAtOffsetList::RegisterAtOffsetList):
* jit/RegisterAtOffsetList.h:
(JSC::RegisterAtOffsetList::registerCount const):
(JSC::RegisterAtOffsetList::sizeOfAreaInBytes const):
(JSC::RegisterAtOffsetList::adjustOffsets):
(JSC::RegisterAtOffsetList::size const): Deleted.
(JSC::RegisterAtOffsetList::at): Deleted.
* jit/RegisterSet.cpp:
(JSC::RegisterSet::macroScratchRegisters):
(JSC::RegisterSet::vmCalleeSaveRegisters):
* llint/LowLevelInterpreter.asm:
* offlineasm/arm.rb:
* wasm/js/JSToWasm.cpp:
(JSC::Wasm::createJSToWasmWrapper):
* wasm/js/WasmToJS.cpp:
(JSC::Wasm::wasmToJS):
* wasm/js/WebAssemblyFunction.cpp:
(JSC::WebAssemblyFunction::jsCallEntrypointSlow):

Canonical link: https://commits.webkit.org/250952@main

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/assembler/ARMv7Registers.h (294793 => 294794)


--- trunk/Source/_javascript_Core/assembler/ARMv7Registers.h	2022-05-25 10:41:30 UTC (rev 294793)
+++ trunk/Source/_javascript_Core/assembler/ARMv7Registers.h	2022-05-25 13:32:59 UTC (rev 294794)
@@ -104,22 +104,22 @@
     macro(s13, "s13", 0, 0)                     \
     macro(s14, "s14", 0, 0)                     \
     macro(s15, "s15", 0, 0)                     \
-    macro(s16, "s16", 0, 0)                     \
-    macro(s17, "s17", 0, 0)                     \
-    macro(s18, "s18", 0, 0)                     \
-    macro(s19, "s19", 0, 0)                     \
-    macro(s20, "s20", 0, 0)                     \
-    macro(s21, "s21", 0, 0)                     \
-    macro(s22, "s22", 0, 0)                     \
-    macro(s23, "s23", 0, 0)                     \
-    macro(s24, "s24", 0, 0)                     \
-    macro(s25, "s25", 0, 0)                     \
-    macro(s26, "s26", 0, 0)                     \
-    macro(s27, "s27", 0, 0)                     \
-    macro(s28, "s28", 0, 0)                     \
-    macro(s29, "s29", 0, 0)                     \
-    macro(s30, "s30", 0, 0)                     \
-    macro(s31, "s31", 0, 0)
+    macro(s16, "s16", 0, 1)                     \
+    macro(s17, "s17", 0, 1)                     \
+    macro(s18, "s18", 0, 1)                     \
+    macro(s19, "s19", 0, 1)                     \
+    macro(s20, "s20", 0, 1)                     \
+    macro(s21, "s21", 0, 1)                     \
+    macro(s22, "s22", 0, 1)                     \
+    macro(s23, "s23", 0, 1)                     \
+    macro(s24, "s24", 0, 1)                     \
+    macro(s25, "s25", 0, 1)                     \
+    macro(s26, "s26", 0, 1)                     \
+    macro(s27, "s27", 0, 1)                     \
+    macro(s28, "s28", 0, 1)                     \
+    macro(s29, "s29", 0, 1)                     \
+    macro(s30, "s30", 0, 1)                     \
+    macro(s31, "s31", 0, 1)
 
 #if CPU(ARM_NEON) || CPU(ARM_VFP_V3_D32)
 #define FOR_EACH_FP_DOUBLE_REGISTER(macro)      \
@@ -131,14 +131,14 @@
     macro(d5,  "d5",  0, 0)                     \
     macro(d6,  "d6",  0, 0)                     \
     macro(d7,  "d7",  0, 0)                     \
-    macro(d8,  "d8",  0, 0)                     \
-    macro(d9,  "d9",  0, 0)                     \
-    macro(d10, "d10", 0, 0)                     \
-    macro(d11, "d11", 0, 0)                     \
-    macro(d12, "d12", 0, 0)                     \
-    macro(d13, "d13", 0, 0)                     \
-    macro(d14, "d14", 0, 0)                     \
-    macro(d15, "d15", 0, 0)                     \
+    macro(d8,  "d8",  0, 1)                     \
+    macro(d9,  "d9",  0, 1)                     \
+    macro(d10, "d10", 0, 1)                     \
+    macro(d11, "d11", 0, 1)                     \
+    macro(d12, "d12", 0, 1)                     \
+    macro(d13, "d13", 0, 1)                     \
+    macro(d14, "d14", 0, 1)                     \
+    macro(d15, "d15", 0, 1)                     \
     macro(d16, "d16", 0, 0)                     \
     macro(d17, "d17", 0, 0)                     \
     macro(d18, "d18", 0, 0)                     \
@@ -165,14 +165,14 @@
     macro(d5,  "d5",  0, 0)                     \
     macro(d6,  "d6",  0, 0)                     \
     macro(d7,  "d7",  0, 0)                     \
-    macro(d8,  "d8",  0, 0)                     \
-    macro(d9,  "d9",  0, 0)                     \
-    macro(d10, "d10", 0, 0)                     \
-    macro(d11, "d11", 0, 0)                     \
-    macro(d12, "d12", 0, 0)                     \
-    macro(d13, "d13", 0, 0)                     \
-    macro(d14, "d14", 0, 0)                     \
-    macro(d15, "d15", 0, 0)
+    macro(d8,  "d8",  0, 1)                     \
+    macro(d9,  "d9",  0, 1)                     \
+    macro(d10, "d10", 0, 1)                     \
+    macro(d11, "d11", 0, 1)                     \
+    macro(d12, "d12", 0, 1)                     \
+    macro(d13, "d13", 0, 1)                     \
+    macro(d14, "d14", 0, 1)                     \
+    macro(d15, "d15", 0, 1)
 #endif
 
 #if CPU(ARM_NEON)
@@ -181,10 +181,10 @@
     macro(q1, "q1", 0, 0)                       \
     macro(q2, "q2", 0, 0)                       \
     macro(q3, "q3", 0, 0)                       \
-    macro(q4, "q4", 0, 0)                       \
-    macro(q5, "q5", 0, 0)                       \
-    macro(q6, "q6", 0, 0)                       \
-    macro(q7, "q7", 0, 0)                       \
+    macro(q4, "q4", 0, 1)                       \
+    macro(q5, "q5", 0, 1)                       \
+    macro(q6, "q6", 0, 1)                       \
+    macro(q7, "q7", 0, 1)                       \
     macro(q8, "q8", 0, 0)                       \
     macro(q9, "q9", 0, 0)                       \
     macro(q10, "q10", 0, 0)                     \

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerARMv7.h (294793 => 294794)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerARMv7.h	2022-05-25 10:41:30 UTC (rev 294793)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerARMv7.h	2022-05-25 13:32:59 UTC (rev 294794)
@@ -41,11 +41,14 @@
 public:
     static constexpr size_t nearJumpRange = 16 * MB;
 
-private:
     static constexpr RegisterID dataTempRegister = ARMRegisters::ip;
     static constexpr RegisterID addressTempRegister = ARMRegisters::r6;
 
-    static constexpr ARMRegisters::FPDoubleRegisterID fpTempRegister = ARMRegisters::d7;
+    // d15 is host/C ABI callee save, but is volatile in the VM/JS ABI. We use
+    // this as scratch register so we can use the full range of d0-d7 as
+    // temporary, and in particular as Wasm argument/return register.
+    static constexpr ARMRegisters::FPDoubleRegisterID fpTempRegister = ARMRegisters::d15;
+private:
     inline ARMRegisters::FPSingleRegisterID fpTempRegisterAsSingle() { return ARMRegisters::asSingle(fpTempRegister); }
 
     // In the Thumb-2 instruction set, instructions operating only on registers r0-r7 can often

Modified: trunk/Source/_javascript_Core/b3/air/AirCode.cpp (294793 => 294794)


--- trunk/Source/_javascript_Core/b3/air/AirCode.cpp	2022-05-25 10:41:30 UTC (rev 294793)
+++ trunk/Source/_javascript_Core/b3/air/AirCode.cpp	2022-05-25 13:32:59 UTC (rev 294794)
@@ -229,14 +229,8 @@
 RegisterAtOffsetList Code::calleeSaveRegisterAtOffsetList() const
 {
     RegisterAtOffsetList result = m_uncorrectedCalleeSaveRegisterAtOffsetList;
-    if (StackSlot* slot = m_calleeSaveStackSlot) {
-        ptrdiff_t offset = slot->byteSize() + slot->offsetFromFP();
-        for (size_t i = result.size(); i--;) {
-            result.at(i) = RegisterAtOffset(
-                result.at(i).reg(),
-                result.at(i).offset() + offset);
-        }
-    }
+    if (StackSlot* slot = m_calleeSaveStackSlot)
+        result.adjustOffsets(slot->byteSize() + slot->offsetFromFP());
     return result;
 }
 
@@ -277,7 +271,7 @@
     if (m_callArgAreaSize)
         out.print(tierName, "Call arg area size: ", m_callArgAreaSize, "\n");
     RegisterAtOffsetList calleeSaveRegisters = this->calleeSaveRegisterAtOffsetList();
-    if (calleeSaveRegisters.size())
+    if (calleeSaveRegisters.registerCount())
         out.print(tierName, "Callee saves: ", calleeSaveRegisters, "\n");
 }
 

Modified: trunk/Source/_javascript_Core/b3/testb3_7.cpp (294793 => 294794)


--- trunk/Source/_javascript_Core/b3/testb3_7.cpp	2022-05-25 10:41:30 UTC (rev 294793)
+++ trunk/Source/_javascript_Core/b3/testb3_7.cpp	2022-05-25 13:32:59 UTC (rev 294794)
@@ -1557,7 +1557,7 @@
 
     // The patchpoint early ret() works because we don't have callee saves.
     auto code = compileProc(proc);
-    RELEASE_ASSERT(!proc.calleeSaveRegisterAtOffsetList().size()); 
+    RELEASE_ASSERT(!proc.calleeSaveRegisterAtOffsetList().registerCount());
     invoke<void>(*code, static_cast<uint64_t>(55)); // Shouldn't crash dereferncing 55.
 }
 

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (294793 => 294794)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2022-05-25 10:41:30 UTC (rev 294793)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2022-05-25 13:32:59 UTC (rev 294794)
@@ -2462,21 +2462,14 @@
 }
 
 #if !ENABLE(C_LOOP)
-static size_t roundCalleeSaveSpaceAsVirtualRegisters(size_t calleeSaveRegisters)
-{
-
-    return (WTF::roundUpToMultipleOf(sizeof(Register), calleeSaveRegisters * sizeof(CPURegister)) / sizeof(Register));
-
-}
-
 size_t CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters()
 {
-    return roundCalleeSaveSpaceAsVirtualRegisters(numberOfLLIntBaselineCalleeSaveRegisters());
+    return WTF::roundUpToMultipleOf<sizeof(Register)>(numberOfLLIntBaselineCalleeSaveRegisters() * sizeof(CPURegister)) / sizeof(Register);
 }
 
 size_t CodeBlock::calleeSaveSpaceAsVirtualRegisters(const RegisterAtOffsetList& calleeSaveRegisters)
 {
-    return roundCalleeSaveSpaceAsVirtualRegisters(calleeSaveRegisters.size());
+    return WTF::roundUpToMultipleOf<sizeof(Register)>(calleeSaveRegisters.sizeOfAreaInBytes()) / sizeof(Register);
 }
 #endif
 

Modified: trunk/Source/_javascript_Core/bytecode/ValueRecovery.h (294793 => 294794)


--- trunk/Source/_javascript_Core/bytecode/ValueRecovery.h	2022-05-25 10:41:30 UTC (rev 294793)
+++ trunk/Source/_javascript_Core/bytecode/ValueRecovery.h	2022-05-25 13:32:59 UTC (rev 294794)
@@ -192,7 +192,7 @@
     }
 
 #if USE(JSVALUE32_64)
-    static ValueRecovery calleeSaveRegDisplacedInJSStack(VirtualRegister virtualReg, bool inTag)
+    static ValueRecovery calleeSaveGPRDisplacedInJSStack(VirtualRegister virtualReg, bool inTag)
     {
         ValueRecovery result;
         UnionType u;

Modified: trunk/Source/_javascript_Core/dfg/DFGOSREntry.cpp (294793 => 294794)


--- trunk/Source/_javascript_Core/dfg/DFGOSREntry.cpp	2022-05-25 10:41:30 UTC (rev 294793)
+++ trunk/Source/_javascript_Core/dfg/DFGOSREntry.cpp	2022-05-25 13:32:59 UTC (rev 294794)
@@ -299,7 +299,7 @@
     RegisterAtOffsetList* allCalleeSaves = RegisterSet::vmCalleeSaveRegisterOffsets();
     RegisterSet dontSaveRegisters = RegisterSet(RegisterSet::stackRegisters());
 
-    unsigned registerCount = registerSaveLocations->size();
+    unsigned registerCount = registerSaveLocations->registerCount();
     VMEntryRecord* record = vmEntryRecord(vm.topEntryFrame);
     for (unsigned i = 0; i < registerCount; i++) {
         RegisterAtOffset currentEntry = registerSaveLocations->at(i);

Modified: trunk/Source/_javascript_Core/dfg/DFGOSRExitCompilerCommon.cpp (294793 => 294794)


--- trunk/Source/_javascript_Core/dfg/DFGOSRExitCompilerCommon.cpp	2022-05-25 10:41:30 UTC (rev 294793)
+++ trunk/Source/_javascript_Core/dfg/DFGOSRExitCompilerCommon.cpp	2022-05-25 13:32:59 UTC (rev 294794)
@@ -231,7 +231,7 @@
 CCallHelpers::Address calleeSaveSlot(InlineCallFrame* inlineCallFrame, CodeBlock* baselineCodeBlock, GPRReg calleeSave)
 {
     const RegisterAtOffsetList* calleeSaves = baselineCodeBlock->jitCode()->calleeSaveRegisters();
-    for (unsigned i = 0; i < calleeSaves->size(); i++) {
+    for (unsigned i = 0; i < calleeSaves->registerCount(); i++) {
         RegisterAtOffset entry = calleeSaves->at(i);
         if (entry.reg() != calleeSave)
             continue;

Modified: trunk/Source/_javascript_Core/ftl/FTLOSRExitCompiler.cpp (294793 => 294794)


--- trunk/Source/_javascript_Core/ftl/FTLOSRExitCompiler.cpp	2022-05-25 10:41:30 UTC (rev 294793)
+++ trunk/Source/_javascript_Core/ftl/FTLOSRExitCompiler.cpp	2022-05-25 13:32:59 UTC (rev 294794)
@@ -182,7 +182,7 @@
         sizeof(EncodedJSValue) * (
             exit.m_descriptor->m_values.size() + numMaterializations + maxMaterializationNumArguments) +
         requiredScratchMemorySizeInBytes() +
-        codeBlock->jitCode()->calleeSaveRegisters()->size() * sizeof(uint64_t));
+        codeBlock->jitCode()->calleeSaveRegisters()->sizeOfAreaInBytes());
     EncodedJSValue* scratch = scratchBuffer ? static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer()) : nullptr;
     EncodedJSValue* materializationPointers = scratch + exit.m_descriptor->m_values.size();
     EncodedJSValue* materializationArguments = materializationPointers + numMaterializations;
@@ -452,7 +452,7 @@
         jit.move(CCallHelpers::framePointerRegister, srcBufferGPR);
         jit.move(CCallHelpers::TrustedImmPtr(unwindScratch), destBufferGPR);
         CCallHelpers::CopySpooler spooler(CCallHelpers::CopySpooler::BufferRegs::AllowModification, jit, srcBufferGPR, destBufferGPR, GPRInfo::regT0, GPRInfo::regT1);
-        for (unsigned i = codeBlock->jitCode()->calleeSaveRegisters()->size(); i--;) {
+        for (unsigned i = codeBlock->jitCode()->calleeSaveRegisters()->registerCount(); i--;) {
             RegisterAtOffset entry = codeBlock->jitCode()->calleeSaveRegisters()->at(i);
             spooler.loadGPR(entry.offset());
             spooler.storeGPR(i * sizeof(uint64_t));

Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.cpp (294793 => 294794)


--- trunk/Source/_javascript_Core/interpreter/Interpreter.cpp	2022-05-25 10:41:30 UTC (rev 294793)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.cpp	2022-05-25 13:32:59 UTC (rev 294794)
@@ -625,7 +625,7 @@
         RegisterSet dontCopyRegisters = RegisterSet::stackRegisters();
         CPURegister* frame = reinterpret_cast<CPURegister*>(m_callFrame->registers());
 
-        unsigned registerCount = currentCalleeSaves->size();
+        unsigned registerCount = currentCalleeSaves->registerCount();
         VMEntryRecord* record = vmEntryRecord(m_vm.topEntryFrame);
         for (unsigned i = 0; i < registerCount; i++) {
             RegisterAtOffset currentEntry = currentCalleeSaves->at(i);

Modified: trunk/Source/_javascript_Core/jit/AssemblyHelpers.cpp (294793 => 294794)


--- trunk/Source/_javascript_Core/jit/AssemblyHelpers.cpp	2022-05-25 10:41:30 UTC (rev 294793)
+++ trunk/Source/_javascript_Core/jit/AssemblyHelpers.cpp	2022-05-25 13:32:59 UTC (rev 294794)
@@ -633,7 +633,7 @@
 #if NUMBER_OF_CALLEE_SAVES_REGISTERS > 0
     RegisterAtOffsetList* allCalleeSaves = RegisterSet::vmCalleeSaveRegisterOffsets();
     RegisterSet dontRestoreRegisters = RegisterSet::stackRegisters();
-    unsigned registerCount = allCalleeSaves->size();
+    unsigned registerCount = allCalleeSaves->registerCount();
 
     GPRReg scratch = InvalidGPRReg;
     unsigned scratchGPREntryIndex = 0;
@@ -720,7 +720,7 @@
     addPtr(TrustedImm32(EntryFrame::calleeSaveRegistersBufferOffset()), entryFrameGPR);
 
     RegisterAtOffsetList* allCalleeSaves = RegisterSet::vmCalleeSaveRegisterOffsets();
-    unsigned registerCount = allCalleeSaves->size();
+    unsigned registerCount = allCalleeSaves->registerCount();
 
     LoadRegSpooler spooler(*this, entryFrameGPR);
 
@@ -1109,7 +1109,7 @@
 
     RegisterAtOffsetList* allCalleeSaves = RegisterSet::vmCalleeSaveRegisterOffsets();
     RegisterSet dontCopyRegisters = RegisterSet::stackRegisters();
-    unsigned registerCount = allCalleeSaves->size();
+    unsigned registerCount = allCalleeSaves->registerCount();
 
     StoreRegSpooler spooler(*this, calleeSavesBuffer);
 
@@ -1219,9 +1219,9 @@
 {
     StoreRegSpooler spooler(*this, framePointerRegister);
 
-    size_t listSize = list.size();
+    size_t registerCount = list.registerCount();
     size_t i = 0;
-    for (; i < listSize; i++) {
+    for (; i < registerCount; i++) {
         auto entry = list.at(i);
         if (!entry.reg().isGPR())
             break;
@@ -1229,7 +1229,7 @@
     }
     spooler.finalizeGPR();
 
-    for (; i < listSize; i++)
+    for (; i < registerCount; i++)
         spooler.storeFPR(list.at(i));
     spooler.finalizeFPR();
 }
@@ -1238,9 +1238,9 @@
 {
     LoadRegSpooler spooler(*this, framePointerRegister);
 
-    size_t listSize = list.size();
+    size_t registerCount = list.registerCount();
     size_t i = 0;
-    for (; i < listSize; i++) {
+    for (; i < registerCount; i++) {
         auto entry = list.at(i);
         if (!entry.reg().isGPR())
             break;
@@ -1248,7 +1248,7 @@
     }
     spooler.finalizeGPR();
 
-    for (; i < listSize; i++)
+    for (; i < registerCount; i++)
         spooler.loadFPR(list.at(i));
     spooler.finalizeFPR();
 }
@@ -1256,7 +1256,7 @@
 void AssemblyHelpers::emitSaveCalleeSavesFor(const RegisterAtOffsetList* calleeSaves)
 {
     RegisterSet dontSaveRegisters = RegisterSet(RegisterSet::stackRegisters());
-    unsigned registerCount = calleeSaves->size();
+    unsigned registerCount = calleeSaves->registerCount();
 
     StoreRegSpooler spooler(*this, framePointerRegister);
 
@@ -1282,7 +1282,7 @@
 void AssemblyHelpers::emitRestoreCalleeSavesFor(const RegisterAtOffsetList* calleeSaves)
 {
     RegisterSet dontRestoreRegisters = RegisterSet(RegisterSet::stackRegisters());
-    unsigned registerCount = calleeSaves->size();
+    unsigned registerCount = calleeSaves->registerCount();
     
     LoadRegSpooler spooler(*this, framePointerRegister);
 
@@ -1325,7 +1325,7 @@
     RegisterAtOffsetList* allCalleeSaves = RegisterSet::vmCalleeSaveRegisterOffsets();
     const RegisterAtOffsetList* currentCalleeSaves = &RegisterAtOffsetList::llintBaselineCalleeSaveRegisters();
     RegisterSet dontCopyRegisters = RegisterSet::stackRegisters();
-    unsigned registerCount = allCalleeSaves->size();
+    unsigned registerCount = allCalleeSaves->registerCount();
 
     unsigned i = 0;
     for (; i < registerCount; i++) {
@@ -1373,7 +1373,7 @@
 
     const RegisterAtOffsetList* calleeSaves = &RegisterAtOffsetList::llintBaselineCalleeSaveRegisters();
     RegisterSet dontSaveRegisters = RegisterSet(RegisterSet::stackRegisters());
-    unsigned registerCount = calleeSaves->size();
+    unsigned registerCount = calleeSaves->registerCount();
 
     GPRReg dstBufferGPR = temp1;
     addPtr(TrustedImm32(offsetVirtualRegister.offsetInBytes()), framePointerRegister, dstBufferGPR);

Modified: trunk/Source/_javascript_Core/jit/CallFrameShuffleData.cpp (294793 => 294794)


--- trunk/Source/_javascript_Core/jit/CallFrameShuffleData.cpp	2022-05-25 10:41:30 UTC (rev 294793)
+++ trunk/Source/_javascript_Core/jit/CallFrameShuffleData.cpp	2022-05-25 13:32:59 UTC (rev 294794)
@@ -39,7 +39,7 @@
 {
     RegisterSet calleeSaveRegisters { RegisterSet::vmCalleeSaveRegisters() };
 
-    for (size_t i = 0; i < registerSaveLocations->size(); ++i) {
+    for (size_t i = 0; i < registerSaveLocations->registerCount(); ++i) {
         RegisterAtOffset entry { registerSaveLocations->at(i) };
         if (!calleeSaveRegisters.get(entry.reg()))
             continue;
@@ -52,15 +52,20 @@
         registers[entry.reg()]
             = ValueRecovery::displacedInJSStack(saveSlot, DataFormatJS);
 #elif USE(JSVALUE32_64)
-        // On 32-bit architectures, 2 callee saved registers may be packed into the same slot
-        static_assert(!PayloadOffset || !TagOffset);
-        static_assert(PayloadOffset == 4 || TagOffset == 4);
-        bool inTag = (saveSlotIndexInCPURegisters & 1) == !!TagOffset;
-        if (saveSlotIndexInCPURegisters < 0)
-            saveSlotIndexInCPURegisters -= 1; // Round towards -inf
-        VirtualRegister saveSlot { saveSlotIndexInCPURegisters / 2 };
-        registers[entry.reg()]
-            = ValueRecovery::calleeSaveRegDisplacedInJSStack(saveSlot, inTag);
+        // On 32-bit architectures, 2 callee saved GPRs may be packed into the same slot
+        if (entry.reg().isGPR()) {
+            static_assert(!PayloadOffset || !TagOffset);
+            static_assert(PayloadOffset == 4 || TagOffset == 4);
+            bool inTag = (saveSlotIndexInCPURegisters & 1) == !!TagOffset;
+            if (saveSlotIndexInCPURegisters < 0)
+                saveSlotIndexInCPURegisters -= 1; // Round towards -inf
+            VirtualRegister saveSlot { saveSlotIndexInCPURegisters / 2 };
+            registers[entry.reg()] = ValueRecovery::calleeSaveGPRDisplacedInJSStack(saveSlot, inTag);
+        } else {
+            ASSERT(!(saveSlotIndexInCPURegisters & 1)); // Should be at an even offset
+            VirtualRegister saveSlot { saveSlotIndexInCPURegisters / 2 };
+            registers[entry.reg()] = ValueRecovery::displacedInJSStack(saveSlot, DataFormatDouble);
+        }
 #endif
     }
 
@@ -74,7 +79,7 @@
 #if USE(JSVALUE64)
         registers[reg] = ValueRecovery::inRegister(reg, DataFormatJS);
 #elif USE(JSVALUE32_64)
-        registers[reg] = ValueRecovery::inRegister(reg, DataFormatInt32);
+        registers[reg] = ValueRecovery::inRegister(reg, reg.isGPR() ? DataFormatInt32 : DataFormatDouble);
 #endif
     }
 }

Modified: trunk/Source/_javascript_Core/jit/CallFrameShuffler.h (294793 => 294794)


--- trunk/Source/_javascript_Core/jit/CallFrameShuffler.h	2022-05-25 10:41:30 UTC (rev 294793)
+++ trunk/Source/_javascript_Core/jit/CallFrameShuffler.h	2022-05-25 13:32:59 UTC (rev 294794)
@@ -119,11 +119,11 @@
             data.registers[reg] = cachedRecovery->recovery();
 #elif USE(JSVALUE32_64)
             ValueRecovery recovery = cachedRecovery->recovery();
-            if (recovery.technique() == DisplacedInJSStack) {
+            if (reg.isGPR() && recovery.technique() == DisplacedInJSStack) {
                 JSValueRegs wantedJSValueReg = cachedRecovery->wantedJSValueRegs();
                 ASSERT(reg == wantedJSValueReg.payloadGPR() || reg == wantedJSValueReg.tagGPR());
                 bool inTag = reg == wantedJSValueReg.tagGPR();
-                data.registers[reg] = ValueRecovery::calleeSaveRegDisplacedInJSStack(recovery.virtualRegister(), inTag);
+                data.registers[reg] = ValueRecovery::calleeSaveGPRDisplacedInJSStack(recovery.virtualRegister(), inTag);
             } else
                 data.registers[reg] = recovery;
 #else

Modified: trunk/Source/_javascript_Core/jit/CallFrameShuffler32_64.cpp (294793 => 294794)


--- trunk/Source/_javascript_Core/jit/CallFrameShuffler32_64.cpp	2022-05-25 10:41:30 UTC (rev 294793)
+++ trunk/Source/_javascript_Core/jit/CallFrameShuffler32_64.cpp	2022-05-25 13:32:59 UTC (rev 294794)
@@ -183,11 +183,10 @@
 {
     ASSERT(location.recovery().isInRegisters());
     JSValueRegs wantedJSValueRegs { location.wantedJSValueRegs() };
-    ASSERT(wantedJSValueRegs); // We don't support wanted FPRs on 32bit platforms
-
     GPRReg wantedTagGPR { wantedJSValueRegs.tagGPR() };
     GPRReg wantedPayloadGPR { wantedJSValueRegs.payloadGPR() };
-    
+    FPRReg wantedFPR { location.wantedFPR() };
+
     if (wantedTagGPR != InvalidGPRReg) {
         ASSERT(!m_lockedRegisters.get(wantedTagGPR));
         if (CachedRecovery* currentTag { m_registers[wantedTagGPR] }) {
@@ -208,6 +207,7 @@
 
     if (location.recovery().technique() == InPair
         || location.recovery().isInGPR()) {
+        ASSERT(wantedJSValueRegs); // We don't support wanted FPRs on 32bit platforms at the moment
         GPRReg payloadGPR;
         if (location.recovery().technique() == InPair)
             payloadGPR = location.recovery().payloadGPR();
@@ -273,22 +273,28 @@
         default:
             RELEASE_ASSERT_NOT_REACHED();
         }
+        updateRecovery(location, ValueRecovery::inPair(wantedTagGPR, wantedPayloadGPR));
     } else {
         ASSERT(location.recovery().isInFPR());
-        if (wantedTagGPR == InvalidGPRReg) {
-            ASSERT(wantedPayloadGPR != InvalidGPRReg);
-            m_lockedRegisters.set(wantedPayloadGPR);
-            wantedTagGPR = getFreeGPR();
-            m_lockedRegisters.clear(wantedPayloadGPR);
+        if (wantedFPR != InvalidFPRReg) {
+            m_jit.moveDouble(location.recovery().fpr(), wantedFPR);
+            updateRecovery(location, ValueRecovery::inRegister(wantedFPR, DataFormatJS));
+        } else {
+            if (wantedTagGPR == InvalidGPRReg) {
+                ASSERT(wantedPayloadGPR != InvalidGPRReg);
+                m_lockedRegisters.set(wantedPayloadGPR);
+                wantedTagGPR = getFreeGPR();
+                m_lockedRegisters.clear(wantedPayloadGPR);
+            }
+            if (wantedPayloadGPR == InvalidGPRReg) {
+                m_lockedRegisters.set(wantedTagGPR);
+                wantedPayloadGPR = getFreeGPR();
+                m_lockedRegisters.clear(wantedTagGPR);
+            }
+            m_jit.moveDoubleToInts(location.recovery().fpr(), wantedPayloadGPR, wantedTagGPR);
+            updateRecovery(location, ValueRecovery::inPair(wantedTagGPR, wantedPayloadGPR));
         }
-        if (wantedPayloadGPR == InvalidGPRReg) {
-            m_lockedRegisters.set(wantedTagGPR);
-            wantedPayloadGPR = getFreeGPR();
-            m_lockedRegisters.clear(wantedTagGPR);
-        }
-        m_jit.boxDouble(location.recovery().fpr(), wantedTagGPR, wantedPayloadGPR);
     }
-    updateRecovery(location, ValueRecovery::inPair(wantedTagGPR, wantedPayloadGPR));
 }
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/jit/FPRInfo.h (294793 => 294794)


--- trunk/Source/_javascript_Core/jit/FPRInfo.h	2022-05-25 10:41:30 UTC (rev 294793)
+++ trunk/Source/_javascript_Core/jit/FPRInfo.h	2022-05-25 13:32:59 UTC (rev 294794)
@@ -106,7 +106,7 @@
 class FPRInfo {
 public:
     typedef FPRReg RegisterType;
-    static constexpr unsigned numberOfRegisters = 6;
+    static constexpr unsigned numberOfRegisters = 8;
 
 #if CPU(ARM_HARDFP)
     static constexpr unsigned numberOfArgumentRegisters = 8;
@@ -115,7 +115,7 @@
 #endif
 
     // Temporary registers.
-    // d7 is use by the MacroAssembler as fpTempRegister.
+    // d8-d15 are callee saved, d15 is use by the MacroAssembler as fpTempRegister.
     static constexpr FPRReg fpRegT0 = ARMRegisters::d0;
     static constexpr FPRReg fpRegT1 = ARMRegisters::d1;
     static constexpr FPRReg fpRegT2 = ARMRegisters::d2;
@@ -122,6 +122,16 @@
     static constexpr FPRReg fpRegT3 = ARMRegisters::d3;
     static constexpr FPRReg fpRegT4 = ARMRegisters::d4;
     static constexpr FPRReg fpRegT5 = ARMRegisters::d5;
+    static constexpr FPRReg fpRegT6 = ARMRegisters::d6;
+    static constexpr FPRReg fpRegT7 = ARMRegisters::d7;
+    static constexpr FPRReg fpRegCS0 = ARMRegisters::d8;
+    static constexpr FPRReg fpRegCS1 = ARMRegisters::d9;
+    static constexpr FPRReg fpRegCS2 = ARMRegisters::d10;
+    static constexpr FPRReg fpRegCS3 = ARMRegisters::d11;
+    static constexpr FPRReg fpRegCS4 = ARMRegisters::d12;
+    static constexpr FPRReg fpRegCS5 = ARMRegisters::d13;
+    static constexpr FPRReg fpRegCS6 = ARMRegisters::d14;
+
     // ARMv7 doesn't pass arguments in fp registers. The return
     // value is also actually in integer registers, for now
     // we'll return in d0 for simplicity.
@@ -140,6 +150,8 @@
     static_assert(ARMRegisters::d3 == 3);
     static_assert(ARMRegisters::d4 == 4);
     static_assert(ARMRegisters::d5 == 5);
+    static_assert(ARMRegisters::d6 == 6);
+    static_assert(ARMRegisters::d7 == 7);
     static FPRReg toRegister(unsigned index)
     {
         return (FPRReg)index;

Modified: trunk/Source/_javascript_Core/jit/GPRInfo.h (294793 => 294794)


--- trunk/Source/_javascript_Core/jit/GPRInfo.h	2022-05-25 10:41:30 UTC (rev 294793)
+++ trunk/Source/_javascript_Core/jit/GPRInfo.h	2022-05-25 13:32:59 UTC (rev 294794)
@@ -553,7 +553,8 @@
 
 #if CPU(ARM_THUMB2)
 #define NUMBER_OF_ARGUMENT_REGISTERS 4u
-#define NUMBER_OF_CALLEE_SAVES_REGISTERS 2u
+// Callee Saves includes r10, r11, and FP registers d8..d15, which are twice the size of a GPR
+#define NUMBER_OF_CALLEE_SAVES_REGISTERS 18u
 
 class GPRInfo {
 public:

Modified: trunk/Source/_javascript_Core/jit/RegisterAtOffsetList.cpp (294793 => 294794)


--- trunk/Source/_javascript_Core/jit/RegisterAtOffsetList.cpp	2022-05-25 10:41:30 UTC (rev 294793)
+++ trunk/Source/_javascript_Core/jit/RegisterAtOffsetList.cpp	2022-05-25 13:32:59 UTC (rev 294794)
@@ -39,18 +39,41 @@
 RegisterAtOffsetList::RegisterAtOffsetList(RegisterSet registerSet, OffsetBaseType offsetBaseType)
     : m_registers(registerSet.numberOfSetRegisters())
 {
-    size_t numberOfRegisters = registerSet.numberOfSetRegisters();
-    ptrdiff_t offset = 0;
-    
+    constexpr size_t sizeOfGPR = sizeof(CPURegister);
+    constexpr size_t sizeOfFPR = sizeof(double);
+
+    size_t sizeOfAreaInBytes;
+    {
+#if USE(JSVALUE64)
+        static_assert(sizeOfGPR == sizeOfFPR);
+        size_t numberOfRegs = registerSet.numberOfSetRegisters();
+        sizeOfAreaInBytes = numberOfRegs * sizeOfGPR;
+#elif USE(JSVALUE32_64)
+        static_assert(2 * sizeOfGPR == sizeOfFPR);
+        size_t numberOfGPRs = registerSet.numberOfSetGPRs();
+        size_t numberOfFPRs = registerSet.numberOfSetFPRs();
+        if (numberOfFPRs)
+            numberOfGPRs = WTF::roundUpToMultipleOf<2>(numberOfGPRs);
+        sizeOfAreaInBytes = numberOfGPRs * sizeOfGPR + numberOfFPRs * sizeOfFPR;
+        m_sizeOfAreaInBytes = sizeOfAreaInBytes; // Hold on to it to avoid having to re-compute it
+#endif
+    }
+
+    ptrdiff_t startOffset = 0;
     if (offsetBaseType == FramePointerBased)
-        offset = -(static_cast<ptrdiff_t>(numberOfRegisters) * sizeof(CPURegister));
+        startOffset = -static_cast<ptrdiff_t>(sizeOfAreaInBytes);
 
+    ptrdiff_t offset = startOffset;
     unsigned index = 0;
+
     registerSet.forEach([&] (Reg reg) {
-        m_registers[index] = RegisterAtOffset(reg, offset);
-        offset += sizeof(CPURegister);
-        ++index;
+        size_t registerSize = reg.isGPR() ? sizeOfGPR : sizeOfFPR;
+        offset = WTF::roundUpToMultipleOf(registerSize, offset);
+        m_registers[index++] = RegisterAtOffset(reg, offset);
+        offset += registerSize;
     });
+
+    ASSERT(static_cast<size_t>(offset - startOffset) == sizeOfAreaInBytes);
 }
 
 void RegisterAtOffsetList::dump(PrintStream& out) const

Modified: trunk/Source/_javascript_Core/jit/RegisterAtOffsetList.h (294793 => 294794)


--- trunk/Source/_javascript_Core/jit/RegisterAtOffsetList.h	2022-05-25 10:41:30 UTC (rev 294793)
+++ trunk/Source/_javascript_Core/jit/RegisterAtOffsetList.h	2022-05-25 13:32:59 UTC (rev 294794)
@@ -44,9 +44,15 @@
 
     void dump(PrintStream&) const;
 
-    size_t size() const
+    size_t registerCount() const { return m_registers.size(); }
+    size_t sizeOfAreaInBytes() const
     {
-        return m_registers.size();
+#if USE(JSVALUE64)
+        static_assert(sizeof(CPURegister) == sizeof(double));
+        return registerCount() * sizeof(CPURegister);
+#elif USE(JSVALUE32_64)
+        return m_sizeOfAreaInBytes;
+#endif
     }
 
     const RegisterAtOffset& at(size_t index) const
@@ -54,11 +60,13 @@
         return m_registers.at(index);
     }
 
-    RegisterAtOffset& at(size_t index)
+    void adjustOffsets(ptrdiff_t addend)
     {
-        return m_registers.at(index);
+        // This preserves m_sizeOfAreaInBytes
+        for (RegisterAtOffset &item : m_registers)
+            item = RegisterAtOffset { item.reg(), item.offset() + addend };
     }
-    
+
     RegisterAtOffset* find(Reg) const;
     unsigned indexOf(Reg) const; // Returns UINT_MAX if not found.
 
@@ -65,11 +73,15 @@
     FixedVector<RegisterAtOffset>::const_iterator begin() const { return m_registers.begin(); }
     FixedVector<RegisterAtOffset>::const_iterator end() const { return m_registers.end(); }
 
+
     static const RegisterAtOffsetList& llintBaselineCalleeSaveRegisters(); // Registers and Offsets saved and used by the LLInt.
     static const RegisterAtOffsetList& dfgCalleeSaveRegisters(); // Registers and Offsets saved and used by DFG.
 
 private:
     FixedVector<RegisterAtOffset> m_registers;
+#if USE(JSVALUE32_64) // On JSVALUE64, we can compute this cheaply
+    size_t m_sizeOfAreaInBytes { 0 };
+#endif
 };
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/jit/RegisterSet.cpp (294793 => 294794)


--- trunk/Source/_javascript_Core/jit/RegisterSet.cpp	2022-05-25 10:41:30 UTC (rev 294793)
+++ trunk/Source/_javascript_Core/jit/RegisterSet.cpp	2022-05-25 13:32:59 UTC (rev 294794)
@@ -94,6 +94,12 @@
     return RegisterSet(MacroAssembler::s_scratchRegister);
 #elif CPU(ARM64) || CPU(RISCV64)
     return RegisterSet(MacroAssembler::dataTempRegister, MacroAssembler::memoryTempRegister);
+#elif CPU(ARM_THUMB2)
+    RegisterSet result;
+    result.set(MacroAssembler::dataTempRegister);
+    result.set(MacroAssembler::addressTempRegister);
+    result.set(MacroAssembler::fpTempRegister);
+    return result;
 #elif CPU(MIPS)
     RegisterSet result;
     result.set(MacroAssembler::immTempRegister);
@@ -152,9 +158,19 @@
     result.set(FPRInfo::fpRegCS5);
     result.set(FPRInfo::fpRegCS6);
     result.set(FPRInfo::fpRegCS7);
-#elif CPU(ARM_THUMB2) || CPU(MIPS)
+#elif CPU(ARM_THUMB2)
     result.set(GPRInfo::regCS0);
     result.set(GPRInfo::regCS1);
+    result.set(FPRInfo::fpRegCS0);
+    result.set(FPRInfo::fpRegCS1);
+    result.set(FPRInfo::fpRegCS2);
+    result.set(FPRInfo::fpRegCS3);
+    result.set(FPRInfo::fpRegCS4);
+    result.set(FPRInfo::fpRegCS5);
+    result.set(FPRInfo::fpRegCS6);
+#elif CPU(MIPS)
+    result.set(GPRInfo::regCS0);
+    result.set(GPRInfo::regCS1);
 #elif CPU(RISCV64)
     result.set(GPRInfo::regCS0);
     result.set(GPRInfo::regCS1);

Modified: trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm (294793 => 294794)


--- trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm	2022-05-25 10:41:30 UTC (rev 294793)
+++ trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm	2022-05-25 13:32:59 UTC (rev 294794)
@@ -756,7 +756,7 @@
 if C_LOOP or C_LOOP_WIN or ARM64 or ARM64E or X86_64 or X86_64_WIN or RISCV64
     const CalleeSaveRegisterCount = 0
 elsif ARMv7
-    const CalleeSaveRegisterCount = 7
+    const CalleeSaveRegisterCount = 7 + 2 * 1 // 7 32-bit GPRs + 1 64-bit FPR
 elsif MIPS
     const CalleeSaveRegisterCount = 3
 elsif X86 or X86_WIN
@@ -772,6 +772,7 @@
 macro pushCalleeSaves()
     if C_LOOP or C_LOOP_WIN or ARM64 or ARM64E or X86_64 or X86_64_WIN or RISCV64
     elsif ARMv7
+        emit "vpush.64 {d15}"
         emit "push {r4-r6, r8-r11}"
     elsif MIPS
         emit "addiu $sp, $sp, -12"
@@ -795,6 +796,7 @@
     if C_LOOP or C_LOOP_WIN or ARM64 or ARM64E or X86_64 or X86_64_WIN or RISCV64
     elsif ARMv7
         emit "pop {r4-r6, r8-r11}"
+        emit "vpop.64 {d15}"
     elsif MIPS
         emit "lw $s0, 0($sp)"
         emit "lw $s1, 4($sp)"
@@ -933,9 +935,19 @@
             storeq csr4, 32[entryFrame]
             storeq csr5, 40[entryFrame]
             storeq csr6, 48[entryFrame]
-        elsif ARMv7 or MIPS
+        elsif ARMv7
             storep csr0, [entryFrame]
             storep csr1, 4[entryFrame]
+            stored csfr0, 8[entryFrame]
+            stored csfr1, 16[entryFrame]
+            stored csfr2, 24[entryFrame]
+            stored csfr3, 32[entryFrame]
+            stored csfr4, 40[entryFrame]
+            stored csfr5, 48[entryFrame]
+            stored csfr6, 56[entryFrame]
+        elsif MIPS
+            storep csr0, [entryFrame]
+            storep csr1, 4[entryFrame]
         elsif RISCV64
             storep csr0, [entryFrame]
             storep csr1, 8[entryFrame]
@@ -1009,9 +1021,19 @@
             loadq 32[temp], csr4
             loadq 40[temp], csr5
             loadq 48[temp], csr6
-        elsif ARMv7 or MIPS
+        elsif ARMv7
             loadp [temp], csr0
             loadp 4[temp], csr1
+            loadd 8[temp], csfr0
+            loadd 16[temp], csfr1
+            loadd 24[temp], csfr2
+            loadd 32[temp], csfr3
+            loadd 40[temp], csfr4
+            loadd 48[temp], csfr5
+            loadd 56[temp], csfr6
+        elsif MIPS
+            loadp [temp], csr0
+            loadp 4[temp], csr1
         elsif RISCV64
             loadq [temp], csr0
             loadq 8[temp], csr1

Modified: trunk/Source/_javascript_Core/offlineasm/arm.rb (294793 => 294794)


--- trunk/Source/_javascript_Core/offlineasm/arm.rb	2022-05-25 10:41:30 UTC (rev 294793)
+++ trunk/Source/_javascript_Core/offlineasm/arm.rb	2022-05-25 13:32:59 UTC (rev 294794)
@@ -48,14 +48,22 @@
 #
 # FPR conventions, to match the baseline JIT
 #
-# d0 => ft0, fa0, fr
-# d1 => ft1, fa1
-# d2 => ft2
-# d3 => ft3
-# d4 => ft4
-# d5 => ft5
-# d6 =>              (scratch)
-# d7 =>              (scratch)
+#  d0 => ft0, fa0, fr
+#  d1 => ft1, fa1
+#  d2 => ft2
+#  d3 => ft3
+#  d4 => ft4
+#  d5 => ft5
+#  d6 => ft6
+#  d7 => ft7
+#  d8 => csfr0
+#  d9 => csfr1
+# d10 => csfr2
+# d11 => csfr3
+# d12 => csfr4
+# d13 => csfr5
+# d14 => csfr6
+# d15 => scratch
 
 class Node
     def armSingle
@@ -76,7 +84,7 @@
 # only as last resort.
 ARM_EXTRA_GPRS = [SpecialRegister.new("r9"), SpecialRegister.new("r12"), SpecialRegister.new("r6")]
 ARM_EXTRA_FPRS = [SpecialRegister.new("d7")]
-ARM_SCRATCH_FPR = SpecialRegister.new("d6")
+ARM_SCRATCH_FPR = SpecialRegister.new("d15")
 OS_DARWIN = ((RUBY_PLATFORM =~ /darwin/i) != nil)
 
 def armMoveImmediate(value, register)
@@ -147,6 +155,24 @@
             "d4"
         when "ft5"
             "d5"
+        when "ft6"
+            "d6"
+        when "ft7"
+            "d7"
+        when "csfr0"
+            "d8"
+        when "csfr1"
+            "d9"
+        when "csfr2"
+            "d10"
+        when "csfr3"
+            "d11"
+        when "csfr4"
+            "d12"
+        when "csfr5"
+            "d13"
+        when "csfr6"
+            "d14"
         else
             raise "Bad register #{name} for ARM at #{codeOriginString}"
         end

Modified: trunk/Source/_javascript_Core/wasm/js/JSToWasm.cpp (294793 => 294794)


--- trunk/Source/_javascript_Core/wasm/js/JSToWasm.cpp	2022-05-25 10:41:30 UTC (rev 294793)
+++ trunk/Source/_javascript_Core/wasm/js/JSToWasm.cpp	2022-05-25 13:32:59 UTC (rev 294794)
@@ -197,11 +197,11 @@
     RegisterAtOffsetList registersToSpill(toSave, RegisterAtOffsetList::OffsetBaseType::FramePointerBased);
     result->entrypoint.calleeSaveRegisters = registersToSpill;
 
-    size_t totalFrameSize = registersToSpill.size() * sizeof(CPURegister);
+    size_t totalFrameSize = registersToSpill.sizeOfAreaInBytes();
     CallInformation wasmFrameConvention = wasmCallingConvention().callInformationFor(typeDefinition);
     RegisterAtOffsetList savedResultRegisters = wasmFrameConvention.computeResultsOffsetList();
     totalFrameSize += wasmFrameConvention.headerAndArgumentStackSizeInBytes;
-    totalFrameSize += savedResultRegisters.size() * sizeof(CPURegister);
+    totalFrameSize += savedResultRegisters.sizeOfAreaInBytes();
 
     totalFrameSize = WTF::roundUpToMultipleOf(stackAlignmentBytes(), totalFrameSize);
     jit.subPtr(MacroAssembler::TrustedImm32(totalFrameSize), MacroAssembler::stackPointerRegister);

Modified: trunk/Source/_javascript_Core/wasm/js/WasmToJS.cpp (294793 => 294794)


--- trunk/Source/_javascript_Core/wasm/js/WasmToJS.cpp	2022-05-25 10:41:30 UTC (rev 294793)
+++ trunk/Source/_javascript_Core/wasm/js/WasmToJS.cpp	2022-05-25 13:32:59 UTC (rev 294794)
@@ -88,7 +88,7 @@
     const unsigned numberOfParameters = argCount + 1; // There is a "this" argument.
     const unsigned numberOfRegsForCall = CallFrame::headerSizeInRegisters + numberOfParameters;
     const unsigned numberOfBytesForCall = numberOfRegsForCall * sizeof(Register) - sizeof(CallerFrameAndPC);
-    const unsigned stackOffset = WTF::roundUpToMultipleOf(stackAlignmentBytes(), std::max<unsigned>(numberOfBytesForCall, savedResultRegisters.size() * sizeof(CPURegister)));
+    const unsigned stackOffset = WTF::roundUpToMultipleOf(stackAlignmentBytes(), std::max<unsigned>(numberOfBytesForCall, savedResultRegisters.sizeOfAreaInBytes()));
     jit.subPtr(MacroAssembler::TrustedImm32(stackOffset), MacroAssembler::stackPointerRegister);
     JIT::Address calleeFrame = CCallHelpers::Address(MacroAssembler::stackPointerRegister, -static_cast<ptrdiff_t>(sizeof(CallerFrameAndPC)));
 

Modified: trunk/Source/_javascript_Core/wasm/js/WebAssemblyFunction.cpp (294793 => 294794)


--- trunk/Source/_javascript_Core/wasm/js/WebAssemblyFunction.cpp	2022-05-25 10:41:30 UTC (rev 294793)
+++ trunk/Source/_javascript_Core/wasm/js/WebAssemblyFunction.cpp	2022-05-25 13:32:59 UTC (rev 294794)
@@ -193,10 +193,10 @@
     Wasm::CallInformation jsCallInfo = Wasm::jsCallingConvention().callInformationFor(typeDefinition, Wasm::CallRole::Callee);
     RegisterAtOffsetList savedResultRegisters = wasmCallInfo.computeResultsOffsetList();
 
-    unsigned totalFrameSize = registersToSpill.size() * sizeof(CPURegister);
+    unsigned totalFrameSize = registersToSpill.sizeOfAreaInBytes();
     totalFrameSize += sizeof(CPURegister); // Slot for the VM's previous wasm instance.
     totalFrameSize += wasmCallInfo.headerAndArgumentStackSizeInBytes;
-    totalFrameSize += savedResultRegisters.size() * sizeof(CPURegister);
+    totalFrameSize += savedResultRegisters.sizeOfAreaInBytes();
 
     // FIXME: Optimize Wasm function call even if arguments include I64.
     // This requires I64 extraction from BigInt.
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to