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-vixl.h" 28 #include "utils-vixl.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 VIXL_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 VIXL_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 VIXL_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 VIXL_ASSERT(instr->Bit(28) == 0x1); 168 VisitPCRelAddressing(instr); 169 } 170 171 172 void Decoder::DecodeBranchSystemException(Instruction* instr) { 173 VIXL_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 VIXL_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 VIXL_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 VIXL_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 VIXL_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 VIXL_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 VIXL_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: VIXL_UNREACHABLE(); 669 } 670 } 671 } 672 } 673 } else { 674 // Bit 30 == 1 has been handled earlier. 675 VIXL_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 VIXL_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 VIXL_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 VIXL_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 713