diff options
author | Nick Clifton <nickc@redhat.com> | 2015-11-24 08:47:59 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2015-11-24 08:47:59 +0000 |
commit | 2e8cf49e1387eba9c4ce062885b99a6eb76c01f8 (patch) | |
tree | 363800e2edad589cb37f72e10fc842097a8ec9c4 /sim/aarch64/cpustate.h | |
parent | 351e610191016136a49ee2a0889f1c4929169fc6 (diff) | |
download | gdb-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.h | 333 |
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 */ |