aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@me.com>2013-09-25 15:17:16 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-10-04 11:36:59 +0200
commit0889e861b689bbd628b803a0a0824421c2399a1c (patch)
tree0c311a832fc8a80716bc3be4f80362a5d3044218 /src/qml/compiler
parent9c52e37bda2c7f7bd5c9ba0e0448b88e30ddc024 (diff)
V4 JIT: fix visitRet for 32-bit architectures.
Change-Id: I004fe8d5de0f5a932c23393ed06a04738b8e8bf1 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/qml/compiler')
-rw-r--r--src/qml/compiler/qv4isel_masm.cpp53
1 files changed, 43 insertions, 10 deletions
diff --git a/src/qml/compiler/qv4isel_masm.cpp b/src/qml/compiler/qv4isel_masm.cpp
index fed1ca865e..dd754288db 100644
--- a/src/qml/compiler/qv4isel_masm.cpp
+++ b/src/qml/compiler/qv4isel_masm.cpp
@@ -1755,16 +1755,49 @@ void InstructionSelection::visitCJump(V4IR::CJump *s)
void InstructionSelection::visitRet(V4IR::Ret *s)
{
if (V4IR::Temp *t = s->expr->asTemp()) {
-#if CPU(X86)
- Address addr = _as->loadTempAddress(Assembler::ScratchRegister, t);
- _as->load32(addr, JSC::X86Registers::eax);
- addr.offset += 4;
- _as->load32(addr, JSC::X86Registers::edx);
-#elif CPU(ARM)
- Address addr = _as->loadTempAddress(Assembler::ScratchRegister, t);
- _as->load32(addr, JSC::ARMRegisters::r0);
- addr.offset += 4;
- _as->load32(addr, JSC::ARMRegisters::r1);
+#if CPU(X86) || CPU(ARM)
+
+# if CPU(X86)
+ Assembler::RegisterID lowReg = JSC::X86Registers::eax;
+ Assembler::RegisterID highReg = JSC::X86Registers::edx;
+# else // CPU(ARM)
+ Assembler::RegisterID lowReg = JSC::ARMRegisters::r0;
+ Assembler::RegisterID highReg = JSC::ARMRegisters::r1;
+# endif
+
+ if (t->kind == V4IR::Temp::PhysicalRegister) {
+ switch (t->type) {
+ case V4IR::DoubleType:
+ _as->moveDoubleToInts((Assembler::FPRegisterID) t->index, lowReg, highReg);
+ break;
+ case V4IR::UInt32Type: {
+ Assembler::RegisterID srcReg = (Assembler::RegisterID) t->index;
+ Assembler::Jump intRange = _as->branch32(Assembler::GreaterThanOrEqual, srcReg, Assembler::TrustedImm32(0));
+ _as->convertUInt32ToDouble(srcReg, Assembler::FPGpr0, Assembler::ReturnValueRegister);
+ _as->moveDoubleToInts(Assembler::FPGpr0, lowReg, highReg);
+ Assembler::Jump done = _as->jump();
+ intRange.link(_as);
+ _as->move(srcReg, lowReg);
+ _as->move(Assembler::TrustedImm32(QV4::Value::_Integer_Type), highReg);
+ done.link(_as);
+ } break;
+ case V4IR::SInt32Type:
+ _as->move((Assembler::RegisterID) t->index, lowReg);
+ _as->move(Assembler::TrustedImm32(QV4::Value::_Integer_Type), highReg);
+ break;
+ case V4IR::BoolType:
+ _as->move((Assembler::RegisterID) t->index, lowReg);
+ _as->move(Assembler::TrustedImm32(QV4::Value::_Boolean_Type), highReg);
+ break;
+ default:
+ Q_UNREACHABLE();
+ }
+ } else {
+ Pointer addr = _as->loadTempAddress(Assembler::ScratchRegister, t);
+ _as->load32(addr, lowReg);
+ addr.offset += 4;
+ _as->load32(addr, highReg);
+ }
#else
if (t->kind == V4IR::Temp::PhysicalRegister) {
if (t->type == V4IR::DoubleType) {