1/* decode.h -- Prototypes for AArch64 simulator decoder functions.
2
3   Copyright (C) 2015-2023 Free Software Foundation, Inc.
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
33typedef 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
58typedef 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
69typedef 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
81typedef 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
98typedef 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
114typedef 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.  */
125static inline uint32_t
126mask32 (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.  */
133static inline uint64_t
134mask64 (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.  */
141static inline uint32_t
142pick32 (uint32_t val, int hi, int lo)
143{
144  return val & mask32 (hi, lo);
145}
146
147/* Pick bits [hi,...,lo] from val.  */
148static inline uint64_t
149pick64 (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].  */
155static inline uint32_t
156pickshift32 (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.  */
167static inline uint32_t
168pickbits32 (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.  */
174static inline uint64_t
175pickbits64 (uint64_t val, int hi, int lo)
176{
177  return pick64 (val, hi, lo) >> lo;
178}
179
180static inline uint32_t
181uimm (uint32_t val, int hi, int lo)
182{
183  return pickbits32 (val, hi, lo);
184}
185
186static inline int32_t
187simm32 (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
199static inline int64_t
200simm64 (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
212/* Operation decode.
213   Bits [28,24] are the primary dispatch vector.  */
214
215static inline uint32_t
216dispatchGroup (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
228enum 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
250static inline uint32_t
251dispatchPseudo (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
259enum 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
273static inline uint32_t
274dispatchDPImm (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
282enum 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
296static inline uint32_t
297dispatchLS (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
306enum 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
320static inline uint32_t
321dispatchDPReg (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
331enum 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
347static inline uint32_t
348dispatchBrExSys (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
356enum 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 */
375