/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) */ #include <linux/linkage.h> #ifdef __LITTLE_ENDIAN__ #define WORD2 r2 #define SHIFT r3 #else /* BIG ENDIAN */ #define WORD2 r3 #define SHIFT r2 #endif ENTRY_CFI(memcmp) or r12,r0,r1 asl_s r12,r12,30 sub r3,r2,1 brls r2,r12,.Lbytewise ld r4,[r0,0] ld r5,[r1,0] lsr.f lp_count,r3,3 #ifdef CONFIG_ISA_ARCV2 /* In ARCv2 a branch can't be the last instruction in a zero overhead * loop. * So we move the branch to the start of the loop, duplicate it * after the end, and set up r12 so that the branch isn't taken * initially. */ mov_s r12,WORD2 lpne .Loop_end brne WORD2,r12,.Lodd ld WORD2,[r0,4] #else lpne .Loop_end ld_s WORD2,[r0,4] #endif ld_s r12,[r1,4] brne r4,r5,.Leven ld.a r4,[r0,8] ld.a r5,[r1,8] #ifdef CONFIG_ISA_ARCV2 .Loop_end: brne WORD2,r12,.Lodd #else brne WORD2,r12,.Lodd .Loop_end: #endif asl_s SHIFT,SHIFT,3 bhs_s .Last_cmp brne r4,r5,.Leven ld r4,[r0,4] ld r5,[r1,4] #ifdef __LITTLE_ENDIAN__ nop_s ; one more load latency cycle .Last_cmp: xor r0,r4,r5 bset r0,r0,SHIFT sub_s r1,r0,1 bic_s r1,r1,r0 norm r1,r1 b.d .Leven_cmp and r1,r1,24 .Leven: xor r0,r4,r5 sub_s r1,r0,1 bic_s r1,r1,r0 norm r1,r1 ; slow track insn and r1,r1,24 .Leven_cmp: asl r2,r4,r1 asl r12,r5,r1 lsr_s r2,r2,1 lsr_s r12,r12,1 j_s.d [blink] sub r0,r2,r12 .balign 4 .Lodd: xor r0,WORD2,r12 sub_s r1,r0,1 bic_s r1,r1,r0 norm r1,r1 ; slow track insn and r1,r1,24 asl_s r2,r2,r1 asl_s r12,r12,r1 lsr_s r2,r2,1 lsr_s r12,r12,1 j_s.d [blink] sub r0,r2,r12 #else /* BIG ENDIAN */ .Last_cmp: neg_s SHIFT,SHIFT lsr r4,r4,SHIFT lsr r5,r5,SHIFT ; slow track insn .Leven: sub.f r0,r4,r5 mov.ne r0,1 j_s.d [blink] bset.cs r0,r0,31 .Lodd: cmp_s WORD2,r12 mov_s r0,1 j_s.d [blink] bset.cs r0,r0,31 #endif /* ENDIAN */ .balign 4 .Lbytewise: breq r2,0,.Lnil ldb r4,[r0,0] ldb r5,[r1,0] lsr.f lp_count,r3 #ifdef CONFIG_ISA_ARCV2 mov r12,r3 lpne .Lbyte_end brne r3,r12,.Lbyte_odd #else lpne .Lbyte_end #endif ldb_s r3,[r0,1] ldb r12,[r1,1] brne r4,r5,.Lbyte_even ldb.a r4,[r0,2] ldb.a r5,[r1,2] #ifdef CONFIG_ISA_ARCV2 .Lbyte_end: brne r3,r12,.Lbyte_odd #else brne r3,r12,.Lbyte_odd .Lbyte_end: #endif bcc .Lbyte_even brne r4,r5,.Lbyte_even ldb_s r3,[r0,1] ldb_s r12,[r1,1] .Lbyte_odd: j_s.d [blink] sub r0,r3,r12 .Lbyte_even: j_s.d [blink] sub r0,r4,r5 .Lnil: j_s.d [blink] mov r0,0 END_CFI(memcmp)