Linux 4.18.10
[linux/fpc-iii.git] / arch / arc / lib / memcmp.S
blob21a103044b70ac45f58c85a1c9f10c9155bf5279
1 /*
2  * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  */
9 #include <linux/linkage.h>
11 #ifdef __LITTLE_ENDIAN__
12 #define WORD2 r2
13 #define SHIFT r3
14 #else /* BIG ENDIAN */
15 #define WORD2 r3
16 #define SHIFT r2
17 #endif
19 ENTRY_CFI(memcmp)
20         or      r12,r0,r1
21         asl_s   r12,r12,30
22         sub     r3,r2,1
23         brls    r2,r12,.Lbytewise
24         ld      r4,[r0,0]
25         ld      r5,[r1,0]
26         lsr.f   lp_count,r3,3
27 #ifdef CONFIG_ISA_ARCV2
28         /* In ARCv2 a branch can't be the last instruction in a zero overhead
29          * loop.
30          * So we move the branch to the start of the loop, duplicate it
31          * after the end, and set up r12 so that the branch isn't taken
32          *  initially.
33          */
34         mov_s   r12,WORD2
35         lpne    .Loop_end
36         brne    WORD2,r12,.Lodd
37         ld      WORD2,[r0,4]
38 #else
39         lpne    .Loop_end
40         ld_s    WORD2,[r0,4]
41 #endif
42         ld_s    r12,[r1,4]
43         brne    r4,r5,.Leven
44         ld.a    r4,[r0,8]
45         ld.a    r5,[r1,8]
46 #ifdef CONFIG_ISA_ARCV2
47 .Loop_end:
48         brne    WORD2,r12,.Lodd
49 #else
50         brne    WORD2,r12,.Lodd
51 .Loop_end:
52 #endif
53         asl_s   SHIFT,SHIFT,3
54         bhs_s   .Last_cmp
55         brne    r4,r5,.Leven
56         ld      r4,[r0,4]
57         ld      r5,[r1,4]
58 #ifdef __LITTLE_ENDIAN__
59         nop_s
60         ; one more load latency cycle
61 .Last_cmp:
62         xor     r0,r4,r5
63         bset    r0,r0,SHIFT
64         sub_s   r1,r0,1
65         bic_s   r1,r1,r0
66         norm    r1,r1
67         b.d     .Leven_cmp
68         and     r1,r1,24
69 .Leven:
70         xor     r0,r4,r5
71         sub_s   r1,r0,1
72         bic_s   r1,r1,r0
73         norm    r1,r1
74         ; slow track insn
75         and     r1,r1,24
76 .Leven_cmp:
77         asl     r2,r4,r1
78         asl     r12,r5,r1
79         lsr_s   r2,r2,1
80         lsr_s   r12,r12,1
81         j_s.d   [blink]
82         sub     r0,r2,r12
83         .balign 4
84 .Lodd:
85         xor     r0,WORD2,r12
86         sub_s   r1,r0,1
87         bic_s   r1,r1,r0
88         norm    r1,r1
89         ; slow track insn
90         and     r1,r1,24
91         asl_s   r2,r2,r1
92         asl_s   r12,r12,r1
93         lsr_s   r2,r2,1
94         lsr_s   r12,r12,1
95         j_s.d   [blink]
96         sub     r0,r2,r12
97 #else /* BIG ENDIAN */
98 .Last_cmp:
99         neg_s   SHIFT,SHIFT
100         lsr     r4,r4,SHIFT
101         lsr     r5,r5,SHIFT
102         ; slow track insn
103 .Leven:
104         sub.f   r0,r4,r5
105         mov.ne  r0,1
106         j_s.d   [blink]
107         bset.cs r0,r0,31
108 .Lodd:
109         cmp_s   WORD2,r12
110         mov_s   r0,1
111         j_s.d   [blink]
112         bset.cs r0,r0,31
113 #endif /* ENDIAN */
114         .balign 4
115 .Lbytewise:
116         breq    r2,0,.Lnil
117         ldb     r4,[r0,0]
118         ldb     r5,[r1,0]
119         lsr.f   lp_count,r3
120 #ifdef CONFIG_ISA_ARCV2
121         mov     r12,r3
122         lpne    .Lbyte_end
123         brne    r3,r12,.Lbyte_odd
124 #else
125         lpne    .Lbyte_end
126 #endif
127         ldb_s   r3,[r0,1]
128         ldb     r12,[r1,1]
129         brne    r4,r5,.Lbyte_even
130         ldb.a   r4,[r0,2]
131         ldb.a   r5,[r1,2]
132 #ifdef CONFIG_ISA_ARCV2
133 .Lbyte_end:
134         brne    r3,r12,.Lbyte_odd
135 #else
136         brne    r3,r12,.Lbyte_odd
137 .Lbyte_end:
138 #endif
139         bcc     .Lbyte_even
140         brne    r4,r5,.Lbyte_even
141         ldb_s   r3,[r0,1]
142         ldb_s   r12,[r1,1]
143 .Lbyte_odd:
144         j_s.d   [blink]
145         sub     r0,r3,r12
146 .Lbyte_even:
147         j_s.d   [blink]
148         sub     r0,r4,r5
149 .Lnil:
150         j_s.d   [blink]
151         mov     r0,0
152 END_CFI(memcmp)