aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jit/qv4targetplatform_p.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/jit/qv4targetplatform_p.h')
-rw-r--r--src/qml/jit/qv4targetplatform_p.h139
1 files changed, 101 insertions, 38 deletions
diff --git a/src/qml/jit/qv4targetplatform_p.h b/src/qml/jit/qv4targetplatform_p.h
index 1c29aa2a70..d9f8034b1f 100644
--- a/src/qml/jit/qv4targetplatform_p.h
+++ b/src/qml/jit/qv4targetplatform_p.h
@@ -55,6 +55,7 @@
#if ENABLE(ASSEMBLER)
+#include <private/qv4value_p.h>
#include "qv4registerinfo_p.h"
#include <assembler/MacroAssembler.h>
@@ -97,6 +98,7 @@ public:
using PlatformAssembler = JSC::MacroAssemblerX86;
using RegisterID = PlatformAssembler::RegisterID;
using FPRegisterID = PlatformAssembler::FPRegisterID;
+ using TrustedImm32 = PlatformAssembler::TrustedImm32;
enum { RegAllocIsSupported = 1 };
@@ -130,10 +132,8 @@ public:
}
# define HAVE_ALU_OPS_WITH_MEM_OPERAND 1
-# undef VALUE_FITS_IN_REGISTER
static const int RegisterSize = 4;
-# undef ARGUMENTS_IN_REGISTERS
static const int RegisterArgumentCount = 0;
static RegisterID registerForArgument(int) { Q_UNREACHABLE(); }
@@ -141,15 +141,19 @@ public:
static const int StackShadowSpace = 0;
static const int StackSpaceAllocatedUponFunctionEntry = RegisterSize; // Return address is pushed onto stack by the CPU.
static void platformEnterStandardStackFrame(PlatformAssembler *as) { as->push(FramePointerRegister); }
- static void platformLeaveStandardStackFrame(PlatformAssembler *as) { as->pop(FramePointerRegister); }
+ static void platformFinishEnteringStandardStackFrame(PlatformAssembler *) {}
+ static void platformLeaveStandardStackFrame(PlatformAssembler *as, int frameSize)
+ {
+ if (frameSize > 0)
+ as->add32(TrustedImm32(frameSize), StackPointerRegister);
+ as->pop(FramePointerRegister);
+ }
#if OS(WINDOWS) || OS(QNX) || \
((OS(LINUX) || OS(FREEBSD)) && (defined(__PIC__) || defined(__PIE__)))
-#define RESTORE_EBX_ON_CALL
- using Address = PlatformAssembler::Address;
- static Address ebxAddressOnStack()
- {
+ static const int gotRegister = JSC::X86Registers::ebx;
+ static int savedGOTRegisterSlotOnStack() {
static int ebxIdx = -1;
if (ebxIdx == -1) {
int calleeSaves = 0;
@@ -165,8 +169,11 @@ public:
Q_ASSERT(ebxIdx >= 0);
ebxIdx += 1;
}
- return Address(FramePointerRegister, ebxIdx * -int(sizeof(void*)));
+ return ebxIdx * -int(sizeof(void*));
}
+#else
+ static const int gotRegister = -1;
+ static int savedGOTRegisterSlotOnStack() { return -1; }
#endif
};
#endif // x86
@@ -179,6 +186,7 @@ public:
using PlatformAssembler = JSC::MacroAssemblerX86_64;
using RegisterID = PlatformAssembler::RegisterID;
using FPRegisterID = PlatformAssembler::FPRegisterID;
+ using TrustedImm32 = PlatformAssembler::TrustedImm32;
enum { RegAllocIsSupported = 1 };
@@ -188,6 +196,7 @@ public:
static const RegisterID EngineRegister = JSC::X86Registers::r14;
static const RegisterID ReturnValueRegister = JSC::X86Registers::eax;
static const RegisterID ScratchRegister = JSC::X86Registers::r10;
+ static const RegisterID DoubleMaskRegister = JSC::X86Registers::r13;
static const FPRegisterID FPGpr0 = JSC::X86Registers::xmm0;
static const FPRegisterID FPGpr1 = JSC::X86Registers::xmm1;
@@ -201,8 +210,9 @@ public:
<< RI(JSC::X86Registers::edx, QStringLiteral("rdx"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
<< RI(JSC::X86Registers::r9, QStringLiteral("r9"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
<< RI(JSC::X86Registers::r8, QStringLiteral("r8"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
+ // r11 is used as scratch register by the macro assembler
<< RI(JSC::X86Registers::r12, QStringLiteral("r12"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
- << RI(JSC::X86Registers::r13, QStringLiteral("r13"), RI::RegularRegister, RI::CalleeSaved, RI::RegAlloc)
+ << RI(JSC::X86Registers::r13, QStringLiteral("r13"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
<< RI(JSC::X86Registers::r14, QStringLiteral("r14"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
<< RI(JSC::X86Registers::r15, QStringLiteral("r15"), RI::RegularRegister, RI::CalleeSaved, RI::RegAlloc)
<< RI(JSC::X86Registers::xmm2, QStringLiteral("xmm2"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
@@ -216,10 +226,8 @@ public:
}
#define HAVE_ALU_OPS_WITH_MEM_OPERAND 1
-#define VALUE_FITS_IN_REGISTER
static const int RegisterSize = 8;
-#define ARGUMENTS_IN_REGISTERS
static const int RegisterArgumentCount = 6;
static RegisterID registerForArgument(int index)
{
@@ -239,7 +247,19 @@ public:
static const int StackShadowSpace = 0;
static const int StackSpaceAllocatedUponFunctionEntry = RegisterSize; // Return address is pushed onto stack by the CPU.
static void platformEnterStandardStackFrame(PlatformAssembler *as) { as->push(FramePointerRegister); }
- static void platformLeaveStandardStackFrame(PlatformAssembler *as) { as->pop(FramePointerRegister); }
+ static void platformFinishEnteringStandardStackFrame(PlatformAssembler *as)
+ {
+ as->move(PlatformAssembler::TrustedImm64(QV4::Value::NaNEncodeMask), DoubleMaskRegister);
+ }
+ static void platformLeaveStandardStackFrame(PlatformAssembler *as, int frameSize)
+ {
+ if (frameSize > 0)
+ as->add64(TrustedImm32(frameSize), StackPointerRegister);
+ as->pop(FramePointerRegister);
+ }
+
+ static const int gotRegister = -1;
+ static int savedGOTRegisterSlotOnStack() { return -1; }
};
#endif // Linux/MacOS on x86_64
@@ -251,11 +271,9 @@ public:
using PlatformAssembler = JSC::MacroAssemblerX86_64;
using RegisterID = PlatformAssembler::RegisterID;
using FPRegisterID = PlatformAssembler::FPRegisterID;
+ using TrustedImm32 = PlatformAssembler::TrustedImm32;
- // Register allocation is not (yet) supported on win64, because the ABI related stack handling
- // is not completely implemented. Specifically, the saving of xmm registers, and the saving of
- // incoming function parameters to the shadow space is missing.
- enum { RegAllocIsSupported = 0 };
+ enum { RegAllocIsSupported = 1 };
static const RegisterID FramePointerRegister = JSC::X86Registers::ebp;
static const RegisterID StackPointerRegister = JSC::X86Registers::esp;
@@ -263,6 +281,7 @@ public:
static const RegisterID EngineRegister = JSC::X86Registers::r14;
static const RegisterID ReturnValueRegister = JSC::X86Registers::eax;
static const RegisterID ScratchRegister = JSC::X86Registers::r10;
+ static const RegisterID DoubleMaskRegister = JSC::X86Registers::r13;
static const FPRegisterID FPGpr0 = JSC::X86Registers::xmm0;
static const FPRegisterID FPGpr1 = JSC::X86Registers::xmm1;
@@ -270,25 +289,30 @@ public:
{
typedef RegisterInfo RI;
static RegisterInformation info = RegisterInformation()
- << RI(JSC::X86Registers::ebx, QStringLiteral("rbx"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
- << RI(JSC::X86Registers::edi, QStringLiteral("rdi"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
- << RI(JSC::X86Registers::esi, QStringLiteral("rsi"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
- << RI(JSC::X86Registers::edx, QStringLiteral("rdx"), RI::RegularRegister, RI::CallerSaved, RI::Predefined)
- << RI(JSC::X86Registers::r9, QStringLiteral("r9"), RI::RegularRegister, RI::CallerSaved, RI::Predefined)
- << RI(JSC::X86Registers::r8, QStringLiteral("r8"), RI::RegularRegister, RI::CallerSaved, RI::Predefined)
+ << RI(JSC::X86Registers::ebx, QStringLiteral("rbx"), RI::RegularRegister, RI::CalleeSaved, RI::RegAlloc)
+ << RI(JSC::X86Registers::edi, QStringLiteral("rdi"), RI::RegularRegister, RI::CalleeSaved, RI::RegAlloc)
+ << RI(JSC::X86Registers::esi, QStringLiteral("rsi"), RI::RegularRegister, RI::CalleeSaved, RI::RegAlloc)
+ << RI(JSC::X86Registers::edx, QStringLiteral("rdx"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
+ << RI(JSC::X86Registers::r8, QStringLiteral("r8"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
+ << RI(JSC::X86Registers::r9, QStringLiteral("r9"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
+ // r11 is used as scratch register by the macro assembler
<< RI(JSC::X86Registers::r12, QStringLiteral("r12"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
<< RI(JSC::X86Registers::r13, QStringLiteral("r13"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
<< RI(JSC::X86Registers::r14, QStringLiteral("r14"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
- << RI(JSC::X86Registers::r15, QStringLiteral("r15"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
+ << RI(JSC::X86Registers::r15, QStringLiteral("r15"), RI::RegularRegister, RI::CalleeSaved, RI::RegAlloc)
+ << RI(JSC::X86Registers::xmm2, QStringLiteral("xmm2"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
+ << RI(JSC::X86Registers::xmm3, QStringLiteral("xmm3"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
+ << RI(JSC::X86Registers::xmm4, QStringLiteral("xmm4"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
+ << RI(JSC::X86Registers::xmm5, QStringLiteral("xmm5"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
+ << RI(JSC::X86Registers::xmm6, QStringLiteral("xmm6"), RI::FloatingPointRegister, RI::CalleeSaved, RI::RegAlloc)
+ << RI(JSC::X86Registers::xmm7, QStringLiteral("xmm7"), RI::FloatingPointRegister, RI::CalleeSaved, RI::RegAlloc)
;
return info;
}
#define HAVE_ALU_OPS_WITH_MEM_OPERAND 1
-#define VALUE_FITS_IN_REGISTER
static const int RegisterSize = 8;
-#define ARGUMENTS_IN_REGISTERS
static const int RegisterArgumentCount = 4;
static RegisterID registerForArgument(int index)
{
@@ -300,13 +324,25 @@ public:
};
Q_ASSERT(index >= 0 && index < RegisterArgumentCount);
return regs[index];
- };
+ }
static const int StackAlignment = 16;
static const int StackShadowSpace = 32;
static const int StackSpaceAllocatedUponFunctionEntry = RegisterSize; // Return address is pushed onto stack by the CPU.
static void platformEnterStandardStackFrame(PlatformAssembler *as) { as->push(FramePointerRegister); }
- static void platformLeaveStandardStackFrame(PlatformAssembler *as) { as->pop(FramePointerRegister); }
+ static void platformFinishEnteringStandardStackFrame(PlatformAssembler *as)
+ {
+ as->move(PlatformAssembler::TrustedImm64(QV4::Value::NaNEncodeMask), DoubleMaskRegister);
+ }
+ static void platformLeaveStandardStackFrame(PlatformAssembler *as, int frameSize)
+ {
+ if (frameSize > 0)
+ as->add64(TrustedImm32(frameSize), StackPointerRegister);
+ as->pop(FramePointerRegister);
+ }
+
+ static const int gotRegister = -1;
+ static int savedGOTRegisterSlotOnStack() { return -1; }
};
#endif // Windows on x86_64
@@ -318,6 +354,7 @@ public:
using PlatformAssembler = JSC::MacroAssemblerARMv7;
using RegisterID = PlatformAssembler::RegisterID;
using FPRegisterID = PlatformAssembler::FPRegisterID;
+ using TrustedImm32 = PlatformAssembler::TrustedImm32;
enum { RegAllocIsSupported = 1 };
@@ -389,10 +426,8 @@ public:
}
#undef HAVE_ALU_OPS_WITH_MEM_OPERAND
-#undef VALUE_FITS_IN_REGISTER
static const int RegisterSize = 4;
-#define ARGUMENTS_IN_REGISTERS
static const int RegisterArgumentCount = 4;
static RegisterID registerForArgument(int index)
{
@@ -417,15 +452,26 @@ public:
as->push(FramePointerRegister);
}
- static void platformLeaveStandardStackFrame(PlatformAssembler *as)
+ static void platformFinishEnteringStandardStackFrame(PlatformAssembler *) {}
+
+ static void platformLeaveStandardStackFrame(PlatformAssembler *as, int frameSize)
{
+ if (frameSize > 0) {
+ // Work around bug in ARMv7Assembler.h where add32(imm, sp, sp) doesn't
+ // work well for large immediates.
+ as->move(TrustedImm32(frameSize), JSC::ARMRegisters::r3);
+ as->add32(JSC::ARMRegisters::r3, StackPointerRegister);
+ }
as->pop(FramePointerRegister);
as->pop(JSC::ARMRegisters::lr);
}
+
+ static const int gotRegister = -1;
+ static int savedGOTRegisterSlotOnStack() { return -1; }
};
#endif // ARM (32 bit)
-#if CPU(ARM64)
+#if CPU(ARM64) || defined(V4_BOOTSTRAP)
template <>
class TargetPlatform<JSC::MacroAssemblerARM64, NoOperatingSystemSpecialization>
{
@@ -433,6 +479,7 @@ public:
using PlatformAssembler = JSC::MacroAssemblerARM64;
using RegisterID = PlatformAssembler::RegisterID;
using FPRegisterID = PlatformAssembler::FPRegisterID;
+ using TrustedImm32 = PlatformAssembler::TrustedImm32;
enum { RegAllocIsSupported = 1 };
@@ -442,6 +489,7 @@ public:
static const RegisterID ScratchRegister = JSC::ARM64Registers::x9;
static const RegisterID EngineRegister = JSC::ARM64Registers::x27;
static const RegisterID ReturnValueRegister = JSC::ARM64Registers::x0;
+ static const RegisterID DoubleMaskRegister = JSC::ARM64Registers::x26;
static const FPRegisterID FPGpr0 = JSC::ARM64Registers::q0;
static const FPRegisterID FPGpr1 = JSC::ARM64Registers::q1;
@@ -472,7 +520,7 @@ public:
<< RI(JSC::ARM64Registers::x23, QStringLiteral("x23"), RI::RegularRegister, RI::CalleeSaved, RI::RegAlloc)
<< RI(JSC::ARM64Registers::x24, QStringLiteral("x24"), RI::RegularRegister, RI::CalleeSaved, RI::RegAlloc)
<< RI(JSC::ARM64Registers::x25, QStringLiteral("x25"), RI::RegularRegister, RI::CalleeSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::x26, QStringLiteral("x26"), RI::RegularRegister, RI::CalleeSaved, RI::RegAlloc)
+ << RI(JSC::ARM64Registers::x26, QStringLiteral("x26"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
<< RI(JSC::ARM64Registers::x27, QStringLiteral("x27"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
<< RI(JSC::ARM64Registers::x28, QStringLiteral("x28"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
@@ -510,10 +558,8 @@ public:
}
#undef HAVE_ALU_OPS_WITH_MEM_OPERAND
-#define VALUE_FITS_IN_REGISTER
static const int RegisterSize = 8;
-#define ARGUMENTS_IN_REGISTERS
static const int RegisterArgumentCount = 8;
static RegisterID registerForArgument(int index)
{
@@ -541,10 +587,20 @@ public:
as->pushPair(FramePointerRegister, JSC::ARM64Registers::lr);
}
- static void platformLeaveStandardStackFrame(PlatformAssembler *as)
+ static void platformFinishEnteringStandardStackFrame(PlatformAssembler *as)
+ {
+ as->move(PlatformAssembler::TrustedImm64(QV4::Value::NaNEncodeMask), DoubleMaskRegister);
+ }
+
+ static void platformLeaveStandardStackFrame(PlatformAssembler *as, int frameSize)
{
+ if (frameSize > 0)
+ as->add64(TrustedImm32(frameSize), StackPointerRegister);
as->popPair(FramePointerRegister, JSC::ARM64Registers::lr);
}
+
+ static const int gotRegister = -1;
+ static int savedGOTRegisterSlotOnStack() { return -1; }
};
#endif // ARM64
@@ -556,6 +612,7 @@ public:
using PlatformAssembler = JSC::MacroAssemblerMIPS;
using RegisterID = PlatformAssembler::RegisterID;
using FPRegisterID = PlatformAssembler::FPRegisterID;
+ using TrustedImm32 = PlatformAssembler::TrustedImm32;
enum { RegAllocIsSupported = 1 };
static const RegisterID FramePointerRegister = JSC::MIPSRegisters::fp;
@@ -598,10 +655,8 @@ public:
}
#undef HAVE_ALU_OPS_WITH_MEM_OPERAND
-#undef VALUE_FITS_IN_REGISTER
static const int RegisterSize = 4;
-#define ARGUMENTS_IN_REGISTERS
static const int RegisterArgumentCount = 4;
static RegisterID registerForArgument(int index)
{
@@ -626,11 +681,19 @@ public:
as->push(FramePointerRegister);
}
- static void platformLeaveStandardStackFrame(PlatformAssembler *as)
+ static void platformFinishEnteringStandardStackFrame(PlatformAssembler *) {}
+
+ static void platformLeaveStandardStackFrame(PlatformAssembler *as, int frameSize)
{
+ if (frameSize > 0)
+ as->add32(TrustedImm32(frameSize), StackPointerRegister);
as->pop(FramePointerRegister);
as->pop(JSC::MIPSRegisters::ra);
}
+
+
+ static const int gotRegister = -1;
+ static int savedGOTRegisterSlotOnStack() { return -1; }
};
#endif // Linux on MIPS (32 bit)