xref: /xnu-11215.41.3/osfmk/arm64/instructions.h (revision 33de042d024d46de5ff4e89f2471de6608e37fa4)
1 /*
2  * Copyright (c) 2019 Apple Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 #ifndef _INSTRUCTIONS_H_
29 #define _INSTRUCTIONS_H_
30 
31 #define ARM64_INSTR_LDST_MASK         (0x0a000000)
32 #define ARM64_INSTR_LDST_BITS         (0x08000000)
33 #define ARM64_INSTR_IS_LDST(x)        (((x) & ARM64_INSTR_LDST_MASK) == ARM64_INSTR_LDST_BITS)
34 
35 #define ARM64_INSTR_LDST_RN_MASK      0x1f
36 #define ARM64_INSTR_LDST_RN_SHIFT     5
37 #define ARM64_INSTR_LDST_RN_GET(x)    (((x) >> ARM64_INSTR_LDST_RN_SHIFT) & ARM64_INSTR_LDST_RN_MASK)
38 
39 
40 
41 #define ARM64_INSTR_CAS_MASK          (0x3fa07c00)
42 #define ARM64_INSTR_CAS_BITS          (0x08a07c00)
43 #define ARM64_INSTR_IS_CAS(x)         (((x) & ARM64_INSTR_CAS_MASK) == ARM64_INSTR_CAS_BITS)
44 
45 #define ARM64_INSTR_CAS_SZ_MASK   0x3
46 #define ARM64_INSTR_CAS_SZ_SHIFT  30
47 #define ARM64_INSTR_CAS_SZ_GET(x) (((x) >> ARM64_INSTR_CAS_SZ_SHIFT) & ARM64_INSTR_CAS_SZ_MASK)
48 
49 #define ARM64_INSTR_CAS_A_MASK    0x1
50 #define ARM64_INSTR_CAS_A_SHIFT   22
51 #define ARM64_INSTR_CAS_A_GET(x)  (((x) >> ARM64_INSTR_CAS_A_SHIFT) & ARM64_INSTR_CAS_A_MASK)
52 
53 #define ARM64_INSTR_CAS_RS_MASK   0x1f
54 #define ARM64_INSTR_CAS_RS_SHIFT  16
55 #define ARM64_INSTR_CAS_RS_GET(x) (((x) >> ARM64_INSTR_CAS_RS_SHIFT) & ARM64_INSTR_CAS_RS_MASK)
56 
57 #define ARM64_INSTR_CAS_R_MASK    0x1
58 #define ARM64_INSTR_CAS_R_SHIFT   15
59 #define ARM64_INSTR_CAS_R_GET(x)  (((x) >> ARM64_INSTR_CAS_R_SHIFT) & ARM64_INSTR_CAS_R_MASK)
60 
61 #define ARM64_INSTR_CAS_RN_GET(x) ARM64_INSTR_LDST_RN_GET(x)
62 
63 #define ARM64_INSTR_CAS_RT_MASK   0x1f
64 #define ARM64_INSTR_CAS_RT_SHIFT  0
65 #define ARM64_INSTR_CAS_RT_GET(x) (((x) >> ARM64_INSTR_CAS_RT_SHIFT) & ARM64_INSTR_CAS_RT_MASK)
66 
67 
68 
69 #define ARM64_INSTR_CASP_MASK         (0xbfa07c00)
70 #define ARM64_INSTR_CASP_BITS         (0x08207c00)
71 #define ARM64_INSTR_IS_CASP(x)        (((x) & ARM64_INSTR_CASP_MASK) == ARM64_INSTR_CASP_BITS)
72 
73 #define ARM64_INSTR_CASP_SZ_MASK   0x1
74 #define ARM64_INSTR_CASP_SZ_SHIFT  30
75 #define ARM64_INSTR_CASP_SZ_GET(x) (((x) >> ARM64_INSTR_CASP_SZ_SHIFT) & ARM64_INSTR_CASP_SZ_MASK)
76 
77 #define ARM64_INSTR_CASP_A_MASK    0x1
78 #define ARM64_INSTR_CASP_A_SHIFT   22
79 #define ARM64_INSTR_CASP_A_GET(x)  (((x) >> ARM64_INSTR_CASP_A_SHIFT) & ARM64_INSTR_CASP_A_MASK)
80 
81 #define ARM64_INSTR_CASP_RS_MASK   0x1f
82 #define ARM64_INSTR_CASP_RS_SHIFT  16
83 #define ARM64_INSTR_CASP_RS_GET(x) (((x) >> ARM64_INSTR_CASP_RS_SHIFT) & ARM64_INSTR_CASP_RS_MASK)
84 
85 #define ARM64_INSTR_CASP_R_MASK    0x1
86 #define ARM64_INSTR_CASP_R_SHIFT   15
87 #define ARM64_INSTR_CASP_R_GET(x)  (((x) >> ARM64_INSTR_CASP_R_SHIFT) & ARM64_INSTR_CASP_R_MASK)
88 
89 #define ARM64_INSTR_CASP_RN_GET(x) ARM64_INSTR_LDST_RN_GET(x)
90 
91 #define ARM64_INSTR_CASP_RT_MASK   0x1f
92 #define ARM64_INSTR_CASP_RT_SHIFT  0
93 #define ARM64_INSTR_CASP_RT_GET(x) (((x) >> ARM64_INSTR_CASP_RT_SHIFT) & ARM64_INSTR_CASP_RT_MASK)
94 
95 
96 
97 #define ARM64_INSTR_ATOMIC_LDST_MASK  (0x3f208c00)
98 #define ARM64_INSTR_ATOMIC_LDST_BITS  (0x38200000)
99 #define ARM64_INSTR_IS_ATOMIC_LDST(x) (((x) & ARM64_INSTR_ATOMIC_LDST_MASK) == ARM64_INSTR_ATOMIC_LDST_BITS)
100 
101 #define ARM64_INSTR_ATOMIC_LDST_SZ_MASK   0x3
102 #define ARM64_INSTR_ATOMIC_LDST_SZ_SHIFT  30
103 #define ARM64_INSTR_ATOMIC_LDST_SZ_GET(x) (((x) >> ARM64_INSTR_ATOMIC_LDST_SZ_SHIFT) & ARM64_INSTR_ATOMIC_LDST_SZ_MASK)
104 
105 #define ARM64_INSTR_ATOMIC_LDST_A_MASK    0x1
106 #define ARM64_INSTR_ATOMIC_LDST_A_SHIFT   23
107 #define ARM64_INSTR_ATOMIC_LDST_A_GET(x)  (((x) >> ARM64_INSTR_ATOMIC_LDST_A_SHIFT) & ARM64_INSTR_ATOMIC_LDST_A_MASK)
108 
109 #define ARM64_INSTR_ATOMIC_LDST_R_MASK    0x1
110 #define ARM64_INSTR_ATOMIC_LDST_R_SHIFT   22
111 #define ARM64_INSTR_ATOMIC_LDST_R_GET(x)  (((x) >> ARM64_INSTR_ATOMIC_LDST_R_SHIFT) & ARM64_INSTR_ATOMIC_LDST_R_MASK)
112 
113 #define ARM64_INSTR_ATOMIC_LDST_RS_MASK   0x1f
114 #define ARM64_INSTR_ATOMIC_LDST_RS_SHIFT  16
115 #define ARM64_INSTR_ATOMIC_LDST_RS_GET(x) (((x) >> ARM64_INSTR_ATOMIC_LDST_RS_SHIFT) & ARM64_INSTR_ATOMIC_LDST_RS_MASK)
116 
117 #define ARM64_INSTR_ATOMIC_LDST_OPC_ADD    0
118 #define ARM64_INSTR_ATOMIC_LDST_OPC_BIC    1
119 #define ARM64_INSTR_ATOMIC_LDST_OPC_EOR    2
120 #define ARM64_INSTR_ATOMIC_LDST_OPC_ORR    3
121 #define ARM64_INSTR_ATOMIC_LDST_OPC_SMAX   4
122 #define ARM64_INSTR_ATOMIC_LDST_OPC_SMIN   5
123 #define ARM64_INSTR_ATOMIC_LDST_OPC_UMAX   6
124 #define ARM64_INSTR_ATOMIC_LDST_OPC_UMIN   7
125 
126 #define ARM64_INSTR_ATOMIC_LDST_OPC_MASK   0x7
127 #define ARM64_INSTR_ATOMIC_LDST_OPC_SHIFT  12
128 #define ARM64_INSTR_ATOMIC_LDST_OPC_GET(x) (((x) >> ARM64_INSTR_ATOMIC_LDST_OPC_SHIFT) & ARM64_INSTR_ATOMIC_LDST_OPC_MASK)
129 
130 #define ARM64_INSTR_ATOMIC_LDST_RN_GET(x) ARM64_INSTR_LDST_RN_GET(x)
131 
132 #define ARM64_INSTR_ATOMIC_LDST_RT_MASK   0x1f
133 #define ARM64_INSTR_ATOMIC_LDST_RT_SHIFT  0
134 #define ARM64_INSTR_ATOMIC_LDST_RT_GET(x) (((x) >> ARM64_INSTR_ATOMIC_LDST_RT_SHIFT) & ARM64_INSTR_ATOMIC_LDST_RT_MASK)
135 
136 
137 
138 #define ARM64_INSTR_SWP_MASK          (0x3f208c00)
139 #define ARM64_INSTR_SWP_BITS          (0x38208000)
140 #define ARM64_INSTR_IS_SWP(x)         (((x) & ARM64_INSTR_SWP_MASK) == ARM64_INSTR_SWP_BITS)
141 
142 #define ARM64_INSTR_SWP_SZ_MASK   0x3
143 #define ARM64_INSTR_SWP_SZ_SHIFT  30
144 #define ARM64_INSTR_SWP_SZ_GET(x) (((x) >> ARM64_INSTR_SWP_SZ_SHIFT) & ARM64_INSTR_SWP_SZ_MASK)
145 
146 #define ARM64_INSTR_SWP_A_MASK    0x1
147 #define ARM64_INSTR_SWP_A_SHIFT   23
148 #define ARM64_INSTR_SWP_A_GET(x)  (((x) >> ARM64_INSTR_SWP_A_SHIFT) & ARM64_INSTR_SWP_A_MASK)
149 
150 #define ARM64_INSTR_SWP_R_MASK    0x1
151 #define ARM64_INSTR_SWP_R_SHIFT   22
152 #define ARM64_INSTR_SWP_R_GET(x)  (((x) >> ARM64_INSTR_SWP_R_SHIFT) & ARM64_INSTR_SWP_R_MASK)
153 
154 #define ARM64_INSTR_SWP_RS_MASK   0x1f
155 #define ARM64_INSTR_SWP_RS_SHIFT  16
156 #define ARM64_INSTR_SWP_RS_GET(x) (((x) >> ARM64_INSTR_SWP_RS_SHIFT) & ARM64_INSTR_SWP_RS_MASK)
157 
158 #define ARM64_INSTR_SWP_OPC_MASK   0x7
159 #define ARM64_INSTR_SWP_OPC_SHIFT  12
160 #define ARM64_INSTR_SWP_OPC_GET(x) (((x) >> ARM64_INSTR_SWP_OPC_SHIFT) & ARM64_INSTR_SWP_OPC_MASK)
161 
162 #define ARM64_INSTR_SWP_RN_GET(x) ARM64_INSTR_LDST_RN_GET(x)
163 
164 #define ARM64_INSTR_SWP_RT_MASK   0x1f
165 #define ARM64_INSTR_SWP_RT_SHIFT  0
166 #define ARM64_INSTR_SWP_RT_GET(x) (((x) >> ARM64_INSTR_SWP_RT_SHIFT) & ARM64_INSTR_SWP_RT_MASK)
167 
168 
169 
170 #define ARM64_INSTR_LDST_REG_OFFSET_MASK                (0x3b200c00)
171 #define ARM64_INSTR_LDST_REG_OFFSET_BITS                (0x38200800)
172 #define ARM64_INSTR_IS_LDST_REG_OFFSET(x)               (((x) & ARM64_INSTR_LDST_REG_OFFSET_MASK) == ARM64_INSTR_LDST_REG_OFFSET_BITS)
173 
174 #define ARM64_INSTR_LDST_REG_OFFSET_RM_MASK             0x1f
175 #define ARM64_INSTR_LDST_REG_OFFSET_RM_SHIFT            16
176 #define ARM64_INSTR_LDST_REG_OFFSET_RM_GET(x)           (((x) >> ARM64_INSTR_LDST_REG_OFFSET_RM_MASK) & ARM64_INSTR_LDST_REG_OFFSET_RM_SHIFT)
177 
178 enum arm64_ldst_reg_extend_type {
179 	ARM64_INSTR_LDST_REG_OFFSET_OPTION_UXTB = 0b000,
180 	ARM64_INSTR_LDST_REG_OFFSET_OPTION_UXTH = 0b001,
181 	ARM64_INSTR_LDST_REG_OFFSET_OPTION_UXTW = 0b010,
182 	ARM64_INSTR_LDST_REG_OFFSET_OPTION_UXTX = 0b011,
183 	ARM64_INSTR_LDST_REG_OFFSET_OPTION_STXB = 0b100,
184 	ARM64_INSTR_LDST_REG_OFFSET_OPTION_STXH = 0b101,
185 	ARM64_INSTR_LDST_REG_OFFSET_OPTION_SXTW = 0b110,
186 	ARM64_INSTR_LDST_REG_OFFSET_OPTION_SXTX = 0b111,
187 };
188 #define ARM64_INSTR_LDST_REG_OFFSET_OPTION_MASK         0b111
189 #define ARM64_INSTR_LDST_REG_OFFSET_OPTION_SHIFT        13
190 #define ARM64_INSTR_LDST_REG_OFFSET_OPTION_GET(x)       (((x) >> ARM64_INSTR_LDST_REG_OFFSET_OPTION_SHIFT) & ARM64_INSTR_LDST_REG_OFFSET_OPTION_MASK)
191 
192 #define ARM64_INSTR_LDST_REG_OFFSET_S_MASK              0b1
193 #define ARM64_INSTR_LDST_REG_OFFSET_S_SHIFT             12
194 #define ARM64_INSTR_LDST_REG_OFFSET_S_GET(x)            (((x) >> ARM64_INSTR_LDST_REG_OFFSET_S_MASK) & ARM64_INSTR_LDST_REG_OFFSET_S_SHIFT)
195 
196 
197 
198 #define ARM64_INSTR_AUTxx_MASK          (0xffffd000)
199 #define ARM64_INSTR_AUTxx_BITS          (0xdac11000)
200 #define ARM64_INSTR_IS_AUTxx(x)         (((x) & ARM64_INSTR_AUTxx_MASK) == ARM64_INSTR_AUTxx_BITS)
201 
202 #define ARM64_INSTR_AUTxx_RD_MASK       0x1f
203 #define ARM64_INSTR_AUTxx_RD_SHIFT      0
204 #define ARM64_INSTR_AUTxx_RD_GET(x)     (((x) >> ARM64_INSTR_AUTxx_RD_SHIFT) & ARM64_INSTR_AUTxx_RD_MASK)
205 
206 
207 
208 #define ARM64_INSTR_AUTIx_SYSTEM_MASK                   (0xfffffd9f)
209 #define ARM64_INSTR_AUTIx_SYSTEM_BITS                   (0xd503219f)
210 #define ARM64_INSTR_IS_AUTIx_SYSTEM(x)                  (((x) & ARM64_INSTR_AUTIx_SYSTEM_MASK) == ARM64_INSTR_AUTIx_SYSTEM_BITS)
211 
212 #define ARM64_INSTR_AUTIx_SYSTEM_CRM_OP2_MASK           0x7c
213 #define ARM64_INSTR_AUTIx_SYSTEM_CRM_OP2_SHIFT          0x5
214 #define ARM64_INSTR_AUTIx_SYSTEM_CRM_OP2_GET(x)         (((x) >> ARM64_INSTR_AUTIx_SYSTEM_CRM_OP2_SHIFT) & ARM64_INSTR_AUTIx_SYSTEM_CRM_OP2_MASK)
215 #define ARM64_INSTR_AUTIx_SYSTEM_CRM_OP2_AUTIA1716      0xc
216 #define ARM64_INSTR_AUTIx_SYSTEM_CRM_OP2_AUTIB1716      0xe
217 
218 #define ARM64_INSTR_BxRAx_MASK          (0xfedff800)
219 #define ARM64_INSTR_BxRAx_BITS          (0xd61f0800)
220 #define ARM64_INSTR_IS_BxRAx(x)         (((x) & ARM64_INSTR_BxRAx_MASK) == ARM64_INSTR_BxRAx_BITS)
221 
222 #define ARM64_INSTR_BxRAx_RN_MASK       0x1f
223 #define ARM64_INSTR_BxRAx_RN_SHIFT      5
224 #define ARM64_INSTR_BxRAx_RN_GET(x)     (((x) >> ARM64_INSTR_BxRAx_RN_SHIFT) & ARM64_INSTR_BxRAx_RN_MASK)
225 
226 #define ARM64_INSTR_RETAx_MASK          (0xfffffbff)
227 #define ARM64_INSTR_RETAx_BITS          (0xd65f0bff)
228 #define ARM64_INSTR_IS_RETAx(x)         (((x) & ARM64_INSTR_RETAx_MASK) == ARM64_INSTR_RETAx_BITS)
229 
230 #if HAS_ARM_FEAT_SME
231 #define ARM64_INSTR_RDSVL_MASK                          (0xfffff800)
232 #define ARM64_INSTR_RDSVL_BITS                          (0x04bf5800)
233 #define ARM64_INSTR_IS_RDSVL(x)                         (((x) & ARM64_INSTR_RDSVL_MASK) == ARM64_INSTR_RDSVL_BITS)
234 
235 #define ARM64_INSTR_RDSVL_IMM6_MASK                     0x3f
236 #define ARM64_INSTR_RDSVL_IMM6_SHIFT                    5
237 static inline int8_t
ARM64_INSTR_RDSVL_IMM6_GET(unsigned int opcode)238 ARM64_INSTR_RDSVL_IMM6_GET(unsigned int opcode)
239 {
240 	uint8_t imm6_unsigned = (opcode >> ARM64_INSTR_RDSVL_IMM6_SHIFT) & ARM64_INSTR_RDSVL_IMM6_MASK;
241 	if (imm6_unsigned & (1 << 5)) {
242 		return (int8_t)(0b11000000 | imm6_unsigned);
243 	} else {
244 		return (int8_t)imm6_unsigned;
245 	}
246 }
247 #define ARM64_INSTR_RDSVL_RD_MASK                       0x1f
248 #define ARM64_INSTR_RDSVL_RD_SHIFT                      0
249 #define ARM64_INSTR_RDSVL_RD_GET(x)                     (((x) >> ARM64_INSTR_RDSVL_RD_SHIFT) & ARM64_INSTR_RDSVL_RD_MASK)
250 #endif /* HAS_ARM_FEAT_SME */
251 
252 #endif /* _INSTRUCTIONS_H_ */
253