aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2017-01-30 12:48:04 +0100
committerSimon Hausmann <simon.hausmann@qt.io>2017-01-31 20:45:34 +0000
commita3f7f40045421c1e1aaba7aa13232b3a788d9149 (patch)
treeb60d3fcdc00a333d61917d0fcecf1efdf34b04e6 /src
parent26b5b643b0207b7f631de734db260149db8aca23 (diff)
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 <lars.knoll@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/qml/jit/qv4assembler.cpp32
-rw-r--r--src/qml/jit/qv4assembler_p.h99
-rw-r--r--src/qml/jit/qv4isel_masm.cpp139
3 files changed, 132 insertions, 138 deletions
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<TargetConfiguration>::setStackLayout(int maxArgCountForBuiltins,
_stackLayout.reset(new StackLayout(_function, maxArgCountForBuiltins, regularRegistersToSave, fpRegistersToSave));
}
+template <typename TargetConfiguration>
+void Assembler<TargetConfiguration>::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 RegisterSizeDependentAssembler<JITAssembler, MacroAssembler, TargetPlatfo
as->store32(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 RegisterSizeDependentAssembler<JITAssembler, MacroAssembler, TargetPlatfo
as->store64(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<JITAssembler>::visitCJump(IR::CJump *s)
template <typename JITAssembler>
void InstructionSelection<JITAssembler>::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 <typename JITAssembler>