1/* Copyright (C) 2020-2021 Free Software Foundation, Inc. 2 3 This file is part of the GNU C Library. 4 5 The GNU C Library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with the GNU C Library. If not, see 17 <http://www.gnu.org/licenses/>. */ 18 19#include <sysdep.h> 20 21#ifdef USE_MTAG 22 23/* Assumptions: 24 * 25 * ARMv8-a, AArch64, MTE, LP64 ABI. 26 * 27 * Interface contract: 28 * Address is 16 byte aligned and size is multiple of 16. 29 * Returns the passed pointer. 30 * The memory region may remain untagged if tagging is not enabled. 31 */ 32 .arch armv8.5-a 33 .arch_extension memtag 34 35#define dstin x0 36#define count x1 37#define dst x2 38#define dstend x3 39#define tmp x4 40#define zva_val x4 41 42ENTRY (__libc_mtag_tag_region) 43 PTR_ARG (0) 44 SIZE_ARG (1) 45 46 add dstend, dstin, count 47 48 cmp count, 96 49 b.hi L(set_long) 50 51 tbnz count, 6, L(set96) 52 53 /* Set 0, 16, 32, or 48 bytes. */ 54 lsr tmp, count, 5 55 add tmp, dstin, tmp, lsl 4 56 cbz count, L(end) 57 stg dstin, [dstin] 58 stg dstin, [tmp] 59 stg dstin, [dstend, -16] 60L(end): 61 ret 62 63 .p2align 4 64 /* Set 64..96 bytes. Write 64 bytes from the start and 65 32 bytes from the end. */ 66L(set96): 67 st2g dstin, [dstin] 68 st2g dstin, [dstin, 32] 69 st2g dstin, [dstend, -32] 70 ret 71 72 .p2align 4 73 /* Size is > 96 bytes. */ 74L(set_long): 75 cmp count, 160 76 b.lo L(no_zva) 77 78#ifndef SKIP_ZVA_CHECK 79 mrs zva_val, dczid_el0 80 and zva_val, zva_val, 31 81 cmp zva_val, 4 /* ZVA size is 64 bytes. */ 82 b.ne L(no_zva) 83#endif 84 st2g dstin, [dstin] 85 st2g dstin, [dstin, 32] 86 bic dst, dstin, 63 87 sub count, dstend, dst /* Count is now 64 too large. */ 88 sub count, count, 128 /* Adjust count and bias for loop. */ 89 90 .p2align 4 91L(zva_loop): 92 add dst, dst, 64 93 dc gva, dst 94 subs count, count, 64 95 b.hi L(zva_loop) 96 st2g dstin, [dstend, -64] 97 st2g dstin, [dstend, -32] 98 ret 99 100L(no_zva): 101 sub dst, dstin, 32 /* Dst is biased by -32. */ 102 sub count, count, 64 /* Adjust count for loop. */ 103L(no_zva_loop): 104 st2g dstin, [dst, 32] 105 st2g dstin, [dst, 64]! 106 subs count, count, 64 107 b.hi L(no_zva_loop) 108 st2g dstin, [dstend, -64] 109 st2g dstin, [dstend, -32] 110 ret 111 112END (__libc_mtag_tag_region) 113#endif /* USE_MTAG */ 114