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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [newlib-1.17.0/] [newlib/] [libc/] [machine/] [i960/] [strcpy_ca.S] - Blame information for rev 862

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 148 jeremybenn
/*******************************************************************************
2
 *
3
 * Copyright (c) 1993 Intel Corporation
4
 *
5
 * Intel hereby grants you permission to copy, modify, and distribute this
6
 * software and its documentation.  Intel grants this permission provided
7
 * that the above copyright notice appears in all copies and that both the
8
 * copyright notice and this permission notice appear in supporting
9
 * documentation.  In addition, Intel grants this permission provided that
10
 * you prominently mark as "not part of the original" any modifications
11
 * made to this software or documentation, and that the name of Intel
12
 * Corporation not be used in advertising or publicity pertaining to
13
 * distribution of the software or the documentation without specific,
14
 * written prior permission.
15
 *
16
 * Intel Corporation provides this AS IS, WITHOUT ANY WARRANTY, EXPRESS OR
17
 * IMPLIED, INCLUDING, WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY
18
 * OR FITNESS FOR A PARTICULAR PURPOSE.  Intel makes no guarantee or
19
 * representations regarding the use of, or the results of the use of,
20
 * the software and documentation in terms of correctness, accuracy,
21
 * reliability, currentness, or otherwise; and you rely on the software,
22
 * documentation and results solely at your own risk.
23
 *
24
 * IN NO EVENT SHALL INTEL BE LIABLE FOR ANY LOSS OF USE, LOSS OF BUSINESS,
25
 * LOSS OF PROFITS, INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES
26
 * OF ANY KIND.  IN NO EVENT SHALL INTEL'S TOTAL LIABILITY EXCEED THE SUM
27
 * PAID TO INTEL FOR THE PRODUCT LICENSED HEREUNDER.
28
 *
29
 ******************************************************************************/
30
 
31
        .file "strcp_ca.s"
32
#ifdef  __PIC
33
        .pic
34
#endif
35
#ifdef  __PID
36
        .pid
37
#endif
38
/*
39
 * (c) copyright 1988,1993 Intel Corp., all rights reserved
40
 */
41
 
42
/*
43
        procedure strcpy  (optimized assembler version for the CA)
44
 
45
        dest_addr = strcpy (dest_addr, src_addr)
46
 
47
        copy the null terminated string pointed to by src_addr to
48
        the string space pointed to by dest_addr.  Return the original
49
        dest_addr.
50
 
51
        This routine will fail if the source and destination string
52
        overlap (in particular, if the end of the source is overlapped
53
        by the beginning of the destination).  The behavior is undefined.
54
        This is acceptable according to the draft C standard.
55
 
56
        Undefined behavior will also occur if the end of the source string
57
        (i.e. the terminating null byte) is in the last word of the program's
58
        allocated memory space.  This is so because, in several cases, strcpy
59
        will fetch ahead one word.  Disallowing the fetch ahead would impose
60
        a severe performance penalty.
61
 
62
        This program handles five cases:
63
 
64
        1) both arguments start on a word boundary
65
        2) neither are word aligned, but they are offset by the same amount
66
        3) source is word aligned, destination is not
67
        4) destination is word aligned, source is not
68
        5) neither is word aligned, and they are offset by differing amounts
69
 
70
        At the time of this writing, only g0 thru g7 and g13 are available
71
        for use in this leafproc;  other registers would have to be saved and
72
        restored.  These nine registers, plus tricky use of g14 are sufficient
73
        to implement the routine.  The registers are used as follows:
74
 
75
        g0  original dest ptr;  not modified, so that it may be returned.
76
        g1  src ptr;  shift count
77
        g2  dest ptr;  4 bytes of src
78
        g3  src ptr (word aligned)
79
        g4  dest ptr (word aligned)
80
        g5  0xff  --  byte extraction mask
81
        g6  lsw of double word for extraction of 4 bytes (little endian)
82
            msw of double word for extraction of 4 bytes (big endian)
83
        g7  msw of double word for extraction of 4 bytes (little endian)
84
            lsw of double word for extraction of 4 bytes (big endian)
85
        g13 return address
86
        g14 byte extracted.  When reaches null byte, which is zero, we will
87
            be in conformance with register conventions, and can return to
88
            the caller with a clear conscience.
89
 
90
        procedure strcat
91
 
92
        dest_addr = strcat (dest_addr, src_addr)
93
 
94
        Appends the string pointed to by src_addr to the string pointed
95
        to by dest_addr.  The first character of the source string is
96
        copied to the location initially occupied by the trailing null
97
        byte of the destination string.  Thereafter, characters are copied
98
        from the source to the destination up thru the null byte that
99
        trails the source string.
100
*/
101
 
102
#if __i960_BIG_ENDIAN__
103
#define MSW g6
104
#define LSW g7
105
#else
106
#define LSW g6
107
#define MSW g7
108
#endif
109
 
110
        .globl  _strcpy, _strcat
111
        .globl  __strcpy, __strcat
112
        .leafproc       _strcpy, __strcpy
113
        .leafproc       _strcat, __strcat
114
        .align  2
115
_strcat:
116
#ifndef __PIC
117
        lda     Lrett,g14
118
#else
119
        lda     Lrett-(.+8)(ip),g14
120
#endif
121
__strcat:
122
        notand  g0,3,g4         # extract word addr of start of dest
123
        lda     (g14),g13       # preserve return address
124
        and     g0,3,LSW        # extract byte offset of dest
125
        ld      (g4),MSW        # fetch word containing at least first byte
126
        shlo    3,LSW,g14       # get shift count for making mask for first word
127
        subi    1,0,LSW         # mask initially all ones
128
#if __i960_BIG_ENDIAN__
129
        shro    g14,LSW,LSW     # get mask for bytes needed from first word
130
        lda     0xff000000,g5   # byte extraction mask
131
#else
132
        shlo    g14,LSW,LSW     # get mask for bytes needed from first word
133
        lda     0xff,g5         # byte extraction mask
134
#endif
135
        notor   MSW,LSW,MSW     # set unneeded bytes to all ones
136
Lsearch_for_word_with_null:
137
        scanbyte 0,MSW          # check for null byte
138
        lda     4(g4),g4        # post-increment dest word pointer
139
        mov     MSW,LSW         # keep a copy of current word
140
        ld      (g4),MSW        # fetch next word of dest
141
        bno.t   Lsearch_for_word_with_null      # branch if null not found yet
142
        and     g5,LSW,g14      # extract byte
143
        cmpo    0,g14           # branch if null is first byte of word
144
        subo    4,g4,g4         # move dest word ptr back to word with null
145
        notand  g1,3,g3         # extract word addr of start of src
146
        lda     (g4),g2         # set dest byte ptr to 1st byte of word w/ null
147
        be.f    Lcase_14
148
Lsearch_for_null:
149
#if __i960_BIG_ENDIAN__
150
        shro    8,g5,g5         # move mask down to next byte
151
#else
152
        shlo    8,g5,g5         # move mask up to next byte
153
#endif
154
        lda     1(g2),g2        # move dest byte ptr to next byte
155
        and     g5,LSW,g14      # extract byte
156
        cmpobne.t 0,g14,Lsearch_for_null        # branch if null is not yet found
157
        lda     0xff,g5         # byte extraction mask
158
        b       Lcase_235.a
159
 
160
 
161
_strcpy:
162
#ifndef __PIC
163
        lda     Lrett,g14
164
#else
165
        lda     Lrett-(.+8)(ip),g14
166
#endif
167
__strcpy:
168
        notand  g0,3,g4         # extract word addr of start of dest
169
        lda     (g14),g13       # preserve return address
170
        cmpo    g0,g4           # check alignment of dest
171
        lda     0xff,g5         # load mask for byte extraction
172
        notand  g1,3,g3         # extract word addr of start of src
173
        bne.f   Lcase_235       # branch if dest is NOT word aligned
174
 
175
Lcase_14:
176
        cmpo    g3,g1           # check alignment of src
177
        ld      (g3),LSW        # fetch word containing at least first byte
178
        shlo    3,g1,g1         # compute shift count
179
        lda     4(g3),g3        # advance src word addr
180
#if __i960_BIG_ENDIAN__
181
        lda     0xff,g5         # byte extraction mask
182
#endif
183
        bne.f   Lcase_4         # branch if src is NOT word aligned
184
 
185
Lcase_1:                                # src and dest are word aligned
186
        subo    4,g4,g4         # store is pre-incrementing;  back up dest addr
187
Lcase_1_wloop:                  # word copying loop
188
        scanbyte 0,LSW          # check for null byte in src word
189
        lda     (LSW),g2        # keep a copy of the src word
190
        addo    4,g4,g4         # pre-increment dest addr
191
        ld      (g3),LSW        # pre-fetch next word of src
192
        addo    4,g3,g3         # post-increment src addr
193
        bo.f    Lcase_1_cloop   # branch if word contains null byte
194
        st      g2,(g4)         # store word in dest string
195
        b       Lcase_1_wloop
196
 
197
Lcase_3_cloop:
198
Lcase_1_cloop:                  # character copying loop
199
#if __i960_BIG_ENDIAN__
200
        rotate  8,g2,g2         # move next byte into position for extraction
201
        and     g5,g2,g14       # extract next char
202
#else
203
        and     g5,g2,g14       # extract next char
204
        shro    8,g2,g2         # move next byte into position for extraction
205
#endif
206
        cmpo    0,g14           # check for null byte
207
        stob    g14,(g4)        # store the byte in dest
208
        lda     1(g4),g4        # post-increment dest byte addr
209
        bne.t   Lcase_1_cloop   # branch if null not reached
210
 
211
Lexit_code:
212
        bx      (g13)           # g0 = addr of dest;  g14 = 0
213
Lrett:
214
        ret
215
 
216
Lcase_3:                                # src is word aligned; dest is not
217
        addo    4,g4,g4         # move dest word ptr to first word boundary
218
        mov     LSW,MSW         # make copy of first word of src
219
        lda     0,g1            # initialize shift count to zero
220
 
221
Lcase_25:
222
Lcase_3_cloop_at_start:         # character copying loop for start of dest str
223
#if __i960_BIG_ENDIAN__
224
        rotate  8,MSW,MSW       # move next byte into position for extraction
225
        and     g5,MSW,g14      # extract next char
226
#else
227
        and     g5,MSW,g14      # extract next char
228
        shro    8,MSW,MSW       # move next byte into position for extraction
229
#endif
230
        cmpo    0,g14           # check for null byte
231
        stob    g14,(g2)        # store the byte in dest
232
        lda     1(g2),g2        # post-increment dest ptr
233
        be.f    Lexit_code      # branch if null byte reached
234
        cmpo    g2,g4           # have we reached word boundary in dest?
235
        lda     8(g1),g1        # augment the shift counter
236
        bne.t   Lcase_3_cloop_at_start
237
 
238
Lcase_4:
239
        ld      (g3),MSW        # fetch msw of operand for double shift
240
#if __i960_BIG_ENDIAN__
241
        subo    g1,0,g1         # Adjust shift count for big endian.
242
#endif
243
 
244
Lcase_3_wloop:
245
        eshro   g1,g6,g2        # extract 4 bytes of src
246
        lda     4(g3),g3        # post-increment src word addr
247
        scanbyte 0,g2           # check for null byte
248
        lda     (MSW),LSW       # move msw to lsw
249
        ld      (g3),MSW        # pre-fetch msw of operand for double shift
250
        bo.f    Lcase_3_cloop   # branch if word contains null byte
251
        st      g2,(g4)         # store 4 bytes to dest
252
        addo    4,g4,g4         # post-increment dest ptr
253
        b       Lcase_3_wloop
254
 
255
Lcase_235:
256
        lda     (g0),g2         # copy dest ptr
257
Lcase_235.a:
258
        cmpo    g3,g1           # check alignment of src
259
        ld      (g3),LSW        # fetch word containing at least first byte
260
        and     3,g1,g14        # compute shift count
261
        lda     4(g3),g3        # advance src word addr
262
        shlo    3,g14,g1
263
        be.t    Lcase_3         # branch if dest is word aligned
264
        or      g4,g14,g14      # is src earlier in word, later, or sync w/ dst
265
        ld      (g3),MSW        # pre-fetch second half
266
        cmpo    g2,g14          # < indicates first word of dest has more bytes
267
        lda     4(g4),g4        # move dest word addr to first word boundary
268
                                /* than first word of source. */
269
#if __i960_BIG_ENDIAN__
270
        subo    g1,0,g14        # Adjust shift count for big endian.
271
        eshro   g14,g6,g14      # extract four bytes
272
        bge.f   1f
273
#else
274
        eshro   g1,g6,g14       # extract four bytes
275
        bg.f    1f
276
#endif
277
        mov     MSW,LSW
278
        lda     4(g3),g3        # move src word addr to second word boundary
279
1:
280
        mov     g14,MSW
281
        b       Lcase_25
282
 
283
/* end of strcpy */
284
 

powered by: WebSVN 2.1.0

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