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
| 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>
|
43 StaticInstPtr decodeNeon3Same(ExtMachInst machInst); 44 // AdvSIMD three different
| 44 StaticInstPtr decodeNeon3Same(ExtMachInst machInst); 45 // AdvSIMD three different
|
45 StaticInstPtr decodeNeon3Diff(ExtMachInst machInst);
| 46 inline StaticInstPtr decodeNeon3Diff(ExtMachInst machInst);
|
46 // AdvSIMD two-reg misc
| 47 // AdvSIMD two-reg misc
|
47 StaticInstPtr decodeNeon2RegMisc(ExtMachInst machInst);
| 48 inline StaticInstPtr decodeNeon2RegMisc(ExtMachInst machInst);
|
48 // AdvSIMD across lanes
| 49 // AdvSIMD across lanes
|
49 StaticInstPtr decodeNeonAcrossLanes(ExtMachInst machInst);
| 50 inline StaticInstPtr decodeNeonAcrossLanes(ExtMachInst machInst);
|
50 // AdvSIMD copy
| 51 // AdvSIMD copy
|
51 StaticInstPtr decodeNeonCopy(ExtMachInst machInst);
| 52 inline StaticInstPtr decodeNeonCopy(ExtMachInst machInst);
|
52 // AdvSIMD vector x indexed element
| 53 // AdvSIMD vector x indexed element
|
| 54 template <typename DecoderFeatures>
|
53 StaticInstPtr decodeNeonIndexedElem(ExtMachInst machInst); 54 // AdvSIMD modified immediate
| 55 StaticInstPtr decodeNeonIndexedElem(ExtMachInst machInst); 56 // AdvSIMD modified immediate
|
55 StaticInstPtr decodeNeonModImm(ExtMachInst machInst);
| 57 inline StaticInstPtr decodeNeonModImm(ExtMachInst machInst);
|
56 // AdvSIMD shift by immediate
| 58 // AdvSIMD shift by immediate
|
57 StaticInstPtr decodeNeonShiftByImm(ExtMachInst machInst);
| 59 inline StaticInstPtr decodeNeonShiftByImm(ExtMachInst machInst);
|
58 // AdvSIMD TBL/TBX
| 60 // AdvSIMD TBL/TBX
|
59 StaticInstPtr decodeNeonTblTbx(ExtMachInst machInst);
| 61 inline StaticInstPtr decodeNeonTblTbx(ExtMachInst machInst);
|
60 // AdvSIMD ZIP/UZP/TRN
| 62 // AdvSIMD ZIP/UZP/TRN
|
61 StaticInstPtr decodeNeonZipUzpTrn(ExtMachInst machInst);
| 63 inline StaticInstPtr decodeNeonZipUzpTrn(ExtMachInst machInst);
|
62 // AdvSIMD EXT
| 64 // AdvSIMD EXT
|
63 StaticInstPtr decodeNeonExt(ExtMachInst machInst);
| 65 inline StaticInstPtr decodeNeonExt(ExtMachInst machInst);
|
64 65 // AdvSIMD scalar three same
| 66 67 // AdvSIMD scalar three same
|
66 StaticInstPtr decodeNeonSc3Same(ExtMachInst machInst);
| 68 inline StaticInstPtr decodeNeonSc3Same(ExtMachInst machInst);
|
67 // AdvSIMD scalar three different
| 69 // AdvSIMD scalar three different
|
68 StaticInstPtr decodeNeonSc3Diff(ExtMachInst machInst);
| 70 inline StaticInstPtr decodeNeonSc3Diff(ExtMachInst machInst);
|
69 // AdvSIMD scalar two-reg misc
| 71 // AdvSIMD scalar two-reg misc
|
70 StaticInstPtr decodeNeonSc2RegMisc(ExtMachInst machInst);
| 72 inline StaticInstPtr decodeNeonSc2RegMisc(ExtMachInst machInst);
|
71 // AdvSIMD scalar pairwise
| 73 // AdvSIMD scalar pairwise
|
72 StaticInstPtr decodeNeonScPwise(ExtMachInst machInst);
| 74 inline StaticInstPtr decodeNeonScPwise(ExtMachInst machInst);
|
73 // AdvSIMD scalar copy
| 75 // AdvSIMD scalar copy
|
74 StaticInstPtr decodeNeonScCopy(ExtMachInst machInst);
| 76 inline StaticInstPtr decodeNeonScCopy(ExtMachInst machInst);
|
75 // AdvSIMD scalar x indexed element
| 77 // AdvSIMD scalar x indexed element
|
76 StaticInstPtr decodeNeonScIndexedElem(ExtMachInst machInst);
| 78 inline StaticInstPtr decodeNeonScIndexedElem(ExtMachInst machInst);
|
77 // AdvSIMD scalar shift by immediate
| 79 // AdvSIMD scalar shift by immediate
|
78 StaticInstPtr decodeNeonScShiftByImm(ExtMachInst machInst);
| 80 inline StaticInstPtr decodeNeonScShiftByImm(ExtMachInst machInst);
|
79 80 // AdvSIMD load/store
| 81 82 // AdvSIMD load/store
|
81 StaticInstPtr decodeNeonMem(ExtMachInst machInst);
| 83 inline StaticInstPtr decodeNeonMem(ExtMachInst machInst);
|
82} 83}}; 84 85output decoder {{ 86namespace Aarch64 87{
| 84} 85}}; 86 87output decoder {{ 88namespace Aarch64 89{
|
| 90 template <typename DecoderFeatures>
|
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
| 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>
|
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}};
| 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}};
|