xref: /kernel/linux/linux-6.6/arch/arc/lib/memcmp.S (revision 62306a36)
162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#include <linux/linkage.h>
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#ifdef __LITTLE_ENDIAN__
962306a36Sopenharmony_ci#define WORD2 r2
1062306a36Sopenharmony_ci#define SHIFT r3
1162306a36Sopenharmony_ci#else /* BIG ENDIAN */
1262306a36Sopenharmony_ci#define WORD2 r3
1362306a36Sopenharmony_ci#define SHIFT r2
1462306a36Sopenharmony_ci#endif
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ciENTRY_CFI(memcmp)
1762306a36Sopenharmony_ci	or	r12,r0,r1
1862306a36Sopenharmony_ci	asl_s	r12,r12,30
1962306a36Sopenharmony_ci	sub	r3,r2,1
2062306a36Sopenharmony_ci	brls	r2,r12,.Lbytewise
2162306a36Sopenharmony_ci	ld	r4,[r0,0]
2262306a36Sopenharmony_ci	ld	r5,[r1,0]
2362306a36Sopenharmony_ci	lsr.f	lp_count,r3,3
2462306a36Sopenharmony_ci#ifdef CONFIG_ISA_ARCV2
2562306a36Sopenharmony_ci	/* In ARCv2 a branch can't be the last instruction in a zero overhead
2662306a36Sopenharmony_ci	 * loop.
2762306a36Sopenharmony_ci	 * So we move the branch to the start of the loop, duplicate it
2862306a36Sopenharmony_ci	 * after the end, and set up r12 so that the branch isn't taken
2962306a36Sopenharmony_ci	 *  initially.
3062306a36Sopenharmony_ci	 */
3162306a36Sopenharmony_ci	mov_s	r12,WORD2
3262306a36Sopenharmony_ci	lpne	.Loop_end
3362306a36Sopenharmony_ci	brne	WORD2,r12,.Lodd
3462306a36Sopenharmony_ci	ld	WORD2,[r0,4]
3562306a36Sopenharmony_ci#else
3662306a36Sopenharmony_ci	lpne	.Loop_end
3762306a36Sopenharmony_ci	ld_s	WORD2,[r0,4]
3862306a36Sopenharmony_ci#endif
3962306a36Sopenharmony_ci	ld_s	r12,[r1,4]
4062306a36Sopenharmony_ci	brne	r4,r5,.Leven
4162306a36Sopenharmony_ci	ld.a	r4,[r0,8]
4262306a36Sopenharmony_ci	ld.a	r5,[r1,8]
4362306a36Sopenharmony_ci#ifdef CONFIG_ISA_ARCV2
4462306a36Sopenharmony_ci.Loop_end:
4562306a36Sopenharmony_ci	brne	WORD2,r12,.Lodd
4662306a36Sopenharmony_ci#else
4762306a36Sopenharmony_ci	brne	WORD2,r12,.Lodd
4862306a36Sopenharmony_ci.Loop_end:
4962306a36Sopenharmony_ci#endif
5062306a36Sopenharmony_ci	asl_s	SHIFT,SHIFT,3
5162306a36Sopenharmony_ci	bhs_s	.Last_cmp
5262306a36Sopenharmony_ci	brne	r4,r5,.Leven
5362306a36Sopenharmony_ci	ld	r4,[r0,4]
5462306a36Sopenharmony_ci	ld	r5,[r1,4]
5562306a36Sopenharmony_ci#ifdef __LITTLE_ENDIAN__
5662306a36Sopenharmony_ci	nop_s
5762306a36Sopenharmony_ci	; one more load latency cycle
5862306a36Sopenharmony_ci.Last_cmp:
5962306a36Sopenharmony_ci	xor	r0,r4,r5
6062306a36Sopenharmony_ci	bset	r0,r0,SHIFT
6162306a36Sopenharmony_ci	sub_s	r1,r0,1
6262306a36Sopenharmony_ci	bic_s	r1,r1,r0
6362306a36Sopenharmony_ci	norm	r1,r1
6462306a36Sopenharmony_ci	b.d	.Leven_cmp
6562306a36Sopenharmony_ci	and	r1,r1,24
6662306a36Sopenharmony_ci.Leven:
6762306a36Sopenharmony_ci	xor	r0,r4,r5
6862306a36Sopenharmony_ci	sub_s	r1,r0,1
6962306a36Sopenharmony_ci	bic_s	r1,r1,r0
7062306a36Sopenharmony_ci	norm	r1,r1
7162306a36Sopenharmony_ci	; slow track insn
7262306a36Sopenharmony_ci	and	r1,r1,24
7362306a36Sopenharmony_ci.Leven_cmp:
7462306a36Sopenharmony_ci	asl	r2,r4,r1
7562306a36Sopenharmony_ci	asl	r12,r5,r1
7662306a36Sopenharmony_ci	lsr_s	r2,r2,1
7762306a36Sopenharmony_ci	lsr_s	r12,r12,1
7862306a36Sopenharmony_ci	j_s.d	[blink]
7962306a36Sopenharmony_ci	sub	r0,r2,r12
8062306a36Sopenharmony_ci	.balign	4
8162306a36Sopenharmony_ci.Lodd:
8262306a36Sopenharmony_ci	xor	r0,WORD2,r12
8362306a36Sopenharmony_ci	sub_s	r1,r0,1
8462306a36Sopenharmony_ci	bic_s	r1,r1,r0
8562306a36Sopenharmony_ci	norm	r1,r1
8662306a36Sopenharmony_ci	; slow track insn
8762306a36Sopenharmony_ci	and	r1,r1,24
8862306a36Sopenharmony_ci	asl_s	r2,r2,r1
8962306a36Sopenharmony_ci	asl_s	r12,r12,r1
9062306a36Sopenharmony_ci	lsr_s	r2,r2,1
9162306a36Sopenharmony_ci	lsr_s	r12,r12,1
9262306a36Sopenharmony_ci	j_s.d	[blink]
9362306a36Sopenharmony_ci	sub	r0,r2,r12
9462306a36Sopenharmony_ci#else /* BIG ENDIAN */
9562306a36Sopenharmony_ci.Last_cmp:
9662306a36Sopenharmony_ci	neg_s	SHIFT,SHIFT
9762306a36Sopenharmony_ci	lsr	r4,r4,SHIFT
9862306a36Sopenharmony_ci	lsr	r5,r5,SHIFT
9962306a36Sopenharmony_ci	; slow track insn
10062306a36Sopenharmony_ci.Leven:
10162306a36Sopenharmony_ci	sub.f	r0,r4,r5
10262306a36Sopenharmony_ci	mov.ne	r0,1
10362306a36Sopenharmony_ci	j_s.d	[blink]
10462306a36Sopenharmony_ci	bset.cs	r0,r0,31
10562306a36Sopenharmony_ci.Lodd:
10662306a36Sopenharmony_ci	cmp_s	WORD2,r12
10762306a36Sopenharmony_ci	mov_s	r0,1
10862306a36Sopenharmony_ci	j_s.d	[blink]
10962306a36Sopenharmony_ci	bset.cs	r0,r0,31
11062306a36Sopenharmony_ci#endif /* ENDIAN */
11162306a36Sopenharmony_ci	.balign	4
11262306a36Sopenharmony_ci.Lbytewise:
11362306a36Sopenharmony_ci	breq	r2,0,.Lnil
11462306a36Sopenharmony_ci	ldb	r4,[r0,0]
11562306a36Sopenharmony_ci	ldb	r5,[r1,0]
11662306a36Sopenharmony_ci	lsr.f	lp_count,r3
11762306a36Sopenharmony_ci#ifdef CONFIG_ISA_ARCV2
11862306a36Sopenharmony_ci	mov	r12,r3
11962306a36Sopenharmony_ci	lpne	.Lbyte_end
12062306a36Sopenharmony_ci	brne	r3,r12,.Lbyte_odd
12162306a36Sopenharmony_ci#else
12262306a36Sopenharmony_ci	lpne	.Lbyte_end
12362306a36Sopenharmony_ci#endif
12462306a36Sopenharmony_ci	ldb_s	r3,[r0,1]
12562306a36Sopenharmony_ci	ldb	r12,[r1,1]
12662306a36Sopenharmony_ci	brne	r4,r5,.Lbyte_even
12762306a36Sopenharmony_ci	ldb.a	r4,[r0,2]
12862306a36Sopenharmony_ci	ldb.a	r5,[r1,2]
12962306a36Sopenharmony_ci#ifdef CONFIG_ISA_ARCV2
13062306a36Sopenharmony_ci.Lbyte_end:
13162306a36Sopenharmony_ci	brne	r3,r12,.Lbyte_odd
13262306a36Sopenharmony_ci#else
13362306a36Sopenharmony_ci	brne	r3,r12,.Lbyte_odd
13462306a36Sopenharmony_ci.Lbyte_end:
13562306a36Sopenharmony_ci#endif
13662306a36Sopenharmony_ci	bcc	.Lbyte_even
13762306a36Sopenharmony_ci	brne	r4,r5,.Lbyte_even
13862306a36Sopenharmony_ci	ldb_s	r3,[r0,1]
13962306a36Sopenharmony_ci	ldb_s	r12,[r1,1]
14062306a36Sopenharmony_ci.Lbyte_odd:
14162306a36Sopenharmony_ci	j_s.d	[blink]
14262306a36Sopenharmony_ci	sub	r0,r3,r12
14362306a36Sopenharmony_ci.Lbyte_even:
14462306a36Sopenharmony_ci	j_s.d	[blink]
14562306a36Sopenharmony_ci	sub	r0,r4,r5
14662306a36Sopenharmony_ci.Lnil:
14762306a36Sopenharmony_ci	j_s.d	[blink]
14862306a36Sopenharmony_ci	mov	r0,0
14962306a36Sopenharmony_ciEND_CFI(memcmp)
150