1/* Copyright (c) 2006, Carlos Lamas
2
3   based on libc/pmstring/strlcpy_P.S which is
4   Copyright (c) 2003, Eric B. Weddington
5
6   All rights reserved.
7
8   Redistribution and use in source and binary forms, with or without
9   modification, are permitted provided that the following conditions are met:
10
11   * Redistributions of source code must retain the above copyright
12     notice, this list of conditions and the following disclaimer.
13   * Redistributions in binary form must reproduce the above copyright
14     notice, this list of conditions and the following disclaimer in
15     the documentation and/or other materials provided with the
16     distribution.
17   * Neither the name of the copyright holders nor the names of
18     contributors may be used to endorse or promote products derived
19     from this software without specific prior written permission.
20
21  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  POSSIBILITY OF SUCH DAMAGE.
32
33*/
34
35/* $Id: strlcpy_PF.S 2503 2016-02-07 22:59:47Z joerg_wunsch $ */
36
37#if !defined(__AVR_TINY__)
38
39#if !defined(__DOXYGEN__)
40
41#include "macros.inc"
42
43#define dst_b1		r25
44#define dst_b0		r24
45#define src_b3		r23
46#define src_b2		r22
47#define src_b1		r21
48#define src_b0		r20
49#define siz_b1		r19
50#define siz_b0		r18
51
52#define rWord_b1	r25
53#define rWord_b0	r24
54
55	.text
56	.global	_U(strlcpy_PF)
57	.type	_U(strlcpy_PF), @function
58
59_U(strlcpy_PF):
60
61	X_movw	ZL, src_b0		; Z = src
62	LPM_R0_ZPLUS_INIT src_b2
63	X_movw	XL, dst_b0		; X = dst
64	cp	siz_b0, __zero_reg__
65	cpc	siz_b0, __zero_reg__	; size == 0 ?
66	breq	.L_strlcpy_PF_truncated
67
68.L_strlcpy_PF_copy_loop:		; copy src to dst
69
70	subi	siz_b0, lo8(1)
71	sbci	siz_b1, hi8(1)		; decrement siz
72	breq	1f 			; --> siz chars copied
73	LPM_R0_ZPLUS_NEXT src_b2	; get next src char
74	st	X+, r0			; copy char
75	tst	r0			; end of src string ?
76	breq	.L_strlcpy_PF_len	; --> all src chars copied
77	rjmp	.L_strlcpy_PF_copy_loop	; next char
781:	st	X, __zero_reg__		; truncate dst string
79
80.L_strlcpy_PF_truncated:		; find Z = end of src string
81
82	LPM_R0_ZPLUS_NEXT src_b2	; get next char from src
83	tst	r0			; end of src string ?
84	brne	.L_strlcpy_PF_truncated	; next char
85
86.L_strlcpy_PF_len:			; calculate strlen(src)
87
88	sub	ZL, src_b0
89	sbc	ZH, src_b1		; Z points past \0
90	sbiw	ZL, 1
91	X_movw	rWord_b0, ZL
92	ret
93
94.L_strlcpy_PF_end:
95
96	.size	_U(strlcpy_PF), .L_strlcpy_PF_end - _U(strlcpy_PF)
97
98#endif /* not __DOXYGEN__ */
99
100#endif /* !defined(__AVR_TINY__) */
101