Home | History | Annotate | Download | only in aarch64
      1 // Copyright 2014, VIXL authors
      2 // All rights reserved.
      3 //
      4 // Redistribution and use in source and binary forms, with or without
      5 // modification, are permitted provided that the following conditions are met:
      6 //
      7 //   * Redistributions of source code must retain the above copyright notice,
      8 //     this list of conditions and the following disclaimer.
      9 //   * Redistributions in binary form must reproduce the above copyright notice,
     10 //     this list of conditions and the following disclaimer in the documentation
     11 //     and/or other materials provided with the distribution.
     12 //   * Neither the name of ARM Limited nor the names of its contributors may be
     13 //     used to endorse or promote products derived from this software without
     14 //     specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
     17 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     18 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     19 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
     20 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     22 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
     23 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26 
     27 #include "../globals-vixl.h"
     28 #include "../utils-vixl.h"
     29 
     30 #include "decoder-aarch64.h"
     31 
     32 namespace vixl {
     33 namespace aarch64 {
     34 
     35 void Decoder::DecodeInstruction(const Instruction* instr) {
     36   if (instr->ExtractBits(28, 27) == 0) {
     37     VisitUnallocated(instr);
     38   } else {
     39     switch (instr->ExtractBits(27, 24)) {
     40       // 0:   PC relative addressing.
     41       case 0x0:
     42         DecodePCRelAddressing(instr);
     43         break;
     44 
     45       // 1:   Add/sub immediate.
     46       case 0x1:
     47         DecodeAddSubImmediate(instr);
     48         break;
     49 
     50       // A:   Logical shifted register.
     51       //      Add/sub with carry.
     52       //      Conditional compare register.
     53       //      Conditional compare immediate.
     54       //      Conditional select.
     55       //      Data processing 1 source.
     56       //      Data processing 2 source.
     57       // B:   Add/sub shifted register.
     58       //      Add/sub extended register.
     59       //      Data processing 3 source.
     60       case 0xA:
     61       case 0xB:
     62         DecodeDataProcessing(instr);
     63         break;
     64 
     65       // 2:   Logical immediate.
     66       //      Move wide immediate.
     67       case 0x2:
     68         DecodeLogical(instr);
     69         break;
     70 
     71       // 3:   Bitfield.
     72       //      Extract.
     73       case 0x3:
     74         DecodeBitfieldExtract(instr);
     75         break;
     76 
     77       // 4:   Unconditional branch immediate.
     78       //      Exception generation.
     79       //      Compare and branch immediate.
     80       // 5:   Compare and branch immediate.
     81       //      Conditional branch.
     82       //      System.
     83       // 6,7: Unconditional branch.
     84       //      Test and branch immediate.
     85       case 0x4:
     86       case 0x5:
     87       case 0x6:
     88       case 0x7:
     89         DecodeBranchSystemException(instr);
     90         break;
     91 
     92       // 8,9: Load/store register pair post-index.
     93       //      Load register literal.
     94       //      Load/store register unscaled immediate.
     95       //      Load/store register immediate post-index.
     96       //      Load/store register immediate pre-index.
     97       //      Load/store register offset.
     98       //      Load/store exclusive.
     99       // C,D: Load/store register pair offset.
    100       //      Load/store register pair pre-index.
    101       //      Load/store register unsigned immediate.
    102       //      Advanced SIMD.
    103       case 0x8:
    104       case 0x9:
    105       case 0xC:
    106       case 0xD:
    107         DecodeLoadStore(instr);
    108         break;
    109 
    110       // E:   FP fixed point conversion.
    111       //      FP integer conversion.
    112       //      FP data processing 1 source.
    113       //      FP compare.
    114       //      FP immediate.
    115       //      FP data processing 2 source.
    116       //      FP conditional compare.
    117       //      FP conditional select.
    118       //      Advanced SIMD.
    119       // F:   FP data processing 3 source.
    120       //      Advanced SIMD.
    121       case 0xE:
    122       case 0xF:
    123         DecodeFP(instr);
    124         break;
    125     }
    126   }
    127 }
    128 
    129 void Decoder::AppendVisitor(DecoderVisitor* new_visitor) {
    130   visitors_.push_back(new_visitor);
    131 }
    132 
    133 
    134 void Decoder::PrependVisitor(DecoderVisitor* new_visitor) {
    135   visitors_.push_front(new_visitor);
    136 }
    137 
    138 
    139 void Decoder::InsertVisitorBefore(DecoderVisitor* new_visitor,
    140                                   DecoderVisitor* registered_visitor) {
    141   std::list<DecoderVisitor*>::iterator it;
    142   for (it = visitors_.begin(); it != visitors_.end(); it++) {
    143     if (*it == registered_visitor) {
    144       visitors_.insert(it, new_visitor);
    145       return;
    146     }
    147   }
    148   // We reached the end of the list. The last element must be
    149   // registered_visitor.
    150   VIXL_ASSERT(*it == registered_visitor);
    151   visitors_.insert(it, new_visitor);
    152 }
    153 
    154 
    155 void Decoder::InsertVisitorAfter(DecoderVisitor* new_visitor,
    156                                  DecoderVisitor* registered_visitor) {
    157   std::list<DecoderVisitor*>::iterator it;
    158   for (it = visitors_.begin(); it != visitors_.end(); it++) {
    159     if (*it == registered_visitor) {
    160       it++;
    161       visitors_.insert(it, new_visitor);
    162       return;
    163     }
    164   }
    165   // We reached the end of the list. The last element must be
    166   // registered_visitor.
    167   VIXL_ASSERT(*it == registered_visitor);
    168   visitors_.push_back(new_visitor);
    169 }
    170 
    171 
    172 void Decoder::RemoveVisitor(DecoderVisitor* visitor) {
    173   visitors_.remove(visitor);
    174 }
    175 
    176 
    177 void Decoder::DecodePCRelAddressing(const Instruction* instr) {
    178   VIXL_ASSERT(instr->ExtractBits(27, 24) == 0x0);
    179   // We know bit 28 is set, as <b28:b27> = 0 is filtered out at the top level
    180   // decode.
    181   VIXL_ASSERT(instr->ExtractBit(28) == 0x1);
    182   VisitPCRelAddressing(instr);
    183 }
    184 
    185 
    186 void Decoder::DecodeBranchSystemException(const Instruction* instr) {
    187   VIXL_ASSERT((instr->ExtractBits(27, 24) == 0x4) ||
    188               (instr->ExtractBits(27, 24) == 0x5) ||
    189               (instr->ExtractBits(27, 24) == 0x6) ||
    190               (instr->ExtractBits(27, 24) == 0x7));
    191 
    192   switch (instr->ExtractBits(31, 29)) {
    193     case 0:
    194     case 4: {
    195       VisitUnconditionalBranch(instr);
    196       break;
    197     }
    198     case 1:
    199     case 5: {
    200       if (instr->ExtractBit(25) == 0) {
    201         VisitCompareBranch(instr);
    202       } else {
    203         VisitTestBranch(instr);
    204       }
    205       break;
    206     }
    207     case 2: {
    208       if (instr->ExtractBit(25) == 0) {
    209         if ((instr->ExtractBit(24) == 0x1) ||
    210             (instr->Mask(0x01000010) == 0x00000010)) {
    211           VisitUnallocated(instr);
    212         } else {
    213           VisitConditionalBranch(instr);
    214         }
    215       } else {
    216         VisitUnallocated(instr);
    217       }
    218       break;
    219     }
    220     case 6: {
    221       if (instr->ExtractBit(25) == 0) {
    222         if (instr->ExtractBit(24) == 0) {
    223           if ((instr->ExtractBits(4, 2) != 0) ||
    224               (instr->Mask(0x00E0001D) == 0x00200001) ||
    225               (instr->Mask(0x00E0001D) == 0x00400001) ||
    226               (instr->Mask(0x00E0001E) == 0x00200002) ||
    227               (instr->Mask(0x00E0001E) == 0x00400002) ||
    228               (instr->Mask(0x00E0001C) == 0x00600000) ||
    229               (instr->Mask(0x00E0001C) == 0x00800000) ||
    230               (instr->Mask(0x00E0001F) == 0x00A00000) ||
    231               (instr->Mask(0x00C0001C) == 0x00C00000)) {
    232             VisitUnallocated(instr);
    233           } else {
    234             VisitException(instr);
    235           }
    236         } else {
    237           if (instr->ExtractBits(23, 22) == 0) {
    238             const Instr masked_003FF0E0 = instr->Mask(0x003FF0E0);
    239             if ((instr->ExtractBits(21, 19) == 0x4) ||
    240                 (masked_003FF0E0 == 0x00033000) ||
    241                 (masked_003FF0E0 == 0x003FF020) ||
    242                 (masked_003FF0E0 == 0x003FF060) ||
    243                 (masked_003FF0E0 == 0x003FF0E0) ||
    244                 (instr->Mask(0x00388000) == 0x00008000) ||
    245                 (instr->Mask(0x0038E000) == 0x00000000) ||
    246                 (instr->Mask(0x0039E000) == 0x00002000) ||
    247                 (instr->Mask(0x003AE000) == 0x00002000) ||
    248                 (instr->Mask(0x003CE000) == 0x00042000) ||
    249                 (instr->Mask(0x003FFFC0) == 0x000320C0) ||
    250                 (instr->Mask(0x003FF100) == 0x00032100) ||
    251                 (instr->Mask(0x003FF200) == 0x00032200) ||
    252                 (instr->Mask(0x003FF400) == 0x00032400) ||
    253                 (instr->Mask(0x003FF800) == 0x00032800) ||
    254                 (instr->Mask(0x0038F000) == 0x00005000) ||
    255                 (instr->Mask(0x0038E000) == 0x00006000)) {
    256               VisitUnallocated(instr);
    257             } else {
    258               VisitSystem(instr);
    259             }
    260           } else {
    261             VisitUnallocated(instr);
    262           }
    263         }
    264       } else {
    265         if ((instr->ExtractBit(24) == 0x1) ||
    266             (instr->ExtractBits(20, 16) != 0x1F) ||
    267             (instr->ExtractBits(15, 10) != 0) ||
    268             (instr->ExtractBits(4, 0) != 0) ||
    269             (instr->ExtractBits(24, 21) == 0x3) ||
    270             (instr->ExtractBits(24, 22) == 0x3)) {
    271           VisitUnallocated(instr);
    272         } else {
    273           VisitUnconditionalBranchToRegister(instr);
    274         }
    275       }
    276       break;
    277     }
    278     case 3:
    279     case 7: {
    280       VisitUnallocated(instr);
    281       break;
    282     }
    283   }
    284 }
    285 
    286 
    287 void Decoder::DecodeLoadStore(const Instruction* instr) {
    288   VIXL_ASSERT((instr->ExtractBits(27, 24) == 0x8) ||
    289               (instr->ExtractBits(27, 24) == 0x9) ||
    290               (instr->ExtractBits(27, 24) == 0xC) ||
    291               (instr->ExtractBits(27, 24) == 0xD));
    292   // TODO(all): rearrange the tree to integrate this branch.
    293   if ((instr->ExtractBit(28) == 0) && (instr->ExtractBit(29) == 0) &&
    294       (instr->ExtractBit(26) == 1)) {
    295     DecodeNEONLoadStore(instr);
    296     return;
    297   }
    298 
    299   if (instr->ExtractBit(24) == 0) {
    300     if (instr->ExtractBit(28) == 0) {
    301       if (instr->ExtractBit(29) == 0) {
    302         if (instr->ExtractBit(26) == 0) {
    303           VisitLoadStoreExclusive(instr);
    304         } else {
    305           VIXL_UNREACHABLE();
    306         }
    307       } else {
    308         if ((instr->ExtractBits(31, 30) == 0x3) ||
    309             (instr->Mask(0xC4400000) == 0x40000000)) {
    310           VisitUnallocated(instr);
    311         } else {
    312           if (instr->ExtractBit(23) == 0) {
    313             if (instr->Mask(0xC4400000) == 0xC0400000) {
    314               VisitUnallocated(instr);
    315             } else {
    316               VisitLoadStorePairNonTemporal(instr);
    317             }
    318           } else {
    319             VisitLoadStorePairPostIndex(instr);
    320           }
    321         }
    322       }
    323     } else {
    324       if (instr->ExtractBit(29) == 0) {
    325         if (instr->Mask(0xC4000000) == 0xC4000000) {
    326           VisitUnallocated(instr);
    327         } else {
    328           VisitLoadLiteral(instr);
    329         }
    330       } else {
    331         if ((instr->Mask(0x84C00000) == 0x80C00000) ||
    332             (instr->Mask(0x44800000) == 0x44800000) ||
    333             (instr->Mask(0x84800000) == 0x84800000)) {
    334           VisitUnallocated(instr);
    335         } else {
    336           if (instr->ExtractBit(21) == 0) {
    337             switch (instr->ExtractBits(11, 10)) {
    338               case 0: {
    339                 VisitLoadStoreUnscaledOffset(instr);
    340                 break;
    341               }
    342               case 1: {
    343                 if (instr->Mask(0xC4C00000) == 0xC0800000) {
    344                   VisitUnallocated(instr);
    345                 } else {
    346                   VisitLoadStorePostIndex(instr);
    347                 }
    348                 break;
    349               }
    350               case 2: {
    351                 // TODO: VisitLoadStoreRegisterOffsetUnpriv.
    352                 VisitUnimplemented(instr);
    353                 break;
    354               }
    355               case 3: {
    356                 if (instr->Mask(0xC4C00000) == 0xC0800000) {
    357                   VisitUnallocated(instr);
    358                 } else {
    359                   VisitLoadStorePreIndex(instr);
    360                 }
    361                 break;
    362               }
    363             }
    364           } else {
    365             if (instr->ExtractBits(11, 10) == 0x2) {
    366               if (instr->ExtractBit(14) == 0) {
    367                 VisitUnallocated(instr);
    368               } else {
    369                 VisitLoadStoreRegisterOffset(instr);
    370               }
    371             } else {
    372               VisitUnallocated(instr);
    373             }
    374           }
    375         }
    376       }
    377     }
    378   } else {
    379     if (instr->ExtractBit(28) == 0) {
    380       if (instr->ExtractBit(29) == 0) {
    381         VisitUnallocated(instr);
    382       } else {
    383         if ((instr->ExtractBits(31, 30) == 0x3) ||
    384             (instr->Mask(0xC4400000) == 0x40000000)) {
    385           VisitUnallocated(instr);
    386         } else {
    387           if (instr->ExtractBit(23) == 0) {
    388             VisitLoadStorePairOffset(instr);
    389           } else {
    390             VisitLoadStorePairPreIndex(instr);
    391           }
    392         }
    393       }
    394     } else {
    395       if (instr->ExtractBit(29) == 0) {
    396         VisitUnallocated(instr);
    397       } else {
    398         if ((instr->Mask(0x84C00000) == 0x80C00000) ||
    399             (instr->Mask(0x44800000) == 0x44800000) ||
    400             (instr->Mask(0x84800000) == 0x84800000)) {
    401           VisitUnallocated(instr);
    402         } else {
    403           VisitLoadStoreUnsignedOffset(instr);
    404         }
    405       }
    406     }
    407   }
    408 }
    409 
    410 
    411 void Decoder::DecodeLogical(const Instruction* instr) {
    412   VIXL_ASSERT(instr->ExtractBits(27, 24) == 0x2);
    413 
    414   if (instr->Mask(0x80400000) == 0x00400000) {
    415     VisitUnallocated(instr);
    416   } else {
    417     if (instr->ExtractBit(23) == 0) {
    418       VisitLogicalImmediate(instr);
    419     } else {
    420       if (instr->ExtractBits(30, 29) == 0x1) {
    421         VisitUnallocated(instr);
    422       } else {
    423         VisitMoveWideImmediate(instr);
    424       }
    425     }
    426   }
    427 }
    428 
    429 
    430 void Decoder::DecodeBitfieldExtract(const Instruction* instr) {
    431   VIXL_ASSERT(instr->ExtractBits(27, 24) == 0x3);
    432 
    433   if ((instr->Mask(0x80400000) == 0x80000000) ||
    434       (instr->Mask(0x80400000) == 0x00400000) ||
    435       (instr->Mask(0x80008000) == 0x00008000)) {
    436     VisitUnallocated(instr);
    437   } else if (instr->ExtractBit(23) == 0) {
    438     if ((instr->Mask(0x80200000) == 0x00200000) ||
    439         (instr->Mask(0x60000000) == 0x60000000)) {
    440       VisitUnallocated(instr);
    441     } else {
    442       VisitBitfield(instr);
    443     }
    444   } else {
    445     if ((instr->Mask(0x60200000) == 0x00200000) ||
    446         (instr->Mask(0x60000000) != 0x00000000)) {
    447       VisitUnallocated(instr);
    448     } else {
    449       VisitExtract(instr);
    450     }
    451   }
    452 }
    453 
    454 
    455 void Decoder::DecodeAddSubImmediate(const Instruction* instr) {
    456   VIXL_ASSERT(instr->ExtractBits(27, 24) == 0x1);
    457   if (instr->ExtractBit(23) == 1) {
    458     VisitUnallocated(instr);
    459   } else {
    460     VisitAddSubImmediate(instr);
    461   }
    462 }
    463 
    464 
    465 void Decoder::DecodeDataProcessing(const Instruction* instr) {
    466   VIXL_ASSERT((instr->ExtractBits(27, 24) == 0xA) ||
    467               (instr->ExtractBits(27, 24) == 0xB));
    468 
    469   if (instr->ExtractBit(24) == 0) {
    470     if (instr->ExtractBit(28) == 0) {
    471       if (instr->Mask(0x80008000) == 0x00008000) {
    472         VisitUnallocated(instr);
    473       } else {
    474         VisitLogicalShifted(instr);
    475       }
    476     } else {
    477       switch (instr->ExtractBits(23, 21)) {
    478         case 0: {
    479           if (instr->Mask(0x0000FC00) != 0) {
    480             VisitUnallocated(instr);
    481           } else {
    482             VisitAddSubWithCarry(instr);
    483           }
    484           break;
    485         }
    486         case 2: {
    487           if ((instr->ExtractBit(29) == 0) || (instr->Mask(0x00000410) != 0)) {
    488             VisitUnallocated(instr);
    489           } else {
    490             if (instr->ExtractBit(11) == 0) {
    491               VisitConditionalCompareRegister(instr);
    492             } else {
    493               VisitConditionalCompareImmediate(instr);
    494             }
    495           }
    496           break;
    497         }
    498         case 4: {
    499           if (instr->Mask(0x20000800) != 0x00000000) {
    500             VisitUnallocated(instr);
    501           } else {
    502             VisitConditionalSelect(instr);
    503           }
    504           break;
    505         }
    506         case 6: {
    507           if (instr->ExtractBit(29) == 0x1) {
    508             VisitUnallocated(instr);
    509             VIXL_FALLTHROUGH();
    510           } else {
    511             if (instr->ExtractBit(30) == 0) {
    512               if ((instr->ExtractBit(15) == 0x1) ||
    513                   (instr->ExtractBits(15, 11) == 0) ||
    514                   (instr->ExtractBits(15, 12) == 0x1) ||
    515                   (instr->ExtractBits(15, 12) == 0x3) ||
    516                   (instr->ExtractBits(15, 13) == 0x3) ||
    517                   (instr->Mask(0x8000EC00) == 0x00004C00) ||
    518                   (instr->Mask(0x8000E800) == 0x80004000) ||
    519                   (instr->Mask(0x8000E400) == 0x80004000)) {
    520                 VisitUnallocated(instr);
    521               } else {
    522                 VisitDataProcessing2Source(instr);
    523               }
    524             } else {
    525               if ((instr->ExtractBit(13) == 1) ||
    526                   (instr->ExtractBits(20, 16) != 0) ||
    527                   (instr->ExtractBits(15, 14) != 0) ||
    528                   (instr->Mask(0xA01FFC00) == 0x00000C00) ||
    529                   (instr->Mask(0x201FF800) == 0x00001800)) {
    530                 VisitUnallocated(instr);
    531               } else {
    532                 VisitDataProcessing1Source(instr);
    533               }
    534             }
    535             break;
    536           }
    537         }
    538         case 1:
    539         case 3:
    540         case 5:
    541         case 7:
    542           VisitUnallocated(instr);
    543           break;
    544       }
    545     }
    546   } else {
    547     if (instr->ExtractBit(28) == 0) {
    548       if (instr->ExtractBit(21) == 0) {
    549         if ((instr->ExtractBits(23, 22) == 0x3) ||
    550             (instr->Mask(0x80008000) == 0x00008000)) {
    551           VisitUnallocated(instr);
    552         } else {
    553           VisitAddSubShifted(instr);
    554         }
    555       } else {
    556         if ((instr->Mask(0x00C00000) != 0x00000000) ||
    557             (instr->Mask(0x00001400) == 0x00001400) ||
    558             (instr->Mask(0x00001800) == 0x00001800)) {
    559           VisitUnallocated(instr);
    560         } else {
    561           VisitAddSubExtended(instr);
    562         }
    563       }
    564     } else {
    565       if ((instr->ExtractBit(30) == 0x1) ||
    566           (instr->ExtractBits(30, 29) == 0x1) ||
    567           (instr->Mask(0xE0600000) == 0x00200000) ||
    568           (instr->Mask(0xE0608000) == 0x00400000) ||
    569           (instr->Mask(0x60608000) == 0x00408000) ||
    570           (instr->Mask(0x60E00000) == 0x00E00000) ||
    571           (instr->Mask(0x60E00000) == 0x00800000) ||
    572           (instr->Mask(0x60E00000) == 0x00600000)) {
    573         VisitUnallocated(instr);
    574       } else {
    575         VisitDataProcessing3Source(instr);
    576       }
    577     }
    578   }
    579 }
    580 
    581 
    582 void Decoder::DecodeFP(const Instruction* instr) {
    583   VIXL_ASSERT((instr->ExtractBits(27, 24) == 0xE) ||
    584               (instr->ExtractBits(27, 24) == 0xF));
    585   if (instr->ExtractBit(28) == 0) {
    586     DecodeNEONVectorDataProcessing(instr);
    587   } else {
    588     if (instr->ExtractBits(31, 30) == 0x3) {
    589       VisitUnallocated(instr);
    590     } else if (instr->ExtractBits(31, 30) == 0x1) {
    591       DecodeNEONScalarDataProcessing(instr);
    592     } else {
    593       if (instr->ExtractBit(29) == 0) {
    594         if (instr->ExtractBit(24) == 0) {
    595           if (instr->ExtractBit(21) == 0) {
    596             if ((instr->ExtractBit(23) == 1) || (instr->ExtractBit(18) == 1) ||
    597                 (instr->Mask(0x80008000) == 0x00000000) ||
    598                 (instr->Mask(0x000E0000) == 0x00000000) ||
    599                 (instr->Mask(0x000E0000) == 0x000A0000) ||
    600                 (instr->Mask(0x00160000) == 0x00000000) ||
    601                 (instr->Mask(0x00160000) == 0x00120000)) {
    602               VisitUnallocated(instr);
    603             } else {
    604               VisitFPFixedPointConvert(instr);
    605             }
    606           } else {
    607             if (instr->ExtractBits(15, 10) == 32) {
    608               VisitUnallocated(instr);
    609             } else if (instr->ExtractBits(15, 10) == 0) {
    610               if ((instr->ExtractBits(23, 22) == 0x3) ||
    611                   (instr->Mask(0x000E0000) == 0x000A0000) ||
    612                   (instr->Mask(0x000E0000) == 0x000C0000) ||
    613                   (instr->Mask(0x00160000) == 0x00120000) ||
    614                   (instr->Mask(0x00160000) == 0x00140000) ||
    615                   (instr->Mask(0x20C40000) == 0x00800000) ||
    616                   (instr->Mask(0x20C60000) == 0x00840000) ||
    617                   (instr->Mask(0xA0C60000) == 0x80060000) ||
    618                   (instr->Mask(0xA0C60000) == 0x00860000) ||
    619                   (instr->Mask(0xA0C60000) == 0x00460000) ||
    620                   (instr->Mask(0xA0CE0000) == 0x80860000) ||
    621                   (instr->Mask(0xA0CE0000) == 0x804E0000) ||
    622                   (instr->Mask(0xA0CE0000) == 0x000E0000) ||
    623                   (instr->Mask(0xA0D60000) == 0x00160000) ||
    624                   (instr->Mask(0xA0D60000) == 0x80560000) ||
    625                   (instr->Mask(0xA0D60000) == 0x80960000)) {
    626                 VisitUnallocated(instr);
    627               } else {
    628                 VisitFPIntegerConvert(instr);
    629               }
    630             } else if (instr->ExtractBits(14, 10) == 16) {
    631               const Instr masked_A0DF8000 = instr->Mask(0xA0DF8000);
    632               if ((instr->Mask(0x80180000) != 0) ||
    633                   (masked_A0DF8000 == 0x00020000) ||
    634                   (masked_A0DF8000 == 0x00030000) ||
    635                   (masked_A0DF8000 == 0x00068000) ||
    636                   (masked_A0DF8000 == 0x00428000) ||
    637                   (masked_A0DF8000 == 0x00430000) ||
    638                   (masked_A0DF8000 == 0x00468000) ||
    639                   (instr->Mask(0xA0D80000) == 0x00800000) ||
    640                   (instr->Mask(0xA0DE0000) == 0x00C00000) ||
    641                   (instr->Mask(0xA0DF0000) == 0x00C30000) ||
    642                   (instr->Mask(0xA0DC0000) == 0x00C40000)) {
    643                 VisitUnallocated(instr);
    644               } else {
    645                 VisitFPDataProcessing1Source(instr);
    646               }
    647             } else if (instr->ExtractBits(13, 10) == 8) {
    648               if ((instr->ExtractBits(15, 14) != 0) ||
    649                   (instr->ExtractBits(2, 0) != 0) ||
    650                   (instr->Mask(0x80800000) != 0x00000000)) {
    651                 VisitUnallocated(instr);
    652               } else {
    653                 VisitFPCompare(instr);
    654               }
    655             } else if (instr->ExtractBits(12, 10) == 4) {
    656               if ((instr->ExtractBits(9, 5) != 0) ||
    657                   (instr->Mask(0x80800000) != 0x00000000)) {
    658                 VisitUnallocated(instr);
    659               } else {
    660                 VisitFPImmediate(instr);
    661               }
    662             } else {
    663               if (instr->Mask(0x80800000) != 0x00000000) {
    664                 VisitUnallocated(instr);
    665               } else {
    666                 switch (instr->ExtractBits(11, 10)) {
    667                   case 1: {
    668                     VisitFPConditionalCompare(instr);
    669                     break;
    670                   }
    671                   case 2: {
    672                     if ((instr->ExtractBits(15, 14) == 0x3) ||
    673                         (instr->Mask(0x00009000) == 0x00009000) ||
    674                         (instr->Mask(0x0000A000) == 0x0000A000)) {
    675                       VisitUnallocated(instr);
    676                     } else {
    677                       VisitFPDataProcessing2Source(instr);
    678                     }
    679                     break;
    680                   }
    681                   case 3: {
    682                     VisitFPConditionalSelect(instr);
    683                     break;
    684                   }
    685                   default:
    686                     VIXL_UNREACHABLE();
    687                 }
    688               }
    689             }
    690           }
    691         } else {
    692           // Bit 30 == 1 has been handled earlier.
    693           VIXL_ASSERT(instr->ExtractBit(30) == 0);
    694           if (instr->Mask(0xA0800000) != 0) {
    695             VisitUnallocated(instr);
    696           } else {
    697             VisitFPDataProcessing3Source(instr);
    698           }
    699         }
    700       } else {
    701         VisitUnallocated(instr);
    702       }
    703     }
    704   }
    705 }
    706 
    707 
    708 void Decoder::DecodeNEONLoadStore(const Instruction* instr) {
    709   VIXL_ASSERT(instr->ExtractBits(29, 25) == 0x6);
    710   if (instr->ExtractBit(31) == 0) {
    711     if ((instr->ExtractBit(24) == 0) && (instr->ExtractBit(21) == 1)) {
    712       VisitUnallocated(instr);
    713       return;
    714     }
    715 
    716     if (instr->ExtractBit(23) == 0) {
    717       if (instr->ExtractBits(20, 16) == 0) {
    718         if (instr->ExtractBit(24) == 0) {
    719           VisitNEONLoadStoreMultiStruct(instr);
    720         } else {
    721           VisitNEONLoadStoreSingleStruct(instr);
    722         }
    723       } else {
    724         VisitUnallocated(instr);
    725       }
    726     } else {
    727       if (instr->ExtractBit(24) == 0) {
    728         VisitNEONLoadStoreMultiStructPostIndex(instr);
    729       } else {
    730         VisitNEONLoadStoreSingleStructPostIndex(instr);
    731       }
    732     }
    733   } else {
    734     VisitUnallocated(instr);
    735   }
    736 }
    737 
    738 
    739 void Decoder::DecodeNEONVectorDataProcessing(const Instruction* instr) {
    740   VIXL_ASSERT(instr->ExtractBits(28, 25) == 0x7);
    741   if (instr->ExtractBit(31) == 0) {
    742     if (instr->ExtractBit(24) == 0) {
    743       if (instr->ExtractBit(21) == 0) {
    744         if (instr->ExtractBit(15) == 0) {
    745           if (instr->ExtractBit(10) == 0) {
    746             if (instr->ExtractBit(29) == 0) {
    747               if (instr->ExtractBit(11) == 0) {
    748                 VisitNEONTable(instr);
    749               } else {
    750                 VisitNEONPerm(instr);
    751               }
    752             } else {
    753               VisitNEONExtract(instr);
    754             }
    755           } else {
    756             if (instr->ExtractBits(23, 22) == 0) {
    757               VisitNEONCopy(instr);
    758             } else {
    759               VisitUnallocated(instr);
    760             }
    761           }
    762         } else {
    763           VisitUnallocated(instr);
    764         }
    765       } else {
    766         if (instr->ExtractBit(10) == 0) {
    767           if (instr->ExtractBit(11) == 0) {
    768             VisitNEON3Different(instr);
    769           } else {
    770             if (instr->ExtractBits(18, 17) == 0) {
    771               if (instr->ExtractBit(20) == 0) {
    772                 if (instr->ExtractBit(19) == 0) {
    773                   VisitNEON2RegMisc(instr);
    774                 } else {
    775                   if (instr->ExtractBits(30, 29) == 0x2) {
    776                     VisitCryptoAES(instr);
    777                   } else {
    778                     VisitUnallocated(instr);
    779                   }
    780                 }
    781               } else {
    782                 if (instr->ExtractBit(19) == 0) {
    783                   VisitNEONAcrossLanes(instr);
    784                 } else {
    785                   VisitUnallocated(instr);
    786                 }
    787               }
    788             } else {
    789               VisitUnallocated(instr);
    790             }
    791           }
    792         } else {
    793           VisitNEON3Same(instr);
    794         }
    795       }
    796     } else {
    797       if (instr->ExtractBit(10) == 0) {
    798         VisitNEONByIndexedElement(instr);
    799       } else {
    800         if (instr->ExtractBit(23) == 0) {
    801           if (instr->ExtractBits(22, 19) == 0) {
    802             VisitNEONModifiedImmediate(instr);
    803           } else {
    804             VisitNEONShiftImmediate(instr);
    805           }
    806         } else {
    807           VisitUnallocated(instr);
    808         }
    809       }
    810     }
    811   } else {
    812     VisitUnallocated(instr);
    813   }
    814 }
    815 
    816 
    817 void Decoder::DecodeNEONScalarDataProcessing(const Instruction* instr) {
    818   VIXL_ASSERT(instr->ExtractBits(28, 25) == 0xF);
    819   if (instr->ExtractBit(24) == 0) {
    820     if (instr->ExtractBit(21) == 0) {
    821       if (instr->ExtractBit(15) == 0) {
    822         if (instr->ExtractBit(10) == 0) {
    823           if (instr->ExtractBit(29) == 0) {
    824             if (instr->ExtractBit(11) == 0) {
    825               VisitCrypto3RegSHA(instr);
    826             } else {
    827               VisitUnallocated(instr);
    828             }
    829           } else {
    830             VisitUnallocated(instr);
    831           }
    832         } else {
    833           if (instr->ExtractBits(23, 22) == 0) {
    834             VisitNEONScalarCopy(instr);
    835           } else {
    836             VisitUnallocated(instr);
    837           }
    838         }
    839       } else {
    840         VisitUnallocated(instr);
    841       }
    842     } else {
    843       if (instr->ExtractBit(10) == 0) {
    844         if (instr->ExtractBit(11) == 0) {
    845           VisitNEONScalar3Diff(instr);
    846         } else {
    847           if (instr->ExtractBits(18, 17) == 0) {
    848             if (instr->ExtractBit(20) == 0) {
    849               if (instr->ExtractBit(19) == 0) {
    850                 VisitNEONScalar2RegMisc(instr);
    851               } else {
    852                 if (instr->ExtractBit(29) == 0) {
    853                   VisitCrypto2RegSHA(instr);
    854                 } else {
    855                   VisitUnallocated(instr);
    856                 }
    857               }
    858             } else {
    859               if (instr->ExtractBit(19) == 0) {
    860                 VisitNEONScalarPairwise(instr);
    861               } else {
    862                 VisitUnallocated(instr);
    863               }
    864             }
    865           } else {
    866             VisitUnallocated(instr);
    867           }
    868         }
    869       } else {
    870         VisitNEONScalar3Same(instr);
    871       }
    872     }
    873   } else {
    874     if (instr->ExtractBit(10) == 0) {
    875       VisitNEONScalarByIndexedElement(instr);
    876     } else {
    877       if (instr->ExtractBit(23) == 0) {
    878         VisitNEONScalarShiftImmediate(instr);
    879       } else {
    880         VisitUnallocated(instr);
    881       }
    882     }
    883   }
    884 }
    885 
    886 
    887 #define DEFINE_VISITOR_CALLERS(A)                               \
    888   void Decoder::Visit##A(const Instruction* instr) {            \
    889     VIXL_ASSERT(instr->Mask(A##FMask) == A##Fixed);             \
    890     std::list<DecoderVisitor*>::iterator it;                    \
    891     for (it = visitors_.begin(); it != visitors_.end(); it++) { \
    892       (*it)->Visit##A(instr);                                   \
    893     }                                                           \
    894   }
    895 VISITOR_LIST(DEFINE_VISITOR_CALLERS)
    896 #undef DEFINE_VISITOR_CALLERS
    897 }  // namespace aarch64
    898 }  // namespace vixl
    899