11cb0ef41Sopenharmony_ci// Copyright 2014 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#ifndef V8_CODEGEN_ARM64_DECODER_ARM64_INL_H_
61cb0ef41Sopenharmony_ci#define V8_CODEGEN_ARM64_DECODER_ARM64_INL_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include "src/codegen/arm64/decoder-arm64.h"
91cb0ef41Sopenharmony_ci#include "src/common/globals.h"
101cb0ef41Sopenharmony_ci#include "src/utils/utils.h"
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_cinamespace v8 {
131cb0ef41Sopenharmony_cinamespace internal {
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ci// Top-level instruction decode function.
161cb0ef41Sopenharmony_citemplate <typename V>
171cb0ef41Sopenharmony_civoid Decoder<V>::Decode(Instruction* instr) {
181cb0ef41Sopenharmony_ci  if (instr->Bits(28, 27) == 0) {
191cb0ef41Sopenharmony_ci    V::VisitUnallocated(instr);
201cb0ef41Sopenharmony_ci  } else {
211cb0ef41Sopenharmony_ci    switch (instr->Bits(27, 24)) {
221cb0ef41Sopenharmony_ci      // 0:   PC relative addressing.
231cb0ef41Sopenharmony_ci      case 0x0:
241cb0ef41Sopenharmony_ci        DecodePCRelAddressing(instr);
251cb0ef41Sopenharmony_ci        break;
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_ci      // 1:   Add/sub immediate.
281cb0ef41Sopenharmony_ci      case 0x1:
291cb0ef41Sopenharmony_ci        DecodeAddSubImmediate(instr);
301cb0ef41Sopenharmony_ci        break;
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ci      // A:   Logical shifted register.
331cb0ef41Sopenharmony_ci      //      Add/sub with carry.
341cb0ef41Sopenharmony_ci      //      Conditional compare register.
351cb0ef41Sopenharmony_ci      //      Conditional compare immediate.
361cb0ef41Sopenharmony_ci      //      Conditional select.
371cb0ef41Sopenharmony_ci      //      Data processing 1 source.
381cb0ef41Sopenharmony_ci      //      Data processing 2 source.
391cb0ef41Sopenharmony_ci      // B:   Add/sub shifted register.
401cb0ef41Sopenharmony_ci      //      Add/sub extended register.
411cb0ef41Sopenharmony_ci      //      Data processing 3 source.
421cb0ef41Sopenharmony_ci      case 0xA:
431cb0ef41Sopenharmony_ci      case 0xB:
441cb0ef41Sopenharmony_ci        DecodeDataProcessing(instr);
451cb0ef41Sopenharmony_ci        break;
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ci      // 2:   Logical immediate.
481cb0ef41Sopenharmony_ci      //      Move wide immediate.
491cb0ef41Sopenharmony_ci      case 0x2:
501cb0ef41Sopenharmony_ci        DecodeLogical(instr);
511cb0ef41Sopenharmony_ci        break;
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_ci      // 3:   Bitfield.
541cb0ef41Sopenharmony_ci      //      Extract.
551cb0ef41Sopenharmony_ci      case 0x3:
561cb0ef41Sopenharmony_ci        DecodeBitfieldExtract(instr);
571cb0ef41Sopenharmony_ci        break;
581cb0ef41Sopenharmony_ci
591cb0ef41Sopenharmony_ci      // 4:   Unconditional branch immediate.
601cb0ef41Sopenharmony_ci      //      Exception generation.
611cb0ef41Sopenharmony_ci      //      Compare and branch immediate.
621cb0ef41Sopenharmony_ci      // 5:   Compare and branch immediate.
631cb0ef41Sopenharmony_ci      //      Conditional branch.
641cb0ef41Sopenharmony_ci      //      System.
651cb0ef41Sopenharmony_ci      // 6,7: Unconditional branch.
661cb0ef41Sopenharmony_ci      //      Test and branch immediate.
671cb0ef41Sopenharmony_ci      case 0x4:
681cb0ef41Sopenharmony_ci      case 0x5:
691cb0ef41Sopenharmony_ci      case 0x6:
701cb0ef41Sopenharmony_ci      case 0x7:
711cb0ef41Sopenharmony_ci        DecodeBranchSystemException(instr);
721cb0ef41Sopenharmony_ci        break;
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_ci      // 8,9: Load/store register pair post-index.
751cb0ef41Sopenharmony_ci      //      Load register literal.
761cb0ef41Sopenharmony_ci      //      Load/store register unscaled immediate.
771cb0ef41Sopenharmony_ci      //      Load/store register immediate post-index.
781cb0ef41Sopenharmony_ci      //      Load/store register immediate pre-index.
791cb0ef41Sopenharmony_ci      //      Load/store register offset.
801cb0ef41Sopenharmony_ci      // C,D: Load/store register pair offset.
811cb0ef41Sopenharmony_ci      //      Load/store register pair pre-index.
821cb0ef41Sopenharmony_ci      //      Load/store register unsigned immediate.
831cb0ef41Sopenharmony_ci      //      Advanced SIMD.
841cb0ef41Sopenharmony_ci      case 0x8:
851cb0ef41Sopenharmony_ci      case 0x9:
861cb0ef41Sopenharmony_ci      case 0xC:
871cb0ef41Sopenharmony_ci      case 0xD:
881cb0ef41Sopenharmony_ci        DecodeLoadStore(instr);
891cb0ef41Sopenharmony_ci        break;
901cb0ef41Sopenharmony_ci
911cb0ef41Sopenharmony_ci      // E:   FP fixed point conversion.
921cb0ef41Sopenharmony_ci      //      FP integer conversion.
931cb0ef41Sopenharmony_ci      //      FP data processing 1 source.
941cb0ef41Sopenharmony_ci      //      FP compare.
951cb0ef41Sopenharmony_ci      //      FP immediate.
961cb0ef41Sopenharmony_ci      //      FP data processing 2 source.
971cb0ef41Sopenharmony_ci      //      FP conditional compare.
981cb0ef41Sopenharmony_ci      //      FP conditional select.
991cb0ef41Sopenharmony_ci      //      Advanced SIMD.
1001cb0ef41Sopenharmony_ci      // F:   FP data processing 3 source.
1011cb0ef41Sopenharmony_ci      //      Advanced SIMD.
1021cb0ef41Sopenharmony_ci      case 0xE:
1031cb0ef41Sopenharmony_ci      case 0xF:
1041cb0ef41Sopenharmony_ci        DecodeFP(instr);
1051cb0ef41Sopenharmony_ci        break;
1061cb0ef41Sopenharmony_ci    }
1071cb0ef41Sopenharmony_ci  }
1081cb0ef41Sopenharmony_ci}
1091cb0ef41Sopenharmony_ci
1101cb0ef41Sopenharmony_citemplate <typename V>
1111cb0ef41Sopenharmony_civoid Decoder<V>::DecodePCRelAddressing(Instruction* instr) {
1121cb0ef41Sopenharmony_ci  DCHECK_EQ(0x0, instr->Bits(27, 24));
1131cb0ef41Sopenharmony_ci  // We know bit 28 is set, as <b28:b27> = 0 is filtered out at the top level
1141cb0ef41Sopenharmony_ci  // decode.
1151cb0ef41Sopenharmony_ci  DCHECK_EQ(0x1, instr->Bit(28));
1161cb0ef41Sopenharmony_ci  V::VisitPCRelAddressing(instr);
1171cb0ef41Sopenharmony_ci}
1181cb0ef41Sopenharmony_ci
1191cb0ef41Sopenharmony_citemplate <typename V>
1201cb0ef41Sopenharmony_civoid Decoder<V>::DecodeBranchSystemException(Instruction* instr) {
1211cb0ef41Sopenharmony_ci  DCHECK_EQ(0x4, instr->Bits(27, 24) & 0xC);  // 0x4, 0x5, 0x6, 0x7
1221cb0ef41Sopenharmony_ci
1231cb0ef41Sopenharmony_ci  switch (instr->Bits(31, 29)) {
1241cb0ef41Sopenharmony_ci    case 0:
1251cb0ef41Sopenharmony_ci    case 4: {
1261cb0ef41Sopenharmony_ci      V::VisitUnconditionalBranch(instr);
1271cb0ef41Sopenharmony_ci      break;
1281cb0ef41Sopenharmony_ci    }
1291cb0ef41Sopenharmony_ci    case 1:
1301cb0ef41Sopenharmony_ci    case 5: {
1311cb0ef41Sopenharmony_ci      if (instr->Bit(25) == 0) {
1321cb0ef41Sopenharmony_ci        V::VisitCompareBranch(instr);
1331cb0ef41Sopenharmony_ci      } else {
1341cb0ef41Sopenharmony_ci        V::VisitTestBranch(instr);
1351cb0ef41Sopenharmony_ci      }
1361cb0ef41Sopenharmony_ci      break;
1371cb0ef41Sopenharmony_ci    }
1381cb0ef41Sopenharmony_ci    case 2: {
1391cb0ef41Sopenharmony_ci      if (instr->Bit(25) == 0) {
1401cb0ef41Sopenharmony_ci        if ((instr->Bit(24) == 0x1) ||
1411cb0ef41Sopenharmony_ci            (instr->Mask(0x01000010) == 0x00000010)) {
1421cb0ef41Sopenharmony_ci          V::VisitUnallocated(instr);
1431cb0ef41Sopenharmony_ci        } else {
1441cb0ef41Sopenharmony_ci          V::VisitConditionalBranch(instr);
1451cb0ef41Sopenharmony_ci        }
1461cb0ef41Sopenharmony_ci      } else {
1471cb0ef41Sopenharmony_ci        V::VisitUnallocated(instr);
1481cb0ef41Sopenharmony_ci      }
1491cb0ef41Sopenharmony_ci      break;
1501cb0ef41Sopenharmony_ci    }
1511cb0ef41Sopenharmony_ci    case 6: {
1521cb0ef41Sopenharmony_ci      if (instr->Bit(25) == 0) {
1531cb0ef41Sopenharmony_ci        if (instr->Bit(24) == 0) {
1541cb0ef41Sopenharmony_ci          if ((instr->Bits(4, 2) != 0) ||
1551cb0ef41Sopenharmony_ci              (instr->Mask(0x00E0001D) == 0x00200001) ||
1561cb0ef41Sopenharmony_ci              (instr->Mask(0x00E0001D) == 0x00400001) ||
1571cb0ef41Sopenharmony_ci              (instr->Mask(0x00E0001E) == 0x00200002) ||
1581cb0ef41Sopenharmony_ci              (instr->Mask(0x00E0001E) == 0x00400002) ||
1591cb0ef41Sopenharmony_ci              (instr->Mask(0x00E0001C) == 0x00600000) ||
1601cb0ef41Sopenharmony_ci              (instr->Mask(0x00E0001C) == 0x00800000) ||
1611cb0ef41Sopenharmony_ci              (instr->Mask(0x00E0001F) == 0x00A00000) ||
1621cb0ef41Sopenharmony_ci              (instr->Mask(0x00C0001C) == 0x00C00000)) {
1631cb0ef41Sopenharmony_ci            V::VisitUnallocated(instr);
1641cb0ef41Sopenharmony_ci          } else {
1651cb0ef41Sopenharmony_ci            V::VisitException(instr);
1661cb0ef41Sopenharmony_ci          }
1671cb0ef41Sopenharmony_ci        } else {
1681cb0ef41Sopenharmony_ci          if (instr->Bits(23, 22) == 0) {
1691cb0ef41Sopenharmony_ci            const Instr masked_003FF0E0 = instr->Mask(0x003FF0E0);
1701cb0ef41Sopenharmony_ci            if ((instr->Bits(21, 19) == 0x4) ||
1711cb0ef41Sopenharmony_ci                (masked_003FF0E0 == 0x00033000) ||
1721cb0ef41Sopenharmony_ci                (masked_003FF0E0 == 0x003FF020) ||
1731cb0ef41Sopenharmony_ci                (masked_003FF0E0 == 0x003FF060) ||
1741cb0ef41Sopenharmony_ci                (masked_003FF0E0 == 0x003FF0E0) ||
1751cb0ef41Sopenharmony_ci                (instr->Mask(0x00388000) == 0x00008000) ||
1761cb0ef41Sopenharmony_ci                (instr->Mask(0x0038E000) == 0x00000000) ||
1771cb0ef41Sopenharmony_ci                (instr->Mask(0x0039E000) == 0x00002000) ||
1781cb0ef41Sopenharmony_ci                (instr->Mask(0x003AE000) == 0x00002000) ||
1791cb0ef41Sopenharmony_ci                (instr->Mask(0x003CE000) == 0x00042000) ||
1801cb0ef41Sopenharmony_ci                (instr->Mask(0x0038F000) == 0x00005000) ||
1811cb0ef41Sopenharmony_ci                (instr->Mask(0x0038E000) == 0x00006000)) {
1821cb0ef41Sopenharmony_ci              V::VisitUnallocated(instr);
1831cb0ef41Sopenharmony_ci            } else {
1841cb0ef41Sopenharmony_ci              V::VisitSystem(instr);
1851cb0ef41Sopenharmony_ci            }
1861cb0ef41Sopenharmony_ci          } else {
1871cb0ef41Sopenharmony_ci            V::VisitUnallocated(instr);
1881cb0ef41Sopenharmony_ci          }
1891cb0ef41Sopenharmony_ci        }
1901cb0ef41Sopenharmony_ci      } else {
1911cb0ef41Sopenharmony_ci        if ((instr->Bit(24) == 0x1) || (instr->Bits(20, 16) != 0x1F) ||
1921cb0ef41Sopenharmony_ci            (instr->Bits(15, 10) != 0) || (instr->Bits(4, 0) != 0) ||
1931cb0ef41Sopenharmony_ci            (instr->Bits(24, 21) == 0x3) || (instr->Bits(24, 22) == 0x3)) {
1941cb0ef41Sopenharmony_ci          V::VisitUnallocated(instr);
1951cb0ef41Sopenharmony_ci        } else {
1961cb0ef41Sopenharmony_ci          V::VisitUnconditionalBranchToRegister(instr);
1971cb0ef41Sopenharmony_ci        }
1981cb0ef41Sopenharmony_ci      }
1991cb0ef41Sopenharmony_ci      break;
2001cb0ef41Sopenharmony_ci    }
2011cb0ef41Sopenharmony_ci    case 3:
2021cb0ef41Sopenharmony_ci    case 7: {
2031cb0ef41Sopenharmony_ci      V::VisitUnallocated(instr);
2041cb0ef41Sopenharmony_ci      break;
2051cb0ef41Sopenharmony_ci    }
2061cb0ef41Sopenharmony_ci  }
2071cb0ef41Sopenharmony_ci}
2081cb0ef41Sopenharmony_ci
2091cb0ef41Sopenharmony_citemplate <typename V>
2101cb0ef41Sopenharmony_civoid Decoder<V>::DecodeLoadStore(Instruction* instr) {
2111cb0ef41Sopenharmony_ci  DCHECK_EQ(0x8, instr->Bits(27, 24) & 0xA);  // 0x8, 0x9, 0xC, 0xD
2121cb0ef41Sopenharmony_ci
2131cb0ef41Sopenharmony_ci  if ((instr->Bit(28) == 0) && (instr->Bit(29) == 0) && (instr->Bit(26) == 1)) {
2141cb0ef41Sopenharmony_ci    DecodeNEONLoadStore(instr);
2151cb0ef41Sopenharmony_ci    return;
2161cb0ef41Sopenharmony_ci  }
2171cb0ef41Sopenharmony_ci
2181cb0ef41Sopenharmony_ci  if (instr->Bit(24) == 0) {
2191cb0ef41Sopenharmony_ci    if (instr->Bit(28) == 0) {
2201cb0ef41Sopenharmony_ci      if (instr->Bit(29) == 0) {
2211cb0ef41Sopenharmony_ci        if (instr->Bit(26) == 0) {
2221cb0ef41Sopenharmony_ci          if (instr->Mask(0xA08000) == 0x800000 ||
2231cb0ef41Sopenharmony_ci              instr->Mask(0xA00000) == 0xA00000) {
2241cb0ef41Sopenharmony_ci            V::VisitUnallocated(instr);
2251cb0ef41Sopenharmony_ci          } else if (instr->Mask(0x808000) == 0) {
2261cb0ef41Sopenharmony_ci            // Load/Store exclusive without acquire/release are unimplemented.
2271cb0ef41Sopenharmony_ci            V::VisitUnimplemented(instr);
2281cb0ef41Sopenharmony_ci          } else {
2291cb0ef41Sopenharmony_ci            V::VisitLoadStoreAcquireRelease(instr);
2301cb0ef41Sopenharmony_ci          }
2311cb0ef41Sopenharmony_ci        }
2321cb0ef41Sopenharmony_ci      } else {
2331cb0ef41Sopenharmony_ci        if ((instr->Bits(31, 30) == 0x3) ||
2341cb0ef41Sopenharmony_ci            (instr->Mask(0xC4400000) == 0x40000000)) {
2351cb0ef41Sopenharmony_ci          V::VisitUnallocated(instr);
2361cb0ef41Sopenharmony_ci        } else {
2371cb0ef41Sopenharmony_ci          if (instr->Bit(23) == 0) {
2381cb0ef41Sopenharmony_ci            if (instr->Mask(0xC4400000) == 0xC0400000) {
2391cb0ef41Sopenharmony_ci              V::VisitUnallocated(instr);
2401cb0ef41Sopenharmony_ci            } else {
2411cb0ef41Sopenharmony_ci              // Nontemporals are unimplemented.
2421cb0ef41Sopenharmony_ci              V::VisitUnimplemented(instr);
2431cb0ef41Sopenharmony_ci            }
2441cb0ef41Sopenharmony_ci          } else {
2451cb0ef41Sopenharmony_ci            V::VisitLoadStorePairPostIndex(instr);
2461cb0ef41Sopenharmony_ci          }
2471cb0ef41Sopenharmony_ci        }
2481cb0ef41Sopenharmony_ci      }
2491cb0ef41Sopenharmony_ci    } else {
2501cb0ef41Sopenharmony_ci      if (instr->Bit(29) == 0) {
2511cb0ef41Sopenharmony_ci        if (instr->Mask(0xC4000000) == 0xC4000000) {
2521cb0ef41Sopenharmony_ci          V::VisitUnallocated(instr);
2531cb0ef41Sopenharmony_ci        } else {
2541cb0ef41Sopenharmony_ci          V::VisitLoadLiteral(instr);
2551cb0ef41Sopenharmony_ci        }
2561cb0ef41Sopenharmony_ci      } else {
2571cb0ef41Sopenharmony_ci        if ((instr->Mask(0x84C00000) == 0x80C00000) ||
2581cb0ef41Sopenharmony_ci            (instr->Mask(0x44800000) == 0x44800000) ||
2591cb0ef41Sopenharmony_ci            (instr->Mask(0x84800000) == 0x84800000)) {
2601cb0ef41Sopenharmony_ci          V::VisitUnallocated(instr);
2611cb0ef41Sopenharmony_ci        } else {
2621cb0ef41Sopenharmony_ci          if (instr->Bit(21) == 0) {
2631cb0ef41Sopenharmony_ci            switch (instr->Bits(11, 10)) {
2641cb0ef41Sopenharmony_ci              case 0: {
2651cb0ef41Sopenharmony_ci                V::VisitLoadStoreUnscaledOffset(instr);
2661cb0ef41Sopenharmony_ci                break;
2671cb0ef41Sopenharmony_ci              }
2681cb0ef41Sopenharmony_ci              case 1: {
2691cb0ef41Sopenharmony_ci                if (instr->Mask(0xC4C00000) == 0xC0800000) {
2701cb0ef41Sopenharmony_ci                  V::VisitUnallocated(instr);
2711cb0ef41Sopenharmony_ci                } else {
2721cb0ef41Sopenharmony_ci                  V::VisitLoadStorePostIndex(instr);
2731cb0ef41Sopenharmony_ci                }
2741cb0ef41Sopenharmony_ci                break;
2751cb0ef41Sopenharmony_ci              }
2761cb0ef41Sopenharmony_ci              case 2: {
2771cb0ef41Sopenharmony_ci                // TODO(all): VisitLoadStoreRegisterOffsetUnpriv.
2781cb0ef41Sopenharmony_ci                V::VisitUnimplemented(instr);
2791cb0ef41Sopenharmony_ci                break;
2801cb0ef41Sopenharmony_ci              }
2811cb0ef41Sopenharmony_ci              case 3: {
2821cb0ef41Sopenharmony_ci                if (instr->Mask(0xC4C00000) == 0xC0800000) {
2831cb0ef41Sopenharmony_ci                  V::VisitUnallocated(instr);
2841cb0ef41Sopenharmony_ci                } else {
2851cb0ef41Sopenharmony_ci                  V::VisitLoadStorePreIndex(instr);
2861cb0ef41Sopenharmony_ci                }
2871cb0ef41Sopenharmony_ci                break;
2881cb0ef41Sopenharmony_ci              }
2891cb0ef41Sopenharmony_ci            }
2901cb0ef41Sopenharmony_ci          } else {
2911cb0ef41Sopenharmony_ci            if (instr->Bits(11, 10) == 0x2) {
2921cb0ef41Sopenharmony_ci              if (instr->Bit(14) == 0) {
2931cb0ef41Sopenharmony_ci                V::VisitUnallocated(instr);
2941cb0ef41Sopenharmony_ci              } else {
2951cb0ef41Sopenharmony_ci                V::VisitLoadStoreRegisterOffset(instr);
2961cb0ef41Sopenharmony_ci              }
2971cb0ef41Sopenharmony_ci            } else {
2981cb0ef41Sopenharmony_ci              V::VisitUnallocated(instr);
2991cb0ef41Sopenharmony_ci            }
3001cb0ef41Sopenharmony_ci          }
3011cb0ef41Sopenharmony_ci        }
3021cb0ef41Sopenharmony_ci      }
3031cb0ef41Sopenharmony_ci    }
3041cb0ef41Sopenharmony_ci  } else {
3051cb0ef41Sopenharmony_ci    if (instr->Bit(28) == 0) {
3061cb0ef41Sopenharmony_ci      if (instr->Bit(29) == 0) {
3071cb0ef41Sopenharmony_ci        V::VisitUnallocated(instr);
3081cb0ef41Sopenharmony_ci      } else {
3091cb0ef41Sopenharmony_ci        if ((instr->Bits(31, 30) == 0x3) ||
3101cb0ef41Sopenharmony_ci            (instr->Mask(0xC4400000) == 0x40000000)) {
3111cb0ef41Sopenharmony_ci          V::VisitUnallocated(instr);
3121cb0ef41Sopenharmony_ci        } else {
3131cb0ef41Sopenharmony_ci          if (instr->Bit(23) == 0) {
3141cb0ef41Sopenharmony_ci            V::VisitLoadStorePairOffset(instr);
3151cb0ef41Sopenharmony_ci          } else {
3161cb0ef41Sopenharmony_ci            V::VisitLoadStorePairPreIndex(instr);
3171cb0ef41Sopenharmony_ci          }
3181cb0ef41Sopenharmony_ci        }
3191cb0ef41Sopenharmony_ci      }
3201cb0ef41Sopenharmony_ci    } else {
3211cb0ef41Sopenharmony_ci      if (instr->Bit(29) == 0) {
3221cb0ef41Sopenharmony_ci        V::VisitUnallocated(instr);
3231cb0ef41Sopenharmony_ci      } else {
3241cb0ef41Sopenharmony_ci        if ((instr->Mask(0x84C00000) == 0x80C00000) ||
3251cb0ef41Sopenharmony_ci            (instr->Mask(0x44800000) == 0x44800000) ||
3261cb0ef41Sopenharmony_ci            (instr->Mask(0x84800000) == 0x84800000)) {
3271cb0ef41Sopenharmony_ci          V::VisitUnallocated(instr);
3281cb0ef41Sopenharmony_ci        } else {
3291cb0ef41Sopenharmony_ci          V::VisitLoadStoreUnsignedOffset(instr);
3301cb0ef41Sopenharmony_ci        }
3311cb0ef41Sopenharmony_ci      }
3321cb0ef41Sopenharmony_ci    }
3331cb0ef41Sopenharmony_ci  }
3341cb0ef41Sopenharmony_ci}
3351cb0ef41Sopenharmony_ci
3361cb0ef41Sopenharmony_citemplate <typename V>
3371cb0ef41Sopenharmony_civoid Decoder<V>::DecodeLogical(Instruction* instr) {
3381cb0ef41Sopenharmony_ci  DCHECK_EQ(0x2, instr->Bits(27, 24));
3391cb0ef41Sopenharmony_ci
3401cb0ef41Sopenharmony_ci  if (instr->Mask(0x80400000) == 0x00400000) {
3411cb0ef41Sopenharmony_ci    V::VisitUnallocated(instr);
3421cb0ef41Sopenharmony_ci  } else {
3431cb0ef41Sopenharmony_ci    if (instr->Bit(23) == 0) {
3441cb0ef41Sopenharmony_ci      V::VisitLogicalImmediate(instr);
3451cb0ef41Sopenharmony_ci    } else {
3461cb0ef41Sopenharmony_ci      if (instr->Bits(30, 29) == 0x1) {
3471cb0ef41Sopenharmony_ci        V::VisitUnallocated(instr);
3481cb0ef41Sopenharmony_ci      } else {
3491cb0ef41Sopenharmony_ci        V::VisitMoveWideImmediate(instr);
3501cb0ef41Sopenharmony_ci      }
3511cb0ef41Sopenharmony_ci    }
3521cb0ef41Sopenharmony_ci  }
3531cb0ef41Sopenharmony_ci}
3541cb0ef41Sopenharmony_ci
3551cb0ef41Sopenharmony_citemplate <typename V>
3561cb0ef41Sopenharmony_civoid Decoder<V>::DecodeBitfieldExtract(Instruction* instr) {
3571cb0ef41Sopenharmony_ci  DCHECK_EQ(0x3, instr->Bits(27, 24));
3581cb0ef41Sopenharmony_ci
3591cb0ef41Sopenharmony_ci  if ((instr->Mask(0x80400000) == 0x80000000) ||
3601cb0ef41Sopenharmony_ci      (instr->Mask(0x80400000) == 0x00400000) ||
3611cb0ef41Sopenharmony_ci      (instr->Mask(0x80008000) == 0x00008000)) {
3621cb0ef41Sopenharmony_ci    V::VisitUnallocated(instr);
3631cb0ef41Sopenharmony_ci  } else if (instr->Bit(23) == 0) {
3641cb0ef41Sopenharmony_ci    if ((instr->Mask(0x80200000) == 0x00200000) ||
3651cb0ef41Sopenharmony_ci        (instr->Mask(0x60000000) == 0x60000000)) {
3661cb0ef41Sopenharmony_ci      V::VisitUnallocated(instr);
3671cb0ef41Sopenharmony_ci    } else {
3681cb0ef41Sopenharmony_ci      V::VisitBitfield(instr);
3691cb0ef41Sopenharmony_ci    }
3701cb0ef41Sopenharmony_ci  } else {
3711cb0ef41Sopenharmony_ci    if ((instr->Mask(0x60200000) == 0x00200000) ||
3721cb0ef41Sopenharmony_ci        (instr->Mask(0x60000000) != 0x00000000)) {
3731cb0ef41Sopenharmony_ci      V::VisitUnallocated(instr);
3741cb0ef41Sopenharmony_ci    } else {
3751cb0ef41Sopenharmony_ci      V::VisitExtract(instr);
3761cb0ef41Sopenharmony_ci    }
3771cb0ef41Sopenharmony_ci  }
3781cb0ef41Sopenharmony_ci}
3791cb0ef41Sopenharmony_ci
3801cb0ef41Sopenharmony_citemplate <typename V>
3811cb0ef41Sopenharmony_civoid Decoder<V>::DecodeAddSubImmediate(Instruction* instr) {
3821cb0ef41Sopenharmony_ci  DCHECK_EQ(0x1, instr->Bits(27, 24));
3831cb0ef41Sopenharmony_ci  if (instr->Bit(23) == 1) {
3841cb0ef41Sopenharmony_ci    V::VisitUnallocated(instr);
3851cb0ef41Sopenharmony_ci  } else {
3861cb0ef41Sopenharmony_ci    V::VisitAddSubImmediate(instr);
3871cb0ef41Sopenharmony_ci  }
3881cb0ef41Sopenharmony_ci}
3891cb0ef41Sopenharmony_ci
3901cb0ef41Sopenharmony_citemplate <typename V>
3911cb0ef41Sopenharmony_civoid Decoder<V>::DecodeDataProcessing(Instruction* instr) {
3921cb0ef41Sopenharmony_ci  DCHECK((instr->Bits(27, 24) == 0xA) || (instr->Bits(27, 24) == 0xB));
3931cb0ef41Sopenharmony_ci
3941cb0ef41Sopenharmony_ci  if (instr->Bit(24) == 0) {
3951cb0ef41Sopenharmony_ci    if (instr->Bit(28) == 0) {
3961cb0ef41Sopenharmony_ci      if (instr->Mask(0x80008000) == 0x00008000) {
3971cb0ef41Sopenharmony_ci        V::VisitUnallocated(instr);
3981cb0ef41Sopenharmony_ci      } else {
3991cb0ef41Sopenharmony_ci        V::VisitLogicalShifted(instr);
4001cb0ef41Sopenharmony_ci      }
4011cb0ef41Sopenharmony_ci    } else {
4021cb0ef41Sopenharmony_ci      switch (instr->Bits(23, 21)) {
4031cb0ef41Sopenharmony_ci        case 0: {
4041cb0ef41Sopenharmony_ci          if (instr->Mask(0x0000FC00) != 0) {
4051cb0ef41Sopenharmony_ci            V::VisitUnallocated(instr);
4061cb0ef41Sopenharmony_ci          } else {
4071cb0ef41Sopenharmony_ci            V::VisitAddSubWithCarry(instr);
4081cb0ef41Sopenharmony_ci          }
4091cb0ef41Sopenharmony_ci          break;
4101cb0ef41Sopenharmony_ci        }
4111cb0ef41Sopenharmony_ci        case 2: {
4121cb0ef41Sopenharmony_ci          if ((instr->Bit(29) == 0) || (instr->Mask(0x00000410) != 0)) {
4131cb0ef41Sopenharmony_ci            V::VisitUnallocated(instr);
4141cb0ef41Sopenharmony_ci          } else {
4151cb0ef41Sopenharmony_ci            if (instr->Bit(11) == 0) {
4161cb0ef41Sopenharmony_ci              V::VisitConditionalCompareRegister(instr);
4171cb0ef41Sopenharmony_ci            } else {
4181cb0ef41Sopenharmony_ci              V::VisitConditionalCompareImmediate(instr);
4191cb0ef41Sopenharmony_ci            }
4201cb0ef41Sopenharmony_ci          }
4211cb0ef41Sopenharmony_ci          break;
4221cb0ef41Sopenharmony_ci        }
4231cb0ef41Sopenharmony_ci        case 4: {
4241cb0ef41Sopenharmony_ci          if (instr->Mask(0x20000800) != 0x00000000) {
4251cb0ef41Sopenharmony_ci            V::VisitUnallocated(instr);
4261cb0ef41Sopenharmony_ci          } else {
4271cb0ef41Sopenharmony_ci            V::VisitConditionalSelect(instr);
4281cb0ef41Sopenharmony_ci          }
4291cb0ef41Sopenharmony_ci          break;
4301cb0ef41Sopenharmony_ci        }
4311cb0ef41Sopenharmony_ci        case 6: {
4321cb0ef41Sopenharmony_ci          if (instr->Bit(29) == 0x1) {
4331cb0ef41Sopenharmony_ci            V::VisitUnallocated(instr);
4341cb0ef41Sopenharmony_ci          } else {
4351cb0ef41Sopenharmony_ci            if (instr->Bit(30) == 0) {
4361cb0ef41Sopenharmony_ci              if ((instr->Bit(15) == 0x1) || (instr->Bits(15, 11) == 0) ||
4371cb0ef41Sopenharmony_ci                  (instr->Bits(15, 12) == 0x1) ||
4381cb0ef41Sopenharmony_ci                  (instr->Bits(15, 12) == 0x3) ||
4391cb0ef41Sopenharmony_ci                  (instr->Bits(15, 13) == 0x3) ||
4401cb0ef41Sopenharmony_ci                  (instr->Mask(0x8000EC00) == 0x00004C00) ||
4411cb0ef41Sopenharmony_ci                  (instr->Mask(0x8000E800) == 0x80004000) ||
4421cb0ef41Sopenharmony_ci                  (instr->Mask(0x8000E400) == 0x80004000)) {
4431cb0ef41Sopenharmony_ci                V::VisitUnallocated(instr);
4441cb0ef41Sopenharmony_ci              } else {
4451cb0ef41Sopenharmony_ci                V::VisitDataProcessing2Source(instr);
4461cb0ef41Sopenharmony_ci              }
4471cb0ef41Sopenharmony_ci            } else {
4481cb0ef41Sopenharmony_ci              if ((instr->Bit(13) == 1) || (instr->Bits(20, 16) != 0) ||
4491cb0ef41Sopenharmony_ci                  (instr->Bits(15, 14) != 0) ||
4501cb0ef41Sopenharmony_ci                  (instr->Mask(0xA01FFC00) == 0x00000C00) ||
4511cb0ef41Sopenharmony_ci                  (instr->Mask(0x201FF800) == 0x00001800)) {
4521cb0ef41Sopenharmony_ci                V::VisitUnallocated(instr);
4531cb0ef41Sopenharmony_ci              } else {
4541cb0ef41Sopenharmony_ci                V::VisitDataProcessing1Source(instr);
4551cb0ef41Sopenharmony_ci              }
4561cb0ef41Sopenharmony_ci            }
4571cb0ef41Sopenharmony_ci            break;
4581cb0ef41Sopenharmony_ci          }
4591cb0ef41Sopenharmony_ci          V8_FALLTHROUGH;
4601cb0ef41Sopenharmony_ci        }
4611cb0ef41Sopenharmony_ci        case 1:
4621cb0ef41Sopenharmony_ci        case 3:
4631cb0ef41Sopenharmony_ci        case 5:
4641cb0ef41Sopenharmony_ci        case 7:
4651cb0ef41Sopenharmony_ci          V::VisitUnallocated(instr);
4661cb0ef41Sopenharmony_ci          break;
4671cb0ef41Sopenharmony_ci      }
4681cb0ef41Sopenharmony_ci    }
4691cb0ef41Sopenharmony_ci  } else {
4701cb0ef41Sopenharmony_ci    if (instr->Bit(28) == 0) {
4711cb0ef41Sopenharmony_ci      if (instr->Bit(21) == 0) {
4721cb0ef41Sopenharmony_ci        if ((instr->Bits(23, 22) == 0x3) ||
4731cb0ef41Sopenharmony_ci            (instr->Mask(0x80008000) == 0x00008000)) {
4741cb0ef41Sopenharmony_ci          V::VisitUnallocated(instr);
4751cb0ef41Sopenharmony_ci        } else {
4761cb0ef41Sopenharmony_ci          V::VisitAddSubShifted(instr);
4771cb0ef41Sopenharmony_ci        }
4781cb0ef41Sopenharmony_ci      } else {
4791cb0ef41Sopenharmony_ci        if ((instr->Mask(0x00C00000) != 0x00000000) ||
4801cb0ef41Sopenharmony_ci            (instr->Mask(0x00001400) == 0x00001400) ||
4811cb0ef41Sopenharmony_ci            (instr->Mask(0x00001800) == 0x00001800)) {
4821cb0ef41Sopenharmony_ci          V::VisitUnallocated(instr);
4831cb0ef41Sopenharmony_ci        } else {
4841cb0ef41Sopenharmony_ci          V::VisitAddSubExtended(instr);
4851cb0ef41Sopenharmony_ci        }
4861cb0ef41Sopenharmony_ci      }
4871cb0ef41Sopenharmony_ci    } else {
4881cb0ef41Sopenharmony_ci      if ((instr->Bit(30) == 0x1) || (instr->Bits(30, 29) == 0x1) ||
4891cb0ef41Sopenharmony_ci          (instr->Mask(0xE0600000) == 0x00200000) ||
4901cb0ef41Sopenharmony_ci          (instr->Mask(0xE0608000) == 0x00400000) ||
4911cb0ef41Sopenharmony_ci          (instr->Mask(0x60608000) == 0x00408000) ||
4921cb0ef41Sopenharmony_ci          (instr->Mask(0x60E00000) == 0x00E00000) ||
4931cb0ef41Sopenharmony_ci          (instr->Mask(0x60E00000) == 0x00800000) ||
4941cb0ef41Sopenharmony_ci          (instr->Mask(0x60E00000) == 0x00600000)) {
4951cb0ef41Sopenharmony_ci        V::VisitUnallocated(instr);
4961cb0ef41Sopenharmony_ci      } else {
4971cb0ef41Sopenharmony_ci        V::VisitDataProcessing3Source(instr);
4981cb0ef41Sopenharmony_ci      }
4991cb0ef41Sopenharmony_ci    }
5001cb0ef41Sopenharmony_ci  }
5011cb0ef41Sopenharmony_ci}
5021cb0ef41Sopenharmony_ci
5031cb0ef41Sopenharmony_citemplate <typename V>
5041cb0ef41Sopenharmony_civoid Decoder<V>::DecodeFP(Instruction* instr) {
5051cb0ef41Sopenharmony_ci  DCHECK((instr->Bits(27, 24) == 0xE) || (instr->Bits(27, 24) == 0xF));
5061cb0ef41Sopenharmony_ci
5071cb0ef41Sopenharmony_ci  if (instr->Bit(28) == 0) {
5081cb0ef41Sopenharmony_ci    DecodeNEONVectorDataProcessing(instr);
5091cb0ef41Sopenharmony_ci  } else {
5101cb0ef41Sopenharmony_ci    if (instr->Bits(31, 30) == 0x3) {
5111cb0ef41Sopenharmony_ci      V::VisitUnallocated(instr);
5121cb0ef41Sopenharmony_ci    } else if (instr->Bits(31, 30) == 0x1) {
5131cb0ef41Sopenharmony_ci      DecodeNEONScalarDataProcessing(instr);
5141cb0ef41Sopenharmony_ci    } else {
5151cb0ef41Sopenharmony_ci      if (instr->Bit(29) == 0) {
5161cb0ef41Sopenharmony_ci        if (instr->Bit(24) == 0) {
5171cb0ef41Sopenharmony_ci          if (instr->Bit(21) == 0) {
5181cb0ef41Sopenharmony_ci            if ((instr->Bit(23) == 1) || (instr->Bit(18) == 1) ||
5191cb0ef41Sopenharmony_ci                (instr->Mask(0x80008000) == 0x00000000) ||
5201cb0ef41Sopenharmony_ci                (instr->Mask(0x000E0000) == 0x00000000) ||
5211cb0ef41Sopenharmony_ci                (instr->Mask(0x000E0000) == 0x000A0000) ||
5221cb0ef41Sopenharmony_ci                (instr->Mask(0x00160000) == 0x00000000) ||
5231cb0ef41Sopenharmony_ci                (instr->Mask(0x00160000) == 0x00120000)) {
5241cb0ef41Sopenharmony_ci              V::VisitUnallocated(instr);
5251cb0ef41Sopenharmony_ci            } else {
5261cb0ef41Sopenharmony_ci              V::VisitFPFixedPointConvert(instr);
5271cb0ef41Sopenharmony_ci            }
5281cb0ef41Sopenharmony_ci          } else {
5291cb0ef41Sopenharmony_ci            if (instr->Bits(15, 10) == 32) {
5301cb0ef41Sopenharmony_ci              V::VisitUnallocated(instr);
5311cb0ef41Sopenharmony_ci            } else if (instr->Bits(15, 10) == 0) {
5321cb0ef41Sopenharmony_ci              if ((instr->Bits(23, 22) == 0x3) ||
5331cb0ef41Sopenharmony_ci                  (instr->Mask(0x000E0000) == 0x000A0000) ||
5341cb0ef41Sopenharmony_ci                  (instr->Mask(0x000E0000) == 0x000C0000) ||
5351cb0ef41Sopenharmony_ci                  (instr->Mask(0x00160000) == 0x00120000) ||
5361cb0ef41Sopenharmony_ci                  (instr->Mask(0x00160000) == 0x00140000) ||
5371cb0ef41Sopenharmony_ci                  (instr->Mask(0x20C40000) == 0x00800000) ||
5381cb0ef41Sopenharmony_ci                  (instr->Mask(0x20C60000) == 0x00840000) ||
5391cb0ef41Sopenharmony_ci                  (instr->Mask(0xA0C60000) == 0x80060000) ||
5401cb0ef41Sopenharmony_ci                  (instr->Mask(0xA0C60000) == 0x00860000) ||
5411cb0ef41Sopenharmony_ci                  (instr->Mask(0xA0CE0000) == 0x80860000) ||
5421cb0ef41Sopenharmony_ci                  (instr->Mask(0xA0CE0000) == 0x804E0000) ||
5431cb0ef41Sopenharmony_ci                  (instr->Mask(0xA0CE0000) == 0x000E0000) ||
5441cb0ef41Sopenharmony_ci                  (instr->Mask(0xA0D60000) == 0x00160000) ||
5451cb0ef41Sopenharmony_ci                  (instr->Mask(0xA0D60000) == 0x80560000) ||
5461cb0ef41Sopenharmony_ci                  (instr->Mask(0xA0D60000) == 0x80960000)) {
5471cb0ef41Sopenharmony_ci                V::VisitUnallocated(instr);
5481cb0ef41Sopenharmony_ci              } else {
5491cb0ef41Sopenharmony_ci                V::VisitFPIntegerConvert(instr);
5501cb0ef41Sopenharmony_ci              }
5511cb0ef41Sopenharmony_ci            } else if (instr->Bits(14, 10) == 16) {
5521cb0ef41Sopenharmony_ci              const Instr masked_A0DF8000 = instr->Mask(0xA0DF8000);
5531cb0ef41Sopenharmony_ci              if ((instr->Mask(0x80180000) != 0) ||
5541cb0ef41Sopenharmony_ci                  (masked_A0DF8000 == 0x00020000) ||
5551cb0ef41Sopenharmony_ci                  (masked_A0DF8000 == 0x00030000) ||
5561cb0ef41Sopenharmony_ci                  (masked_A0DF8000 == 0x00068000) ||
5571cb0ef41Sopenharmony_ci                  (masked_A0DF8000 == 0x00428000) ||
5581cb0ef41Sopenharmony_ci                  (masked_A0DF8000 == 0x00430000) ||
5591cb0ef41Sopenharmony_ci                  (masked_A0DF8000 == 0x00468000) ||
5601cb0ef41Sopenharmony_ci                  (instr->Mask(0xA0D80000) == 0x00800000) ||
5611cb0ef41Sopenharmony_ci                  (instr->Mask(0xA0DE0000) == 0x00C00000) ||
5621cb0ef41Sopenharmony_ci                  (instr->Mask(0xA0DF0000) == 0x00C30000) ||
5631cb0ef41Sopenharmony_ci                  (instr->Mask(0xA0DC0000) == 0x00C40000)) {
5641cb0ef41Sopenharmony_ci                V::VisitUnallocated(instr);
5651cb0ef41Sopenharmony_ci              } else {
5661cb0ef41Sopenharmony_ci                V::VisitFPDataProcessing1Source(instr);
5671cb0ef41Sopenharmony_ci              }
5681cb0ef41Sopenharmony_ci            } else if (instr->Bits(13, 10) == 8) {
5691cb0ef41Sopenharmony_ci              if ((instr->Bits(15, 14) != 0) || (instr->Bits(2, 0) != 0) ||
5701cb0ef41Sopenharmony_ci                  (instr->Mask(0x80800000) != 0x00000000)) {
5711cb0ef41Sopenharmony_ci                V::VisitUnallocated(instr);
5721cb0ef41Sopenharmony_ci              } else {
5731cb0ef41Sopenharmony_ci                V::VisitFPCompare(instr);
5741cb0ef41Sopenharmony_ci              }
5751cb0ef41Sopenharmony_ci            } else if (instr->Bits(12, 10) == 4) {
5761cb0ef41Sopenharmony_ci              if ((instr->Bits(9, 5) != 0) ||
5771cb0ef41Sopenharmony_ci                  (instr->Mask(0x80800000) != 0x00000000)) {
5781cb0ef41Sopenharmony_ci                V::VisitUnallocated(instr);
5791cb0ef41Sopenharmony_ci              } else {
5801cb0ef41Sopenharmony_ci                V::VisitFPImmediate(instr);
5811cb0ef41Sopenharmony_ci              }
5821cb0ef41Sopenharmony_ci            } else {
5831cb0ef41Sopenharmony_ci              if (instr->Mask(0x80800000) != 0x00000000) {
5841cb0ef41Sopenharmony_ci                V::VisitUnallocated(instr);
5851cb0ef41Sopenharmony_ci              } else {
5861cb0ef41Sopenharmony_ci                switch (instr->Bits(11, 10)) {
5871cb0ef41Sopenharmony_ci                  case 1: {
5881cb0ef41Sopenharmony_ci                    V::VisitFPConditionalCompare(instr);
5891cb0ef41Sopenharmony_ci                    break;
5901cb0ef41Sopenharmony_ci                  }
5911cb0ef41Sopenharmony_ci                  case 2: {
5921cb0ef41Sopenharmony_ci                    if ((instr->Bits(15, 14) == 0x3) ||
5931cb0ef41Sopenharmony_ci                        (instr->Mask(0x00009000) == 0x00009000) ||
5941cb0ef41Sopenharmony_ci                        (instr->Mask(0x0000A000) == 0x0000A000)) {
5951cb0ef41Sopenharmony_ci                      V::VisitUnallocated(instr);
5961cb0ef41Sopenharmony_ci                    } else {
5971cb0ef41Sopenharmony_ci                      V::VisitFPDataProcessing2Source(instr);
5981cb0ef41Sopenharmony_ci                    }
5991cb0ef41Sopenharmony_ci                    break;
6001cb0ef41Sopenharmony_ci                  }
6011cb0ef41Sopenharmony_ci                  case 3: {
6021cb0ef41Sopenharmony_ci                    V::VisitFPConditionalSelect(instr);
6031cb0ef41Sopenharmony_ci                    break;
6041cb0ef41Sopenharmony_ci                  }
6051cb0ef41Sopenharmony_ci                  default:
6061cb0ef41Sopenharmony_ci                    UNREACHABLE();
6071cb0ef41Sopenharmony_ci                }
6081cb0ef41Sopenharmony_ci              }
6091cb0ef41Sopenharmony_ci            }
6101cb0ef41Sopenharmony_ci          }
6111cb0ef41Sopenharmony_ci        } else {
6121cb0ef41Sopenharmony_ci          // Bit 30 == 1 has been handled earlier.
6131cb0ef41Sopenharmony_ci          DCHECK_EQ(0, instr->Bit(30));
6141cb0ef41Sopenharmony_ci          if (instr->Mask(0xA0800000) != 0) {
6151cb0ef41Sopenharmony_ci            V::VisitUnallocated(instr);
6161cb0ef41Sopenharmony_ci          } else {
6171cb0ef41Sopenharmony_ci            V::VisitFPDataProcessing3Source(instr);
6181cb0ef41Sopenharmony_ci          }
6191cb0ef41Sopenharmony_ci        }
6201cb0ef41Sopenharmony_ci      } else {
6211cb0ef41Sopenharmony_ci        V::VisitUnallocated(instr);
6221cb0ef41Sopenharmony_ci      }
6231cb0ef41Sopenharmony_ci    }
6241cb0ef41Sopenharmony_ci  }
6251cb0ef41Sopenharmony_ci}
6261cb0ef41Sopenharmony_ci
6271cb0ef41Sopenharmony_citemplate <typename V>
6281cb0ef41Sopenharmony_civoid Decoder<V>::DecodeNEONLoadStore(Instruction* instr) {
6291cb0ef41Sopenharmony_ci  DCHECK_EQ(0x6, instr->Bits(29, 25));
6301cb0ef41Sopenharmony_ci  if (instr->Bit(31) == 0) {
6311cb0ef41Sopenharmony_ci    if ((instr->Bit(24) == 0) && (instr->Bit(21) == 1)) {
6321cb0ef41Sopenharmony_ci      V::VisitUnallocated(instr);
6331cb0ef41Sopenharmony_ci      return;
6341cb0ef41Sopenharmony_ci    }
6351cb0ef41Sopenharmony_ci
6361cb0ef41Sopenharmony_ci    if (instr->Bit(23) == 0) {
6371cb0ef41Sopenharmony_ci      if (instr->Bits(20, 16) == 0) {
6381cb0ef41Sopenharmony_ci        if (instr->Bit(24) == 0) {
6391cb0ef41Sopenharmony_ci          V::VisitNEONLoadStoreMultiStruct(instr);
6401cb0ef41Sopenharmony_ci        } else {
6411cb0ef41Sopenharmony_ci          V::VisitNEONLoadStoreSingleStruct(instr);
6421cb0ef41Sopenharmony_ci        }
6431cb0ef41Sopenharmony_ci      } else {
6441cb0ef41Sopenharmony_ci        V::VisitUnallocated(instr);
6451cb0ef41Sopenharmony_ci      }
6461cb0ef41Sopenharmony_ci    } else {
6471cb0ef41Sopenharmony_ci      if (instr->Bit(24) == 0) {
6481cb0ef41Sopenharmony_ci        V::VisitNEONLoadStoreMultiStructPostIndex(instr);
6491cb0ef41Sopenharmony_ci      } else {
6501cb0ef41Sopenharmony_ci        V::VisitNEONLoadStoreSingleStructPostIndex(instr);
6511cb0ef41Sopenharmony_ci      }
6521cb0ef41Sopenharmony_ci    }
6531cb0ef41Sopenharmony_ci  } else {
6541cb0ef41Sopenharmony_ci    V::VisitUnallocated(instr);
6551cb0ef41Sopenharmony_ci  }
6561cb0ef41Sopenharmony_ci}
6571cb0ef41Sopenharmony_ci
6581cb0ef41Sopenharmony_citemplate <typename V>
6591cb0ef41Sopenharmony_civoid Decoder<V>::DecodeNEONVectorDataProcessing(Instruction* instr) {
6601cb0ef41Sopenharmony_ci  DCHECK_EQ(0x7, instr->Bits(28, 25));
6611cb0ef41Sopenharmony_ci  if (instr->Bit(31) == 0) {
6621cb0ef41Sopenharmony_ci    if (instr->Bit(24) == 0) {
6631cb0ef41Sopenharmony_ci      if (instr->Bit(21) == 0) {
6641cb0ef41Sopenharmony_ci        if (instr->Bit(15) == 0) {
6651cb0ef41Sopenharmony_ci          if (instr->Bit(10) == 0) {
6661cb0ef41Sopenharmony_ci            if (instr->Bit(29) == 0) {
6671cb0ef41Sopenharmony_ci              if (instr->Bit(11) == 0) {
6681cb0ef41Sopenharmony_ci                V::VisitNEONTable(instr);
6691cb0ef41Sopenharmony_ci              } else {
6701cb0ef41Sopenharmony_ci                V::VisitNEONPerm(instr);
6711cb0ef41Sopenharmony_ci              }
6721cb0ef41Sopenharmony_ci            } else {
6731cb0ef41Sopenharmony_ci              V::VisitNEONExtract(instr);
6741cb0ef41Sopenharmony_ci            }
6751cb0ef41Sopenharmony_ci          } else {
6761cb0ef41Sopenharmony_ci            if (instr->Bits(23, 22) == 0) {
6771cb0ef41Sopenharmony_ci              V::VisitNEONCopy(instr);
6781cb0ef41Sopenharmony_ci            } else {
6791cb0ef41Sopenharmony_ci              V::VisitUnallocated(instr);
6801cb0ef41Sopenharmony_ci            }
6811cb0ef41Sopenharmony_ci          }
6821cb0ef41Sopenharmony_ci        } else {
6831cb0ef41Sopenharmony_ci          V::VisitUnallocated(instr);
6841cb0ef41Sopenharmony_ci        }
6851cb0ef41Sopenharmony_ci      } else {
6861cb0ef41Sopenharmony_ci        if (instr->Bit(10) == 0) {
6871cb0ef41Sopenharmony_ci          if (instr->Bit(11) == 0) {
6881cb0ef41Sopenharmony_ci            V::VisitNEON3Different(instr);
6891cb0ef41Sopenharmony_ci          } else {
6901cb0ef41Sopenharmony_ci            if (instr->Bits(18, 17) == 0) {
6911cb0ef41Sopenharmony_ci              if (instr->Bit(20) == 0) {
6921cb0ef41Sopenharmony_ci                if (instr->Bit(19) == 0) {
6931cb0ef41Sopenharmony_ci                  V::VisitNEON2RegMisc(instr);
6941cb0ef41Sopenharmony_ci                } else {
6951cb0ef41Sopenharmony_ci                  if (instr->Bits(30, 29) == 0x2) {
6961cb0ef41Sopenharmony_ci                    V::VisitUnallocated(instr);
6971cb0ef41Sopenharmony_ci                  } else {
6981cb0ef41Sopenharmony_ci                    V::VisitUnallocated(instr);
6991cb0ef41Sopenharmony_ci                  }
7001cb0ef41Sopenharmony_ci                }
7011cb0ef41Sopenharmony_ci              } else {
7021cb0ef41Sopenharmony_ci                if (instr->Bit(19) == 0) {
7031cb0ef41Sopenharmony_ci                  V::VisitNEONAcrossLanes(instr);
7041cb0ef41Sopenharmony_ci                } else {
7051cb0ef41Sopenharmony_ci                  V::VisitUnallocated(instr);
7061cb0ef41Sopenharmony_ci                }
7071cb0ef41Sopenharmony_ci              }
7081cb0ef41Sopenharmony_ci            } else {
7091cb0ef41Sopenharmony_ci              V::VisitUnallocated(instr);
7101cb0ef41Sopenharmony_ci            }
7111cb0ef41Sopenharmony_ci          }
7121cb0ef41Sopenharmony_ci        } else {
7131cb0ef41Sopenharmony_ci          V::VisitNEON3Same(instr);
7141cb0ef41Sopenharmony_ci        }
7151cb0ef41Sopenharmony_ci      }
7161cb0ef41Sopenharmony_ci    } else {
7171cb0ef41Sopenharmony_ci      if (instr->Bit(10) == 0) {
7181cb0ef41Sopenharmony_ci        V::VisitNEONByIndexedElement(instr);
7191cb0ef41Sopenharmony_ci      } else {
7201cb0ef41Sopenharmony_ci        if (instr->Bit(23) == 0) {
7211cb0ef41Sopenharmony_ci          if (instr->Bits(22, 19) == 0) {
7221cb0ef41Sopenharmony_ci            V::VisitNEONModifiedImmediate(instr);
7231cb0ef41Sopenharmony_ci          } else {
7241cb0ef41Sopenharmony_ci            V::VisitNEONShiftImmediate(instr);
7251cb0ef41Sopenharmony_ci          }
7261cb0ef41Sopenharmony_ci        } else {
7271cb0ef41Sopenharmony_ci          V::VisitUnallocated(instr);
7281cb0ef41Sopenharmony_ci        }
7291cb0ef41Sopenharmony_ci      }
7301cb0ef41Sopenharmony_ci    }
7311cb0ef41Sopenharmony_ci  } else {
7321cb0ef41Sopenharmony_ci    V::VisitUnallocated(instr);
7331cb0ef41Sopenharmony_ci  }
7341cb0ef41Sopenharmony_ci}
7351cb0ef41Sopenharmony_ci
7361cb0ef41Sopenharmony_citemplate <typename V>
7371cb0ef41Sopenharmony_civoid Decoder<V>::DecodeNEONScalarDataProcessing(Instruction* instr) {
7381cb0ef41Sopenharmony_ci  DCHECK_EQ(0xF, instr->Bits(28, 25));
7391cb0ef41Sopenharmony_ci  if (instr->Bit(24) == 0) {
7401cb0ef41Sopenharmony_ci    if (instr->Bit(21) == 0) {
7411cb0ef41Sopenharmony_ci      if (instr->Bit(15) == 0) {
7421cb0ef41Sopenharmony_ci        if (instr->Bit(10) == 0) {
7431cb0ef41Sopenharmony_ci          if (instr->Bit(29) == 0) {
7441cb0ef41Sopenharmony_ci            if (instr->Bit(11) == 0) {
7451cb0ef41Sopenharmony_ci              V::VisitUnallocated(instr);
7461cb0ef41Sopenharmony_ci            } else {
7471cb0ef41Sopenharmony_ci              V::VisitUnallocated(instr);
7481cb0ef41Sopenharmony_ci            }
7491cb0ef41Sopenharmony_ci          } else {
7501cb0ef41Sopenharmony_ci            V::VisitUnallocated(instr);
7511cb0ef41Sopenharmony_ci          }
7521cb0ef41Sopenharmony_ci        } else {
7531cb0ef41Sopenharmony_ci          if (instr->Bits(23, 22) == 0) {
7541cb0ef41Sopenharmony_ci            V::VisitNEONScalarCopy(instr);
7551cb0ef41Sopenharmony_ci          } else {
7561cb0ef41Sopenharmony_ci            V::VisitUnallocated(instr);
7571cb0ef41Sopenharmony_ci          }
7581cb0ef41Sopenharmony_ci        }
7591cb0ef41Sopenharmony_ci      } else {
7601cb0ef41Sopenharmony_ci        V::VisitUnallocated(instr);
7611cb0ef41Sopenharmony_ci      }
7621cb0ef41Sopenharmony_ci    } else {
7631cb0ef41Sopenharmony_ci      if (instr->Bit(10) == 0) {
7641cb0ef41Sopenharmony_ci        if (instr->Bit(11) == 0) {
7651cb0ef41Sopenharmony_ci          V::VisitNEONScalar3Diff(instr);
7661cb0ef41Sopenharmony_ci        } else {
7671cb0ef41Sopenharmony_ci          if (instr->Bits(18, 17) == 0) {
7681cb0ef41Sopenharmony_ci            if (instr->Bit(20) == 0) {
7691cb0ef41Sopenharmony_ci              if (instr->Bit(19) == 0) {
7701cb0ef41Sopenharmony_ci                V::VisitNEONScalar2RegMisc(instr);
7711cb0ef41Sopenharmony_ci              } else {
7721cb0ef41Sopenharmony_ci                if (instr->Bit(29) == 0) {
7731cb0ef41Sopenharmony_ci                  V::VisitUnallocated(instr);
7741cb0ef41Sopenharmony_ci                } else {
7751cb0ef41Sopenharmony_ci                  V::VisitUnallocated(instr);
7761cb0ef41Sopenharmony_ci                }
7771cb0ef41Sopenharmony_ci              }
7781cb0ef41Sopenharmony_ci            } else {
7791cb0ef41Sopenharmony_ci              if (instr->Bit(19) == 0) {
7801cb0ef41Sopenharmony_ci                V::VisitNEONScalarPairwise(instr);
7811cb0ef41Sopenharmony_ci              } else {
7821cb0ef41Sopenharmony_ci                V::VisitUnallocated(instr);
7831cb0ef41Sopenharmony_ci              }
7841cb0ef41Sopenharmony_ci            }
7851cb0ef41Sopenharmony_ci          } else {
7861cb0ef41Sopenharmony_ci            V::VisitUnallocated(instr);
7871cb0ef41Sopenharmony_ci          }
7881cb0ef41Sopenharmony_ci        }
7891cb0ef41Sopenharmony_ci      } else {
7901cb0ef41Sopenharmony_ci        V::VisitNEONScalar3Same(instr);
7911cb0ef41Sopenharmony_ci      }
7921cb0ef41Sopenharmony_ci    }
7931cb0ef41Sopenharmony_ci  } else {
7941cb0ef41Sopenharmony_ci    if (instr->Bit(10) == 0) {
7951cb0ef41Sopenharmony_ci      V::VisitNEONScalarByIndexedElement(instr);
7961cb0ef41Sopenharmony_ci    } else {
7971cb0ef41Sopenharmony_ci      if (instr->Bit(23) == 0) {
7981cb0ef41Sopenharmony_ci        V::VisitNEONScalarShiftImmediate(instr);
7991cb0ef41Sopenharmony_ci      } else {
8001cb0ef41Sopenharmony_ci        V::VisitUnallocated(instr);
8011cb0ef41Sopenharmony_ci      }
8021cb0ef41Sopenharmony_ci    }
8031cb0ef41Sopenharmony_ci  }
8041cb0ef41Sopenharmony_ci}
8051cb0ef41Sopenharmony_ci
8061cb0ef41Sopenharmony_ci}  // namespace internal
8071cb0ef41Sopenharmony_ci}  // namespace v8
8081cb0ef41Sopenharmony_ci
8091cb0ef41Sopenharmony_ci#endif  // V8_CODEGEN_ARM64_DECODER_ARM64_INL_H_
810