| 32 |
|
|
| 33 |
*/ |
*/ |
| 34 |
|
|
| 35 |
|
/* $Id$ */ |
| 36 |
|
|
| 37 |
/** \ingroup avr_string |
/** \ingroup avr_string |
| 38 |
\fn size_t strlcpy (char *dst, const char *src, size_t siz) |
\fn size_t strlcpy (char *dst, const char *src, size_t siz) |
| 58 |
#define rWord r24 |
#define rWord r24 |
| 59 |
#define rWord_hi r25 |
#define rWord_hi r25 |
| 60 |
#define rWord_lo r24 |
#define rWord_lo r24 |
|
#define Z_hi r31 |
|
|
#define Z_lo r30 |
|
| 61 |
|
|
| 62 |
.text |
.text |
| 63 |
.global _U(strlcpy) |
.global _U(strlcpy) |
| 64 |
.type _U(strlcpy), @function |
.type _U(strlcpy), @function |
| 65 |
|
|
| 66 |
_U(strlcpy): |
_U(strlcpy): |
| 67 |
LOAD_X (dst_lo, dst_hi) ; X = dst |
X_movw XL, dst_lo ; X = dst |
| 68 |
LOAD_Z (src_lo, src_hi) ; Z = src |
X_movw ZL, src_lo ; Z = src |
| 69 |
cp siz_lo, __zero_reg__ |
cp siz_lo, __zero_reg__ |
| 70 |
cpc siz_hi, __zero_reg__ ; size == 0 ? |
cpc siz_hi, __zero_reg__ ; size == 0 ? |
| 71 |
breq .strlcpy_truncated |
breq .L_strlcpy_truncated |
| 72 |
|
|
| 73 |
.strlcpy_copy_loop: ; copy src to dst |
.L_strlcpy_copy_loop: ; copy src to dst |
| 74 |
subi siz_lo, lo8(-(-1)) |
subi siz_lo, lo8(-(-1)) |
| 75 |
sbci siz_hi, hi8(-(-1)) ; decrement siz |
sbci siz_hi, hi8(-(-1)) ; decrement siz |
| 76 |
breq 1f ; --> siz chars copied |
breq 1f ; --> siz chars copied |
| 77 |
ld __tmp_reg__, Z+ ; get next src char |
ld __tmp_reg__, Z+ ; get next src char |
| 78 |
st X+, __tmp_reg__ ; copy char |
st X+, __tmp_reg__ ; copy char |
| 79 |
tst __tmp_reg__ ; end of src string ? |
tst __tmp_reg__ ; end of src string ? |
| 80 |
breq .strlcpy_len ; --> all src chars copied |
breq .L_strlcpy_len ; --> all src chars copied |
| 81 |
rjmp .strlcpy_copy_loop ; next char |
rjmp .L_strlcpy_copy_loop ; next char |
| 82 |
1: st X, __zero_reg__ ; truncate dst string |
1: st X, __zero_reg__ ; truncate dst string |
| 83 |
|
|
| 84 |
.strlcpy_truncated: ; find Z = end of src string |
.L_strlcpy_truncated: ; find Z = end of src string |
| 85 |
ld __tmp_reg__, Z+ ; get next char from src |
ld __tmp_reg__, Z+ ; get next char from src |
| 86 |
tst __tmp_reg__ ; end of src string ? |
tst __tmp_reg__ ; end of src string ? |
| 87 |
brne .strlcpy_truncated ; next char |
brne .L_strlcpy_truncated ; next char |
| 88 |
|
|
| 89 |
.strlcpy_len: ; calculate strlen(src) |
.L_strlcpy_len: ; calculate strlen(src) |
| 90 |
sub Z_lo, src_lo |
sub ZL, src_lo |
| 91 |
sbc Z_hi, src_hi ; Z points past \0 |
sbc ZH, src_hi ; Z points past \0 |
| 92 |
sbiw Z_lo, 1 |
sbiw ZL, 1 |
| 93 |
#if __AVR_ENHANCED__ |
X_movw rWord, ZL |
|
movw rWord, Z_lo |
|
|
#else |
|
|
mov rWord_lo, Z_lo |
|
|
mov rWord_hi, Z_hi |
|
|
#endif |
|
| 94 |
ret |
ret |
| 95 |
|
|
| 96 |
.strlcpy_end: |
.L_strlcpy_end: |
| 97 |
.size _U(strlcpy), .strlcpy_end - _U(strlcpy) |
.size _U(strlcpy), .L_strlcpy_end - _U(strlcpy) |
| 98 |
|
|
| 99 |
#endif /* not DOXYGEN */ |
#endif /* not DOXYGEN */ |