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/decode.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/decode.h')
-rw-r--r-- | sim/aarch64/decode.h | 418 |
1 files changed, 418 insertions, 0 deletions
diff --git a/sim/aarch64/decode.h b/sim/aarch64/decode.h new file mode 100644 index 0000000..edb3c28 --- /dev/null +++ b/sim/aarch64/decode.h @@ -0,0 +1,418 @@ +/* decode.h -- Prototypes for AArch64 simulator decoder 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 _DECODE_H +#define _DECODE_H + +#include <sys/types.h> +#include "cpustate.h" + +/* Codes used in conditional instructions + + These are passed to conditional operations to identify which + condition to test for. */ + +typedef enum CondCode +{ + EQ = 0x0, /* meaning Z == 1 */ + NE = 0x1, /* meaning Z == 0 */ + HS = 0x2, /* meaning C == 1 */ + CS = HS, + LO = 0x3, /* meaning C == 0 */ + CC = LO, + MI = 0x4, /* meaning N == 1 */ + PL = 0x5, /* meaning N == 0 */ + VS = 0x6, /* meaning V == 1 */ + VC = 0x7, /* meaning V == 0 */ + HI = 0x8, /* meaning C == 1 && Z == 0 */ + LS = 0x9, /* meaning !(C == 1 && Z == 0) */ + GE = 0xa, /* meaning N == V */ + LT = 0xb, /* meaning N != V */ + GT = 0xc, /* meaning Z == 0 && N == V */ + LE = 0xd, /* meaning !(Z == 0 && N == V) */ + AL = 0xe, /* meaning ANY */ + NV = 0xf /* ditto */ +} CondCode; + +/* Certain addressing modes for load require pre or post writeback of + the computed address to a base register. */ + +typedef enum WriteBack +{ + Post = 0, + Pre = 1, + NoWriteBack = -1 +} WriteBack; + +/* Certain addressing modes for load require an offset to + be optionally scaled so the decode needs to pass that + through to the execute routine. */ + +typedef enum Scaling +{ + Unscaled = 0, + Scaled = 1, + NoScaling = -1 +} Scaling; + +/* When we do have to scale we do so by shifting using + log(bytes in data element - 1) as the shift count. + so we don't have to scale offsets when loading + bytes. */ + +typedef enum ScaleShift +{ + ScaleShift16 = 1, + ScaleShift32 = 2, + ScaleShift64 = 3, + ScaleShift128 = 4 +} ScaleShift; + +/* One of the addressing modes for load requires a 32-bit register + value to be either zero- or sign-extended for these instructions + UXTW or SXTW should be passed. + + Arithmetic register data processing operations can optionally + extend a portion of the second register value for these + instructions the value supplied must identify the portion of the + register which is to be zero- or sign-exended. */ + +typedef enum Extension +{ + UXTB = 0, + UXTH = 1, + UXTW = 2, + UXTX = 3, + SXTB = 4, + SXTH = 5, + SXTW = 6, + SXTX = 7, + NoExtension = -1 +} Extension; + +/* Arithmetic and logical register data processing operations + optionally perform a shift on the second register value. */ + +typedef enum Shift +{ + LSL = 0, + LSR = 1, + ASR = 2, + ROR = 3 +} Shift; + +/* Bit twiddling helpers for instruction decode. */ + +/* 32 bit mask with bits [hi,...,lo] set. */ +static inline uint32_t +mask32 (int hi, int lo) +{ + int nbits = (hi + 1) - lo; + return ((1 << nbits) - 1) << lo; +} + +/* 64 bit mask with bits [hi,...,lo] set. */ +static inline uint64_t +mask64 (int hi, int lo) +{ + int nbits = (hi + 1) - lo; + return ((1L << nbits) - 1) << lo; +} + +/* Pick bits [hi,...,lo] from val. */ +static inline uint32_t +pick32 (uint32_t val, int hi, int lo) +{ + return val & mask32 (hi, lo); +} + +/* Pick bits [hi,...,lo] from val. */ +static inline uint64_t +pick64 (uint64_t val, int hi, int lo) +{ + return val & mask64 (hi, lo); +} + +/* Pick bits [hi,...,lo] from val and shift to [(hi-(newlo - lo)),newlo]. */ +static inline uint32_t +pickshift32 (uint32_t val, int hi, int lo, int newlo) +{ + uint32_t bits = pick32 (val, hi, lo); + + if (lo < newlo) + return bits << (newlo - lo); + + return bits >> (lo - newlo); +} + +/* Mask [hi,lo] and shift down to start at bit 0. */ +static inline uint32_t +pickbits32 (uint32_t val, int hi, int lo) +{ + return pick32 (val, hi, lo) >> lo; +} + +/* Mask [hi,lo] and shift down to start at bit 0. */ +static inline uint64_t +pickbits64 (uint64_t val, int hi, int lo) +{ + return pick64 (val, hi, lo) >> lo; +} + +/* Decode registers, immediates and constants of various types. */ + +static inline GReg +greg (uint32_t val, int lo) +{ + return (GReg) pickbits32 (val, lo + 4, lo); +} + +static inline VReg +vreg (uint32_t val, int lo) +{ + return (VReg) pickbits32 (val, lo + 4, lo); +} + +static inline uint32_t +uimm (uint32_t val, int hi, int lo) +{ + return pickbits32 (val, hi, lo); +} + +static inline int32_t +simm32 (uint32_t val, int hi, int lo) +{ + union + { + uint32_t u; + int32_t n; + } x; + + x.u = val << (31 - hi); + return x.n >> (31 - hi + lo); +} + +static inline int64_t +simm64 (uint64_t val, int hi, int lo) +{ + union + { + uint64_t u; + int64_t n; + } x; + + x.u = val << (63 - hi); + return x.n >> (63 - hi + lo); +} + +static inline Shift +shift (uint32_t val, int lo) +{ + return (Shift) pickbits32 (val, lo + 1, lo); +} + +static inline Extension +extension (uint32_t val, int lo) +{ + return (Extension) pickbits32 (val, lo + 2, lo); +} + +static inline Scaling +scaling (uint32_t val, int lo) +{ + return (Scaling) pickbits32 (val, lo, lo); +} + +static inline WriteBack +writeback (uint32_t val, int lo) +{ + return (WriteBack) pickbits32 (val, lo, lo); +} + +static inline CondCode +condcode (uint32_t val, int lo) +{ + return (CondCode) pickbits32 (val, lo + 3, lo); +} + +/* Operation decode. + Bits [28,24] are the primary dispatch vector. */ + +static inline uint32_t +dispatchGroup (uint32_t val) +{ + return pickshift32 (val, 28, 25, 0); +} + +/* The 16 possible values for bits [28,25] identified by tags which + map them to the 5 main instruction groups LDST, DPREG, ADVSIMD, + BREXSYS and DPIMM. + + An extra group PSEUDO is included in one of the unallocated ranges + for simulator-specific pseudo-instructions. */ + +enum DispatchGroup +{ + GROUP_PSEUDO_0000, + GROUP_UNALLOC_0001, + GROUP_UNALLOC_0010, + GROUP_UNALLOC_0011, + GROUP_LDST_0100, + GROUP_DPREG_0101, + GROUP_LDST_0110, + GROUP_ADVSIMD_0111, + GROUP_DPIMM_1000, + GROUP_DPIMM_1001, + GROUP_BREXSYS_1010, + GROUP_BREXSYS_1011, + GROUP_LDST_1100, + GROUP_DPREG_1101, + GROUP_LDST_1110, + GROUP_ADVSIMD_1111 +}; + +/* Bits [31, 29] of a Pseudo are the secondary dispatch vector. */ + +static inline uint32_t +dispatchPseudo (uint32_t val) +{ + return pickshift32 (val, 31, 29, 0); +} + +/* The 8 possible values for bits [31,29] in a Pseudo Instruction. + Bits [28,25] are always 0000. */ + +enum DispatchPseudo +{ + PSEUDO_UNALLOC_000, /* Unallocated. */ + PSEUDO_UNALLOC_001, /* Ditto. */ + PSEUDO_UNALLOC_010, /* Ditto. */ + PSEUDO_UNALLOC_011, /* Ditto. */ + PSEUDO_UNALLOC_100, /* Ditto. */ + PSEUDO_UNALLOC_101, /* Ditto. */ + PSEUDO_CALLOUT_110, /* CALLOUT -- bits [24,0] identify call/ret sig. */ + PSEUDO_HALT_111 /* HALT -- bits [24, 0] identify halt code. */ +}; + +/* Bits [25, 23] of a DPImm are the secondary dispatch vector. */ + +static inline uint32_t +dispatchDPImm (uint32_t instr) +{ + return pickshift32 (instr, 25, 23, 0); +} + +/* The 8 possible values for bits [25,23] in a Data Processing Immediate + Instruction. Bits [28,25] are always 100_. */ + +enum DispatchDPImm +{ + DPIMM_PCADR_000, /* PC-rel-addressing. */ + DPIMM_PCADR_001, /* Ditto. */ + DPIMM_ADDSUB_010, /* Add/Subtract (immediate). */ + DPIMM_ADDSUB_011, /* Ditto. */ + DPIMM_LOG_100, /* Logical (immediate). */ + DPIMM_MOV_101, /* Move Wide (immediate). */ + DPIMM_BITF_110, /* Bitfield. */ + DPIMM_EXTR_111 /* Extract. */ +}; + +/* Bits [29,28:26] of a LS are the secondary dispatch vector. */ + +static inline uint32_t +dispatchLS (uint32_t instr) +{ + return ( pickshift32 (instr, 29, 28, 1) + | pickshift32 (instr, 26, 26, 0)); +} + +/* The 8 possible values for bits [29,28:26] in a Load/Store + Instruction. Bits [28,25] are always _1_0. */ + +enum DispatchLS +{ + LS_EXCL_000, /* Load/store exclusive (includes some unallocated). */ + LS_ADVSIMD_001, /* AdvSIMD load/store (various -- includes some unallocated). */ + LS_LIT_010, /* Load register literal (includes some unallocated). */ + LS_LIT_011, /* Ditto. */ + LS_PAIR_100, /* Load/store register pair (various). */ + LS_PAIR_101, /* Ditto. */ + LS_OTHER_110, /* Other load/store formats. */ + LS_OTHER_111 /* Ditto. */ +}; + +/* Bits [28:24:21] of a DPReg are the secondary dispatch vector. */ + +static inline uint32_t +dispatchDPReg (uint32_t instr) +{ + return ( pickshift32 (instr, 28, 28, 2) + | pickshift32 (instr, 24, 24, 1) + | pickshift32 (instr, 21, 21, 0)); +} + +/* The 8 possible values for bits [28:24:21] in a Data Processing + Register Instruction. Bits [28,25] are always _101. */ + +enum DispatchDPReg +{ + DPREG_LOG_000, /* Logical (shifted register). */ + DPREG_LOG_001, /* Ditto. */ + DPREG_ADDSHF_010, /* Add/subtract (shifted register). */ + DPREG_ADDEXT_011, /* Add/subtract (extended register). */ + DPREG_ADDCOND_100, /* Add/subtract (with carry) AND + Cond compare/select AND + Data Processing (1/2 source). */ + DPREG_UNALLOC_101, /* Unallocated. */ + DPREG_3SRC_110, /* Data Processing (3 source). */ + DPREG_3SRC_111 /* Data Processing (3 source). */ +}; + +/* bits [31,29] of a BrExSys are the secondary dispatch vector. */ + +static inline uint32_t +dispatchBrExSys (uint32_t instr) +{ + return pickbits32 (instr, 31, 29); +} + +/* The 8 possible values for bits [31,29] in a Branch/Exception/System + Instruction. Bits [28,25] are always 101_. */ + +enum DispatchBr +{ + BR_IMM_000, /* Unconditional branch (immediate). */ + BR_IMMCMP_001, /* Compare & branch (immediate) AND + Test & branch (immediate). */ + BR_IMMCOND_010, /* Conditional branch (immediate) AND Unallocated. */ + BR_UNALLOC_011, /* Unallocated. */ + BR_IMM_100, /* Unconditional branch (immediate). */ + BR_IMMCMP_101, /* Compare & branch (immediate) AND + Test & branch (immediate). */ + BR_REG_110, /* Unconditional branch (register) AND System AND + Excn gen AND Unallocated. */ + BR_UNALLOC_111 /* Unallocated. */ +}; + +/* TODO still need to provide secondary decode and dispatch for + AdvSIMD Insructions with instr[28,25] = 0111 or 1111. */ + +#endif /* _DECODE_H */ |