Merge branch 'master' of 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
16         .text
17         .global memset
18
19 #ifdef CONFIG_ISA_DUAL_ISSUE
20
21         .align 4
22 memset:
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
29 word_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) */
34 align_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
40 word_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
46 word_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
53 qword_align_check:                      /* len >= 16 */
54         and3    r3, r4, #15
55         bnez    r3, word_align_check
56 qword_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
62 qword_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
70 set_remainder:
71         cmpui   r2, #4
72         bc      byte_set_wrap1
73         addi    r2, #-4
74         bra     word_set_loop
75
76 byte_set_wrap:
77         addi    r2, #4
78         cmpz    r2
79         jc      r14
80 byte_set_wrap1:
81         addi    r4, #4
82 #if defined(CONFIG_ISA_M32R2)
83 byte_set:
84         addi    r2, #-1             ||  stb     r1, @r4+
85         bnez    r2, byte_set
86 #elif defined(CONFIG_ISA_M32R)
87 byte_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
94 end_memset:
95         jmp     r14
96
97 #else /* not CONFIG_ISA_DUAL_ISSUE */
98
99         .align 4
100 memset:
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
107 word_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) */
112 align_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
120 word_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
128 word_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
136 qword_align_check:                      /* len >= 16 */
137         and3    r3, r4, #15
138         bnez    r3, word_align_check
139 qword_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
146 qword_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
157 set_remainder:
158         cmpui   r2, #4
159         bc      byte_set_wrap1
160         addi    r2, #-4
161         bra     word_set_loop
162
163 byte_set_wrap:
164         addi    r2, #4
165         beqz    r2, end_memset
166 byte_set_wrap1:
167         addi    r4, #4
168 byte_set:
169         addi    r2, #-1
170         stb     r1, @r4
171         addi    r4, #1
172         bnez    r2, byte_set
173 end_memset:
174         jmp     r14
175
176 #endif /* not CONFIG_ISA_DUAL_ISSUE */
177
178         .end