aboutsummaryrefslogtreecommitdiff
path: root/sim/aarch64/decode.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/decode.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/decode.h')
-rw-r--r--sim/aarch64/decode.h418
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 */