diff options
Diffstat (limited to 'arch/arc/lib/memcmp.S')
-rw-r--r-- | arch/arc/lib/memcmp.S | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/arch/arc/lib/memcmp.S b/arch/arc/lib/memcmp.S new file mode 100644 index 000000000000..bc813d55b6c3 --- /dev/null +++ b/arch/arc/lib/memcmp.S | |||
@@ -0,0 +1,124 @@ | |||
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 | */ | ||
8 | |||
9 | #include <asm/linkage.h> | ||
10 | |||
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 | ||
18 | |||
19 | ARC_ENTRY 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 | lpne .Loop_end | ||
28 | ld_s WORD2,[r0,4] | ||
29 | ld_s r12,[r1,4] | ||
30 | brne r4,r5,.Leven | ||
31 | ld.a r4,[r0,8] | ||
32 | ld.a r5,[r1,8] | ||
33 | brne WORD2,r12,.Lodd | ||
34 | .Loop_end: | ||
35 | asl_s SHIFT,SHIFT,3 | ||
36 | bhs_s .Last_cmp | ||
37 | brne r4,r5,.Leven | ||
38 | ld r4,[r0,4] | ||
39 | ld r5,[r1,4] | ||
40 | #ifdef __LITTLE_ENDIAN__ | ||
41 | nop_s | ||
42 | ; one more load latency cycle | ||
43 | .Last_cmp: | ||
44 | xor r0,r4,r5 | ||
45 | bset r0,r0,SHIFT | ||
46 | sub_s r1,r0,1 | ||
47 | bic_s r1,r1,r0 | ||
48 | norm r1,r1 | ||
49 | b.d .Leven_cmp | ||
50 | and r1,r1,24 | ||
51 | .Leven: | ||
52 | xor r0,r4,r5 | ||
53 | sub_s r1,r0,1 | ||
54 | bic_s r1,r1,r0 | ||
55 | norm r1,r1 | ||
56 | ; slow track insn | ||
57 | and r1,r1,24 | ||
58 | .Leven_cmp: | ||
59 | asl r2,r4,r1 | ||
60 | asl r12,r5,r1 | ||
61 | lsr_s r2,r2,1 | ||
62 | lsr_s r12,r12,1 | ||
63 | j_s.d [blink] | ||
64 | sub r0,r2,r12 | ||
65 | .balign 4 | ||
66 | .Lodd: | ||
67 | xor r0,WORD2,r12 | ||
68 | sub_s r1,r0,1 | ||
69 | bic_s r1,r1,r0 | ||
70 | norm r1,r1 | ||
71 | ; slow track insn | ||
72 | and r1,r1,24 | ||
73 | asl_s r2,r2,r1 | ||
74 | asl_s r12,r12,r1 | ||
75 | lsr_s r2,r2,1 | ||
76 | lsr_s r12,r12,1 | ||
77 | j_s.d [blink] | ||
78 | sub r0,r2,r12 | ||
79 | #else /* BIG ENDIAN */ | ||
80 | .Last_cmp: | ||
81 | neg_s SHIFT,SHIFT | ||
82 | lsr r4,r4,SHIFT | ||
83 | lsr r5,r5,SHIFT | ||
84 | ; slow track insn | ||
85 | .Leven: | ||
86 | sub.f r0,r4,r5 | ||
87 | mov.ne r0,1 | ||
88 | j_s.d [blink] | ||
89 | bset.cs r0,r0,31 | ||
90 | .Lodd: | ||
91 | cmp_s WORD2,r12 | ||
92 | |||
93 | mov_s r0,1 | ||
94 | j_s.d [blink] | ||
95 | bset.cs r0,r0,31 | ||
96 | #endif /* ENDIAN */ | ||
97 | .balign 4 | ||
98 | .Lbytewise: | ||
99 | breq r2,0,.Lnil | ||
100 | ldb r4,[r0,0] | ||
101 | ldb r5,[r1,0] | ||
102 | lsr.f lp_count,r3 | ||
103 | lpne .Lbyte_end | ||
104 | ldb_s r3,[r0,1] | ||
105 | ldb r12,[r1,1] | ||
106 | brne r4,r5,.Lbyte_even | ||
107 | ldb.a r4,[r0,2] | ||
108 | ldb.a r5,[r1,2] | ||
109 | brne r3,r12,.Lbyte_odd | ||
110 | .Lbyte_end: | ||
111 | bcc .Lbyte_even | ||
112 | brne r4,r5,.Lbyte_even | ||
113 | ldb_s r3,[r0,1] | ||
114 | ldb_s r12,[r1,1] | ||
115 | .Lbyte_odd: | ||
116 | j_s.d [blink] | ||
117 | sub r0,r3,r12 | ||
118 | .Lbyte_even: | ||
119 | j_s.d [blink] | ||
120 | sub r0,r4,r5 | ||
121 | .Lnil: | ||
122 | j_s.d [blink] | ||
123 | mov r0,0 | ||
124 | ARC_EXIT memcmp | ||