Cygwin: Add new APIs tc[gs]etwinsize()
[newlib-cygwin.git] / newlib / libc / machine / z8k / memmove.S
blobc4d0c73f8823438374f449144cdf7513b4ab0920
1 /*
2  * memmove routine for Z8000
3  * Copyright (C) 2004 Christian Groessler <chris@groessler.org>
4  *
5  * Permission to use, copy, modify, and distribute this file
6  * for any purpose is hereby granted without fee, provided that
7  * the above copyright notice and this notice appears in all
8  * copies.
9  *
10  * This file is distributed WITHOUT ANY WARRANTY; without even the implied
11  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12  */
14 /* void *memmove(void *dest, const void *src, size_t length);
15  */
17         name    "memmove.S"
19         .text
20         even
21 global  _memmove
23 _memmove:
25 #ifdef __Z8001__
26         segm
28 #ifdef __STD_CALL__
29         ldl     rr6,rr14(#4)
30         ldl     rr4,rr14(#8)
31         ldl     rr2,rr14(#12)
32 #else
33         pushl   @rr14,rr6
34 #endif
36 /* rr2  - length        (high word ignored)
37  * rr4  - src
38  * rr6  - dest
39  */
41         testl   rr2
42         jr      z,finish
44 /*  check for destructive overlap (src < dest && dest < src + length) */
46         cpl     rr6,rr4
47         jp      ule,memmove_entry       /* non-destructive, let memcpy do the work */
48         ldl     rr0,rr2
49         addl    rr0,rr4                 /* rr0 = src + length */
50         cpl     rr0,rr6
51         jp      ult,memmove_entry       /* non-destructive, let memcpy do the work */
53 /* set-up pointers to copy backwards, add (length - 1) */
54         addl    rr4,rr2                 /* src + length */
55         addl    rr6,rr2                 /* dest + length */
56         subl    rr4,#1
57         subl    rr6,#1
59 /* check alignment */
60         bitb    rl7,#0          /* odd destination address? */
61         jr      z,testsrc
62         bitb    rl5,#0          /* odd source address? */
63         jr      z,odd_copy
64         jr      even_copy
66 testsrc:
67         bitb    rl5,#0
68         jr      nz,odd_copy     /* src even, dest odd */
69         lddb    @rr6,@rr4,r3
70         jr      ov,finish       /* jump if r5 is zero now */
72 /* copy words */
73 even_copy:
74         ld      r2,r3                   /* remember length */
75         srl     r3,#1
76 /*      jr      z,no_words         it cannot be zero here */
78         dec     r5,#1
79         dec     r7,#1
80         lddr    @rr6,@rr4,r3
82 no_words:
83         bitb    rl2,#0          /* odd length? */
84         jr      z,finish
85         inc     r5,#1
86         inc     r7,#1
87         lddb    @rr6,@rr4,r2    /* yes, copy last byte */
88         jr      finish
90 /* copy bytes */
91 odd_copy:
92         lddrb   @rr6,@rr4,r3
94 finish:
95 #ifdef __STD_CALL__
96         ldl     rr6,rr14(#4)
97 #else
98         popl    rr2,@rr14
99 #endif
102 #else           /* above Z8001, below Z8002 */
105         unsegm
107 #ifdef __STD_CALL__
108         ld      r7,r15(#2)
109         ld      r6,r15(#4)
110         ld      r5,r15(#6)
111 #else
112         ld      r2,r7           /* buffer pointer return value */
113 #endif
115 /* r5  - length
116  * r6  - src
117  * r7  - dest
118  */
119         test    r5
120         jr      z,finish
122 /*  check for destructive overlap (src < dest && dest < src + length) */
124         cp      r7,r6
125         jp      ule,memmove_entry       /* non-destructive, let memcpy do the work */
126         ld      r0,r5
127         add     r0,r6                   /* r0 = src + length */
128         cp      r0,r7
129         jp      ult,memmove_entry       /* non-destructive, let memcpy do the work */
131 /* set-up pointers to copy backwards, add (length - 1) */
132         add     r6,r5                   /* src + length */
133         add     r7,r5                   /* dest + length */
134         dec     r6,#1
135         dec     r7,#1
137 /* check alignment */
138         bitb    rl7,#0          /* odd destination address? */
139         jr      z,testsrc
140         bitb    rl6,#0          /* odd source address? */
141         jr      z,odd_copy
142         jr      even_copy
144 testsrc:
145         bitb    rl6,#0
146         jr      nz,odd_copy     /* src even, dest odd */
147         lddb    @r7,@r6,r5
148         jr      ov,finish       /* jump if r5 is zero now */
150 /* copy words */
151 even_copy:
152         ld      r4,r5           /* remember length */
153         srl     r5,#1
154 /*      jr      z,no_words         it cannot be zero here */
156         dec     r6,#1
157         dec     r7,#1
158         lddr    @r7,@r6,r5
160 no_words:
161         bitb    rl4,#0          /* odd length? */
162         jr      z,finish
163         inc     r6,#1
164         inc     r7,#1
165         lddb    @r7,@r6,r4      /* yes, copy last byte */
166         jr      finish
168 /* copy bytes */
169 odd_copy:
170         lddrb   @r7,@r6,r5
172 finish:
173 #ifdef __STD_CALL__
174         ld      r7,r15(#2)
175 #endif
177 #endif  /* Z8002 */
179         ret
180         .end