aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@me.com>2013-10-11 15:21:57 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-10-12 13:14:02 +0200
commit6f886cd6a841eeb76e1c590b8abd3af6fdd5c494 (patch)
treeb1860d7dd5fbef48624e0699248fe6a7e11c4096 /src/qml/compiler
parent2fcb8cfcdfb795ab3872146dc56bcacc72abf131 (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.cpp79
-rw-r--r--src/qml/compiler/qv4isel_masm_p.h29
-rw-r--r--src/qml/compiler/qv4regalloc.cpp44
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;
}