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