diff mbox

JDK8: Add char_array_equals

Message ID 1406805523.15691.53.camel@localhost.localdomain
State New
Headers show

Commit Message

Edward Nevill July 31, 2014, 11:18 a.m. UTC
Hi,

This is the first of three patches. This one adds support for char_array_equals, the next two will add support for encodeISOArray and indexOf.

This has taken slightly longer than expected because I got sidetracked with other issues.

Also, I am on holiday tomorrow so it will be next week sometime before I can generate the other two patches.

All the best,
Ed.

--- CUT HERE ---
# HG changeset patch
# User Edward Nevill edward.nevill@linaro.org
# Date 1406805043 -3600
#      Thu Jul 31 12:10:43 2014 +0100
# Node ID a028c5a90df38cda792a68056923a0d5975e5837
# Parent  5e238903a8753fdca06994bec8b36363ae930664
Add char_array_equals intrinsic

Comments

Andrew Haley July 31, 2014, 11:35 a.m. UTC | #1
On 07/31/2014 12:18 PM, Edward Nevill wrote:
> This is the first of three patches. This one adds support for char_array_equals, the next two will add support for encodeISOArray and indexOf.

OK, thanks.

Andrew.
diff mbox

Patch

diff -r 5e238903a875 -r a028c5a90df3 src/cpu/aarch64/vm/aarch64.ad
--- a/src/cpu/aarch64/vm/aarch64.ad	Tue Jul 29 06:00:26 2014 -0400
+++ b/src/cpu/aarch64/vm/aarch64.ad	Thu Jul 31 12:10:43 2014 +0100
@@ -11677,6 +11677,20 @@ 
   ins_pipe(pipe_class_memory);
 %}
 
+instruct array_equals(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result,
+                      iRegP_R10 tmp, rFlagsReg cr)
+%{
+  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 %{
+    __ char_arrays_equals($ary1$$Register, $ary2$$Register,
+                          $result$$Register, $tmp$$Register);
+  %}
+  ins_pipe(pipe_class_memory);
+%}
+
 // ============================================================================
 // This name is KNOWN by the ADLC and cannot be changed.
 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type
diff -r 5e238903a875 -r a028c5a90df3 src/cpu/aarch64/vm/macroAssembler_aarch64.cpp
--- a/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Tue Jul 29 06:00:26 2014 -0400
+++ b/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Thu Jul 31 12:10:43 2014 +0100
@@ -3512,3 +3512,71 @@ 
 
   BLOCK_COMMENT("} string_equals");
 }
+
+// Compare char[] arrays aligned to 4 bytes
+void MacroAssembler::char_arrays_equals(Register ary1, Register ary2,
+                                        Register result, Register tmp1)
+{
+  Register cnt1 = rscratch1;
+  Register cnt2 = rscratch2;
+  Register tmp2 = rscratch2;
+
+  Label SAME, DIFFER, NEXT, TAIL03, TAIL01;
+
+  int length_offset  = arrayOopDesc::length_offset_in_bytes();
+  int base_offset    = arrayOopDesc::base_offset_in_bytes(T_CHAR);
+
+  BLOCK_COMMENT("char_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, 4);
+    br(LT, TAIL03);
+
+  BIND(NEXT);
+    ldr(tmp1, Address(post(ary1, 8)));
+    ldr(tmp2, Address(post(ary2, 8)));
+    subs(cnt1, cnt1, 4);
+    eor(tmp1, tmp1, tmp2);
+    cbnz(tmp1, DIFFER);
+    br(GE, NEXT);
+
+  BIND(TAIL03);  // 0-3 chars left, cnt1 = #chars left - 4
+    tst(cnt1, 0b10);
+    br(EQ, TAIL01);
+    ldrw(tmp1, Address(post(ary1, 4)));
+    ldrw(tmp2, Address(post(ary2, 4)));
+    cmp(tmp1, tmp2);
+    br(NE, DIFFER);
+  BIND(TAIL01);  // 0-1 chars left
+    tst(cnt1, 0b01);
+    br(EQ, SAME);
+    ldrh(tmp1, ary1);
+    ldrh(tmp2, ary2);
+    cmp(tmp1, tmp2);
+    br(NE, DIFFER);
+
+  BIND(SAME);
+    mov(result, true);
+  BIND(DIFFER);	// result already set
+  
+  BLOCK_COMMENT("} char_arrays_equals");
+}
diff -r 5e238903a875 -r a028c5a90df3 src/cpu/aarch64/vm/macroAssembler_aarch64.hpp
--- a/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp	Tue Jul 29 06:00:26 2014 -0400
+++ b/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp	Thu Jul 31 12:10:43 2014 +0100
@@ -1085,6 +1085,8 @@ 
   void string_equals(Register str1, Register str2,
 		     Register cnt, Register result,
 		     Register tmp1);
+  void char_arrays_equals(Register ary1, Register ary2,
+                          Register result, Register tmp1);
 };
 
 // Used by aarch64.ad to control code generation
--- CUT HERE ---