1/* 2 * __strcmp_aarch64_sve - compare two strings 3 * 4 * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5 * See https://llvm.org/LICENSE.txt for license information. 6 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 */ 8 9#if __ARM_FEATURE_SVE 10/* Assumptions: 11 * 12 * ARMv8-a, AArch64 13 * SVE Available. 14 */ 15 16 .arch armv8-a+sve 17 .text 18 19 .globl __strcmp_aarch64_sve 20 .type __strcmp_aarch64_sve, %function 21 .p2align 4 22__strcmp_aarch64_sve: 23 setffr /* initialize FFR */ 24 ptrue p1.b, all /* all ones; loop invariant */ 25 mov x2, 0 /* initialize offset */ 26 nop 27 28 /* Read a vector's worth of bytes, stopping on first fault. */ 290: ldff1b z0.b, p1/z, [x0, x2] 30 ldff1b z1.b, p1/z, [x1, x2] 31 rdffrs p0.b, p1/z 32 b.nlast 2f 33 34 /* First fault did not fail: the whole vector is valid. 35 Avoid depending on the contents of FFR beyond the branch. */ 36 incb x2, all /* skip bytes for next round */ 37 cmpeq p2.b, p1/z, z0.b, z1.b /* compare strings */ 38 cmpne p3.b, p1/z, z0.b, 0 /* search for ~zero */ 39 nands p2.b, p1/z, p2.b, p3.b /* ~(eq & ~zero) -> ne | zero */ 40 b.none 0b 41 42 /* Found end-of-string or inequality. */ 431: brkb p2.b, p1/z, p2.b /* find first such */ 44 lasta w0, p2, z0.b /* extract each char */ 45 lasta w1, p2, z1.b 46 sub x0, x0, x1 /* return comparison */ 47 ret 48 49 /* First fault failed: only some of the vector is valid. 50 Perform the comparison only on the valid bytes. */ 512: incp x2, p0.b /* skip bytes for next round */ 52 setffr /* re-init FFR for next round */ 53 cmpeq p2.b, p0/z, z0.b, z1.b /* compare strings, as above */ 54 cmpne p3.b, p0/z, z0.b, 0 55 nands p2.b, p0/z, p2.b, p3.b 56 b.none 0b 57 b 1b 58 59 .size __strcmp_aarch64_sve, . - __strcmp_aarch64_sve 60#endif 61