1/* MN10300 Optimised simple memory to memory copy
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 *memcpy(void *dst, const void *src, size_t n)
19#
20###############################################################################
21	.globl	memcpy
22        .type	memcpy,@function
23memcpy:
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	d1,a1				# src
30	mov	d0,e3				# the return value
31
32	cmp	+0,d2
33	beq	memcpy_done			# return if zero-length copy
34
35	# see if the three parameters are all four-byte aligned
36	or	d0,d1,d3
37	or	d2,d3
38	and	+3,d3
39	bne	memcpy_1			# jump if not
40
41	# we want to transfer as much as we can in chunks of 32 bytes
42	cmp	+31,d2
43	bls	memcpy_4_remainder		# 4-byte aligned remainder
44
45	movm	[exreg1],(sp)
46	add	-32,d2
47	mov	+32,d3
48
49memcpy_4_loop:
50	mov	(a1+),d0
51	mov	(a1+),d1
52	mov	(a1+),e0
53	mov	(a1+),e1
54	mov	(a1+),e4
55	mov	(a1+),e5
56	mov	(a1+),e6
57	mov	(a1+),e7
58	mov	d0,(a0+)
59	mov	d1,(a0+)
60	mov	e0,(a0+)
61	mov	e1,(a0+)
62	mov	e4,(a0+)
63	mov	e5,(a0+)
64	mov	e6,(a0+)
65	mov	e7,(a0+)
66
67	sub	d3,d2
68	bcc	memcpy_4_loop
69
70	movm	(sp),[exreg1]
71	add	d3,d2
72	beq	memcpy_4_no_remainder
73
74memcpy_4_remainder:
75	# cut 4-7 words down to 0-3
76	cmp	+16,d2
77	bcs	memcpy_4_three_or_fewer_words
78	mov	(a1+),d0
79	mov	(a1+),d1
80	mov	(a1+),e0
81	mov	(a1+),e1
82	mov	d0,(a0+)
83	mov	d1,(a0+)
84	mov	e0,(a0+)
85	mov	e1,(a0+)
86	add	-16,d2
87	beq	memcpy_4_no_remainder
88
89	# copy the remaining 1, 2 or 3 words
90memcpy_4_three_or_fewer_words:
91	cmp	+8,d2
92	bcs	memcpy_4_one_word
93	beq	memcpy_4_two_words
94	mov	(a1+),d0
95	mov	d0,(a0+)
96memcpy_4_two_words:
97	mov	(a1+),d0
98	mov	d0,(a0+)
99memcpy_4_one_word:
100	mov	(a1+),d0
101	mov	d0,(a0+)
102
103memcpy_4_no_remainder:
104	# check we copied the correct amount
105	# TODO: REMOVE CHECK
106	sub	e3,a0,d2
107	mov	(20,sp),d1
108	cmp	d2,d1
109	beq	memcpy_done
110	break
111	break
112	break
113
114memcpy_done:
115	mov	e3,a0
116	ret	[d2,d3],8
117
118	# handle misaligned copying
119memcpy_1:
120	add	-1,d2
121	mov	+1,d3
122	setlb					# setlb requires the next insns
123						# to occupy exactly 4 bytes
124
125	sub	d3,d2
126	movbu	(a1),d0
127	movbu	d0,(a0)
128	add_add	d3,a1,d3,a0
129	lcc
130
131	mov	e3,a0
132	ret	[d2,d3],8
133
134memcpy_end:
135	.size	memcpy, memcpy_end-memcpy
136