1/* 2 * strcpy/stpcpy - copy a string returning pointer to start/end. 3 * 4 * Copyright (c) 2018-2022, Arm Limited. 5 * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception 6 */ 7 8#include "asmdefs.h" 9 10.arch armv8-a+sve 11 12/* Assumptions: 13 * 14 * ARMv8-a, AArch64 15 * SVE Available. 16 */ 17 18/* To build as stpcpy, define BUILD_STPCPY before compiling this file. */ 19#ifdef BUILD_STPCPY 20#define FUNC __stpcpy_aarch64_sve 21#else 22#define FUNC __strcpy_aarch64_sve 23#endif 24 25ENTRY (FUNC) 26 setffr /* initialize FFR */ 27 ptrue p2.b, all /* all ones; loop invariant */ 28 mov x2, 0 /* initialize offset */ 29 30 .p2align 4 31 /* Read a vector's worth of bytes, stopping on first fault. */ 320: ldff1b z0.b, p2/z, [x1, x2] 33 rdffrs p0.b, p2/z 34 b.nlast 1f 35 36 /* First fault did not fail: the whole vector is valid. 37 Avoid depending on the contexts of FFR beyond the branch. */ 38 cmpeq p1.b, p2/z, z0.b, 0 /* search for zeros */ 39 b.any 2f 40 41 /* No zero found. Store the whole vector and loop. */ 42 st1b z0.b, p2, [x0, x2] 43 incb x2, all 44 b 0b 45 46 /* First fault failed: only some of the vector is valid. 47 Perform the comparison only on the valid bytes. */ 481: cmpeq p1.b, p0/z, z0.b, 0 /* search for zeros */ 49 b.any 2f 50 51 /* No zero found. Store the valid portion of the vector and loop. */ 52 setffr /* re-init FFR */ 53 st1b z0.b, p0, [x0, x2] 54 incp x2, p0.b 55 b 0b 56 57 /* Zero found. Crop the vector to the found zero and finish. */ 582: brka p0.b, p2/z, p1.b 59 st1b z0.b, p0, [x0, x2] 60#ifdef BUILD_STPCPY 61 add x0, x0, x2 62 sub x0, x0, 1 63 incp x0, p0.b 64#endif 65 ret 66 67END (FUNC) 68