Skip to content
Permalink
Browse files
[JSC][ARMv7] Support callee save FPRs
Patch by Geza Lore <glore@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
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@294794 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
gezalore authored and webkit-commit-queue committed May 25, 2022
1 parent 651fcae commit 60a5bb34ca68a176d03301ba5956f64569ced3c9
Showing 24 changed files with 250 additions and 137 deletions.
@@ -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) \
@@ -41,11 +41,14 @@ class MacroAssemblerARMv7 : public AbstractMacroAssembler<Assembler> {
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
@@ -229,14 +229,8 @@ void Code::setCalleeSaveRegisterAtOffsetList(RegisterAtOffsetList&& registerAtOf
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 @@ void Code::dump(PrintStream& out) const
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");
}

@@ -1557,7 +1557,7 @@ void testInfiniteLoopDoesntCauseBadHoisting()

// 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.
}

@@ -2462,21 +2462,14 @@ unsigned CodeBlock::reoptimizationRetryCounter() const
}

#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

@@ -192,7 +192,7 @@ class ValueRecovery {
}

#if USE(JSVALUE32_64)
static ValueRecovery calleeSaveRegDisplacedInJSStack(VirtualRegister virtualReg, bool inTag)
static ValueRecovery calleeSaveGPRDisplacedInJSStack(VirtualRegister virtualReg, bool inTag)
{
ValueRecovery result;
UnionType u;
@@ -299,7 +299,7 @@ void* prepareOSREntry(VM& vm, CallFrame* callFrame, CodeBlock* codeBlock, Byteco
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);
@@ -231,7 +231,7 @@ static MacroAssemblerCodePtr<JSEntryPtrTag> callerReturnPC(CodeBlock* baselineCo
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;
@@ -182,7 +182,7 @@ static void compileStub(VM& vm, unsigned exitID, JITCode* jitCode, OSRExit& exit
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 @@ static void compileStub(VM& vm, unsigned exitID, JITCode* jitCode, OSRExit& exit
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));
@@ -625,7 +625,7 @@ class UnwindFunctor {
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);
@@ -633,7 +633,7 @@ void AssemblyHelpers::restoreCalleeSavesFromEntryFrameCalleeSavesBuffer(EntryFra
#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 @@ void AssemblyHelpers::restoreCalleeSavesFromVMEntryFrameCalleeSavesBufferImpl(GP
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 @@ void AssemblyHelpers::copyCalleeSavesToEntryFrameCalleeSavesBufferImpl(GPRReg ca

RegisterAtOffsetList* allCalleeSaves = RegisterSet::vmCalleeSaveRegisterOffsets();
RegisterSet dontCopyRegisters = RegisterSet::stackRegisters();
unsigned registerCount = allCalleeSaves->size();
unsigned registerCount = allCalleeSaves->registerCount();

StoreRegSpooler spooler(*this, calleeSavesBuffer);

@@ -1219,17 +1219,17 @@ void AssemblyHelpers::emitSave(const RegisterAtOffsetList& list)
{
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;
spooler.storeGPR(entry);
}
spooler.finalizeGPR();

for (; i < listSize; i++)
for (; i < registerCount; i++)
spooler.storeFPR(list.at(i));
spooler.finalizeFPR();
}
@@ -1238,25 +1238,25 @@ void AssemblyHelpers::emitRestore(const RegisterAtOffsetList& list)
{
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;
spooler.loadGPR(entry);
}
spooler.finalizeGPR();

for (; i < listSize; i++)
for (; i < registerCount; i++)
spooler.loadFPR(list.at(i));
spooler.finalizeFPR();
}

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::emitSaveCalleeSavesFor(const RegisterAtOffsetList* calleeS
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 @@ void AssemblyHelpers::copyLLIntBaselineCalleeSavesFromFrameOrRegisterToEntryFram
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 @@ void AssemblyHelpers::emitSaveOrCopyLLIntBaselineCalleeSavesFor(CodeBlock* codeB

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);
@@ -39,7 +39,7 @@ void CallFrameShuffleData::setupCalleeSaveRegisters(const RegisterAtOffsetList*
{
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 @@ void CallFrameShuffleData::setupCalleeSaveRegisters(const RegisterAtOffsetList*
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 @@ void CallFrameShuffleData::setupCalleeSaveRegisters(const RegisterAtOffsetList*
#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
}
}
@@ -119,11 +119,11 @@ class CallFrameShuffler {
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

0 comments on commit 60a5bb3

Please sign in to comment.