Title: [286020] trunk/Source/_javascript_Core
Revision
286020
Author
[email protected]
Date
2021-11-18 12:04:48 -0800 (Thu, 18 Nov 2021)

Log Message

[JSC] Add branchTest16 operation
https://bugs.webkit.org/show_bug.cgi?id=233275

Reviewed by Mark Lam.

This patch adds branchTest16 to all macro assemblers. And it also fixes the existing bug of
edge case of branchTest8: when we cannot represent the imm as ARM logical value, then we are
failing to emit the right instructions. Probably this bug does not appear since we are not using
such a value as an imm for branchTest8. We added tests to testmasm so that these code is stressed
now.

* assembler/MacroAssembler.h:
(JSC::MacroAssembler::branchTest16):
* assembler/MacroAssemblerARM64.h:
(JSC::MacroAssemblerARM64::load16SignedExtendTo32):
(JSC::MacroAssemblerARM64::branchTest32):
(JSC::MacroAssemblerARM64::branchTest8):
(JSC::MacroAssemblerARM64::branchTest16):
* assembler/MacroAssemblerARMv7.h:
(JSC::MacroAssemblerARMv7::branchTest16):
(JSC::MacroAssemblerARMv7::test32):
(JSC::MacroAssemblerARMv7::test8):
* assembler/MacroAssemblerHelpers.h:
(JSC::MacroAssemblerHelpers::mask16OnCondition):
(JSC::MacroAssemblerHelpers::load16OnCondition):
* assembler/MacroAssemblerMIPS.h:
(JSC::MacroAssemblerMIPS::load16):
(JSC::MacroAssemblerMIPS::load16SignedExtendTo32):
(JSC::MacroAssemblerMIPS::mask16OnTest):
(JSC::MacroAssemblerMIPS::branchTest16):
* assembler/MacroAssemblerX86Common.h:
(JSC::MacroAssemblerX86Common::branchTest16):
* assembler/MacroAssemblerX86_64.h:
(JSC::MacroAssemblerX86_64::branchTest16):
* assembler/X86Assembler.h:
(JSC::X86Assembler::cmpw_im):
(JSC::X86Assembler::testw_im):
* assembler/testmasm.cpp:
(JSC::testBranchTest8):
(JSC::testBranchTest16):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (286019 => 286020)


--- trunk/Source/_javascript_Core/ChangeLog	2021-11-18 19:38:01 UTC (rev 286019)
+++ trunk/Source/_javascript_Core/ChangeLog	2021-11-18 20:04:48 UTC (rev 286020)
@@ -1,3 +1,46 @@
+2021-11-18  Yusuke Suzuki  <[email protected]>
+
+        [JSC] Add branchTest16 operation
+        https://bugs.webkit.org/show_bug.cgi?id=233275
+
+        Reviewed by Mark Lam.
+
+        This patch adds branchTest16 to all macro assemblers. And it also fixes the existing bug of
+        edge case of branchTest8: when we cannot represent the imm as ARM logical value, then we are
+        failing to emit the right instructions. Probably this bug does not appear since we are not using
+        such a value as an imm for branchTest8. We added tests to testmasm so that these code is stressed
+        now.
+
+        * assembler/MacroAssembler.h:
+        (JSC::MacroAssembler::branchTest16):
+        * assembler/MacroAssemblerARM64.h:
+        (JSC::MacroAssemblerARM64::load16SignedExtendTo32):
+        (JSC::MacroAssemblerARM64::branchTest32):
+        (JSC::MacroAssemblerARM64::branchTest8):
+        (JSC::MacroAssemblerARM64::branchTest16):
+        * assembler/MacroAssemblerARMv7.h:
+        (JSC::MacroAssemblerARMv7::branchTest16):
+        (JSC::MacroAssemblerARMv7::test32):
+        (JSC::MacroAssemblerARMv7::test8):
+        * assembler/MacroAssemblerHelpers.h:
+        (JSC::MacroAssemblerHelpers::mask16OnCondition):
+        (JSC::MacroAssemblerHelpers::load16OnCondition):
+        * assembler/MacroAssemblerMIPS.h:
+        (JSC::MacroAssemblerMIPS::load16):
+        (JSC::MacroAssemblerMIPS::load16SignedExtendTo32):
+        (JSC::MacroAssemblerMIPS::mask16OnTest):
+        (JSC::MacroAssemblerMIPS::branchTest16):
+        * assembler/MacroAssemblerX86Common.h:
+        (JSC::MacroAssemblerX86Common::branchTest16):
+        * assembler/MacroAssemblerX86_64.h:
+        (JSC::MacroAssemblerX86_64::branchTest16):
+        * assembler/X86Assembler.h:
+        (JSC::X86Assembler::cmpw_im):
+        (JSC::X86Assembler::testw_im):
+        * assembler/testmasm.cpp:
+        (JSC::testBranchTest8):
+        (JSC::testBranchTest16):
+
 2021-11-18  David Kilzer  <[email protected]>
 
         Add missing dependencies for <wtf/Platform.h> when generating derived sources

Modified: trunk/Source/_javascript_Core/assembler/MacroAssembler.h (286019 => 286020)


--- trunk/Source/_javascript_Core/assembler/MacroAssembler.h	2021-11-18 19:38:01 UTC (rev 286019)
+++ trunk/Source/_javascript_Core/assembler/MacroAssembler.h	2021-11-18 20:04:48 UTC (rev 286020)
@@ -880,6 +880,12 @@
         return MacroAssemblerBase::branchTest8(cond, Address(address.base, address.offset), mask);
     }
 
+    using MacroAssemblerBase::branchTest16;
+    Jump branchTest16(ResultCondition cond, ExtendedAddress address, TrustedImm32 mask = TrustedImm32(-1))
+    {
+        return MacroAssemblerBase::branchTest16(cond, Address(address.base, address.offset), mask);
+    }
+
 #else // !CPU(ADDRESS64)
 
     void addPtr(RegisterID src, RegisterID dest)

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerARM64.h (286019 => 286020)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerARM64.h	2021-11-18 19:38:01 UTC (rev 286019)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerARM64.h	2021-11-18 20:04:48 UTC (rev 286020)
@@ -1805,6 +1805,14 @@
         m_assembler.ldrsh<32>(dest, address.base, memoryTempRegister);
     }
 
+    void load16SignedExtendTo32(const void* address, RegisterID dest)
+    {
+        moveToCachedReg(TrustedImmPtr(address), cachedMemoryTempRegister());
+        m_assembler.ldrsh<32>(dest, memoryTempRegister, ARM64Registers::zr);
+        if (dest == memoryTempRegister)
+            cachedMemoryTempRegister().invalidate();
+    }
+
     void zeroExtend16To32(RegisterID src, RegisterID dest)
     {
         m_assembler.uxth<32>(dest, src);
@@ -3410,6 +3418,7 @@
                 return Jump(makeBranch(cond));
             }
 
+            ASSERT(reg != dataTempRegister);
             move(mask, getCachedDataTempRegisterIDAndInvalidate());
             m_assembler.tst<32>(reg, dataTempRegister);
         }
@@ -3514,37 +3523,71 @@
     Jump branchTest8(ResultCondition cond, Address address, TrustedImm32 mask = TrustedImm32(-1))
     {
         TrustedImm32 mask8 = MacroAssemblerHelpers::mask8OnCondition(*this, cond, mask);
-        MacroAssemblerHelpers::load8OnCondition(*this, cond, address, getCachedDataTempRegisterIDAndInvalidate());
-        return branchTest32(cond, dataTempRegister, mask8);
+        MacroAssemblerHelpers::load8OnCondition(*this, cond, address, getCachedMemoryTempRegisterIDAndInvalidate());
+        return branchTest32(cond, memoryTempRegister, mask8);
     }
 
     Jump branchTest8(ResultCondition cond, AbsoluteAddress address, TrustedImm32 mask = TrustedImm32(-1))
     {
         TrustedImm32 mask8 = MacroAssemblerHelpers::mask8OnCondition(*this, cond, mask);
-        MacroAssemblerHelpers::load8OnCondition(*this, cond, address.m_ptr, getCachedDataTempRegisterIDAndInvalidate());
-        return branchTest32(cond, dataTempRegister, mask8);
+        MacroAssemblerHelpers::load8OnCondition(*this, cond, address.m_ptr, getCachedMemoryTempRegisterIDAndInvalidate());
+        return branchTest32(cond, memoryTempRegister, mask8);
     }
 
     Jump branchTest8(ResultCondition cond, ExtendedAddress address, TrustedImm32 mask = TrustedImm32(-1))
     {
         TrustedImm32 mask8 = MacroAssemblerHelpers::mask8OnCondition(*this, cond, mask);
-        move(TrustedImmPtr(reinterpret_cast<void*>(address.offset)), getCachedDataTempRegisterIDAndInvalidate());
+        move(TrustedImmPtr(reinterpret_cast<void*>(address.offset)), getCachedMemoryTempRegisterIDAndInvalidate());
 
         if (MacroAssemblerHelpers::isUnsigned<MacroAssemblerARM64>(cond))
-            m_assembler.ldrb(dataTempRegister, address.base, dataTempRegister);
+            m_assembler.ldrb(memoryTempRegister, address.base, memoryTempRegister);
         else
-            m_assembler.ldrsb<32>(dataTempRegister, address.base, dataTempRegister);
+            m_assembler.ldrsb<32>(memoryTempRegister, address.base, memoryTempRegister);
 
-        return branchTest32(cond, dataTempRegister, mask8);
+        return branchTest32(cond, memoryTempRegister, mask8);
     }
 
     Jump branchTest8(ResultCondition cond, BaseIndex address, TrustedImm32 mask = TrustedImm32(-1))
     {
         TrustedImm32 mask8 = MacroAssemblerHelpers::mask8OnCondition(*this, cond, mask);
-        MacroAssemblerHelpers::load8OnCondition(*this, cond, address, getCachedDataTempRegisterIDAndInvalidate());
-        return branchTest32(cond, dataTempRegister, mask8);
+        MacroAssemblerHelpers::load8OnCondition(*this, cond, address, getCachedMemoryTempRegisterIDAndInvalidate());
+        return branchTest32(cond, memoryTempRegister, mask8);
     }
 
+    Jump branchTest16(ResultCondition cond, Address address, TrustedImm32 mask = TrustedImm32(-1))
+    {
+        TrustedImm32 mask16 = MacroAssemblerHelpers::mask16OnCondition(*this, cond, mask);
+        MacroAssemblerHelpers::load16OnCondition(*this, cond, address, getCachedMemoryTempRegisterIDAndInvalidate());
+        return branchTest32(cond, memoryTempRegister, mask16);
+    }
+
+    Jump branchTest16(ResultCondition cond, AbsoluteAddress address, TrustedImm32 mask = TrustedImm32(-1))
+    {
+        TrustedImm32 mask16 = MacroAssemblerHelpers::mask16OnCondition(*this, cond, mask);
+        MacroAssemblerHelpers::load16OnCondition(*this, cond, address.m_ptr, getCachedMemoryTempRegisterIDAndInvalidate());
+        return branchTest32(cond, memoryTempRegister, mask16);
+    }
+
+    Jump branchTest16(ResultCondition cond, ExtendedAddress address, TrustedImm32 mask = TrustedImm32(-1))
+    {
+        TrustedImm32 mask16 = MacroAssemblerHelpers::mask16OnCondition(*this, cond, mask);
+        move(TrustedImmPtr(reinterpret_cast<void*>(address.offset)), getCachedMemoryTempRegisterIDAndInvalidate());
+
+        if (MacroAssemblerHelpers::isUnsigned<MacroAssemblerARM64>(cond))
+            m_assembler.ldrh(memoryTempRegister, address.base, memoryTempRegister);
+        else
+            m_assembler.ldrsh<32>(memoryTempRegister, address.base, memoryTempRegister);
+
+        return branchTest32(cond, memoryTempRegister, mask16);
+    }
+
+    Jump branchTest16(ResultCondition cond, BaseIndex address, TrustedImm32 mask = TrustedImm32(-1))
+    {
+        TrustedImm32 mask16 = MacroAssemblerHelpers::mask16OnCondition(*this, cond, mask);
+        MacroAssemblerHelpers::load16OnCondition(*this, cond, address, getCachedMemoryTempRegisterIDAndInvalidate());
+        return branchTest32(cond, memoryTempRegister, mask16);
+    }
+
     Jump branch32WithUnalignedHalfWords(RelationalCondition cond, BaseIndex left, TrustedImm32 right)
     {
         return branch32(cond, left, right);

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerARMv7.h (286019 => 286020)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerARMv7.h	2021-11-18 19:38:01 UTC (rev 286019)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerARMv7.h	2021-11-18 20:04:48 UTC (rev 286020)
@@ -1772,7 +1772,7 @@
 
     Jump branchTest8(ResultCondition cond, BaseIndex address, TrustedImm32 mask = TrustedImm32(-1))
     {
-        // use addressTempRegister incase the branchTest8 we call uses dataTempRegister. :-/
+        // use addressTempRegister incase the branchTest32 we call uses dataTempRegister. :-/
         TrustedImm32 mask8 = MacroAssemblerHelpers::mask8OnCondition(*this, cond, mask);
         MacroAssemblerHelpers::load8OnCondition(*this, cond, address, addressTempRegister);
         return branchTest32(cond, addressTempRegister, mask8);
@@ -1780,7 +1780,7 @@
 
     Jump branchTest8(ResultCondition cond, Address address, TrustedImm32 mask = TrustedImm32(-1))
     {
-        // use addressTempRegister incase the branchTest8 we call uses dataTempRegister. :-/
+        // use addressTempRegister incase the branchTest32 we call uses dataTempRegister. :-/
         TrustedImm32 mask8 = MacroAssemblerHelpers::mask8OnCondition(*this, cond, mask);
         MacroAssemblerHelpers::load8OnCondition(*this, cond, address, addressTempRegister);
         return branchTest32(cond, addressTempRegister, mask8);
@@ -1788,7 +1788,7 @@
 
     Jump branchTest8(ResultCondition cond, AbsoluteAddress address, TrustedImm32 mask = TrustedImm32(-1))
     {
-        // use addressTempRegister incase the branchTest8 we call uses dataTempRegister. :-/
+        // use addressTempRegister incase the branchTest32 we call uses dataTempRegister. :-/
         TrustedImm32 mask8 = MacroAssemblerHelpers::mask8OnCondition(*this, cond, mask);
         move(TrustedImmPtr(address.m_ptr), addressTempRegister);
         MacroAssemblerHelpers::load8OnCondition(*this, cond, Address(addressTempRegister), addressTempRegister);
@@ -1795,6 +1795,31 @@
         return branchTest32(cond, addressTempRegister, mask8);
     }
 
+    Jump branchTest16(ResultCondition cond, BaseIndex address, TrustedImm32 mask = TrustedImm32(-1))
+    {
+        // use addressTempRegister incase the branchTest32 we call uses dataTempRegister. :-/
+        TrustedImm32 mask16 = MacroAssemblerHelpers::mask16OnCondition(*this, cond, mask);
+        MacroAssemblerHelpers::load16OnCondition(*this, cond, address, addressTempRegister);
+        return branchTest32(cond, addressTempRegister, mask16);
+    }
+
+    Jump branchTest16(ResultCondition cond, Address address, TrustedImm32 mask = TrustedImm32(-1))
+    {
+        // use addressTempRegister incase the branchTest32 we call uses dataTempRegister. :-/
+        TrustedImm32 mask16 = MacroAssemblerHelpers::mask16OnCondition(*this, cond, mask);
+        MacroAssemblerHelpers::load16OnCondition(*this, cond, address, addressTempRegister);
+        return branchTest32(cond, addressTempRegister, mask16);
+    }
+
+    Jump branchTest16(ResultCondition cond, AbsoluteAddress address, TrustedImm32 mask = TrustedImm32(-1))
+    {
+        // use addressTempRegister incase the branchTest32 we call uses dataTempRegister. :-/
+        TrustedImm32 mask16 = MacroAssemblerHelpers::mask16OnCondition(*this, cond, mask);
+        move(TrustedImmPtr(address.m_ptr), addressTempRegister);
+        MacroAssemblerHelpers::load16OnCondition(*this, cond, Address(addressTempRegister), addressTempRegister);
+        return branchTest32(cond, addressTempRegister, mask16);
+    }
+
     void farJump(RegisterID target, PtrTag)
     {
         m_assembler.bx(target);
@@ -2041,8 +2066,8 @@
     // asm ops like test, or pseudo ops like pop().
     void test32(ResultCondition cond, Address address, TrustedImm32 mask, RegisterID dest)
     {
-        load32(address, dataTempRegister);
-        test32(dataTempRegister, mask);
+        load32(address, addressTempRegister);
+        test32(addressTempRegister, mask);
         m_assembler.it(armV7Condition(cond), false);
         m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(1));
         m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(0));
@@ -2051,8 +2076,8 @@
     void test8(ResultCondition cond, Address address, TrustedImm32 mask, RegisterID dest)
     {
         TrustedImm32 mask8 = MacroAssemblerHelpers::mask8OnCondition(*this, cond, mask);
-        MacroAssemblerHelpers::load8OnCondition(*this, cond, address, dataTempRegister);
-        test32(dataTempRegister, mask8);
+        MacroAssemblerHelpers::load8OnCondition(*this, cond, address, addressTempRegister);
+        test32(addressTempRegister, mask8);
         m_assembler.it(armV7Condition(cond), false);
         m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(1));
         m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(0));

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerHelpers.h (286019 => 286020)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerHelpers.h	2021-11-18 19:38:01 UTC (rev 286019)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerHelpers.h	2021-11-18 20:04:48 UTC (rev 286020)
@@ -126,6 +126,30 @@
     return typename MacroAssemblerType::TrustedImm32(static_cast<int8_t>(value.m_value));
 }
 
+template<typename MacroAssemblerType>
+inline typename MacroAssemblerType::TrustedImm32 mask16OnCondition(MacroAssemblerType&, typename MacroAssemblerType::RelationalCondition cond, typename MacroAssemblerType::TrustedImm32 value)
+{
+    if (isUnsigned<MacroAssemblerType>(cond))
+        return typename MacroAssemblerType::TrustedImm32(static_cast<uint16_t>(value.m_value));
+    return typename MacroAssemblerType::TrustedImm32(static_cast<int16_t>(value.m_value));
+}
+
+template<typename MacroAssemblerType>
+inline typename MacroAssemblerType::TrustedImm32 mask16OnCondition(MacroAssemblerType&, typename MacroAssemblerType::ResultCondition cond, typename MacroAssemblerType::TrustedImm32 value)
+{
+    // If condition is Zero or NonZero, upper bits are unrelated.
+    // Since branchTest32 handles -1 in an optimized manner, we keep -1 as is instead of converting it to 0xffff.
+    if (cond == MacroAssemblerType::Zero || cond == MacroAssemblerType::NonZero) {
+        if (value.m_value == -1)
+            return value;
+    }
+    if (isUnsigned<MacroAssemblerType>(cond))
+        return typename MacroAssemblerType::TrustedImm32(static_cast<uint16_t>(value.m_value));
+    ASSERT_WITH_MESSAGE(cond != MacroAssemblerType::Overflow, "Overflow is not used for 16bit test operations.");
+    ASSERT(isSigned<MacroAssemblerType>(cond));
+    return typename MacroAssemblerType::TrustedImm32(static_cast<int16_t>(value.m_value));
+}
+
 template<typename MacroAssemblerType, typename Condition, typename ...Args>
 void load8OnCondition(MacroAssemblerType& jit, Condition cond, Args... args)
 {
@@ -134,4 +158,12 @@
     return jit.load8SignedExtendTo32(std::forward<Args>(args)...);
 }
 
+template<typename MacroAssemblerType, typename Condition, typename ...Args>
+void load16OnCondition(MacroAssemblerType& jit, Condition cond, Args... args)
+{
+    if (isUnsigned<MacroAssemblerType>(cond))
+        return jit.load16(std::forward<Args>(args)...);
+    return jit.load16SignedExtendTo32(std::forward<Args>(args)...);
+}
+
 } } // namespace JSC

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerMIPS.h (286019 => 286020)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerMIPS.h	2021-11-18 19:38:01 UTC (rev 286019)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerMIPS.h	2021-11-18 20:04:48 UTC (rev 286020)
@@ -1272,6 +1272,29 @@
         }
     }
 
+    ALWAYS_INLINE void load16(AbsoluteAddress address, RegisterID dest)
+    {
+        load16(address.m_ptr, dest);
+    }
+
+    /* Need to use zero-extened load half-word for load16.  */
+    void load16SignedExtendTo32(Address address, RegisterID dest)
+    {
+        if (address.offset >= -32768 && address.offset <= 32767
+            && !m_fixedWidth)
+            m_assembler.lh(dest, address.base, address.offset);
+        else {
+            /*
+                lui     addrTemp, (offset + 0x8000) >> 16
+                addu    addrTemp, addrTemp, base
+                lh      dest, (offset & 0xffff)(addrTemp)
+              */
+            m_assembler.lui(addrTempRegister, (address.offset + 0x8000) >> 16);
+            m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+            m_assembler.lh(dest, addrTempRegister, address.offset);
+        }
+    }
+
     void load16SignedExtendTo32(BaseIndex address, RegisterID dest)
     {
         if (!m_fixedWidth) {
@@ -1293,6 +1316,28 @@
         }
     }
 
+    ALWAYS_INLINE void load16SignedExtendTo32(AbsoluteAddress address, RegisterID dest)
+    {
+        load16SignedExtendTo32(address.m_ptr, dest);
+    }
+
+    void load16SignedExtendTo32(const void* address, RegisterID dest)
+    {
+        if (m_fixedWidth) {
+            /*
+                li  addrTemp, address
+                lh dest, 0(addrTemp)
+            */
+            move(TrustedImmPtr(address), addrTempRegister);
+            m_assembler.lh(dest, addrTempRegister, 0);
+        } else {
+            uintptr_t adr = reinterpret_cast<uintptr_t>(address);
+            m_assembler.lui(addrTempRegister, (adr + 0x8000) >> 16);
+            m_assembler.lh(dest, addrTempRegister, adr & 0xffff);
+        }
+    }
+
+
     void loadPair32(RegisterID src, RegisterID dest1, RegisterID dest2)
     {
         loadPair32(src, TrustedImm32(0), dest1, dest2);
@@ -2043,6 +2088,34 @@
         return branchTest32(cond, dataTempRegister, mask8);
     }
 
+    TrustedImm32 mask16OnTest(ResultCondition cond, TrustedImm32 mask)
+    {
+        if (mask.m_value == -1 && !m_fixedWidth)
+            return TrustedImm32(-1);
+        return MacroAssemblerHelpers::mask16OnCondition(*this, cond, mask);
+    }
+
+    Jump branchTest16(ResultCondition cond, BaseIndex address, TrustedImm32 mask = TrustedImm32(-1))
+    {
+        TrustedImm32 mask16 = mask16OnTest(cond, mask);
+        MacroAssemblerHelpers::load16OnCondition(*this, cond, address, dataTempRegister);
+        return branchTest32(cond, dataTempRegister, mask16);
+    }
+
+    Jump branchTest16(ResultCondition cond, Address address, TrustedImm32 mask = TrustedImm32(-1))
+    {
+        TrustedImm32 mask16 = mask16OnTest(cond, mask);
+        MacroAssemblerHelpers::load16OnCondition(*this, cond, address, dataTempRegister);
+        return branchTest32(cond, dataTempRegister, mask16);
+    }
+
+    Jump branchTest16(ResultCondition cond, AbsoluteAddress address, TrustedImm32 mask = TrustedImm32(-1))
+    {
+        TrustedImm32 mask16 = mask16OnTest(cond, mask);
+        MacroAssemblerHelpers::load16OnCondition(*this, cond, address, dataTempRegister);
+        return branchTest32(cond, dataTempRegister, mask16);
+    }
+
     Jump jump()
     {
         return branchEqual(MIPSRegisters::zero, MIPSRegisters::zero);

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerX86Common.h (286019 => 286020)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerX86Common.h	2021-11-18 19:38:01 UTC (rev 286019)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerX86Common.h	2021-11-18 20:04:48 UTC (rev 286020)
@@ -2759,6 +2759,26 @@
         return Jump(m_assembler.jCC(x86Condition(cond)));
     }
 
+    Jump branchTest16(ResultCondition cond, Address address, TrustedImm32 mask = TrustedImm32(-1))
+    {
+        TrustedImm32 mask16(static_cast<int16_t>(mask.m_value));
+        if (mask16.m_value == -1)
+            m_assembler.cmpw_im(0, address.offset, address.base);
+        else
+            m_assembler.testw_im(mask16.m_value, address.offset, address.base);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
+    Jump branchTest16(ResultCondition cond, BaseIndex address, TrustedImm32 mask = TrustedImm32(-1))
+    {
+        TrustedImm32 mask16(static_cast<int16_t>(mask.m_value));
+        if (mask16.m_value == -1)
+            m_assembler.cmpw_im(0, address.offset, address.base, address.index, address.scale);
+        else
+            m_assembler.testw_im(mask16.m_value, address.offset, address.base, address.index, address.scale);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
     Jump branch8(RelationalCondition cond, BaseIndex left, TrustedImm32 right)
     {
         TrustedImm32 right8(static_cast<int8_t>(right.m_value));

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerX86_64.h (286019 => 286020)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerX86_64.h	2021-11-18 19:38:01 UTC (rev 286019)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerX86_64.h	2021-11-18 20:04:48 UTC (rev 286020)
@@ -1563,7 +1563,23 @@
         MacroAssemblerX86Common::move(TrustedImmPtr(address.m_ptr), scratchRegister());
         return MacroAssemblerX86Common::branchTest8(cond, Address(scratchRegister()), mask8);
     }
-    
+
+    using MacroAssemblerX86Common::branchTest16;
+    Jump branchTest16(ResultCondition cond, ExtendedAddress address, TrustedImm32 mask = TrustedImm32(-1))
+    {
+        TrustedImm32 mask16(static_cast<int16_t>(mask.m_value));
+        TrustedImmPtr addr(reinterpret_cast<void*>(address.offset));
+        MacroAssemblerX86Common::move(addr, scratchRegister());
+        return MacroAssemblerX86Common::branchTest16(cond, BaseIndex(scratchRegister(), address.base, TimesOne), mask16);
+    }
+
+    Jump branchTest16(ResultCondition cond, AbsoluteAddress address, TrustedImm32 mask = TrustedImm32(-1))
+    {
+        TrustedImm32 mask16(static_cast<int16_t>(mask.m_value));
+        MacroAssemblerX86Common::move(TrustedImmPtr(address.m_ptr), scratchRegister());
+        return MacroAssemblerX86Common::branchTest16(cond, Address(scratchRegister()), mask16);
+    }
+
     void xchg64(RegisterID reg, Address address)
     {
         m_assembler.xchgq_rm(reg, address.offset, address.base);

Modified: trunk/Source/_javascript_Core/assembler/X86Assembler.h (286019 => 286020)


--- trunk/Source/_javascript_Core/assembler/X86Assembler.h	2021-11-18 19:38:01 UTC (rev 286019)
+++ trunk/Source/_javascript_Core/assembler/X86Assembler.h	2021-11-18 20:04:48 UTC (rev 286020)
@@ -2049,6 +2049,19 @@
         m_formatter.oneByteOp(OP_CMP_EvGv, src, base, index, scale, offset);
     }
 
+    void cmpw_im(int imm, int offset, RegisterID base)
+    {
+        if (CAN_SIGN_EXTEND_8_32(imm)) {
+            m_formatter.prefix(PRE_OPERAND_SIZE);
+            m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, offset);
+            m_formatter.immediate8(imm);
+        } else {
+            m_formatter.prefix(PRE_OPERAND_SIZE);
+            m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, offset);
+            m_formatter.immediate16(imm);
+        }
+    }
+
     void cmpw_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
     {
         if (CAN_SIGN_EXTEND_8_32(imm)) {
@@ -2151,7 +2164,21 @@
         m_formatter.prefix(PRE_OPERAND_SIZE);
         m_formatter.oneByteOp(OP_TEST_EvGv, src, dst);
     }
-    
+
+    void testw_im(int imm, int offset, RegisterID base)
+    {
+        m_formatter.prefix(PRE_OPERAND_SIZE);
+        m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, offset);
+        m_formatter.immediate16(imm);
+    }
+
+    void testw_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
+    {
+        m_formatter.prefix(PRE_OPERAND_SIZE);
+        m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, index, scale, offset);
+        m_formatter.immediate16(imm);
+    }
+
     void testb_i8r(int imm, RegisterID dst)
     {
         if (dst == X86Registers::eax)

Modified: trunk/Source/_javascript_Core/assembler/testmasm.cpp (286019 => 286020)


--- trunk/Source/_javascript_Core/assembler/testmasm.cpp	2021-11-18 19:38:01 UTC (rev 286019)
+++ trunk/Source/_javascript_Core/assembler/testmasm.cpp	2021-11-18 20:04:48 UTC (rev 286020)
@@ -326,6 +326,98 @@
     }), expected);
 }
 
+void testBranchTest8()
+{
+    for (auto value : int32Operands()) {
+        for (auto value2 : int32Operands()) {
+            auto test1 = compile([=] (CCallHelpers& jit) {
+                emitFunctionPrologue(jit);
+
+                auto branch = jit.branchTest8(MacroAssembler::NonZero, CCallHelpers::Address(GPRInfo::argumentGPR0, 1), CCallHelpers::TrustedImm32(value2));
+                jit.move(CCallHelpers::TrustedImm32(0), GPRInfo::returnValueGPR);
+                auto done = jit.jump();
+                branch.link(&jit);
+                jit.move(CCallHelpers::TrustedImm32(1), GPRInfo::returnValueGPR);
+                done.link(&jit);
+
+                emitFunctionEpilogue(jit);
+                jit.ret();
+            });
+
+            auto test2 = compile([=] (CCallHelpers& jit) {
+                emitFunctionPrologue(jit);
+
+                auto branch = jit.branchTest8(MacroAssembler::NonZero, CCallHelpers::BaseIndex(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, CCallHelpers::TimesOne), CCallHelpers::TrustedImm32(value2));
+                jit.move(CCallHelpers::TrustedImm32(0), GPRInfo::returnValueGPR);
+                auto done = jit.jump();
+                branch.link(&jit);
+                jit.move(CCallHelpers::TrustedImm32(1), GPRInfo::returnValueGPR);
+                done.link(&jit);
+
+                emitFunctionEpilogue(jit);
+                jit.ret();
+            });
+
+            int result = 0;
+            if (static_cast<uint8_t>(value) & static_cast<uint8_t>(value2))
+                result = 1;
+
+            uint8_t array[] = {
+                0,
+                static_cast<uint8_t>(value)
+            };
+            CHECK_EQ(invoke<int>(test1, array), result);
+            CHECK_EQ(invoke<int>(test2, array, 1), result);
+        }
+    }
+}
+
+void testBranchTest16()
+{
+    for (auto value : int32Operands()) {
+        for (auto value2 : int32Operands()) {
+            auto test1 = compile([=] (CCallHelpers& jit) {
+                emitFunctionPrologue(jit);
+
+                auto branch = jit.branchTest16(MacroAssembler::NonZero, CCallHelpers::Address(GPRInfo::argumentGPR0, 2), CCallHelpers::TrustedImm32(value2));
+                jit.move(CCallHelpers::TrustedImm32(0), GPRInfo::returnValueGPR);
+                auto done = jit.jump();
+                branch.link(&jit);
+                jit.move(CCallHelpers::TrustedImm32(1), GPRInfo::returnValueGPR);
+                done.link(&jit);
+
+                emitFunctionEpilogue(jit);
+                jit.ret();
+            });
+
+            auto test2 = compile([=] (CCallHelpers& jit) {
+                emitFunctionPrologue(jit);
+
+                auto branch = jit.branchTest16(MacroAssembler::NonZero, CCallHelpers::BaseIndex(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, CCallHelpers::TimesTwo), CCallHelpers::TrustedImm32(value2));
+                jit.move(CCallHelpers::TrustedImm32(0), GPRInfo::returnValueGPR);
+                auto done = jit.jump();
+                branch.link(&jit);
+                jit.move(CCallHelpers::TrustedImm32(1), GPRInfo::returnValueGPR);
+                done.link(&jit);
+
+                emitFunctionEpilogue(jit);
+                jit.ret();
+            });
+
+            int result = 0;
+            if (static_cast<uint16_t>(value) & static_cast<uint16_t>(value2))
+                result = 1;
+
+            uint16_t array[] = {
+                0,
+                static_cast<uint16_t>(value)
+            };
+            CHECK_EQ(invoke<int>(test1, array), result);
+            CHECK_EQ(invoke<int>(test2, array, 1), result);
+        }
+    }
+}
+
 #if CPU(X86_64)
 void testBranchTestBit32RegReg()
 {
@@ -5649,6 +5741,9 @@
     RUN(testLoadStorePair32());
     RUN(testSub32ArgImm());
 
+    RUN(testBranchTest8());
+    RUN(testBranchTest16());
+
 #if CPU(X86_64)
     RUN(testBranchTestBit32RegReg());
     RUN(testBranchTestBit32RegImm());
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to