copy_sparc.hpp revision 1491:2d127394260e
119370Spst/*
298948Sobrien * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
3130809Smarcel * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
498948Sobrien *
519370Spst * This code is free software; you can redistribute it and/or modify it
619370Spst * under the terms of the GNU General Public License version 2 only, as
798948Sobrien * published by the Free Software Foundation.
819370Spst *
998948Sobrien * This code is distributed in the hope that it will be useful, but WITHOUT
1098948Sobrien * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1198948Sobrien * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1298948Sobrien * version 2 for more details (a copy is included in the LICENSE file that
1319370Spst * accompanied this code).
1498948Sobrien *
1598948Sobrien * You should have received a copy of the GNU General Public License version
1698948Sobrien * 2 along with this work; if not, write to the Free Software Foundation,
1798948Sobrien * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1819370Spst *
1998948Sobrien * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
2098948Sobrien * CA 95054 USA or visit www.sun.com if you need additional information or
2198948Sobrien * have any questions.
2298948Sobrien *
2319370Spst */
2419370Spst
2519370Spst// Inline functions for memory copy and fill.
2619370Spst
2746283Sdfrstatic void pd_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
2819370Spst  (void)memmove(to, from, count * HeapWordSize);
2919370Spst}
3019370Spst
31130809Smarcelstatic void pd_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
3219370Spst  switch (count) {
3319370Spst  case 8:  to[7] = from[7];
3419370Spst  case 7:  to[6] = from[6];
3519370Spst  case 6:  to[5] = from[5];
3619370Spst  case 5:  to[4] = from[4];
3719370Spst  case 4:  to[3] = from[3];
3819370Spst  case 3:  to[2] = from[2];
3919370Spst  case 2:  to[1] = from[1];
4019370Spst  case 1:  to[0] = from[0];
4119370Spst  case 0:  break;
4219370Spst  default: (void)memcpy(to, from, count * HeapWordSize);
4319370Spst           break;
4498948Sobrien  }
45130809Smarcel}
46130809Smarcel
4719370Spststatic void pd_disjoint_words_atomic(HeapWord* from, HeapWord* to, size_t count) {
48130809Smarcel  switch (count) {
49130809Smarcel  case 8:  to[7] = from[7];
5098948Sobrien  case 7:  to[6] = from[6];
5119370Spst  case 6:  to[5] = from[5];
5298948Sobrien  case 5:  to[4] = from[4];
5398948Sobrien  case 4:  to[3] = from[3];
5498948Sobrien  case 3:  to[2] = from[2];
5598948Sobrien  case 2:  to[1] = from[1];
5619370Spst  case 1:  to[0] = from[0];
5798948Sobrien  case 0:  break;
5898948Sobrien  default: while (count-- > 0) {
5998948Sobrien             *to++ = *from++;
6098948Sobrien           }
6198948Sobrien           break;
6298948Sobrien  }
6398948Sobrien}
6419370Spst
6519370Spststatic void pd_aligned_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
6619370Spst  (void)memmove(to, from, count * HeapWordSize);
6719370Spst}
6819370Spst
6919370Spststatic void pd_aligned_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
7019370Spst  pd_disjoint_words(from, to, count);
7119370Spst}
7219370Spst
7319370Spststatic void pd_conjoint_bytes(void* from, void* to, size_t count) {
7419370Spst  (void)memmove(to, from, count);
7519370Spst}
7619370Spst
7719370Spststatic void pd_conjoint_bytes_atomic(void* from, void* to, size_t count) {
7819370Spst  (void)memmove(to, from, count);
7919370Spst}
8019370Spst
8119370Spststatic void pd_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) {
8219370Spst  // FIXME
8319370Spst  (void)memmove(to, from, count << LogBytesPerShort);
8419370Spst}
8519370Spst
8619370Spststatic void pd_conjoint_jints_atomic(jint* from, jint* to, size_t count) {
8719370Spst  // FIXME
8819370Spst  (void)memmove(to, from, count << LogBytesPerInt);
8919370Spst}
9019370Spst
9119370Spststatic void pd_conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) {
9219370Spst#ifdef _LP64
9319370Spst  assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size");
9419370Spst  pd_conjoint_oops_atomic((oop*)from, (oop*)to, count);
9519370Spst#else
9619370Spst  // Guarantee use of ldd/std via some asm code, because compiler won't.
9719370Spst  // See solaris_sparc.il.
9819370Spst  _Copy_conjoint_jlongs_atomic(from, to, count);
9998948Sobrien#endif
10098948Sobrien}
10198948Sobrien
10298948Sobrienstatic void pd_conjoint_oops_atomic(oop* from, oop* to, size_t count) {
10319370Spst  // Do better than this: inline memmove body  NEEDS CLEANUP
10419370Spst  if (from > to) {
10519370Spst    while (count-- > 0) {
10619370Spst      // Copy forwards
10719370Spst      *to++ = *from++;
10898948Sobrien    }
10919370Spst  } else {
11019370Spst    from += count - 1;
11119370Spst    to   += count - 1;
11219370Spst    while (count-- > 0) {
11319370Spst      // Copy backwards
11498948Sobrien      *to-- = *from--;
11598948Sobrien    }
11698948Sobrien  }
11719370Spst}
11846283Sdfr
11946283Sdfrstatic void pd_arrayof_conjoint_bytes(HeapWord* from, HeapWord* to, size_t count) {
12046283Sdfr  pd_conjoint_bytes_atomic(from, to, count);
12146283Sdfr}
12219370Spst
12319370Spststatic void pd_arrayof_conjoint_jshorts(HeapWord* from, HeapWord* to, size_t count) {
12419370Spst  pd_conjoint_jshorts_atomic((jshort*)from, (jshort*)to, count);
12519370Spst}
12619370Spst
12719370Spststatic void pd_arrayof_conjoint_jints(HeapWord* from, HeapWord* to, size_t count) {
12819370Spst  pd_conjoint_jints_atomic((jint*)from, (jint*)to, count);
12998948Sobrien}
13098948Sobrien
13198948Sobrienstatic void pd_arrayof_conjoint_jlongs(HeapWord* from, HeapWord* to, size_t count) {
13298948Sobrien  pd_conjoint_jlongs_atomic((jlong*)from, (jlong*)to, count);
13398948Sobrien}
13498948Sobrien
13598948Sobrienstatic void pd_arrayof_conjoint_oops(HeapWord* from, HeapWord* to, size_t count) {
13698948Sobrien  pd_conjoint_oops_atomic((oop*)from, (oop*)to, count);
13798948Sobrien}
13898948Sobrien
13919370Spststatic void pd_fill_to_words(HeapWord* tohw, size_t count, juint value) {
14098948Sobrien#ifdef _LP64
14119370Spst  guarantee(mask_bits((uintptr_t)tohw, right_n_bits(LogBytesPerLong)) == 0,
14298948Sobrien         "unaligned fill words");
14319370Spst  julong* to = (julong*)tohw;
14498948Sobrien  julong  v  = ((julong)value << 32) | value;
14598948Sobrien  while (count-- > 0) {
14619370Spst    *to++ = v;
14798948Sobrien  }
14898948Sobrien#else // _LP64
14919370Spst  juint* to = (juint*)tohw;
15098948Sobrien  while (count-- > 0) {
15198948Sobrien    *to++ = value;
15298948Sobrien  }
15319370Spst#endif // _LP64
15498948Sobrien}
15519370Spst
15698948Sobrienstatic void pd_fill_to_aligned_words(HeapWord* tohw, size_t count, juint value) {
15798948Sobrien  assert(MinObjAlignmentInBytes >= BytesPerLong, "need alternate implementation");
15898948Sobrien
15919370Spst   julong* to = (julong*)tohw;
16098948Sobrien   julong  v  = ((julong)value << 32) | value;
16119370Spst   // If count is odd, odd will be equal to 1 on 32-bit platform
16298948Sobrien   // and be equal to 0 on 64-bit platform.
16319370Spst   size_t odd = count % (BytesPerLong / HeapWordSize) ;
16498948Sobrien
16519370Spst   size_t aligned_count = align_object_offset(count - odd) / HeapWordsPerLong;
16698948Sobrien   julong* end = ((julong*)tohw) + aligned_count - 1;
16719370Spst   while (to <= end) {
16898948Sobrien     DEBUG_ONLY(count -= BytesPerLong / HeapWordSize ;)
16919370Spst     *to++ = v;
17098948Sobrien   }
17119370Spst   assert(count == odd, "bad bounds on loop filling to aligned words");
17298948Sobrien   if (odd) {
17319370Spst     *((juint*)to) = value;
17498948Sobrien
17519370Spst   }
17698948Sobrien}
17719370Spst
17898948Sobrienstatic void pd_fill_to_bytes(void* to, size_t count, jubyte value) {
17919370Spst  (void)memset(to, value, count);
18098948Sobrien}
18198948Sobrien
18219370Spststatic void pd_zero_to_words(HeapWord* tohw, size_t count) {
18398948Sobrien  pd_fill_to_words(tohw, count, 0);
18419370Spst}
18519370Spst
18619370Spststatic void pd_zero_to_bytes(void* to, size_t count) {
18719370Spst  (void)memset(to, 0, count);
18819370Spst}
18919370Spst