aboutsummaryrefslogtreecommitdiff
path: root/newlib/libc/machine/sh/memset.S
blob: 7352b4141ca19d454322964d27ab2fccebdfc3ce (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
!
! Fast SH memset
!
! by Toshiyasu Morita (tm@netcom.com)
!
! Entry: r4: destination pointer
!        r5: fill value
!        r6: byte count
!
! Exit:  r0-r3: trashed
!

! This assumes that the first four bytes of the address space (0..3) are
! reserved - usually by the linker script.  Otherwise, we would had to check
! for the case of objects of the size 12..15 at address 0..3 .

#include "asm.h"

ENTRY(memset)
	mov	#12,r0	! Check for small number of bytes
	cmp/gt	r6,r0
	mov	r4,r0
	SL(bt, L_store_byte_loop_check0, add r4,r6)

	tst	#3,r0	! Align destination
	SL(bt,	L_dup_bytes, extu.b r5,r5)
	.balignw 4,0x0009
L_align_loop:
	mov.b	r5,@r0
	add	#1,r0
	tst	#3,r0
	bf	L_align_loop

L_dup_bytes:	
	swap.b	r5,r2	! Duplicate bytes across longword
	or	r2,r5
	swap.w	r5,r2
	or	r2,r5

	add	#-16,r6

	.balignw 4,0x0009
L_store_long_loop:
	mov.l	r5,@r0	! Store double longs to memory
	cmp/hs	r6,r0
	mov.l	r5,@(4,r0)
	SL(bf, L_store_long_loop, add #8,r0)

	add	#16,r6

L_store_byte_loop_check0:
	cmp/eq	r6,r0
	bt	L_exit
	.balignw 4,0x0009
L_store_byte_loop:
	mov.b	r5,@r0	! Store bytes to memory
	add	#1,r0
	cmp/eq	r6,r0
	bf	L_store_byte_loop

L_exit:
	rts
	mov	r4,r0