1// Copyright (c) 2012-2013 ARM Limited 2// All rights reserved 3// 4// The license below extends only to copyright in the software and shall 5// not be construed as granting a license to any other intellectual 6// property including but not limited to intellectual property relating 7// to a hardware implementation of the functionality of the software 8// licensed hereunder. You may use the software subject to the license 9// terms below provided that you ensure that this notice is replicated 10// unmodified and in its entirety in all distributions of the software, 11// modified or unmodified, in source code or in binary form. 12// 13// Redistribution and use in source and binary forms, with or without 14// modification, are permitted provided that the following conditions are 15// met: redistributions of source code must retain the above copyright 16// notice, this list of conditions and the following disclaimer; 17// redistributions in binary form must reproduce the above copyright 18// notice, this list of conditions and the following disclaimer in the 19// documentation and/or other materials provided with the distribution; 20// neither the name of the copyright holders nor the names of its 21// contributors may be used to endorse or promote products derived from 22// this software without specific prior written permission. 23// 24// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 27// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 28// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 29// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 30// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 31// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 32// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 34// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35// 36// Authors: Giacomo Gabrielli 37// Mbou Eyole 38 39output header {{ 40namespace Aarch64 41{ 42 // AdvSIMD three same 43 template <typename DecoderFeatures> 44 StaticInstPtr decodeNeon3Same(ExtMachInst machInst); 45 // AdvSIMD three different 46 inline StaticInstPtr decodeNeon3Diff(ExtMachInst machInst); 47 // AdvSIMD two-reg misc 48 inline StaticInstPtr decodeNeon2RegMisc(ExtMachInst machInst); 49 // AdvSIMD across lanes 50 inline StaticInstPtr decodeNeonAcrossLanes(ExtMachInst machInst); 51 // AdvSIMD copy 52 inline StaticInstPtr decodeNeonCopy(ExtMachInst machInst); 53 // AdvSIMD vector x indexed element 54 template <typename DecoderFeatures> 55 StaticInstPtr decodeNeonIndexedElem(ExtMachInst machInst); 56 // AdvSIMD modified immediate 57 inline StaticInstPtr decodeNeonModImm(ExtMachInst machInst); 58 // AdvSIMD shift by immediate 59 inline StaticInstPtr decodeNeonShiftByImm(ExtMachInst machInst); 60 // AdvSIMD TBL/TBX 61 inline StaticInstPtr decodeNeonTblTbx(ExtMachInst machInst); 62 // AdvSIMD ZIP/UZP/TRN 63 inline StaticInstPtr decodeNeonZipUzpTrn(ExtMachInst machInst); 64 // AdvSIMD EXT 65 inline StaticInstPtr decodeNeonExt(ExtMachInst machInst); 66 67 // AdvSIMD scalar three same 68 inline StaticInstPtr decodeNeonSc3Same(ExtMachInst machInst); 69 // AdvSIMD scalar three different 70 inline StaticInstPtr decodeNeonSc3Diff(ExtMachInst machInst); 71 // AdvSIMD scalar two-reg misc 72 inline StaticInstPtr decodeNeonSc2RegMisc(ExtMachInst machInst); 73 // AdvSIMD scalar pairwise 74 inline StaticInstPtr decodeNeonScPwise(ExtMachInst machInst); 75 // AdvSIMD scalar copy 76 inline StaticInstPtr decodeNeonScCopy(ExtMachInst machInst); 77 // AdvSIMD scalar x indexed element 78 inline StaticInstPtr decodeNeonScIndexedElem(ExtMachInst machInst); 79 // AdvSIMD scalar shift by immediate 80 inline StaticInstPtr decodeNeonScShiftByImm(ExtMachInst machInst); 81 82 // AdvSIMD load/store 83 inline StaticInstPtr decodeNeonMem(ExtMachInst machInst); 84} 85}}; 86 87output decoder {{ 88namespace Aarch64 89{ 90 template <typename DecoderFeatures> 91 StaticInstPtr 92 decodeNeon3Same(ExtMachInst machInst) 93 { 94 uint8_t q = bits(machInst, 30); 95 uint8_t u = bits(machInst, 29); 96 uint8_t size = bits(machInst, 23, 22); 97 uint8_t opcode = bits(machInst, 15, 11); 98 99 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0); 100 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5); 101 IntRegIndex vm = (IntRegIndex) (uint8_t) bits(machInst, 20, 16); 102 103 uint8_t size_q = (size << 1) | q; 104 uint8_t sz_q = size_q & 0x3; 105 106 switch (opcode) { 107 case 0x00: 108 if (size == 0x3) 109 return new Unknown64(machInst); 110 if (u) 111 return decodeNeonUThreeSReg<UhaddDX, UhaddQX>( 112 q, size, machInst, vd, vn, vm); 113 else 114 return decodeNeonSThreeSReg<ShaddDX, ShaddQX>( 115 q, size, machInst, vd, vn, vm); 116 case 0x01: 117 if (size_q == 0x6) 118 return new Unknown64(machInst); 119 if (u) 120 return decodeNeonUThreeXReg<UqaddDX, UqaddQX>( 121 q, size, machInst, vd, vn, vm); 122 else 123 return decodeNeonSThreeXReg<SqaddDX, SqaddQX>( 124 q, size, machInst, vd, vn, vm); 125 case 0x02: 126 if (size == 0x3) 127 return new Unknown64(machInst); 128 if (u) 129 return decodeNeonUThreeSReg<UrhaddDX, UrhaddQX>( 130 q, size, machInst, vd, vn, vm); 131 else 132 return decodeNeonSThreeSReg<SrhaddDX, SrhaddQX>( 133 q, size, machInst, vd, vn, vm); 134 case 0x03: 135 switch (size) { 136 case 0x0: 137 if (u) { 138 if (q) 139 return new EorQX<uint64_t>(machInst, vd, vn, vm); 140 else 141 return new EorDX<uint64_t>(machInst, vd, vn, vm); 142 } else { 143 if (q) 144 return new AndQX<uint64_t>(machInst, vd, vn, vm); 145 else 146 return new AndDX<uint64_t>(machInst, vd, vn, vm); 147 } 148 case 0x1: 149 if (u) { 150 if (q) 151 return new BslQX<uint64_t>(machInst, vd, vn, vm); 152 else 153 return new BslDX<uint64_t>(machInst, vd, vn, vm); 154 } else { 155 if (q) 156 return new BicQX<uint64_t>(machInst, vd, vn, vm); 157 else 158 return new BicDX<uint64_t>(machInst, vd, vn, vm); 159 } 160 case 0x2: 161 if (u) { 162 if (q) 163 return new BitQX<uint64_t>(machInst, vd, vn, vm); 164 else 165 return new BitDX<uint64_t>(machInst, vd, vn, vm); 166 } else { 167 if (q) 168 return new OrrQX<uint64_t>(machInst, vd, vn, vm); 169 else 170 return new OrrDX<uint64_t>(machInst, vd, vn, vm); 171 } 172 case 0x3: 173 if (u) { 174 if (q) 175 return new BifQX<uint64_t>(machInst, vd, vn, vm); 176 else 177 return new BifDX<uint64_t>(machInst, vd, vn, vm); 178 } else { 179 if (q) 180 return new OrnQX<uint64_t>(machInst, vd, vn, vm); 181 else 182 return new OrnDX<uint64_t>(machInst, vd, vn, vm); 183 } 184 default: 185 M5_UNREACHABLE; 186 } 187 case 0x04: 188 if (size == 0x3) 189 return new Unknown64(machInst); 190 if (u) 191 return decodeNeonUThreeSReg<UhsubDX, UhsubQX>( 192 q, size, machInst, vd, vn, vm); 193 else 194 return decodeNeonSThreeSReg<ShsubDX, ShsubQX>( 195 q, size, machInst, vd, vn, vm); 196 case 0x05: 197 if (size_q == 0x6) 198 return new Unknown64(machInst); 199 if (u) 200 return decodeNeonUThreeXReg<UqsubDX, UqsubQX>( 201 q, size, machInst, vd, vn, vm); 202 else 203 return decodeNeonSThreeXReg<SqsubDX, SqsubQX>( 204 q, size, machInst, vd, vn, vm); 205 case 0x06: 206 if (size_q == 0x6) 207 return new Unknown64(machInst); 208 if (u) 209 return decodeNeonUThreeXReg<CmhiDX, CmhiQX>( 210 q, size, machInst, vd, vn, vm); 211 else 212 return decodeNeonSThreeXReg<CmgtDX, CmgtQX>( 213 q, size, machInst, vd, vn, vm); 214 case 0x07: 215 if (size_q == 0x6) 216 return new Unknown64(machInst); 217 if (u) 218 return decodeNeonUThreeXReg<CmhsDX, CmhsQX>( 219 q, size, machInst, vd, vn, vm); 220 else 221 return decodeNeonSThreeXReg<CmgeDX, CmgeQX>( 222 q, size, machInst, vd, vn, vm); 223 case 0x08: 224 if (size_q == 0x6) 225 return new Unknown64(machInst); 226 if (u) 227 return decodeNeonUThreeXReg<UshlDX, UshlQX>( 228 q, size, machInst, vd, vn, vm); 229 else 230 return decodeNeonSThreeXReg<SshlDX, SshlQX>( 231 q, size, machInst, vd, vn, vm); 232 case 0x09: 233 if (size_q == 0x6) 234 return new Unknown64(machInst); 235 if (u) 236 return decodeNeonUThreeXReg<UqshlDX, UqshlQX>( 237 q, size, machInst, vd, vn, vm); 238 else 239 return decodeNeonSThreeXReg<SqshlDX, SqshlQX>( 240 q, size, machInst, vd, vn, vm); 241 case 0x0a: 242 if (size_q == 0x6) 243 return new Unknown64(machInst); 244 if (u) 245 return decodeNeonUThreeXReg<UrshlDX, UrshlQX>( 246 q, size, machInst, vd, vn, vm); 247 else 248 return decodeNeonSThreeXReg<SrshlDX, SrshlQX>( 249 q, size, machInst, vd, vn, vm); 250 case 0x0b: 251 if (size_q == 0x6) 252 return new Unknown64(machInst); 253 if (u) 254 return decodeNeonUThreeXReg<UqrshlDX, UqrshlQX>( 255 q, size, machInst, vd, vn, vm); 256 else 257 return decodeNeonSThreeXReg<SqrshlDX, SqrshlQX>( 258 q, size, machInst, vd, vn, vm); 259 case 0x0c: 260 if (size == 0x3) 261 return new Unknown64(machInst); 262 if (u) 263 return decodeNeonUThreeSReg<UmaxDX, UmaxQX>( 264 q, size, machInst, vd, vn, vm); 265 else 266 return decodeNeonSThreeSReg<SmaxDX, SmaxQX>( 267 q, size, machInst, vd, vn, vm); 268 case 0x0d: 269 if (size == 0x3) 270 return new Unknown64(machInst); 271 if (u) 272 return decodeNeonUThreeSReg<UminDX, UminQX>( 273 q, size, machInst, vd, vn, vm); 274 else 275 return decodeNeonSThreeSReg<SminDX, SminQX>( 276 q, size, machInst, vd, vn, vm); 277 case 0x0e: 278 if (size == 0x3) 279 return new Unknown64(machInst); 280 if (u) 281 return decodeNeonUThreeSReg<UabdDX, UabdQX>( 282 q, size, machInst, vd, vn, vm); 283 else 284 return decodeNeonSThreeSReg<SabdDX, SabdQX>( 285 q, size, machInst, vd, vn, vm); 286 case 0x0f: 287 if (size == 0x3) 288 return new Unknown64(machInst); 289 if (u) 290 return decodeNeonUThreeSReg<UabaDX, UabaQX>( 291 q, size, machInst, vd, vn, vm); 292 else 293 return decodeNeonSThreeSReg<SabaDX, SabaQX>( 294 q, size, machInst, vd, vn, vm); 295 case 0x10: 296 if (size_q == 0x6) 297 return new Unknown64(machInst); 298 if (u) 299 return decodeNeonUThreeXReg<SubDX, SubQX>( 300 q, size, machInst, vd, vn, vm); 301 else 302 return decodeNeonUThreeXReg<AddDX, AddQX>( 303 q, size, machInst, vd, vn, vm); 304 case 0x11: 305 if (size_q == 0x6) 306 return new Unknown64(machInst); 307 if (u) 308 return decodeNeonUThreeXReg<CmeqDX, CmeqQX>( 309 q, size, machInst, vd, vn, vm); 310 else 311 return decodeNeonUThreeXReg<CmtstDX, CmtstQX>( 312 q, size, machInst, vd, vn, vm); 313 case 0x12: 314 if (size == 0x3) 315 return new Unknown64(machInst); 316 if (u) 317 return decodeNeonUThreeSReg<MlsDX, MlsQX>( 318 q, size, machInst, vd, vn, vm); 319 else 320 return decodeNeonUThreeSReg<MlaDX, MlaQX>( 321 q, size, machInst, vd, vn, vm); 322 case 0x13: 323 if (size == 0x3 || (size != 0x0 && bits(machInst, 29))) 324 return new Unknown64(machInst); 325 if (u) { 326 if (q) 327 return new PmulQX<uint8_t>(machInst, vd, vn, vm); 328 else 329 return new PmulDX<uint8_t>(machInst, vd, vn, vm); 330 } else { 331 return decodeNeonUThreeSReg<MulDX, MulQX>( 332 q, size, machInst, vd, vn, vm); 333 } 334 case 0x14: 335 if (size == 0x3) 336 return new Unknown64(machInst); 337 if (u) 338 return decodeNeonUThreeSReg<UmaxpDX, UmaxpQX>( 339 q, size, machInst, vd, vn, vm); 340 else 341 return decodeNeonSThreeSReg<SmaxpDX, SmaxpQX>( 342 q, size, machInst, vd, vn, vm); 343 case 0x15: 344 if (size == 0x3) 345 return new Unknown64(machInst); 346 if (u) 347 return decodeNeonUThreeSReg<UminpDX, UminpQX>( 348 q, size, machInst, vd, vn, vm); 349 else 350 return decodeNeonSThreeSReg<SminpDX, SminpQX>( 351 q, size, machInst, vd, vn, vm); 352 case 0x16: 353 if (size == 0x3 || size == 0x0) 354 return new Unknown64(machInst); 355 if (u) { 356 if (q) 357 return decodeNeonSThreeHAndWReg<SqrdmulhQX>( 358 size, machInst, vd, vn, vm); 359 else 360 return decodeNeonSThreeHAndWReg<SqrdmulhDX>( 361 size, machInst, vd, vn, vm); 362 } else { 363 if (q) 364 return decodeNeonSThreeHAndWReg<SqdmulhQX>( 365 size, machInst, vd, vn, vm); 366 else 367 return decodeNeonSThreeHAndWReg<SqdmulhDX>( 368 size, machInst, vd, vn, vm); 369 } 370 case 0x17: 371 if (u || size_q == 0x6) 372 return new Unknown64(machInst); 373 else 374 return decodeNeonUThreeXReg<AddpDX, AddpQX>( 375 q, size, machInst, vd, vn, vm); 376 case 0x18: 377 if (sz_q == 0x2) 378 return new Unknown64(machInst); 379 if (size < 0x2) { 380 if (u) 381 return decodeNeonUThreeFpReg<FmaxnmpDX, FmaxnmpQX>( 382 q, size & 0x1, machInst, vd, vn, vm); 383 else 384 return decodeNeonUThreeFpReg<FmaxnmDX, FmaxnmQX>( 385 q, size & 0x1, machInst, vd, vn, vm); 386 } else { 387 if (u) 388 return decodeNeonUThreeFpReg<FminnmpDX, FminnmpQX>( 389 q, size & 0x1, machInst, vd, vn, vm); 390 else 391 return decodeNeonUThreeFpReg<FminnmDX, FminnmQX>( 392 q, size & 0x1, machInst, vd, vn, vm); 393 } 394 case 0x19: 395 if (size < 0x2) { 396 if (u || sz_q == 0x2) 397 return new Unknown64(machInst); 398 else 399 return decodeNeonUThreeFpReg<FmlaDX, FmlaQX>( 400 q, size & 0x1, machInst, vd, vn, vm); 401 } else { 402 if (u || sz_q == 0x2) 403 return new Unknown64(machInst); 404 else 405 return decodeNeonUThreeFpReg<FmlsDX, FmlsQX>( 406 q, size & 0x1, machInst, vd, vn, vm); 407 } 408 case 0x1a: 409 if (sz_q == 0x2) 410 return new Unknown64(machInst); 411 if (size < 0x2) { 412 if (u) 413 return decodeNeonUThreeFpReg<FaddpDX, FaddpQX>( 414 q, size & 0x1, machInst, vd, vn, vm); 415 else 416 return decodeNeonUThreeFpReg<FaddDX, FaddQX>( 417 q, size & 0x1, machInst, vd, vn, vm); 418 } else { 419 if (u) 420 return decodeNeonUThreeFpReg<FabdDX, FabdQX>( 421 q, size & 0x1, machInst, vd, vn, vm); 422 else 423 return decodeNeonUThreeFpReg<FsubDX, FsubQX>( 424 q, size & 0x1, machInst, vd, vn, vm); 425 } 426 case 0x1b: 427 if (size < 0x2 && sz_q != 0x2) { 428 if (u) 429 return decodeNeonUThreeFpReg<FmulDX, FmulQX>( 430 q, size & 0x1, machInst, vd, vn, vm); 431 else 432 return decodeNeonUThreeFpReg<FmulxDX, FmulxQX>( 433 q, size & 0x1, machInst, vd, vn, vm); 434 } else { 435 return new Unknown64(machInst); 436 } 437 case 0x1c: 438 if (size < 0x2) { 439 if (u) 440 return decodeNeonUThreeFpReg<FcmgeDX, FcmgeQX>( 441 q, size & 0x1, machInst, vd, vn, vm); 442 else 443 return decodeNeonUThreeFpReg<FcmeqDX, FcmeqQX>( 444 q, size & 0x1, machInst, vd, vn, vm); 445 } else { 446 if (u) 447 return decodeNeonUThreeFpReg<FcmgtDX, FcmgtQX>( 448 q, size & 0x1, machInst, vd, vn, vm); 449 else 450 return new Unknown64(machInst); 451 } 452 case 0x1d: 453 if (size < 0x2) { 454 if (u) 455 return decodeNeonUThreeFpReg<FacgeDX, FacgeQX>( 456 q, size & 0x1, machInst, vd, vn, vm); 457 else 458 return new Unknown64(machInst); 459 } else { 460 if (u) 461 return decodeNeonUThreeFpReg<FacgtDX, FacgtQX>( 462 q, size & 0x1, machInst, vd, vn, vm); 463 else 464 return new Unknown64(machInst); 465 } 466 case 0x1e: 467 if (sz_q == 0x2) 468 return new Unknown64(machInst); 469 if (size < 0x2) { 470 if (u) 471 return decodeNeonUThreeFpReg<FmaxpDX, FmaxpQX>( 472 q, size & 0x1, machInst, vd, vn, vm); 473 else 474 return decodeNeonUThreeFpReg<FmaxDX, FmaxQX>( 475 q, size & 0x1, machInst, vd, vn, vm); 476 } else { 477 if (u) 478 return decodeNeonUThreeFpReg<FminpDX, FminpQX>( 479 q, size & 0x1, machInst, vd, vn, vm); 480 else 481 return decodeNeonUThreeFpReg<FminDX, FminQX>( 482 q, size & 0x1, machInst, vd, vn, vm); 483 } 484 case 0x1f: 485 if (sz_q == 0x2) 486 return new Unknown64(machInst); 487 if (size < 0x2) { 488 if (u) 489 return decodeNeonUThreeFpReg<FdivDX, FdivQX>( 490 q, size & 0x1, machInst, vd, vn, vm); 491 else 492 return decodeNeonUThreeFpReg<FrecpsDX, FrecpsQX>( 493 q, size & 0x1, machInst, vd, vn, vm); 494 } else { 495 if (u) 496 return new Unknown64(machInst); 497 else 498 return decodeNeonUThreeFpReg<FrsqrtsDX, FrsqrtsQX>( 499 q, size & 0x1, machInst, vd, vn, vm); 500 } 501 default: 502 return new Unknown64(machInst); 503 } 504 } 505 506 StaticInstPtr 507 decodeNeon3Diff(ExtMachInst machInst) 508 { 509 uint8_t q = bits(machInst, 30); 510 uint8_t u = bits(machInst, 29); 511 uint8_t size = bits(machInst, 23, 22); 512 uint8_t opcode = bits(machInst, 15, 12); 513 514 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0); 515 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5); 516 IntRegIndex vm = (IntRegIndex) (uint8_t) bits(machInst, 20, 16); 517 518 switch (opcode) { 519 case 0x0: 520 if (size == 0x3) 521 return new Unknown64(machInst); 522 if (u) 523 return decodeNeonUThreeSReg<UaddlX, Uaddl2X>( 524 q, size, machInst, vd, vn, vm); 525 else 526 return decodeNeonSThreeSReg<SaddlX, Saddl2X>( 527 q, size, machInst, vd, vn, vm); 528 case 0x1: 529 if (size == 0x3) 530 return new Unknown64(machInst); 531 if (u) 532 return decodeNeonUThreeSReg<UaddwX, Uaddw2X>( 533 q, size, machInst, vd, vn, vm); 534 else 535 return decodeNeonSThreeSReg<SaddwX, Saddw2X>( 536 q, size, machInst, vd, vn, vm); 537 case 0x2: 538 if (size == 0x3) 539 return new Unknown64(machInst); 540 if (u) 541 return decodeNeonUThreeSReg<UsublX, Usubl2X>( 542 q, size, machInst, vd, vn, vm); 543 else 544 return decodeNeonSThreeSReg<SsublX, Ssubl2X>( 545 q, size, machInst, vd, vn, vm); 546 case 0x3: 547 if (size == 0x3) 548 return new Unknown64(machInst); 549 if (u) 550 return decodeNeonUThreeSReg<UsubwX, Usubw2X>( 551 q, size, machInst, vd, vn, vm); 552 else 553 return decodeNeonSThreeSReg<SsubwX, Ssubw2X>( 554 q, size, machInst, vd, vn, vm); 555 case 0x4: 556 if (size == 0x3) 557 return new Unknown64(machInst); 558 if (u) 559 return decodeNeonUThreeSReg<RaddhnX, Raddhn2X>( 560 q, size, machInst, vd, vn, vm); 561 else 562 return decodeNeonUThreeSReg<AddhnX, Addhn2X>( 563 q, size, machInst, vd, vn, vm); 564 case 0x5: 565 if (size == 0x3) 566 return new Unknown64(machInst); 567 if (u) 568 return decodeNeonUThreeSReg<UabalX, Uabal2X>( 569 q, size, machInst, vd, vn, vm); 570 else 571 return decodeNeonSThreeSReg<SabalX, Sabal2X>( 572 q, size, machInst, vd, vn, vm); 573 case 0x6: 574 if (size == 0x3) 575 return new Unknown64(machInst); 576 if (u) 577 return decodeNeonUThreeSReg<RsubhnX, Rsubhn2X>( 578 q, size, machInst, vd, vn, vm); 579 else 580 return decodeNeonUThreeSReg<SubhnX, Subhn2X>( 581 q, size, machInst, vd, vn, vm); 582 case 0x7: 583 if (size == 0x3) 584 return new Unknown64(machInst); 585 if (u) 586 return decodeNeonUThreeSReg<UabdlX, Uabdl2X>( 587 q, size, machInst, vd, vn, vm); 588 else 589 return decodeNeonSThreeSReg<SabdlX, Sabdl2X>( 590 q, size, machInst, vd, vn, vm); 591 case 0x8: 592 if (size == 0x3) 593 return new Unknown64(machInst); 594 if (u) 595 return decodeNeonUThreeSReg<UmlalX, Umlal2X>( 596 q, size, machInst, vd, vn, vm); 597 else 598 return decodeNeonSThreeSReg<SmlalX, Smlal2X>( 599 q, size, machInst, vd, vn, vm); 600 case 0x9: 601 if (u || (size == 0x0 || size == 0x3)) { 602 return new Unknown64(machInst); 603 } else { 604 if (q) { 605 return decodeNeonSThreeHAndWReg<Sqdmlal2X>( 606 size, machInst, vd, vn, vm); 607 } else { 608 return decodeNeonSThreeHAndWReg<SqdmlalX>( 609 size, machInst, vd, vn, vm); 610 } 611 } 612 case 0xa: 613 if (size == 0x3) 614 return new Unknown64(machInst); 615 if (u) 616 return decodeNeonUThreeSReg<UmlslX, Umlsl2X>( 617 q, size, machInst, vd, vn, vm); 618 else 619 return decodeNeonSThreeSReg<SmlslX, Smlsl2X>( 620 q, size, machInst, vd, vn, vm); 621 case 0xb: 622 if (u || (size == 0x0 || size == 0x3)) { 623 return new Unknown64(machInst); 624 } else { 625 if (q) { 626 return decodeNeonSThreeHAndWReg<Sqdmlsl2X>( 627 size, machInst, vd, vn, vm); 628 } else { 629 return decodeNeonSThreeHAndWReg<SqdmlslX>( 630 size, machInst, vd, vn, vm); 631 } 632 } 633 case 0xc: 634 if (size == 0x3) 635 return new Unknown64(machInst); 636 if (u) 637 return decodeNeonUThreeSReg<UmullX, Umull2X>( 638 q, size, machInst, vd, vn, vm); 639 else 640 return decodeNeonSThreeSReg<SmullX, Smull2X>( 641 q, size, machInst, vd, vn, vm); 642 case 0xd: 643 if (u || (size == 0x0 || size == 0x3)) { 644 return new Unknown64(machInst); 645 } else { 646 if (q) { 647 return decodeNeonSThreeHAndWReg<Sqdmull2X>( 648 size, machInst, vd, vn, vm); 649 } else { 650 return decodeNeonSThreeHAndWReg<SqdmullX>( 651 size, machInst, vd, vn, vm); 652 } 653 } 654 case 0xe: 655 if (u || size != 0) { 656 return new Unknown64(machInst); 657 } else { 658 if (q) 659 return new Pmull2X<uint8_t>(machInst, vd, vn, vm); 660 else 661 return new PmullX<uint8_t>(machInst, vd, vn, vm); 662 } 663 default: 664 return new Unknown64(machInst); 665 } 666 } 667 668 StaticInstPtr 669 decodeNeon2RegMisc(ExtMachInst machInst) 670 { 671 uint8_t q = bits(machInst, 30); 672 uint8_t u = bits(machInst, 29); 673 uint8_t size = bits(machInst, 23, 22); 674 uint8_t opcode = bits(machInst, 16, 12); 675 676 IntRegIndex vd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 677 IntRegIndex vn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 678 679 uint8_t size_q = (size << 1) | q; 680 uint8_t sz_q = size_q & 0x3; 681 uint8_t op = (uint8_t)((bits(machInst, 12) << 1) | 682 bits(machInst, 29)); 683 uint8_t switchVal = opcode | ((u ? 1 : 0) << 5); 684 685 switch (switchVal) { 686 case 0x00: 687 if (op + size >= 3) 688 return new Unknown64(machInst); 689 return decodeNeonUTwoMiscSReg<Rev64DX, Rev64QX>( 690 q, size, machInst, vd, vn); 691 case 0x01: 692 if (op + size >= 3) 693 return new Unknown64(machInst); 694 if (q) 695 return new Rev16QX<uint8_t>(machInst, vd, vn); 696 else 697 return new Rev16DX<uint8_t>(machInst, vd, vn); 698 case 0x02: 699 if (size == 0x3) 700 return new Unknown64(machInst); 701 return decodeNeonSTwoMiscSReg<SaddlpDX, SaddlpQX>( 702 q, size, machInst, vd, vn); 703 case 0x03: 704 if (size_q == 0x6) 705 return new Unknown64(machInst); 706 return decodeNeonUTwoMiscXReg<SuqaddDX, SuqaddQX>( 707 q, size, machInst, vd, vn); 708 case 0x04: 709 if (size == 0x3) 710 return new Unknown64(machInst); 711 return decodeNeonSTwoMiscSReg<ClsDX, ClsQX>( 712 q, size, machInst, vd, vn); 713 case 0x05: 714 if (size != 0x0) 715 return new Unknown64(machInst); 716 if (q) 717 return new CntQX<uint8_t>(machInst, vd, vn); 718 else 719 return new CntDX<uint8_t>(machInst, vd, vn); 720 case 0x06: 721 if (size == 0x3) 722 return new Unknown64(machInst); 723 return decodeNeonSTwoMiscSReg<SadalpDX, SadalpQX>( 724 q, size, machInst, vd, vn); 725 case 0x07: 726 if (size_q == 0x6) 727 return new Unknown64(machInst); 728 return decodeNeonSTwoMiscXReg<SqabsDX, SqabsQX>( 729 q, size, machInst, vd, vn); 730 case 0x08: 731 if (size_q == 0x6) 732 return new Unknown64(machInst); 733 return decodeNeonSTwoMiscXReg<CmgtZeroDX, CmgtZeroQX>( 734 q, size, machInst, vd, vn); 735 case 0x09: 736 if (size_q == 0x6) 737 return new Unknown64(machInst); 738 return decodeNeonSTwoMiscXReg<CmeqZeroDX, CmeqZeroQX>( 739 q, size, machInst, vd, vn); 740 case 0x0a: 741 if (size_q == 0x6) 742 return new Unknown64(machInst); 743 return decodeNeonSTwoMiscXReg<CmltZeroDX, CmltZeroQX>( 744 q, size, machInst, vd, vn); 745 case 0x0b: 746 if (size_q == 0x6) 747 return new Unknown64(machInst); 748 return decodeNeonSTwoMiscXReg<AbsDX, AbsQX>( 749 q, size, machInst, vd, vn); 750 case 0x0c: 751 if (size < 0x2 || sz_q == 0x2) 752 return new Unknown64(machInst); 753 return decodeNeonUTwoMiscFpReg<FcmgtZeroDX, FcmgtZeroQX>( 754 q, size & 0x1, machInst, vd, vn); 755 case 0x0d: 756 if (size < 0x2 || sz_q == 0x2) 757 return new Unknown64(machInst); 758 return decodeNeonUTwoMiscFpReg<FcmeqZeroDX, FcmeqZeroQX>( 759 q, size & 0x1, machInst, vd, vn); 760 case 0x0e: 761 if (size < 0x2 || sz_q == 0x2) 762 return new Unknown64(machInst); 763 return decodeNeonUTwoMiscFpReg<FcmltZeroDX, FcmltZeroQX>( 764 q, size & 0x1, machInst, vd, vn); 765 case 0x0f: 766 if (size < 0x2 || sz_q == 0x2) 767 return new Unknown64(machInst); 768 return decodeNeonUTwoMiscFpReg<FabsDX, FabsQX>( 769 q, size & 0x1, machInst, vd, vn); 770 case 0x12: 771 if (size == 0x3) 772 return new Unknown64(machInst); 773 return decodeNeonUTwoMiscSReg<XtnX, Xtn2X>( 774 q, size, machInst, vd, vn); 775 case 0x14: 776 if (size == 0x3) 777 return new Unknown64(machInst); 778 return decodeNeonSTwoMiscSReg<SqxtnX, Sqxtn2X>( 779 q, size, machInst, vd, vn); 780 case 0x16: 781 if (size > 0x1) 782 return new Unknown64(machInst); 783 if (q) { 784 if (size) 785 return new Fcvtn2X<uint32_t>(machInst, vd, vn); 786 else 787 return new Fcvtn2X<uint16_t>(machInst, vd, vn); 788 } else { 789 if (size) 790 return new FcvtnX<uint32_t>(machInst, vd, vn); 791 else 792 return new FcvtnX<uint16_t>(machInst, vd, vn); 793 } 794 case 0x17: 795 if (size > 0x1) 796 return new Unknown64(machInst); 797 if (q) { 798 if (size) 799 return new Fcvtl2X<uint32_t>(machInst, vd, vn); 800 else 801 return new Fcvtl2X<uint16_t>(machInst, vd, vn); 802 } else { 803 if (size) 804 return new FcvtlX<uint32_t>(machInst, vd, vn); 805 else 806 return new FcvtlX<uint16_t>(machInst, vd, vn); 807 } 808 case 0x18: 809 if (sz_q == 0x2) 810 return new Unknown64(machInst); 811 if (size < 0x2) 812 return decodeNeonUTwoMiscFpReg<FrintnDX, FrintnQX>( 813 q, size & 0x1, machInst, vd, vn); 814 else 815 return decodeNeonUTwoMiscFpReg<FrintpDX, FrintpQX>( 816 q, size & 0x1, machInst, vd, vn); 817 case 0x19: 818 if (sz_q == 0x2) 819 return new Unknown64(machInst); 820 if (size < 0x2) 821 return decodeNeonUTwoMiscFpReg<FrintmDX, FrintmQX>( 822 q, size & 0x1, machInst, vd, vn); 823 else 824 return decodeNeonUTwoMiscFpReg<FrintzDX, FrintzQX>( 825 q, size & 0x1, machInst, vd, vn); 826 case 0x1a: 827 if (sz_q == 0x2) 828 return new Unknown64(machInst); 829 if (size < 0x2) 830 return decodeNeonUTwoMiscFpReg<FcvtnsDX, FcvtnsQX>( 831 q, size & 0x1, machInst, vd, vn); 832 else 833 return decodeNeonUTwoMiscFpReg<FcvtpsDX, FcvtpsQX>( 834 q, size & 0x1, machInst, vd, vn); 835 case 0x1b: 836 if (sz_q == 0x2) 837 return new Unknown64(machInst); 838 if (size < 0x2) 839 return decodeNeonUTwoMiscFpReg<FcvtmsDX, FcvtmsQX>( 840 q, size & 0x1, machInst, vd, vn); 841 else 842 return decodeNeonUTwoMiscFpReg<FcvtzsIntDX, FcvtzsIntQX>( 843 q, size & 0x1, machInst, vd, vn); 844 case 0x1c: 845 if (size < 0x2) { 846 if (sz_q == 0x2) 847 return new Unknown64(machInst); 848 return decodeNeonUTwoMiscFpReg<FcvtasDX, FcvtasQX>( 849 q, size & 0x1, machInst, vd, vn); 850 } else { 851 if (size & 0x1) 852 return new Unknown64(machInst); 853 if (q) 854 return new UrecpeQX<uint32_t>(machInst, vd, vn); 855 else 856 return new UrecpeDX<uint32_t>(machInst, vd, vn); 857 } 858 case 0x1d: 859 if (sz_q == 0x2) 860 return new Unknown64(machInst); 861 if (size < 0x2) { 862 if (q) { 863 if (size & 0x1) 864 return new ScvtfIntDQX<uint64_t>(machInst, vd, vn); 865 else 866 return new ScvtfIntSQX<uint32_t>(machInst, vd, vn); 867 } else { 868 if (size & 0x1) 869 return new Unknown(machInst); 870 else 871 return new ScvtfIntDX<uint32_t>(machInst, vd, vn); 872 } 873 } else { 874 return decodeNeonUTwoMiscFpReg<FrecpeDX, FrecpeQX>( 875 q, size & 0x1, machInst, vd, vn); 876 } 877 case 0x20: 878 if (op + size >= 3) 879 return new Unknown64(machInst); 880 if (q) { 881 if (size & 0x1) 882 return new Rev32QX<uint16_t>(machInst, vd, vn); 883 else 884 return new Rev32QX<uint8_t>(machInst, vd, vn); 885 } else { 886 if (size & 0x1) 887 return new Rev32DX<uint16_t>(machInst, vd, vn); 888 else 889 return new Rev32DX<uint8_t>(machInst, vd, vn); 890 } 891 case 0x22: 892 if (size == 0x3) 893 return new Unknown64(machInst); 894 return decodeNeonUTwoMiscSReg<UaddlpDX, UaddlpQX>( 895 q, size, machInst, vd, vn); 896 case 0x23: 897 if (size_q == 0x6) 898 return new Unknown64(machInst); 899 return decodeNeonUTwoMiscXReg<UsqaddDX, UsqaddQX>( 900 q, size, machInst, vd, vn); 901 return new Unknown64(machInst); 902 case 0x24: 903 if (size == 0x3) 904 return new Unknown64(machInst); 905 return decodeNeonSTwoMiscSReg<ClzDX, ClzQX>( 906 q, size, machInst, vd, vn); 907 case 0x25: 908 if (size == 0x0) { 909 if (q) 910 return new MvnQX<uint64_t>(machInst, vd, vn); 911 else 912 return new MvnDX<uint64_t>(machInst, vd, vn); 913 } else if (size == 0x1) { 914 if (q) 915 return new RbitQX<uint8_t>(machInst, vd, vn); 916 else 917 return new RbitDX<uint8_t>(machInst, vd, vn); 918 } else { 919 return new Unknown64(machInst); 920 } 921 case 0x26: 922 if (size == 0x3) 923 return new Unknown64(machInst); 924 return decodeNeonUTwoMiscSReg<UadalpDX, UadalpQX>( 925 q, size, machInst, vd, vn); 926 case 0x27: 927 if (size_q == 0x6) 928 return new Unknown64(machInst); 929 return decodeNeonSTwoMiscXReg<SqnegDX, SqnegQX>( 930 q, size, machInst, vd, vn); 931 case 0x28: 932 if (size_q == 0x6) 933 return new Unknown64(machInst); 934 return decodeNeonSTwoMiscXReg<CmgeZeroDX, CmgeZeroQX>( 935 q, size, machInst, vd, vn); 936 case 0x29: 937 if (size_q == 0x6) 938 return new Unknown64(machInst); 939 return decodeNeonSTwoMiscXReg<CmleZeroDX, CmleZeroQX>( 940 q, size, machInst, vd, vn); 941 case 0x2b: 942 if (size_q == 0x6) 943 return new Unknown64(machInst); 944 return decodeNeonSTwoMiscXReg<NegDX, NegQX>( 945 q, size, machInst, vd, vn); 946 case 0x2c: 947 if (size < 0x2 || sz_q == 0x2) 948 return new Unknown64(machInst); 949 return decodeNeonUTwoMiscFpReg<FcmgeZeroDX, FcmgeZeroQX>( 950 q, size & 0x1, machInst, vd, vn); 951 case 0x2d: 952 if (size < 0x2 || sz_q == 0x2) 953 return new Unknown64(machInst); 954 return decodeNeonUTwoMiscFpReg<FcmleZeroDX, FcmleZeroQX>( 955 q, size & 0x1, machInst, vd, vn); 956 case 0x2f: 957 if (size < 0x2 || size_q == 0x6) 958 return new Unknown64(machInst); 959 return decodeNeonUTwoMiscFpReg<FnegDX, FnegQX>( 960 q, size & 0x1, machInst, vd, vn); 961 case 0x32: 962 if (size == 0x3) 963 return new Unknown64(machInst); 964 return decodeNeonSTwoMiscSReg<SqxtunX, Sqxtun2X>( 965 q, size, machInst, vd, vn); 966 case 0x33: 967 if (size == 0x3) 968 return new Unknown64(machInst); 969 return decodeNeonUTwoMiscSReg<ShllX, Shll2X>( 970 q, size, machInst, vd, vn); 971 case 0x34: 972 if (size == 0x3) 973 return new Unknown64(machInst); 974 return decodeNeonUTwoMiscSReg<UqxtnX, Uqxtn2X>( 975 q, size, machInst, vd, vn); 976 case 0x36: 977 if (size != 0x1) 978 return new Unknown64(machInst); 979 if (q) 980 return new Fcvtxn2X<uint32_t>(machInst, vd, vn); 981 else 982 return new FcvtxnX<uint32_t>(machInst, vd, vn); 983 case 0x38: 984 if (size > 0x1 || sz_q == 0x2) 985 return new Unknown64(machInst); 986 return decodeNeonUTwoMiscFpReg<FrintaDX, FrintaQX>( 987 q, size & 0x1, machInst, vd, vn); 988 case 0x39: 989 if (sz_q == 0x2) 990 return new Unknown64(machInst); 991 if (size < 0x2) 992 return decodeNeonUTwoMiscFpReg<FrintxDX, FrintxQX>( 993 q, size & 0x1, machInst, vd, vn); 994 else 995 return decodeNeonUTwoMiscFpReg<FrintiDX, FrintiQX>( 996 q, size & 0x1, machInst, vd, vn); 997 case 0x3a: 998 if (sz_q == 0x2) 999 return new Unknown64(machInst); 1000 if (size < 0x2) 1001 return decodeNeonUTwoMiscFpReg<FcvtnuDX, FcvtnuQX>( 1002 q, size & 0x1, machInst, vd, vn); 1003 else 1004 return decodeNeonUTwoMiscFpReg<FcvtpuDX, FcvtpuQX>( 1005 q, size & 0x1, machInst, vd, vn); 1006 case 0x3b: 1007 if (sz_q == 0x2) 1008 return new Unknown64(machInst); 1009 if (size < 0x2) 1010 return decodeNeonUTwoMiscFpReg<FcvtmuDX, FcvtmuQX>( 1011 q, size & 0x1, machInst, vd, vn); 1012 else 1013 return decodeNeonUTwoMiscFpReg<FcvtzuIntDX, FcvtzuIntQX>( 1014 q, size & 0x1, machInst, vd, vn); 1015 case 0x3c: 1016 if (size < 0x2) { 1017 return decodeNeonUTwoMiscFpReg<FcvtauDX, FcvtauQX>( 1018 q, size & 0x1, machInst, vd, vn); 1019 } else if (size == 0x2) { 1020 if (q) 1021 return new UrsqrteQX<uint32_t>(machInst, vd, vn); 1022 else 1023 return new UrsqrteDX<uint32_t>(machInst, vd, vn); 1024 } else { 1025 return new Unknown64(machInst); 1026 } 1027 case 0x3d: 1028 if (sz_q == 0x2) 1029 return new Unknown64(machInst); 1030 if (size < 0x2) 1031 return decodeNeonUTwoMiscFpReg<UcvtfIntDX, UcvtfIntQX>( 1032 q, size & 0x1, machInst, vd, vn); 1033 else 1034 return decodeNeonUTwoMiscFpReg<FrsqrteDX, FrsqrteQX>( 1035 q, size & 0x1, machInst, vd, vn); 1036 case 0x3f: 1037 if (size < 0x2 || sz_q == 0x2) 1038 return new Unknown64(machInst); 1039 return decodeNeonUTwoMiscFpReg<FsqrtDX, FsqrtQX>( 1040 q, size & 0x1, machInst, vd, vn); 1041 default: 1042 return new Unknown64(machInst); 1043 } 1044 } 1045 1046 StaticInstPtr 1047 decodeNeonAcrossLanes(ExtMachInst machInst) 1048 { 1049 uint8_t q = bits(machInst, 30); 1050 uint8_t u = bits(machInst, 29); 1051 uint8_t size = bits(machInst, 23, 22); 1052 uint8_t opcode = bits(machInst, 16, 12); 1053 1054 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0); 1055 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5); 1056 1057 uint8_t size_q = (size << 1) | q; 1058 uint8_t sz_q = size_q & 0x3; 1059 uint8_t switchVal = opcode | ((u ? 1 : 0) << 5); 1060 1061 switch (switchVal) { 1062 case 0x03: 1063 if (size_q == 0x4 || size == 0x3) 1064 return new Unknown64(machInst); 1065 return decodeNeonSAcrossLanesLongReg<SaddlvDX, SaddlvQX, 1066 SaddlvBQX>( 1067 q, size, machInst, vd, vn); 1068 case 0x0a: 1069 if (size_q == 0x4 || size == 0x3) 1070 return new Unknown64(machInst); 1071 return decodeNeonSAcrossLanesReg<SmaxvDX, SmaxvQX>( 1072 q, size, machInst, vd, vn); 1073 case 0x1a: 1074 if (size_q == 0x4 || size == 0x3) 1075 return new Unknown64(machInst); 1076 return decodeNeonSAcrossLanesReg<SminvDX, SminvQX>( 1077 q, size, machInst, vd, vn); 1078 case 0x1b: 1079 if (size_q == 0x4 || size == 0x3) 1080 return new Unknown64(machInst); 1081 return decodeNeonUAcrossLanesReg<AddvDX, AddvQX>( 1082 q, size, machInst, vd, vn); 1083 case 0x23: 1084 if (size_q == 0x4 || size == 0x3) 1085 return new Unknown64(machInst); 1086 return decodeNeonUAcrossLanesLongReg<UaddlvDX, UaddlvQX, 1087 UaddlvBQX>( 1088 q, size, machInst, vd, vn); 1089 case 0x2a: 1090 if (size_q == 0x4 || size == 0x3) 1091 return new Unknown64(machInst); 1092 return decodeNeonUAcrossLanesReg<UmaxvDX, UmaxvQX>( 1093 q, size, machInst, vd, vn); 1094 case 0x2c: 1095 if (sz_q != 0x1) 1096 return new Unknown64(machInst); 1097 if (size < 0x2) { 1098 if (q) 1099 return new FmaxnmvQX<uint32_t>(machInst, vd, vn); 1100 else 1101 return new Unknown64(machInst); 1102 } else { 1103 if (q) 1104 return new FminnmvQX<uint32_t>(machInst, vd, vn); 1105 else 1106 return new Unknown64(machInst); 1107 } 1108 case 0x2f: 1109 if (sz_q != 0x1) 1110 return new Unknown64(machInst); 1111 if (size < 0x2) { 1112 if (q) 1113 return new FmaxvQX<uint32_t>(machInst, vd, vn); 1114 else 1115 return new Unknown64(machInst); 1116 } else { 1117 if (q) 1118 return new FminvQX<uint32_t>(machInst, vd, vn); 1119 else 1120 return new Unknown64(machInst); 1121 } 1122 case 0x3a: 1123 if (size_q == 0x4 || size == 0x3) 1124 return new Unknown64(machInst); 1125 return decodeNeonUAcrossLanesReg<UminvDX, UminvQX>( 1126 q, size, machInst, vd, vn); 1127 default: 1128 return new Unknown64(machInst); 1129 } 1130 } 1131 1132 StaticInstPtr 1133 decodeNeonCopy(ExtMachInst machInst) 1134 { 1135 uint8_t q = bits(machInst, 30); 1136 uint8_t op = bits(machInst, 29); 1137 uint8_t imm5 = bits(machInst, 20, 16); 1138 uint8_t imm4 = bits(machInst, 14, 11); 1139 1140 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0); 1141 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5); 1142 1143 uint8_t imm5_pos = findLsbSet(imm5); 1144 uint8_t index1 = 0, index2 = 0; 1145 1146 if (op) { 1147 if (!q || (imm4 & mask(imm5_pos))) 1148 return new Unknown64(machInst); 1149 1150 index1 = bits(imm5, 4, imm5_pos + 1); // dst 1151 index2 = bits(imm4, 3, imm5_pos); // src 1152 1153 switch (imm5_pos) { 1154 case 0: 1155 return new InsElemX<uint8_t>(machInst, vd, vn, index1, index2); 1156 case 1: 1157 return new InsElemX<uint16_t>(machInst, vd, vn, index1, index2); 1158 case 2: 1159 return new InsElemX<uint32_t>(machInst, vd, vn, index1, index2); 1160 case 3: 1161 return new InsElemX<uint64_t>(machInst, vd, vn, index1, index2); 1162 default: 1163 return new Unknown64(machInst); 1164 } 1165 } 1166 1167 switch (imm4) { 1168 case 0x0: 1169 index1 = bits(imm5, 4, imm5_pos + 1); 1170 switch (imm5_pos) { 1171 case 0: 1172 if (q) 1173 return new DupElemQX<uint8_t>(machInst, vd, vn, index1); 1174 else 1175 return new DupElemDX<uint8_t>(machInst, vd, vn, index1); 1176 case 1: 1177 if (q) 1178 return new DupElemQX<uint16_t>(machInst, vd, vn, index1); 1179 else 1180 return new DupElemDX<uint16_t>(machInst, vd, vn, index1); 1181 case 2: 1182 if (q) 1183 return new DupElemQX<uint32_t>(machInst, vd, vn, index1); 1184 else 1185 return new DupElemDX<uint32_t>(machInst, vd, vn, index1); 1186 case 3: 1187 if (q) 1188 return new DupElemQX<uint64_t>(machInst, vd, vn, index1); 1189 else 1190 return new Unknown64(machInst); 1191 default: 1192 return new Unknown64(machInst); 1193 } 1194 case 0x1: 1195 switch (imm5) { 1196 case 0x1: 1197 if (q) 1198 return new DupGprWQX<uint8_t>(machInst, vd, vn); 1199 else 1200 return new DupGprWDX<uint8_t>(machInst, vd, vn); 1201 case 0x2: 1202 if (q) 1203 return new DupGprWQX<uint16_t>(machInst, vd, vn); 1204 else 1205 return new DupGprWDX<uint16_t>(machInst, vd, vn); 1206 case 0x4: 1207 if (q) 1208 return new DupGprWQX<uint32_t>(machInst, vd, vn); 1209 else 1210 return new DupGprWDX<uint32_t>(machInst, vd, vn); 1211 case 0x8: 1212 if (q) 1213 return new DupGprXQX<uint64_t>(machInst, vd, vn); 1214 else 1215 return new Unknown64(machInst); 1216 default: 1217 return new Unknown64(machInst); 1218 } 1219 case 0x3: 1220 index1 = imm5 >> (imm5_pos + 1); 1221 switch (imm5_pos) { 1222 case 0: 1223 return new InsGprWX<uint8_t>(machInst, vd, vn, index1); 1224 case 1: 1225 return new InsGprWX<uint16_t>(machInst, vd, vn, index1); 1226 case 2: 1227 return new InsGprWX<uint32_t>(machInst, vd, vn, index1); 1228 case 3: 1229 return new InsGprXX<uint64_t>(machInst, vd, vn, index1); 1230 default: 1231 return new Unknown64(machInst); 1232 } 1233 case 0x5: 1234 index1 = bits(imm5, 4, imm5_pos + 1); 1235 switch (imm5_pos) { 1236 case 0: 1237 if (q) 1238 return new SmovXX<int8_t>(machInst, vd, vn, index1); 1239 else 1240 return new SmovWX<int8_t>(machInst, vd, vn, index1); 1241 case 1: 1242 if (q) 1243 return new SmovXX<int16_t>(machInst, vd, vn, index1); 1244 else 1245 return new SmovWX<int16_t>(machInst, vd, vn, index1); 1246 case 2: 1247 if (q) 1248 return new SmovXX<int32_t>(machInst, vd, vn, index1); 1249 else 1250 return new Unknown64(machInst); 1251 default: 1252 return new Unknown64(machInst); 1253 } 1254 case 0x7: 1255 index1 = imm5 >> (imm5_pos + 1); 1256 1257 if ((q && imm5_pos != 3) || (!q && imm5_pos >= 3)) 1258 return new Unknown64(machInst); 1259 1260 switch (imm5_pos) { 1261 case 0: 1262 return new UmovWX<uint8_t>(machInst, vd, vn, index1); 1263 case 1: 1264 return new UmovWX<uint16_t>(machInst, vd, vn, index1); 1265 case 2: 1266 return new UmovWX<uint32_t>(machInst, vd, vn, index1); 1267 case 3: 1268 return new UmovXX<uint64_t>(machInst, vd, vn, index1); 1269 default: 1270 return new Unknown64(machInst); 1271 } 1272 default: 1273 return new Unknown64(machInst); 1274 } 1275 } 1276 1277 template <typename DecoderFeatures> 1278 StaticInstPtr 1279 decodeNeonIndexedElem(ExtMachInst machInst) 1280 { 1281 uint8_t q = bits(machInst, 30); 1282 uint8_t u = bits(machInst, 29); 1283 uint8_t size = bits(machInst, 23, 22); 1284 uint8_t L = bits(machInst, 21); 1285 uint8_t M = bits(machInst, 20); 1286 uint8_t opcode = bits(machInst, 15, 12); 1287 uint8_t H = bits(machInst, 11); 1288 1289 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0); 1290 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5); 1291 IntRegIndex vm_bf = (IntRegIndex) (uint8_t) bits(machInst, 19, 16); 1292 1293 uint8_t index = 0; 1294 uint8_t index_fp = 0; 1295 uint8_t vmh = 0; 1296 uint8_t sz = size & 0x1; 1297 uint8_t sz_q = (sz << 1) | bits(machInst, 30); 1298 uint8_t sz_L = (sz << 1) | L; 1299 1300 // Index and 2nd register operand for integer instructions 1301 if (size == 0x1) { 1302 index = (H << 2) | (L << 1) | M; 1303 // vmh = 0; 1304 } else if (size == 0x2) { 1305 index = (H << 1) | L; 1306 vmh = M; 1307 } 1308 IntRegIndex vm = (IntRegIndex) (uint8_t) (vmh << 4 | vm_bf); 1309 1310 // Index and 2nd register operand for FP instructions 1311 vmh = M; 1312 if ((size & 0x1) == 0) { 1313 index_fp = (H << 1) | L; 1314 } else if (L == 0) { 1315 index_fp = H; 1316 } 1317 IntRegIndex vm_fp = (IntRegIndex) (uint8_t) (vmh << 4 | vm_bf); 1318 1319 switch (opcode) { 1320 case 0x0: 1321 if (!u || (size == 0x0 || size == 0x3)) 1322 return new Unknown64(machInst); 1323 else 1324 return decodeNeonUThreeImmHAndWReg<MlaElemDX, MlaElemQX>( 1325 q, size, machInst, vd, vn, vm, index); 1326 case 0x1: 1327 if (!u && size >= 2 && sz_q != 0x2 && sz_L != 0x3) 1328 return decodeNeonUThreeImmFpReg<FmlaElemDX, FmlaElemQX>( 1329 q, sz, machInst, vd, vn, vm_fp, index_fp); 1330 else 1331 return new Unknown64(machInst); 1332 case 0x2: 1333 if (size == 0x0 || size == 0x3) 1334 return new Unknown64(machInst); 1335 if (u) 1336 return decodeNeonUThreeImmHAndWReg<UmlalElemX, UmlalElem2X>( 1337 q, size, machInst, vd, vn, vm, index); 1338 else 1339 return decodeNeonSThreeImmHAndWReg<SmlalElemX, SmlalElem2X>( 1340 q, size, machInst, vd, vn, vm, index); 1341 case 0x3: 1342 if (u || (size == 0x0 || size == 0x3)) 1343 return new Unknown64(machInst); 1344 else 1345 return decodeNeonSThreeImmHAndWReg<SqdmlalElemX, 1346 SqdmlalElem2X>( 1347 q, size, machInst, vd, vn, vm, index); 1348 case 0x4: 1349 if (u && !(size == 0x0 || size == 0x3)) 1350 return decodeNeonUThreeImmHAndWReg<MlsElemDX, MlsElemQX>( 1351 q, size, machInst, vd, vn, vm, index); 1352 else 1353 return new Unknown64(machInst); 1354 case 0x5: 1355 if (!u && size >= 0x2 && sz_L != 0x3 && sz_q != 0x2) 1356 return decodeNeonUThreeImmFpReg<FmlsElemDX, FmlsElemQX>( 1357 q, sz, machInst, vd, vn, vm_fp, index_fp); 1358 else 1359 return new Unknown64(machInst); 1360 case 0x6: 1361 if (size == 0x0 || size == 0x3) 1362 return new Unknown64(machInst); 1363 if (u) 1364 return decodeNeonUThreeImmHAndWReg<UmlslElemX, UmlslElem2X>( 1365 q, size, machInst, vd, vn, vm, index); 1366 else 1367 return decodeNeonSThreeImmHAndWReg<SmlslElemX, SmlslElem2X>( 1368 q, size, machInst, vd, vn, vm, index); 1369 case 0x7: 1370 if (u || (size == 0x0 || size == 0x3)) 1371 return new Unknown64(machInst); 1372 else 1373 return decodeNeonSThreeImmHAndWReg<SqdmlslElemX, 1374 SqdmlslElem2X>( 1375 q, size, machInst, vd, vn, vm, index); 1376 case 0x8: 1377 if (u || (size == 0x0 || size == 0x3)) 1378 return new Unknown64(machInst); 1379 else 1380 return decodeNeonUThreeImmHAndWReg<MulElemDX, MulElemQX>( 1381 q, size, machInst, vd, vn, vm, index); 1382 case 0x9: 1383 if (size >= 2 && sz_q != 0x2 && sz_L != 0x3) { 1384 if (u) 1385 return decodeNeonUThreeImmFpReg<FmulxElemDX, FmulxElemQX>( 1386 q, sz, machInst, vd, vn, vm_fp, index_fp); 1387 else 1388 return decodeNeonUThreeImmFpReg<FmulElemDX, FmulElemQX>( 1389 q, sz, machInst, vd, vn, vm_fp, index_fp); 1390 } else { 1391 return new Unknown64(machInst); 1392 } 1393 case 0xa: 1394 if (size == 0x0 || size == 0x3) 1395 return new Unknown64(machInst); 1396 if (u) 1397 return decodeNeonUThreeImmHAndWReg<UmullElemX, UmullElem2X>( 1398 q, size, machInst, vd, vn, vm, index); 1399 else 1400 return decodeNeonSThreeImmHAndWReg<SmullElemX, SmullElem2X>( 1401 q, size, machInst, vd, vn, vm, index); 1402 case 0xb: 1403 if (u || (size == 0x0 || size == 0x3)) 1404 return new Unknown64(machInst); 1405 else 1406 return decodeNeonSThreeImmHAndWReg<SqdmullElemX, SqdmullElem2X>( 1407 q, size, machInst, vd, vn, vm, index); 1408 case 0xc: 1409 if (u || (size == 0x0 || size == 0x3)) 1410 return new Unknown64(machInst); 1411 else 1412 return decodeNeonSThreeImmHAndWReg<SqdmulhElemDX, SqdmulhElemQX>( 1413 q, size, machInst, vd, vn, vm, index); 1414 case 0xd: 1415 if (u || (size == 0x0 || size == 0x3)) 1416 return new Unknown64(machInst); 1417 else 1418 return decodeNeonSThreeImmHAndWReg<SqrdmulhElemDX, SqrdmulhElemQX>( 1419 q, size, machInst, vd, vn, vm, index); 1420 default: 1421 return new Unknown64(machInst); 1422 } 1423 } 1424 1425 StaticInstPtr 1426 decodeNeonModImm(ExtMachInst machInst) 1427 { 1428 uint8_t q = bits(machInst, 30); 1429 uint8_t op = bits(machInst, 29); 1430 uint8_t abcdefgh = (bits(machInst, 18, 16) << 5) | 1431 bits(machInst, 9, 5); 1432 uint8_t cmode = bits(machInst, 15, 12); 1433 uint8_t o2 = bits(machInst, 11); 1434 1435 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0); 1436 1437 if (o2 == 0x1 || (op == 0x1 && cmode == 0xf && !q)) 1438 return new Unknown64(machInst); 1439 1440 bool immValid = true; 1441 const uint64_t bigImm = simd_modified_imm(op, cmode, abcdefgh, 1442 immValid, 1443 true /* isAarch64 */); 1444 if (!immValid) { 1445 return new Unknown(machInst); 1446 } 1447 1448 if (op) { 1449 if (bits(cmode, 3) == 0) { 1450 if (bits(cmode, 0) == 0) { 1451 if (q) 1452 return new MvniQX<uint64_t>(machInst, vd, bigImm); 1453 else 1454 return new MvniDX<uint64_t>(machInst, vd, bigImm); 1455 } else { 1456 if (q) 1457 return new BicImmQX<uint64_t>(machInst, vd, bigImm); 1458 else 1459 return new BicImmDX<uint64_t>(machInst, vd, bigImm); 1460 } 1461 } else { 1462 if (bits(cmode, 2) == 1) { 1463 switch (bits(cmode, 1, 0)) { 1464 case 0: 1465 case 1: 1466 if (q) 1467 return new MvniQX<uint64_t>(machInst, vd, bigImm); 1468 else 1469 return new MvniDX<uint64_t>(machInst, vd, bigImm); 1470 case 2: 1471 if (q) 1472 return new MoviQX<uint64_t>(machInst, vd, bigImm); 1473 else 1474 return new MoviDX<uint64_t>(machInst, vd, bigImm); 1475 case 3: 1476 if (q) 1477 return new FmovQX<uint64_t>(machInst, vd, bigImm); 1478 else 1479 return new MoviDX<uint64_t>(machInst, vd, bigImm); 1480 } 1481 } else { 1482 if (bits(cmode, 0) == 0) { 1483 if (q) 1484 return new MvniQX<uint64_t>(machInst, vd, bigImm); 1485 else 1486 return new MvniDX<uint64_t>(machInst, vd, bigImm); 1487 } else { 1488 if (q) 1489 return new BicImmQX<uint64_t>(machInst, vd, 1490 bigImm); 1491 else 1492 return new BicImmDX<uint64_t>(machInst, vd, 1493 bigImm); 1494 } 1495 } 1496 } 1497 } else { 1498 if (bits(cmode, 3) == 0) { 1499 if (bits(cmode, 0) == 0) { 1500 if (q) 1501 return new MoviQX<uint64_t>(machInst, vd, bigImm); 1502 else 1503 return new MoviDX<uint64_t>(machInst, vd, bigImm); 1504 } else { 1505 if (q) 1506 return new OrrImmQX<uint64_t>(machInst, vd, bigImm); 1507 else 1508 return new OrrImmDX<uint64_t>(machInst, vd, bigImm); 1509 } 1510 } else { 1511 if (bits(cmode, 2) == 1) { 1512 if (bits(cmode, 1, 0) == 0x3) { 1513 if (q) 1514 return new FmovQX<uint32_t>(machInst, vd, bigImm); 1515 else 1516 return new FmovDX<uint32_t>(machInst, vd, bigImm); 1517 } else { 1518 if (q) 1519 return new MoviQX<uint64_t>(machInst, vd, bigImm); 1520 else 1521 return new MoviDX<uint64_t>(machInst, vd, bigImm); 1522 } 1523 } else { 1524 if (bits(cmode, 0) == 0) { 1525 if (q) 1526 return new MoviQX<uint64_t>(machInst, vd, bigImm); 1527 else 1528 return new MoviDX<uint64_t>(machInst, vd, bigImm); 1529 } else { 1530 if (q) 1531 return new OrrImmQX<uint64_t>(machInst, vd, 1532 bigImm); 1533 else 1534 return new OrrImmDX<uint64_t>(machInst, vd, bigImm); 1535 } 1536 } 1537 } 1538 } 1539 return new Unknown(machInst); 1540 } 1541 1542 StaticInstPtr 1543 decodeNeonShiftByImm(ExtMachInst machInst) 1544 { 1545 uint8_t q = bits(machInst, 30); 1546 uint8_t u = bits(machInst, 29); 1547 uint8_t immh = bits(machInst, 22, 19); 1548 uint8_t immb = bits(machInst, 18, 16); 1549 uint8_t opcode = bits(machInst, 15, 11); 1550 1551 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0); 1552 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5); 1553 1554 uint8_t immh3 = bits(machInst, 22); 1555 uint8_t immh3_q = (immh3 << 1) | q; 1556 uint8_t op_u = (bits(machInst, 12) << 1) | u; 1557 uint8_t size = findMsbSet(immh); 1558 int shiftAmt = 0; 1559 1560 switch (opcode) { 1561 case 0x00: 1562 if (immh3_q == 0x2) 1563 return new Unknown64(machInst); 1564 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb); 1565 if (u) 1566 return decodeNeonUTwoShiftXReg<UshrDX, UshrQX>( 1567 q, size, machInst, vd, vn, shiftAmt); 1568 else 1569 return decodeNeonSTwoShiftXReg<SshrDX, SshrQX>( 1570 q, size, machInst, vd, vn, shiftAmt); 1571 case 0x02: 1572 if (immh3_q == 0x2) 1573 return new Unknown64(machInst); 1574 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb); 1575 if (u) 1576 return decodeNeonUTwoShiftXReg<UsraDX, UsraQX>( 1577 q, size, machInst, vd, vn, shiftAmt); 1578 else 1579 return decodeNeonSTwoShiftXReg<SsraDX, SsraQX>( 1580 q, size, machInst, vd, vn, shiftAmt); 1581 case 0x04: 1582 if (immh3_q == 0x2) 1583 return new Unknown64(machInst); 1584 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb); 1585 if (u) 1586 return decodeNeonUTwoShiftXReg<UrshrDX, UrshrQX>( 1587 q, size, machInst, vd, vn, shiftAmt); 1588 else 1589 return decodeNeonSTwoShiftXReg<SrshrDX, SrshrQX>( 1590 q, size, machInst, vd, vn, shiftAmt); 1591 case 0x06: 1592 if (immh3_q == 0x2) 1593 return new Unknown64(machInst); 1594 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb); 1595 if (u) 1596 return decodeNeonUTwoShiftXReg<UrsraDX, UrsraQX>( 1597 q, size, machInst, vd, vn, shiftAmt); 1598 else 1599 return decodeNeonSTwoShiftXReg<SrsraDX, SrsraQX>( 1600 q, size, machInst, vd, vn, shiftAmt); 1601 case 0x08: 1602 if (u && !(immh3_q == 0x2)) { 1603 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb); 1604 return decodeNeonUTwoShiftXReg<SriDX, SriQX>( 1605 q, size, machInst, vd, vn, shiftAmt); 1606 } else { 1607 return new Unknown64(machInst); 1608 } 1609 case 0x0a: 1610 if (immh3_q == 0x2) 1611 return new Unknown64(machInst); 1612 shiftAmt = ((immh << 3) | immb) - (8 << size); 1613 if (u) 1614 return decodeNeonUTwoShiftXReg<SliDX, SliQX>( 1615 q, size, machInst, vd, vn, shiftAmt); 1616 else 1617 return decodeNeonUTwoShiftXReg<ShlDX, ShlQX>( 1618 q, size, machInst, vd, vn, shiftAmt); 1619 case 0x0c: 1620 if (u && !(immh3_q == 0x2 || op_u == 0x0)) { 1621 shiftAmt = ((immh << 3) | immb) - (8 << size); 1622 return decodeNeonSTwoShiftXReg<SqshluDX, SqshluQX>( 1623 q, size, machInst, vd, vn, shiftAmt); 1624 } else { 1625 return new Unknown64(machInst); 1626 } 1627 case 0x0e: 1628 if (immh3_q == 0x2 || op_u == 0x0) 1629 return new Unknown64(machInst); 1630 shiftAmt = ((immh << 3) | immb) - (8 << size); 1631 if (u) 1632 return decodeNeonUTwoShiftXReg<UqshlImmDX, UqshlImmQX>( 1633 q, size, machInst, vd, vn, shiftAmt); 1634 else 1635 return decodeNeonSTwoShiftXReg<SqshlImmDX, SqshlImmQX>( 1636 q, size, machInst, vd, vn, shiftAmt); 1637 case 0x10: 1638 if (immh3) 1639 return new Unknown64(machInst); 1640 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb); 1641 if (u) 1642 return decodeNeonSTwoShiftSReg<SqshrunX, Sqshrun2X>( 1643 q, size, machInst, vd, vn, shiftAmt); 1644 else 1645 return decodeNeonUTwoShiftSReg<ShrnX, Shrn2X>( 1646 q, size, machInst, vd, vn, shiftAmt); 1647 case 0x11: 1648 if (immh3) 1649 return new Unknown64(machInst); 1650 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb); 1651 if (u) 1652 return decodeNeonSTwoShiftSReg<SqrshrunX, Sqrshrun2X>( 1653 q, size, machInst, vd, vn, shiftAmt); 1654 else 1655 return decodeNeonUTwoShiftSReg<RshrnX, Rshrn2X>( 1656 q, size, machInst, vd, vn, shiftAmt); 1657 case 0x12: 1658 if (immh3) 1659 return new Unknown64(machInst); 1660 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb); 1661 if (u) 1662 return decodeNeonUTwoShiftSReg<UqshrnX, Uqshrn2X>( 1663 q, size, machInst, vd, vn, shiftAmt); 1664 else 1665 return decodeNeonSTwoShiftSReg<SqshrnX, Sqshrn2X>( 1666 q, size, machInst, vd, vn, shiftAmt); 1667 case 0x13: 1668 if (immh3) 1669 return new Unknown64(machInst); 1670 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb); 1671 if (u) 1672 return decodeNeonUTwoShiftSReg<UqrshrnX, Uqrshrn2X>( 1673 q, size, machInst, vd, vn, shiftAmt); 1674 else 1675 return decodeNeonSTwoShiftSReg<SqrshrnX, Sqrshrn2X>( 1676 q, size, machInst, vd, vn, shiftAmt); 1677 case 0x14: 1678 if (immh3) 1679 return new Unknown64(machInst); 1680 shiftAmt = ((immh << 3) | immb) - (8 << size); 1681 if (u) 1682 return decodeNeonUTwoShiftSReg<UshllX, Ushll2X>( 1683 q, size, machInst, vd, vn, shiftAmt); 1684 else 1685 return decodeNeonSTwoShiftSReg<SshllX, Sshll2X>( 1686 q, size, machInst, vd, vn, shiftAmt); 1687 case 0x1c: 1688 if (immh < 0x4 || immh3_q == 0x2) 1689 return new Unknown64(machInst); 1690 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb); 1691 if (u) { 1692 return decodeNeonUTwoShiftFpReg<UcvtfFixedDX, UcvtfFixedQX>( 1693 q, size & 0x1, machInst, vd, vn, shiftAmt); 1694 } else { 1695 if (q) { 1696 if (size & 0x1) 1697 return new ScvtfFixedDQX<uint64_t>(machInst, vd, vn, 1698 shiftAmt); 1699 else 1700 return new ScvtfFixedSQX<uint32_t>(machInst, vd, vn, 1701 shiftAmt); 1702 } else { 1703 if (size & 0x1) 1704 return new Unknown(machInst); 1705 else 1706 return new ScvtfFixedDX<uint32_t>(machInst, vd, vn, 1707 shiftAmt); 1708 } 1709 } 1710 case 0x1f: 1711 if (immh < 0x4 || immh3_q == 0x2) 1712 return new Unknown64(machInst); 1713 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb); 1714 if (u) 1715 return decodeNeonUTwoShiftFpReg<FcvtzuFixedDX, FcvtzuFixedQX>( 1716 q, size & 0x1, machInst, vd, vn, shiftAmt); 1717 else 1718 return decodeNeonUTwoShiftFpReg<FcvtzsFixedDX, FcvtzsFixedQX>( 1719 q, size & 0x1, machInst, vd, vn, shiftAmt); 1720 default: 1721 return new Unknown64(machInst); 1722 } 1723 } 1724 1725 StaticInstPtr 1726 decodeNeonTblTbx(ExtMachInst machInst) 1727 { 1728 uint8_t q = bits(machInst, 30); 1729 1730 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0); 1731 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5); 1732 IntRegIndex vm = (IntRegIndex) (uint8_t) bits(machInst, 20, 16); 1733 1734 uint8_t switchVal = bits(machInst, 14, 12); 1735 1736 switch (switchVal) { 1737 case 0x0: 1738 if (q) 1739 return new Tbl1QX<uint8_t>(machInst, vd, vn, vm); 1740 else 1741 return new Tbl1DX<uint8_t>(machInst, vd, vn, vm); 1742 case 0x1: 1743 if (q) 1744 return new Tbx1QX<uint8_t>(machInst, vd, vn, vm); 1745 else 1746 return new Tbx1DX<uint8_t>(machInst, vd, vn, vm); 1747 case 0x2: 1748 if (q) 1749 return new Tbl2QX<uint8_t>(machInst, vd, vn, vm); 1750 else 1751 return new Tbl2DX<uint8_t>(machInst, vd, vn, vm); 1752 case 0x3: 1753 if (q) 1754 return new Tbx2QX<uint8_t>(machInst, vd, vn, vm); 1755 else 1756 return new Tbx2DX<uint8_t>(machInst, vd, vn, vm); 1757 case 0x4: 1758 if (q) 1759 return new Tbl3QX<uint8_t>(machInst, vd, vn, vm); 1760 else 1761 return new Tbl3DX<uint8_t>(machInst, vd, vn, vm); 1762 case 0x5: 1763 if (q) 1764 return new Tbx3QX<uint8_t>(machInst, vd, vn, vm); 1765 else 1766 return new Tbx3DX<uint8_t>(machInst, vd, vn, vm); 1767 case 0x6: 1768 if (q) 1769 return new Tbl4QX<uint8_t>(machInst, vd, vn, vm); 1770 else 1771 return new Tbl4DX<uint8_t>(machInst, vd, vn, vm); 1772 case 0x7: 1773 if (q) 1774 return new Tbx4QX<uint8_t>(machInst, vd, vn, vm); 1775 else 1776 return new Tbx4DX<uint8_t>(machInst, vd, vn, vm); 1777 default: 1778 return new Unknown64(machInst); 1779 } 1780 1781 return new Unknown64(machInst); 1782 } 1783 1784 StaticInstPtr 1785 decodeNeonZipUzpTrn(ExtMachInst machInst) 1786 { 1787 uint8_t q = bits(machInst, 30); 1788 uint8_t size = bits(machInst, 23, 22); 1789 uint8_t opcode = bits(machInst, 14, 12); 1790 1791 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0); 1792 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5); 1793 IntRegIndex vm = (IntRegIndex) (uint8_t) bits(machInst, 20, 16); 1794 1795 switch (opcode) { 1796 case 0x1: 1797 return decodeNeonUThreeXReg<Uzp1DX, Uzp1QX>( 1798 q, size, machInst, vd, vn, vm); 1799 case 0x2: 1800 return decodeNeonUThreeXReg<Trn1DX, Trn1QX>( 1801 q, size, machInst, vd, vn, vm); 1802 case 0x3: 1803 return decodeNeonUThreeXReg<Zip1DX, Zip1QX>( 1804 q, size, machInst, vd, vn, vm); 1805 case 0x5: 1806 return decodeNeonUThreeXReg<Uzp2DX, Uzp2QX>( 1807 q, size, machInst, vd, vn, vm); 1808 case 0x6: 1809 return decodeNeonUThreeXReg<Trn2DX, Trn2QX>( 1810 q, size, machInst, vd, vn, vm); 1811 case 0x7: 1812 return decodeNeonUThreeXReg<Zip2DX, Zip2QX>( 1813 q, size, machInst, vd, vn, vm); 1814 default: 1815 return new Unknown64(machInst); 1816 } 1817 return new Unknown64(machInst); 1818 } 1819 1820 StaticInstPtr 1821 decodeNeonExt(ExtMachInst machInst) 1822 { 1823 uint8_t q = bits(machInst, 30); 1824 uint8_t op2 = bits(machInst, 23, 22); 1825 uint8_t imm4 = bits(machInst, 14, 11); 1826 1827 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0); 1828 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5); 1829 IntRegIndex vm = (IntRegIndex) (uint8_t) bits(machInst, 20, 16); 1830 1831 if (op2 != 0 || (q == 0x0 && bits(imm4, 3) == 0x1)) 1832 return new Unknown64(machInst); 1833 1834 uint8_t index = q ? imm4 : imm4 & 0x7; 1835 1836 if (q) { 1837 return new ExtQX<uint8_t>(machInst, vd, vn, vm, index); 1838 } else { 1839 return new ExtDX<uint8_t>(machInst, vd, vn, vm, index); 1840 } 1841 } 1842 1843 StaticInstPtr 1844 decodeNeonSc3Same(ExtMachInst machInst) 1845 { 1846 uint8_t u = bits(machInst, 29); 1847 uint8_t size = bits(machInst, 23, 22); 1848 uint8_t opcode = bits(machInst, 15, 11); 1849 uint8_t s = bits(machInst, 11); 1850 1851 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0); 1852 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5); 1853 IntRegIndex vm = (IntRegIndex) (uint8_t) bits(machInst, 20, 16); 1854 1855 switch (opcode) { 1856 case 0x01: 1857 if (u) 1858 return decodeNeonUThreeUReg<UqaddScX>( 1859 size, machInst, vd, vn, vm); 1860 else 1861 return decodeNeonSThreeUReg<SqaddScX>( 1862 size, machInst, vd, vn, vm); 1863 case 0x05: 1864 if (u) 1865 return decodeNeonUThreeUReg<UqsubScX>( 1866 size, machInst, vd, vn, vm); 1867 else 1868 return decodeNeonSThreeUReg<SqsubScX>( 1869 size, machInst, vd, vn, vm); 1870 case 0x06: 1871 if (size != 0x3) 1872 return new Unknown64(machInst); 1873 if (u) 1874 return new CmhiDX<uint64_t>(machInst, vd, vn, vm); 1875 else 1876 return new CmgtDX<int64_t>(machInst, vd, vn, vm); 1877 case 0x07: 1878 if (size != 0x3) 1879 return new Unknown64(machInst); 1880 if (u) 1881 return new CmhsDX<uint64_t>(machInst, vd, vn, vm); 1882 else 1883 return new CmgeDX<int64_t>(machInst, vd, vn, vm); 1884 case 0x08: 1885 if (!s && size != 0x3) 1886 return new Unknown64(machInst); 1887 if (u) 1888 return new UshlDX<uint64_t>(machInst, vd, vn, vm); 1889 else 1890 return new SshlDX<int64_t>(machInst, vd, vn, vm); 1891 case 0x09: 1892 if (!s && size != 0x3) 1893 return new Unknown64(machInst); 1894 if (u) 1895 return decodeNeonUThreeUReg<UqshlScX>( 1896 size, machInst, vd, vn, vm); 1897 else 1898 return decodeNeonSThreeUReg<SqshlScX>( 1899 size, machInst, vd, vn, vm); 1900 case 0x0a: 1901 if (!s && size != 0x3) 1902 return new Unknown64(machInst); 1903 if (u) 1904 return new UrshlDX<uint64_t>(machInst, vd, vn, vm); 1905 else 1906 return new SrshlDX<int64_t>(machInst, vd, vn, vm); 1907 case 0x0b: 1908 if (!s && size != 0x3) 1909 return new Unknown64(machInst); 1910 if (u) 1911 return decodeNeonUThreeUReg<UqrshlScX>( 1912 size, machInst, vd, vn, vm); 1913 else 1914 return decodeNeonSThreeUReg<SqrshlScX>( 1915 size, machInst, vd, vn, vm); 1916 case 0x10: 1917 if (size != 0x3) 1918 return new Unknown64(machInst); 1919 if (u) 1920 return new SubDX<uint64_t>(machInst, vd, vn, vm); 1921 else 1922 return new AddDX<uint64_t>(machInst, vd, vn, vm); 1923 case 0x11: 1924 if (size != 0x3) 1925 return new Unknown64(machInst); 1926 if (u) 1927 return new CmeqDX<uint64_t>(machInst, vd, vn, vm); 1928 else 1929 return new CmtstDX<uint64_t>(machInst, vd, vn, vm); 1930 case 0x16: 1931 if (size == 0x3 || size == 0x0) 1932 return new Unknown64(machInst); 1933 if (u) 1934 return decodeNeonSThreeHAndWReg<SqrdmulhScX>( 1935 size, machInst, vd, vn, vm); 1936 else 1937 return decodeNeonSThreeHAndWReg<SqdmulhScX>( 1938 size, machInst, vd, vn, vm); 1939 case 0x1a: 1940 if (!u || size < 0x2) 1941 return new Unknown64(machInst); 1942 else 1943 return decodeNeonUThreeScFpReg<FabdScX>( 1944 size & 0x1, machInst, vd, vn, vm); 1945 case 0x1b: 1946 if (u || size > 0x1) 1947 return new Unknown64(machInst); 1948 else 1949 return decodeNeonUThreeScFpReg<FmulxScX>( 1950 size & 0x1, machInst, vd, vn, vm); 1951 case 0x1c: 1952 if (size < 0x2) { 1953 if (u) 1954 return decodeNeonUThreeScFpReg<FcmgeScX>( 1955 size & 0x1, machInst, vd, vn, vm); 1956 else 1957 return decodeNeonUThreeScFpReg<FcmeqScX>( 1958 size & 0x1, machInst, vd, vn, vm); 1959 } else { 1960 if (u) 1961 return decodeNeonUThreeScFpReg<FcmgtScX>( 1962 size & 0x1, machInst, vd, vn, vm); 1963 else 1964 return new Unknown64(machInst); 1965 } 1966 case 0x1d: 1967 if (!u) 1968 return new Unknown64(machInst); 1969 if (size < 0x2) 1970 return decodeNeonUThreeScFpReg<FacgeScX>( 1971 size & 0x1, machInst, vd, vn, vm); 1972 else 1973 return decodeNeonUThreeScFpReg<FacgtScX>( 1974 size & 0x1, machInst, vd, vn, vm); 1975 case 0x1f: 1976 if (u) 1977 return new Unknown64(machInst); 1978 if (size < 0x2) 1979 return decodeNeonUThreeScFpReg<FrecpsScX>( 1980 size & 0x1, machInst, vd, vn, vm); 1981 else 1982 return decodeNeonUThreeScFpReg<FrsqrtsScX>( 1983 size & 0x1, machInst, vd, vn, vm); 1984 default: 1985 return new Unknown64(machInst); 1986 } 1987 } 1988 1989 StaticInstPtr 1990 decodeNeonSc3Diff(ExtMachInst machInst) 1991 { 1992 if (bits(machInst, 29)) 1993 return new Unknown64(machInst); 1994 1995 uint8_t size = bits(machInst, 23, 22); 1996 if (size == 0x0 || size == 0x3) 1997 return new Unknown64(machInst); 1998 1999 uint8_t opcode = bits(machInst, 15, 12); 2000 2001 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0); 2002 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5); 2003 IntRegIndex vm = (IntRegIndex) (uint8_t) bits(machInst, 20, 16); 2004 2005 switch (opcode) { 2006 case 0x9: 2007 return decodeNeonSThreeHAndWReg<SqdmlalScX>(size, machInst, vd, vn, vm); 2008 case 0xb: 2009 return decodeNeonSThreeHAndWReg<SqdmlslScX>(size, machInst, vd, vn, vm); 2010 case 0xd: 2011 return decodeNeonSThreeHAndWReg<SqdmullScX>(size, machInst, vd, vn, vm); 2012 default: 2013 return new Unknown64(machInst); 2014 } 2015 } 2016 2017 StaticInstPtr 2018 decodeNeonSc2RegMisc(ExtMachInst machInst) 2019 { 2020 uint8_t u = bits(machInst, 29); 2021 uint8_t size = bits(machInst, 23, 22); 2022 uint8_t opcode = bits(machInst, 16, 12); 2023 2024 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0); 2025 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5); 2026 2027 uint8_t switchVal = opcode | ((u ? 1 : 0) << 5); 2028 switch (switchVal) { 2029 case 0x03: 2030 return decodeNeonUTwoMiscUReg<SuqaddScX>(size, machInst, vd, vn); 2031 case 0x07: 2032 return decodeNeonSTwoMiscUReg<SqabsScX>(size, machInst, vd, vn); 2033 case 0x08: 2034 if (size != 0x3) 2035 return new Unknown64(machInst); 2036 else 2037 return new CmgtZeroDX<int64_t>(machInst, vd, vn); 2038 case 0x09: 2039 if (size != 0x3) 2040 return new Unknown64(machInst); 2041 else 2042 return new CmeqZeroDX<int64_t>(machInst, vd, vn); 2043 case 0x0a: 2044 if (size != 0x3) 2045 return new Unknown64(machInst); 2046 else 2047 return new CmltZeroDX<int64_t>(machInst, vd, vn); 2048 case 0x0b: 2049 if (size != 0x3) 2050 return new Unknown64(machInst); 2051 else 2052 return new AbsDX<int64_t>(machInst, vd, vn); 2053 case 0x0c: 2054 if (size < 0x2) 2055 return new Unknown64(machInst); 2056 else 2057 return decodeNeonUTwoMiscScFpReg<FcmgtZeroScX>( 2058 size & 0x1, machInst, vd, vn); 2059 case 0x0d: 2060 if (size < 0x2) 2061 return new Unknown64(machInst); 2062 else 2063 return decodeNeonUTwoMiscScFpReg<FcmeqZeroScX>( 2064 size & 0x1, machInst, vd, vn); 2065 case 0x0e: 2066 if (size < 0x2) 2067 return new Unknown64(machInst); 2068 else 2069 return decodeNeonUTwoMiscScFpReg<FcmltZeroScX>( 2070 size & 0x1, machInst, vd, vn); 2071 case 0x14: 2072 switch (size) { 2073 case 0x0: 2074 return new SqxtnScX<int8_t>(machInst, vd, vn); 2075 case 0x1: 2076 return new SqxtnScX<int16_t>(machInst, vd, vn); 2077 case 0x2: 2078 return new SqxtnScX<int32_t>(machInst, vd, vn); 2079 case 0x3: 2080 return new Unknown64(machInst); 2081 default: 2082 M5_UNREACHABLE; 2083 } 2084 case 0x1a: 2085 if (size < 0x2) 2086 return decodeNeonUTwoMiscScFpReg<FcvtnsScX>( 2087 size & 0x1, machInst, vd, vn); 2088 else 2089 return decodeNeonUTwoMiscScFpReg<FcvtpsScX>( 2090 size & 0x1, machInst, vd, vn); 2091 case 0x1b: 2092 if (size < 0x2) 2093 return decodeNeonUTwoMiscScFpReg<FcvtmsScX>( 2094 size & 0x1, machInst, vd, vn); 2095 else 2096 return decodeNeonUTwoMiscScFpReg<FcvtzsIntScX>( 2097 size & 0x1, machInst, vd, vn); 2098 case 0x1c: 2099 if (size < 0x2) 2100 return decodeNeonUTwoMiscScFpReg<FcvtasScX>( 2101 size & 0x1, machInst, vd, vn); 2102 else 2103 return new Unknown64(machInst); 2104 case 0x1d: 2105 if (size < 0x2) { 2106 if (size & 0x1) 2107 return new ScvtfIntScDX<uint64_t>(machInst, vd, vn); 2108 else 2109 return new ScvtfIntScSX<uint32_t>(machInst, vd, vn); 2110 } else { 2111 return decodeNeonUTwoMiscScFpReg<FrecpeScX>( 2112 size & 0x1, machInst, vd, vn); 2113 } 2114 case 0x1f: 2115 if (size < 0x2) 2116 return new Unknown64(machInst); 2117 else 2118 return decodeNeonUTwoMiscScFpReg<FrecpxX>( 2119 size & 0x1, machInst, vd, vn); 2120 case 0x23: 2121 return decodeNeonUTwoMiscUReg<UsqaddScX>(size, machInst, vd, vn); 2122 case 0x27: 2123 return decodeNeonSTwoMiscUReg<SqnegScX>(size, machInst, vd, vn); 2124 case 0x28: 2125 if (size != 0x3) 2126 return new Unknown64(machInst); 2127 else 2128 return new CmgeZeroDX<int64_t>(machInst, vd, vn); 2129 case 0x29: 2130 if (size != 0x3) 2131 return new Unknown64(machInst); 2132 else 2133 return new CmleZeroDX<int64_t>(machInst, vd, vn); 2134 case 0x2b: 2135 if (size != 0x3) 2136 return new Unknown64(machInst); 2137 else 2138 return new NegDX<int64_t>(machInst, vd, vn); 2139 case 0x2c: 2140 if (size < 0x2) 2141 return new Unknown64(machInst); 2142 else 2143 return decodeNeonUTwoMiscScFpReg<FcmgeZeroScX>( 2144 size & 0x1, machInst, vd, vn); 2145 case 0x2d: 2146 if (size < 0x2) 2147 return new Unknown64(machInst); 2148 else 2149 return decodeNeonUTwoMiscScFpReg<FcmleZeroScX>( 2150 size & 0x1, machInst, vd, vn); 2151 case 0x32: 2152 switch (size) { 2153 case 0x0: 2154 return new SqxtunScX<int8_t>(machInst, vd, vn); 2155 case 0x1: 2156 return new SqxtunScX<int16_t>(machInst, vd, vn); 2157 case 0x2: 2158 return new SqxtunScX<int32_t>(machInst, vd, vn); 2159 case 0x3: 2160 return new Unknown64(machInst); 2161 default: 2162 M5_UNREACHABLE; 2163 } 2164 case 0x34: 2165 switch (size) { 2166 case 0x0: 2167 return new UqxtnScX<uint8_t>(machInst, vd, vn); 2168 case 0x1: 2169 return new UqxtnScX<uint16_t>(machInst, vd, vn); 2170 case 0x2: 2171 return new UqxtnScX<uint32_t>(machInst, vd, vn); 2172 case 0x3: 2173 return new Unknown64(machInst); 2174 default: 2175 M5_UNREACHABLE; 2176 } 2177 case 0x36: 2178 if (size != 0x1) { 2179 return new Unknown64(machInst); 2180 } else { 2181 return new FcvtxnScX<uint32_t>(machInst, vd, vn); 2182 } 2183 case 0x3a: 2184 if (size < 0x2) 2185 return decodeNeonUTwoMiscScFpReg<FcvtnuScX>( 2186 size & 0x1, machInst, vd, vn); 2187 else 2188 return decodeNeonUTwoMiscScFpReg<FcvtpuScX>( 2189 size & 0x1, machInst, vd, vn); 2190 case 0x3b: 2191 if (size < 0x2) 2192 return decodeNeonUTwoMiscScFpReg<FcvtmuScX>( 2193 size & 0x1, machInst, vd, vn); 2194 else 2195 return decodeNeonUTwoMiscScFpReg<FcvtzuIntScX>( 2196 size & 0x1, machInst, vd, vn); 2197 case 0x3c: 2198 if (size < 0x2) 2199 return decodeNeonUTwoMiscScFpReg<FcvtauScX>( 2200 size & 0x1, machInst, vd, vn); 2201 else 2202 return new Unknown64(machInst); 2203 case 0x3d: 2204 if (size < 0x2) 2205 return decodeNeonUTwoMiscScFpReg<UcvtfIntScX>( 2206 size & 0x1, machInst, vd, vn); 2207 else 2208 return decodeNeonUTwoMiscScFpReg<FrsqrteScX>( 2209 size & 0x1, machInst, vd, vn); 2210 default: 2211 return new Unknown64(machInst); 2212 } 2213 } 2214 2215 StaticInstPtr 2216 decodeNeonScPwise(ExtMachInst machInst) 2217 { 2218 uint8_t u = bits(machInst, 29); 2219 uint8_t size = bits(machInst, 23, 22); 2220 uint8_t opcode = bits(machInst, 16, 12); 2221 2222 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0); 2223 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5); 2224 2225 if (!u) { 2226 if (opcode == 0x1b && size == 0x3) 2227 return new AddpScQX<uint64_t>(machInst, vd, vn); 2228 else 2229 return new Unknown64(machInst); 2230 } 2231 2232 uint8_t switchVal = (opcode << 0) | (size << 5); 2233 switch (switchVal) { 2234 case 0x0c: 2235 case 0x2c: 2236 return decodeNeonUTwoMiscPwiseScFpReg<FmaxnmpScDX, FmaxnmpScQX>( 2237 size & 0x1, machInst, vd, vn); 2238 case 0x0d: 2239 case 0x2d: 2240 return decodeNeonUTwoMiscPwiseScFpReg<FaddpScDX, FaddpScQX>( 2241 size & 0x1, machInst, vd, vn); 2242 case 0x0f: 2243 case 0x2f: 2244 return decodeNeonUTwoMiscPwiseScFpReg<FmaxpScDX, FmaxpScQX>( 2245 size & 0x1, machInst, vd, vn); 2246 case 0x4c: 2247 case 0x6c: 2248 return decodeNeonUTwoMiscPwiseScFpReg<FminnmpScDX, FminnmpScQX>( 2249 size & 0x1, machInst, vd, vn); 2250 case 0x4f: 2251 case 0x6f: 2252 return decodeNeonUTwoMiscPwiseScFpReg<FminpScDX, FminpScQX>( 2253 size & 0x1, machInst, vd, vn); 2254 default: 2255 return new Unknown64(machInst); 2256 } 2257 } 2258 2259 StaticInstPtr 2260 decodeNeonScCopy(ExtMachInst machInst) 2261 { 2262 if (bits(machInst, 14, 11) != 0 || bits(machInst, 29)) 2263 return new Unknown64(machInst); 2264 2265 uint8_t imm5 = bits(machInst, 20, 16); 2266 2267 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0); 2268 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5); 2269 2270 uint8_t size = findLsbSet(imm5); 2271 uint8_t index = bits(imm5, 4, size + 1); 2272 2273 return decodeNeonUTwoShiftUReg<DupElemScX>( 2274 size, machInst, vd, vn, index); 2275 } 2276 2277 StaticInstPtr 2278 decodeNeonScIndexedElem(ExtMachInst machInst) 2279 { 2280 uint8_t u = bits(machInst, 29); 2281 uint8_t size = bits(machInst, 23, 22); 2282 uint8_t L = bits(machInst, 21); 2283 uint8_t M = bits(machInst, 20); 2284 uint8_t opcode = bits(machInst, 15, 12); 2285 uint8_t H = bits(machInst, 11); 2286 2287 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0); 2288 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5); 2289 IntRegIndex vm_bf = (IntRegIndex) (uint8_t) bits(machInst, 19, 16); 2290 2291 uint8_t index = 0; 2292 uint8_t index_fp = 0; 2293 uint8_t vmh = 0; 2294 uint8_t sz_L = bits(machInst, 22, 21); 2295 2296 // Index and 2nd register operand for integer instructions 2297 if (size == 0x1) { 2298 index = (H << 2) | (L << 1) | M; 2299 // vmh = 0; 2300 } else if (size == 0x2) { 2301 index = (H << 1) | L; 2302 vmh = M; 2303 } else if (size == 0x3) { 2304 index = H; 2305 vmh = M; 2306 } 2307 IntRegIndex vm = (IntRegIndex) (uint8_t) (vmh << 4 | vm_bf); 2308 2309 // Index and 2nd register operand for FP instructions 2310 vmh = M; 2311 if ((size & 0x1) == 0) { 2312 index_fp = (H << 1) | L; 2313 } else if (L == 0) { 2314 index_fp = H; 2315 } 2316 IntRegIndex vm_fp = (IntRegIndex) (uint8_t) (vmh << 4 | vm_bf); 2317 2318 if (u && opcode != 9) 2319 return new Unknown64(machInst); 2320 2321 switch (opcode) { 2322 case 0x1: 2323 if (size < 2 || sz_L == 0x3) 2324 return new Unknown64(machInst); 2325 else 2326 return decodeNeonUThreeImmScFpReg<FmlaElemScX>( 2327 size & 0x1, machInst, vd, vn, vm_fp, index_fp); 2328 case 0x3: 2329 if (size == 0x0 || size == 0x3) 2330 return new Unknown64(machInst); 2331 else 2332 return decodeNeonSThreeImmHAndWReg<SqdmlalElemScX>( 2333 size, machInst, vd, vn, vm, index); 2334 case 0x5: 2335 if (size < 2 || sz_L == 0x3) 2336 return new Unknown64(machInst); 2337 else 2338 return decodeNeonUThreeImmScFpReg<FmlsElemScX>( 2339 size & 0x1, machInst, vd, vn, vm_fp, index_fp); 2340 case 0x7: 2341 if (size == 0x0 || size == 0x3) 2342 return new Unknown64(machInst); 2343 else 2344 return decodeNeonSThreeImmHAndWReg<SqdmlslElemScX>( 2345 size, machInst, vd, vn, vm, index); 2346 case 0x9: 2347 if (size < 2 || sz_L == 0x3) 2348 return new Unknown64(machInst); 2349 if (u) 2350 return decodeNeonUThreeImmScFpReg<FmulxElemScX>( 2351 size & 0x1, machInst, vd, vn, vm_fp, index_fp); 2352 else 2353 return decodeNeonUThreeImmScFpReg<FmulElemScX>( 2354 size & 0x1, machInst, vd, vn, vm_fp, index_fp); 2355 case 0xb: 2356 if (size == 0x0 || size == 0x3) 2357 return new Unknown64(machInst); 2358 else 2359 return decodeNeonSThreeImmHAndWReg<SqdmullElemScX>( 2360 size, machInst, vd, vn, vm, index); 2361 case 0xc: 2362 if (size == 0x0 || size == 0x3) 2363 return new Unknown64(machInst); 2364 else 2365 return decodeNeonSThreeImmHAndWReg<SqdmulhElemScX>( 2366 size, machInst, vd, vn, vm, index); 2367 case 0xd: 2368 if (size == 0x0 || size == 0x3) 2369 return new Unknown64(machInst); 2370 else 2371 return decodeNeonSThreeImmHAndWReg<SqrdmulhElemScX>( 2372 size, machInst, vd, vn, vm, index); 2373 default: 2374 return new Unknown64(machInst); 2375 } 2376 } 2377 2378 StaticInstPtr 2379 decodeNeonScShiftByImm(ExtMachInst machInst) 2380 { 2381 bool u = bits(machInst, 29); 2382 uint8_t immh = bits(machInst, 22, 19); 2383 uint8_t immb = bits(machInst, 18, 16); 2384 uint8_t opcode = bits(machInst, 15, 11); 2385 2386 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0); 2387 IntRegIndex vn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5); 2388 2389 uint8_t immh3 = bits(machInst, 22); 2390 uint8_t size = findMsbSet(immh); 2391 int shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb); 2392 2393 if (immh == 0x0) 2394 return new Unknown64(machInst); 2395 2396 switch (opcode) { 2397 case 0x00: 2398 if (!immh3) 2399 return new Unknown64(machInst); 2400 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb); 2401 if (u) 2402 return new UshrDX<uint64_t>(machInst, vd, vn, shiftAmt); 2403 else 2404 return new SshrDX<int64_t>(machInst, vd, vn, shiftAmt); 2405 case 0x02: 2406 if (!immh3) 2407 return new Unknown64(machInst); 2408 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb); 2409 if (u) 2410 return new UsraDX<uint64_t>(machInst, vd, vn, shiftAmt); 2411 else 2412 return new SsraDX<int64_t>(machInst, vd, vn, shiftAmt); 2413 case 0x04: 2414 if (!immh3) 2415 return new Unknown64(machInst); 2416 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb); 2417 if (u) 2418 return new UrshrDX<uint64_t>(machInst, vd, vn, shiftAmt); 2419 else 2420 return new SrshrDX<int64_t>(machInst, vd, vn, shiftAmt); 2421 case 0x06: 2422 if (!immh3) 2423 return new Unknown64(machInst); 2424 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb); 2425 if (u) 2426 return new UrsraDX<uint64_t>(machInst, vd, vn, shiftAmt); 2427 else 2428 return new SrsraDX<int64_t>(machInst, vd, vn, shiftAmt); 2429 case 0x08: 2430 if (!immh3) 2431 return new Unknown64(machInst); 2432 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb); 2433 if (u) 2434 return new SriDX<uint64_t>(machInst, vd, vn, shiftAmt); 2435 else 2436 return new Unknown64(machInst); 2437 case 0x0a: 2438 if (!immh3) 2439 return new Unknown64(machInst); 2440 shiftAmt = ((immh << 3) | immb) - (8 << size); 2441 if (u) 2442 return new SliDX<uint64_t>(machInst, vd, vn, shiftAmt); 2443 else 2444 return new ShlDX<uint64_t>(machInst, vd, vn, shiftAmt); 2445 case 0x0c: 2446 if (u) { 2447 shiftAmt = ((immh << 3) | immb) - (8 << size); 2448 return decodeNeonSTwoShiftUReg<SqshluScX>( 2449 size, machInst, vd, vn, shiftAmt); 2450 } else { 2451 return new Unknown64(machInst); 2452 } 2453 case 0x0e: 2454 shiftAmt = ((immh << 3) | immb) - (8 << size); 2455 if (u) 2456 return decodeNeonUTwoShiftUReg<UqshlImmScX>( 2457 size, machInst, vd, vn, shiftAmt); 2458 else 2459 return decodeNeonSTwoShiftUReg<SqshlImmScX>( 2460 size, machInst, vd, vn, shiftAmt); 2461 case 0x10: 2462 if (!u || immh3) 2463 return new Unknown64(machInst); 2464 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb); 2465 return decodeNeonSTwoShiftUSReg<SqshrunScX>( 2466 size, machInst, vd, vn, shiftAmt); 2467 case 0x11: 2468 if (!u || immh3) 2469 return new Unknown64(machInst); 2470 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb); 2471 return decodeNeonSTwoShiftUSReg<SqrshrunScX>( 2472 size, machInst, vd, vn, shiftAmt); 2473 case 0x12: 2474 if (immh3) 2475 return new Unknown64(machInst); 2476 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb); 2477 if (u) 2478 return decodeNeonUTwoShiftUSReg<UqshrnScX>( 2479 size, machInst, vd, vn, shiftAmt); 2480 else 2481 return decodeNeonSTwoShiftUSReg<SqshrnScX>( 2482 size, machInst, vd, vn, shiftAmt); 2483 case 0x13: 2484 if (immh3) 2485 return new Unknown64(machInst); 2486 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb); 2487 if (u) 2488 return decodeNeonUTwoShiftUSReg<UqrshrnScX>( 2489 size, machInst, vd, vn, shiftAmt); 2490 else 2491 return decodeNeonSTwoShiftUSReg<SqrshrnScX>( 2492 size, machInst, vd, vn, shiftAmt); 2493 case 0x1c: 2494 if (immh < 0x4) 2495 return new Unknown64(machInst); 2496 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb); 2497 if (u) { 2498 return decodeNeonUTwoShiftUFpReg<UcvtfFixedScX>( 2499 size & 0x1, machInst, vd, vn, shiftAmt); 2500 } else { 2501 if (size & 0x1) 2502 return new ScvtfFixedScDX<uint64_t>(machInst, vd, vn, 2503 shiftAmt); 2504 else 2505 return new ScvtfFixedScSX<uint32_t>(machInst, vd, vn, 2506 shiftAmt); 2507 } 2508 case 0x1f: 2509 if (immh < 0x4) 2510 return new Unknown64(machInst); 2511 shiftAmt = (8 << (size + 1)) - ((immh << 3) | immb); 2512 if (u) 2513 return decodeNeonUTwoShiftUFpReg<FcvtzuFixedScX>( 2514 size & 0x1, machInst, vd, vn, shiftAmt); 2515 else 2516 return decodeNeonUTwoShiftUFpReg<FcvtzsFixedScX>( 2517 size & 0x1, machInst, vd, vn, shiftAmt); 2518 default: 2519 return new Unknown64(machInst); 2520 } 2521 } 2522 2523 StaticInstPtr 2524 decodeNeonMem(ExtMachInst machInst) 2525 { 2526 uint8_t dataSize = bits(machInst, 30) ? 128 : 64; 2527 bool multiple = bits(machInst, 24, 23) < 0x2; 2528 bool load = bits(machInst, 22); 2529 2530 uint8_t numStructElems = 0; 2531 uint8_t numRegs = 0; 2532 2533 if (multiple) { // AdvSIMD load/store multiple structures 2534 uint8_t opcode = bits(machInst, 15, 12); 2535 uint8_t eSize = bits(machInst, 11, 10); 2536 bool wb = !(bits(machInst, 20, 16) == 0x0 && !bits(machInst, 23)); 2537 2538 switch (opcode) { 2539 case 0x0: // LD/ST4 (4 regs) 2540 numStructElems = 4; 2541 numRegs = 4; 2542 break; 2543 case 0x2: // LD/ST1 (4 regs) 2544 numStructElems = 1; 2545 numRegs = 4; 2546 break; 2547 case 0x4: // LD/ST3 (3 regs) 2548 numStructElems = 3; 2549 numRegs = 3; 2550 break; 2551 case 0x6: // LD/ST1 (3 regs) 2552 numStructElems = 1; 2553 numRegs = 3; 2554 break; 2555 case 0x7: // LD/ST1 (1 reg) 2556 numStructElems = 1; 2557 numRegs = 1; 2558 break; 2559 case 0x8: // LD/ST2 (2 regs) 2560 numStructElems = 2; 2561 numRegs = 2; 2562 break; 2563 case 0xa: // LD/ST1 (2 regs) 2564 numStructElems = 1; 2565 numRegs = 2; 2566 break; 2567 default: 2568 return new Unknown64(machInst); 2569 } 2570 2571 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0); 2572 IntRegIndex rn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5); 2573 IntRegIndex rm = (IntRegIndex) (uint8_t) bits(machInst, 20, 16); 2574 2575 if (load) { 2576 return new VldMult64(machInst, rn, vd, rm, eSize, dataSize, 2577 numStructElems, numRegs, wb); 2578 } else { 2579 return new VstMult64(machInst, rn, vd, rm, eSize, dataSize, 2580 numStructElems, numRegs, wb); 2581 } 2582 } else { // AdvSIMD load/store single structure 2583 uint8_t scale = bits(machInst, 15, 14); 2584 uint8_t numStructElems = (((uint8_t) bits(machInst, 13) << 1) | 2585 (uint8_t) bits(machInst, 21)) + 1; 2586 uint8_t index = 0; 2587 bool wb = !(bits(machInst, 20, 16) == 0x0 && !bits(machInst, 23)); 2588 bool replicate = false; 2589 2590 switch (scale) { 2591 case 0x0: 2592 index = ((uint8_t) bits(machInst, 30) << 3) | 2593 ((uint8_t) bits(machInst, 12) << 2) | 2594 (uint8_t) bits(machInst, 11, 10); 2595 break; 2596 case 0x1: 2597 index = ((uint8_t) bits(machInst, 30) << 2) | 2598 ((uint8_t) bits(machInst, 12) << 1) | 2599 (uint8_t) bits(machInst, 11); 2600 break; 2601 case 0x2: 2602 if (bits(machInst, 10) == 0x0) { 2603 index = ((uint8_t) bits(machInst, 30) << 1) | 2604 bits(machInst, 12); 2605 } else { 2606 index = (uint8_t) bits(machInst, 30); 2607 scale = 0x3; 2608 } 2609 break; 2610 case 0x3: 2611 scale = bits(machInst, 11, 10); 2612 replicate = true; 2613 break; 2614 default: 2615 return new Unknown64(machInst); 2616 } 2617 2618 uint8_t eSize = scale; 2619 2620 IntRegIndex vd = (IntRegIndex) (uint8_t) bits(machInst, 4, 0); 2621 IntRegIndex rn = (IntRegIndex) (uint8_t) bits(machInst, 9, 5); 2622 IntRegIndex rm = (IntRegIndex) (uint8_t) bits(machInst, 20, 16); 2623 2624 if (load) { 2625 return new VldSingle64(machInst, rn, vd, rm, eSize, dataSize, 2626 numStructElems, index, wb, replicate); 2627 } else { 2628 return new VstSingle64(machInst, rn, vd, rm, eSize, dataSize, 2629 numStructElems, index, wb, replicate); 2630 } 2631 } 2632 } 2633} 2634}}; 2635