V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
decoder-arm64-inl.h
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_EQ(0x0, instr->Bits(27, 24));
100  // We know bit 28 is set, as <b28:b27> = 0 is filtered out at the top level
101  // decode.
102  DCHECK_EQ(0x1, instr->Bit(28));
103  V::VisitPCRelAddressing(instr);
104 }
105 
106 
107 template<typename V>
108 void Decoder<V>::DecodeBranchSystemException(Instruction* instr) {
109  DCHECK_EQ(0x4, instr->Bits(27, 24) & 0xC); // 0x4, 0x5, 0x6, 0x7
110 
111  switch (instr->Bits(31, 29)) {
112  case 0:
113  case 4: {
114  V::VisitUnconditionalBranch(instr);
115  break;
116  }
117  case 1:
118  case 5: {
119  if (instr->Bit(25) == 0) {
120  V::VisitCompareBranch(instr);
121  } else {
122  V::VisitTestBranch(instr);
123  }
124  break;
125  }
126  case 2: {
127  if (instr->Bit(25) == 0) {
128  if ((instr->Bit(24) == 0x1) ||
129  (instr->Mask(0x01000010) == 0x00000010)) {
130  V::VisitUnallocated(instr);
131  } else {
132  V::VisitConditionalBranch(instr);
133  }
134  } else {
135  V::VisitUnallocated(instr);
136  }
137  break;
138  }
139  case 6: {
140  if (instr->Bit(25) == 0) {
141  if (instr->Bit(24) == 0) {
142  if ((instr->Bits(4, 2) != 0) ||
143  (instr->Mask(0x00E0001D) == 0x00200001) ||
144  (instr->Mask(0x00E0001D) == 0x00400001) ||
145  (instr->Mask(0x00E0001E) == 0x00200002) ||
146  (instr->Mask(0x00E0001E) == 0x00400002) ||
147  (instr->Mask(0x00E0001C) == 0x00600000) ||
148  (instr->Mask(0x00E0001C) == 0x00800000) ||
149  (instr->Mask(0x00E0001F) == 0x00A00000) ||
150  (instr->Mask(0x00C0001C) == 0x00C00000)) {
151  V::VisitUnallocated(instr);
152  } else {
153  V::VisitException(instr);
154  }
155  } else {
156  if (instr->Bits(23, 22) == 0) {
157  const Instr masked_003FF0E0 = instr->Mask(0x003FF0E0);
158  if ((instr->Bits(21, 19) == 0x4) ||
159  (masked_003FF0E0 == 0x00033000) ||
160  (masked_003FF0E0 == 0x003FF020) ||
161  (masked_003FF0E0 == 0x003FF060) ||
162  (masked_003FF0E0 == 0x003FF0E0) ||
163  (instr->Mask(0x00388000) == 0x00008000) ||
164  (instr->Mask(0x0038E000) == 0x00000000) ||
165  (instr->Mask(0x0039E000) == 0x00002000) ||
166  (instr->Mask(0x003AE000) == 0x00002000) ||
167  (instr->Mask(0x003CE000) == 0x00042000) ||
168  (instr->Mask(0x0038F000) == 0x00005000) ||
169  (instr->Mask(0x0038E000) == 0x00006000)) {
170  V::VisitUnallocated(instr);
171  } else {
172  V::VisitSystem(instr);
173  }
174  } else {
175  V::VisitUnallocated(instr);
176  }
177  }
178  } else {
179  if ((instr->Bit(24) == 0x1) ||
180  (instr->Bits(20, 16) != 0x1F) ||
181  (instr->Bits(15, 10) != 0) ||
182  (instr->Bits(4, 0) != 0) ||
183  (instr->Bits(24, 21) == 0x3) ||
184  (instr->Bits(24, 22) == 0x3)) {
185  V::VisitUnallocated(instr);
186  } else {
187  V::VisitUnconditionalBranchToRegister(instr);
188  }
189  }
190  break;
191  }
192  case 3:
193  case 7: {
194  V::VisitUnallocated(instr);
195  break;
196  }
197  }
198 }
199 
200 
201 template<typename V>
202 void Decoder<V>::DecodeLoadStore(Instruction* instr) {
203  DCHECK_EQ(0x8, instr->Bits(27, 24) & 0xA); // 0x8, 0x9, 0xC, 0xD
204 
205  if ((instr->Bit(28) == 0) && (instr->Bit(29) == 0) && (instr->Bit(26) == 1)) {
206  DecodeNEONLoadStore(instr);
207  return;
208  }
209 
210  if (instr->Bit(24) == 0) {
211  if (instr->Bit(28) == 0) {
212  if (instr->Bit(29) == 0) {
213  if (instr->Bit(26) == 0) {
214  if (instr->Mask(0xA08000) == 0x800000 ||
215  instr->Mask(0xA00000) == 0xA00000) {
216  V::VisitUnallocated(instr);
217  } else if (instr->Mask(0x808000) == 0) {
218  // Load/Store exclusive without acquire/release are unimplemented.
219  V::VisitUnimplemented(instr);
220  } else {
221  V::VisitLoadStoreAcquireRelease(instr);
222  }
223  }
224  } else {
225  if ((instr->Bits(31, 30) == 0x3) ||
226  (instr->Mask(0xC4400000) == 0x40000000)) {
227  V::VisitUnallocated(instr);
228  } else {
229  if (instr->Bit(23) == 0) {
230  if (instr->Mask(0xC4400000) == 0xC0400000) {
231  V::VisitUnallocated(instr);
232  } else {
233  // Nontemporals are unimplemented.
234  V::VisitUnimplemented(instr);
235  }
236  } else {
237  V::VisitLoadStorePairPostIndex(instr);
238  }
239  }
240  }
241  } else {
242  if (instr->Bit(29) == 0) {
243  if (instr->Mask(0xC4000000) == 0xC4000000) {
244  V::VisitUnallocated(instr);
245  } else {
246  V::VisitLoadLiteral(instr);
247  }
248  } else {
249  if ((instr->Mask(0x84C00000) == 0x80C00000) ||
250  (instr->Mask(0x44800000) == 0x44800000) ||
251  (instr->Mask(0x84800000) == 0x84800000)) {
252  V::VisitUnallocated(instr);
253  } else {
254  if (instr->Bit(21) == 0) {
255  switch (instr->Bits(11, 10)) {
256  case 0: {
257  V::VisitLoadStoreUnscaledOffset(instr);
258  break;
259  }
260  case 1: {
261  if (instr->Mask(0xC4C00000) == 0xC0800000) {
262  V::VisitUnallocated(instr);
263  } else {
264  V::VisitLoadStorePostIndex(instr);
265  }
266  break;
267  }
268  case 2: {
269  // TODO(all): VisitLoadStoreRegisterOffsetUnpriv.
270  V::VisitUnimplemented(instr);
271  break;
272  }
273  case 3: {
274  if (instr->Mask(0xC4C00000) == 0xC0800000) {
275  V::VisitUnallocated(instr);
276  } else {
277  V::VisitLoadStorePreIndex(instr);
278  }
279  break;
280  }
281  }
282  } else {
283  if (instr->Bits(11, 10) == 0x2) {
284  if (instr->Bit(14) == 0) {
285  V::VisitUnallocated(instr);
286  } else {
287  V::VisitLoadStoreRegisterOffset(instr);
288  }
289  } else {
290  V::VisitUnallocated(instr);
291  }
292  }
293  }
294  }
295  }
296  } else {
297  if (instr->Bit(28) == 0) {
298  if (instr->Bit(29) == 0) {
299  V::VisitUnallocated(instr);
300  } else {
301  if ((instr->Bits(31, 30) == 0x3) ||
302  (instr->Mask(0xC4400000) == 0x40000000)) {
303  V::VisitUnallocated(instr);
304  } else {
305  if (instr->Bit(23) == 0) {
306  V::VisitLoadStorePairOffset(instr);
307  } else {
308  V::VisitLoadStorePairPreIndex(instr);
309  }
310  }
311  }
312  } else {
313  if (instr->Bit(29) == 0) {
314  V::VisitUnallocated(instr);
315  } else {
316  if ((instr->Mask(0x84C00000) == 0x80C00000) ||
317  (instr->Mask(0x44800000) == 0x44800000) ||
318  (instr->Mask(0x84800000) == 0x84800000)) {
319  V::VisitUnallocated(instr);
320  } else {
321  V::VisitLoadStoreUnsignedOffset(instr);
322  }
323  }
324  }
325  }
326 }
327 
328 
329 template<typename V>
330 void Decoder<V>::DecodeLogical(Instruction* instr) {
331  DCHECK_EQ(0x2, instr->Bits(27, 24));
332 
333  if (instr->Mask(0x80400000) == 0x00400000) {
334  V::VisitUnallocated(instr);
335  } else {
336  if (instr->Bit(23) == 0) {
337  V::VisitLogicalImmediate(instr);
338  } else {
339  if (instr->Bits(30, 29) == 0x1) {
340  V::VisitUnallocated(instr);
341  } else {
342  V::VisitMoveWideImmediate(instr);
343  }
344  }
345  }
346 }
347 
348 
349 template<typename V>
350 void Decoder<V>::DecodeBitfieldExtract(Instruction* instr) {
351  DCHECK_EQ(0x3, instr->Bits(27, 24));
352 
353  if ((instr->Mask(0x80400000) == 0x80000000) ||
354  (instr->Mask(0x80400000) == 0x00400000) ||
355  (instr->Mask(0x80008000) == 0x00008000)) {
356  V::VisitUnallocated(instr);
357  } else if (instr->Bit(23) == 0) {
358  if ((instr->Mask(0x80200000) == 0x00200000) ||
359  (instr->Mask(0x60000000) == 0x60000000)) {
360  V::VisitUnallocated(instr);
361  } else {
362  V::VisitBitfield(instr);
363  }
364  } else {
365  if ((instr->Mask(0x60200000) == 0x00200000) ||
366  (instr->Mask(0x60000000) != 0x00000000)) {
367  V::VisitUnallocated(instr);
368  } else {
369  V::VisitExtract(instr);
370  }
371  }
372 }
373 
374 
375 template<typename V>
376 void Decoder<V>::DecodeAddSubImmediate(Instruction* instr) {
377  DCHECK_EQ(0x1, instr->Bits(27, 24));
378  if (instr->Bit(23) == 1) {
379  V::VisitUnallocated(instr);
380  } else {
381  V::VisitAddSubImmediate(instr);
382  }
383 }
384 
385 
386 template<typename V>
387 void Decoder<V>::DecodeDataProcessing(Instruction* instr) {
388  DCHECK((instr->Bits(27, 24) == 0xA) ||
389  (instr->Bits(27, 24) == 0xB) );
390 
391  if (instr->Bit(24) == 0) {
392  if (instr->Bit(28) == 0) {
393  if (instr->Mask(0x80008000) == 0x00008000) {
394  V::VisitUnallocated(instr);
395  } else {
396  V::VisitLogicalShifted(instr);
397  }
398  } else {
399  switch (instr->Bits(23, 21)) {
400  case 0: {
401  if (instr->Mask(0x0000FC00) != 0) {
402  V::VisitUnallocated(instr);
403  } else {
404  V::VisitAddSubWithCarry(instr);
405  }
406  break;
407  }
408  case 2: {
409  if ((instr->Bit(29) == 0) ||
410  (instr->Mask(0x00000410) != 0)) {
411  V::VisitUnallocated(instr);
412  } else {
413  if (instr->Bit(11) == 0) {
414  V::VisitConditionalCompareRegister(instr);
415  } else {
416  V::VisitConditionalCompareImmediate(instr);
417  }
418  }
419  break;
420  }
421  case 4: {
422  if (instr->Mask(0x20000800) != 0x00000000) {
423  V::VisitUnallocated(instr);
424  } else {
425  V::VisitConditionalSelect(instr);
426  }
427  break;
428  }
429  case 6: {
430  if (instr->Bit(29) == 0x1) {
431  V::VisitUnallocated(instr);
432  } else {
433  if (instr->Bit(30) == 0) {
434  if ((instr->Bit(15) == 0x1) ||
435  (instr->Bits(15, 11) == 0) ||
436  (instr->Bits(15, 12) == 0x1) ||
437  (instr->Bits(15, 12) == 0x3) ||
438  (instr->Bits(15, 13) == 0x3) ||
439  (instr->Mask(0x8000EC00) == 0x00004C00) ||
440  (instr->Mask(0x8000E800) == 0x80004000) ||
441  (instr->Mask(0x8000E400) == 0x80004000)) {
442  V::VisitUnallocated(instr);
443  } else {
444  V::VisitDataProcessing2Source(instr);
445  }
446  } else {
447  if ((instr->Bit(13) == 1) ||
448  (instr->Bits(20, 16) != 0) ||
449  (instr->Bits(15, 14) != 0) ||
450  (instr->Mask(0xA01FFC00) == 0x00000C00) ||
451  (instr->Mask(0x201FF800) == 0x00001800)) {
452  V::VisitUnallocated(instr);
453  } else {
454  V::VisitDataProcessing1Source(instr);
455  }
456  }
457  break;
458  }
459  V8_FALLTHROUGH;
460  }
461  case 1:
462  case 3:
463  case 5:
464  case 7: V::VisitUnallocated(instr); break;
465  }
466  }
467  } else {
468  if (instr->Bit(28) == 0) {
469  if (instr->Bit(21) == 0) {
470  if ((instr->Bits(23, 22) == 0x3) ||
471  (instr->Mask(0x80008000) == 0x00008000)) {
472  V::VisitUnallocated(instr);
473  } else {
474  V::VisitAddSubShifted(instr);
475  }
476  } else {
477  if ((instr->Mask(0x00C00000) != 0x00000000) ||
478  (instr->Mask(0x00001400) == 0x00001400) ||
479  (instr->Mask(0x00001800) == 0x00001800)) {
480  V::VisitUnallocated(instr);
481  } else {
482  V::VisitAddSubExtended(instr);
483  }
484  }
485  } else {
486  if ((instr->Bit(30) == 0x1) ||
487  (instr->Bits(30, 29) == 0x1) ||
488  (instr->Mask(0xE0600000) == 0x00200000) ||
489  (instr->Mask(0xE0608000) == 0x00400000) ||
490  (instr->Mask(0x60608000) == 0x00408000) ||
491  (instr->Mask(0x60E00000) == 0x00E00000) ||
492  (instr->Mask(0x60E00000) == 0x00800000) ||
493  (instr->Mask(0x60E00000) == 0x00600000)) {
494  V::VisitUnallocated(instr);
495  } else {
496  V::VisitDataProcessing3Source(instr);
497  }
498  }
499  }
500 }
501 
502 
503 template<typename V>
504 void Decoder<V>::DecodeFP(Instruction* instr) {
505  DCHECK((instr->Bits(27, 24) == 0xE) ||
506  (instr->Bits(27, 24) == 0xF) );
507 
508  if (instr->Bit(28) == 0) {
509  DecodeNEONVectorDataProcessing(instr);
510  } else {
511  if (instr->Bits(31, 30) == 0x3) {
512  V::VisitUnallocated(instr);
513  } else if (instr->Bits(31, 30) == 0x1) {
514  DecodeNEONScalarDataProcessing(instr);
515  } else {
516  if (instr->Bit(29) == 0) {
517  if (instr->Bit(24) == 0) {
518  if (instr->Bit(21) == 0) {
519  if ((instr->Bit(23) == 1) ||
520  (instr->Bit(18) == 1) ||
521  (instr->Mask(0x80008000) == 0x00000000) ||
522  (instr->Mask(0x000E0000) == 0x00000000) ||
523  (instr->Mask(0x000E0000) == 0x000A0000) ||
524  (instr->Mask(0x00160000) == 0x00000000) ||
525  (instr->Mask(0x00160000) == 0x00120000)) {
526  V::VisitUnallocated(instr);
527  } else {
528  V::VisitFPFixedPointConvert(instr);
529  }
530  } else {
531  if (instr->Bits(15, 10) == 32) {
532  V::VisitUnallocated(instr);
533  } else if (instr->Bits(15, 10) == 0) {
534  if ((instr->Bits(23, 22) == 0x3) ||
535  (instr->Mask(0x000E0000) == 0x000A0000) ||
536  (instr->Mask(0x000E0000) == 0x000C0000) ||
537  (instr->Mask(0x00160000) == 0x00120000) ||
538  (instr->Mask(0x00160000) == 0x00140000) ||
539  (instr->Mask(0x20C40000) == 0x00800000) ||
540  (instr->Mask(0x20C60000) == 0x00840000) ||
541  (instr->Mask(0xA0C60000) == 0x80060000) ||
542  (instr->Mask(0xA0C60000) == 0x00860000) ||
543  (instr->Mask(0xA0C60000) == 0x00460000) ||
544  (instr->Mask(0xA0CE0000) == 0x80860000) ||
545  (instr->Mask(0xA0CE0000) == 0x804E0000) ||
546  (instr->Mask(0xA0CE0000) == 0x000E0000) ||
547  (instr->Mask(0xA0D60000) == 0x00160000) ||
548  (instr->Mask(0xA0D60000) == 0x80560000) ||
549  (instr->Mask(0xA0D60000) == 0x80960000)) {
550  V::VisitUnallocated(instr);
551  } else {
552  V::VisitFPIntegerConvert(instr);
553  }
554  } else if (instr->Bits(14, 10) == 16) {
555  const Instr masked_A0DF8000 = instr->Mask(0xA0DF8000);
556  if ((instr->Mask(0x80180000) != 0) ||
557  (masked_A0DF8000 == 0x00020000) ||
558  (masked_A0DF8000 == 0x00030000) ||
559  (masked_A0DF8000 == 0x00068000) ||
560  (masked_A0DF8000 == 0x00428000) ||
561  (masked_A0DF8000 == 0x00430000) ||
562  (masked_A0DF8000 == 0x00468000) ||
563  (instr->Mask(0xA0D80000) == 0x00800000) ||
564  (instr->Mask(0xA0DE0000) == 0x00C00000) ||
565  (instr->Mask(0xA0DF0000) == 0x00C30000) ||
566  (instr->Mask(0xA0DC0000) == 0x00C40000)) {
567  V::VisitUnallocated(instr);
568  } else {
569  V::VisitFPDataProcessing1Source(instr);
570  }
571  } else if (instr->Bits(13, 10) == 8) {
572  if ((instr->Bits(15, 14) != 0) ||
573  (instr->Bits(2, 0) != 0) ||
574  (instr->Mask(0x80800000) != 0x00000000)) {
575  V::VisitUnallocated(instr);
576  } else {
577  V::VisitFPCompare(instr);
578  }
579  } else if (instr->Bits(12, 10) == 4) {
580  if ((instr->Bits(9, 5) != 0) ||
581  (instr->Mask(0x80800000) != 0x00000000)) {
582  V::VisitUnallocated(instr);
583  } else {
584  V::VisitFPImmediate(instr);
585  }
586  } else {
587  if (instr->Mask(0x80800000) != 0x00000000) {
588  V::VisitUnallocated(instr);
589  } else {
590  switch (instr->Bits(11, 10)) {
591  case 1: {
592  V::VisitFPConditionalCompare(instr);
593  break;
594  }
595  case 2: {
596  if ((instr->Bits(15, 14) == 0x3) ||
597  (instr->Mask(0x00009000) == 0x00009000) ||
598  (instr->Mask(0x0000A000) == 0x0000A000)) {
599  V::VisitUnallocated(instr);
600  } else {
601  V::VisitFPDataProcessing2Source(instr);
602  }
603  break;
604  }
605  case 3: {
606  V::VisitFPConditionalSelect(instr);
607  break;
608  }
609  default: UNREACHABLE();
610  }
611  }
612  }
613  }
614  } else {
615  // Bit 30 == 1 has been handled earlier.
616  DCHECK_EQ(0, instr->Bit(30));
617  if (instr->Mask(0xA0800000) != 0) {
618  V::VisitUnallocated(instr);
619  } else {
620  V::VisitFPDataProcessing3Source(instr);
621  }
622  }
623  } else {
624  V::VisitUnallocated(instr);
625  }
626  }
627  }
628 }
629 
630 template <typename V>
631 void Decoder<V>::DecodeNEONLoadStore(Instruction* instr) {
632  DCHECK_EQ(0x6, instr->Bits(29, 25));
633  if (instr->Bit(31) == 0) {
634  if ((instr->Bit(24) == 0) && (instr->Bit(21) == 1)) {
635  V::VisitUnallocated(instr);
636  return;
637  }
638 
639  if (instr->Bit(23) == 0) {
640  if (instr->Bits(20, 16) == 0) {
641  if (instr->Bit(24) == 0) {
642  V::VisitNEONLoadStoreMultiStruct(instr);
643  } else {
644  V::VisitNEONLoadStoreSingleStruct(instr);
645  }
646  } else {
647  V::VisitUnallocated(instr);
648  }
649  } else {
650  if (instr->Bit(24) == 0) {
651  V::VisitNEONLoadStoreMultiStructPostIndex(instr);
652  } else {
653  V::VisitNEONLoadStoreSingleStructPostIndex(instr);
654  }
655  }
656  } else {
657  V::VisitUnallocated(instr);
658  }
659 }
660 
661 template <typename V>
662 void Decoder<V>::DecodeNEONVectorDataProcessing(Instruction* instr) {
663  DCHECK_EQ(0x7, instr->Bits(28, 25));
664  if (instr->Bit(31) == 0) {
665  if (instr->Bit(24) == 0) {
666  if (instr->Bit(21) == 0) {
667  if (instr->Bit(15) == 0) {
668  if (instr->Bit(10) == 0) {
669  if (instr->Bit(29) == 0) {
670  if (instr->Bit(11) == 0) {
671  V::VisitNEONTable(instr);
672  } else {
673  V::VisitNEONPerm(instr);
674  }
675  } else {
676  V::VisitNEONExtract(instr);
677  }
678  } else {
679  if (instr->Bits(23, 22) == 0) {
680  V::VisitNEONCopy(instr);
681  } else {
682  V::VisitUnallocated(instr);
683  }
684  }
685  } else {
686  V::VisitUnallocated(instr);
687  }
688  } else {
689  if (instr->Bit(10) == 0) {
690  if (instr->Bit(11) == 0) {
691  V::VisitNEON3Different(instr);
692  } else {
693  if (instr->Bits(18, 17) == 0) {
694  if (instr->Bit(20) == 0) {
695  if (instr->Bit(19) == 0) {
696  V::VisitNEON2RegMisc(instr);
697  } else {
698  if (instr->Bits(30, 29) == 0x2) {
699  V::VisitUnallocated(instr);
700  } else {
701  V::VisitUnallocated(instr);
702  }
703  }
704  } else {
705  if (instr->Bit(19) == 0) {
706  V::VisitNEONAcrossLanes(instr);
707  } else {
708  V::VisitUnallocated(instr);
709  }
710  }
711  } else {
712  V::VisitUnallocated(instr);
713  }
714  }
715  } else {
716  V::VisitNEON3Same(instr);
717  }
718  }
719  } else {
720  if (instr->Bit(10) == 0) {
721  V::VisitNEONByIndexedElement(instr);
722  } else {
723  if (instr->Bit(23) == 0) {
724  if (instr->Bits(22, 19) == 0) {
725  V::VisitNEONModifiedImmediate(instr);
726  } else {
727  V::VisitNEONShiftImmediate(instr);
728  }
729  } else {
730  V::VisitUnallocated(instr);
731  }
732  }
733  }
734  } else {
735  V::VisitUnallocated(instr);
736  }
737 }
738 
739 template <typename V>
740 void Decoder<V>::DecodeNEONScalarDataProcessing(Instruction* instr) {
741  DCHECK_EQ(0xF, instr->Bits(28, 25));
742  if (instr->Bit(24) == 0) {
743  if (instr->Bit(21) == 0) {
744  if (instr->Bit(15) == 0) {
745  if (instr->Bit(10) == 0) {
746  if (instr->Bit(29) == 0) {
747  if (instr->Bit(11) == 0) {
748  V::VisitUnallocated(instr);
749  } else {
750  V::VisitUnallocated(instr);
751  }
752  } else {
753  V::VisitUnallocated(instr);
754  }
755  } else {
756  if (instr->Bits(23, 22) == 0) {
757  V::VisitNEONScalarCopy(instr);
758  } else {
759  V::VisitUnallocated(instr);
760  }
761  }
762  } else {
763  V::VisitUnallocated(instr);
764  }
765  } else {
766  if (instr->Bit(10) == 0) {
767  if (instr->Bit(11) == 0) {
768  V::VisitNEONScalar3Diff(instr);
769  } else {
770  if (instr->Bits(18, 17) == 0) {
771  if (instr->Bit(20) == 0) {
772  if (instr->Bit(19) == 0) {
773  V::VisitNEONScalar2RegMisc(instr);
774  } else {
775  if (instr->Bit(29) == 0) {
776  V::VisitUnallocated(instr);
777  } else {
778  V::VisitUnallocated(instr);
779  }
780  }
781  } else {
782  if (instr->Bit(19) == 0) {
783  V::VisitNEONScalarPairwise(instr);
784  } else {
785  V::VisitUnallocated(instr);
786  }
787  }
788  } else {
789  V::VisitUnallocated(instr);
790  }
791  }
792  } else {
793  V::VisitNEONScalar3Same(instr);
794  }
795  }
796  } else {
797  if (instr->Bit(10) == 0) {
798  V::VisitNEONScalarByIndexedElement(instr);
799  } else {
800  if (instr->Bit(23) == 0) {
801  V::VisitNEONScalarShiftImmediate(instr);
802  } else {
803  V::VisitUnallocated(instr);
804  }
805  }
806  }
807 }
808 
809 
810 } // namespace internal
811 } // namespace v8
812 
813 #endif // V8_ARM64_DECODER_ARM64_INL_H_
Definition: libplatform.h:13