1/* $OpenBSD: strrchr.S,v 1.6 2022/12/07 19:26:39 guenther Exp $ */ 2/* $NetBSD: strrchr.S,v 1.3 2014/03/22 19:16:34 jakllsch Exp $ */ 3 4/* 5 * Written by J.T. Conklin <jtc@acorntoolworks.com> 6 * Public domain. 7 */ 8 9#include <machine/asm.h> 10 11STRONG_ALIAS(rindex, strrchr) 12 13ENTRY(strrchr) 14 RETGUARD_SETUP(strrchr, r10) 15 movzbq %sil,%rcx 16 17 /* zero return value */ 18 xorq %rax,%rax 19 20 /* 21 * Align to word boundary. 22 * Consider unrolling loop? 23 */ 24.Lalign: 25 testb $7,%dil 26 je .Lword_aligned 27 movb (%rdi),%dl 28 cmpb %cl,%dl 29 cmoveq %rdi,%rax 30 incq %rdi 31 testb %dl,%dl 32 jne .Lalign 33 jmp .Ldone 34 35.Lword_aligned: 36 /* copy char to all bytes in word */ 37 movb %cl,%ch 38 movq %rcx,%rdx 39 salq $16,%rcx 40 orq %rdx,%rcx 41 movq %rcx,%rdx 42 salq $32,%rcx 43 orq %rdx,%rcx 44 45 movabsq $0x0101010101010101,%r8 46 movabsq $0x8080808080808080,%r9 47 48 /* Check whether any byte in the word is equal to ch or 0. */ 49 _ALIGN_TEXT 50.Lloop: 51 movq (%rdi),%rdx 52 addq $8,%rdi 53 movq %rdx,%rsi 54 subq %r8,%rdx 55 xorq %rcx,%rsi 56 subq %r8,%rsi 57 orq %rsi,%rdx 58 testq %r9,%rdx 59 je .Lloop 60 61 /* 62 * In rare cases, the above loop may exit prematurely. We must 63 * return to the loop if none of the bytes in the word match 64 * ch or are equal to 0. 65 */ 66 67 movb -8(%rdi),%dl 68 cmpb %cl,%dl /* 1st byte == ch? */ 69 jne 1f 70 leaq -8(%rdi),%rax 711: testb %dl,%dl /* 1st byte == 0? */ 72 je .Ldone 73 74 movb -7(%rdi),%dl 75 cmpb %cl,%dl /* 2nd byte == ch? */ 76 jne 1f 77 leaq -7(%rdi),%rax 781: testb %dl,%dl /* 2nd byte == 0? */ 79 je .Ldone 80 81 movb -6(%rdi),%dl 82 cmpb %cl,%dl /* 3rd byte == ch? */ 83 jne 1f 84 leaq -6(%rdi),%rax 851: testb %dl,%dl /* 3rd byte == 0? */ 86 je .Ldone 87 88 movb -5(%rdi),%dl 89 cmpb %cl,%dl /* 4th byte == ch? */ 90 jne 1f 91 leaq -5(%rdi),%rax 921: testb %dl,%dl /* 4th byte == 0? */ 93 je .Ldone 94 95 movb -4(%rdi),%dl 96 cmpb %cl,%dl /* 5th byte == ch? */ 97 jne 1f 98 leaq -4(%rdi),%rax 991: testb %dl,%dl /* 5th byte == 0? */ 100 je .Ldone 101 102 movb -3(%rdi),%dl 103 cmpb %cl,%dl /* 6th byte == ch? */ 104 jne 1f 105 leaq -3(%rdi),%rax 1061: testb %dl,%dl /* 6th byte == 0? */ 107 je .Ldone 108 109 movb -2(%rdi),%dl 110 cmpb %cl,%dl /* 7th byte == ch? */ 111 jne 1f 112 leaq -2(%rdi),%rax 1131: testb %dl,%dl /* 7th byte == 0? */ 114 je .Ldone 115 116 movb -1(%rdi),%dl 117 cmpb %cl,%dl /* 8th byte == ch? */ 118 jne 1f 119 leaq -1(%rdi),%rax 1201: testb %dl,%dl /* 8th byte == 0? */ 121 jne .Lloop 122 123.Ldone: 124 RETGUARD_CHECK(strrchr, r10) 125 ret 126 lfence 127END(strrchr) 128