From a11278570d6eb3766da6277ccbce0aa96e820d0c Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Tue, 10 Jan 2017 16:48:43 +0100 Subject: Make binop and unop a template Change-Id: I220505e6dc7f1401875b13a280a1b96ab8997783 Reviewed-by: Lars Knoll --- src/qml/jit/qv4binop.cpp | 103 +++++++++++++++++++++++-------------------- src/qml/jit/qv4binop_p.h | 67 ++++++++++++++-------------- src/qml/jit/qv4isel_masm.cpp | 4 +- src/qml/jit/qv4unop.cpp | 52 ++++++++++++---------- src/qml/jit/qv4unop_p.h | 12 +++-- 5 files changed, 128 insertions(+), 110 deletions(-) diff --git a/src/qml/jit/qv4binop.cpp b/src/qml/jit/qv4binop.cpp index 4ced79318f..df19ddb31c 100644 --- a/src/qml/jit/qv4binop.cpp +++ b/src/qml/jit/qv4binop.cpp @@ -57,7 +57,8 @@ using namespace JIT; #define NULL_OP \ { 0, 0, 0, 0, 0, false } -const Binop::OpInfo Binop::operations[IR::LastAluOp + 1] = { +template +const typename Binop::OpInfo Binop::operations[IR::LastAluOp + 1] = { NULL_OP, // OpInvalid NULL_OP, // OpIfTrue NULL_OP, // OpNot @@ -67,20 +68,20 @@ const Binop::OpInfo Binop::operations[IR::LastAluOp + 1] = { NULL_OP, // OpIncrement NULL_OP, // OpDecrement - INLINE_OP(bitAnd, &Binop::inline_and32, &Binop::inline_and32), // OpBitAnd - INLINE_OP(bitOr, &Binop::inline_or32, &Binop::inline_or32), // OpBitOr - INLINE_OP(bitXor, &Binop::inline_xor32, &Binop::inline_xor32), // OpBitXor + INLINE_OP(bitAnd, &Binop::inline_and32, &Binop::inline_and32), // OpBitAnd + INLINE_OP(bitOr, &Binop::inline_or32, &Binop::inline_or32), // OpBitOr + INLINE_OP(bitXor, &Binop::inline_xor32, &Binop::inline_xor32), // OpBitXor - INLINE_OPCONTEXT(add, &Binop::inline_add32, &Binop::inline_add32), // OpAdd - INLINE_OP(sub, &Binop::inline_sub32, &Binop::inline_sub32), // OpSub - INLINE_OP(mul, &Binop::inline_mul32, &Binop::inline_mul32), // OpMul + INLINE_OPCONTEXT(add, &Binop::inline_add32, &Binop::inline_add32), // OpAdd + INLINE_OP(sub, &Binop::inline_sub32, &Binop::inline_sub32), // OpSub + INLINE_OP(mul, &Binop::inline_mul32, &Binop::inline_mul32), // OpMul OP(div), // OpDiv OP(mod), // OpMod - INLINE_OP(shl, &Binop::inline_shl32, &Binop::inline_shl32), // OpLShift - INLINE_OP(shr, &Binop::inline_shr32, &Binop::inline_shr32), // OpRShift - INLINE_OP(ushr, &Binop::inline_ushr32, &Binop::inline_ushr32), // OpURShift + INLINE_OP(shl, &Binop::inline_shl32, &Binop::inline_shl32), // OpLShift + INLINE_OP(shr, &Binop::inline_shr32, &Binop::inline_shr32), // OpRShift + INLINE_OP(ushr, &Binop::inline_ushr32, &Binop::inline_ushr32), // OpURShift OP(greaterThan), // OpGt OP(lessThan), // OpLt @@ -100,7 +101,8 @@ const Binop::OpInfo Binop::operations[IR::LastAluOp + 1] = { -void Binop::generate(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target) +template +void Binop::generate(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target) { if (op != IR::OpMod && lhs->type == IR::DoubleType && rhs->type == IR::DoubleType) { @@ -125,15 +127,15 @@ void Binop::generate(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target) info = stringAdd; } - Assembler::RuntimeCall fallBack(info.fallbackImplementation); - Assembler::RuntimeCall context(info.contextImplementation); + typename JITAssembler::RuntimeCall fallBack(info.fallbackImplementation); + typename JITAssembler::RuntimeCall context(info.contextImplementation); if (fallBack.isValid()) { as->generateFunctionCallImp(info.needsExceptionCheck, target, info.name, fallBack, PointerToValue(lhs), PointerToValue(rhs)); } else if (context.isValid()) { as->generateFunctionCallImp(info.needsExceptionCheck, target, info.name, context, - Assembler::EngineRegister, + JITAssembler::EngineRegister, PointerToValue(lhs), PointerToValue(rhs)); } else { @@ -145,14 +147,15 @@ void Binop::generate(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target) } -void Binop::doubleBinop(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target) +template +void Binop::doubleBinop(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target) { IR::Temp *targetTemp = target->asTemp(); FPRegisterID targetReg; if (targetTemp && targetTemp->kind == IR::Temp::PhysicalRegister) targetReg = (FPRegisterID) targetTemp->index; else - targetReg = Assembler::FPGpr0; + targetReg = JITAssembler::FPGpr0; switch (op) { case IR::OpAdd: @@ -162,7 +165,7 @@ void Binop::doubleBinop(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target) #if CPU(X86) if (IR::Const *c = rhs->asConst()) { // Y = X + constant -> Y = X; Y += [constant-address] as->moveDouble(as->toDoubleRegister(lhs, targetReg), targetReg); - Address addr = as->loadConstant(c, Assembler::ScratchRegister); + Address addr = as->loadConstant(c, JITAssembler::ScratchRegister); as->addDouble(addr, targetReg); break; } @@ -174,7 +177,7 @@ void Binop::doubleBinop(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target) } } #endif - as->addDouble(as->toDoubleRegister(lhs, Assembler::FPGpr0), as->toDoubleRegister(rhs, Assembler::FPGpr1), targetReg); + as->addDouble(as->toDoubleRegister(lhs, JITAssembler::FPGpr0), as->toDoubleRegister(rhs, JITAssembler::FPGpr1), targetReg); break; case IR::OpMul: @@ -184,7 +187,7 @@ void Binop::doubleBinop(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target) #if CPU(X86) if (IR::Const *c = rhs->asConst()) { // Y = X * constant -> Y = X; Y *= [constant-address] as->moveDouble(as->toDoubleRegister(lhs, targetReg), targetReg); - Address addr = as->loadConstant(c, Assembler::ScratchRegister); + Address addr = as->loadConstant(c, JITAssembler::ScratchRegister); as->mulDouble(addr, targetReg); break; } @@ -196,14 +199,14 @@ void Binop::doubleBinop(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target) } } #endif - as->mulDouble(as->toDoubleRegister(lhs, Assembler::FPGpr0), as->toDoubleRegister(rhs, Assembler::FPGpr1), targetReg); + as->mulDouble(as->toDoubleRegister(lhs, JITAssembler::FPGpr0), as->toDoubleRegister(rhs, JITAssembler::FPGpr1), targetReg); break; case IR::OpSub: #if CPU(X86) if (IR::Const *c = rhs->asConst()) { // Y = X - constant -> Y = X; Y -= [constant-address] as->moveDouble(as->toDoubleRegister(lhs, targetReg), targetReg); - Address addr = as->loadConstant(c, Assembler::ScratchRegister); + Address addr = as->loadConstant(c, JITAssembler::ScratchRegister); as->subDouble(addr, targetReg); break; } @@ -219,19 +222,19 @@ void Binop::doubleBinop(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target) && targetTemp && targetTemp->kind == IR::Temp::PhysicalRegister && targetTemp->index == rhs->asTemp()->index) { // Y = X - Y -> Tmp = Y; Y = X - Tmp - as->moveDouble(as->toDoubleRegister(rhs, Assembler::FPGpr1), Assembler::FPGpr1); - as->subDouble(as->toDoubleRegister(lhs, Assembler::FPGpr0), Assembler::FPGpr1, targetReg); + as->moveDouble(as->toDoubleRegister(rhs, JITAssembler::FPGpr1), JITAssembler::FPGpr1); + as->subDouble(as->toDoubleRegister(lhs, JITAssembler::FPGpr0), JITAssembler::FPGpr1, targetReg); break; } - as->subDouble(as->toDoubleRegister(lhs, Assembler::FPGpr0), as->toDoubleRegister(rhs, Assembler::FPGpr1), targetReg); + as->subDouble(as->toDoubleRegister(lhs, JITAssembler::FPGpr0), as->toDoubleRegister(rhs, JITAssembler::FPGpr1), targetReg); break; case IR::OpDiv: #if CPU(X86) if (IR::Const *c = rhs->asConst()) { // Y = X / constant -> Y = X; Y /= [constant-address] as->moveDouble(as->toDoubleRegister(lhs, targetReg), targetReg); - Address addr = as->loadConstant(c, Assembler::ScratchRegister); + Address addr = as->loadConstant(c, JITAssembler::ScratchRegister); as->divDouble(addr, targetReg); break; } @@ -248,12 +251,12 @@ void Binop::doubleBinop(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target) && targetTemp && targetTemp->kind == IR::Temp::PhysicalRegister && targetTemp->index == rhs->asTemp()->index) { // Y = X / Y -> Tmp = Y; Y = X / Tmp - as->moveDouble(as->toDoubleRegister(rhs, Assembler::FPGpr1), Assembler::FPGpr1); - as->divDouble(as->toDoubleRegister(lhs, Assembler::FPGpr0), Assembler::FPGpr1, targetReg); + as->moveDouble(as->toDoubleRegister(rhs, JITAssembler::FPGpr1), JITAssembler::FPGpr1); + as->divDouble(as->toDoubleRegister(lhs, JITAssembler::FPGpr0), JITAssembler::FPGpr1, targetReg); break; } - as->divDouble(as->toDoubleRegister(lhs, Assembler::FPGpr0), as->toDoubleRegister(rhs, Assembler::FPGpr1), targetReg); + as->divDouble(as->toDoubleRegister(lhs, JITAssembler::FPGpr0), as->toDoubleRegister(rhs, JITAssembler::FPGpr1), targetReg); break; default: { @@ -271,8 +274,8 @@ void Binop::doubleBinop(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target) as->storeDouble(targetReg, target); } - -bool Binop::int32Binop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *target) +template +bool Binop::int32Binop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *target) { Q_ASSERT(leftSource->type == IR::SInt32Type); Q_ASSERT(rightSource->type == IR::SInt32Type); @@ -305,7 +308,7 @@ bool Binop::int32Binop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *ta bool inplaceOpWithAddress = false; IR::Temp *targetTemp = target->asTemp(); - RegisterID targetReg = Assembler::ReturnValueRegister; + RegisterID targetReg = JITAssembler::ReturnValueRegister; if (targetTemp && targetTemp->kind == IR::Temp::PhysicalRegister) { IR::Temp *rhs = rightSource->asTemp(); if (!rhs || rhs->kind != IR::Temp::PhysicalRegister || rhs->index != targetTemp->index) { @@ -369,12 +372,12 @@ bool Binop::int32Binop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *ta && targetTemp->index == rightSource->asTemp()->index) { // X = Y - X -> Tmp = X; X = Y; X -= Tmp targetReg = (RegisterID) targetTemp->index; - as->move(targetReg, Assembler::ScratchRegister); + as->move(targetReg, JITAssembler::ScratchRegister); as->move(as->toInt32Register(leftSource, targetReg), targetReg); - as->sub32(Assembler::ScratchRegister, targetReg); + as->sub32(JITAssembler::ScratchRegister, targetReg); } else { as->move(as->toInt32Register(leftSource, targetReg), targetReg); - as->sub32(as->toInt32Register(rightSource, Assembler::ScratchRegister), targetReg); + as->sub32(as->toInt32Register(rightSource, JITAssembler::ScratchRegister), targetReg); } as->storeInt32(targetReg, target); return true; @@ -419,7 +422,7 @@ bool Binop::int32Binop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *ta return false; } } else if (inplaceOpWithAddress) { // All cases of X = X op [address-of-Y] - Pointer rhsAddr = as->loadAddress(Assembler::ScratchRegister, rightSource); + Pointer rhsAddr = as->loadAddress(JITAssembler::ScratchRegister, rightSource); switch (op) { case IR::OpBitAnd: as->and32(rhsAddr, targetReg); break; case IR::OpBitOr: as->or32 (rhsAddr, targetReg); break; @@ -433,7 +436,7 @@ bool Binop::int32Binop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *ta return false; } } else { // All cases of Z = X op Y - RegisterID r = as->toInt32Register(rightSource, Assembler::ScratchRegister); + RegisterID r = as->toInt32Register(rightSource, JITAssembler::ScratchRegister); switch (op) { case IR::OpBitAnd: as->and32(l, r, targetReg); break; case IR::OpBitOr: as->or32 (l, r, targetReg); break; @@ -481,17 +484,19 @@ bool Binop::int32Binop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *ta return true; } -static inline Assembler::FPRegisterID getFreeFPReg(IR::Expr *shouldNotOverlap, unsigned hint) +template +inline typename JITAssembler::FPRegisterID getFreeFPReg(IR::Expr *shouldNotOverlap, unsigned hint) { if (IR::Temp *t = shouldNotOverlap->asTemp()) if (t->type == IR::DoubleType) if (t->kind == IR::Temp::PhysicalRegister) if (t->index == hint) - return Assembler::FPRegisterID(hint + 1); - return Assembler::FPRegisterID(hint); + return typename JITAssembler::FPRegisterID(hint + 1); + return typename JITAssembler::FPRegisterID(hint); } -Assembler::Jump Binop::genInlineBinop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *target) +template +typename JITAssembler::Jump Binop::genInlineBinop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *target) { Jump done; @@ -505,8 +510,8 @@ Assembler::Jump Binop::genInlineBinop(IR::Expr *leftSource, IR::Expr *rightSourc // register. switch (op) { case IR::OpAdd: { - FPRegisterID lReg = getFreeFPReg(rightSource, 2); - FPRegisterID rReg = getFreeFPReg(leftSource, 4); + FPRegisterID lReg = getFreeFPReg(rightSource, 2); + FPRegisterID rReg = getFreeFPReg(leftSource, 4); Jump leftIsNoDbl = as->genTryDoubleConversion(leftSource, lReg); Jump rightIsNoDbl = as->genTryDoubleConversion(rightSource, rReg); @@ -520,8 +525,8 @@ Assembler::Jump Binop::genInlineBinop(IR::Expr *leftSource, IR::Expr *rightSourc rightIsNoDbl.link(as); } break; case IR::OpMul: { - FPRegisterID lReg = getFreeFPReg(rightSource, 2); - FPRegisterID rReg = getFreeFPReg(leftSource, 4); + FPRegisterID lReg = getFreeFPReg(rightSource, 2); + FPRegisterID rReg = getFreeFPReg(leftSource, 4); Jump leftIsNoDbl = as->genTryDoubleConversion(leftSource, lReg); Jump rightIsNoDbl = as->genTryDoubleConversion(rightSource, rReg); @@ -535,8 +540,8 @@ Assembler::Jump Binop::genInlineBinop(IR::Expr *leftSource, IR::Expr *rightSourc rightIsNoDbl.link(as); } break; case IR::OpSub: { - FPRegisterID lReg = getFreeFPReg(rightSource, 2); - FPRegisterID rReg = getFreeFPReg(leftSource, 4); + FPRegisterID lReg = getFreeFPReg(rightSource, 2); + FPRegisterID rReg = getFreeFPReg(leftSource, 4); Jump leftIsNoDbl = as->genTryDoubleConversion(leftSource, lReg); Jump rightIsNoDbl = as->genTryDoubleConversion(rightSource, rReg); @@ -550,8 +555,8 @@ Assembler::Jump Binop::genInlineBinop(IR::Expr *leftSource, IR::Expr *rightSourc rightIsNoDbl.link(as); } break; case IR::OpDiv: { - FPRegisterID lReg = getFreeFPReg(rightSource, 2); - FPRegisterID rReg = getFreeFPReg(leftSource, 4); + FPRegisterID lReg = getFreeFPReg(rightSource, 2); + FPRegisterID rReg = getFreeFPReg(leftSource, 4); Jump leftIsNoDbl = as->genTryDoubleConversion(leftSource, lReg); Jump rightIsNoDbl = as->genTryDoubleConversion(rightSource, rReg); @@ -571,4 +576,6 @@ Assembler::Jump Binop::genInlineBinop(IR::Expr *leftSource, IR::Expr *rightSourc return done; } +template struct QV4::JIT::Binop; + #endif diff --git a/src/qml/jit/qv4binop_p.h b/src/qml/jit/qv4binop_p.h index 3742e99e5a..d2d9ba7753 100644 --- a/src/qml/jit/qv4binop_p.h +++ b/src/qml/jit/qv4binop_p.h @@ -61,21 +61,22 @@ QT_BEGIN_NAMESPACE namespace QV4 { namespace JIT { +template struct Binop { - Binop(Assembler *assembler, IR::AluOp operation) + Binop(JITAssembler *assembler, IR::AluOp operation) : as(assembler) , op(operation) {} - using Jump = Assembler::Jump; - using Address = Assembler::Address; - using RegisterID = Assembler::RegisterID; - using FPRegisterID = Assembler::FPRegisterID; - using TrustedImm32 = Assembler::TrustedImm32; - using ResultCondition = Assembler::ResultCondition; - using RelationalCondition = Assembler::RelationalCondition; - using Pointer = Assembler::Pointer; - using PointerToValue = Assembler::PointerToValue; + using Jump = typename JITAssembler::Jump; + using Address = typename JITAssembler::Address; + using RegisterID = typename JITAssembler::RegisterID; + using FPRegisterID = typename JITAssembler::FPRegisterID; + using TrustedImm32 = typename JITAssembler::TrustedImm32; + using ResultCondition = typename JITAssembler::ResultCondition; + using RelationalCondition = typename JITAssembler::RelationalCondition; + using Pointer = typename JITAssembler::Pointer; + using PointerToValue = typename JITAssembler::PointerToValue; void generate(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target); void doubleBinop(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target); @@ -103,8 +104,8 @@ struct Binop { #if HAVE(ALU_OPS_WITH_MEM_OPERAND) return as->branchAdd32(ResultCondition::Overflow, addr, reg); #else - as->load32(addr, Assembler::ScratchRegister); - return as->branchAdd32(ResultCondition::Overflow, Assembler::ScratchRegister, reg); + as->load32(addr, JITAssembler::ScratchRegister); + return as->branchAdd32(ResultCondition::Overflow, JITAssembler::ScratchRegister, reg); #endif } @@ -118,8 +119,8 @@ struct Binop { #if HAVE(ALU_OPS_WITH_MEM_OPERAND) return as->branchSub32(ResultCondition::Overflow, addr, reg); #else - as->load32(addr, Assembler::ScratchRegister); - return as->branchSub32(ResultCondition::Overflow, Assembler::ScratchRegister, reg); + as->load32(addr, JITAssembler::ScratchRegister); + return as->branchSub32(ResultCondition::Overflow, JITAssembler::ScratchRegister, reg); #endif } @@ -131,10 +132,10 @@ struct Binop { Jump inline_mul32(Address addr, RegisterID reg) { #if HAVE(ALU_OPS_WITH_MEM_OPERAND) - return as->branchMul32(Assembler::Overflow, addr, reg); + return as->branchMul32(JITAssembler::Overflow, addr, reg); #else - as->load32(addr, Assembler::ScratchRegister); - return as->branchMul32(ResultCondition::Overflow, Assembler::ScratchRegister, reg); + as->load32(addr, JITAssembler::ScratchRegister); + return as->branchMul32(ResultCondition::Overflow, JITAssembler::ScratchRegister, reg); #endif } @@ -145,9 +146,9 @@ struct Binop { Jump inline_shl32(Address addr, RegisterID reg) { - as->load32(addr, Assembler::ScratchRegister); - as->and32(TrustedImm32(0x1f), Assembler::ScratchRegister); - as->lshift32(Assembler::ScratchRegister, reg); + as->load32(addr, JITAssembler::ScratchRegister); + as->and32(TrustedImm32(0x1f), JITAssembler::ScratchRegister); + as->lshift32(JITAssembler::ScratchRegister, reg); return Jump(); } @@ -160,9 +161,9 @@ struct Binop { Jump inline_shr32(Address addr, RegisterID reg) { - as->load32(addr, Assembler::ScratchRegister); - as->and32(TrustedImm32(0x1f), Assembler::ScratchRegister); - as->rshift32(Assembler::ScratchRegister, reg); + as->load32(addr, JITAssembler::ScratchRegister); + as->and32(TrustedImm32(0x1f), JITAssembler::ScratchRegister); + as->rshift32(JITAssembler::ScratchRegister, reg); return Jump(); } @@ -175,9 +176,9 @@ struct Binop { Jump inline_ushr32(Address addr, RegisterID reg) { - as->load32(addr, Assembler::ScratchRegister); - as->and32(TrustedImm32(0x1f), Assembler::ScratchRegister); - as->urshift32(Assembler::ScratchRegister, reg); + as->load32(addr, JITAssembler::ScratchRegister); + as->and32(TrustedImm32(0x1f), JITAssembler::ScratchRegister); + as->urshift32(JITAssembler::ScratchRegister, reg); return as->branchTest32(ResultCondition::Signed, reg, reg); } @@ -193,8 +194,8 @@ struct Binop { #if HAVE(ALU_OPS_WITH_MEM_OPERAND) as->and32(addr, reg); #else - as->load32(addr, Assembler::ScratchRegister); - as->and32(Assembler::ScratchRegister, reg); + as->load32(addr, JITAssembler::ScratchRegister); + as->and32(JITAssembler::ScratchRegister, reg); #endif return Jump(); } @@ -210,8 +211,8 @@ struct Binop { #if HAVE(ALU_OPS_WITH_MEM_OPERAND) as->or32(addr, reg); #else - as->load32(addr, Assembler::ScratchRegister); - as->or32(Assembler::ScratchRegister, reg); + as->load32(addr, JITAssembler::ScratchRegister); + as->or32(JITAssembler::ScratchRegister, reg); #endif return Jump(); } @@ -227,8 +228,8 @@ struct Binop { #if HAVE(ALU_OPS_WITH_MEM_OPERAND) as->xor32(addr, reg); #else - as->load32(addr, Assembler::ScratchRegister); - as->xor32(Assembler::ScratchRegister, reg); + as->load32(addr, JITAssembler::ScratchRegister); + as->xor32(JITAssembler::ScratchRegister, reg); #endif return Jump(); } @@ -241,7 +242,7 @@ struct Binop { - Assembler *as; + JITAssembler *as; IR::AluOp op; }; diff --git a/src/qml/jit/qv4isel_masm.cpp b/src/qml/jit/qv4isel_masm.cpp index 7a570d0b6b..a5c3d94648 100644 --- a/src/qml/jit/qv4isel_masm.cpp +++ b/src/qml/jit/qv4isel_masm.cpp @@ -794,14 +794,14 @@ void InstructionSelection::swapValues(IR::Expr *source, IR::Expr *target) void InstructionSelection::unop(IR::AluOp oper, IR::Expr *source, IR::Expr *target) { - QV4::JIT::Unop unop(_as, oper); + QV4::JIT::Unop unop(_as, oper); unop.generate(source, target); } void InstructionSelection::binop(IR::AluOp oper, IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *target) { - QV4::JIT::Binop binop(_as, oper); + QV4::JIT::Binop binop(_as, oper); binop.generate(leftSource, rightSource, target); } diff --git a/src/qml/jit/qv4unop.cpp b/src/qml/jit/qv4unop.cpp index bb52ba012b..937441b7be 100644 --- a/src/qml/jit/qv4unop.cpp +++ b/src/qml/jit/qv4unop.cpp @@ -48,14 +48,15 @@ using namespace JIT; #define stringIfy(s) stringIfyx(s) #define setOp(operation) \ do { \ - call = Assembler::RuntimeCall(qOffsetOf(QV4::Runtime, operation)); name = "Runtime::" stringIfy(operation); \ + call = typename JITAssembler::RuntimeCall(qOffsetOf(QV4::Runtime, operation)); name = "Runtime::" stringIfy(operation); \ needsExceptionCheck = Runtime::Method_##operation##_NeedsExceptionCheck; \ } while (0) -void Unop::generate(IR::Expr *source, IR::Expr *target) +template +void Unop::generate(IR::Expr *source, IR::Expr *target) { bool needsExceptionCheck; - Assembler::RuntimeCall call; + typename JITAssembler::RuntimeCall call; const char *name = 0; switch (op) { case IR::OpNot: @@ -75,17 +76,18 @@ void Unop::generate(IR::Expr *source, IR::Expr *target) } // switch Q_ASSERT(call.isValid()); - _as->generateFunctionCallImp(needsExceptionCheck, target, name, call, Assembler::PointerToValue(source)); + _as->generateFunctionCallImp(needsExceptionCheck, target, name, call, PointerToValue(source)); } -void Unop::generateUMinus(IR::Expr *source, IR::Expr *target) +template +void Unop::generateUMinus(IR::Expr *source, IR::Expr *target) { IR::Temp *targetTemp = target->asTemp(); if (source->type == IR::SInt32Type) { - Assembler::RegisterID tReg = Assembler::ScratchRegister; + typename JITAssembler::RegisterID tReg = JITAssembler::ScratchRegister; if (targetTemp && targetTemp->kind == IR::Temp::PhysicalRegister) - tReg = (Assembler::RegisterID) targetTemp->index; - Assembler::RegisterID sReg = _as->toInt32Register(source, tReg); + tReg = (typename JITAssembler::RegisterID) targetTemp->index; + typename JITAssembler::RegisterID sReg = _as->toInt32Register(source, tReg); _as->move(sReg, tReg); _as->neg32(tReg); if (!targetTemp || targetTemp->kind != IR::Temp::PhysicalRegister) @@ -93,26 +95,27 @@ void Unop::generateUMinus(IR::Expr *source, IR::Expr *target) return; } - generateRuntimeCall(target, uMinus, Assembler::PointerToValue(source)); + generateRuntimeCall(target, uMinus, PointerToValue(source)); } -void Unop::generateNot(IR::Expr *source, IR::Expr *target) +template +void Unop::generateNot(IR::Expr *source, IR::Expr *target) { IR::Temp *targetTemp = target->asTemp(); if (source->type == IR::BoolType) { - Assembler::RegisterID tReg = Assembler::ScratchRegister; + typename JITAssembler::RegisterID tReg = JITAssembler::ScratchRegister; if (targetTemp && targetTemp->kind == IR::Temp::PhysicalRegister) - tReg = (Assembler::RegisterID) targetTemp->index; - _as->xor32(Assembler::TrustedImm32(0x1), _as->toInt32Register(source, tReg), tReg); + tReg = (typename JITAssembler::RegisterID) targetTemp->index; + _as->xor32(TrustedImm32(0x1), _as->toInt32Register(source, tReg), tReg); if (!targetTemp || targetTemp->kind != IR::Temp::PhysicalRegister) _as->storeBool(tReg, target); return; } else if (source->type == IR::SInt32Type) { - Assembler::RegisterID tReg = Assembler::ScratchRegister; + typename JITAssembler::RegisterID tReg = JITAssembler::ScratchRegister; if (targetTemp && targetTemp->kind == IR::Temp::PhysicalRegister) - tReg = (Assembler::RegisterID) targetTemp->index; - _as->compare32(Assembler::Equal, - _as->toInt32Register(source, Assembler::ScratchRegister), Assembler::TrustedImm32(0), + tReg = (typename JITAssembler::RegisterID) targetTemp->index; + _as->compare32(RelationalCondition::Equal, + _as->toInt32Register(source, JITAssembler::ScratchRegister), TrustedImm32(0), tReg); if (!targetTemp || targetTemp->kind != IR::Temp::PhysicalRegister) _as->storeBool(tReg, target); @@ -122,22 +125,25 @@ void Unop::generateNot(IR::Expr *source, IR::Expr *target) } // ## generic implementation testing for int/bool - generateRuntimeCall(target, uNot, Assembler::PointerToValue(source)); + generateRuntimeCall(target, uNot, PointerToValue(source)); } -void Unop::generateCompl(IR::Expr *source, IR::Expr *target) +template +void Unop::generateCompl(IR::Expr *source, IR::Expr *target) { IR::Temp *targetTemp = target->asTemp(); if (source->type == IR::SInt32Type) { - Assembler::RegisterID tReg = Assembler::ScratchRegister; + typename JITAssembler::RegisterID tReg = JITAssembler::ScratchRegister; if (targetTemp && targetTemp->kind == IR::Temp::PhysicalRegister) - tReg = (Assembler::RegisterID) targetTemp->index; - _as->xor32(Assembler::TrustedImm32(0xffffffff), _as->toInt32Register(source, tReg), tReg); + tReg = (typename JITAssembler::RegisterID) targetTemp->index; + _as->xor32(TrustedImm32(0xffffffff), _as->toInt32Register(source, tReg), tReg); if (!targetTemp || targetTemp->kind != IR::Temp::PhysicalRegister) _as->storeInt32(tReg, target); return; } - generateRuntimeCall(target, complement, Assembler::PointerToValue(source)); + generateRuntimeCall(target, complement, PointerToValue(source)); } +template struct QV4::JIT::Unop; + #endif diff --git a/src/qml/jit/qv4unop_p.h b/src/qml/jit/qv4unop_p.h index 1141a84913..fb68f80eec 100644 --- a/src/qml/jit/qv4unop_p.h +++ b/src/qml/jit/qv4unop_p.h @@ -60,21 +60,25 @@ QT_BEGIN_NAMESPACE namespace QV4 { namespace JIT { -class Assembler; - +template struct Unop { - Unop(Assembler *assembler, IR::AluOp operation) + Unop(JITAssembler *assembler, IR::AluOp operation) : _as(assembler) , op(operation) {} + using RelationalCondition = typename JITAssembler::RelationalCondition; + using PointerToValue = typename JITAssembler::PointerToValue; + using RuntimeCall = typename JITAssembler::RuntimeCall; + using TrustedImm32 = typename JITAssembler::TrustedImm32; + void generate(IR::Expr *source, IR::Expr *target); void generateUMinus(IR::Expr *source, IR::Expr *target); void generateNot(IR::Expr *source, IR::Expr *target); void generateCompl(IR::Expr *source, IR::Expr *target); - Assembler *_as; + JITAssembler *_as; IR::AluOp op; }; -- cgit v1.2.3