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