summaryrefslogtreecommitdiff
path: root/firmware/target/coldfire/memset16-coldfire.S
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/coldfire/memset16-coldfire.S')
-rwxr-xr-xfirmware/target/coldfire/memset16-coldfire.S144
1 files changed, 144 insertions, 0 deletions
diff --git a/firmware/target/coldfire/memset16-coldfire.S b/firmware/target/coldfire/memset16-coldfire.S
new file mode 100755
index 0000000000..d9f72f683f
--- /dev/null
+++ b/firmware/target/coldfire/memset16-coldfire.S
@@ -0,0 +1,144 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 by Jens Arnold
11 *
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
23 .global memset16
24 .type memset16,@function
25
26/* Fills a memory region with specified word value
27 * Start address must be word aligned, length is in words
28 * 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:
36 * %d0 - start address
37 *
38 * register usage:
39 * %d0 - data (spread to both words when using long stores)
40 * %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 */
50memset16:
51 move.l (4,%sp),%a0 /* start address */
52 move.l (8,%sp),%d0 /* data */
53 move.l (12,%sp),%a1 /* length */
54 add.l %a1,%a1
55 add.l %a0,%a1 /* %a1 = end address */
56
57 move.l %a0,%d1
58 addq.l #6,%d1
59 and.l #0xFFFFFFFC,%d1 /* %d1 = first long bound + 4 */
60 cmp.l %d1,%a1 /* at least one aligned longword to fill? */
61 blo.b .no_longs /* no, jump directly to word loop */
62
63 and.l #0xFFFF,%d0 /* start: spread data to both words */
64 move.l %d0,%d1
65 swap %d1
66 or.l %d1,%d0 /* data now in both words */
67
68 move.l %a1,%d1
69 and.l #0xFFFFFFFC,%d1 /* %d1 = last long bound */
70 cmp.l %d1,%a1 /* one extra word? */
71 bls.b .end_w1 /* no: skip */
72
73 move.w %d0,-(%a1) /* set leading word */
74
75.end_w1:
76 moveq.l #30,%d1
77 add.l %a0,%d1
78 and.l #0xFFFFFFF0,%d1 /* %d1 = first line bound + 16 */
79 cmp.l %d1,%a1 /* at least one full line to fill? */
80 blo.b .no_lines /* no, jump to longword loop */
81
82 mov.l %a1,%d1
83 and.l #0xFFFFFFF0,%d1 /* %d1 = last line bound */
84 cmp.l %d1,%a1 /* any longwords to set? */
85 bls.b .end_l1 /* no: skip longword loop */
86
87 /* leading longword loop: sets 0..3 longwords */
88.loop_l1:
89 move.l %d0,-(%a1) /* store longword */
90 cmp.l %d1,%a1 /* runs %a1 down to last line bound */
91 bhi.b .loop_l1
92
93.end_l1:
94 move.l %d2,-(%sp) /* free some registers */
95 move.l %d3,-(%sp)
96
97 move.l %d0,%d1 /* spread data to 4 data registers */
98 move.l %d0,%d2
99 move.l %d0,%d3
100 lea.l (14,%a0),%a0 /* start address += 14, acct. for trl. data */
101
102 /* main loop: set whole lines utilising burst mode */
103.loop_line:
104 lea.l (-16,%a1),%a1 /* pre-decrement */
105 movem.l %d0-%d3,(%a1) /* store line */
106 cmp.l %a0,%a1 /* runs %a1 down to first line bound */
107 bhi.b .loop_line
108
109 lea.l (-14,%a0),%a0 /* correct start address */
110 move.l (%sp)+,%d3 /* restore registers */
111 move.l (%sp)+,%d2
112
113 move.l %a0,%d1 /* %d1 = start address ... */
114 addq.l #2,%d1 /* ... +2, account for possible trailing word */
115 cmp.l %d1,%a1 /* any longwords left */
116 bhi.b .loop_l2 /* yes: jump to longword loop */
117 bra.b .no_longs /* no: skip loop */
118
119.no_lines:
120 move.l %a0,%d1 /* %d1 = start address ... */
121 addq.l #2,%d1 /* ... +2, account for possible trailing word */
122
123 /* trailing longword loop */
124.loop_l2:
125 move.l %d0,-(%a1) /* store longword */
126 cmp.l %d1,%a1 /* runs %a1 down to first long bound */
127 bhi.b .loop_l2
128
129.no_longs:
130 cmp.l %a0,%a1 /* any words left? */
131 bls.b .end_w2 /* no: skip loop */
132
133 /* trailing word loop */
134.loop_w2:
135 move.w %d0,-(%a1) /* store word */
136 cmp.l %a0,%a1 /* runs %a1 down to start address */
137 bhi.b .loop_w2
138
139.end_w2:
140 move.l %a0,%d0 /* return start address */
141 rts
142
143.end:
144 .size memset16,.end-memset16