]>
Commit | Line | Data |
---|---|---|
cf7c6d10 RH |
1 | /* |
2 | * QEMU ARM CP Register access and descriptions | |
3 | * | |
4 | * Copyright (c) 2022 Linaro Ltd | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or | |
7 | * modify it under the terms of the GNU General Public License | |
8 | * as published by the Free Software Foundation; either version 2 | |
9 | * of the License, or (at your option) any later version. | |
10 | * | |
11 | * This program is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | * GNU General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU General Public License | |
17 | * along with this program; if not, see | |
18 | * <http://www.gnu.org/licenses/gpl-2.0.html> | |
19 | */ | |
20 | ||
21 | #ifndef TARGET_ARM_CPREGS_H | |
22 | #define TARGET_ARM_CPREGS_H | |
23 | ||
24 | /* | |
87c3f0f2 | 25 | * ARMCPRegInfo type field bits: |
cf7c6d10 | 26 | */ |
87c3f0f2 RH |
27 | enum { |
28 | /* | |
29 | * Register must be handled specially during translation. | |
30 | * The method is one of the values below: | |
31 | */ | |
32 | ARM_CP_SPECIAL_MASK = 0x000f, | |
33 | /* Special: no change to PE state: writes ignored, reads ignored. */ | |
34 | ARM_CP_NOP = 0x0001, | |
35 | /* Special: sysreg is WFI, for v5 and v6. */ | |
36 | ARM_CP_WFI = 0x0002, | |
37 | /* Special: sysreg is NZCV. */ | |
38 | ARM_CP_NZCV = 0x0003, | |
39 | /* Special: sysreg is CURRENTEL. */ | |
40 | ARM_CP_CURRENTEL = 0x0004, | |
41 | /* Special: sysreg is DC ZVA or similar. */ | |
42 | ARM_CP_DC_ZVA = 0x0005, | |
43 | ARM_CP_DC_GVA = 0x0006, | |
44 | ARM_CP_DC_GZVA = 0x0007, | |
45 | ||
46 | /* Flag: reads produce resetvalue; writes ignored. */ | |
47 | ARM_CP_CONST = 1 << 4, | |
48 | /* Flag: For ARM_CP_STATE_AA32, sysreg is 64-bit. */ | |
49 | ARM_CP_64BIT = 1 << 5, | |
50 | /* | |
51 | * Flag: TB should not be ended after a write to this register | |
52 | * (the default is that the TB ends after cp writes). | |
53 | */ | |
54 | ARM_CP_SUPPRESS_TB_END = 1 << 6, | |
55 | /* | |
56 | * Flag: Permit a register definition to override a previous definition | |
57 | * for the same (cp, is64, crn, crm, opc1, opc2) tuple: either the new | |
58 | * or the old must have the ARM_CP_OVERRIDE bit set. | |
59 | */ | |
60 | ARM_CP_OVERRIDE = 1 << 7, | |
61 | /* | |
62 | * Flag: Register is an alias view of some underlying state which is also | |
63 | * visible via another register, and that the other register is handling | |
64 | * migration and reset; registers marked ARM_CP_ALIAS will not be migrated | |
65 | * but may have their state set by syncing of register state from KVM. | |
66 | */ | |
67 | ARM_CP_ALIAS = 1 << 8, | |
68 | /* | |
69 | * Flag: Register does I/O and therefore its accesses need to be marked | |
70 | * with gen_io_start() and also end the TB. In particular, registers which | |
71 | * implement clocks or timers require this. | |
72 | */ | |
73 | ARM_CP_IO = 1 << 9, | |
74 | /* | |
75 | * Flag: Register has no underlying state and does not support raw access | |
76 | * for state saving/loading; it will not be used for either migration or | |
77 | * KVM state synchronization. Typically this is for "registers" which are | |
78 | * actually used as instructions for cache maintenance and so on. | |
79 | */ | |
80 | ARM_CP_NO_RAW = 1 << 10, | |
81 | /* | |
82 | * Flag: The read or write hook might raise an exception; the generated | |
83 | * code will synchronize the CPU state before calling the hook so that it | |
84 | * is safe for the hook to call raise_exception(). | |
85 | */ | |
86 | ARM_CP_RAISES_EXC = 1 << 11, | |
87 | /* | |
88 | * Flag: Writes to the sysreg might change the exception level - typically | |
89 | * on older ARM chips. For those cases we need to re-read the new el when | |
90 | * recomputing the translation flags. | |
91 | */ | |
92 | ARM_CP_NEWEL = 1 << 12, | |
93 | /* | |
94 | * Flag: Access check for this sysreg is identical to accessing FPU state | |
95 | * from an instruction: use translation fp_access_check(). | |
96 | */ | |
97 | ARM_CP_FPU = 1 << 13, | |
98 | /* | |
99 | * Flag: Access check for this sysreg is identical to accessing SVE state | |
100 | * from an instruction: use translation sve_access_check(). | |
101 | */ | |
102 | ARM_CP_SVE = 1 << 14, | |
103 | /* Flag: Do not expose in gdb sysreg xml. */ | |
104 | ARM_CP_NO_GDB = 1 << 15, | |
696ba377 RH |
105 | /* |
106 | * Flags: If EL3 but not EL2... | |
107 | * - UNDEF: discard the cpreg, | |
108 | * - KEEP: retain the cpreg as is, | |
109 | * - C_NZ: set const on the cpreg, but retain resetvalue, | |
110 | * - else: set const on the cpreg, zero resetvalue, aka RES0. | |
111 | * See rule RJFFP in section D1.1.3 of DDI0487H.a. | |
112 | */ | |
113 | ARM_CP_EL3_NO_EL2_UNDEF = 1 << 16, | |
114 | ARM_CP_EL3_NO_EL2_KEEP = 1 << 17, | |
115 | ARM_CP_EL3_NO_EL2_C_NZ = 1 << 18, | |
87c3f0f2 | 116 | }; |
cf7c6d10 RH |
117 | |
118 | /* | |
119 | * Valid values for ARMCPRegInfo state field, indicating which of | |
120 | * the AArch32 and AArch64 execution states this register is visible in. | |
121 | * If the reginfo doesn't explicitly specify then it is AArch32 only. | |
122 | * If the reginfo is declared to be visible in both states then a second | |
123 | * reginfo is synthesised for the AArch32 view of the AArch64 register, | |
124 | * such that the AArch32 view is the lower 32 bits of the AArch64 one. | |
125 | * Note that we rely on the values of these enums as we iterate through | |
126 | * the various states in some places. | |
127 | */ | |
d95101d6 | 128 | typedef enum { |
cf7c6d10 RH |
129 | ARM_CP_STATE_AA32 = 0, |
130 | ARM_CP_STATE_AA64 = 1, | |
131 | ARM_CP_STATE_BOTH = 2, | |
d95101d6 | 132 | } CPState; |
cf7c6d10 RH |
133 | |
134 | /* | |
135 | * ARM CP register secure state flags. These flags identify security state | |
136 | * attributes for a given CP register entry. | |
137 | * The existence of both or neither secure and non-secure flags indicates that | |
138 | * the register has both a secure and non-secure hash entry. A single one of | |
139 | * these flags causes the register to only be hashed for the specified | |
140 | * security state. | |
141 | * Although definitions may have any combination of the S/NS bits, each | |
142 | * registered entry will only have one to identify whether the entry is secure | |
143 | * or non-secure. | |
144 | */ | |
cbe64585 RH |
145 | typedef enum { |
146 | ARM_CP_SECSTATE_BOTH = 0, /* define one cpreg for each secstate */ | |
cf7c6d10 RH |
147 | ARM_CP_SECSTATE_S = (1 << 0), /* bit[0]: Secure state register */ |
148 | ARM_CP_SECSTATE_NS = (1 << 1), /* bit[1]: Non-secure state register */ | |
cbe64585 | 149 | } CPSecureState; |
cf7c6d10 | 150 | |
cf7c6d10 RH |
151 | /* |
152 | * Access rights: | |
153 | * We define bits for Read and Write access for what rev C of the v7-AR ARM ARM | |
154 | * defines as PL0 (user), PL1 (fiq/irq/svc/abt/und/sys, ie privileged), and | |
155 | * PL2 (hyp). The other level which has Read and Write bits is Secure PL1 | |
156 | * (ie any of the privileged modes in Secure state, or Monitor mode). | |
157 | * If a register is accessible in one privilege level it's always accessible | |
158 | * in higher privilege levels too. Since "Secure PL1" also follows this rule | |
159 | * (ie anything visible in PL2 is visible in S-PL1, some things are only | |
160 | * visible in S-PL1) but "Secure PL1" is a bit of a mouthful, we bend the | |
161 | * terminology a little and call this PL3. | |
162 | * In AArch64 things are somewhat simpler as the PLx bits line up exactly | |
163 | * with the ELx exception levels. | |
164 | * | |
165 | * If access permissions for a register are more complex than can be | |
166 | * described with these bits, then use a laxer set of restrictions, and | |
167 | * do the more restrictive/complex check inside a helper function. | |
168 | */ | |
39107337 RH |
169 | typedef enum { |
170 | PL3_R = 0x80, | |
171 | PL3_W = 0x40, | |
172 | PL2_R = 0x20 | PL3_R, | |
173 | PL2_W = 0x10 | PL3_W, | |
174 | PL1_R = 0x08 | PL2_R, | |
175 | PL1_W = 0x04 | PL2_W, | |
176 | PL0_R = 0x02 | PL1_R, | |
177 | PL0_W = 0x01 | PL1_W, | |
cf7c6d10 | 178 | |
39107337 RH |
179 | /* |
180 | * For user-mode some registers are accessible to EL0 via a kernel | |
181 | * trap-and-emulate ABI. In this case we define the read permissions | |
182 | * as actually being PL0_R. However some bits of any given register | |
183 | * may still be masked. | |
184 | */ | |
cf7c6d10 | 185 | #ifdef CONFIG_USER_ONLY |
39107337 | 186 | PL0U_R = PL0_R, |
cf7c6d10 | 187 | #else |
39107337 | 188 | PL0U_R = PL1_R, |
cf7c6d10 RH |
189 | #endif |
190 | ||
39107337 RH |
191 | PL3_RW = PL3_R | PL3_W, |
192 | PL2_RW = PL2_R | PL2_W, | |
193 | PL1_RW = PL1_R | PL1_W, | |
194 | PL0_RW = PL0_R | PL0_W, | |
195 | } CPAccessRights; | |
cf7c6d10 RH |
196 | |
197 | typedef enum CPAccessResult { | |
198 | /* Access is permitted */ | |
199 | CP_ACCESS_OK = 0, | |
330477ea RH |
200 | |
201 | /* | |
202 | * Combined with one of the following, the low 2 bits indicate the | |
203 | * target exception level. If 0, the exception is taken to the usual | |
204 | * target EL (EL1 or PL1 if in EL0, otherwise to the current EL). | |
205 | */ | |
206 | CP_ACCESS_EL_MASK = 3, | |
207 | ||
cf7c6d10 RH |
208 | /* |
209 | * Access fails due to a configurable trap or enable which would | |
210 | * result in a categorized exception syndrome giving information about | |
211 | * the failing instruction (ie syndrome category 0x3, 0x4, 0x5, 0x6, | |
330477ea | 212 | * 0xc or 0x18). |
cf7c6d10 | 213 | */ |
330477ea RH |
214 | CP_ACCESS_TRAP = (1 << 2), |
215 | CP_ACCESS_TRAP_EL2 = CP_ACCESS_TRAP | 2, | |
216 | CP_ACCESS_TRAP_EL3 = CP_ACCESS_TRAP | 3, | |
217 | ||
cf7c6d10 RH |
218 | /* |
219 | * Access fails and results in an exception syndrome 0x0 ("uncategorized"). | |
220 | * Note that this is not a catch-all case -- the set of cases which may | |
221 | * result in this failure is specifically defined by the architecture. | |
222 | */ | |
330477ea RH |
223 | CP_ACCESS_TRAP_UNCATEGORIZED = (2 << 2), |
224 | CP_ACCESS_TRAP_UNCATEGORIZED_EL2 = CP_ACCESS_TRAP_UNCATEGORIZED | 2, | |
225 | CP_ACCESS_TRAP_UNCATEGORIZED_EL3 = CP_ACCESS_TRAP_UNCATEGORIZED | 3, | |
cf7c6d10 RH |
226 | } CPAccessResult; |
227 | ||
228 | typedef struct ARMCPRegInfo ARMCPRegInfo; | |
229 | ||
230 | /* | |
231 | * Access functions for coprocessor registers. These cannot fail and | |
232 | * may not raise exceptions. | |
233 | */ | |
234 | typedef uint64_t CPReadFn(CPUARMState *env, const ARMCPRegInfo *opaque); | |
235 | typedef void CPWriteFn(CPUARMState *env, const ARMCPRegInfo *opaque, | |
236 | uint64_t value); | |
237 | /* Access permission check functions for coprocessor registers. */ | |
238 | typedef CPAccessResult CPAccessFn(CPUARMState *env, | |
239 | const ARMCPRegInfo *opaque, | |
240 | bool isread); | |
241 | /* Hook function for register reset */ | |
242 | typedef void CPResetFn(CPUARMState *env, const ARMCPRegInfo *opaque); | |
243 | ||
244 | #define CP_ANY 0xff | |
245 | ||
246 | /* Definition of an ARM coprocessor register */ | |
247 | struct ARMCPRegInfo { | |
248 | /* Name of register (useful mainly for debugging, need not be unique) */ | |
249 | const char *name; | |
250 | /* | |
251 | * Location of register: coprocessor number and (crn,crm,opc1,opc2) | |
252 | * tuple. Any of crm, opc1 and opc2 may be CP_ANY to indicate a | |
253 | * 'wildcard' field -- any value of that field in the MRC/MCR insn | |
254 | * will be decoded to this register. The register read and write | |
255 | * callbacks will be passed an ARMCPRegInfo with the crn/crm/opc1/opc2 | |
256 | * used by the program, so it is possible to register a wildcard and | |
257 | * then behave differently on read/write if necessary. | |
258 | * For 64 bit registers, only crm and opc1 are relevant; crn and opc2 | |
259 | * must both be zero. | |
260 | * For AArch64-visible registers, opc0 is also used. | |
261 | * Since there are no "coprocessors" in AArch64, cp is purely used as a | |
262 | * way to distinguish (for KVM's benefit) guest-visible system registers | |
263 | * from demuxed ones provided to preserve the "no side effects on | |
264 | * KVM register read/write from QEMU" semantics. cp==0x13 is guest | |
265 | * visible (to match KVM's encoding); cp==0 will be converted to | |
266 | * cp==0x13 when the ARMCPRegInfo is registered, for convenience. | |
267 | */ | |
268 | uint8_t cp; | |
269 | uint8_t crn; | |
270 | uint8_t crm; | |
271 | uint8_t opc0; | |
272 | uint8_t opc1; | |
273 | uint8_t opc2; | |
274 | /* Execution state in which this register is visible: ARM_CP_STATE_* */ | |
d95101d6 | 275 | CPState state; |
cf7c6d10 RH |
276 | /* Register type: ARM_CP_* bits/values */ |
277 | int type; | |
278 | /* Access rights: PL*_[RW] */ | |
39107337 | 279 | CPAccessRights access; |
cf7c6d10 | 280 | /* Security state: ARM_CP_SECSTATE_* bits/values */ |
cbe64585 | 281 | CPSecureState secure; |
cf7c6d10 RH |
282 | /* |
283 | * The opaque pointer passed to define_arm_cp_regs_with_opaque() when | |
284 | * this register was defined: can be used to hand data through to the | |
285 | * register read/write functions, since they are passed the ARMCPRegInfo*. | |
286 | */ | |
287 | void *opaque; | |
288 | /* | |
289 | * Value of this register, if it is ARM_CP_CONST. Otherwise, if | |
290 | * fieldoffset is non-zero, the reset value of the register. | |
291 | */ | |
292 | uint64_t resetvalue; | |
293 | /* | |
294 | * Offset of the field in CPUARMState for this register. | |
295 | * This is not needed if either: | |
296 | * 1. type is ARM_CP_CONST or one of the ARM_CP_SPECIALs | |
297 | * 2. both readfn and writefn are specified | |
298 | */ | |
299 | ptrdiff_t fieldoffset; /* offsetof(CPUARMState, field) */ | |
300 | ||
301 | /* | |
302 | * Offsets of the secure and non-secure fields in CPUARMState for the | |
303 | * register if it is banked. These fields are only used during the static | |
304 | * registration of a register. During hashing the bank associated | |
305 | * with a given security state is copied to fieldoffset which is used from | |
306 | * there on out. | |
307 | * | |
308 | * It is expected that register definitions use either fieldoffset or | |
309 | * bank_fieldoffsets in the definition but not both. It is also expected | |
310 | * that both bank offsets are set when defining a banked register. This | |
311 | * use indicates that a register is banked. | |
312 | */ | |
313 | ptrdiff_t bank_fieldoffsets[2]; | |
314 | ||
315 | /* | |
316 | * Function for making any access checks for this register in addition to | |
317 | * those specified by the 'access' permissions bits. If NULL, no extra | |
318 | * checks required. The access check is performed at runtime, not at | |
319 | * translate time. | |
320 | */ | |
321 | CPAccessFn *accessfn; | |
322 | /* | |
323 | * Function for handling reads of this register. If NULL, then reads | |
324 | * will be done by loading from the offset into CPUARMState specified | |
325 | * by fieldoffset. | |
326 | */ | |
327 | CPReadFn *readfn; | |
328 | /* | |
329 | * Function for handling writes of this register. If NULL, then writes | |
330 | * will be done by writing to the offset into CPUARMState specified | |
331 | * by fieldoffset. | |
332 | */ | |
333 | CPWriteFn *writefn; | |
334 | /* | |
335 | * Function for doing a "raw" read; used when we need to copy | |
336 | * coprocessor state to the kernel for KVM or out for | |
337 | * migration. This only needs to be provided if there is also a | |
338 | * readfn and it has side effects (for instance clear-on-read bits). | |
339 | */ | |
340 | CPReadFn *raw_readfn; | |
341 | /* | |
342 | * Function for doing a "raw" write; used when we need to copy KVM | |
343 | * kernel coprocessor state into userspace, or for inbound | |
344 | * migration. This only needs to be provided if there is also a | |
345 | * writefn and it masks out "unwritable" bits or has write-one-to-clear | |
346 | * or similar behaviour. | |
347 | */ | |
348 | CPWriteFn *raw_writefn; | |
349 | /* | |
350 | * Function for resetting the register. If NULL, then reset will be done | |
351 | * by writing resetvalue to the field specified in fieldoffset. If | |
352 | * fieldoffset is 0 then no reset will be done. | |
353 | */ | |
354 | CPResetFn *resetfn; | |
355 | ||
356 | /* | |
357 | * "Original" writefn and readfn. | |
358 | * For ARMv8.1-VHE register aliases, we overwrite the read/write | |
359 | * accessor functions of various EL1/EL0 to perform the runtime | |
360 | * check for which sysreg should actually be modified, and then | |
361 | * forwards the operation. Before overwriting the accessors, | |
362 | * the original function is copied here, so that accesses that | |
363 | * really do go to the EL1/EL0 version proceed normally. | |
364 | * (The corresponding EL2 register is linked via opaque.) | |
365 | */ | |
366 | CPReadFn *orig_readfn; | |
367 | CPWriteFn *orig_writefn; | |
368 | }; | |
369 | ||
370 | /* | |
371 | * Macros which are lvalues for the field in CPUARMState for the | |
372 | * ARMCPRegInfo *ri. | |
373 | */ | |
374 | #define CPREG_FIELD32(env, ri) \ | |
375 | (*(uint32_t *)((char *)(env) + (ri)->fieldoffset)) | |
376 | #define CPREG_FIELD64(env, ri) \ | |
377 | (*(uint64_t *)((char *)(env) + (ri)->fieldoffset)) | |
378 | ||
5809ac57 RH |
379 | void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu, const ARMCPRegInfo *reg, |
380 | void *opaque); | |
cf7c6d10 | 381 | |
cf7c6d10 RH |
382 | static inline void define_one_arm_cp_reg(ARMCPU *cpu, const ARMCPRegInfo *regs) |
383 | { | |
5809ac57 | 384 | define_one_arm_cp_reg_with_opaque(cpu, regs, NULL); |
cf7c6d10 | 385 | } |
5809ac57 RH |
386 | |
387 | void define_arm_cp_regs_with_opaque_len(ARMCPU *cpu, const ARMCPRegInfo *regs, | |
388 | void *opaque, size_t len); | |
389 | ||
390 | #define define_arm_cp_regs_with_opaque(CPU, REGS, OPAQUE) \ | |
391 | do { \ | |
392 | QEMU_BUILD_BUG_ON(ARRAY_SIZE(REGS) == 0); \ | |
393 | define_arm_cp_regs_with_opaque_len(CPU, REGS, OPAQUE, \ | |
394 | ARRAY_SIZE(REGS)); \ | |
395 | } while (0) | |
396 | ||
397 | #define define_arm_cp_regs(CPU, REGS) \ | |
398 | define_arm_cp_regs_with_opaque(CPU, REGS, NULL) | |
399 | ||
cf7c6d10 RH |
400 | const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp); |
401 | ||
402 | /* | |
403 | * Definition of an ARM co-processor register as viewed from | |
404 | * userspace. This is used for presenting sanitised versions of | |
405 | * registers to userspace when emulating the Linux AArch64 CPU | |
406 | * ID/feature ABI (advertised as HWCAP_CPUID). | |
407 | */ | |
408 | typedef struct ARMCPRegUserSpaceInfo { | |
409 | /* Name of register */ | |
410 | const char *name; | |
411 | ||
412 | /* Is the name actually a glob pattern */ | |
413 | bool is_glob; | |
414 | ||
415 | /* Only some bits are exported to user space */ | |
416 | uint64_t exported_bits; | |
417 | ||
418 | /* Fixed bits are applied after the mask */ | |
419 | uint64_t fixed_bits; | |
420 | } ARMCPRegUserSpaceInfo; | |
421 | ||
5809ac57 RH |
422 | void modify_arm_cp_regs_with_len(ARMCPRegInfo *regs, size_t regs_len, |
423 | const ARMCPRegUserSpaceInfo *mods, | |
424 | size_t mods_len); | |
cf7c6d10 | 425 | |
5809ac57 RH |
426 | #define modify_arm_cp_regs(REGS, MODS) \ |
427 | do { \ | |
428 | QEMU_BUILD_BUG_ON(ARRAY_SIZE(REGS) == 0); \ | |
429 | QEMU_BUILD_BUG_ON(ARRAY_SIZE(MODS) == 0); \ | |
430 | modify_arm_cp_regs_with_len(REGS, ARRAY_SIZE(REGS), \ | |
431 | MODS, ARRAY_SIZE(MODS)); \ | |
432 | } while (0) | |
cf7c6d10 RH |
433 | |
434 | /* CPWriteFn that can be used to implement writes-ignored behaviour */ | |
435 | void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri, | |
436 | uint64_t value); | |
437 | /* CPReadFn that can be used for read-as-zero behaviour */ | |
438 | uint64_t arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri); | |
439 | ||
440 | /* | |
441 | * CPResetFn that does nothing, for use if no reset is required even | |
442 | * if fieldoffset is non zero. | |
443 | */ | |
444 | void arm_cp_reset_ignore(CPUARMState *env, const ARMCPRegInfo *opaque); | |
445 | ||
446 | /* | |
447 | * Return true if this reginfo struct's field in the cpu state struct | |
448 | * is 64 bits wide. | |
449 | */ | |
450 | static inline bool cpreg_field_is_64bit(const ARMCPRegInfo *ri) | |
451 | { | |
452 | return (ri->state == ARM_CP_STATE_AA64) || (ri->type & ARM_CP_64BIT); | |
453 | } | |
454 | ||
455 | static inline bool cp_access_ok(int current_el, | |
456 | const ARMCPRegInfo *ri, int isread) | |
457 | { | |
458 | return (ri->access >> ((current_el * 2) + isread)) & 1; | |
459 | } | |
460 | ||
461 | /* Raw read of a coprocessor register (as needed for migration, etc) */ | |
462 | uint64_t read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri); | |
463 | ||
464 | #endif /* TARGET_ARM_CPREGS_H */ |