1 /* decode.h -- Prototypes for AArch64 simulator decoder functions. 2 3 Copyright (C) 2015-2024 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 */ 375