xref: /netbsd-src/external/gpl3/gdb/dist/sim/aarch64/cpustate.h (revision a45db23f655e22f0c2354600d3b3c2cb98abf2dc)
1 /* cpustate.h -- Prototypes for AArch64 cpu state 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 _CPU_STATE_H
23 #define _CPU_STATE_H
24 
25 #include <sys/types.h>
26 #include <stdint.h>
27 #include <inttypes.h>
28 
29 #include "sim/sim.h"
30 
31 /* Symbolic names used to identify general registers which also match
32    the registers indices in machine code.
33 
34    We have 32 general registers which can be read/written as 32 bit or
35    64 bit sources/sinks and are appropriately referred to as Wn or Xn
36    in the assembly code.  Some instructions mix these access modes
37    (e.g. ADD X0, X1, W2) so the implementation of the instruction
38    needs to *know* which type of read or write access is required.  */
39 typedef enum GReg
40 {
41   R0,
42   R1,
43   R2,
44   R3,
45   R4,
46   R5,
47   R6,
48   R7,
49   R8,
50   R9,
51   R10,
52   R11,
53   R12,
54   R13,
55   R14,
56   R15,
57   R16,
58   R17,
59   R18,
60   R19,
61   R20,
62   R21,
63   R22,
64   R23,
65   R24,
66   R25,
67   R26,
68   R27,
69   R28,
70   R29,
71   R30,
72   R31,
73   FP = R29,
74   LR = R30,
75   SP = R31,
76   ZR = R31
77 } GReg;
78 
79 /* Symbolic names used to refer to floating point registers which also
80    match the registers indices in machine code.
81 
82    We have 32 FP registers which can be read/written as 8, 16, 32, 64
83    and 128 bit sources/sinks and are appropriately referred to as Bn,
84    Hn, Sn, Dn and Qn in the assembly code. Some instructions mix these
85    access modes (e.g. FCVT S0, D0) so the implementation of the
86    instruction needs to *know* which type of read or write access is
87    required.  */
88 
89 typedef enum VReg
90 {
91   V0,
92   V1,
93   V2,
94   V3,
95   V4,
96   V5,
97   V6,
98   V7,
99   V8,
100   V9,
101   V10,
102   V11,
103   V12,
104   V13,
105   V14,
106   V15,
107   V16,
108   V17,
109   V18,
110   V19,
111   V20,
112   V21,
113   V22,
114   V23,
115   V24,
116   V25,
117   V26,
118   V27,
119   V28,
120   V29,
121   V30,
122   V31,
123 } VReg;
124 
125 /* All the different integer bit patterns for the components of a
126    general register are overlaid here using a union so as to allow
127    all reading and writing of the desired bits.  Note that we have
128    to take care when emulating a big-endian AArch64 as we are
129    running on a little endian host.  */
130 
131 typedef union GRegisterValue
132 {
133 #if !WORDS_BIGENDIAN
134   int8_t   s8;
135   int16_t  s16;
136   int32_t  s32;
137   int64_t  s64;
138   uint8_t  u8;
139   uint16_t u16;
140   uint32_t u32;
141   uint64_t u64;
142 #else
143   struct { int64_t :56; int8_t s8; };
144   struct { int64_t :48; int16_t s16; };
145   struct { int64_t :32; int32_t s32; };
146   int64_t s64;
147   struct { uint64_t :56; uint8_t u8; };
148   struct { uint64_t :48; uint16_t u16; };
149   struct { uint64_t :32; uint32_t u32; };
150   uint64_t u64;
151 #endif
152 } GRegister;
153 
154 /* Float registers provide for storage of a single, double or quad
155    word format float in the same register.  Single floats are not
156    paired within each double register as per 32 bit arm.  Instead each
157    128 bit register Vn embeds the bits for Sn, and Dn in the lower
158    quarter and half, respectively, of the bits for Qn.
159 
160    The upper bits can also be accessed as single or double floats by
161    the float vector operations using indexing e.g. V1.D[1], V1.S[3]
162    etc and, for SIMD operations using a horrible index range notation.
163 
164    The spec also talks about accessing float registers as half words
165    and bytes with Hn and Bn providing access to the low 16 and 8 bits
166    of Vn but it is not really clear what these bits represent.  We can
167    probably ignore this for Java anyway.  However, we do need to access
168    the raw bits at 32 and 64 bit resolution to load to/from integer
169    registers.
170 
171    Note - we do not use the long double type.  Aliasing issues between
172    integer and float values mean that it is unreliable to use them.  */
173 
174 typedef union FRegisterValue
175 {
176   float        s;
177   double       d;
178 
179   uint64_t     v[2];
180   uint32_t     w[4];
181   uint16_t     h[8];
182   uint8_t      b[16];
183 
184   int64_t      V[2];
185   int32_t      W[4];
186   int16_t      H[8];
187   int8_t       B[16];
188 
189   float        S[4];
190   double       D[2];
191 
192 } FRegister;
193 
194 /* Condition register bit select values.
195 
196    The order of bits here is important because some of
197    the flag setting conditional instructions employ a
198    bit field to populate the flags when a false condition
199    bypasses execution of the operation and we want to
200    be able to assign the flags register using the
201    supplied value.  */
202 
203 typedef enum FlagIdx
204 {
205   V_IDX = 0,
206   C_IDX = 1,
207   Z_IDX = 2,
208   N_IDX = 3
209 } FlagIdx;
210 
211 typedef enum FlagMask
212 {
213   V = 1 << V_IDX,
214   C = 1 << C_IDX,
215   Z = 1 << Z_IDX,
216   N = 1 << N_IDX
217 } FlagMask;
218 
219 #define CPSR_ALL_FLAGS (V | C | Z | N)
220 
221 typedef uint32_t FlagsRegister;
222 
223 /* FPSR register -- floating point status register
224 
225    This register includes IDC, IXC, UFC, OFC, DZC, IOC and QC bits,
226    and the floating point N, Z, C, V bits but the latter are unused in
227    aarch64 mode.  The sim ignores QC for now.
228 
229    Bit positions are as per the ARMv7 FPSCR register
230 
231    IDC :  7 ==> Input Denormal (cumulative exception bit)
232    IXC :  4 ==> Inexact
233    UFC :  3 ==> Underflow
234    OFC :  2 ==> Overflow
235    DZC :  1 ==> Division by Zero
236    IOC :  0 ==> Invalid Operation
237 
238    The rounding mode is held in bits [23,22] defined as follows:
239 
240    0b00 Round to Nearest (RN) mode
241    0b01 Round towards Plus Infinity (RP) mode
242    0b10 Round towards Minus Infinity (RM) mode
243    0b11 Round towards Zero (RZ) mode.  */
244 
245 /* Indices for bits in the FPSR register value.  */
246 typedef enum FPSRIdx
247 {
248   IO_IDX = 0,
249   DZ_IDX = 1,
250   OF_IDX = 2,
251   UF_IDX = 3,
252   IX_IDX = 4,
253   ID_IDX = 7
254 } FPSRIdx;
255 
256 /* Corresponding bits as numeric values.  */
257 typedef enum FPSRMask
258 {
259   IO = (1 << IO_IDX),
260   DZ = (1 << DZ_IDX),
261   OF = (1 << OF_IDX),
262   UF = (1 << UF_IDX),
263   IX = (1 << IX_IDX),
264   ID = (1 << ID_IDX)
265 } FPSRMask;
266 
267 #define FPSR_ALL_FPSRS (IO | DZ | OF | UF | IX | ID)
268 
269 /* General Register access functions.  */
270 extern uint64_t    aarch64_get_reg_u64 (sim_cpu *, GReg, int);
271 extern int64_t     aarch64_get_reg_s64 (sim_cpu *, GReg, int);
272 extern uint32_t    aarch64_get_reg_u32 (sim_cpu *, GReg, int);
273 extern int32_t     aarch64_get_reg_s32 (sim_cpu *, GReg, int);
274 extern uint32_t    aarch64_get_reg_u16 (sim_cpu *, GReg, int);
275 extern int32_t     aarch64_get_reg_s16 (sim_cpu *, GReg, int);
276 extern uint32_t    aarch64_get_reg_u8  (sim_cpu *, GReg, int);
277 extern int32_t     aarch64_get_reg_s8  (sim_cpu *, GReg, int);
278 
279 extern void        aarch64_set_reg_u64 (sim_cpu *, GReg, int, uint64_t);
280 extern void        aarch64_set_reg_u32 (sim_cpu *, GReg, int, uint32_t);
281 extern void        aarch64_set_reg_s64 (sim_cpu *, GReg, int, int64_t);
282 extern void        aarch64_set_reg_s32 (sim_cpu *, GReg, int, int32_t);
283 
284 /* FP Register access functions.  */
285 extern float       aarch64_get_FP_half   (sim_cpu *, VReg);
286 extern float       aarch64_get_FP_float  (sim_cpu *, VReg);
287 extern double      aarch64_get_FP_double (sim_cpu *, VReg);
288 extern void        aarch64_get_FP_long_double (sim_cpu *, VReg, FRegister *);
289 
290 extern void        aarch64_set_FP_half   (sim_cpu *, VReg, float);
291 extern void        aarch64_set_FP_float  (sim_cpu *, VReg, float);
292 extern void        aarch64_set_FP_double (sim_cpu *, VReg, double);
293 extern void        aarch64_set_FP_long_double (sim_cpu *, VReg, FRegister);
294 
295 /* PC register accessors.  */
296 extern uint64_t    aarch64_get_PC (sim_cpu *);
297 extern uint64_t    aarch64_get_next_PC (sim_cpu *);
298 extern void        aarch64_set_next_PC (sim_cpu *, uint64_t);
299 extern void        aarch64_set_next_PC_by_offset (sim_cpu *, int64_t);
300 extern void        aarch64_update_PC (sim_cpu *);
301 extern void        aarch64_save_LR (sim_cpu *);
302 
303 /* Instruction accessor - implemented as a
304    macro as we do not need to annotate it.  */
305 #define aarch64_get_instr(cpu)  ((cpu)->instr)
306 
307 /* Flag register accessors.  */
308 extern uint32_t    aarch64_get_CPSR       (sim_cpu *);
309 extern void        aarch64_set_CPSR       (sim_cpu *, uint32_t);
310 extern uint32_t    aarch64_get_CPSR_bits  (sim_cpu *, FlagMask);
311 extern void        aarch64_set_CPSR_bits  (sim_cpu *, uint32_t, uint32_t);
312 extern uint32_t    aarch64_test_CPSR_bit  (sim_cpu *, FlagMask);
313 extern void        aarch64_set_CPSR_bit   (sim_cpu *, FlagMask);
314 extern void        aarch64_clear_CPSR_bit (sim_cpu *, FlagMask);
315 
316 extern void        aarch64_set_FPSR (sim_cpu *, uint32_t);
317 extern uint32_t    aarch64_get_FPSR (sim_cpu *);
318 extern void        aarch64_set_FPSR_bits (sim_cpu *, uint32_t, uint32_t);
319 extern uint32_t    aarch64_get_FPSR_bits (sim_cpu *, uint32_t);
320 extern int         aarch64_test_FPSR_bit (sim_cpu *, FPSRMask);
321 
322 /* Vector register accessors.  */
323 extern uint64_t    aarch64_get_vec_u64 (sim_cpu *, VReg, unsigned);
324 extern uint32_t    aarch64_get_vec_u32 (sim_cpu *, VReg, unsigned);
325 extern uint16_t    aarch64_get_vec_u16 (sim_cpu *, VReg, unsigned);
326 extern uint8_t     aarch64_get_vec_u8  (sim_cpu *, VReg, unsigned);
327 extern void        aarch64_set_vec_u64 (sim_cpu *, VReg, unsigned, uint64_t);
328 extern void        aarch64_set_vec_u32 (sim_cpu *, VReg, unsigned, uint32_t);
329 extern void        aarch64_set_vec_u16 (sim_cpu *, VReg, unsigned, uint16_t);
330 extern void        aarch64_set_vec_u8  (sim_cpu *, VReg, unsigned, uint8_t);
331 
332 extern int64_t     aarch64_get_vec_s64 (sim_cpu *, VReg, unsigned);
333 extern int32_t     aarch64_get_vec_s32 (sim_cpu *, VReg, unsigned);
334 extern int16_t     aarch64_get_vec_s16 (sim_cpu *, VReg, unsigned);
335 extern int8_t      aarch64_get_vec_s8  (sim_cpu *, VReg, unsigned);
336 extern void        aarch64_set_vec_s64 (sim_cpu *, VReg, unsigned, int64_t);
337 extern void        aarch64_set_vec_s32 (sim_cpu *, VReg, unsigned, int32_t);
338 extern void        aarch64_set_vec_s16 (sim_cpu *, VReg, unsigned, int16_t);
339 extern void        aarch64_set_vec_s8  (sim_cpu *, VReg, unsigned, int8_t);
340 
341 extern float       aarch64_get_vec_float  (sim_cpu *, VReg, unsigned);
342 extern double      aarch64_get_vec_double (sim_cpu *, VReg, unsigned);
343 extern void        aarch64_set_vec_float  (sim_cpu *, VReg, unsigned, float);
344 extern void        aarch64_set_vec_double (sim_cpu *, VReg, unsigned, double);
345 
346 /* System register accessors.  */
347 extern uint64_t	   aarch64_get_thread_id (sim_cpu *);
348 extern uint32_t	   aarch64_get_FPCR (sim_cpu *);
349 extern void	   aarch64_set_FPCR (sim_cpu *, uint32_t);
350 
351 #endif /* _CPU_STATE_H  */
352