1 /* SPDX-License-Identifier: GPL-2.0-only */
3 * Copyright (c) 2013-2021, Arm Limited.
5 * Adapted from the original at:
6 * https://github.com/ARM-software/optimized-routines/blob/e823e3abf5f89ecb/string/aarch64/memcmp.S
9 #include <linux/linkage.h>
10 #include <asm/assembler.h>
14 * ARMv8-a, AArch64, unaligned accesses.
17 #define L(label) .L ## label
19 /* Parameters and result. */
25 /* Internal variables. */
35 SYM_FUNC_START(__pi_memcmp)
47 ldr data1, [src1, limit]
48 ldr data2, [src2, limit]
57 /* Jump directly to comparing the last 16 bytes for 32 byte (or less)
62 /* We overlap loads between 0-32 bytes at either side of SRC1 when we
63 try to align, so limit it only to strings larger than 128 bytes. */
67 /* Align src1 and adjust src2 with bytes not yet done. */
69 add limit, limit, tmp1
73 /* Loop performing 16 bytes per iteration using aligned src1.
74 Limit is pre-decremented by 16 and must be larger than zero.
75 Exit if <= 16 bytes left to do or if the data is not equal. */
78 ldp data1, data1h, [src1], 16
79 ldp data2, data2h, [src2], 16
81 ccmp data1, data2, 0, hi
82 ccmp data1h, data2h, 0, eq
92 /* Compare last 1-16 bytes using unaligned access. */
96 ldp data1, data1h, [src1]
97 ldp data2, data2h, [src2]
104 /* Compare data bytes and set return value to 0, -1 or 1. */
106 #ifndef __AARCH64EB__
113 cneg result, result, lo
117 /* Compare up to 8 bytes. Limit is [-8..-1]. */
121 ldr data1w, [src1], 4
122 ldr data2w, [src2], 4
130 ldrb data1w, [src1], 1
131 ldrb data2w, [src2], 1
133 ccmp data1w, data2w, 0, ne /* NZCV = 0b0000. */
135 sub result, data1w, data2w
137 SYM_FUNC_END(__pi_memcmp)
138 SYM_FUNC_ALIAS_WEAK(memcmp, __pi_memcmp)
139 EXPORT_SYMBOL_NOKASAN(memcmp)