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

Subversion Repositories openrisc

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

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 "sncmp_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 strncmp  (optimized assembler version for the CA)
44
 
45
        result = strncmp (src1_addr, src2_addr, max_bytes)
46
 
47
        compare the null terminated string pointed to by src1_addr to
48
        the string space pointed to by src2_addr.  Return 0 iff the strings
49
        are equal, -1 if src1_addr is lexicly less than src2_addr, and 1
50
        if it is lexicly greater.  Do not compare more than max_bytes bytes.
51
 
52
        Undefined behavior will occur if the end of either source string
53
        (i.e. the terminating null byte) is in the last word of the program's
54
        allocated memory space.  This is so because, in several cases, strncmp
55
        will fetch ahead one word.  Disallowing the fetch ahead would impose
56
        a severe performance penalty.
57
 
58
        This program handles five cases:
59
 
60
        1) both arguments start on a word boundary
61
        2) neither are word aligned, but they are offset by the same amount
62
        3) source1 is word aligned, source2 is not
63
        4) source2 is word aligned, source1 is not
64
        5) neither is word aligned, and they are offset by differing amounts
65
 
66
        At the time of this writing, only g0 thru g7 and g14 are available
67
        for use in this leafproc;  other registers would have to be saved and
68
        restored.  These nine registers are sufficient to implement the routine.
69
        The registers are used as follows:
70
 
71
        g0  original src1 ptr;  extracted word;  return result
72
        g1  src2 ptr;  0xff  --  byte extraction mask
73
        g2  maximum number of bytes to compare
74
        g3  src2 word ptr
75
        Little endian:
76
                g4  lsw of src1
77
                g5  msw of src1
78
                g6  src2 word
79
                g7  src1 word ptr
80
        Big endian:
81
                g4  msw of src1
82
                g5  lsw of src1
83
                g6  src1 word ptr
84
                g7  src2 word
85
        g13 return address
86
        g14 shift count
87
*/
88
 
89
#if __i960_BIG_ENDIAN__
90
#define MSW g4
91
#define LSW g5
92
#define SRC1 g6
93
#define SRC2 g7
94
#else
95
#define LSW g4
96
#define MSW g5
97
#define SRC2 g6
98
#define SRC1 g7
99
#endif
100
 
101
        .globl  _strncmp
102
        .globl  __strncmp
103
        .leafproc       _strncmp, __strncmp
104
        .align  2
105
_strncmp:
106
#ifndef __PIC
107
        lda     Lrett,g14
108
#else
109
        lda     Lrett-(.+8)(ip),g14
110
#endif
111
__strncmp:
112
Lrestart:
113
        notand  g0,3,SRC1       # extract word addr of start of src1
114
         lda    (g14),g13       # preserve return address
115
         cmpibge.f 0,g2,Lequal_exit     # return equality if number of bytes to
116
                                        /* compare is none. */
117
#if __i960_BIG_ENDIAN__
118
        cmpo    g0,SRC1         # check alignment of src1
119
#endif
120
         ld     (SRC1),LSW      # fetch word with at least first byte of src1
121
        notand  g1,3,g3         # extract word addr of start of src2
122
         ld     4(SRC1),MSW     # fetch second word of src1
123
#if __i960_BIG_ENDIAN__
124
         bne    Lsrc1_unaligned # branch if src1 is unaligned
125
        cmpo    g3,g1           # check alignment of src2
126
         ld     (g3),SRC2       # fetch word with at least first byte of src2
127
        shlo    3,g0,g14        # compute shift count for src1
128
        subo    g14,0,g14       # adjust shift count for big endian
129
         lda    8(SRC1),SRC1    # advance src1 word addr
130
         bne.f  Lsrc2_unaligned # branch if src2 is NOT word aligned
131
 
132
                                /* src2 is word aligned */
133
 
134
        mov     LSW,g0
135
 
136
Lwloop2:                                # word comparing loop
137
        cmpo    SRC2,g0         # compare src1 and src2 words
138
         lda    0xff000000,g1   # byte extraction mask
139
        mov     MSW,LSW         # move msw of src1 to lsw
140
         ld     (SRC1),MSW      # pre-fetch next msw of src1
141
        addo    4,SRC1,SRC1     # post-increment src1 addr
142
         lda    4(g3),g3        # pre-increment src2 addr
143
         bne.f  Lcloop          # branch if src1 and src2 unequal
144
        scanbyte 0,g0           # check for null byte in src1 word
145
         ld     (g3),SRC2       # pre-fetch next word of src2
146
        mov     LSW,g0          # extract word of src1
147
         subi   4,g2,g2         # decrement maximum byte count
148
        bo.f    Lequal_exit     # branch if null byte encountered
149
        cmpibl.t 0,g2,Lwloop2   # branch if max_bytes not reached yet
150
 
151
        b       Lequal_exit     # strings were equal up through max_bytes
152
 
153
Lsrc1_unaligned:
154
#endif
155
        cmpo    g3,g1           # check alignment of src2
156
         ld     (g3),SRC2       # fetch word with at least first byte of src2
157
        shlo    3,g0,g14        # compute shift count for src1
158
#if __i960_BIG_ENDIAN__
159
        subo    g14,0,g14       # adjust shift count for big endian
160
#endif
161
        eshro   g14,g4,LSW      # extract word of src1
162
         lda    8(SRC1),SRC1    # advance src1 word addr
163
         bne.f  Lsrc2_unaligned # branch if src2 is NOT word aligned
164
 
165
                                /* at least src2 is word aligned */
166
 
167
        mov     LSW,g0
168
 
169
Lwloop:                         # word comparing loop
170
        cmpo    SRC2,g0         # compare src1 and src2 words
171
#if __i960_BIG_ENDIAN__
172
         lda    0xff000000,g1   # byte extraction mask
173
#else
174
         lda    0xff,g1         # byte extraction mask
175
#endif
176
        mov     MSW,LSW         # move msw of src1 to lsw
177
         ld     (SRC1),MSW      # pre-fetch next msw of src1
178
        addo    4,SRC1,SRC1     # post-increment src1 addr
179
         lda    4(g3),g3        # pre-increment src2 addr
180
         bne.f  Lcloop          # branch if src1 and src2 unequal
181
        scanbyte 0,g0           # check for null byte in src1 word
182
         ld     (g3),SRC2       # pre-fetch next word of src2
183
        eshro   g14,g4,g0       # extract word of src1
184
         subi   4,g2,g2         # decrement maximum byte count
185
        bo.f    Lequal_exit     # branch if null byte encountered
186
        cmpibl.t 0,g2,Lwloop    # branch if max_bytes not reached yet
187
 
188
        b       Lequal_exit     # strings were equal up through max_bytes
189
 
190
Lcloop_setup:                   # setup for coming from Lsrc2_unaligned
191
        mov     LSW,g0          # restore extracted src1 word
192
#if __i960_BIG_ENDIAN__
193
         lda    0xff000000,g1   # byte extraction mask
194
#else
195
         lda    0xff,g1         # byte extraction mask
196
#endif
197
 
198
Lcloop:                         # character comparing loop
199
        and     SRC2,g1,g3      # extract next char of src2
200
        and     g0,g1,LSW       # extract next char of src1
201
        cmpobne.f LSW,g3,.diff  # check for equality
202
        cmpo    0,LSW           # check for null byte
203
#if __i960_BIG_ENDIAN__
204
        shro    8,g1,g1         # shift mask for next byte
205
#else
206
        shlo    8,g1,g1         # shift mask for next byte
207
#endif
208
        subi    1,g2,g2         # decrement character counter
209
         bne.t  Lcloop          # branch if null not reached
210
 
211
                                /* words are equal up thru null byte */
212
 
213
Lequal_exit:
214
        mov     0,g14           # conform to register conventions
215
         lda    0,g0            # return zero, indicating equality
216
        bx      (g13)           # return
217
 
218
Lrett:
219
        ret
220
 
221
.diff:
222
        mov     0,g14
223
         bl     Lless_than_exit
224
Lgreater_than_exit:
225
        cmpibge.f 0,g2,Lequal_exit  # branch if difference is beyond max_bytes
226
        mov     1,g0
227
         bx     (g13)           # g0 = 1 (src1 > src2)
228
Lless_than_exit:
229
        cmpibge.f 0,g2,Lequal_exit  # branch if difference is beyond max_bytes
230
        subi    1,0,g0
231
         bx     (g13)           # g0 = -1 (src1 < src2)
232
 
233
Lsrc2_unaligned:
234
        notor   g1,3,g14        # first step in computing new src1 ptr
235
         ld     4(g3),SRC1      # fetch second word of src2
236
        shlo    3,g1,MSW        # compute shift count for src2
237
#if __i960_BIG_ENDIAN__
238
        subo    MSW,0,MSW       # adjust shift count for big endian
239
#endif
240
        eshro   MSW,g6,SRC2     # extract word of src2
241
        cmpo    LSW,SRC2        # compare src1 and src2 words
242
         lda    4(g3),g1        # set new src2 ptr
243
         bne.f  Lcloop_setup    # first four bytes differ
244
        scanbyte 0,LSW          # check for null byte
245
        subo    g14,g0,g0       # second (final) step in computing new src1 ptr
246
        addi    g14,g2,g2       # compute new max_bytes too
247
         lda    (g13),g14       # prepare return pointer for Lrestart
248
         bno.t  Lrestart                # if null byte not encountered, continue
249
                                /* with both string fetches shifted such that*/
250
                                /* src2 is now word aligned.*/
251
        mov     0,g14           # conform to register conventions.
252
         lda    0,g0            # return indicator of equality.
253
        bx      (g13)

powered by: WebSVN 2.1.0

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