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