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