Title: [280391] trunk/Source/_javascript_Core
Revision
280391
Author
[email protected]
Date
2021-07-28 11:49:28 -0700 (Wed, 28 Jul 2021)

Log Message

[JSC] load/store with BaseIndex is inefficient in ARM64
https://bugs.webkit.org/show_bug.cgi?id=228543

Reviewed by Mark Lam.

While we are frequently using load + BaseIndex (with offset) in RegExp code,
we emit 3 instructions in ARM64. This can be represented in 2 instructions.
This patch adds that path to make generated code tight in ARM64 RegExp.

* assembler/MacroAssemblerARM64.h:
(JSC::MacroAssemblerARM64::load64):
(JSC::MacroAssemblerARM64::load32):
(JSC::MacroAssemblerARM64::load16):
(JSC::MacroAssemblerARM64::load16SignedExtendTo32):
(JSC::MacroAssemblerARM64::load8):
(JSC::MacroAssemblerARM64::load8SignedExtendTo32):
(JSC::MacroAssemblerARM64::store64):
(JSC::MacroAssemblerARM64::store32):
(JSC::MacroAssemblerARM64::store16):
(JSC::MacroAssemblerARM64::store8):
(JSC::MacroAssemblerARM64::loadDouble):
(JSC::MacroAssemblerARM64::loadFloat):
(JSC::MacroAssemblerARM64::storeDouble):
(JSC::MacroAssemblerARM64::storeFloat):
(JSC::MacroAssemblerARM64::tryFoldBaseAndOffsetPart):
* assembler/testmasm.cpp:
(JSC::testLoadBaseIndex):
(JSC::testStoreBaseIndex):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (280390 => 280391)


--- trunk/Source/_javascript_Core/ChangeLog	2021-07-28 17:53:29 UTC (rev 280390)
+++ trunk/Source/_javascript_Core/ChangeLog	2021-07-28 18:49:28 UTC (rev 280391)
@@ -1,3 +1,34 @@
+2021-07-28  Yusuke Suzuki  <[email protected]>
+
+        [JSC] load/store with BaseIndex is inefficient in ARM64
+        https://bugs.webkit.org/show_bug.cgi?id=228543
+
+        Reviewed by Mark Lam.
+
+        While we are frequently using load + BaseIndex (with offset) in RegExp code,
+        we emit 3 instructions in ARM64. This can be represented in 2 instructions.
+        This patch adds that path to make generated code tight in ARM64 RegExp.
+
+        * assembler/MacroAssemblerARM64.h:
+        (JSC::MacroAssemblerARM64::load64):
+        (JSC::MacroAssemblerARM64::load32):
+        (JSC::MacroAssemblerARM64::load16):
+        (JSC::MacroAssemblerARM64::load16SignedExtendTo32):
+        (JSC::MacroAssemblerARM64::load8):
+        (JSC::MacroAssemblerARM64::load8SignedExtendTo32):
+        (JSC::MacroAssemblerARM64::store64):
+        (JSC::MacroAssemblerARM64::store32):
+        (JSC::MacroAssemblerARM64::store16):
+        (JSC::MacroAssemblerARM64::store8):
+        (JSC::MacroAssemblerARM64::loadDouble):
+        (JSC::MacroAssemblerARM64::loadFloat):
+        (JSC::MacroAssemblerARM64::storeDouble):
+        (JSC::MacroAssemblerARM64::storeFloat):
+        (JSC::MacroAssemblerARM64::tryFoldBaseAndOffsetPart):
+        * assembler/testmasm.cpp:
+        (JSC::testLoadBaseIndex):
+        (JSC::testStoreBaseIndex):
+
 2021-07-28  Philippe Normand  <[email protected]>
 
         [WPE][GTK] SVN_REVISION drifting away if bots don't re-run cmake

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerARM64.h (280390 => 280391)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerARM64.h	2021-07-28 17:53:29 UTC (rev 280390)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerARM64.h	2021-07-28 18:49:28 UTC (rev 280391)
@@ -1430,9 +1430,11 @@
 
     void load64(BaseIndex address, RegisterID dest)
     {
-        if (!address.offset && (!address.scale || address.scale == 3)) {
-            m_assembler.ldr<64>(dest, address.base, address.index, indexExtendType(address), address.scale);
-            return;
+        if (address.scale == TimesOne || address.scale == TimesEight) {
+            if (auto baseGPR = tryFoldBaseAndOffsetPart(address)) {
+                m_assembler.ldr<64>(dest, baseGPR.value(), address.index, indexExtendType(address), address.scale);
+                return;
+            }
         }
 
         signExtend32ToPtr(TrustedImm32(address.offset), getCachedMemoryTempRegisterIDAndInvalidate());
@@ -1529,9 +1531,11 @@
 
     void load32(BaseIndex address, RegisterID dest)
     {
-        if (!address.offset && (!address.scale || address.scale == 2)) {
-            m_assembler.ldr<32>(dest, address.base, address.index, indexExtendType(address), address.scale);
-            return;
+        if (address.scale == TimesOne || address.scale == TimesFour) {
+            if (auto baseGPR = tryFoldBaseAndOffsetPart(address)) {
+                m_assembler.ldr<32>(dest, baseGPR.value(), address.index, indexExtendType(address), address.scale);
+                return;
+            }
         }
 
         signExtend32ToPtr(TrustedImm32(address.offset), getCachedMemoryTempRegisterIDAndInvalidate());
@@ -1576,9 +1580,11 @@
     
     void load16(BaseIndex address, RegisterID dest)
     {
-        if (!address.offset && (!address.scale || address.scale == 1)) {
-            m_assembler.ldrh(dest, address.base, address.index, indexExtendType(address), address.scale);
-            return;
+        if (address.scale == TimesOne || address.scale == TimesTwo) {
+            if (auto baseGPR = tryFoldBaseAndOffsetPart(address)) {
+                m_assembler.ldrh(dest, baseGPR.value(), address.index, indexExtendType(address), address.scale);
+                return;
+            }
         }
 
         signExtend32ToPtr(TrustedImm32(address.offset), getCachedMemoryTempRegisterIDAndInvalidate());
@@ -1620,9 +1626,11 @@
 
     void load16SignedExtendTo32(BaseIndex address, RegisterID dest)
     {
-        if (!address.offset && (!address.scale || address.scale == 1)) {
-            m_assembler.ldrsh<32>(dest, address.base, address.index, indexExtendType(address), address.scale);
-            return;
+        if (address.scale == TimesOne || address.scale == TimesTwo) {
+            if (auto baseGPR = tryFoldBaseAndOffsetPart(address)) {
+                m_assembler.ldrsh<32>(dest, baseGPR.value(), address.index, indexExtendType(address), address.scale);
+                return;
+            }
         }
 
         signExtend32ToPtr(TrustedImm32(address.offset), getCachedMemoryTempRegisterIDAndInvalidate());
@@ -1651,9 +1659,11 @@
 
     void load8(BaseIndex address, RegisterID dest)
     {
-        if (!address.offset && !address.scale) {
-            m_assembler.ldrb(dest, address.base, address.index, indexExtendType(address), address.scale);
-            return;
+        if (address.scale == TimesOne) {
+            if (auto baseGPR = tryFoldBaseAndOffsetPart(address)) {
+                m_assembler.ldrb(dest, baseGPR.value(), address.index, indexExtendType(address), address.scale);
+                return;
+            }
         }
 
         signExtend32ToPtr(TrustedImm32(address.offset), getCachedMemoryTempRegisterIDAndInvalidate());
@@ -1685,9 +1695,11 @@
 
     void load8SignedExtendTo32(BaseIndex address, RegisterID dest)
     {
-        if (!address.offset && !address.scale) {
-            m_assembler.ldrsb<32>(dest, address.base, address.index, indexExtendType(address), address.scale);
-            return;
+        if (address.scale == TimesOne) {
+            if (auto baseGPR = tryFoldBaseAndOffsetPart(address)) {
+                m_assembler.ldrsb<32>(dest, baseGPR.value(), address.index, indexExtendType(address), address.scale);
+                return;
+            }
         }
 
         signExtend32ToPtr(TrustedImm32(address.offset), getCachedMemoryTempRegisterIDAndInvalidate());
@@ -1724,9 +1736,11 @@
 
     void store64(RegisterID src, BaseIndex address)
     {
-        if (!address.offset && (!address.scale || address.scale == 3)) {
-            m_assembler.str<64>(src, address.base, address.index, indexExtendType(address), address.scale);
-            return;
+        if (address.scale == TimesOne || address.scale == TimesEight) {
+            if (auto baseGPR = tryFoldBaseAndOffsetPart(address)) {
+                m_assembler.str<64>(src, baseGPR.value(), address.index, indexExtendType(address), address.scale);
+                return;
+            }
         }
 
         signExtend32ToPtr(TrustedImm32(address.offset), getCachedMemoryTempRegisterIDAndInvalidate());
@@ -1831,9 +1845,11 @@
 
     void store32(RegisterID src, BaseIndex address)
     {
-        if (!address.offset && (!address.scale || address.scale == 2)) {
-            m_assembler.str<32>(src, address.base, address.index, indexExtendType(address), address.scale);
-            return;
+        if (address.scale == TimesOne || address.scale == TimesFour) {
+            if (auto baseGPR = tryFoldBaseAndOffsetPart(address)) {
+                m_assembler.str<32>(src, baseGPR.value(), address.index, indexExtendType(address), address.scale);
+                return;
+            }
         }
 
         signExtend32ToPtr(TrustedImm32(address.offset), getCachedMemoryTempRegisterIDAndInvalidate());
@@ -1898,9 +1914,11 @@
 
     void store16(RegisterID src, BaseIndex address)
     {
-        if (!address.offset && (!address.scale || address.scale == 1)) {
-            m_assembler.strh(src, address.base, address.index, indexExtendType(address), address.scale);
-            return;
+        if (address.scale == TimesOne || address.scale == TimesTwo) {
+            if (auto baseGPR = tryFoldBaseAndOffsetPart(address)) {
+                m_assembler.strh(src, baseGPR.value(), address.index, indexExtendType(address), address.scale);
+                return;
+            }
         }
 
         signExtend32ToPtr(TrustedImm32(address.offset), getCachedMemoryTempRegisterIDAndInvalidate());
@@ -1926,9 +1944,11 @@
 
     void store8(RegisterID src, BaseIndex address)
     {
-        if (!address.offset && !address.scale) {
-            m_assembler.strb(src, address.base, address.index, indexExtendType(address), address.scale);
-            return;
+        if (address.scale == TimesOne) {
+            if (auto baseGPR = tryFoldBaseAndOffsetPart(address)) {
+                m_assembler.strb(src, baseGPR.value(), address.index, indexExtendType(address), address.scale);
+                return;
+            }
         }
 
         signExtend32ToPtr(TrustedImm32(address.offset), getCachedMemoryTempRegisterIDAndInvalidate());
@@ -2239,9 +2259,11 @@
 
     void loadDouble(BaseIndex address, FPRegisterID dest)
     {
-        if (!address.offset && (!address.scale || address.scale == 3)) {
-            m_assembler.ldr<64>(dest, address.base, address.index, indexExtendType(address), address.scale);
-            return;
+        if (address.scale == TimesOne || address.scale == TimesEight) {
+            if (auto baseGPR = tryFoldBaseAndOffsetPart(address)) {
+                m_assembler.ldr<64>(dest, baseGPR.value(), address.index, indexExtendType(address), address.scale);
+                return;
+            }
         }
 
         signExtend32ToPtr(TrustedImm32(address.offset), getCachedMemoryTempRegisterIDAndInvalidate());
@@ -2266,9 +2288,11 @@
 
     void loadFloat(BaseIndex address, FPRegisterID dest)
     {
-        if (!address.offset && (!address.scale || address.scale == 2)) {
-            m_assembler.ldr<32>(dest, address.base, address.index, indexExtendType(address), address.scale);
-            return;
+        if (address.scale == TimesOne || address.scale == TimesFour) {
+            if (auto baseGPR = tryFoldBaseAndOffsetPart(address)) {
+                m_assembler.ldr<32>(dest, baseGPR.value(), address.index, indexExtendType(address), address.scale);
+                return;
+            }
         }
 
         signExtend32ToPtr(TrustedImm32(address.offset), getCachedMemoryTempRegisterIDAndInvalidate());
@@ -2523,9 +2547,11 @@
 
     void storeDouble(FPRegisterID src, BaseIndex address)
     {
-        if (!address.offset && (!address.scale || address.scale == 3)) {
-            m_assembler.str<64>(src, address.base, address.index, indexExtendType(address), address.scale);
-            return;
+        if (address.scale == TimesOne || address.scale == TimesEight) {
+            if (auto baseGPR = tryFoldBaseAndOffsetPart(address)) {
+                m_assembler.str<64>(src, baseGPR.value(), address.index, indexExtendType(address), address.scale);
+                return;
+            }
         }
 
         signExtend32ToPtr(TrustedImm32(address.offset), getCachedMemoryTempRegisterIDAndInvalidate());
@@ -2544,9 +2570,11 @@
     
     void storeFloat(FPRegisterID src, BaseIndex address)
     {
-        if (!address.offset && (!address.scale || address.scale == 2)) {
-            m_assembler.str<32>(src, address.base, address.index, indexExtendType(address), address.scale);
-            return;
+        if (address.scale == TimesOne || address.scale == TimesFour) {
+            if (auto baseGPR = tryFoldBaseAndOffsetPart(address)) {
+                m_assembler.str<32>(src, baseGPR.value(), address.index, indexExtendType(address), address.scale);
+                return;
+            }
         }
 
         signExtend32ToPtr(TrustedImm32(address.offset), getCachedMemoryTempRegisterIDAndInvalidate());
@@ -4799,6 +4827,21 @@
         }
         return false;
     }
+
+    std::optional<RegisterID> tryFoldBaseAndOffsetPart(BaseIndex address)
+    {
+        if (!address.offset)
+            return address.base;
+        if (isUInt12(address.offset)) {
+            m_assembler.add<64>(getCachedMemoryTempRegisterIDAndInvalidate(), address.base, UInt12(address.offset));
+            return memoryTempRegister;
+        }
+        if (isUInt12(-address.offset)) {
+            m_assembler.sub<64>(getCachedMemoryTempRegisterIDAndInvalidate(), address.base, UInt12(-address.offset));
+            return memoryTempRegister;
+        }
+        return std::nullopt;
+    }
     
     template<int datasize>
     void loadLink(RegisterID src, RegisterID dest)

Modified: trunk/Source/_javascript_Core/assembler/testmasm.cpp (280390 => 280391)


--- trunk/Source/_javascript_Core/assembler/testmasm.cpp	2021-07-28 17:53:29 UTC (rev 280390)
+++ trunk/Source/_javascript_Core/assembler/testmasm.cpp	2021-07-28 18:49:28 UTC (rev 280391)
@@ -4209,6 +4209,336 @@
 #endif
 }
 
+void testLoadBaseIndex()
+{
+#if CPU(ARM64) || CPU(X86_64)
+    // load64
+    {
+        auto test = compile([=](CCallHelpers& jit) {
+            emitFunctionPrologue(jit);
+            jit.load64(CCallHelpers::BaseIndex(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, CCallHelpers::TimesEight, -8), GPRInfo::returnValueGPR);
+            emitFunctionEpilogue(jit);
+            jit.ret();
+        });
+        uint64_t array[] = { UINT64_MAX - 1, UINT64_MAX - 2, UINT64_MAX - 3, UINT64_MAX - 4, UINT64_MAX - 5, };
+        CHECK_EQ(invoke<uint64_t>(test, array, static_cast<UCPURegister>(3)), UINT64_MAX - 3);
+    }
+    {
+        auto test = compile([=](CCallHelpers& jit) {
+            emitFunctionPrologue(jit);
+            jit.load64(CCallHelpers::BaseIndex(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, CCallHelpers::TimesEight, 8), GPRInfo::returnValueGPR);
+            emitFunctionEpilogue(jit);
+            jit.ret();
+        });
+        uint64_t array[] = { UINT64_MAX - 1, UINT64_MAX - 2, UINT64_MAX - 3, UINT64_MAX - 4, UINT64_MAX - 5, };
+        CHECK_EQ(invoke<uint64_t>(test, array, static_cast<UCPURegister>(3)), UINT64_MAX - 5);
+    }
+#endif
+
+    // load32
+    {
+        auto test = compile([=](CCallHelpers& jit) {
+            emitFunctionPrologue(jit);
+            jit.load32(CCallHelpers::BaseIndex(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, CCallHelpers::TimesFour, -4), GPRInfo::returnValueGPR);
+            emitFunctionEpilogue(jit);
+            jit.ret();
+        });
+        uint32_t array[] = { UINT32_MAX - 1, UINT32_MAX - 2, UINT32_MAX - 3, UINT32_MAX - 4, UINT32_MAX - 5, };
+        CHECK_EQ(invoke<uint32_t>(test, array, static_cast<UCPURegister>(3)), UINT32_MAX - 3);
+    }
+    {
+        auto test = compile([=](CCallHelpers& jit) {
+            emitFunctionPrologue(jit);
+            jit.load32(CCallHelpers::BaseIndex(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, CCallHelpers::TimesFour, 4), GPRInfo::returnValueGPR);
+            emitFunctionEpilogue(jit);
+            jit.ret();
+        });
+        uint32_t array[] = { UINT32_MAX - 1, UINT32_MAX - 2, UINT32_MAX - 3, UINT32_MAX - 4, UINT32_MAX - 5, };
+        CHECK_EQ(invoke<uint32_t>(test, array, static_cast<UCPURegister>(3)), UINT32_MAX - 5);
+    }
+
+    // load16
+    {
+        auto test = compile([=](CCallHelpers& jit) {
+            emitFunctionPrologue(jit);
+            jit.load16(CCallHelpers::BaseIndex(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, CCallHelpers::TimesTwo, -2), GPRInfo::returnValueGPR);
+            emitFunctionEpilogue(jit);
+            jit.ret();
+        });
+        uint16_t array[] = { UINT16_MAX - 1, UINT16_MAX - 2, UINT16_MAX - 3, UINT16_MAX - 4, UINT16_MAX - 5, };
+        CHECK_EQ(invoke<uint32_t>(test, array, static_cast<UCPURegister>(3)), UINT16_MAX - 3);
+    }
+    {
+        auto test = compile([=](CCallHelpers& jit) {
+            emitFunctionPrologue(jit);
+            jit.load16(CCallHelpers::BaseIndex(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, CCallHelpers::TimesTwo, 2), GPRInfo::returnValueGPR);
+            emitFunctionEpilogue(jit);
+            jit.ret();
+        });
+        uint16_t array[] = { UINT16_MAX - 1, UINT16_MAX - 2, UINT16_MAX - 3, UINT16_MAX - 4, static_cast<uint16_t>(-1), };
+        CHECK_EQ(invoke<uint32_t>(test, array, static_cast<UCPURegister>(3)), 0xffff);
+    }
+
+    // load16SignedExtendTo32
+    {
+        auto test = compile([=](CCallHelpers& jit) {
+            emitFunctionPrologue(jit);
+            jit.load16SignedExtendTo32(CCallHelpers::BaseIndex(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, CCallHelpers::TimesTwo, -2), GPRInfo::returnValueGPR);
+            emitFunctionEpilogue(jit);
+            jit.ret();
+        });
+        uint16_t array[] = { 1, 2, 0x7ff3, 4, 5, };
+        CHECK_EQ(invoke<uint32_t>(test, array, static_cast<UCPURegister>(3)), 0x7ff3);
+    }
+    {
+        auto test = compile([=](CCallHelpers& jit) {
+            emitFunctionPrologue(jit);
+            jit.load16SignedExtendTo32(CCallHelpers::BaseIndex(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, CCallHelpers::TimesTwo, 2), GPRInfo::returnValueGPR);
+            emitFunctionEpilogue(jit);
+            jit.ret();
+        });
+        uint16_t array[] = { UINT16_MAX - 1, UINT16_MAX - 2, UINT16_MAX - 3, UINT16_MAX - 4, static_cast<uint16_t>(-1), };
+        CHECK_EQ(invoke<uint32_t>(test, array, static_cast<UCPURegister>(3)), static_cast<uint32_t>(-1));
+    }
+
+    // load8
+    {
+        auto test = compile([=](CCallHelpers& jit) {
+            emitFunctionPrologue(jit);
+            jit.load8(CCallHelpers::BaseIndex(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, CCallHelpers::TimesOne, -1), GPRInfo::returnValueGPR);
+            emitFunctionEpilogue(jit);
+            jit.ret();
+        });
+        uint8_t array[] = { UINT8_MAX - 1, UINT8_MAX - 2, UINT8_MAX - 3, UINT8_MAX - 4, UINT8_MAX - 5, };
+        CHECK_EQ(invoke<uint32_t>(test, array, static_cast<UCPURegister>(3)), UINT8_MAX - 3);
+    }
+    {
+        auto test = compile([=](CCallHelpers& jit) {
+            emitFunctionPrologue(jit);
+            jit.load8(CCallHelpers::BaseIndex(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, CCallHelpers::TimesOne, 1), GPRInfo::returnValueGPR);
+            emitFunctionEpilogue(jit);
+            jit.ret();
+        });
+        uint8_t array[] = { UINT8_MAX - 1, UINT8_MAX - 2, UINT8_MAX - 3, UINT8_MAX - 4, static_cast<uint8_t>(-1), };
+        CHECK_EQ(invoke<uint32_t>(test, array, static_cast<UCPURegister>(3)), 0xff);
+    }
+
+    // load8SignedExtendTo32
+    {
+        auto test = compile([=](CCallHelpers& jit) {
+            emitFunctionPrologue(jit);
+            jit.load8SignedExtendTo32(CCallHelpers::BaseIndex(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, CCallHelpers::TimesOne, -1), GPRInfo::returnValueGPR);
+            emitFunctionEpilogue(jit);
+            jit.ret();
+        });
+        uint8_t array[] = { 1, 2, 0x73, 4, 5, };
+        CHECK_EQ(invoke<uint32_t>(test, array, static_cast<UCPURegister>(3)), 0x73);
+    }
+    {
+        auto test = compile([=](CCallHelpers& jit) {
+            emitFunctionPrologue(jit);
+            jit.load8SignedExtendTo32(CCallHelpers::BaseIndex(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, CCallHelpers::TimesOne, 1), GPRInfo::returnValueGPR);
+            emitFunctionEpilogue(jit);
+            jit.ret();
+        });
+        uint8_t array[] = { UINT8_MAX - 1, UINT8_MAX - 2, UINT8_MAX - 3, UINT8_MAX - 4, static_cast<uint8_t>(-1), };
+        CHECK_EQ(invoke<uint32_t>(test, array, static_cast<UCPURegister>(3)), static_cast<uint32_t>(-1));
+    }
+
+    // loadDouble
+    {
+        auto test = compile([=](CCallHelpers& jit) {
+            emitFunctionPrologue(jit);
+            jit.loadDouble(CCallHelpers::BaseIndex(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, CCallHelpers::TimesEight, -8), FPRInfo::returnValueFPR);
+            emitFunctionEpilogue(jit);
+            jit.ret();
+        });
+        double array[] = { 1, 2, 3, 4, 5, };
+        CHECK_EQ(invoke<double>(test, array, static_cast<UCPURegister>(3)), 3.0);
+    }
+    {
+        auto test = compile([=](CCallHelpers& jit) {
+            emitFunctionPrologue(jit);
+            jit.loadDouble(CCallHelpers::BaseIndex(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, CCallHelpers::TimesEight, 8), FPRInfo::returnValueFPR);
+            emitFunctionEpilogue(jit);
+            jit.ret();
+        });
+        double array[] = { 1, 2, 3, 4, 5, };
+        CHECK_EQ(invoke<double>(test, array, static_cast<UCPURegister>(3)), 5.0);
+    }
+
+    // loadFloat
+    {
+        auto test = compile([=](CCallHelpers& jit) {
+            emitFunctionPrologue(jit);
+            jit.loadFloat(CCallHelpers::BaseIndex(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, CCallHelpers::TimesFour, -4), FPRInfo::returnValueFPR);
+            emitFunctionEpilogue(jit);
+            jit.ret();
+        });
+        float array[] = { 1, 2, 3, 4, 5, };
+        CHECK_EQ(invoke<float>(test, array, static_cast<UCPURegister>(3)), 3.0);
+    }
+    {
+        auto test = compile([=](CCallHelpers& jit) {
+            emitFunctionPrologue(jit);
+            jit.loadFloat(CCallHelpers::BaseIndex(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, CCallHelpers::TimesFour, 4), FPRInfo::returnValueFPR);
+            emitFunctionEpilogue(jit);
+            jit.ret();
+        });
+        float array[] = { 1, 2, 3, 4, 5, };
+        CHECK_EQ(invoke<float>(test, array, static_cast<UCPURegister>(3)), 5.0);
+    }
+}
+
+void testStoreBaseIndex()
+{
+#if CPU(ARM64) || CPU(X86_64)
+    // store64
+    {
+        auto test = compile([=](CCallHelpers& jit) {
+            emitFunctionPrologue(jit);
+            jit.store64(GPRInfo::argumentGPR2, CCallHelpers::BaseIndex(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, CCallHelpers::TimesEight, -8));
+            emitFunctionEpilogue(jit);
+            jit.ret();
+        });
+        uint64_t array[] = { 1, 2, 3, 4, 5, };
+        invoke<void>(test, array, 3, UINT64_MAX - 42);
+        CHECK_EQ(array[2], UINT64_MAX - 42);
+    }
+    {
+        auto test = compile([=](CCallHelpers& jit) {
+            emitFunctionPrologue(jit);
+            jit.store64(GPRInfo::argumentGPR2, CCallHelpers::BaseIndex(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, CCallHelpers::TimesEight, 8));
+            emitFunctionEpilogue(jit);
+            jit.ret();
+        });
+        uint64_t array[] = { 1, 2, 3, 4, 5, };
+        invoke<void>(test, array, 3, UINT64_MAX - 42);
+        CHECK_EQ(array[4], UINT64_MAX - 42);
+    }
+#endif
+
+    // store32
+    {
+        auto test = compile([=](CCallHelpers& jit) {
+            emitFunctionPrologue(jit);
+            jit.store32(GPRInfo::argumentGPR2, CCallHelpers::BaseIndex(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, CCallHelpers::TimesFour, -4));
+            emitFunctionEpilogue(jit);
+            jit.ret();
+        });
+        uint32_t array[] = { 1, 2, 3, 4, 5, };
+        invoke<void>(test, array, 3, UINT32_MAX - 42);
+        CHECK_EQ(array[2], UINT32_MAX - 42);
+    }
+    {
+        auto test = compile([=](CCallHelpers& jit) {
+            emitFunctionPrologue(jit);
+            jit.store32(GPRInfo::argumentGPR2, CCallHelpers::BaseIndex(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, CCallHelpers::TimesFour, 4));
+            emitFunctionEpilogue(jit);
+            jit.ret();
+        });
+        uint32_t array[] = { 1, 2, 3, 4, 5, };
+        invoke<void>(test, array, 3, UINT32_MAX - 42);
+        CHECK_EQ(array[4], UINT32_MAX - 42);
+    }
+
+    // store16
+    {
+        auto test = compile([=](CCallHelpers& jit) {
+            emitFunctionPrologue(jit);
+            jit.store16(GPRInfo::argumentGPR2, CCallHelpers::BaseIndex(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, CCallHelpers::TimesTwo, -2));
+            emitFunctionEpilogue(jit);
+            jit.ret();
+        });
+        uint16_t array[] = { 1, 2, 3, 4, 5, };
+        invoke<void>(test, array, 3, UINT16_MAX - 42);
+        CHECK_EQ(array[2], UINT16_MAX - 42);
+    }
+    {
+        auto test = compile([=](CCallHelpers& jit) {
+            emitFunctionPrologue(jit);
+            jit.store16(GPRInfo::argumentGPR2, CCallHelpers::BaseIndex(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, CCallHelpers::TimesTwo, 2));
+            emitFunctionEpilogue(jit);
+            jit.ret();
+        });
+        uint16_t array[] = { 1, 2, 3, 4, static_cast<uint16_t>(-1), };
+        invoke<void>(test, array, 3, UINT16_MAX - 42);
+        CHECK_EQ(array[4], UINT16_MAX - 42);
+    }
+
+    // store8
+    {
+        auto test = compile([=](CCallHelpers& jit) {
+            emitFunctionPrologue(jit);
+            jit.store8(GPRInfo::argumentGPR2, CCallHelpers::BaseIndex(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, CCallHelpers::TimesOne, -1));
+            emitFunctionEpilogue(jit);
+            jit.ret();
+        });
+        uint8_t array[] = { 1, 2, 3, 4, 5, };
+        invoke<void>(test, array, 3, UINT8_MAX - 42);
+        CHECK_EQ(array[2], UINT8_MAX - 42);
+    }
+    {
+        auto test = compile([=](CCallHelpers& jit) {
+            emitFunctionPrologue(jit);
+            jit.store8(GPRInfo::argumentGPR2, CCallHelpers::BaseIndex(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, CCallHelpers::TimesOne, 1));
+            emitFunctionEpilogue(jit);
+            jit.ret();
+        });
+        uint8_t array[] = { 1, 2, 3, 4, static_cast<uint8_t>(-1), };
+        invoke<void>(test, array, 3, UINT8_MAX - 42);
+        CHECK_EQ(array[4], UINT8_MAX - 42);
+    }
+
+    // storeDouble
+    {
+        auto test = compile([=](CCallHelpers& jit) {
+            emitFunctionPrologue(jit);
+            jit.storeDouble(FPRInfo::argumentFPR0, CCallHelpers::BaseIndex(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, CCallHelpers::TimesEight, -8));
+            emitFunctionEpilogue(jit);
+            jit.ret();
+        });
+        double array[] = { 1, 2, 3, 4, 5, };
+        invoke<void>(test, array, static_cast<UCPURegister>(3), 42.0);
+        CHECK_EQ(array[2], 42.0);
+    }
+    {
+        auto test = compile([=](CCallHelpers& jit) {
+            emitFunctionPrologue(jit);
+            jit.storeDouble(FPRInfo::argumentFPR0, CCallHelpers::BaseIndex(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, CCallHelpers::TimesEight, 8));
+            emitFunctionEpilogue(jit);
+            jit.ret();
+        });
+        double array[] = { 1, 2, 3, 4, 5, };
+        invoke<void>(test, array, static_cast<UCPURegister>(3), 42.0);
+        CHECK_EQ(array[4], 42.0);
+    }
+
+    // storeFloat
+    {
+        auto test = compile([=](CCallHelpers& jit) {
+            emitFunctionPrologue(jit);
+            jit.storeFloat(FPRInfo::argumentFPR0, CCallHelpers::BaseIndex(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, CCallHelpers::TimesFour, -4));
+            emitFunctionEpilogue(jit);
+            jit.ret();
+        });
+        float array[] = { 1, 2, 3, 4, 5, };
+        invoke<void>(test, array, static_cast<UCPURegister>(3), 42.0f);
+        CHECK_EQ(array[2], 42.0f);
+    }
+    {
+        auto test = compile([=](CCallHelpers& jit) {
+            emitFunctionPrologue(jit);
+            jit.storeFloat(FPRInfo::argumentFPR0, CCallHelpers::BaseIndex(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, CCallHelpers::TimesFour, 4));
+            emitFunctionEpilogue(jit);
+            jit.ret();
+        });
+        float array[] = { 1, 2, 3, 4, 5, };
+        invoke<void>(test, array, static_cast<UCPURegister>(3), 42.0f);
+        CHECK_EQ(array[4], 42.0f);
+    }
+}
+
 static void testCagePreservesPACFailureBit()
 {
 #if GIGACAGE_ENABLED
@@ -4523,6 +4853,8 @@
     RUN(testByteSwap());
     RUN(testMoveDoubleConditionally32());
     RUN(testMoveDoubleConditionally64());
+    RUN(testLoadBaseIndex());
+    RUN(testStoreBaseIndex());
 
     RUN(testCagePreservesPACFailureBit());
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to