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