Commit | Line | Data |
---|---|---|
2e8cf49e NC |
1 | /* cpustate.h -- Prototypes for AArch64 cpu state functions. |
2 | ||
b811d2c2 | 3 | Copyright (C) 2015-2020 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 _CPU_STATE_H | |
23 | #define _CPU_STATE_H | |
24 | ||
c7be4414 | 25 | #include "config.h" |
2e8cf49e NC |
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 | |
c7be4414 JW |
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 | ||
2e8cf49e NC |
132 | typedef union GRegisterValue |
133 | { | |
c7be4414 | 134 | #if !WORDS_BIGENDIAN |
2e8cf49e NC |
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; | |
c7be4414 JW |
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 | |
2e8cf49e NC |
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 | ||
5ab6d79e NC |
180 | uint64_t v[2]; |
181 | uint32_t w[4]; | |
182 | uint16_t h[8]; | |
183 | uint8_t b[16]; | |
2e8cf49e NC |
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 | { | |
5ab6d79e NC |
206 | V_IDX = 0, |
207 | C_IDX = 1, | |
208 | Z_IDX = 2, | |
209 | N_IDX = 3 | |
2e8cf49e NC |
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 | |
5ab6d79e | 228 | aarch64 mode. The sim ignores QC for now. |
2e8cf49e NC |
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); | |
7517e550 | 281 | extern void aarch64_set_reg_u32 (sim_cpu *, GReg, int, uint32_t); |
2e8cf49e | 282 | extern void aarch64_set_reg_s64 (sim_cpu *, GReg, int, int64_t); |
7517e550 | 283 | extern void aarch64_set_reg_s32 (sim_cpu *, GReg, int, int32_t); |
2e8cf49e NC |
284 | |
285 | /* FP Register access functions. */ | |
5ab6d79e | 286 | extern float aarch64_get_FP_half (sim_cpu *, VReg); |
2e8cf49e NC |
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 *); | |
5ab6d79e NC |
290 | |
291 | extern void aarch64_set_FP_half (sim_cpu *, VReg, float); | |
2e8cf49e NC |
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 | ||
5ab6d79e NC |
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 | ||
2e8cf49e | 352 | #endif /* _CPU_STATE_H */ |