source: trunk/libs/newlib/src/newlib/libc/machine/i960/strcmp_ca.S @ 444

Last change on this file since 444 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 7.8 KB
Line 
1/*******************************************************************************
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 "strcm_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 strcmp  (optimized assembler version for the CA)
44
45        result = strcmp (src1_addr, src2_addr)
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.
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, strcmp
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;  return result
72        g1  src2 ptr;  0xff  --  byte extraction mask
73        g2  src1 word ptr
74        g3  src2 word ptr
75        Little endian:
76                g4  lsw of src1
77                g5  msw of src1
78                g6  src2 word
79                g7  extracted src1
80        Big endian:
81                g4  msw of src1
82                g5  lsw of src1
83                g6  extracted src1
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  _strcmp
102        .globl  __strcmp
103        .leafproc       _strcmp, __strcmp
104        .align  2
105_strcmp:
106#ifndef __PIC
107        lda     Lrett,g14
108#else
109        lda     Lrett-(.+8)(ip),g14
110#endif
111
112__strcmp:
113Lrestart:
114        notand  g0,3,g2         # extract word addr of start of src1
115         lda    (g14),g13       # preserve return address
116#if __i960_BIG_ENDIAN__
117        cmpo    g0,g2           # check alignment of src1
118#endif
119         ld     (g2),LSW        # fetch word with at least first byte of src1
120        notand  g1,3,g3         # extract word addr of start of src2
121         ld     4(g2),MSW       # fetch second word of src1
122#if __i960_BIG_ENDIAN__
123         bne    Lsrc1_unaligned # branch if src1 is unaligned
124        cmpo    g3,g1           # check alignment of src2
125         ld     (g3),SRC2       # fetch word with at least first byte of src2
126        mov     LSW,SRC1        # extract word of src1
127         lda    8(g2),g2        # advance src1 word addr
128         bne.f  Lsrc2_unaligned # branch if src2 is NOT word aligned
129
130                                /* src2 is word aligned */
131
132Lwloop2:                                # word comparing loop
133        cmpo    SRC2,SRC1       # compare src1 and src2 words
134         lda    0xff000000,g1   # byte extraction mask
135        mov     MSW,LSW         # move msw of src1 to lsw
136         ld     (g2),MSW        # pre-fetch next msw of src1
137        addo    4,g2,g2         # post-increment src1 addr
138         lda    4(g3),g3        # pre-increment src2 addr
139         bne.f  Lcloop          # branch if src1 and src2 unequal
140        scanbyte 0,SRC1         # check for null byte in src1 word
141         ld     (g3),SRC2       # pre-fetch next word of src2
142        mov     LSW,SRC1        # extract word of src1
143         lda    0,g0            # prepare to return zero, indicating equality
144        bno.t   Lwloop2         # branch if null byte not encountered
145
146                                /* words were equal and contained null byte */
147
148        mov     0,g14           # conform to register conventions
149         bx     (g13)           # return
150       
151
152Lsrc1_unaligned:
153#endif
154        cmpo    g3,g1           # check alignment of src2
155         ld     (g3),SRC2       # fetch word with at least first byte of src2
156        shlo    3,g0,g14        # compute shift count for src1
157#if __i960_BIG_ENDIAN__
158        subo    g14,0,g14       # 32 - shift count for big endian.
159#endif
160        eshro   g14,g4,SRC1     # extract word of src1
161         lda    8(g2),g2        # advance src1 word addr
162         bne.f  Lsrc2_unaligned # branch if src2 is NOT word aligned
163
164                                /* at least src2 is word aligned */
165
166Lwloop:                         # word comparing loop
167        cmpo    SRC2,SRC1       # compare src1 and src2 words
168#if __i960_BIG_ENDIAN__
169         lda    0xff000000,g1   # byte extraction mask
170#else
171         lda    0xff,g1         # byte extraction mask
172#endif
173        mov     MSW,LSW         # move msw of src1 to lsw
174         ld     (g2),MSW        # pre-fetch next msw of src1
175        addo    4,g2,g2         # post-increment src1 addr
176         lda    4(g3),g3        # pre-increment src2 addr
177         bne.f  Lcloop          # branch if src1 and src2 unequal
178        scanbyte 0,SRC1         # check for null byte in src1 word
179         ld     (g3),SRC2       # pre-fetch next word of src2
180        eshro   g14,g4,SRC1     # extract word of src1
181         lda    0,g0            # prepare to return zero, indicating equality
182        bno.t   Lwloop          # branch if null byte not encountered
183
184                                /* words were equal and contained null byte */
185
186        mov     0,g14           # conform to register conventions
187         bx     (g13)           # return
188       
189Lcloop_setup:                   # setup for coming from Lsrc2_unaligned
190        mov     LSW,SRC1        # restore extracted src1 word
191#if __i960_BIG_ENDIAN__
192         lda    0xff000000,g1   # byte extraction mask
193#else
194         lda    0xff,g1         # byte extraction mask
195#endif
196
197Lcloop:                         # character comparing loop
198        and     SRC2,g1,g3      # extract next char of src2
199        and     SRC1,g1,g0      # extract next char of src1
200        cmpobne.f g0,g3,.diff   # check for equality
201        cmpo    0,g0            # check for null byte
202#if __i960_BIG_ENDIAN__
203        shro    8,g1,g1         # shift mask for next byte
204#else
205        shlo    8,g1,g1         # shift mask for next byte
206#endif
207         bne.t  Lcloop          # branch if null not reached
208
209                                /* words are equal up thru null byte */
210
211        mov     0,g14
212         bx     (g13)           # g0 = 0 (src1 == src2)
213Lrett:
214        ret
215
216.diff:
217        mov     0,g14
218         bl     Lless_than_exit
219Lgreater_than_exit:
220        mov     1,g0
221         bx     (g13)           # g0 = 1 (src1 > src2)
222Lless_than_exit:
223        subi    1,0,g0
224         bx     (g13)           # g0 = -1 (src1 < src2)
225
226Lsrc2_unaligned:
227        mov     SRC1,LSW        # retain src1 extracted word
228         ld     4(g3),SRC1      # fetch second word of src2
229        shlo    3,g1,MSW        # compute shift count for src2
230#if __i960_BIG_ENDIAN__
231        subo    MSW,0,MSW       # 32 - shift count for big endian.
232#endif
233        eshro   MSW,g6,SRC2     # extract word of src2
234        cmpo    LSW,SRC2        # compare src1 and src2 words
235        notor   g1,3,MSW        # first step in computing new src1 ptr
236         lda    4(g3),g1        # set new src2 ptr
237         bne.f  Lcloop_setup    # first four bytes differ
238        scanbyte 0,LSW          # check for null byte
239         lda    (g13),g14       # prepare return pointer for Lrestart
240        subo    MSW,g0,g0       # second (final) step in computing new src1 ptr
241         bno.t  Lrestart                # if null byte not encountered, continue
242                                /* with both string fetches shifted such that */
243                                /* src2 is now word aligned. */
244        mov     0,g14           # conform to register conventions.
245         lda    0,g0            # return indicator of equality.
246        bx      (g13)
Note: See TracBrowser for help on using the repository browser.