~ubuntu-branches/ubuntu/vivid/qemu/vivid

« back to all changes in this revision

Viewing changes to disas/libvixl/a64/decoder-a64.cc

  • Committer: Package Import Robot
  • Author(s): dann frazier
  • Date: 2014-02-11 15:41:53 UTC
  • Revision ID: package-import@ubuntu.com-20140211154153-2d001tf0ium08u81
Tags: 1.7.0+dfsg-3ubuntu2
* Backport changes to enable qemu-user-static support for aarch64
* debian/control: add ppc64el to Architectures
* debian/rules: only install qemu-system-aarch64 on arm64.
  Fixes a FTBFS  when built twice in a row on non-arm64 due to a stale
  debian/qemu-system-aarch64 directory

Show diffs side-by-side

added added

removed removed

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