Simplify special case function, speedup of about 0.2MHz on both coldfire and pp decod...
[kugel-rb.git] / firmware / target / mips / memset-mips.S
blob8db76d91237a43281ece42e3a49881c6b3256498
1 /***************************************************************************
2  *             __________               __   ___.
3  *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
4  *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
5  *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
6  *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
7  *                     \/            \/     \/    \/            \/
8  * $Id$
9  *
10  * This file was originally part of the Linux/MIPS GNU C Library
11  * Copyright (C) 1998 by Ralf Baechle
12  * Adapted for Rockbox by Maurus Cuelenaere, 2009
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20  * KIND, either express or implied.
21  *
22  ****************************************************************************/
24 #include "config.h"
25 #include "mips.h"
27 #define FILL256(dst, offset, val)     \
28     sw  val, (offset + 0x00)(dst);    \
29     sw  val, (offset + 0x04)(dst);    \
30     sw  val, (offset + 0x08)(dst);    \
31     sw  val, (offset + 0x0c)(dst);    \
32     sw  val, (offset + 0x10)(dst);    \
33     sw  val, (offset + 0x14)(dst);    \
34     sw  val, (offset + 0x18)(dst);    \
35     sw  val, (offset + 0x1c)(dst);    \
36     sw  val, (offset + 0x20)(dst);    \
37     sw  val, (offset + 0x24)(dst);    \
38     sw  val, (offset + 0x28)(dst);    \
39     sw  val, (offset + 0x2c)(dst);    \
40     sw  val, (offset + 0x30)(dst);    \
41     sw  val, (offset + 0x34)(dst);    \
42     sw  val, (offset + 0x38)(dst);    \
43     sw  val, (offset + 0x3c)(dst);    \
44     sw  val, (offset + 0x40)(dst);    \
45     sw  val, (offset + 0x44)(dst);    \
46     sw  val, (offset + 0x48)(dst);    \
47     sw  val, (offset + 0x4c)(dst);    \
48     sw  val, (offset + 0x50)(dst);    \
49     sw  val, (offset + 0x54)(dst);    \
50     sw  val, (offset + 0x58)(dst);    \
51     sw  val, (offset + 0x5c)(dst);    \
52     sw  val, (offset + 0x60)(dst);    \
53     sw  val, (offset + 0x64)(dst);    \
54     sw  val, (offset + 0x68)(dst);    \
55     sw  val, (offset + 0x6c)(dst);    \
56     sw  val, (offset + 0x70)(dst);    \
57     sw  val, (offset + 0x74)(dst);    \
58     sw  val, (offset + 0x78)(dst);    \
59     sw  val, (offset + 0x7c)(dst);    \
60     sw  val, (offset + 0x80)(dst);    \
61     sw  val, (offset + 0x84)(dst);    \
62     sw  val, (offset + 0x88)(dst);    \
63     sw  val, (offset + 0x8c)(dst);    \
64     sw  val, (offset + 0x90)(dst);    \
65     sw  val, (offset + 0x94)(dst);    \
66     sw  val, (offset + 0x98)(dst);    \
67     sw  val, (offset + 0x9c)(dst);    \
68     sw  val, (offset + 0xa0)(dst);    \
69     sw  val, (offset + 0xa4)(dst);    \
70     sw  val, (offset + 0xa8)(dst);    \
71     sw  val, (offset + 0xac)(dst);    \
72     sw  val, (offset + 0xb0)(dst);    \
73     sw  val, (offset + 0xb4)(dst);    \
74     sw  val, (offset + 0xb8)(dst);    \
75     sw  val, (offset + 0xbc)(dst);    \
76     sw  val, (offset + 0xc0)(dst);    \
77     sw  val, (offset + 0xc4)(dst);    \
78     sw  val, (offset + 0xc8)(dst);    \
79     sw  val, (offset + 0xcc)(dst);    \
80     sw  val, (offset + 0xd0)(dst);    \
81     sw  val, (offset + 0xd4)(dst);    \
82     sw  val, (offset + 0xd8)(dst);    \
83     sw  val, (offset + 0xdc)(dst);    \
84     sw  val, (offset + 0xe0)(dst);    \
85     sw  val, (offset + 0xe4)(dst);    \
86     sw  val, (offset + 0xe8)(dst);    \
87     sw  val, (offset + 0xec)(dst);    \
88     sw  val, (offset + 0xf0)(dst);    \
89     sw  val, (offset + 0xf4)(dst);    \
90     sw  val, (offset + 0xf8)(dst);    \
91     sw  val, (offset + 0xfc)(dst);
93 #define FILL128(dst, offset, val)     \
94     sw  val, (offset + 0x00)(dst);    \
95     sw  val, (offset + 0x04)(dst);    \
96     sw  val, (offset + 0x08)(dst);    \
97     sw  val, (offset + 0x0c)(dst);    \
98     sw  val, (offset + 0x10)(dst);    \
99     sw  val, (offset + 0x14)(dst);    \
100     sw  val, (offset + 0x18)(dst);    \
101     sw  val, (offset + 0x1c)(dst);    \
102     sw  val, (offset + 0x20)(dst);    \
103     sw  val, (offset + 0x24)(dst);    \
104     sw  val, (offset + 0x28)(dst);    \
105     sw  val, (offset + 0x2c)(dst);    \
106     sw  val, (offset + 0x30)(dst);    \
107     sw  val, (offset + 0x34)(dst);    \
108     sw  val, (offset + 0x38)(dst);    \
109     sw  val, (offset + 0x3c)(dst);    \
110     sw  val, (offset + 0x40)(dst);    \
111     sw  val, (offset + 0x44)(dst);    \
112     sw  val, (offset + 0x48)(dst);    \
113     sw  val, (offset + 0x4c)(dst);    \
114     sw  val, (offset + 0x50)(dst);    \
115     sw  val, (offset + 0x54)(dst);    \
116     sw  val, (offset + 0x58)(dst);    \
117     sw  val, (offset + 0x5c)(dst);    \
118     sw  val, (offset + 0x60)(dst);    \
119     sw  val, (offset + 0x64)(dst);    \
120     sw  val, (offset + 0x68)(dst);    \
121     sw  val, (offset + 0x6c)(dst);    \
122     sw  val, (offset + 0x70)(dst);    \
123     sw  val, (offset + 0x74)(dst);    \
124     sw  val, (offset + 0x78)(dst);    \
125     sw  val, (offset + 0x7c)(dst);
127 #define FILL64(dst, offset, val)      \
128     sw  val, (offset + 0x00)(dst);    \
129     sw  val, (offset + 0x04)(dst);    \
130     sw  val, (offset + 0x08)(dst);    \
131     sw  val, (offset + 0x0c)(dst);    \
132     sw  val, (offset + 0x10)(dst);    \
133     sw  val, (offset + 0x14)(dst);    \
134     sw  val, (offset + 0x18)(dst);    \
135     sw  val, (offset + 0x1c)(dst);    \
136     sw  val, (offset + 0x20)(dst);    \
137     sw  val, (offset + 0x24)(dst);    \
138     sw  val, (offset + 0x28)(dst);    \
139     sw  val, (offset + 0x2c)(dst);    \
140     sw  val, (offset + 0x30)(dst);    \
141     sw  val, (offset + 0x34)(dst);    \
142     sw  val, (offset + 0x38)(dst);    \
143     sw  val, (offset + 0x3c)(dst);
145 #define FILL32(dst, offset, val)      \
146     sw  val, (offset + 0x00)(dst);    \
147     sw  val, (offset + 0x04)(dst);    \
148     sw  val, (offset + 0x08)(dst);    \
149     sw  val, (offset + 0x0c)(dst);    \
150     sw  val, (offset + 0x10)(dst);    \
151     sw  val, (offset + 0x14)(dst);    \
152     sw  val, (offset + 0x18)(dst);    \
153     sw  val, (offset + 0x1c)(dst);
155 #define FILL    64
156 #define F_FILL  FILL64
159 #ifdef ROCKBOX_BIG_ENDIAN
160 # define SWHI   swl                /* high part is left in big-endian        */
161 #else
162 # define SWHI   swr                /* high part is right in little-endian    */
163 #endif
166  * memset(void *s, int c, size_t n)
168  * a0: start of area to clear
169  * a1: char to fill with
170  * a2: size of area to clear
171  */
172     .section   .icode, "ax", %progbits
174     .global    memset
175     .type      memset, %function
176     
177     .set       noreorder
178     .align     5
179 memset:
180     beqz    a1, 1f
181     move    v0, a0                /* result */
183     andi    a1, 0xff              /* spread fillword */
184     sll     t1, a1, 8
185     or      a1, t1
186     sll     t1, a1, 16
187     or      a1, t1
190     sltiu   t0, a2, 4             /* very small region? */
191     bnez    t0, small_memset
192     andi    t0, a0, 3             /* aligned? */
194     beqz    t0, 1f
195     subu    t0, 4                 /* alignment in bytes */
197     SWHI    a1, (a0)              /* make word aligned */
198     subu    a0, t0                /* word align ptr */
199     addu    a2, t0                /* correct size */
201 1:  ori     t1, a2, (FILL-1)      /* # of full blocks */
202     xori    t1, (FILL-1)
203     beqz    t1, memset_partial    /* no block to fill */
204     andi    t0, a2, (FILL-4)
206     addu    t1, a0                /* end address */
207     .set    reorder
208 1:  addiu   a0, FILL
209     F_FILL( a0, -FILL, a1 )
210     bne     t1, a0, 1b
211     .set    noreorder
213 memset_partial:
214     la      t1, 2f                /* where to start */
215     subu    t1, t0
216     jr      t1
217     addu    a0, t0                /* dest ptr */
219     F_FILL( a0, -FILL, a1 )       /* ... but first do words ... */
220 2:  andi    a2, 3                 /* 0 <= n <= 3 to go */
222     beqz    a2, 1f
223     addu    a0, a2                /* What's left */
224     SWHI    a1, -1(a0)
225 1:  jr      ra
226     move    a2, zero
228 small_memset:
229     beqz    a2, 2f
230     addu    t1, a0, a2
232 1:  addiu   a0, 1                 /* fill bytewise */
233     bne     t1, a0, 1b
234     sb      a1, -1(a0)
236 2:  jr      ra                    /* done */
237     move    a2, zero
239     .set       reorder