blob: 7c9fe88463efcc40497b99ff074566e7a038fe3c [file] [log] [blame]
Jens Arnoldeb65f892006-02-22 01:20:45 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
Linus Nielsen Feltzing5a0cb682006-07-25 11:16:03 +000010 * Copyright (C) 2004 by Jens Arnold
Jens Arnoldeb65f892006-02-22 01:20:45 +000011 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include "config.h"
20
21 .section .icode,"ax",@progbits
22
Linus Nielsen Feltzing5a0cb682006-07-25 11:16:03 +000023 .align 2
24 .global memset
25 .type memset,@function
Jens Arnoldeb65f892006-02-22 01:20:45 +000026
Linus Nielsen Feltzing5a0cb682006-07-25 11:16:03 +000027/* Fills a memory region with specified byte value
Jens Arnoldeb65f892006-02-22 01:20:45 +000028 * This version is optimized for speed
29 *
30 * arguments:
31 * (4,%sp) - start address
32 * (8,%sp) - data
33 * (12,%sp) - length
34 *
35 * return value:
Linus Nielsen Feltzing5a0cb682006-07-25 11:16:03 +000036 * %d0 - start address (like ANSI version)
Jens Arnoldeb65f892006-02-22 01:20:45 +000037 *
38 * register usage:
Linus Nielsen Feltzing5a0cb682006-07-25 11:16:03 +000039 * %d0 - data (spread to all 4 bytes when using long stores)
Jens Arnoldeb65f892006-02-22 01:20:45 +000040 * %d1 - temporary / data (for burst transfer)
41 * %d2 - data (for burst transfer)
42 * %d3 - data (for burst transfer)
43 * %a0 - start address
44 * %a1 - current address (runs down from end to start)
45 *
46 * For maximum speed this routine uses both long stores and burst mode,
47 * storing whole lines with movem.l. The routine fills memory from end
48 * to start in order to ease returning the start address.
49 */
Linus Nielsen Feltzing5a0cb682006-07-25 11:16:03 +000050memset:
Jens Arnoldeb65f892006-02-22 01:20:45 +000051 move.l (4,%sp),%a0 /* start address */
52 move.l (8,%sp),%d0 /* data */
53 move.l (12,%sp),%a1 /* length */
Jens Arnoldeb65f892006-02-22 01:20:45 +000054 add.l %a0,%a1 /* %a1 = end address */
55
56 move.l %a0,%d1
Linus Nielsen Feltzing5a0cb682006-07-25 11:16:03 +000057 addq.l #7,%d1
Jens Arnoldeb65f892006-02-22 01:20:45 +000058 and.l #0xFFFFFFFC,%d1 /* %d1 = first long bound + 4 */
59 cmp.l %d1,%a1 /* at least one aligned longword to fill? */
Linus Nielsen Feltzing5a0cb682006-07-25 11:16:03 +000060 blo.b .no_longs /* no, jump directly to byte loop */
Jens Arnoldeb65f892006-02-22 01:20:45 +000061
Linus Nielsen Feltzing5a0cb682006-07-25 11:16:03 +000062 and.l #0xFF,%d0 /* start: spread data to all 4 bytes */
Jens Arnoldeb65f892006-02-22 01:20:45 +000063 move.l %d0,%d1
Linus Nielsen Feltzing5a0cb682006-07-25 11:16:03 +000064 lsl.l #8,%d1
65 or.l %d1,%d0 /* data now in 2 lower bytes of %d0 */
66 move.l %d0,%d1
67 swap %d0
68 or.l %d1,%d0 /* data now in all 4 bytes of %d0 */
Jens Arnoldeb65f892006-02-22 01:20:45 +000069
70 move.l %a1,%d1
71 and.l #0xFFFFFFFC,%d1 /* %d1 = last long bound */
Linus Nielsen Feltzing5a0cb682006-07-25 11:16:03 +000072 cmp.l %d1,%a1 /* any bytes to set? */
73 bls.b .end_b1 /* no: skip byte loop */
Jens Arnoldeb65f892006-02-22 01:20:45 +000074
Linus Nielsen Feltzing5a0cb682006-07-25 11:16:03 +000075 /* leading byte loop: sets 0..3 bytes */
76.loop_b1:
77 move.b %d0,-(%a1) /* store byte */
78 cmp.l %d1,%a1 /* runs %a1 down to last long bound */
79 bhi.b .loop_b1
80
81.end_b1:
82 moveq.l #31,%d1
Jens Arnoldeb65f892006-02-22 01:20:45 +000083 add.l %a0,%d1
84 and.l #0xFFFFFFF0,%d1 /* %d1 = first line bound + 16 */
85 cmp.l %d1,%a1 /* at least one full line to fill? */
86 blo.b .no_lines /* no, jump to longword loop */
87
88 mov.l %a1,%d1
89 and.l #0xFFFFFFF0,%d1 /* %d1 = last line bound */
90 cmp.l %d1,%a1 /* any longwords to set? */
91 bls.b .end_l1 /* no: skip longword loop */
92
93 /* leading longword loop: sets 0..3 longwords */
94.loop_l1:
95 move.l %d0,-(%a1) /* store longword */
96 cmp.l %d1,%a1 /* runs %a1 down to last line bound */
97 bhi.b .loop_l1
98
99.end_l1:
100 move.l %d2,-(%sp) /* free some registers */
101 move.l %d3,-(%sp)
102
103 move.l %d0,%d1 /* spread data to 4 data registers */
104 move.l %d0,%d2
105 move.l %d0,%d3
Linus Nielsen Feltzing5a0cb682006-07-25 11:16:03 +0000106 lea.l (15,%a0),%a0 /* start address += 15, acct. for trl. data */
Jens Arnoldeb65f892006-02-22 01:20:45 +0000107
108 /* main loop: set whole lines utilising burst mode */
109.loop_line:
110 lea.l (-16,%a1),%a1 /* pre-decrement */
111 movem.l %d0-%d3,(%a1) /* store line */
112 cmp.l %a0,%a1 /* runs %a1 down to first line bound */
113 bhi.b .loop_line
114
Linus Nielsen Feltzing5a0cb682006-07-25 11:16:03 +0000115 lea.l (-15,%a0),%a0 /* correct start address */
Jens Arnoldeb65f892006-02-22 01:20:45 +0000116 move.l (%sp)+,%d3 /* restore registers */
117 move.l (%sp)+,%d2
118
119 move.l %a0,%d1 /* %d1 = start address ... */
Linus Nielsen Feltzing5a0cb682006-07-25 11:16:03 +0000120 addq.l #3,%d1 /* ... +3, account for possible trailing bytes */
Jens Arnoldeb65f892006-02-22 01:20:45 +0000121 cmp.l %d1,%a1 /* any longwords left */
122 bhi.b .loop_l2 /* yes: jump to longword loop */
123 bra.b .no_longs /* no: skip loop */
124
125.no_lines:
126 move.l %a0,%d1 /* %d1 = start address ... */
Linus Nielsen Feltzing5a0cb682006-07-25 11:16:03 +0000127 addq.l #3,%d1 /* ... +3, account for possible trailing bytes */
Jens Arnoldeb65f892006-02-22 01:20:45 +0000128
129 /* trailing longword loop */
130.loop_l2:
131 move.l %d0,-(%a1) /* store longword */
132 cmp.l %d1,%a1 /* runs %a1 down to first long bound */
133 bhi.b .loop_l2
134
135.no_longs:
Linus Nielsen Feltzing5a0cb682006-07-25 11:16:03 +0000136 cmp.l %a0,%a1 /* any bytes left? */
137 bls.b .end_b2 /* no: skip loop */
Jens Arnoldeb65f892006-02-22 01:20:45 +0000138
Linus Nielsen Feltzing5a0cb682006-07-25 11:16:03 +0000139 /* trailing byte loop */
140.loop_b2:
141 move.b %d0,-(%a1) /* store byte */
Jens Arnoldeb65f892006-02-22 01:20:45 +0000142 cmp.l %a0,%a1 /* runs %a1 down to start address */
Linus Nielsen Feltzing5a0cb682006-07-25 11:16:03 +0000143 bhi.b .loop_b2
Jens Arnoldeb65f892006-02-22 01:20:45 +0000144
Linus Nielsen Feltzing5a0cb682006-07-25 11:16:03 +0000145.end_b2:
Jens Arnoldeb65f892006-02-22 01:20:45 +0000146 move.l %a0,%d0 /* return start address */
147 rts
148
149.end:
Linus Nielsen Feltzing5a0cb682006-07-25 11:16:03 +0000150 .size memset,.end-memset