1/*
2 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25#ifndef OS_CPU_WINDOWS_X86_VM_COPY_WINDOWS_X86_INLINE_HPP
26#define OS_CPU_WINDOWS_X86_VM_COPY_WINDOWS_X86_INLINE_HPP
27
28static void pd_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
29  (void)memmove(to, from, count * HeapWordSize);
30}
31
32static void pd_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
33#ifdef AMD64
34  switch (count) {
35  case 8:  to[7] = from[7];
36  case 7:  to[6] = from[6];
37  case 6:  to[5] = from[5];
38  case 5:  to[4] = from[4];
39  case 4:  to[3] = from[3];
40  case 3:  to[2] = from[2];
41  case 2:  to[1] = from[1];
42  case 1:  to[0] = from[0];
43  case 0:  break;
44  default:
45    (void)memcpy(to, from, count * HeapWordSize);
46    break;
47  }
48#else
49  (void)memcpy(to, from, count * HeapWordSize);
50#endif // AMD64
51}
52
53static void pd_disjoint_words_atomic(HeapWord* from, HeapWord* to, size_t count) {
54  switch (count) {
55  case 8:  to[7] = from[7];
56  case 7:  to[6] = from[6];
57  case 6:  to[5] = from[5];
58  case 5:  to[4] = from[4];
59  case 4:  to[3] = from[3];
60  case 3:  to[2] = from[2];
61  case 2:  to[1] = from[1];
62  case 1:  to[0] = from[0];
63  case 0:  break;
64  default: while (count-- > 0) {
65             *to++ = *from++;
66           }
67           break;
68  }
69}
70
71static void pd_aligned_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
72  (void)memmove(to, from, count * HeapWordSize);
73}
74
75static void pd_aligned_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
76  pd_disjoint_words(from, to, count);
77}
78
79static void pd_conjoint_bytes(void* from, void* to, size_t count) {
80  (void)memmove(to, from, count);
81}
82
83static void pd_conjoint_bytes_atomic(void* from, void* to, size_t count) {
84  pd_conjoint_bytes(from, to, count);
85}
86
87static void pd_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) {
88  if (from > to) {
89    while (count-- > 0) {
90      // Copy forwards
91      *to++ = *from++;
92    }
93  } else {
94    from += count - 1;
95    to   += count - 1;
96    while (count-- > 0) {
97      // Copy backwards
98      *to-- = *from--;
99    }
100  }
101}
102
103static void pd_conjoint_jints_atomic(jint* from, jint* to, size_t count) {
104  if (from > to) {
105    while (count-- > 0) {
106      // Copy forwards
107      *to++ = *from++;
108    }
109  } else {
110    from += count - 1;
111    to   += count - 1;
112    while (count-- > 0) {
113      // Copy backwards
114      *to-- = *from--;
115    }
116  }
117}
118
119static void pd_conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) {
120#ifdef AMD64
121  assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size");
122  pd_conjoint_oops_atomic((oop*)from, (oop*)to, count);
123#else
124  // Guarantee use of fild/fistp or xmm regs via some asm code, because compilers won't.
125  __asm {
126    mov    eax, from;
127    mov    edx, to;
128    mov    ecx, count;
129    cmp    eax, edx;
130    jbe    downtest;
131    jmp    uptest;
132  up:
133    fild   qword ptr [eax];
134    fistp  qword ptr [edx];
135    add    eax, 8;
136    add    edx, 8;
137  uptest:
138    sub    ecx, 1;
139    jge    up;
140    jmp    done;
141  down:
142    fild   qword ptr [eax][ecx*8];
143    fistp  qword ptr [edx][ecx*8];
144  downtest:
145    sub    ecx, 1;
146    jge    down;
147  done:;
148  }
149#endif // AMD64
150}
151
152static void pd_conjoint_oops_atomic(oop* from, oop* to, size_t count) {
153  // Do better than this: inline memmove body  NEEDS CLEANUP
154  if (from > to) {
155    while (count-- > 0) {
156      // Copy forwards
157      *to++ = *from++;
158    }
159  } else {
160    from += count - 1;
161    to   += count - 1;
162    while (count-- > 0) {
163      // Copy backwards
164      *to-- = *from--;
165    }
166  }
167}
168
169static void pd_arrayof_conjoint_bytes(HeapWord* from, HeapWord* to, size_t count) {
170#ifdef AMD64
171  pd_conjoint_bytes_atomic(from, to, count);
172#else
173  pd_conjoint_bytes(from, to, count);
174#endif // AMD64
175}
176
177static void pd_arrayof_conjoint_jshorts(HeapWord* from, HeapWord* to, size_t count) {
178  pd_conjoint_jshorts_atomic((jshort*)from, (jshort*)to, count);
179}
180
181static void pd_arrayof_conjoint_jints(HeapWord* from, HeapWord* to, size_t count) {
182  pd_conjoint_jints_atomic((jint*)from, (jint*)to, count);
183}
184
185static void pd_arrayof_conjoint_jlongs(HeapWord* from, HeapWord* to, size_t count) {
186  pd_conjoint_jlongs_atomic((jlong*)from, (jlong*)to, count);
187}
188
189static void pd_arrayof_conjoint_oops(HeapWord* from, HeapWord* to, size_t count) {
190  pd_conjoint_oops_atomic((oop*)from, (oop*)to, count);
191}
192
193#endif // OS_CPU_WINDOWS_X86_VM_COPY_WINDOWS_X86_INLINE_HPP
194