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