Hackfix and re-enable strtoull and wcstoull, see bug #3798.
[sdcc.git] / sdcc / device / lib / _memset.c
blob87b1f3180ec27be4f141c33308af2454c09bb645
1 /*-------------------------------------------------------------------------
2 _memset.c - part of string library functions
4 Copyright (C) 1999, Sandeep Dutta . sandeep.dutta@usa.net
5 Copyright (C) 2020, Sergey Belyashov sergey.belyashov@gmail.com
6 Copyright (C) 2022, Sebastian 'basxto' Riedel
7 mcs51 assembler by Frieder Ferlemann (2007)
9 This library is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
12 later version.
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this library; see the file COPYING. If not, write to the
21 Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
22 MA 02110-1301, USA.
24 As a special exception, if you link this library with other files,
25 some of which are compiled with SDCC, to produce an executable,
26 this library does not by itself cause the resulting executable to
27 be covered by the GNU General Public License. This exception does
28 not however invalidate any other reasons why the executable file
29 might be covered by the GNU General Public License.
30 -------------------------------------------------------------------------*/
32 #include <stdlib.h>
33 #include <string.h>
35 #undef memset /* Avoid conflict with builtin memset() in Z80 and some related ports */
37 #if defined (_SDCC_NO_ASM_LIB_FUNCS) || !defined (__SDCC_mcs51) || \
38 (!defined (__SDCC_MODEL_SMALL) && !defined (__SDCC_MODEL_LARGE)) || \
39 (defined (__SDCC_STACK_AUTO) || defined (__SDCC_PARMS_IN_BANK1) )
41 #ifdef __SDCC_BROKEN_STRING_FUNCTIONS
42 void *memset (void *s, unsigned char c, size_t n)
43 #else
44 void *memset (void *s, int c, size_t n)
45 #endif
47 #if !defined (_SDCC_NO_ASM_LIB_FUNCS) && (\
48 defined (__SDCC_z80) ||\
49 defined (__SDCC_z180) ||\
50 defined (__SDCC_z80n) ||\
51 defined (__SDCC_r800))
52 #ifdef __SDCC_BROKEN_STRING_FUNCTIONS
53 #error Unimplemented broken string function
54 #endif
55 __naked
57 (void)s;
58 (void)c;
59 (void)n;
60 __asm
61 pop iy
62 pop bc
63 push hl
64 ld a, c
65 or a, b
66 jr Z, end
67 ld (hl), e
68 dec bc
69 ld a, c
70 or a, b
71 jr Z, end
72 ld e, l
73 ld d, h
74 inc de
75 ldir
76 end:
77 pop de
78 jp (iy)
79 __endasm;
81 #elif !defined (_SDCC_NO_ASM_LIB_FUNCS) && defined(__SDCC_sm83)
82 __naked
84 (void)s;//de
85 (void)c;//bc or for broken string function in a
86 (void)n;//stack+2, stack+3
87 __asm
88 ; Algorithm is Duff`s device
89 ldhl sp, #3
90 __endasm;
91 #ifdef __SDCC_BROKEN_STRING_FUNCTIONS
92 __asm
93 ld b, (hl)
94 dec hl
95 __endasm;
96 #else
97 __asm
99 ld a, (hl-)
100 ld b, a
101 ld a, c
102 __endasm;
103 #endif
104 __asm
105 ld c, (hl)
106 ld l, e
107 ld h, d
108 ;shift LSB to carry
109 srl b
110 rr c
111 jr nc, skip_one
112 ld (hl+), a
113 skip_one:
114 ;n/2 in bc
115 ;shift second LSB to carry
116 srl b
117 rr c
118 ;n/4 in bc
119 inc b
120 inc c
121 jr nc, test
122 jr copy_two
123 copy_four:
124 ld (hl+), a
125 ld (hl+), a
126 copy_two:
127 ld (hl+), a
128 ld (hl+), a
129 test:
130 dec c
131 jr NZ, copy_four
132 dec b
133 jr NZ, copy_four
134 ;restore dest
135 ld c, e
136 ld b, d
137 pop hl
138 pop af
139 jp (hl)
140 __endasm;
142 #else
144 register size_t sz = n;
145 if (sz != 0)
147 register char *dst = s;
148 register char data = (char)c;
149 do {
150 *dst++ = data;
151 } while (--sz);
153 return s;
155 #endif
156 #else
158 /* assembler implementation for mcs51 */
159 static void dummy(void) __naked
161 __asm
163 /* assigning function parameters to registers.
164 __SDCC_PARMS_IN_BANK1 or __SDCC_STACK_AUTO not yet implemented. */
165 #if defined (__SDCC_MODEL_SMALL)
167 #if defined(__SDCC_NOOVERLAY)
168 .area DSEG (DATA)
169 #else
170 .area OSEG (OVR,DATA)
171 #endif
172 _memset_PARM_2::
173 .ds 1
174 _memset_PARM_3::
175 .ds 2
177 .area CSEG (CODE)
179 _memset::
181 ; Assign buf (b holds memspace, no need to touch)
182 mov r4,dpl
183 mov r5,dph
185 ; Assign count
186 mov r6,_memset_PARM_3
187 mov r7,(_memset_PARM_3 + 1)
189 ; if (!count) return buf;
190 ; check for count != 0 intermangled with gymnastic
191 ; preparing djnz instructions
192 cjne r6,#0x00,COUNT_LSB_NOT_ZERO
193 mov a,r7
194 jz MEMSET_END
195 dec r7
196 COUNT_LSB_NOT_ZERO:
197 inc r7
199 ; This was 8 byte overhead for preparing
200 ; the count argument for an integer loop with two
201 ; djnz instructions - it might make sense to
202 ; let SDCC automatically generate this when
203 ; it encounters a loop like:
204 ; for(i=0;i<j;i++){...}
205 ; (at least for option --opt-code-speed)
208 ; Assign ch
209 mov a,_memset_PARM_2
211 #else
213 .area XSEG (XDATA)
215 _memset_PARM_2::
216 .ds 1
217 _memset_PARM_3::
218 .ds 2
220 .area CSEG (CODE)
222 _memset::
224 ; Assign buf (b holds memspace, no need to touch)
225 mov r4,dpl
226 mov r5,dph
228 ; Assign count
229 mov dptr,#_memset_PARM_3
230 movx a,@dptr
231 mov r6,a
232 inc dptr
233 movx a,@dptr
234 mov r7,a
236 ; if (!count) return buf;
237 ; check for count != 0 intermangled with gymnastic
238 ; preparing djnz instructions
239 cjne r6,#0x00,COUNT_LSB_NOT_ZERO
240 ; acc holds r7
241 jz MEMSET_END
242 dec r7
243 COUNT_LSB_NOT_ZERO:
244 inc r7
246 ; Assign ch
247 mov dptr,#_memset_PARM_2
248 movx a,@dptr
249 ; acc is precious now
251 ; Restore dptr
252 mov dpl,r4
253 mov dph,r5
255 #endif
257 /* now independent of the parameter passing everything
258 should be in registers by now and the loop may start */
259 ; _memset.c do {
261 MEMSET_LOOP:
262 ; _memset.c *p = ch;
263 lcall __gptrput
265 ; _memset.c p++;
266 inc dptr
268 ; _memset.c } while(--count) ;
269 djnz r6,MEMSET_LOOP
270 djnz r7,MEMSET_LOOP
273 MEMSET_END:
274 ; _memset.c return buf ;
275 ; b was unchanged
276 mov dpl,r4
277 mov dph,r5
281 __endasm;
284 #endif