4#ifndef QV4PLATFORMASSEMBLER_P_H
5#define QV4PLATFORMASSEMBLER_P_H
18#include <private/qv4engine_p.h>
19#include <private/qv4function_p.h>
20#include <private/qv4global_p.h>
21#include <private/qv4stackframe_p.h>
23#include <wtf/Vector.h>
24#include <assembler/MacroAssembler.h>
26#include <QtCore/qhash.h>
35#if defined(Q_PROCESSOR_X86_64) || defined(ENABLE_ALL_ASSEMBLERS_FOR_REFACTORING_PURPOSES)
36#if defined(Q_OS_LINUX) || defined(Q_OS_QNX) || defined(Q_OS_FREEBSD) || defined(Q_OS_DARWIN) || defined(Q_OS_SOLARIS)
38class PlatformAssembler_X86_64_SysV :
public JSC::MacroAssembler<JSC::MacroAssemblerX86_64>
41 static constexpr int NativeStackAlignment = 16;
43 static const RegisterID NoRegister = RegisterID::none;
45 static const RegisterID ReturnValueRegister = RegisterID::eax;
46 static const RegisterID ReturnValueRegisterValue = ReturnValueRegister;
47 static const RegisterID AccumulatorRegister = RegisterID::eax;
48 static const RegisterID AccumulatorRegisterValue = AccumulatorRegister;
49 static const RegisterID ScratchRegister = RegisterID::r10;
50 static const RegisterID ScratchRegister2 = RegisterID::r9;
51 static const RegisterID JSStackFrameRegister = RegisterID::r12;
52 static const RegisterID CppStackFrameRegister = RegisterID::r13;
53 static const RegisterID EngineRegister = RegisterID::r14;
54 static const RegisterID StackPointerRegister = RegisterID::esp;
55 static const RegisterID FramePointerRegister = RegisterID::ebp;
56 static const FPRegisterID FPScratchRegister = FPRegisterID::xmm1;
57 static const FPRegisterID FPScratchRegister2 = FPRegisterID::xmm2;
59 static const RegisterID Arg0Reg = RegisterID::edi;
60 static const RegisterID Arg1Reg = RegisterID::esi;
61 static const RegisterID Arg2Reg = RegisterID::edx;
62 static const RegisterID Arg3Reg = RegisterID::ecx;
63 static const RegisterID Arg4Reg = RegisterID::r8;
64 static const RegisterID Arg5Reg = RegisterID::r9;
65 static const RegisterID Arg6Reg = NoRegister;
66 static const RegisterID Arg7Reg = NoRegister;
67 static const int ArgInRegCount = 6;
71 addPtr(TrustedImmPtr(
sizeof(ReturnedValue)), StackPointerRegister);
74 void generatePlatformFunctionEntry()
76 push(FramePointerRegister);
77 move(StackPointerRegister, FramePointerRegister);
78 move(TrustedImmPtr(
nullptr), AccumulatorRegister);
push(AccumulatorRegister);
79 push(JSStackFrameRegister);
80 push(CppStackFrameRegister);
82 move(Arg0Reg, CppStackFrameRegister);
83 move(Arg1Reg, EngineRegister);
86 void generatePlatformFunctionExit(
bool tailCall =
false)
89 pop(CppStackFrameRegister);
90 pop(JSStackFrameRegister);
92 pop(FramePointerRegister);
97 void callAbsolute(
const void *funcPtr)
99 move(TrustedImmPtr(funcPtr), ScratchRegister);
100 call(ScratchRegister);
103 void jumpAbsolute(
const void *funcPtr)
105 move(TrustedImmPtr(funcPtr), ScratchRegister);
106 jump(ScratchRegister);
109 void pushAligned(RegisterID reg)
111 subPtr(TrustedImm32(PointerSize), StackPointerRegister);
115 void popAligned(RegisterID reg)
118 addPtr(TrustedImm32(PointerSize), StackPointerRegister);
122typedef PlatformAssembler_X86_64_SysV PlatformAssemblerBase;
127class PlatformAssembler_Win64 :
public JSC::MacroAssembler<JSC::MacroAssemblerX86_64>
130 static const RegisterID NoRegister = RegisterID::none;
132 static const RegisterID ReturnValueRegister = RegisterID::eax;
133 static const RegisterID ReturnValueRegisterValue = ReturnValueRegister;
134 static const RegisterID AccumulatorRegister = RegisterID::eax;
135 static const RegisterID AccumulatorRegisterValue = AccumulatorRegister;
136 static const RegisterID ScratchRegister = RegisterID::r10;
137 static const RegisterID ScratchRegister2 = RegisterID::r9;
138 static const RegisterID JSStackFrameRegister = RegisterID::r12;
139 static const RegisterID CppStackFrameRegister = RegisterID::r13;
140 static const RegisterID EngineRegister = RegisterID::r14;
141 static const RegisterID StackPointerRegister = RegisterID::esp;
142 static const RegisterID FramePointerRegister = RegisterID::ebp;
143 static const FPRegisterID FPScratchRegister = FPRegisterID::xmm1;
145 static const RegisterID Arg0Reg = RegisterID::ecx;
146 static const RegisterID Arg1Reg = RegisterID::edx;
147 static const RegisterID Arg2Reg = RegisterID::r8;
148 static const RegisterID Arg3Reg = RegisterID::r9;
149 static const RegisterID Arg4Reg = NoRegister;
150 static const RegisterID Arg5Reg = NoRegister;
151 static const RegisterID Arg6Reg = NoRegister;
152 static const RegisterID Arg7Reg = NoRegister;
153 static const int ArgInRegCount = 4;
157 addPtr(TrustedImmPtr(
sizeof(ReturnedValue)), StackPointerRegister);
160 void generatePlatformFunctionEntry()
162 push(FramePointerRegister);
163 move(StackPointerRegister, FramePointerRegister);
164 move(TrustedImmPtr(
nullptr), AccumulatorRegister);
push(AccumulatorRegister);
165 push(JSStackFrameRegister);
166 push(CppStackFrameRegister);
167 push(EngineRegister);
168 move(Arg0Reg, CppStackFrameRegister);
169 move(Arg1Reg, EngineRegister);
172 void generatePlatformFunctionExit(
bool tailCall =
false)
175 pop(CppStackFrameRegister);
176 pop(JSStackFrameRegister);
178 pop(FramePointerRegister);
183 void callAbsolute(
const void *funcPtr)
185 move(TrustedImmPtr(funcPtr), ScratchRegister);
186 subPtr(TrustedImm32(4 * PointerSize), StackPointerRegister);
187 call(ScratchRegister);
188 addPtr(TrustedImm32(4 * PointerSize), StackPointerRegister);
191 void jumpAbsolute(
const void *funcPtr)
193 move(TrustedImmPtr(funcPtr), ScratchRegister);
194 jump(ScratchRegister);
197 void pushAligned(RegisterID reg)
199 subPtr(TrustedImm32(PointerSize), StackPointerRegister);
203 void popAligned(RegisterID reg)
206 addPtr(TrustedImm32(PointerSize), StackPointerRegister);
210typedef PlatformAssembler_Win64 PlatformAssemblerBase;
215#if (defined(Q_PROCESSOR_X86) && !defined(Q_PROCESSOR_X86_64)) || defined(ENABLE_ALL_ASSEMBLERS_FOR_REFACTORING_PURPOSES)
217class PlatformAssembler_X86_All :
public JSC::MacroAssembler<JSC::MacroAssemblerX86>
220 static const RegisterID NoRegister = RegisterID::none;
222 static const RegisterID ReturnValueRegisterValue = RegisterID::eax;
223 static const RegisterID ReturnValueRegisterTag = RegisterID::edx;
224 static const RegisterID ScratchRegister = RegisterID::ecx;
225 static const RegisterID AccumulatorRegisterValue = ReturnValueRegisterValue;
226 static const RegisterID AccumulatorRegisterTag = ReturnValueRegisterTag;
227 static const RegisterID JSStackFrameRegister = RegisterID::ebx;
228 static const RegisterID CppStackFrameRegister = RegisterID::esi;
229 static const RegisterID EngineRegister = RegisterID::edi;
230 static const RegisterID StackPointerRegister = RegisterID::esp;
231 static const RegisterID FramePointerRegister = RegisterID::ebp;
232 static const FPRegisterID FPScratchRegister = FPRegisterID::xmm1;
234 static const RegisterID Arg0Reg = NoRegister;
235 static const RegisterID Arg1Reg = NoRegister;
236 static const RegisterID Arg2Reg = NoRegister;
237 static const RegisterID Arg3Reg = NoRegister;
238 static const RegisterID Arg4Reg = NoRegister;
239 static const RegisterID Arg5Reg = NoRegister;
240 static const RegisterID Arg6Reg = NoRegister;
241 static const RegisterID Arg7Reg = NoRegister;
242 static const int ArgInRegCount = 0;
246 addPtr(TrustedImmPtr(
sizeof(ReturnedValue)), StackPointerRegister);
249 void generatePlatformFunctionEntry()
251 push(RegisterID::ebp);
252 move(RegisterID::esp, RegisterID::ebp);
253 move(TrustedImmPtr(
nullptr), AccumulatorRegisterValue);
push(AccumulatorRegisterValue);
254 push(JSStackFrameRegister);
255 push(CppStackFrameRegister);
256 push(EngineRegister);
259 subPtr(TrustedImm32(8), StackPointerRegister);
260 loadPtr(Address(FramePointerRegister, 2 * PointerSize), CppStackFrameRegister);
261 loadPtr(Address(FramePointerRegister, 3 * PointerSize), EngineRegister);
264 void generatePlatformFunctionExit(
bool tailCall =
false)
266 addPtr(TrustedImm32(8), StackPointerRegister);
268 pop(CppStackFrameRegister);
269 pop(JSStackFrameRegister);
271 pop(RegisterID::ebp);
276 void callAbsolute(
const void *funcPtr)
278 move(TrustedImmPtr(funcPtr), ScratchRegister);
279 call(ScratchRegister);
282 void jumpAbsolute(
const void *funcPtr)
284 move(TrustedImmPtr(funcPtr), ScratchRegister);
285 jump(ScratchRegister);
288 void pushAligned(RegisterID reg)
290 subPtr(TrustedImm32(3 * PointerSize), StackPointerRegister);
294 void popAligned(RegisterID reg)
297 addPtr(TrustedImm32(3 * PointerSize), StackPointerRegister);
301typedef PlatformAssembler_X86_All PlatformAssemblerBase;
305#if defined(Q_PROCESSOR_ARM_64) || defined(ENABLE_ALL_ASSEMBLERS_FOR_REFACTORING_PURPOSES)
307class PlatformAssembler_ARM64 :
public JSC::MacroAssembler<JSC::MacroAssemblerARM64>
310 static const RegisterID NoRegister = RegisterID::none;
312 static const RegisterID ReturnValueRegister = JSC::ARM64Registers::x0;
313 static const RegisterID ReturnValueRegisterValue = ReturnValueRegister;
314 static const RegisterID AccumulatorRegister = JSC::ARM64Registers::x9;
315 static const RegisterID AccumulatorRegisterValue = AccumulatorRegister;
316 static const RegisterID ScratchRegister = JSC::ARM64Registers::x10;
317 static const RegisterID ScratchRegister2 = JSC::ARM64Registers::x7;
318 static const RegisterID JSStackFrameRegister = JSC::ARM64Registers::x19;
319 static const RegisterID CppStackFrameRegister = JSC::ARM64Registers::x20;
320 static const RegisterID EngineRegister = JSC::ARM64Registers::x21;
321 static const RegisterID StackPointerRegister = JSC::ARM64Registers::sp;
322 static const RegisterID FramePointerRegister = JSC::ARM64Registers::fp;
323 static const FPRegisterID FPScratchRegister = JSC::ARM64Registers::q1;
325 static const RegisterID Arg0Reg = JSC::ARM64Registers::x0;
326 static const RegisterID Arg1Reg = JSC::ARM64Registers::x1;
327 static const RegisterID Arg2Reg = JSC::ARM64Registers::x2;
328 static const RegisterID Arg3Reg = JSC::ARM64Registers::x3;
329 static const RegisterID Arg4Reg = JSC::ARM64Registers::x4;
330 static const RegisterID Arg5Reg = JSC::ARM64Registers::x5;
331 static const RegisterID Arg6Reg = JSC::ARM64Registers::x6;
332 static const RegisterID Arg7Reg = JSC::ARM64Registers::x7;
333 static const int ArgInRegCount = 8;
340 void pop(RegisterID dest)
347 add64(TrustedImm32(16), stackPointerRegister);
355 void generatePlatformFunctionEntry()
357 pushPair(JSC::ARM64Registers::fp, JSC::ARM64Registers::lr);
358 move(RegisterID::sp, RegisterID::fp);
359 move(TrustedImmPtr(
nullptr), AccumulatorRegister);
360 pushPair(JSStackFrameRegister, AccumulatorRegister);
361 pushPair(EngineRegister, CppStackFrameRegister);
362 move(Arg0Reg, CppStackFrameRegister);
363 move(Arg1Reg, EngineRegister);
366 void generatePlatformFunctionExit(
bool tailCall =
false)
369 move(AccumulatorRegister, ReturnValueRegister);
370 popPair(EngineRegister, CppStackFrameRegister);
371 popPair(JSStackFrameRegister, AccumulatorRegister);
372 popPair(JSC::ARM64Registers::fp, JSC::ARM64Registers::lr);
377 void callAbsolute(
const void *funcPtr)
379 move(TrustedImmPtr(funcPtr), ScratchRegister);
380 call(ScratchRegister);
383 void jumpAbsolute(
const void *funcPtr)
385 move(TrustedImmPtr(funcPtr), ScratchRegister);
386 jump(ScratchRegister);
389 void pushAligned(RegisterID reg)
394 void popAligned(RegisterID reg)
400typedef PlatformAssembler_ARM64 PlatformAssemblerBase;
404#if defined(Q_PROCESSOR_ARM_32) || defined(ENABLE_ALL_ASSEMBLERS_FOR_REFACTORING_PURPOSES)
406class PlatformAssembler_ARM32 :
public JSC::MacroAssembler<JSC::MacroAssemblerARMv7>
409 static const RegisterID NoRegister = RegisterID::none;
411 static const RegisterID ReturnValueRegisterValue = JSC::ARMRegisters::r0;
412 static const RegisterID ReturnValueRegisterTag = JSC::ARMRegisters::r1;
413 static const RegisterID ScratchRegister = JSC::ARMRegisters::r2;
414 static const RegisterID AccumulatorRegisterValue = JSC::ARMRegisters::r4;
415 static const RegisterID AccumulatorRegisterTag = JSC::ARMRegisters::r5;
417 static const RegisterID JSStackFrameRegister = JSC::ARMRegisters::r8;
418 static const RegisterID CppStackFrameRegister = JSC::ARMRegisters::r10;
420 static const RegisterID FramePointerRegister = JSC::ARMRegisters::r7;
421 static const RegisterID EngineRegister = JSC::ARMRegisters::r11;
423 static const RegisterID FramePointerRegister = JSC::ARMRegisters::r11;
424 static const RegisterID EngineRegister = JSC::ARMRegisters::r7;
426 static const RegisterID StackPointerRegister = JSC::ARMRegisters::r13;
427 static const FPRegisterID FPScratchRegister = JSC::ARMRegisters::d1;
429 static const RegisterID Arg0Reg = JSC::ARMRegisters::r0;
430 static const RegisterID Arg1Reg = JSC::ARMRegisters::r1;
431 static const RegisterID Arg2Reg = JSC::ARMRegisters::r2;
432 static const RegisterID Arg3Reg = JSC::ARMRegisters::r3;
433 static const RegisterID Arg4Reg = NoRegister;
434 static const RegisterID Arg5Reg = NoRegister;
435 static const RegisterID Arg6Reg = NoRegister;
436 static const RegisterID Arg7Reg = NoRegister;
437 static const int ArgInRegCount = 4;
441 addPtr(TrustedImm32(
sizeof(ReturnedValue)), StackPointerRegister);
444 void generatePlatformFunctionEntry()
446 push(JSC::ARMRegisters::lr);
447 push(FramePointerRegister);
448 move(StackPointerRegister, FramePointerRegister);
449 push(TrustedImm32(0));
450 push(AccumulatorRegisterValue);
451 push(AccumulatorRegisterTag);
452 push(addressTempRegister);
453 push(JSStackFrameRegister);
454 push(CppStackFrameRegister);
455 push(EngineRegister);
456 subPtr(TrustedImm32(4), StackPointerRegister);
457 move(Arg0Reg, CppStackFrameRegister);
458 move(Arg1Reg, EngineRegister);
461 void generatePlatformFunctionExit(
bool tailCall =
false)
464 move(AccumulatorRegisterValue, ReturnValueRegisterValue);
465 move(AccumulatorRegisterTag, ReturnValueRegisterTag);
467 addPtr(TrustedImm32(4), StackPointerRegister);
469 pop(CppStackFrameRegister);
470 pop(JSStackFrameRegister);
471 pop(addressTempRegister);
472 pop(AccumulatorRegisterTag);
473 pop(AccumulatorRegisterValue);
475 pop(FramePointerRegister);
476 pop(JSC::ARMRegisters::lr);
481 void callAbsolute(
const void *funcPtr)
483 move(TrustedImmPtr(funcPtr), dataTempRegister);
484 call(dataTempRegister);
487 void jumpAbsolute(
const void *funcPtr)
489 move(TrustedImmPtr(funcPtr), dataTempRegister);
490 jump(dataTempRegister);
493 void pushAligned(RegisterID reg)
495 subPtr(TrustedImm32(PointerSize), StackPointerRegister);
499 void popAligned(RegisterID reg)
502 addPtr(TrustedImm32(PointerSize), StackPointerRegister);
506typedef PlatformAssembler_ARM32 PlatformAssemblerBase;
509class PlatformAssemblerCommon :
public JIT::PlatformAssemblerBase
512 PlatformAssemblerCommon(
const Value *constantTable)
513 : constantTable(constantTable)
516 virtual ~PlatformAssemblerCommon();
518 Address exceptionHandlerAddress()
const
520 return Address(FramePointerRegister, -1 * PointerSize);
523 Address contextAddress()
const
525 return Address(JSStackFrameRegister, offsetof(CallData,
context));
528 RegisterID registerForArg(
int arg)
const
533 case 0:
return Arg0Reg;
534 case 1:
return Arg1Reg;
535 case 2:
return Arg2Reg;
536 case 3:
return Arg3Reg;
537 case 4:
return Arg4Reg;
538 case 5:
return Arg5Reg;
539 case 6:
return Arg6Reg;
540 case 7:
return Arg7Reg;
547 Address loadFunctionPtr(RegisterID
target)
549 Address
addr(CppStackFrameRegister, offsetof(JSTypesStackFrame, v4Function));
554 Address loadCompilationUnitPtr(RegisterID
target)
562 Address loadConstAddress(
int constIndex, RegisterID baseReg = ScratchRegister)
564 Address
addr = loadCompilationUnitPtr(baseReg);
566 loadPtr(
addr, baseReg);
571 Address loadStringAddress(
int stringId)
573 Address
addr = loadCompilationUnitPtr(ScratchRegister);
575 loadPtr(
addr, ScratchRegister);
576 return Address(ScratchRegister, stringId * PointerSize);
579 void passAsArg(RegisterID
src,
int arg)
581 move(
src, registerForArg(
arg));
584 void generateCatchTrampoline(std::function<
void()> loadUndefined)
586 for (Jump
j : catchyJumps)
592 loadPtr(exceptionHandlerAddress(), ScratchRegister);
593 Jump exitFunction = branchPtr(Equal, ScratchRegister, TrustedImmPtr(0));
595 jump(ScratchRegister);
596 exitFunction.link(
this);
598 if (functionExit.isSet())
601 generateFunctionExit();
604 void checkException()
610 Address(EngineRegister, offsetof(EngineBase, hasException)),
614 void addCatchyJump(Jump
j)
617 catchyJumps.push_back(
j);
620 void generateFunctionEntry()
622 generatePlatformFunctionEntry();
623 loadPtr(Address(CppStackFrameRegister, offsetof(JSTypesStackFrame, jsFrame)),
624 JSStackFrameRegister);
625 allocateStackSpace();
628 virtual void allocateStackSpace() {}
630 void generateFunctionExit()
632 if (functionExit.isSet()) {
637 functionExit =
label();
639 generatePlatformFunctionExit();
642 virtual void freeStackSpace() {}
644 void addLabelForOffset(
int offset)
646 if (!labelForOffset.contains(
offset))
650 void addJumpToOffset(
const Jump &
jump,
int offset)
655 void addEHTarget(
const DataLabelPtr &
label,
int offset)
660 void link(
Function *function,
const char *jitKind);
663 {
return constantTable[idx]; }
666 void prepareCallWithArgCount(
int argc);
667 void storeInstructionPointer(
int instructionOffset);
668 void passAccumulatorAsArg(
int arg);
669 void pushAccumulatorAsArg(
int arg);
670 void passFunctionAsArg(
int arg);
671 void passEngineAsArg(
int arg);
672 void passJSSlotAsArg(
int reg,
int arg);
673 void passAddressAsArg(Address
addr,
int arg);
674 void passCppFrameAsArg(
int arg);
675 void passInt32AsArg(
int value,
int arg);
676 void passPointerAsArg(
void *
ptr,
int arg);
677 void callRuntime(
const void *funcPtr,
const char *functionName =
nullptr);
678 void callRuntimeUnchecked(
const void *funcPtr,
const char *functionName =
nullptr);
679 void tailCallRuntime(
const void *funcPtr,
const char *functionName =
nullptr);
680 void setTailCallArg(RegisterID
src,
int arg);
681 Address jsAlloca(
int slotCount);
682 void storeInt32AsValue(
int srcInt, Address destAddr);
685 void passAccumulatorAsArg_internal(
int arg,
bool doPush);
686 static Address argStackAddress(
int arg);
689 const Value* constantTable;
690 struct JumpTarget { JSC::MacroAssemblerBase::Jump
jump;
int offset; };
691 std::vector<JumpTarget> jumpsToLink;
692 struct ExceptionHanlderTarget { JSC::MacroAssemblerBase::DataLabelPtr
label;
int offset; };
693 std::vector<ExceptionHanlderTarget> ehTargets;
696 std::vector<Jump> catchyJumps;
700 enum { NoCall = -1 };
701 int remainingArgcForCall = NoCall;
703 int argcOnStackForCall = 0;
Combined button and popup list for selecting options.
\qmltype Particle \inqmlmodule QtQuick.Particles
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
static void jump(QtMsgType t, const QMessageLogContext &context, const QString &m)
static ControlElement< T > * ptr(QWidget *widget)
GLuint GLsizei const GLchar * label
[43]
GLenum GLuint GLintptr offset
#define Q_UNIMPLEMENTED()
static const QV4::Value & constant(Function *function, int index)