1.1 --- a/src/cpu/sparc/vm/stubGenerator_sparc.cpp Mon Sep 13 23:24:30 2010 -0700 1.2 +++ b/src/cpu/sparc/vm/stubGenerator_sparc.cpp Tue Sep 14 14:09:24 2010 -0700 1.3 @@ -1609,7 +1609,7 @@ 1.4 assert_clean_int(count, O3); // Make sure 'count' is clean int. 1.5 1.6 Label L_exit, L_skip_align1, L_skip_align2, L_fill_byte; 1.7 - Label L_fill_2_bytes, L_fill_4_bytes, L_fill_32_bytes; 1.8 + Label L_fill_2_bytes, L_fill_elements, L_fill_32_bytes; 1.9 1.10 int shift = -1; 1.11 switch (t) { 1.12 @@ -1635,8 +1635,8 @@ 1.13 } 1.14 if (t == T_SHORT) { 1.15 // Zero extend value 1.16 - __ sethi(0xffff0000, O3); 1.17 - __ andn(value, O3, value); 1.18 + __ sllx(value, 48, value); 1.19 + __ srlx(value, 48, value); 1.20 } 1.21 if (t == T_BYTE || t == T_SHORT) { 1.22 __ sllx(value, 16, O3); 1.23 @@ -1644,8 +1644,8 @@ 1.24 } 1.25 1.26 __ cmp(count, 2<<shift); // Short arrays (< 8 bytes) fill by element 1.27 - __ brx(Assembler::lessUnsigned, false, Assembler::pn, L_fill_4_bytes); // use unsigned cmp 1.28 - __ delayed()->andcc(count, 1<<shift, G0); 1.29 + __ brx(Assembler::lessUnsigned, false, Assembler::pn, L_fill_elements); // use unsigned cmp 1.30 + __ delayed()->andcc(count, 1, G0); 1.31 1.32 if (!aligned && (t == T_BYTE || t == T_SHORT)) { 1.33 // align source address at 4 bytes address boundary 1.34 @@ -1698,7 +1698,7 @@ 1.35 __ brx(Assembler::less, false, Assembler::pt, L_check_fill_8_bytes); 1.36 __ delayed()->nop(); 1.37 1.38 - Label L_fill_32_bytes_loop; 1.39 + Label L_fill_32_bytes_loop, L_fill_4_bytes; 1.40 __ align(16); 1.41 __ BIND(L_fill_32_bytes_loop); 1.42 1.43 @@ -1730,6 +1730,9 @@ 1.44 1.45 // fill trailing 4 bytes 1.46 __ andcc(count, 1<<shift, G0); // in delay slot of branches 1.47 + if (t == T_INT) { 1.48 + __ BIND(L_fill_elements); 1.49 + } 1.50 __ BIND(L_fill_4_bytes); 1.51 __ brx(Assembler::zero, false, Assembler::pt, L_fill_2_bytes); 1.52 if (t == T_BYTE || t == T_SHORT) { 1.53 @@ -1762,7 +1765,48 @@ 1.54 } 1.55 __ BIND(L_exit); 1.56 __ retl(); 1.57 - __ delayed()->mov(G0, O0); // return 0 1.58 + __ delayed()->nop(); 1.59 + 1.60 + // Handle copies less than 8 bytes. Int is handled elsewhere. 1.61 + if (t == T_BYTE) { 1.62 + __ BIND(L_fill_elements); 1.63 + Label L_fill_2, L_fill_4; 1.64 + // in delay slot __ andcc(count, 1, G0); 1.65 + __ brx(Assembler::zero, false, Assembler::pt, L_fill_2); 1.66 + __ delayed()->andcc(count, 2, G0); 1.67 + __ stb(value, to, 0); 1.68 + __ inc(to, 1); 1.69 + __ BIND(L_fill_2); 1.70 + __ brx(Assembler::zero, false, Assembler::pt, L_fill_4); 1.71 + __ delayed()->andcc(count, 4, G0); 1.72 + __ stb(value, to, 0); 1.73 + __ stb(value, to, 1); 1.74 + __ inc(to, 2); 1.75 + __ BIND(L_fill_4); 1.76 + __ brx(Assembler::zero, false, Assembler::pt, L_exit); 1.77 + __ delayed()->nop(); 1.78 + __ stb(value, to, 0); 1.79 + __ stb(value, to, 1); 1.80 + __ stb(value, to, 2); 1.81 + __ retl(); 1.82 + __ delayed()->stb(value, to, 3); 1.83 + } 1.84 + 1.85 + if (t == T_SHORT) { 1.86 + Label L_fill_2; 1.87 + __ BIND(L_fill_elements); 1.88 + // in delay slot __ andcc(count, 1, G0); 1.89 + __ brx(Assembler::zero, false, Assembler::pt, L_fill_2); 1.90 + __ delayed()->andcc(count, 2, G0); 1.91 + __ sth(value, to, 0); 1.92 + __ inc(to, 2); 1.93 + __ BIND(L_fill_2); 1.94 + __ brx(Assembler::zero, false, Assembler::pt, L_exit); 1.95 + __ delayed()->nop(); 1.96 + __ sth(value, to, 0); 1.97 + __ retl(); 1.98 + __ delayed()->sth(value, to, 2); 1.99 + } 1.100 return start; 1.101 } 1.102