Elliott Hughes | 06708df | 2013-06-08 00:42:35 +0000 | [diff] [blame] | 1 | /* $OpenBSD: strcat.S,v 1.8 2005/08/07 11:30:38 espie Exp $ */ |
| 2 | /* |
| 3 | * Written by J.T. Conklin <jtc@netbsd.org>. |
| 4 | * Public domain. |
| 5 | */ |
| 6 | |
| 7 | #include <machine/asm.h> |
| 8 | |
| 9 | #if defined(APIWARN) |
| 10 | #APP |
| 11 | .section .gnu.warning.strcat |
| 12 | .ascii "warning: strcat() is almost always misused, please use strlcat()" |
| 13 | #NO_APP |
| 14 | #endif |
| 15 | |
| 16 | /* |
| 17 | * NOTE: I've unrolled the loop eight times: large enough to make a |
| 18 | * significant difference, and small enough not to totally trash the |
| 19 | * cache. |
| 20 | */ |
| 21 | |
| 22 | ENTRY(strcat) |
| 23 | pushl %edi /* save edi */ |
| 24 | movl 8(%esp),%edi /* dst address */ |
| 25 | movl 12(%esp),%edx /* src address */ |
| 26 | pushl %edi /* push destination address */ |
| 27 | |
| 28 | cld /* set search forward */ |
| 29 | xorl %eax,%eax /* set search for null terminator */ |
| 30 | movl $-1,%ecx /* set search for lots of characters */ |
| 31 | repne /* search! */ |
| 32 | scasb |
| 33 | |
| 34 | leal -1(%edi),%ecx /* correct dst address */ |
| 35 | |
| 36 | .align 2,0x90 |
| 37 | L1: movb (%edx),%al /* unroll loop, but not too much */ |
| 38 | movb %al,(%ecx) |
| 39 | testb %al,%al |
| 40 | jz L2 |
| 41 | movb 1(%edx),%al |
| 42 | movb %al,1(%ecx) |
| 43 | testb %al,%al |
| 44 | jz L2 |
| 45 | movb 2(%edx),%al |
| 46 | movb %al,2(%ecx) |
| 47 | testb %al,%al |
| 48 | jz L2 |
| 49 | movb 3(%edx),%al |
| 50 | movb %al,3(%ecx) |
| 51 | testb %al,%al |
| 52 | jz L2 |
| 53 | movb 4(%edx),%al |
| 54 | movb %al,4(%ecx) |
| 55 | testb %al,%al |
| 56 | jz L2 |
| 57 | movb 5(%edx),%al |
| 58 | movb %al,5(%ecx) |
| 59 | testb %al,%al |
| 60 | jz L2 |
| 61 | movb 6(%edx),%al |
| 62 | movb %al,6(%ecx) |
| 63 | testb %al,%al |
| 64 | jz L2 |
| 65 | movb 7(%edx),%al |
| 66 | movb %al,7(%ecx) |
| 67 | addl $8,%edx |
| 68 | addl $8,%ecx |
| 69 | testb %al,%al |
| 70 | jnz L1 |
| 71 | L2: popl %eax /* pop destination address */ |
| 72 | popl %edi /* restore edi */ |
| 73 | ret |
| 74 | END(strcat) |