123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998 |
- /*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #ifndef DFGCCallHelpers_h
- #define DFGCCallHelpers_h
- #include <wtf/Platform.h>
- #if ENABLE(DFG_JIT)
- #include "DFGAssemblyHelpers.h"
- #include "DFGGPRInfo.h"
- namespace JSC { namespace DFG {
- class CCallHelpers : public AssemblyHelpers {
- public:
- CCallHelpers(VM* vm, CodeBlock* codeBlock = 0)
- : AssemblyHelpers(vm, codeBlock)
- {
- }
- // These methods used to sort arguments into the correct registers.
- // On X86 we use cdecl calling conventions, which pass all arguments on the
- // stack. On other architectures we may need to sort values into the
- // correct registers.
- #if !NUMBER_OF_ARGUMENT_REGISTERS
- unsigned m_callArgumentOffset;
- void resetCallArguments() { m_callArgumentOffset = 0; }
- // These methods are using internally to implement the callOperation methods.
- void addCallArgument(GPRReg value)
- {
- poke(value, m_callArgumentOffset++);
- }
- void addCallArgument(TrustedImm32 imm)
- {
- poke(imm, m_callArgumentOffset++);
- }
- void addCallArgument(TrustedImmPtr pointer)
- {
- poke(pointer, m_callArgumentOffset++);
- }
- void addCallArgument(FPRReg value)
- {
- storeDouble(value, Address(stackPointerRegister, m_callArgumentOffset * sizeof(void*)));
- m_callArgumentOffset += sizeof(double) / sizeof(void*);
- }
- ALWAYS_INLINE void setupArguments(FPRReg arg1)
- {
- resetCallArguments();
- addCallArgument(arg1);
- }
- ALWAYS_INLINE void setupArguments(FPRReg arg1, FPRReg arg2)
- {
- resetCallArguments();
- addCallArgument(arg1);
- addCallArgument(arg2);
- }
- ALWAYS_INLINE void setupArguments(GPRReg arg1)
- {
- resetCallArguments();
- addCallArgument(arg1);
- }
- ALWAYS_INLINE void setupArguments(GPRReg arg1, GPRReg arg2)
- {
- resetCallArguments();
- addCallArgument(arg1);
- addCallArgument(arg2);
- }
-
- ALWAYS_INLINE void setupArguments(TrustedImmPtr arg1)
- {
- resetCallArguments();
- addCallArgument(arg1);
- }
- ALWAYS_INLINE void setupArgumentsExecState()
- {
- resetCallArguments();
- addCallArgument(GPRInfo::callFrameRegister);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1)
- {
- resetCallArguments();
- addCallArgument(GPRInfo::callFrameRegister);
- addCallArgument(arg1);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1)
- {
- resetCallArguments();
- addCallArgument(GPRInfo::callFrameRegister);
- addCallArgument(arg1);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1)
- {
- resetCallArguments();
- addCallArgument(GPRInfo::callFrameRegister);
- addCallArgument(arg1);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2)
- {
- resetCallArguments();
- addCallArgument(GPRInfo::callFrameRegister);
- addCallArgument(arg1);
- addCallArgument(arg2);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2)
- {
- resetCallArguments();
- addCallArgument(GPRInfo::callFrameRegister);
- addCallArgument(arg1);
- addCallArgument(arg2);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2)
- {
- resetCallArguments();
- addCallArgument(GPRInfo::callFrameRegister);
- addCallArgument(arg1);
- addCallArgument(arg2);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2)
- {
- resetCallArguments();
- addCallArgument(GPRInfo::callFrameRegister);
- addCallArgument(arg1);
- addCallArgument(arg2);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2)
- {
- resetCallArguments();
- addCallArgument(GPRInfo::callFrameRegister);
- addCallArgument(arg1);
- addCallArgument(arg2);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2)
- {
- resetCallArguments();
- addCallArgument(GPRInfo::callFrameRegister);
- addCallArgument(arg1);
- addCallArgument(arg2);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImmPtr arg2)
- {
- resetCallArguments();
- addCallArgument(GPRInfo::callFrameRegister);
- addCallArgument(arg1);
- addCallArgument(arg2);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImm32 arg2)
- {
- resetCallArguments();
- addCallArgument(GPRInfo::callFrameRegister);
- addCallArgument(arg1);
- addCallArgument(arg2);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3)
- {
- resetCallArguments();
- addCallArgument(GPRInfo::callFrameRegister);
- addCallArgument(arg1);
- addCallArgument(arg2);
- addCallArgument(arg3);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImmPtr arg3)
- {
- resetCallArguments();
- addCallArgument(GPRInfo::callFrameRegister);
- addCallArgument(arg1);
- addCallArgument(arg2);
- addCallArgument(arg3);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2, GPRReg arg3)
- {
- resetCallArguments();
- addCallArgument(GPRInfo::callFrameRegister);
- addCallArgument(arg1);
- addCallArgument(arg2);
- addCallArgument(arg3);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2, TrustedImmPtr arg3)
- {
- resetCallArguments();
- addCallArgument(GPRInfo::callFrameRegister);
- addCallArgument(arg1);
- addCallArgument(arg2);
- addCallArgument(arg3);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImmPtr arg2, TrustedImmPtr arg3)
- {
- resetCallArguments();
- addCallArgument(GPRInfo::callFrameRegister);
- addCallArgument(arg1);
- addCallArgument(arg2);
- addCallArgument(arg3);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImmPtr arg3)
- {
- resetCallArguments();
- addCallArgument(GPRInfo::callFrameRegister);
- addCallArgument(arg1);
- addCallArgument(arg2);
- addCallArgument(arg3);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4)
- {
- resetCallArguments();
- addCallArgument(GPRInfo::callFrameRegister);
- addCallArgument(arg1);
- addCallArgument(arg2);
- addCallArgument(arg3);
- addCallArgument(arg4);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5)
- {
- resetCallArguments();
- addCallArgument(GPRInfo::callFrameRegister);
- addCallArgument(arg1);
- addCallArgument(arg2);
- addCallArgument(arg3);
- addCallArgument(arg4);
- addCallArgument(arg5);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4)
- {
- resetCallArguments();
- addCallArgument(GPRInfo::callFrameRegister);
- addCallArgument(arg1);
- addCallArgument(arg2);
- addCallArgument(arg3);
- addCallArgument(arg4);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4)
- {
- resetCallArguments();
- addCallArgument(GPRInfo::callFrameRegister);
- addCallArgument(arg1);
- addCallArgument(arg2);
- addCallArgument(arg3);
- addCallArgument(arg4);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImmPtr arg2, GPRReg arg3)
- {
- resetCallArguments();
- addCallArgument(GPRInfo::callFrameRegister);
- addCallArgument(arg1);
- addCallArgument(arg2);
- addCallArgument(arg3);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImmPtr arg4)
- {
- resetCallArguments();
- addCallArgument(GPRInfo::callFrameRegister);
- addCallArgument(arg1);
- addCallArgument(arg2);
- addCallArgument(arg3);
- addCallArgument(arg4);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImm32 arg4)
- {
- resetCallArguments();
- addCallArgument(GPRInfo::callFrameRegister);
- addCallArgument(arg1);
- addCallArgument(arg2);
- addCallArgument(arg3);
- addCallArgument(arg4);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, GPRReg arg3, GPRReg arg4)
- {
- resetCallArguments();
- addCallArgument(GPRInfo::callFrameRegister);
- addCallArgument(arg1);
- addCallArgument(arg2);
- addCallArgument(arg3);
- addCallArgument(arg4);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5)
- {
- resetCallArguments();
- addCallArgument(GPRInfo::callFrameRegister);
- addCallArgument(arg1);
- addCallArgument(arg2);
- addCallArgument(arg3);
- addCallArgument(arg4);
- addCallArgument(arg5);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, GPRReg arg2)
- {
- resetCallArguments();
- addCallArgument(GPRInfo::callFrameRegister);
- addCallArgument(arg1);
- addCallArgument(arg2);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3)
- {
- resetCallArguments();
- addCallArgument(GPRInfo::callFrameRegister);
- addCallArgument(arg1);
- addCallArgument(arg2);
- addCallArgument(arg3);
- }
- #endif // !NUMBER_OF_ARGUMENT_REGISTERS
- // These methods are suitable for any calling convention that provides for
- // at least 4 argument registers, e.g. X86_64, ARMv7.
- #if NUMBER_OF_ARGUMENT_REGISTERS >= 4
- template<GPRReg destA, GPRReg destB>
- void setupTwoStubArgs(GPRReg srcA, GPRReg srcB)
- {
- // Assuming that srcA != srcB, there are 7 interesting states the registers may be in:
- // (1) both are already in arg regs, the right way around.
- // (2) both are already in arg regs, the wrong way around.
- // (3) neither are currently in arg registers.
- // (4) srcA in in its correct reg.
- // (5) srcA in in the incorrect reg.
- // (6) srcB in in its correct reg.
- // (7) srcB in in the incorrect reg.
- //
- // The trivial approach is to simply emit two moves, to put srcA in place then srcB in
- // place (the MacroAssembler will omit redundant moves). This apporach will be safe in
- // cases 1, 3, 4, 5, 6, and in cases where srcA==srcB. The two problem cases are 2
- // (requires a swap) and 7 (must move srcB first, to avoid trampling.)
- if (srcB != destA) {
- // Handle the easy cases - two simple moves.
- move(srcA, destA);
- move(srcB, destB);
- } else if (srcA != destB) {
- // Handle the non-swap case - just put srcB in place first.
- move(srcB, destB);
- move(srcA, destA);
- } else
- swap(destA, destB);
- }
- #if CPU(X86_64)
- template<FPRReg destA, FPRReg destB>
- void setupTwoStubArgs(FPRReg srcA, FPRReg srcB)
- {
- // Assuming that srcA != srcB, there are 7 interesting states the registers may be in:
- // (1) both are already in arg regs, the right way around.
- // (2) both are already in arg regs, the wrong way around.
- // (3) neither are currently in arg registers.
- // (4) srcA in in its correct reg.
- // (5) srcA in in the incorrect reg.
- // (6) srcB in in its correct reg.
- // (7) srcB in in the incorrect reg.
- //
- // The trivial approach is to simply emit two moves, to put srcA in place then srcB in
- // place (the MacroAssembler will omit redundant moves). This apporach will be safe in
- // cases 1, 3, 4, 5, 6, and in cases where srcA==srcB. The two problem cases are 2
- // (requires a swap) and 7 (must move srcB first, to avoid trampling.)
- if (srcB != destA) {
- // Handle the easy cases - two simple moves.
- moveDouble(srcA, destA);
- moveDouble(srcB, destB);
- return;
- }
-
- if (srcA != destB) {
- // Handle the non-swap case - just put srcB in place first.
- moveDouble(srcB, destB);
- moveDouble(srcA, destA);
- return;
- }
- ASSERT(srcB == destA && srcA == destB);
- // Need to swap; pick a temporary register.
- FPRReg temp;
- if (destA != FPRInfo::argumentFPR3 && destA != FPRInfo::argumentFPR3)
- temp = FPRInfo::argumentFPR3;
- else if (destA != FPRInfo::argumentFPR2 && destA != FPRInfo::argumentFPR2)
- temp = FPRInfo::argumentFPR2;
- else {
- ASSERT(destA != FPRInfo::argumentFPR1 && destA != FPRInfo::argumentFPR1);
- temp = FPRInfo::argumentFPR1;
- }
- moveDouble(destA, temp);
- moveDouble(destB, destA);
- moveDouble(temp, destB);
- }
- #endif
- void setupStubArguments(GPRReg arg1, GPRReg arg2)
- {
- setupTwoStubArgs<GPRInfo::argumentGPR1, GPRInfo::argumentGPR2>(arg1, arg2);
- }
- void setupStubArguments(GPRReg arg1, GPRReg arg2, GPRReg arg3)
- {
- // If neither of arg2/arg3 are in our way, then we can move arg1 into place.
- // Then we can use setupTwoStubArgs to fix arg2/arg3.
- if (arg2 != GPRInfo::argumentGPR1 && arg3 != GPRInfo::argumentGPR1) {
- move(arg1, GPRInfo::argumentGPR1);
- setupTwoStubArgs<GPRInfo::argumentGPR2, GPRInfo::argumentGPR3>(arg2, arg3);
- return;
- }
- // If neither of arg1/arg3 are in our way, then we can move arg2 into place.
- // Then we can use setupTwoStubArgs to fix arg1/arg3.
- if (arg1 != GPRInfo::argumentGPR2 && arg3 != GPRInfo::argumentGPR2) {
- move(arg2, GPRInfo::argumentGPR2);
- setupTwoStubArgs<GPRInfo::argumentGPR1, GPRInfo::argumentGPR3>(arg1, arg3);
- return;
- }
- // If neither of arg1/arg2 are in our way, then we can move arg3 into place.
- // Then we can use setupTwoStubArgs to fix arg1/arg2.
- if (arg1 != GPRInfo::argumentGPR3 && arg2 != GPRInfo::argumentGPR3) {
- move(arg3, GPRInfo::argumentGPR3);
- setupTwoStubArgs<GPRInfo::argumentGPR1, GPRInfo::argumentGPR2>(arg1, arg2);
- return;
- }
- // If we get here, we haven't been able to move any of arg1/arg2/arg3.
- // Since all three are blocked, then all three must already be in the argument register.
- // But are they in the right ones?
- // First, ensure arg1 is in place.
- if (arg1 != GPRInfo::argumentGPR1) {
- swap(arg1, GPRInfo::argumentGPR1);
- // If arg1 wasn't in argumentGPR1, one of arg2/arg3 must be.
- ASSERT(arg2 == GPRInfo::argumentGPR1 || arg3 == GPRInfo::argumentGPR1);
- // If arg2 was in argumentGPR1 it no longer is (due to the swap).
- // Otherwise arg3 must have been. Mark him as moved.
- if (arg2 == GPRInfo::argumentGPR1)
- arg2 = arg1;
- else
- arg3 = arg1;
- }
- // Either arg2 & arg3 need swapping, or we're all done.
- ASSERT((arg2 == GPRInfo::argumentGPR2 || arg3 == GPRInfo::argumentGPR3)
- || (arg2 == GPRInfo::argumentGPR3 || arg3 == GPRInfo::argumentGPR2));
- if (arg2 != GPRInfo::argumentGPR2)
- swap(GPRInfo::argumentGPR2, GPRInfo::argumentGPR3);
- }
- #if CPU(X86_64)
- ALWAYS_INLINE void setupArguments(FPRReg arg1)
- {
- moveDouble(arg1, FPRInfo::argumentFPR0);
- }
- ALWAYS_INLINE void setupArguments(FPRReg arg1, FPRReg arg2)
- {
- setupTwoStubArgs<FPRInfo::argumentFPR0, FPRInfo::argumentFPR1>(arg1, arg2);
- }
-
- ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, GPRReg arg2)
- {
- moveDouble(arg1, FPRInfo::argumentFPR0);
- move(arg2, GPRInfo::argumentGPR1);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3)
- {
- moveDouble(arg3, FPRInfo::argumentFPR0);
- setupStubArguments(arg1, arg2);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- }
- #elif CPU(ARM)
- #if CPU(ARM_HARDFP)
- ALWAYS_INLINE void setupArguments(FPRReg arg1)
- {
- moveDouble(arg1, FPRInfo::argumentFPR0);
- }
- ALWAYS_INLINE void setupArguments(FPRReg arg1, FPRReg arg2)
- {
- if (arg2 != FPRInfo::argumentFPR0) {
- moveDouble(arg1, FPRInfo::argumentFPR0);
- moveDouble(arg2, FPRInfo::argumentFPR1);
- } else if (arg1 != FPRInfo::argumentFPR1) {
- moveDouble(arg2, FPRInfo::argumentFPR1);
- moveDouble(arg1, FPRInfo::argumentFPR0);
- } else {
- // Swap arg1, arg2.
- moveDouble(FPRInfo::argumentFPR0, ARMRegisters::d2);
- moveDouble(FPRInfo::argumentFPR1, FPRInfo::argumentFPR0);
- moveDouble(ARMRegisters::d2, FPRInfo::argumentFPR1);
- }
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, GPRReg arg2)
- {
- moveDouble(arg1, FPRInfo::argumentFPR0);
- move(arg2, GPRInfo::argumentGPR1);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3)
- {
- moveDouble(arg3, FPRInfo::argumentFPR0);
- setupStubArguments(arg1, arg2);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- }
- #else
- ALWAYS_INLINE void setupArguments(FPRReg arg1)
- {
- assembler().vmov(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, arg1);
- }
- ALWAYS_INLINE void setupArguments(FPRReg arg1, FPRReg arg2)
- {
- assembler().vmov(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, arg1);
- assembler().vmov(GPRInfo::argumentGPR2, GPRInfo::argumentGPR3, arg2);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, GPRReg arg2)
- {
- move(arg2, GPRInfo::argumentGPR3);
- assembler().vmov(GPRInfo::argumentGPR1, GPRInfo::argumentGPR2, arg1);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3)
- {
- setupStubArguments(arg1, arg2);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- assembler().vmov(GPRInfo::argumentGPR3, GPRInfo::nonArgGPR0, arg3);
- poke(GPRInfo::nonArgGPR0);
- }
- #endif // CPU(ARM_HARDFP)
- #elif CPU(MIPS)
- ALWAYS_INLINE void setupArguments(FPRReg arg1)
- {
- moveDouble(arg1, FPRInfo::argumentFPR0);
- }
- ALWAYS_INLINE void setupArguments(FPRReg arg1, FPRReg arg2)
- {
- if (arg2 != FPRInfo::argumentFPR0) {
- moveDouble(arg1, FPRInfo::argumentFPR0);
- moveDouble(arg2, FPRInfo::argumentFPR1);
- } else if (arg1 != FPRInfo::argumentFPR1) {
- moveDouble(arg2, FPRInfo::argumentFPR1);
- moveDouble(arg1, FPRInfo::argumentFPR0);
- } else {
- // Swap arg1, arg2.
- swapDouble(FPRInfo::argumentFPR0, FPRInfo::argumentFPR1);
- }
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, GPRReg arg2)
- {
- assembler().vmov(GPRInfo::argumentGPR2, GPRInfo::argumentGPR3, arg1);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- poke(arg2, 4);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3)
- {
- setupStubArguments(arg1, arg2);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- poke(arg3, 4);
- }
- #else
- #error "DFG JIT not supported on this platform."
- #endif
- ALWAYS_INLINE void setupArguments(GPRReg arg1)
- {
- move(arg1, GPRInfo::argumentGPR0);
- }
- ALWAYS_INLINE void setupArguments(GPRReg arg1, GPRReg arg2)
- {
- setupTwoStubArgs<GPRInfo::argumentGPR0, GPRInfo::argumentGPR1>(arg1, arg2);
- }
-
- ALWAYS_INLINE void setupArguments(TrustedImmPtr arg1)
- {
- move(arg1, GPRInfo::argumentGPR0);
- }
- ALWAYS_INLINE void setupArgumentsExecState()
- {
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1)
- {
- move(arg1, GPRInfo::argumentGPR1);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1)
- {
- move(arg1, GPRInfo::argumentGPR1);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1)
- {
- move(arg1, GPRInfo::argumentGPR1);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2)
- {
- setupStubArguments(arg1, arg2);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2)
- {
- move(arg1, GPRInfo::argumentGPR1);
- move(arg2, GPRInfo::argumentGPR2);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- }
- #if CPU(X86_64)
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm64 arg2)
- {
- move(arg1, GPRInfo::argumentGPR1);
- move(arg2, GPRInfo::argumentGPR2);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- }
-
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm64 arg1, GPRReg arg2)
- {
- move(arg2, GPRInfo::argumentGPR2); // Move this first, so setting arg1 does not trample!
- move(arg1, GPRInfo::argumentGPR1);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- }
- #endif
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2)
- {
- move(arg1, GPRInfo::argumentGPR1);
- move(arg2, GPRInfo::argumentGPR2);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- }
-
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, ImmPtr arg2)
- {
- move(arg1, GPRInfo::argumentGPR1);
- move(arg2, GPRInfo::argumentGPR2);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2)
- {
- move(arg2, GPRInfo::argumentGPR2); // Move this first, so setting arg1 does not trample!
- move(arg1, GPRInfo::argumentGPR1);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- }
-
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2)
- {
- move(arg2, GPRInfo::argumentGPR2); // Move this first, so setting arg1 does not trample!
- move(arg1, GPRInfo::argumentGPR1);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- }
-
- ALWAYS_INLINE void setupArgumentsWithExecState(ImmPtr arg1, GPRReg arg2)
- {
- move(arg2, GPRInfo::argumentGPR2); // Move this first, so setting arg1 does not trample!
- move(arg1, GPRInfo::argumentGPR1);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2)
- {
- move(arg1, GPRInfo::argumentGPR1);
- move(arg2, GPRInfo::argumentGPR2);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImmPtr arg2)
- {
- move(arg1, GPRInfo::argumentGPR1);
- move(arg2, GPRInfo::argumentGPR2);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImm32 arg2)
- {
- move(arg1, GPRInfo::argumentGPR1);
- move(arg2, GPRInfo::argumentGPR2);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3)
- {
- setupStubArguments(arg1, arg2, arg3);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3)
- {
- setupStubArguments(arg1, arg2);
- move(arg3, GPRInfo::argumentGPR3);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2, GPRReg arg3)
- {
- setupTwoStubArgs<GPRInfo::argumentGPR1, GPRInfo::argumentGPR3>(arg1, arg3);
- move(arg2, GPRInfo::argumentGPR2);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2, TrustedImmPtr arg3)
- {
- move(arg1, GPRInfo::argumentGPR1);
- move(arg2, GPRInfo::argumentGPR2);
- move(arg3, GPRInfo::argumentGPR3);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3)
- {
- move(arg1, GPRInfo::argumentGPR1);
- move(arg2, GPRInfo::argumentGPR2);
- move(arg3, GPRInfo::argumentGPR3);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImmPtr arg3)
- {
- move(arg1, GPRInfo::argumentGPR1);
- move(arg2, GPRInfo::argumentGPR2);
- move(arg3, GPRInfo::argumentGPR3);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImmPtr arg3)
- {
- setupStubArguments(arg1, arg2);
- move(arg3, GPRInfo::argumentGPR3);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, GPRReg arg3)
- {
- move(arg3, GPRInfo::argumentGPR3);
- move(arg1, GPRInfo::argumentGPR1);
- move(arg2, GPRInfo::argumentGPR2);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImmPtr arg2, GPRReg arg3)
- {
- move(arg3, GPRInfo::argumentGPR3);
- move(arg1, GPRInfo::argumentGPR1);
- move(arg2, GPRInfo::argumentGPR2);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, TrustedImm32 arg3)
- {
- move(arg2, GPRInfo::argumentGPR2);
- move(arg1, GPRInfo::argumentGPR1);
- move(arg3, GPRInfo::argumentGPR3);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3)
- {
- setupTwoStubArgs<GPRInfo::argumentGPR2, GPRInfo::argumentGPR3>(arg2, arg3);
- move(arg1, GPRInfo::argumentGPR1);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImmPtr arg2, TrustedImmPtr arg3)
- {
- move(arg1, GPRInfo::argumentGPR1);
- move(arg2, GPRInfo::argumentGPR2);
- move(arg3, GPRInfo::argumentGPR3);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, TrustedImm32 arg3)
- {
- move(arg1, GPRInfo::argumentGPR1);
- move(arg2, GPRInfo::argumentGPR2);
- move(arg3, GPRInfo::argumentGPR3);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- }
- #endif // NUMBER_OF_ARGUMENT_REGISTERS >= 4
- // These methods are suitable for any calling convention that provides for
- // exactly 4 argument registers, e.g. ARMv7.
- #if NUMBER_OF_ARGUMENT_REGISTERS == 4
- #if CPU(MIPS)
- #define POKE_ARGUMENT_OFFSET 4
- #else
- #define POKE_ARGUMENT_OFFSET 0
- #endif
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4)
- {
- poke(arg4, POKE_ARGUMENT_OFFSET);
- setupArgumentsWithExecState(arg1, arg2, arg3);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4)
- {
- poke(arg4, POKE_ARGUMENT_OFFSET);
- setupArgumentsWithExecState(arg1, arg2, arg3);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4)
- {
- poke(arg4, POKE_ARGUMENT_OFFSET);
- setupArgumentsWithExecState(arg1, arg2, arg3);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5)
- {
- poke(arg5, POKE_ARGUMENT_OFFSET + 1);
- poke(arg4, POKE_ARGUMENT_OFFSET);
- setupArgumentsWithExecState(arg1, arg2, arg3);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImm32 arg4)
- {
- poke(arg4, POKE_ARGUMENT_OFFSET);
- setupArgumentsWithExecState(arg1, arg2, arg3);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, GPRReg arg3, GPRReg arg4)
- {
- poke(arg4, POKE_ARGUMENT_OFFSET);
- setupArgumentsWithExecState(arg1, arg2, arg3);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImmPtr arg4)
- {
- poke(arg4, POKE_ARGUMENT_OFFSET);
- setupArgumentsWithExecState(arg1, arg2, arg3);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5)
- {
- poke(arg5, POKE_ARGUMENT_OFFSET + 1);
- poke(arg4, POKE_ARGUMENT_OFFSET);
- setupArgumentsWithExecState(arg1, arg2, arg3);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4)
- {
- poke(arg4, POKE_ARGUMENT_OFFSET);
- setupArgumentsWithExecState(arg1, arg2, arg3);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, TrustedImmPtr arg4)
- {
- poke(arg4, POKE_ARGUMENT_OFFSET);
- setupArgumentsWithExecState(arg1, arg2, arg3);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImmPtr arg4)
- {
- poke(arg4, POKE_ARGUMENT_OFFSET);
- setupArgumentsWithExecState(arg1, arg2, arg3);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4)
- {
- poke(arg4, POKE_ARGUMENT_OFFSET);
- setupArgumentsWithExecState(arg1, arg2, arg3);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5)
- {
- poke(arg5, POKE_ARGUMENT_OFFSET + 1);
- poke(arg4, POKE_ARGUMENT_OFFSET);
- setupArgumentsWithExecState(arg1, arg2, arg3);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4, TrustedImm32 arg5)
- {
- poke(arg5, POKE_ARGUMENT_OFFSET + 1);
- poke(arg4, POKE_ARGUMENT_OFFSET);
- setupArgumentsWithExecState(arg1, arg2, arg3);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, TrustedImmPtr arg5)
- {
- poke(arg5, POKE_ARGUMENT_OFFSET + 1);
- poke(arg4, POKE_ARGUMENT_OFFSET);
- setupArgumentsWithExecState(arg1, arg2, arg3);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4, TrustedImm32 arg5)
- {
- poke(arg5, POKE_ARGUMENT_OFFSET + 1);
- poke(arg4, POKE_ARGUMENT_OFFSET);
- setupArgumentsWithExecState(arg1, arg2, arg3);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5)
- {
- poke(arg5, POKE_ARGUMENT_OFFSET + 1);
- poke(arg4, POKE_ARGUMENT_OFFSET);
- setupArgumentsWithExecState(arg1, arg2, arg3);
- }
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5)
- {
- poke(arg5, POKE_ARGUMENT_OFFSET + 1);
- poke(arg4, POKE_ARGUMENT_OFFSET);
- setupArgumentsWithExecState(arg1, arg2, arg3);
- }
- #endif // NUMBER_OF_ARGUMENT_REGISTERS == 4
- #if NUMBER_OF_ARGUMENT_REGISTERS >= 5
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4)
- {
- setupTwoStubArgs<GPRInfo::argumentGPR1, GPRInfo::argumentGPR4>(arg1, arg4);
- move(arg2, GPRInfo::argumentGPR2);
- move(arg3, GPRInfo::argumentGPR3);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- }
- #endif
- void setupResults(GPRReg destA, GPRReg destB)
- {
- GPRReg srcA = GPRInfo::returnValueGPR;
- GPRReg srcB = GPRInfo::returnValueGPR2;
- if (srcB != destA) {
- // Handle the easy cases - two simple moves.
- move(srcA, destA);
- move(srcB, destB);
- } else if (srcA != destB) {
- // Handle the non-swap case - just put srcB in place first.
- move(srcB, destB);
- move(srcA, destA);
- } else
- swap(destA, destB);
- }
- };
- } } // namespace JSC::DFG
- #endif // ENABLE(DFG_JIT)
- #endif // DFGCCallHelpers_h
|