Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (290906 => 290907)
--- trunk/Source/_javascript_Core/ChangeLog 2022-03-07 21:19:40 UTC (rev 290906)
+++ trunk/Source/_javascript_Core/ChangeLog 2022-03-07 21:55:08 UTC (rev 290907)
@@ -1,3 +1,30 @@
+2022-03-07 Angelos Oikonomopoulos <[email protected]>
+
+ 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):
+
2022-03-07 Zan Dobersek <[email protected]>
[JSC] Add missing CPU(RISCV64) guards in CTI thunk prologue, epilogue generators
Modified: trunk/Source/_javascript_Core/assembler/ARMv7Assembler.h (290906 => 290907)
--- trunk/Source/_javascript_Core/assembler/ARMv7Assembler.h 2022-03-07 21:19:40 UTC (rev 290906)
+++ trunk/Source/_javascript_Core/assembler/ARMv7Assembler.h 2022-03-07 21:55:08 UTC (rev 290907)
@@ -583,6 +583,8 @@
OP_CMP_reg_T2 = 0xEBB0,
OP_VMOV_CtoD = 0xEC00,
OP_VMOV_DtoC = 0xEC10,
+ OP_VSTMIA = 0xEC80,
+ OP_VLDMIA = 0xEC90,
OP_FSTS = 0xED00,
OP_VSTR = 0xED00,
OP_FLDS = 0xED10,
@@ -688,6 +690,8 @@
OP_VSQRT_T1b = 0x0A40,
OP_VCVTSD_T1b = 0x0A40,
OP_VCVTDS_T1b = 0x0A40,
+ OP_VSTMIAb = 0x0B00,
+ OP_VLDMIAb = 0x0B00,
OP_NOP_T2b = 0x8000,
OP_DMB_SY_T1b = 0x8F5F,
OP_DMB_ISHST_T1b = 0x8F5A,
@@ -1926,6 +1930,18 @@
}
#endif
+ void vldmia(RegisterID rn, FPDoubleRegisterID rs, uint32_t count)
+ {
+ ASSERT(count < 16);
+ m_formatter.vfpMemOp(OP_VLDMIA, OP_VLDMIAb, true, rn, rs, count << 3);
+ }
+
+ void vstmia(RegisterID rn, FPDoubleRegisterID rs, uint32_t count)
+ {
+ ASSERT(count < 16);
+ m_formatter.vfpMemOp(OP_VSTMIA, OP_VSTMIAb, true, rn, rs, count << 3);
+ }
+
void vand(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm)
{
m_formatter.vfpOp(OP_VAND_T1, OP_VAND_T1b, true, rn, rd, rm);
Modified: trunk/Source/_javascript_Core/assembler/CPU.h (290906 => 290907)
--- trunk/Source/_javascript_Core/assembler/CPU.h 2022-03-07 21:19:40 UTC (rev 290906)
+++ trunk/Source/_javascript_Core/assembler/CPU.h 2022-03-07 21:55:08 UTC (rev 290907)
@@ -42,6 +42,15 @@
#endif
}
+constexpr bool isARM()
+{
+#if CPU(ARM)
+ return true;
+#else
+ return false;
+#endif
+}
+
constexpr bool isARM64()
{
#if CPU(ARM64)
Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerARMv7.h (290906 => 290907)
--- trunk/Source/_javascript_Core/assembler/MacroAssemblerARMv7.h 2022-03-07 21:19:40 UTC (rev 290906)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerARMv7.h 2022-03-07 21:55:08 UTC (rev 290907)
@@ -934,6 +934,33 @@
loadPair32(Address(scratch, address.offset), dest1, dest2);
}
+ void loadPair64(RegisterID src, TrustedImm32 offset, FPRegisterID dest1, FPRegisterID dest2)
+ {
+ ASSERT(dest1 != dest2);
+ if ((dest2 == (dest1 + 1)) && !offset.m_value) {
+ // Only emit a VLDMIA if the registers happen to be consecutive and
+ // in the proper order and the offset happens to be zero. Otherwise,
+ // the extra instructions to adjust things mean there are no space
+ // savings and the VLDM itself might be a performance loss.
+ m_assembler.vldmia(src, dest1, 2);
+ } else {
+ loadDouble(Address(src, offset.m_value), dest1);
+ loadDouble(Address(src, offset.m_value + 8), dest2);
+ }
+ }
+
+ void storePair64(FPRegisterID src1, FPRegisterID src2, RegisterID dest, TrustedImm32 offset)
+ {
+ if ((src2 == (src1 + 1)) && !offset.m_value) {
+ // Only emit a VSTMIA under a narrow set of conditions. See
+ // loadPair64 for the rationale.
+ m_assembler.vstmia(dest, src1, 2);
+ } else {
+ storeDouble(src1, Address(dest, offset.m_value));
+ storeDouble(src2, Address(dest, offset.m_value + 8));
+ }
+ }
+
void store32(RegisterID src, Address address)
{
store32(src, setupArmAddress(address));
Modified: trunk/Source/_javascript_Core/jit/AssemblyHelpers.cpp (290906 => 290907)
--- trunk/Source/_javascript_Core/jit/AssemblyHelpers.cpp 2022-03-07 21:19:40 UTC (rev 290906)
+++ trunk/Source/_javascript_Core/jit/AssemblyHelpers.cpp 2022-03-07 21:55:08 UTC (rev 290907)
@@ -1289,8 +1289,8 @@
GPRReg destBufferGPR = usedRegisters.getFreeGPR(0);
GPRReg temp1 = usedRegisters.getFreeGPR(1);
FPRReg fpTemp1 = usedRegisters.getFreeFPR(0);
- GPRReg temp2 = isARM64() ? usedRegisters.getFreeGPR(2) : InvalidGPRReg;
- FPRReg fpTemp2 = isARM64() ? usedRegisters.getFreeFPR(1) : InvalidFPRReg;
+ GPRReg temp2 = usedRegisters.getFreeGPR(2);
+ FPRReg fpTemp2 = usedRegisters.getFreeFPR(1);
loadPtr(&topEntryFrame, destBufferGPR);
addPtr(TrustedImm32(EntryFrame::calleeSaveRegistersBufferOffset()), destBufferGPR);
Modified: trunk/Source/_javascript_Core/jit/AssemblyHelpersSpoolers.h (290906 => 290907)
--- trunk/Source/_javascript_Core/jit/AssemblyHelpersSpoolers.h 2022-03-07 21:19:40 UTC (rev 290906)
+++ trunk/Source/_javascript_Core/jit/AssemblyHelpersSpoolers.h 2022-03-07 21:55:08 UTC (rev 290907)
@@ -136,11 +136,7 @@
}
private:
-#if CPU(ARM64)
- static constexpr bool hasPairOp = true;
-#else
- static constexpr bool hasPairOp = false;
-#endif
+ static constexpr bool hasPairOp = isARM() || isARM64();
Op& op() { return *reinterpret_cast<Op*>(this); }
@@ -164,12 +160,19 @@
ALWAYS_INLINE void finalizeFPR() { finalize<FPRReg>(); }
private:
-#if CPU(ARM64)
- template<typename RegType>
- ALWAYS_INLINE void executePair(ptrdiff_t offset, RegType reg1, RegType reg2)
+#if CPU(ARM64) || CPU(ARM)
+ ALWAYS_INLINE void executePair(ptrdiff_t offset, GPRReg reg1, GPRReg reg2)
{
+#if USE(JSVALUE64)
m_jit.loadPair64(m_baseGPR, TrustedImm32(offset), reg1, reg2);
+#else
+ m_jit.loadPair32(m_baseGPR, TrustedImm32(offset), reg1, reg2);
+#endif
}
+ ALWAYS_INLINE void executePair(ptrdiff_t offset, FPRReg reg1, FPRReg reg2)
+ {
+ m_jit.loadPair64(m_baseGPR, TrustedImm32(offset), reg1, reg2);
+ }
#else
template<typename RegType>
ALWAYS_INLINE void executePair(ptrdiff_t, RegType, RegType) { }
@@ -206,12 +209,19 @@
ALWAYS_INLINE void finalizeFPR() { finalize<FPRReg>(); }
private:
-#if CPU(ARM64)
- template<typename RegType>
- ALWAYS_INLINE void executePair(ptrdiff_t offset, RegType reg1, RegType reg2)
+#if CPU(ARM64) || CPU(ARM)
+ ALWAYS_INLINE void executePair(ptrdiff_t offset, GPRReg reg1, GPRReg reg2)
{
+#if USE(JSVALUE64)
m_jit.storePair64(reg1, reg2, m_baseGPR, TrustedImm32(offset));
+#else
+ m_jit.storePair32(reg1, reg2, m_baseGPR, TrustedImm32(offset));
+#endif
}
+ ALWAYS_INLINE void executePair(ptrdiff_t offset, FPRReg reg1, FPRReg reg2)
+ {
+ m_jit.storePair64(reg1, reg2, m_baseGPR, TrustedImm32(offset));
+ }
#else
template<typename RegType>
ALWAYS_INLINE void executePair(ptrdiff_t, RegType, RegType) { }
@@ -263,8 +273,8 @@
, m_temp1FPR(fpTemp1)
, m_temp2FPR(fpTemp2)
, m_bufferRegsAttr(attribute)
- {
- if constexpr (hasPairOp && !isARM64())
+ {
+ if constexpr (hasPairOp && !(isARM() || isARM64()))
RELEASE_ASSERT_NOT_REACHED(); // unsupported architecture.
}
@@ -522,19 +532,35 @@
m_jit.storeDouble(src, Address(m_dstBufferGPR, offset));
}
-#if CPU(ARM64)
- template<typename RegType>
- ALWAYS_INLINE void loadPair(int offset, RegType dest1, RegType dest2)
+#if CPU(ARM64) || CPU(ARM)
+ ALWAYS_INLINE void loadPair(int offset, GPRReg dest1, GPRReg dest2)
{
+#if USE(JSVALUE64)
m_jit.loadPair64(m_srcBufferGPR, TrustedImm32(offset), dest1, dest2);
+#else
+ m_jit.loadPair32(m_srcBufferGPR, TrustedImm32(offset), dest1, dest2);
+#endif
}
- template<typename RegType>
- ALWAYS_INLINE void storePair(RegType src1, RegType src2, int offset)
+ ALWAYS_INLINE void loadPair(int offset, FPRReg dest1, FPRReg dest2)
{
+ m_jit.loadPair64(m_srcBufferGPR, TrustedImm32(offset), dest1, dest2);
+ }
+
+ ALWAYS_INLINE void storePair(GPRReg src1, GPRReg src2, int offset)
+ {
+#if USE(JSVALUE64)
m_jit.storePair64(src1, src2, m_dstBufferGPR, TrustedImm32(offset));
+#else
+ m_jit.storePair32(src1, src2, m_dstBufferGPR, TrustedImm32(offset));
+#endif
}
+ ALWAYS_INLINE void storePair(FPRReg src1, FPRReg src2, int offset)
+ {
+ m_jit.storePair64(src1, src2, m_dstBufferGPR, TrustedImm32(offset));
+ }
+
static constexpr bool hasPairOp = true;
#else
template<typename RegType> ALWAYS_INLINE void loadPair(int, RegType, RegType) { }