/* 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,0END_CFI(memcmp)
/* 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)