aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@digia.com>2014-08-12 16:28:49 +0200
committerErik Verbruggen <erik.verbruggen@digia.com>2014-08-14 15:27:59 +0200
commit8e47157252b41c537bb1e05c621d16654c2639fd (patch)
tree81ec3733176bff10bb0085bfa281fbdb634e173f /src
parenta503efe0df31742bac7d5af6ed4a53ee79a4c2a7 (diff)
V4 JIT: support saving used callee saved FP registers.
This is not used yet by any platform/abi we support, because we do not define any callee-saved FP registers. Yet. Change-Id: I5857a452456175398c5e9681ff33800b9431b9da Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/qml/jit/qv4assembler.cpp37
-rw-r--r--src/qml/jit/qv4assembler_p.h17
-rw-r--r--src/qml/jit/qv4isel_masm.cpp12
-rw-r--r--src/qml/jit/qv4isel_masm_p.h1
4 files changed, 46 insertions, 21 deletions
diff --git a/src/qml/jit/qv4assembler.cpp b/src/qml/jit/qv4assembler.cpp
index e76d498409..130a673484 100644
--- a/src/qml/jit/qv4assembler.cpp
+++ b/src/qml/jit/qv4assembler.cpp
@@ -239,37 +239,50 @@ void Assembler::storeValue(QV4::Primitive value, IR::Expr *destination)
storeValue(value, addr);
}
-void Assembler::enterStandardStackFrame(const RegisterInformation &regularRegistersToSave)
+void Assembler::enterStandardStackFrame(const RegisterInformation &regularRegistersToSave,
+ const RegisterInformation &fpRegistersToSave)
{
platformEnterStandardStackFrame(this);
- // ### FIXME: Handle through calleeSavedRegisters mechanism
- // or eliminate StackFrameRegister altogether.
push(StackFrameRegister);
move(StackPointerRegister, StackFrameRegister);
- int frameSize = _stackLayout->calculateStackFrameSize();
-
+ const int frameSize = _stackLayout->calculateStackFrameSize();
subPtr(TrustedImm32(frameSize), StackPointerRegister);
- Address slotAddr(StackFrameRegister, -RegisterSize);
+ Address slotAddr(StackFrameRegister, 0);
for (int i = 0, ei = regularRegistersToSave.size(); i < ei; ++i) {
- storePtr(regularRegistersToSave.at(i).reg<RegisterID>(), slotAddr);
+ Q_ASSERT(regularRegistersToSave.at(i).isRegularRegister());
slotAddr.offset -= RegisterSize;
+ storePtr(regularRegistersToSave.at(i).reg<RegisterID>(), slotAddr);
+ }
+ for (int i = 0, ei = fpRegistersToSave.size(); i < ei; ++i) {
+ Q_ASSERT(fpRegistersToSave.at(i).isFloatingPoint());
+ slotAddr.offset -= sizeof(double);
+ JSC::MacroAssembler::storeDouble(fpRegistersToSave.at(i).reg<FPRegisterID>(), slotAddr);
}
}
-void Assembler::leaveStandardStackFrame(const RegisterInformation &regularRegistersToSave)
+void Assembler::leaveStandardStackFrame(const RegisterInformation &regularRegistersToSave,
+ const RegisterInformation &fpRegistersToSave)
{
- Address slotAddr(StackFrameRegister, -regularRegistersToSave.size() * RegisterSize);
+ Address slotAddr(StackFrameRegister, -regularRegistersToSave.size() * RegisterSize - fpRegistersToSave.size() * sizeof(double));
// restore the callee saved registers
+ for (int i = fpRegistersToSave.size() - 1; i >= 0; --i) {
+ Q_ASSERT(fpRegistersToSave.at(i).isFloatingPoint());
+ JSC::MacroAssembler::loadDouble(slotAddr, fpRegistersToSave.at(i).reg<FPRegisterID>());
+ slotAddr.offset += sizeof(double);
+ }
for (int i = regularRegistersToSave.size() - 1; i >= 0; --i) {
+ Q_ASSERT(regularRegistersToSave.at(i).isRegularRegister());
loadPtr(slotAddr, regularRegistersToSave.at(i).reg<RegisterID>());
slotAddr.offset += RegisterSize;
}
- int frameSize = _stackLayout->calculateStackFrameSize();
+ Q_ASSERT(slotAddr.offset == 0);
+
+ const int frameSize = _stackLayout->calculateStackFrameSize();
// Work around bug in ARMv7Assembler.h where add32(imm, sp, sp) doesn't
// work well for large immediates.
#if CPU(ARM_THUMB2)
@@ -390,9 +403,9 @@ Assembler::Jump Assembler::branchInt32(bool invertCondition, IR::AluOp op, IR::E
toInt32Register(right, Assembler::ReturnValueRegister));
}
-void Assembler::setStackLayout(int maxArgCountForBuiltins, int regularRegistersToSave)
+void Assembler::setStackLayout(int maxArgCountForBuiltins, int regularRegistersToSave, int fpRegistersToSave)
{
- _stackLayout.reset(new StackLayout(_function, maxArgCountForBuiltins, regularRegistersToSave));
+ _stackLayout.reset(new StackLayout(_function, maxArgCountForBuiltins, regularRegistersToSave, fpRegistersToSave));
}
#endif
diff --git a/src/qml/jit/qv4assembler_p.h b/src/qml/jit/qv4assembler_p.h
index 7d774f93f7..8f50610072 100644
--- a/src/qml/jit/qv4assembler_p.h
+++ b/src/qml/jit/qv4assembler_p.h
@@ -182,8 +182,9 @@ public:
class StackLayout
{
public:
- StackLayout(IR::Function *function, int maxArgCountForBuiltins, int normalRegistersToSave)
+ StackLayout(IR::Function *function, int maxArgCountForBuiltins, int normalRegistersToSave, int fpRegistersToSave)
: normalRegistersToSave(normalRegistersToSave)
+ , fpRegistersToSave(fpRegistersToSave)
, maxOutgoingArgumentCount(function->maxNumberOfArguments)
, localCount(function->tempCount)
, savedRegCount(maxArgCountForBuiltins)
@@ -216,7 +217,7 @@ public:
+ RegisterSize; // saved StackFrameRegister
// space for the callee saved registers
- int frameSize = RegisterSize * normalRegistersToSave;
+ int frameSize = RegisterSize * normalRegistersToSave + sizeof(double) * fpRegistersToSave;
frameSize += savedRegCount * sizeof(QV4::Value); // these get written out as Values, not as native registers
Q_ASSERT(frameSize + stackSpaceAllocatedOtherwise < INT_MAX);
@@ -269,11 +270,13 @@ public:
int calleeSavedRegisterSpace() const
{
// plus 1 for the old FP
- return RegisterSize * (normalRegistersToSave + 1);
+ return RegisterSize * (normalRegistersToSave + 1)
+ + sizeof(double) * fpRegistersToSave;
}
private:
int normalRegistersToSave;
+ int fpRegistersToSave;
/// arg count for calls to JS functions
int maxOutgoingArgumentCount;
@@ -794,8 +797,10 @@ public:
void storeValue(QV4::Primitive value, IR::Expr* temp);
- void enterStandardStackFrame(const RegisterInformation &regularRegistersToSave);
- void leaveStandardStackFrame(const RegisterInformation &regularRegistersToSave);
+ void enterStandardStackFrame(const RegisterInformation &regularRegistersToSave,
+ const RegisterInformation &fpRegistersToSave);
+ void leaveStandardStackFrame(const RegisterInformation &regularRegistersToSave,
+ const RegisterInformation &fpRegistersToSave);
void checkException() {
loadPtr(Address(ContextRegister, qOffsetOf(QV4::ExecutionContext::Data, engine)), ScratchRegister);
@@ -1146,7 +1151,7 @@ public:
JSC::MacroAssemblerCodeRef link(int *codeSize);
- void setStackLayout(int maxArgCountForBuiltins, int regularRegistersToSave);
+ void setStackLayout(int maxArgCountForBuiltins, int regularRegistersToSave, int fpRegistersToSave);
const StackLayout &stackLayout() const { return *_stackLayout.data(); }
ConstantTable &constantTable() { return _constTable; }
diff --git a/src/qml/jit/qv4isel_masm.cpp b/src/qml/jit/qv4isel_masm.cpp
index 39e7c0fbc2..104cd2e903 100644
--- a/src/qml/jit/qv4isel_masm.cpp
+++ b/src/qml/jit/qv4isel_masm.cpp
@@ -242,8 +242,9 @@ void InstructionSelection::run(int functionIndex)
Assembler* oldAssembler = _as;
_as = new Assembler(this, _function, executableAllocator);
_as->setStackLayout(6, // 6 == max argc for calls to built-ins with an argument array
- regularRegistersToSave.size());
- _as->enterStandardStackFrame(regularRegistersToSave);
+ regularRegistersToSave.size(),
+ fpRegistersToSave.size());
+ _as->enterStandardStackFrame(regularRegistersToSave, fpRegistersToSave);
#ifdef ARGUMENTS_IN_REGISTERS
_as->move(_as->registerForArgument(0), Assembler::ContextRegister);
@@ -1474,7 +1475,7 @@ void InstructionSelection::visitRet(IR::Ret *s)
_as->loadPtr(Address(Assembler::ContextRegister, qOffsetOf(ExecutionContext::Data, engine)), Assembler::ScratchRegister);
_as->storePtr(Assembler::LocalsRegister, Address(Assembler::ScratchRegister, qOffsetOf(ExecutionEngine, jsStackTop)));
- _as->leaveStandardStackFrame(regularRegistersToSave);
+ _as->leaveStandardStackFrame(regularRegistersToSave, fpRegistersToSave);
_as->ret();
}
@@ -1532,6 +1533,7 @@ int InstructionSelection::prepareCallData(IR::ExprList* args, IR::Expr *thisObje
void InstructionSelection::calculateRegistersToSave(const RegisterInformation &used)
{
regularRegistersToSave.clear();
+ fpRegistersToSave.clear();
foreach (const RegisterInfo &ri, Assembler::getRegisterInfo()) {
if (ri.isCallerSaved())
@@ -1546,6 +1548,10 @@ void InstructionSelection::calculateRegistersToSave(const RegisterInformation &u
#endif // RESTORE_EBX_ON_CALL
if (ri.isPredefined() || used.contains(ri))
regularRegistersToSave.append(ri);
+ } else {
+ Q_ASSERT(ri.isFloatingPoint());
+ if (ri.isPredefined() || used.contains(ri))
+ fpRegistersToSave.append(ri);
}
}
}
diff --git a/src/qml/jit/qv4isel_masm_p.h b/src/qml/jit/qv4isel_masm_p.h
index bbe0f05556..264ad2d179 100644
--- a/src/qml/jit/qv4isel_masm_p.h
+++ b/src/qml/jit/qv4isel_masm_p.h
@@ -266,6 +266,7 @@ private:
QScopedPointer<CompilationUnit> compilationUnit;
QQmlEnginePrivate *qmlEngine;
RegisterInformation regularRegistersToSave;
+ RegisterInformation fpRegistersToSave;
};
class Q_QML_EXPORT ISelFactory: public EvalISelFactory