Merge branch 'genirq' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux...
[linux-2.6] / arch / mn10300 / lib / memset.S
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
23 memset:
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
52 memset_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
68 memset_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
80 memset_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+)
85 memset_4_two_words:
86         mov     d1,(a0+)
87 memset_4_one_word:
88         mov     d1,(a0+)
89
90 memset_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
101 memset_done:
102         mov     e3,a0
103         ret     [d2,d3],8
104
105         # handle misaligned copying
106 memset_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
120 memset_end:
121         .size   memset, memset_end-memset