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