1 /*
2  * strcmp.c -- strcmp function.  On at least some MIPS chips, a strcmp that is
3  * unrolled twice is faster than the 'optimized' C version in newlib.
4  *
5  * Copyright (c) 2001 Red Hat, Inc.
6  *
7  * The authors hereby grant permission to use, copy, modify, distribute,
8  * and license this software and its documentation for any purpose, provided
9  * that existing copyright notices are retained in all copies and that this
10  * notice is included verbatim in any distributions. No written agreement,
11  * license, or royalty fee is required for any of the authorized uses.
12  * Modifications to this software may be copyrighted by their authors
13  * and need not follow the licensing terms described here, provided that
14  * the new terms are clearly indicated on the first page of each file where
15  * they apply.  */
16 
17 #include <stddef.h>
18 #include <string.h>
19 #include <stdlib.h>
20 
21 int
strcmp(const char * s1,const char * s2)22 strcmp (const char *s1, const char *s2)
23 {
24   unsigned const char *us1 = (unsigned const char *)s1;
25   unsigned const char *us2 = (unsigned const char *)s2;
26   int c1a, c1b;
27   int c2a, c2b;
28 
29   /* If the pointers aren't both aligned to a 16-byte boundary, do the
30      comparison byte by byte, so that we don't get an invalid page fault if we
31      are comparing a string whose null byte is at the last byte on the last
32      valid page.  */
33   if (((((long)us1) | ((long)us2)) & 1) == 0)
34     {
35       c1a = *us1;
36       for (;;)
37 	{
38 	  c1b = *us2;
39 	  us1 += 2;
40 	  if (c1a == '\0')
41 	    goto ret1;
42 
43 	  c2a = us1[-1];
44 	  if (c1a != c1b)
45 	    goto ret1;
46 
47 	  c2b = us2[1];
48 	  us2 += 2;
49 	  if (c2a == '\0')
50 	    break;
51 
52 	  c1a = *us1;
53 	  if (c2a != c2b)
54 	    break;
55 	}
56 
57       return c2a - c2b;
58     }
59   else
60     {
61       do
62 	{
63 	  c1a = *us1++;
64 	  c1b = *us2++;
65 	}
66       while (c1a != '\0' && c1a == c1b);
67     }
68 
69  ret1:
70   return c1a - c1b;
71 }
72