Commit | Line | Data |
---|---|---|
2e8cf49e NC |
1 | /* decode.h -- Prototypes for AArch64 simulator decoder functions. |
2 | ||
e2882c85 | 3 | Copyright (C) 2015-2018 Free Software Foundation, Inc. |
2e8cf49e NC |
4 | |
5 | Contributed by Red Hat. | |
6 | ||
7 | This file is part of GDB. | |
8 | ||
9 | This program is free software; you can redistribute it and/or modify | |
10 | it under the terms of the GNU General Public License as published by | |
11 | the Free Software Foundation; either version 3 of the License, or | |
12 | (at your option) any later version. | |
13 | ||
14 | This program is distributed in the hope that it will be useful, | |
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | GNU General Public License for more details. | |
18 | ||
19 | You should have received a copy of the GNU General Public License | |
20 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
21 | ||
22 | #ifndef _DECODE_H | |
23 | #define _DECODE_H | |
24 | ||
25 | #include <sys/types.h> | |
26 | #include "cpustate.h" | |
27 | ||
28 | /* Codes used in conditional instructions | |
29 | ||
30 | These are passed to conditional operations to identify which | |
31 | condition to test for. */ | |
32 | ||
33 | typedef enum CondCode | |
34 | { | |
35 | EQ = 0x0, /* meaning Z == 1 */ | |
36 | NE = 0x1, /* meaning Z == 0 */ | |
37 | HS = 0x2, /* meaning C == 1 */ | |
38 | CS = HS, | |
39 | LO = 0x3, /* meaning C == 0 */ | |
40 | CC = LO, | |
41 | MI = 0x4, /* meaning N == 1 */ | |
42 | PL = 0x5, /* meaning N == 0 */ | |
43 | VS = 0x6, /* meaning V == 1 */ | |
44 | VC = 0x7, /* meaning V == 0 */ | |
45 | HI = 0x8, /* meaning C == 1 && Z == 0 */ | |
46 | LS = 0x9, /* meaning !(C == 1 && Z == 0) */ | |
47 | GE = 0xa, /* meaning N == V */ | |
48 | LT = 0xb, /* meaning N != V */ | |
49 | GT = 0xc, /* meaning Z == 0 && N == V */ | |
50 | LE = 0xd, /* meaning !(Z == 0 && N == V) */ | |
51 | AL = 0xe, /* meaning ANY */ | |
52 | NV = 0xf /* ditto */ | |
53 | } CondCode; | |
54 | ||
55 | /* Certain addressing modes for load require pre or post writeback of | |
56 | the computed address to a base register. */ | |
57 | ||
58 | typedef enum WriteBack | |
59 | { | |
60 | Post = 0, | |
61 | Pre = 1, | |
62 | NoWriteBack = -1 | |
63 | } WriteBack; | |
64 | ||
65 | /* Certain addressing modes for load require an offset to | |
66 | be optionally scaled so the decode needs to pass that | |
67 | through to the execute routine. */ | |
68 | ||
69 | typedef enum Scaling | |
70 | { | |
71 | Unscaled = 0, | |
72 | Scaled = 1, | |
73 | NoScaling = -1 | |
74 | } Scaling; | |
75 | ||
76 | /* When we do have to scale we do so by shifting using | |
77 | log(bytes in data element - 1) as the shift count. | |
78 | so we don't have to scale offsets when loading | |
79 | bytes. */ | |
80 | ||
81 | typedef enum ScaleShift | |
82 | { | |
83 | ScaleShift16 = 1, | |
84 | ScaleShift32 = 2, | |
85 | ScaleShift64 = 3, | |
86 | ScaleShift128 = 4 | |
87 | } ScaleShift; | |
88 | ||
89 | /* One of the addressing modes for load requires a 32-bit register | |
90 | value to be either zero- or sign-extended for these instructions | |
91 | UXTW or SXTW should be passed. | |
92 | ||
93 | Arithmetic register data processing operations can optionally | |
94 | extend a portion of the second register value for these | |
95 | instructions the value supplied must identify the portion of the | |
96 | register which is to be zero- or sign-exended. */ | |
97 | ||
98 | typedef enum Extension | |
99 | { | |
100 | UXTB = 0, | |
101 | UXTH = 1, | |
102 | UXTW = 2, | |
103 | UXTX = 3, | |
104 | SXTB = 4, | |
105 | SXTH = 5, | |
106 | SXTW = 6, | |
107 | SXTX = 7, | |
108 | NoExtension = -1 | |
109 | } Extension; | |
110 | ||
111 | /* Arithmetic and logical register data processing operations | |
112 | optionally perform a shift on the second register value. */ | |
113 | ||
114 | typedef enum Shift | |
115 | { | |
116 | LSL = 0, | |
117 | LSR = 1, | |
118 | ASR = 2, | |
119 | ROR = 3 | |
120 | } Shift; | |
121 | ||
122 | /* Bit twiddling helpers for instruction decode. */ | |
123 | ||
124 | /* 32 bit mask with bits [hi,...,lo] set. */ | |
125 | static inline uint32_t | |
126 | mask32 (int hi, int lo) | |
127 | { | |
128 | int nbits = (hi + 1) - lo; | |
129 | return ((1 << nbits) - 1) << lo; | |
130 | } | |
131 | ||
132 | /* 64 bit mask with bits [hi,...,lo] set. */ | |
133 | static inline uint64_t | |
134 | mask64 (int hi, int lo) | |
135 | { | |
136 | int nbits = (hi + 1) - lo; | |
137 | return ((1L << nbits) - 1) << lo; | |
138 | } | |
139 | ||
140 | /* Pick bits [hi,...,lo] from val. */ | |
141 | static inline uint32_t | |
142 | pick32 (uint32_t val, int hi, int lo) | |
143 | { | |
144 | return val & mask32 (hi, lo); | |
145 | } | |
146 | ||
147 | /* Pick bits [hi,...,lo] from val. */ | |
148 | static inline uint64_t | |
149 | pick64 (uint64_t val, int hi, int lo) | |
150 | { | |
151 | return val & mask64 (hi, lo); | |
152 | } | |
153 | ||
154 | /* Pick bits [hi,...,lo] from val and shift to [(hi-(newlo - lo)),newlo]. */ | |
155 | static inline uint32_t | |
156 | pickshift32 (uint32_t val, int hi, int lo, int newlo) | |
157 | { | |
158 | uint32_t bits = pick32 (val, hi, lo); | |
159 | ||
160 | if (lo < newlo) | |
161 | return bits << (newlo - lo); | |
162 | ||
163 | return bits >> (lo - newlo); | |
164 | } | |
165 | ||
166 | /* Mask [hi,lo] and shift down to start at bit 0. */ | |
167 | static inline uint32_t | |
168 | pickbits32 (uint32_t val, int hi, int lo) | |
169 | { | |
170 | return pick32 (val, hi, lo) >> lo; | |
171 | } | |
172 | ||
173 | /* Mask [hi,lo] and shift down to start at bit 0. */ | |
174 | static inline uint64_t | |
175 | pickbits64 (uint64_t val, int hi, int lo) | |
176 | { | |
177 | return pick64 (val, hi, lo) >> lo; | |
178 | } | |
179 | ||
2e8cf49e NC |
180 | static inline uint32_t |
181 | uimm (uint32_t val, int hi, int lo) | |
182 | { | |
183 | return pickbits32 (val, hi, lo); | |
184 | } | |
185 | ||
186 | static inline int32_t | |
187 | simm32 (uint32_t val, int hi, int lo) | |
188 | { | |
189 | union | |
190 | { | |
191 | uint32_t u; | |
192 | int32_t n; | |
193 | } x; | |
194 | ||
195 | x.u = val << (31 - hi); | |
196 | return x.n >> (31 - hi + lo); | |
197 | } | |
198 | ||
199 | static inline int64_t | |
200 | simm64 (uint64_t val, int hi, int lo) | |
201 | { | |
202 | union | |
203 | { | |
204 | uint64_t u; | |
205 | int64_t n; | |
206 | } x; | |
207 | ||
208 | x.u = val << (63 - hi); | |
209 | return x.n >> (63 - hi + lo); | |
210 | } | |
211 | ||
2e8cf49e NC |
212 | /* Operation decode. |
213 | Bits [28,24] are the primary dispatch vector. */ | |
214 | ||
215 | static inline uint32_t | |
216 | dispatchGroup (uint32_t val) | |
217 | { | |
218 | return pickshift32 (val, 28, 25, 0); | |
219 | } | |
220 | ||
221 | /* The 16 possible values for bits [28,25] identified by tags which | |
222 | map them to the 5 main instruction groups LDST, DPREG, ADVSIMD, | |
223 | BREXSYS and DPIMM. | |
224 | ||
225 | An extra group PSEUDO is included in one of the unallocated ranges | |
226 | for simulator-specific pseudo-instructions. */ | |
227 | ||
228 | enum DispatchGroup | |
229 | { | |
230 | GROUP_PSEUDO_0000, | |
231 | GROUP_UNALLOC_0001, | |
232 | GROUP_UNALLOC_0010, | |
233 | GROUP_UNALLOC_0011, | |
234 | GROUP_LDST_0100, | |
235 | GROUP_DPREG_0101, | |
236 | GROUP_LDST_0110, | |
237 | GROUP_ADVSIMD_0111, | |
238 | GROUP_DPIMM_1000, | |
239 | GROUP_DPIMM_1001, | |
240 | GROUP_BREXSYS_1010, | |
241 | GROUP_BREXSYS_1011, | |
242 | GROUP_LDST_1100, | |
243 | GROUP_DPREG_1101, | |
244 | GROUP_LDST_1110, | |
245 | GROUP_ADVSIMD_1111 | |
246 | }; | |
247 | ||
248 | /* Bits [31, 29] of a Pseudo are the secondary dispatch vector. */ | |
249 | ||
250 | static inline uint32_t | |
251 | dispatchPseudo (uint32_t val) | |
252 | { | |
253 | return pickshift32 (val, 31, 29, 0); | |
254 | } | |
255 | ||
256 | /* The 8 possible values for bits [31,29] in a Pseudo Instruction. | |
257 | Bits [28,25] are always 0000. */ | |
258 | ||
259 | enum DispatchPseudo | |
260 | { | |
261 | PSEUDO_UNALLOC_000, /* Unallocated. */ | |
262 | PSEUDO_UNALLOC_001, /* Ditto. */ | |
263 | PSEUDO_UNALLOC_010, /* Ditto. */ | |
264 | PSEUDO_UNALLOC_011, /* Ditto. */ | |
265 | PSEUDO_UNALLOC_100, /* Ditto. */ | |
266 | PSEUDO_UNALLOC_101, /* Ditto. */ | |
267 | PSEUDO_CALLOUT_110, /* CALLOUT -- bits [24,0] identify call/ret sig. */ | |
268 | PSEUDO_HALT_111 /* HALT -- bits [24, 0] identify halt code. */ | |
269 | }; | |
270 | ||
271 | /* Bits [25, 23] of a DPImm are the secondary dispatch vector. */ | |
272 | ||
273 | static inline uint32_t | |
274 | dispatchDPImm (uint32_t instr) | |
275 | { | |
276 | return pickshift32 (instr, 25, 23, 0); | |
277 | } | |
278 | ||
279 | /* The 8 possible values for bits [25,23] in a Data Processing Immediate | |
280 | Instruction. Bits [28,25] are always 100_. */ | |
281 | ||
282 | enum DispatchDPImm | |
283 | { | |
284 | DPIMM_PCADR_000, /* PC-rel-addressing. */ | |
285 | DPIMM_PCADR_001, /* Ditto. */ | |
286 | DPIMM_ADDSUB_010, /* Add/Subtract (immediate). */ | |
287 | DPIMM_ADDSUB_011, /* Ditto. */ | |
288 | DPIMM_LOG_100, /* Logical (immediate). */ | |
289 | DPIMM_MOV_101, /* Move Wide (immediate). */ | |
290 | DPIMM_BITF_110, /* Bitfield. */ | |
291 | DPIMM_EXTR_111 /* Extract. */ | |
292 | }; | |
293 | ||
294 | /* Bits [29,28:26] of a LS are the secondary dispatch vector. */ | |
295 | ||
296 | static inline uint32_t | |
297 | dispatchLS (uint32_t instr) | |
298 | { | |
299 | return ( pickshift32 (instr, 29, 28, 1) | |
300 | | pickshift32 (instr, 26, 26, 0)); | |
301 | } | |
302 | ||
303 | /* The 8 possible values for bits [29,28:26] in a Load/Store | |
304 | Instruction. Bits [28,25] are always _1_0. */ | |
305 | ||
306 | enum DispatchLS | |
307 | { | |
308 | LS_EXCL_000, /* Load/store exclusive (includes some unallocated). */ | |
309 | LS_ADVSIMD_001, /* AdvSIMD load/store (various -- includes some unallocated). */ | |
310 | LS_LIT_010, /* Load register literal (includes some unallocated). */ | |
311 | LS_LIT_011, /* Ditto. */ | |
312 | LS_PAIR_100, /* Load/store register pair (various). */ | |
313 | LS_PAIR_101, /* Ditto. */ | |
314 | LS_OTHER_110, /* Other load/store formats. */ | |
315 | LS_OTHER_111 /* Ditto. */ | |
316 | }; | |
317 | ||
318 | /* Bits [28:24:21] of a DPReg are the secondary dispatch vector. */ | |
319 | ||
320 | static inline uint32_t | |
321 | dispatchDPReg (uint32_t instr) | |
322 | { | |
323 | return ( pickshift32 (instr, 28, 28, 2) | |
324 | | pickshift32 (instr, 24, 24, 1) | |
325 | | pickshift32 (instr, 21, 21, 0)); | |
326 | } | |
327 | ||
328 | /* The 8 possible values for bits [28:24:21] in a Data Processing | |
329 | Register Instruction. Bits [28,25] are always _101. */ | |
330 | ||
331 | enum DispatchDPReg | |
332 | { | |
333 | DPREG_LOG_000, /* Logical (shifted register). */ | |
334 | DPREG_LOG_001, /* Ditto. */ | |
335 | DPREG_ADDSHF_010, /* Add/subtract (shifted register). */ | |
336 | DPREG_ADDEXT_011, /* Add/subtract (extended register). */ | |
337 | DPREG_ADDCOND_100, /* Add/subtract (with carry) AND | |
338 | Cond compare/select AND | |
339 | Data Processing (1/2 source). */ | |
340 | DPREG_UNALLOC_101, /* Unallocated. */ | |
341 | DPREG_3SRC_110, /* Data Processing (3 source). */ | |
342 | DPREG_3SRC_111 /* Data Processing (3 source). */ | |
343 | }; | |
344 | ||
345 | /* bits [31,29] of a BrExSys are the secondary dispatch vector. */ | |
346 | ||
347 | static inline uint32_t | |
348 | dispatchBrExSys (uint32_t instr) | |
349 | { | |
350 | return pickbits32 (instr, 31, 29); | |
351 | } | |
352 | ||
353 | /* The 8 possible values for bits [31,29] in a Branch/Exception/System | |
354 | Instruction. Bits [28,25] are always 101_. */ | |
355 | ||
356 | enum DispatchBr | |
357 | { | |
358 | BR_IMM_000, /* Unconditional branch (immediate). */ | |
359 | BR_IMMCMP_001, /* Compare & branch (immediate) AND | |
360 | Test & branch (immediate). */ | |
361 | BR_IMMCOND_010, /* Conditional branch (immediate) AND Unallocated. */ | |
362 | BR_UNALLOC_011, /* Unallocated. */ | |
363 | BR_IMM_100, /* Unconditional branch (immediate). */ | |
364 | BR_IMMCMP_101, /* Compare & branch (immediate) AND | |
365 | Test & branch (immediate). */ | |
366 | BR_REG_110, /* Unconditional branch (register) AND System AND | |
367 | Excn gen AND Unallocated. */ | |
368 | BR_UNALLOC_111 /* Unallocated. */ | |
369 | }; | |
370 | ||
371 | /* TODO still need to provide secondary decode and dispatch for | |
372 | AdvSIMD Insructions with instr[28,25] = 0111 or 1111. */ | |
373 | ||
374 | #endif /* _DECODE_H */ |