source: trunk/libs/newlib/src/newlib/libc/machine/hppa/strcmp.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: 8.8 KB
Line 
1/*
2 *  (c) Copyright 1986 HEWLETT-PACKARD COMPANY
3 *
4 *  To anyone who acknowledges that this file is provided "AS IS"
5 *  without any express or implied warranty:
6 *      permission to use, copy, modify, and distribute this file
7 *  for any purpose is hereby granted without fee, provided that
8 *  the above copyright notice and this notice appears in all
9 *  copies, and that the name of Hewlett-Packard Company not be
10 *  used in advertising or publicity pertaining to distribution
11 *  of the software without specific, written prior permission.
12 *  Hewlett-Packard Company makes no representations about the
13 *  suitability of this software for any purpose.
14 */
15
16/*
17
18        strcmp
19
20        Jerry Huck
21        Edgar Circenis
22
23*/
24/*
25 * strcmp(s1, s2)
26 *
27 * returns integer: < 0 iff s1 lexicographically less than s2
28 *                  > 0 iff s1 lexicographically greater than s2
29 *                  = 0 iff s1 lexicographically equal to s2
30 */
31
32#include "DEFS.h"
33
34#define s1       26
35#define s2       25
36#define tmp1     19
37#define s2word   20
38#define tmp3     21
39#define tmp7     22
40#define s1word   23
41#define save      1
42#define tmp6     24
43#define tmp5     28
44
45ENTRY(strcmp)
46        comb,=,n   s1,s2,samestring
47        comib,=,n  0,s1,s1isnull
48        comib,=,n  0,s2,s2isnull
49/* Hope for word alignment.  Pick up low two bits of each adress */
50        extru,<>   s1,31,2,tmp1
51        ldwm       4(s1),s1word
52        dep,=      s2,29,2,tmp1
53        b,n        case_analysis
54
55/* Start looping until null is found in s1 or they mis-compare */
56loop:
57        ldwm       4(s2),s2word
58loop_plus:
59        uxor,nbz   s1word,r0,r0   /* Null in this? */
60        b,n        nullins1
61        comb,=,n   s1word,s2word,loop
62        ldwm       4(s1),s1word
63
64/* The words do not compare equal and s1 does not have a null.
65   Need to treat words as unsigned and generate either a positive
66   or negative return value */
67wordcomparereturn:
68        comclr,>>  s1word,s2word,ret0    /*Set ret0 to 0 and skip if greater*/
69        ldi        -2,ret0           /*Set ret0 to -2 when less */
70        bv         r0(rp)
71        addi       1,ret0,ret0           /*Fix return value to be -1 or +1 */
72
73/* s1 has a null.  s2 has not been checked. */
74nullins1:
75        /*If s2 has no nulls this is simple, but assume that it might
76          and fix up s1 to allow the word comparision to work by
77          scanning s1 and duplicating all the bytes in s2 below that byte into
78          the remainder of s1.  A remainder only exists if the zero byte
79          is found in the upper three bytes */
80        extru,<>   s1word,7,8,r0         /*in the first byte? */
81        dep,tr     s2word,31,24,s1word   /*copy low 3 bytes of *s2 into *s1 */
82        extru,<>   s1word,15,8,r0         /*in the second byte? */
83        dep,tr     s2word,31,16,s1word   /*copy low 2 bytes of *s2 into *s1 */
84        extru,<>   s1word,23,8,r0         /*in the third byte? */
85        dep        s2word,31,8,s1word   /*copy low 1 byte of *s2 into *s1 */
86        /* Do the normal unsigned compare and return */
87        comclr,<>  s1word,s2word,ret0    /*Set ret0 to 0 and skip if not equal */
88        bv,n       r0(rp)
89        comclr,>>  s1word,s2word,ret0    /*Set ret0 to 0 and skip if greater*/
90        ldi        -2,ret0           /*Set ret0 to -2 when less */
91        bv         r0(rp)
92        addi       1,ret0,ret0           /*Fix return value to be -1 or +1 */
93
94/* s1 and s2 are the same string and therefore equal */
95samestring:
96        bv      r0(rp)
97        copy    r0,ret0
98/* s1 is null.  Treat as string of nulls.  Therefore return
99   the negative of s2's first byte.  s2 cannot be zero. */
100s1isnull:
101        ldbs    0(0,s2),ret0
102        bv      r0(rp)
103        sub     0,ret0,ret0
104/* s2 is null.  Treat as string of nulls.  Therefore return
105   s1's first byte.  s1 cannot be zero. */
106s2isnull:
107        bv      r0(rp)
108        ldbs    0(0,s1),ret0
109
110case_analysis:
111        blr     tmp1,r0
112        nop
113
114        /*
115           Case statement for non-aligned cases (we've already
116           checked the aligned case.
117           NOTE: for non-aligned cases, the absolute shift value
118           gets loaded into tmp3.
119        */
120
121                                /* S2 S1 */
122        nop                     /* 00 00 can't happen */
123        nop
124        b       shifts2         /* 00 01 */
125        ldi     8,tmp3          /* load shift count (delay slot) */
126        b       shifts2         /* 00 10 */
127        ldi     16,tmp3         /* load shift count (delay slot) */
128        b       shifts2         /* 00 11 */
129        ldi     24,tmp3         /* load shift count (delay slot) */
130        b       shifts1_0       /* 01 00 */
131        ldi     8,tmp3          /* load shift count (delay slot) */
132        b       eq_align1       /* 01 01 */
133        ldbs,ma 1(s1),s1word
134        b       shifts2         /* 01 10 */
135        ldi     8,tmp3          /* load shift count (delay slot) */
136        b       shifts2         /* 01 11 */
137        ldi     16,tmp3         /* load shift count (delay slot) */
138        b       shifts1_0       /* 10 00 */
139        ldi     16,tmp3         /* load shift count (delay slot) */
140        b       shifts1         /* 10 01 */
141        ldi     8,tmp3          /* load shift count (delay slot) */
142        b       eq_align2       /* 10 10 */
143        ldhs,ma 2(s1),s1word
144        b       shifts2         /* 10 11 */
145        ldi     8,tmp3          /* load shift count (delay slot) */
146        b       shifts1_0       /* 11 00 */
147        ldi     24,tmp3         /* load shift count (delay slot) */
148        b       shifts1         /* 11 01 */
149        ldi     16,tmp3         /* load shift count (delay slot) */
150        b       shifts1         /* 11 10 */
151        ldi     8,tmp3          /* load shift count (delay slot) */
152        ldbs,ma 1(s1),s1word    /* 11 11 */
153        ldbs,ma 1(s2),s2word
154        sub,=   s1word,s2word,ret0      /* if not equal, we can return now */
155        bv,n    r0(rp)
156        comclr,<>       s1word,r0,ret0
157        bv,n    r0(rp)                 
158        b       loop                    /* fall into main loop */
159        ldwm    4(s1),s1word
160
161eq_align1:
162        ldbs,ma 1(s2),s2word
163        sub,=   s1word,s2word,ret0      /* if not equal, we can return now */
164        bv,n    r0(rp)
165        comclr,<>       s1word,r0,ret0
166        bv,n    r0(rp)                 
167        /* fall through to half-word aligned case */
168        ldhs,ma 2(s1),s1word            /* load next halfword */
169eq_align2:
170        ldhs,ma 2(s2),s2word            /* load next halfword */
171        /* form the mask: 0xffff0000 and mask leading nulls in s1word and s2word
172           so that we can fall into the main loop with word aligned data */
173        ldi     16,save
174        mtctl   save,r11
175        zvdepi  -2,32,save
176        or      save,s1word,s1word
177        b       loop_plus               /* fall into main loop */
178        or      save,s2word,s2word
179
180/* s2's alignment is greater than s1's alignment, so we will shift s1 */
181shifts1_0:
182        addi    -4,s1,s1                /* fix up s1 due to earlier read */
183shifts1:
184        extru   s1,31,2,tmp1
185        extru   s2,31,2,tmp5
186        dep     r0,31,2,s1              /* Compute word address of s1 */
187        dep     r0,31,2,s2              /* Compute word address of s2 */
188        ldwm    4(s1),s1word            /* get first word of s1 */
189        ldwm    4(s2),s2word            /* get first word of s2 */
190        combt,=,n       r0,tmp1,masks2  /* Do we need to mask beginning of s1 */
191        sh3add  tmp1,r0,save            /* save now has number of bits to mask */
192        mtctl   save,r11
193        zvdepi  -2,32,save              /* load save with proper mask */
194        or      save,s1word,s1word
195masks2:
196        sh3add  tmp5,r0,save            /* save now has number of bits to mask */
197        mtctl   save,r11
198        zvdepi  -2,32,save              /* load save with proper mask */
199        or      save,s2word,s2word
200        ldi     -1,tmp7                 /* load tmp7 with 0xffffffff */
201        mtctl   tmp3,r11                /* Move shift amount to CR11 */
202more:   uxor,nbz        s1word,r0,r0    /* Is there a null in s1? */
203        b       ends1
204        vshd    tmp7,s1word,save
205        combf,=,n       save,s2word,cmps1
206        ldwm    4(s1),tmp7
207        ldwm    4(s2),s2word
208        uxor,nbz        tmp7,r0,r0      /* is there a null in s1? */
209        b       ends1_0
210        vshd    s1word,tmp7,save
211        combf,=,n       save,s2word,cmps1
212        ldwm    4(s1),s1word
213        b       more
214        ldwm    4(s2),s2word
215
216cmps1:  movb,tr         save,s1word,wordcomparereturn
217        nop
218
219ends1_0:
220        copy    tmp7,s1word                     /* move tmp7 to s1word */
221ends1:
222        combf,=,n       save,s2word,nullins1    /* branch if no match */
223        copy    save,s1word                     /* delay slot */
224/* At this point, we know that we've read a null */
225/* from s1, so we can't read more from s1 */
226        uxor,nbz        save,r0,r0              /* are the strings equal? */
227        b,n     samestring
228        vshd    s1word,r0,s1word
229        b       nullins1
230        ldwm    4(s2),s2word
231
232/* s1's alignment is greater than s2's alignment, so we will shift s2 */
233shifts2:
234        extru   s1,31,2,tmp1
235        extru   s2,31,2,tmp5
236        dep     r0,31,2,s1              /* Compute word address of s1 */
237        dep     r0,31,2,s2              /* Compute word address of s2 */
238        ldwm    4(s2),s2word            /* get first word of s2 */
239        ldwm    4(s1),s1word            /* get first word of s1 */
240        combt,=,n       r0,tmp5,masks1  /* Do we need to mask beginning of s2 */
241        sh3add  tmp5,r0,save            /* save now has number of bits to mask */
242        mtctl   save,r11
243        zvdepi  -2,32,save              /* load save with proper mask */
244        or      save,s2word,s2word
245masks1:
246        sh3add  tmp1,r0,save            /* save now has number of bits to mask */
247        mtctl   save,r11
248        zvdepi  -2,32,save              /* load save with proper mask */
249        or      save,s1word,s1word
250        ldi     -1,tmp7                 /* load tmp7 with 0xffffffff */
251        mtctl   tmp3,r11                /* Move shift amount to CR11 */
252more1:  uxor,nbz        s2word,r0,r0    /* is there a null in s2? */
253        b       ends2
254        vshd    tmp7,s2word,save
255        combf,=,n       s1word,save,cmps2
256        ldwm    4(s2),tmp7
257        ldwm    4(s1),s1word
258        uxor,nbz        tmp7,r0,r0      /* is there a null in s2? */
259        b       ends2_0
260        vshd    s2word,tmp7,save
261        combf,=,n       s1word,save,cmps2
262        ldwm    4(s2),s2word
263        b       more1
264        ldwm    4(s1),s1word
265
266cmps2:  movb,tr         save,s2word,wordcomparereturn
267        nop
268
269ends2_0:
270        copy    tmp7,s2word                     /* move tmp7 to s2word */
271ends2:
272        combf,=,n       s1word,save,nullins1    /* branch if no match */
273        copy    save,s2word                     /* delay slot */
274/* At this point, we know that we've read a null */
275/* from s2, so we can't read more from s2 */
276        uxor,nbz        save,r0,r0              /* are the strings equal? */
277        b,n     samestring
278        vshd    s2word,r0,s2word
279        b       nullins1
280        ldwm    4(s1),s1word
281
282EXIT(strcmp)
Note: See TracBrowser for help on using the repository browser.