| 1 | /* decode.h -- Prototypes for AArch64 simulator decoder functions. |
| 2 | |
| 3 | Copyright (C) 2015-2020 Free Software Foundation, Inc. |
| 4 | |
| 5 | Contributed by Red Hat. |
| 6 | |
| 7 | This file is part of GDB. |
| 8 | |
| 9 | This program is free software; you can redistribute it and/or modify |
| 10 | it under the terms of the GNU General Public License as published by |
| 11 | the Free Software Foundation; either version 3 of the License, or |
| 12 | (at your option) any later version. |
| 13 | |
| 14 | This program is distributed in the hope that it will be useful, |
| 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 17 | GNU General Public License for more details. |
| 18 | |
| 19 | You should have received a copy of the GNU General Public License |
| 20 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
| 21 | |
| 22 | #ifndef _DECODE_H |
| 23 | #define _DECODE_H |
| 24 | |
| 25 | #include <sys/types.h> |
| 26 | #include "cpustate.h" |
| 27 | |
| 28 | /* Codes used in conditional instructions |
| 29 | |
| 30 | These are passed to conditional operations to identify which |
| 31 | condition to test for. */ |
| 32 | |
| 33 | typedef enum CondCode |
| 34 | { |
| 35 | EQ = 0x0, /* meaning Z == 1 */ |
| 36 | NE = 0x1, /* meaning Z == 0 */ |
| 37 | HS = 0x2, /* meaning C == 1 */ |
| 38 | CS = HS, |
| 39 | LO = 0x3, /* meaning C == 0 */ |
| 40 | CC = LO, |
| 41 | MI = 0x4, /* meaning N == 1 */ |
| 42 | PL = 0x5, /* meaning N == 0 */ |
| 43 | VS = 0x6, /* meaning V == 1 */ |
| 44 | VC = 0x7, /* meaning V == 0 */ |
| 45 | HI = 0x8, /* meaning C == 1 && Z == 0 */ |
| 46 | LS = 0x9, /* meaning !(C == 1 && Z == 0) */ |
| 47 | GE = 0xa, /* meaning N == V */ |
| 48 | LT = 0xb, /* meaning N != V */ |
| 49 | GT = 0xc, /* meaning Z == 0 && N == V */ |
| 50 | LE = 0xd, /* meaning !(Z == 0 && N == V) */ |
| 51 | AL = 0xe, /* meaning ANY */ |
| 52 | NV = 0xf /* ditto */ |
| 53 | } CondCode; |
| 54 | |
| 55 | /* Certain addressing modes for load require pre or post writeback of |
| 56 | the computed address to a base register. */ |
| 57 | |
| 58 | typedef enum WriteBack |
| 59 | { |
| 60 | Post = 0, |
| 61 | Pre = 1, |
| 62 | NoWriteBack = -1 |
| 63 | } WriteBack; |
| 64 | |
| 65 | /* Certain addressing modes for load require an offset to |
| 66 | be optionally scaled so the decode needs to pass that |
| 67 | through to the execute routine. */ |
| 68 | |
| 69 | typedef enum Scaling |
| 70 | { |
| 71 | Unscaled = 0, |
| 72 | Scaled = 1, |
| 73 | NoScaling = -1 |
| 74 | } Scaling; |
| 75 | |
| 76 | /* When we do have to scale we do so by shifting using |
| 77 | log(bytes in data element - 1) as the shift count. |
| 78 | so we don't have to scale offsets when loading |
| 79 | bytes. */ |
| 80 | |
| 81 | typedef enum ScaleShift |
| 82 | { |
| 83 | ScaleShift16 = 1, |
| 84 | ScaleShift32 = 2, |
| 85 | ScaleShift64 = 3, |
| 86 | ScaleShift128 = 4 |
| 87 | } ScaleShift; |
| 88 | |
| 89 | /* One of the addressing modes for load requires a 32-bit register |
| 90 | value to be either zero- or sign-extended for these instructions |
| 91 | UXTW or SXTW should be passed. |
| 92 | |
| 93 | Arithmetic register data processing operations can optionally |
| 94 | extend a portion of the second register value for these |
| 95 | instructions the value supplied must identify the portion of the |
| 96 | register which is to be zero- or sign-exended. */ |
| 97 | |
| 98 | typedef enum Extension |
| 99 | { |
| 100 | UXTB = 0, |
| 101 | UXTH = 1, |
| 102 | UXTW = 2, |
| 103 | UXTX = 3, |
| 104 | SXTB = 4, |
| 105 | SXTH = 5, |
| 106 | SXTW = 6, |
| 107 | SXTX = 7, |
| 108 | NoExtension = -1 |
| 109 | } Extension; |
| 110 | |
| 111 | /* Arithmetic and logical register data processing operations |
| 112 | optionally perform a shift on the second register value. */ |
| 113 | |
| 114 | typedef enum Shift |
| 115 | { |
| 116 | LSL = 0, |
| 117 | LSR = 1, |
| 118 | ASR = 2, |
| 119 | ROR = 3 |
| 120 | } Shift; |
| 121 | |
| 122 | /* Bit twiddling helpers for instruction decode. */ |
| 123 | |
| 124 | /* 32 bit mask with bits [hi,...,lo] set. */ |
| 125 | static inline uint32_t |
| 126 | mask32 (int hi, int lo) |
| 127 | { |
| 128 | int nbits = (hi + 1) - lo; |
| 129 | return ((1 << nbits) - 1) << lo; |
| 130 | } |
| 131 | |
| 132 | /* 64 bit mask with bits [hi,...,lo] set. */ |
| 133 | static inline uint64_t |
| 134 | mask64 (int hi, int lo) |
| 135 | { |
| 136 | int nbits = (hi + 1) - lo; |
| 137 | return ((1L << nbits) - 1) << lo; |
| 138 | } |
| 139 | |
| 140 | /* Pick bits [hi,...,lo] from val. */ |
| 141 | static inline uint32_t |
| 142 | pick32 (uint32_t val, int hi, int lo) |
| 143 | { |
| 144 | return val & mask32 (hi, lo); |
| 145 | } |
| 146 | |
| 147 | /* Pick bits [hi,...,lo] from val. */ |
| 148 | static inline uint64_t |
| 149 | pick64 (uint64_t val, int hi, int lo) |
| 150 | { |
| 151 | return val & mask64 (hi, lo); |
| 152 | } |
| 153 | |
| 154 | /* Pick bits [hi,...,lo] from val and shift to [(hi-(newlo - lo)),newlo]. */ |
| 155 | static inline uint32_t |
| 156 | pickshift32 (uint32_t val, int hi, int lo, int newlo) |
| 157 | { |
| 158 | uint32_t bits = pick32 (val, hi, lo); |
| 159 | |
| 160 | if (lo < newlo) |
| 161 | return bits << (newlo - lo); |
| 162 | |
| 163 | return bits >> (lo - newlo); |
| 164 | } |
| 165 | |
| 166 | /* Mask [hi,lo] and shift down to start at bit 0. */ |
| 167 | static inline uint32_t |
| 168 | pickbits32 (uint32_t val, int hi, int lo) |
| 169 | { |
| 170 | return pick32 (val, hi, lo) >> lo; |
| 171 | } |
| 172 | |
| 173 | /* Mask [hi,lo] and shift down to start at bit 0. */ |
| 174 | static inline uint64_t |
| 175 | pickbits64 (uint64_t val, int hi, int lo) |
| 176 | { |
| 177 | return pick64 (val, hi, lo) >> lo; |
| 178 | } |
| 179 | |
| 180 | static inline uint32_t |
| 181 | uimm (uint32_t val, int hi, int lo) |
| 182 | { |
| 183 | return pickbits32 (val, hi, lo); |
| 184 | } |
| 185 | |
| 186 | static inline int32_t |
| 187 | simm32 (uint32_t val, int hi, int lo) |
| 188 | { |
| 189 | union |
| 190 | { |
| 191 | uint32_t u; |
| 192 | int32_t n; |
| 193 | } x; |
| 194 | |
| 195 | x.u = val << (31 - hi); |
| 196 | return x.n >> (31 - hi + lo); |
| 197 | } |
| 198 | |
| 199 | static inline int64_t |
| 200 | simm64 (uint64_t val, int hi, int lo) |
| 201 | { |
| 202 | union |
| 203 | { |
| 204 | uint64_t u; |
| 205 | int64_t n; |
| 206 | } x; |
| 207 | |
| 208 | x.u = val << (63 - hi); |
| 209 | return x.n >> (63 - hi + lo); |
| 210 | } |
| 211 | |
| 212 | /* Operation decode. |
| 213 | Bits [28,24] are the primary dispatch vector. */ |
| 214 | |
| 215 | static inline uint32_t |
| 216 | dispatchGroup (uint32_t val) |
| 217 | { |
| 218 | return pickshift32 (val, 28, 25, 0); |
| 219 | } |
| 220 | |
| 221 | /* The 16 possible values for bits [28,25] identified by tags which |
| 222 | map them to the 5 main instruction groups LDST, DPREG, ADVSIMD, |
| 223 | BREXSYS and DPIMM. |
| 224 | |
| 225 | An extra group PSEUDO is included in one of the unallocated ranges |
| 226 | for simulator-specific pseudo-instructions. */ |
| 227 | |
| 228 | enum DispatchGroup |
| 229 | { |
| 230 | GROUP_PSEUDO_0000, |
| 231 | GROUP_UNALLOC_0001, |
| 232 | GROUP_UNALLOC_0010, |
| 233 | GROUP_UNALLOC_0011, |
| 234 | GROUP_LDST_0100, |
| 235 | GROUP_DPREG_0101, |
| 236 | GROUP_LDST_0110, |
| 237 | GROUP_ADVSIMD_0111, |
| 238 | GROUP_DPIMM_1000, |
| 239 | GROUP_DPIMM_1001, |
| 240 | GROUP_BREXSYS_1010, |
| 241 | GROUP_BREXSYS_1011, |
| 242 | GROUP_LDST_1100, |
| 243 | GROUP_DPREG_1101, |
| 244 | GROUP_LDST_1110, |
| 245 | GROUP_ADVSIMD_1111 |
| 246 | }; |
| 247 | |
| 248 | /* Bits [31, 29] of a Pseudo are the secondary dispatch vector. */ |
| 249 | |
| 250 | static inline uint32_t |
| 251 | dispatchPseudo (uint32_t val) |
| 252 | { |
| 253 | return pickshift32 (val, 31, 29, 0); |
| 254 | } |
| 255 | |
| 256 | /* The 8 possible values for bits [31,29] in a Pseudo Instruction. |
| 257 | Bits [28,25] are always 0000. */ |
| 258 | |
| 259 | enum DispatchPseudo |
| 260 | { |
| 261 | PSEUDO_UNALLOC_000, /* Unallocated. */ |
| 262 | PSEUDO_UNALLOC_001, /* Ditto. */ |
| 263 | PSEUDO_UNALLOC_010, /* Ditto. */ |
| 264 | PSEUDO_UNALLOC_011, /* Ditto. */ |
| 265 | PSEUDO_UNALLOC_100, /* Ditto. */ |
| 266 | PSEUDO_UNALLOC_101, /* Ditto. */ |
| 267 | PSEUDO_CALLOUT_110, /* CALLOUT -- bits [24,0] identify call/ret sig. */ |
| 268 | PSEUDO_HALT_111 /* HALT -- bits [24, 0] identify halt code. */ |
| 269 | }; |
| 270 | |
| 271 | /* Bits [25, 23] of a DPImm are the secondary dispatch vector. */ |
| 272 | |
| 273 | static inline uint32_t |
| 274 | dispatchDPImm (uint32_t instr) |
| 275 | { |
| 276 | return pickshift32 (instr, 25, 23, 0); |
| 277 | } |
| 278 | |
| 279 | /* The 8 possible values for bits [25,23] in a Data Processing Immediate |
| 280 | Instruction. Bits [28,25] are always 100_. */ |
| 281 | |
| 282 | enum DispatchDPImm |
| 283 | { |
| 284 | DPIMM_PCADR_000, /* PC-rel-addressing. */ |
| 285 | DPIMM_PCADR_001, /* Ditto. */ |
| 286 | DPIMM_ADDSUB_010, /* Add/Subtract (immediate). */ |
| 287 | DPIMM_ADDSUB_011, /* Ditto. */ |
| 288 | DPIMM_LOG_100, /* Logical (immediate). */ |
| 289 | DPIMM_MOV_101, /* Move Wide (immediate). */ |
| 290 | DPIMM_BITF_110, /* Bitfield. */ |
| 291 | DPIMM_EXTR_111 /* Extract. */ |
| 292 | }; |
| 293 | |
| 294 | /* Bits [29,28:26] of a LS are the secondary dispatch vector. */ |
| 295 | |
| 296 | static inline uint32_t |
| 297 | dispatchLS (uint32_t instr) |
| 298 | { |
| 299 | return ( pickshift32 (instr, 29, 28, 1) |
| 300 | | pickshift32 (instr, 26, 26, 0)); |
| 301 | } |
| 302 | |
| 303 | /* The 8 possible values for bits [29,28:26] in a Load/Store |
| 304 | Instruction. Bits [28,25] are always _1_0. */ |
| 305 | |
| 306 | enum DispatchLS |
| 307 | { |
| 308 | LS_EXCL_000, /* Load/store exclusive (includes some unallocated). */ |
| 309 | LS_ADVSIMD_001, /* AdvSIMD load/store (various -- includes some unallocated). */ |
| 310 | LS_LIT_010, /* Load register literal (includes some unallocated). */ |
| 311 | LS_LIT_011, /* Ditto. */ |
| 312 | LS_PAIR_100, /* Load/store register pair (various). */ |
| 313 | LS_PAIR_101, /* Ditto. */ |
| 314 | LS_OTHER_110, /* Other load/store formats. */ |
| 315 | LS_OTHER_111 /* Ditto. */ |
| 316 | }; |
| 317 | |
| 318 | /* Bits [28:24:21] of a DPReg are the secondary dispatch vector. */ |
| 319 | |
| 320 | static inline uint32_t |
| 321 | dispatchDPReg (uint32_t instr) |
| 322 | { |
| 323 | return ( pickshift32 (instr, 28, 28, 2) |
| 324 | | pickshift32 (instr, 24, 24, 1) |
| 325 | | pickshift32 (instr, 21, 21, 0)); |
| 326 | } |
| 327 | |
| 328 | /* The 8 possible values for bits [28:24:21] in a Data Processing |
| 329 | Register Instruction. Bits [28,25] are always _101. */ |
| 330 | |
| 331 | enum DispatchDPReg |
| 332 | { |
| 333 | DPREG_LOG_000, /* Logical (shifted register). */ |
| 334 | DPREG_LOG_001, /* Ditto. */ |
| 335 | DPREG_ADDSHF_010, /* Add/subtract (shifted register). */ |
| 336 | DPREG_ADDEXT_011, /* Add/subtract (extended register). */ |
| 337 | DPREG_ADDCOND_100, /* Add/subtract (with carry) AND |
| 338 | Cond compare/select AND |
| 339 | Data Processing (1/2 source). */ |
| 340 | DPREG_UNALLOC_101, /* Unallocated. */ |
| 341 | DPREG_3SRC_110, /* Data Processing (3 source). */ |
| 342 | DPREG_3SRC_111 /* Data Processing (3 source). */ |
| 343 | }; |
| 344 | |
| 345 | /* bits [31,29] of a BrExSys are the secondary dispatch vector. */ |
| 346 | |
| 347 | static inline uint32_t |
| 348 | dispatchBrExSys (uint32_t instr) |
| 349 | { |
| 350 | return pickbits32 (instr, 31, 29); |
| 351 | } |
| 352 | |
| 353 | /* The 8 possible values for bits [31,29] in a Branch/Exception/System |
| 354 | Instruction. Bits [28,25] are always 101_. */ |
| 355 | |
| 356 | enum DispatchBr |
| 357 | { |
| 358 | BR_IMM_000, /* Unconditional branch (immediate). */ |
| 359 | BR_IMMCMP_001, /* Compare & branch (immediate) AND |
| 360 | Test & branch (immediate). */ |
| 361 | BR_IMMCOND_010, /* Conditional branch (immediate) AND Unallocated. */ |
| 362 | BR_UNALLOC_011, /* Unallocated. */ |
| 363 | BR_IMM_100, /* Unconditional branch (immediate). */ |
| 364 | BR_IMMCMP_101, /* Compare & branch (immediate) AND |
| 365 | Test & branch (immediate). */ |
| 366 | BR_REG_110, /* Unconditional branch (register) AND System AND |
| 367 | Excn gen AND Unallocated. */ |
| 368 | BR_UNALLOC_111 /* Unallocated. */ |
| 369 | }; |
| 370 | |
| 371 | /* TODO still need to provide secondary decode and dispatch for |
| 372 | AdvSIMD Insructions with instr[28,25] = 0111 or 1111. */ |
| 373 | |
| 374 | #endif /* _DECODE_H */ |