src/hotspot/cpu/aarch64/decode_aarch64.hpp
branchJDK-8200758-branch
changeset 57588 dac8f245de8e
parent 57587 16c4975e9e09
parent 57586 f459f98aa30d
child 57591 6805e0ef7453
equal deleted inserted replaced
57587:16c4975e9e09 57588:dac8f245de8e
     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 
       
    33 extern 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  */
       
    43 enum 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  */
       
    68 enum 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  */
       
    78 enum 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  */
       
    89 enum 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  */
       
   106 enum 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  */
       
   121 enum 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 
       
   134 static 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 
       
   140 static 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
       
   147 static 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
       
   153 static 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]
       
   159 static 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
       
   170 static 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
       
   176 static 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 
       
   185 static inline GReg greg(u_int32_t val, int lo)
       
   186 {
       
   187   return (GReg)pickbits32(val, lo + 4, lo);
       
   188 }
       
   189 
       
   190 static inline VReg vreg(u_int32_t val, int lo)
       
   191 {
       
   192   return (VReg)pickbits32(val, lo + 4, lo);
       
   193 }
       
   194 
       
   195 static inline u_int32_t uimm(u_int32_t val, int hi, int lo)
       
   196 {
       
   197   return pickbits32(val, hi, lo);
       
   198 }
       
   199 
       
   200 static 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 
       
   211 static 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 
       
   222 static inline Shift shift(u_int32_t val, int lo)
       
   223 {
       
   224   return (Shift)pickbits32(val, lo+1, lo);
       
   225 }
       
   226 
       
   227 static inline Extension extension(u_int32_t val, int lo)
       
   228 {
       
   229   return (Extension)pickbits32(val, lo+2, lo);
       
   230 }
       
   231 
       
   232 static inline Scaling scaling(u_int32_t val, int lo)
       
   233 {
       
   234   return (Scaling)pickbits32(val, lo, lo);
       
   235 }
       
   236 
       
   237 static inline WriteBack writeback(u_int32_t val, int lo)
       
   238 {
       
   239   return (WriteBack)pickbits32(val, lo, lo);
       
   240 }
       
   241 
       
   242 static 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 
       
   252 static 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  */
       
   265 enum 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 
       
   286 static 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 
       
   296 enum 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 
       
   309 static 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 
       
   319 enum 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 
       
   332 static 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 
       
   343 enum 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 
       
   356 static 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 
       
   368 enum 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 
       
   383 static 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 
       
   393 enum 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