This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / 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 word_set_wrap:
74         cmpui   r2, #4
75         bc      byte_set
76         addi    r2, #-4
77         bra     word_set_loop
78
79 byte_set_wrap:
80         addi    r2, #4
81         addi    r4, #4              ||  cmpz    r2
82         jc      r14
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, word_set_wrap
157         jmp     r14
158 word_set_wrap:
159         cmpui   r2, #4
160         bc      byte_set
161         addi    r2, #-4
162         bra     word_set_loop
163
164 byte_set_wrap:
165         addi    r2, #4
166         addi    r4, #4
167         beqz    r2, end_memset
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