Decoder-vixl.cpp (28979B)
1 // Copyright 2014, VIXL authors 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 "jit/arm64/vixl/Decoder-vixl.h" 28 29 #include <algorithm> 30 31 #include "jit/arm64/vixl/Globals-vixl.h" 32 #include "jit/arm64/vixl/Utils-vixl.h" 33 34 namespace vixl { 35 36 void Decoder::DecodeInstruction(const Instruction *instr) { 37 if (instr->Bits(28, 27) == 0) { 38 VisitUnallocated(instr); 39 } else { 40 switch (instr->Bits(27, 24)) { 41 // 0: PC relative addressing. 42 case 0x0: DecodePCRelAddressing(instr); break; 43 44 // 1: Add/sub immediate. 45 case 0x1: DecodeAddSubImmediate(instr); break; 46 47 // A: Logical shifted register. 48 // Add/sub with carry. 49 // Conditional compare register. 50 // Conditional compare immediate. 51 // Conditional select. 52 // Data processing 1 source. 53 // Data processing 2 source. 54 // B: Add/sub shifted register. 55 // Add/sub extended register. 56 // Data processing 3 source. 57 case 0xA: 58 case 0xB: DecodeDataProcessing(instr); break; 59 60 // 2: Logical immediate. 61 // Move wide immediate. 62 case 0x2: DecodeLogical(instr); break; 63 64 // 3: Bitfield. 65 // Extract. 66 case 0x3: DecodeBitfieldExtract(instr); break; 67 68 // 4: Unconditional branch immediate. 69 // Exception generation. 70 // Compare and branch immediate. 71 // 5: Compare and branch immediate. 72 // Conditional branch. 73 // System. 74 // 6,7: Unconditional branch. 75 // Test and branch immediate. 76 case 0x4: 77 case 0x5: 78 case 0x6: 79 case 0x7: DecodeBranchSystemException(instr); break; 80 81 // 8,9: Load/store register pair post-index. 82 // Load register literal. 83 // Load/store register unscaled immediate. 84 // Load/store register immediate post-index. 85 // Load/store register immediate pre-index. 86 // Load/store register offset. 87 // Load/store exclusive. 88 // C,D: Load/store register pair offset. 89 // Load/store register pair pre-index. 90 // Load/store register unsigned immediate. 91 // Advanced SIMD. 92 case 0x8: 93 case 0x9: 94 case 0xC: 95 case 0xD: DecodeLoadStore(instr); break; 96 97 // E: FP fixed point conversion. 98 // FP integer conversion. 99 // FP data processing 1 source. 100 // FP compare. 101 // FP immediate. 102 // FP data processing 2 source. 103 // FP conditional compare. 104 // FP conditional select. 105 // Advanced SIMD. 106 // F: FP data processing 3 source. 107 // Advanced SIMD. 108 case 0xE: 109 case 0xF: DecodeFP(instr); break; 110 } 111 } 112 } 113 114 void Decoder::AppendVisitor(DecoderVisitor* new_visitor) { 115 MOZ_ALWAYS_TRUE(visitors_.append(new_visitor)); 116 } 117 118 119 void Decoder::PrependVisitor(DecoderVisitor* new_visitor) { 120 MOZ_ALWAYS_TRUE(visitors_.insert(visitors_.begin(), new_visitor)); 121 } 122 123 124 void Decoder::InsertVisitorBefore(DecoderVisitor* new_visitor, 125 DecoderVisitor* registered_visitor) { 126 for (auto it = visitors_.begin(); it != visitors_.end(); it++) { 127 if (*it == registered_visitor) { 128 MOZ_ALWAYS_TRUE(visitors_.insert(it, new_visitor)); 129 return; 130 } 131 } 132 // We reached the end of the list without finding registered_visitor. 133 MOZ_ALWAYS_TRUE(visitors_.append(new_visitor)); 134 } 135 136 137 void Decoder::InsertVisitorAfter(DecoderVisitor* new_visitor, 138 DecoderVisitor* registered_visitor) { 139 for (auto it = visitors_.begin(); it != visitors_.end(); it++) { 140 if (*it == registered_visitor) { 141 it++; 142 MOZ_ALWAYS_TRUE(visitors_.insert(it, new_visitor)); 143 return; 144 } 145 } 146 // We reached the end of the list without finding registered_visitor. 147 MOZ_ALWAYS_TRUE(visitors_.append(new_visitor)); 148 } 149 150 151 void Decoder::RemoveVisitor(DecoderVisitor* visitor) { 152 visitors_.erase(std::remove(visitors_.begin(), visitors_.end(), visitor), 153 visitors_.end()); 154 } 155 156 157 void Decoder::DecodePCRelAddressing(const Instruction* instr) { 158 VIXL_ASSERT(instr->Bits(27, 24) == 0x0); 159 // We know bit 28 is set, as <b28:b27> = 0 is filtered out at the top level 160 // decode. 161 VIXL_ASSERT(instr->Bit(28) == 0x1); 162 VisitPCRelAddressing(instr); 163 } 164 165 166 void Decoder::DecodeBranchSystemException(const Instruction* instr) { 167 VIXL_ASSERT((instr->Bits(27, 24) == 0x4) || 168 (instr->Bits(27, 24) == 0x5) || 169 (instr->Bits(27, 24) == 0x6) || 170 (instr->Bits(27, 24) == 0x7) ); 171 172 switch (instr->Bits(31, 29)) { 173 case 0: 174 case 4: { 175 VisitUnconditionalBranch(instr); 176 break; 177 } 178 case 1: 179 case 5: { 180 if (instr->Bit(25) == 0) { 181 VisitCompareBranch(instr); 182 } else { 183 VisitTestBranch(instr); 184 } 185 break; 186 } 187 case 2: { 188 if (instr->Bit(25) == 0) { 189 if ((instr->Bit(24) == 0x1) || 190 (instr->Mask(0x01000010) == 0x00000010)) { 191 VisitUnallocated(instr); 192 } else { 193 VisitConditionalBranch(instr); 194 } 195 } else { 196 VisitUnallocated(instr); 197 } 198 break; 199 } 200 case 6: { 201 if (instr->Bit(25) == 0) { 202 if (instr->Bit(24) == 0) { 203 if ((instr->Bits(4, 2) != 0) || 204 (instr->Mask(0x00E0001D) == 0x00200001) || 205 (instr->Mask(0x00E0001D) == 0x00400001) || 206 (instr->Mask(0x00E0001E) == 0x00200002) || 207 (instr->Mask(0x00E0001E) == 0x00400002) || 208 (instr->Mask(0x00E0001C) == 0x00600000) || 209 (instr->Mask(0x00E0001C) == 0x00800000) || 210 (instr->Mask(0x00E0001F) == 0x00A00000) || 211 (instr->Mask(0x00C0001C) == 0x00C00000)) { 212 if (instr->InstructionBits() == UNDEFINED_INST_PATTERN) { 213 VisitException(instr); 214 } else { 215 VisitUnallocated(instr); 216 } 217 } else { 218 VisitException(instr); 219 } 220 } else { 221 if (instr->Bits(23, 22) == 0) { 222 const Instr masked_003FF0E0 = instr->Mask(0x003FF0E0); 223 if ((instr->Bits(21, 19) == 0x4) || 224 (masked_003FF0E0 == 0x00033000) || 225 (masked_003FF0E0 == 0x003FF020) || 226 (masked_003FF0E0 == 0x003FF060) || 227 (masked_003FF0E0 == 0x003FF0E0) || 228 (instr->Mask(0x00388000) == 0x00008000) || 229 (instr->Mask(0x0038E000) == 0x00000000) || 230 (instr->Mask(0x0039E000) == 0x00002000) || 231 (instr->Mask(0x003AE000) == 0x00002000) || 232 (instr->Mask(0x003CE000) == 0x00042000) || 233 (instr->Mask(0x003FFFC0) == 0x000320C0) || 234 (instr->Mask(0x003FF100) == 0x00032100) || 235 // (instr->Mask(0x003FF200) == 0x00032200) || // match CSDB 236 (instr->Mask(0x003FF400) == 0x00032400) || 237 (instr->Mask(0x003FF800) == 0x00032800) || 238 (instr->Mask(0x0038F000) == 0x00005000) || 239 (instr->Mask(0x0038E000) == 0x00006000)) { 240 VisitUnallocated(instr); 241 } else { 242 VisitSystem(instr); 243 } 244 } else { 245 VisitUnallocated(instr); 246 } 247 } 248 } else { 249 if ((instr->Bit(24) == 0x1) || 250 (instr->Bits(20, 16) != 0x1F) || 251 (instr->Bits(15, 10) != 0) || 252 (instr->Bits(4, 0) != 0) || 253 (instr->Bits(24, 21) == 0x3) || 254 (instr->Bits(24, 22) == 0x3)) { 255 VisitUnallocated(instr); 256 } else { 257 VisitUnconditionalBranchToRegister(instr); 258 } 259 } 260 break; 261 } 262 case 3: 263 case 7: { 264 VisitUnallocated(instr); 265 break; 266 } 267 } 268 } 269 270 271 void Decoder::DecodeLoadStore(const Instruction* instr) { 272 VIXL_ASSERT((instr->Bits(27, 24) == 0x8) || 273 (instr->Bits(27, 24) == 0x9) || 274 (instr->Bits(27, 24) == 0xC) || 275 (instr->Bits(27, 24) == 0xD) ); 276 // TODO(all): rearrange the tree to integrate this branch. 277 if ((instr->Bit(28) == 0) && (instr->Bit(29) == 0) && (instr->Bit(26) == 1)) { 278 DecodeNEONLoadStore(instr); 279 return; 280 } 281 282 if (instr->Bit(24) == 0) { 283 if (instr->Bit(28) == 0) { 284 if (instr->Bit(29) == 0) { 285 if (instr->Bit(26) == 0) { 286 VisitLoadStoreExclusive(instr); 287 } else { 288 VIXL_UNREACHABLE(); 289 } 290 } else { 291 if ((instr->Bits(31, 30) == 0x3) || 292 (instr->Mask(0xC4400000) == 0x40000000)) { 293 VisitUnallocated(instr); 294 } else { 295 if (instr->Bit(23) == 0) { 296 if (instr->Mask(0xC4400000) == 0xC0400000) { 297 VisitUnallocated(instr); 298 } else { 299 VisitLoadStorePairNonTemporal(instr); 300 } 301 } else { 302 VisitLoadStorePairPostIndex(instr); 303 } 304 } 305 } 306 } else { 307 if (instr->Bit(29) == 0) { 308 if (instr->Mask(0xC4000000) == 0xC4000000) { 309 VisitUnallocated(instr); 310 } else { 311 VisitLoadLiteral(instr); 312 } 313 } else { 314 if ((instr->Mask(0x44800000) == 0x44800000) || 315 (instr->Mask(0x84800000) == 0x84800000)) { 316 VisitUnallocated(instr); 317 } else { 318 if (instr->Bit(21) == 0) { 319 switch (instr->Bits(11, 10)) { 320 case 0: { 321 VisitLoadStoreUnscaledOffset(instr); 322 break; 323 } 324 case 1: { 325 if (instr->Mask(0xC4C00000) == 0xC0800000) { 326 VisitUnallocated(instr); 327 } else { 328 VisitLoadStorePostIndex(instr); 329 } 330 break; 331 } 332 case 2: { 333 // TODO: VisitLoadStoreRegisterOffsetUnpriv. 334 VisitUnimplemented(instr); 335 break; 336 } 337 case 3: { 338 if (instr->Mask(0xC4C00000) == 0xC0800000) { 339 VisitUnallocated(instr); 340 } else { 341 VisitLoadStorePreIndex(instr); 342 } 343 break; 344 } 345 } 346 } else { 347 if (instr->Bits(11, 10) == 0x2) { 348 if (instr->Bit(14) == 0) { 349 VisitUnallocated(instr); 350 } else { 351 VisitLoadStoreRegisterOffset(instr); 352 } 353 } else { 354 if (instr->Bits(11, 10) == 0x0) { 355 if (instr->Bit(25) == 0) { 356 if (instr->Bit(26) == 0) { 357 if ((instr->Bit(15) == 1) && 358 ((instr->Bits(14, 12) == 0x1) || 359 (instr->Bit(13) == 1) || 360 (instr->Bits(14, 12) == 0x5) || 361 ((instr->Bits(14, 12) == 0x4) && 362 ((instr->Bit(23) == 0) || 363 (instr->Bits(23, 22) == 0x3))))) { 364 VisitUnallocated(instr); 365 } else { 366 VisitAtomicMemory(instr); 367 } 368 } else { 369 VisitUnallocated(instr); 370 } 371 } else { 372 VisitUnallocated(instr); 373 } 374 } else { 375 VisitUnallocated(instr); 376 } 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(const Instruction* instr) { 416 VIXL_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(const Instruction* instr) { 435 VIXL_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(const Instruction* instr) { 460 VIXL_ASSERT(instr->Bits(27, 24) == 0x1); 461 if (instr->Bit(23) == 1) { 462 if (instr->Bit(22) == 1) { 463 VisitMaxMinImmediate(instr); 464 } else { 465 VisitUnallocated(instr); 466 } 467 } else { 468 VisitAddSubImmediate(instr); 469 } 470 } 471 472 473 void Decoder::DecodeDataProcessing(const Instruction* instr) { 474 VIXL_ASSERT((instr->Bits(27, 24) == 0xA) || 475 (instr->Bits(27, 24) == 0xB)); 476 477 if (instr->Bit(24) == 0) { 478 if (instr->Bit(28) == 0) { 479 if (instr->Mask(0x80008000) == 0x00008000) { 480 VisitUnallocated(instr); 481 } else { 482 VisitLogicalShifted(instr); 483 } 484 } else { 485 switch (instr->Bits(23, 21)) { 486 case 0: { 487 if (instr->Mask(0x0000FC00) != 0) { 488 VisitUnallocated(instr); 489 } else { 490 VisitAddSubWithCarry(instr); 491 } 492 break; 493 } 494 case 2: { 495 if ((instr->Bit(29) == 0) || 496 (instr->Mask(0x00000410) != 0)) { 497 VisitUnallocated(instr); 498 } else { 499 if (instr->Bit(11) == 0) { 500 VisitConditionalCompareRegister(instr); 501 } else { 502 VisitConditionalCompareImmediate(instr); 503 } 504 } 505 break; 506 } 507 case 4: { 508 if (instr->Mask(0x20000800) != 0x00000000) { 509 VisitUnallocated(instr); 510 } else { 511 VisitConditionalSelect(instr); 512 } 513 break; 514 } 515 case 6: { 516 if (instr->Bit(29) == 0x1) { 517 VisitUnallocated(instr); 518 VIXL_FALLTHROUGH(); 519 } else { 520 if (instr->Bit(30) == 0) { 521 if ((instr->Bit(15) == 0x1) || 522 (instr->Bits(15, 11) == 0) || 523 (instr->Bits(15, 12) == 0x1) || 524 (instr->Bits(15, 12) == 0x3) || 525 (instr->Mask(0x8000EC00) == 0x00004C00) || 526 (instr->Mask(0x8000E800) == 0x80004000) || 527 (instr->Mask(0x8000E400) == 0x80004000)) { 528 VisitUnallocated(instr); 529 } else { 530 VisitDataProcessing2Source(instr); 531 } 532 } else { 533 if ((instr->Bits(20, 16) != 0) || 534 (instr->Bits(15, 14) != 0) || 535 (instr->Mask(0xA01FFC00) == 0x00000C00)) { 536 VisitUnallocated(instr); 537 } else { 538 VisitDataProcessing1Source(instr); 539 } 540 } 541 break; 542 } 543 } 544 case 1: 545 case 3: 546 case 5: 547 case 7: VisitUnallocated(instr); break; 548 } 549 } 550 } else { 551 if (instr->Bit(28) == 0) { 552 if (instr->Bit(21) == 0) { 553 if ((instr->Bits(23, 22) == 0x3) || 554 (instr->Mask(0x80008000) == 0x00008000)) { 555 VisitUnallocated(instr); 556 } else { 557 VisitAddSubShifted(instr); 558 } 559 } else { 560 if ((instr->Mask(0x00C00000) != 0x00000000) || 561 (instr->Mask(0x00001400) == 0x00001400) || 562 (instr->Mask(0x00001800) == 0x00001800)) { 563 VisitUnallocated(instr); 564 } else { 565 VisitAddSubExtended(instr); 566 } 567 } 568 } else { 569 if ((instr->Bit(30) == 0x1) || 570 (instr->Bits(30, 29) == 0x1) || 571 (instr->Mask(0xE0600000) == 0x00200000) || 572 (instr->Mask(0xE0608000) == 0x00400000) || 573 (instr->Mask(0x60608000) == 0x00408000) || 574 (instr->Mask(0x60E00000) == 0x00E00000) || 575 (instr->Mask(0x60E00000) == 0x00800000) || 576 (instr->Mask(0x60E00000) == 0x00600000)) { 577 VisitUnallocated(instr); 578 } else { 579 VisitDataProcessing3Source(instr); 580 } 581 } 582 } 583 } 584 585 586 void Decoder::DecodeFP(const Instruction* instr) { 587 VIXL_ASSERT((instr->Bits(27, 24) == 0xE) || 588 (instr->Bits(27, 24) == 0xF)); 589 if (instr->Bit(28) == 0) { 590 DecodeNEONVectorDataProcessing(instr); 591 } else { 592 if (instr->Bits(31, 30) == 0x3) { 593 VisitUnallocated(instr); 594 } else if (instr->Bits(31, 30) == 0x1) { 595 DecodeNEONScalarDataProcessing(instr); 596 } else { 597 if (instr->Bit(29) == 0) { 598 if (instr->Bit(24) == 0) { 599 if (instr->Bit(21) == 0) { 600 if ((instr->Bit(23) == 1) || 601 (instr->Bit(18) == 1) || 602 (instr->Mask(0x80008000) == 0x00000000) || 603 (instr->Mask(0x000E0000) == 0x00000000) || 604 (instr->Mask(0x000E0000) == 0x000A0000) || 605 (instr->Mask(0x00160000) == 0x00000000) || 606 (instr->Mask(0x00160000) == 0x00120000)) { 607 VisitUnallocated(instr); 608 } else { 609 VisitFPFixedPointConvert(instr); 610 } 611 } else { 612 if (instr->Bits(15, 10) == 32) { 613 VisitUnallocated(instr); 614 } else if (instr->Bits(15, 10) == 0) { 615 if ((instr->Bits(23, 22) == 0x3) || 616 (instr->Mask(0x000E0000) == 0x000A0000) || 617 (instr->Mask(0x000E0000) == 0x000C0000) || 618 (instr->Mask(0x00160000) == 0x00120000) || 619 (instr->Mask(0x00160000) == 0x00140000) || 620 (instr->Mask(0x20C40000) == 0x00800000) || 621 (instr->Mask(0x20C60000) == 0x00840000) || 622 (instr->Mask(0xA0C60000) == 0x80060000) || 623 (instr->Mask(0xA0C60000) == 0x00860000) || 624 (instr->Mask(0xA0CE0000) == 0x80860000) || 625 (instr->Mask(0xA0CE0000) == 0x804E0000) || 626 (instr->Mask(0xA0CE0000) == 0x000E0000) || 627 (instr->Mask(0xA0D60000) == 0x00160000) || 628 (instr->Mask(0xA0D60000) == 0x80560000) || 629 (instr->Mask(0xA0D60000) == 0x80960000)) { 630 VisitUnallocated(instr); 631 } else { 632 VisitFPIntegerConvert(instr); 633 } 634 } else if (instr->Bits(14, 10) == 16) { 635 const Instr masked_A0DF8000 = instr->Mask(0xA0DF8000); 636 if ((instr->Mask(0x80180000) != 0) || 637 (masked_A0DF8000 == 0x00020000) || 638 (masked_A0DF8000 == 0x00030000) || 639 (masked_A0DF8000 == 0x00068000) || 640 (masked_A0DF8000 == 0x00428000) || 641 (masked_A0DF8000 == 0x00430000) || 642 (masked_A0DF8000 == 0x00468000) || 643 (instr->Mask(0xA0D80000) == 0x00800000) || 644 (instr->Mask(0xA0DE0000) == 0x00C00000) || 645 (instr->Mask(0xA0DF0000) == 0x00C30000) || 646 (instr->Mask(0xA0DC0000) == 0x00C40000)) { 647 VisitUnallocated(instr); 648 } else { 649 VisitFPDataProcessing1Source(instr); 650 } 651 } else if (instr->Bits(13, 10) == 8) { 652 if ((instr->Bits(15, 14) != 0) || 653 (instr->Bits(2, 0) != 0) || 654 (instr->Mask(0x80800000) != 0x00000000)) { 655 VisitUnallocated(instr); 656 } else { 657 VisitFPCompare(instr); 658 } 659 } else if (instr->Bits(12, 10) == 4) { 660 if ((instr->Bits(9, 5) != 0) || 661 (instr->Mask(0x80800000) != 0x00000000)) { 662 VisitUnallocated(instr); 663 } else { 664 VisitFPImmediate(instr); 665 } 666 } else { 667 if (instr->Mask(0x80800000) != 0x00000000) { 668 VisitUnallocated(instr); 669 } else { 670 switch (instr->Bits(11, 10)) { 671 case 1: { 672 VisitFPConditionalCompare(instr); 673 break; 674 } 675 case 2: { 676 if ((instr->Bits(15, 14) == 0x3) || 677 (instr->Mask(0x00009000) == 0x00009000) || 678 (instr->Mask(0x0000A000) == 0x0000A000)) { 679 VisitUnallocated(instr); 680 } else { 681 VisitFPDataProcessing2Source(instr); 682 } 683 break; 684 } 685 case 3: { 686 VisitFPConditionalSelect(instr); 687 break; 688 } 689 default: VIXL_UNREACHABLE(); 690 } 691 } 692 } 693 } 694 } else { 695 // Bit 30 == 1 has been handled earlier. 696 VIXL_ASSERT(instr->Bit(30) == 0); 697 if (instr->Mask(0xA0800000) != 0) { 698 VisitUnallocated(instr); 699 } else { 700 VisitFPDataProcessing3Source(instr); 701 } 702 } 703 } else { 704 VisitUnallocated(instr); 705 } 706 } 707 } 708 } 709 710 711 void Decoder::DecodeNEONLoadStore(const Instruction* instr) { 712 VIXL_ASSERT(instr->Bits(29, 25) == 0x6); 713 if (instr->Bit(31) == 0) { 714 if ((instr->Bit(24) == 0) && (instr->Bit(21) == 1)) { 715 VisitUnallocated(instr); 716 return; 717 } 718 719 if (instr->Bit(23) == 0) { 720 if (instr->Bits(20, 16) == 0) { 721 if (instr->Bit(24) == 0) { 722 VisitNEONLoadStoreMultiStruct(instr); 723 } else { 724 VisitNEONLoadStoreSingleStruct(instr); 725 } 726 } else { 727 VisitUnallocated(instr); 728 } 729 } else { 730 if (instr->Bit(24) == 0) { 731 VisitNEONLoadStoreMultiStructPostIndex(instr); 732 } else { 733 VisitNEONLoadStoreSingleStructPostIndex(instr); 734 } 735 } 736 } else { 737 VisitUnallocated(instr); 738 } 739 } 740 741 742 void Decoder::DecodeNEONVectorDataProcessing(const Instruction* instr) { 743 VIXL_ASSERT(instr->Bits(28, 25) == 0x7); 744 if (instr->Bit(31) == 0) { 745 if (instr->Bit(24) == 0) { 746 if (instr->Bit(21) == 0) { 747 if (instr->Bit(15) == 0) { 748 if (instr->Bit(10) == 0) { 749 if (instr->Bit(29) == 0) { 750 if (instr->Bit(11) == 0) { 751 VisitNEONTable(instr); 752 } else { 753 VisitNEONPerm(instr); 754 } 755 } else { 756 VisitNEONExtract(instr); 757 } 758 } else { 759 if (instr->Bits(23, 22) == 0) { 760 VisitNEONCopy(instr); 761 } else { 762 VisitUnallocated(instr); 763 } 764 } 765 } else { 766 VisitUnallocated(instr); 767 } 768 } else { 769 if (instr->Bit(10) == 0) { 770 if (instr->Bit(11) == 0) { 771 VisitNEON3Different(instr); 772 } else { 773 if (instr->Bits(18, 17) == 0) { 774 if (instr->Bit(20) == 0) { 775 if (instr->Bit(19) == 0) { 776 VisitNEON2RegMisc(instr); 777 } else { 778 if (instr->Bits(30, 29) == 0x2) { 779 VisitCryptoAES(instr); 780 } else { 781 VisitUnallocated(instr); 782 } 783 } 784 } else { 785 if (instr->Bit(19) == 0) { 786 VisitNEONAcrossLanes(instr); 787 } else { 788 VisitUnallocated(instr); 789 } 790 } 791 } else { 792 VisitUnallocated(instr); 793 } 794 } 795 } else { 796 VisitNEON3Same(instr); 797 } 798 } 799 } else { 800 if (instr->Bit(10) == 0) { 801 VisitNEONByIndexedElement(instr); 802 } else { 803 if (instr->Bit(23) == 0) { 804 if (instr->Bits(22, 19) == 0) { 805 VisitNEONModifiedImmediate(instr); 806 } else { 807 VisitNEONShiftImmediate(instr); 808 } 809 } else { 810 VisitUnallocated(instr); 811 } 812 } 813 } 814 } else { 815 VisitUnallocated(instr); 816 } 817 } 818 819 820 void Decoder::DecodeNEONScalarDataProcessing(const Instruction* instr) { 821 VIXL_ASSERT(instr->Bits(28, 25) == 0xF); 822 if (instr->Bit(24) == 0) { 823 if (instr->Bit(21) == 0) { 824 if (instr->Bit(15) == 0) { 825 if (instr->Bit(10) == 0) { 826 if (instr->Bit(29) == 0) { 827 if (instr->Bit(11) == 0) { 828 VisitCrypto3RegSHA(instr); 829 } else { 830 VisitUnallocated(instr); 831 } 832 } else { 833 VisitUnallocated(instr); 834 } 835 } else { 836 if (instr->Bits(23, 22) == 0) { 837 VisitNEONScalarCopy(instr); 838 } else { 839 VisitUnallocated(instr); 840 } 841 } 842 } else { 843 VisitUnallocated(instr); 844 } 845 } else { 846 if (instr->Bit(10) == 0) { 847 if (instr->Bit(11) == 0) { 848 VisitNEONScalar3Diff(instr); 849 } else { 850 if (instr->Bits(18, 17) == 0) { 851 if (instr->Bit(20) == 0) { 852 if (instr->Bit(19) == 0) { 853 VisitNEONScalar2RegMisc(instr); 854 } else { 855 if (instr->Bit(29) == 0) { 856 VisitCrypto2RegSHA(instr); 857 } else { 858 VisitUnallocated(instr); 859 } 860 } 861 } else { 862 if (instr->Bit(19) == 0) { 863 VisitNEONScalarPairwise(instr); 864 } else { 865 VisitUnallocated(instr); 866 } 867 } 868 } else { 869 VisitUnallocated(instr); 870 } 871 } 872 } else { 873 VisitNEONScalar3Same(instr); 874 } 875 } 876 } else { 877 if (instr->Bit(10) == 0) { 878 VisitNEONScalarByIndexedElement(instr); 879 } else { 880 if (instr->Bit(23) == 0) { 881 VisitNEONScalarShiftImmediate(instr); 882 } else { 883 VisitUnallocated(instr); 884 } 885 } 886 } 887 } 888 889 890 #define DEFINE_VISITOR_CALLERS(A) \ 891 void Decoder::Visit##A(const Instruction *instr) { \ 892 VIXL_ASSERT(A##FMask == 0 || instr->Mask(A##FMask) == A##Fixed); \ 893 for (auto visitor : visitors_) { \ 894 visitor->Visit##A(instr); \ 895 } \ 896 } 897 VISITOR_LIST(DEFINE_VISITOR_CALLERS) 898 #undef DEFINE_VISITOR_CALLERS 899 } // namespace vixl