diff options
author | Simon Hausmann <simon.hausmann@qt.io> | 2017-01-17 16:57:28 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2017-01-31 13:40:26 +0000 |
commit | c9916e003929a94a2abd65ee685c2b9b146fd0fc (patch) | |
tree | c68686e45ecb45f5bbd11986c703ae3381bbd800 /src/qml/jit/qv4assembler_p.h | |
parent | ea06fdf810759c21f8b9af4f639ea23e40c6ba2c (diff) |
Remove 64-/32-bit platform ifdef in assembler instruction selection
We can replace that code with a compile-time if statement where the
compiler will throw away the unused part.
Change-Id: I827633a14b3025bb7acaef6f85a52682d6df3da1
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/qml/jit/qv4assembler_p.h')
-rw-r--r-- | src/qml/jit/qv4assembler_p.h | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/src/qml/jit/qv4assembler_p.h b/src/qml/jit/qv4assembler_p.h index 6dee0d4b0a..ddd1463cec 100644 --- a/src/qml/jit/qv4assembler_p.h +++ b/src/qml/jit/qv4assembler_p.h @@ -136,6 +136,7 @@ struct RegisterSizeDependentAssembler<JITAssembler, MacroAssembler, TargetPlatfo using Pointer = typename JITAssembler::Pointer; using TrustedImm32 = typename JITAssembler::TrustedImm32; using TrustedImm64 = typename JITAssembler::TrustedImm64; + using Jump = typename JITAssembler::Jump; static void loadDouble(JITAssembler *as, Address addr, FPRegisterID dest) { @@ -230,6 +231,39 @@ struct RegisterSizeDependentAssembler<JITAssembler, MacroAssembler, TargetPlatfo Q_UNUSED(cond); Q_ASSERT(!"unimplemented generateCJumpOnCompare with TrustedImm64 for 32-bit"); } + + static void convertVarToSInt32(JITAssembler *as, IR::Expr *source, IR::Expr *target) + { + Q_ASSERT(source->type == IR::VarType); + // load the tag: + Pointer addr = as->loadAddress(TargetPlatform::ScratchRegister, source); + Pointer tagAddr = addr; + tagAddr.offset += 4; + as->load32(tagAddr, TargetPlatform::ReturnValueRegister); + + // check if it's an int32: + Jump fallback = as->branch32(RelationalCondition::NotEqual, TargetPlatform::ReturnValueRegister, + TrustedImm32(Value::Integer_Type_Internal)); + 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); + } else { + as->load32(addr, (RegisterID) targetTemp->index); + } + Jump intDone = as->jump(); + + // not an int: + fallback.link(as); + generateRuntimeCall(as, TargetPlatform::ReturnValueRegister, toInt, + as->loadAddress(TargetPlatform::ScratchRegister, source)); + as->storeInt32(TargetPlatform::ReturnValueRegister, target); + + intDone.link(as); + } }; template <typename JITAssembler, typename MacroAssembler, typename TargetPlatform> @@ -238,9 +272,11 @@ struct RegisterSizeDependentAssembler<JITAssembler, MacroAssembler, TargetPlatfo using RegisterID = typename JITAssembler::RegisterID; using FPRegisterID = typename JITAssembler::FPRegisterID; using Address = typename JITAssembler::Address; + using TrustedImm32 = typename JITAssembler::TrustedImm32; using TrustedImm64 = typename JITAssembler::TrustedImm64; using Pointer = typename JITAssembler::Pointer; using RelationalCondition = typename JITAssembler::RelationalCondition; + using BranchTruncateType = typename JITAssembler::BranchTruncateType; using Jump = typename JITAssembler::Jump; static void loadDouble(JITAssembler *as, Address addr, FPRegisterID dest) @@ -373,6 +409,50 @@ struct RegisterSizeDependentAssembler<JITAssembler, MacroAssembler, TargetPlatfo as->jumpToBlock(currentBlock, falseBlock); } } + + static void convertVarToSInt32(JITAssembler *as, IR::Expr *source, IR::Expr *target) + { + Q_ASSERT(source->type == IR::VarType); + Pointer addr = as->loadAddress(TargetPlatform::ScratchRegister, source); + as->load64(addr, TargetPlatform::ScratchRegister); + as->move(TargetPlatform::ScratchRegister, TargetPlatform::ReturnValueRegister); + + // check if it's integer convertible + as->urshift64(TrustedImm32(QV4::Value::IsIntegerConvertible_Shift), TargetPlatform::ScratchRegister); + Jump isIntConvertible = as->branch32(RelationalCondition::Equal, TargetPlatform::ScratchRegister, TrustedImm32(3)); + + // nope, not integer convertible, so check for a double: + as->urshift64(TrustedImm32( + QV4::Value::IsDoubleTag_Shift - QV4::Value::IsIntegerConvertible_Shift), + TargetPlatform::ScratchRegister); + Jump fallback = as->branch32(RelationalCondition::GreaterThan, TargetPlatform::ScratchRegister, TrustedImm32(0)); + + // it's a double + as->move(TrustedImm64(QV4::Value::NaNEncodeMask), TargetPlatform::ScratchRegister); + as->xor64(TargetPlatform::ScratchRegister, TargetPlatform::ReturnValueRegister); + as->move64ToDouble(TargetPlatform::ReturnValueRegister, TargetPlatform::FPGpr0); + Jump success = + as->branchTruncateDoubleToInt32(TargetPlatform::FPGpr0, TargetPlatform::ReturnValueRegister, + BranchTruncateType::BranchIfTruncateSuccessful); + + // not an int: + fallback.link(as); + generateRuntimeCall(as, TargetPlatform::ReturnValueRegister, toInt, + as->loadAddress(TargetPlatform::ScratchRegister, source)); + + + isIntConvertible.link(as); + success.link(as); + IR::Temp *targetTemp = target->asTemp(); + if (!targetTemp || targetTemp->kind == IR::Temp::StackSlot) { + Pointer targetAddr = as->loadAddress(TargetPlatform::ScratchRegister, target); + as->store32(TargetPlatform::ReturnValueRegister, targetAddr); + targetAddr.offset += 4; + as->store32(TrustedImm32(Value::Integer_Type_Internal), targetAddr); + } else { + as->storeInt32(TargetPlatform::ReturnValueRegister, target); + } + } }; template <typename TargetConfiguration> |