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