1/* 2 * strcpy/stpcpy - copy a string returning pointer to start/end. 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/* To build as stpcpy, define BUILD_STPCPY before compiling this file. */ 20#ifdef BUILD_STPCPY 21#define FUNC __stpcpy_aarch64_sve 22#else 23#define FUNC __strcpy_aarch64_sve 24#endif 25 26 .globl FUNC 27 .type FUNC, %function 28 .p2align 4 29FUNC: 30 setffr /* initialize FFR */ 31 ptrue p2.b, all /* all ones; loop invariant */ 32 mov x2, 0 /* initialize offset */ 33 34 .p2align 4 35 /* Read a vector's worth of bytes, stopping on first fault. */ 360: ldff1b z0.b, p2/z, [x1, x2] 37 rdffrs p0.b, p2/z 38 b.nlast 1f 39 40 /* First fault did not fail: the whole vector is valid. 41 Avoid depending on the contexts of FFR beyond the branch. */ 42 cmpeq p1.b, p2/z, z0.b, 0 /* search for zeros */ 43 b.any 2f 44 45 /* No zero found. Store the whole vector and loop. */ 46 st1b z0.b, p2, [x0, x2] 47 incb x2, all 48 b 0b 49 50 /* First fault failed: only some of the vector is valid. 51 Perform the comparison only on the valid bytes. */ 521: cmpeq p1.b, p0/z, z0.b, 0 /* search for zeros */ 53 b.any 2f 54 55 /* No zero found. Store the valid portion of the vector and loop. */ 56 setffr /* re-init FFR */ 57 st1b z0.b, p0, [x0, x2] 58 incp x2, p0.b 59 b 0b 60 61 /* Zero found. Crop the vector to the found zero and finish. */ 622: brka p0.b, p2/z, p1.b 63 st1b z0.b, p0, [x0, x2] 64#ifdef BUILD_STPCPY 65 add x0, x0, x2 66 sub x0, x0, 1 67 incp x0, p0.b 68#endif 69 ret 70 71 .size FUNC, . - FUNC 72#endif 73