32 |
|
|
33 |
*/ |
*/ |
34 |
|
|
35 |
|
/* $Id$ */ |
36 |
|
|
37 |
/** \ingroup avr_string |
/** \ingroup avr_string |
38 |
\fn size_t strlcat (char *dst, const char *src, size_t siz) |
\fn size_t strlcat (char *dst, const char *src, size_t siz) |
60 |
#define dlen_lo r18 |
#define dlen_lo r18 |
61 |
#define rWord_hi r25 |
#define rWord_hi r25 |
62 |
#define rWord_lo r24 |
#define rWord_lo r24 |
|
#define Z_hi r31 |
|
|
#define Z_lo r30 |
|
|
#define X_hi r27 |
|
|
#define X_lo r26 |
|
63 |
|
|
64 |
.text |
.text |
65 |
.global _U(strlcat) |
.global _U(strlcat) |
66 |
.type _U(strlcat),@function |
.type _U(strlcat),@function |
67 |
|
|
68 |
_U(strlcat): |
_U(strlcat): |
69 |
LOAD_X (dst_lo, dst_hi) ; X = dst |
X_movw XL, dst_lo ; X = dst |
70 |
LOAD_Z (src_lo, src_hi) ; Z = src |
X_movw ZL, src_lo ; Z = src |
71 |
|
|
72 |
.strlcat_dlen: ; Find end of dst string |
.L_strlcat_dlen: ; Find end of dst string |
73 |
ld __tmp_reg__, X+ ; get next char from dst |
ld __tmp_reg__, X+ ; get next char from dst |
74 |
cp siz_lo, __zero_reg__ ; and calc dlen = len of dst |
cp siz_lo, __zero_reg__ ; and calc dlen = len of dst |
75 |
cpc siz_hi, __zero_reg__ ; size == 0 ? |
cpc siz_hi, __zero_reg__ ; size == 0 ? |
78 |
breq 1f ; --> done |
breq 1f ; --> done |
79 |
subi siz_lo, lo8(-(-1)) |
subi siz_lo, lo8(-(-1)) |
80 |
sbci siz_hi, hi8(-(-1)) ; siz-- |
sbci siz_hi, hi8(-(-1)) ; siz-- |
81 |
rjmp .strlcat_dlen ; --> next char |
rjmp .L_strlcat_dlen ; --> next char |
82 |
1: sbiw X_lo, 1 ; undo post increment |
1: sbiw XL, 1 ; undo post increment |
83 |
#if __AVR_ENHANCED__ |
X_movw dlen_lo, XL |
|
movw dlen_lo, X_lo |
|
|
#else |
|
|
mov dlen_lo, X_lo |
|
|
mov dlen_hi, X_hi |
|
|
#endif |
|
84 |
sub dlen_lo, dst_lo |
sub dlen_lo, dst_lo |
85 |
sbc dlen_hi, dst_hi ; dlen = X - dst |
sbc dlen_hi, dst_hi ; dlen = X - dst |
86 |
cp siz_lo, __zero_reg__ |
cp siz_lo, __zero_reg__ |
87 |
cpc siz_hi, __zero_reg__ ; size == 0 ? |
cpc siz_hi, __zero_reg__ ; size == 0 ? |
88 |
breq .strlcat_slen ; --> done |
breq .L_strlcat_slen ; --> done |
89 |
subi siz_lo, lo8(-(-1)) |
subi siz_lo, lo8(-(-1)) |
90 |
sbci siz_hi, hi8(-(-1)) ; siz-- |
sbci siz_hi, hi8(-(-1)) ; siz-- |
91 |
|
|
92 |
.strlcat_concat: ; Concatenate |
.L_strlcat_concat: ; Concatenate |
93 |
ld __tmp_reg__, Z+ ; get next char from src |
ld __tmp_reg__, Z+ ; get next char from src |
94 |
cp siz_lo, __zero_reg__ |
cp siz_lo, __zero_reg__ |
95 |
cpc siz_hi, __zero_reg__ ; size == 0 ? |
cpc siz_hi, __zero_reg__ ; size == 0 ? |
99 |
st X+, __tmp_reg__ ; store in dest |
st X+, __tmp_reg__ ; store in dest |
100 |
subi siz_lo, lo8(-(-1)) |
subi siz_lo, lo8(-(-1)) |
101 |
sbci siz_hi, hi8(-(-1)) ; siz-- |
sbci siz_hi, hi8(-(-1)) ; siz-- |
102 |
rjmp .strlcat_concat ; --> next char |
rjmp .L_strlcat_concat ; --> next char |
103 |
1: st X, __zero_reg__ ; *X = '\0' |
1: st X, __zero_reg__ ; *X = '\0' |
104 |
sbiw Z_lo, 1 ; undo post increment |
sbiw ZL, 1 ; undo post increment |
105 |
|
|
106 |
.strlcat_slen: |
.L_strlcat_slen: |
107 |
ld __tmp_reg__, Z+ ; get next char from src |
ld __tmp_reg__, Z+ ; get next char from src |
108 |
tst __tmp_reg__ ; end of src ? |
tst __tmp_reg__ ; end of src ? |
109 |
brne .strlcat_slen ; --> next char |
brne .L_strlcat_slen ; --> next char |
110 |
sbiw Z_lo, 1 ; undo post increment |
sbiw ZL, 1 ; undo post increment |
111 |
#if __AVR_ENHANCED__ |
X_movw rWord_lo, dlen_lo |
112 |
movw rWord_lo, dlen_lo |
add rWord_lo, ZL |
113 |
#else |
adc rWord_hi, ZH |
|
mov rWord_lo, dlen_lo |
|
|
mov rWord_hi, dlen_hi |
|
|
#endif |
|
|
add rWord_lo, Z_lo |
|
|
adc rWord_hi, Z_hi |
|
114 |
sub rWord_lo, src_lo |
sub rWord_lo, src_lo |
115 |
sbc rWord_hi, src_hi ; return(dlen + (Z - src)) |
sbc rWord_hi, src_hi ; return(dlen + (Z - src)) |
116 |
ret |
ret |
117 |
|
|
118 |
.strlcat_end: |
.L_strlcat_end: |
119 |
.size _U(strlcat), .strlcat_end - _U(strlcat) |
.size _U(strlcat), .L_strlcat_end - _U(strlcat) |
120 |
|
|
121 |
#endif /* not __DOXYGEN__ */ |
#endif /* not __DOXYGEN__ */ |