Path: blob/main/contrib/arm-optimized-routines/string/aarch64/experimental/strncmp-sve.S
39536 views
/*1* strncmp - compare two strings with limit2*3* Copyright (c) 2018-2022, Arm Limited.4* SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception5*/67#include "asmdefs.h"89.arch armv8-a+sve1011/* Assumptions:12*13* ARMv8-a, AArch6414* SVE Available.15*/1617ENTRY (__strncmp_aarch64_sve)18setffr /* initialize FFR */19mov x3, 0 /* initialize off */20210: whilelo p0.b, x3, x2 /* while off < max */22b.none 9f2324ldff1b z0.b, p0/z, [x0, x3]25ldff1b z1.b, p0/z, [x1, x3]26rdffrs p1.b, p0/z27b.nlast 2f2829/* First fault did not fail: the vector up to max is valid.30Avoid depending on the contents of FFR beyond the branch.31Increment for a whole vector, even if we've only read a partial.32This is significantly cheaper than INCP, and since OFF is not33used after the loop it is ok to increment OFF past MAX. */34incb x335cmpeq p1.b, p0/z, z0.b, z1.b /* compare strings */36cmpne p2.b, p0/z, z0.b, 0 /* search for ~zero */37nands p2.b, p0/z, p1.b, p2.b /* ~(eq & ~zero) -> ne | zero */38b.none 0b3940/* Found end-of-string or inequality. */411: brkb p2.b, p0/z, p2.b /* find first such */42lasta w0, p2, z0.b /* extract each char */43lasta w1, p2, z1.b44sub x0, x0, x1 /* return comparison */45ret4647/* First fault failed: only some of the vector is valid.48Perform the comparison only on the valid bytes. */492: cmpeq p2.b, p1/z, z0.b, z1.b /* compare strings, as above */50cmpne p3.b, p1/z, z0.b, 051nands p2.b, p1/z, p2.b, p3.b52b.any 1b5354/* No inequality or zero found. Re-init FFR, incr and loop. */55setffr56incp x3, p1.b57b 0b5859/* Found end-of-count. */609: mov x0, 0 /* return equal */61ret6263END (__strncmp_aarch64_sve)646566