]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/uclibc/lib/contrib/uclibc/libc/string/xtensa/strcpy.S
update
[l4.git] / l4 / pkg / uclibc / lib / contrib / uclibc / libc / string / xtensa / strcpy.S
1 /* Optimized strcpy for Xtensa.
2    Copyright (C) 2001, 2007 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <http://www.gnu.org/licenses/>.  */
18
19 #include <sysdep.h>
20 #include <bits/xtensa-config.h>
21
22 #ifdef __XTENSA_EB__
23 #define MASK0 0xff000000
24 #define MASK1 0x00ff0000
25 #define MASK2 0x0000ff00
26 #define MASK3 0x000000ff
27 #else
28 #define MASK0 0x000000ff
29 #define MASK1 0x0000ff00
30 #define MASK2 0x00ff0000
31 #define MASK3 0xff000000
32 #endif
33
34         .text
35 ENTRY (strcpy)
36         /* a2 = dst, a3 = src */
37
38         mov     a10, a2         /* leave dst in return value register */
39         movi    a4, MASK0
40         movi    a5, MASK1
41         movi    a6, MASK2
42         movi    a7, MASK3
43         bbsi.l  a3, 0, .Lsrc1mod2
44         bbsi.l  a3, 1, .Lsrc2mod4
45 .Lsrcaligned:
46
47         /* Check if the destination is aligned.  */
48         movi    a8, 3
49         bnone   a10, a8, .Laligned
50
51         j       .Ldstunaligned
52
53 .Lsrc1mod2: /* src address is odd */
54         l8ui    a8, a3, 0       /* get byte 0 */
55         addi    a3, a3, 1       /* advance src pointer */
56         s8i     a8, a10, 0      /* store byte 0 */
57         beqz    a8, 1f          /* if byte 0 is zero */
58         addi    a10, a10, 1     /* advance dst pointer */
59         bbci.l  a3, 1, .Lsrcaligned /* if src is now word-aligned */
60
61 .Lsrc2mod4: /* src address is 2 mod 4 */
62         l8ui    a8, a3, 0       /* get byte 0 */
63         /* 1-cycle interlock */
64         s8i     a8, a10, 0      /* store byte 0 */
65         beqz    a8, 1f          /* if byte 0 is zero */
66         l8ui    a8, a3, 1       /* get byte 0 */
67         addi    a3, a3, 2       /* advance src pointer */
68         s8i     a8, a10, 1      /* store byte 0 */
69         addi    a10, a10, 2     /* advance dst pointer */
70         bnez    a8, .Lsrcaligned
71 1:      retw
72
73
74 /* dst is word-aligned; src is word-aligned.  */
75
76         .align  4
77 #if XCHAL_HAVE_LOOPS
78         /* (2 mod 4) alignment for loop instruction */
79 .Laligned:
80         _movi.n a8, 0           /* set up for the maximum loop count */
81         loop    a8, .Lz3        /* loop forever (almost anyway) */
82         l32i    a8, a3, 0       /* get word from src */
83         addi    a3, a3, 4       /* advance src pointer */
84         bnone   a8, a4, .Lz0    /* if byte 0 is zero */
85         bnone   a8, a5, .Lz1    /* if byte 1 is zero */
86         bnone   a8, a6, .Lz2    /* if byte 2 is zero */
87         s32i    a8, a10, 0      /* store word to dst */
88         bnone   a8, a7, .Lz3    /* if byte 3 is zero */
89         addi    a10, a10, 4     /* advance dst pointer */
90
91 #else /* !XCHAL_HAVE_LOOPS */
92
93 1:      addi    a10, a10, 4     /* advance dst pointer */
94 .Laligned:
95         l32i    a8, a3, 0       /* get word from src */
96         addi    a3, a3, 4       /* advance src pointer */
97         bnone   a8, a4, .Lz0    /* if byte 0 is zero */
98         bnone   a8, a5, .Lz1    /* if byte 1 is zero */
99         bnone   a8, a6, .Lz2    /* if byte 2 is zero */
100         s32i    a8, a10, 0      /* store word to dst */
101         bany    a8, a7, 1b      /* if byte 3 is zero */
102 #endif /* !XCHAL_HAVE_LOOPS */
103
104 .Lz3:   /* Byte 3 is zero.  */
105         retw
106
107 .Lz0:   /* Byte 0 is zero.  */
108 #ifdef __XTENSA_EB__
109         movi    a8, 0
110 #endif
111         s8i     a8, a10, 0
112         retw
113
114 .Lz1:   /* Byte 1 is zero.  */
115 #ifdef __XTENSA_EB__
116         extui   a8, a8, 16, 16
117 #endif
118         s16i    a8, a10, 0
119         retw
120
121 .Lz2:   /* Byte 2 is zero.  */
122 #ifdef __XTENSA_EB__
123         extui   a8, a8, 16, 16
124 #endif
125         s16i    a8, a10, 0
126         movi    a8, 0
127         s8i     a8, a10, 2
128         retw
129
130         .align  4
131         /* (2 mod 4) alignment for loop instruction */
132 .Ldstunaligned:
133
134 #if XCHAL_HAVE_LOOPS
135         _movi.n a8, 0           /* set up for the maximum loop count */
136         loop    a8, 2f          /* loop forever (almost anyway) */
137 #endif
138 1:      l8ui    a8, a3, 0
139         addi    a3, a3, 1
140         s8i     a8, a10, 0
141         addi    a10, a10, 1
142 #if XCHAL_HAVE_LOOPS
143         beqz    a8, 2f
144 #else
145         bnez    a8, 1b
146 #endif
147 2:      retw
148
149 libc_hidden_def (strcpy)