Cygwin: access: Fix X_OK behaviour for backup operators and admins
[newlib-cygwin.git] / newlib / libc / machine / riscv / strcmp.S
blob9af9ca1f33774ef36d4ae59da7089e6605223340
1 /* Copyright (c) 2017  SiFive Inc. All rights reserved.
3    This copyrighted material is made available to anyone wishing to use,
4    modify, copy, or redistribute it subject to the terms and conditions
5    of the FreeBSD License.   This program is distributed in the hope that
6    it will be useful, but WITHOUT ANY WARRANTY expressed or implied,
7    including the implied warranties of MERCHANTABILITY or FITNESS FOR
8    A PARTICULAR PURPOSE.  A copy of this license is available at
9    http://www.opensource.org/licenses.
12 #include <sys/asm.h>
14 .text
15 .globl strcmp
16 .type  strcmp, @function
17 strcmp:
18 #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
20   lbu   a2, 0(a0)
21   lbu   a3, 0(a1)
22   add   a0, a0, 1
23   add   a1, a1, 1
24   bne   a2, a3, 2f
25   bnez  a2, 1b
28   sub   a0, a2, a3
29   ret
31 .size   strcmp, .-strcmp
32 #else
33   or    a4, a0, a1
34   li    t2, -1
35   and   a4, a4, SZREG-1
36   bnez  a4, .Lmisaligned
38 #if SZREG == 4
39   li a5, 0x7f7f7f7f
40 #else
41   ld a5, mask
42 #endif
44   .macro check_one_word i n
45     REG_L a2, \i*SZREG(a0)
46     REG_L a3, \i*SZREG(a1)
48     and   t0, a2, a5
49     or    t1, a2, a5
50     add   t0, t0, a5
51     or    t0, t0, t1
53     bne   t0, t2, .Lnull\i
54     .if \i+1-\n
55       bne   a2, a3, .Lmismatch
56     .else
57       add   a0, a0, \n*SZREG
58       add   a1, a1, \n*SZREG
59       beq   a2, a3, .Lloop
60       # fall through to .Lmismatch
61     .endif
62   .endm
64   .macro foundnull i n
65     .ifne \i
66       .Lnull\i:
67       add   a0, a0, \i*SZREG
68       add   a1, a1, \i*SZREG
69       .ifeq \i-1
70         .Lnull0:
71       .endif
72       bne   a2, a3, .Lmisaligned
73       li    a0, 0
74       ret
75     .endif
76   .endm
78 .Lloop:
79   # examine full words at a time, favoring strings of a couple dozen chars
80 #if __riscv_xlen == 32
81   check_one_word 0 5
82   check_one_word 1 5
83   check_one_word 2 5
84   check_one_word 3 5
85   check_one_word 4 5
86 #else
87   check_one_word 0 3
88   check_one_word 1 3
89   check_one_word 2 3
90 #endif
91   # backwards branch to .Lloop contained above
93 .Lmismatch:
94   # words don't match, but a2 has no null byte.
96 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
98 #if __riscv_xlen == 64
99   sll   a4, a2, 48
100   sll   a5, a3, 48
101   bne   a4, a5, .Lmismatch_upper
102   sll   a4, a2, 32
103   sll   a5, a3, 32
104   bne   a4, a5, .Lmismatch_upper
105 #endif
106   sll   a4, a2, 16
107   sll   a5, a3, 16
108   bne   a4, a5, .Lmismatch_upper
110   srl   a4, a2, 8*SZREG-16
111   srl   a5, a3, 8*SZREG-16
112   sub   a0, a4, a5
113   and   a1, a0, 0xff
114   bnez  a1, 1f
115   ret
117 .Lmismatch_upper:
118   srl   a4, a4, 8*SZREG-16
119   srl   a5, a5, 8*SZREG-16
120   sub   a0, a4, a5
121   and   a1, a0, 0xff
122   bnez  a1, 1f
123   ret
125 1:and   a4, a4, 0xff
126   and   a5, a5, 0xff
127   sub   a0, a4, a5
128   ret
130 #else
132 #if __riscv_xlen == 64
133   srl   a4, a2, 48
134   srl   a5, a3, 48
135   bne   a4, a5, .Lmismatch_lower
136   srl   a4, a2, 32
137   srl   a5, a3, 32
138   bne   a4, a5, .Lmismatch_lower
139 #endif
140   srl   a4, a2, 16
141   srl   a5, a3, 16
142   bne   a4, a5, .Lmismatch_lower
144   srl   a4, a2, 8
145   srl   a5, a3, 8
146   bne   a4, a5, 1f
147   and   a4, a2, 0xff
148   and   a5, a3, 0xff
149 1:sub   a0, a4, a5
150   ret
152 .Lmismatch_lower:
153   srl   a2, a4, 8
154   srl   a3, a5, 8
155   bne   a2, a3, 1f
156   and   a2, a4, 0xff
157   and   a3, a5, 0xff
158 1:sub   a0, a2, a3
159   ret
161 #endif
162         
163 .Lmisaligned:
164   # misaligned
165   lbu   a2, 0(a0)
166   lbu   a3, 0(a1)
167   add   a0, a0, 1
168   add   a1, a1, 1
169   bne   a2, a3, 1f
170   bnez  a2, .Lmisaligned
173   sub   a0, a2, a3
174   ret
176   # cases in which a null byte was detected
177 #if __riscv_xlen == 32
178   foundnull 0 5
179   foundnull 1 5
180   foundnull 2 5
181   foundnull 3 5
182   foundnull 4 5
183 #else
184   foundnull 0 3
185   foundnull 1 3
186   foundnull 2 3
187 #endif
188 .size   strcmp, .-strcmp
190 #if SZREG == 8
191 .section .srodata.cst8,"aM",@progbits,8
192 .align 3
193 mask:
194 .dword 0x7f7f7f7f7f7f7f7f
195 #endif
196 #endif