diff options
author | Erik Verbruggen <erik.verbruggen@me.com> | 2013-09-25 15:17:16 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-10-04 11:36:59 +0200 |
commit | 0889e861b689bbd628b803a0a0824421c2399a1c (patch) | |
tree | 0c311a832fc8a80716bc3be4f80362a5d3044218 /src/qml/compiler | |
parent | 9c52e37bda2c7f7bd5c9ba0e0448b88e30ddc024 (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.cpp | 53 |
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) { |