1#
2# Copyright (c) 2008, 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	.type _Copy_conjoint_bytes, %function
33        .globl _Copy_arrayof_conjoint_bytes
34	.type _Copy_arrayof_conjoint_bytes, %function
35	.globl _Copy_disjoint_words
36	.type _Copy_disjoint_words, %function
37	.globl _Copy_conjoint_words
38	.type _Copy_conjoint_words, %function
39        .globl _Copy_conjoint_jshorts_atomic
40	.type _Copy_conjoint_jshorts_atomic, %function
41	.globl _Copy_arrayof_conjoint_jshorts
42	.type _Copy_arrayof_conjoint_jshorts, %function
43        .globl _Copy_conjoint_jints_atomic
44	.type _Copy_conjoint_jints_atomic, %function
45        .globl _Copy_arrayof_conjoint_jints
46	.type _Copy_arrayof_conjoint_jints, %function
47	.globl _Copy_conjoint_jlongs_atomic
48	.type _Copy_conjoint_jlongs_atomic, %function
49	.globl _Copy_arrayof_conjoint_jlongs
50	.type _Copy_arrayof_conjoint_jlongs, %function
51
52from	.req	r0
53to	.req	r1
54
55	.text
56        .globl  SpinPause
57        .type SpinPause, %function
58SpinPause:
59        bx      LR
60
61        # Support for void Copy::conjoint_bytes(void* from,
62        #                                       void* to,
63        #                                       size_t count)
64_Copy_conjoint_bytes:
65        swi     0x9f0001
66
67        # Support for void Copy::arrayof_conjoint_bytes(void* from,
68        #                                               void* to,
69        #                                               size_t count)
70_Copy_arrayof_conjoint_bytes:
71        swi     0x9f0001
72
73
74        # Support for void Copy::disjoint_words(void* from,
75        #                                       void* to,
76        #                                       size_t count)
77_Copy_disjoint_words:
78        stmdb    sp!, {r3 - r9, ip}
79
80        cmp     r2, #0
81        beq     disjoint_words_finish
82
83        pld     [from, #0]
84        cmp     r2, #12
85        ble disjoint_words_small
86
87        .align 3
88dw_f2b_loop_32:
89        subs    r2, #32
90	blt	dw_f2b_loop_32_finish
91        ldmia from!, {r3 - r9, ip}
92        nop
93	pld     [from]
94        stmia to!, {r3 - r9, ip}
95        bgt     dw_f2b_loop_32
96dw_f2b_loop_32_finish:
97        addlts  r2, #32
98        beq     disjoint_words_finish
99        cmp     r2, #16
100	blt	disjoint_words_small
101        ldmia from!, {r3 - r6}
102        subge   r2, r2, #16
103        stmia to!, {r3 - r6}
104        beq     disjoint_words_finish
105disjoint_words_small:
106        cmp     r2, #8
107        ldr     r7, [from], #4
108        ldrge   r8, [from], #4
109        ldrgt   r9, [from], #4
110        str     r7, [to], #4
111        strge   r8, [to], #4
112        strgt   r9, [to], #4
113
114disjoint_words_finish:
115        ldmia   sp!, {r3 - r9, ip}
116        bx      lr
117
118
119        # Support for void Copy::conjoint_words(void* from,
120        #                                       void* to,
121        #                                       size_t count)
122_Copy_conjoint_words:
123        stmdb    sp!, {r3 - r9, ip}
124
125	cmp	r2, #0
126	beq	conjoint_words_finish
127
128        pld     [from, #0]
129        cmp     r2, #12
130        ble conjoint_words_small
131
132        subs    r3, to, from
133        cmphi   r2, r3
134        bhi     cw_b2f_copy
135        .align 3
136cw_f2b_loop_32:
137        subs    r2, #32
138	blt	cw_f2b_loop_32_finish
139        ldmia from!, {r3 - r9, ip}
140        nop
141	pld     [from]
142        stmia to!, {r3 - r9, ip}
143        bgt     cw_f2b_loop_32
144cw_f2b_loop_32_finish:
145        addlts  r2, #32
146        beq     conjoint_words_finish
147        cmp     r2, #16
148	blt	conjoint_words_small
149        ldmia from!, {r3 - r6}
150        subge   r2, r2, #16
151        stmia to!, {r3 - r6}
152        beq     conjoint_words_finish
153conjoint_words_small:
154        cmp     r2, #8
155        ldr     r7, [from], #4
156        ldrge   r8, [from], #4
157        ldrgt   r9, [from], #4
158        str     r7, [to], #4
159        strge   r8, [to], #4
160        strgt   r9, [to], #4
161        b       conjoint_words_finish
162
163	# Src and dest overlap, copy in a descending order
164cw_b2f_copy:
165        add     from, r2
166        pld     [from, #-32]
167        add     to, r2
168        .align 3
169cw_b2f_loop_32:
170        subs    r2, #32
171	blt	cw_b2f_loop_32_finish
172        ldmdb from!, {r3-r9,ip}
173        nop
174	pld     [from, #-32]
175        stmdb to!, {r3-r9,ip}
176        bgt     cw_b2f_loop_32
177cw_b2f_loop_32_finish:
178        addlts  r2, #32
179        beq     conjoint_words_finish
180        cmp     r2, #16
181	blt	cw_b2f_copy_small
182        ldmdb from!, {r3 - r6}
183        subge   r2, r2, #16
184        stmdb to!, {r3 - r6}
185        beq     conjoint_words_finish
186cw_b2f_copy_small:
187        cmp     r2, #8
188        ldr     r7, [from, #-4]!
189        ldrge   r8, [from, #-4]!
190        ldrgt   r9, [from, #-4]!
191        str     r7, [to, #-4]!
192        strge   r8, [to, #-4]!
193        strgt   r9, [to, #-4]!
194
195conjoint_words_finish:
196        ldmia   sp!, {r3 - r9, ip}
197        bx      lr
198
199        # Support for void Copy::conjoint_jshorts_atomic(void* from,
200        #                                                void* to,
201        #                                                size_t count)
202_Copy_conjoint_jshorts_atomic:
203        stmdb   sp!, {r3 - r9, ip}
204
205	cmp	r2, #0
206	beq	conjoint_shorts_finish
207
208        subs    r3, to, from
209        cmphi   r2, r3
210        bhi     cs_b2f_copy
211
212        pld     [from]
213
214        ands    r3, to, #3
215        bne     cs_f2b_dest_u
216        ands    r3, from, #3
217        bne     cs_f2b_src_u
218
219	# Aligned source address
220        .align 3
221cs_f2b_loop_32:
222        subs    r2, #32
223	blt	cs_f2b_loop_32_finish
224        ldmia from!, {r3 - r9, ip}
225        nop
226        pld     [from]
227        stmia to!, {r3 - r9, ip}
228        bgt     cs_f2b_loop_32
229cs_f2b_loop_32_finish:
230        addlts  r2, #32
231        beq     conjoint_shorts_finish
232        movs    r6, r2, lsr #3
233        .align 3
234cs_f2b_8_loop:
235        beq     cs_f2b_4
236        ldmia   from!, {r4-r5}
237        subs    r6, #1
238        stmia   to!, {r4-r5}
239        bgt     cs_f2b_8_loop
240
241cs_f2b_4:
242        ands    r2, #7
243        beq     conjoint_shorts_finish
244        cmp     r2, #4
245        ldrh    r3, [from], #2
246        ldrgeh  r4, [from], #2
247        ldrgth  r5, [from], #2
248        strh    r3, [to], #2
249        strgeh  r4, [to], #2
250        strgth  r5, [to], #2
251        b       conjoint_shorts_finish
252
253	# Destination not aligned
254cs_f2b_dest_u:
255        ldrh    r3, [from], #2
256        subs    r2, #2
257        strh    r3, [to], #2
258        beq     conjoint_shorts_finish
259
260	# Check to see if source is not aligned ether
261        ands    r3, from, #3
262        beq     cs_f2b_loop_32
263
264cs_f2b_src_u:
265        cmp     r2, #16
266        blt     cs_f2b_8_u
267
268	# Load 2 first bytes to r7 and make src ptr word aligned
269        bic     from, #3
270        ldr     r7, [from], #4
271
272	# Destination aligned, source not
273        mov     r8, r2, lsr #4
274        .align 3
275cs_f2b_16_u_loop:
276        mov     r3, r7, lsr #16
277        ldmia   from!, {r4 - r7}
278        orr     r3, r3, r4, lsl #16
279        mov     r4, r4, lsr #16
280        pld     [from]
281        orr     r4, r4, r5, lsl #16
282        mov     r5, r5, lsr #16
283        orr     r5, r5, r6, lsl #16
284        mov     r6, r6, lsr #16
285        orr     r6, r6, r7, lsl #16
286        stmia   to!, {r3 - r6}
287        subs    r8, #1
288        bgt     cs_f2b_16_u_loop
289        ands    r2, #0xf
290        beq     conjoint_shorts_finish
291        sub     from, #2
292
293cs_f2b_8_u:
294        cmp     r2, #8
295        blt     cs_f2b_4_u
296        ldrh    r4, [from], #2
297        ldr     r5, [from], #4
298        ldrh    r6, [from], #2
299        orr     r4, r4, r5, lsl #16
300        mov     r5, r5, lsr #16
301        orr     r5, r5, r6, lsl #16
302        subs    r2, #8
303        stmia	to!, {r4 - r5}
304cs_f2b_4_u:
305        beq     conjoint_shorts_finish
306        cmp     r2, #4
307        ldrh    r3, [from], #2
308        ldrgeh  r4, [from], #2
309        ldrgth  r5, [from], #2
310        strh    r3, [to], #2
311        strgeh  r4, [to], #2
312        strgth  r5, [to], #2
313        b       conjoint_shorts_finish
314
315	# Src and dest overlap, copy in a descending order
316cs_b2f_copy:
317        add     from, r2
318        pld     [from, #-32]
319        add     to, r2
320
321        ands    r3, to, #3
322        bne     cs_b2f_dest_u
323        ands    r3, from, #3
324        bne     cs_b2f_src_u
325        .align 3
326cs_b2f_loop_32:
327        subs    r2, #32
328	blt	cs_b2f_loop_32_finish
329        ldmdb from!, {r3-r9,ip}
330        nop
331        pld     [from, #-32]
332        stmdb to!, {r3-r9,ip}
333        bgt     cs_b2f_loop_32
334cs_b2f_loop_32_finish:
335        addlts  r2, #32
336        beq     conjoint_shorts_finish
337        cmp     r2, #24
338        blt     cs_b2f_16
339        ldmdb   from!, {r3-r8}
340        sub     r2, #24
341        stmdb   to!, {r3-r8}
342        beq     conjoint_shorts_finish
343cs_b2f_16:
344        cmp     r2, #16
345        blt     cs_b2f_8
346        ldmdb   from!, {r3-r6}
347        sub     r2, #16
348        stmdb   to!, {r3-r6}
349        beq     conjoint_shorts_finish
350cs_b2f_8:
351        cmp     r2, #8
352        blt     cs_b2f_all_copy
353        ldmdb   from!, {r3-r4}
354        sub     r2, #8
355        stmdb   to!, {r3-r4}
356        beq     conjoint_shorts_finish
357
358cs_b2f_all_copy:
359        cmp     r2, #4
360        ldrh    r3, [from, #-2]!
361        ldrgeh  r4, [from, #-2]!
362        ldrgth  r5, [from, #-2]!
363        strh    r3, [to, #-2]!
364        strgeh  r4, [to, #-2]!
365        strgth  r5, [to, #-2]!
366        b       conjoint_shorts_finish
367
368	# Destination not aligned
369cs_b2f_dest_u:
370        ldrh    r3, [from, #-2]!
371        strh    r3, [to, #-2]!
372        sub     r2, #2
373	# Check source alignment as well
374        ands    r3, from, #3
375        beq     cs_b2f_loop_32
376
377	# Source not aligned
378cs_b2f_src_u:
379        bic     from, #3
380        .align 3
381cs_b2f_16_loop_u:
382        subs    r2, #16
383        blt     cs_b2f_16_loop_u_finished
384        ldr     r7, [from]
385        mov     r3, r7
386        ldmdb   from!, {r4 - r7}
387        mov     r4, r4, lsr #16
388        orr     r4, r4, r5, lsl #16
389        pld     [from, #-32]
390        mov     r5, r5, lsr #16
391        orr     r5, r5, r6, lsl #16
392        mov     r6, r6, lsr #16
393        orr     r6, r6, r7, lsl #16
394        mov     r7, r7, lsr #16
395        orr     r7, r7, r3, lsl #16
396        stmdb   to!, {r4 - r7}
397        bgt     cs_b2f_16_loop_u
398        beq     conjoint_shorts_finish
399cs_b2f_16_loop_u_finished:
400        addlts  r2, #16
401        ldr     r3, [from]
402	cmp     r2, #10
403        blt     cs_b2f_2_u_loop
404        ldmdb   from!, {r4 - r5}
405        mov     r6, r4, lsr #16
406        orr     r6, r6, r5, lsl #16
407        mov     r7, r5, lsr #16
408        orr     r7, r7, r3, lsl #16
409        stmdb   to!, {r6-r7}
410        sub     r2, #8
411	.align 3
412cs_b2f_2_u_loop:
413        subs    r2, #2
414        ldrh    r3, [from], #-2
415        strh    r3, [to, #-2]!
416        bgt     cs_b2f_2_u_loop
417
418conjoint_shorts_finish:
419        ldmia   sp!, {r3 - r9, ip}
420        bx      lr
421
422
423        # Support for void Copy::arrayof_conjoint_jshorts(void* from,
424        #                                                 void* to,
425        #                                                 size_t count)
426_Copy_arrayof_conjoint_jshorts:
427        swi     0x9f0001
428
429        # Support for void Copy::conjoint_jints_atomic(void* from,
430        #                                              void* to,
431        #                                              size_t count)
432_Copy_conjoint_jints_atomic:
433_Copy_arrayof_conjoint_jints:
434        swi     0x9f0001
435
436        # Support for void Copy::conjoint_jlongs_atomic(jlong* from,
437        #                                               jlong* to,
438        #                                               size_t count)
439_Copy_conjoint_jlongs_atomic:
440_Copy_arrayof_conjoint_jlongs:
441        stmdb    sp!, {r3 - r9, ip}
442
443	cmp	r2, #0
444	beq	conjoint_longs_finish
445
446        pld     [from, #0]
447        cmp     r2, #24
448        ble conjoint_longs_small
449
450        subs    r3, to, from
451        cmphi   r2, r3
452        bhi     cl_b2f_copy
453        .align 3
454cl_f2b_loop_32:
455        subs    r2, #32
456	blt	cl_f2b_loop_32_finish
457        ldmia from!, {r3 - r9, ip}
458        nop
459	pld     [from]
460        stmia to!, {r3 - r9, ip}
461        bgt     cl_f2b_loop_32
462cl_f2b_loop_32_finish:
463        addlts  r2, #32
464        beq     conjoint_longs_finish
465conjoint_longs_small:
466        cmp     r2, #16
467	blt	cl_f2b_copy_8
468	bgt	cl_f2b_copy_24
469        ldmia 	from!, {r3 - r6}
470        stmia 	to!, {r3 - r6}
471	b	conjoint_longs_finish
472cl_f2b_copy_8:
473        ldmia   from!, {r3 - r4}
474        stmia   to!, {r3 - r4}
475        b       conjoint_longs_finish
476cl_f2b_copy_24:
477	ldmia   from!, {r3 - r8}
478        stmia   to!, {r3 - r8}
479        b       conjoint_longs_finish
480
481	# Src and dest overlap, copy in a descending order
482cl_b2f_copy:
483        add     from, r2
484        pld     [from, #-32]
485        add     to, r2
486        .align 3
487cl_b2f_loop_32:
488        subs    r2, #32
489	blt	cl_b2f_loop_32_finish
490        ldmdb 	from!, {r3 - r9, ip}
491        nop
492	pld     [from]
493        stmdb 	to!, {r3 - r9, ip}
494        bgt     cl_b2f_loop_32
495cl_b2f_loop_32_finish:
496        addlts  r2, #32
497        beq     conjoint_longs_finish
498        cmp     r2, #16
499	blt	cl_b2f_copy_8
500	bgt	cl_b2f_copy_24
501        ldmdb   from!, {r3 - r6}
502        stmdb   to!, {r3 - r6}
503        b       conjoint_longs_finish
504cl_b2f_copy_8:
505	ldmdb   from!, {r3 - r4}
506        stmdb   to!, {r3 - r4}
507        b       conjoint_longs_finish
508cl_b2f_copy_24:
509	ldmdb   from!, {r3 - r8}
510        stmdb   to!, {r3 - r8}
511
512conjoint_longs_finish:
513        ldmia   sp!, {r3 - r9, ip}
514        bx      lr
515
516
517