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: strrchr.S,v 1.3 2014/03/22 19:16:34 jakllsch Exp $") 10 1.1 christos #endif 11 1.1 christos 12 1.1 christos ENTRY(strrchr) 13 1.1 christos movzbq %sil,%rcx 14 1.1 christos 15 1.1 christos /* zero return value */ 16 1.1 christos xorq %rax,%rax 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 $7,%dil 24 1.1 christos je .Lword_aligned 25 1.1 christos movb (%rdi),%dl 26 1.1 christos cmpb %cl,%dl 27 1.1 christos cmoveq %rdi,%rax 28 1.1 christos incq %rdi 29 1.1 christos testb %dl,%dl 30 1.1 christos jne .Lalign 31 1.1 christos jmp .Ldone 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 movq %rcx,%rdx 37 1.1 christos salq $16,%rcx 38 1.1 christos orq %rdx,%rcx 39 1.1 christos movq %rcx,%rdx 40 1.1 christos salq $32,%rcx 41 1.1 christos orq %rdx,%rcx 42 1.1 christos 43 1.1 christos movabsq $0x0101010101010101,%r8 44 1.1 christos movabsq $0x8080808080808080,%r9 45 1.1 christos 46 1.1 christos /* Check whether any byte in the word is equal to ch or 0. */ 47 1.1 christos _ALIGN_TEXT 48 1.1 christos .Lloop: 49 1.1 christos movq (%rdi),%rdx 50 1.1 christos addq $8,%rdi 51 1.1 christos movq %rdx,%rsi 52 1.1 christos subq %r8,%rdx 53 1.1 christos xorq %rcx,%rsi 54 1.1 christos subq %r8,%rsi 55 1.1 christos orq %rsi,%rdx 56 1.1 christos testq %r9,%rdx 57 1.1 christos je .Lloop 58 1.1 christos 59 1.1 christos /* 60 1.1 christos * In rare cases, the above loop may exit prematurely. We must 61 1.1 christos * return to the loop if none of the bytes in the word match 62 1.1 christos * ch or are equal to 0. 63 1.1 christos */ 64 1.1 christos 65 1.1 christos movb -8(%rdi),%dl 66 1.1 christos cmpb %cl,%dl /* 1st byte == ch? */ 67 1.1 christos jne 1f 68 1.1 christos leaq -8(%rdi),%rax 69 1.1 christos 1: testb %dl,%dl /* 1st byte == 0? */ 70 1.1 christos je .Ldone 71 1.1 christos 72 1.1 christos movb -7(%rdi),%dl 73 1.1 christos cmpb %cl,%dl /* 2nd byte == ch? */ 74 1.1 christos jne 1f 75 1.1 christos leaq -7(%rdi),%rax 76 1.1 christos 1: testb %dl,%dl /* 2nd byte == 0? */ 77 1.1 christos je .Ldone 78 1.1 christos 79 1.1 christos movb -6(%rdi),%dl 80 1.1 christos cmpb %cl,%dl /* 3rd byte == ch? */ 81 1.1 christos jne 1f 82 1.1 christos leaq -6(%rdi),%rax 83 1.1 christos 1: testb %dl,%dl /* 3rd byte == 0? */ 84 1.1 christos je .Ldone 85 1.1 christos 86 1.1 christos movb -5(%rdi),%dl 87 1.1 christos cmpb %cl,%dl /* 4th byte == ch? */ 88 1.1 christos jne 1f 89 1.1 christos leaq -5(%rdi),%rax 90 1.1 christos 1: testb %dl,%dl /* 4th byte == 0? */ 91 1.1 christos je .Ldone 92 1.1 christos 93 1.1 christos movb -4(%rdi),%dl 94 1.1 christos cmpb %cl,%dl /* 5th byte == ch? */ 95 1.1 christos jne 1f 96 1.1 christos leaq -4(%rdi),%rax 97 1.1 christos 1: testb %dl,%dl /* 5th byte == 0? */ 98 1.1 christos je .Ldone 99 1.1 christos 100 1.1 christos movb -3(%rdi),%dl 101 1.1 christos cmpb %cl,%dl /* 6th byte == ch? */ 102 1.1 christos jne 1f 103 1.1 christos leaq -3(%rdi),%rax 104 1.1 christos 1: testb %dl,%dl /* 6th byte == 0? */ 105 1.1 christos je .Ldone 106 1.1 christos 107 1.1 christos movb -2(%rdi),%dl 108 1.1 christos cmpb %cl,%dl /* 7th byte == ch? */ 109 1.1 christos jne 1f 110 1.1 christos leaq -2(%rdi),%rax 111 1.1 christos 1: testb %dl,%dl /* 7th byte == 0? */ 112 1.1 christos je .Ldone 113 1.1 christos 114 1.1 christos movb -1(%rdi),%dl 115 1.1 christos cmpb %cl,%dl /* 8th byte == ch? */ 116 1.1 christos jne 1f 117 1.1 christos leaq -1(%rdi),%rax 118 1.1 christos 1: testb %dl,%dl /* 8th byte == 0? */ 119 1.1 christos jne .Lloop 120 1.1 christos 121 1.1 christos .Ldone: 122 1.1 christos ret 123 1.3 jakllsch END(strrchr) 124 1.2 dsl 125 1.2 dsl STRONG_ALIAS(rindex,strrchr) 126