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