fixes for host gcc 4.6.1
[zpugcc/jano.git] / toolchain / gcc / newlib / libc / machine / hppa / strcmp.S
blob007a648492d0e0f08d2e6b886c244d50418132bf
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  */
18         strcmp
20         Jerry Huck
21         Edgar Circenis
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  */
32 #include "DEFS.h"
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
45 ENTRY(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
55 /* Start looping until null is found in s1 or they mis-compare */
56 loop:
57         ldwm       4(s2),s2word
58 loop_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
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 */
67 wordcomparereturn:
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 */
73 /* s1 has a null.  s2 has not been checked. */
74 nullins1:
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 */
94 /* s1 and s2 are the same string and therefore equal */
95 samestring:
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. */
100 s1isnull:
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. */
106 s2isnull:
107         bv      r0(rp)
108         ldbs    0(0,s1),ret0
110 case_analysis:
111         blr     tmp1,r0
112         nop
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         */
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
161 eq_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 */
169 eq_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
180 /* s2's alignment is greater than s1's alignment, so we will shift s1 */
181 shifts1_0:
182         addi    -4,s1,s1                /* fix up s1 due to earlier read */
183 shifts1:
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
195 masks2:
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 */
202 more:   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
216 cmps1:  movb,tr         save,s1word,wordcomparereturn
217         nop
219 ends1_0:
220         copy    tmp7,s1word                     /* move tmp7 to s1word */
221 ends1:
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
232 /* s1's alignment is greater than s2's alignment, so we will shift s2 */
233 shifts2:
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
245 masks1:
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 */
252 more1:  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
266 cmps2:  movb,tr         save,s2word,wordcomparereturn
267         nop
269 ends2_0:
270         copy    tmp7,s2word                     /* move tmp7 to s2word */
271 ends2:
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
282 EXIT(strcmp)