src/cpu/sparc/vm/stubGenerator_sparc.cpp

changeset 2149
065dd1ca3ab6
parent 2137
f353275af40e
child 2199
75588558f1bf
     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  

mercurial