8149100: AArch64: "bad AD file" for LL enconding AryEq Node matching
Summary: add byte array equal support for aarch64
Reviewed-by: aph
--- a/hotspot/src/cpu/aarch64/vm/aarch64.ad Mon Feb 08 14:14:35 2016 +0000
+++ b/hotspot/src/cpu/aarch64/vm/aarch64.ad Sat Feb 06 04:09:47 2016 -0800
@@ -14928,7 +14928,22 @@
ins_pipe(pipe_class_memory);
%}
-instruct array_equals(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result,
+instruct array_equalsB(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result,
+ iRegP_R10 tmp, rFlagsReg cr)
+%{
+ predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL);
+ match(Set result (AryEq ary1 ary2));
+ effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, KILL cr);
+
+ format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %}
+ ins_encode %{
+ __ byte_arrays_equals($ary1$$Register, $ary2$$Register,
+ $result$$Register, $tmp$$Register);
+ %}
+ ins_pipe(pipe_class_memory);
+%}
+
+instruct array_equalsC(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result,
iRegP_R10 tmp, rFlagsReg cr)
%{
predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
--- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp Mon Feb 08 14:14:35 2016 +0000
+++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp Sat Feb 06 04:09:47 2016 -0800
@@ -4561,6 +4561,82 @@
BLOCK_COMMENT("} string_equals");
}
+
+void MacroAssembler::byte_arrays_equals(Register ary1, Register ary2,
+ Register result, Register tmp1)
+{
+ Register cnt1 = rscratch1;
+ Register cnt2 = rscratch2;
+ Register tmp2 = rscratch2;
+
+ Label SAME, DIFFER, NEXT, TAIL07, TAIL03, TAIL01;
+
+ int length_offset = arrayOopDesc::length_offset_in_bytes();
+ int base_offset = arrayOopDesc::base_offset_in_bytes(T_BYTE);
+
+ BLOCK_COMMENT("byte_arrays_equals {");
+
+ // different until proven equal
+ mov(result, false);
+
+ // same array?
+ cmp(ary1, ary2);
+ br(Assembler::EQ, SAME);
+
+ // ne if either null
+ cbz(ary1, DIFFER);
+ cbz(ary2, DIFFER);
+
+ // lengths ne?
+ ldrw(cnt1, Address(ary1, length_offset));
+ ldrw(cnt2, Address(ary2, length_offset));
+ cmp(cnt1, cnt2);
+ br(Assembler::NE, DIFFER);
+
+ lea(ary1, Address(ary1, base_offset));
+ lea(ary2, Address(ary2, base_offset));
+
+ subs(cnt1, cnt1, 8);
+ br(LT, TAIL07);
+
+ BIND(NEXT);
+ ldr(tmp1, Address(post(ary1, 8)));
+ ldr(tmp2, Address(post(ary2, 8)));
+ subs(cnt1, cnt1, 8);
+ eor(tmp1, tmp1, tmp2);
+ cbnz(tmp1, DIFFER);
+ br(GE, NEXT);
+
+ BIND(TAIL07); // 0-7 bytes left, cnt1 = #bytes left - 4
+ tst(cnt1, 0b100);
+ br(EQ, TAIL03);
+ ldrw(tmp1, Address(post(ary1, 4)));
+ ldrw(tmp2, Address(post(ary2, 4)));
+ cmp(tmp1, tmp2);
+ br(NE, DIFFER);
+
+ BIND(TAIL03); // 0-3 bytes left, cnt1 = #bytes left - 4
+ tst(cnt1, 0b10);
+ br(EQ, TAIL01);
+ ldrh(tmp1, Address(post(ary1, 2)));
+ ldrh(tmp2, Address(post(ary2, 2)));
+ cmp(tmp1, tmp2);
+ br(NE, DIFFER);
+ BIND(TAIL01); // 0-1 byte left
+ tst(cnt1, 0b01);
+ br(EQ, SAME);
+ ldrb(tmp1, ary1);
+ ldrb(tmp2, ary2);
+ cmp(tmp1, tmp2);
+ br(NE, DIFFER);
+
+ BIND(SAME);
+ mov(result, true);
+ BIND(DIFFER); // result already set
+
+ BLOCK_COMMENT("} byte_arrays_equals");
+}
+
// Compare char[] arrays aligned to 4 bytes
void MacroAssembler::char_arrays_equals(Register ary1, Register ary2,
Register result, Register tmp1)
--- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp Mon Feb 08 14:14:35 2016 +0000
+++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp Sat Feb 06 04:09:47 2016 -0800
@@ -1191,6 +1191,8 @@
Register tmp1);
void char_arrays_equals(Register ary1, Register ary2,
Register result, Register tmp1);
+ void byte_arrays_equals(Register ary1, Register ary2,
+ Register result, Register tmp1);
void encode_iso_array(Register src, Register dst,
Register len, Register result,
FloatRegister Vtmp1, FloatRegister Vtmp2,