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