src/cpu/sparc/vm/assembler_sparc.cpp

changeset 1421
62001a362ce9
parent 1280
df6caf649ff7
child 1441
dcf03e02b020
     1.1 --- a/src/cpu/sparc/vm/assembler_sparc.cpp	Mon Sep 14 09:49:54 2009 -0700
     1.2 +++ b/src/cpu/sparc/vm/assembler_sparc.cpp	Mon Sep 14 12:14:20 2009 -0700
     1.3 @@ -4676,3 +4676,50 @@
     1.4      load_ptr_contents(base, G6_heapbase);
     1.5    }
     1.6  }
     1.7 +
     1.8 +// Compare char[] arrays aligned to 4 bytes.
     1.9 +void MacroAssembler::char_arrays_equals(Register ary1, Register ary2,
    1.10 +                                        Register limit, Register result,
    1.11 +                                        Register chr1, Register chr2, Label& Ldone) {
    1.12 +  Label Lvector, Lloop;
    1.13 +  assert(chr1 == result, "should be the same");
    1.14 +
    1.15 +  // Note: limit contains number of bytes (2*char_elements) != 0.
    1.16 +  andcc(limit, 0x2, chr1); // trailing character ?
    1.17 +  br(Assembler::zero, false, Assembler::pt, Lvector);
    1.18 +  delayed()->nop();
    1.19 +
    1.20 +  // compare the trailing char
    1.21 +  sub(limit, sizeof(jchar), limit);
    1.22 +  lduh(ary1, limit, chr1);
    1.23 +  lduh(ary2, limit, chr2);
    1.24 +  cmp(chr1, chr2);
    1.25 +  br(Assembler::notEqual, true, Assembler::pt, Ldone);
    1.26 +  delayed()->mov(G0, result);     // not equal
    1.27 +
    1.28 +  // only one char ?
    1.29 +  br_on_reg_cond(rc_z, true, Assembler::pn, limit, Ldone);
    1.30 +  delayed()->add(G0, 1, result); // zero-length arrays are equal
    1.31 +
    1.32 +  // word by word compare, dont't need alignment check
    1.33 +  bind(Lvector);
    1.34 +  // Shift ary1 and ary2 to the end of the arrays, negate limit
    1.35 +  add(ary1, limit, ary1);
    1.36 +  add(ary2, limit, ary2);
    1.37 +  neg(limit, limit);
    1.38 +
    1.39 +  lduw(ary1, limit, chr1);
    1.40 +  bind(Lloop);
    1.41 +  lduw(ary2, limit, chr2);
    1.42 +  cmp(chr1, chr2);
    1.43 +  br(Assembler::notEqual, true, Assembler::pt, Ldone);
    1.44 +  delayed()->mov(G0, result);     // not equal
    1.45 +  inccc(limit, 2*sizeof(jchar));
    1.46 +  // annul LDUW if branch is not taken to prevent access past end of array
    1.47 +  br(Assembler::notZero, true, Assembler::pt, Lloop);
    1.48 +  delayed()->lduw(ary1, limit, chr1); // hoisted
    1.49 +
    1.50 +  // Caller should set it:
    1.51 +  // add(G0, 1, result); // equals
    1.52 +}
    1.53 +

mercurial