Update copyright dates with scripts/update-copyrights
[glibc.git] / sysdeps / aarch64 / __mtag_tag_region.S
blobef820b45b3a18c56115c2c58684d16dec76cf991
1 /* Copyright (C) 2020-2023 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
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.
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.
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/>.  */
19 #include <sysdep.h>
21 #ifdef USE_MTAG
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
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
42 ENTRY (__libc_mtag_tag_region)
43         PTR_ARG (0)
44         SIZE_ARG (1)
46         add     dstend, dstin, count
48         cmp     count, 96
49         b.hi    L(set_long)
51         tbnz    count, 6, L(set96)
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]
60 L(end):
61         ret
63         .p2align 4
64         /* Set 64..96 bytes.  Write 64 bytes from the start and
65            32 bytes from the end.  */
66 L(set96):
67         st2g    dstin, [dstin]
68         st2g    dstin, [dstin, 32]
69         st2g    dstin, [dstend, -32]
70         ret
72         .p2align 4
73         /* Size is > 96 bytes.  */
74 L(set_long):
75         cmp     count, 160
76         b.lo    L(no_zva)
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.  */
90         .p2align 4
91 L(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
100 L(no_zva):
101         sub     dst, dstin, 32          /* Dst is biased by -32.  */
102         sub     count, count, 64        /* Adjust count for loop.  */
103 L(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
112 END (__libc_mtag_tag_region)
113 #endif /* USE_MTAG */