Commit | Line | Data |
---|---|---|
2e8cf49e NC |
1 | /* cpustate.h -- Prototypes for AArch64 cpu state functions. |
2 | ||
618f726f | 3 | Copyright (C) 2015-2016 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 | ||
25 | #include <sys/types.h> | |
26 | #include <stdint.h> | |
27 | #include <inttypes.h> | |
28 | ||
29 | #include "gdb/remote-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 all | |
127 | reading and writing of the desired bits. | |
128 | ||
129 | N.B. the ARM spec says that when you write a 32 bit register you | |
130 | are supposed to write the low 32 bits and zero the high 32 | |
131 | bits. But we don't actually have to care about this because Java | |
132 | will only ever consume the 32 bits value as a 64 bit quantity after | |
133 | an explicit extend. */ | |
134 | typedef union GRegisterValue | |
135 | { | |
136 | int8_t s8; | |
137 | int16_t s16; | |
138 | int32_t s32; | |
139 | int64_t s64; | |
140 | uint8_t u8; | |
141 | uint16_t u16; | |
142 | uint32_t u32; | |
143 | uint64_t u64; | |
144 | } GRegister; | |
145 | ||
146 | /* Float registers provide for storage of a single, double or quad | |
147 | word format float in the same register. Single floats are not | |
148 | paired within each double register as per 32 bit arm. Instead each | |
149 | 128 bit register Vn embeds the bits for Sn, and Dn in the lower | |
150 | quarter and half, respectively, of the bits for Qn. | |
151 | ||
152 | The upper bits can also be accessed as single or double floats by | |
153 | the float vector operations using indexing e.g. V1.D[1], V1.S[3] | |
154 | etc and, for SIMD operations using a horrible index range notation. | |
155 | ||
156 | The spec also talks about accessing float registers as half words | |
157 | and bytes with Hn and Bn providing access to the low 16 and 8 bits | |
158 | of Vn but it is not really clear what these bits represent. We can | |
159 | probably ignore this for Java anyway. However, we do need to access | |
160 | the raw bits at 32 and 64 bit resolution to load to/from integer | |
161 | registers. | |
162 | ||
163 | Note - we do not use the long double type. Aliasing issues between | |
164 | integer and float values mean that it is unreliable to use them. */ | |
165 | ||
166 | typedef union FRegisterValue | |
167 | { | |
168 | float s; | |
169 | double d; | |
170 | ||
5ab6d79e NC |
171 | uint64_t v[2]; |
172 | uint32_t w[4]; | |
173 | uint16_t h[8]; | |
174 | uint8_t b[16]; | |
2e8cf49e NC |
175 | |
176 | int64_t V[2]; | |
177 | int32_t W[4]; | |
178 | int16_t H[8]; | |
179 | int8_t B[16]; | |
180 | ||
181 | float S[4]; | |
182 | double D[2]; | |
183 | ||
184 | } FRegister; | |
185 | ||
186 | /* Condition register bit select values. | |
187 | ||
188 | The order of bits here is important because some of | |
189 | the flag setting conditional instructions employ a | |
190 | bit field to populate the flags when a false condition | |
191 | bypasses execution of the operation and we want to | |
192 | be able to assign the flags register using the | |
193 | supplied value. */ | |
194 | ||
195 | typedef enum FlagIdx | |
196 | { | |
5ab6d79e NC |
197 | V_IDX = 0, |
198 | C_IDX = 1, | |
199 | Z_IDX = 2, | |
200 | N_IDX = 3 | |
2e8cf49e NC |
201 | } FlagIdx; |
202 | ||
203 | typedef enum FlagMask | |
204 | { | |
205 | V = 1 << V_IDX, | |
206 | C = 1 << C_IDX, | |
207 | Z = 1 << Z_IDX, | |
208 | N = 1 << N_IDX | |
209 | } FlagMask; | |
210 | ||
211 | #define CPSR_ALL_FLAGS (V | C | Z | N) | |
212 | ||
213 | typedef uint32_t FlagsRegister; | |
214 | ||
215 | /* FPSR register -- floating point status register | |
216 | ||
217 | This register includes IDC, IXC, UFC, OFC, DZC, IOC and QC bits, | |
218 | and the floating point N, Z, C, V bits but the latter are unused in | |
5ab6d79e | 219 | aarch64 mode. The sim ignores QC for now. |
2e8cf49e NC |
220 | |
221 | Bit positions are as per the ARMv7 FPSCR register | |
222 | ||
223 | IDC : 7 ==> Input Denormal (cumulative exception bit) | |
224 | IXC : 4 ==> Inexact | |
225 | UFC : 3 ==> Underflow | |
226 | OFC : 2 ==> Overflow | |
227 | DZC : 1 ==> Division by Zero | |
228 | IOC : 0 ==> Invalid Operation | |
229 | ||
230 | The rounding mode is held in bits [23,22] defined as follows: | |
231 | ||
232 | 0b00 Round to Nearest (RN) mode | |
233 | 0b01 Round towards Plus Infinity (RP) mode | |
234 | 0b10 Round towards Minus Infinity (RM) mode | |
235 | 0b11 Round towards Zero (RZ) mode. */ | |
236 | ||
237 | /* Indices for bits in the FPSR register value. */ | |
238 | typedef enum FPSRIdx | |
239 | { | |
240 | IO_IDX = 0, | |
241 | DZ_IDX = 1, | |
242 | OF_IDX = 2, | |
243 | UF_IDX = 3, | |
244 | IX_IDX = 4, | |
245 | ID_IDX = 7 | |
246 | } FPSRIdx; | |
247 | ||
248 | /* Corresponding bits as numeric values. */ | |
249 | typedef enum FPSRMask | |
250 | { | |
251 | IO = (1 << IO_IDX), | |
252 | DZ = (1 << DZ_IDX), | |
253 | OF = (1 << OF_IDX), | |
254 | UF = (1 << UF_IDX), | |
255 | IX = (1 << IX_IDX), | |
256 | ID = (1 << ID_IDX) | |
257 | } FPSRMask; | |
258 | ||
259 | #define FPSR_ALL_FPSRS (IO | DZ | OF | UF | IX | ID) | |
260 | ||
261 | /* General Register access functions. */ | |
262 | extern uint64_t aarch64_get_reg_u64 (sim_cpu *, GReg, int); | |
263 | extern int64_t aarch64_get_reg_s64 (sim_cpu *, GReg, int); | |
264 | extern uint32_t aarch64_get_reg_u32 (sim_cpu *, GReg, int); | |
265 | extern int32_t aarch64_get_reg_s32 (sim_cpu *, GReg, int); | |
266 | extern uint32_t aarch64_get_reg_u16 (sim_cpu *, GReg, int); | |
267 | extern int32_t aarch64_get_reg_s16 (sim_cpu *, GReg, int); | |
268 | extern uint32_t aarch64_get_reg_u8 (sim_cpu *, GReg, int); | |
269 | extern int32_t aarch64_get_reg_s8 (sim_cpu *, GReg, int); | |
270 | ||
271 | extern void aarch64_set_reg_u64 (sim_cpu *, GReg, int, uint64_t); | |
7517e550 | 272 | extern void aarch64_set_reg_u32 (sim_cpu *, GReg, int, uint32_t); |
2e8cf49e | 273 | extern void aarch64_set_reg_s64 (sim_cpu *, GReg, int, int64_t); |
7517e550 | 274 | extern void aarch64_set_reg_s32 (sim_cpu *, GReg, int, int32_t); |
2e8cf49e NC |
275 | |
276 | /* FP Register access functions. */ | |
5ab6d79e | 277 | extern float aarch64_get_FP_half (sim_cpu *, VReg); |
2e8cf49e NC |
278 | extern float aarch64_get_FP_float (sim_cpu *, VReg); |
279 | extern double aarch64_get_FP_double (sim_cpu *, VReg); | |
280 | extern void aarch64_get_FP_long_double (sim_cpu *, VReg, FRegister *); | |
5ab6d79e NC |
281 | |
282 | extern void aarch64_set_FP_half (sim_cpu *, VReg, float); | |
2e8cf49e NC |
283 | extern void aarch64_set_FP_float (sim_cpu *, VReg, float); |
284 | extern void aarch64_set_FP_double (sim_cpu *, VReg, double); | |
285 | extern void aarch64_set_FP_long_double (sim_cpu *, VReg, FRegister); | |
286 | ||
287 | /* PC register accessors. */ | |
288 | extern uint64_t aarch64_get_PC (sim_cpu *); | |
289 | extern uint64_t aarch64_get_next_PC (sim_cpu *); | |
290 | extern void aarch64_set_next_PC (sim_cpu *, uint64_t); | |
291 | extern void aarch64_set_next_PC_by_offset (sim_cpu *, int64_t); | |
292 | extern void aarch64_update_PC (sim_cpu *); | |
293 | extern void aarch64_save_LR (sim_cpu *); | |
294 | ||
295 | /* Instruction accessor - implemented as a | |
296 | macro as we do not need to annotate it. */ | |
297 | #define aarch64_get_instr(cpu) ((cpu)->instr) | |
298 | ||
299 | /* Flag register accessors. */ | |
300 | extern uint32_t aarch64_get_CPSR (sim_cpu *); | |
301 | extern void aarch64_set_CPSR (sim_cpu *, uint32_t); | |
302 | extern uint32_t aarch64_get_CPSR_bits (sim_cpu *, uint32_t); | |
303 | extern void aarch64_set_CPSR_bits (sim_cpu *, uint32_t, uint32_t); | |
304 | extern uint32_t aarch64_test_CPSR_bit (sim_cpu *, FlagMask); | |
305 | extern void aarch64_set_CPSR_bit (sim_cpu *, FlagMask); | |
306 | extern void aarch64_clear_CPSR_bit (sim_cpu *, FlagMask); | |
307 | ||
308 | extern void aarch64_set_FPSR (sim_cpu *, uint32_t); | |
309 | extern uint32_t aarch64_get_FPSR (sim_cpu *); | |
310 | extern void aarch64_set_FPSR_bits (sim_cpu *, uint32_t, uint32_t); | |
311 | extern uint32_t aarch64_get_FPSR_bits (sim_cpu *, uint32_t); | |
312 | extern int aarch64_test_FPSR_bit (sim_cpu *, FPSRMask); | |
313 | ||
314 | /* Vector register accessors. */ | |
315 | extern uint64_t aarch64_get_vec_u64 (sim_cpu *, VReg, unsigned); | |
316 | extern uint32_t aarch64_get_vec_u32 (sim_cpu *, VReg, unsigned); | |
317 | extern uint16_t aarch64_get_vec_u16 (sim_cpu *, VReg, unsigned); | |
318 | extern uint8_t aarch64_get_vec_u8 (sim_cpu *, VReg, unsigned); | |
319 | extern void aarch64_set_vec_u64 (sim_cpu *, VReg, unsigned, uint64_t); | |
320 | extern void aarch64_set_vec_u32 (sim_cpu *, VReg, unsigned, uint32_t); | |
321 | extern void aarch64_set_vec_u16 (sim_cpu *, VReg, unsigned, uint16_t); | |
322 | extern void aarch64_set_vec_u8 (sim_cpu *, VReg, unsigned, uint8_t); | |
323 | ||
324 | extern int64_t aarch64_get_vec_s64 (sim_cpu *, VReg, unsigned); | |
325 | extern int32_t aarch64_get_vec_s32 (sim_cpu *, VReg, unsigned); | |
326 | extern int16_t aarch64_get_vec_s16 (sim_cpu *, VReg, unsigned); | |
327 | extern int8_t aarch64_get_vec_s8 (sim_cpu *, VReg, unsigned); | |
328 | extern void aarch64_set_vec_s64 (sim_cpu *, VReg, unsigned, int64_t); | |
329 | extern void aarch64_set_vec_s32 (sim_cpu *, VReg, unsigned, int32_t); | |
330 | extern void aarch64_set_vec_s16 (sim_cpu *, VReg, unsigned, int16_t); | |
331 | extern void aarch64_set_vec_s8 (sim_cpu *, VReg, unsigned, int8_t); | |
332 | ||
333 | extern float aarch64_get_vec_float (sim_cpu *, VReg, unsigned); | |
334 | extern double aarch64_get_vec_double (sim_cpu *, VReg, unsigned); | |
335 | extern void aarch64_set_vec_float (sim_cpu *, VReg, unsigned, float); | |
336 | extern void aarch64_set_vec_double (sim_cpu *, VReg, unsigned, double); | |
337 | ||
5ab6d79e NC |
338 | /* System register accessors. */ |
339 | extern uint64_t aarch64_get_thread_id (sim_cpu *); | |
340 | extern uint32_t aarch64_get_FPCR (sim_cpu *); | |
341 | extern void aarch64_set_FPCR (sim_cpu *, uint32_t); | |
342 | ||
2e8cf49e | 343 | #endif /* _CPU_STATE_H */ |