summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/qml/compiler/qv4isel_masm.cpp17
-rw-r--r--src/qml/compiler/qv4isel_masm_p.h9
2 files changed, 22 insertions, 4 deletions
diff --git a/src/qml/compiler/qv4isel_masm.cpp b/src/qml/compiler/qv4isel_masm.cpp
index 33c2279c2d..3f3c47d804 100644
--- a/src/qml/compiler/qv4isel_masm.cpp
+++ b/src/qml/compiler/qv4isel_masm.cpp
@@ -358,7 +358,6 @@ void Assembler::copyValue(Result result, V4IR::Expr* source)
}
}
-
void Assembler::storeValue(QV4::Value value, V4IR::Temp* destination)
{
Address addr = loadTempAddress(ScratchRegister, destination);
@@ -1128,7 +1127,9 @@ void InstructionSelection::copyValue(V4IR::Temp *sourceTemp, V4IR::Temp *targetT
}
}
- _as->copyValue(targetTemp, sourceTemp);
+ // The target is not a physical register, nor is the source. So we can do a memory-to-memory copy:
+ _as->memcopyValue(_as->loadTempAddress(Assembler::ReturnValueRegister, targetTemp), sourceTemp,
+ Assembler::ScratchRegister);
}
void InstructionSelection::swapValues(V4IR::Temp *sourceTemp, V4IR::Temp *targetTemp)
@@ -1910,7 +1911,11 @@ int InstructionSelection::prepareVariableArguments(V4IR::ExprList* args)
for (V4IR::ExprList *it = args; it; it = it->next, ++i) {
V4IR::Expr *arg = it->expr;
Q_ASSERT(arg != 0);
- _as->copyValue(_as->stackLayout().argumentAddressForCall(i), arg);
+ Pointer dst(_as->stackLayout().argumentAddressForCall(i));
+ if (arg->asTemp() && arg->asTemp()->kind != V4IR::Temp::PhysicalRegister)
+ _as->memcopyValue(dst, arg->asTemp(), Assembler::ScratchRegister);
+ else
+ _as->copyValue(dst, arg);
}
return argc;
@@ -1937,7 +1942,11 @@ int InstructionSelection::prepareCallData(V4IR::ExprList* args, V4IR::Expr *this
for (V4IR::ExprList *it = args; it; it = it->next, ++i) {
V4IR::Expr *arg = it->expr;
Q_ASSERT(arg != 0);
- _as->copyValue(_as->stackLayout().argumentAddressForCall(i), arg);
+ Pointer dst(_as->stackLayout().argumentAddressForCall(i));
+ if (arg->asTemp() && arg->asTemp()->kind != V4IR::Temp::PhysicalRegister)
+ _as->memcopyValue(dst, arg->asTemp(), Assembler::ScratchRegister);
+ else
+ _as->copyValue(dst, arg);
}
return argc;
}
diff --git a/src/qml/compiler/qv4isel_masm_p.h b/src/qml/compiler/qv4isel_masm_p.h
index a4550c63ed..86a4dd6304 100644
--- a/src/qml/compiler/qv4isel_masm_p.h
+++ b/src/qml/compiler/qv4isel_masm_p.h
@@ -808,6 +808,15 @@ public:
template <typename Result>
void copyValue(Result result, V4IR::Expr* source);
+ // The scratch register is used to calculate the temp address for the source.
+ void memcopyValue(Pointer target, V4IR::Temp *sourceTemp, RegisterID scratchRegister)
+ {
+ Q_ASSERT(sourceTemp->kind != V4IR::Temp::PhysicalRegister);
+ Q_ASSERT(target.base != scratchRegister);
+ JSC::MacroAssembler::loadDouble(loadTempAddress(scratchRegister, sourceTemp), FPGpr0);
+ JSC::MacroAssembler::storeDouble(FPGpr0, target);
+ }
+
void storeValue(QV4::Value value, RegisterID destination)
{
Q_UNUSED(value);