Commit | Line | Data |
---|---|---|
b920de1b DH |
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 | |
23 | memcpy: | |
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 | ||
49 | memcpy_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 | ||
74 | memcpy_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 | |
90 | memcpy_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+) | |
96 | memcpy_4_two_words: | |
97 | mov (a1+),d0 | |
98 | mov d0,(a0+) | |
99 | memcpy_4_one_word: | |
100 | mov (a1+),d0 | |
101 | mov d0,(a0+) | |
102 | ||
103 | memcpy_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 | ||
114 | memcpy_done: | |
115 | mov e3,a0 | |
116 | ret [d2,d3],8 | |
117 | ||
118 | # handle misaligned copying | |
119 | memcpy_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 | ||
134 | memcpy_end: | |
135 | .size memcpy, memcpy_end-memcpy |