Imported Upstream version 2.9.0
[debian/cc1111] / device / lib / _memset.c
1 /*-------------------------------------------------------------------------
2   _memset.c - part of string library functions
3
4              Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1999)
5                            mcs51 assembler by Frieder Ferlemann (2007)
6
7    This library is free software; you can redistribute it and/or modify it
8    under the terms of the GNU Library General Public License as published by the
9    Free Software Foundation; either version 2, or (at your option) any
10    later version.
11    
12    This library is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU Library General Public License for more details.
16    
17    You should have received a copy of the GNU Library General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20    
21    In other words, you are welcome to use, share and improve this program.
22    You are forbidden to forbid anyone else to use, share and improve
23    what you give them.   Help stamp out software-hoarding!  
24 -------------------------------------------------------------------------*/
25 #include "string.h" 
26
27 #if defined (_SDCC_NO_ASM_LIB_FUNCS) || !defined (SDCC_mcs51) || \
28     (!defined (SDCC_MODEL_SMALL) && !defined (SDCC_MODEL_LARGE)) || \
29      (defined (SDCC_STACK_AUTO) || defined (SDCC_PARMS_IN_BANK1) )
30
31   void * memset (
32           void * buf,
33           unsigned char ch ,
34           size_t count) 
35   {
36           register unsigned char * ret = buf;
37
38           while (count--) {
39                   *(unsigned char *) ret = ch;
40                   ret = ((unsigned char *) ret) + 1;
41           }
42
43           return buf ;
44   }
45
46 #else
47
48   /* assembler implementation for mcs51 */
49   static void dummy(void) __naked
50   {
51     __asm
52
53   /* assigning function parameters to registers.
54      SDCC_PARMS_IN_BANK1 or SDCC_STACK_AUTO not yet implemented. */
55   #if defined (SDCC_MODEL_SMALL)
56
57     #if defined(SDCC_NOOVERLAY)
58         .area DSEG    (DATA)
59     #else
60         .area OSEG    (OVR,DATA)
61     #endif
62         _memset_PARM_2::
63               .ds 1
64         _memset_PARM_3::
65               .ds 2
66
67         .area CSEG    (CODE)
68
69         _memset::
70
71         ;   Assign buf (b holds memspace, no need to touch)
72                 mov     r4,dpl
73                 mov     r5,dph
74                 ;
75         ;   Assign count
76                 mov     r6,_memset_PARM_3
77                 mov     r7,(_memset_PARM_3 + 1)
78                 ;
79         ;   if (!count) return buf;
80         ;   check for count != 0 intermangled with gymnastic
81         ;   preparing djnz instructions
82                 cjne    r6,#0x00,COUNT_LSB_NOT_ZERO
83                 mov     a,r7
84                 jz      MEMSET_END
85                 dec     r7
86         COUNT_LSB_NOT_ZERO:
87                 inc     r7
88                 ;
89                 ; This was 8 byte overhead for preparing
90                 ; the count argument for an integer loop with two
91                 ; djnz instructions - it might make sense to
92                 ; let SDCC automatically generate this when
93                 ; it encounters a loop like:
94                 ; for(i=0;i<j;i++){...}
95                 ; (at least for option --opt-code-speed)
96                 ;
97
98         ;   Assign ch
99                 mov     a,_memset_PARM_2
100
101   #else
102
103         .area XSEG    (XDATA)
104
105         _memset_PARM_2::
106                 .ds 1
107         _memset_PARM_3::
108                 .ds 2
109
110         .area CSEG    (CODE)
111
112         _memset::
113
114         ;   Assign buf (b holds memspace, no need to touch)
115                 mov     r4,dpl
116                 mov     r5,dph
117                 ;
118         ;   Assign count
119                 mov     dptr,#_memset_PARM_3
120                 movx    a,@dptr
121                 mov     r6,a
122                 inc     dptr
123                 movx    a,@dptr
124                 mov     r7,a
125                 ;
126         ;   if (!count) return buf;
127         ;   check for count != 0 intermangled with gymnastic
128         ;   preparing djnz instructions
129                 cjne    r6,#0x00,COUNT_LSB_NOT_ZERO
130         ;   acc holds r7
131                 jz      MEMSET_END
132                 dec     r7
133         COUNT_LSB_NOT_ZERO:
134                 inc     r7
135                 ;
136         ;   Assign ch
137                 mov     dptr,#_memset_PARM_2
138                 movx    a,@dptr
139         ;   acc is precious now
140                 ;
141         ;   Restore dptr
142                 mov     dpl,r4
143                 mov     dph,r5
144
145   #endif
146
147         /* now independent of the parameter passing everything
148            should be in registers by now and the loop may start */
149         ;   _memset.c do {
150
151         MEMSET_LOOP:
152         ;   _memset.c *p = ch;
153                 lcall   __gptrput
154
155         ;   _memset.c p++;
156                 inc     dptr
157
158         ;   _memset.c } while(--count) ;
159                 djnz    r6,MEMSET_LOOP
160                 djnz    r7,MEMSET_LOOP
161                 ;
162
163         MEMSET_END:
164         ;   _memset.c return buf ;
165                 ; b was unchanged
166                 mov     dpl,r4
167                 mov     dph,r5
168                 ;
169                 ret
170
171     __endasm;
172   }
173
174 #endif