123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374 |
- /* decode.h -- Prototypes for AArch64 simulator decoder functions.
- Copyright (C) 2015-2022 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;
- }
- 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);
- }
- /* 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 */
|