1/* Optimised simple memory fill
2 *
3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11#include <asm/cache.h>
12
13        .section .text
14        .balign	L1_CACHE_BYTES
15
16###############################################################################
17#
18# void *memset(void *dst, int c, size_t n)
19#
20###############################################################################
21	.globl	memset
22        .type	memset,@function
23memset:
24	movm	[d2,d3],(sp)
25	mov	d0,(12,sp)
26	mov	d1,(16,sp)
27	mov	(20,sp),d2			# count
28	mov	d0,a0				# dst
29	mov	d0,e3				# the return value
30
31	cmp	+0,d2
32	beq	memset_done			# return if zero-length fill
33
34	# see if the region parameters are four-byte aligned
35	or	d0,d2,d3
36	and	+3,d3
37	bne	memset_1			# jump if not
38
39	extbu	d1
40	mov_asl	d1,d3,8,d1
41	or_asl	d1,d3,8,d1
42	or_asl	d1,d3,8,d1
43	or	d3,d1
44
45	# we want to transfer as much as we can in chunks of 32 bytes
46	cmp	+31,d2
47	bls	memset_4_remainder		# 4-byte aligned remainder
48
49	add	-32,d2
50	mov	+32,d3
51
52memset_4_loop:
53	mov	d1,(a0+)
54	mov	d1,(a0+)
55	mov	d1,(a0+)
56	mov	d1,(a0+)
57	mov	d1,(a0+)
58	mov	d1,(a0+)
59	mov	d1,(a0+)
60	mov	d1,(a0+)
61
62	sub	d3,d2
63	bcc	memset_4_loop
64
65	add	d3,d2
66	beq	memset_4_no_remainder
67
68memset_4_remainder:
69	# cut 4-7 words down to 0-3
70	cmp	+16,d2
71	bcs	memset_4_three_or_fewer_words
72	mov	d1,(a0+)
73	mov	d1,(a0+)
74	mov	d1,(a0+)
75	mov	d1,(a0+)
76	add	-16,d2
77	beq	memset_4_no_remainder
78
79	# copy the remaining 1, 2 or 3 words
80memset_4_three_or_fewer_words:
81	cmp	+8,d2
82	bcs	memset_4_one_word
83	beq	memset_4_two_words
84	mov	d1,(a0+)
85memset_4_two_words:
86	mov	d1,(a0+)
87memset_4_one_word:
88	mov	d1,(a0+)
89
90memset_4_no_remainder:
91	# check we set the correct amount
92	# TODO: REMOVE CHECK
93	sub	e3,a0,d2
94	mov	(20,sp),d1
95	cmp	d2,d1
96	beq	memset_done
97	break
98	break
99	break
100
101memset_done:
102	mov	e3,a0
103	ret	[d2,d3],8
104
105	# handle misaligned copying
106memset_1:
107	add	-1,d2
108	mov	+1,d3
109	setlb					# setlb requires the next insns
110						# to occupy exactly 4 bytes
111
112	sub	d3,d2
113	movbu	d1,(a0)
114	inc	a0
115	lcc
116
117	mov	e3,a0
118	ret	[d2,d3],8
119
120memset_end:
121	.size	memset, memset_end-memset
122