xref: /linux/arch/csky/abiv2/memset.S (revision 3eb66e91a25497065c5322b1268cbc3953642227)
1*c5af58b7SGuo Ren/* SPDX-License-Identifier: GPL-2.0 */
2*c5af58b7SGuo Ren// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
3*c5af58b7SGuo Ren
4*c5af58b7SGuo Ren#include <linux/linkage.h>
5*c5af58b7SGuo Ren#include "sysdep.h"
6*c5af58b7SGuo Ren
7*c5af58b7SGuo Ren	.weak memset
8*c5af58b7SGuo RenENTRY(__memset)
9*c5af58b7SGuo RenENTRY(memset)
10*c5af58b7SGuo Ren	/* Test if len less than 4 bytes.  */
11*c5af58b7SGuo Ren	mov	r12, r0
12*c5af58b7SGuo Ren	cmplti	r2, 8
13*c5af58b7SGuo Ren	bt	.L_set_by_byte
14*c5af58b7SGuo Ren
15*c5af58b7SGuo Ren	andi	r13, r0, 3
16*c5af58b7SGuo Ren	movi	r19, 4
17*c5af58b7SGuo Ren	/* Test if dest is not 4 bytes aligned.  */
18*c5af58b7SGuo Ren	bnez	r13, .L_dest_not_aligned
19*c5af58b7SGuo Ren	/* Hardware can handle unaligned access directly.  */
20*c5af58b7SGuo Ren.L_dest_aligned:
21*c5af58b7SGuo Ren        zextb   r3, r1
22*c5af58b7SGuo Ren        lsli    r1, 8
23*c5af58b7SGuo Ren        or      r1, r3
24*c5af58b7SGuo Ren        lsli    r3, r1, 16
25*c5af58b7SGuo Ren        or      r3, r1
26*c5af58b7SGuo Ren
27*c5af58b7SGuo Ren	/* If dest is aligned, then copy.  */
28*c5af58b7SGuo Ren	zext	r18, r2, 31, 4
29*c5af58b7SGuo Ren	/* Test if len less than 16 bytes.  */
30*c5af58b7SGuo Ren	bez	r18, .L_len_less_16bytes
31*c5af58b7SGuo Ren
32*c5af58b7SGuo Ren	LABLE_ALIGN
33*c5af58b7SGuo Ren.L_len_larger_16bytes:
34*c5af58b7SGuo Ren	stw	r3, (r0, 0)
35*c5af58b7SGuo Ren	stw	r3, (r0, 4)
36*c5af58b7SGuo Ren	stw	r3, (r0, 8)
37*c5af58b7SGuo Ren	stw	r3, (r0, 12)
38*c5af58b7SGuo Ren	PRE_BNEZAD (r18)
39*c5af58b7SGuo Ren	addi	r0, 16
40*c5af58b7SGuo Ren	BNEZAD (r18, .L_len_larger_16bytes)
41*c5af58b7SGuo Ren
42*c5af58b7SGuo Ren.L_len_less_16bytes:
43*c5af58b7SGuo Ren	zext	r18, r2, 3, 2
44*c5af58b7SGuo Ren	andi	r2, 3
45*c5af58b7SGuo Ren	bez	r18, .L_set_by_byte
46*c5af58b7SGuo Ren.L_len_less_16bytes_loop:
47*c5af58b7SGuo Ren	stw	r3, (r0, 0)
48*c5af58b7SGuo Ren	PRE_BNEZAD (r18)
49*c5af58b7SGuo Ren	addi	r0, 4
50*c5af58b7SGuo Ren	BNEZAD (r18, .L_len_less_16bytes_loop)
51*c5af58b7SGuo Ren
52*c5af58b7SGuo Ren	/* Test if len less than 4 bytes.  */
53*c5af58b7SGuo Ren.L_set_by_byte:
54*c5af58b7SGuo Ren	zext	r18, r2, 2, 0
55*c5af58b7SGuo Ren	bez	r18, .L_return
56*c5af58b7SGuo Ren.L_set_by_byte_loop:
57*c5af58b7SGuo Ren	stb	r1, (r0, 0)
58*c5af58b7SGuo Ren	PRE_BNEZAD (r18)
59*c5af58b7SGuo Ren	addi	r0, 1
60*c5af58b7SGuo Ren	BNEZAD (r18, .L_set_by_byte_loop)
61*c5af58b7SGuo Ren
62*c5af58b7SGuo Ren.L_return:
63*c5af58b7SGuo Ren	mov	r0, r12
64*c5af58b7SGuo Ren	rts
65*c5af58b7SGuo Ren
66*c5af58b7SGuo Ren	/* If dest is not aligned, just set some bytes makes the dest
67*c5af58b7SGuo Ren	   align.  */
68*c5af58b7SGuo Ren
69*c5af58b7SGuo Ren.L_dest_not_aligned:
70*c5af58b7SGuo Ren	sub	r13, r19, r13
71*c5af58b7SGuo Ren	sub	r2, r13
72*c5af58b7SGuo Ren.L_dest_not_aligned_loop:
73*c5af58b7SGuo Ren	/* Makes the dest align.  */
74*c5af58b7SGuo Ren	stb	r1, (r0, 0)
75*c5af58b7SGuo Ren	PRE_BNEZAD (r13)
76*c5af58b7SGuo Ren	addi	r0, 1
77*c5af58b7SGuo Ren	BNEZAD (r13, .L_dest_not_aligned_loop)
78*c5af58b7SGuo Ren	cmplti	r2, 8
79*c5af58b7SGuo Ren	bt	.L_set_by_byte
80*c5af58b7SGuo Ren	/* Check whether the src is aligned.  */
81*c5af58b7SGuo Ren	jbr	.L_dest_aligned
82*c5af58b7SGuo RenENDPROC(memset)
83*c5af58b7SGuo RenENDPROC(__memset)
84