1 /* ANSI C standard library function strcpy.
3 Copyright (c) 2001-2008 Tensilica Inc.
5 Permission is hereby granted, free of charge, to any person obtaining
6 a copy of this software and associated documentation files (the
7 "Software"), to deal in the Software without restriction, including
8 without limitation the rights to use, copy, modify, merge, publish,
9 distribute, sublicense, and/or sell copies of the Software, and to
10 permit persons to whom the Software is furnished to do so, subject to
11 the following conditions:
13 The above copyright notice and this permission notice shall be included
14 in all copies or substantial portions of the Software.
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
24 #include "xtensa-asm.h"
31 .type strcpy, @function
34 /* a2 = dst, a3 = src */
36 mov a10, a2 // leave dst in return value register
41 bbsi.l a3, 0, .Lsrc1mod2
42 bbsi.l a3, 1, .Lsrc2mod4
45 /* Check if the destination is aligned. */
47 bnone a10, a8, .Laligned
51 .Lsrc1mod2: // src address is odd
52 l8ui a8, a3, 0 // get byte 0
53 addi a3, a3, 1 // advance src pointer
54 s8i a8, a10, 0 // store byte 0
55 #if XTENSA_ESP32_PSRAM_CACHE_FIX
58 beqz a8, 1f // if byte 0 is zero
59 addi a10, a10, 1 // advance dst pointer
60 bbci.l a3, 1, .Lsrcaligned // if src is now word-aligned
62 .Lsrc2mod4: // src address is 2 mod 4
63 l8ui a8, a3, 0 // get byte 0
64 /* 1-cycle interlock */
65 s8i a8, a10, 0 // store byte 0
66 #if XTENSA_ESP32_PSRAM_CACHE_FIX
69 beqz a8, 1f // if byte 0 is zero
70 l8ui a8, a3, 1 // get byte 0
71 addi a3, a3, 2 // advance src pointer
72 s8i a8, a10, 1 // store byte 0
73 addi a10, a10, 2 // advance dst pointer
74 #if XTENSA_ESP32_PSRAM_CACHE_FIX
81 /* dst is word-aligned; src is word-aligned. */
85 #if XCHAL_HAVE_DENSITY
86 /* (2 mod 4) alignment for loop instruction */
88 /* (1 mod 4) alignment for loop instruction */
93 #if XCHAL_HAVE_DENSITY
94 _movi.n a8, 0 // set up for the maximum loop count
96 _movi a8, 0 // set up for the maximum loop count
98 loop a8, .Lz3 // loop forever (almost anyway)
99 l32i a8, a3, 0 // get word from src
100 addi a3, a3, 4 // advance src pointer
101 bnone a8, a4, .Lz0 // if byte 0 is zero
102 bnone a8, a5, .Lz1 // if byte 1 is zero
103 bnone a8, a6, .Lz2 // if byte 2 is zero
104 s32i a8, a10, 0 // store word to dst
105 #if XTENSA_ESP32_PSRAM_CACHE_FIX
109 bnone a8, a7, .Lz3 // if byte 3 is zero
110 addi a10, a10, 4 // advance dst pointer
112 #else /* !XCHAL_HAVE_LOOPS */
114 1: addi a10, a10, 4 // advance dst pointer
116 l32i a8, a3, 0 // get word from src
117 addi a3, a3, 4 // advance src pointer
118 bnone a8, a4, .Lz0 // if byte 0 is zero
119 bnone a8, a5, .Lz1 // if byte 1 is zero
120 bnone a8, a6, .Lz2 // if byte 2 is zero
121 s32i a8, a10, 0 // store word to dst
122 #if XTENSA_ESP32_PSRAM_CACHE_FIX
127 bany a8, a7, 1b // if byte 3 is zero
128 #endif /* !XCHAL_HAVE_LOOPS */
130 .Lz3: /* Byte 3 is zero. */
133 .Lz0: /* Byte 0 is zero. */
138 #if XTENSA_ESP32_PSRAM_CACHE_FIX
143 .Lz1: /* Byte 1 is zero. */
148 #if XTENSA_ESP32_PSRAM_CACHE_FIX
153 .Lz2: /* Byte 2 is zero. */
160 #if XTENSA_ESP32_PSRAM_CACHE_FIX
166 /* For now just use byte copy loop for the unaligned destination case. */
170 #if XCHAL_HAVE_DENSITY
171 /* (2 mod 4) alignment for loop instruction */
173 /* (1 mod 4) alignment for loop instruction */
181 #if XCHAL_HAVE_DENSITY
182 _movi.n a8, 0 // set up for the maximum loop count
184 _movi a8, 0 // set up for the maximum loop count
186 loop a8, 2f // loop forever (almost anyway)
192 #if XTENSA_ESP32_PSRAM_CACHE_FIX
204 /* This code is not functional yet. */
207 l32i a9, a2, 0 // load word from dst
209 ssa8b a9 // rotate by dst alignment so that
210 src a9, a9, a9 // shift in loop will put back in place
211 ssa8l a9 // shift left by byte*8
213 ssa8l a9 // rotate by dst alignment so that
214 src a9, a9, a9 // shift in loop will put back in place
215 ssa8b a9 // shift left by 32-byte*8
218 /* dst is word-aligned; src is unaligned. */
221 l32i a8, a3, 0 // get word from src
222 /* 1-cycle interlock */
223 bnone a8, a4, .Lu0 // if byte 0 is zero
224 bnone a8, a5, .Lu1 // if byte 1 is zero
225 bnone a8, a6, .Lu2 // if byte 2 is zero
226 src a9, a8, a9 // combine last word and this word
227 s32i a9, a10, 0 // store word to dst
228 bnone a8, a7, .Lu3 // if byte 3 is nonzero, iterate
229 l32i a9, a3, 4 // get word from src
230 addi a3, a3, 8 // advance src pointer
231 bnone a9, a4, .Lu4 // if byte 0 is zero
232 bnone a9, a5, .Lu5 // if byte 1 is zero
233 bnone a9, a6, .Lu6 // if byte 2 is zero
234 src a8, a9, a8 // combine last word and this word
235 s32i a8, a10, 4 // store word to dst
236 addi a10, a10, 8 // advance dst pointer
237 bany a8, a7, .Ldstunalignedloop // if byte 3 is nonzero, iterate
239 /* Byte 7 is zero. */
242 .Lu0: /* Byte 0 is zero. */
247 #if XTENSA_ESP32_PSRAM_CACHE_FIX
252 .Lu1: /* Byte 1 is zero. */
257 #if XTENSA_ESP32_PSRAM_CACHE_FIX
262 .Lu2: /* Byte 2 is zero. */
266 #if XTENSA_ESP32_PSRAM_CACHE_FIX
274 .size strcpy, . - strcpy