@@ -5484,29 +5484,38 @@ void MacroAssembler::multiply_to_len(Register x, Register xlen, Register y, Regi
54845484 const Register jdx = tmp1;
54855485
54865486 if (AvoidUnalignedAccesses) {
5487- // Check if x and y are both 8-byte aligned.
5488- orr (t0, xlen, ylen);
5489- test_bit (t0, t0, 0 );
5490- beqz (t0, L_multiply_64_x_64_loop);
5487+ int base_offset = arrayOopDesc::base_offset_in_bytes (T_INT);
5488+ assert ((base_offset % (UseCompactObjectHeaders ? 4 :
5489+ (UseCompressedClassPointers ? 8 : 4 ))) == 0 , " Must be" );
5490+
5491+ if ((base_offset % 8 ) == 0 ) {
5492+ // multiply_64_x_64_loop emits 8-byte load/store to access two elements
5493+ // at a time from int arrays x and y. When base_offset is 8 bytes, these
5494+ // accesses are naturally aligned if both xlen and ylen are even numbers.
5495+ orr (t0, xlen, ylen);
5496+ test_bit (t0, t0, 0 );
5497+ beqz (t0, L_multiply_64_x_64_loop);
5498+ }
5499+
5500+ Label L_second_loop_unaligned, L_third_loop, L_third_loop_exit;
54915501
54925502 multiply_32_x_32_loop (x, xstart, x_xstart, y, y_idx, z, carry, product, idx, kdx);
54935503 shadd (t0, xstart, z, t0, LogBytesPerInt);
54945504 sw (carry, Address (t0, 0 ));
54955505
5496- Label L_second_loop_unaligned;
54975506 bind (L_second_loop_unaligned);
54985507 mv (carry, zr);
54995508 mv (jdx, ylen);
55005509 subiw (xstart, xstart, 1 );
55015510 bltz (xstart, L_done);
5511+
55025512 subi (sp, sp, 2 * wordSize);
55035513 sd (z, Address (sp, 0 ));
55045514 sd (zr, Address (sp, wordSize));
55055515 shadd (t0, xstart, z, t0, LogBytesPerInt);
55065516 addi (z, t0, 4 );
55075517 shadd (t0, xstart, x, t0, LogBytesPerInt);
55085518 lwu (product, Address (t0, 0 ));
5509- Label L_third_loop, L_third_loop_exit;
55105519
55115520 blez (jdx, L_third_loop_exit);
55125521
0 commit comments