Changeset 230717 in webkit


Ignore:
Timestamp:
Apr 17, 2018 10:05:21 AM (6 years ago)
Author:
commit-queue@webkit.org
Message:

Implement setupArgumentsImpl for ARM and MIPS
https://bugs.webkit.org/show_bug.cgi?id=183786

Patch by Dominik Infuehr <dinfuehr@igalia.com> on 2018-04-17
Reviewed by Yusuke Suzuki.

Implement setupArgumentsImpl for ARM (hardfp and softfp) and MIPS calling convention. Added
numCrossSources and extraGPRArgs to ArgCollection to keep track of extra
registers used for 64-bit values on 32-bit architectures. numCrossSources
keeps track of assignments from FPR to GPR registers as happens e.g. on MIPS.

  • assembler/MacroAssemblerARMv7.h:

(JSC::MacroAssemblerARMv7::moveDouble):

  • assembler/MacroAssemblerMIPS.h:

(JSC::MacroAssemblerMIPS::moveDouble):

  • jit/CCallHelpers.h:

(JSC::CCallHelpers::setupStubCrossArgs):
(JSC::CCallHelpers::ArgCollection::ArgCollection):
(JSC::CCallHelpers::ArgCollection::pushRegArg):
(JSC::CCallHelpers::ArgCollection::pushExtraRegArg):
(JSC::CCallHelpers::ArgCollection::addGPRArg):
(JSC::CCallHelpers::ArgCollection::addGPRExtraArg):
(JSC::CCallHelpers::ArgCollection::addStackArg):
(JSC::CCallHelpers::ArgCollection::addPoke):
(JSC::CCallHelpers::ArgCollection::argCount):
(JSC::CCallHelpers::calculatePokeOffset):
(JSC::CCallHelpers::pokeForArgument):
(JSC::CCallHelpers::stackAligned):
(JSC::CCallHelpers::marshallArgumentRegister):
(JSC::CCallHelpers::setupArgumentsImpl):
(JSC::CCallHelpers::pokeArgumentsAligned):
(JSC::CCallHelpers::std::is_integral<CURRENT_ARGUMENT_TYPE>::value):
(JSC::CCallHelpers::std::is_pointer<CURRENT_ARGUMENT_TYPE>::value):
(JSC::CCallHelpers::setupArguments):

  • jit/FPRInfo.h:

(JSC::FPRInfo::toArgumentRegister):

Location:
trunk/Source/JavaScriptCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r230711 r230717  
     12018-04-17  Dominik Infuehr  <dinfuehr@igalia.com>
     2
     3        Implement setupArgumentsImpl for ARM and MIPS
     4        https://bugs.webkit.org/show_bug.cgi?id=183786
     5
     6        Reviewed by Yusuke Suzuki.
     7
     8        Implement setupArgumentsImpl for ARM (hardfp and softfp) and MIPS calling convention. Added
     9        numCrossSources and extraGPRArgs to ArgCollection to keep track of extra
     10        registers used for 64-bit values on 32-bit architectures. numCrossSources
     11        keeps track of assignments from FPR to GPR registers as happens e.g. on MIPS.
     12
     13        * assembler/MacroAssemblerARMv7.h:
     14        (JSC::MacroAssemblerARMv7::moveDouble):
     15        * assembler/MacroAssemblerMIPS.h:
     16        (JSC::MacroAssemblerMIPS::moveDouble):
     17        * jit/CCallHelpers.h:
     18        (JSC::CCallHelpers::setupStubCrossArgs):
     19        (JSC::CCallHelpers::ArgCollection::ArgCollection):
     20        (JSC::CCallHelpers::ArgCollection::pushRegArg):
     21        (JSC::CCallHelpers::ArgCollection::pushExtraRegArg):
     22        (JSC::CCallHelpers::ArgCollection::addGPRArg):
     23        (JSC::CCallHelpers::ArgCollection::addGPRExtraArg):
     24        (JSC::CCallHelpers::ArgCollection::addStackArg):
     25        (JSC::CCallHelpers::ArgCollection::addPoke):
     26        (JSC::CCallHelpers::ArgCollection::argCount):
     27        (JSC::CCallHelpers::calculatePokeOffset):
     28        (JSC::CCallHelpers::pokeForArgument):
     29        (JSC::CCallHelpers::stackAligned):
     30        (JSC::CCallHelpers::marshallArgumentRegister):
     31        (JSC::CCallHelpers::setupArgumentsImpl):
     32        (JSC::CCallHelpers::pokeArgumentsAligned):
     33        (JSC::CCallHelpers::std::is_integral<CURRENT_ARGUMENT_TYPE>::value):
     34        (JSC::CCallHelpers::std::is_pointer<CURRENT_ARGUMENT_TYPE>::value):
     35        (JSC::CCallHelpers::setupArguments):
     36        * jit/FPRInfo.h:
     37        (JSC::FPRInfo::toArgumentRegister):
     38
    1392018-04-17  Saam Barati  <sbarati@apple.com>
    240
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h

    r230592 r230717  
    965965    }
    966966
     967    void moveDouble(FPRegisterID src, RegisterID dest)
     968    {
     969        m_assembler.vmov(dest, RegisterID(dest + 1), src);
     970    }
     971
    967972    void moveZeroToDouble(FPRegisterID reg)
    968973    {
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h

    r230592 r230717  
    30623062    }
    30633063
     3064    void moveDouble(FPRegisterID src, RegisterID dest)
     3065    {
     3066        m_assembler.mfc1(dest, src);
     3067        m_assembler.mfc1(RegisterID(dest + 1), FPRegisterID(src + 1));
     3068    }
     3069
    30643070    void moveZeroToDouble(FPRegisterID reg)
    30653071    {
  • trunk/Source/JavaScriptCore/jit/CCallHelpers.h

    r230556 r230717  
    192192    }
    193193
     194#if CPU(MIPS) || (CPU(ARM) && !CPU(ARM_HARDFP))
     195    template<unsigned NumCrossSources, unsigned NumberOfRegisters>
     196    ALWAYS_INLINE void setupStubCrossArgs(std::array<GPRReg, NumberOfRegisters> destinations, std::array<FPRReg, NumberOfRegisters> sources) {
     197        for (unsigned i = 0; i < NumCrossSources; i++) {
     198            GPRReg dest = destinations[i];
     199            FPRReg source = sources[i];
     200
     201            moveDouble(source, dest);
     202        }
     203    }
     204#endif
     205
    194206    template<typename RegType>
    195207    using InfoTypeForReg = decltype(toInfoFromReg(RegType(-1)));
    196208
     209    // extraGPRArgs is used to track 64-bit argument types passed in register on 32-bit architectures.
    197210    // extraPoke is used to track 64-bit argument types passed on the stack.
    198     template<unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned extraPoke>
     211    template<unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke>
    199212    struct ArgCollection {
    200213        ArgCollection()
     
    204217            fprSources.fill(InvalidFPRReg);
    205218            fprDestinations.fill(InvalidFPRReg);
    206         }
    207 
    208         template<unsigned a, unsigned b, unsigned c, unsigned d, unsigned e>
    209         ArgCollection(ArgCollection<a, b, c, d, e>& other)
     219            crossSources.fill(InvalidFPRReg);
     220            crossDestinations.fill(InvalidGPRReg);
     221        }
     222
     223        template<unsigned a, unsigned b, unsigned c, unsigned d, unsigned e, unsigned f, unsigned g>
     224        ArgCollection(ArgCollection<a, b, c, d, e, f, g>& other)
    210225        {
    211226            gprSources = other.gprSources;
     
    213228            fprSources = other.fprSources;
    214229            fprDestinations = other.fprDestinations;
    215         }
    216 
    217         ArgCollection<numGPRArgs + 1, numGPRSources + 1, numFPRArgs, numFPRSources, extraPoke> pushRegArg(GPRReg argument, GPRReg destination)
    218         {
    219             ArgCollection<numGPRArgs + 1, numGPRSources + 1, numFPRArgs, numFPRSources, extraPoke> result(*this);
     230            crossSources = other.crossSources;
     231            crossDestinations = other.crossDestinations;
     232        }
     233
     234        ArgCollection<numGPRArgs + 1, numGPRSources + 1, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> pushRegArg(GPRReg argument, GPRReg destination)
     235        {
     236            ArgCollection<numGPRArgs + 1, numGPRSources + 1, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> result(*this);
    220237
    221238            result.gprSources[numGPRSources] = argument;
     
    224241        }
    225242
    226         ArgCollection<numGPRArgs, numGPRSources, numFPRArgs + 1, numFPRSources + 1, extraPoke> pushRegArg(FPRReg argument, FPRReg destination)
    227         {
    228             ArgCollection<numGPRArgs, numGPRSources, numFPRArgs + 1, numFPRSources + 1, extraPoke> result(*this);
     243        ArgCollection<numGPRArgs, numGPRSources, numFPRArgs + 1, numFPRSources + 1, numCrossSources, extraGPRArgs, extraPoke> pushRegArg(FPRReg argument, FPRReg destination)
     244        {
     245            ArgCollection<numGPRArgs, numGPRSources, numFPRArgs + 1, numFPRSources + 1, numCrossSources, extraGPRArgs, extraPoke> result(*this);
    229246
    230247            result.fprSources[numFPRSources] = argument;
     
    233250        }
    234251
    235         ArgCollection<numGPRArgs + 1, numGPRSources, numFPRArgs, numFPRSources, extraPoke> addGPRArg()
    236         {
    237             return ArgCollection<numGPRArgs + 1, numGPRSources, numFPRArgs, numFPRSources, extraPoke>(*this);
    238         }
    239 
    240         ArgCollection<numGPRArgs + 1, numGPRSources, numFPRArgs, numFPRSources, extraPoke> addStackArg(GPRReg)
    241         {
    242             return ArgCollection<numGPRArgs + 1, numGPRSources, numFPRArgs, numFPRSources, extraPoke>(*this);
    243         }
    244 
    245         ArgCollection<numGPRArgs, numGPRSources, numFPRArgs + 1, numFPRSources, extraPoke> addStackArg(FPRReg)
    246         {
    247             return ArgCollection<numGPRArgs, numGPRSources, numFPRArgs + 1, numFPRSources, extraPoke>(*this);
    248         }
    249 
    250         ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, extraPoke + 1> addPoke()
    251         {
    252             return ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, extraPoke + 1>(*this);
     252        ArgCollection<numGPRArgs, numGPRSources, numFPRArgs + 1, numFPRSources, numCrossSources + 1, extraGPRArgs, extraPoke> pushRegArg(FPRReg argument, GPRReg destination)
     253        {
     254            ArgCollection<numGPRArgs, numGPRSources, numFPRArgs + 1, numFPRSources, numCrossSources + 1, extraGPRArgs, extraPoke> result(*this);
     255
     256            result.crossSources[numCrossSources] = argument;
     257            result.crossDestinations[numCrossSources] = destination;
     258            return result;
     259        }
     260
     261        ArgCollection<numGPRArgs, numGPRSources + 1, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs + 1, extraPoke> pushExtraRegArg(GPRReg argument, GPRReg destination)
     262        {
     263            ArgCollection<numGPRArgs, numGPRSources + 1, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs + 1, extraPoke> result(*this);
     264
     265            result.gprSources[numGPRSources] = argument;
     266            result.gprDestinations[numGPRSources] = destination;
     267            return result;
     268        }
     269
     270        ArgCollection<numGPRArgs + 1, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> addGPRArg()
     271        {
     272            return ArgCollection<numGPRArgs + 1, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke>(*this);
     273        }
     274
     275        ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs + 1, extraPoke> addGPRExtraArg()
     276        {
     277            return ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs + 1, extraPoke>(*this);
     278        }
     279
     280        ArgCollection<numGPRArgs + 1, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> addStackArg(GPRReg)
     281        {
     282            return ArgCollection<numGPRArgs + 1, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke>(*this);
     283        }
     284
     285        ArgCollection<numGPRArgs, numGPRSources, numFPRArgs + 1, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> addStackArg(FPRReg)
     286        {
     287            return ArgCollection<numGPRArgs, numGPRSources, numFPRArgs + 1, numFPRSources, numCrossSources, extraGPRArgs, extraPoke>(*this);
     288        }
     289
     290        ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke + 1> addPoke()
     291        {
     292            return ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke + 1>(*this);
    253293        }
    254294
     
    257297        unsigned argCount(FPRReg) { return numGPRArgs + numFPRArgs; }
    258298#else
    259         unsigned argCount(GPRReg) { return numGPRArgs; }
     299        unsigned argCount(GPRReg) { return numGPRArgs + extraGPRArgs; }
    260300        unsigned argCount(FPRReg) { return numFPRArgs; }
    261301#endif
    262302
     303        // store GPR -> GPR assignments
    263304        std::array<GPRReg, GPRInfo::numberOfRegisters> gprSources;
    264305        std::array<GPRReg, GPRInfo::numberOfRegisters> gprDestinations;
     306
     307        // store FPR -> FPR assignments
    265308        std::array<FPRReg, FPRInfo::numberOfRegisters> fprSources;
    266309        std::array<FPRReg, FPRInfo::numberOfRegisters> fprDestinations;
     310
     311        // store FPR -> GPR assignments
     312        std::array<FPRReg, GPRInfo::numberOfRegisters> crossSources;
     313        std::array<GPRReg, GPRInfo::numberOfRegisters> crossDestinations;
    267314    };
    268315
     
    283330    }
    284331
    285     template<typename ArgType>
    286     ALWAYS_INLINE void pokeForArgument(ArgType arg, unsigned currentGPRArgument, unsigned currentFPRArgument, unsigned extraPoke)
     332    ALWAYS_INLINE unsigned calculatePokeOffset(unsigned currentGPRArgument, unsigned currentFPRArgument, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke)
    287333    {
    288334        // Clang claims that it cannot find the symbol for FPRReg/GPRReg::numberOfArgumentRegisters when they are passed directly to std::max... seems like a bug
    289335        unsigned numberOfFPArgumentRegisters = FPRInfo::numberOfArgumentRegisters;
    290336        unsigned numberOfGPArgumentRegisters = GPRInfo::numberOfArgumentRegisters;
     337
     338        currentGPRArgument += extraGPRArgs;
     339        currentFPRArgument -= numCrossSources;
    291340        ASSERT(currentGPRArgument >= GPRInfo::numberOfArgumentRegisters || currentFPRArgument >= FPRInfo::numberOfArgumentRegisters);
    292341
     
    294343        pokeOffset += std::max(currentGPRArgument, numberOfGPArgumentRegisters) - numberOfGPArgumentRegisters;
    295344        pokeOffset += std::max(currentFPRArgument, numberOfFPArgumentRegisters) - numberOfFPArgumentRegisters;
     345        return pokeOffset;
     346    }
     347
     348    template<typename ArgType>
     349    ALWAYS_INLINE void pokeForArgument(ArgType arg, unsigned currentGPRArgument, unsigned currentFPRArgument, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke)
     350    {
     351        unsigned pokeOffset = calculatePokeOffset(currentGPRArgument, currentFPRArgument, numCrossSources, extraGPRArgs, extraPoke);
    296352        poke(arg, pokeOffset);
     353    }
     354
     355    ALWAYS_INLINE bool stackAligned(unsigned currentGPRArgument, unsigned currentFPRArgument, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke)
     356    {
     357        unsigned pokeOffset = calculatePokeOffset(currentGPRArgument, currentFPRArgument, numCrossSources, extraGPRArgs, extraPoke);
     358        return !(pokeOffset & 1);
    297359    }
    298360
     
    311373
    312374    // Avoid MSVC optimization time explosion associated with __forceinline in recursive templates.
    313     template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned extraPoke, typename RegType, typename... Args>
    314     ALWAYS_INLINE_EXCEPT_MSVC void marshallArgumentRegister(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, extraPoke> argSourceRegs, RegType arg, Args... args)
     375    template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename RegType, typename... Args>
     376    ALWAYS_INLINE_EXCEPT_MSVC void marshallArgumentRegister(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, RegType arg, Args... args)
    315377    {
    316378        using InfoType = InfoTypeForReg<RegType>;
     
    327389        }
    328390
    329         pokeForArgument(arg, numGPRArgs, numFPRArgs, extraPoke);
     391        pokeForArgument(arg, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke);
    330392        setupArgumentsImpl<OperationType>(argSourceRegs.addStackArg(arg), args...);
    331393    }
    332394
    333     template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned extraPoke, typename... Args>
    334     ALWAYS_INLINE void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, extraPoke> argSourceRegs, FPRReg arg, Args... args)
     395    template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename... Args>
     396    ALWAYS_INLINE void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, FPRReg arg, Args... args)
    335397    {
    336398        static_assert(std::is_same<CURRENT_ARGUMENT_TYPE, double>::value, "We should only be passing FPRRegs to a double");
     
    338400    }
    339401
    340     template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned extraPoke, typename... Args>
    341     ALWAYS_INLINE void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, extraPoke> argSourceRegs, GPRReg arg, Args... args)
     402    template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename... Args>
     403    ALWAYS_INLINE void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, GPRReg arg, Args... args)
    342404    {
    343405        marshallArgumentRegister<OperationType>(argSourceRegs, arg, args...);
    344406    }
    345407
    346     template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned extraPoke, typename... Args>
    347     ALWAYS_INLINE void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, extraPoke> argSourceRegs, JSValueRegs arg, Args... args)
     408    template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename... Args>
     409    ALWAYS_INLINE void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, JSValueRegs arg, Args... args)
    348410    {
    349411        marshallArgumentRegister<OperationType>(argSourceRegs, arg.gpr(), args...);
    350412    }
    351413
    352     template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned extraPoke, typename... Args>
    353     ALWAYS_INLINE void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, extraPoke> argSourceRegs, CellValue arg, Args... args)
     414    template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename... Args>
     415    ALWAYS_INLINE void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, CellValue arg, Args... args)
    354416    {
    355417        marshallArgumentRegister<OperationType>(argSourceRegs, arg.gpr(), args...);
     
    357419
    358420#else // USE(JSVALUE64)
    359 
    360     // These functions are a hack for X86 since it has no argument gprs...
    361 
    362     template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned extraPoke, typename... Args>
    363     ALWAYS_INLINE void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, extraPoke> argSourceRegs, FPRReg arg, Args... args)
     421#if CPU(X86)
     422
     423    template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename... Args>
     424    ALWAYS_INLINE void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, FPRReg arg, Args... args)
    364425    {
    365426        static_assert(std::is_same<CURRENT_ARGUMENT_TYPE, double>::value, "We should only be passing FPRRegs to a double");
    366         pokeForArgument(arg, numGPRArgs, numFPRArgs, extraPoke);
     427        pokeForArgument(arg, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke);
    367428        setupArgumentsImpl<OperationType>(argSourceRegs.addStackArg(arg).addPoke(), args...);
    368429    }
    369430
    370     template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned extraPoke, typename... Args>
     431    template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename... Args>
    371432    ALWAYS_INLINE std::enable_if_t<sizeof(CURRENT_ARGUMENT_TYPE) <= 4>
    372     setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, extraPoke> argSourceRegs, GPRReg arg, Args... args)
    373     {
    374         pokeForArgument(arg, numGPRArgs, numFPRArgs, extraPoke);
     433    setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, GPRReg arg, Args... args)
     434    {
     435        pokeForArgument(arg, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke);
    375436        setupArgumentsImpl<OperationType>(argSourceRegs.addGPRArg(), args...);
    376437    }
    377438
    378     template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned extraPoke, typename... Args>
     439    template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename... Args>
    379440    ALWAYS_INLINE std::enable_if_t<std::is_same<CURRENT_ARGUMENT_TYPE, EncodedJSValue>::value>
    380     setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, extraPoke> argSourceRegs, JSValueRegs arg, Args... args)
    381     {
    382         pokeForArgument(arg.payloadGPR(), numGPRArgs, numFPRArgs, extraPoke);
    383         pokeForArgument(arg.tagGPR(), numGPRArgs, numFPRArgs, extraPoke + 1);
     441    setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, CellValue payload, Args... args)
     442    {
     443        pokeForArgument(payload.gpr(), numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke);
     444        pokeForArgument(TrustedImm32(JSValue::CellTag), numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke + 1);
    384445        setupArgumentsImpl<OperationType>(argSourceRegs.addGPRArg().addPoke(), args...);
    385446    }
    386447
    387     template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned extraPoke, typename... Args>
     448    template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename... Args>
    388449    ALWAYS_INLINE std::enable_if_t<std::is_same<CURRENT_ARGUMENT_TYPE, EncodedJSValue>::value>
    389     setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, extraPoke> argSourceRegs, CellValue arg, Args... args)
    390     {
    391         pokeForArgument(arg.gpr(), numGPRArgs, numFPRArgs, extraPoke);
    392         pokeForArgument(TrustedImm32(JSValue::CellTag), numGPRArgs, numFPRArgs, extraPoke + 1);
     450    setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, JSValueRegs arg, Args... args)
     451    {
     452        pokeForArgument(arg.payloadGPR(), numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke);
     453        pokeForArgument(arg.tagGPR(), numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke + 1);
    393454        setupArgumentsImpl<OperationType>(argSourceRegs.addGPRArg().addPoke(), args...);
    394455    }
    395456
     457#elif CPU(ARM) || CPU(MIPS)
     458
     459    template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename... Args>
     460    void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, FPRReg arg, Args... args)
     461    {
     462        static_assert(std::is_same<CURRENT_ARGUMENT_TYPE, double>::value, "We should only be passing FPRRegs to a double");
     463
     464        // MIPS and ARM-hardfp pass FP arguments in FP registers.
     465#if CPU(MIPS)
     466        unsigned numberOfFPArgumentRegisters = FPRInfo::numberOfArgumentRegisters;
     467        unsigned currentFPArgCount = argSourceRegs.argCount(arg);
     468
     469        // MIPS can only use FP argument registers if it isn't preceeded by any GP argument.
     470        if (currentFPArgCount < numberOfFPArgumentRegisters && !numGPRArgs) {
     471            auto updatedArgSourceRegs = argSourceRegs.pushRegArg(arg, FPRInfo::toArgumentRegister(currentFPArgCount));
     472            setupArgumentsImpl<OperationType>(updatedArgSourceRegs.addGPRExtraArg().addGPRExtraArg(), args...);
     473            return;
     474        }
     475#elif CPU(ARM) && CPU(ARM_HARDFP)
     476        unsigned numberOfFPArgumentRegisters = FPRInfo::numberOfArgumentRegisters;
     477        unsigned currentFPArgCount = argSourceRegs.argCount(arg);
     478
     479        if (currentFPArgCount < numberOfFPArgumentRegisters) {
     480            auto updatedArgSourceRegs = argSourceRegs.pushRegArg(arg, FPRInfo::toArgumentRegister(currentFPArgCount));
     481            setupArgumentsImpl<OperationType>(updatedArgSourceRegs, args...);
     482            return;
     483        }
     484#endif
     485
     486#if CPU(MIPS) || (CPU(ARM) && !CPU(ARM_HARDFP))
     487        // On MIPS and ARM-softfp FP arguments can be passed in GP registers.
     488        unsigned numberOfGPArgumentRegisters = GPRInfo::numberOfArgumentRegisters;
     489        unsigned currentGPArgCount = argSourceRegs.argCount(GPRInfo::regT0);
     490        unsigned alignedGPArgCount = roundUpToMultipleOf<2>(currentGPArgCount);
     491
     492        if (alignedGPArgCount + 1 < numberOfGPArgumentRegisters) {
     493            auto updatedArgSourceRegs = argSourceRegs.pushRegArg(arg, GPRInfo::toArgumentRegister(alignedGPArgCount));
     494
     495            if (alignedGPArgCount > currentGPArgCount)
     496                setupArgumentsImpl<OperationType>(updatedArgSourceRegs.addGPRExtraArg().addGPRExtraArg().addGPRExtraArg(), args...);
     497            else
     498                setupArgumentsImpl<OperationType>(updatedArgSourceRegs.addGPRExtraArg().addGPRExtraArg(), args...);
     499
     500            return;
     501        }
     502
     503        if (currentGPArgCount < numberOfGPArgumentRegisters) {
     504            pokeForArgument(arg, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs + 1, extraPoke);
     505            setupArgumentsImpl<OperationType>(argSourceRegs.addGPRExtraArg().addStackArg(arg).addPoke(), args...);
     506            return;
     507        }
     508#endif
     509
     510        // Otherwise pass FP argument on stack.
     511        if (stackAligned(numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke)) {
     512            pokeForArgument(arg, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke);
     513            setupArgumentsImpl<OperationType>(argSourceRegs.addStackArg(arg).addPoke(), args...);
     514        } else {
     515            pokeForArgument(arg, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke + 1);
     516            setupArgumentsImpl<OperationType>(argSourceRegs.addStackArg(arg).addPoke().addPoke(), args...);
     517        }
     518    }
     519
     520    template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename... Args>
     521    std::enable_if_t<sizeof(CURRENT_ARGUMENT_TYPE) <= 4>
     522    setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, GPRReg arg, Args... args)
     523    {
     524        unsigned numArgRegisters = GPRInfo::numberOfArgumentRegisters;
     525        unsigned currentArgCount = argSourceRegs.argCount(arg);
     526        if (currentArgCount < numArgRegisters) {
     527            auto updatedArgSourceRegs = argSourceRegs.pushRegArg(arg, GPRInfo::toArgumentRegister(currentArgCount));
     528            setupArgumentsImpl<OperationType>(updatedArgSourceRegs, args...);
     529            return;
     530        }
     531
     532        pokeForArgument(arg, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke);
     533        setupArgumentsImpl<OperationType>(argSourceRegs.addStackArg(arg), args...);
     534    }
     535
     536    template<typename OperationType, typename Arg1, typename Arg2, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename... Args>
     537    void pokeArgumentsAligned(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, Arg1 arg1, Arg2 arg2, Args... args)
     538    {
     539        unsigned numArgRegisters = GPRInfo::numberOfArgumentRegisters;
     540        unsigned currentArgCount = argSourceRegs.argCount(GPRInfo::regT0);
     541
     542        if (currentArgCount + 1 == numArgRegisters) {
     543            pokeForArgument(arg1, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs + 1, extraPoke);
     544            pokeForArgument(arg2, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs + 1, extraPoke + 1);
     545            setupArgumentsImpl<OperationType>(argSourceRegs.addGPRExtraArg().addGPRArg().addPoke(), args...);
     546        } else if (stackAligned(numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke)) {
     547            pokeForArgument(arg1, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke);
     548            pokeForArgument(arg2, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke + 1);
     549            setupArgumentsImpl<OperationType>(argSourceRegs.addGPRArg().addPoke(), args...);
     550        } else {
     551            pokeForArgument(arg1, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke + 1);
     552            pokeForArgument(arg2, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke + 2);
     553            setupArgumentsImpl<OperationType>(argSourceRegs.addGPRArg().addPoke().addPoke(), args...);
     554        }
     555    }
     556
     557    template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename... Args>
     558    std::enable_if_t<std::is_same<CURRENT_ARGUMENT_TYPE, EncodedJSValue>::value>
     559    setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, CellValue payload, Args... args)
     560    {
     561        unsigned numArgRegisters = GPRInfo::numberOfArgumentRegisters;
     562        unsigned currentArgCount = argSourceRegs.argCount(payload.gpr());
     563        unsigned alignedArgCount = roundUpToMultipleOf<2>(currentArgCount);
     564
     565        if (alignedArgCount + 1 < numArgRegisters) {
     566            auto updatedArgSourceRegs = argSourceRegs.pushRegArg(payload.gpr(), GPRInfo::toArgumentRegister(alignedArgCount));
     567
     568            if (alignedArgCount > currentArgCount)
     569                setupArgumentsImpl<OperationType>(updatedArgSourceRegs.addGPRExtraArg().addGPRExtraArg(), args...);
     570            else
     571                setupArgumentsImpl<OperationType>(updatedArgSourceRegs.addGPRExtraArg(), args...);
     572
     573            move(TrustedImm32(JSValue::CellTag), GPRInfo::toArgumentRegister(alignedArgCount + 1));
     574
     575        } else
     576            pokeArgumentsAligned<OperationType>(argSourceRegs, payload.gpr(), TrustedImm32(JSValue::CellTag), args...);
     577    }
     578
     579    template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename... Args>
     580    std::enable_if_t<std::is_same<CURRENT_ARGUMENT_TYPE, EncodedJSValue>::value>
     581    setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, JSValueRegs arg, Args... args)
     582    {
     583        unsigned numArgRegisters = GPRInfo::numberOfArgumentRegisters;
     584        unsigned currentArgCount = argSourceRegs.argCount(arg.tagGPR());
     585        unsigned alignedArgCount = roundUpToMultipleOf<2>(currentArgCount);
     586
     587        if (alignedArgCount + 1 < numArgRegisters) {
     588            // JSValueRegs is passed in two 32-bit registers on these architectures. Increase both numGPRArgs and extraGPRArgs by 1.
     589            // We can't just add 2 to numGPRArgs, since it is used for CURRENT_ARGUMENT_TYPE. Adding 2 would lead to a skipped argument.
     590            auto updatedArgSourceRegs1 = argSourceRegs.pushRegArg(arg.payloadGPR(), GPRInfo::toArgumentRegister(alignedArgCount));
     591            auto updatedArgSourceRegs2 = updatedArgSourceRegs1.pushExtraRegArg(arg.tagGPR(), GPRInfo::toArgumentRegister(alignedArgCount + 1));
     592
     593            if (alignedArgCount > currentArgCount)
     594                setupArgumentsImpl<OperationType>(updatedArgSourceRegs2.addGPRExtraArg(), args...);
     595            else
     596                setupArgumentsImpl<OperationType>(updatedArgSourceRegs2, args...);
     597        } else
     598            pokeArgumentsAligned<OperationType>(argSourceRegs, arg.payloadGPR(), arg.tagGPR(), args...);
     599    }
     600
     601#endif // CPU(ARM) || CPU(MIPS)
    396602#endif // USE(JSVALUE64)
    397603
    398     template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned extraPoke, typename Arg, typename... Args>
     604    template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename Arg, typename... Args>
    399605    ALWAYS_INLINE std::enable_if_t<
    400606        std::is_base_of<TrustedImm, Arg>::value
    401607        || std::is_convertible<Arg, TrustedImm>::value> // We have this since DFGSpeculativeJIT has it's own implementation of TrustedImmPtr
    402     setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, extraPoke> argSourceRegs, Arg arg, Args... args)
     608    setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, Arg arg, Args... args)
    403609    {
    404610        // Right now this only supports non-floating point immediate arguments since we never call operations with non-register values.
     
    410616        auto currentArgCount = numGPRArgs + numFPRArgs + (std::is_same<RESULT_TYPE, SlowPathReturnType>::value ? 1 : 0);
    411617#else
    412         auto currentArgCount = numGPRArgs;
     618        auto currentArgCount = numGPRArgs + extraGPRArgs;
    413619#endif
    414620        if (currentArgCount < numArgRegisters) {
     
    418624        }
    419625
    420         pokeForArgument(arg, numGPRArgs, numFPRArgs, extraPoke);
     626        pokeForArgument(arg, numGPRArgs, numFPRArgs, numCrossSources, extraGPRArgs, extraPoke);
    421627        setupArgumentsImpl<OperationType>(argSourceRegs.addGPRArg(), args...);
    422628    }
    423629
    424     template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned extraPoke, typename Arg, typename... Args>
     630    template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename Arg, typename... Args>
    425631    ALWAYS_INLINE std::enable_if_t<
    426632        std::is_same<CURRENT_ARGUMENT_TYPE, Arg>::value
    427633        && std::is_integral<CURRENT_ARGUMENT_TYPE>::value
    428634        && (sizeof(CURRENT_ARGUMENT_TYPE) <= 4)>
    429     setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, extraPoke> argSourceRegs, Arg arg, Args... args)
     635    setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, Arg arg, Args... args)
    430636    {
    431637        setupArgumentsImpl<OperationType>(argSourceRegs, TrustedImm32(arg), args...);
    432638    }
    433639
    434     template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned extraPoke, typename Arg, typename... Args>
     640    template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename Arg, typename... Args>
    435641    ALWAYS_INLINE std::enable_if_t<
    436642        std::is_same<CURRENT_ARGUMENT_TYPE, Arg>::value
    437643        && std::is_integral<CURRENT_ARGUMENT_TYPE>::value
    438644        && (sizeof(CURRENT_ARGUMENT_TYPE) == 8)>
    439     setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, extraPoke> argSourceRegs, Arg arg, Args... args)
     645    setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, Arg arg, Args... args)
    440646    {
    441647        setupArgumentsImpl<OperationType>(argSourceRegs, TrustedImm64(arg), args...);
    442648    }
    443649
    444     template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned extraPoke, typename Arg, typename... Args>
     650    template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename Arg, typename... Args>
    445651    ALWAYS_INLINE std::enable_if_t<
    446652        std::is_pointer<CURRENT_ARGUMENT_TYPE>::value
    447653        && ((std::is_pointer<Arg>::value && std::is_convertible<std::remove_const_t<std::remove_pointer_t<Arg>>*, CURRENT_ARGUMENT_TYPE>::value)
    448654            || std::is_same<Arg, std::nullptr_t>::value)>
    449     setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, extraPoke> argSourceRegs, Arg arg, Args... args)
     655    setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, Arg arg, Args... args)
    450656    {
    451657        setupArgumentsImpl<OperationType>(argSourceRegs, TrustedImmPtr(arg), args...);
     
    453659
    454660    // Special case DFG::RegisteredStructure because it's really annoying to deal with otherwise...
    455     template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned extraPoke, typename Arg, typename... Args>
     661    template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke, typename Arg, typename... Args>
    456662    ALWAYS_INLINE std::enable_if_t<
    457663        std::is_same<CURRENT_ARGUMENT_TYPE, Structure*>::value
    458664        && std::is_same<Arg, DFG::RegisteredStructure>::value>
    459     setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, extraPoke> argSourceRegs, Arg arg, Args... args)
     665    setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs, Arg arg, Args... args)
    460666    {
    461667        setupArgumentsImpl<OperationType>(argSourceRegs, TrustedImmPtr(arg.get()), args...);
     
    466672
    467673    // Base case; set up the argument registers.
    468     template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned extraPoke>
    469     ALWAYS_INLINE void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, extraPoke> argSourceRegs)
     674    template<typename OperationType, unsigned numGPRArgs, unsigned numGPRSources, unsigned numFPRArgs, unsigned numFPRSources, unsigned numCrossSources, unsigned extraGPRArgs, unsigned extraPoke>
     675    ALWAYS_INLINE void setupArgumentsImpl(ArgCollection<numGPRArgs, numGPRSources, numFPRArgs, numFPRSources, numCrossSources, extraGPRArgs, extraPoke> argSourceRegs)
    470676    {
    471677        static_assert(FunctionTraits<OperationType>::arity == numGPRArgs + numFPRArgs, "One last sanity check");
     678#if CPU(JSVALUE64) || CPU(X86)
    472679        static_assert(FunctionTraits<OperationType>::cCallArity() == numGPRArgs + numFPRArgs + extraPoke, "Check the CCall arity");
     680#endif
    473681        setupStubArgs<numGPRSources, GPRReg>(clampArrayToSize<numGPRSources, GPRReg>(argSourceRegs.gprDestinations), clampArrayToSize<numGPRSources, GPRReg>(argSourceRegs.gprSources));
    474 
     682#if CPU(MIPS) || (CPU(ARM) && !CPU(ARM_HARDFP))
     683        setupStubCrossArgs<numCrossSources>(argSourceRegs.crossDestinations, argSourceRegs.crossSources);
     684#else
     685        static_assert(!numCrossSources, "shouldn't be used on this architecture.");
     686#endif
    475687        setupStubArgs<numFPRSources, FPRReg>(clampArrayToSize<numFPRSources, FPRReg>(argSourceRegs.fprDestinations), clampArrayToSize<numFPRSources, FPRReg>(argSourceRegs.fprSources));
    476688    }
     
    487699        static_assert(FunctionTraits<OperationType>::cCallArity() == sizeof...(Args) + 1, "Basic sanity check");
    488700#endif
    489         setupArgumentsImpl<OperationType, 0, 0, 0, 0, 0>(ArgCollection<0, 0, 0, 0, 0>(), GPRInfo::callFrameRegister, args...);
     701        setupArgumentsImpl<OperationType, 0, 0, 0, 0, 0, 0, 0>(ArgCollection<0, 0, 0, 0, 0, 0, 0>(), GPRInfo::callFrameRegister, args...);
    490702    }
    491703
     
    497709        static_assert(FunctionTraits<OperationType>::cCallArity() == sizeof...(Args), "Basic sanity check");
    498710#endif
    499         setupArgumentsImpl<OperationType, 0, 0, 0, 0, 0>(ArgCollection<0, 0, 0, 0, 0>(), args...);
     711        setupArgumentsImpl<OperationType, 0, 0, 0, 0, 0, 0, 0>(ArgCollection<0, 0, 0, 0, 0, 0, 0>(), args...);
    500712    }
    501713
  • trunk/Source/JavaScriptCore/jit/FPRInfo.h

    r229772 r230717  
    108108    typedef FPRReg RegisterType;
    109109    static const unsigned numberOfRegisters = 6;
     110
     111#if CPU(ARM_HARDFP)
     112    static const unsigned numberOfArgumentRegisters = 8;
     113#else
    110114    static const unsigned numberOfArgumentRegisters = 0;
     115#endif
    111116
    112117    // Temporary registers.
     
    144149        return (unsigned)reg;
    145150    }
     151
     152#if CPU(ARM_HARDFP)
     153    static FPRReg toArgumentRegister(unsigned index)
     154    {
     155        ASSERT(index < numberOfArgumentRegisters);
     156        return static_cast<FPRReg>(index);
     157    }
     158#endif
    146159
    147160    static const char* debugName(FPRReg reg)
     
    282295    }
    283296
     297    static FPRReg toArgumentRegister(unsigned index)
     298    {
     299        ASSERT(index < numberOfArgumentRegisters);
     300        static const FPRReg indexForRegister[2] = {
     301            argumentFPR0, argumentFPR1
     302        };
     303        return indexForRegister[index];
     304    }
     305
    284306    static unsigned toIndex(FPRReg reg)
    285307    {
Note: See TracChangeset for help on using the changeset viewer.