Drop main() prototype. Syncs with NetBSD-8
[minix.git] / common / lib / libc / arch / or1k / string / memmove.S
bloba79268cc8ddf9113997511866c7b67d80e529ed9
1 /* $NetBSD: memmove.S,v 1.1 2014/09/03 19:34:25 matt Exp $ */
3 /* stropt/memmove.S, pl_string_common, pl_linux 10/11/04 11:45:37
4  * ==========================================================================
5  * Optimized memmove implementation for IBM PowerPC 405/440.
6  *
7  *      Copyright (c) 2003, IBM Corporation
8  *      All rights reserved.            
9  *                                      
10  *      Redistribution and use in source and binary forms, with or      
11  *      without modification, are permitted provided that the following 
12  *      conditions are met:                                             
13  *                                                                      
14  *      * Redistributions of source code must retain the above  
15  *      copyright notice, this list of conditions and the following 
16  *      disclaimer.                                              
17  *      * Redistributions in binary form must reproduce the above       
18  *      copyright notice, this list of conditions and the following 
19  *      disclaimer in the documentation and/or other materials  
20  *      provided with the distribution.                         
21  *      * Neither the name of IBM nor the names of its contributors     
22  *      may be used to endorse or promote products derived from this
23  *      software without specific prior written permission.      
24  *                                                                      
25  *      THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          
26  *      CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     
27  *      INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        
28  *      MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        
29  *      DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS       
30  *      BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 
31  *      OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,                
32  *      PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR      
33  *      PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
34  *      OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT    
35  *      (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE       
36  *      USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37  *                                                                              
38  * ==========================================================================
39  *
40  * Function: Move memory area (handles overlapping regions)
41  *
42  *              void *memmove(void * dest, const void * src, int n) 
43  *      
44  * Input:       r3 - destination address 
45  *              r4 - source address 
46  *              r5 - byte count
47  * Output:      r11 - destination address
48  *
49  * ==========================================================================
50  */
52 #include <machine/asm.h>
54 #ifdef _BCOPY
55 /* bcopy = memcpy/memmove with arguments reversed. */
56 /* LINTSTUB: Func: void bcopy(void *, void *, size_t) */
57 ENTRY(bcopy)
58         l.or    r6, r3, r0              /* swap src/dst */
59         l.or    r3, r4, r0
60         l.or    r4, r6, r0
61 #else
62 /* LINTSTUB: Func: void *memmove(void *, const void *, size_t) */
63 ENTRY(memmove)
64 #endif
66         l.or    r11, r3, r0             /* Save dst (return value)      */
67         
68         l.sfges r4, r3                  /* Branch to reverse if         */
69         l.bnf   .Lreverse               /* src < dest. Don't want to    */
70                                         /* overwrite end of src with    */
71                                         /* start of dest                */
73         l.addi  r4, r4, -4              /* Back up src and dst pointers */
74         l.addi  r3, r3, -4              /* due to auto-update of 'load' */ 
75         
76         l.srli  r13, r5, 2              /* How many words in total cnt  */
77         l.sfeqi r13, 0
78         l.bf    .Llast1                 /* Handle byte by byte if < 4   */
79                                         /* bytes total                  */
80         l.lwz   r7, 4(r4)               /* Preload first word           */
81         l.addi  r4, r4, 4
82         
83         l.j     .Lg1
84         l.nop
86 .Lg0:                                   /* Main loop                    */
88         l.lwz   r7, 4(r4)               /* Load a new word              */
89         l.sw    4(r3), r6               /* Store previous word          */
90         l.addi  r4, r4, 4               /* advance */
91         l.addi  r3, r3, 4               /* advance */
92         
93 .Lg1:
95         l.addi  r13, r13, -1
96         l.sfeqi r13, 0
97         l.bf    .Llast                  /* Dec cnt, and branch if just  */
98         l.nop
99                                         /* one word to store            */
100         l.lwz   r6, 4(r4)               /* Load another word            */
101         l.sw    4(r3), r7               /* Store previous word          */
102         l.addi  r4, r4, 4               /* advance to next word         */
103         l.addi  r3, r3, 4               /* advance to next word         */
104         l.addi  r13, r13, -1            /* Decrement count              */
105         l.sfeqi r13, 0                  /* last word?                   */
106         l.bnf   .Lg0                    /*    no, loop, more words      */
107         l.nop
109         l.or    r7, r6, r0              /* If word count -> 0, then...  */
110         
111 .Llast:
113         l.sw    4(r3), r7               /* ... store last word          */
114         l.addi  r3, r3, 4
116 .Llast1:                                /* Byte-by-byte copy            */
118         l.andi  r5, r5, 3               /* get remaining byte count     */
119         l.sfeqi r5, 0                   /* is it 0?                     */
120         l.bf    .Ldone                  /*   yes, we're done            */
121         l.nop                           /* -- delay slot --             */
123         l.lbz   r6, 4(r4)               /* 1st byte: update addr by 4   */
124         l.sb    4(r3), r6               /* since we pre-adjusted by 4   */
125         l.addi  r4, r4, 4               /* advance to next word         */
126         l.addi  r3, r3, 4               /* advance to next word         */
127         l.addi  r5, r5, -1              /* decrement count              */
128         l.sfeqi r5, 0                   /* is it 0?                     */
129         l.bf    .Ldone                  /*    yes, we're done           */
130         l.nop                           /* -- delay slot --             */
132 .Llast2:
134         l.lbz   r6, 1(r4)               /* But handle the rest by       */
135         l.sb    1(r3), r6               /* updating addr by 1           */
136         l.addi  r4, r4, 1               /* advance to next word         */
137         l.addi  r3, r3, 1               /* advance to next word         */
138         l.addi  r5, r5, -1              /* decrement count              */
139         l.sfeqi r5, 0                   /* is it 0?                     */
140         l.bnf   .Llast2                 /*    yes, we're done           */
141         l.nop                           /* -- delay slot --             */
142 .Ldone:
143         l.jr    lr                      /* return                       */
144         l.nop                           /* -- delay slot --             */
146         /* We're here since src < dest. Don't want to overwrite end of  */
147         /* src with start of dest                                               */
149 .Lreverse:
151         l.add   r4, r4, r5              /* Work from end to beginning   */
152         l.add   r3, r3, r5              /* so add count to string ptrs  */
153         l.srli  r13, r5, 2              /* Words in total count         */
154         l.sfeqi r13, 0
155         l.bf    .Lrlast1                /* Handle byte by byte if < 4   */
156                                         /* bytes total                  */
157         l.nop
158         
159         l.lwz   r7, -4(r4)              /* Preload first word           */
160         l.addi  r4, r4, -4              /* update pointer               */
162         l.j     .Lrg1
164 .Lrg0:                                  /* Main loop                    */
166         l.lwz   r7, -4(r4)              /* Load a new word              */
167         l.sw    -4(r3), r6              /* Store previous word          */
168         l.addi  r4, r4, -4
169         l.addi  r3, r3, -4
170         
171 .Lrg1:
173         l.addi  r13, r13, -1            /* decrement count              */
174         l.sfeqi r13, 0                  /* just one pending word left?  */
175         l.bf    .Lrlast                 /*    yes, deal with it         */
177         l.lwz   r6, -4(r4)              /* Load another word            */
178         l.sw    -4(r3), r7              /* Store previous word          */
179         l.addi  r4, r4, -4
180         l.addi  r3, r3, -4
182         l.addi  r13, r13, -1            /* decrement count              */
183         l.sfeqi r13, 0                  /* just one pending word left?  */
184         l.bnf   .Lrg0                   /*    no, loop again more words */
185         l.nop
187         l.or    r7, r6, r0              /* If word count -> 0, then...  */
188         
189 .Lrlast:
191         l.sw    -4(r3), r7              /* ... store last word          */
192         l.addi  r3, r3, -4              /* update pointer */
194 .Lrlast1:                               /* Byte-by-byte copy            */
196         l.andi  r5, r5, 3
197         l.sfeqi r5, 0
198         l.bf    .Lrdone
200 .Lrlast2:
202         l.lbz   r6, -1(r4)              /* Handle the rest, byte by     */
203         l.sb    -1(r3), r6              /* byte                         */
204         l.addi  r4, r4, -1
205         l.addi  r3, r3, -1
206         l.addi  r5, r5, -1              /* decrement count              */
207         l.sfeqi r5, 0                   /* is it 0?                     */
208         l.bnf   .Lrlast2                /*    no, loop again            */
209         l.nop
210 .Lrdone:
211         l.jr    lr
212         l.nop
214 #ifdef _BCOPY
215 END(bcopy)
216 #else
217 END(memmove)
218 #endif