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