]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/aarch64/cpustate.c
sim: switch config.h usage to defs.h
[thirdparty/binutils-gdb.git] / sim / aarch64 / cpustate.c
CommitLineData
2e8cf49e
NC
1/* cpustate.h -- Prototypes for AArch64 simulator functions.
2
3666a048 3 Copyright (C) 2015-2021 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
6df01ab8
MF
22/* This must come before any other includes. */
23#include "defs.h"
24
2e8cf49e 25#include <stdio.h>
c0386d4d 26#include <math.h>
2e8cf49e
NC
27
28#include "sim-main.h"
29#include "cpustate.h"
30#include "simulator.h"
cd5b6074 31#include "libiberty.h"
2e8cf49e
NC
32
33/* Some operands are allowed to access the stack pointer (reg 31).
34 For others a read from r31 always returns 0, and a write to r31 is ignored. */
35#define reg_num(reg) (((reg) == R31 && !r31_is_sp) ? 32 : (reg))
36
37void
38aarch64_set_reg_u64 (sim_cpu *cpu, GReg reg, int r31_is_sp, uint64_t val)
39{
40 if (reg == R31 && ! r31_is_sp)
41 {
e101a78b 42 TRACE_REGISTER (cpu, "GR[31] NOT CHANGED!");
2e8cf49e
NC
43 return;
44 }
45
46 if (val != cpu->gr[reg].u64)
47 TRACE_REGISTER (cpu,
e101a78b 48 "GR[%2d] changes from %16" PRIx64 " to %16" PRIx64,
2e8cf49e
NC
49 reg, cpu->gr[reg].u64, val);
50
51 cpu->gr[reg].u64 = val;
52}
53
54void
55aarch64_set_reg_s64 (sim_cpu *cpu, GReg reg, int r31_is_sp, int64_t val)
56{
57 if (reg == R31 && ! r31_is_sp)
58 {
e101a78b 59 TRACE_REGISTER (cpu, "GR[31] NOT CHANGED!");
2e8cf49e
NC
60 return;
61 }
62
63 if (val != cpu->gr[reg].s64)
64 TRACE_REGISTER (cpu,
e101a78b 65 "GR[%2d] changes from %16" PRIx64 " to %16" PRIx64,
2e8cf49e
NC
66 reg, cpu->gr[reg].s64, val);
67
68 cpu->gr[reg].s64 = val;
69}
70
71uint64_t
72aarch64_get_reg_u64 (sim_cpu *cpu, GReg reg, int r31_is_sp)
73{
74 return cpu->gr[reg_num(reg)].u64;
75}
76
77int64_t
78aarch64_get_reg_s64 (sim_cpu *cpu, GReg reg, int r31_is_sp)
79{
80 return cpu->gr[reg_num(reg)].s64;
81}
82
83uint32_t
84aarch64_get_reg_u32 (sim_cpu *cpu, GReg reg, int r31_is_sp)
85{
86 return cpu->gr[reg_num(reg)].u32;
87}
88
89int32_t
90aarch64_get_reg_s32 (sim_cpu *cpu, GReg reg, int r31_is_sp)
91{
92 return cpu->gr[reg_num(reg)].s32;
93}
94
7517e550
NC
95void
96aarch64_set_reg_s32 (sim_cpu *cpu, GReg reg, int r31_is_sp, int32_t val)
97{
98 if (reg == R31 && ! r31_is_sp)
99 {
100 TRACE_REGISTER (cpu, "GR[31] NOT CHANGED!");
101 return;
102 }
103
104 if (val != cpu->gr[reg].s32)
105 TRACE_REGISTER (cpu, "GR[%2d] changes from %8x to %8x",
106 reg, cpu->gr[reg].s32, val);
107
108 /* The ARM ARM states that (C1.2.4):
109 When the data size is 32 bits, the lower 32 bits of the
110 register are used and the upper 32 bits are ignored on
111 a read and cleared to zero on a write.
112 We simulate this by first clearing the whole 64-bits and
113 then writing to the 32-bit value in the GRegister union. */
114 cpu->gr[reg].s64 = 0;
115 cpu->gr[reg].s32 = val;
116}
117
118void
119aarch64_set_reg_u32 (sim_cpu *cpu, GReg reg, int r31_is_sp, uint32_t val)
120{
121 if (reg == R31 && ! r31_is_sp)
122 {
123 TRACE_REGISTER (cpu, "GR[31] NOT CHANGED!");
124 return;
125 }
126
127 if (val != cpu->gr[reg].u32)
128 TRACE_REGISTER (cpu, "GR[%2d] changes from %8x to %8x",
129 reg, cpu->gr[reg].u32, val);
130
131 cpu->gr[reg].u64 = 0;
132 cpu->gr[reg].u32 = val;
133}
134
2e8cf49e
NC
135uint32_t
136aarch64_get_reg_u16 (sim_cpu *cpu, GReg reg, int r31_is_sp)
137{
138 return cpu->gr[reg_num(reg)].u16;
139}
140
141int32_t
142aarch64_get_reg_s16 (sim_cpu *cpu, GReg reg, int r31_is_sp)
143{
144 return cpu->gr[reg_num(reg)].s16;
145}
146
147uint32_t
148aarch64_get_reg_u8 (sim_cpu *cpu, GReg reg, int r31_is_sp)
149{
150 return cpu->gr[reg_num(reg)].u8;
151}
152
153int32_t
154aarch64_get_reg_s8 (sim_cpu *cpu, GReg reg, int r31_is_sp)
155{
156 return cpu->gr[reg_num(reg)].s8;
157}
158
159uint64_t
160aarch64_get_PC (sim_cpu *cpu)
161{
162 return cpu->pc;
163}
164
165uint64_t
166aarch64_get_next_PC (sim_cpu *cpu)
167{
168 return cpu->nextpc;
169}
170
171void
172aarch64_set_next_PC (sim_cpu *cpu, uint64_t next)
173{
174 if (next != cpu->nextpc + 4)
175 TRACE_REGISTER (cpu,
e101a78b 176 "NextPC changes from %16" PRIx64 " to %16" PRIx64,
2e8cf49e
NC
177 cpu->nextpc, next);
178
179 cpu->nextpc = next;
180}
181
182void
183aarch64_set_next_PC_by_offset (sim_cpu *cpu, int64_t offset)
184{
185 if (cpu->pc + offset != cpu->nextpc + 4)
186 TRACE_REGISTER (cpu,
e101a78b 187 "NextPC changes from %16" PRIx64 " to %16" PRIx64,
2e8cf49e
NC
188 cpu->nextpc, cpu->pc + offset);
189
190 cpu->nextpc = cpu->pc + offset;
191}
192
193/* Install nextpc as current pc. */
194void
195aarch64_update_PC (sim_cpu *cpu)
196{
197 cpu->pc = cpu->nextpc;
198 /* Rezero the register we hand out when asked for ZR just in case it
199 was used as the destination for a write by the previous
200 instruction. */
201 cpu->gr[32].u64 = 0UL;
202}
203
204/* This instruction can be used to save the next PC to LR
205 just before installing a branch PC. */
206void
207aarch64_save_LR (sim_cpu *cpu)
208{
209 if (cpu->gr[LR].u64 != cpu->nextpc)
210 TRACE_REGISTER (cpu,
e101a78b 211 "LR changes from %16" PRIx64 " to %16" PRIx64,
2e8cf49e
NC
212 cpu->gr[LR].u64, cpu->nextpc);
213
214 cpu->gr[LR].u64 = cpu->nextpc;
215}
216
217static const char *
218decode_cpsr (FlagMask flags)
219{
220 switch (flags & CPSR_ALL_FLAGS)
221 {
222 default:
223 case 0: return "----";
224 case 1: return "---V";
225 case 2: return "--C-";
226 case 3: return "--CV";
227 case 4: return "-Z--";
228 case 5: return "-Z-V";
229 case 6: return "-ZC-";
230 case 7: return "-ZCV";
231 case 8: return "N---";
232 case 9: return "N--V";
233 case 10: return "N-C-";
234 case 11: return "N-CV";
235 case 12: return "NZ--";
236 case 13: return "NZ-V";
237 case 14: return "NZC-";
238 case 15: return "NZCV";
239 }
240}
241
242/* Retrieve the CPSR register as an int. */
243uint32_t
244aarch64_get_CPSR (sim_cpu *cpu)
245{
246 return cpu->CPSR;
247}
248
249/* Set the CPSR register as an int. */
250void
251aarch64_set_CPSR (sim_cpu *cpu, uint32_t new_flags)
252{
253 if (TRACE_REGISTER_P (cpu))
254 {
255 if (cpu->CPSR != new_flags)
256 TRACE_REGISTER (cpu,
e101a78b 257 "CPSR changes from %s to %s",
2e8cf49e
NC
258 decode_cpsr (cpu->CPSR), decode_cpsr (new_flags));
259 else
260 TRACE_REGISTER (cpu,
e101a78b 261 "CPSR stays at %s", decode_cpsr (cpu->CPSR));
2e8cf49e
NC
262 }
263
264 cpu->CPSR = new_flags & CPSR_ALL_FLAGS;
265}
266
267/* Read a specific subset of the CPSR as a bit pattern. */
268uint32_t
269aarch64_get_CPSR_bits (sim_cpu *cpu, FlagMask mask)
270{
271 return cpu->CPSR & mask;
272}
273
274/* Assign a specific subset of the CPSR as a bit pattern. */
275void
276aarch64_set_CPSR_bits (sim_cpu *cpu, uint32_t mask, uint32_t value)
277{
278 uint32_t old_flags = cpu->CPSR;
279
280 mask &= CPSR_ALL_FLAGS;
281 cpu->CPSR &= ~ mask;
282 cpu->CPSR |= (value & mask);
283
284 if (old_flags != cpu->CPSR)
285 TRACE_REGISTER (cpu,
e101a78b 286 "CPSR changes from %s to %s",
2e8cf49e
NC
287 decode_cpsr (old_flags), decode_cpsr (cpu->CPSR));
288}
289
290/* Test the value of a single CPSR returned as non-zero or zero. */
291uint32_t
292aarch64_test_CPSR_bit (sim_cpu *cpu, FlagMask bit)
293{
294 return cpu->CPSR & bit;
295}
296
297/* Set a single flag in the CPSR. */
298void
299aarch64_set_CPSR_bit (sim_cpu *cpu, FlagMask bit)
300{
301 uint32_t old_flags = cpu->CPSR;
302
303 cpu->CPSR |= (bit & CPSR_ALL_FLAGS);
304
305 if (old_flags != cpu->CPSR)
306 TRACE_REGISTER (cpu,
e101a78b 307 "CPSR changes from %s to %s",
2e8cf49e
NC
308 decode_cpsr (old_flags), decode_cpsr (cpu->CPSR));
309}
310
311/* Clear a single flag in the CPSR. */
312void
313aarch64_clear_CPSR_bit (sim_cpu *cpu, FlagMask bit)
314{
315 uint32_t old_flags = cpu->CPSR;
316
317 cpu->CPSR &= ~(bit & CPSR_ALL_FLAGS);
318
319 if (old_flags != cpu->CPSR)
320 TRACE_REGISTER (cpu,
e101a78b 321 "CPSR changes from %s to %s",
2e8cf49e
NC
322 decode_cpsr (old_flags), decode_cpsr (cpu->CPSR));
323}
324
5ab6d79e
NC
325float
326aarch64_get_FP_half (sim_cpu *cpu, VReg reg)
327{
328 union
329 {
330 uint16_t h[2];
331 float f;
332 } u;
333
7517e550
NC
334 u.h[0] = 0;
335 u.h[1] = cpu->fr[reg].h[0];
5ab6d79e
NC
336 return u.f;
337}
338
339
2e8cf49e
NC
340float
341aarch64_get_FP_float (sim_cpu *cpu, VReg reg)
342{
343 return cpu->fr[reg].s;
344}
345
346double
347aarch64_get_FP_double (sim_cpu *cpu, VReg reg)
348{
349 return cpu->fr[reg].d;
350}
351
352void
353aarch64_get_FP_long_double (sim_cpu *cpu, VReg reg, FRegister *a)
354{
355 a->v[0] = cpu->fr[reg].v[0];
356 a->v[1] = cpu->fr[reg].v[1];
357}
358
5ab6d79e
NC
359void
360aarch64_set_FP_half (sim_cpu *cpu, VReg reg, float val)
361{
362 union
363 {
364 uint16_t h[2];
365 float f;
366 } u;
367
368 u.f = val;
7517e550 369 cpu->fr[reg].h[0] = u.h[1];
5ab6d79e
NC
370 cpu->fr[reg].h[1] = 0;
371}
372
373
2e8cf49e
NC
374void
375aarch64_set_FP_float (sim_cpu *cpu, VReg reg, float val)
376{
c0386d4d
JW
377 if (val != cpu->fr[reg].s
378 /* Handle +/- zero. */
379 || signbit (val) != signbit (cpu->fr[reg].s))
e101a78b
NC
380 {
381 FRegister v;
382
383 v.s = val;
384 TRACE_REGISTER (cpu,
f1ca3215 385 "FR[%d].s changes from %f to %f [hex: %0" PRIx64 "]",
e101a78b
NC
386 reg, cpu->fr[reg].s, val, v.v[0]);
387 }
2e8cf49e
NC
388
389 cpu->fr[reg].s = val;
390}
391
392void
393aarch64_set_FP_double (sim_cpu *cpu, VReg reg, double val)
394{
c0386d4d
JW
395 if (val != cpu->fr[reg].d
396 /* Handle +/- zero. */
397 || signbit (val) != signbit (cpu->fr[reg].d))
e101a78b
NC
398 {
399 FRegister v;
2e8cf49e 400
e101a78b
NC
401 v.d = val;
402 TRACE_REGISTER (cpu,
f1ca3215 403 "FR[%d].d changes from %f to %f [hex: %0" PRIx64 "]",
e101a78b
NC
404 reg, cpu->fr[reg].d, val, v.v[0]);
405 }
2e8cf49e
NC
406 cpu->fr[reg].d = val;
407}
408
409void
410aarch64_set_FP_long_double (sim_cpu *cpu, VReg reg, FRegister a)
411{
412 if (cpu->fr[reg].v[0] != a.v[0]
413 || cpu->fr[reg].v[1] != a.v[1])
414 TRACE_REGISTER (cpu,
f1ca3215
MF
415 "FR[%d].q changes from [%0" PRIx64 " %0" PRIx64 "] to [%0"
416 PRIx64 " %0" PRIx64 "] ",
2e8cf49e
NC
417 reg,
418 cpu->fr[reg].v[0], cpu->fr[reg].v[1],
419 a.v[0], a.v[1]);
420
421 cpu->fr[reg].v[0] = a.v[0];
422 cpu->fr[reg].v[1] = a.v[1];
423}
424
e101a78b
NC
425#define GET_VEC_ELEMENT(REG, ELEMENT, FIELD) \
426 do \
427 { \
87bba7a5 428 if (ELEMENT >= ARRAY_SIZE (cpu->fr[0].FIELD)) \
e101a78b
NC
429 { \
430 TRACE_REGISTER (cpu, \
431 "Internal SIM error: invalid element number: %d ",\
432 ELEMENT); \
433 sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu), \
434 sim_stopped, SIM_SIGBUS); \
435 } \
436 return cpu->fr[REG].FIELD [ELEMENT]; \
437 } \
438 while (0)
439
2e8cf49e
NC
440uint64_t
441aarch64_get_vec_u64 (sim_cpu *cpu, VReg reg, unsigned element)
442{
e101a78b 443 GET_VEC_ELEMENT (reg, element, v);
2e8cf49e
NC
444}
445
446uint32_t
e101a78b 447aarch64_get_vec_u32 (sim_cpu *cpu, VReg reg, unsigned element)
2e8cf49e 448{
e101a78b 449 GET_VEC_ELEMENT (reg, element, w);
2e8cf49e
NC
450}
451
452uint16_t
e101a78b 453aarch64_get_vec_u16 (sim_cpu *cpu, VReg reg, unsigned element)
2e8cf49e 454{
e101a78b 455 GET_VEC_ELEMENT (reg, element, h);
2e8cf49e
NC
456}
457
458uint8_t
e101a78b 459aarch64_get_vec_u8 (sim_cpu *cpu, VReg reg, unsigned element)
2e8cf49e 460{
e101a78b 461 GET_VEC_ELEMENT (reg, element, b);
2e8cf49e
NC
462}
463
e101a78b
NC
464int64_t
465aarch64_get_vec_s64 (sim_cpu *cpu, VReg reg, unsigned element)
2e8cf49e 466{
e101a78b 467 GET_VEC_ELEMENT (reg, element, V);
2e8cf49e
NC
468}
469
e101a78b
NC
470int32_t
471aarch64_get_vec_s32 (sim_cpu *cpu, VReg reg, unsigned element)
2e8cf49e 472{
e101a78b 473 GET_VEC_ELEMENT (reg, element, W);
2e8cf49e
NC
474}
475
e101a78b
NC
476int16_t
477aarch64_get_vec_s16 (sim_cpu *cpu, VReg reg, unsigned element)
2e8cf49e 478{
e101a78b 479 GET_VEC_ELEMENT (reg, element, H);
2e8cf49e
NC
480}
481
e101a78b
NC
482int8_t
483aarch64_get_vec_s8 (sim_cpu *cpu, VReg reg, unsigned element)
2e8cf49e 484{
e101a78b 485 GET_VEC_ELEMENT (reg, element, B);
2e8cf49e
NC
486}
487
e101a78b
NC
488float
489aarch64_get_vec_float (sim_cpu *cpu, VReg reg, unsigned element)
2e8cf49e 490{
e101a78b 491 GET_VEC_ELEMENT (reg, element, S);
2e8cf49e
NC
492}
493
e101a78b
NC
494double
495aarch64_get_vec_double (sim_cpu *cpu, VReg reg, unsigned element)
496{
497 GET_VEC_ELEMENT (reg, element, D);
498}
499
500
7517e550
NC
501#define SET_VEC_ELEMENT(REG, ELEMENT, VAL, FIELD, PRINTER) \
502 do \
503 { \
4c0ca98e 504 if (ELEMENT >= ARRAY_SIZE (cpu->fr[0].FIELD)) \
e101a78b 505 { \
7517e550 506 TRACE_REGISTER (cpu, \
e101a78b
NC
507 "Internal SIM error: invalid element number: %d ",\
508 ELEMENT); \
509 sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu), \
510 sim_stopped, SIM_SIGBUS); \
511 } \
512 if (VAL != cpu->fr[REG].FIELD [ELEMENT]) \
513 TRACE_REGISTER (cpu, \
514 "VR[%2d]." #FIELD " [%d] changes from " PRINTER \
515 " to " PRINTER , REG, \
516 ELEMENT, cpu->fr[REG].FIELD [ELEMENT], VAL); \
7517e550
NC
517 \
518 cpu->fr[REG].FIELD [ELEMENT] = VAL; \
519 } \
e101a78b 520 while (0)
2e8cf49e
NC
521
522void
ef0d8ffc 523aarch64_set_vec_u64 (sim_cpu *cpu, VReg reg, unsigned element, uint64_t val)
2e8cf49e 524{
f1ca3215 525 SET_VEC_ELEMENT (reg, element, val, v, "%16" PRIx64);
2e8cf49e
NC
526}
527
e101a78b 528void
ef0d8ffc 529aarch64_set_vec_u32 (sim_cpu *cpu, VReg reg, unsigned element, uint32_t val)
2e8cf49e 530{
e101a78b 531 SET_VEC_ELEMENT (reg, element, val, w, "%8x");
2e8cf49e
NC
532}
533
e101a78b 534void
ef0d8ffc 535aarch64_set_vec_u16 (sim_cpu *cpu, VReg reg, unsigned element, uint16_t val)
2e8cf49e 536{
e101a78b 537 SET_VEC_ELEMENT (reg, element, val, h, "%4x");
2e8cf49e
NC
538}
539
e101a78b 540void
ef0d8ffc 541aarch64_set_vec_u8 (sim_cpu *cpu, VReg reg, unsigned element, uint8_t val)
2e8cf49e 542{
e101a78b 543 SET_VEC_ELEMENT (reg, element, val, b, "%x");
2e8cf49e
NC
544}
545
546void
e101a78b 547aarch64_set_vec_s64 (sim_cpu *cpu, VReg reg, unsigned element, int64_t val)
2e8cf49e 548{
f1ca3215 549 SET_VEC_ELEMENT (reg, element, val, V, "%16" PRIx64);
2e8cf49e
NC
550}
551
552void
e101a78b 553aarch64_set_vec_s32 (sim_cpu *cpu, VReg reg, unsigned element, int32_t val)
2e8cf49e 554{
e101a78b 555 SET_VEC_ELEMENT (reg, element, val, W, "%8x");
2e8cf49e
NC
556}
557
e101a78b
NC
558void
559aarch64_set_vec_s16 (sim_cpu *cpu, VReg reg, unsigned element, int16_t val)
2e8cf49e 560{
e101a78b 561 SET_VEC_ELEMENT (reg, element, val, H, "%4x");
2e8cf49e
NC
562}
563
e101a78b
NC
564void
565aarch64_set_vec_s8 (sim_cpu *cpu, VReg reg, unsigned element, int8_t val)
2e8cf49e 566{
e101a78b 567 SET_VEC_ELEMENT (reg, element, val, B, "%x");
2e8cf49e
NC
568}
569
e101a78b
NC
570void
571aarch64_set_vec_float (sim_cpu *cpu, VReg reg, unsigned element, float val)
2e8cf49e 572{
e101a78b 573 SET_VEC_ELEMENT (reg, element, val, S, "%f");
2e8cf49e
NC
574}
575
e101a78b
NC
576void
577aarch64_set_vec_double (sim_cpu *cpu, VReg reg, unsigned element, double val)
2e8cf49e 578{
e101a78b 579 SET_VEC_ELEMENT (reg, element, val, D, "%f");
2e8cf49e
NC
580}
581
582void
e101a78b 583aarch64_set_FPSR (sim_cpu *cpu, uint32_t value)
2e8cf49e 584{
e101a78b 585 if (cpu->FPSR != value)
2e8cf49e 586 TRACE_REGISTER (cpu,
e101a78b 587 "FPSR changes from %x to %x", cpu->FPSR, value);
2e8cf49e 588
e101a78b 589 cpu->FPSR = value & FPSR_ALL_FPSRS;
2e8cf49e
NC
590}
591
e101a78b
NC
592uint32_t
593aarch64_get_FPSR (sim_cpu *cpu)
2e8cf49e 594{
e101a78b 595 return cpu->FPSR;
2e8cf49e
NC
596}
597
598void
e101a78b 599aarch64_set_FPSR_bits (sim_cpu *cpu, uint32_t mask, uint32_t value)
2e8cf49e 600{
e101a78b
NC
601 uint32_t old_FPSR = cpu->FPSR;
602
603 mask &= FPSR_ALL_FPSRS;
604 cpu->FPSR &= ~mask;
605 cpu->FPSR |= (value & mask);
2e8cf49e 606
e101a78b
NC
607 if (cpu->FPSR != old_FPSR)
608 TRACE_REGISTER (cpu,
609 "FPSR changes from %x to %x", old_FPSR, cpu->FPSR);
2e8cf49e
NC
610}
611
e101a78b
NC
612uint32_t
613aarch64_get_FPSR_bits (sim_cpu *cpu, uint32_t mask)
2e8cf49e 614{
e101a78b
NC
615 mask &= FPSR_ALL_FPSRS;
616 return cpu->FPSR & mask;
617}
2e8cf49e 618
e101a78b
NC
619int
620aarch64_test_FPSR_bit (sim_cpu *cpu, FPSRMask flag)
621{
622 return cpu->FPSR & flag;
2e8cf49e 623}
5ab6d79e
NC
624
625uint64_t
ef0d8ffc 626aarch64_get_thread_id (sim_cpu *cpu)
5ab6d79e
NC
627{
628 return cpu->tpidr;
629}
630
631uint32_t
ef0d8ffc 632aarch64_get_FPCR (sim_cpu *cpu)
5ab6d79e
NC
633{
634 return cpu->FPCR;
635}
636
637void
ef0d8ffc 638aarch64_set_FPCR (sim_cpu *cpu, uint32_t val)
5ab6d79e
NC
639{
640 if (cpu->FPCR != val)
641 TRACE_REGISTER (cpu,
642 "FPCR changes from %x to %x", cpu->FPCR, val);
643 cpu->FPCR = val;
644}