1 1.1 christos /* 2 1.1 christos * Written by J.T. Conklin <jtc (at) acorntoolworks.com> 3 1.1 christos * Public domain. 4 1.1 christos */ 5 1.1 christos 6 1.1 christos #include <machine/asm.h> 7 1.1 christos 8 1.1 christos #if defined(LIBC_SCCS) 9 1.3 jakllsch RCSID("$NetBSD: strchr.S,v 1.3 2014/03/22 19:38:46 jakllsch Exp $") 10 1.1 christos #endif 11 1.1 christos 12 1.1 christos ENTRY(strchr) 13 1.1 christos pushl %esi 14 1.1 christos pushl %ebx 15 1.1 christos movl 12(%esp),%eax 16 1.1 christos movzbl 16(%esp),%ecx 17 1.1 christos 18 1.1 christos /* 19 1.1 christos * Align to word boundary. 20 1.1 christos * Consider unrolling loop? 21 1.1 christos */ 22 1.1 christos .Lalign: 23 1.1 christos testb $3,%al 24 1.1 christos je .Lword_aligned 25 1.1 christos movb (%eax),%bl 26 1.1 christos cmpb %cl,%bl 27 1.1 christos je .Ldone 28 1.1 christos testb %bl,%bl 29 1.1 christos je .Lzero 30 1.1 christos incl %eax 31 1.1 christos jmp .Lalign 32 1.1 christos 33 1.1 christos .Lword_aligned: 34 1.1 christos /* copy char to all bytes in word */ 35 1.1 christos movb %cl,%ch 36 1.1 christos movl %ecx,%edx 37 1.1 christos sall $16,%ecx 38 1.1 christos orl %edx,%ecx 39 1.1 christos 40 1.1 christos /* Check whether any byte in the word is equal to ch or 0. */ 41 1.1 christos _ALIGN_TEXT 42 1.1 christos .Lloop: 43 1.1 christos movl (%eax),%ebx 44 1.1 christos addl $4,%eax 45 1.1 christos movl %ebx,%esi 46 1.1 christos leal -0x01010101(%ebx),%edx 47 1.1 christos xorl %ecx,%esi 48 1.1 christos subl $0x01010101,%esi 49 1.1 christos orl %esi,%edx 50 1.1 christos testl $0x80808080,%edx 51 1.1 christos je .Lloop 52 1.1 christos 53 1.1 christos /* 54 1.1 christos * In rare cases, the above loop may exit prematurely. We must 55 1.1 christos * return to the loop if none of the bytes in the word match 56 1.1 christos * ch or are equal to 0. 57 1.1 christos */ 58 1.1 christos 59 1.1 christos /* 60 1.1 christos * Alignment here avoids a stall on the Athlon, even though 61 1.1 christos * it's not a branch target. 62 1.1 christos */ 63 1.1 christos 64 1.1 christos _ALIGN_TEXT 65 1.1 christos cmpb %cl,%bl /* 1st byte == ch? */ 66 1.1 christos jne 1f 67 1.1 christos subl $4,%eax 68 1.1 christos jmp .Ldone 69 1.1 christos 1: testb %bl,%bl /* 1st byte == 0? */ 70 1.1 christos je .Lzero 71 1.1 christos 72 1.1 christos cmpb %cl,%bh /* 2nd byte == ch? */ 73 1.1 christos jne 1f 74 1.1 christos subl $3,%eax 75 1.1 christos jmp .Ldone 76 1.1 christos 1: testb %bh,%bh /* 2nd byte == 0? */ 77 1.1 christos je .Lzero 78 1.1 christos 79 1.1 christos shrl $16,%ebx 80 1.1 christos cmpb %cl,%bl /* 3rd byte == ch? */ 81 1.1 christos jne 1f 82 1.1 christos subl $2,%eax 83 1.1 christos jmp .Ldone 84 1.1 christos 1: testb %bl,%bl /* 3rd byte == 0? */ 85 1.1 christos je .Lzero 86 1.1 christos 87 1.1 christos cmpb %cl,%bh /* 4th byte == ch? */ 88 1.1 christos jne 1f 89 1.1 christos decl %eax 90 1.1 christos jmp .Ldone 91 1.1 christos 1: testb %bh,%bh /* 4th byte == 0? */ 92 1.1 christos jne .Lloop 93 1.1 christos 94 1.1 christos .Lzero: 95 1.1 christos /* If a ch wasn't found, return 0. */ 96 1.1 christos xorl %eax,%eax 97 1.1 christos 98 1.1 christos .Ldone: 99 1.1 christos popl %ebx 100 1.1 christos popl %esi 101 1.1 christos ret 102 1.3 jakllsch END(strchr) 103 1.2 dsl 104 1.2 dsl STRONG_ALIAS(index,strchr) 105