Merge remote-tracking branches 'asoc/topic/ac97', 'asoc/topic/ac97-mfd', 'asoc/topic...
[sfrench/cifs-2.6.git] / arch / m32r / lib / memset.S
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  *  linux/arch/m32r/lib/memset.S
4  *
5  *  Copyright (C) 2001,2002  Hiroyuki Kondo, and Hirokazu Takata
6  *  Copyright (C) 2004  Hirokazu Takata
7  *
8  *  void *memset(void *dst, int val, int len);
9  *
10  *        dst: r0
11  *        val: r1
12  *        len: r2
13  *        ret: r0
14  *
15  */
16
17         .text
18         .global memset
19
20 #ifdef CONFIG_ISA_DUAL_ISSUE
21
22         .align 4
23 memset:
24         mv      r4, r0              ||  cmpz    r2
25         jc      r14
26         cmpui   r2, #16
27         bnc     qword_align_check
28         cmpui   r2, #4
29         bc      byte_set
30 word_align_check:                       /* len >= 4 */
31         and3    r3, r4, #3
32         beqz    r3, word_set
33         addi    r3, #-4
34         neg     r3, r3                  /* r3 = -(r3 - 4) */
35 align_word:
36         stb     r1, @r4             ||  addi    r4, #1
37         addi    r2, #-1             ||  addi    r3, #-1
38         bnez    r3, align_word
39         cmpui   r2, #4
40         bc      byte_set
41 word_set:
42         and3    r1, r1, #0x00ff         /* r1: abababab <-- ??????ab */
43         sll3    r3, r1, #8
44         or      r1, r3              ||  addi    r4, #-4
45         sll3    r3, r1, #16
46         or      r1, r3              ||  addi    r2, #-4
47 word_set_loop:
48         st      r1, @+r4            ||  addi    r2, #-4
49         bgtz    r2, word_set_loop
50         bnez    r2, byte_set_wrap
51         st      r1, @+r4
52         jmp     r14
53
54 qword_align_check:                      /* len >= 16 */
55         and3    r3, r4, #15
56         bnez    r3, word_align_check
57 qword_set:
58         and3    r1, r1, #0x00ff         /* r1: abababab <-- ??????ab */
59         sll3    r3, r1, #8
60         or      r1, r3              ||  addi    r4, #-4
61         sll3    r3, r1, #16
62         or      r1, r3              ||  ldi     r5, #16
63 qword_set_loop:
64         ld      r3, @(4,r4)             /* cache line allocate */
65         st      r1, @+r4            ||  addi    r2, #-16
66         st      r1, @+r4            ||  cmpu    r2, r5
67         st      r1, @+r4
68         st      r1, @+r4
69         bnc     qword_set_loop      ||  cmpz    r2
70         jc      r14
71 set_remainder:
72         cmpui   r2, #4
73         bc      byte_set_wrap1
74         addi    r2, #-4
75         bra     word_set_loop
76
77 byte_set_wrap:
78         addi    r2, #4
79         cmpz    r2
80         jc      r14
81 byte_set_wrap1:
82         addi    r4, #4
83 #if defined(CONFIG_ISA_M32R2)
84 byte_set:
85         addi    r2, #-1             ||  stb     r1, @r4+
86         bnez    r2, byte_set
87 #elif defined(CONFIG_ISA_M32R)
88 byte_set:
89         addi    r2, #-1             ||  stb     r1, @r4
90         addi    r4, #1
91         bnez    r2, byte_set
92 #else
93 #error unknown isa configuration
94 #endif
95 end_memset:
96         jmp     r14
97
98 #else /* not CONFIG_ISA_DUAL_ISSUE */
99
100         .align 4
101 memset:
102         mv      r4, r0
103         beqz    r2, end_memset
104         cmpui   r2, #16
105         bnc     qword_align_check
106         cmpui   r2, #4
107         bc      byte_set
108 word_align_check:                       /* len >= 4 */
109         and3    r3, r4, #3
110         beqz    r3, word_set
111         addi    r3, #-4
112         neg     r3, r3                  /* r3 = -(r3 - 4) */
113 align_word:
114         stb     r1, @r4
115         addi    r4, #1
116         addi    r2, #-1
117         addi    r3, #-1
118         bnez    r3, align_word
119         cmpui   r2, #4
120         bc      byte_set
121 word_set:
122         and3    r1, r1, #0x00ff         /* r1: abababab <-- ??????ab */
123         sll3    r3, r1, #8
124         or      r1, r3
125         sll3    r3, r1, #16
126         or      r1, r3
127         addi    r2, #-4
128         addi    r4, #-4
129 word_set_loop:
130         st      r1, @+r4
131         addi    r2, #-4
132         bgtz    r2, word_set_loop
133         bnez    r2, byte_set_wrap
134         st      r1, @+r4
135         jmp     r14
136
137 qword_align_check:                      /* len >= 16 */
138         and3    r3, r4, #15
139         bnez    r3, word_align_check
140 qword_set:
141         and3    r1, r1, #0x00ff         /* r1: abababab <-- ??????ab */
142         sll3    r3, r1, #8
143         or      r1, r3
144         sll3    r3, r1, #16
145         or      r1, r3
146         addi    r4, #-4
147 qword_set_loop:
148         ld      r3, @(4,r4)             /* cache line allocate */
149         addi    r2, #-16
150         st      r1, @+r4
151         st      r1, @+r4
152         cmpui   r2, #16
153         st      r1, @+r4
154         st      r1, @+r4
155         bnc     qword_set_loop
156         bnez    r2, set_remainder
157         jmp     r14
158 set_remainder:
159         cmpui   r2, #4
160         bc      byte_set_wrap1
161         addi    r2, #-4
162         bra     word_set_loop
163
164 byte_set_wrap:
165         addi    r2, #4
166         beqz    r2, end_memset
167 byte_set_wrap1:
168         addi    r4, #4
169 byte_set:
170         addi    r2, #-1
171         stb     r1, @r4
172         addi    r4, #1
173         bnez    r2, byte_set
174 end_memset:
175         jmp     r14
176
177 #endif /* not CONFIG_ISA_DUAL_ISSUE */
178
179         .end