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