aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2013-10-04 15:38:42 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-10-11 16:01:24 +0200
commitf6de6160b915b5a35e75746a35c4ef94ceb9b2c2 (patch)
treeb75e37bc0579a2195c36074999cd4b116aeb7a1f /src/qml/compiler
parent886c359ebb86afcad3a62ce6cf7697fd7d6a1ea8 (diff)
Optimise code generation for convertTypeToSInt32
Add 64 bit code patch and avoid some duplicated calculation in 32 bit mode Change-Id: I0e111de8ac4e733aa8802c49b4b15d785688d7ea Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/qml/compiler')
-rw-r--r--src/qml/compiler/qv4isel_masm.cpp57
1 files changed, 52 insertions, 5 deletions
diff --git a/src/qml/compiler/qv4isel_masm.cpp b/src/qml/compiler/qv4isel_masm.cpp
index 574b4e278b..4ca4f82cef 100644
--- a/src/qml/compiler/qv4isel_masm.cpp
+++ b/src/qml/compiler/qv4isel_masm.cpp
@@ -1590,15 +1590,60 @@ void InstructionSelection::convertTypeToSInt32(V4IR::Temp *source, V4IR::Temp *t
{
switch (source->type) {
case V4IR::VarType: {
+
+#if QT_POINTER_SIZE == 8
+ Assembler::Pointer addr = _as->loadTempAddress(Assembler::ScratchRegister, source);
+ _as->load64(addr, Assembler::ScratchRegister);
+ _as->move(Assembler::ScratchRegister, Assembler::ReturnValueRegister);
+
+ // check if it's a number
+ _as->urshift64(Assembler::TrustedImm32(QV4::Value::IsNumber_Shift), Assembler::ScratchRegister);
+ Assembler::Jump fallback = _as->branch32(Assembler::Equal, Assembler::ScratchRegister, Assembler::TrustedImm32(0));
+ // we have a number
+ _as->urshift64(Assembler::TrustedImm32(1), Assembler::ScratchRegister);
+ Assembler::Jump isInt = _as->branch32(Assembler::Equal, Assembler::ScratchRegister, Assembler::TrustedImm32(0));
+
+ // it's a double
+ _as->move(Assembler::TrustedImm64(QV4::Value::NaNEncodeMask), Assembler::ScratchRegister);
+ _as->xor64(Assembler::ScratchRegister, Assembler::ReturnValueRegister);
+ _as->move64ToDouble(Assembler::ReturnValueRegister, Assembler::FPGpr0);
+ Assembler::Jump success =
+ _as->branchTruncateDoubleToInt32(Assembler::FPGpr0, Assembler::ReturnValueRegister,
+ Assembler::BranchIfTruncateSuccessful);
+ generateFunctionCall(Assembler::ReturnValueRegister, __qmljs_double_to_int32,
+ Assembler::PointerToValue(source));
+ Assembler::Jump converted = _as->jump();
+
+ // not an int:
+ fallback.link(_as);
+ generateFunctionCall(Assembler::ReturnValueRegister, __qmljs_value_to_int32,
+ _as->loadTempAddress(Assembler::ScratchRegister, source));
+
+ isInt.link(_as);
+ success.link(_as);
+ converted.link(_as);
+ if (target->kind == V4IR::Temp::StackSlot) {
+// _as->move(Assembler::TrustedImm32(QV4::Value::_Integer_Type), Assembler::ScratchRegister);
+// _as->lshift64(Assembler::TrustedImm32(32), Assembler::ScratchRegister);
+// _as->or64(Assembler::ScratchRegister, Assembler::ReturnValueRegister, Assembler::ScratchRegister);
+// _as->store64(Assembler::ScratchRegister, target);
+ Assembler::Pointer targetAddr = _as->stackSlotPointer(target);
+ _as->store32(Assembler::ReturnValueRegister, targetAddr);
+ targetAddr.offset += 4;
+ _as->store32(Assembler::TrustedImm32(Value::_Integer_Type), targetAddr);
+ } else {
+ _as->storeInt32(Assembler::ReturnValueRegister, target);
+ }
+#else
// load the tag:
- Assembler::Pointer tagAddr = _as->loadTempAddress(Assembler::ScratchRegister, source);
+ Assembler::Pointer addr = _as->loadTempAddress(Assembler::ScratchRegister, source);
+ Assembler::Pointer tagAddr = addr;
tagAddr.offset += 4;
- _as->load32(tagAddr, Assembler::ScratchRegister);
+ _as->load32(tagAddr, Assembler::ReturnValueRegister);
// check if it's an int32:
- Assembler::Jump isNoInt = _as->branch32(Assembler::NotEqual, Assembler::ScratchRegister,
+ Assembler::Jump fallback = _as->branch32(Assembler::NotEqual, Assembler::ReturnValueRegister,
Assembler::TrustedImm32(Value::_Integer_Type));
- Assembler::Pointer addr = _as->loadTempAddress(Assembler::ScratchRegister, source);
if (target->kind == V4IR::Temp::StackSlot) {
_as->load32(addr, Assembler::ScratchRegister);
Assembler::Pointer targetAddr = _as->stackSlotPointer(target);
@@ -1611,12 +1656,14 @@ void InstructionSelection::convertTypeToSInt32(V4IR::Temp *source, V4IR::Temp *t
Assembler::Jump intDone = _as->jump();
// not an int:
- isNoInt.link(_as);
+ fallback.link(_as);
generateFunctionCall(Assembler::ReturnValueRegister, __qmljs_value_to_int32,
_as->loadTempAddress(Assembler::ScratchRegister, source));
_as->storeInt32(Assembler::ReturnValueRegister, target);
intDone.link(_as);
+#endif
+
} break;
case V4IR::DoubleType: {
Assembler::FPRegisterID reg = _as->toDoubleRegister(source);