Skip to content

Commit

Permalink
Add RealFYang patch
Browse files Browse the repository at this point in the history
  • Loading branch information
zifeihan committed Mar 15, 2024
1 parent 07acc0b commit 799b44e
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 45 deletions.
124 changes: 80 additions & 44 deletions src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1536,74 +1536,110 @@ void C2_MacroAssembler::string_compare(Register str1, Register str2,
BLOCK_COMMENT("} string_compare");
}

void C2_MacroAssembler::arrays_equals(Register a1, Register a2, Register tmp3,
Register tmp4, Register tmp5, Register tmp6, Register result,
void C2_MacroAssembler::arrays_equals(Register a1, Register a2, Register tmp1,
Register tmp2, Register tmp3, Register tmp4, Register result,
Register cnt1, int elem_size) {
Label DONE, SAME, NEXT_DWORD, SHORT, TAIL, TAIL2, IS_TMP5_ZR;
Register tmp1 = t0;
Register tmp2 = t1;
Register cnt2 = tmp2; // cnt2 only used in array length compare
Register elem_per_word = tmp6;
Label DONE, SAME;
Label NEXT_16BYTE, TAIL_1BYTE, TAIL_2BYTE, TAIL_4BYTE, TAIL_8BYTE;

int elem_per_word = wordSize/elem_size;
int log_elem_size = exact_log2(elem_size);
int length_offset = arrayOopDesc::length_offset_in_bytes();
int base_offset = arrayOopDesc::base_offset_in_bytes(elem_size == 2 ? T_CHAR : T_BYTE);

assert(elem_size == 1 || elem_size == 2, "must be char or byte");
assert_different_registers(a1, a2, result, cnt1, t0, t1, tmp3, tmp4, tmp5, tmp6);
mv(elem_per_word, wordSize / elem_size);
assert_different_registers(a1, a2, result, cnt1, t0, t1, tmp1, tmp2, tmp3, tmp4);

BLOCK_COMMENT("arrays_equals {");

// if (a1 == a2), return true
beq(a1, a2, SAME);

mv(result, false);
// if (a1 == nullptr || a2 == nullptr)
// return false;
beqz(a1, DONE);
beqz(a2, DONE);

// if (a1.length != a2.length)
// return false;
Register cnt2 = tmp1; // cnt2 only used in array length compare
lwu(cnt1, Address(a1, length_offset));
lwu(cnt2, Address(a2, length_offset));
bne(cnt2, cnt1, DONE);
bne(cnt1, cnt2, DONE);

// if (a1.length == 0)
// return true;
beqz(cnt1, SAME);

slli(tmp5, cnt1, 3 + log_elem_size);
sub(tmp5, zr, tmp5);
add(a1, a1, base_offset);
add(a2, a2, base_offset);
ld(tmp3, Address(a1, 0));
ld(tmp4, Address(a2, 0));
ble(cnt1, elem_per_word, SHORT); // short or same

// Main 16 byte comparison loop with 2 exits
bind(NEXT_DWORD); {
ld(tmp1, Address(a1, wordSize));
ld(tmp2, Address(a2, wordSize));
sub(cnt1, cnt1, 2 * wordSize / elem_size);
blez(cnt1, TAIL);
la(a1, Address(a1, base_offset));
la(a2, Address(a2, base_offset));
// Check for short strings, i.e. smaller than 16 bytes.
mv(t1, elem_per_word * 2);
blt(cnt1, t1, TAIL_8BYTE);

if (AvoidUnalignedAccesses) {
// TODO: Add code to make sure a1 and a2 are 8-byte aligned.
}

// Main 16-byte comparison loop.
bind(NEXT_16BYTE); {
ld(tmp1, Address(a1, 0));
ld(tmp2, Address(a2, 0));
ld(tmp3, Address(a1, wordSize));
ld(tmp4, Address(a2, wordSize));
addi(a1, a1, 2 * wordSize);
addi(a2, a2, 2 * wordSize);
addi(cnt1, cnt1, -elem_per_word * 2);
bne(tmp1, tmp2, DONE);
bne(tmp3, tmp4, DONE);
ld(tmp3, Address(a1, 2 * wordSize));
ld(tmp4, Address(a2, 2 * wordSize));
add(a1, a1, 2 * wordSize);
add(a2, a2, 2 * wordSize);
ble(cnt1, elem_per_word, TAIL2);
} beq(tmp1, tmp2, NEXT_DWORD);
j(DONE);
} bge(cnt1, t1, NEXT_16BYTE);

bind(TAIL);
xorr(tmp4, tmp3, tmp4);
xorr(tmp2, tmp1, tmp2);
sll(tmp2, tmp2, tmp5);
orr(tmp5, tmp4, tmp2);
j(IS_TMP5_ZR);
beqz(cnt1, SAME);

bind(TAIL2);
bne(tmp1, tmp2, DONE);
bind(TAIL_8BYTE);
test_bit(tmp1, cnt1, 3 - log_elem_size);
beqz(tmp1, TAIL_4BYTE); // 0-15 bytes left.
{
ld(tmp1, Address(a1));
ld(tmp2, Address(a2));
addi(a1, a1, 8);
addi(a2, a2, 8);
bne(tmp1, tmp2, DONE);
}

bind(SHORT);
xorr(tmp4, tmp3, tmp4);
sll(tmp5, tmp4, tmp5);
bind(TAIL_4BYTE);
test_bit(tmp1, cnt1, 2 - log_elem_size);
beqz(tmp1, TAIL_2BYTE); // 0-7 bytes left.
{
lwu(tmp1, Address(a1));
lwu(tmp2, Address(a2));
addi(a1, a1, 4);
addi(a2, a2, 4);
bne(tmp1, tmp2, DONE);
}

bind(IS_TMP5_ZR);
bnez(tmp5, DONE);
bind(TAIL_2BYTE);
test_bit(tmp3, cnt1, 1 - log_elem_size);
beqz(tmp1, TAIL_1BYTE); // 0-3 bytes left.
{
lhu(tmp3, Address(a1));
lhu(tmp4, Address(a2));
addi(a1, a1, 2);
addi(a2, a2, 2);
bne(tmp3, tmp4, DONE);
}

bind(TAIL_1BYTE);
if (elem_size == 1) { // Only needed when comparing byte arrays.
test_bit(tmp1, cnt1, 0);
beqz(tmp1, SAME); // 0-1 bytes left.
{
lbu(tmp1, a1);
lbu(tmp2, a2);
bne(tmp1, tmp2, DONE);
}
}

bind(SAME);
mv(result, true);
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@
int needle_con_cnt, Register result, int ae);

void arrays_equals(Register r1, Register r2,
Register tmp1, Register tmp2,
Register tmp3, Register tmp4,
Register tmp5, Register tmp6,
Register result, Register cnt1,
int elem_size);

Expand Down

0 comments on commit 799b44e

Please sign in to comment.