32 |
|
|
33 |
*/ |
*/ |
34 |
|
|
35 |
|
/* $Id$ */ |
36 |
|
|
37 |
/** \ingroup avr_pgmspace |
/** \ingroup avr_pgmspace |
38 |
\fn size_t strlcpy_P (char *dst, PGM_P, size_t siz) |
\fn size_t strlcpy_P (char *dst, PGM_P, size_t siz) |
46 |
|
|
47 |
#if !defined(__DOXYGEN__) |
#if !defined(__DOXYGEN__) |
48 |
|
|
|
#include "gasava.inc" |
|
49 |
#include "macros.inc" |
#include "macros.inc" |
50 |
|
|
51 |
#define dst_hi r25 |
#define dst_hi r25 |
65 |
.type _U(strlcpy_P), @function |
.type _U(strlcpy_P), @function |
66 |
|
|
67 |
_U(strlcpy_P): |
_U(strlcpy_P): |
68 |
LOAD_X (dst_lo, dst_hi) ; X = dst |
X_movw XL, dst_lo ; X = dst |
69 |
LOAD_Z (src_lo, src_hi) ; Z = src |
X_movw ZL, src_lo ; Z = src |
70 |
cp siz_lo, __zero_reg__ |
cp siz_lo, __zero_reg__ |
71 |
cpc siz_hi, __zero_reg__ ; size == 0 ? |
cpc siz_hi, __zero_reg__ ; size == 0 ? |
72 |
breq .strlcpy_P_truncated |
breq .L_strlcpy_P_truncated |
73 |
|
|
74 |
.strlcpy_P_copy_loop: ; copy src to dst |
.L_strlcpy_P_copy_loop: ; copy src to dst |
75 |
subi siz_lo, lo8(-(-1)) |
subi siz_lo, lo8(-(-1)) |
76 |
sbci siz_hi, hi8(-(-1)) ; decrement siz |
sbci siz_hi, hi8(-(-1)) ; decrement siz |
77 |
breq 1f ; --> siz chars copied |
breq 1f ; --> siz chars copied |
78 |
LPM_R0_ZP ; get next src char |
LPM_R0_ZP ; get next src char |
79 |
st X+, __tmp_reg__ ; copy char |
st X+, __tmp_reg__ ; copy char |
80 |
tst __tmp_reg__ ; end of src string ? |
tst __tmp_reg__ ; end of src string ? |
81 |
breq .strlcpy_P_len ; --> all src chars copied |
breq .L_strlcpy_P_len ; --> all src chars copied |
82 |
rjmp .strlcpy_P_copy_loop ; next char |
rjmp .L_strlcpy_P_copy_loop ; next char |
83 |
1: st X, __zero_reg__ ; truncate dst string |
1: st X, __zero_reg__ ; truncate dst string |
84 |
|
|
85 |
.strlcpy_P_truncated: ; find Z = end of src string |
.L_strlcpy_P_truncated: ; find Z = end of src string |
86 |
LPM_R0_ZP ; get next char from src |
LPM_R0_ZP ; get next char from src |
87 |
tst __tmp_reg__ ; end of src string ? |
tst __tmp_reg__ ; end of src string ? |
88 |
brne .strlcpy_P_truncated ; next char |
brne .L_strlcpy_P_truncated ; next char |
89 |
|
|
90 |
.strlcpy_P_len: ; calculate strlen(src) |
.L_strlcpy_P_len: ; calculate strlen(src) |
91 |
sub Z_lo, src_lo |
sub Z_lo, src_lo |
92 |
sbc Z_hi, src_hi ; Z points past \0 |
sbc Z_hi, src_hi ; Z points past \0 |
93 |
sbiw Z_lo, 1 |
sbiw Z_lo, 1 |
94 |
#if __AVR_ENHANCED__ |
X_movw rWord, Z_lo |
|
movw rWord, Z_lo |
|
|
#else |
|
|
mov rWord_lo, Z_lo |
|
|
mov rWord_hi, Z_hi |
|
|
#endif |
|
95 |
ret |
ret |
96 |
|
|
97 |
.strlcpy_P_end: |
.L_strlcpy_P_end: |
98 |
.size _U(strlcpy_P), .strlcpy_P_end - _U(strlcpy_P) |
.size _U(strlcpy_P), .L_strlcpy_P_end - _U(strlcpy_P) |
99 |
|
|
100 |
#endif /* not __DOXYGEN__ */ |
#endif /* not __DOXYGEN__ */ |