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