1#
2# Copyright (c) 2004, 2013, 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        # NOTE WELL!  The _Copy functions are called directly
26	# from server-compiler-generated code via CallLeafNoFP,
27	# which means that they *must* either not use floating
28	# point or use it in the same manner as does the server
29	# compiler.
30
31        .globl _Copy_conjoint_bytes
32        .globl _Copy_arrayof_conjoint_bytes
33        .globl _Copy_conjoint_jshorts_atomic
34	.globl _Copy_arrayof_conjoint_jshorts
35        .globl _Copy_conjoint_jints_atomic
36        .globl _Copy_arrayof_conjoint_jints
37	.globl _Copy_conjoint_jlongs_atomic
38	.globl _mmx_Copy_arrayof_conjoint_jshorts
39
40        .globl _Atomic_cmpxchg_long
41        .globl _Atomic_move_long
42
43	.text
44
45        .globl  SpinPause
46	.type   SpinPause,@function
47        .p2align 4,,15
48SpinPause:
49        rep
50        nop
51        movl    $1, %eax
52        ret
53
54        # Support for void Copy::conjoint_bytes(void* from,
55        #                                       void* to,
56        #                                       size_t count)
57        .p2align 4,,15
58	.type    _Copy_conjoint_bytes,@function
59_Copy_conjoint_bytes:
60        pushl    %esi
61        movl     4+12(%esp),%ecx      # count
62        pushl    %edi
63        movl     8+ 4(%esp),%esi      # from
64        movl     8+ 8(%esp),%edi      # to
65        cmpl     %esi,%edi
66        leal     -1(%esi,%ecx),%eax   # from + count - 1
67        jbe      cb_CopyRight
68        cmpl     %eax,%edi
69        jbe      cb_CopyLeft
70        # copy from low to high
71cb_CopyRight:
72        cmpl     $3,%ecx
73        jbe      5f                   # <= 3 bytes
74        # align source address at dword address boundary
75        movl     %ecx,%eax            # original count
76        movl     $4,%ecx
77        subl     %esi,%ecx
78        andl     $3,%ecx              # prefix byte count
79        jz       1f                   # no prefix
80        subl     %ecx,%eax            # byte count less prefix
81        # copy prefix
82        subl     %esi,%edi
830:      movb     (%esi),%dl
84        movb     %dl,(%edi,%esi,1)
85        addl     $1,%esi
86        subl     $1,%ecx
87        jnz      0b
88        addl     %esi,%edi
891:      movl     %eax,%ecx            # byte count less prefix
90        shrl     $2,%ecx              # dword count
91        jz       4f                   # no dwords to move
92        cmpl     $32,%ecx
93        jbe      2f                   # <= 32 dwords
94        # copy aligned dwords
95        rep;     smovl
96        jmp      4f
97        # copy aligned dwords
982:      subl     %esi,%edi
99        .p2align 4,,15
1003:      movl     (%esi),%edx
101        movl     %edx,(%edi,%esi,1)
102        addl     $4,%esi
103        subl     $1,%ecx
104        jnz      3b
105        addl     %esi,%edi
1064:      movl     %eax,%ecx            # byte count less prefix
1075:      andl     $3,%ecx              # suffix byte count
108        jz       7f                   # no suffix
109        # copy suffix
110        xorl     %eax,%eax
1116:      movb     (%esi,%eax,1),%dl
112        movb     %dl,(%edi,%eax,1)
113        addl     $1,%eax
114        subl     $1,%ecx
115        jnz      6b
1167:      popl     %edi
117        popl     %esi
118        ret
119        # copy from high to low
120cb_CopyLeft:
121        std
122        leal     -4(%edi,%ecx),%edi   # to + count - 4
123        movl     %eax,%esi            # from + count - 1
124        movl     %ecx,%eax
125        subl     $3,%esi              # from + count - 4
126        cmpl     $3,%ecx
127        jbe      5f                   # <= 3 bytes
1281:      shrl     $2,%ecx              # dword count
129        jz       4f                   # no dwords to move
130        cmpl     $32,%ecx
131        ja       3f                   # > 32 dwords
132        # copy dwords, aligned or not
133        subl     %esi,%edi
134        .p2align 4,,15
1352:      movl     (%esi),%edx
136        movl     %edx,(%edi,%esi,1)
137        subl     $4,%esi
138        subl     $1,%ecx
139        jnz      2b
140        addl     %esi,%edi
141        jmp      4f
142        # copy dwords, aligned or not
1433:      rep;     smovl
1444:      movl     %eax,%ecx            # byte count
1455:      andl     $3,%ecx              # suffix byte count
146        jz       7f                   # no suffix
147        # copy suffix
148        subl     %esi,%edi
149        addl     $3,%esi
1506:      movb     (%esi),%dl
151        movb     %dl,(%edi,%esi,1)
152	subl     $1,%esi
153        subl     $1,%ecx
154        jnz      6b
1557:      cld
156        popl     %edi
157        popl     %esi
158        ret
159
160        # Support for void Copy::arrayof_conjoint_bytes(void* from,
161        #                                               void* to,
162        #                                               size_t count)
163        #
164        # Same as _Copy_conjoint_bytes, except no source alignment check.
165        .p2align 4,,15
166	.type    _Copy_arrayof_conjoint_bytes,@function
167_Copy_arrayof_conjoint_bytes:
168        pushl    %esi
169        movl     4+12(%esp),%ecx      # count
170        pushl    %edi
171        movl     8+ 4(%esp),%esi      # from
172        movl     8+ 8(%esp),%edi      # to
173        cmpl     %esi,%edi
174        leal     -1(%esi,%ecx),%eax   # from + count - 1
175        jbe      acb_CopyRight
176        cmpl     %eax,%edi
177        jbe      acb_CopyLeft
178        # copy from low to high
179acb_CopyRight:
180        cmpl     $3,%ecx
181        jbe      5f
1821:      movl     %ecx,%eax
183        shrl     $2,%ecx
184        jz       4f
185        cmpl     $32,%ecx
186        ja       3f
187        # copy aligned dwords
188        subl     %esi,%edi
189        .p2align 4,,15
1902:      movl     (%esi),%edx
191        movl     %edx,(%edi,%esi,1)
192        addl     $4,%esi
193        subl     $1,%ecx
194        jnz      2b
195        addl     %esi,%edi
196        jmp      4f
197        # copy aligned dwords
1983:      rep;     smovl
1994:      movl     %eax,%ecx
2005:      andl     $3,%ecx
201        jz       7f
202        # copy suffix
203        xorl     %eax,%eax
2046:      movb     (%esi,%eax,1),%dl
205        movb     %dl,(%edi,%eax,1)
206        addl     $1,%eax
207        subl     $1,%ecx
208        jnz      6b
2097:      popl     %edi
210        popl     %esi
211        ret
212acb_CopyLeft:
213        std
214        leal     -4(%edi,%ecx),%edi   # to + count - 4
215        movl     %eax,%esi            # from + count - 1
216        movl     %ecx,%eax
217        subl     $3,%esi              # from + count - 4
218        cmpl     $3,%ecx
219        jbe      5f
2201:      shrl     $2,%ecx
221        jz       4f
222        cmpl     $32,%ecx
223        jbe      2f                   # <= 32 dwords
224        rep;     smovl
225        jmp      4f
226	.space 8
2272:      subl     %esi,%edi
228        .p2align 4,,15
2293:      movl     (%esi),%edx
230        movl     %edx,(%edi,%esi,1)
231        subl     $4,%esi
232        subl     $1,%ecx
233        jnz      3b
234        addl     %esi,%edi
2354:      movl     %eax,%ecx
2365:      andl     $3,%ecx
237        jz       7f
238        subl     %esi,%edi
239        addl     $3,%esi
2406:      movb     (%esi),%dl
241        movb     %dl,(%edi,%esi,1)
242	subl     $1,%esi
243        subl     $1,%ecx
244        jnz      6b
2457:      cld
246        popl     %edi
247        popl     %esi
248        ret
249
250        # Support for void Copy::conjoint_jshorts_atomic(void* from,
251        #                                                void* to,
252        #                                                size_t count)
253        .p2align 4,,15
254	.type    _Copy_conjoint_jshorts_atomic,@function
255_Copy_conjoint_jshorts_atomic:
256        pushl    %esi
257        movl     4+12(%esp),%ecx      # count
258        pushl    %edi
259        movl     8+ 4(%esp),%esi      # from
260        movl     8+ 8(%esp),%edi      # to
261        cmpl     %esi,%edi
262        leal     -2(%esi,%ecx,2),%eax # from + count*2 - 2
263        jbe      cs_CopyRight
264        cmpl     %eax,%edi
265        jbe      cs_CopyLeft
266        # copy from low to high
267cs_CopyRight:
268        # align source address at dword address boundary
269        movl     %esi,%eax            # original from
270        andl     $3,%eax              # either 0 or 2
271        jz       1f                   # no prefix
272        # copy prefix
273        subl     $1,%ecx
274        jl       5f                   # zero count
275        movw     (%esi),%dx
276        movw     %dx,(%edi)
277        addl     %eax,%esi            # %eax == 2
278        addl     %eax,%edi
2791:      movl     %ecx,%eax            # word count less prefix
280        sarl     %ecx                 # dword count
281        jz       4f                   # no dwords to move
282        cmpl     $32,%ecx
283        jbe      2f                   # <= 32 dwords
284        # copy aligned dwords
285        rep;     smovl
286        jmp      4f
287        # copy aligned dwords
2882:      subl     %esi,%edi
289        .p2align 4,,15
2903:      movl     (%esi),%edx
291        movl     %edx,(%edi,%esi,1)
292        addl     $4,%esi
293        subl     $1,%ecx
294        jnz      3b
295        addl     %esi,%edi
2964:      andl     $1,%eax              # suffix count
297        jz       5f                   # no suffix
298        # copy suffix
299        movw     (%esi),%dx
300        movw     %dx,(%edi)
3015:      popl     %edi
302        popl     %esi
303        ret
304        # copy from high to low
305cs_CopyLeft:
306        std
307        leal     -4(%edi,%ecx,2),%edi # to + count*2 - 4
308        movl     %eax,%esi            # from + count*2 - 2
309        movl     %ecx,%eax
310        subl     $2,%esi              # from + count*2 - 4
3111:      sarl     %ecx                 # dword count
312        jz       4f                   # no dwords to move
313        cmpl     $32,%ecx
314        ja       3f                   # > 32 dwords
315        subl     %esi,%edi
316        .p2align 4,,15
3172:      movl     (%esi),%edx
318        movl     %edx,(%edi,%esi,1)
319        subl     $4,%esi
320        subl     $1,%ecx
321        jnz      2b
322        addl     %esi,%edi
323        jmp      4f
3243:      rep;     smovl
3254:      andl     $1,%eax              # suffix count
326        jz       5f                   # no suffix
327        # copy suffix
328        addl     $2,%esi
329        addl     $2,%edi
330        movw     (%esi),%dx
331        movw     %dx,(%edi)
3325:      cld
333        popl     %edi
334        popl     %esi
335        ret
336
337        # Support for void Copy::arrayof_conjoint_jshorts(void* from,
338        #                                                 void* to,
339        #                                                 size_t count)
340        .p2align 4,,15
341	.type    _Copy_arrayof_conjoint_jshorts,@function
342_Copy_arrayof_conjoint_jshorts:
343        pushl    %esi
344        movl     4+12(%esp),%ecx      # count
345        pushl    %edi
346        movl     8+ 4(%esp),%esi      # from
347        movl     8+ 8(%esp),%edi      # to
348        cmpl     %esi,%edi
349        leal     -2(%esi,%ecx,2),%eax # from + count*2 - 2
350        jbe      acs_CopyRight
351        cmpl     %eax,%edi
352        jbe      acs_CopyLeft
353acs_CopyRight:
354        movl     %ecx,%eax            # word count
355        sarl     %ecx                 # dword count
356        jz       4f                   # no dwords to move
357        cmpl     $32,%ecx
358        jbe      2f                   # <= 32 dwords
359        # copy aligned dwords
360        rep;     smovl
361        jmp      4f
362        # copy aligned dwords
363        .space 5
3642:      subl     %esi,%edi
365        .p2align 4,,15
3663:      movl     (%esi),%edx
367        movl     %edx,(%edi,%esi,1)
368        addl     $4,%esi
369        subl     $1,%ecx
370        jnz      3b
371        addl     %esi,%edi
3724:      andl     $1,%eax              # suffix count
373        jz       5f                   # no suffix
374        # copy suffix
375        movw     (%esi),%dx
376        movw     %dx,(%edi)
3775:      popl     %edi
378        popl     %esi
379        ret
380acs_CopyLeft:
381        std
382        leal     -4(%edi,%ecx,2),%edi # to + count*2 - 4
383        movl     %eax,%esi            # from + count*2 - 2
384        movl     %ecx,%eax
385        subl     $2,%esi              # from + count*2 - 4
386        sarl     %ecx                 # dword count
387        jz       4f                   # no dwords to move
388        cmpl     $32,%ecx
389        ja       3f                   # > 32 dwords
390        subl     %esi,%edi
391        .p2align 4,,15
3922:      movl     (%esi),%edx
393        movl     %edx,(%edi,%esi,1)
394        subl     $4,%esi
395        subl     $1,%ecx
396        jnz      2b
397        addl     %esi,%edi
398        jmp      4f
3993:      rep;     smovl
4004:      andl     $1,%eax              # suffix count
401        jz       5f                   # no suffix
402        # copy suffix
403        addl     $2,%esi
404        addl     $2,%edi
405        movw     (%esi),%dx
406        movw     %dx,(%edi)
4075:      cld
408        popl     %edi
409        popl     %esi
410        ret
411
412        # Support for void Copy::conjoint_jints_atomic(void* from,
413        #                                              void* to,
414        #                                              size_t count)
415        # Equivalent to
416        #   arrayof_conjoint_jints
417        .p2align 4,,15
418	.type    _Copy_conjoint_jints_atomic,@function
419	.type    _Copy_arrayof_conjoint_jints,@function
420_Copy_conjoint_jints_atomic:
421_Copy_arrayof_conjoint_jints:
422        pushl    %esi
423        movl     4+12(%esp),%ecx      # count
424        pushl    %edi
425        movl     8+ 4(%esp),%esi      # from
426        movl     8+ 8(%esp),%edi      # to
427        cmpl     %esi,%edi
428        leal     -4(%esi,%ecx,4),%eax # from + count*4 - 4
429        jbe      ci_CopyRight
430        cmpl     %eax,%edi
431        jbe      ci_CopyLeft
432ci_CopyRight:
433        cmpl     $32,%ecx
434        jbe      2f                   # <= 32 dwords
435        rep;     smovl
436        popl     %edi
437        popl     %esi
438        ret
439        .space 10
4402:      subl     %esi,%edi
441        jmp      4f
442        .p2align 4,,15
4433:      movl     (%esi),%edx
444        movl     %edx,(%edi,%esi,1)
445        addl     $4,%esi
4464:      subl     $1,%ecx
447        jge      3b
448        popl     %edi
449        popl     %esi
450        ret
451ci_CopyLeft:
452        std
453        leal     -4(%edi,%ecx,4),%edi # to + count*4 - 4
454        cmpl     $32,%ecx
455        ja       4f                   # > 32 dwords
456        subl     %eax,%edi            # eax == from + count*4 - 4
457        jmp      3f
458        .p2align 4,,15
4592:      movl     (%eax),%edx
460        movl     %edx,(%edi,%eax,1)
461        subl     $4,%eax
4623:      subl     $1,%ecx
463        jge      2b
464        cld
465        popl     %edi
466        popl     %esi
467        ret
4684:      movl     %eax,%esi            # from + count*4 - 4
469        rep;     smovl
470        cld
471        popl     %edi
472        popl     %esi
473        ret
474
475        # Support for void Copy::conjoint_jlongs_atomic(jlong* from,
476        #                                               jlong* to,
477        #                                               size_t count)
478        #
479        # 32-bit
480        #
481        # count treated as signed
482        #
483        # if (from > to) {
484        #   while (--count >= 0) {
485        #     *to++ = *from++;
486        #   }
487        # } else {
488        #   while (--count >= 0) {
489        #     to[count] = from[count];
490        #   }
491        # }
492        .p2align 4,,15
493	.type    _Copy_conjoint_jlongs_atomic,@function
494_Copy_conjoint_jlongs_atomic:
495        movl     4+8(%esp),%ecx       # count
496        movl     4+0(%esp),%eax       # from
497        movl     4+4(%esp),%edx       # to
498        cmpl     %eax,%edx
499        jae      cla_CopyLeft
500cla_CopyRight:
501        subl     %eax,%edx
502        jmp      2f
503        .p2align 4,,15
5041:      fildll   (%eax)
505        fistpll  (%edx,%eax,1)
506        addl     $8,%eax
5072:      subl     $1,%ecx
508        jge      1b
509        ret
510        .p2align 4,,15
5113:      fildll   (%eax,%ecx,8)
512        fistpll  (%edx,%ecx,8)
513cla_CopyLeft:
514        subl     $1,%ecx
515        jge      3b
516        ret
517
518        # Support for void Copy::arrayof_conjoint_jshorts(void* from,
519        #                                                 void* to,
520        #                                                 size_t count)
521        .p2align 4,,15
522	.type    _mmx_Copy_arrayof_conjoint_jshorts,@function
523_mmx_Copy_arrayof_conjoint_jshorts:
524        pushl    %esi
525        movl     4+12(%esp),%ecx
526        pushl    %edi
527        movl     8+ 4(%esp),%esi
528        movl     8+ 8(%esp),%edi
529        cmpl     %esi,%edi
530        leal     -2(%esi,%ecx,2),%eax
531        jbe      mmx_acs_CopyRight
532        cmpl     %eax,%edi
533        jbe      mmx_acs_CopyLeft
534mmx_acs_CopyRight:
535        movl     %ecx,%eax
536        sarl     %ecx
537        je       5f
538        cmpl     $33,%ecx
539        jae      3f
5401:      subl     %esi,%edi
541        .p2align 4,,15
5422:      movl     (%esi),%edx
543        movl     %edx,(%edi,%esi,1)
544        addl     $4,%esi
545        subl     $1,%ecx
546        jnz      2b
547        addl     %esi,%edi
548        jmp      5f
5493:      smovl # align to 8 bytes, we know we are 4 byte aligned to start
550        subl     $1,%ecx
5514:      .p2align 4,,15
552        movq     0(%esi),%mm0
553        addl     $64,%edi
554        movq     8(%esi),%mm1
555        subl     $16,%ecx
556        movq     16(%esi),%mm2
557        movq     %mm0,-64(%edi)
558        movq     24(%esi),%mm0
559        movq     %mm1,-56(%edi)
560        movq     32(%esi),%mm1
561        movq     %mm2,-48(%edi)
562        movq     40(%esi),%mm2
563        movq     %mm0,-40(%edi)
564        movq     48(%esi),%mm0
565        movq     %mm1,-32(%edi)
566        movq     56(%esi),%mm1
567        movq     %mm2,-24(%edi)
568        movq     %mm0,-16(%edi)
569        addl     $64,%esi
570        movq     %mm1,-8(%edi)
571        cmpl     $16,%ecx
572        jge      4b
573        emms
574	testl    %ecx,%ecx
575	ja       1b
5765:      andl     $1,%eax
577        je       7f
5786:      movw     (%esi),%dx
579        movw     %dx,(%edi)
5807:	popl     %edi
581        popl     %esi
582        ret
583mmx_acs_CopyLeft:
584        std
585        leal     -4(%edi,%ecx,2),%edi
586        movl     %eax,%esi
587        movl     %ecx,%eax
588        subl     $2,%esi
589        sarl     %ecx
590        je       4f
591        cmpl     $32,%ecx
592        ja       3f
593        subl     %esi,%edi
594        .p2align 4,,15
5952:      movl     (%esi),%edx
596        movl     %edx,(%edi,%esi,1)
597        subl     $4,%esi
598        subl     $1,%ecx
599        jnz      2b
600        addl     %esi,%edi
601        jmp      4f
6023:      rep;     smovl
6034:      andl     $1,%eax
604        je       6f
605        addl     $2,%esi
606        addl     $2,%edi
6075:      movw     (%esi),%dx
608        movw     %dx,(%edi)
6096:      cld
610        popl     %edi
611        popl     %esi
612        ret
613
614
615        # Support for jlong Atomic::cmpxchg(jlong exchange_value,
616        #                                   volatile jlong* dest,
617        #                                   jlong compare_value,
618        #                                   bool is_MP)
619        #
620        .p2align 4,,15
621	.type    _Atomic_cmpxchg_long,@function
622_Atomic_cmpxchg_long:
623                                   #  8(%esp) : return PC
624        pushl    %ebx              #  4(%esp) : old %ebx
625        pushl    %edi              #  0(%esp) : old %edi
626        movl     12(%esp), %ebx    # 12(%esp) : exchange_value (low)
627        movl     16(%esp), %ecx    # 16(%esp) : exchange_value (high)
628        movl     24(%esp), %eax    # 24(%esp) : compare_value (low)
629        movl     28(%esp), %edx    # 28(%esp) : compare_value (high)
630        movl     20(%esp), %edi    # 20(%esp) : dest
631        cmpl     $0, 32(%esp)      # 32(%esp) : is_MP
632        je       1f
633        lock
6341:      cmpxchg8b (%edi)
635        popl     %edi
636        popl     %ebx
637        ret
638
639
640        # Support for jlong Atomic::load and Atomic::store.
641        # void _Atomic_move_long(volatile jlong* src, volatile jlong* dst)
642        .p2align 4,,15
643	.type    _Atomic_move_long,@function
644_Atomic_move_long:
645        movl     4(%esp), %eax   # src
646        fildll    (%eax)
647        movl     8(%esp), %eax   # dest
648        fistpll   (%eax)
649        ret
650
651