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