Root/target/linux/ubicom32/files/arch/ubicom32/lib/mem_ubicom32.c

1/*
2 * arch/ubicom32/lib/mem_ubicom32.c
3 * String functions.
4 *
5 * (C) Copyright 2009, Ubicom, Inc.
6 *
7 * This file is part of the Ubicom32 Linux Kernel Port.
8 *
9 * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10 * it and/or modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation, either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * The Ubicom32 Linux Kernel Port is distributed in the hope that it
15 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
16 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
17 * the GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with the Ubicom32 Linux Kernel Port. If not,
21 * see <http://www.gnu.org/licenses/>.
22 *
23 * Ubicom32 implementation derived from (with many thanks):
24 * arch/m68knommu
25 * arch/blackfin
26 * arch/parisc
27 */
28
29#include <linux/module.h>
30#include <linux/types.h>
31#include <linux/compiler.h>
32
33#define LIKELY likely
34#define UNLIKELY unlikely
35
36typedef u32_t addr_t;
37
38/*
39 * memcpy()
40 */
41void *memcpy(void *dest, const void *src, size_t n)
42{
43    void *dest_ret = dest;
44
45    if (LIKELY((((addr_t)dest ^ (addr_t)src) & 3) == 0) && LIKELY(n > 6)) {
46        size_t m;
47        n -= (4 - (addr_t)dest) & 0x03;
48        m = n >> 2;
49        asm volatile (
50        " sub.4 d15, #0, %2 \n\t" // set up for jump table
51        " and.4 d15, #(32-1), d15 \n\t" // d15 = (-m) & (32 - 1)
52        " moveai a3, #%%hi(1f) \n\t"
53        " lea.1 a3, %%lo(1f)(a3) \n\t"
54        " lea.4 a3, (a3,d15) \n\t"
55
56        " bfextu d15, %0, #2 \n\t" // d15 = (dest & 3)
57        " jmpne.w.f 100f \n\t"
58        " calli a3, 0(a3) \n\t" // 4-byte alignment
59
60        "100: cmpi d15, #2 \n\t"
61        " jmpne.s.f 101f \n\t"
62        " move.2 (%0)2++, (%1)2++ \n\t"
63        " calli a3, 0(a3) \n\t" // 2-byte alignment
64
65        "101: move.1 (%0)1++, (%1)1++ \n\t"
66        " jmpgt.s.f 102f \n\t" // 3-byte alignment
67        " move.2 (%0)2++, (%1)2++ \n\t" // 1-byte alignment
68        "102: calli a3, 0(a3) \n\t"
69
70        "200: cmpi %3, #2 \n\t"
71        " jmplt.s.f 201f \n\t"
72        " move.2 (%0)2++, (%1)2++ \n\t"
73        " jmpeq.s.t 2f \n\t"
74        "201: move.1 (%0)1++, (%1)1++ \n\t"
75        " jmpt.w.t 2f \n\t"
76
77        "1: .rept 25 \n\t"
78        " movea (%0)4++, (%1)4++ \n\t"
79        " .endr \n\t"
80        " .rept 7 \n\t"
81        " move.4 (%0)4++, (%1)4++ \n\t"
82        " .endr \n\t"
83        " add.4 %2, #-32, %2 \n\t"
84        " jmpgt.w.f 1b \n\t"
85
86        " and.4 %3, #3, %3 \n\t" // check n
87        " jmpne.w.f 200b \n\t"
88        "2: \n\t"
89            : "+a" (dest), "+a" (src), "+d" (m), "+d" (n)
90            :
91            : "d15", "a3", "memory", "cc"
92        );
93
94        return dest_ret;
95    }
96
97    if (LIKELY((((addr_t)dest ^ (addr_t)src) & 1) == 0) && LIKELY(n > 2)) {
98        size_t m;
99        n -= (addr_t)dest & 0x01;
100        m = n >> 1;
101        asm volatile (
102        " sub.4 d15, #0, %2 \n\t" // set up for jump table
103        " and.4 d15, #(32-1), d15 \n\t" // d15 = (-m) & (32 - 1)
104        " moveai a3, #%%hi(1f) \n\t"
105        " lea.1 a3, %%lo(1f)(a3) \n\t"
106        " lea.4 a3, (a3,d15) \n\t"
107
108        " btst %0, #0 \n\t" // check bit 0
109        " jmpne.w.f 100f \n\t"
110        " calli a3, 0(a3) \n\t" // 4-byte alignment
111
112        "100: move.1 (%0)1++, (%1)1++ \n\t"
113        " calli a3, 0(a3) \n\t"
114
115        "200: move.1 (%0)1++, (%1)1++ \n\t"
116        " jmpt.w.t 2f \n\t"
117
118        "1: .rept 32 \n\t"
119        " move.2 (%0)2++, (%1)2++ \n\t"
120        " .endr \n\t"
121        " add.4 %2, #-32, %2 \n\t"
122        " jmpgt.w.f 1b \n\t"
123
124        " and.4 %3, #1, %3 \n\t" // check n
125        " jmpne.w.f 200b \n\t"
126        "2: \n\t"
127
128            : "+a" (dest), "+a" (src), "+d" (m), "+d" (n)
129            :
130            : "d15", "a3", "memory", "cc"
131        );
132
133        return dest_ret;
134    }
135
136    asm volatile (
137    " sub.4 d15, #0, %2 \n\t"
138    " jmpeq.w.f 2f \n\t"
139    " and.4 d15, #(16-1), d15 \n\t" // d15 = (-n) & (16 - 1)
140    " moveai a3, #%%hi(1f) \n\t"
141    " lea.1 a3, %%lo(1f)(a3) \n\t"
142    " lea.4 a3, (a3,d15) \n\t"
143    " calli a3, 0(a3) \n\t"
144
145    "1: .rept 16 \n\t"
146    " move.1 (%0)1++, (%1)1++ \n\t"
147    " .endr \n\t"
148    " add.4 %2, #-16, %2 \n\t"
149    " jmpgt.w.f 1b \n\t"
150    "2: \n\t"
151
152        : "+a" (dest), "+a" (src), "+d" (n)
153        :
154        : "d15", "a3", "memory", "cc"
155    );
156
157    return dest_ret;
158}
159
160/*
161 * memset()
162 */
163void *memset(void *s, int c, size_t n)
164{
165    void *s_ret = s;
166
167    if (LIKELY(n > 6)) {
168        size_t m;
169        n -= (4 - (addr_t)s) & 0x03;
170        m = n >> 2;
171        asm volatile (
172        " sub.4 d15, #0, %2 \n\t" // set up for jump table
173        " and.4 d15, #(32-1), d15 \n\t" // d15 = (-m) & (32 - 1)
174        " shmrg.1 %1, %1, %1 \n\t"
175        " shmrg.2 %1, %1, %1 \n\t" // %1 = (c<<24)|(c<<16)|(c<<8)|c
176        " moveai a3, #%%hi(1f) \n\t"
177        " lea.1 a3, %%lo(1f)(a3) \n\t"
178        " lea.4 a3, (a3,d15) \n\t"
179
180        " bfextu d15, %0, #2 \n\t" // d15 = (s & 3)
181        " jmpne.w.f 100f \n\t"
182        " calli a3, 0(a3) \n\t" // 4-byte alignment
183
184        "100: cmpi d15, #2 \n\t"
185        " jmpne.s.f 101f \n\t"
186        " move.2 (%0)2++, %1 \n\t"
187        " calli a3, 0(a3) \n\t" // 2-byte alignment
188
189        "101: move.1 (%0)1++, %1 \n\t"
190        " jmpgt.s.f 102f \n\t" // 3-byte alignment
191        " move.2 (%0)2++, %1 \n\t" // 1-byte alignment
192        "102: calli a3, 0(a3) \n\t"
193
194        "200: cmpi %3, #2 \n\t"
195        " jmplt.s.f 201f \n\t"
196        " move.2 (%0)2++, %1 \n\t"
197        " jmpeq.s.t 2f \n\t"
198        "201: move.1 (%0)1++, %1 \n\t"
199        " jmpt.w.t 2f \n\t"
200
201        "1: .rept 25 \n\t"
202        " movea (%0)4++, %1 \n\t"
203        " .endr \n\t"
204        " .rept 7 \n\t"
205        " move.4 (%0)4++, %1 \n\t"
206        " .endr \n\t"
207        " add.4 %2, #-32, %2 \n\t"
208        " jmpgt.w.f 1b \n\t"
209
210        " and.4 %3, #3, %3 \n\t" // test bit 1 of n
211        " jmpne.w.f 200b \n\t"
212        "2: \n\t"
213
214            : "+a" (s), "+d" (c), "+d" (m), "+d" (n)
215            :
216            : "d15", "a3", "memory", "cc"
217        );
218
219        return s_ret;
220    }
221
222    asm volatile (
223    " sub.4 d15, #0, %2 \n\t"
224    " jmpeq.w.f 2f \n\t"
225    " and.4 d15, #(8-1), d15 \n\t" // d15 = (-%2) & (16 - 1)
226    " moveai a3, #%%hi(1f) \n\t"
227    " lea.1 a3, %%lo(1f)(a3) \n\t"
228    " lea.4 a3, (a3,d15) \n\t"
229    " calli a3, 0(a3) \n\t"
230
231    "1: .rept 8 \n\t"
232    " move.1 (%0)1++, %1 \n\t"
233    " .endr \n\t"
234    "2: \n\t"
235
236        : "+a" (s), "+d" (c), "+d" (n)
237        :
238        : "d15", "a3", "memory", "cc"
239    );
240
241    return s_ret;
242}
243
244void *memmove(void *dest, const void *src, size_t n)
245{
246    char *tmp;
247    const char *s;
248
249    if (n == 0)
250        return dest;
251
252    tmp = dest;
253    s = src;
254
255    /*
256     * Will perform 16-bit move if possible
257     */
258    if (likely((((u32)dest | (u32)src | n) & 1) == 0)) {
259        if (dest <= src) {
260            asm volatile (
261            " sub.4 d15, #0, %2 \n\t" // set up for jump table
262            " and.4 d15, #(32-2), d15 \n\t" // d15 = (- count) & (32 - 2)
263            " moveai a3, #%%hi(1f) \n\t"
264            " lea.1 a3, %%lo(1f)(a3) \n\t"
265            " lea.2 a3, (a3,d15) \n\t"
266            " calli a3, 0(a3) \n\t"
267
268            "1: .rept 16 \n\t"
269            " move.2 (%0)2++, (%1)2++ \n\t"
270            " .endr \n\t"
271            " add.4 %2, #-32, %2 \n\t"
272            " jmpgt.w.f 1b \n\t"
273
274            : "+a" (tmp), "+a" (s), "+d" (n)
275            :
276            : "d15", "a3", "memory", "cc"
277            );
278        } else {
279            tmp += n;
280            s += n;
281            asm volatile (
282            " sub.4 d15, #0, %2 \n\t" // set up for jump table
283            " and.4 d15, #(32-2), d15 \n\t" // d15 = (- count) & (32 - 2)
284            " moveai a3, #%%hi(1f) \n\t"
285            " lea.1 a3, %%lo(1f)(a3) \n\t"
286            " lea.2 a3, (a3,d15) \n\t"
287            " calli a3, 0(a3) \n\t"
288
289            "1: .rept 16 \n\t"
290            " move.2 -2(%0)++, -2(%1)++ \n\t"
291            " .endr \n\t"
292            " add.4 %2, #-32, %2 \n\t"
293            " jmpgt.w.f 1b \n\t"
294
295            : "+a" (tmp), "+a" (s), "+d" (n)
296            :
297            : "d15", "a3", "memory", "cc"
298            );
299        }
300        return dest;
301    }
302
303    if (dest <= src) {
304        asm volatile (
305        " sub.4 d15, #0, %2 \n\t" // set up for jump table
306        " and.4 d15, #(16-1), d15 \n\t" // d15 = (- count) & (16 - 1)
307        " moveai a3, #%%hi(1f) \n\t"
308        " lea.1 a3, %%lo(1f)(a3) \n\t"
309        " lea.4 a3, (a3,d15) \n\t"
310        " calli a3, 0(a3) \n\t"
311
312        "1: .rept 16 \n\t"
313        " move.1 (%0)1++, (%1)1++ \n\t"
314        " .endr \n\t"
315        " add.4 %2, #-16, %2 \n\t"
316        " jmpgt.w.f 1b \n\t"
317        : "+a" (tmp), "+a" (s), "+d" (n)
318        :
319        : "d15", "a3", "memory", "cc"
320        );
321    } else {
322        tmp += n;
323        s += n;
324        asm volatile (
325        " sub.4 d15, #0, %2 \n\t" // set up for jump table
326        " and.4 d15, #(16-1), d15 \n\t" // d15 = (- count) & (16 - 1)
327        " moveai a3, #%%hi(1f) \n\t"
328        " lea.1 a3, %%lo(1f)(a3) \n\t"
329        " lea.4 a3, (a3,d15) \n\t"
330        " calli a3, 0(a3) \n\t"
331
332        "1: .rept 16 \n\t"
333        " move.1 -1(%0)++, -1(%1)++ \n\t"
334        " .endr \n\t"
335        " add.4 %2, #-16, %2 \n\t"
336        " jmpgt.w.f 1b \n\t"
337        : "+a" (tmp), "+a" (s), "+d" (n)
338        :
339        : "d15", "a3", "memory", "cc"
340        );
341    }
342    return dest;
343}
344

Archive Download this file



interactive