aboutsummaryrefslogtreecommitdiff
path: root/sim/aarch64/cpustate.h
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2015-11-24 08:47:59 +0000
committerNick Clifton <nickc@redhat.com>2015-11-24 08:47:59 +0000
commit2e8cf49e1387eba9c4ce062885b99a6eb76c01f8 (patch)
tree363800e2edad589cb37f72e10fc842097a8ec9c4 /sim/aarch64/cpustate.h
parent351e610191016136a49ee2a0889f1c4929169fc6 (diff)
downloadgdb-2e8cf49e1387eba9c4ce062885b99a6eb76c01f8.zip
gdb-2e8cf49e1387eba9c4ce062885b99a6eb76c01f8.tar.gz
gdb-2e8cf49e1387eba9c4ce062885b99a6eb76c01f8.tar.bz2
Add an AArch64 simulator to GDB.
sim * configure.tgt: Add aarch64 entry. * configure: Regenerate. * sim/aarch64/configure.ac: New configure template. * sim/aarch64/aclocal.m4: Generate. * sim/aarch64/config.in: Generate. * sim/aarch64/configure: Generate. * sim/aarch64/cpustate.c: New file - functions for accessing AArch64 registers. * sim/aarch64/cpustate.h: New header. * sim/aarch64/decode.h: New header. * sim/aarch64/interp.c: New file - interface between GDB and simulator. * sim/aarch64/Makefile.in: New makefile template. * sim/aarch64/memory.c: New file - functions for simulating aarch64 memory accesses. * sim/aarch64/memory.h: New header. * sim/aarch64/sim-main.h: New header. * sim/aarch64/simulator.c: New file - aarch64 simulator functions. * sim/aarch64/simulator.h: New header. include/gdb * sim-aarch64.h: New file. sim/test * configure: Regenerate. * sim/aarch64: New directory.
Diffstat (limited to 'sim/aarch64/cpustate.h')
-rw-r--r--sim/aarch64/cpustate.h333
1 files changed, 333 insertions, 0 deletions
diff --git a/sim/aarch64/cpustate.h b/sim/aarch64/cpustate.h
new file mode 100644
index 0000000..8734423
--- /dev/null
+++ b/sim/aarch64/cpustate.h
@@ -0,0 +1,333 @@
+/* cpustate.h -- Prototypes for AArch64 cpu state functions.
+
+ Copyright (C) 2015 Free Software Foundation, Inc.
+
+ Contributed by Red Hat.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef _CPU_STATE_H
+#define _CPU_STATE_H
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include "gdb/remote-sim.h"
+
+/* Symbolic names used to identify general registers which also match
+ the registers indices in machine code.
+
+ We have 32 general registers which can be read/written as 32 bit or
+ 64 bit sources/sinks and are appropriately referred to as Wn or Xn
+ in the assembly code. Some instructions mix these access modes
+ (e.g. ADD X0, X1, W2) so the implementation of the instruction
+ needs to *know* which type of read or write access is required. */
+typedef enum GReg
+{
+ R0,
+ R1,
+ R2,
+ R3,
+ R4,
+ R5,
+ R6,
+ R7,
+ R8,
+ R9,
+ R10,
+ R11,
+ R12,
+ R13,
+ R14,
+ R15,
+ R16,
+ R17,
+ R18,
+ R19,
+ R20,
+ R21,
+ R22,
+ R23,
+ R24,
+ R25,
+ R26,
+ R27,
+ R28,
+ R29,
+ R30,
+ R31,
+ FP = R29,
+ LR = R30,
+ SP = R31,
+ ZR = R31
+} GReg;
+
+/* Symbolic names used to refer to floating point registers which also
+ match the registers indices in machine code.
+
+ We have 32 FP registers which can be read/written as 8, 16, 32, 64
+ and 128 bit sources/sinks and are appropriately referred to as Bn,
+ Hn, Sn, Dn and Qn in the assembly code. Some instructions mix these
+ access modes (e.g. FCVT S0, D0) so the implementation of the
+ instruction needs to *know* which type of read or write access is
+ required. */
+
+typedef enum VReg
+{
+ V0,
+ V1,
+ V2,
+ V3,
+ V4,
+ V5,
+ V6,
+ V7,
+ V8,
+ V9,
+ V10,
+ V11,
+ V12,
+ V13,
+ V14,
+ V15,
+ V16,
+ V17,
+ V18,
+ V19,
+ V20,
+ V21,
+ V22,
+ V23,
+ V24,
+ V25,
+ V26,
+ V27,
+ V28,
+ V29,
+ V30,
+ V31,
+} VReg;
+
+/* All the different integer bit patterns for the components of a
+ general register are overlaid here using a union so as to allow all
+ reading and writing of the desired bits.
+
+ N.B. the ARM spec says that when you write a 32 bit register you
+ are supposed to write the low 32 bits and zero the high 32
+ bits. But we don't actually have to care about this because Java
+ will only ever consume the 32 bits value as a 64 bit quantity after
+ an explicit extend. */
+typedef union GRegisterValue
+{
+ int8_t s8;
+ int16_t s16;
+ int32_t s32;
+ int64_t s64;
+ uint8_t u8;
+ uint16_t u16;
+ uint32_t u32;
+ uint64_t u64;
+} GRegister;
+
+/* Float registers provide for storage of a single, double or quad
+ word format float in the same register. Single floats are not
+ paired within each double register as per 32 bit arm. Instead each
+ 128 bit register Vn embeds the bits for Sn, and Dn in the lower
+ quarter and half, respectively, of the bits for Qn.
+
+ The upper bits can also be accessed as single or double floats by
+ the float vector operations using indexing e.g. V1.D[1], V1.S[3]
+ etc and, for SIMD operations using a horrible index range notation.
+
+ The spec also talks about accessing float registers as half words
+ and bytes with Hn and Bn providing access to the low 16 and 8 bits
+ of Vn but it is not really clear what these bits represent. We can
+ probably ignore this for Java anyway. However, we do need to access
+ the raw bits at 32 and 64 bit resolution to load to/from integer
+ registers.
+
+ Note - we do not use the long double type. Aliasing issues between
+ integer and float values mean that it is unreliable to use them. */
+
+typedef union FRegisterValue
+{
+ float s;
+ double d;
+
+ uint64_t v[2];
+ uint32_t w[4];
+ uint16_t h[8];
+ uint8_t b[16];
+
+ int64_t V[2];
+ int32_t W[4];
+ int16_t H[8];
+ int8_t B[16];
+
+ float S[4];
+ double D[2];
+
+} FRegister;
+
+/* Condition register bit select values.
+
+ The order of bits here is important because some of
+ the flag setting conditional instructions employ a
+ bit field to populate the flags when a false condition
+ bypasses execution of the operation and we want to
+ be able to assign the flags register using the
+ supplied value. */
+
+typedef enum FlagIdx
+{
+ V_IDX,
+ C_IDX,
+ Z_IDX,
+ N_IDX
+} FlagIdx;
+
+typedef enum FlagMask
+{
+ V = 1 << V_IDX,
+ C = 1 << C_IDX,
+ Z = 1 << Z_IDX,
+ N = 1 << N_IDX
+} FlagMask;
+
+#define CPSR_ALL_FLAGS (V | C | Z | N)
+
+typedef uint32_t FlagsRegister;
+
+/* FPSR register -- floating point status register
+
+ This register includes IDC, IXC, UFC, OFC, DZC, IOC and QC bits,
+ and the floating point N, Z, C, V bits but the latter are unused in
+ aarch64 mode. the sim ignores QC for now.
+
+ Bit positions are as per the ARMv7 FPSCR register
+
+ IDC : 7 ==> Input Denormal (cumulative exception bit)
+ IXC : 4 ==> Inexact
+ UFC : 3 ==> Underflow
+ OFC : 2 ==> Overflow
+ DZC : 1 ==> Division by Zero
+ IOC : 0 ==> Invalid Operation
+
+ The rounding mode is held in bits [23,22] defined as follows:
+
+ 0b00 Round to Nearest (RN) mode
+ 0b01 Round towards Plus Infinity (RP) mode
+ 0b10 Round towards Minus Infinity (RM) mode
+ 0b11 Round towards Zero (RZ) mode. */
+
+/* Indices for bits in the FPSR register value. */
+typedef enum FPSRIdx
+{
+ IO_IDX = 0,
+ DZ_IDX = 1,
+ OF_IDX = 2,
+ UF_IDX = 3,
+ IX_IDX = 4,
+ ID_IDX = 7
+} FPSRIdx;
+
+/* Corresponding bits as numeric values. */
+typedef enum FPSRMask
+{
+ IO = (1 << IO_IDX),
+ DZ = (1 << DZ_IDX),
+ OF = (1 << OF_IDX),
+ UF = (1 << UF_IDX),
+ IX = (1 << IX_IDX),
+ ID = (1 << ID_IDX)
+} FPSRMask;
+
+#define FPSR_ALL_FPSRS (IO | DZ | OF | UF | IX | ID)
+
+/* General Register access functions. */
+extern uint64_t aarch64_get_reg_u64 (sim_cpu *, GReg, int);
+extern int64_t aarch64_get_reg_s64 (sim_cpu *, GReg, int);
+extern uint32_t aarch64_get_reg_u32 (sim_cpu *, GReg, int);
+extern int32_t aarch64_get_reg_s32 (sim_cpu *, GReg, int);
+extern uint32_t aarch64_get_reg_u16 (sim_cpu *, GReg, int);
+extern int32_t aarch64_get_reg_s16 (sim_cpu *, GReg, int);
+extern uint32_t aarch64_get_reg_u8 (sim_cpu *, GReg, int);
+extern int32_t aarch64_get_reg_s8 (sim_cpu *, GReg, int);
+
+extern void aarch64_set_reg_u64 (sim_cpu *, GReg, int, uint64_t);
+extern void aarch64_set_reg_s64 (sim_cpu *, GReg, int, int64_t);
+
+/* FP Register access functions. */
+extern float aarch64_get_FP_float (sim_cpu *, VReg);
+extern double aarch64_get_FP_double (sim_cpu *, VReg);
+extern void aarch64_get_FP_long_double (sim_cpu *, VReg, FRegister *);
+extern void aarch64_set_FP_float (sim_cpu *, VReg, float);
+extern void aarch64_set_FP_double (sim_cpu *, VReg, double);
+extern void aarch64_set_FP_long_double (sim_cpu *, VReg, FRegister);
+
+/* PC register accessors. */
+extern uint64_t aarch64_get_PC (sim_cpu *);
+extern uint64_t aarch64_get_next_PC (sim_cpu *);
+extern void aarch64_set_next_PC (sim_cpu *, uint64_t);
+extern void aarch64_set_next_PC_by_offset (sim_cpu *, int64_t);
+extern void aarch64_update_PC (sim_cpu *);
+extern void aarch64_save_LR (sim_cpu *);
+
+/* Instruction accessor - implemented as a
+ macro as we do not need to annotate it. */
+#define aarch64_get_instr(cpu) ((cpu)->instr)
+
+/* Flag register accessors. */
+extern uint32_t aarch64_get_CPSR (sim_cpu *);
+extern void aarch64_set_CPSR (sim_cpu *, uint32_t);
+extern uint32_t aarch64_get_CPSR_bits (sim_cpu *, uint32_t);
+extern void aarch64_set_CPSR_bits (sim_cpu *, uint32_t, uint32_t);
+extern uint32_t aarch64_test_CPSR_bit (sim_cpu *, FlagMask);
+extern void aarch64_set_CPSR_bit (sim_cpu *, FlagMask);
+extern void aarch64_clear_CPSR_bit (sim_cpu *, FlagMask);
+
+extern void aarch64_set_FPSR (sim_cpu *, uint32_t);
+extern uint32_t aarch64_get_FPSR (sim_cpu *);
+extern void aarch64_set_FPSR_bits (sim_cpu *, uint32_t, uint32_t);
+extern uint32_t aarch64_get_FPSR_bits (sim_cpu *, uint32_t);
+extern int aarch64_test_FPSR_bit (sim_cpu *, FPSRMask);
+
+/* Vector register accessors. */
+extern uint64_t aarch64_get_vec_u64 (sim_cpu *, VReg, unsigned);
+extern uint32_t aarch64_get_vec_u32 (sim_cpu *, VReg, unsigned);
+extern uint16_t aarch64_get_vec_u16 (sim_cpu *, VReg, unsigned);
+extern uint8_t aarch64_get_vec_u8 (sim_cpu *, VReg, unsigned);
+extern void aarch64_set_vec_u64 (sim_cpu *, VReg, unsigned, uint64_t);
+extern void aarch64_set_vec_u32 (sim_cpu *, VReg, unsigned, uint32_t);
+extern void aarch64_set_vec_u16 (sim_cpu *, VReg, unsigned, uint16_t);
+extern void aarch64_set_vec_u8 (sim_cpu *, VReg, unsigned, uint8_t);
+
+extern int64_t aarch64_get_vec_s64 (sim_cpu *, VReg, unsigned);
+extern int32_t aarch64_get_vec_s32 (sim_cpu *, VReg, unsigned);
+extern int16_t aarch64_get_vec_s16 (sim_cpu *, VReg, unsigned);
+extern int8_t aarch64_get_vec_s8 (sim_cpu *, VReg, unsigned);
+extern void aarch64_set_vec_s64 (sim_cpu *, VReg, unsigned, int64_t);
+extern void aarch64_set_vec_s32 (sim_cpu *, VReg, unsigned, int32_t);
+extern void aarch64_set_vec_s16 (sim_cpu *, VReg, unsigned, int16_t);
+extern void aarch64_set_vec_s8 (sim_cpu *, VReg, unsigned, int8_t);
+
+extern float aarch64_get_vec_float (sim_cpu *, VReg, unsigned);
+extern double aarch64_get_vec_double (sim_cpu *, VReg, unsigned);
+extern void aarch64_set_vec_float (sim_cpu *, VReg, unsigned, float);
+extern void aarch64_set_vec_double (sim_cpu *, VReg, unsigned, double);
+
+#endif /* _CPU_STATE_H */