diff options
author | Erik Verbruggen <erik.verbruggen@me.com> | 2013-10-11 15:21:57 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-10-12 13:14:02 +0200 |
commit | 6f886cd6a841eeb76e1c590b8abd3af6fdd5c494 (patch) | |
tree | b1860d7dd5fbef48624e0699248fe6a7e11c4096 /src/qml/compiler | |
parent | 2fcb8cfcdfb795ab3872146dc56bcacc72abf131 (diff) |
V4 JIT: clean-up conversion functions and add toUInt32.
Change-Id: I7ac685145fa41db2a0e02c4d15d1d287d80621f8
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/qml/compiler')
-rw-r--r-- | src/qml/compiler/qv4isel_masm.cpp | 79 | ||||
-rw-r--r-- | src/qml/compiler/qv4isel_masm_p.h | 29 | ||||
-rw-r--r-- | src/qml/compiler/qv4regalloc.cpp | 44 |
3 files changed, 107 insertions, 45 deletions
diff --git a/src/qml/compiler/qv4isel_masm.cpp b/src/qml/compiler/qv4isel_masm.cpp index 4ca4f82cef..461186a719 100644 --- a/src/qml/compiler/qv4isel_masm.cpp +++ b/src/qml/compiler/qv4isel_masm.cpp @@ -1491,6 +1491,9 @@ void InstructionSelection::convertTypeToDouble(V4IR::Temp *source, V4IR::Temp *t convertUIntToDouble(source, target); break; case V4IR::UndefinedType: + _as->loadDouble(_as->loadTempAddress(Assembler::ScratchRegister, source), Assembler::FPGpr0); + _as->storeDouble(Assembler::FPGpr0, target); + break; case V4IR::StringType: case V4IR::VarType: { // load the tag: @@ -1666,46 +1669,86 @@ void InstructionSelection::convertTypeToSInt32(V4IR::Temp *source, V4IR::Temp *t } break; case V4IR::DoubleType: { - Assembler::FPRegisterID reg = _as->toDoubleRegister(source); Assembler::Jump success = - _as->branchTruncateDoubleToInt32(reg, Assembler::ReturnValueRegister, + _as->branchTruncateDoubleToInt32(_as->toDoubleRegister(source), + Assembler::ReturnValueRegister, Assembler::BranchIfTruncateSuccessful); generateFunctionCall(Assembler::ReturnValueRegister, __qmljs_double_to_int32, Assembler::PointerToValue(source)); success.link(_as); _as->storeInt32(Assembler::ReturnValueRegister, target); } break; - case V4IR::UInt32Type: { - Assembler::RegisterID reg = _as->toUInt32Register(source, Assembler::ReturnValueRegister); - Assembler::Jump easy = _as->branch32(Assembler::GreaterThanOrEqual, reg, Assembler::TrustedImm32(0)); - generateFunctionCall(Assembler::ReturnValueRegister, __qmljs_value_to_int32, - Assembler::PointerToValue(source)); - easy.link(_as); - _as->storeInt32(Assembler::ReturnValueRegister, target); - } break; + case V4IR::UInt32Type: + _as->storeInt32(_as->toUInt32Register(source, Assembler::ReturnValueRegister), target); + break; case V4IR::NullType: case V4IR::UndefinedType: _as->move(Assembler::TrustedImm32(0), Assembler::ReturnValueRegister); _as->storeInt32(Assembler::ReturnValueRegister, target); break; - case V4IR::StringType: - generateFunctionCall(Assembler::ReturnValueRegister, __qmljs_value_to_int32, - _as->loadTempAddress(Assembler::ScratchRegister, source)); - _as->storeInt32(Assembler::ReturnValueRegister, target); - break; case V4IR::BoolType: _as->storeInt32(_as->toInt32Register(source, Assembler::ReturnValueRegister), target); break; + case V4IR::StringType: default: + generateFunctionCall(Assembler::ReturnValueRegister, __qmljs_value_to_int32, + _as->loadTempAddress(Assembler::ScratchRegister, source)); + _as->storeInt32(Assembler::ReturnValueRegister, target); break; } // switch (source->type) } void InstructionSelection::convertTypeToUInt32(V4IR::Temp *source, V4IR::Temp *target) { - generateFunctionCall(Assembler::ReturnValueRegister, __qmljs_value_to_uint32, - Assembler::PointerToValue(source)); - _as->storeUInt32(Assembler::ReturnValueRegister, target); + switch (source->type) { + case V4IR::VarType: { + // load the tag: + Assembler::Pointer tagAddr = _as->loadTempAddress(Assembler::ScratchRegister, source); + tagAddr.offset += 4; + _as->load32(tagAddr, Assembler::ScratchRegister); + + // check if it's an int32: + Assembler::Jump isNoInt = _as->branch32(Assembler::NotEqual, Assembler::ScratchRegister, + Assembler::TrustedImm32(Value::_Integer_Type)); + Assembler::Pointer addr = _as->loadTempAddress(Assembler::ScratchRegister, source); + _as->storeUInt32(_as->toInt32Register(addr, Assembler::ScratchRegister), target); + Assembler::Jump intDone = _as->jump(); + + // not an int: + isNoInt.link(_as); + generateFunctionCall(Assembler::ReturnValueRegister, __qmljs_value_to_uint32, + _as->loadTempAddress(Assembler::ScratchRegister, source)); + _as->storeInt32(Assembler::ReturnValueRegister, target); + + intDone.link(_as); + } break; + case V4IR::DoubleType: { + Assembler::FPRegisterID reg = _as->toDoubleRegister(source); + Assembler::Jump success = + _as->branchTruncateDoubleToUint32(reg, Assembler::ReturnValueRegister, + Assembler::BranchIfTruncateSuccessful); + generateFunctionCall(Assembler::ReturnValueRegister, __qmljs_double_to_uint32, + Assembler::PointerToValue(source)); + success.link(_as); + _as->storeUInt32(Assembler::ReturnValueRegister, target); + } break; + case V4IR::NullType: + case V4IR::UndefinedType: + _as->move(Assembler::TrustedImm32(0), Assembler::ReturnValueRegister); + _as->storeUInt32(Assembler::ReturnValueRegister, target); + break; + case V4IR::StringType: + generateFunctionCall(Assembler::ReturnValueRegister, __qmljs_value_to_uint32, + Assembler::PointerToValue(source)); + _as->storeUInt32(Assembler::ReturnValueRegister, target); + break; + case V4IR::SInt32Type: + case V4IR::BoolType: + _as->storeUInt32(_as->toInt32Register(source, Assembler::ReturnValueRegister), target); + break; + default: + break; + } // switch (source->type) } void InstructionSelection::constructActivationProperty(V4IR::Name *func, V4IR::ExprList *args, V4IR::Temp *result) diff --git a/src/qml/compiler/qv4isel_masm_p.h b/src/qml/compiler/qv4isel_masm_p.h index 3dfd979654..a0f81a7412 100644 --- a/src/qml/compiler/qv4isel_masm_p.h +++ b/src/qml/compiler/qv4isel_masm_p.h @@ -1294,6 +1294,8 @@ public: RegisterID toUInt32Register(Pointer addr, RegisterID scratchReg) { + Q_ASSERT(addr.base != scratchReg); + // The UInt32 representation in QV4::Value is really convoluted. See also storeUInt32. Pointer tagAddr = addr; tagAddr.offset += 4; @@ -1480,30 +1482,25 @@ private: void convertUIntToDouble(V4IR::Temp *source, V4IR::Temp *target) { + Assembler::RegisterID tmpReg = Assembler::ScratchRegister; + Assembler::RegisterID reg = _as->toInt32Register(source, tmpReg); + if (target->kind == V4IR::Temp::PhysicalRegister) { - _as->convertUInt32ToDouble(_as->toInt32Register(source, Assembler::ScratchRegister), - (Assembler::FPRegisterID) target->index, - Assembler::ScratchRegister); - } else if (target->kind == V4IR::Temp::StackSlot) { - _as->convertUInt32ToDouble(_as->toUInt32Register(source, Assembler::ScratchRegister), - Assembler::FPGpr0, Assembler::ScratchRegister); - _as->storeDouble(Assembler::FPGpr0, _as->stackSlotPointer(target)); + _as->convertUInt32ToDouble(reg, (Assembler::FPRegisterID) target->index, tmpReg); } else { - Q_UNIMPLEMENTED(); + _as->convertUInt32ToDouble(_as->toUInt32Register(source, tmpReg), + Assembler::FPGpr0, tmpReg); + _as->storeDouble(Assembler::FPGpr0, _as->stackSlotPointer(target)); } } void convertIntToBool(V4IR::Temp *source, V4IR::Temp *target) { - Assembler::RegisterID reg = Assembler::ScratchRegister; - if (target->kind == V4IR::Temp::PhysicalRegister) { - reg = _as->toInt32Register(source, reg); - } else if (target->kind == V4IR::Temp::StackSlot) { - _as->move(_as->toInt32Register(source, reg), reg); - } else { - Q_UNIMPLEMENTED(); - } + Assembler::RegisterID reg = target->kind == V4IR::Temp::PhysicalRegister + ? (Assembler::RegisterID) target->index + : Assembler::ScratchRegister; + _as->move(_as->toInt32Register(source, reg), reg); _as->compare32(Assembler::NotEqual, reg, Assembler::TrustedImm32(0), reg); _as->storeBool(reg, target); } diff --git a/src/qml/compiler/qv4regalloc.cpp b/src/qml/compiler/qv4regalloc.cpp index 210ae686c8..b4ec0f357b 100644 --- a/src/qml/compiler/qv4regalloc.cpp +++ b/src/qml/compiler/qv4regalloc.cpp @@ -242,27 +242,27 @@ protected: // IRDecoder switch (target->type) { case DoubleType: - if (source->type == UInt32Type) { - sourceReg = Use::MustHaveRegister; + switch (source->type) { + case UInt32Type: + case SInt32Type: + case NullType: + case UndefinedType: + case BoolType: needsCall = false; break; - } - case SInt32Type: - if (source->type == DoubleType || source->type == UInt32Type) { - // this might need a call + default: break; } -#if 0 // TODO: change masm to generate code - case UInt32Type: -#endif + break; case BoolType: switch (source->type) { case UInt32Type: - case BoolType: - case DoubleType: sourceReg = Use::MustHaveRegister; needsCall = false; break; + case DoubleType: + case UndefinedType: + case NullType: case SInt32Type: needsCall = false; break; @@ -270,6 +270,28 @@ protected: // IRDecoder break; } break; + case SInt32Type: + switch (source->type) { + case UInt32Type: + case NullType: + case UndefinedType: + case BoolType: + needsCall = false; + default: + break; + } + break; + case UInt32Type: + switch (source->type) { + case SInt32Type: + case NullType: + case UndefinedType: + case BoolType: + needsCall = false; + default: + break; + } + break; default: break; } |