4 ; Fast memory manipulation (TMA)
6 ; © 1994-1998 Straylight
9 ;----- Licensing note -------------------------------------------------------
11 ; This file is part of Straylight's core libraries (corelib).
13 ; Corelib is free software; you can redistribute it and/or modify
14 ; it under the terms of the GNU General Public License as published by
15 ; the Free Software Foundation; either version 2, or (at your option)
18 ; Corelib is distributed in the hope that it will be useful,
19 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 ; GNU General Public License for more details.
23 ; You should have received a copy of the GNU General Public License
24 ; along with Corelib. If not, write to the Free Software Foundation,
25 ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 ;----- Standard header ------------------------------------------------------
32 ;----- External dependencies ------------------------------------------------
36 ;----- Main Code ------------------------------------------------------------
38 AREA |Sapphire$$Code|,CODE,READONLY
42 ; On entry: R0 == destination pointer
43 ; R1 == source pointer
44 ; R2 == number of bytes to move
48 ; Use: A very fast block moving routine. Word aligning is not
49 ; necessary, and the blocks may overlap. This is basically
50 ; the routine from PRM 2, hacked to cope with overlapping.
55 ; --- Do we need to do it backwards? ---
61 ; --- Copy downwards ---
63 STMFD R13!,{R0-R12,R14} ;Stack some registers
65 TST R0,#3 ;Is destination word aligned
66 BNE %10fastMove ;No -- word align it
68 00fastMove TST R1,#3 ;Is source word aligned
69 BNE %20fastMove ;No -- word align that
71 ; --- Source and destination are now word aligned ---
73 SUBS R2,R2,#16 ;4 or more words to do?
76 SUBS R2,R2,#16 ;8 or more words to do?
79 ; --- 8 words at a time ---
81 01fastMove LDMIA R1!,{R3-R9,R14} ;Load 8 words
82 STMIA R0!,{R3-R9,R14} ;Move them
83 SUBS R2,R2,#32 ;Decrement count
84 BGE %01fastMove ;Keep moving blocks if we can
86 CMP R2,#-32 ;Are we finished?
87 LDMEQFD R13!,{R0-R12,PC}^ ;Yes -- return
89 ; --- 4 words at a time ---
91 02fastMove ADDS R2,R2,#16 ;4 whole words to do?
94 LDMIA R1!,{R3-R6} ;Load 4 words
95 STMIA R0!,{R3-R6} ;Move them
96 LDMEQFD R13!,{R0-R12,PC}^ ;Return if finished
99 ; --- Less than 4 words left ---
101 03fastMove ADDS R2,R2,#8 ;2 words to do?
104 LDMIA R1!,{R3,R4} ;Load 2 words
105 STMIA R0!,{R3,R4} ;Move them
106 LDMEQFD R13!,{R0-R12,PC}^ ;Return if finished
109 ; --- Less than 2 words left ---
111 04fastMove ADDS R2,R2,#4 ;1 word to do?
114 LDR R3,[R1],#4 ;Load a word
115 STR R3,[R0],#4 ;Move it
116 LDMEQFD R13!,{R0-R12,PC}^ ;Return if finished
119 ; --- Less than 1 word! ---
121 05fastMove ADDS R2,R2,#4
122 LDMEQFD R13!,{R0-R12,PC}^ ;Pointless?
124 ; --- 1, 2 or 3 bytes left ---
127 06fastMove STRB R14,[R0],#1
131 LDMFD R13!,{R0-R12,PC}^ ;Finished at last!
133 ; --- Word align destination ---
135 10fastMove LDRB R14,[R1],#1
138 LDMEQFD R13!,{R0-R12,PC}^
140 TST R0,#3 ;Is it word aligned?
141 BNE %10fastMove ;No -- keep going
143 B %00fastMove ;Move the rest
145 ; --- Word align source (Urggg... bloogle...) ---
146 ; --- PRM for documentation ---
148 20fastMove AND R11,R1,#3
155 SUBS R2,R2,#16 ;4 or more words to do?
158 SUBS R2,R2,#16 ;8 or more words to do?
161 ; --- 8 words at a time ---
163 21fastMove LDMIA R1!,{R4-R10,R14} ;Load 8 words
182 ORR R9,R9,R10,LSL R12
185 ORR R10,R10,R14,LSL R12
187 STMIA R0!,{R3-R10} ;Move them
189 SUBS R2,R2,#32 ;Decrement count
190 BGE %21fastMove ;Keep moving blocks if we can
192 CMP R2,#-32 ;Are we finished?
193 LDMEQFD R13!,{R0-R12,PC}^ ;Yes -- return
195 ; --- 4 words at a time ---
197 22fastMove ADDS R2,R2,#16 ;4 whole words to do?
200 LDMIA R1!,{R4-R7} ;Load 4 words
212 STMIA R0!,{R3-R6} ;Move them
213 LDMEQFD R13!,{R0-R12,PC}^ ;Return if finished
217 ; --- Less than 4 words left ---
219 23fastMove ADDS R2,R2,#8 ;2 words to do?
222 LDMIA R1!,{R4,R5} ;Load 2 words
228 STMIA R0!,{R3,R4} ;Move them
229 LDMEQFD R13!,{R0-R12,PC}^ ;Return if finished
233 ; --- Less than 2 words left ---
235 24fastMove ADDS R2,R2,#4 ;1 word to do?
238 LDR R4,[R1],#4 ;Load a word
241 STR R3,[R0],#4 ;Move it
242 LDMEQFD R13!,{R0-R12,PC}^ ;Return if finished
246 ; --- Less than 1 word! ---
248 25fastMove ADDS R2,R2,#4
249 LDMEQFD R13!,{R0-R12,PC}^ ;Pointless?
251 ; --- 1, 2 or 3 bytes left ---
254 ORR R3,R3,R14,LSL R12
255 26fastMove STRB R3,[R0],#1
260 LDMFD R13!,{R0-R12,PC}^ ;Finished at last!
262 ; --- Copy upwards ---
264 49fastMove STMFD R13!,{R0-R12,R14} ;Stack some registers
268 TST R0,#3 ;Is destination word aligned
269 BNE %60fastMove ;No -- word align it
271 50fastMove TST R1,#3 ;Is source word aligned
272 BNE %70fastMove ;No -- word align that
274 ; --- Source and destination are now word aligned ---
276 SUBS R2,R2,#16 ;4 or more words to do?
279 SUBS R2,R2,#16 ;8 or more words to do?
282 ; --- 8 words at a time ---
284 51fastMove LDMDB R1!,{R3-R9,R14} ;Load 8 words
285 STMDB R0!,{R3-R9,R14} ;Move them
286 SUBS R2,R2,#32 ;Decrement count
287 BGE %51fastMove ;Keep moving blocks if we can
289 CMP R2,#-32 ;Are we finished?
290 LDMEQFD R13!,{R0-R12,PC}^ ;Yes -- return
292 ; --- 4 words at a time ---
294 52fastMove ADDS R2,R2,#16 ;4 whole words to do?
297 LDMDB R1!,{R3-R6} ;Load 4 words
298 STMDB R0!,{R3-R6} ;Move them
299 LDMEQFD R13!,{R0-R12,PC}^ ;Return if finished
302 ; --- Less than 4 words left ---
304 53fastMove ADDS R2,R2,#8 ;2 words to do?
307 LDMDB R1!,{R3,R4} ;Load 2 words
308 STMDB R0!,{R3,R4} ;Move them
309 LDMEQFD R13!,{R0-R12,PC}^ ;Return if finished
312 ; --- Less than 2 words left ---
314 54fastMove ADDS R2,R2,#4 ;1 word to do?
317 LDR R3,[R1,#-4]! ;Load a word
318 STR R3,[R0,#-4]! ;Move it
319 LDMEQFD R13!,{R0-R12,PC}^ ;Return if finished
322 ; --- Less than 1 word! ---
324 55fastMove ADDS R2,R2,#4
325 LDMEQFD R13!,{R0-R12,PC}^ ;Pointless?
327 ; --- 1, 2 or 3 bytes left ---
330 56fastMove MOV R3,R14,LSR #24
336 LDMFD R13!,{R0-R12,PC}^ ;Finished at last!
338 ; --- Word align destination ---
340 60fastMove LDRB R14,[R1,#-1]!
343 LDMEQFD R13!,{R0-R12,PC}^
345 TST R0,#3 ;Is it word aligned?
346 BNE %60fastMove ;No -- keep going
348 B %50fastMove ;Move the rest
350 ; --- Word align source (Urggg... bloogle...) ---
352 ; There are several oddnesses here.
354 70fastMove AND R11,R1,#3
355 BIC R1,R1,#3 ;Word align source
356 MOV R11,R11,LSL #3 ;This is the right shift
357 RSB R12,R11,#32 ;This is the left shift
359 MOV R14,R14,LSL R12 ;Get the odd bit
361 SUBS R2,R2,#16 ;4 or more words to do?
364 SUBS R2,R2,#16 ;8 or more words to do?
367 ; --- 8 words at a time ---
369 71fastMove LDMDA R1!,{R3-R10} ;Load 8 words
370 ORR R14,R14,R10,LSR R11
373 ORR R10,R10,R9,LSR R11
393 STMDB R0!,{R4-R10,R14} ;Move them
395 SUBS R2,R2,#32 ;Decrement count
396 BGE %71fastMove ;Keep moving blocks if we can
398 CMP R2,#-32 ;Are we finished?
399 LDMEQFD R13!,{R0-R12,PC}^ ;Yes -- return
401 ; --- 4 words at a time ---
403 72fastMove ADDS R2,R2,#16 ;4 whole words to do?
406 LDMDA R1!,{R3-R6} ;Load 4 words
407 ORR R14,R14,R6,LSR R11
418 STMDB R0!,{R4-R6,R14} ;Move them
419 LDMEQFD R13!,{R0-R12,PC}^ ;Return if finished
423 ; --- Less than 4 words left ---
425 73fastMove ADDS R2,R2,#8 ;2 words to do?
428 LDMDA R1!,{R3,R4} ;Load 2 words
429 ORR R14,R14,R4,LSR R11
434 STMDB R0!,{R4,R14} ;Move them
435 LDMEQFD R13!,{R0-R12,PC}^ ;Return if finished
439 ; --- Less than 2 words left ---
441 74fastMove ADDS R2,R2,#4 ;1 word to do?
444 LDR R3,[R1],#-4 ;Load a word
445 ORR R14,R14,R3,LSR R11
447 STR R14,[R0,#-4]! ;Move it
448 LDMEQFD R13!,{R0-R12,PC}^ ;Return if finished
452 ; --- Less than 1 word! ---
454 75fastMove ADDS R2,R2,#4
455 LDMEQFD R13!,{R0-R12,PC}^ ;Pointless?
457 ; --- 1, 2 or 3 bytes left ---
460 ORR R14,R14,R3,LSR R11
461 76fastMove MOV R3,R14,LSR #24
467 LDMFD R13!,{R0-R12,PC}^ ;Finished at last!
469 ;----- Workspace ------------------------------------------------------------
473 ;----- That's all folks -----------------------------------------------------