diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h index 08b15d9fc4b62..9bb3d5cfb6020 100644 --- a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h +++ b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h @@ -940,23 +940,32 @@ class MacroAssemblerARMv7 : public AbstractMacroAssembler { loadPair32(Address(scratch), dest1, dest2); } else { ASSERT(dest1 != dest2); // If it is the same, ldp becomes illegal instruction. - int32_t absOffset = address.u.offset; - if (absOffset < 0) - absOffset = -absOffset; - if (!(absOffset & ~0x3fc)) { - if ((dest1 == addressTempRegister) || (dest2 == addressTempRegister)) - invalidateCachedAddressTempRegister(); - if ((dest1 == dataTempRegister) || (dest2 == dataTempRegister)) - cachedDataTempRegister().invalidate(); - m_assembler.ldrd(dest1, dest2, address.base, address.u.offset, /* index: */ true, /* wback: */ false); - } else if (address.base == dest1) { + // Check if dest1 or dest2 aliases the base register to avoid UNPREDICTABLE ldrd behavior + if (address.base == dest1) { + // Load high word first to avoid clobbering base register ArmAddress highAddress(address.base, address.u.offset + 4); load32(highAddress, dest2); load32(address, dest1); - } else { + } else if (address.base == dest2) { + // Load low word first to avoid clobbering base register load32(address, dest1); ArmAddress highAddress(address.base, address.u.offset + 4); load32(highAddress, dest2); + } else { + int32_t absOffset = address.u.offset; + if (absOffset < 0) + absOffset = -absOffset; + if (!(absOffset & ~0x3fc)) { + if ((dest1 == addressTempRegister) || (dest2 == addressTempRegister)) + invalidateCachedAddressTempRegister(); + if ((dest1 == dataTempRegister) || (dest2 == dataTempRegister)) + cachedDataTempRegister().invalidate(); + m_assembler.ldrd(dest1, dest2, address.base, address.u.offset, /* index: */ true, /* wback: */ false); + } else { + load32(address, dest1); + ArmAddress highAddress(address.base, address.u.offset + 4); + load32(highAddress, dest2); + } } } }