Remove "[Add new features here]" for 2.27
[glibc.git] / sysdeps / aarch64 / memcmp.S
blobb99c081bba2c7f26b5b53315d6b806ae22eaaafc
1 /* memcmp - compare memory
3    Copyright (C) 2013-2017 Free Software Foundation, Inc.
5    This file is part of the GNU C Library.
7    The GNU C Library is free software; you can redistribute it and/or
8    modify it under the terms of the GNU Lesser General Public
9    License as published by the Free Software Foundation; either
10    version 2.1 of the License, or (at your option) any later version.
12    The GNU C Library is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    Lesser General Public License for more details.
17    You should have received a copy of the GNU Lesser General Public
18    License along with the GNU C Library.  If not, see
19    <http://www.gnu.org/licenses/>.  */
21 #include <sysdep.h>
23 /* Assumptions:
24  *
25  * ARMv8-a, AArch64, unaligned accesses.
26  */
28 /* Parameters and result.  */
29 #define src1            x0
30 #define src2            x1
31 #define limit           x2
32 #define result          w0
34 /* Internal variables.  */
35 #define data1           x3
36 #define data1w          w3
37 #define data2           x4
38 #define data2w          w4
39 #define tmp1            x5
41 ENTRY_ALIGN (memcmp, 6)
42         DELOUSE (0)
43         DELOUSE (1)
44         DELOUSE (2)
46         subs    limit, limit, 8
47         b.lo    .Lless8
49         /* Limit >= 8, so check first 8 bytes using unaligned loads.  */
50         ldr     data1, [src1], 8
51         ldr     data2, [src2], 8
52         and     tmp1, src1, 7
53         add     limit, limit, tmp1
54         cmp     data1, data2
55         bne     .Lreturn
57         /* Align src1 and adjust src2 with bytes not yet done.  */
58         sub     src1, src1, tmp1
59         sub     src2, src2, tmp1
61         subs    limit, limit, 8
62         b.ls    .Llast_bytes
64         /* Loop performing 8 bytes per iteration using aligned src1.
65            Limit is pre-decremented by 8 and must be larger than zero.
66            Exit if <= 8 bytes left to do or if the data is not equal.  */
67         .p2align 4
68 .Lloop8:
69         ldr     data1, [src1], 8
70         ldr     data2, [src2], 8
71         subs    limit, limit, 8
72         ccmp    data1, data2, 0, hi  /* NZCV = 0b0000.  */
73         b.eq    .Lloop8
75         cmp     data1, data2
76         bne     .Lreturn
78         /* Compare last 1-8 bytes using unaligned access.  */
79 .Llast_bytes:
80         ldr     data1, [src1, limit]
81         ldr     data2, [src2, limit]
83         /* Compare data bytes and set return value to 0, -1 or 1.  */
84 .Lreturn:
85 #ifndef __AARCH64EB__
86         rev     data1, data1
87         rev     data2, data2
88 #endif
89         cmp     data1, data2
90 .Lret_eq:
91         cset    result, ne
92         cneg    result, result, lo
93         ret
95         .p2align 4
96         /* Compare up to 8 bytes.  Limit is [-8..-1].  */
97 .Lless8:
98         adds    limit, limit, 4
99         b.lo    .Lless4
100         ldr     data1w, [src1], 4
101         ldr     data2w, [src2], 4
102         cmp     data1w, data2w
103         b.ne    .Lreturn
104         sub     limit, limit, 4
105 .Lless4:
106         adds    limit, limit, 4
107         beq     .Lret_eq
108 .Lbyte_loop:
109         ldrb    data1w, [src1], 1
110         ldrb    data2w, [src2], 1
111         subs    limit, limit, 1
112         ccmp    data1w, data2w, 0, ne   /* NZCV = 0b0000.  */
113         b.eq    .Lbyte_loop
114         sub     result, data1w, data2w
115         ret
117 END (memcmp)
118 #undef bcmp
119 weak_alias (memcmp, bcmp)
120 libc_hidden_builtin_def (memcmp)