decoder-a64.cc (28131B)
1// Copyright 2014, 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 "vixl/globals.h" 28#include "vixl/utils.h" 29#include "vixl/a64/decoder-a64.h" 30 31namespace vixl { 32 33void Decoder::DecodeInstruction(const 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 111void Decoder::AppendVisitor(DecoderVisitor* new_visitor) { 112 visitors_.push_back(new_visitor); 113} 114 115 116void Decoder::PrependVisitor(DecoderVisitor* new_visitor) { 117 visitors_.push_front(new_visitor); 118} 119 120 121void Decoder::InsertVisitorBefore(DecoderVisitor* new_visitor, 122 DecoderVisitor* registered_visitor) { 123 std::list<DecoderVisitor*>::iterator it; 124 for (it = visitors_.begin(); it != visitors_.end(); it++) { 125 if (*it == registered_visitor) { 126 visitors_.insert(it, new_visitor); 127 return; 128 } 129 } 130 // We reached the end of the list. The last element must be 131 // registered_visitor. 132 VIXL_ASSERT(*it == registered_visitor); 133 visitors_.insert(it, new_visitor); 134} 135 136 137void Decoder::InsertVisitorAfter(DecoderVisitor* new_visitor, 138 DecoderVisitor* registered_visitor) { 139 std::list<DecoderVisitor*>::iterator it; 140 for (it = visitors_.begin(); it != visitors_.end(); it++) { 141 if (*it == registered_visitor) { 142 it++; 143 visitors_.insert(it, new_visitor); 144 return; 145 } 146 } 147 // We reached the end of the list. The last element must be 148 // registered_visitor. 149 VIXL_ASSERT(*it == registered_visitor); 150 visitors_.push_back(new_visitor); 151} 152 153 154void Decoder::RemoveVisitor(DecoderVisitor* visitor) { 155 visitors_.remove(visitor); 156} 157 158 159void Decoder::DecodePCRelAddressing(const Instruction* instr) { 160 VIXL_ASSERT(instr->Bits(27, 24) == 0x0); 161 // We know bit 28 is set, as <b28:b27> = 0 is filtered out at the top level 162 // decode. 163 VIXL_ASSERT(instr->Bit(28) == 0x1); 164 VisitPCRelAddressing(instr); 165} 166 167 168void Decoder::DecodeBranchSystemException(const Instruction* instr) { 169 VIXL_ASSERT((instr->Bits(27, 24) == 0x4) || 170 (instr->Bits(27, 24) == 0x5) || 171 (instr->Bits(27, 24) == 0x6) || 172 (instr->Bits(27, 24) == 0x7) ); 173 174 switch (instr->Bits(31, 29)) { 175 case 0: 176 case 4: { 177 VisitUnconditionalBranch(instr); 178 break; 179 } 180 case 1: 181 case 5: { 182 if (instr->Bit(25) == 0) { 183 VisitCompareBranch(instr); 184 } else { 185 VisitTestBranch(instr); 186 } 187 break; 188 } 189 case 2: { 190 if (instr->Bit(25) == 0) { 191 if ((instr->Bit(24) == 0x1) || 192 (instr->Mask(0x01000010) == 0x00000010)) { 193 VisitUnallocated(instr); 194 } else { 195 VisitConditionalBranch(instr); 196 } 197 } else { 198 VisitUnallocated(instr); 199 } 200 break; 201 } 202 case 6: { 203 if (instr->Bit(25) == 0) { 204 if (instr->Bit(24) == 0) { 205 if ((instr->Bits(4, 2) != 0) || 206 (instr->Mask(0x00E0001D) == 0x00200001) || 207 (instr->Mask(0x00E0001D) == 0x00400001) || 208 (instr->Mask(0x00E0001E) == 0x00200002) || 209 (instr->Mask(0x00E0001E) == 0x00400002) || 210 (instr->Mask(0x00E0001C) == 0x00600000) || 211 (instr->Mask(0x00E0001C) == 0x00800000) || 212 (instr->Mask(0x00E0001F) == 0x00A00000) || 213 (instr->Mask(0x00C0001C) == 0x00C00000)) { 214 VisitUnallocated(instr); 215 } else { 216 VisitException(instr); 217 } 218 } else { 219 if (instr->Bits(23, 22) == 0) { 220 const Instr masked_003FF0E0 = instr->Mask(0x003FF0E0); 221 if ((instr->Bits(21, 19) == 0x4) || 222 (masked_003FF0E0 == 0x00033000) || 223 (masked_003FF0E0 == 0x003FF020) || 224 (masked_003FF0E0 == 0x003FF060) || 225 (masked_003FF0E0 == 0x003FF0E0) || 226 (instr->Mask(0x00388000) == 0x00008000) || 227 (instr->Mask(0x0038E000) == 0x00000000) || 228 (instr->Mask(0x0039E000) == 0x00002000) || 229 (instr->Mask(0x003AE000) == 0x00002000) || 230 (instr->Mask(0x003CE000) == 0x00042000) || 231 (instr->Mask(0x003FFFC0) == 0x000320C0) || 232 (instr->Mask(0x003FF100) == 0x00032100) || 233 (instr->Mask(0x003FF200) == 0x00032200) || 234 (instr->Mask(0x003FF400) == 0x00032400) || 235 (instr->Mask(0x003FF800) == 0x00032800) || 236 (instr->Mask(0x0038F000) == 0x00005000) || 237 (instr->Mask(0x0038E000) == 0x00006000)) { 238 VisitUnallocated(instr); 239 } else { 240 VisitSystem(instr); 241 } 242 } else { 243 VisitUnallocated(instr); 244 } 245 } 246 } else { 247 if ((instr->Bit(24) == 0x1) || 248 (instr->Bits(20, 16) != 0x1F) || 249 (instr->Bits(15, 10) != 0) || 250 (instr->Bits(4, 0) != 0) || 251 (instr->Bits(24, 21) == 0x3) || 252 (instr->Bits(24, 22) == 0x3)) { 253 VisitUnallocated(instr); 254 } else { 255 VisitUnconditionalBranchToRegister(instr); 256 } 257 } 258 break; 259 } 260 case 3: 261 case 7: { 262 VisitUnallocated(instr); 263 break; 264 } 265 } 266} 267 268 269void Decoder::DecodeLoadStore(const Instruction* instr) { 270 VIXL_ASSERT((instr->Bits(27, 24) == 0x8) || 271 (instr->Bits(27, 24) == 0x9) || 272 (instr->Bits(27, 24) == 0xC) || 273 (instr->Bits(27, 24) == 0xD) ); 274 // TODO(all): rearrange the tree to integrate this branch. 275 if ((instr->Bit(28) == 0) && (instr->Bit(29) == 0) && (instr->Bit(26) == 1)) { 276 DecodeNEONLoadStore(instr); 277 return; 278 } 279 280 if (instr->Bit(24) == 0) { 281 if (instr->Bit(28) == 0) { 282 if (instr->Bit(29) == 0) { 283 if (instr->Bit(26) == 0) { 284 VisitLoadStoreExclusive(instr); 285 } else { 286 VIXL_UNREACHABLE(); 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 392void Decoder::DecodeLogical(const 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 411void Decoder::DecodeBitfieldExtract(const 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 436void Decoder::DecodeAddSubImmediate(const 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 446void Decoder::DecodeDataProcessing(const 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 VIXL_FALLTHROUGH(); 492 } else { 493 if (instr->Bit(30) == 0) { 494 if ((instr->Bit(15) == 0x1) || 495 (instr->Bits(15, 11) == 0) || 496 (instr->Bits(15, 12) == 0x1) || 497 (instr->Bits(15, 12) == 0x3) || 498 (instr->Bits(15, 13) == 0x3) || 499 (instr->Mask(0x8000EC00) == 0x00004C00) || 500 (instr->Mask(0x8000E800) == 0x80004000) || 501 (instr->Mask(0x8000E400) == 0x80004000)) { 502 VisitUnallocated(instr); 503 } else { 504 VisitDataProcessing2Source(instr); 505 } 506 } else { 507 if ((instr->Bit(13) == 1) || 508 (instr->Bits(20, 16) != 0) || 509 (instr->Bits(15, 14) != 0) || 510 (instr->Mask(0xA01FFC00) == 0x00000C00) || 511 (instr->Mask(0x201FF800) == 0x00001800)) { 512 VisitUnallocated(instr); 513 } else { 514 VisitDataProcessing1Source(instr); 515 } 516 } 517 break; 518 } 519 } 520 case 1: 521 case 3: 522 case 5: 523 case 7: VisitUnallocated(instr); break; 524 } 525 } 526 } else { 527 if (instr->Bit(28) == 0) { 528 if (instr->Bit(21) == 0) { 529 if ((instr->Bits(23, 22) == 0x3) || 530 (instr->Mask(0x80008000) == 0x00008000)) { 531 VisitUnallocated(instr); 532 } else { 533 VisitAddSubShifted(instr); 534 } 535 } else { 536 if ((instr->Mask(0x00C00000) != 0x00000000) || 537 (instr->Mask(0x00001400) == 0x00001400) || 538 (instr->Mask(0x00001800) == 0x00001800)) { 539 VisitUnallocated(instr); 540 } else { 541 VisitAddSubExtended(instr); 542 } 543 } 544 } else { 545 if ((instr->Bit(30) == 0x1) || 546 (instr->Bits(30, 29) == 0x1) || 547 (instr->Mask(0xE0600000) == 0x00200000) || 548 (instr->Mask(0xE0608000) == 0x00400000) || 549 (instr->Mask(0x60608000) == 0x00408000) || 550 (instr->Mask(0x60E00000) == 0x00E00000) || 551 (instr->Mask(0x60E00000) == 0x00800000) || 552 (instr->Mask(0x60E00000) == 0x00600000)) { 553 VisitUnallocated(instr); 554 } else { 555 VisitDataProcessing3Source(instr); 556 } 557 } 558 } 559} 560 561 562void Decoder::DecodeFP(const Instruction* instr) { 563 VIXL_ASSERT((instr->Bits(27, 24) == 0xE) || 564 (instr->Bits(27, 24) == 0xF)); 565 if (instr->Bit(28) == 0) { 566 DecodeNEONVectorDataProcessing(instr); 567 } else { 568 if (instr->Bits(31, 30) == 0x3) { 569 VisitUnallocated(instr); 570 } else if (instr->Bits(31, 30) == 0x1) { 571 DecodeNEONScalarDataProcessing(instr); 572 } else { 573 if (instr->Bit(29) == 0) { 574 if (instr->Bit(24) == 0) { 575 if (instr->Bit(21) == 0) { 576 if ((instr->Bit(23) == 1) || 577 (instr->Bit(18) == 1) || 578 (instr->Mask(0x80008000) == 0x00000000) || 579 (instr->Mask(0x000E0000) == 0x00000000) || 580 (instr->Mask(0x000E0000) == 0x000A0000) || 581 (instr->Mask(0x00160000) == 0x00000000) || 582 (instr->Mask(0x00160000) == 0x00120000)) { 583 VisitUnallocated(instr); 584 } else { 585 VisitFPFixedPointConvert(instr); 586 } 587 } else { 588 if (instr->Bits(15, 10) == 32) { 589 VisitUnallocated(instr); 590 } else if (instr->Bits(15, 10) == 0) { 591 if ((instr->Bits(23, 22) == 0x3) || 592 (instr->Mask(0x000E0000) == 0x000A0000) || 593 (instr->Mask(0x000E0000) == 0x000C0000) || 594 (instr->Mask(0x00160000) == 0x00120000) || 595 (instr->Mask(0x00160000) == 0x00140000) || 596 (instr->Mask(0x20C40000) == 0x00800000) || 597 (instr->Mask(0x20C60000) == 0x00840000) || 598 (instr->Mask(0xA0C60000) == 0x80060000) || 599 (instr->Mask(0xA0C60000) == 0x00860000) || 600 (instr->Mask(0xA0C60000) == 0x00460000) || 601 (instr->Mask(0xA0CE0000) == 0x80860000) || 602 (instr->Mask(0xA0CE0000) == 0x804E0000) || 603 (instr->Mask(0xA0CE0000) == 0x000E0000) || 604 (instr->Mask(0xA0D60000) == 0x00160000) || 605 (instr->Mask(0xA0D60000) == 0x80560000) || 606 (instr->Mask(0xA0D60000) == 0x80960000)) { 607 VisitUnallocated(instr); 608 } else { 609 VisitFPIntegerConvert(instr); 610 } 611 } else if (instr->Bits(14, 10) == 16) { 612 const Instr masked_A0DF8000 = instr->Mask(0xA0DF8000); 613 if ((instr->Mask(0x80180000) != 0) || 614 (masked_A0DF8000 == 0x00020000) || 615 (masked_A0DF8000 == 0x00030000) || 616 (masked_A0DF8000 == 0x00068000) || 617 (masked_A0DF8000 == 0x00428000) || 618 (masked_A0DF8000 == 0x00430000) || 619 (masked_A0DF8000 == 0x00468000) || 620 (instr->Mask(0xA0D80000) == 0x00800000) || 621 (instr->Mask(0xA0DE0000) == 0x00C00000) || 622 (instr->Mask(0xA0DF0000) == 0x00C30000) || 623 (instr->Mask(0xA0DC0000) == 0x00C40000)) { 624 VisitUnallocated(instr); 625 } else { 626 VisitFPDataProcessing1Source(instr); 627 } 628 } else if (instr->Bits(13, 10) == 8) { 629 if ((instr->Bits(15, 14) != 0) || 630 (instr->Bits(2, 0) != 0) || 631 (instr->Mask(0x80800000) != 0x00000000)) { 632 VisitUnallocated(instr); 633 } else { 634 VisitFPCompare(instr); 635 } 636 } else if (instr->Bits(12, 10) == 4) { 637 if ((instr->Bits(9, 5) != 0) || 638 (instr->Mask(0x80800000) != 0x00000000)) { 639 VisitUnallocated(instr); 640 } else { 641 VisitFPImmediate(instr); 642 } 643 } else { 644 if (instr->Mask(0x80800000) != 0x00000000) { 645 VisitUnallocated(instr); 646 } else { 647 switch (instr->Bits(11, 10)) { 648 case 1: { 649 VisitFPConditionalCompare(instr); 650 break; 651 } 652 case 2: { 653 if ((instr->Bits(15, 14) == 0x3) || 654 (instr->Mask(0x00009000) == 0x00009000) || 655 (instr->Mask(0x0000A000) == 0x0000A000)) { 656 VisitUnallocated(instr); 657 } else { 658 VisitFPDataProcessing2Source(instr); 659 } 660 break; 661 } 662 case 3: { 663 VisitFPConditionalSelect(instr); 664 break; 665 } 666 default: VIXL_UNREACHABLE(); 667 } 668 } 669 } 670 } 671 } else { 672 // Bit 30 == 1 has been handled earlier. 673 VIXL_ASSERT(instr->Bit(30) == 0); 674 if (instr->Mask(0xA0800000) != 0) { 675 VisitUnallocated(instr); 676 } else { 677 VisitFPDataProcessing3Source(instr); 678 } 679 } 680 } else { 681 VisitUnallocated(instr); 682 } 683 } 684 } 685} 686 687 688void Decoder::DecodeNEONLoadStore(const Instruction* instr) { 689 VIXL_ASSERT(instr->Bits(29, 25) == 0x6); 690 if (instr->Bit(31) == 0) { 691 if ((instr->Bit(24) == 0) && (instr->Bit(21) == 1)) { 692 VisitUnallocated(instr); 693 return; 694 } 695 696 if (instr->Bit(23) == 0) { 697 if (instr->Bits(20, 16) == 0) { 698 if (instr->Bit(24) == 0) { 699 VisitNEONLoadStoreMultiStruct(instr); 700 } else { 701 VisitNEONLoadStoreSingleStruct(instr); 702 } 703 } else { 704 VisitUnallocated(instr); 705 } 706 } else { 707 if (instr->Bit(24) == 0) { 708 VisitNEONLoadStoreMultiStructPostIndex(instr); 709 } else { 710 VisitNEONLoadStoreSingleStructPostIndex(instr); 711 } 712 } 713 } else { 714 VisitUnallocated(instr); 715 } 716} 717 718 719void Decoder::DecodeNEONVectorDataProcessing(const Instruction* instr) { 720 VIXL_ASSERT(instr->Bits(28, 25) == 0x7); 721 if (instr->Bit(31) == 0) { 722 if (instr->Bit(24) == 0) { 723 if (instr->Bit(21) == 0) { 724 if (instr->Bit(15) == 0) { 725 if (instr->Bit(10) == 0) { 726 if (instr->Bit(29) == 0) { 727 if (instr->Bit(11) == 0) { 728 VisitNEONTable(instr); 729 } else { 730 VisitNEONPerm(instr); 731 } 732 } else { 733 VisitNEONExtract(instr); 734 } 735 } else { 736 if (instr->Bits(23, 22) == 0) { 737 VisitNEONCopy(instr); 738 } else { 739 VisitUnallocated(instr); 740 } 741 } 742 } else { 743 VisitUnallocated(instr); 744 } 745 } else { 746 if (instr->Bit(10) == 0) { 747 if (instr->Bit(11) == 0) { 748 VisitNEON3Different(instr); 749 } else { 750 if (instr->Bits(18, 17) == 0) { 751 if (instr->Bit(20) == 0) { 752 if (instr->Bit(19) == 0) { 753 VisitNEON2RegMisc(instr); 754 } else { 755 if (instr->Bits(30, 29) == 0x2) { 756 VisitCryptoAES(instr); 757 } else { 758 VisitUnallocated(instr); 759 } 760 } 761 } else { 762 if (instr->Bit(19) == 0) { 763 VisitNEONAcrossLanes(instr); 764 } else { 765 VisitUnallocated(instr); 766 } 767 } 768 } else { 769 VisitUnallocated(instr); 770 } 771 } 772 } else { 773 VisitNEON3Same(instr); 774 } 775 } 776 } else { 777 if (instr->Bit(10) == 0) { 778 VisitNEONByIndexedElement(instr); 779 } else { 780 if (instr->Bit(23) == 0) { 781 if (instr->Bits(22, 19) == 0) { 782 VisitNEONModifiedImmediate(instr); 783 } else { 784 VisitNEONShiftImmediate(instr); 785 } 786 } else { 787 VisitUnallocated(instr); 788 } 789 } 790 } 791 } else { 792 VisitUnallocated(instr); 793 } 794} 795 796 797void Decoder::DecodeNEONScalarDataProcessing(const Instruction* instr) { 798 VIXL_ASSERT(instr->Bits(28, 25) == 0xF); 799 if (instr->Bit(24) == 0) { 800 if (instr->Bit(21) == 0) { 801 if (instr->Bit(15) == 0) { 802 if (instr->Bit(10) == 0) { 803 if (instr->Bit(29) == 0) { 804 if (instr->Bit(11) == 0) { 805 VisitCrypto3RegSHA(instr); 806 } else { 807 VisitUnallocated(instr); 808 } 809 } else { 810 VisitUnallocated(instr); 811 } 812 } else { 813 if (instr->Bits(23, 22) == 0) { 814 VisitNEONScalarCopy(instr); 815 } else { 816 VisitUnallocated(instr); 817 } 818 } 819 } else { 820 VisitUnallocated(instr); 821 } 822 } else { 823 if (instr->Bit(10) == 0) { 824 if (instr->Bit(11) == 0) { 825 VisitNEONScalar3Diff(instr); 826 } else { 827 if (instr->Bits(18, 17) == 0) { 828 if (instr->Bit(20) == 0) { 829 if (instr->Bit(19) == 0) { 830 VisitNEONScalar2RegMisc(instr); 831 } else { 832 if (instr->Bit(29) == 0) { 833 VisitCrypto2RegSHA(instr); 834 } else { 835 VisitUnallocated(instr); 836 } 837 } 838 } else { 839 if (instr->Bit(19) == 0) { 840 VisitNEONScalarPairwise(instr); 841 } else { 842 VisitUnallocated(instr); 843 } 844 } 845 } else { 846 VisitUnallocated(instr); 847 } 848 } 849 } else { 850 VisitNEONScalar3Same(instr); 851 } 852 } 853 } else { 854 if (instr->Bit(10) == 0) { 855 VisitNEONScalarByIndexedElement(instr); 856 } else { 857 if (instr->Bit(23) == 0) { 858 VisitNEONScalarShiftImmediate(instr); 859 } else { 860 VisitUnallocated(instr); 861 } 862 } 863 } 864} 865 866 867#define DEFINE_VISITOR_CALLERS(A) \ 868 void Decoder::Visit##A(const Instruction *instr) { \ 869 VIXL_ASSERT(instr->Mask(A##FMask) == A##Fixed); \ 870 std::list<DecoderVisitor*>::iterator it; \ 871 for (it = visitors_.begin(); it != visitors_.end(); it++) { \ 872 (*it)->Visit##A(instr); \ 873 } \ 874 } 875VISITOR_LIST(DEFINE_VISITOR_CALLERS) 876#undef DEFINE_VISITOR_CALLERS 877} // namespace vixl