⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 290907 in webkit


Ignore:
Timestamp:
Mar 7, 2022, 1:55:08 PM (5 years ago)
Author:
Angelos Oikonomopoulos
Message:

AssemblyHelpersSpoolers: use load/store pair on ARMv7
​https://bugs.webkit.org/show_bug.cgi?id=235112

Reviewed by Žan Doberšek.

Save ~1% code size for baseline JIT on JS2 by emitting load/store pair
instructions on 32-bit ARM.

  • assembler/ARMv7Assembler.h:

(JSC::ARMv6Assembler::vldmia):
(JSC::ARMv7Assembler::vstmia):

  • assembler/CPU.h:

(JSC::isARM):

  • assembler/MacroAssemblerARMv7.h:

(JSC::MacroAssemblerARMv7::loadPair64):
(JSC::MacroAssemblerARMv7::storePair64):

  • jit/AssemblyHelpers.cpp:

(JSC::AssemblyHelpers::copyLLIntBaselineCalleeSavesFromFrameOrRegisterToEntryFrameCalleeSavesBuffer):

  • jit/AssemblyHelpersSpoolers.h:

(JSC::AssemblyHelpers::LoadRegSpooler::executePair):
(JSC::AssemblyHelpers::StoreRegSpooler::executePair):
(JSC::AssemblyHelpers::CopySpooler::CopySpooler):
(JSC::AssemblyHelpers::CopySpooler::loadPair):
(JSC::AssemblyHelpers::CopySpooler::storePair):

Location:
trunk/Source/JavaScriptCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r290882 r290907  
     12022-03-07  Angelos Oikonomopoulos  <angelos@igalia.com>
     2
     3        AssemblyHelpersSpoolers: use load/store pair on ARMv7
     4        https://bugs.webkit.org/show_bug.cgi?id=235112
     5
     6        Reviewed by Žan Doberšek.
     7
     8        Save ~1% code size for baseline JIT on JS2 by emitting load/store pair
     9        instructions on 32-bit ARM.
     10
     11        * assembler/ARMv7Assembler.h:
     12        (JSC::ARMv6Assembler::vldmia):
     13        (JSC::ARMv7Assembler::vstmia):
     14        * assembler/CPU.h:
     15        (JSC::isARM):
     16        * assembler/MacroAssemblerARMv7.h:
     17        (JSC::MacroAssemblerARMv7::loadPair64):
     18        (JSC::MacroAssemblerARMv7::storePair64):
     19        * jit/AssemblyHelpers.cpp:
     20        (JSC::AssemblyHelpers::copyLLIntBaselineCalleeSavesFromFrameOrRegisterToEntryFrameCalleeSavesBuffer):
     21        * jit/AssemblyHelpersSpoolers.h:
     22        (JSC::AssemblyHelpers::LoadRegSpooler::executePair):
     23        (JSC::AssemblyHelpers::StoreRegSpooler::executePair):
     24        (JSC::AssemblyHelpers::CopySpooler::CopySpooler):
     25        (JSC::AssemblyHelpers::CopySpooler::loadPair):
     26        (JSC::AssemblyHelpers::CopySpooler::storePair):
     27
    1282022-03-07  Zan Dobersek  <zdobersek@igalia.com>
    229
  • trunk/Source/JavaScriptCore/assembler/ARMv7Assembler.h

    r287516 r290907  
    584584        OP_VMOV_CtoD    = 0xEC00,
    585585        OP_VMOV_DtoC    = 0xEC10,
     586        OP_VSTMIA       = 0xEC80,
     587        OP_VLDMIA       = 0xEC90,
    586588        OP_FSTS         = 0xED00,
    587589        OP_VSTR         = 0xED00,
    … …  
    689691        OP_VCVTSD_T1b    = 0x0A40,
    690692        OP_VCVTDS_T1b    = 0x0A40,
     693        OP_VSTMIAb       = 0x0B00,
     694        OP_VLDMIAb       = 0x0B00,
    691695        OP_NOP_T2b       = 0x8000,
    692696        OP_DMB_SY_T1b    = 0x8F5F,
    … …  
    19261930    }
    19271931#endif
     1932
     1933    void vldmia(RegisterID rn, FPDoubleRegisterID rs, uint32_t count)
     1934    {
     1935        ASSERT(count < 16);
     1936        m_formatter.vfpMemOp(OP_VLDMIA, OP_VLDMIAb, true, rn, rs, count << 3);
     1937    }
     1938
     1939    void vstmia(RegisterID rn, FPDoubleRegisterID rs, uint32_t count)
     1940    {
     1941        ASSERT(count < 16);
     1942        m_formatter.vfpMemOp(OP_VSTMIA, OP_VSTMIAb, true, rn, rs, count << 3);
     1943    }
    19281944
    19291945    void vand(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm)
  • trunk/Source/JavaScriptCore/assembler/CPU.h

    r289740 r290907  
    3737{
    3838#if HAVE(ARM_IDIV_INSTRUCTIONS)
     39    return true;
     40#else
     41    return false;
     42#endif
     43}
     44
     45constexpr bool isARM()
     46{
     47#if CPU(ARM)
    3948    return true;
    4049#else
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h

    r290828 r290907  
    935935    }
    936936
     937    void loadPair64(RegisterID src, TrustedImm32 offset, FPRegisterID dest1, FPRegisterID dest2)
     938    {
     939        ASSERT(dest1 != dest2);
     940        if ((dest2 == (dest1 + 1)) && !offset.m_value) {
     941            // Only emit a VLDMIA if the registers happen to be consecutive and
     942            // in the proper order and the offset happens to be zero. Otherwise,
     943            // the extra instructions to adjust things mean there are no space
     944            // savings and the VLDM itself might be a performance loss.
     945            m_assembler.vldmia(src, dest1, 2);
     946        } else {
     947            loadDouble(Address(src, offset.m_value), dest1);
     948            loadDouble(Address(src, offset.m_value + 8), dest2);
     949        }
     950    }
     951
     952    void storePair64(FPRegisterID src1, FPRegisterID src2, RegisterID dest, TrustedImm32 offset)
     953    {
     954        if ((src2 == (src1 + 1)) && !offset.m_value) {
     955            // Only emit a VSTMIA under a narrow set of conditions. See
     956            // loadPair64 for the rationale.
     957            m_assembler.vstmia(dest, src1, 2);
     958        } else {
     959            storeDouble(src1, Address(dest, offset.m_value));
     960            storeDouble(src2, Address(dest, offset.m_value + 8));
     961        }
     962    }
     963
    937964    void store32(RegisterID src, Address address)
    938965    {
  • trunk/Source/JavaScriptCore/jit/AssemblyHelpers.cpp

    r288885 r290907  
    12901290    GPRReg temp1 = usedRegisters.getFreeGPR(1);
    12911291    FPRReg fpTemp1 = usedRegisters.getFreeFPR(0);
    1292     GPRReg temp2 = isARM64() ? usedRegisters.getFreeGPR(2) : InvalidGPRReg;
    1293     FPRReg fpTemp2 = isARM64() ? usedRegisters.getFreeFPR(1) : InvalidFPRReg;
     1292    GPRReg temp2 = usedRegisters.getFreeGPR(2);
     1293    FPRReg fpTemp2 = usedRegisters.getFreeFPR(1);
    12941294
    12951295    loadPtr(&topEntryFrame, destBufferGPR);
  • trunk/Source/JavaScriptCore/jit/AssemblyHelpersSpoolers.h

    r279256 r290907  
    137137
    138138private:
    139 #if CPU(ARM64)
    140     static constexpr bool hasPairOp = true;
    141 #else
    142     static constexpr bool hasPairOp = false;
    143 #endif
     139    static constexpr bool hasPairOp = isARM() || isARM64();
    144140
    145141    Op& op() { return *reinterpret_cast<Op*>(this); }
    … …  
    165161
    166162private:
    167 #if CPU(ARM64)
    168     template<typename RegType>
    169     ALWAYS_INLINE void executePair(ptrdiff_t offset, RegType reg1, RegType reg2)
     163#if CPU(ARM64) || CPU(ARM)
     164    ALWAYS_INLINE void executePair(ptrdiff_t offset, GPRReg reg1, GPRReg reg2)
     165    {
     166#if USE(JSVALUE64)
     167        m_jit.loadPair64(m_baseGPR, TrustedImm32(offset), reg1, reg2);
     168#else
     169        m_jit.loadPair32(m_baseGPR, TrustedImm32(offset), reg1, reg2);
     170#endif
     171    }
     172    ALWAYS_INLINE void executePair(ptrdiff_t offset, FPRReg reg1, FPRReg reg2)
    170173    {
    171174        m_jit.loadPair64(m_baseGPR, TrustedImm32(offset), reg1, reg2);
    … …  
    207210
    208211private:
    209 #if CPU(ARM64)
    210     template<typename RegType>
    211     ALWAYS_INLINE void executePair(ptrdiff_t offset, RegType reg1, RegType reg2)
     212#if CPU(ARM64) || CPU(ARM)
     213    ALWAYS_INLINE void executePair(ptrdiff_t offset, GPRReg reg1, GPRReg reg2)
     214    {
     215#if USE(JSVALUE64)
     216        m_jit.storePair64(reg1, reg2, m_baseGPR, TrustedImm32(offset));
     217#else
     218        m_jit.storePair32(reg1, reg2, m_baseGPR, TrustedImm32(offset));
     219#endif
     220    }
     221    ALWAYS_INLINE void executePair(ptrdiff_t offset, FPRReg reg1, FPRReg reg2)
    212222    {
    213223        m_jit.storePair64(reg1, reg2, m_baseGPR, TrustedImm32(offset));
    … …  
    264274        , m_temp2FPR(fpTemp2)
    265275        , m_bufferRegsAttr(attribute)
    266     {
    267         if constexpr (hasPairOp && !isARM64())
     276        {
     277        if constexpr (hasPairOp && !(isARM() || isARM64()))
    268278            RELEASE_ASSERT_NOT_REACHED(); // unsupported architecture.
    269279    }
    … …  
    523533    }
    524534
    525 #if CPU(ARM64)
    526     template<typename RegType>
    527     ALWAYS_INLINE void loadPair(int offset, RegType dest1, RegType dest2)
    528     {
     535#if CPU(ARM64) || CPU(ARM)
     536    ALWAYS_INLINE void loadPair(int offset, GPRReg dest1, GPRReg dest2)
     537    {
     538#if USE(JSVALUE64)
    529539        m_jit.loadPair64(m_srcBufferGPR, TrustedImm32(offset), dest1, dest2);
    530     }
    531 
    532     template<typename RegType>
    533     ALWAYS_INLINE void storePair(RegType src1, RegType src2, int offset)
     540#else
     541        m_jit.loadPair32(m_srcBufferGPR, TrustedImm32(offset), dest1, dest2);
     542#endif
     543    }
     544
     545    ALWAYS_INLINE void loadPair(int offset, FPRReg dest1, FPRReg dest2)
     546    {
     547        m_jit.loadPair64(m_srcBufferGPR, TrustedImm32(offset), dest1, dest2);
     548    }
     549
     550    ALWAYS_INLINE void storePair(GPRReg src1, GPRReg src2, int offset)
     551    {
     552#if USE(JSVALUE64)
     553        m_jit.storePair64(src1, src2, m_dstBufferGPR, TrustedImm32(offset));
     554#else
     555        m_jit.storePair32(src1, src2, m_dstBufferGPR, TrustedImm32(offset));
     556#endif
     557    }
     558
     559    ALWAYS_INLINE void storePair(FPRReg src1, FPRReg src2, int offset)
    534560    {
    535561        m_jit.storePair64(src1, src2, m_dstBufferGPR, TrustedImm32(offset));
Note: See TracChangeset for help on using the changeset viewer.