From a3f7f40045421c1e1aaba7aa13232b3a788d9149 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 30 Jan 2017 12:48:04 +0100 Subject: Remove platform ifdefs in JIT::ISel::visitRet Use templates to encode the various platform dependent ways of encoding the return values. Change-Id: Icb481a75924da7d78396ff1c95474dc9c29ca494 Reviewed-by: Lars Knoll --- src/qml/jit/qv4assembler.cpp | 32 ++++++++++ src/qml/jit/qv4assembler_p.h | 99 ++++++++++++++++++++++++++++++ src/qml/jit/qv4isel_masm.cpp | 139 +------------------------------------------ 3 files changed, 132 insertions(+), 138 deletions(-) (limited to 'src') diff --git a/src/qml/jit/qv4assembler.cpp b/src/qml/jit/qv4assembler.cpp index 3800307de0..141bc7132a 100644 --- a/src/qml/jit/qv4assembler.cpp +++ b/src/qml/jit/qv4assembler.cpp @@ -516,6 +516,38 @@ void Assembler::setStackLayout(int maxArgCountForBuiltins, _stackLayout.reset(new StackLayout(_function, maxArgCountForBuiltins, regularRegistersToSave, fpRegistersToSave)); } +template +void Assembler::returnFromFunction(IR::Ret *s, RegisterInformation regularRegistersToSave, RegisterInformation fpRegistersToSave) +{ + if (!s) { + // this only happens if the method doesn't have a return statement and can + // only exit through an exception + } 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); + RegisterSizeDependentOps::setFunctionReturnValueFromConst(this, retVal); + } else { + Q_UNREACHABLE(); + Q_UNUSED(s); + } + + Label leaveStackFrame = label(); + + const int locals = stackLayout().calculateJSStackFrameSize(); + subPtr(TrustedImm32(sizeof(QV4::Value)*locals), JITTargetPlatform::LocalsRegister); + loadPtr(Address(JITTargetPlatform::EngineRegister, qOffsetOf(QV4::ExecutionEngine, current)), JITTargetPlatform::ScratchRegister); + loadPtr(Address(JITTargetPlatform::ScratchRegister, qOffsetOf(ExecutionContext::Data, engine)), JITTargetPlatform::ScratchRegister); + storePtr(JITTargetPlatform::LocalsRegister, Address(JITTargetPlatform::ScratchRegister, qOffsetOf(ExecutionEngine, jsStackTop))); + + leaveStandardStackFrame(regularRegistersToSave, fpRegistersToSave); + ret(); + + exceptionReturnLabel = label(); + QV4::Primitive retVal = Primitive::undefinedValue(); + RegisterSizeDependentOps::setFunctionReturnValueFromConst(this, retVal); + jump(leaveStackFrame); +} namespace { class QIODevicePrintStream: public FilePrintStream diff --git a/src/qml/jit/qv4assembler_p.h b/src/qml/jit/qv4assembler_p.h index f063593ecf..6c2084b027 100644 --- a/src/qml/jit/qv4assembler_p.h +++ b/src/qml/jit/qv4assembler_p.h @@ -199,6 +199,52 @@ struct RegisterSizeDependentAssemblerstore32(TargetPlatform::HighReturnValueRegister, destination); } + static void setFunctionReturnValueFromTemp(JITAssembler *as, IR::Temp *t) + { + const auto lowReg = TargetPlatform::LowReturnValueRegister; + const auto highReg = TargetPlatform::HighReturnValueRegister; + + if (t->kind == IR::Temp::PhysicalRegister) { + switch (t->type) { + case IR::DoubleType: + as->moveDoubleToInts((FPRegisterID) t->index, lowReg, highReg); + break; + case IR::UInt32Type: { + RegisterID srcReg = (RegisterID) t->index; + Jump intRange = as->branch32(JITAssembler::GreaterThanOrEqual, srcReg, TrustedImm32(0)); + as->convertUInt32ToDouble(srcReg, TargetPlatform::FPGpr0, TargetPlatform::ReturnValueRegister); + as->moveDoubleToInts(TargetPlatform::FPGpr0, lowReg, highReg); + Jump done = as->jump(); + intRange.link(as); + as->move(srcReg, lowReg); + as->move(TrustedImm32(QV4::Value::Integer_Type_Internal), highReg); + done.link(as); + } break; + case IR::SInt32Type: + as->move((RegisterID) t->index, lowReg); + as->move(TrustedImm32(QV4::Value::Integer_Type_Internal), highReg); + break; + case IR::BoolType: + as->move((RegisterID) t->index, lowReg); + as->move(TrustedImm32(QV4::Value::Boolean_Type_Internal), highReg); + break; + default: + Q_UNREACHABLE(); + } + } else { + Pointer addr = as->loadAddress(TargetPlatform::ScratchRegister, t); + as->load32(addr, lowReg); + addr.offset += 4; + as->load32(addr, highReg); + } + } + + static void setFunctionReturnValueFromConst(JITAssembler *as, QV4::Primitive retVal) + { + as->move(TrustedImm32(retVal.int_32()), TargetPlatform::LowReturnValueRegister); + as->move(TrustedImm32(retVal.tag()), TargetPlatform::HighReturnValueRegister); + } + static void loadArgumentInRegister(JITAssembler *as, IR::Temp* temp, RegisterID dest, int argumentNumber) { Q_UNUSED(as); @@ -346,6 +392,56 @@ struct RegisterSizeDependentAssemblerstore64(TargetPlatform::ReturnValueRegister, dest); } + static void setFunctionReturnValueFromTemp(JITAssembler *as, IR::Temp *t) + { + if (t->kind == IR::Temp::PhysicalRegister) { + if (t->type == IR::DoubleType) { + as->moveDoubleTo64((FPRegisterID) t->index, + TargetPlatform::ReturnValueRegister); + as->move(TrustedImm64(QV4::Value::NaNEncodeMask), + TargetPlatform::ScratchRegister); + as->xor64(TargetPlatform::ScratchRegister, TargetPlatform::ReturnValueRegister); + } else if (t->type == IR::UInt32Type) { + RegisterID srcReg = (RegisterID) t->index; + Jump intRange = as->branch32(RelationalCondition::GreaterThanOrEqual, srcReg, TrustedImm32(0)); + as->convertUInt32ToDouble(srcReg, TargetPlatform::FPGpr0, TargetPlatform::ReturnValueRegister); + as->moveDoubleTo64(TargetPlatform::FPGpr0, TargetPlatform::ReturnValueRegister); + as->move(TrustedImm64(QV4::Value::NaNEncodeMask), TargetPlatform::ScratchRegister); + as->xor64(TargetPlatform::ScratchRegister, TargetPlatform::ReturnValueRegister); + Jump done = as->jump(); + intRange.link(as); + as->zeroExtend32ToPtr(srcReg, TargetPlatform::ReturnValueRegister); + quint64 tag = QV4::Value::Integer_Type_Internal; + as->or64(TrustedImm64(tag << 32), + TargetPlatform::ReturnValueRegister); + done.link(as); + } else { + as->zeroExtend32ToPtr((RegisterID) t->index, TargetPlatform::ReturnValueRegister); + quint64 tag; + switch (t->type) { + case IR::SInt32Type: + tag = QV4::Value::Integer_Type_Internal; + break; + case IR::BoolType: + tag = QV4::Value::Boolean_Type_Internal; + break; + default: + tag = 31337; // bogus value + Q_UNREACHABLE(); + } + as->or64(TrustedImm64(tag << 32), + TargetPlatform::ReturnValueRegister); + } + } else { + as->copyValue(TargetPlatform::ReturnValueRegister, t); + } + } + + static void setFunctionReturnValueFromConst(JITAssembler *as, QV4::Primitive retVal) + { + as->move(TrustedImm64(retVal.rawValue()), TargetPlatform::ReturnValueRegister); + } + static void storeValue(JITAssembler *as, QV4::Primitive value, Address destination) { as->store64(TrustedImm64(value.rawValue()), destination); @@ -542,6 +638,7 @@ public: using MacroAssembler::convertInt32ToDouble; using MacroAssembler::rshift32; using MacroAssembler::storePtr; + using MacroAssembler::ret; using JITTargetPlatform = typename TargetConfiguration::Platform; using JITTargetPlatform::RegisterArgumentCount; @@ -1435,6 +1532,8 @@ public: return scratchReg; } + void returnFromFunction(IR::Ret *s, RegisterInformation regularRegistersToSave, RegisterInformation fpRegistersToSave); + JSC::MacroAssemblerCodeRef link(int *codeSize); void setStackLayout(int maxArgCountForBuiltins, int regularRegistersToSave, int fpRegistersToSave); diff --git a/src/qml/jit/qv4isel_masm.cpp b/src/qml/jit/qv4isel_masm.cpp index 7a051067f3..03881e6776 100644 --- a/src/qml/jit/qv4isel_masm.cpp +++ b/src/qml/jit/qv4isel_masm.cpp @@ -1325,144 +1325,7 @@ void InstructionSelection::visitCJump(IR::CJump *s) template void InstructionSelection::visitRet(IR::Ret *s) { - if (!s) { - // this only happens if the method doesn't have a return statement and can - // only exit through an exception - } else if (IR::Temp *t = s->expr->asTemp()) { -#if CPU(X86) || CPU(ARM) || CPU(MIPS) - -# if CPU(X86) - RegisterID lowReg = JSC::X86Registers::eax; - RegisterID highReg = JSC::X86Registers::edx; -# elif CPU(MIPS) - RegisterID lowReg = JSC::MIPSRegisters::v0; - RegisterID highReg = JSC::MIPSRegisters::v1; -# else // CPU(ARM) - RegisterID lowReg = JSC::ARMRegisters::r0; - RegisterID highReg = JSC::ARMRegisters::r1; -# endif - - if (t->kind == IR::Temp::PhysicalRegister) { - switch (t->type) { - case IR::DoubleType: - _as->moveDoubleToInts((FPRegisterID) t->index, lowReg, highReg); - break; - case IR::UInt32Type: { - RegisterID srcReg = (RegisterID) t->index; - Jump intRange = _as->branch32(JITAssembler::GreaterThanOrEqual, srcReg, TrustedImm32(0)); - _as->convertUInt32ToDouble(srcReg, JITTargetPlatform::FPGpr0, JITTargetPlatform::ReturnValueRegister); - _as->moveDoubleToInts(JITTargetPlatform::FPGpr0, lowReg, highReg); - Jump done = _as->jump(); - intRange.link(_as); - _as->move(srcReg, lowReg); - _as->move(TrustedImm32(QV4::Value::Integer_Type_Internal), highReg); - done.link(_as); - } break; - case IR::SInt32Type: - _as->move((RegisterID) t->index, lowReg); - _as->move(TrustedImm32(QV4::Value::Integer_Type_Internal), highReg); - break; - case IR::BoolType: - _as->move((RegisterID) t->index, lowReg); - _as->move(TrustedImm32(QV4::Value::Boolean_Type_Internal), highReg); - break; - default: - Q_UNREACHABLE(); - } - } else { - Pointer addr = _as->loadAddress(JITTargetPlatform::ScratchRegister, t); - _as->load32(addr, lowReg); - addr.offset += 4; - _as->load32(addr, highReg); - } -#else - if (t->kind == IR::Temp::PhysicalRegister) { - if (t->type == IR::DoubleType) { - _as->moveDoubleTo64((FPRegisterID) t->index, - JITTargetPlatform::ReturnValueRegister); - _as->move(TrustedImm64(QV4::Value::NaNEncodeMask), - JITTargetPlatform::ScratchRegister); - _as->xor64(JITTargetPlatform::ScratchRegister, JITTargetPlatform::ReturnValueRegister); - } else if (t->type == IR::UInt32Type) { - RegisterID srcReg = (RegisterID) t->index; - Jump intRange = _as->branch32(RelationalCondition::GreaterThanOrEqual, srcReg, TrustedImm32(0)); - _as->convertUInt32ToDouble(srcReg, JITTargetPlatform::FPGpr0, JITTargetPlatform::ReturnValueRegister); - _as->moveDoubleTo64(JITTargetPlatform::FPGpr0, JITTargetPlatform::ReturnValueRegister); - _as->move(TrustedImm64(QV4::Value::NaNEncodeMask), JITTargetPlatform::ScratchRegister); - _as->xor64(JITTargetPlatform::ScratchRegister, JITTargetPlatform::ReturnValueRegister); - Jump done = _as->jump(); - intRange.link(_as); - _as->zeroExtend32ToPtr(srcReg, JITTargetPlatform::ReturnValueRegister); - quint64 tag = QV4::Value::Integer_Type_Internal; - _as->or64(TrustedImm64(tag << 32), - JITTargetPlatform::ReturnValueRegister); - done.link(_as); - } else { - _as->zeroExtend32ToPtr((RegisterID) t->index, JITTargetPlatform::ReturnValueRegister); - quint64 tag; - switch (t->type) { - case IR::SInt32Type: - tag = QV4::Value::Integer_Type_Internal; - break; - case IR::BoolType: - tag = QV4::Value::Boolean_Type_Internal; - break; - default: - tag = 31337; // bogus value - Q_UNREACHABLE(); - } - _as->or64(TrustedImm64(tag << 32), - JITTargetPlatform::ReturnValueRegister); - } - } else { - _as->copyValue(JITTargetPlatform::ReturnValueRegister, t); - } -#endif - } else if (IR::Const *c = s->expr->asConst()) { - QV4::Primitive retVal = convertToValue(c); -#if CPU(X86) - _as->move(TrustedImm32(retVal.int_32()), JSC::X86Registers::eax); - _as->move(TrustedImm32(retVal.tag()), JSC::X86Registers::edx); -#elif CPU(ARM) - _as->move(TrustedImm32(retVal.int_32()), JSC::ARMRegisters::r0); - _as->move(TrustedImm32(retVal.tag()), JSC::ARMRegisters::r1); -#elif CPU(MIPS) - _as->move(TrustedImm32(retVal.int_32()), JSC::MIPSRegisters::v0); - _as->move(TrustedImm32(retVal.tag()), JSC::MIPSRegisters::v1); -#else - _as->move(TrustedImm64(retVal.rawValue()), JITTargetPlatform::ReturnValueRegister); -#endif - } else { - Q_UNREACHABLE(); - Q_UNUSED(s); - } - - Label leaveStackFrame = _as->label(); - - const int locals = _as->stackLayout().calculateJSStackFrameSize(); - _as->subPtr(TrustedImm32(sizeof(QV4::Value)*locals), JITTargetPlatform::LocalsRegister); - _as->loadPtr(Address(JITTargetPlatform::EngineRegister, qOffsetOf(QV4::ExecutionEngine, current)), JITTargetPlatform::ScratchRegister); - _as->loadPtr(Address(JITTargetPlatform::ScratchRegister, qOffsetOf(ExecutionContext::Data, engine)), JITTargetPlatform::ScratchRegister); - _as->storePtr(JITTargetPlatform::LocalsRegister, Address(JITTargetPlatform::ScratchRegister, qOffsetOf(ExecutionEngine, jsStackTop))); - - _as->leaveStandardStackFrame(regularRegistersToSave, fpRegistersToSave); - _as->ret(); - - _as->exceptionReturnLabel = _as->label(); - QV4::Primitive retVal = Primitive::undefinedValue(); -#if CPU(X86) - _as->move(TrustedImm32(retVal.int_32()), JSC::X86Registers::eax); - _as->move(TrustedImm32(retVal.tag()), JSC::X86Registers::edx); -#elif CPU(ARM) - _as->move(TrustedImm32(retVal.int_32()), JSC::ARMRegisters::r0); - _as->move(TrustedImm32(retVal.tag()), JSC::ARMRegisters::r1); -#elif CPU(MIPS) - _as->move(TrustedImm32(retVal.int_32()), JSC::MIPSRegisters::v0); - _as->move(TrustedImm32(retVal.tag()), JSC::MIPSRegisters::v1); -#else - _as->move(TrustedImm64(retVal.rawValue()), JITTargetPlatform::ReturnValueRegister); -#endif - _as->jump(leaveStackFrame); + _as->returnFromFunction(s, regularRegistersToSave, fpRegistersToSave); } template -- cgit v1.2.3