1/* 2 * Adapted by Guillaume Morin <guillaume@morinfr.org> from strcpy.S 3 * written by J.T. Conklin <jtc@acorntoolworks.com> 4 * Public domain. 5 */ 6 7#include <machine/asm.h> 8__FBSDID("$FreeBSD$"); 9 10/* 11 * This stpcpy implementation copies a byte at a time until the 12 * source pointer is aligned to a word boundary, it then copies by 13 * words until it finds a word containing a zero byte, and finally 14 * copies by bytes until the end of the string is reached. 15 * 16 * While this may result in unaligned stores if the source and 17 * destination pointers are unaligned with respect to each other, 18 * it is still faster than either byte copies or the overhead of 19 * an implementation suitable for machines with strict alignment 20 * requirements. 21 */ 22 23 .globl stpcpy,__stpcpy 24ENTRY(stpcpy) 25__stpcpy: 26 movabsq $0x0101010101010101,%r8 27 movabsq $0x8080808080808080,%r9 28 29 /* 30 * Align source to a word boundary. 31 * Consider unrolling loop? 32 */ 33.Lalign: 34 testb $7,%sil 35 je .Lword_aligned 36 movb (%rsi),%dl 37 incq %rsi 38 movb %dl,(%rdi) 39 incq %rdi 40 testb %dl,%dl 41 jne .Lalign 42 movq %rdi,%rax 43 dec %rax 44 ret 45 46 .p2align 4 47.Lloop: 48 movq %rdx,(%rdi) 49 addq $8,%rdi 50.Lword_aligned: 51 movq (%rsi),%rdx 52 movq %rdx,%rcx 53 addq $8,%rsi 54 subq %r8,%rcx 55 testq %r9,%rcx 56 je .Lloop 57 58 /* 59 * In rare cases, the above loop may exit prematurely. We must 60 * return to the loop if none of the bytes in the word equal 0. 61 */ 62 63 movb %dl,(%rdi) 64 testb %dl,%dl /* 1st byte == 0? */ 65 je .Ldone 66 incq %rdi 67 68 shrq $8,%rdx 69 movb %dl,(%rdi) 70 testb %dl,%dl /* 2nd byte == 0? */ 71 je .Ldone 72 incq %rdi 73 74 shrq $8,%rdx 75 movb %dl,(%rdi) 76 testb %dl,%dl /* 3rd byte == 0? */ 77 je .Ldone 78 incq %rdi 79 80 shrq $8,%rdx 81 movb %dl,(%rdi) 82 testb %dl,%dl /* 4th byte == 0? */ 83 je .Ldone 84 incq %rdi 85 86 shrq $8,%rdx 87 movb %dl,(%rdi) 88 testb %dl,%dl /* 5th byte == 0? */ 89 je .Ldone 90 incq %rdi 91 92 shrq $8,%rdx 93 movb %dl,(%rdi) 94 testb %dl,%dl /* 6th byte == 0? */ 95 je .Ldone 96 incq %rdi 97 98 shrq $8,%rdx 99 movb %dl,(%rdi) 100 testb %dl,%dl /* 7th byte == 0? */ 101 je .Ldone 102 incq %rdi 103 104 shrq $8,%rdx 105 movb %dl,(%rdi) 106 incq %rdi 107 testb %dl,%dl /* 8th byte == 0? */ 108 jne .Lword_aligned 109 decq %rdi 110 111.Ldone: 112 movq %rdi,%rax 113 ret 114END(stpcpy) 115 116 .section .note.GNU-stack,"",%progbits 117