blob: 1a2043a57a1941dcf7dc9348d5ab3b2d45e7819a [file] [log] [blame]
Siddhesh Poyarekare3a57772018-03-13 15:31:46 +00001/* memcmp - compare memory
2
3 Copyright (c) 2013, 2018 Linaro Limited
4 All rights reserved.
5
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
8 * Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
13 * Neither the name of the Linaro nor the
14 names of its contributors may be used to endorse or promote products
15 derived from this software without specific prior written permission.
16
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
28
Sebastian Poped9bfc42017-06-19 12:39:02 -050029/*
30 * Copyright (c) 2017 ARM Ltd
31 * All rights reserved.
32 *
33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted provided that the following conditions
35 * are met:
36 * 1. Redistributions of source code must retain the above copyright
37 * notice, this list of conditions and the following disclaimer.
38 * 2. Redistributions in binary form must reproduce the above copyright
39 * notice, this list of conditions and the following disclaimer in the
40 * documentation and/or other materials provided with the distribution.
41 * 3. The name of the company may not be used to endorse or promote
42 * products derived from this software without specific prior written
43 * permission.
44 *
45 * THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED
46 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
47 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
48 * IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
49 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
50 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
51 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
52 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
53 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
54 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
55 */
Bernhard Rosenkraenzer7e4fa562014-03-05 11:40:57 +010056
57/* Assumptions:
58 *
Sebastian Poped9bfc42017-06-19 12:39:02 -050059 * ARMv8-a, AArch64, unaligned accesses.
Bernhard Rosenkraenzer7e4fa562014-03-05 11:40:57 +010060 */
61
62#include <private/bionic_asm.h>
63
Siddhesh Poyarekare3a57772018-03-13 15:31:46 +000064#define L(l) .L ## l
65
Bernhard Rosenkraenzer7e4fa562014-03-05 11:40:57 +010066/* Parameters and result. */
67#define src1 x0
68#define src2 x1
69#define limit x2
Sebastian Poped9bfc42017-06-19 12:39:02 -050070#define result w0
Bernhard Rosenkraenzer7e4fa562014-03-05 11:40:57 +010071
72/* Internal variables. */
73#define data1 x3
74#define data1w w3
Siddhesh Poyarekare3a57772018-03-13 15:31:46 +000075#define data1h x4
76#define data2 x5
77#define data2w w5
78#define data2h x6
79#define tmp1 x7
80#define tmp2 x8
Sebastian Poped9bfc42017-06-19 12:39:02 -050081
82.p2align 6
Bernhard Rosenkraenzer7e4fa562014-03-05 11:40:57 +010083ENTRY(memcmp)
Sebastian Poped9bfc42017-06-19 12:39:02 -050084 subs limit, limit, 8
Siddhesh Poyarekare3a57772018-03-13 15:31:46 +000085 b.lo L(less8)
Bernhard Rosenkraenzer7e4fa562014-03-05 11:40:57 +010086
Sebastian Poped9bfc42017-06-19 12:39:02 -050087 ldr data1, [src1], 8
88 ldr data2, [src2], 8
Sebastian Poped9bfc42017-06-19 12:39:02 -050089 cmp data1, data2
Siddhesh Poyarekare3a57772018-03-13 15:31:46 +000090 b.ne L(return)
91
92 subs limit, limit, 8
93 b.gt L(more16)
94
95 ldr data1, [src1, limit]
96 ldr data2, [src2, limit]
97 b L(return)
98
99L(more16):
100 ldr data1, [src1], 8
101 ldr data2, [src2], 8
102 cmp data1, data2
103 bne L(return)
104
105 /* Jump directly to comparing the last 16 bytes for 32 byte (or less)
106 strings. */
107 subs limit, limit, 16
108 b.ls L(last_bytes)
109
110 /* We overlap loads between 0-32 bytes at either side of SRC1 when we
111 try to align, so limit it only to strings larger than 128 bytes. */
112 cmp limit, 96
113 b.ls L(loop16)
Bernhard Rosenkraenzer7e4fa562014-03-05 11:40:57 +0100114
Sebastian Poped9bfc42017-06-19 12:39:02 -0500115 /* Align src1 and adjust src2 with bytes not yet done. */
Siddhesh Poyarekare3a57772018-03-13 15:31:46 +0000116 and tmp1, src1, 15
117 add limit, limit, tmp1
Sebastian Poped9bfc42017-06-19 12:39:02 -0500118 sub src1, src1, tmp1
119 sub src2, src2, tmp1
Bernhard Rosenkraenzer7e4fa562014-03-05 11:40:57 +0100120
Siddhesh Poyarekare3a57772018-03-13 15:31:46 +0000121 /* Loop performing 16 bytes per iteration using aligned src1.
122 Limit is pre-decremented by 16 and must be larger than zero.
123 Exit if <= 16 bytes left to do or if the data is not equal. */
Sebastian Poped9bfc42017-06-19 12:39:02 -0500124 .p2align 4
Siddhesh Poyarekare3a57772018-03-13 15:31:46 +0000125L(loop16):
126 ldp data1, data1h, [src1], 16
127 ldp data2, data2h, [src2], 16
128 subs limit, limit, 16
129 ccmp data1, data2, 0, hi
130 ccmp data1h, data2h, 0, eq
131 b.eq L(loop16)
Bernhard Rosenkraenzer7e4fa562014-03-05 11:40:57 +0100132
Sebastian Poped9bfc42017-06-19 12:39:02 -0500133 cmp data1, data2
Siddhesh Poyarekare3a57772018-03-13 15:31:46 +0000134 bne L(return)
135 mov data1, data1h
136 mov data2, data2h
137 cmp data1, data2
138 bne L(return)
Sebastian Poped9bfc42017-06-19 12:39:02 -0500139
Siddhesh Poyarekare3a57772018-03-13 15:31:46 +0000140 /* Compare last 1-16 bytes using unaligned access. */
141L(last_bytes):
142 add src1, src1, limit
143 add src2, src2, limit
144 ldp data1, data1h, [src1]
145 ldp data2, data2h, [src2]
146 cmp data1, data2
147 bne L(return)
148 mov data1, data1h
149 mov data2, data2h
150 cmp data1, data2
Sebastian Poped9bfc42017-06-19 12:39:02 -0500151
152 /* Compare data bytes and set return value to 0, -1 or 1. */
Siddhesh Poyarekare3a57772018-03-13 15:31:46 +0000153L(return):
Sebastian Poped9bfc42017-06-19 12:39:02 -0500154#ifndef __AARCH64EB__
Bernhard Rosenkraenzer7e4fa562014-03-05 11:40:57 +0100155 rev data1, data1
156 rev data2, data2
157#endif
Sebastian Poped9bfc42017-06-19 12:39:02 -0500158 cmp data1, data2
Siddhesh Poyarekare3a57772018-03-13 15:31:46 +0000159L(ret_eq):
Sebastian Poped9bfc42017-06-19 12:39:02 -0500160 cset result, ne
161 cneg result, result, lo
Siddhesh Poyarekare3a57772018-03-13 15:31:46 +0000162 ret
Bernhard Rosenkraenzer7e4fa562014-03-05 11:40:57 +0100163
Sebastian Poped9bfc42017-06-19 12:39:02 -0500164 .p2align 4
165 /* Compare up to 8 bytes. Limit is [-8..-1]. */
Siddhesh Poyarekare3a57772018-03-13 15:31:46 +0000166L(less8):
Sebastian Poped9bfc42017-06-19 12:39:02 -0500167 adds limit, limit, 4
Siddhesh Poyarekare3a57772018-03-13 15:31:46 +0000168 b.lo L(less4)
Sebastian Poped9bfc42017-06-19 12:39:02 -0500169 ldr data1w, [src1], 4
170 ldr data2w, [src2], 4
171 cmp data1w, data2w
Siddhesh Poyarekare3a57772018-03-13 15:31:46 +0000172 b.ne L(return)
Sebastian Poped9bfc42017-06-19 12:39:02 -0500173 sub limit, limit, 4
Siddhesh Poyarekare3a57772018-03-13 15:31:46 +0000174L(less4):
Sebastian Poped9bfc42017-06-19 12:39:02 -0500175 adds limit, limit, 4
Siddhesh Poyarekare3a57772018-03-13 15:31:46 +0000176 beq L(ret_eq)
177L(byte_loop):
Sebastian Poped9bfc42017-06-19 12:39:02 -0500178 ldrb data1w, [src1], 1
179 ldrb data2w, [src2], 1
180 subs limit, limit, 1
181 ccmp data1w, data2w, 0, ne /* NZCV = 0b0000. */
Siddhesh Poyarekare3a57772018-03-13 15:31:46 +0000182 b.eq L(byte_loop)
Sebastian Poped9bfc42017-06-19 12:39:02 -0500183 sub result, data1w, data2w
Bernhard Rosenkraenzer7e4fa562014-03-05 11:40:57 +0100184 ret
185END(memcmp)