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