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