diff options
Diffstat (limited to 'src/qml/jit/qv4assembler.cpp')
-rw-r--r-- | src/qml/jit/qv4assembler.cpp | 131 |
1 files changed, 47 insertions, 84 deletions
diff --git a/src/qml/jit/qv4assembler.cpp b/src/qml/jit/qv4assembler.cpp index cd44b537df..cb2279b336 100644 --- a/src/qml/jit/qv4assembler.cpp +++ b/src/qml/jit/qv4assembler.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtQml module of the Qt Toolkit. @@ -91,58 +91,6 @@ QV4::ExecutableAllocator::ChunkOfPages *CompilationUnit::chunkForFunction(int fu return handle->chunk(); } - - -/* Platform/Calling convention/Architecture specific section */ - -#if CPU(X86_64) -# if OS(LINUX) || OS(MAC_OS_X) -static const Assembler::RegisterID calleeSavedRegisters[] = { - JSC::X86Registers::ebx, - JSC::X86Registers::r12, // LocalsRegister - JSC::X86Registers::r13, - JSC::X86Registers::r14, // ContextRegister - JSC::X86Registers::r15 -}; -# elif OS(WINDOWS) -static const Assembler::RegisterID calleeSavedRegisters[] = { - JSC::X86Registers::ebx, - JSC::X86Registers::esi, - JSC::X86Registers::edi, - JSC::X86Registers::r12, // LocalsRegister - JSC::X86Registers::r13, - JSC::X86Registers::r14, // ContextRegister - JSC::X86Registers::r15 -}; -# endif -#endif - -#if CPU(X86) -static const Assembler::RegisterID calleeSavedRegisters[] = { - JSC::X86Registers::ebx, // temporary register - JSC::X86Registers::esi, // ContextRegister - JSC::X86Registers::edi // LocalsRegister -}; -#endif - -#if CPU(ARM) -static const Assembler::RegisterID calleeSavedRegisters[] = { - JSC::ARMRegisters::r11, - JSC::ARMRegisters::r10, - JSC::ARMRegisters::r9, - JSC::ARMRegisters::r8, - JSC::ARMRegisters::r7, - JSC::ARMRegisters::r6, - JSC::ARMRegisters::r5, - JSC::ARMRegisters::r4 -}; -#endif - -const int Assembler::calleeSavedRegisterCount = sizeof(calleeSavedRegisters) / sizeof(calleeSavedRegisters[0]); - -/* End of platform/calling convention/architecture specific section */ - - const Assembler::VoidType Assembler::Void; Assembler::Assembler(InstructionSelection *isel, IR::Function* function, QV4::ExecutableAllocator *executableAllocator, @@ -223,33 +171,47 @@ void Assembler::generateCJumpOnCompare(RelationalCondition cond, RegisterID left } } -Assembler::Pointer Assembler::loadTempAddress(RegisterID baseReg, IR::Temp *t) +Assembler::Pointer Assembler::loadAddress(RegisterID tmp, IR::Expr *e) +{ + IR::Temp *t = e->asTemp(); + if (t) + return loadTempAddress(t); + else + return loadArgLocalAddress(tmp, e->asArgLocal()); +} + +Assembler::Pointer Assembler::loadTempAddress(IR::Temp *t) +{ + if (t->kind == IR::Temp::StackSlot) + return stackSlotPointer(t); + else + Q_UNREACHABLE(); +} + +Assembler::Pointer Assembler::loadArgLocalAddress(RegisterID baseReg, IR::ArgLocal *al) { int32_t offset = 0; - int scope = t->scope; + int scope = al->scope; RegisterID context = ContextRegister; if (scope) { - loadPtr(Address(ContextRegister, qOffsetOf(ExecutionContext, outer)), baseReg); + loadPtr(Address(ContextRegister, qOffsetOf(ExecutionContext::Data, outer)), baseReg); --scope; context = baseReg; while (scope) { - loadPtr(Address(context, qOffsetOf(ExecutionContext, outer)), context); + loadPtr(Address(context, qOffsetOf(ExecutionContext::Data, outer)), context); --scope; } } - switch (t->kind) { - case IR::Temp::Formal: - case IR::Temp::ScopedFormal: { - loadPtr(Address(context, qOffsetOf(ExecutionContext, callData)), baseReg); - offset = sizeof(CallData) + (t->index - 1) * sizeof(Value); + switch (al->kind) { + case IR::ArgLocal::Formal: + case IR::ArgLocal::ScopedFormal: { + loadPtr(Address(context, qOffsetOf(ExecutionContext::Data, callData)), baseReg); + offset = sizeof(CallData) + (al->index - 1) * sizeof(Value); } break; - case IR::Temp::Local: - case IR::Temp::ScopedLocal: { - loadPtr(Address(context, qOffsetOf(CallContext, locals)), baseReg); - offset = t->index * sizeof(Value); - } break; - case IR::Temp::StackSlot: { - return stackSlotPointer(t); + case IR::ArgLocal::Local: + case IR::ArgLocal::ScopedLocal: { + loadPtr(Address(context, qOffsetOf(CallContext::Data, locals)), baseReg); + offset = al->index * sizeof(Value); } break; default: Q_UNREACHABLE(); @@ -259,7 +221,7 @@ Assembler::Pointer Assembler::loadTempAddress(RegisterID baseReg, IR::Temp *t) Assembler::Pointer Assembler::loadStringAddress(RegisterID reg, const QString &string) { - loadPtr(Address(Assembler::ContextRegister, qOffsetOf(QV4::ExecutionContext, compilationUnit)), Assembler::ScratchRegister); + loadPtr(Address(Assembler::ContextRegister, qOffsetOf(QV4::ExecutionContext::Data, compilationUnit)), Assembler::ScratchRegister); loadPtr(Address(Assembler::ScratchRegister, qOffsetOf(QV4::CompiledData::CompilationUnit, runtimeStrings)), reg); const int id = _isel->registerString(string); return Pointer(reg, id * sizeof(QV4::StringValue)); @@ -267,21 +229,21 @@ Assembler::Pointer Assembler::loadStringAddress(RegisterID reg, const QString &s void Assembler::loadStringRef(RegisterID reg, const QString &string) { - loadPtr(Address(Assembler::ContextRegister, qOffsetOf(QV4::ExecutionContext, compilationUnit)), reg); + loadPtr(Address(Assembler::ContextRegister, qOffsetOf(QV4::ExecutionContext::Data, compilationUnit)), reg); loadPtr(Address(reg, qOffsetOf(QV4::CompiledData::CompilationUnit, runtimeStrings)), reg); const int id = _isel->registerString(string); - addPtr(TrustedImmPtr(id * sizeof(QV4::StringValue)), reg); + loadPtr(Address(reg, id * sizeof(QV4::StringValue)), reg); } -void Assembler::storeValue(QV4::Primitive value, IR::Temp* destination) +void Assembler::storeValue(QV4::Primitive value, IR::Expr *destination) { - Address addr = loadTempAddress(ScratchRegister, destination); + Address addr = loadAddress(ScratchRegister, destination); storeValue(value, addr); } void Assembler::enterStandardStackFrame() { - platformEnterStandardStackFrame(); + platformEnterStandardStackFrame(this); // ### FIXME: Handle through calleeSavedRegisters mechanism // or eliminate StackFrameRegister altogether. @@ -292,16 +254,18 @@ void Assembler::enterStandardStackFrame() subPtr(TrustedImm32(frameSize), StackPointerRegister); - for (int i = 0; i < calleeSavedRegisterCount; ++i) - storePtr(calleeSavedRegisters[i], Address(StackFrameRegister, -(i + 1) * sizeof(void*))); + const RegisterInformation &calleeSavedRegisters = getCalleeSavedRegisters(); + for (int i = 0; i < calleeSavedRegisterCount(); ++i) + storePtr(calleeSavedRegisters[i].reg<RegisterID>(), Address(StackFrameRegister, -(i + 1) * sizeof(void*))); } void Assembler::leaveStandardStackFrame() { // restore the callee saved registers - for (int i = calleeSavedRegisterCount - 1; i >= 0; --i) - loadPtr(Address(StackFrameRegister, -(i + 1) * sizeof(void*)), calleeSavedRegisters[i]); + const RegisterInformation &calleeSavedRegisters = getCalleeSavedRegisters(); + for (int i = calleeSavedRegisterCount() - 1; i >= 0; --i) + loadPtr(Address(StackFrameRegister, -(i + 1) * sizeof(void*)), calleeSavedRegisters[i].reg<RegisterID>()); int frameSize = _stackLayout.calculateStackFrameSize(); // Work around bug in ARMv7Assembler.h where add32(imm, sp, sp) doesn't @@ -314,7 +278,7 @@ void Assembler::leaveStandardStackFrame() #endif pop(StackFrameRegister); - platformLeaveStandardStackFrame(); + platformLeaveStandardStackFrame(this); } @@ -347,13 +311,12 @@ Assembler::Jump Assembler::genTryDoubleConversion(IR::Expr *src, Assembler::FPRe break; } - IR::Temp *sourceTemp = src->asTemp(); - Q_ASSERT(sourceTemp); + Q_ASSERT(src->asTemp() || src->asArgLocal()); // It's not a number type, so it cannot be in a register. - Q_ASSERT(sourceTemp->kind != IR::Temp::PhysicalRegister || sourceTemp->type == IR::BoolType); + Q_ASSERT(src->asArgLocal() || src->asTemp()->kind != IR::Temp::PhysicalRegister || src->type == IR::BoolType); - Assembler::Pointer tagAddr = loadTempAddress(Assembler::ScratchRegister, sourceTemp); + Assembler::Pointer tagAddr = loadAddress(Assembler::ScratchRegister, src); tagAddr.offset += 4; load32(tagAddr, Assembler::ScratchRegister); |