1/* 2 * Written by J.T. Conklin <jtc@acorntoolworks.com> 3 * Public domain. 4 */ 5 6#include <machine/asm.h> 7 8#if defined(LIBC_SCCS) 9 RCSID("$NetBSD: strchr.S,v 1.1 2005/12/20 19:28:51 christos Exp $") 10#endif 11 12#ifdef INDEX 13ENTRY(index) 14#else 15ENTRY(strchr) 16#endif 17 movzbq %sil,%rcx 18 19 /* 20 * Align to word boundary. 21 * Consider unrolling loop? 22 */ 23.Lalign: 24 testb $7,%dil 25 je .Lword_aligned 26 movb (%rdi),%dl 27 cmpb %cl,%dl 28 je .Ldone 29 incq %rdi 30 testb %dl,%dl 31 jne .Lalign 32 jmp .Lzero 33 34.Lword_aligned: 35 /* copy char to all bytes in word */ 36 movb %cl,%ch 37 movq %rcx,%rdx 38 salq $16,%rcx 39 orq %rdx,%rcx 40 movq %rcx,%rdx 41 salq $32,%rcx 42 orq %rdx,%rcx 43 44 movabsq $0x0101010101010101,%r8 45 movabsq $0x8080808080808080,%r9 46 47 /* Check whether any byte in the word is equal to ch or 0. */ 48 _ALIGN_TEXT 49.Lloop: 50 movq (%rdi),%rdx 51 addq $8,%rdi 52 movq %rdx,%rsi 53 subq %r8,%rdx 54 xorq %rcx,%rsi 55 subq %r8,%rsi 56 orq %rsi,%rdx 57 testq %r9,%rdx 58 je .Lloop 59 60 /* 61 * In rare cases, the above loop may exit prematurely. We must 62 * return to the loop if none of the bytes in the word match 63 * ch or are equal to 0. 64 */ 65 66 movb -8(%rdi),%dl 67 cmpb %cl,%dl /* 1st byte == ch? */ 68 jne 1f 69 subq $8,%rdi 70 jmp .Ldone 711: testb %dl,%dl /* 1st byte == 0? */ 72 je .Lzero 73 74 movb -7(%rdi),%dl 75 cmpb %cl,%dl /* 2nd byte == ch? */ 76 jne 1f 77 subq $7,%rdi 78 jmp .Ldone 791: testb %dl,%dl /* 2nd byte == 0? */ 80 je .Lzero 81 82 movb -6(%rdi),%dl 83 cmpb %cl,%dl /* 3rd byte == ch? */ 84 jne 1f 85 subq $6,%rdi 86 jmp .Ldone 871: testb %dl,%dl /* 3rd byte == 0? */ 88 je .Lzero 89 90 movb -5(%rdi),%dl 91 cmpb %cl,%dl /* 4th byte == ch? */ 92 jne 1f 93 subq $5,%rdi 94 jmp .Ldone 951: testb %dl,%dl /* 4th byte == 0? */ 96 je .Lzero 97 98 movb -4(%rdi),%dl 99 cmpb %cl,%dl /* 5th byte == ch? */ 100 jne 1f 101 subq $4,%rdi 102 jmp .Ldone 1031: testb %dl,%dl /* 5th byte == 0? */ 104 je .Lzero 105 106 movb -3(%rdi),%dl 107 cmpb %cl,%dl /* 6th byte == ch? */ 108 jne 1f 109 subq $3,%rdi 110 jmp .Ldone 1111: testb %dl,%dl /* 6th byte == 0? */ 112 je .Lzero 113 114 movb -2(%rdi),%dl 115 cmpb %cl,%dl /* 7th byte == ch? */ 116 jne 1f 117 subq $2,%rdi 118 jmp .Ldone 1191: testb %dl,%dl /* 7th byte == 0? */ 120 je .Lzero 121 122 movb -1(%rdi),%dl 123 cmpb %cl,%dl /* 8th byte == ch? */ 124 jne 1f 125 subq $1,%rdi 126 jmp .Ldone 1271: testb %dl,%dl /* 8th byte == 0? */ 128 jne .Lloop 129 130.Lzero: 131 /* If a ch wasn't found, return 0. */ 132 xorq %rdi,%rdi 133 134.Ldone: 135 movq %rdi,%rax 136 ret 137