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