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