1!   Copyright (C) 2008-2012 Imagination Technologies Ltd.
2
3	.text
4	.global	_memset
5	.type	_memset,function
6! D1Ar1 dst
7! D0Ar2 c
8! D1Ar3 cnt
9! D0Re0 dst
10_memset:
11	AND	D0Ar2,D0Ar2,#0xFF	! Ensure a byte input value
12	MULW 	D0Ar2,D0Ar2,#0x0101	! Duplicate byte value into  0-15
13	ANDS	D0Ar4,D1Ar1,#7		! Extract bottom LSBs of dst
14	LSL 	D0Re0,D0Ar2,#16		! Duplicate byte value into 16-31
15	ADD	A0.2,D0Ar2,D0Re0	! Duplicate byte value into 4 (A0.2)
16	MOV	D0Re0,D1Ar1		! Return dst
17	BZ	$LLongStub		! if start address is aligned
18	! start address is not aligned on an 8 byte boundary, so we
19	! need the number of bytes up to the next 8 byte address
20	! boundary, or the length of the string if less than 8, in D1Ar5
21	MOV	D0Ar2,#8		! Need 8 - N in D1Ar5 ...
22	SUB	D1Ar5,D0Ar2,D0Ar4	!            ... subtract N
23	CMP	D1Ar3,D1Ar5
24	MOVMI	D1Ar5,D1Ar3
25	B	$LByteStub		! dst is mis-aligned, do $LByteStub
26
27!
28! Preamble to LongLoop which generates 4*8 bytes per interation (5 cycles)
29!
30$LLongStub:
31	LSRS	D0Ar2,D1Ar3,#5
32	AND	D1Ar3,D1Ar3,#0x1F
33	MOV	A1.2,A0.2
34	BEQ	$LLongishStub
35	SUB	TXRPT,D0Ar2,#1
36	CMP	D1Ar3,#0
37$LLongLoop:
38	SETL 	[D1Ar1++],A0.2,A1.2
39	SETL 	[D1Ar1++],A0.2,A1.2
40	SETL 	[D1Ar1++],A0.2,A1.2
41	SETL 	[D1Ar1++],A0.2,A1.2
42	BR	$LLongLoop
43	BZ	$Lexit
44!
45! Preamble to LongishLoop which generates 1*8 bytes per interation (2 cycles)
46!
47$LLongishStub:
48	LSRS	D0Ar2,D1Ar3,#3
49	AND	D1Ar3,D1Ar3,#0x7
50	MOV	D1Ar5,D1Ar3
51	BEQ	$LByteStub
52	SUB	TXRPT,D0Ar2,#1
53	CMP	D1Ar3,#0
54$LLongishLoop:
55	SETL 	[D1Ar1++],A0.2,A1.2
56	BR	$LLongishLoop
57	BZ	$Lexit
58!
59! This does a byte structured burst of up to 7 bytes
60!
61!	D1Ar1 should point to the location required
62!	D1Ar3 should be the remaining total byte count
63!	D1Ar5 should be burst size (<= D1Ar3)
64!
65$LByteStub:
66	SUBS	D1Ar3,D1Ar3,D1Ar5	! Reduce count
67	ADD	D1Ar1,D1Ar1,D1Ar5	! Advance pointer to end of area
68	MULW	D1Ar5,D1Ar5,#4		! Scale to (1*4), (2*4), (3*4)
69	SUB	D1Ar5,D1Ar5,#(8*4)	! Rebase to -(7*4), -(6*4), -(5*4), ...
70	MOV	A1.2,D1Ar5
71	SUB	PC,CPC1,A1.2		! Jump into table below
72	SETB 	[D1Ar1+#(-7)],A0.2
73	SETB 	[D1Ar1+#(-6)],A0.2
74	SETB 	[D1Ar1+#(-5)],A0.2
75	SETB 	[D1Ar1+#(-4)],A0.2
76	SETB 	[D1Ar1+#(-3)],A0.2
77	SETB 	[D1Ar1+#(-2)],A0.2
78	SETB 	[D1Ar1+#(-1)],A0.2
79!
80! Return if all data has been output, otherwise do $LLongStub
81!
82	BNZ	$LLongStub
83$Lexit:
84	MOV	PC,D1RtP
85        .size _memset,.-_memset
86
87