OpenCores
URL https://opencores.org/ocsvn/s6soc/s6soc/trunk

Subversion Repositories s6soc

[/] [s6soc/] [trunk/] [sw/] [zipos/] [string.c] - Blame information for rev 48

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 48 dgisselq
////////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    string.c
4
//
5
// Project:     CMod S6 System on a Chip, ZipCPU demonstration project
6
//
7
// Purpose:     To provide *some* of the C-library's capabilities, without
8
//              using perfectly optimal functions--but rather simple things that
9
//      can be easily tested and debugged.
10
//
11
// Creator:     Dan Gisselquist, Ph.D.
12
//              Gisselquist Technology, LLC
13
//
14
////////////////////////////////////////////////////////////////////////////////
15
//
16
// Copyright (C) 2017, Gisselquist Technology, LLC
17
//
18
// This program is free software (firmware): you can redistribute it and/or
19
// modify it under the terms of  the GNU General Public License as published
20
// by the Free Software Foundation, either version 3 of the License, or (at
21
// your option) any later version.
22
//
23
// This program is distributed in the hope that it will be useful, but WITHOUT
24
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
25
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
26
// for more details.
27
//
28
// You should have received a copy of the GNU General Public License along
29
// with this program.  (It's in the $(ROOT)/doc directory.  Run make with no
30
// target there if the PDF file isn't present.)  If not, see
31
// <http://www.gnu.org/licenses/> for a copy.
32
//
33
// License:     GPL, v3, as defined and found on www.gnu.org,
34
//              http://www.gnu.org/licenses/gpl.html
35
//
36
//
37
////////////////////////////////////////////////////////////////////////////////
38
//
39
//
40
#include "string.h"
41
#include "txfns.h"
42
 
43
char *
44
strcpy(char *dst, const char *src) {
45
        char    v, *d = dst;
46
        do {
47
                *dst++ = (v = *src++);
48
        } while(v);
49
 
50
        return d;
51
}
52
 
53
char *
54
strcat(char *dst, const char *src) {
55
        char    v, *d = dst;
56
        do {
57
                v = *dst++;
58
        } while(v);
59
 
60
        dst--;
61
        strcpy(dst, src);
62
 
63
        return d;
64
}
65
 
66
#ifdef  C_STRING_FNS
67
size_t
68
strlen(const char *str) {
69
        size_t  ln = 0;
70
        while(*str++)
71
                ln++;
72
        return ln;
73
}
74
#else
75
asm("\t.section\t.text\n"
76
        "\t.global\tstrlen\n"
77
"strlen:\n"
78
        "\tMOV\tR1,R2\n"
79
        "\tCLR\tR1\n"
80
".Lstrlen_loop:\n"
81
        "\tLB\t(R2),R3\n"
82
        "\tCMP\t0,R3\n"
83
        "\tRTN.Z\n"
84
        "\tADD\t1,R2\n"
85
        "\tADD\t1,R1\n"
86
        "\tBRA\t.Lstrlen_loop\n");
87
#endif
88
 
89
#ifdef  C_STRING_FNS
90
void    *memcpy(void *dest, const void *src, size_t ln) {
91
        char    *d = dest; const char *s = src;
92
 
93
/*
94
        if (((((unsigned)d ^ (unsigned)s)&3)==0)&&(ln>4)) {
95
                // Source and destination are aligned with each other
96
 
97
                // Align them to a word boundary
98
                int n = (3-(((unsigned)d)&3));
99
                ln -= n;
100
                while(n>0) {
101
                        *d++ = *s++; n--;
102
                }
103
 
104
                int *id = (int *)d;
105
                const int *is = (const int *)s;
106
                while(ln >= 4) {
107
                        *id++ = *is++; ln-=4;
108
                } d = (char *)id; s = (const char *)is;
109
        }
110
*/
111
 
112
        while(ln > 0) {
113
                *d++ = *s++; ln--;
114
        } return dest;
115
}
116
#else
117
asm("\t.section\t.text\n"
118
        "\t.global\tmemcpy\n"
119
"memcpy:\n"
120
        "\tCMP  0,R3\n"
121
        "\tRTN.Z\n"
122
        "\tMOV\tR1,R4\n"
123
        "\tSUB  4,SP\n"
124
        "\tSW   R5,(SP)\n"
125
        //
126
        "\tTST\t3,R2\n"
127
        "\tBZ\t.Lpre_aligned\n"
128
        "\tLB\t(R2),R5\n"
129
        "\tSB\tR5,(R4),R5\n"
130
        "\tADD\t1,R2\n"
131
        "\tADD\t1,R4\n"
132
        "\tSUB\t1,R3\n"
133
        "\tBZ\t.Lmemcpy_epilogue\n"
134
        //
135
        "\tTST\t3,R2\n"
136
        "\tBZ\t.Lpre_aligned\n"
137
        "\tLB\t(R2),R5\n"
138
        "\tSB\tR5,(R4),R5\n"
139
        "\tADD\t1,R2\n"
140
        "\tADD\t1,R4\n"
141
        "\tSUB\t1,R3\n"
142
        "\tBZ\t.Lmemcpy_epilogue\n"
143
        //
144
        "\tTST\t3,R2\n"
145
        "\tBZ\t.Lpre_aligned\n"
146
        "\tLB\t(R2),R5\n"
147
        "\tSB\tR5,(R4),R5\n"
148
        "\tADD\t1,R2\n"
149
        "\tADD\t1,R4\n"
150
        "\tSUB\t1,R3\n"
151
        "\tBZ\t.Lmemcpy_epilogue\n"
152
        //
153
".Lpre_aligned:\n"
154
        "\tTST\t1,R4\n"
155
        "\tBNZ\t.Lmemcpy_unaligned\n"
156
        "\tTST\t2,R4\n"
157
        "\tBNZ\t.Lmemcpy_half_aligned\n"
158
".Lmemcpy_highspeed:\n"
159
        "\tSUB\t32,R3\n"
160
        "\tBLT\t.Lend_of_high_speed\n"
161
        //
162
        "\tLW\t(R2),R5\n"
163
        "\tSW\tR5,(R4)\n"
164
        "\tLW\t4(R2),R5\n"
165
        "\tSW\tR5,4(R4)\n"
166
        "\tLW\t8(R2),R5\n"
167
        "\tSW\tR5,8(R4)\n"
168
        "\tLW\t12(R2),R5\n"
169
        "\tSW\tR5,12(R4)\n"
170
        //
171
        "\tLW\t16(R2),R5\n"
172
        "\tSW\tR5,16(R4)\n"
173
        "\tLW\t20(R2),R5\n"
174
        "\tSW\tR5,20(R4)\n"
175
        "\tLW\t24(R2),R5\n"
176
        "\tSW\tR5,24(R4)\n"
177
        "\tLW\t28(R2),R5\n"
178
        "\tSW\tR5,28(R4)\n"
179
        //
180
        "\tADD\t32,R2\n"
181
        "\tADD\t32,R4\n"
182
        "\tBRA\t.Lmemcpy_highspeed\n"
183
".Lend_of_high_speed:\n"
184
        "\tADD\t32,R3\n"
185
".Lmemcpy_half_aligned:\n"
186
        "\tSUB\t4,R3\n"
187
        "\tBLT\t.Lend_of_short_speed\n"
188
        "\tLH\t(R2),R5\n"
189
        "\tSH\tR5,(R4)\n"
190
        "\tLH\t2(R2),R5\n"
191
        "\tSH\tR5,2(R4)\n"
192
        "\tADD\t4,R2\n"
193
        "\tADD\t4,R4\n"
194
        "\tBRA\t.Lmemcpy_half_aligned\n"
195
".Lend_of_short_speed:\n"
196
        "\tADD\t4,R3\n"
197
".Lmemcpy_unaligned:\n"
198
        "\tSUB\t1,R3\n"
199
        "\tBLT\t.Lmemcpy_epilogue\n"
200
        "\tLB\t(R2),R5\n"
201
        "\tSB\tR5,(R4)\n"
202
        "\tADD\t1,R2\n"
203
        "\tADD\t1,R4\n"
204
        "\tBRA\t.Lmemcpy_unaligned\n"
205
".Lmemcpy_epilogue:\n"
206
        "\tLW\t(SP),R5\n"
207
        "\tADD\t4,SP\n"
208
        "\tRETN\n"
209
);
210
/*
211
asm("\t.section\t.text\n"
212
        "\t.global\tmemcpy\n"
213
"memcpy:\n"
214
        "\tCMP  0,R3\n"
215
        "\tRTN.Z\n"
216
        "\tSUB  8,SP\n"
217
        "\tSW   R5,(SP)\n"
218
#define HIGH_SPEED_MEMCPY
219
#ifdef  HIGH_SPEED_MEMCPY
220
        "\tSW   R6,4(SP)\n"
221
        "\tMOV  R1,R4\n"
222
        "\tXOR  R2,R4\n"
223
        "\tTEST 3,R4\n"
224
        "\tBNZ  .Lmemcpy_unaligned\n"
225
        "\tCMP  8,R3\n"
226
        "\tBLT  .Lmemcpy_unaligned\n"
227
 
228
        // n = 3+ ~((unsigned)d&3)+1
229
        "\tMOV\tR1,R4\n"
230
        "\tAND\t3,R4\n"
231
        "\tLDI\t3,R5\n"
232
        "\tSUB\tR4,R5"  "\t; R5 = n\n"
233
        "\tMOV\tR1,R4"  "\t; R4 = d\n"
234
        "\tBZ\t.Lmemcpy_n_is_zero\n"
235
 
236
        "\tSUB\tR5,R3"  "\t; ln -= n\n"
237
        "\tTEST\t1,R5\n"
238
        "\tLB.NZ\t(R2),R6\n"
239
        "\tSB.NZ\tR6,(R4)\n"
240
        "\tADD.NZ\t1,R4\n"
241
        "\tADD.NZ\t1,R2\n"
242
        "\tTEST\t2,R5\n"
243
        "\tLH.NZ\t(R2),R6\n"
244
        "\tSH.NZ\tR6,(R4)\n"
245
        "\tADD.NZ\t2,R4\n"
246
        "\tADD.NZ\t2,R2\n"
247
 
248
".Lmemcpy_n_is_zero:\n"
249
".Lmemcpy_word_loop:\n"
250
        "\tSUB\t4,R3\n"
251
        "\tBLT\t.Lmemcpy_pretail\n"
252
        "\tLW\t(R4),R5\n"
253
        "\tSW\tR5,(R2)\n"
254
        "\tADD\t4,R4\n"
255
        "\tADD\t4,R2\n"
256
        "\tBRA\t.Lmemcpy_word_loop\n"
257
".Lmemcpy_pretail:\n"
258
        "\tADD\t4,R3\n"
259
        "\tBZ\t.Lmemcpy_epilogue\n"
260
        "\tBRA\t.Lmemcpy_unaligned_loop\n"
261
 
262
".Lmemcpy_unaligned:\n"
263
        "\tCMP  0,R3\n"
264
        "\tBZ   .Lmemcpy_epilogue\n"
265
#endif
266
        "\tMOV\tR1,R4\n"
267
".Lmemcpy_unaligned_loop:\n"
268
        "\tLB\t(R2),R5\n"
269
        "\tSB\tR5,(R4)\n"
270
        "\tADD\t1,R4\n"
271
        "\tADD\t1,R2\n"
272
        "\tSUB\t1,R3\n"
273
        "\tBNZ\t.Lmemcpy_unaligned_loop\n"
274
".Lmemcpy_epilogue:\n"
275
        "\tLW\t(SP),R5\n"
276
#ifdef  HIGH_SPEED_MEMCPY
277
        "\tLW\t4(SP),R6\n"
278
#endif
279
        "\tADD\t8,SP\n"
280
        "\tRTN\n"
281
);
282
*/
283
#endif
284
 
285
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.