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 16ENTRY_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 149END_CFI(memcmp) 150