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