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.