Rev 1408 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1627 | serge | 1 | /* _memmove() Author: Kees J. Bot */ |
2 | /* 2 Jan 1994 */ |
||
1408 | serge | 3 | |
1627 | serge | 4 | /* void *_memmove(void *s1, const void *s2, size_t n) */ |
5 | /* Copy a chunk of memory. Handle overlap. */ |
||
6 | /* */ |
||
1408 | serge | 7 | |
1627 | serge | 8 | #include "asm.h" |
1408 | serge | 9 | |
1627 | serge | 10 | ENTRY(_memmove) |
11 | push %ebp |
||
12 | movl %esp, %ebp |
||
13 | push %esi |
||
14 | push %edi |
||
15 | movl 8(%ebp), %edi /* String s1 */ |
||
16 | movl 12(%ebp), %esi /* String s2 */ |
||
17 | movl 16(%ebp), %ecx /* Length */ |
||
18 | movl %edi, %eax |
||
19 | subl %esi, %eax |
||
20 | cmpl %ecx, %eax |
||
21 | jb downwards /* if (s2 - s1) < n then copy downwards */ |
||
22 | LABEL(_memcpy) |
||
23 | cld /* Clear direction bit: upwards */ |
||
24 | cmpl $16, %ecx |
||
25 | jb upbyte /* Don't bother being smart with short arrays */ |
||
26 | movl %esi, %eax |
||
27 | orl %edi, %eax |
||
28 | testb $1, %al |
||
29 | jne upbyte /* Bit 0 set, use byte copy */ |
||
30 | testb $2, %al |
||
31 | jne upword /* Bit 1 set, use word copy */ |
||
32 | uplword: |
||
33 | shrdl $2, %ecx, %eax /* Save low 2 bits of ecx in eax */ |
||
34 | shrl $2, %ecx |
||
1408 | serge | 35 | |
1627 | serge | 36 | rep movsl /* Copy longwords. */ |
37 | shldl $2, %eax, %ecx /* Restore excess count */ |
||
38 | upword: |
||
39 | shrl $1, %ecx |
||
1408 | serge | 40 | |
1627 | serge | 41 | rep movsw /* Copy words */ |
42 | adcl %ecx, %ecx /* One more byte? */ |
||
1408 | serge | 43 | upbyte: |
1627 | serge | 44 | rep movsb /* Copy bytes */ |
1408 | serge | 45 | done: |
1627 | serge | 46 | movl 8(%ebp), %eax /* Absolutely noone cares about this value */ |
47 | pop %edi |
||
48 | pop %esi |
||
49 | pop %ebp |
||
50 | ret |
||
1408 | serge | 51 | |
1627 | serge | 52 | /* Handle bad overlap by copying downwards, don't bother to do word copies. */ |
53 | downwards: |
||
54 | std /* Set direction bit: downwards */ |
||
55 | leal -1(%esi,%ecx,1), %esi |
||
56 | leal -1(%edi,%ecx,1), %edi |
||
1408 | serge | 57 | |
1627 | serge | 58 | rep movsb /* Copy bytes */ |
59 | cld |
||
60 | jmp done> |