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