Diff
Modified: branches/jsc-tailcall/Source/_javascript_Core/ChangeLog (189279 => 189280)
--- branches/jsc-tailcall/Source/_javascript_Core/ChangeLog 2015-09-03 19:45:44 UTC (rev 189279)
+++ branches/jsc-tailcall/Source/_javascript_Core/ChangeLog 2015-09-03 19:56:35 UTC (rev 189280)
@@ -1,3 +1,44 @@
+2015-09-02 Michael Saboff <[email protected]>
+
+ jsc-tailcall: Need to handle all architected callee saves for ARM64
+ https://bugs.webkit.org/show_bug.cgi?id=148652
+
+ Reviewed by Basile Clement.
+
+ Enumerate and handle all 10 ARM64 general purpose and 8 floating point callee save registers.
+ Moved the callee saved registers used by LLInt to be the last three callee saves.
+ Eliminated GPRInfo::numberOfLLIntBaselineCalleeSaveRegisters and use the number of registers
+ defined in RegisterSet::llintCalleeSaveRegisters() instead.
+ Eliminated GPRInfo::nonArgGPR1 for all architectures except ARM as it was a callee save for
+ other architectures.
+ Found and fixed an issue where we trash callee save 0 (csr0) in the nativeCallTrampoline() macro.
+
+ * bytecode/CodeBlock.cpp:
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::numberOfLLIntBaselineCalleeSaveRegisters):
+ * ftl/FTLOSRExitCompiler.cpp:
+ (JSC::FTL::compileStub):
+ * ftl/FTLThunks.cpp:
+ (JSC::FTL::osrExitGenerationThunkGenerator):
+ * jit/AssemblyHelpers.h:
+ * jit/FPRInfo.h:
+ * jit/GPRInfo.h:
+ * jit/RegisterAtOffsetList.cpp:
+ (JSC::RegisterAtOffsetList::RegisterAtOffsetList):
+ * jit/RegisterSet.cpp:
+ (JSC::RegisterSet::llintCalleeSaveRegisters):
+ (JSC::RegisterSet::baselineCalleeSaveRegisters):
+ (JSC::RegisterSet::dfgCalleeSaveRegisters):
+ (JSC::RegisterSet::ftlCalleeSaveRegisters):
+ * jit/TempRegisterSet.h:
+ (JSC::TempRegisterSet::getFPRByIndex):
+ (JSC::TempRegisterSet::getFreeFPR):
+ (JSC::TempRegisterSet::setByIndex):
+ * llint/LowLevelInterpreter.asm:
+ * llint/LowLevelInterpreter64.asm:
+ * offlineasm/arm64.rb:
+ * offlineasm/registers.rb:
+
2015-08-27 Michael Saboff <[email protected]>
jsc-tailcall: ARM64 crashes running most any test
Modified: branches/jsc-tailcall/Source/_javascript_Core/bytecode/CodeBlock.cpp (189279 => 189280)
--- branches/jsc-tailcall/Source/_javascript_Core/bytecode/CodeBlock.cpp 2015-09-03 19:45:44 UTC (rev 189279)
+++ branches/jsc-tailcall/Source/_javascript_Core/bytecode/CodeBlock.cpp 2015-09-03 19:56:35 UTC (rev 189280)
@@ -55,6 +55,7 @@
#include "PolymorphicPutByIdList.h"
#include "ProfilerDatabase.h"
#include "ReduceWhitespace.h"
+#include "RegisterSet.h"
#include "Repatch.h"
#include "RepatchBuffer.h"
#include "SlotVisitorInlines.h"
Modified: branches/jsc-tailcall/Source/_javascript_Core/bytecode/CodeBlock.h (189279 => 189280)
--- branches/jsc-tailcall/Source/_javascript_Core/bytecode/CodeBlock.h 2015-09-03 19:45:44 UTC (rev 189279)
+++ branches/jsc-tailcall/Source/_javascript_Core/bytecode/CodeBlock.h 2015-09-03 19:56:35 UTC (rev 189280)
@@ -733,7 +733,7 @@
JS_EXPORT_PRIVATE unsigned reoptimizationRetryCounter() const;
void countReoptimization();
#if ENABLE(JIT)
- static unsigned numberOfLLIntBaselineCalleeSaveRegisters() { return GPRInfo::numberOfLLIntBaselineCalleeSaveRegisters; }
+ static unsigned numberOfLLIntBaselineCalleeSaveRegisters() { return RegisterSet::llintCalleeSaveRegisters().numberOfSetRegisters(); }
static size_t llintBaselineCalleeSaveSpaceAsVirtualRegisters();
size_t calleeSaveSpaceAsVirtualRegisters();
Modified: branches/jsc-tailcall/Source/_javascript_Core/ftl/FTLOSRExitCompiler.cpp (189279 => 189280)
--- branches/jsc-tailcall/Source/_javascript_Core/ftl/FTLOSRExitCompiler.cpp 2015-09-03 19:45:44 UTC (rev 189279)
+++ branches/jsc-tailcall/Source/_javascript_Core/ftl/FTLOSRExitCompiler.cpp 2015-09-03 19:56:35 UTC (rev 189280)
@@ -440,25 +440,38 @@
unsigned unwindIndex = codeBlock->calleeSaveRegisters()->indexOf(reg);
RegisterAtOffset* baselineRegisterOffset = baselineCalleeSaves->find(reg);
- GPRReg regToLoad = baselineRegisterOffset ? GPRInfo::regT0 : reg.gpr();
+ if (reg.isGPR()) {
+ GPRReg regToLoad = baselineRegisterOffset ? GPRInfo::regT0 : reg.gpr();
- if (unwindIndex == UINT_MAX) {
- // The FTL compilation didn't preserve this register. This means that it also
- // didn't use the register. So its value at the beginning of OSR exit should be
- // preserved by the thunk. Luckily, we saved all registers into the register
- // scratch buffer, so we can restore them from there.
- jit.load64(registerScratch + offsetOfReg(reg), regToLoad);
+ if (unwindIndex == UINT_MAX) {
+ // The FTL compilation didn't preserve this register. This means that it also
+ // didn't use the register. So its value at the beginning of OSR exit should be
+ // preserved by the thunk. Luckily, we saved all registers into the register
+ // scratch buffer, so we can restore them from there.
+ jit.load64(registerScratch + offsetOfReg(reg), regToLoad);
+ } else {
+ // The FTL compilation preserved the register. Its new value is therefore
+ // irrelevant, but we can get the value that was preserved by using the unwind
+ // data. We've already copied all unwind-able preserved registers into the unwind
+ // scratch buffer, so we can get it from there.
+ jit.load64(unwindScratch + unwindIndex, regToLoad);
+ }
+
+ if (baselineRegisterOffset)
+ jit.store64(regToLoad, MacroAssembler::Address(MacroAssembler::framePointerRegister, baselineRegisterOffset->offset()));
} else {
- // The FTL compilation preserved the register. Its new value is therefore
- // irrelevant, but we can get the value that was preserved by using the unwind
- // data. We've already copied all unwind-able preserved registers into the unwind
- // scratch buffer, so we can get it from there.
- jit.load64(unwindScratch + unwindIndex, regToLoad);
+ FPRReg fpRegToLoad = baselineRegisterOffset ? FPRInfo::fpRegT0 : reg.fpr();
+
+ if (unwindIndex == UINT_MAX)
+ jit.loadDouble(MacroAssembler::TrustedImmPtr(registerScratch + offsetOfReg(reg)), fpRegToLoad);
+ else
+ jit.loadDouble(MacroAssembler::TrustedImmPtr(unwindScratch + unwindIndex), fpRegToLoad);
+
+ if (baselineRegisterOffset)
+ jit.storeDouble(fpRegToLoad, MacroAssembler::Address(MacroAssembler::framePointerRegister, baselineRegisterOffset->offset()));
}
+ }
- if (baselineRegisterOffset)
- jit.store64(regToLoad, MacroAssembler::Address(MacroAssembler::framePointerRegister, baselineRegisterOffset->offset()));
- }
size_t baselineVirtualRegistersForCalleeSaves = baselineCodeBlock->calleeSaveSpaceAsVirtualRegisters();
// Now get state out of the scratch buffer and place it back into the stack. The values are
Modified: branches/jsc-tailcall/Source/_javascript_Core/ftl/FTLThunks.cpp (189279 => 189280)
--- branches/jsc-tailcall/Source/_javascript_Core/ftl/FTLThunks.cpp 2015-09-03 19:45:44 UTC (rev 189279)
+++ branches/jsc-tailcall/Source/_javascript_Core/ftl/FTLThunks.cpp 2015-09-03 19:56:35 UTC (rev 189280)
@@ -66,8 +66,8 @@
saveAllRegisters(jit, buffer);
// Tell GC mark phase how much of the scratch buffer is active during call.
- jit.move(MacroAssembler::TrustedImmPtr(scratchBuffer->activeLengthPtr()), GPRInfo::nonArgGPR1);
- jit.storePtr(MacroAssembler::TrustedImmPtr(requiredScratchMemorySizeInBytes()), GPRInfo::nonArgGPR1);
+ jit.move(MacroAssembler::TrustedImmPtr(scratchBuffer->activeLengthPtr()), GPRInfo::nonArgGPR0);
+ jit.storePtr(MacroAssembler::TrustedImmPtr(requiredScratchMemorySizeInBytes()), GPRInfo::nonArgGPR0);
jit.loadPtr(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
jit.peek(
Modified: branches/jsc-tailcall/Source/_javascript_Core/jit/AssemblyHelpers.h (189279 => 189280)
--- branches/jsc-tailcall/Source/_javascript_Core/jit/AssemblyHelpers.h 2015-09-03 19:45:44 UTC (rev 189279)
+++ branches/jsc-tailcall/Source/_javascript_Core/jit/AssemblyHelpers.h 2015-09-03 19:56:35 UTC (rev 189280)
@@ -232,7 +232,10 @@
RegisterAtOffset entry = allCalleeSaves->at(i);
if (dontCopyRegisters.get(entry.reg()))
continue;
- storePtr(entry.reg().gpr(), Address(temp1, entry.offset()));
+ if (entry.reg().isGPR())
+ storePtr(entry.reg().gpr(), Address(temp1, entry.offset()));
+ else
+ storeDouble(entry.reg().fpr(), Address(temp1, entry.offset()));
}
}
@@ -250,7 +253,10 @@
RegisterAtOffset entry = allCalleeSaves->at(i);
if (dontRestoreRegisters.get(entry.reg()))
continue;
- loadPtr(Address(temp1, entry.offset()), entry.reg().gpr());
+ if (entry.reg().isGPR())
+ loadPtr(Address(temp1, entry.offset()), entry.reg().gpr());
+ else
+ loadDouble(Address(temp1, entry.offset()), entry.reg().fpr());
}
}
@@ -258,6 +264,7 @@
{
GPRReg temp1 = usedRegisters.getFreeGPR(0);
GPRReg temp2 = usedRegisters.getFreeGPR(1);
+ FPRReg fpTemp = usedRegisters.getFreeFPR();
ASSERT(temp2 != InvalidGPRReg);
ASSERT(codeBlock());
@@ -269,24 +276,36 @@
RegisterAtOffsetList* currentCalleeSaves = codeBlock()->calleeSaveRegisters();
RegisterSet dontCopyRegisters = RegisterSet::stackRegisters();
unsigned registerCount = allCalleeSaves->size();
-
+
for (unsigned i = 0; i < registerCount; i++) {
- GPRReg regToStore;
-
RegisterAtOffset vmEntry = allCalleeSaves->at(i);
if (dontCopyRegisters.get(vmEntry.reg()))
continue;
RegisterAtOffset* currentFrameEntry = currentCalleeSaves->find(vmEntry.reg());
-
- if (currentFrameEntry) {
- // Load calleeSave from stack into temp register
- regToStore = temp2;
- loadPtr(Address(framePointerRegister, currentFrameEntry->offset()), regToStore);
- } else
- // Just store callee save directly
- regToStore = vmEntry.reg().gpr();
-
- storePtr(regToStore, Address(temp1, vmEntry.offset()));
+
+ if (vmEntry.reg().isGPR()) {
+ GPRReg regToStore;
+ if (currentFrameEntry) {
+ // Load calleeSave from stack into temp register
+ regToStore = temp2;
+ loadPtr(Address(framePointerRegister, currentFrameEntry->offset()), regToStore);
+ } else
+ // Just store callee save directly
+ regToStore = vmEntry.reg().gpr();
+
+ storePtr(regToStore, Address(temp1, vmEntry.offset()));
+ } else {
+ FPRReg fpRegToStore;
+ if (currentFrameEntry) {
+ // Load calleeSave from stack into temp register
+ fpRegToStore = fpTemp;
+ loadDouble(Address(framePointerRegister, currentFrameEntry->offset()), fpRegToStore);
+ } else
+ // Just store callee save directly
+ fpRegToStore = vmEntry.reg().fpr();
+
+ storeDouble(fpRegToStore, Address(temp1, vmEntry.offset()));
+ }
}
}
Modified: branches/jsc-tailcall/Source/_javascript_Core/jit/FPRInfo.h (189279 => 189280)
--- branches/jsc-tailcall/Source/_javascript_Core/jit/FPRInfo.h 2015-09-03 19:45:44 UTC (rev 189279)
+++ branches/jsc-tailcall/Source/_javascript_Core/jit/FPRInfo.h 2015-09-03 19:56:35 UTC (rev 189280)
@@ -208,6 +208,14 @@
static const FPRReg fpRegT20 = ARM64Registers::q28;
static const FPRReg fpRegT21 = ARM64Registers::q29;
static const FPRReg fpRegT22 = ARM64Registers::q30;
+ static const FPRReg fpRegCS0 = ARM64Registers::q8;
+ static const FPRReg fpRegCS1 = ARM64Registers::q9;
+ static const FPRReg fpRegCS2 = ARM64Registers::q10;
+ static const FPRReg fpRegCS3 = ARM64Registers::q11;
+ static const FPRReg fpRegCS4 = ARM64Registers::q12;
+ static const FPRReg fpRegCS5 = ARM64Registers::q13;
+ static const FPRReg fpRegCS6 = ARM64Registers::q14;
+ static const FPRReg fpRegCS7 = ARM64Registers::q15;
static const FPRReg argumentFPR0 = ARM64Registers::q0; // fpRegT0
static const FPRReg argumentFPR1 = ARM64Registers::q1; // fpRegT1
Modified: branches/jsc-tailcall/Source/_javascript_Core/jit/GPRInfo.h (189279 => 189280)
--- branches/jsc-tailcall/Source/_javascript_Core/jit/GPRInfo.h 2015-09-03 19:45:44 UTC (rev 189279)
+++ branches/jsc-tailcall/Source/_javascript_Core/jit/GPRInfo.h 2015-09-03 19:56:35 UTC (rev 189280)
@@ -336,7 +336,6 @@
static const GPRReg argumentGPR2 = X86Registers::eax; // regT0
static const GPRReg argumentGPR3 = X86Registers::ebx; // regT3
static const GPRReg nonArgGPR0 = X86Registers::esi; // regT4
- static const GPRReg nonArgGPR1 = X86Registers::edi; // regT5
static const GPRReg returnValueGPR = X86Registers::eax; // regT0
static const GPRReg returnValueGPR2 = X86Registers::edx; // regT1
static const GPRReg nonPreservedNonReturnGPR = X86Registers::ecx;
@@ -447,17 +446,15 @@
static const GPRReg argumentGPR3 = X86Registers::r9; // regT3
#endif
static const GPRReg nonArgGPR0 = X86Registers::r10; // regT5 (regT4 on Windows)
- static const GPRReg nonArgGPR1 = X86Registers::ebx; // Callee save
static const GPRReg returnValueGPR = X86Registers::eax; // regT0
static const GPRReg returnValueGPR2 = X86Registers::edx; // regT1 or regT2
static const GPRReg nonPreservedNonReturnGPR = X86Registers::r10; // regT5 (regT4 on Windows)
static const GPRReg nonPreservedNonArgumentGPR = X86Registers::r10; // regT5 (regT4 on Windows)
static const GPRReg patchpointScratchRegister = MacroAssembler::scratchRegister;
+ static const int numberOfLLIntBaselineCalleeSaveRegisters = 3; // r13 (LLInt only), r14 & r15
#if !OS(WINDOWS)
- static const int numberOfLLIntBaselineCalleeSaveRegisters = 3; // rbx, r14 & r15
static const int numberCalleeSaveRegisters = 5;
#else
- static const int numberOfLLIntBaselineCalleeSaveRegisters = 3; // rbx, r14 & r15
static const int numberCalleeSaveRegisters = 7;
#endif
@@ -545,7 +542,6 @@
static const GPRReg argumentGPR3 = ARMRegisters::r3; // regT3
static const GPRReg nonArgGPR0 = ARMRegisters::r4; // regT8
static const GPRReg nonArgGPR1 = ARMRegisters::r8; // regT4
- static const GPRReg nonArgGPR2 = ARMRegisters::r9; // regT5
static const GPRReg returnValueGPR = ARMRegisters::r0; // regT0
static const GPRReg returnValueGPR2 = ARMRegisters::r1; // regT1
static const GPRReg nonPreservedNonReturnGPR = ARMRegisters::r5;
@@ -628,9 +624,16 @@
static const GPRReg regT13 = ARM64Registers::x13;
static const GPRReg regT14 = ARM64Registers::x14;
static const GPRReg regT15 = ARM64Registers::x15;
- static const GPRReg regCS0 = ARM64Registers::x26; // Used by LLInt only
- static const GPRReg regCS1 = ARM64Registers::x27; // tagTypeNumber
- static const GPRReg regCS2 = ARM64Registers::x28; // tagMask
+ static const GPRReg regCS0 = ARM64Registers::x19; // Used by FTL only
+ static const GPRReg regCS1 = ARM64Registers::x20; // Used by FTL only
+ static const GPRReg regCS2 = ARM64Registers::x21; // Used by FTL only
+ static const GPRReg regCS3 = ARM64Registers::x22; // Used by FTL only
+ static const GPRReg regCS4 = ARM64Registers::x23; // Used by FTL only
+ static const GPRReg regCS5 = ARM64Registers::x24; // Used by FTL only
+ static const GPRReg regCS6 = ARM64Registers::x25; // Used by FTL only
+ static const GPRReg regCS7 = ARM64Registers::x26;
+ static const GPRReg regCS8 = ARM64Registers::x27; // tagTypeNumber
+ static const GPRReg regCS9 = ARM64Registers::x28; // tagMask
// These constants provide the names for the general purpose argument & return value registers.
static const GPRReg argumentGPR0 = ARM64Registers::x0; // regT0
static const GPRReg argumentGPR1 = ARM64Registers::x1; // regT1
@@ -641,16 +644,15 @@
static const GPRReg argumentGPR6 = ARM64Registers::x6; // regT6
static const GPRReg argumentGPR7 = ARM64Registers::x7; // regT7
static const GPRReg nonArgGPR0 = ARM64Registers::x8; // regT8
- static const GPRReg nonArgGPR1 = ARM64Registers::x9; // regT9
static const GPRReg returnValueGPR = ARM64Registers::x0; // regT0
static const GPRReg returnValueGPR2 = ARM64Registers::x1; // regT1
static const GPRReg nonPreservedNonReturnGPR = ARM64Registers::x2;
static const GPRReg nonPreservedNonArgumentGPR = ARM64Registers::x8;
static const GPRReg patchpointScratchRegister = ARM64Registers::ip0;
static const int numberOfLLIntBaselineCalleeSaveRegisters = 3; // x26 (LLInt only), x27 & x28
- static const int numberCalleeSaveRegisters = 10;
+ static const int numberCalleeSaveRegisters = 18; // x19..x28 and q8..q15
- // GPRReg mapping is direct, the machine regsiter numbers can
+ // GPRReg mapping is direct, the machine register numbers can
// be used directly as indices into the GPR RegisterBank.
COMPILE_ASSERT(ARM64Registers::q0 == 0, q0_is_0);
COMPILE_ASSERT(ARM64Registers::q1 == 1, q1_is_1);
@@ -732,7 +734,6 @@
static const GPRReg argumentGPR2 = MIPSRegisters::a2;
static const GPRReg argumentGPR3 = MIPSRegisters::a3;
static const GPRReg nonArgGPR0 = regT0;
- static const GPRReg nonArgGPR1 = regT1;
static const GPRReg returnValueGPR = regT0;
static const GPRReg returnValueGPR2 = regT1;
static const GPRReg nonPreservedNonReturnGPR = regT2;
@@ -808,7 +809,6 @@
static const GPRReg argumentGPR2 = SH4Registers::r6; // regT2
static const GPRReg argumentGPR3 = SH4Registers::r7; // regT3
static const GPRReg nonArgGPR0 = regT4;
- static const GPRReg nonArgGPR1 = regT5;
static const GPRReg returnValueGPR = regT0;
static const GPRReg returnValueGPR2 = regT1;
static const GPRReg nonPreservedNonReturnGPR = regT2;
Modified: branches/jsc-tailcall/Source/_javascript_Core/jit/RegisterAtOffsetList.cpp (189279 => 189280)
--- branches/jsc-tailcall/Source/_javascript_Core/jit/RegisterAtOffsetList.cpp 2015-09-03 19:45:44 UTC (rev 189279)
+++ branches/jsc-tailcall/Source/_javascript_Core/jit/RegisterAtOffsetList.cpp 2015-09-03 19:56:35 UTC (rev 189280)
@@ -36,14 +36,14 @@
RegisterAtOffsetList::RegisterAtOffsetList(RegisterSet registerSet, OffsetBaseType offsetBaseType)
{
- size_t numberOfRegisters = registerSet.numberOfSetGPRs();
+ size_t numberOfRegisters = registerSet.numberOfSetRegisters();
ptrdiff_t offset = 0;
if (offsetBaseType == FramePointerBased)
offset = -(static_cast<ptrdiff_t>(numberOfRegisters) * sizeof(void*));
for (Reg reg = Reg::first(); reg <= Reg::last();reg = reg.next()) {
- if (registerSet.get(reg) && reg.isGPR()) {
+ if (registerSet.get(reg)) {
append(RegisterAtOffset(reg, offset));
offset += sizeof(void*);
}
Modified: branches/jsc-tailcall/Source/_javascript_Core/jit/RegisterSet.cpp (189279 => 189280)
--- branches/jsc-tailcall/Source/_javascript_Core/jit/RegisterSet.cpp 2015-09-03 19:45:44 UTC (rev 189279)
+++ branches/jsc-tailcall/Source/_javascript_Core/jit/RegisterSet.cpp 2015-09-03 19:56:35 UTC (rev 189280)
@@ -132,13 +132,14 @@
RegisterSet result;
#if CPU(X86)
#elif CPU(X86_64)
- result.set(GPRInfo::regCS0);
#if !OS(WINDOWS)
+ result.set(GPRInfo::regCS2);
ASSERT(GPRInfo::regCS3 == GPRInfo::tagTypeNumberRegister);
ASSERT(GPRInfo::regCS4 == GPRInfo::tagMaskRegister);
result.set(GPRInfo::regCS3);
result.set(GPRInfo::regCS4);
#else
+ result.set(GPRInfo::regCS4);
ASSERT(GPRInfo::regCS5 == GPRInfo::tagTypeNumberRegister);
ASSERT(GPRInfo::regCS6 == GPRInfo::tagMaskRegister);
result.set(GPRInfo::regCS5);
@@ -147,11 +148,11 @@
#elif CPU(ARM_THUMB2)
#elif CPU(ARM_TRADITIONAL)
#elif CPU(ARM64)
- result.set(GPRInfo::regCS0);
- ASSERT(GPRInfo::regCS1 == GPRInfo::tagTypeNumberRegister);
- ASSERT(GPRInfo::regCS2 == GPRInfo::tagMaskRegister);
- result.set(GPRInfo::regCS1);
- result.set(GPRInfo::regCS2);
+ result.set(GPRInfo::regCS7);
+ ASSERT(GPRInfo::regCS8 == GPRInfo::tagTypeNumberRegister);
+ ASSERT(GPRInfo::regCS9 == GPRInfo::tagMaskRegister);
+ result.set(GPRInfo::regCS8);
+ result.set(GPRInfo::regCS9);
#elif CPU(MIPS)
#elif CPU(SH4)
#else
@@ -165,7 +166,6 @@
RegisterSet result;
#if CPU(X86)
#elif CPU(X86_64)
- result.set(GPRInfo::regCS0);
#if !OS(WINDOWS)
ASSERT(GPRInfo::regCS3 == GPRInfo::tagTypeNumberRegister);
ASSERT(GPRInfo::regCS4 == GPRInfo::tagMaskRegister);
@@ -180,10 +180,10 @@
#elif CPU(ARM_THUMB2)
#elif CPU(ARM_TRADITIONAL)
#elif CPU(ARM64)
- ASSERT(GPRInfo::regCS1 == GPRInfo::tagTypeNumberRegister);
- ASSERT(GPRInfo::regCS2 == GPRInfo::tagMaskRegister);
- result.set(GPRInfo::regCS1);
- result.set(GPRInfo::regCS2);
+ ASSERT(GPRInfo::regCS8 == GPRInfo::tagTypeNumberRegister);
+ ASSERT(GPRInfo::regCS9 == GPRInfo::tagMaskRegister);
+ result.set(GPRInfo::regCS8);
+ result.set(GPRInfo::regCS9);
#elif CPU(MIPS)
#elif CPU(SH4)
#else
@@ -216,10 +216,10 @@
#elif CPU(ARM_THUMB2)
#elif CPU(ARM_TRADITIONAL)
#elif CPU(ARM64)
- ASSERT(GPRInfo::regCS1 == GPRInfo::tagTypeNumberRegister);
- ASSERT(GPRInfo::regCS2 == GPRInfo::tagMaskRegister);
- result.set(GPRInfo::regCS1);
- result.set(GPRInfo::regCS2);
+ ASSERT(GPRInfo::regCS8 == GPRInfo::tagTypeNumberRegister);
+ ASSERT(GPRInfo::regCS9 == GPRInfo::tagMaskRegister);
+ result.set(GPRInfo::regCS8);
+ result.set(GPRInfo::regCS9);
#elif CPU(MIPS)
#elif CPU(SH4)
#else
@@ -242,18 +242,26 @@
result.set(GPRInfo::regCS4);
#elif CPU(ARM64)
// LLVM might save and use all ARM64 callee saves specified in the ABI.
- result.set(ARM64Registers::x19);
- result.set(ARM64Registers::x20);
- result.set(ARM64Registers::x21);
- result.set(ARM64Registers::x22);
- result.set(ARM64Registers::x23);
- result.set(ARM64Registers::x24);
- result.set(ARM64Registers::x25);
result.set(GPRInfo::regCS0);
- ASSERT(GPRInfo::regCS1 == GPRInfo::tagTypeNumberRegister);
- ASSERT(GPRInfo::regCS2 == GPRInfo::tagMaskRegister);
result.set(GPRInfo::regCS1);
result.set(GPRInfo::regCS2);
+ result.set(GPRInfo::regCS3);
+ result.set(GPRInfo::regCS4);
+ result.set(GPRInfo::regCS5);
+ result.set(GPRInfo::regCS6);
+ result.set(GPRInfo::regCS7);
+ ASSERT(GPRInfo::regCS8 == GPRInfo::tagTypeNumberRegister);
+ ASSERT(GPRInfo::regCS9 == GPRInfo::tagMaskRegister);
+ result.set(GPRInfo::regCS8);
+ result.set(GPRInfo::regCS9);
+ 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);
+ result.set(FPRInfo::fpRegCS7);
#else
UNREACHABLE_FOR_PLATFORM();
#endif
Modified: branches/jsc-tailcall/Source/_javascript_Core/jit/TempRegisterSet.h (189279 => 189280)
--- branches/jsc-tailcall/Source/_javascript_Core/jit/TempRegisterSet.h 2015-09-03 19:45:44 UTC (rev 189279)
+++ branches/jsc-tailcall/Source/_javascript_Core/jit/TempRegisterSet.h 2015-09-03 19:56:35 UTC (rev 189280)
@@ -115,6 +115,16 @@
return getBit(GPRInfo::numberOfRegisters + index);
}
+ // Return the index'th free FPR.
+ FPRReg getFreeFPR(unsigned index = 0) const
+ {
+ for (unsigned i = FPRInfo::numberOfRegisters; i--;) {
+ if (!getFPRByIndex(i) && !index--)
+ return FPRInfo::toRegister(i);
+ }
+ return InvalidFPRReg;
+ }
+
template<typename BankInfo>
void setByIndex(unsigned index)
{
Modified: branches/jsc-tailcall/Source/_javascript_Core/llint/LowLevelInterpreter.asm (189279 => 189280)
--- branches/jsc-tailcall/Source/_javascript_Core/llint/LowLevelInterpreter.asm 2015-09-03 19:45:44 UTC (rev 189279)
+++ branches/jsc-tailcall/Source/_javascript_Core/llint/LowLevelInterpreter.asm 2015-09-03 19:56:35 UTC (rev 189280)
@@ -107,10 +107,9 @@
# - t4 and t5 are never argument registers, t3 can only be a3, t1 can only be
# a1; but t0 and t2 can be either a0 or a2.
#
-# - On 64 bits, csr0, csr1, csr2 and optionally csr3, csr4, csr5 and csr6
-# are available as callee-save registers.
-# csr0 is used to store the PC base, while the last two csr registers are used
-# to store special tag values. Don't use them for anything else.
+# - On 64 bits, there are callee-save registers named csr0, csr1, ... csrN.
+# The last three csr registers are used used to store the PC base and
+# two special tag values. Don't use them for anything else.
#
# Additional platform-specific details (you shouldn't rely on this remaining
# true):
@@ -243,14 +242,16 @@
# - C calls are still given the Instruction* rather than the PC index.
# This requires an add before the call, and a sub after.
const PC = t4
- const PB = csr0
if ARM64
- const tagTypeNumber = csr1
- const tagMask = csr2
+ const PB = csr7
+ const tagTypeNumber = csr8
+ const tagMask = csr9
elsif X86_64
+ const PB = csr2
const tagTypeNumber = csr3
const tagMask = csr4
elsif X86_64_WIN
+ const PB = csr4
const tagTypeNumber = csr5
const tagMask = csr6
end
@@ -518,11 +519,11 @@
elsif X86_64
storep csr4, -8[cfr]
storep csr3, -16[cfr]
- storep csr0, -24[cfr]
+ storep csr2, -24[cfr]
elsif X86_64_WIN
storep csr6, -8[cfr]
storep csr5, -16[cfr]
- storep csr0, -24[cfr]
+ storep csr4, -24[cfr]
end
end
@@ -538,11 +539,11 @@
elsif X86
elsif X86_WIN
elsif X86_64
- loadp -24[cfr], csr0
+ loadp -24[cfr], csr2
loadp -16[cfr], csr3
loadp -8[cfr], csr4
elsif X86_64_WIN
- loadp -24[cfr], csr0
+ loadp -24[cfr], csr4
loadp -16[cfr], csr5
loadp -8[cfr], csr6
end
@@ -555,6 +556,21 @@
storep csr0, [temp]
storep csr1, 8[temp]
storep csr2, 16[temp]
+ storep csr3, 24[temp]
+ storep csr4, 32[temp]
+ storep csr5, 40[temp]
+ storep csr6, 48[temp]
+ storep csr7, 56[temp]
+ storep csr8, 64[temp]
+ storep csr9, 72[temp]
+ stored csfr0, 80[temp]
+ stored csfr1, 88[temp]
+ stored csfr2, 96[temp]
+ stored csfr3, 104[temp]
+ stored csfr4, 112[temp]
+ stored csfr5, 120[temp]
+ stored csfr6, 128[temp]
+ stored csfr7, 136[temp]
elsif X86_64
storep csr0, [temp]
storep csr1, 8[temp]
@@ -580,6 +596,21 @@
loadp [temp], csr0
loadp 8[temp], csr1
loadp 16[temp], csr2
+ loadp 24[temp], csr3
+ loadp 32[temp], csr4
+ loadp 40[temp], csr5
+ loadp 48[temp], csr6
+ loadp 56[temp], csr7
+ loadp 64[temp], csr8
+ loadp 72[temp], csr9
+ loadd 80[temp], csfr0
+ loadd 88[temp], csfr1
+ loadd 96[temp], csfr2
+ loadd 104[temp], csfr3
+ loadd 112[temp], csfr4
+ loadd 120[temp], csfr5
+ loadd 128[temp], csfr6
+ loadd 136[temp], csfr7
elsif X86_64
loadp [temp], csr0
loadp 8[temp], csr1
@@ -609,17 +640,6 @@
end
end
-macro restoreReturnAddressBeforeReturn(sourceRegister)
- if C_LOOP or ARM or ARMv7 or ARMv7_TRADITIONAL or ARM64 or MIPS or SH4
- # In C_LOOP case, we're only restoring the bytecode vPC.
- move sourceRegister, lr
- elsif X86 or X86_WIN or X86_64 or X86_64_WIN
- push sourceRegister
- else
- error
- end
-end
-
macro functionPrologue()
if X86 or X86_WIN or X86_64 or X86_64_WIN
push cfr
Modified: branches/jsc-tailcall/Source/_javascript_Core/llint/LowLevelInterpreter64.asm (189279 => 189280)
--- branches/jsc-tailcall/Source/_javascript_Core/llint/LowLevelInterpreter64.asm 2015-09-03 19:45:44 UTC (rev 189279)
+++ branches/jsc-tailcall/Source/_javascript_Core/llint/LowLevelInterpreter64.asm 2015-09-03 19:56:35 UTC (rev 189280)
@@ -1835,7 +1835,6 @@
loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t1], t1
storep cfr, VM::topCallFrame[t1]
if ARM64 or C_LOOP
- move lr, csr0
storep lr, ReturnPC[cfr]
end
move cfr, a0
@@ -1853,9 +1852,6 @@
addp 32, sp
end
end
- if ARM64 or C_LOOP
- move csr0, lr
- end
loadp Callee[cfr], t3
andp MarkedBlockMask, t3
loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
Modified: branches/jsc-tailcall/Source/_javascript_Core/offlineasm/arm64.rb (189279 => 189280)
--- branches/jsc-tailcall/Source/_javascript_Core/offlineasm/arm64.rb 2015-09-03 19:45:44 UTC (rev 189279)
+++ branches/jsc-tailcall/Source/_javascript_Core/offlineasm/arm64.rb 2015-09-03 19:56:35 UTC (rev 189280)
@@ -61,6 +61,14 @@
# q3 => ft3, fa3
# q4 => ft4 (unused in baseline)
# q5 => ft5 (unused in baseline)
+# q8 => csfr0 (Only the lower 64 bits)
+# q9 => csfr1 (Only the lower 64 bits)
+# q10 => csfr2 (Only the lower 64 bits)
+# q11 => csfr3 (Only the lower 64 bits)
+# q12 => csfr4 (Only the lower 64 bits)
+# q13 => csfr5 (Only the lower 64 bits)
+# q14 => csfr6 (Only the lower 64 bits)
+# q15 => csfr7 (Only the lower 64 bits)
# q31 => scratch
def arm64GPRName(name, kind)
@@ -116,10 +124,24 @@
when 'cfr'
arm64GPRName('x29', kind)
when 'csr0'
+ arm64GPRName('x19', kind)
+ when 'csr1'
+ arm64GPRName('x20', kind)
+ when 'csr2'
+ arm64GPRName('x21', kind)
+ when 'csr3'
+ arm64GPRName('x22', kind)
+ when 'csr4'
+ arm64GPRName('x23', kind)
+ when 'csr5'
+ arm64GPRName('x24', kind)
+ when 'csr6'
+ arm64GPRName('x25', kind)
+ when 'csr7'
arm64GPRName('x26', kind)
- when 'csr1'
+ when 'csr8'
arm64GPRName('x27', kind)
- when 'csr2'
+ when 'csr9'
arm64GPRName('x28', kind)
when 'sp'
'sp'
@@ -146,6 +168,22 @@
arm64FPRName('q4', kind)
when 'ft5'
arm64FPRName('q5', kind)
+ when 'csfr0'
+ arm64FPRName('q8', kind)
+ when 'csfr1'
+ arm64FPRName('q9', kind)
+ when 'csfr2'
+ arm64FPRName('q10', kind)
+ when 'csfr3'
+ arm64FPRName('q11', kind)
+ when 'csfr4'
+ arm64FPRName('q12', kind)
+ when 'csfr5'
+ arm64FPRName('q13', kind)
+ when 'csfr6'
+ arm64FPRName('q14', kind)
+ when 'csfr7'
+ arm64FPRName('q15', kind)
else "Bad register name #{@name} at #{codeOriginString}"
end
end
Modified: branches/jsc-tailcall/Source/_javascript_Core/offlineasm/registers.rb (189279 => 189280)
--- branches/jsc-tailcall/Source/_javascript_Core/offlineasm/registers.rb 2015-09-03 19:45:44 UTC (rev 189279)
+++ branches/jsc-tailcall/Source/_javascript_Core/offlineasm/registers.rb 2015-09-03 19:56:35 UTC (rev 189280)
@@ -48,7 +48,10 @@
"csr3",
"csr4",
"csr5",
- "csr6"
+ "csr6",
+ "csr7",
+ "csr8",
+ "csr9"
]
FPRS =
@@ -63,6 +66,14 @@
"fa1",
"fa2",
"fa3",
+ "csfr0",
+ "csfr1",
+ "csfr2",
+ "csfr3",
+ "csfr4",
+ "csfr5",
+ "csfr6",
+ "csfr7",
"fr"
]