8149100: AArch64: "bad AD file" for LL enconding AryEq Node matching
authorhshi
Sat, 06 Feb 2016 04:09:47 -0800
changeset 35842 1d34635308b0
parent 35841 39f8dc1df42b
child 35843 67b6050f5ce8
8149100: AArch64: "bad AD file" for LL enconding AryEq Node matching Summary: add byte array equal support for aarch64 Reviewed-by: aph
hotspot/src/cpu/aarch64/vm/aarch64.ad
hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp
hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp
--- 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,