2.9
[glibc/nacl-glibc.git] / sysdeps / sparc / sparc64 / sparcv9v2 / memcpy.S
blobb261f461a4ccfbbd800f272cbedcee4ea0066e51
1 /* Copy SIZE bytes from SRC to DEST.  For SUN4V Niagara-2.
2    Copyright (C) 2007, 2008 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by David S. Miller (davem@davemloft.net)
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; if not, write to the Free
18    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19    02111-1307 USA.  */
21 #include <sysdep.h>
23 #define ASI_BLK_INIT_QUAD_LDD_P 0xe2
24 #define ASI_BLK_P               0xf0
25 #define ASI_P                   0x80
26 #define ASI_PNF                 0x82
28 #define FPRS_FEF                0x04
30 #define VISEntryHalf                    \
31         rd      %fprs, %o5;             \
32         wr      %g0, FPRS_FEF, %fprs
34 #define VISExitHalf                     \
35         and     %o5, FPRS_FEF, %o5;     \
36         wr      %o5, 0x0, %fprs
38 #define STORE_ASI               ASI_BLK_INIT_QUAD_LDD_P
40 #define LOAD(type,addr,dest)    type [addr], dest
41 #define LOAD_BLK(addr,dest)     ldda [addr] ASI_BLK_P, dest
42 #define STORE(type,src,addr)    type src, [addr]
43 #define STORE_BLK(src,addr)     stda src, [addr] ASI_BLK_P
44 #define STORE_INIT(src,addr)    stxa src, [addr] STORE_ASI
46 #ifndef XCC
47 #define USE_BPR
48 #define XCC xcc
49 #endif
51 #define FREG_FROB(x0, x1, x2, x3, x4, x5, x6, x7, x8) \
52         faligndata      %x0, %x1, %f0; \
53         faligndata      %x1, %x2, %f2; \
54         faligndata      %x2, %x3, %f4; \
55         faligndata      %x3, %x4, %f6; \
56         faligndata      %x4, %x5, %f8; \
57         faligndata      %x5, %x6, %f10; \
58         faligndata      %x6, %x7, %f12; \
59         faligndata      %x7, %x8, %f14;
61 #define FREG_MOVE_1(x0) \
62         fmovd           %x0, %f0;
63 #define FREG_MOVE_2(x0, x1) \
64         fmovd           %x0, %f0; \
65         fmovd           %x1, %f2;
66 #define FREG_MOVE_3(x0, x1, x2) \
67         fmovd           %x0, %f0; \
68         fmovd           %x1, %f2; \
69         fmovd           %x2, %f4;
70 #define FREG_MOVE_4(x0, x1, x2, x3) \
71         fmovd           %x0, %f0; \
72         fmovd           %x1, %f2; \
73         fmovd           %x2, %f4; \
74         fmovd           %x3, %f6;
75 #define FREG_MOVE_5(x0, x1, x2, x3, x4) \
76         fmovd           %x0, %f0; \
77         fmovd           %x1, %f2; \
78         fmovd           %x2, %f4; \
79         fmovd           %x3, %f6; \
80         fmovd           %x4, %f8;
81 #define FREG_MOVE_6(x0, x1, x2, x3, x4, x5) \
82         fmovd           %x0, %f0; \
83         fmovd           %x1, %f2; \
84         fmovd           %x2, %f4; \
85         fmovd           %x3, %f6; \
86         fmovd           %x4, %f8; \
87         fmovd           %x5, %f10;
88 #define FREG_MOVE_7(x0, x1, x2, x3, x4, x5, x6) \
89         fmovd           %x0, %f0; \
90         fmovd           %x1, %f2; \
91         fmovd           %x2, %f4; \
92         fmovd           %x3, %f6; \
93         fmovd           %x4, %f8; \
94         fmovd           %x5, %f10; \
95         fmovd           %x6, %f12;
96 #define FREG_MOVE_8(x0, x1, x2, x3, x4, x5, x6, x7) \
97         fmovd           %x0, %f0; \
98         fmovd           %x1, %f2; \
99         fmovd           %x2, %f4; \
100         fmovd           %x3, %f6; \
101         fmovd           %x4, %f8; \
102         fmovd           %x5, %f10; \
103         fmovd           %x6, %f12; \
104         fmovd           %x7, %f14;
105 #define FREG_LOAD_1(base, x0) \
106         LOAD(ldd, base + 0x00, %x0)
107 #define FREG_LOAD_2(base, x0, x1) \
108         LOAD(ldd, base + 0x00, %x0); \
109         LOAD(ldd, base + 0x08, %x1);
110 #define FREG_LOAD_3(base, x0, x1, x2) \
111         LOAD(ldd, base + 0x00, %x0); \
112         LOAD(ldd, base + 0x08, %x1); \
113         LOAD(ldd, base + 0x10, %x2);
114 #define FREG_LOAD_4(base, x0, x1, x2, x3) \
115         LOAD(ldd, base + 0x00, %x0); \
116         LOAD(ldd, base + 0x08, %x1); \
117         LOAD(ldd, base + 0x10, %x2); \
118         LOAD(ldd, base + 0x18, %x3);
119 #define FREG_LOAD_5(base, x0, x1, x2, x3, x4) \
120         LOAD(ldd, base + 0x00, %x0); \
121         LOAD(ldd, base + 0x08, %x1); \
122         LOAD(ldd, base + 0x10, %x2); \
123         LOAD(ldd, base + 0x18, %x3); \
124         LOAD(ldd, base + 0x20, %x4);
125 #define FREG_LOAD_6(base, x0, x1, x2, x3, x4, x5) \
126         LOAD(ldd, base + 0x00, %x0); \
127         LOAD(ldd, base + 0x08, %x1); \
128         LOAD(ldd, base + 0x10, %x2); \
129         LOAD(ldd, base + 0x18, %x3); \
130         LOAD(ldd, base + 0x20, %x4); \
131         LOAD(ldd, base + 0x28, %x5);
132 #define FREG_LOAD_7(base, x0, x1, x2, x3, x4, x5, x6) \
133         LOAD(ldd, base + 0x00, %x0); \
134         LOAD(ldd, base + 0x08, %x1); \
135         LOAD(ldd, base + 0x10, %x2); \
136         LOAD(ldd, base + 0x18, %x3); \
137         LOAD(ldd, base + 0x20, %x4); \
138         LOAD(ldd, base + 0x28, %x5); \
139         LOAD(ldd, base + 0x30, %x6);
141         .register       %g2,#scratch
142         .register       %g3,#scratch
143         .register       %g6,#scratch
145         .text
146         .align          32
148 ENTRY(bcopy)
149         sub             %o1, %o0, %o4
150         mov             %o0, %g4
151         cmp             %o4, %o2
152         mov             %o1, %o0
153         bgeu,pt         %XCC, 100f
154          mov            %g4, %o1
155 #ifndef USE_BPR
156         srl             %o2, 0, %o2
157 #endif
158         brnz,pn         %o2, 220f
159          add            %o0, %o2, %o0
160         retl
161          nop
162 END(bcopy)
164         .align          32
165 ENTRY(memcpy)
166 #ifndef USE_BPR
167         srl             %o2, 0, %o2
168 #endif
169 100:    /* %o0=dst, %o1=src, %o2=len */
170         mov             %o0, %g5
171         cmp             %o2, 0
172         be,pn           %XCC, 85f
173 218:     or             %o0, %o1, %o3
174         cmp             %o2, 16
175         blu,a,pn        %XCC, 80f
176          or             %o3, %o2, %o3
178         /* 2 blocks (128 bytes) is the minimum we can do the block
179          * copy with.  We need to ensure that we'll iterate at least
180          * once in the block copy loop.  At worst we'll need to align
181          * the destination to a 64-byte boundary which can chew up
182          * to (64 - 1) bytes from the length before we perform the
183          * block copy loop.
184          *
185          * However, the cut-off point, performance wise, is around
186          * 4 64-byte blocks.
187          */
188         cmp             %o2, (4 * 64)
189         blu,pt          %XCC, 75f
190          andcc          %o3, 0x7, %g0
192         /* %o0: dst
193          * %o1: src
194          * %o2: len  (known to be >= 128)
195          *
196          * The block copy loops can use %o4, %g2, %g3 as
197          * temporaries while copying the data.  %o5 must
198          * be preserved between VISEntryHalf and VISExitHalf
199          */
201         LOAD(prefetch, %o1 + 0x000, #one_read)
202         LOAD(prefetch, %o1 + 0x040, #one_read)
203         LOAD(prefetch, %o1 + 0x080, #one_read)
205         /* Align destination on 64-byte boundary.  */
206         andcc           %o0, (64 - 1), %o4
207         be,pt           %XCC, 2f
208          sub            %o4, 64, %o4
209         sub             %g0, %o4, %o4   ! bytes to align dst
210         sub             %o2, %o4, %o2
211 1:      subcc           %o4, 1, %o4
212         LOAD(ldub, %o1, %g1)
213         STORE(stb, %g1, %o0)
214         add             %o1, 1, %o1
215         bne,pt          %XCC, 1b
216         add             %o0, 1, %o0
219         /* Clobbers o5/g1/g2/g3/g7/icc/xcc.  We must preserve
220          * o5 from here until we hit VISExitHalf.
221          */
222         VISEntryHalf
224         alignaddr       %o1, %g0, %g0
226         add             %o1, (64 - 1), %o4
227         andn            %o4, (64 - 1), %o4
228         andn            %o2, (64 - 1), %g1
229         sub             %o2, %g1, %o2
231         and             %o1, (64 - 1), %g2
232         add             %o1, %g1, %o1
233         sub             %o0, %o4, %g3
234         brz,pt          %g2, 190f
235          cmp            %g2, 32
236         blu,a           5f
237          cmp            %g2, 16
238         cmp             %g2, 48
239         blu,a           4f
240          cmp            %g2, 40
241         cmp             %g2, 56
242         blu             170f
243          nop
244         ba,a,pt         %xcc, 180f
246 4:      /* 32 <= low bits < 48 */
247         blu             150f
248          nop
249         ba,a,pt         %xcc, 160f
250 5:      /* 0 < low bits < 32 */
251         blu,a           6f
252          cmp            %g2, 8
253         cmp             %g2, 24
254         blu             130f
255          nop
256         ba,a,pt         %xcc, 140f
257 6:      /* 0 < low bits < 16 */
258         bgeu            120f
259          nop
260         /* fall through for 0 < low bits < 8 */
261 110:    sub             %o4, 64, %g2
262         LOAD_BLK(%g2, %f0)
263 1:      STORE_INIT(%g0, %o4 + %g3)
264         LOAD_BLK(%o4, %f16)
265         FREG_FROB(f0, f2, f4, f6, f8, f10, f12, f14, f16)
266         STORE_BLK(%f0, %o4 + %g3)
267         FREG_MOVE_8(f16, f18, f20, f22, f24, f26, f28, f30)
268         subcc           %g1, 64, %g1
269         add             %o4, 64, %o4
270         bne,pt          %XCC, 1b
271          LOAD(prefetch, %o4 + 64, #one_read)
272         ba,pt           %xcc, 195f
273          nop
275 120:    sub             %o4, 56, %g2
276         FREG_LOAD_7(%g2, f0, f2, f4, f6, f8, f10, f12)
277 1:      STORE_INIT(%g0, %o4 + %g3)
278         LOAD_BLK(%o4, %f16)
279         FREG_FROB(f0, f2, f4, f6, f8, f10, f12, f16, f18)
280         STORE_BLK(%f0, %o4 + %g3)
281         FREG_MOVE_7(f18, f20, f22, f24, f26, f28, f30)
282         subcc           %g1, 64, %g1
283         add             %o4, 64, %o4
284         bne,pt          %XCC, 1b
285          LOAD(prefetch, %o4 + 64, #one_read)
286         ba,pt           %xcc, 195f
287          nop
289 130:    sub             %o4, 48, %g2
290         FREG_LOAD_6(%g2, f0, f2, f4, f6, f8, f10)
291 1:      STORE_INIT(%g0, %o4 + %g3)
292         LOAD_BLK(%o4, %f16)
293         FREG_FROB(f0, f2, f4, f6, f8, f10, f16, f18, f20)
294         STORE_BLK(%f0, %o4 + %g3)
295         FREG_MOVE_6(f20, f22, f24, f26, f28, f30)
296         subcc           %g1, 64, %g1
297         add             %o4, 64, %o4
298         bne,pt          %XCC, 1b
299          LOAD(prefetch, %o4 + 64, #one_read)
300         ba,pt           %xcc, 195f
301          nop
303 140:    sub             %o4, 40, %g2
304         FREG_LOAD_5(%g2, f0, f2, f4, f6, f8)
305 1:      STORE_INIT(%g0, %o4 + %g3)
306         LOAD_BLK(%o4, %f16)
307         FREG_FROB(f0, f2, f4, f6, f8, f16, f18, f20, f22)
308         STORE_BLK(%f0, %o4 + %g3)
309         FREG_MOVE_5(f22, f24, f26, f28, f30)
310         subcc           %g1, 64, %g1
311         add             %o4, 64, %o4
312         bne,pt          %XCC, 1b
313          LOAD(prefetch, %o4 + 64, #one_read)
314         ba,pt           %xcc, 195f
315          nop
317 150:    sub             %o4, 32, %g2
318         FREG_LOAD_4(%g2, f0, f2, f4, f6)
319 1:      STORE_INIT(%g0, %o4 + %g3)
320         LOAD_BLK(%o4, %f16)
321         FREG_FROB(f0, f2, f4, f6, f16, f18, f20, f22, f24)
322         STORE_BLK(%f0, %o4 + %g3)
323         FREG_MOVE_4(f24, f26, f28, f30)
324         subcc           %g1, 64, %g1
325         add             %o4, 64, %o4
326         bne,pt          %XCC, 1b
327          LOAD(prefetch, %o4 + 64, #one_read)
328         ba,pt           %xcc, 195f
329          nop
331 160:    sub             %o4, 24, %g2
332         FREG_LOAD_3(%g2, f0, f2, f4)
333 1:      STORE_INIT(%g0, %o4 + %g3)
334         LOAD_BLK(%o4, %f16)
335         FREG_FROB(f0, f2, f4, f16, f18, f20, f22, f24, f26)
336         STORE_BLK(%f0, %o4 + %g3)
337         FREG_MOVE_3(f26, f28, f30)
338         subcc           %g1, 64, %g1
339         add             %o4, 64, %o4
340         bne,pt          %XCC, 1b
341          LOAD(prefetch, %o4 + 64, #one_read)
342         ba,pt           %xcc, 195f
343          nop
345 170:    sub             %o4, 16, %g2
346         FREG_LOAD_2(%g2, f0, f2)
347 1:      STORE_INIT(%g0, %o4 + %g3)
348         LOAD_BLK(%o4, %f16)
349         FREG_FROB(f0, f2, f16, f18, f20, f22, f24, f26, f28)
350         STORE_BLK(%f0, %o4 + %g3)
351         FREG_MOVE_2(f28, f30)
352         subcc           %g1, 64, %g1
353         add             %o4, 64, %o4
354         bne,pt          %XCC, 1b
355          LOAD(prefetch, %o4 + 64, #one_read)
356         ba,pt           %xcc, 195f
357          nop
359 180:    sub             %o4, 8, %g2
360         FREG_LOAD_1(%g2, f0)
361 1:      STORE_INIT(%g0, %o4 + %g3)
362         LOAD_BLK(%o4, %f16)
363         FREG_FROB(f0, f16, f18, f20, f22, f24, f26, f28, f30)
364         STORE_BLK(%f0, %o4 + %g3)
365         FREG_MOVE_1(f30)
366         subcc           %g1, 64, %g1
367         add             %o4, 64, %o4
368         bne,pt          %XCC, 1b
369          LOAD(prefetch, %o4 + 64, #one_read)
370         ba,pt           %xcc, 195f
371          nop
373 190:
374 1:      STORE_INIT(%g0, %o4 + %g3)
375         subcc           %g1, 64, %g1
376         LOAD_BLK(%o4, %f0)
377         STORE_BLK(%f0, %o4 + %g3)
378         add             %o4, 64, %o4
379         bne,pt          %XCC, 1b
380          LOAD(prefetch, %o4 + 64, #one_read)
382 195:
383         add             %o4, %g3, %o0
384         membar          #Sync
386         VISExitHalf
388         /* %o2 contains any final bytes still needed to be copied
389          * over. If anything is left, we copy it one byte at a time.
390          */
391         brz,pt          %o2, 85f
392          sub            %o0, %o1, %o3
393         ba,a,pt         %XCC, 90f
395         .align          64
396 75: /* 16 < len <= 64 */
397         bne,pn          %XCC, 75f
398          sub            %o0, %o1, %o3
401         andn            %o2, 0xf, %o4
402         and             %o2, 0xf, %o2
403 1:      subcc           %o4, 0x10, %o4
404         LOAD(ldx, %o1, %o5)
405         add             %o1, 0x08, %o1
406         LOAD(ldx, %o1, %g1)
407         sub             %o1, 0x08, %o1
408         STORE(stx, %o5, %o1 + %o3)
409         add             %o1, 0x8, %o1
410         STORE(stx, %g1, %o1 + %o3)
411         bgu,pt          %XCC, 1b
412          add            %o1, 0x8, %o1
413 73:     andcc           %o2, 0x8, %g0
414         be,pt           %XCC, 1f
415          nop
416         sub             %o2, 0x8, %o2
417         LOAD(ldx, %o1, %o5)
418         STORE(stx, %o5, %o1 + %o3)
419         add             %o1, 0x8, %o1
420 1:      andcc           %o2, 0x4, %g0
421         be,pt           %XCC, 1f
422          nop
423         sub             %o2, 0x4, %o2
424         LOAD(lduw, %o1, %o5)
425         STORE(stw, %o5, %o1 + %o3)
426         add             %o1, 0x4, %o1
427 1:      cmp             %o2, 0
428         be,pt           %XCC, 85f
429          nop
430         ba,pt           %xcc, 90f
431          nop
434         andcc           %o0, 0x7, %g1
435         sub             %g1, 0x8, %g1
436         be,pn           %icc, 2f
437          sub            %g0, %g1, %g1
438         sub             %o2, %g1, %o2
440 1:      subcc           %g1, 1, %g1
441         LOAD(ldub, %o1, %o5)
442         STORE(stb, %o5, %o1 + %o3)
443         bgu,pt          %icc, 1b
444          add            %o1, 1, %o1
446 2:      add             %o1, %o3, %o0
447         andcc           %o1, 0x7, %g1
448         bne,pt          %icc, 8f
449          sll            %g1, 3, %g1
451         cmp             %o2, 16
452         bgeu,pt         %icc, 72b
453          nop
454         ba,a,pt         %xcc, 73b
456 8:      mov             64, %o3
457         andn            %o1, 0x7, %o1
458         LOAD(ldx, %o1, %g2)
459         sub             %o3, %g1, %o3
460         andn            %o2, 0x7, %o4
461         sllx            %g2, %g1, %g2
462 1:      add             %o1, 0x8, %o1
463         LOAD(ldx, %o1, %g3)
464         subcc           %o4, 0x8, %o4
465         srlx            %g3, %o3, %o5
466         or              %o5, %g2, %o5
467         STORE(stx, %o5, %o0)
468         add             %o0, 0x8, %o0
469         bgu,pt          %icc, 1b
470          sllx           %g3, %g1, %g2
472         srl             %g1, 3, %g1
473         andcc           %o2, 0x7, %o2
474         be,pn           %icc, 85f
475          add            %o1, %g1, %o1
476         ba,pt           %xcc, 90f
477          sub            %o0, %o1, %o3
479         .align          64
480 80: /* 0 < len <= 16 */
481         andcc           %o3, 0x3, %g0
482         bne,pn          %XCC, 90f
483          sub            %o0, %o1, %o3
486         subcc           %o2, 4, %o2
487         LOAD(lduw, %o1, %g1)
488         STORE(stw, %g1, %o1 + %o3)
489         bgu,pt          %XCC, 1b
490          add            %o1, 4, %o1
492 85:     retl
493          mov            %g5, %o0
495         .align          32
497         subcc           %o2, 1, %o2
498         LOAD(ldub, %o1, %g1)
499         STORE(stb, %g1, %o1 + %o3)
500         bgu,pt          %XCC, 90b
501          add            %o1, 1, %o1
502         retl
503          mov            %g5, %o0
505 END(memcpy)
507 #define RMOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3)        \
508         ldx             [%src - offset - 0x20], %t0;            \
509         ldx             [%src - offset - 0x18], %t1;            \
510         ldx             [%src - offset - 0x10], %t2;            \
511         ldx             [%src - offset - 0x08], %t3;            \
512         stw             %t0, [%dst - offset - 0x1c];            \
513         srlx            %t0, 32, %t0;                           \
514         stw             %t0, [%dst - offset - 0x20];            \
515         stw             %t1, [%dst - offset - 0x14];            \
516         srlx            %t1, 32, %t1;                           \
517         stw             %t1, [%dst - offset - 0x18];            \
518         stw             %t2, [%dst - offset - 0x0c];            \
519         srlx            %t2, 32, %t2;                           \
520         stw             %t2, [%dst - offset - 0x10];            \
521         stw             %t3, [%dst - offset - 0x04];            \
522         srlx            %t3, 32, %t3;                           \
523         stw             %t3, [%dst - offset - 0x08];
525 #define RMOVE_BIGALIGNCHUNK(src, dst, offset, t0, t1, t2, t3)   \
526         ldx             [%src - offset - 0x20], %t0;            \
527         ldx             [%src - offset - 0x18], %t1;            \
528         ldx             [%src - offset - 0x10], %t2;            \
529         ldx             [%src - offset - 0x08], %t3;            \
530         stx             %t0, [%dst - offset - 0x20];            \
531         stx             %t1, [%dst - offset - 0x18];            \
532         stx             %t2, [%dst - offset - 0x10];            \
533         stx             %t3, [%dst - offset - 0x08];            \
534         ldx             [%src - offset - 0x40], %t0;            \
535         ldx             [%src - offset - 0x38], %t1;            \
536         ldx             [%src - offset - 0x30], %t2;            \
537         ldx             [%src - offset - 0x28], %t3;            \
538         stx             %t0, [%dst - offset - 0x40];            \
539         stx             %t1, [%dst - offset - 0x38];            \
540         stx             %t2, [%dst - offset - 0x30];            \
541         stx             %t3, [%dst - offset - 0x28];
543 #define RMOVE_LASTCHUNK(src, dst, offset, t0, t1, t2, t3)       \
544         ldx             [%src + offset + 0x00], %t0;            \
545         ldx             [%src + offset + 0x08], %t1;            \
546         stw             %t0, [%dst + offset + 0x04];            \
547         srlx            %t0, 32, %t2;                           \
548         stw             %t2, [%dst + offset + 0x00];            \
549         stw             %t1, [%dst + offset + 0x0c];            \
550         srlx            %t1, 32, %t3;                           \
551         stw             %t3, [%dst + offset + 0x08];
553 #define RMOVE_LASTALIGNCHUNK(src, dst, offset, t0, t1)          \
554         ldx             [%src + offset + 0x00], %t0;            \
555         ldx             [%src + offset + 0x08], %t1;            \
556         stx             %t0, [%dst + offset + 0x00];            \
557         stx             %t1, [%dst + offset + 0x08];
559         .align          32
560 228:    andcc           %o2, 1, %g0
561         be,pt           %icc, 2f+4
562 1:       ldub           [%o1 - 1], %o5
563         sub             %o1, 1, %o1
564         sub             %o0, 1, %o0
565         subcc           %o2, 1, %o2
566         be,pn           %XCC, 229f
567          stb            %o5, [%o0]
568 2:      ldub            [%o1 - 1], %o5
569         sub             %o0, 2, %o0
570         ldub            [%o1 - 2], %g5
571         sub             %o1, 2, %o1
572         subcc           %o2, 2, %o2
573         stb             %o5, [%o0 + 1]
574         bne,pt          %XCC, 2b
575          stb            %g5, [%o0]
576 229:    retl
577          mov            %g4, %o0
578 out:    retl
579          mov            %g5, %o0
581         .align          32
582 ENTRY(memmove)
583         mov             %o0, %g5
584 #ifndef USE_BPR
585         srl             %o2, 0, %o2
586 #endif
587         brz,pn          %o2, out
588          sub            %o0, %o1, %o4
589         cmp             %o4, %o2
590         bgeu,pt         %XCC, 218b
591          mov            %o0, %g4
592         add             %o0, %o2, %o0
593 220:    add             %o1, %o2, %o1
594         cmp             %o2, 15
595         bleu,pn         %XCC, 228b
596          andcc          %o0, 7, %g2
597         sub             %o0, %o1, %g5
598         andcc           %g5, 3, %o5
599         bne,pn          %XCC, 232f
600          andcc          %o1, 3, %g0
601         be,a,pt         %XCC, 236f
602          andcc          %o1, 4, %g0
603         andcc           %o1, 1, %g0
604         be,pn           %XCC, 4f
605          andcc          %o1, 2, %g0
606         ldub            [%o1 - 1], %g2
607         sub             %o1, 1, %o1
608         sub             %o0, 1, %o0
609         sub             %o2, 1, %o2
610         be,pn           %XCC, 5f
611          stb            %g2, [%o0]
612 4:      lduh            [%o1 - 2], %g2
613         sub             %o1, 2, %o1
614         sub             %o0, 2, %o0
615         sub             %o2, 2, %o2
616         sth             %g2, [%o0]
617 5:      andcc           %o1, 4, %g0
618 236:    be,a,pn         %XCC, 2f
619          andcc          %o2, -128, %g6
620         lduw            [%o1 - 4], %g5
621         sub             %o1, 4, %o1
622         sub             %o0, 4, %o0
623         sub             %o2, 4, %o2
624         stw             %g5, [%o0]
625         andcc           %o2, -128, %g6
626 2:      be,pn           %XCC, 235f
627          andcc          %o0, 4, %g0
628         be,pn           %XCC, 282f + 4
629 5:      RMOVE_BIGCHUNK(o1, o0, 0x00, g1, g3, g5, o5)
630         RMOVE_BIGCHUNK(o1, o0, 0x20, g1, g3, g5, o5)
631         RMOVE_BIGCHUNK(o1, o0, 0x40, g1, g3, g5, o5)
632         RMOVE_BIGCHUNK(o1, o0, 0x60, g1, g3, g5, o5)
633         subcc           %g6, 128, %g6
634         sub             %o1, 128, %o1
635         bne,pt          %XCC, 5b
636          sub            %o0, 128, %o0
637 235:    andcc           %o2, 0x70, %g6
638 41:     be,pn           %XCC, 280f
639          andcc          %o2, 8, %g0
641 279:    rd              %pc, %o5
642         sll             %g6, 1, %g5
643         sub             %o1, %g6, %o1
644         sub             %o5, %g5, %o5
645         jmpl            %o5 + %lo(280f - 279b), %g0
646          sub            %o0, %g6, %o0
647         RMOVE_LASTCHUNK(o1, o0, 0x60, g2, g3, g5, o5)
648         RMOVE_LASTCHUNK(o1, o0, 0x50, g2, g3, g5, o5)
649         RMOVE_LASTCHUNK(o1, o0, 0x40, g2, g3, g5, o5)
650         RMOVE_LASTCHUNK(o1, o0, 0x30, g2, g3, g5, o5)
651         RMOVE_LASTCHUNK(o1, o0, 0x20, g2, g3, g5, o5)
652         RMOVE_LASTCHUNK(o1, o0, 0x10, g2, g3, g5, o5)
653         RMOVE_LASTCHUNK(o1, o0, 0x00, g2, g3, g5, o5)
654 280:    be,pt           %XCC, 281f
655          andcc          %o2, 4, %g0
656         ldx             [%o1 - 8], %g2
657         sub             %o0, 8, %o0
658         stw             %g2, [%o0 + 4]
659         sub             %o1, 8, %o1
660         srlx            %g2, 32, %g2
661         stw             %g2, [%o0]
662 281:    be,pt           %XCC, 1f
663          andcc          %o2, 2, %g0
664         lduw            [%o1 - 4], %g2
665         sub             %o1, 4, %o1
666         stw             %g2, [%o0 - 4]
667         sub             %o0, 4, %o0
668 1:      be,pt           %XCC, 1f
669          andcc          %o2, 1, %g0
670         lduh            [%o1 - 2], %g2
671         sub             %o1, 2, %o1
672         sth             %g2, [%o0 - 2]
673         sub             %o0, 2, %o0
674 1:      be,pt           %XCC, 211f
675          nop
676         ldub            [%o1 - 1], %g2
677         stb             %g2, [%o0 - 1]
678 211:    retl
679          mov            %g4, %o0
681 282:    RMOVE_BIGALIGNCHUNK(o1, o0, 0x00, g1, g3, g5, o5)
682         RMOVE_BIGALIGNCHUNK(o1, o0, 0x40, g1, g3, g5, o5)
683         subcc           %g6, 128, %g6
684         sub             %o1, 128, %o1
685         bne,pt          %XCC, 282b
686          sub            %o0, 128, %o0
687         andcc           %o2, 0x70, %g6
688         be,pn           %XCC, 284f
689          andcc          %o2, 8, %g0
691 283:    rd              %pc, %o5
692         sub             %o1, %g6, %o1
693         sub             %o5, %g6, %o5
694         jmpl            %o5 + %lo(284f - 283b), %g0
695          sub            %o0, %g6, %o0
696         RMOVE_LASTALIGNCHUNK(o1, o0, 0x60, g2, g3)
697         RMOVE_LASTALIGNCHUNK(o1, o0, 0x50, g2, g3)
698         RMOVE_LASTALIGNCHUNK(o1, o0, 0x40, g2, g3)
699         RMOVE_LASTALIGNCHUNK(o1, o0, 0x30, g2, g3)
700         RMOVE_LASTALIGNCHUNK(o1, o0, 0x20, g2, g3)
701         RMOVE_LASTALIGNCHUNK(o1, o0, 0x10, g2, g3)
702         RMOVE_LASTALIGNCHUNK(o1, o0, 0x00, g2, g3)
703 284:    be,pt           %XCC, 285f
704          andcc          %o2, 4, %g0
705         ldx             [%o1 - 8], %g2
706         sub             %o0, 8, %o0
707         sub             %o1, 8, %o1
708         stx             %g2, [%o0]
709 285:    be,pt           %XCC, 1f
710          andcc          %o2, 2, %g0
711         lduw            [%o1 - 4], %g2
712         sub             %o0, 4, %o0
713         sub             %o1, 4, %o1
714         stw             %g2, [%o0]
715 1:      be,pt           %XCC, 1f
716          andcc          %o2, 1, %g0
717         lduh            [%o1 - 2], %g2
718         sub             %o0, 2, %o0
719         sub             %o1, 2, %o1
720         sth             %g2, [%o0]
721 1:      be,pt           %XCC, 1f
722          nop
723         ldub            [%o1 - 1], %g2
724         stb             %g2, [%o0 - 1]
725 1:      retl
726          mov            %g4, %o0
728 232:    ldub            [%o1 - 1], %g5
729         sub             %o1, 1, %o1
730         sub             %o0, 1, %o0
731         subcc           %o2, 1, %o2
732         bne,pt          %XCC, 232b
733          stb            %g5, [%o0]
734 234:    retl
735          mov            %g4, %o0
736 END(memmove)
738 #ifdef USE_BPR
739 weak_alias (memcpy, __align_cpy_1)
740 weak_alias (memcpy, __align_cpy_2)
741 weak_alias (memcpy, __align_cpy_4)
742 weak_alias (memcpy, __align_cpy_8)
743 weak_alias (memcpy, __align_cpy_16)
744 #endif
745 libc_hidden_builtin_def (memcpy)
746 libc_hidden_builtin_def (memmove)