OSDN Git Service

hidden_def/hidden_proto: convert all users (I hope) termios split, add some missing...
[uclinux-h8/uClibc.git] / libc / string / mips / memcpy.S
1 /* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Hartvig Ekner <hartvige@mips.com>, 2002.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
19
20 #include <features.h>
21 /*#include <sysdep.h>*/
22 #include <endian.h>
23 #include "sysdep.h"
24
25 #ifdef __mips64
26 #error mips32 code being compiled for mips64!
27 #endif
28
29 /* void *memcpy(void *s1, const void *s2, size_t n);  */
30
31 #if __BYTE_ORDER == __BIG_ENDIAN
32 #  define LWHI  lwl             /* high part is left in big-endian      */
33 #  define SWHI  swl             /* high part is left in big-endian      */
34 #  define LWLO  lwr             /* low part is right in big-endian      */
35 #  define SWLO  swr             /* low part is right in big-endian      */
36 #else
37 #  define LWHI  lwr             /* high part is right in little-endian  */
38 #  define SWHI  swr             /* high part is right in little-endian  */
39 #  define LWLO  lwl             /* low part is left in little-endian    */
40 #  define SWLO  swl             /* low part is left in little-endian    */
41 #endif
42
43 ENTRY (memcpy)
44         .set    noreorder
45
46         slti    t0, a2, 8               # Less than 8?
47         bne     t0, zero, L(last8)
48         move    v0, a0                  # Setup exit value before too late
49
50         xor     t0, a1, a0              # Find a0/a1 displacement
51         andi    t0, 0x3
52         bne     t0, zero, L(shift)      # Go handle the unaligned case
53         subu    t1, zero, a1
54         andi    t1, 0x3                 # a0/a1 are aligned, but are we
55         beq     t1, zero, L(chk8w)      #  starting in the middle of a word?
56         subu    a2, t1
57         LWHI    t0, 0(a1)               # Yes we are... take care of that
58         addu    a1, t1
59         SWHI    t0, 0(a0)
60         addu    a0, t1
61
62 L(chk8w):       
63         andi    t0, a2, 0x1f            # 32 or more bytes left?
64         beq     t0, a2, L(chk1w)
65         subu    a3, a2, t0              # Yes
66         addu    a3, a1                  # a3 = end address of loop
67         move    a2, t0                  # a2 = what will be left after loop
68 L(lop8w):       
69         lw      t0,  0(a1)              # Loop taking 8 words at a time
70         lw      t1,  4(a1)
71         lw      t2,  8(a1)
72         lw      t3, 12(a1)
73         lw      t4, 16(a1)
74         lw      t5, 20(a1)
75         lw      t6, 24(a1)
76         lw      t7, 28(a1)
77         addiu   a0, 32
78         addiu   a1, 32
79         sw      t0, -32(a0)
80         sw      t1, -28(a0)
81         sw      t2, -24(a0)
82         sw      t3, -20(a0)
83         sw      t4, -16(a0)
84         sw      t5, -12(a0)
85         sw      t6,  -8(a0)
86         bne     a1, a3, L(lop8w)
87         sw      t7,  -4(a0)
88
89 L(chk1w):       
90         andi    t0, a2, 0x3             # 4 or more bytes left?
91         beq     t0, a2, L(last8)
92         subu    a3, a2, t0              # Yes, handle them one word at a time
93         addu    a3, a1                  # a3 again end address
94         move    a2, t0
95 L(lop1w):       
96         lw      t0, 0(a1)
97         addiu   a0, 4
98         addiu   a1, 4
99         bne     a1, a3, L(lop1w)
100         sw      t0, -4(a0)
101
102 L(last8):       
103         blez    a2, L(lst8e)            # Handle last 8 bytes, one at a time
104         addu    a3, a2, a1
105 L(lst8l):       
106         lb      t0, 0(a1)
107         addiu   a0, 1
108         addiu   a1, 1
109         bne     a1, a3, L(lst8l)
110         sb      t0, -1(a0)
111 L(lst8e):       
112         jr      ra                      # Bye, bye
113         nop
114
115 L(shift):       
116         subu    a3, zero, a0            # Src and Dest unaligned 
117         andi    a3, 0x3                 #  (unoptimized case...)
118         beq     a3, zero, L(shft1)
119         subu    a2, a3                  # a2 = bytes left
120         LWHI    t0, 0(a1)               # Take care of first odd part
121         LWLO    t0, 3(a1)
122         addu    a1, a3
123         SWHI    t0, 0(a0)
124         addu    a0, a3
125 L(shft1):       
126         andi    t0, a2, 0x3
127         subu    a3, a2, t0
128         addu    a3, a1
129 L(shfth):       
130         LWHI    t1, 0(a1)               # Limp through, word by word
131         LWLO    t1, 3(a1)
132         addiu   a0, 4
133         addiu   a1, 4
134         bne     a1, a3, L(shfth)
135         sw      t1, -4(a0)
136         b       L(last8)                # Handle anything which may be left
137         move    a2, t0
138
139         .set    reorder
140 END (memcpy)
141
142 libc_hidden_def(memcpy)