File: _memset.c

package info (click to toggle)
sdcc 4.2.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 105,232 kB
  • sloc: ansic: 956,095; cpp: 110,511; makefile: 59,314; sh: 29,875; asm: 17,178; perl: 12,136; yacc: 7,480; lisp: 1,672; python: 907; lex: 805; awk: 498; sed: 89
file content (300 lines) | stat: -rw-r--r-- 7,303 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
/*-------------------------------------------------------------------------
   _memset.c - part of string library functions

   Copyright (C) 1999, Sandeep Dutta . sandeep.dutta@usa.net
   Copyright (C) 2020, Sergey Belyashov sergey.belyashov@gmail.com
   mcs51 assembler by Frieder Ferlemann (2007)

   This library is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
   Free Software Foundation; either version 2, or (at your option) any
   later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this library; see the file COPYING. If not, write to the
   Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
   MA 02110-1301, USA.

   As a special exception, if you link this library with other files,
   some of which are compiled with SDCC, to produce an executable,
   this library does not by itself cause the resulting executable to
   be covered by the GNU General Public License. This exception does
   not however invalidate any other reasons why the executable file
   might be covered by the GNU General Public License.
-------------------------------------------------------------------------*/

#include <string.h>

#undef memset /* Avoid conflict with builtin memset() in Z80 and some related ports */

#if defined (_SDCC_NO_ASM_LIB_FUNCS) || !defined (__SDCC_mcs51) || \
    (!defined (__SDCC_MODEL_SMALL) && !defined (__SDCC_MODEL_LARGE)) || \
     (defined (__SDCC_STACK_AUTO) || defined (__SDCC_PARMS_IN_BANK1) )

#ifdef __SDCC_BROKEN_STRING_FUNCTIONS
void *memset (void *s, unsigned char c, size_t n)
#else
void *memset (void *s, int c, size_t n)
#endif

#if !defined (_SDCC_NO_ASM_LIB_FUNCS) && (\
              defined (__SDCC_z80) ||\
              defined (__SDCC_z180) ||\
              defined (__SDCC_z80n))
#ifdef __SDCC_BROKEN_STRING_FUNCTIONS      
#error Unimplemented broken string function
#endif    
__naked
{
  (void)s;
  (void)c;
  (void)n;
  __asm
    pop   iy
    pop   bc
    push  hl
    ld    a, c
    or    a, b
    jr    Z, end
    ld    (hl), e
    dec   bc
    ld    a, c
    or    a, b
    jr    Z, end
    ld    e, l
    ld    d, h
    inc   de
    ldir 
end:
    pop   de
    jp	(iy)
  __endasm;
}
#elif !defined (_SDCC_NO_ASM_LIB_FUNCS) && (\
              defined (__SDCC_ez80_z80) ||\
              defined (__SDCC_r2k) ||\
              defined (__SDCC_z3ka))

__naked
{
  (void)s;
  (void)c;
  (void)n;
  __asm
    pop   af
    pop   hl
#ifdef __SDCC_BROKEN_STRING_FUNCTIONS
    dec   sp
#endif
    pop   de
    pop   bc
    push  bc
    push  de
#ifdef __SDCC_BROKEN_STRING_FUNCTIONS
    inc   sp
#endif
    push  hl
    push  af
    ld    a, c
    or    a, b
    ret   Z
#ifdef __SDCC_BROKEN_STRING_FUNCTIONS
    ld    (hl), d
#else
    ld    (hl), e
#endif
    dec   bc
    ld    a, c
    or    a, b
    ret   Z
    push  hl
    ld    e, l
    ld    d, h
    inc   de
    ldir
    pop   hl
    ret
  __endasm;
}
#elif !defined (_SDCC_NO_ASM_LIB_FUNCS) && defined(__SDCC_sm83)
#ifdef __SDCC_BROKEN_STRING_FUNCTIONS      
#error Unimplemented broken string function
#endif  
__naked
{
	(void)s;
	(void)c;
	(void)n;
__asm
	ld	a, c
	ldhl	sp,	#2
	ld	c, (hl)
	inc	hl
	ld	b, (hl)
	ld	l, e
	ld	h, d
	inc	c
	inc	b
	jr	test
loop:
	ld	(hl+), a
test:
	dec	c
	jr	NZ, loop
	dec	b
	jr	NZ, loop
	ld	c, e
	ld	b, d
	pop	hl
	pop	af
	jp	(hl)
__endasm;
}
#else
{
  register size_t sz = n;
  if (sz != 0)
    {
      register char *dst = s;
      register char data = (char)c;
      do {
        *dst++ = data;
      } while (--sz);
    }
  return s;
}
#endif
#else

  /* assembler implementation for mcs51 */
  static void dummy(void) __naked
  {
    __asm

  /* assigning function parameters to registers.
     __SDCC_PARMS_IN_BANK1 or __SDCC_STACK_AUTO not yet implemented. */
  #if defined (__SDCC_MODEL_SMALL)

    #if defined(__SDCC_NOOVERLAY)
        .area DSEG    (DATA)
    #else
        .area OSEG    (OVR,DATA)
    #endif
        _memset_PARM_2::
              .ds 1
        _memset_PARM_3::
              .ds 2

        .area CSEG    (CODE)

        _memset::

        ;   Assign buf (b holds memspace, no need to touch)
                mov     r4,dpl
                mov     r5,dph
                ;
        ;   Assign count
                mov     r6,_memset_PARM_3
                mov     r7,(_memset_PARM_3 + 1)
                ;
        ;   if (!count) return buf;
        ;   check for count != 0 intermangled with gymnastic
        ;   preparing djnz instructions
                cjne    r6,#0x00,COUNT_LSB_NOT_ZERO
                mov     a,r7
                jz      MEMSET_END
                dec     r7
        COUNT_LSB_NOT_ZERO:
                inc     r7
                ;
                ; This was 8 byte overhead for preparing
                ; the count argument for an integer loop with two
                ; djnz instructions - it might make sense to
                ; let SDCC automatically generate this when
                ; it encounters a loop like:
                ; for(i=0;i<j;i++){...}
                ; (at least for option --opt-code-speed)
                ;

        ;   Assign ch
                mov     a,_memset_PARM_2

  #else

        .area XSEG    (XDATA)

        _memset_PARM_2::
                .ds 1
        _memset_PARM_3::
                .ds 2

        .area CSEG    (CODE)

        _memset::

        ;   Assign buf (b holds memspace, no need to touch)
                mov     r4,dpl
                mov     r5,dph
                ;
        ;   Assign count
                mov     dptr,#_memset_PARM_3
                movx    a,@dptr
                mov     r6,a
                inc     dptr
                movx    a,@dptr
                mov     r7,a
                ;
        ;   if (!count) return buf;
        ;   check for count != 0 intermangled with gymnastic
        ;   preparing djnz instructions
                cjne    r6,#0x00,COUNT_LSB_NOT_ZERO
        ;   acc holds r7
                jz      MEMSET_END
                dec     r7
        COUNT_LSB_NOT_ZERO:
                inc     r7
                ;
        ;   Assign ch
                mov     dptr,#_memset_PARM_2
                movx    a,@dptr
        ;   acc is precious now
                ;
        ;   Restore dptr
                mov     dpl,r4
                mov     dph,r5

  #endif

        /* now independent of the parameter passing everything
           should be in registers by now and the loop may start */
        ;   _memset.c do {

        MEMSET_LOOP:
        ;   _memset.c *p = ch;
                lcall   __gptrput

        ;   _memset.c p++;
                inc     dptr

        ;   _memset.c } while(--count) ;
                djnz    r6,MEMSET_LOOP
                djnz    r7,MEMSET_LOOP
                ;

        MEMSET_END:
        ;   _memset.c return buf ;
                ; b was unchanged
                mov     dpl,r4
                mov     dph,r5
                ;
                ret

    __endasm;
  }

#endif