From a295dae1bc2e2f2d1d1a2c53a9d5faffeeac68c5 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Tue, 28 Mar 2017 10:55:25 +0200 Subject: Fix value type encoding constant usage when cross-compiling Our two value encodings use different masks for the upper 4 bytes. Depending on the target architecture we must use different values when generating code that uses these masks. This patch replaces the #ifdef'ed ValueTypeInternal_* enum values with two C++11 scoped enums that allows for the co-existence of both throughout the code base as well as selective use in the code generators. Change-Id: I380c8c28b84df2874cca521b78bfe7f9388ed228 Reviewed-by: Qt CI Bot Reviewed-by: Lars Knoll --- src/qml/jit/qv4assembler.cpp | 2 +- src/qml/jit/qv4assembler_p.h | 29 +++++++++++++++++------------ src/qml/jit/qv4isel_masm.cpp | 23 ++++++++++++----------- 3 files changed, 30 insertions(+), 24 deletions(-) (limited to 'src/qml/jit') diff --git a/src/qml/jit/qv4assembler.cpp b/src/qml/jit/qv4assembler.cpp index d239ed9907..daa732810b 100644 --- a/src/qml/jit/qv4assembler.cpp +++ b/src/qml/jit/qv4assembler.cpp @@ -437,7 +437,7 @@ typename Assembler::Jump Assembler::ge // check if it's an int32: Assembler::Jump isNoInt = branch32(Assembler::NotEqual, Assembler::ScratchRegister, - Assembler::TrustedImm32(Value::Integer_Type_Internal)); + Assembler::TrustedImm32(quint32(ValueTypeInternal::Integer))); convertInt32ToDouble(toInt32Register(src, Assembler::ScratchRegister), dest); Assembler::Jump intDone = jump(); diff --git a/src/qml/jit/qv4assembler_p.h b/src/qml/jit/qv4assembler_p.h index 3e3aab9452..ad6c29dd49 100644 --- a/src/qml/jit/qv4assembler_p.h +++ b/src/qml/jit/qv4assembler_p.h @@ -153,6 +153,8 @@ struct RegisterSizeDependentAssemblerMacroAssembler::loadDouble(addr, dest); @@ -219,16 +221,16 @@ struct RegisterSizeDependentAssemblerjump(); intRange.link(as); as->move(srcReg, lowReg); - as->move(TrustedImm32(QV4::Value::Integer_Type_Internal), highReg); + as->move(TrustedImm32(quint32(QV4::Value::ValueTypeInternal_32::Integer)), highReg); done.link(as); } break; case IR::SInt32Type: as->move((RegisterID) t->index, lowReg); - as->move(TrustedImm32(QV4::Value::Integer_Type_Internal), highReg); + as->move(TrustedImm32(quint32(QV4::Value::ValueTypeInternal_32::Integer)), highReg); break; case IR::BoolType: as->move((RegisterID) t->index, lowReg); - as->move(TrustedImm32(QV4::Value::Boolean_Type_Internal), highReg); + as->move(TrustedImm32(quint32(QV4::Value::ValueTypeInternal_32::Boolean)), highReg); break; default: Q_UNREACHABLE(); @@ -319,14 +321,14 @@ struct RegisterSizeDependentAssemblerbranch32(RelationalCondition::NotEqual, TargetPlatform::ReturnValueRegister, - TrustedImm32(Value::Integer_Type_Internal)); + TrustedImm32(quint32(Value::ValueTypeInternal_32::Integer))); IR::Temp *targetTemp = target->asTemp(); if (!targetTemp || targetTemp->kind == IR::Temp::StackSlot) { as->load32(addr, TargetPlatform::ReturnValueRegister); Pointer targetAddr = as->loadAddress(TargetPlatform::ScratchRegister, target); as->store32(TargetPlatform::ReturnValueRegister, targetAddr); targetAddr.offset += 4; - as->store32(TrustedImm32(Value::Integer_Type_Internal), targetAddr); + as->store32(TrustedImm32(quint32(Value::ValueTypeInternal_32::Integer)), targetAddr); } else { as->load32(addr, (RegisterID) targetTemp->index); } @@ -384,6 +386,8 @@ struct RegisterSizeDependentAssemblerload64(addr, TargetPlatform::ReturnValueRegister); @@ -433,7 +437,7 @@ struct RegisterSizeDependentAssemblerjump(); intRange.link(as); as->zeroExtend32ToPtr(srcReg, TargetPlatform::ReturnValueRegister); - quint64 tag = QV4::Value::Integer_Type_Internal; + quint64 tag = quint64(QV4::Value::ValueTypeInternal_64::Integer); as->or64(TrustedImm64(tag << 32), TargetPlatform::ReturnValueRegister); done.link(as); @@ -442,10 +446,10 @@ struct RegisterSizeDependentAssemblertype) { case IR::SInt32Type: - tag = QV4::Value::Integer_Type_Internal; + tag = quint64(QV4::Value::ValueTypeInternal_64::Integer); break; case IR::BoolType: - tag = QV4::Value::Boolean_Type_Internal; + tag = quint64(QV4::Value::ValueTypeInternal_64::Boolean); break; default: tag = 31337; // bogus value @@ -623,7 +627,7 @@ struct RegisterSizeDependentAssemblerloadAddress(TargetPlatform::ScratchRegister, target); as->store32(TargetPlatform::ReturnValueRegister, targetAddr); targetAddr.offset += 4; - as->store32(TrustedImm32(Value::Integer_Type_Internal), targetAddr); + as->store32(TrustedImm32(quint32(Value::ValueTypeInternal_64::Integer)), targetAddr); } else { as->storeInt32(TargetPlatform::ReturnValueRegister, target); } @@ -719,8 +723,6 @@ public: return (hostOffset * RegisterSize) / QT_POINTER_SIZE; } - using RegisterSizeDependentOps = RegisterSizeDependentAssembler, MacroAssembler, JITTargetPlatform, RegisterSize>; - struct LookupCall { Address addr; uint getterSetterOffset; @@ -751,6 +753,9 @@ public: {} }; + using RegisterSizeDependentOps = RegisterSizeDependentAssembler, MacroAssembler, JITTargetPlatform, RegisterSize>; + using ValueTypeInternal = typename RegisterSizeDependentOps::ValueTypeInternal; + // V4 uses two stacks: one stack with QV4::Value items, which is checked by the garbage // collector, and one stack used by the native C/C++/ABI code. This C++ stack is not scanned // by the garbage collector, so if any JS object needs to be retained, it should be put on the @@ -1586,7 +1591,7 @@ public: Pointer tagAddr = addr; tagAddr.offset += 4; load32(tagAddr, scratchReg); - Jump inIntRange = branch32(RelationalCondition::Equal, scratchReg, TrustedImm32(QV4::Value::Integer_Type_Internal)); + Jump inIntRange = branch32(RelationalCondition::Equal, scratchReg, TrustedImm32(quint32(ValueTypeInternal::Integer))); // it's not in signed int range, so load it as a double, and truncate it down loadDouble(addr, FPGpr0); diff --git a/src/qml/jit/qv4isel_masm.cpp b/src/qml/jit/qv4isel_masm.cpp index 4a222e20f4..126fb4382b 100644 --- a/src/qml/jit/qv4isel_masm.cpp +++ b/src/qml/jit/qv4isel_masm.cpp @@ -774,10 +774,10 @@ void InstructionSelection::swapValues(IR::Expr *source, IR::Expr * quint32 tag; switch (regTemp->type) { case IR::BoolType: - tag = QV4::Value::Boolean_Type_Internal; + tag = quint32(JITAssembler::ValueTypeInternal::Boolean); break; case IR::SInt32Type: - tag = QV4::Value::Integer_Type_Internal; + tag = quint32(JITAssembler::ValueTypeInternal::Integer); break; default: tag = 31337; // bogus value @@ -925,7 +925,7 @@ void InstructionSelection::convertTypeToDouble(IR::Expr *source, I // check if it's an int32: Jump isNoInt = _as->branch32(RelationalCondition::NotEqual, JITTargetPlatform::ScratchRegister, - TrustedImm32(Value::Integer_Type_Internal)); + TrustedImm32(quint32(JITAssembler::ValueTypeInternal::Integer))); convertIntToDouble(source, target); Jump intDone = _as->jump(); @@ -1003,13 +1003,13 @@ void InstructionSelection::convertTypeToBool(IR::Expr *source, IR: // checkif it's a bool: Jump notBool = _as->branch32(RelationalCondition::NotEqual, JITTargetPlatform::ReturnValueRegister, - TrustedImm32(Value::Boolean_Type_Internal)); + TrustedImm32(quint32(JITAssembler::ValueTypeInternal::Boolean))); _as->load32(addr, JITTargetPlatform::ReturnValueRegister); Jump boolDone = _as->jump(); // check if it's an int32: notBool.link(_as); Jump fallback = _as->branch32(RelationalCondition::NotEqual, JITTargetPlatform::ReturnValueRegister, - TrustedImm32(Value::Integer_Type_Internal)); + TrustedImm32(quint32(JITAssembler::ValueTypeInternal::Integer))); _as->load32(addr, JITTargetPlatform::ReturnValueRegister); Jump isZero = _as->branch32(RelationalCondition::Equal, JITTargetPlatform::ReturnValueRegister, TrustedImm32(0)); @@ -1079,7 +1079,7 @@ void InstructionSelection::convertTypeToUInt32(IR::Expr *source, I // check if it's an int32: Jump isNoInt = _as->branch32(RelationalCondition::NotEqual, JITTargetPlatform::ScratchRegister, - TrustedImm32(Value::Integer_Type_Internal)); + TrustedImm32(quint32(JITAssembler::ValueTypeInternal::Integer))); Pointer addr = _as->loadAddress(JITTargetPlatform::ScratchRegister, source); _as->storeUInt32(_as->toInt32Register(addr, JITTargetPlatform::ScratchRegister), target); Jump intDone = _as->jump(); @@ -1195,7 +1195,8 @@ void InstructionSelection::visitCJump(IR::CJump *s) Address temp = _as->loadAddress(JITTargetPlatform::ScratchRegister, s->cond); Address tag = temp; tag.offset += QV4::Value::tagOffset(); - Jump booleanConversion = _as->branch32(RelationalCondition::NotEqual, tag, TrustedImm32(QV4::Value::Boolean_Type_Internal)); + Jump booleanConversion = _as->branch32(RelationalCondition::NotEqual, tag, + TrustedImm32(quint32(JITAssembler::ValueTypeInternal::Boolean))); Address data = temp; data.offset += QV4::Value::valueOffset(); @@ -1314,7 +1315,7 @@ int InstructionSelection::prepareCallData(IR::ExprList* args, IR:: } Pointer p = _as->stackLayout().callDataAddress(offsetof(CallData, tag)); - _as->store32(TrustedImm32(QV4::Value::Integer_Type_Internal), p); + _as->store32(TrustedImm32(quint32(JITAssembler::ValueTypeInternal::Integer)), p); p = _as->stackLayout().callDataAddress(offsetof(CallData, argc)); _as->store32(TrustedImm32(argc), p); p = _as->stackLayout().callDataAddress(offsetof(CallData, thisObject)); @@ -1456,7 +1457,7 @@ bool InstructionSelection::visitCJumpStrictNull(IR::Binop *binop, RelationalCondition cond = binop->op == IR::OpStrictEqual ? RelationalCondition::Equal : RelationalCondition::NotEqual; - const TrustedImm32 tag(QV4::Value::Null_Type_Internal); + const TrustedImm32 tag{quint32(JITAssembler::ValueTypeInternal::Null)}; _as->generateCJumpOnCompare(cond, tagReg, tag, _block, trueBlock, falseBlock); return true; } @@ -1538,7 +1539,7 @@ bool InstructionSelection::visitCJumpStrictBool(IR::Binop *binop, // check if the tag of the var operand is indicates 'boolean' _as->load32(otherAddr, JITTargetPlatform::ScratchRegister); Jump noBool = _as->branch32(RelationalCondition::NotEqual, JITTargetPlatform::ScratchRegister, - TrustedImm32(QV4::Value::Boolean_Type_Internal)); + TrustedImm32(quint32(JITAssembler::ValueTypeInternal::Boolean))); if (binop->op == IR::OpStrictEqual) _as->addPatch(falseBlock, noBool); else @@ -1588,7 +1589,7 @@ bool InstructionSelection::visitCJumpNullUndefined(IR::Type nullOr if (binop->op == IR::OpNotEqual) qSwap(trueBlock, falseBlock); - Jump isNull = _as->branch32(RelationalCondition::Equal, tagReg, TrustedImm32(int(QV4::Value::Null_Type_Internal))); + Jump isNull = _as->branch32(RelationalCondition::Equal, tagReg, TrustedImm32(quint32(JITAssembler::ValueTypeInternal::Null))); Jump isNotUndefinedTag = _as->branch32(RelationalCondition::NotEqual, tagReg, TrustedImm32(int(QV4::Value::Managed_Type_Internal))); tagAddr.offset -= 4; _as->load32(tagAddr, tagReg); -- cgit v1.2.3 From da6fd9c762561d41ce3372c98a555771d18241d6 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Tue, 28 Mar 2017 14:47:40 +0200 Subject: Fix encoding of primitive constants when cross-compiling QV4::Primitive is using host value encoding, which can differ from the target. The source of QV4::Primitive in the code generator is usually IR::Const, transformed via convertToValue(). That function becomes a template that converts to a simple target primitive type. Change-Id: If028aea9551d77d81eec306f60fd995c25b76710 Reviewed-by: Lars Knoll --- src/qml/jit/qv4assembler.cpp | 12 ++++++------ src/qml/jit/qv4assembler_p.h | 43 +++++++++++++++++++++++-------------------- src/qml/jit/qv4isel_masm.cpp | 12 ++++++------ 3 files changed, 35 insertions(+), 32 deletions(-) (limited to 'src/qml/jit') diff --git a/src/qml/jit/qv4assembler.cpp b/src/qml/jit/qv4assembler.cpp index daa732810b..da2cd49a63 100644 --- a/src/qml/jit/qv4assembler.cpp +++ b/src/qml/jit/qv4assembler.cpp @@ -319,15 +319,15 @@ typename Assembler::Pointer Assembler: template typename Assembler::Address Assembler::loadConstant(IR::Const *c, RegisterID baseReg) { - return loadConstant(convertToValue(c), baseReg); + return loadConstant(convertToValue(c), baseReg); } template -typename Assembler::Address Assembler::loadConstant(const Primitive &v, RegisterID baseReg) +typename Assembler::Address Assembler::loadConstant(const TargetPrimitive &v, RegisterID baseReg) { loadPtr(Address(Assembler::EngineRegister, targetStructureOffset(offsetof(QV4::EngineBase, current))), baseReg); loadPtr(Address(baseReg, targetStructureOffset(Heap::ExecutionContext::baseOffset + offsetof(Heap::ExecutionContextData, constantTable))), baseReg); - const int index = _jsGenerator->registerConstant(v.asReturnedValue()); + const int index = _jsGenerator->registerConstant(v.rawValue()); return Address(baseReg, index * sizeof(QV4::Value)); } @@ -339,7 +339,7 @@ void Assembler::loadStringRef(RegisterID reg, const QString } template -void Assembler::storeValue(QV4::Primitive value, IR::Expr *destination) +void Assembler::storeValue(TargetPrimitive value, IR::Expr *destination) { Address addr = loadAddress(ScratchRegister, destination); storeValue(value, addr); @@ -518,7 +518,7 @@ void Assembler::returnFromFunction(IR::Ret *s, RegisterInfo } else if (IR::Temp *t = s->expr->asTemp()) { RegisterSizeDependentOps::setFunctionReturnValueFromTemp(this, t); } else if (IR::Const *c = s->expr->asConst()) { - QV4::Primitive retVal = convertToValue(c); + auto retVal = convertToValue(c); RegisterSizeDependentOps::setFunctionReturnValueFromConst(this, retVal); } else { Q_UNREACHABLE(); @@ -535,7 +535,7 @@ void Assembler::returnFromFunction(IR::Ret *s, RegisterInfo ret(); exceptionReturnLabel = label(); - QV4::Primitive retVal = Primitive::undefinedValue(); + auto retVal = TargetPrimitive::undefinedValue(); RegisterSizeDependentOps::setFunctionReturnValueFromConst(this, retVal); jump(leaveStackFrame); } diff --git a/src/qml/jit/qv4assembler_p.h b/src/qml/jit/qv4assembler_p.h index ad6c29dd49..fed51e5e94 100644 --- a/src/qml/jit/qv4assembler_p.h +++ b/src/qml/jit/qv4assembler_p.h @@ -154,6 +154,7 @@ struct RegisterSizeDependentAssemblerstoreDouble(source, ptr); } - static void storeValue(JITAssembler *as, QV4::Primitive value, Address destination) + static void storeValue(JITAssembler *as, TargetPrimitive value, Address destination) { - as->store32(TrustedImm32(value.int_32()), destination); + as->store32(TrustedImm32(value.value()), destination); destination.offset += 4; as->store32(TrustedImm32(value.tag()), destination); } @@ -243,9 +244,9 @@ struct RegisterSizeDependentAssemblermove(TrustedImm32(retVal.int_32()), TargetPlatform::LowReturnValueRegister); + as->move(TrustedImm32(retVal.value()), TargetPlatform::LowReturnValueRegister); as->move(TrustedImm32(retVal.tag()), TargetPlatform::HighReturnValueRegister); } @@ -387,6 +388,7 @@ struct RegisterSizeDependentAssemblermove(TrustedImm64(retVal.rawValue()), TargetPlatform::ReturnValueRegister); } - static void storeValue(JITAssembler *as, QV4::Primitive value, Address destination) + static void storeValue(JITAssembler *as, TargetPrimitive value, Address destination) { as->store64(TrustedImm64(value.rawValue()), destination); } @@ -505,7 +507,7 @@ struct RegisterSizeDependentAssemblerloadTempAddress(temp); as->load64(addr, dest); } else { - QV4::Value undefined = QV4::Primitive::undefinedValue(); + auto undefined = TargetPrimitive::undefinedValue(); as->move(TrustedImm64(undefined.rawValue()), dest); } } @@ -518,7 +520,7 @@ struct RegisterSizeDependentAssemblerloadArgLocalAddress(dest, al); as->load64(addr, dest); } else { - QV4::Value undefined = QV4::Primitive::undefinedValue(); + auto undefined = TargetPrimitive::undefinedValue(); as->move(TrustedImm64(undefined.rawValue()), dest); } } @@ -527,7 +529,7 @@ struct RegisterSizeDependentAssembler(c); as->move(TrustedImm64(v.rawValue()), dest); } @@ -536,7 +538,7 @@ struct RegisterSizeDependentAssemblermove(TrustedImm64(undefined.rawValue()), dest); } else if (IR::Temp *t = expr->asTemp()){ loadArgumentInRegister(as, t, dest, argumentNumber); @@ -755,6 +757,7 @@ public: using RegisterSizeDependentOps = RegisterSizeDependentAssembler, MacroAssembler, JITTargetPlatform, RegisterSize>; using ValueTypeInternal = typename RegisterSizeDependentOps::ValueTypeInternal; + using TargetPrimitive = typename RegisterSizeDependentOps::TargetPrimitive; // V4 uses two stacks: one stack with QV4::Value items, which is checked by the garbage // collector, and one stack used by the native C/C++/ABI code. This C++ stack is not scanned @@ -978,7 +981,7 @@ public: Pointer loadArgLocalAddress(RegisterID baseReg, IR::ArgLocal *al); Pointer loadStringAddress(RegisterID reg, const QString &string); Address loadConstant(IR::Const *c, RegisterID baseReg); - Address loadConstant(const Primitive &v, RegisterID baseReg); + Address loadConstant(const TargetPrimitive &v, RegisterID baseReg); void loadStringRef(RegisterID reg, const QString &string); Pointer stackSlotPointer(IR::Temp *t) const { @@ -1240,12 +1243,12 @@ public: TargetConfiguration::MacroAssembler::storeDouble(fpScratchRegister, loadAddress(scratchRegister, target)); } - void storeValue(QV4::Primitive value, Address destination) + void storeValue(TargetPrimitive value, Address destination) { RegisterSizeDependentOps::storeValue(this, value, destination); } - void storeValue(QV4::Primitive value, IR::Expr* temp); + void storeValue(TargetPrimitive value, IR::Expr* temp); void enterStandardStackFrame(const RegisterInformation ®ularRegistersToSave, const RegisterInformation &fpRegistersToSave); @@ -1422,8 +1425,8 @@ public: Address tagAddr = addr; tagAddr.offset += 4; - QV4::Primitive v = convertToValue(c); - store32(TrustedImm32(v.int_32()), addr); + auto v = convertToValue(c); + store32(TrustedImm32(v.value()), addr); store32(TrustedImm32(v.tag()), tagAddr); return Pointer(addr); } @@ -1439,7 +1442,7 @@ public: { store32(reg, addr); addr.offset += 4; - store32(TrustedImm32(QV4::Primitive::fromBoolean(0).tag()), addr); + store32(TrustedImm32(TargetPrimitive::fromBoolean(0).tag()), addr); } void storeBool(RegisterID src, RegisterID dest) @@ -1483,7 +1486,7 @@ public: { store32(reg, addr); addr.offset += 4; - store32(TrustedImm32(QV4::Primitive::fromInt32(0).tag()), addr); + store32(TrustedImm32(TargetPrimitive::fromInt32(0).tag()), addr); } void storeInt32(RegisterID reg, IR::Expr *target) @@ -1552,7 +1555,7 @@ public: RegisterID toInt32Register(IR::Expr *e, RegisterID scratchReg) { if (IR::Const *c = e->asConst()) { - move(TrustedImm32(convertToValue(c).int_32()), scratchReg); + move(TrustedImm32(convertToValue(c).int_32()), scratchReg); return scratchReg; } @@ -1595,7 +1598,7 @@ public: // it's not in signed int range, so load it as a double, and truncate it down loadDouble(addr, FPGpr0); - Address inversionAddress = loadConstant(QV4::Primitive::fromDouble(double(INT_MAX) + 1), scratchReg); + Address inversionAddress = loadConstant(TargetPrimitive::fromDouble(double(INT_MAX) + 1), scratchReg); subDouble(inversionAddress, FPGpr0); Jump canNeverHappen = branchTruncateDoubleToUint32(FPGpr0, scratchReg); canNeverHappen.link(this); @@ -1675,7 +1678,7 @@ void Assembler::copyValue(Result result, IR::Expr* source) } else if (source->asTemp() || source->asArgLocal()) { RegisterSizeDependentOps::copyValueViaRegisters(this, source, result); } else if (IR::Const *c = source->asConst()) { - QV4::Primitive v = convertToValue(c); + auto v = convertToValue(c); storeValue(v, result); } else { Q_UNREACHABLE(); diff --git a/src/qml/jit/qv4isel_masm.cpp b/src/qml/jit/qv4isel_masm.cpp index 126fb4382b..dd48fdfc55 100644 --- a/src/qml/jit/qv4isel_masm.cpp +++ b/src/qml/jit/qv4isel_masm.cpp @@ -256,7 +256,7 @@ void InstructionSelection::callBuiltinDeleteName(const QString &na template void InstructionSelection::callBuiltinDeleteValue(IR::Expr *result) { - _as->storeValue(Primitive::fromBoolean(false), result); + _as->storeValue(JITAssembler::TargetPrimitive::fromBoolean(false), result); } template @@ -376,7 +376,7 @@ void InstructionSelection::callBuiltinDefineObjectLiteral(IR::Expr ++arrayValueCount; // Index - _as->storeValue(QV4::Primitive::fromUInt32(index), _as->stackLayout().argumentAddressForCall(argc++)); + _as->storeValue(JITAssembler::TargetPrimitive::fromUInt32(index), _as->stackLayout().argumentAddressForCall(argc++)); // Value _as->copyValue(_as->stackLayout().argumentAddressForCall(argc++), it->expr); @@ -400,7 +400,7 @@ void InstructionSelection::callBuiltinDefineObjectLiteral(IR::Expr ++arrayGetterSetterCount; // Index - _as->storeValue(QV4::Primitive::fromUInt32(index), _as->stackLayout().argumentAddressForCall(argc++)); + _as->storeValue(JITAssembler::TargetPrimitive::fromUInt32(index), _as->stackLayout().argumentAddressForCall(argc++)); // Getter _as->copyValue(_as->stackLayout().argumentAddressForCall(argc++), it->expr); @@ -486,7 +486,7 @@ void InstructionSelection::loadConst(IR::Const *sourceConst, IR::E _as->toUInt32Register(sourceConst, (RegisterID) targetTemp->index); } else if (targetTemp->type == IR::BoolType) { Q_ASSERT(sourceConst->type == IR::BoolType); - _as->move(TrustedImm32(convertToValue(sourceConst).int_32()), + _as->move(TrustedImm32(convertToValue(sourceConst).int_32()), (RegisterID) targetTemp->index); } else { Q_UNREACHABLE(); @@ -495,7 +495,7 @@ void InstructionSelection::loadConst(IR::Const *sourceConst, IR::E } } - _as->storeValue(convertToValue(sourceConst), target); + _as->storeValue(convertToValue(sourceConst), target); } template @@ -1320,7 +1320,7 @@ int InstructionSelection::prepareCallData(IR::ExprList* args, IR:: _as->store32(TrustedImm32(argc), p); p = _as->stackLayout().callDataAddress(offsetof(CallData, thisObject)); if (!thisObject) - _as->storeValue(QV4::Primitive::undefinedValue(), p); + _as->storeValue(JITAssembler::TargetPrimitive::undefinedValue(), p); else _as->copyValue(p, thisObject); -- cgit v1.2.3 From 0577c872a33156f7bb5a74c7ff874191a8d6f170 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 1 Apr 2017 21:05:09 -0700 Subject: Fix Clang warning about member in template class not defined qv4isel_masm.cpp:285:44: warning: instantiation of variable 'QV4::JIT::Assembler>::Void' required here, but no definition is available [-Wundefined-var-template] Depending on qv4assembler.cpp instantiating the same template that q4isel_masm.pp required is fragile. So move the definition to the header, next to the class. Change-Id: I27b55fdf514247549455fffd14b178ec9d4b508d Reviewed-by: Simon Hausmann --- src/qml/jit/qv4assembler.cpp | 3 --- src/qml/jit/qv4assembler_p.h | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/qml/jit') diff --git a/src/qml/jit/qv4assembler.cpp b/src/qml/jit/qv4assembler.cpp index da2cd49a63..0d06b421f6 100644 --- a/src/qml/jit/qv4assembler.cpp +++ b/src/qml/jit/qv4assembler.cpp @@ -155,9 +155,6 @@ bool CompilationUnit::saveCodeToDisk(QIODevice *device, const CompiledData::Unit return true; } -template -const typename Assembler::VoidType Assembler::Void; - template Assembler::Assembler(QV4::Compiler::JSUnitGenerator *jsGenerator, IR::Function* function, QV4::ExecutableAllocator *executableAllocator) : _function(function) diff --git a/src/qml/jit/qv4assembler_p.h b/src/qml/jit/qv4assembler_p.h index fed51e5e94..0570b9be2b 100644 --- a/src/qml/jit/qv4assembler_p.h +++ b/src/qml/jit/qv4assembler_p.h @@ -1653,6 +1653,9 @@ private: QV4::Compiler::JSUnitGenerator *_jsGenerator; }; +template +const typename Assembler::VoidType Assembler::Void; + template template void Assembler::copyValue(Result result, Source source) -- cgit v1.2.3 From 46c845826251e1da269b13219eedff4e16da7bf4 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 5 Apr 2017 15:50:13 +0200 Subject: Fix loading of strings when cross-compiling from 64-bit host to 32-bit The use of sizeof(Type*) is not allowed when calculating indices into pointer arrays. Change-Id: I5531efc80d0267eaceade76ad2b96d454eab9392 Reviewed-by: Lars Knoll --- src/qml/jit/qv4assembler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/qml/jit') diff --git a/src/qml/jit/qv4assembler.cpp b/src/qml/jit/qv4assembler.cpp index 0d06b421f6..3b9c2904dc 100644 --- a/src/qml/jit/qv4assembler.cpp +++ b/src/qml/jit/qv4assembler.cpp @@ -310,7 +310,7 @@ typename Assembler::Pointer Assembler: loadPtr(Address(Assembler::ScratchRegister, targetStructureOffset(Heap::ExecutionContext::baseOffset + offsetof(Heap::ExecutionContextData, compilationUnit))), Assembler::ScratchRegister); loadPtr(Address(Assembler::ScratchRegister, offsetof(CompiledData::CompilationUnitBase, runtimeStrings)), reg); const int id = _jsGenerator->registerString(string); - return Pointer(reg, id * sizeof(QV4::String*)); + return Pointer(reg, id * RegisterSize); } template -- cgit v1.2.3 From 7a368aaa1cb80b540898b77640dbe64034163526 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 5 Apr 2017 15:52:21 +0200 Subject: Fix engine parameter passing when cross-compiling We currently use addressForArgument() only to access the incoming functions parameters in JIT generated code, which is the engine parameter. While not currently supported by the current set of cross-compiling assemblers, the use of sizeof(Type*) may become an issue in the future, so let's use the correct value right away. Change-Id: I3e44279257f595a8be2c61bcfe15070a90038eb7 Reviewed-by: Lars Knoll --- src/qml/jit/qv4isel_masm_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/qml/jit') diff --git a/src/qml/jit/qv4isel_masm_p.h b/src/qml/jit/qv4isel_masm_p.h index 5c046cb397..0992e96e8b 100644 --- a/src/qml/jit/qv4isel_masm_p.h +++ b/src/qml/jit/qv4isel_masm_p.h @@ -160,7 +160,7 @@ protected: // FramePointerRegister points to its old value on the stack, and above // it we have the return address, hence the need to step over two // values before reaching the first argument. - return Address(JITTargetPlatform::FramePointerRegister, (index + 2) * sizeof(void*)); + return Address(JITTargetPlatform::FramePointerRegister, (index + 2) * JITTargetPlatform::RegisterSize); } Pointer baseAddressForCallArguments() -- cgit v1.2.3 From 5dcd95e376b42e72d5386345dbf65dffb811f1ad Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 5 Apr 2017 15:56:43 +0200 Subject: Fix architecture selection when cross-compiling cache files We pass essentially the values of QSysInfo::buildCpuArchitecture() to qmlcachgen as command line parameters, so our factory function must be aligned with the values returned (and documented) there. That means arm instead of armv7, arm64 instead of armv8 and i386 instead of x86. Change-Id: I89c196b6585f9ba9550c0deb17e8b529980aa448 Reviewed-by: Lars Knoll --- src/qml/jit/qv4isel_masm.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/qml/jit') diff --git a/src/qml/jit/qv4isel_masm.cpp b/src/qml/jit/qv4isel_masm.cpp index dd48fdfc55..7797f8c8db 100644 --- a/src/qml/jit/qv4isel_masm.cpp +++ b/src/qml/jit/qv4isel_masm.cpp @@ -1641,18 +1641,18 @@ Q_QML_EXPORT QV4::EvalISelFactory *createISelForArchitecture(const QString &arch using ARMv7CrossAssembler = QV4::JIT::Assembler>; using ARM64CrossAssembler = QV4::JIT::Assembler>; - if (architecture == QLatin1String("armv7")) + if (architecture == QLatin1String("arm")) return new ISelFactory; - else if (architecture == QLatin1String("armv8")) + else if (architecture == QLatin1String("arm64")) return new ISelFactory; QString hostArch; #if CPU(ARM_THUMB2) - hostArch = QStringLiteral("armv7"); + hostArch = QStringLiteral("arm"); #elif CPU(MIPS) hostArch = QStringLiteral("mips"); #elif CPU(X86) - hostArch = QStringLiteral("x86"); + hostArch = QStringLiteral("i386"); #elif CPU(X86_64) hostArch = QStringLiteral("x86_64"); #endif -- cgit v1.2.3 From 0518ba4d2a1156c316a7bd251210837acd84bf48 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Tue, 4 Apr 2017 15:59:50 +0200 Subject: Fix shadow stack space handling when cross-compiling Both MIPS and X86-64 on Windows reserve space for four registers on the stack, that the called function may use to spill the parameters passed in registers. This needs to be handled without #ifdefs in order to support cross-compilation and from the looks of it it was also wrong on MIPS. Change-Id: If65a6a0f6f64b8536703d32e7678e30ad807f7c8 Reviewed-by: Julien Brianceau Reviewed-by: Lars Knoll --- src/qml/jit/qv4assembler_p.h | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'src/qml/jit') diff --git a/src/qml/jit/qv4assembler_p.h b/src/qml/jit/qv4assembler_p.h index 0570b9be2b..b512398966 100644 --- a/src/qml/jit/qv4assembler_p.h +++ b/src/qml/jit/qv4assembler_p.h @@ -1277,13 +1277,7 @@ public: if (argumentNumber < RegisterArgumentCount) loadArgumentInRegister(value, registerForArgument(argumentNumber), argumentNumber); else -#if OS(WINDOWS) && CPU(X86_64) - loadArgumentOnStack(value, argumentNumber); -#elif CPU(MIPS) // Stack space for 4 arguments needs to be allocated for MIPS platforms. - loadArgumentOnStack(value, argumentNumber + 4); -#else // Sanity: - loadArgumentOnStack(value, argumentNumber); -#endif + loadArgumentOnStack(value, argumentNumber); } template -- cgit v1.2.3 From 028a85f4f462093ca93ae95865eb6cbcbaec199a Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 3 Apr 2017 15:31:57 +0200 Subject: Fix double conversion code generation when cross-compiling We can't use QV4_USE_64_BIT_VALUE_ENCODING for deciding how generate code for checking if the tag of a value contains the necessary mask to detect doubles. Change-Id: Id5a5c1b136313aa4dfd2c997898e97cd4ebaeb83 Reviewed-by: Lars Knoll --- src/qml/jit/qv4assembler.cpp | 8 +------- src/qml/jit/qv4assembler_p.h | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 7 deletions(-) (limited to 'src/qml/jit') diff --git a/src/qml/jit/qv4assembler.cpp b/src/qml/jit/qv4assembler.cpp index 3b9c2904dc..71dabcd590 100644 --- a/src/qml/jit/qv4assembler.cpp +++ b/src/qml/jit/qv4assembler.cpp @@ -440,13 +440,7 @@ typename Assembler::Jump Assembler::ge // not an int, check if it's a double: isNoInt.link(this); -#ifdef QV4_USE_64_BIT_VALUE_ENCODING - rshift32(TrustedImm32(Value::IsDoubleTag_Shift), ScratchRegister); - Assembler::Jump isNoDbl = branch32(RelationalCondition::Equal, JITTargetPlatform::ScratchRegister, TrustedImm32(0)); -#else - and32(Assembler::TrustedImm32(Value::NotDouble_Mask), Assembler::ScratchRegister); - Assembler::Jump isNoDbl = branch32(RelationalCondition::Equal, JITTargetPlatform::ScratchRegister, TrustedImm32(Value::NotDouble_Mask)); -#endif + Assembler::Jump isNoDbl = RegisterSizeDependentOps::checkIfTagRegisterIsDouble(this, ScratchRegister); toDoubleRegister(src, dest); intDone.link(this); diff --git a/src/qml/jit/qv4assembler_p.h b/src/qml/jit/qv4assembler_p.h index b512398966..8b5b307e84 100644 --- a/src/qml/jit/qv4assembler_p.h +++ b/src/qml/jit/qv4assembler_p.h @@ -370,6 +370,13 @@ struct RegisterSizeDependentAssemblerbranchSub32(ResultCondition::NonZero, TrustedImm32(1), TargetPlatform::ScratchRegister); jump.linkTo(loop, as); } + + static Jump checkIfTagRegisterIsDouble(JITAssembler *as, RegisterID tagRegister) + { + as->and32(TrustedImm32(Value::NotDouble_Mask), tagRegister); + Jump isNoDbl = as->branch32(RelationalCondition::Equal, tagRegister, TrustedImm32(Value::NotDouble_Mask)); + return isNoDbl; + } }; template @@ -657,6 +664,13 @@ struct RegisterSizeDependentAssemblerbranchSub32(ResultCondition::NonZero, TrustedImm32(1), TargetPlatform::ScratchRegister); jump.linkTo(loop, as); } + + static Jump checkIfTagRegisterIsDouble(JITAssembler *as, RegisterID tagRegister) + { + as->rshift32(TrustedImm32(Value::IsDoubleTag_Shift), tagRegister); + Jump isNoDbl = as->branch32(RelationalCondition::Equal, tagRegister, TrustedImm32(0)); + return isNoDbl; + } }; template -- cgit v1.2.3 From 7c709ee4404e737bebd576c4a1782593a6ec7da0 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Thu, 6 Apr 2017 15:48:12 +0200 Subject: Fix locals register allocation on ARM when cross-compiling r11 needs to be saved :). This ammends ecda87091f290daec34bee6b55dd9cf920ffdcff Change-Id: Ib69712527e04b9bcec4c9e74dea43a915e2bd0f9 Reviewed-by: Robin Burchell --- src/qml/jit/qv4targetplatform_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/qml/jit') diff --git a/src/qml/jit/qv4targetplatform_p.h b/src/qml/jit/qv4targetplatform_p.h index ce6156802d..6d788f4a93 100644 --- a/src/qml/jit/qv4targetplatform_p.h +++ b/src/qml/jit/qv4targetplatform_p.h @@ -405,7 +405,7 @@ public: << RI(JSC::ARMRegisters::r9, QStringLiteral("r9"), RI::RegularRegister, RI::CalleeSaved, RI::RegAlloc) #endif << RI(JSC::ARMRegisters::r10, QStringLiteral("r10"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined) -#if CPU(ARM_THUMB2) && !defined(V4_BOOTSTRAP) +#if CPU(ARM_THUMB2) || defined(V4_BOOTSTRAP) << RI(JSC::ARMRegisters::r11, QStringLiteral("r11"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined) #endif << RI(JSC::ARMRegisters::d2, QStringLiteral("d2"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc) -- cgit v1.2.3