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());