Home | History | Annotate | Download | only in arm64
      1 // Copyright 2014 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef V8_ARM64_DECODER_ARM64_INL_H_
      6 #define V8_ARM64_DECODER_ARM64_INL_H_
      7 
      8 #include "src/arm64/decoder-arm64.h"
      9 #include "src/globals.h"
     10 #include "src/utils.h"
     11 
     12 
     13 namespace v8 {
     14 namespace internal {
     15 
     16 
     17 // Top-level instruction decode function.
     18 template<typename V>
     19 void Decoder<V>::Decode(Instruction *instr) {
     20   if (instr->Bits(28, 27) == 0) {
     21     V::VisitUnallocated(instr);
     22   } else {
     23     switch (instr->Bits(27, 24)) {
     24       // 0:   PC relative addressing.
     25       case 0x0: DecodePCRelAddressing(instr); break;
     26 
     27       // 1:   Add/sub immediate.
     28       case 0x1: DecodeAddSubImmediate(instr); break;
     29 
     30       // A:   Logical shifted register.
     31       //      Add/sub with carry.
     32       //      Conditional compare register.
     33       //      Conditional compare immediate.
     34       //      Conditional select.
     35       //      Data processing 1 source.
     36       //      Data processing 2 source.
     37       // B:   Add/sub shifted register.
     38       //      Add/sub extended register.
     39       //      Data processing 3 source.
     40       case 0xA:
     41       case 0xB: DecodeDataProcessing(instr); break;
     42 
     43       // 2:   Logical immediate.
     44       //      Move wide immediate.
     45       case 0x2: DecodeLogical(instr); break;
     46 
     47       // 3:   Bitfield.
     48       //      Extract.
     49       case 0x3: DecodeBitfieldExtract(instr); break;
     50 
     51       // 4:   Unconditional branch immediate.
     52       //      Exception generation.
     53       //      Compare and branch immediate.
     54       // 5:   Compare and branch immediate.
     55       //      Conditional branch.
     56       //      System.
     57       // 6,7: Unconditional branch.
     58       //      Test and branch immediate.
     59       case 0x4:
     60       case 0x5:
     61       case 0x6:
     62       case 0x7: DecodeBranchSystemException(instr); break;
     63 
     64       // 8,9: Load/store register pair post-index.
     65       //      Load register literal.
     66       //      Load/store register unscaled immediate.
     67       //      Load/store register immediate post-index.
     68       //      Load/store register immediate pre-index.
     69       //      Load/store register offset.
     70       // C,D: Load/store register pair offset.
     71       //      Load/store register pair pre-index.
     72       //      Load/store register unsigned immediate.
     73       //      Advanced SIMD.
     74       case 0x8:
     75       case 0x9:
     76       case 0xC:
     77       case 0xD: DecodeLoadStore(instr); break;
     78 
     79       // E:   FP fixed point conversion.
     80       //      FP integer conversion.
     81       //      FP data processing 1 source.
     82       //      FP compare.
     83       //      FP immediate.
     84       //      FP data processing 2 source.
     85       //      FP conditional compare.
     86       //      FP conditional select.
     87       //      Advanced SIMD.
     88       // F:   FP data processing 3 source.
     89       //      Advanced SIMD.
     90       case 0xE:
     91       case 0xF: DecodeFP(instr); break;
     92     }
     93   }
     94 }
     95 
     96 
     97 template<typename V>
     98 void Decoder<V>::DecodePCRelAddressing(Instruction* instr) {
     99   DCHECK(instr->Bits(27, 24) == 0x0);
    100   // We know bit 28 is set, as <b28:b27> = 0 is filtered out at the top level
    101   // decode.
    102   DCHECK(instr->Bit(28) == 0x1);
    103   V::VisitPCRelAddressing(instr);
    104 }
    105 
    106 
    107 template<typename V>
    108 void Decoder<V>::DecodeBranchSystemException(Instruction* instr) {
    109   DCHECK((instr->Bits(27, 24) == 0x4) ||
    110          (instr->Bits(27, 24) == 0x5) ||
    111          (instr->Bits(27, 24) == 0x6) ||
    112          (instr->Bits(27, 24) == 0x7) );
    113 
    114   switch (instr->Bits(31, 29)) {
    115     case 0:
    116     case 4: {
    117       V::VisitUnconditionalBranch(instr);
    118       break;
    119     }
    120     case 1:
    121     case 5: {
    122       if (instr->Bit(25) == 0) {
    123         V::VisitCompareBranch(instr);
    124       } else {
    125         V::VisitTestBranch(instr);
    126       }
    127       break;
    128     }
    129     case 2: {
    130       if (instr->Bit(25) == 0) {
    131         if ((instr->Bit(24) == 0x1) ||
    132             (instr->Mask(0x01000010) == 0x00000010)) {
    133           V::VisitUnallocated(instr);
    134         } else {
    135           V::VisitConditionalBranch(instr);
    136         }
    137       } else {
    138         V::VisitUnallocated(instr);
    139       }
    140       break;
    141     }
    142     case 6: {
    143       if (instr->Bit(25) == 0) {
    144         if (instr->Bit(24) == 0) {
    145           if ((instr->Bits(4, 2) != 0) ||
    146               (instr->Mask(0x00E0001D) == 0x00200001) ||
    147               (instr->Mask(0x00E0001D) == 0x00400001) ||
    148               (instr->Mask(0x00E0001E) == 0x00200002) ||
    149               (instr->Mask(0x00E0001E) == 0x00400002) ||
    150               (instr->Mask(0x00E0001C) == 0x00600000) ||
    151               (instr->Mask(0x00E0001C) == 0x00800000) ||
    152               (instr->Mask(0x00E0001F) == 0x00A00000) ||
    153               (instr->Mask(0x00C0001C) == 0x00C00000)) {
    154             V::VisitUnallocated(instr);
    155           } else {
    156             V::VisitException(instr);
    157           }
    158         } else {
    159           if (instr->Bits(23, 22) == 0) {
    160             const Instr masked_003FF0E0 = instr->Mask(0x003FF0E0);
    161             if ((instr->Bits(21, 19) == 0x4) ||
    162                 (masked_003FF0E0 == 0x00033000) ||
    163                 (masked_003FF0E0 == 0x003FF020) ||
    164                 (masked_003FF0E0 == 0x003FF060) ||
    165                 (masked_003FF0E0 == 0x003FF0E0) ||
    166                 (instr->Mask(0x00388000) == 0x00008000) ||
    167                 (instr->Mask(0x0038E000) == 0x00000000) ||
    168                 (instr->Mask(0x0039E000) == 0x00002000) ||
    169                 (instr->Mask(0x003AE000) == 0x00002000) ||
    170                 (instr->Mask(0x003CE000) == 0x00042000) ||
    171                 (instr->Mask(0x003FFFC0) == 0x000320C0) ||
    172                 (instr->Mask(0x003FF100) == 0x00032100) ||
    173                 (instr->Mask(0x003FF200) == 0x00032200) ||
    174                 (instr->Mask(0x003FF400) == 0x00032400) ||
    175                 (instr->Mask(0x003FF800) == 0x00032800) ||
    176                 (instr->Mask(0x0038F000) == 0x00005000) ||
    177                 (instr->Mask(0x0038E000) == 0x00006000)) {
    178               V::VisitUnallocated(instr);
    179             } else {
    180               V::VisitSystem(instr);
    181             }
    182           } else {
    183             V::VisitUnallocated(instr);
    184           }
    185         }
    186       } else {
    187         if ((instr->Bit(24) == 0x1) ||
    188             (instr->Bits(20, 16) != 0x1F) ||
    189             (instr->Bits(15, 10) != 0) ||
    190             (instr->Bits(4, 0) != 0) ||
    191             (instr->Bits(24, 21) == 0x3) ||
    192             (instr->Bits(24, 22) == 0x3)) {
    193           V::VisitUnallocated(instr);
    194         } else {
    195           V::VisitUnconditionalBranchToRegister(instr);
    196         }
    197       }
    198       break;
    199     }
    200     case 3:
    201     case 7: {
    202       V::VisitUnallocated(instr);
    203       break;
    204     }
    205   }
    206 }
    207 
    208 
    209 template<typename V>
    210 void Decoder<V>::DecodeLoadStore(Instruction* instr) {
    211   DCHECK((instr->Bits(27, 24) == 0x8) ||
    212          (instr->Bits(27, 24) == 0x9) ||
    213          (instr->Bits(27, 24) == 0xC) ||
    214          (instr->Bits(27, 24) == 0xD) );
    215 
    216   if (instr->Bit(24) == 0) {
    217     if (instr->Bit(28) == 0) {
    218       if (instr->Bit(29) == 0) {
    219         if (instr->Bit(26) == 0) {
    220           if (instr->Mask(0xA08000) == 0x800000 ||
    221               instr->Mask(0xA00000) == 0xA00000) {
    222             V::VisitUnallocated(instr);
    223           } else if (instr->Mask(0x808000) == 0) {
    224             // Load/Store exclusive without acquire/release are unimplemented.
    225             V::VisitUnimplemented(instr);
    226           } else {
    227             V::VisitLoadStoreAcquireRelease(instr);
    228           }
    229         } else {
    230           DecodeAdvSIMDLoadStore(instr);
    231         }
    232       } else {
    233         if ((instr->Bits(31, 30) == 0x3) ||
    234             (instr->Mask(0xC4400000) == 0x40000000)) {
    235           V::VisitUnallocated(instr);
    236         } else {
    237           if (instr->Bit(23) == 0) {
    238             if (instr->Mask(0xC4400000) == 0xC0400000) {
    239               V::VisitUnallocated(instr);
    240             } else {
    241               // Nontemporals are unimplemented.
    242               V::VisitUnimplemented(instr);
    243             }
    244           } else {
    245             V::VisitLoadStorePairPostIndex(instr);
    246           }
    247         }
    248       }
    249     } else {
    250       if (instr->Bit(29) == 0) {
    251         if (instr->Mask(0xC4000000) == 0xC4000000) {
    252           V::VisitUnallocated(instr);
    253         } else {
    254           V::VisitLoadLiteral(instr);
    255         }
    256       } else {
    257         if ((instr->Mask(0x84C00000) == 0x80C00000) ||
    258             (instr->Mask(0x44800000) == 0x44800000) ||
    259             (instr->Mask(0x84800000) == 0x84800000)) {
    260           V::VisitUnallocated(instr);
    261         } else {
    262           if (instr->Bit(21) == 0) {
    263             switch (instr->Bits(11, 10)) {
    264               case 0: {
    265                 V::VisitLoadStoreUnscaledOffset(instr);
    266                 break;
    267               }
    268               case 1: {
    269                 if (instr->Mask(0xC4C00000) == 0xC0800000) {
    270                   V::VisitUnallocated(instr);
    271                 } else {
    272                   V::VisitLoadStorePostIndex(instr);
    273                 }
    274                 break;
    275               }
    276               case 2: {
    277                 // TODO(all): VisitLoadStoreRegisterOffsetUnpriv.
    278                 V::VisitUnimplemented(instr);
    279                 break;
    280               }
    281               case 3: {
    282                 if (instr->Mask(0xC4C00000) == 0xC0800000) {
    283                   V::VisitUnallocated(instr);
    284                 } else {
    285                   V::VisitLoadStorePreIndex(instr);
    286                 }
    287                 break;
    288               }
    289             }
    290           } else {
    291             if (instr->Bits(11, 10) == 0x2) {
    292               if (instr->Bit(14) == 0) {
    293                 V::VisitUnallocated(instr);
    294               } else {
    295                 V::VisitLoadStoreRegisterOffset(instr);
    296               }
    297             } else {
    298               V::VisitUnallocated(instr);
    299             }
    300           }
    301         }
    302       }
    303     }
    304   } else {
    305     if (instr->Bit(28) == 0) {
    306       if (instr->Bit(29) == 0) {
    307         V::VisitUnallocated(instr);
    308       } else {
    309         if ((instr->Bits(31, 30) == 0x3) ||
    310             (instr->Mask(0xC4400000) == 0x40000000)) {
    311           V::VisitUnallocated(instr);
    312         } else {
    313           if (instr->Bit(23) == 0) {
    314             V::VisitLoadStorePairOffset(instr);
    315           } else {
    316             V::VisitLoadStorePairPreIndex(instr);
    317           }
    318         }
    319       }
    320     } else {
    321       if (instr->Bit(29) == 0) {
    322         V::VisitUnallocated(instr);
    323       } else {
    324         if ((instr->Mask(0x84C00000) == 0x80C00000) ||
    325             (instr->Mask(0x44800000) == 0x44800000) ||
    326             (instr->Mask(0x84800000) == 0x84800000)) {
    327           V::VisitUnallocated(instr);
    328         } else {
    329           V::VisitLoadStoreUnsignedOffset(instr);
    330         }
    331       }
    332     }
    333   }
    334 }
    335 
    336 
    337 template<typename V>
    338 void Decoder<V>::DecodeLogical(Instruction* instr) {
    339   DCHECK(instr->Bits(27, 24) == 0x2);
    340 
    341   if (instr->Mask(0x80400000) == 0x00400000) {
    342     V::VisitUnallocated(instr);
    343   } else {
    344     if (instr->Bit(23) == 0) {
    345       V::VisitLogicalImmediate(instr);
    346     } else {
    347       if (instr->Bits(30, 29) == 0x1) {
    348         V::VisitUnallocated(instr);
    349       } else {
    350         V::VisitMoveWideImmediate(instr);
    351       }
    352     }
    353   }
    354 }
    355 
    356 
    357 template<typename V>
    358 void Decoder<V>::DecodeBitfieldExtract(Instruction* instr) {
    359   DCHECK(instr->Bits(27, 24) == 0x3);
    360 
    361   if ((instr->Mask(0x80400000) == 0x80000000) ||
    362       (instr->Mask(0x80400000) == 0x00400000) ||
    363       (instr->Mask(0x80008000) == 0x00008000)) {
    364     V::VisitUnallocated(instr);
    365   } else if (instr->Bit(23) == 0) {
    366     if ((instr->Mask(0x80200000) == 0x00200000) ||
    367         (instr->Mask(0x60000000) == 0x60000000)) {
    368       V::VisitUnallocated(instr);
    369     } else {
    370       V::VisitBitfield(instr);
    371     }
    372   } else {
    373     if ((instr->Mask(0x60200000) == 0x00200000) ||
    374         (instr->Mask(0x60000000) != 0x00000000)) {
    375       V::VisitUnallocated(instr);
    376     } else {
    377       V::VisitExtract(instr);
    378     }
    379   }
    380 }
    381 
    382 
    383 template<typename V>
    384 void Decoder<V>::DecodeAddSubImmediate(Instruction* instr) {
    385   DCHECK(instr->Bits(27, 24) == 0x1);
    386   if (instr->Bit(23) == 1) {
    387     V::VisitUnallocated(instr);
    388   } else {
    389     V::VisitAddSubImmediate(instr);
    390   }
    391 }
    392 
    393 
    394 template<typename V>
    395 void Decoder<V>::DecodeDataProcessing(Instruction* instr) {
    396   DCHECK((instr->Bits(27, 24) == 0xA) ||
    397          (instr->Bits(27, 24) == 0xB) );
    398 
    399   if (instr->Bit(24) == 0) {
    400     if (instr->Bit(28) == 0) {
    401       if (instr->Mask(0x80008000) == 0x00008000) {
    402         V::VisitUnallocated(instr);
    403       } else {
    404         V::VisitLogicalShifted(instr);
    405       }
    406     } else {
    407       switch (instr->Bits(23, 21)) {
    408         case 0: {
    409           if (instr->Mask(0x0000FC00) != 0) {
    410             V::VisitUnallocated(instr);
    411           } else {
    412             V::VisitAddSubWithCarry(instr);
    413           }
    414           break;
    415         }
    416         case 2: {
    417           if ((instr->Bit(29) == 0) ||
    418               (instr->Mask(0x00000410) != 0)) {
    419             V::VisitUnallocated(instr);
    420           } else {
    421             if (instr->Bit(11) == 0) {
    422               V::VisitConditionalCompareRegister(instr);
    423             } else {
    424               V::VisitConditionalCompareImmediate(instr);
    425             }
    426           }
    427           break;
    428         }
    429         case 4: {
    430           if (instr->Mask(0x20000800) != 0x00000000) {
    431             V::VisitUnallocated(instr);
    432           } else {
    433             V::VisitConditionalSelect(instr);
    434           }
    435           break;
    436         }
    437         case 6: {
    438           if (instr->Bit(29) == 0x1) {
    439             V::VisitUnallocated(instr);
    440           } else {
    441             if (instr->Bit(30) == 0) {
    442               if ((instr->Bit(15) == 0x1) ||
    443                   (instr->Bits(15, 11) == 0) ||
    444                   (instr->Bits(15, 12) == 0x1) ||
    445                   (instr->Bits(15, 12) == 0x3) ||
    446                   (instr->Bits(15, 13) == 0x3) ||
    447                   (instr->Mask(0x8000EC00) == 0x00004C00) ||
    448                   (instr->Mask(0x8000E800) == 0x80004000) ||
    449                   (instr->Mask(0x8000E400) == 0x80004000)) {
    450                 V::VisitUnallocated(instr);
    451               } else {
    452                 V::VisitDataProcessing2Source(instr);
    453               }
    454             } else {
    455               if ((instr->Bit(13) == 1) ||
    456                   (instr->Bits(20, 16) != 0) ||
    457                   (instr->Bits(15, 14) != 0) ||
    458                   (instr->Mask(0xA01FFC00) == 0x00000C00) ||
    459                   (instr->Mask(0x201FF800) == 0x00001800)) {
    460                 V::VisitUnallocated(instr);
    461               } else {
    462                 V::VisitDataProcessing1Source(instr);
    463               }
    464             }
    465             break;
    466           }
    467         }
    468         case 1:
    469         case 3:
    470         case 5:
    471         case 7: V::VisitUnallocated(instr); break;
    472       }
    473     }
    474   } else {
    475     if (instr->Bit(28) == 0) {
    476      if (instr->Bit(21) == 0) {
    477         if ((instr->Bits(23, 22) == 0x3) ||
    478             (instr->Mask(0x80008000) == 0x00008000)) {
    479           V::VisitUnallocated(instr);
    480         } else {
    481           V::VisitAddSubShifted(instr);
    482         }
    483       } else {
    484         if ((instr->Mask(0x00C00000) != 0x00000000) ||
    485             (instr->Mask(0x00001400) == 0x00001400) ||
    486             (instr->Mask(0x00001800) == 0x00001800)) {
    487           V::VisitUnallocated(instr);
    488         } else {
    489           V::VisitAddSubExtended(instr);
    490         }
    491       }
    492     } else {
    493       if ((instr->Bit(30) == 0x1) ||
    494           (instr->Bits(30, 29) == 0x1) ||
    495           (instr->Mask(0xE0600000) == 0x00200000) ||
    496           (instr->Mask(0xE0608000) == 0x00400000) ||
    497           (instr->Mask(0x60608000) == 0x00408000) ||
    498           (instr->Mask(0x60E00000) == 0x00E00000) ||
    499           (instr->Mask(0x60E00000) == 0x00800000) ||
    500           (instr->Mask(0x60E00000) == 0x00600000)) {
    501         V::VisitUnallocated(instr);
    502       } else {
    503         V::VisitDataProcessing3Source(instr);
    504       }
    505     }
    506   }
    507 }
    508 
    509 
    510 template<typename V>
    511 void Decoder<V>::DecodeFP(Instruction* instr) {
    512   DCHECK((instr->Bits(27, 24) == 0xE) ||
    513          (instr->Bits(27, 24) == 0xF) );
    514 
    515   if (instr->Bit(28) == 0) {
    516     DecodeAdvSIMDDataProcessing(instr);
    517   } else {
    518     if (instr->Bit(29) == 1) {
    519       V::VisitUnallocated(instr);
    520     } else {
    521       if (instr->Bits(31, 30) == 0x3) {
    522         V::VisitUnallocated(instr);
    523       } else if (instr->Bits(31, 30) == 0x1) {
    524         DecodeAdvSIMDDataProcessing(instr);
    525       } else {
    526         if (instr->Bit(24) == 0) {
    527           if (instr->Bit(21) == 0) {
    528             if ((instr->Bit(23) == 1) ||
    529                 (instr->Bit(18) == 1) ||
    530                 (instr->Mask(0x80008000) == 0x00000000) ||
    531                 (instr->Mask(0x000E0000) == 0x00000000) ||
    532                 (instr->Mask(0x000E0000) == 0x000A0000) ||
    533                 (instr->Mask(0x00160000) == 0x00000000) ||
    534                 (instr->Mask(0x00160000) == 0x00120000)) {
    535               V::VisitUnallocated(instr);
    536             } else {
    537               V::VisitFPFixedPointConvert(instr);
    538             }
    539           } else {
    540             if (instr->Bits(15, 10) == 32) {
    541               V::VisitUnallocated(instr);
    542             } else if (instr->Bits(15, 10) == 0) {
    543               if ((instr->Bits(23, 22) == 0x3) ||
    544                   (instr->Mask(0x000E0000) == 0x000A0000) ||
    545                   (instr->Mask(0x000E0000) == 0x000C0000) ||
    546                   (instr->Mask(0x00160000) == 0x00120000) ||
    547                   (instr->Mask(0x00160000) == 0x00140000) ||
    548                   (instr->Mask(0x20C40000) == 0x00800000) ||
    549                   (instr->Mask(0x20C60000) == 0x00840000) ||
    550                   (instr->Mask(0xA0C60000) == 0x80060000) ||
    551                   (instr->Mask(0xA0C60000) == 0x00860000) ||
    552                   (instr->Mask(0xA0C60000) == 0x00460000) ||
    553                   (instr->Mask(0xA0CE0000) == 0x80860000) ||
    554                   (instr->Mask(0xA0CE0000) == 0x804E0000) ||
    555                   (instr->Mask(0xA0CE0000) == 0x000E0000) ||
    556                   (instr->Mask(0xA0D60000) == 0x00160000) ||
    557                   (instr->Mask(0xA0D60000) == 0x80560000) ||
    558                   (instr->Mask(0xA0D60000) == 0x80960000)) {
    559                 V::VisitUnallocated(instr);
    560               } else {
    561                 V::VisitFPIntegerConvert(instr);
    562               }
    563             } else if (instr->Bits(14, 10) == 16) {
    564               const Instr masked_A0DF8000 = instr->Mask(0xA0DF8000);
    565               if ((instr->Mask(0x80180000) != 0) ||
    566                   (masked_A0DF8000 == 0x00020000) ||
    567                   (masked_A0DF8000 == 0x00030000) ||
    568                   (masked_A0DF8000 == 0x00068000) ||
    569                   (masked_A0DF8000 == 0x00428000) ||
    570                   (masked_A0DF8000 == 0x00430000) ||
    571                   (masked_A0DF8000 == 0x00468000) ||
    572                   (instr->Mask(0xA0D80000) == 0x00800000) ||
    573                   (instr->Mask(0xA0DE0000) == 0x00C00000) ||
    574                   (instr->Mask(0xA0DF0000) == 0x00C30000) ||
    575                   (instr->Mask(0xA0DC0000) == 0x00C40000)) {
    576                 V::VisitUnallocated(instr);
    577               } else {
    578                 V::VisitFPDataProcessing1Source(instr);
    579               }
    580             } else if (instr->Bits(13, 10) == 8) {
    581               if ((instr->Bits(15, 14) != 0) ||
    582                   (instr->Bits(2, 0) != 0) ||
    583                   (instr->Mask(0x80800000) != 0x00000000)) {
    584                 V::VisitUnallocated(instr);
    585               } else {
    586                 V::VisitFPCompare(instr);
    587               }
    588             } else if (instr->Bits(12, 10) == 4) {
    589               if ((instr->Bits(9, 5) != 0) ||
    590                   (instr->Mask(0x80800000) != 0x00000000)) {
    591                 V::VisitUnallocated(instr);
    592               } else {
    593                 V::VisitFPImmediate(instr);
    594               }
    595             } else {
    596               if (instr->Mask(0x80800000) != 0x00000000) {
    597                 V::VisitUnallocated(instr);
    598               } else {
    599                 switch (instr->Bits(11, 10)) {
    600                   case 1: {
    601                     V::VisitFPConditionalCompare(instr);
    602                     break;
    603                   }
    604                   case 2: {
    605                     if ((instr->Bits(15, 14) == 0x3) ||
    606                         (instr->Mask(0x00009000) == 0x00009000) ||
    607                         (instr->Mask(0x0000A000) == 0x0000A000)) {
    608                       V::VisitUnallocated(instr);
    609                     } else {
    610                       V::VisitFPDataProcessing2Source(instr);
    611                     }
    612                     break;
    613                   }
    614                   case 3: {
    615                     V::VisitFPConditionalSelect(instr);
    616                     break;
    617                   }
    618                   default: UNREACHABLE();
    619                 }
    620               }
    621             }
    622           }
    623         } else {
    624           // Bit 30 == 1 has been handled earlier.
    625           DCHECK(instr->Bit(30) == 0);
    626           if (instr->Mask(0xA0800000) != 0) {
    627             V::VisitUnallocated(instr);
    628           } else {
    629             V::VisitFPDataProcessing3Source(instr);
    630           }
    631         }
    632       }
    633     }
    634   }
    635 }
    636 
    637 
    638 template<typename V>
    639 void Decoder<V>::DecodeAdvSIMDLoadStore(Instruction* instr) {
    640   // TODO(all): Implement Advanced SIMD load/store instruction decode.
    641   DCHECK(instr->Bits(29, 25) == 0x6);
    642   V::VisitUnimplemented(instr);
    643 }
    644 
    645 
    646 template<typename V>
    647 void Decoder<V>::DecodeAdvSIMDDataProcessing(Instruction* instr) {
    648   // TODO(all): Implement Advanced SIMD data processing instruction decode.
    649   DCHECK(instr->Bits(27, 25) == 0x7);
    650   V::VisitUnimplemented(instr);
    651 }
    652 
    653 
    654 }  // namespace internal
    655 }  // namespace v8
    656 
    657 #endif  // V8_ARM64_DECODER_ARM64_INL_H_
    658