source: trunk/libs/newlib/src/newlib/libc/machine/arc/memcmp.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: 3.9 KB
Line 
1/*
2   Copyright (c) 2015, Synopsys, Inc. All rights reserved.
3
4   Redistribution and use in source and binary forms, with or without
5   modification, are permitted provided that the following conditions are met:
6
7   1) Redistributions of source code must retain the above copyright notice,
8   this list of conditions and the following disclaimer.
9
10   2) Redistributions in binary form must reproduce the above copyright notice,
11   this list of conditions and the following disclaimer in the documentation
12   and/or other materials provided with the distribution.
13
14   3) Neither the name of the Synopsys, Inc., nor the names of its contributors
15   may be used to endorse or promote products derived from this software
16   without specific prior written permission.
17
18   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28   POSSIBILITY OF SUCH DAMAGE.
29*/
30
31/* This implementation is optimized for performance.  For code size a generic
32   implementation of this function from newlib/libc/string/memcmp.c will be
33   used.  */
34#if !defined (__OPTIMIZE_SIZE__) && !defined (PREFER_SIZE_OVER_SPEED)
35
36#include "asm.h"
37
38#if defined (__ARC601__) || !defined (__ARC_NORM__) \
39    || !defined (__ARC_BARREL_SHIFTER__)
40
41/* Addresses are unsigned, and at 0 is the vector table, so it's OK to assume
42   that we can subtract 8 from a source end address without underflow.  */
43
44ENTRY (memcmp)
45        or      r12,r0,r1
46        tst     r12,3
47        breq    r2,0,.Lnil
48        add_s   r3,r0,r2
49
50/* This algorithm for big endian targets sometimes works incorrectly
51   when sources are aligned. To be precise the last step is omitted.
52   Just use a simple bytewise variant until the algorithm is reviewed
53   and fixed.  */
54
55#ifdef __LITTLE_ENDIAN__
56        bne_s   .Lbytewise
57#else /* BIG ENDIAN */
58        b_s     .Lbytewise
59#endif /* ENDIAN */
60        sub     r6,r3,8
61        ld      r4,[r0,0]
62        ld      r5,[r1,0]
632:
64        brhs    r0,r6,.Loop_end
65        ld_s    r3,[r0,4]
66        ld_s    r12,[r1,4]
67        brne    r4,r5,.Leven
68        ld.a    r4,[r0,8]
69        breq.d  r3,r12,2b
70        ld.a    r5,[r1,8]
71#ifdef __LITTLE_ENDIAN__
72        mov_s   r4,r3
73        b.d     .Lodd
74        mov_s   r5,r12
75#else /* BIG ENDIAN */
76        cmp_s   r3,r12
77        j_s.d   [blink]
78        rrc     r0,2
79#endif /* ENDIAN */
80
81        .balign 4
82.Loop_end:
83        sub     r3,r0,r6
84        brhs    r3,4,.Last_cmp
85        brne    r4,r5,.Leven
86        ld      r4,[r0,4]
87        ld      r5,[r1,4]
88#ifdef __LITTLE_ENDIAN__
89        .balign 4
90.Last_cmp:
91        mov_l   r0,24
92        add3    r2,r0,r2
93        xor     r0,r4,r5
94        b.d     .Leven_cmp
95        bset    r0,r0,r2
96.Lodd:
97.Leven:
98        xor     r0,r4,r5
99.Leven_cmp:
100        mov_s   r1,0x80808080
101        ; uses long immediate
102        sub_s   r12,r0,1
103        bic_s   r0,r0,r12
104        sub     r0,r1,r0
105        xor_s   r0,r0,r1
106        and     r1,r5,r0
107        and     r0,r4,r0
108#else /* BIG ENDIAN */
109.Last_cmp:
110        mov_s   r3,0
111        sub3    r2,r3,r2
112        sub_s   r3,r3,1
113        bclr    r3,r3,r2
114        add_l   r3,r3,1
115        and     r0,r4,r3
116        and     r1,r5,r3
117.Leven:
118#endif /* ENDIAN */
119        xor.f   0,r0,r1
120        sub_s   r0,r0,r1
121        j_s.d   [blink]
122        mov.mi  r0,r1
123        .balign 4
124.Lbytewise:
125        ldb     r4,[r0,0]
126        ldb     r5,[r1,0]
127        sub     r6,r3,2
1283:
129        brhs    r0,r6,.Lbyte_end
130        ldb_s   r3,[r0,1]
131        ldb_s   r12,[r1,1]
132        brne    r4,r5,.Lbyte_even
133        ldb.a   r4,[r0,2]
134        breq.d  r3,r12,3b
135        ldb.a   r5,[r1,2]
136.Lbyte_odd:
137        j_s.d   [blink]
138        sub     r0,r3,r12
139        .balign 4
140.Lbyte_end:
141        bbit1   r2,0,.Lbyte_even
142        brne    r4,r5,.Lbyte_even
143        ldb     r4,[r0,1]
144        ldb     r5,[r1,1]
145.Lbyte_even:
146        j_s.d   [blink]
147        sub     r0,r4,r5
148.Lnil:
149        j_s.d   [blink]
150        mov_s   r0,0
151ENDFUNC (memcmp)
152#endif /* __ARC601__ || !__ARC_NORM__ || !__ARC_BARREL_SHIFTER__ */
153
154#endif /* !__OPTIMIZE_SIZE__ && !PREFER_SIZE_OVER_SPEED */
Note: See TracBrowser for help on using the repository browser.