1// -*- mode:c++ -*- 2 3// Copyright (c) 2010-2011, 2016-2018 ARM Limited 4// All rights reserved 5// 6// The license below extends only to copyright in the software and shall 7// not be construed as granting a license to any other intellectual 8// property including but not limited to intellectual property relating 9// to a hardware implementation of the functionality of the software 10// licensed hereunder. You may use the software subject to the license 11// terms below provided that you ensure that this notice is replicated 12// unmodified and in its entirety in all distributions of the software, 13// modified or unmodified, in source code or in binary form. 14// 15// Copyright (c) 2007-2008 The Florida State University 16// All rights reserved. 17// 18// Redistribution and use in source and binary forms, with or without 19// modification, are permitted provided that the following conditions are 20// met: redistributions of source code must retain the above copyright 21// notice, this list of conditions and the following disclaimer; 22// redistributions in binary form must reproduce the above copyright 23// notice, this list of conditions and the following disclaimer in the 24// documentation and/or other materials provided with the distribution; 25// neither the name of the copyright holders nor the names of its 26// contributors may be used to endorse or promote products derived from 27// this software without specific prior written permission. 28// 29// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 30// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 31// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 32// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 33// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 34// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 35// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 36// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 37// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 39// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40// 41// Authors: Stephen Hines 42 43//////////////////////////////////////////////////////////////////// 44// 45// Floating Point operate instructions 46// 47 48output header {{ 49 50 template<template <typename T> class Base> 51 StaticInstPtr 52 newNeonMemInst(const unsigned size, 53 const ExtMachInst &machInst, 54 const RegIndex dest, const RegIndex ra, 55 const uint32_t imm, const unsigned extraMemFlags) 56 { 57 switch (size) { 58 case 0: 59 return new Base<uint8_t>(machInst, dest, ra, imm, extraMemFlags); 60 case 1: 61 return new Base<uint16_t>(machInst, dest, ra, imm, extraMemFlags); 62 case 2: 63 return new Base<uint32_t>(machInst, dest, ra, imm, extraMemFlags); 64 case 3: 65 return new Base<uint64_t>(machInst, dest, ra, imm, extraMemFlags); 66 default: 67 panic("Unrecognized width %d for Neon mem inst.\n", (1 << size)); 68 } 69 } 70 71 template<template <typename T> class Base> 72 StaticInstPtr 73 newNeonMixInst(const unsigned size, 74 const ExtMachInst &machInst, 75 const RegIndex dest, const RegIndex op1, 76 const uint32_t step) 77 { 78 switch (size) { 79 case 0: 80 return new Base<uint8_t>(machInst, dest, op1, step); 81 case 1: 82 return new Base<uint16_t>(machInst, dest, op1, step); 83 case 2: 84 return new Base<uint32_t>(machInst, dest, op1, step); 85 case 3: 86 return new Base<uint64_t>(machInst, dest, op1, step); 87 default: 88 panic("Unrecognized width %d for Neon mem inst.\n", (1 << size)); 89 } 90 } 91 92}}; 93 94let {{ 95 header_output = ''' 96 StaticInstPtr 97 decodeNeonMem(ExtMachInst machInst); 98 99 StaticInstPtr 100 decodeNeonData(ExtMachInst machInst); 101 ''' 102 103 decoder_output = ''' 104 StaticInstPtr 105 decodeNeonMem(ExtMachInst machInst) 106 { 107 const uint32_t b = bits(machInst, 11, 8); 108 const bool single = bits(machInst, 23); 109 const bool singleAll = single && (bits(b, 3, 2) == 3); 110 const bool load = bits(machInst, 21); 111 112 unsigned width = 0; 113 114 if (single) { 115 width = bits(b, 1, 0) + 1; 116 } else { 117 switch (bits(b, 3, 1)) { 118 case 0x0: width = 4; 119 break; 120 case 0x1: width = (b & 0x1) ? 2 : 1; 121 break; 122 case 0x2: width = 3; 123 break; 124 case 0x3: width = 1; 125 break; 126 case 0x4: width = 2; 127 break; 128 case 0x5: 129 if ((b & 0x1) == 0) { 130 width = 1; 131 break; 132 } 133 M5_FALLTHROUGH; 134 default: 135 return new Unknown(machInst); 136 } 137 } 138 assert(width > 0 && width <= 4); 139 140 const RegIndex rm = (RegIndex)(uint32_t)bits(machInst, 3, 0); 141 const RegIndex rn = (RegIndex)(uint32_t)bits(machInst, 19, 16); 142 const RegIndex vd = (RegIndex)(uint32_t)(bits(machInst, 15, 12) | 143 bits(machInst, 22) << 4); 144 const uint32_t type = bits(machInst, 11, 8); 145 uint32_t size = 0; 146 uint32_t align = TLB::MustBeOne; 147 unsigned inc = 1; 148 unsigned regs = 1; 149 unsigned lane = 0; 150 if (single) { 151 if (singleAll) { 152 size = bits(machInst, 7, 6); 153 bool t = bits(machInst, 5); 154 align = size | TLB::AllowUnaligned; 155 if (width == 1) { 156 regs = t ? 2 : 1; 157 inc = 1; 158 } else { 159 regs = width; 160 inc = t ? 2 : 1; 161 } 162 switch (width) { 163 case 1: 164 case 2: 165 if (bits(machInst, 4)) 166 align = size + width - 1; 167 break; 168 case 3: 169 break; 170 case 4: 171 if (size == 3) { 172 if (bits(machInst, 4) == 0) 173 return new Unknown(machInst); 174 size = 2; 175 align = 0x4; 176 } else if (size == 2) { 177 if (bits(machInst, 4)) 178 align = 0x3; 179 } else { 180 if (bits(machInst, 4)) 181 align = size + 2; 182 } 183 break; 184 } 185 } else { 186 size = bits(machInst, 11, 10); 187 align = size | TLB::AllowUnaligned; 188 regs = width; 189 unsigned indexAlign = bits(machInst, 7, 4); 190 // If width is 1, inc is always 1. That's overridden later. 191 switch (size) { 192 case 0: 193 inc = 1; 194 lane = bits(indexAlign, 3, 1); 195 break; 196 case 1: 197 inc = bits(indexAlign, 1) ? 2 : 1; 198 lane = bits(indexAlign, 3, 2); 199 break; 200 case 2: 201 inc = bits(indexAlign, 2) ? 2 : 1; 202 lane = bits(indexAlign, 3); 203 break; 204 } 205 // Override inc for width of 1. 206 if (width == 1) { 207 inc = 1; 208 } 209 switch (width) { 210 case 1: 211 switch (size) { 212 case 0: 213 break; 214 case 1: 215 if (bits(indexAlign, 0)) 216 align = 1; 217 break; 218 case 2: 219 if (bits(indexAlign, 1, 0)) 220 align = 2; 221 break; 222 } 223 break; 224 case 2: 225 if (bits(indexAlign, 0)) 226 align = size + 1; 227 break; 228 case 3: 229 break; 230 case 4: 231 switch (size) { 232 case 0: 233 case 1: 234 if (bits(indexAlign, 0)) 235 align = size + 2; 236 break; 237 case 2: 238 if (bits(indexAlign, 0)) 239 align = bits(indexAlign, 1, 0) + 2; 240 break; 241 } 242 break; 243 } 244 } 245 if (size == 0x3) { 246 return new Unknown(machInst); 247 } 248 } else { 249 size = bits(machInst, 7, 6); 250 align = bits(machInst, 5, 4); 251 if (align == 0) { 252 // @align wasn't specified, so alignment can be turned off. 253 align = size | TLB::AllowUnaligned; 254 } else { 255 align = align + 2; 256 } 257 switch (width) { 258 case 1: 259 switch (type) { 260 case 0x7: regs = 1; 261 break; 262 case 0xa: regs = 2; 263 break; 264 case 0x6: regs = 3; 265 break; 266 case 0x2: regs = 4; 267 break; 268 default: 269 return new Unknown(machInst); 270 } 271 break; 272 case 2: 273 // Regs doesn't behave exactly as it does in the manual 274 // because they loop over regs registers twice and we break 275 // it down in the macroop. 276 switch (type) { 277 case 0x8: regs = 2; inc = 1; 278 break; 279 case 0x9: regs = 2; inc = 2; 280 break; 281 case 0x3: regs = 4; inc = 2; 282 break; 283 default: 284 return new Unknown(machInst); 285 } 286 break; 287 case 3: 288 regs = 3; 289 switch (type) { 290 case 0x4: inc = 1; 291 break; 292 case 0x5: inc = 2;; 293 break; 294 default: 295 return new Unknown(machInst); 296 } 297 break; 298 case 4: 299 regs = 4; 300 switch (type) { 301 case 0: inc = 1; 302 break; 303 case 1: inc = 2; 304 break; 305 default: 306 return new Unknown(machInst); 307 } 308 break; 309 } 310 } 311 312 if (load) { 313 // Load instructions. 314 if (single) { 315 return new VldSingle(machInst, singleAll, width, rn, vd, 316 regs, inc, size, align, rm, lane); 317 } else { 318 return new VldMult(machInst, width, rn, vd, 319 regs, inc, size, align, rm); 320 } 321 } else { 322 // Store instructions. 323 if (single) { 324 if (singleAll) { 325 return new Unknown(machInst); 326 } else { 327 return new VstSingle(machInst, false, width, rn, vd, 328 regs, inc, size, align, rm, lane); 329 } 330 } else { 331 return new VstMult(machInst, width, rn, vd, 332 regs, inc, size, align, rm); 333 } 334 } 335 return new Unknown(machInst); 336 } 337 ''' 338 339 decoder_output += ''' 340 static StaticInstPtr 341 decodeNeonThreeRegistersSameLength(ExtMachInst machInst) 342 { 343 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 344 const uint32_t a = bits(machInst, 11, 8); 345 const bool b = bits(machInst, 4); 346 const uint32_t c = bits(machInst, 21, 20); 347 const IntRegIndex vd = 348 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 349 (bits(machInst, 22) << 4))); 350 const IntRegIndex vn = 351 (IntRegIndex)(2 * (bits(machInst, 19, 16) | 352 (bits(machInst, 7) << 4))); 353 const IntRegIndex vm = 354 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 355 (bits(machInst, 5) << 4))); 356 const unsigned size = bits(machInst, 21, 20); 357 const bool q = bits(machInst, 6); 358 if (q && ((vd & 0x1) || (vn & 0x1) || (vm & 0x1))) 359 return new Unknown(machInst); 360 switch (a) { 361 case 0x0: 362 if (b) { 363 if (u) { 364 return decodeNeonUThreeReg<VqaddUD, VqaddUQ>( 365 q, size, machInst, vd, vn, vm); 366 } else { 367 return decodeNeonSThreeReg<VqaddSD, VqaddSQ>( 368 q, size, machInst, vd, vn, vm); 369 } 370 } else { 371 if (size == 3) 372 return new Unknown(machInst); 373 return decodeNeonUSThreeReg<VhaddD, VhaddQ>( 374 q, u, size, machInst, vd, vn, vm); 375 } 376 case 0x1: 377 if (!b) { 378 return decodeNeonUSThreeReg<VrhaddD, VrhaddQ>( 379 q, u, size, machInst, vd, vn, vm); 380 } else { 381 if (u) { 382 switch (c) { 383 case 0: 384 if (q) { 385 return new VeorQ<uint64_t>(machInst, vd, vn, vm); 386 } else { 387 return new VeorD<uint64_t>(machInst, vd, vn, vm); 388 } 389 case 1: 390 if (q) { 391 return new VbslQ<uint64_t>(machInst, vd, vn, vm); 392 } else { 393 return new VbslD<uint64_t>(machInst, vd, vn, vm); 394 } 395 case 2: 396 if (q) { 397 return new VbitQ<uint64_t>(machInst, vd, vn, vm); 398 } else { 399 return new VbitD<uint64_t>(machInst, vd, vn, vm); 400 } 401 case 3: 402 if (q) { 403 return new VbifQ<uint64_t>(machInst, vd, vn, vm); 404 } else { 405 return new VbifD<uint64_t>(machInst, vd, vn, vm); 406 } 407 default: 408 M5_UNREACHABLE; 409 } 410 } else { 411 switch (c) { 412 case 0: 413 if (q) { 414 return new VandQ<uint64_t>(machInst, vd, vn, vm); 415 } else { 416 return new VandD<uint64_t>(machInst, vd, vn, vm); 417 } 418 case 1: 419 if (q) { 420 return new VbicQ<uint64_t>(machInst, vd, vn, vm); 421 } else { 422 return new VbicD<uint64_t>(machInst, vd, vn, vm); 423 } 424 case 2: 425 if (vn == vm) { 426 if (q) { 427 return new VmovQ<uint64_t>( 428 machInst, vd, vn, vm); 429 } else { 430 return new VmovD<uint64_t>( 431 machInst, vd, vn, vm); 432 } 433 } else { 434 if (q) { 435 return new VorrQ<uint64_t>( 436 machInst, vd, vn, vm); 437 } else { 438 return new VorrD<uint64_t>( 439 machInst, vd, vn, vm); 440 } 441 } 442 case 3: 443 if (q) { 444 return new VornQ<uint64_t>( 445 machInst, vd, vn, vm); 446 } else { 447 return new VornD<uint64_t>( 448 machInst, vd, vn, vm); 449 } 450 default: 451 M5_UNREACHABLE; 452 } 453 } 454 } 455 case 0x2: 456 if (b) { 457 if (u) { 458 return decodeNeonUThreeReg<VqsubUD, VqsubUQ>( 459 q, size, machInst, vd, vn, vm); 460 } else { 461 return decodeNeonSThreeReg<VqsubSD, VqsubSQ>( 462 q, size, machInst, vd, vn, vm); 463 } 464 } else { 465 if (size == 3) 466 return new Unknown(machInst); 467 return decodeNeonUSThreeReg<VhsubD, VhsubQ>( 468 q, u, size, machInst, vd, vn, vm); 469 } 470 case 0x3: 471 if (b) { 472 return decodeNeonUSThreeReg<VcgeD, VcgeQ>( 473 q, u, size, machInst, vd, vn, vm); 474 } else { 475 return decodeNeonUSThreeReg<VcgtD, VcgtQ>( 476 q, u, size, machInst, vd, vn, vm); 477 } 478 case 0x4: 479 if (b) { 480 if (u) { 481 return decodeNeonUThreeReg<VqshlUD, VqshlUQ>( 482 q, size, machInst, vd, vm, vn); 483 } else { 484 return decodeNeonSThreeReg<VqshlSD, VqshlSQ>( 485 q, size, machInst, vd, vm, vn); 486 } 487 } else { 488 return decodeNeonUSThreeReg<VshlD, VshlQ>( 489 q, u, size, machInst, vd, vm, vn); 490 } 491 case 0x5: 492 if (b) { 493 if (u) { 494 return decodeNeonUThreeReg<VqrshlUD, VqrshlUQ>( 495 q, size, machInst, vd, vm, vn); 496 } else { 497 return decodeNeonSThreeReg<VqrshlSD, VqrshlSQ>( 498 q, size, machInst, vd, vm, vn); 499 } 500 } else { 501 return decodeNeonUSThreeReg<VrshlD, VrshlQ>( 502 q, u, size, machInst, vd, vm, vn); 503 } 504 case 0x6: 505 if (b) { 506 return decodeNeonUSThreeReg<VminD, VminQ>( 507 q, u, size, machInst, vd, vn, vm); 508 } else { 509 return decodeNeonUSThreeReg<VmaxD, VmaxQ>( 510 q, u, size, machInst, vd, vn, vm); 511 } 512 case 0x7: 513 if (b) { 514 return decodeNeonUSThreeReg<VabaD, VabaQ>( 515 q, u, size, machInst, vd, vn, vm); 516 } else { 517 if (bits(machInst, 23) == 1) { 518 if (q) { 519 return new Unknown(machInst); 520 } else { 521 return decodeNeonUSThreeUSReg<Vabdl>( 522 u, size, machInst, vd, vn, vm); 523 } 524 } else { 525 return decodeNeonUSThreeReg<VabdD, VabdQ>( 526 q, u, size, machInst, vd, vn, vm); 527 } 528 } 529 case 0x8: 530 if (b) { 531 if (u) { 532 return decodeNeonUThreeReg<VceqD, VceqQ>( 533 q, size, machInst, vd, vn, vm); 534 } else { 535 return decodeNeonUThreeReg<VtstD, VtstQ>( 536 q, size, machInst, vd, vn, vm); 537 } 538 } else { 539 if (u) { 540 return decodeNeonUThreeReg<NVsubD, NVsubQ>( 541 q, size, machInst, vd, vn, vm); 542 } else { 543 return decodeNeonUThreeReg<NVaddD, NVaddQ>( 544 q, size, machInst, vd, vn, vm); 545 } 546 } 547 case 0x9: 548 if (b) { 549 if (u) { 550 return decodeNeonUThreeReg<NVmulpD, NVmulpQ>( 551 q, size, machInst, vd, vn, vm); 552 } else { 553 return decodeNeonSThreeReg<NVmulD, NVmulQ>( 554 q, size, machInst, vd, vn, vm); 555 } 556 } else { 557 if (u) { 558 return decodeNeonUSThreeReg<NVmlsD, NVmlsQ>( 559 q, u, size, machInst, vd, vn, vm); 560 } else { 561 return decodeNeonUSThreeReg<NVmlaD, NVmlaQ>( 562 q, u, size, machInst, vd, vn, vm); 563 } 564 } 565 case 0xa: 566 if (q) 567 return new Unknown(machInst); 568 if (b) { 569 return decodeNeonUSThreeUSReg<VpminD>( 570 u, size, machInst, vd, vn, vm); 571 } else { 572 return decodeNeonUSThreeUSReg<VpmaxD>( 573 u, size, machInst, vd, vn, vm); 574 } 575 case 0xb: 576 if (b) { 577 if (u || q) { 578 return new Unknown(machInst); 579 } else { 580 return decodeNeonUThreeUSReg<NVpaddD>( 581 size, machInst, vd, vn, vm); 582 } 583 } else { 584 if (u) { 585 return decodeNeonSThreeSReg<VqrdmulhD, VqrdmulhQ>( 586 q, size, machInst, vd, vn, vm); 587 } else { 588 return decodeNeonSThreeSReg<VqdmulhD, VqdmulhQ>( 589 q, size, machInst, vd, vn, vm); 590 } 591 } 592 case 0xc: 593 if (b) { 594 if (!u) { 595 if (bits(c, 1) == 0) { 596 if (q) { 597 return new NVfmaQFp<float>(machInst, vd, vn, vm); 598 } else { 599 return new NVfmaDFp<float>(machInst, vd, vn, vm); 600 } 601 } else { 602 if (q) { 603 return new NVfmsQFp<float>(machInst, vd, vn, vm); 604 } else { 605 return new NVfmsDFp<float>(machInst, vd, vn, vm); 606 } 607 } 608 }
| 1// -*- mode:c++ -*- 2 3// Copyright (c) 2010-2011, 2016-2018 ARM Limited 4// All rights reserved 5// 6// The license below extends only to copyright in the software and shall 7// not be construed as granting a license to any other intellectual 8// property including but not limited to intellectual property relating 9// to a hardware implementation of the functionality of the software 10// licensed hereunder. You may use the software subject to the license 11// terms below provided that you ensure that this notice is replicated 12// unmodified and in its entirety in all distributions of the software, 13// modified or unmodified, in source code or in binary form. 14// 15// Copyright (c) 2007-2008 The Florida State University 16// All rights reserved. 17// 18// Redistribution and use in source and binary forms, with or without 19// modification, are permitted provided that the following conditions are 20// met: redistributions of source code must retain the above copyright 21// notice, this list of conditions and the following disclaimer; 22// redistributions in binary form must reproduce the above copyright 23// notice, this list of conditions and the following disclaimer in the 24// documentation and/or other materials provided with the distribution; 25// neither the name of the copyright holders nor the names of its 26// contributors may be used to endorse or promote products derived from 27// this software without specific prior written permission. 28// 29// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 30// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 31// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 32// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 33// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 34// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 35// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 36// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 37// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 39// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40// 41// Authors: Stephen Hines 42 43//////////////////////////////////////////////////////////////////// 44// 45// Floating Point operate instructions 46// 47 48output header {{ 49 50 template<template <typename T> class Base> 51 StaticInstPtr 52 newNeonMemInst(const unsigned size, 53 const ExtMachInst &machInst, 54 const RegIndex dest, const RegIndex ra, 55 const uint32_t imm, const unsigned extraMemFlags) 56 { 57 switch (size) { 58 case 0: 59 return new Base<uint8_t>(machInst, dest, ra, imm, extraMemFlags); 60 case 1: 61 return new Base<uint16_t>(machInst, dest, ra, imm, extraMemFlags); 62 case 2: 63 return new Base<uint32_t>(machInst, dest, ra, imm, extraMemFlags); 64 case 3: 65 return new Base<uint64_t>(machInst, dest, ra, imm, extraMemFlags); 66 default: 67 panic("Unrecognized width %d for Neon mem inst.\n", (1 << size)); 68 } 69 } 70 71 template<template <typename T> class Base> 72 StaticInstPtr 73 newNeonMixInst(const unsigned size, 74 const ExtMachInst &machInst, 75 const RegIndex dest, const RegIndex op1, 76 const uint32_t step) 77 { 78 switch (size) { 79 case 0: 80 return new Base<uint8_t>(machInst, dest, op1, step); 81 case 1: 82 return new Base<uint16_t>(machInst, dest, op1, step); 83 case 2: 84 return new Base<uint32_t>(machInst, dest, op1, step); 85 case 3: 86 return new Base<uint64_t>(machInst, dest, op1, step); 87 default: 88 panic("Unrecognized width %d for Neon mem inst.\n", (1 << size)); 89 } 90 } 91 92}}; 93 94let {{ 95 header_output = ''' 96 StaticInstPtr 97 decodeNeonMem(ExtMachInst machInst); 98 99 StaticInstPtr 100 decodeNeonData(ExtMachInst machInst); 101 ''' 102 103 decoder_output = ''' 104 StaticInstPtr 105 decodeNeonMem(ExtMachInst machInst) 106 { 107 const uint32_t b = bits(machInst, 11, 8); 108 const bool single = bits(machInst, 23); 109 const bool singleAll = single && (bits(b, 3, 2) == 3); 110 const bool load = bits(machInst, 21); 111 112 unsigned width = 0; 113 114 if (single) { 115 width = bits(b, 1, 0) + 1; 116 } else { 117 switch (bits(b, 3, 1)) { 118 case 0x0: width = 4; 119 break; 120 case 0x1: width = (b & 0x1) ? 2 : 1; 121 break; 122 case 0x2: width = 3; 123 break; 124 case 0x3: width = 1; 125 break; 126 case 0x4: width = 2; 127 break; 128 case 0x5: 129 if ((b & 0x1) == 0) { 130 width = 1; 131 break; 132 } 133 M5_FALLTHROUGH; 134 default: 135 return new Unknown(machInst); 136 } 137 } 138 assert(width > 0 && width <= 4); 139 140 const RegIndex rm = (RegIndex)(uint32_t)bits(machInst, 3, 0); 141 const RegIndex rn = (RegIndex)(uint32_t)bits(machInst, 19, 16); 142 const RegIndex vd = (RegIndex)(uint32_t)(bits(machInst, 15, 12) | 143 bits(machInst, 22) << 4); 144 const uint32_t type = bits(machInst, 11, 8); 145 uint32_t size = 0; 146 uint32_t align = TLB::MustBeOne; 147 unsigned inc = 1; 148 unsigned regs = 1; 149 unsigned lane = 0; 150 if (single) { 151 if (singleAll) { 152 size = bits(machInst, 7, 6); 153 bool t = bits(machInst, 5); 154 align = size | TLB::AllowUnaligned; 155 if (width == 1) { 156 regs = t ? 2 : 1; 157 inc = 1; 158 } else { 159 regs = width; 160 inc = t ? 2 : 1; 161 } 162 switch (width) { 163 case 1: 164 case 2: 165 if (bits(machInst, 4)) 166 align = size + width - 1; 167 break; 168 case 3: 169 break; 170 case 4: 171 if (size == 3) { 172 if (bits(machInst, 4) == 0) 173 return new Unknown(machInst); 174 size = 2; 175 align = 0x4; 176 } else if (size == 2) { 177 if (bits(machInst, 4)) 178 align = 0x3; 179 } else { 180 if (bits(machInst, 4)) 181 align = size + 2; 182 } 183 break; 184 } 185 } else { 186 size = bits(machInst, 11, 10); 187 align = size | TLB::AllowUnaligned; 188 regs = width; 189 unsigned indexAlign = bits(machInst, 7, 4); 190 // If width is 1, inc is always 1. That's overridden later. 191 switch (size) { 192 case 0: 193 inc = 1; 194 lane = bits(indexAlign, 3, 1); 195 break; 196 case 1: 197 inc = bits(indexAlign, 1) ? 2 : 1; 198 lane = bits(indexAlign, 3, 2); 199 break; 200 case 2: 201 inc = bits(indexAlign, 2) ? 2 : 1; 202 lane = bits(indexAlign, 3); 203 break; 204 } 205 // Override inc for width of 1. 206 if (width == 1) { 207 inc = 1; 208 } 209 switch (width) { 210 case 1: 211 switch (size) { 212 case 0: 213 break; 214 case 1: 215 if (bits(indexAlign, 0)) 216 align = 1; 217 break; 218 case 2: 219 if (bits(indexAlign, 1, 0)) 220 align = 2; 221 break; 222 } 223 break; 224 case 2: 225 if (bits(indexAlign, 0)) 226 align = size + 1; 227 break; 228 case 3: 229 break; 230 case 4: 231 switch (size) { 232 case 0: 233 case 1: 234 if (bits(indexAlign, 0)) 235 align = size + 2; 236 break; 237 case 2: 238 if (bits(indexAlign, 0)) 239 align = bits(indexAlign, 1, 0) + 2; 240 break; 241 } 242 break; 243 } 244 } 245 if (size == 0x3) { 246 return new Unknown(machInst); 247 } 248 } else { 249 size = bits(machInst, 7, 6); 250 align = bits(machInst, 5, 4); 251 if (align == 0) { 252 // @align wasn't specified, so alignment can be turned off. 253 align = size | TLB::AllowUnaligned; 254 } else { 255 align = align + 2; 256 } 257 switch (width) { 258 case 1: 259 switch (type) { 260 case 0x7: regs = 1; 261 break; 262 case 0xa: regs = 2; 263 break; 264 case 0x6: regs = 3; 265 break; 266 case 0x2: regs = 4; 267 break; 268 default: 269 return new Unknown(machInst); 270 } 271 break; 272 case 2: 273 // Regs doesn't behave exactly as it does in the manual 274 // because they loop over regs registers twice and we break 275 // it down in the macroop. 276 switch (type) { 277 case 0x8: regs = 2; inc = 1; 278 break; 279 case 0x9: regs = 2; inc = 2; 280 break; 281 case 0x3: regs = 4; inc = 2; 282 break; 283 default: 284 return new Unknown(machInst); 285 } 286 break; 287 case 3: 288 regs = 3; 289 switch (type) { 290 case 0x4: inc = 1; 291 break; 292 case 0x5: inc = 2;; 293 break; 294 default: 295 return new Unknown(machInst); 296 } 297 break; 298 case 4: 299 regs = 4; 300 switch (type) { 301 case 0: inc = 1; 302 break; 303 case 1: inc = 2; 304 break; 305 default: 306 return new Unknown(machInst); 307 } 308 break; 309 } 310 } 311 312 if (load) { 313 // Load instructions. 314 if (single) { 315 return new VldSingle(machInst, singleAll, width, rn, vd, 316 regs, inc, size, align, rm, lane); 317 } else { 318 return new VldMult(machInst, width, rn, vd, 319 regs, inc, size, align, rm); 320 } 321 } else { 322 // Store instructions. 323 if (single) { 324 if (singleAll) { 325 return new Unknown(machInst); 326 } else { 327 return new VstSingle(machInst, false, width, rn, vd, 328 regs, inc, size, align, rm, lane); 329 } 330 } else { 331 return new VstMult(machInst, width, rn, vd, 332 regs, inc, size, align, rm); 333 } 334 } 335 return new Unknown(machInst); 336 } 337 ''' 338 339 decoder_output += ''' 340 static StaticInstPtr 341 decodeNeonThreeRegistersSameLength(ExtMachInst machInst) 342 { 343 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 344 const uint32_t a = bits(machInst, 11, 8); 345 const bool b = bits(machInst, 4); 346 const uint32_t c = bits(machInst, 21, 20); 347 const IntRegIndex vd = 348 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 349 (bits(machInst, 22) << 4))); 350 const IntRegIndex vn = 351 (IntRegIndex)(2 * (bits(machInst, 19, 16) | 352 (bits(machInst, 7) << 4))); 353 const IntRegIndex vm = 354 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 355 (bits(machInst, 5) << 4))); 356 const unsigned size = bits(machInst, 21, 20); 357 const bool q = bits(machInst, 6); 358 if (q && ((vd & 0x1) || (vn & 0x1) || (vm & 0x1))) 359 return new Unknown(machInst); 360 switch (a) { 361 case 0x0: 362 if (b) { 363 if (u) { 364 return decodeNeonUThreeReg<VqaddUD, VqaddUQ>( 365 q, size, machInst, vd, vn, vm); 366 } else { 367 return decodeNeonSThreeReg<VqaddSD, VqaddSQ>( 368 q, size, machInst, vd, vn, vm); 369 } 370 } else { 371 if (size == 3) 372 return new Unknown(machInst); 373 return decodeNeonUSThreeReg<VhaddD, VhaddQ>( 374 q, u, size, machInst, vd, vn, vm); 375 } 376 case 0x1: 377 if (!b) { 378 return decodeNeonUSThreeReg<VrhaddD, VrhaddQ>( 379 q, u, size, machInst, vd, vn, vm); 380 } else { 381 if (u) { 382 switch (c) { 383 case 0: 384 if (q) { 385 return new VeorQ<uint64_t>(machInst, vd, vn, vm); 386 } else { 387 return new VeorD<uint64_t>(machInst, vd, vn, vm); 388 } 389 case 1: 390 if (q) { 391 return new VbslQ<uint64_t>(machInst, vd, vn, vm); 392 } else { 393 return new VbslD<uint64_t>(machInst, vd, vn, vm); 394 } 395 case 2: 396 if (q) { 397 return new VbitQ<uint64_t>(machInst, vd, vn, vm); 398 } else { 399 return new VbitD<uint64_t>(machInst, vd, vn, vm); 400 } 401 case 3: 402 if (q) { 403 return new VbifQ<uint64_t>(machInst, vd, vn, vm); 404 } else { 405 return new VbifD<uint64_t>(machInst, vd, vn, vm); 406 } 407 default: 408 M5_UNREACHABLE; 409 } 410 } else { 411 switch (c) { 412 case 0: 413 if (q) { 414 return new VandQ<uint64_t>(machInst, vd, vn, vm); 415 } else { 416 return new VandD<uint64_t>(machInst, vd, vn, vm); 417 } 418 case 1: 419 if (q) { 420 return new VbicQ<uint64_t>(machInst, vd, vn, vm); 421 } else { 422 return new VbicD<uint64_t>(machInst, vd, vn, vm); 423 } 424 case 2: 425 if (vn == vm) { 426 if (q) { 427 return new VmovQ<uint64_t>( 428 machInst, vd, vn, vm); 429 } else { 430 return new VmovD<uint64_t>( 431 machInst, vd, vn, vm); 432 } 433 } else { 434 if (q) { 435 return new VorrQ<uint64_t>( 436 machInst, vd, vn, vm); 437 } else { 438 return new VorrD<uint64_t>( 439 machInst, vd, vn, vm); 440 } 441 } 442 case 3: 443 if (q) { 444 return new VornQ<uint64_t>( 445 machInst, vd, vn, vm); 446 } else { 447 return new VornD<uint64_t>( 448 machInst, vd, vn, vm); 449 } 450 default: 451 M5_UNREACHABLE; 452 } 453 } 454 } 455 case 0x2: 456 if (b) { 457 if (u) { 458 return decodeNeonUThreeReg<VqsubUD, VqsubUQ>( 459 q, size, machInst, vd, vn, vm); 460 } else { 461 return decodeNeonSThreeReg<VqsubSD, VqsubSQ>( 462 q, size, machInst, vd, vn, vm); 463 } 464 } else { 465 if (size == 3) 466 return new Unknown(machInst); 467 return decodeNeonUSThreeReg<VhsubD, VhsubQ>( 468 q, u, size, machInst, vd, vn, vm); 469 } 470 case 0x3: 471 if (b) { 472 return decodeNeonUSThreeReg<VcgeD, VcgeQ>( 473 q, u, size, machInst, vd, vn, vm); 474 } else { 475 return decodeNeonUSThreeReg<VcgtD, VcgtQ>( 476 q, u, size, machInst, vd, vn, vm); 477 } 478 case 0x4: 479 if (b) { 480 if (u) { 481 return decodeNeonUThreeReg<VqshlUD, VqshlUQ>( 482 q, size, machInst, vd, vm, vn); 483 } else { 484 return decodeNeonSThreeReg<VqshlSD, VqshlSQ>( 485 q, size, machInst, vd, vm, vn); 486 } 487 } else { 488 return decodeNeonUSThreeReg<VshlD, VshlQ>( 489 q, u, size, machInst, vd, vm, vn); 490 } 491 case 0x5: 492 if (b) { 493 if (u) { 494 return decodeNeonUThreeReg<VqrshlUD, VqrshlUQ>( 495 q, size, machInst, vd, vm, vn); 496 } else { 497 return decodeNeonSThreeReg<VqrshlSD, VqrshlSQ>( 498 q, size, machInst, vd, vm, vn); 499 } 500 } else { 501 return decodeNeonUSThreeReg<VrshlD, VrshlQ>( 502 q, u, size, machInst, vd, vm, vn); 503 } 504 case 0x6: 505 if (b) { 506 return decodeNeonUSThreeReg<VminD, VminQ>( 507 q, u, size, machInst, vd, vn, vm); 508 } else { 509 return decodeNeonUSThreeReg<VmaxD, VmaxQ>( 510 q, u, size, machInst, vd, vn, vm); 511 } 512 case 0x7: 513 if (b) { 514 return decodeNeonUSThreeReg<VabaD, VabaQ>( 515 q, u, size, machInst, vd, vn, vm); 516 } else { 517 if (bits(machInst, 23) == 1) { 518 if (q) { 519 return new Unknown(machInst); 520 } else { 521 return decodeNeonUSThreeUSReg<Vabdl>( 522 u, size, machInst, vd, vn, vm); 523 } 524 } else { 525 return decodeNeonUSThreeReg<VabdD, VabdQ>( 526 q, u, size, machInst, vd, vn, vm); 527 } 528 } 529 case 0x8: 530 if (b) { 531 if (u) { 532 return decodeNeonUThreeReg<VceqD, VceqQ>( 533 q, size, machInst, vd, vn, vm); 534 } else { 535 return decodeNeonUThreeReg<VtstD, VtstQ>( 536 q, size, machInst, vd, vn, vm); 537 } 538 } else { 539 if (u) { 540 return decodeNeonUThreeReg<NVsubD, NVsubQ>( 541 q, size, machInst, vd, vn, vm); 542 } else { 543 return decodeNeonUThreeReg<NVaddD, NVaddQ>( 544 q, size, machInst, vd, vn, vm); 545 } 546 } 547 case 0x9: 548 if (b) { 549 if (u) { 550 return decodeNeonUThreeReg<NVmulpD, NVmulpQ>( 551 q, size, machInst, vd, vn, vm); 552 } else { 553 return decodeNeonSThreeReg<NVmulD, NVmulQ>( 554 q, size, machInst, vd, vn, vm); 555 } 556 } else { 557 if (u) { 558 return decodeNeonUSThreeReg<NVmlsD, NVmlsQ>( 559 q, u, size, machInst, vd, vn, vm); 560 } else { 561 return decodeNeonUSThreeReg<NVmlaD, NVmlaQ>( 562 q, u, size, machInst, vd, vn, vm); 563 } 564 } 565 case 0xa: 566 if (q) 567 return new Unknown(machInst); 568 if (b) { 569 return decodeNeonUSThreeUSReg<VpminD>( 570 u, size, machInst, vd, vn, vm); 571 } else { 572 return decodeNeonUSThreeUSReg<VpmaxD>( 573 u, size, machInst, vd, vn, vm); 574 } 575 case 0xb: 576 if (b) { 577 if (u || q) { 578 return new Unknown(machInst); 579 } else { 580 return decodeNeonUThreeUSReg<NVpaddD>( 581 size, machInst, vd, vn, vm); 582 } 583 } else { 584 if (u) { 585 return decodeNeonSThreeSReg<VqrdmulhD, VqrdmulhQ>( 586 q, size, machInst, vd, vn, vm); 587 } else { 588 return decodeNeonSThreeSReg<VqdmulhD, VqdmulhQ>( 589 q, size, machInst, vd, vn, vm); 590 } 591 } 592 case 0xc: 593 if (b) { 594 if (!u) { 595 if (bits(c, 1) == 0) { 596 if (q) { 597 return new NVfmaQFp<float>(machInst, vd, vn, vm); 598 } else { 599 return new NVfmaDFp<float>(machInst, vd, vn, vm); 600 } 601 } else { 602 if (q) { 603 return new NVfmsQFp<float>(machInst, vd, vn, vm); 604 } else { 605 return new NVfmsDFp<float>(machInst, vd, vn, vm); 606 } 607 } 608 }
|
| 609 } else { 610 if (u) { 611 switch (c) { 612 case 0x0: 613 return new SHA256H(machInst, vd, vn, vm); 614 case 0x1: 615 return new SHA256H2(machInst, vd, vn, vm); 616 case 0x2: 617 return new SHA256SU1(machInst, vd, vn, vm); 618 case 0x3: 619 return new Unknown(machInst); 620 default: 621 M5_UNREACHABLE; 622 } 623 } else { 624 switch (c) { 625 case 0x0: 626 return new SHA1C(machInst, vd, vn, vm); 627 case 0x1: 628 return new SHA1P(machInst, vd, vn, vm); 629 case 0x2: 630 return new SHA1M(machInst, vd, vn, vm); 631 case 0x3: 632 return new SHA1SU0(machInst, vd, vn, vm); 633 default: 634 M5_UNREACHABLE; 635 } 636 }
|
609 } 610 return new Unknown(machInst); 611 case 0xd: 612 if (b) { 613 if (u) { 614 if (bits(c, 1) == 0) { 615 if (q) { 616 return new NVmulQFp<float>(machInst, vd, vn, vm); 617 } else { 618 return new NVmulDFp<float>(machInst, vd, vn, vm); 619 } 620 } else { 621 return new Unknown(machInst); 622 } 623 } else { 624 if (bits(c, 1) == 0) { 625 if (q) { 626 return new NVmlaQFp<float>(machInst, vd, vn, vm); 627 } else { 628 return new NVmlaDFp<float>(machInst, vd, vn, vm); 629 } 630 } else { 631 if (q) { 632 return new NVmlsQFp<float>(machInst, vd, vn, vm); 633 } else { 634 return new NVmlsDFp<float>(machInst, vd, vn, vm); 635 } 636 } 637 } 638 } else { 639 if (u) { 640 if (bits(c, 1) == 0) { 641 if (q) { 642 return new VpaddQFp<float>(machInst, vd, vn, vm); 643 } else { 644 return new VpaddDFp<float>(machInst, vd, vn, vm); 645 } 646 } else { 647 if (q) { 648 return new VabdQFp<float>(machInst, vd, vn, vm); 649 } else { 650 return new VabdDFp<float>(machInst, vd, vn, vm); 651 } 652 } 653 } else { 654 if (bits(c, 1) == 0) { 655 if (q) { 656 return new VaddQFp<float>(machInst, vd, vn, vm); 657 } else { 658 return new VaddDFp<float>(machInst, vd, vn, vm); 659 } 660 } else { 661 if (q) { 662 return new VsubQFp<float>(machInst, vd, vn, vm); 663 } else { 664 return new VsubDFp<float>(machInst, vd, vn, vm); 665 } 666 } 667 } 668 } 669 case 0xe: 670 if (b) { 671 if (u) { 672 if (bits(c, 1) == 0) { 673 if (q) { 674 return new VacgeQFp<float>(machInst, vd, vn, vm); 675 } else { 676 return new VacgeDFp<float>(machInst, vd, vn, vm); 677 } 678 } else { 679 if (q) { 680 return new VacgtQFp<float>(machInst, vd, vn, vm); 681 } else { 682 return new VacgtDFp<float>(machInst, vd, vn, vm); 683 } 684 } 685 } else { 686 return new Unknown(machInst); 687 } 688 } else { 689 if (u) { 690 if (bits(c, 1) == 0) { 691 if (q) { 692 return new VcgeQFp<float>(machInst, vd, vn, vm); 693 } else { 694 return new VcgeDFp<float>(machInst, vd, vn, vm); 695 } 696 } else { 697 if (q) { 698 return new VcgtQFp<float>(machInst, vd, vn, vm); 699 } else { 700 return new VcgtDFp<float>(machInst, vd, vn, vm); 701 } 702 } 703 } else { 704 if (bits(c, 1) == 0) { 705 if (q) { 706 return new VceqQFp<float>(machInst, vd, vn, vm); 707 } else { 708 return new VceqDFp<float>(machInst, vd, vn, vm); 709 } 710 } else { 711 return new Unknown(machInst); 712 } 713 } 714 } 715 case 0xf: 716 if (b) { 717 if (u) { 718 return new Unknown(machInst); 719 } else { 720 if (bits(c, 1) == 0) { 721 if (q) { 722 return new VrecpsQFp<float>(machInst, vd, vn, vm); 723 } else { 724 return new VrecpsDFp<float>(machInst, vd, vn, vm); 725 } 726 } else { 727 if (q) { 728 return new VrsqrtsQFp<float>(machInst, vd, vn, vm); 729 } else { 730 return new VrsqrtsDFp<float>(machInst, vd, vn, vm); 731 } 732 } 733 } 734 } else { 735 if (u) { 736 if (bits(c, 1) == 0) { 737 if (q) { 738 return new VpmaxQFp<float>(machInst, vd, vn, vm); 739 } else { 740 return new VpmaxDFp<float>(machInst, vd, vn, vm); 741 } 742 } else { 743 if (q) { 744 return new VpminQFp<float>(machInst, vd, vn, vm); 745 } else { 746 return new VpminDFp<float>(machInst, vd, vn, vm); 747 } 748 } 749 } else { 750 if (bits(c, 1) == 0) { 751 if (q) { 752 return new VmaxQFp<float>(machInst, vd, vn, vm); 753 } else { 754 return new VmaxDFp<float>(machInst, vd, vn, vm); 755 } 756 } else { 757 if (q) { 758 return new VminQFp<float>(machInst, vd, vn, vm); 759 } else { 760 return new VminDFp<float>(machInst, vd, vn, vm); 761 } 762 } 763 } 764 } 765 } 766 return new Unknown(machInst); 767 } 768 769 static StaticInstPtr 770 decodeNeonOneRegModImm(ExtMachInst machInst) 771 { 772 const IntRegIndex vd = 773 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 774 (bits(machInst, 22) << 4))); 775 const bool q = bits(machInst, 6); 776 const bool op = bits(machInst, 5); 777 const uint8_t cmode = bits(machInst, 11, 8); 778 const uint8_t imm = ((THUMB ? bits(machInst, 28) : 779 bits(machInst, 24)) << 7) | 780 (bits(machInst, 18, 16) << 4) | 781 (bits(machInst, 3, 0) << 0); 782 783 // Check for invalid immediate encodings and return an unknown op 784 // if it happens 785 bool immValid = true; 786 const uint64_t bigImm = simd_modified_imm(op, cmode, imm, immValid); 787 if (!immValid) { 788 return new Unknown(machInst); 789 } 790 791 if (op) { 792 if (bits(cmode, 3) == 0) { 793 if (bits(cmode, 0) == 0) { 794 if (q) 795 return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 796 else 797 return new NVmvniD<uint64_t>(machInst, vd, bigImm); 798 } else { 799 if (q) 800 return new NVbiciQ<uint64_t>(machInst, vd, bigImm); 801 else 802 return new NVbiciD<uint64_t>(machInst, vd, bigImm); 803 } 804 } else { 805 if (bits(cmode, 2) == 1) { 806 switch (bits(cmode, 1, 0)) { 807 case 0: 808 case 1: 809 if (q) 810 return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 811 else 812 return new NVmvniD<uint64_t>(machInst, vd, bigImm); 813 case 2: 814 if (q) 815 return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 816 else 817 return new NVmoviD<uint64_t>(machInst, vd, bigImm); 818 case 3: 819 if (q) 820 return new Unknown(machInst); 821 else 822 return new Unknown(machInst); 823 } 824 } else { 825 if (bits(cmode, 0) == 0) { 826 if (q) 827 return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 828 else 829 return new NVmvniD<uint64_t>(machInst, vd, bigImm); 830 } else { 831 if (q) 832 return new NVbiciQ<uint64_t>(machInst, vd, bigImm); 833 else 834 return new NVbiciD<uint64_t>(machInst, vd, bigImm); 835 } 836 } 837 } 838 } else { 839 if (bits(cmode, 3) == 0) { 840 if (bits(cmode, 0) == 0) { 841 if (q) 842 return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 843 else 844 return new NVmoviD<uint64_t>(machInst, vd, bigImm); 845 } else { 846 if (q) 847 return new NVorriQ<uint64_t>(machInst, vd, bigImm); 848 else 849 return new NVorriD<uint64_t>(machInst, vd, bigImm); 850 } 851 } else { 852 if (bits(cmode, 2) == 1) { 853 if (q) 854 return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 855 else 856 return new NVmoviD<uint64_t>(machInst, vd, bigImm); 857 } else { 858 if (bits(cmode, 0) == 0) { 859 if (q) 860 return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 861 else 862 return new NVmoviD<uint64_t>(machInst, vd, bigImm); 863 } else { 864 if (q) 865 return new NVorriQ<uint64_t>(machInst, vd, bigImm); 866 else 867 return new NVorriD<uint64_t>(machInst, vd, bigImm); 868 } 869 } 870 } 871 } 872 return new Unknown(machInst); 873 } 874 875 static StaticInstPtr 876 decodeNeonTwoRegAndShift(ExtMachInst machInst) 877 { 878 const uint32_t a = bits(machInst, 11, 8); 879 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 880 const bool b = bits(machInst, 6); 881 const bool l = bits(machInst, 7); 882 const IntRegIndex vd = 883 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 884 (bits(machInst, 22) << 4))); 885 const IntRegIndex vm = 886 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 887 (bits(machInst, 5) << 4))); 888 unsigned imm6 = bits(machInst, 21, 16); 889 unsigned imm = ((l ? 1 : 0) << 6) | imm6; 890 unsigned size = 3; 891 unsigned lShiftAmt = 0; 892 unsigned bitSel; 893 for (bitSel = 1 << 6; true; bitSel >>= 1) { 894 if (bitSel & imm) 895 break; 896 else if (!size) 897 return new Unknown(machInst); 898 size--; 899 } 900 lShiftAmt = imm6 & ~bitSel; 901 unsigned rShiftAmt = 0; 902 if (a != 0xe && a != 0xf) { 903 if (size > 2) 904 rShiftAmt = 64 - imm6; 905 else 906 rShiftAmt = 2 * (8 << size) - imm6; 907 } 908 909 switch (a) { 910 case 0x0: 911 return decodeNeonUSTwoShiftReg<NVshrD, NVshrQ>( 912 b, u, size, machInst, vd, vm, rShiftAmt); 913 case 0x1: 914 return decodeNeonUSTwoShiftReg<NVsraD, NVsraQ>( 915 b, u, size, machInst, vd, vm, rShiftAmt); 916 case 0x2: 917 return decodeNeonUSTwoShiftReg<NVrshrD, NVrshrQ>( 918 b, u, size, machInst, vd, vm, rShiftAmt); 919 case 0x3: 920 return decodeNeonUSTwoShiftReg<NVrsraD, NVrsraQ>( 921 b, u, size, machInst, vd, vm, rShiftAmt); 922 case 0x4: 923 if (u) { 924 return decodeNeonUTwoShiftReg<NVsriD, NVsriQ>( 925 b, size, machInst, vd, vm, rShiftAmt); 926 } else { 927 return new Unknown(machInst); 928 } 929 case 0x5: 930 if (u) { 931 return decodeNeonUTwoShiftReg<NVsliD, NVsliQ>( 932 b, size, machInst, vd, vm, lShiftAmt); 933 } else { 934 return decodeNeonUTwoShiftReg<NVshlD, NVshlQ>( 935 b, size, machInst, vd, vm, lShiftAmt); 936 } 937 case 0x6: 938 case 0x7: 939 if (u) { 940 if (a == 0x6) { 941 return decodeNeonSTwoShiftReg<NVqshlusD, NVqshlusQ>( 942 b, size, machInst, vd, vm, lShiftAmt); 943 } else { 944 return decodeNeonUTwoShiftReg<NVqshluD, NVqshluQ>( 945 b, size, machInst, vd, vm, lShiftAmt); 946 } 947 } else { 948 return decodeNeonSTwoShiftReg<NVqshlD, NVqshlQ>( 949 b, size, machInst, vd, vm, lShiftAmt); 950 } 951 case 0x8: 952 if (l) { 953 return new Unknown(machInst); 954 } else if (u) { 955 return decodeNeonSTwoShiftSReg<NVqshruns, NVqrshruns>( 956 b, size, machInst, vd, vm, rShiftAmt); 957 } else { 958 return decodeNeonUTwoShiftSReg<NVshrn, NVrshrn>( 959 b, size, machInst, vd, vm, rShiftAmt); 960 } 961 case 0x9: 962 if (l) { 963 return new Unknown(machInst); 964 } else if (u) { 965 return decodeNeonUTwoShiftSReg<NVqshrun, NVqrshrun>( 966 b, size, machInst, vd, vm, rShiftAmt); 967 } else { 968 return decodeNeonSTwoShiftSReg<NVqshrn, NVqrshrn>( 969 b, size, machInst, vd, vm, rShiftAmt); 970 } 971 case 0xa: 972 if (l || b) { 973 return new Unknown(machInst); 974 } else { 975 return decodeNeonUSTwoShiftSReg<NVmovl, NVshll>( 976 lShiftAmt, u, size, machInst, vd, vm, lShiftAmt); 977 } 978 case 0xe: 979 if (l) { 980 return new Unknown(machInst); 981 } else { 982 if (bits(imm6, 5) == 0) 983 return new Unknown(machInst); 984 if (u) { 985 if (b) { 986 return new NVcvtu2fpQ<float>( 987 machInst, vd, vm, 64 - imm6); 988 } else { 989 return new NVcvtu2fpD<float>( 990 machInst, vd, vm, 64 - imm6); 991 } 992 } else { 993 if (b) { 994 return new NVcvts2fpQ<float>( 995 machInst, vd, vm, 64 - imm6); 996 } else { 997 return new NVcvts2fpD<float>( 998 machInst, vd, vm, 64 - imm6); 999 } 1000 } 1001 } 1002 case 0xf: 1003 if (l) { 1004 return new Unknown(machInst); 1005 } else { 1006 if (bits(imm6, 5) == 0) 1007 return new Unknown(machInst); 1008 if (u) { 1009 if (b) { 1010 return new NVcvt2ufxQ<float>( 1011 machInst, vd, vm, 64 - imm6); 1012 } else { 1013 return new NVcvt2ufxD<float>( 1014 machInst, vd, vm, 64 - imm6); 1015 } 1016 } else { 1017 if (b) { 1018 return new NVcvt2sfxQ<float>( 1019 machInst, vd, vm, 64 - imm6); 1020 } else { 1021 return new NVcvt2sfxD<float>( 1022 machInst, vd, vm, 64 - imm6); 1023 } 1024 } 1025 } 1026 } 1027 return new Unknown(machInst); 1028 } 1029 1030 static StaticInstPtr 1031 decodeNeonThreeRegDiffLengths(ExtMachInst machInst) 1032 { 1033 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 1034 const uint32_t a = bits(machInst, 11, 8); 1035 const IntRegIndex vd = 1036 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1037 (bits(machInst, 22) << 4))); 1038 const IntRegIndex vn = 1039 (IntRegIndex)(2 * (bits(machInst, 19, 16) | 1040 (bits(machInst, 7) << 4))); 1041 const IntRegIndex vm = 1042 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 1043 (bits(machInst, 5) << 4))); 1044 const unsigned size = bits(machInst, 21, 20); 1045 switch (a) { 1046 case 0x0: 1047 return decodeNeonUSThreeUSReg<Vaddl>( 1048 u, size, machInst, vd, vn, vm); 1049 case 0x1: 1050 return decodeNeonUSThreeUSReg<Vaddw>( 1051 u, size, machInst, vd, vn, vm); 1052 case 0x2: 1053 return decodeNeonUSThreeUSReg<Vsubl>( 1054 u, size, machInst, vd, vn, vm); 1055 case 0x3: 1056 return decodeNeonUSThreeUSReg<Vsubw>( 1057 u, size, machInst, vd, vn, vm); 1058 case 0x4: 1059 if (u) { 1060 return decodeNeonUThreeUSReg<Vraddhn>( 1061 size, machInst, vd, vn, vm); 1062 } else { 1063 return decodeNeonUThreeUSReg<Vaddhn>( 1064 size, machInst, vd, vn, vm); 1065 } 1066 case 0x5: 1067 return decodeNeonUSThreeUSReg<Vabal>( 1068 u, size, machInst, vd, vn, vm); 1069 case 0x6: 1070 if (u) { 1071 return decodeNeonUThreeUSReg<Vrsubhn>( 1072 size, machInst, vd, vn, vm); 1073 } else { 1074 return decodeNeonUThreeUSReg<Vsubhn>( 1075 size, machInst, vd, vn, vm); 1076 } 1077 case 0x7: 1078 if (bits(machInst, 23)) { 1079 return decodeNeonUSThreeUSReg<Vabdl>( 1080 u, size, machInst, vd, vn, vm); 1081 } else { 1082 return decodeNeonUSThreeReg<VabdD, VabdQ>( 1083 bits(machInst, 6), u, size, machInst, vd, vn, vm); 1084 } 1085 case 0x8: 1086 return decodeNeonUSThreeUSReg<Vmlal>( 1087 u, size, machInst, vd, vn, vm); 1088 case 0xa: 1089 return decodeNeonUSThreeUSReg<Vmlsl>( 1090 u, size, machInst, vd, vn, vm); 1091 case 0x9: 1092 if (u) { 1093 return new Unknown(machInst); 1094 } else { 1095 return decodeNeonSThreeUSReg<Vqdmlal>( 1096 size, machInst, vd, vn, vm); 1097 } 1098 case 0xb: 1099 if (u) { 1100 return new Unknown(machInst); 1101 } else { 1102 return decodeNeonSThreeUSReg<Vqdmlsl>( 1103 size, machInst, vd, vn, vm); 1104 } 1105 case 0xc: 1106 return decodeNeonUSThreeUSReg<Vmull>( 1107 u, size, machInst, vd, vn, vm); 1108 case 0xd: 1109 if (u) { 1110 return new Unknown(machInst); 1111 } else { 1112 return decodeNeonSThreeUSReg<Vqdmull>( 1113 size, machInst, vd, vn, vm); 1114 } 1115 case 0xe: 1116 return decodeNeonUThreeUSReg<Vmullp>( 1117 size, machInst, vd, vn, vm); 1118 } 1119 return new Unknown(machInst); 1120 } 1121 1122 static StaticInstPtr 1123 decodeNeonTwoRegScalar(ExtMachInst machInst) 1124 { 1125 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 1126 const uint32_t a = bits(machInst, 11, 8); 1127 const unsigned size = bits(machInst, 21, 20); 1128 const IntRegIndex vd = 1129 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1130 (bits(machInst, 22) << 4))); 1131 const IntRegIndex vn = 1132 (IntRegIndex)(2 * (bits(machInst, 19, 16) | 1133 (bits(machInst, 7) << 4))); 1134 const IntRegIndex vm = (size == 2) ? 1135 (IntRegIndex)(2 * bits(machInst, 3, 0)) : 1136 (IntRegIndex)(2 * bits(machInst, 2, 0)); 1137 const unsigned index = (size == 2) ? (unsigned)bits(machInst, 5) : 1138 (bits(machInst, 3) | (bits(machInst, 5) << 1)); 1139 switch (a) { 1140 case 0x0: 1141 if (u) { 1142 switch (size) { 1143 case 1: 1144 return new VmlasQ<uint16_t>(machInst, vd, vn, vm, index); 1145 case 2: 1146 return new VmlasQ<uint32_t>(machInst, vd, vn, vm, index); 1147 default: 1148 return new Unknown(machInst); 1149 } 1150 } else { 1151 switch (size) { 1152 case 1: 1153 return new VmlasD<uint16_t>(machInst, vd, vn, vm, index); 1154 case 2: 1155 return new VmlasD<uint32_t>(machInst, vd, vn, vm, index); 1156 default: 1157 return new Unknown(machInst); 1158 } 1159 } 1160 case 0x1: 1161 if (u) 1162 return new VmlasQFp<float>(machInst, vd, vn, vm, index); 1163 else 1164 return new VmlasDFp<float>(machInst, vd, vn, vm, index); 1165 case 0x4: 1166 if (u) { 1167 switch (size) { 1168 case 1: 1169 return new VmlssQ<uint16_t>(machInst, vd, vn, vm, index); 1170 case 2: 1171 return new VmlssQ<uint32_t>(machInst, vd, vn, vm, index); 1172 default: 1173 return new Unknown(machInst); 1174 } 1175 } else { 1176 switch (size) { 1177 case 1: 1178 return new VmlssD<uint16_t>(machInst, vd, vn, vm, index); 1179 case 2: 1180 return new VmlssD<uint32_t>(machInst, vd, vn, vm, index); 1181 default: 1182 return new Unknown(machInst); 1183 } 1184 } 1185 case 0x5: 1186 if (u) 1187 return new VmlssQFp<float>(machInst, vd, vn, vm, index); 1188 else 1189 return new VmlssDFp<float>(machInst, vd, vn, vm, index); 1190 case 0x2: 1191 if (u) { 1192 switch (size) { 1193 case 1: 1194 return new Vmlals<uint16_t>(machInst, vd, vn, vm, index); 1195 case 2: 1196 return new Vmlals<uint32_t>(machInst, vd, vn, vm, index); 1197 default: 1198 return new Unknown(machInst); 1199 } 1200 } else { 1201 switch (size) { 1202 case 1: 1203 return new Vmlals<int16_t>(machInst, vd, vn, vm, index); 1204 case 2: 1205 return new Vmlals<int32_t>(machInst, vd, vn, vm, index); 1206 default: 1207 return new Unknown(machInst); 1208 } 1209 } 1210 case 0x6: 1211 if (u) { 1212 switch (size) { 1213 case 1: 1214 return new Vmlsls<uint16_t>(machInst, vd, vn, vm, index); 1215 case 2: 1216 return new Vmlsls<uint32_t>(machInst, vd, vn, vm, index); 1217 default: 1218 return new Unknown(machInst); 1219 } 1220 } else { 1221 switch (size) { 1222 case 1: 1223 return new Vmlsls<int16_t>(machInst, vd, vn, vm, index); 1224 case 2: 1225 return new Vmlsls<int32_t>(machInst, vd, vn, vm, index); 1226 default: 1227 return new Unknown(machInst); 1228 } 1229 } 1230 case 0x3: 1231 if (u) { 1232 return new Unknown(machInst); 1233 } else { 1234 switch (size) { 1235 case 1: 1236 return new Vqdmlals<int16_t>(machInst, vd, vn, vm, index); 1237 case 2: 1238 return new Vqdmlals<int32_t>(machInst, vd, vn, vm, index); 1239 default: 1240 return new Unknown(machInst); 1241 } 1242 } 1243 case 0x7: 1244 if (u) { 1245 return new Unknown(machInst); 1246 } else { 1247 switch (size) { 1248 case 1: 1249 return new Vqdmlsls<int16_t>(machInst, vd, vn, vm, index); 1250 case 2: 1251 return new Vqdmlsls<int32_t>(machInst, vd, vn, vm, index); 1252 default: 1253 return new Unknown(machInst); 1254 } 1255 } 1256 case 0x8: 1257 if (u) { 1258 switch (size) { 1259 case 1: 1260 return new VmulsQ<uint16_t>(machInst, vd, vn, vm, index); 1261 case 2: 1262 return new VmulsQ<uint32_t>(machInst, vd, vn, vm, index); 1263 default: 1264 return new Unknown(machInst); 1265 } 1266 } else { 1267 switch (size) { 1268 case 1: 1269 return new VmulsD<uint16_t>(machInst, vd, vn, vm, index); 1270 case 2: 1271 return new VmulsD<uint32_t>(machInst, vd, vn, vm, index); 1272 default: 1273 return new Unknown(machInst); 1274 } 1275 } 1276 case 0x9: 1277 if (u) 1278 return new VmulsQFp<float>(machInst, vd, vn, vm, index); 1279 else 1280 return new VmulsDFp<float>(machInst, vd, vn, vm, index); 1281 case 0xa: 1282 if (u) { 1283 switch (size) { 1284 case 1: 1285 return new Vmulls<uint16_t>(machInst, vd, vn, vm, index); 1286 case 2: 1287 return new Vmulls<uint32_t>(machInst, vd, vn, vm, index); 1288 default: 1289 return new Unknown(machInst); 1290 } 1291 } else { 1292 switch (size) { 1293 case 1: 1294 return new Vmulls<int16_t>(machInst, vd, vn, vm, index); 1295 case 2: 1296 return new Vmulls<int32_t>(machInst, vd, vn, vm, index); 1297 default: 1298 return new Unknown(machInst); 1299 } 1300 } 1301 case 0xb: 1302 if (u) { 1303 return new Unknown(machInst); 1304 } else { 1305 if (u) { 1306 switch (size) { 1307 case 1: 1308 return new Vqdmulls<uint16_t>( 1309 machInst, vd, vn, vm, index); 1310 case 2: 1311 return new Vqdmulls<uint32_t>( 1312 machInst, vd, vn, vm, index); 1313 default: 1314 return new Unknown(machInst); 1315 } 1316 } else { 1317 switch (size) { 1318 case 1: 1319 return new Vqdmulls<int16_t>( 1320 machInst, vd, vn, vm, index); 1321 case 2: 1322 return new Vqdmulls<int32_t>( 1323 machInst, vd, vn, vm, index); 1324 default: 1325 return new Unknown(machInst); 1326 } 1327 } 1328 } 1329 case 0xc: 1330 if (u) { 1331 switch (size) { 1332 case 1: 1333 return new VqdmulhsQ<int16_t>( 1334 machInst, vd, vn, vm, index); 1335 case 2: 1336 return new VqdmulhsQ<int32_t>( 1337 machInst, vd, vn, vm, index); 1338 default: 1339 return new Unknown(machInst); 1340 } 1341 } else { 1342 switch (size) { 1343 case 1: 1344 return new VqdmulhsD<int16_t>( 1345 machInst, vd, vn, vm, index); 1346 case 2: 1347 return new VqdmulhsD<int32_t>( 1348 machInst, vd, vn, vm, index); 1349 default: 1350 return new Unknown(machInst); 1351 } 1352 } 1353 case 0xd: 1354 if (u) { 1355 switch (size) { 1356 case 1: 1357 return new VqrdmulhsQ<int16_t>( 1358 machInst, vd, vn, vm, index); 1359 case 2: 1360 return new VqrdmulhsQ<int32_t>( 1361 machInst, vd, vn, vm, index); 1362 default: 1363 return new Unknown(machInst); 1364 } 1365 } else { 1366 switch (size) { 1367 case 1: 1368 return new VqrdmulhsD<int16_t>( 1369 machInst, vd, vn, vm, index); 1370 case 2: 1371 return new VqrdmulhsD<int32_t>( 1372 machInst, vd, vn, vm, index); 1373 default: 1374 return new Unknown(machInst); 1375 } 1376 } 1377 } 1378 return new Unknown(machInst); 1379 } 1380 1381 static StaticInstPtr 1382 decodeNeonTwoRegMisc(ExtMachInst machInst) 1383 { 1384 const uint32_t a = bits(machInst, 17, 16); 1385 const uint32_t b = bits(machInst, 10, 6); 1386 const bool q = bits(machInst, 6); 1387 const IntRegIndex vd = 1388 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1389 (bits(machInst, 22) << 4))); 1390 const IntRegIndex vm = 1391 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 1392 (bits(machInst, 5) << 4))); 1393 const unsigned size = bits(machInst, 19, 18); 1394 switch (a) { 1395 case 0x0: 1396 switch (bits(b, 4, 1)) { 1397 case 0x0: 1398 switch (size) { 1399 case 0: 1400 if (q) { 1401 return new NVrev64Q<uint8_t>(machInst, vd, vm); 1402 } else { 1403 return new NVrev64D<uint8_t>(machInst, vd, vm); 1404 } 1405 case 1: 1406 if (q) { 1407 return new NVrev64Q<uint16_t>(machInst, vd, vm); 1408 } else { 1409 return new NVrev64D<uint16_t>(machInst, vd, vm); 1410 } 1411 case 2: 1412 if (q) { 1413 return new NVrev64Q<uint32_t>(machInst, vd, vm); 1414 } else { 1415 return new NVrev64D<uint32_t>(machInst, vd, vm); 1416 } 1417 default: 1418 return new Unknown(machInst); 1419 } 1420 case 0x1: 1421 switch (size) { 1422 case 0: 1423 if (q) { 1424 return new NVrev32Q<uint8_t>(machInst, vd, vm); 1425 } else { 1426 return new NVrev32D<uint8_t>(machInst, vd, vm); 1427 } 1428 case 1: 1429 if (q) { 1430 return new NVrev32Q<uint16_t>(machInst, vd, vm); 1431 } else { 1432 return new NVrev32D<uint16_t>(machInst, vd, vm); 1433 } 1434 default: 1435 return new Unknown(machInst); 1436 } 1437 case 0x2: 1438 if (size != 0) { 1439 return new Unknown(machInst); 1440 } else if (q) { 1441 return new NVrev16Q<uint8_t>(machInst, vd, vm); 1442 } else { 1443 return new NVrev16D<uint8_t>(machInst, vd, vm); 1444 } 1445 case 0x4: 1446 return decodeNeonSTwoMiscSReg<NVpaddlD, NVpaddlQ>( 1447 q, size, machInst, vd, vm); 1448 case 0x5: 1449 return decodeNeonUTwoMiscSReg<NVpaddlD, NVpaddlQ>( 1450 q, size, machInst, vd, vm); 1451 case 0x8: 1452 return decodeNeonSTwoMiscReg<NVclsD, NVclsQ>( 1453 q, size, machInst, vd, vm); 1454 case 0x9: 1455 return decodeNeonSTwoMiscReg<NVclzD, NVclzQ>( 1456 q, size, machInst, vd, vm); 1457 case 0xa: 1458 return decodeNeonUTwoMiscReg<NVcntD, NVcntQ>( 1459 q, size, machInst, vd, vm); 1460 case 0xb: 1461 if (q) 1462 return new NVmvnQ<uint64_t>(machInst, vd, vm); 1463 else 1464 return new NVmvnD<uint64_t>(machInst, vd, vm); 1465 case 0xc: 1466 return decodeNeonSTwoMiscSReg<NVpadalD, NVpadalQ>( 1467 q, size, machInst, vd, vm); 1468 case 0xd: 1469 return decodeNeonUTwoMiscSReg<NVpadalD, NVpadalQ>( 1470 q, size, machInst, vd, vm); 1471 case 0xe: 1472 return decodeNeonSTwoMiscReg<NVqabsD, NVqabsQ>( 1473 q, size, machInst, vd, vm); 1474 case 0xf: 1475 return decodeNeonSTwoMiscReg<NVqnegD, NVqnegQ>( 1476 q, size, machInst, vd, vm); 1477 default: 1478 return new Unknown(machInst); 1479 } 1480 case 0x1: 1481 switch (bits(b, 3, 1)) { 1482 case 0x0: 1483 if (bits(b, 4)) { 1484 if (q) { 1485 return new NVcgtQFp<float>(machInst, vd, vm); 1486 } else { 1487 return new NVcgtDFp<float>(machInst, vd, vm); 1488 } 1489 } else { 1490 return decodeNeonSTwoMiscReg<NVcgtD, NVcgtQ>( 1491 q, size, machInst, vd, vm); 1492 } 1493 case 0x1: 1494 if (bits(b, 4)) { 1495 if (q) { 1496 return new NVcgeQFp<float>(machInst, vd, vm); 1497 } else { 1498 return new NVcgeDFp<float>(machInst, vd, vm); 1499 } 1500 } else { 1501 return decodeNeonSTwoMiscReg<NVcgeD, NVcgeQ>( 1502 q, size, machInst, vd, vm); 1503 } 1504 case 0x2: 1505 if (bits(b, 4)) { 1506 if (q) { 1507 return new NVceqQFp<float>(machInst, vd, vm); 1508 } else { 1509 return new NVceqDFp<float>(machInst, vd, vm); 1510 } 1511 } else { 1512 return decodeNeonSTwoMiscReg<NVceqD, NVceqQ>( 1513 q, size, machInst, vd, vm); 1514 } 1515 case 0x3: 1516 if (bits(b, 4)) { 1517 if (q) { 1518 return new NVcleQFp<float>(machInst, vd, vm); 1519 } else { 1520 return new NVcleDFp<float>(machInst, vd, vm); 1521 } 1522 } else { 1523 return decodeNeonSTwoMiscReg<NVcleD, NVcleQ>( 1524 q, size, machInst, vd, vm); 1525 } 1526 case 0x4: 1527 if (bits(b, 4)) { 1528 if (q) { 1529 return new NVcltQFp<float>(machInst, vd, vm); 1530 } else { 1531 return new NVcltDFp<float>(machInst, vd, vm); 1532 } 1533 } else { 1534 return decodeNeonSTwoMiscReg<NVcltD, NVcltQ>( 1535 q, size, machInst, vd, vm); 1536 }
| 637 } 638 return new Unknown(machInst); 639 case 0xd: 640 if (b) { 641 if (u) { 642 if (bits(c, 1) == 0) { 643 if (q) { 644 return new NVmulQFp<float>(machInst, vd, vn, vm); 645 } else { 646 return new NVmulDFp<float>(machInst, vd, vn, vm); 647 } 648 } else { 649 return new Unknown(machInst); 650 } 651 } else { 652 if (bits(c, 1) == 0) { 653 if (q) { 654 return new NVmlaQFp<float>(machInst, vd, vn, vm); 655 } else { 656 return new NVmlaDFp<float>(machInst, vd, vn, vm); 657 } 658 } else { 659 if (q) { 660 return new NVmlsQFp<float>(machInst, vd, vn, vm); 661 } else { 662 return new NVmlsDFp<float>(machInst, vd, vn, vm); 663 } 664 } 665 } 666 } else { 667 if (u) { 668 if (bits(c, 1) == 0) { 669 if (q) { 670 return new VpaddQFp<float>(machInst, vd, vn, vm); 671 } else { 672 return new VpaddDFp<float>(machInst, vd, vn, vm); 673 } 674 } else { 675 if (q) { 676 return new VabdQFp<float>(machInst, vd, vn, vm); 677 } else { 678 return new VabdDFp<float>(machInst, vd, vn, vm); 679 } 680 } 681 } else { 682 if (bits(c, 1) == 0) { 683 if (q) { 684 return new VaddQFp<float>(machInst, vd, vn, vm); 685 } else { 686 return new VaddDFp<float>(machInst, vd, vn, vm); 687 } 688 } else { 689 if (q) { 690 return new VsubQFp<float>(machInst, vd, vn, vm); 691 } else { 692 return new VsubDFp<float>(machInst, vd, vn, vm); 693 } 694 } 695 } 696 } 697 case 0xe: 698 if (b) { 699 if (u) { 700 if (bits(c, 1) == 0) { 701 if (q) { 702 return new VacgeQFp<float>(machInst, vd, vn, vm); 703 } else { 704 return new VacgeDFp<float>(machInst, vd, vn, vm); 705 } 706 } else { 707 if (q) { 708 return new VacgtQFp<float>(machInst, vd, vn, vm); 709 } else { 710 return new VacgtDFp<float>(machInst, vd, vn, vm); 711 } 712 } 713 } else { 714 return new Unknown(machInst); 715 } 716 } else { 717 if (u) { 718 if (bits(c, 1) == 0) { 719 if (q) { 720 return new VcgeQFp<float>(machInst, vd, vn, vm); 721 } else { 722 return new VcgeDFp<float>(machInst, vd, vn, vm); 723 } 724 } else { 725 if (q) { 726 return new VcgtQFp<float>(machInst, vd, vn, vm); 727 } else { 728 return new VcgtDFp<float>(machInst, vd, vn, vm); 729 } 730 } 731 } else { 732 if (bits(c, 1) == 0) { 733 if (q) { 734 return new VceqQFp<float>(machInst, vd, vn, vm); 735 } else { 736 return new VceqDFp<float>(machInst, vd, vn, vm); 737 } 738 } else { 739 return new Unknown(machInst); 740 } 741 } 742 } 743 case 0xf: 744 if (b) { 745 if (u) { 746 return new Unknown(machInst); 747 } else { 748 if (bits(c, 1) == 0) { 749 if (q) { 750 return new VrecpsQFp<float>(machInst, vd, vn, vm); 751 } else { 752 return new VrecpsDFp<float>(machInst, vd, vn, vm); 753 } 754 } else { 755 if (q) { 756 return new VrsqrtsQFp<float>(machInst, vd, vn, vm); 757 } else { 758 return new VrsqrtsDFp<float>(machInst, vd, vn, vm); 759 } 760 } 761 } 762 } else { 763 if (u) { 764 if (bits(c, 1) == 0) { 765 if (q) { 766 return new VpmaxQFp<float>(machInst, vd, vn, vm); 767 } else { 768 return new VpmaxDFp<float>(machInst, vd, vn, vm); 769 } 770 } else { 771 if (q) { 772 return new VpminQFp<float>(machInst, vd, vn, vm); 773 } else { 774 return new VpminDFp<float>(machInst, vd, vn, vm); 775 } 776 } 777 } else { 778 if (bits(c, 1) == 0) { 779 if (q) { 780 return new VmaxQFp<float>(machInst, vd, vn, vm); 781 } else { 782 return new VmaxDFp<float>(machInst, vd, vn, vm); 783 } 784 } else { 785 if (q) { 786 return new VminQFp<float>(machInst, vd, vn, vm); 787 } else { 788 return new VminDFp<float>(machInst, vd, vn, vm); 789 } 790 } 791 } 792 } 793 } 794 return new Unknown(machInst); 795 } 796 797 static StaticInstPtr 798 decodeNeonOneRegModImm(ExtMachInst machInst) 799 { 800 const IntRegIndex vd = 801 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 802 (bits(machInst, 22) << 4))); 803 const bool q = bits(machInst, 6); 804 const bool op = bits(machInst, 5); 805 const uint8_t cmode = bits(machInst, 11, 8); 806 const uint8_t imm = ((THUMB ? bits(machInst, 28) : 807 bits(machInst, 24)) << 7) | 808 (bits(machInst, 18, 16) << 4) | 809 (bits(machInst, 3, 0) << 0); 810 811 // Check for invalid immediate encodings and return an unknown op 812 // if it happens 813 bool immValid = true; 814 const uint64_t bigImm = simd_modified_imm(op, cmode, imm, immValid); 815 if (!immValid) { 816 return new Unknown(machInst); 817 } 818 819 if (op) { 820 if (bits(cmode, 3) == 0) { 821 if (bits(cmode, 0) == 0) { 822 if (q) 823 return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 824 else 825 return new NVmvniD<uint64_t>(machInst, vd, bigImm); 826 } else { 827 if (q) 828 return new NVbiciQ<uint64_t>(machInst, vd, bigImm); 829 else 830 return new NVbiciD<uint64_t>(machInst, vd, bigImm); 831 } 832 } else { 833 if (bits(cmode, 2) == 1) { 834 switch (bits(cmode, 1, 0)) { 835 case 0: 836 case 1: 837 if (q) 838 return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 839 else 840 return new NVmvniD<uint64_t>(machInst, vd, bigImm); 841 case 2: 842 if (q) 843 return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 844 else 845 return new NVmoviD<uint64_t>(machInst, vd, bigImm); 846 case 3: 847 if (q) 848 return new Unknown(machInst); 849 else 850 return new Unknown(machInst); 851 } 852 } else { 853 if (bits(cmode, 0) == 0) { 854 if (q) 855 return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 856 else 857 return new NVmvniD<uint64_t>(machInst, vd, bigImm); 858 } else { 859 if (q) 860 return new NVbiciQ<uint64_t>(machInst, vd, bigImm); 861 else 862 return new NVbiciD<uint64_t>(machInst, vd, bigImm); 863 } 864 } 865 } 866 } else { 867 if (bits(cmode, 3) == 0) { 868 if (bits(cmode, 0) == 0) { 869 if (q) 870 return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 871 else 872 return new NVmoviD<uint64_t>(machInst, vd, bigImm); 873 } else { 874 if (q) 875 return new NVorriQ<uint64_t>(machInst, vd, bigImm); 876 else 877 return new NVorriD<uint64_t>(machInst, vd, bigImm); 878 } 879 } else { 880 if (bits(cmode, 2) == 1) { 881 if (q) 882 return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 883 else 884 return new NVmoviD<uint64_t>(machInst, vd, bigImm); 885 } else { 886 if (bits(cmode, 0) == 0) { 887 if (q) 888 return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 889 else 890 return new NVmoviD<uint64_t>(machInst, vd, bigImm); 891 } else { 892 if (q) 893 return new NVorriQ<uint64_t>(machInst, vd, bigImm); 894 else 895 return new NVorriD<uint64_t>(machInst, vd, bigImm); 896 } 897 } 898 } 899 } 900 return new Unknown(machInst); 901 } 902 903 static StaticInstPtr 904 decodeNeonTwoRegAndShift(ExtMachInst machInst) 905 { 906 const uint32_t a = bits(machInst, 11, 8); 907 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 908 const bool b = bits(machInst, 6); 909 const bool l = bits(machInst, 7); 910 const IntRegIndex vd = 911 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 912 (bits(machInst, 22) << 4))); 913 const IntRegIndex vm = 914 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 915 (bits(machInst, 5) << 4))); 916 unsigned imm6 = bits(machInst, 21, 16); 917 unsigned imm = ((l ? 1 : 0) << 6) | imm6; 918 unsigned size = 3; 919 unsigned lShiftAmt = 0; 920 unsigned bitSel; 921 for (bitSel = 1 << 6; true; bitSel >>= 1) { 922 if (bitSel & imm) 923 break; 924 else if (!size) 925 return new Unknown(machInst); 926 size--; 927 } 928 lShiftAmt = imm6 & ~bitSel; 929 unsigned rShiftAmt = 0; 930 if (a != 0xe && a != 0xf) { 931 if (size > 2) 932 rShiftAmt = 64 - imm6; 933 else 934 rShiftAmt = 2 * (8 << size) - imm6; 935 } 936 937 switch (a) { 938 case 0x0: 939 return decodeNeonUSTwoShiftReg<NVshrD, NVshrQ>( 940 b, u, size, machInst, vd, vm, rShiftAmt); 941 case 0x1: 942 return decodeNeonUSTwoShiftReg<NVsraD, NVsraQ>( 943 b, u, size, machInst, vd, vm, rShiftAmt); 944 case 0x2: 945 return decodeNeonUSTwoShiftReg<NVrshrD, NVrshrQ>( 946 b, u, size, machInst, vd, vm, rShiftAmt); 947 case 0x3: 948 return decodeNeonUSTwoShiftReg<NVrsraD, NVrsraQ>( 949 b, u, size, machInst, vd, vm, rShiftAmt); 950 case 0x4: 951 if (u) { 952 return decodeNeonUTwoShiftReg<NVsriD, NVsriQ>( 953 b, size, machInst, vd, vm, rShiftAmt); 954 } else { 955 return new Unknown(machInst); 956 } 957 case 0x5: 958 if (u) { 959 return decodeNeonUTwoShiftReg<NVsliD, NVsliQ>( 960 b, size, machInst, vd, vm, lShiftAmt); 961 } else { 962 return decodeNeonUTwoShiftReg<NVshlD, NVshlQ>( 963 b, size, machInst, vd, vm, lShiftAmt); 964 } 965 case 0x6: 966 case 0x7: 967 if (u) { 968 if (a == 0x6) { 969 return decodeNeonSTwoShiftReg<NVqshlusD, NVqshlusQ>( 970 b, size, machInst, vd, vm, lShiftAmt); 971 } else { 972 return decodeNeonUTwoShiftReg<NVqshluD, NVqshluQ>( 973 b, size, machInst, vd, vm, lShiftAmt); 974 } 975 } else { 976 return decodeNeonSTwoShiftReg<NVqshlD, NVqshlQ>( 977 b, size, machInst, vd, vm, lShiftAmt); 978 } 979 case 0x8: 980 if (l) { 981 return new Unknown(machInst); 982 } else if (u) { 983 return decodeNeonSTwoShiftSReg<NVqshruns, NVqrshruns>( 984 b, size, machInst, vd, vm, rShiftAmt); 985 } else { 986 return decodeNeonUTwoShiftSReg<NVshrn, NVrshrn>( 987 b, size, machInst, vd, vm, rShiftAmt); 988 } 989 case 0x9: 990 if (l) { 991 return new Unknown(machInst); 992 } else if (u) { 993 return decodeNeonUTwoShiftSReg<NVqshrun, NVqrshrun>( 994 b, size, machInst, vd, vm, rShiftAmt); 995 } else { 996 return decodeNeonSTwoShiftSReg<NVqshrn, NVqrshrn>( 997 b, size, machInst, vd, vm, rShiftAmt); 998 } 999 case 0xa: 1000 if (l || b) { 1001 return new Unknown(machInst); 1002 } else { 1003 return decodeNeonUSTwoShiftSReg<NVmovl, NVshll>( 1004 lShiftAmt, u, size, machInst, vd, vm, lShiftAmt); 1005 } 1006 case 0xe: 1007 if (l) { 1008 return new Unknown(machInst); 1009 } else { 1010 if (bits(imm6, 5) == 0) 1011 return new Unknown(machInst); 1012 if (u) { 1013 if (b) { 1014 return new NVcvtu2fpQ<float>( 1015 machInst, vd, vm, 64 - imm6); 1016 } else { 1017 return new NVcvtu2fpD<float>( 1018 machInst, vd, vm, 64 - imm6); 1019 } 1020 } else { 1021 if (b) { 1022 return new NVcvts2fpQ<float>( 1023 machInst, vd, vm, 64 - imm6); 1024 } else { 1025 return new NVcvts2fpD<float>( 1026 machInst, vd, vm, 64 - imm6); 1027 } 1028 } 1029 } 1030 case 0xf: 1031 if (l) { 1032 return new Unknown(machInst); 1033 } else { 1034 if (bits(imm6, 5) == 0) 1035 return new Unknown(machInst); 1036 if (u) { 1037 if (b) { 1038 return new NVcvt2ufxQ<float>( 1039 machInst, vd, vm, 64 - imm6); 1040 } else { 1041 return new NVcvt2ufxD<float>( 1042 machInst, vd, vm, 64 - imm6); 1043 } 1044 } else { 1045 if (b) { 1046 return new NVcvt2sfxQ<float>( 1047 machInst, vd, vm, 64 - imm6); 1048 } else { 1049 return new NVcvt2sfxD<float>( 1050 machInst, vd, vm, 64 - imm6); 1051 } 1052 } 1053 } 1054 } 1055 return new Unknown(machInst); 1056 } 1057 1058 static StaticInstPtr 1059 decodeNeonThreeRegDiffLengths(ExtMachInst machInst) 1060 { 1061 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 1062 const uint32_t a = bits(machInst, 11, 8); 1063 const IntRegIndex vd = 1064 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1065 (bits(machInst, 22) << 4))); 1066 const IntRegIndex vn = 1067 (IntRegIndex)(2 * (bits(machInst, 19, 16) | 1068 (bits(machInst, 7) << 4))); 1069 const IntRegIndex vm = 1070 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 1071 (bits(machInst, 5) << 4))); 1072 const unsigned size = bits(machInst, 21, 20); 1073 switch (a) { 1074 case 0x0: 1075 return decodeNeonUSThreeUSReg<Vaddl>( 1076 u, size, machInst, vd, vn, vm); 1077 case 0x1: 1078 return decodeNeonUSThreeUSReg<Vaddw>( 1079 u, size, machInst, vd, vn, vm); 1080 case 0x2: 1081 return decodeNeonUSThreeUSReg<Vsubl>( 1082 u, size, machInst, vd, vn, vm); 1083 case 0x3: 1084 return decodeNeonUSThreeUSReg<Vsubw>( 1085 u, size, machInst, vd, vn, vm); 1086 case 0x4: 1087 if (u) { 1088 return decodeNeonUThreeUSReg<Vraddhn>( 1089 size, machInst, vd, vn, vm); 1090 } else { 1091 return decodeNeonUThreeUSReg<Vaddhn>( 1092 size, machInst, vd, vn, vm); 1093 } 1094 case 0x5: 1095 return decodeNeonUSThreeUSReg<Vabal>( 1096 u, size, machInst, vd, vn, vm); 1097 case 0x6: 1098 if (u) { 1099 return decodeNeonUThreeUSReg<Vrsubhn>( 1100 size, machInst, vd, vn, vm); 1101 } else { 1102 return decodeNeonUThreeUSReg<Vsubhn>( 1103 size, machInst, vd, vn, vm); 1104 } 1105 case 0x7: 1106 if (bits(machInst, 23)) { 1107 return decodeNeonUSThreeUSReg<Vabdl>( 1108 u, size, machInst, vd, vn, vm); 1109 } else { 1110 return decodeNeonUSThreeReg<VabdD, VabdQ>( 1111 bits(machInst, 6), u, size, machInst, vd, vn, vm); 1112 } 1113 case 0x8: 1114 return decodeNeonUSThreeUSReg<Vmlal>( 1115 u, size, machInst, vd, vn, vm); 1116 case 0xa: 1117 return decodeNeonUSThreeUSReg<Vmlsl>( 1118 u, size, machInst, vd, vn, vm); 1119 case 0x9: 1120 if (u) { 1121 return new Unknown(machInst); 1122 } else { 1123 return decodeNeonSThreeUSReg<Vqdmlal>( 1124 size, machInst, vd, vn, vm); 1125 } 1126 case 0xb: 1127 if (u) { 1128 return new Unknown(machInst); 1129 } else { 1130 return decodeNeonSThreeUSReg<Vqdmlsl>( 1131 size, machInst, vd, vn, vm); 1132 } 1133 case 0xc: 1134 return decodeNeonUSThreeUSReg<Vmull>( 1135 u, size, machInst, vd, vn, vm); 1136 case 0xd: 1137 if (u) { 1138 return new Unknown(machInst); 1139 } else { 1140 return decodeNeonSThreeUSReg<Vqdmull>( 1141 size, machInst, vd, vn, vm); 1142 } 1143 case 0xe: 1144 return decodeNeonUThreeUSReg<Vmullp>( 1145 size, machInst, vd, vn, vm); 1146 } 1147 return new Unknown(machInst); 1148 } 1149 1150 static StaticInstPtr 1151 decodeNeonTwoRegScalar(ExtMachInst machInst) 1152 { 1153 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 1154 const uint32_t a = bits(machInst, 11, 8); 1155 const unsigned size = bits(machInst, 21, 20); 1156 const IntRegIndex vd = 1157 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1158 (bits(machInst, 22) << 4))); 1159 const IntRegIndex vn = 1160 (IntRegIndex)(2 * (bits(machInst, 19, 16) | 1161 (bits(machInst, 7) << 4))); 1162 const IntRegIndex vm = (size == 2) ? 1163 (IntRegIndex)(2 * bits(machInst, 3, 0)) : 1164 (IntRegIndex)(2 * bits(machInst, 2, 0)); 1165 const unsigned index = (size == 2) ? (unsigned)bits(machInst, 5) : 1166 (bits(machInst, 3) | (bits(machInst, 5) << 1)); 1167 switch (a) { 1168 case 0x0: 1169 if (u) { 1170 switch (size) { 1171 case 1: 1172 return new VmlasQ<uint16_t>(machInst, vd, vn, vm, index); 1173 case 2: 1174 return new VmlasQ<uint32_t>(machInst, vd, vn, vm, index); 1175 default: 1176 return new Unknown(machInst); 1177 } 1178 } else { 1179 switch (size) { 1180 case 1: 1181 return new VmlasD<uint16_t>(machInst, vd, vn, vm, index); 1182 case 2: 1183 return new VmlasD<uint32_t>(machInst, vd, vn, vm, index); 1184 default: 1185 return new Unknown(machInst); 1186 } 1187 } 1188 case 0x1: 1189 if (u) 1190 return new VmlasQFp<float>(machInst, vd, vn, vm, index); 1191 else 1192 return new VmlasDFp<float>(machInst, vd, vn, vm, index); 1193 case 0x4: 1194 if (u) { 1195 switch (size) { 1196 case 1: 1197 return new VmlssQ<uint16_t>(machInst, vd, vn, vm, index); 1198 case 2: 1199 return new VmlssQ<uint32_t>(machInst, vd, vn, vm, index); 1200 default: 1201 return new Unknown(machInst); 1202 } 1203 } else { 1204 switch (size) { 1205 case 1: 1206 return new VmlssD<uint16_t>(machInst, vd, vn, vm, index); 1207 case 2: 1208 return new VmlssD<uint32_t>(machInst, vd, vn, vm, index); 1209 default: 1210 return new Unknown(machInst); 1211 } 1212 } 1213 case 0x5: 1214 if (u) 1215 return new VmlssQFp<float>(machInst, vd, vn, vm, index); 1216 else 1217 return new VmlssDFp<float>(machInst, vd, vn, vm, index); 1218 case 0x2: 1219 if (u) { 1220 switch (size) { 1221 case 1: 1222 return new Vmlals<uint16_t>(machInst, vd, vn, vm, index); 1223 case 2: 1224 return new Vmlals<uint32_t>(machInst, vd, vn, vm, index); 1225 default: 1226 return new Unknown(machInst); 1227 } 1228 } else { 1229 switch (size) { 1230 case 1: 1231 return new Vmlals<int16_t>(machInst, vd, vn, vm, index); 1232 case 2: 1233 return new Vmlals<int32_t>(machInst, vd, vn, vm, index); 1234 default: 1235 return new Unknown(machInst); 1236 } 1237 } 1238 case 0x6: 1239 if (u) { 1240 switch (size) { 1241 case 1: 1242 return new Vmlsls<uint16_t>(machInst, vd, vn, vm, index); 1243 case 2: 1244 return new Vmlsls<uint32_t>(machInst, vd, vn, vm, index); 1245 default: 1246 return new Unknown(machInst); 1247 } 1248 } else { 1249 switch (size) { 1250 case 1: 1251 return new Vmlsls<int16_t>(machInst, vd, vn, vm, index); 1252 case 2: 1253 return new Vmlsls<int32_t>(machInst, vd, vn, vm, index); 1254 default: 1255 return new Unknown(machInst); 1256 } 1257 } 1258 case 0x3: 1259 if (u) { 1260 return new Unknown(machInst); 1261 } else { 1262 switch (size) { 1263 case 1: 1264 return new Vqdmlals<int16_t>(machInst, vd, vn, vm, index); 1265 case 2: 1266 return new Vqdmlals<int32_t>(machInst, vd, vn, vm, index); 1267 default: 1268 return new Unknown(machInst); 1269 } 1270 } 1271 case 0x7: 1272 if (u) { 1273 return new Unknown(machInst); 1274 } else { 1275 switch (size) { 1276 case 1: 1277 return new Vqdmlsls<int16_t>(machInst, vd, vn, vm, index); 1278 case 2: 1279 return new Vqdmlsls<int32_t>(machInst, vd, vn, vm, index); 1280 default: 1281 return new Unknown(machInst); 1282 } 1283 } 1284 case 0x8: 1285 if (u) { 1286 switch (size) { 1287 case 1: 1288 return new VmulsQ<uint16_t>(machInst, vd, vn, vm, index); 1289 case 2: 1290 return new VmulsQ<uint32_t>(machInst, vd, vn, vm, index); 1291 default: 1292 return new Unknown(machInst); 1293 } 1294 } else { 1295 switch (size) { 1296 case 1: 1297 return new VmulsD<uint16_t>(machInst, vd, vn, vm, index); 1298 case 2: 1299 return new VmulsD<uint32_t>(machInst, vd, vn, vm, index); 1300 default: 1301 return new Unknown(machInst); 1302 } 1303 } 1304 case 0x9: 1305 if (u) 1306 return new VmulsQFp<float>(machInst, vd, vn, vm, index); 1307 else 1308 return new VmulsDFp<float>(machInst, vd, vn, vm, index); 1309 case 0xa: 1310 if (u) { 1311 switch (size) { 1312 case 1: 1313 return new Vmulls<uint16_t>(machInst, vd, vn, vm, index); 1314 case 2: 1315 return new Vmulls<uint32_t>(machInst, vd, vn, vm, index); 1316 default: 1317 return new Unknown(machInst); 1318 } 1319 } else { 1320 switch (size) { 1321 case 1: 1322 return new Vmulls<int16_t>(machInst, vd, vn, vm, index); 1323 case 2: 1324 return new Vmulls<int32_t>(machInst, vd, vn, vm, index); 1325 default: 1326 return new Unknown(machInst); 1327 } 1328 } 1329 case 0xb: 1330 if (u) { 1331 return new Unknown(machInst); 1332 } else { 1333 if (u) { 1334 switch (size) { 1335 case 1: 1336 return new Vqdmulls<uint16_t>( 1337 machInst, vd, vn, vm, index); 1338 case 2: 1339 return new Vqdmulls<uint32_t>( 1340 machInst, vd, vn, vm, index); 1341 default: 1342 return new Unknown(machInst); 1343 } 1344 } else { 1345 switch (size) { 1346 case 1: 1347 return new Vqdmulls<int16_t>( 1348 machInst, vd, vn, vm, index); 1349 case 2: 1350 return new Vqdmulls<int32_t>( 1351 machInst, vd, vn, vm, index); 1352 default: 1353 return new Unknown(machInst); 1354 } 1355 } 1356 } 1357 case 0xc: 1358 if (u) { 1359 switch (size) { 1360 case 1: 1361 return new VqdmulhsQ<int16_t>( 1362 machInst, vd, vn, vm, index); 1363 case 2: 1364 return new VqdmulhsQ<int32_t>( 1365 machInst, vd, vn, vm, index); 1366 default: 1367 return new Unknown(machInst); 1368 } 1369 } else { 1370 switch (size) { 1371 case 1: 1372 return new VqdmulhsD<int16_t>( 1373 machInst, vd, vn, vm, index); 1374 case 2: 1375 return new VqdmulhsD<int32_t>( 1376 machInst, vd, vn, vm, index); 1377 default: 1378 return new Unknown(machInst); 1379 } 1380 } 1381 case 0xd: 1382 if (u) { 1383 switch (size) { 1384 case 1: 1385 return new VqrdmulhsQ<int16_t>( 1386 machInst, vd, vn, vm, index); 1387 case 2: 1388 return new VqrdmulhsQ<int32_t>( 1389 machInst, vd, vn, vm, index); 1390 default: 1391 return new Unknown(machInst); 1392 } 1393 } else { 1394 switch (size) { 1395 case 1: 1396 return new VqrdmulhsD<int16_t>( 1397 machInst, vd, vn, vm, index); 1398 case 2: 1399 return new VqrdmulhsD<int32_t>( 1400 machInst, vd, vn, vm, index); 1401 default: 1402 return new Unknown(machInst); 1403 } 1404 } 1405 } 1406 return new Unknown(machInst); 1407 } 1408 1409 static StaticInstPtr 1410 decodeNeonTwoRegMisc(ExtMachInst machInst) 1411 { 1412 const uint32_t a = bits(machInst, 17, 16); 1413 const uint32_t b = bits(machInst, 10, 6); 1414 const bool q = bits(machInst, 6); 1415 const IntRegIndex vd = 1416 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1417 (bits(machInst, 22) << 4))); 1418 const IntRegIndex vm = 1419 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 1420 (bits(machInst, 5) << 4))); 1421 const unsigned size = bits(machInst, 19, 18); 1422 switch (a) { 1423 case 0x0: 1424 switch (bits(b, 4, 1)) { 1425 case 0x0: 1426 switch (size) { 1427 case 0: 1428 if (q) { 1429 return new NVrev64Q<uint8_t>(machInst, vd, vm); 1430 } else { 1431 return new NVrev64D<uint8_t>(machInst, vd, vm); 1432 } 1433 case 1: 1434 if (q) { 1435 return new NVrev64Q<uint16_t>(machInst, vd, vm); 1436 } else { 1437 return new NVrev64D<uint16_t>(machInst, vd, vm); 1438 } 1439 case 2: 1440 if (q) { 1441 return new NVrev64Q<uint32_t>(machInst, vd, vm); 1442 } else { 1443 return new NVrev64D<uint32_t>(machInst, vd, vm); 1444 } 1445 default: 1446 return new Unknown(machInst); 1447 } 1448 case 0x1: 1449 switch (size) { 1450 case 0: 1451 if (q) { 1452 return new NVrev32Q<uint8_t>(machInst, vd, vm); 1453 } else { 1454 return new NVrev32D<uint8_t>(machInst, vd, vm); 1455 } 1456 case 1: 1457 if (q) { 1458 return new NVrev32Q<uint16_t>(machInst, vd, vm); 1459 } else { 1460 return new NVrev32D<uint16_t>(machInst, vd, vm); 1461 } 1462 default: 1463 return new Unknown(machInst); 1464 } 1465 case 0x2: 1466 if (size != 0) { 1467 return new Unknown(machInst); 1468 } else if (q) { 1469 return new NVrev16Q<uint8_t>(machInst, vd, vm); 1470 } else { 1471 return new NVrev16D<uint8_t>(machInst, vd, vm); 1472 } 1473 case 0x4: 1474 return decodeNeonSTwoMiscSReg<NVpaddlD, NVpaddlQ>( 1475 q, size, machInst, vd, vm); 1476 case 0x5: 1477 return decodeNeonUTwoMiscSReg<NVpaddlD, NVpaddlQ>( 1478 q, size, machInst, vd, vm); 1479 case 0x8: 1480 return decodeNeonSTwoMiscReg<NVclsD, NVclsQ>( 1481 q, size, machInst, vd, vm); 1482 case 0x9: 1483 return decodeNeonSTwoMiscReg<NVclzD, NVclzQ>( 1484 q, size, machInst, vd, vm); 1485 case 0xa: 1486 return decodeNeonUTwoMiscReg<NVcntD, NVcntQ>( 1487 q, size, machInst, vd, vm); 1488 case 0xb: 1489 if (q) 1490 return new NVmvnQ<uint64_t>(machInst, vd, vm); 1491 else 1492 return new NVmvnD<uint64_t>(machInst, vd, vm); 1493 case 0xc: 1494 return decodeNeonSTwoMiscSReg<NVpadalD, NVpadalQ>( 1495 q, size, machInst, vd, vm); 1496 case 0xd: 1497 return decodeNeonUTwoMiscSReg<NVpadalD, NVpadalQ>( 1498 q, size, machInst, vd, vm); 1499 case 0xe: 1500 return decodeNeonSTwoMiscReg<NVqabsD, NVqabsQ>( 1501 q, size, machInst, vd, vm); 1502 case 0xf: 1503 return decodeNeonSTwoMiscReg<NVqnegD, NVqnegQ>( 1504 q, size, machInst, vd, vm); 1505 default: 1506 return new Unknown(machInst); 1507 } 1508 case 0x1: 1509 switch (bits(b, 3, 1)) { 1510 case 0x0: 1511 if (bits(b, 4)) { 1512 if (q) { 1513 return new NVcgtQFp<float>(machInst, vd, vm); 1514 } else { 1515 return new NVcgtDFp<float>(machInst, vd, vm); 1516 } 1517 } else { 1518 return decodeNeonSTwoMiscReg<NVcgtD, NVcgtQ>( 1519 q, size, machInst, vd, vm); 1520 } 1521 case 0x1: 1522 if (bits(b, 4)) { 1523 if (q) { 1524 return new NVcgeQFp<float>(machInst, vd, vm); 1525 } else { 1526 return new NVcgeDFp<float>(machInst, vd, vm); 1527 } 1528 } else { 1529 return decodeNeonSTwoMiscReg<NVcgeD, NVcgeQ>( 1530 q, size, machInst, vd, vm); 1531 } 1532 case 0x2: 1533 if (bits(b, 4)) { 1534 if (q) { 1535 return new NVceqQFp<float>(machInst, vd, vm); 1536 } else { 1537 return new NVceqDFp<float>(machInst, vd, vm); 1538 } 1539 } else { 1540 return decodeNeonSTwoMiscReg<NVceqD, NVceqQ>( 1541 q, size, machInst, vd, vm); 1542 } 1543 case 0x3: 1544 if (bits(b, 4)) { 1545 if (q) { 1546 return new NVcleQFp<float>(machInst, vd, vm); 1547 } else { 1548 return new NVcleDFp<float>(machInst, vd, vm); 1549 } 1550 } else { 1551 return decodeNeonSTwoMiscReg<NVcleD, NVcleQ>( 1552 q, size, machInst, vd, vm); 1553 } 1554 case 0x4: 1555 if (bits(b, 4)) { 1556 if (q) { 1557 return new NVcltQFp<float>(machInst, vd, vm); 1558 } else { 1559 return new NVcltDFp<float>(machInst, vd, vm); 1560 } 1561 } else { 1562 return decodeNeonSTwoMiscReg<NVcltD, NVcltQ>( 1563 q, size, machInst, vd, vm); 1564 }
|
| 1565 case 0x5: 1566 if (q) { 1567 return new SHA1H(machInst, vd, vm); 1568 } else { 1569 return new Unknown(machInst); 1570 }
|
1537 case 0x6: 1538 if (bits(machInst, 10)) { 1539 if (q) 1540 return new NVabsQFp<float>(machInst, vd, vm); 1541 else 1542 return new NVabsDFp<float>(machInst, vd, vm); 1543 } else { 1544 return decodeNeonSTwoMiscReg<NVabsD, NVabsQ>( 1545 q, size, machInst, vd, vm); 1546 } 1547 case 0x7: 1548 if (bits(machInst, 10)) { 1549 if (q) 1550 return new NVnegQFp<float>(machInst, vd, vm); 1551 else 1552 return new NVnegDFp<float>(machInst, vd, vm); 1553 } else { 1554 return decodeNeonSTwoMiscReg<NVnegD, NVnegQ>( 1555 q, size, machInst, vd, vm); 1556 } 1557 default: 1558 return new Unknown64(machInst); 1559 } 1560 case 0x2: 1561 switch (bits(b, 4, 1)) { 1562 case 0x0: 1563 if (q) 1564 return new NVswpQ<uint64_t>(machInst, vd, vm); 1565 else 1566 return new NVswpD<uint64_t>(machInst, vd, vm); 1567 case 0x1: 1568 return decodeNeonUTwoMiscSReg<NVtrnD, NVtrnQ>( 1569 q, size, machInst, vd, vm); 1570 case 0x2: 1571 return decodeNeonUTwoMiscReg<NVuzpD, NVuzpQ>( 1572 q, size, machInst, vd, vm); 1573 case 0x3: 1574 return decodeNeonUTwoMiscReg<NVzipD, NVzipQ>( 1575 q, size, machInst, vd, vm); 1576 case 0x4: 1577 if (b == 0x8) { 1578 return decodeNeonUTwoMiscUSReg<NVmovn>( 1579 size, machInst, vd, vm); 1580 } else { 1581 return decodeNeonSTwoMiscUSReg<NVqmovuns>( 1582 size, machInst, vd, vm); 1583 } 1584 case 0x5: 1585 if (q) { 1586 return decodeNeonUTwoMiscUSReg<NVqmovun>( 1587 size, machInst, vd, vm); 1588 } else { 1589 return decodeNeonSTwoMiscUSReg<NVqmovn>( 1590 size, machInst, vd, vm); 1591 } 1592 case 0x6: 1593 if (b == 0xc) { 1594 return decodeNeonSTwoShiftUSReg<NVshll>( 1595 size, machInst, vd, vm, 8 << size); 1596 } else { 1597 return new Unknown(machInst); 1598 }
| 1571 case 0x6: 1572 if (bits(machInst, 10)) { 1573 if (q) 1574 return new NVabsQFp<float>(machInst, vd, vm); 1575 else 1576 return new NVabsDFp<float>(machInst, vd, vm); 1577 } else { 1578 return decodeNeonSTwoMiscReg<NVabsD, NVabsQ>( 1579 q, size, machInst, vd, vm); 1580 } 1581 case 0x7: 1582 if (bits(machInst, 10)) { 1583 if (q) 1584 return new NVnegQFp<float>(machInst, vd, vm); 1585 else 1586 return new NVnegDFp<float>(machInst, vd, vm); 1587 } else { 1588 return decodeNeonSTwoMiscReg<NVnegD, NVnegQ>( 1589 q, size, machInst, vd, vm); 1590 } 1591 default: 1592 return new Unknown64(machInst); 1593 } 1594 case 0x2: 1595 switch (bits(b, 4, 1)) { 1596 case 0x0: 1597 if (q) 1598 return new NVswpQ<uint64_t>(machInst, vd, vm); 1599 else 1600 return new NVswpD<uint64_t>(machInst, vd, vm); 1601 case 0x1: 1602 return decodeNeonUTwoMiscSReg<NVtrnD, NVtrnQ>( 1603 q, size, machInst, vd, vm); 1604 case 0x2: 1605 return decodeNeonUTwoMiscReg<NVuzpD, NVuzpQ>( 1606 q, size, machInst, vd, vm); 1607 case 0x3: 1608 return decodeNeonUTwoMiscReg<NVzipD, NVzipQ>( 1609 q, size, machInst, vd, vm); 1610 case 0x4: 1611 if (b == 0x8) { 1612 return decodeNeonUTwoMiscUSReg<NVmovn>( 1613 size, machInst, vd, vm); 1614 } else { 1615 return decodeNeonSTwoMiscUSReg<NVqmovuns>( 1616 size, machInst, vd, vm); 1617 } 1618 case 0x5: 1619 if (q) { 1620 return decodeNeonUTwoMiscUSReg<NVqmovun>( 1621 size, machInst, vd, vm); 1622 } else { 1623 return decodeNeonSTwoMiscUSReg<NVqmovn>( 1624 size, machInst, vd, vm); 1625 } 1626 case 0x6: 1627 if (b == 0xc) { 1628 return decodeNeonSTwoShiftUSReg<NVshll>( 1629 size, machInst, vd, vm, 8 << size); 1630 } else { 1631 return new Unknown(machInst); 1632 }
|
| 1633 case 0x7: 1634 if (q) { 1635 return new SHA256SU0(machInst, vd, vm); 1636 } else { 1637 return new SHA1SU1(machInst, vd, vm); 1638 }
|
1599 case 0xc: 1600 case 0xe: 1601 if (b == 0x18) { 1602 if (size != 1 || (vm % 2)) 1603 return new Unknown(machInst); 1604 return new NVcvts2h<uint16_t>(machInst, vd, vm); 1605 } else if (b == 0x1c) { 1606 if (size != 1 || (vd % 2)) 1607 return new Unknown(machInst); 1608 return new NVcvth2s<uint16_t>(machInst, vd, vm); 1609 } else { 1610 return new Unknown(machInst); 1611 } 1612 default: 1613 return new Unknown(machInst); 1614 } 1615 case 0x3: 1616 if (bits(b, 4, 3) == 0x3) { 1617 if ((q && (vd % 2 || vm % 2)) || size != 2) { 1618 return new Unknown(machInst); 1619 } else { 1620 if (bits(b, 2)) { 1621 if (bits(b, 1)) { 1622 if (q) { 1623 return new NVcvt2ufxQ<float>( 1624 machInst, vd, vm, 0); 1625 } else { 1626 return new NVcvt2ufxD<float>( 1627 machInst, vd, vm, 0); 1628 } 1629 } else { 1630 if (q) { 1631 return new NVcvt2sfxQ<float>( 1632 machInst, vd, vm, 0); 1633 } else { 1634 return new NVcvt2sfxD<float>( 1635 machInst, vd, vm, 0); 1636 } 1637 } 1638 } else { 1639 if (bits(b, 1)) { 1640 if (q) { 1641 return new NVcvtu2fpQ<float>( 1642 machInst, vd, vm, 0); 1643 } else { 1644 return new NVcvtu2fpD<float>( 1645 machInst, vd, vm, 0); 1646 } 1647 } else { 1648 if (q) { 1649 return new NVcvts2fpQ<float>( 1650 machInst, vd, vm, 0); 1651 } else { 1652 return new NVcvts2fpD<float>( 1653 machInst, vd, vm, 0); 1654 } 1655 } 1656 } 1657 } 1658 } else if ((b & 0x1a) == 0x10) { 1659 if (bits(b, 2)) { 1660 if (q) { 1661 return new NVrecpeQFp<float>(machInst, vd, vm); 1662 } else { 1663 return new NVrecpeDFp<float>(machInst, vd, vm); 1664 } 1665 } else { 1666 if (q) { 1667 return new NVrecpeQ<uint32_t>(machInst, vd, vm); 1668 } else { 1669 return new NVrecpeD<uint32_t>(machInst, vd, vm); 1670 } 1671 } 1672 } else if ((b & 0x1a) == 0x12) { 1673 if (bits(b, 2)) { 1674 if (q) { 1675 return new NVrsqrteQFp<float>(machInst, vd, vm); 1676 } else { 1677 return new NVrsqrteDFp<float>(machInst, vd, vm); 1678 } 1679 } else { 1680 if (q) { 1681 return new NVrsqrteQ<uint32_t>(machInst, vd, vm); 1682 } else { 1683 return new NVrsqrteD<uint32_t>(machInst, vd, vm); 1684 } 1685 } 1686 } else { 1687 return new Unknown(machInst); 1688 } 1689 } 1690 return new Unknown(machInst); 1691 } 1692 1693 StaticInstPtr 1694 decodeNeonData(ExtMachInst machInst) 1695 { 1696 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 1697 const uint32_t a = bits(machInst, 23, 19); 1698 const uint32_t b = bits(machInst, 11, 8); 1699 const uint32_t c = bits(machInst, 7, 4); 1700 if (bits(a, 4) == 0) { 1701 return decodeNeonThreeRegistersSameLength(machInst); 1702 } else if ((c & 0x9) == 1) { 1703 if ((a & 0x7) == 0) { 1704 return decodeNeonOneRegModImm(machInst); 1705 } else { 1706 return decodeNeonTwoRegAndShift(machInst); 1707 } 1708 } else if ((c & 0x9) == 9) { 1709 return decodeNeonTwoRegAndShift(machInst); 1710 } else if (bits(a, 2, 1) != 0x3) { 1711 if ((c & 0x5) == 0) { 1712 return decodeNeonThreeRegDiffLengths(machInst); 1713 } else if ((c & 0x5) == 4) { 1714 return decodeNeonTwoRegScalar(machInst); 1715 } 1716 } else if ((a & 0x16) == 0x16) { 1717 const IntRegIndex vd = 1718 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1719 (bits(machInst, 22) << 4))); 1720 const IntRegIndex vn = 1721 (IntRegIndex)(2 * (bits(machInst, 19, 16) | 1722 (bits(machInst, 7) << 4))); 1723 const IntRegIndex vm = 1724 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 1725 (bits(machInst, 5) << 4))); 1726 if (!u) { 1727 if (bits(c, 0) == 0) { 1728 unsigned imm4 = bits(machInst, 11, 8); 1729 bool q = bits(machInst, 6); 1730 if (imm4 >= 16 && !q) 1731 return new Unknown(machInst); 1732 if (q) { 1733 return new NVextQ<uint8_t>(machInst, vd, vn, vm, imm4); 1734 } else { 1735 return new NVextD<uint8_t>(machInst, vd, vn, vm, imm4); 1736 } 1737 } 1738 } else if (bits(b, 3) == 0 && bits(c, 0) == 0) { 1739 return decodeNeonTwoRegMisc(machInst); 1740 } else if (bits(b, 3, 2) == 0x2 && bits(c, 0) == 0) { 1741 unsigned length = bits(machInst, 9, 8) + 1; 1742 if ((uint32_t)vn / 2 + length > 32) 1743 return new Unknown(machInst); 1744 if (bits(machInst, 6) == 0) { 1745 switch (length) { 1746 case 1: 1747 return new NVtbl1(machInst, vd, vn, vm); 1748 case 2: 1749 return new NVtbl2(machInst, vd, vn, vm); 1750 case 3: 1751 return new NVtbl3(machInst, vd, vn, vm); 1752 case 4: 1753 return new NVtbl4(machInst, vd, vn, vm); 1754 } 1755 } else { 1756 switch (length) { 1757 case 1: 1758 return new NVtbx1(machInst, vd, vn, vm); 1759 case 2: 1760 return new NVtbx2(machInst, vd, vn, vm); 1761 case 3: 1762 return new NVtbx3(machInst, vd, vn, vm); 1763 case 4: 1764 return new NVtbx4(machInst, vd, vn, vm); 1765 } 1766 } 1767 } else if (b == 0xc && (c & 0x9) == 0) { 1768 unsigned imm4 = bits(machInst, 19, 16); 1769 if (bits(imm4, 2, 0) == 0) 1770 return new Unknown(machInst); 1771 unsigned size = 0; 1772 while ((imm4 & 0x1) == 0) { 1773 size++; 1774 imm4 >>= 1; 1775 } 1776 unsigned index = imm4 >> 1; 1777 const bool q = bits(machInst, 6); 1778 return decodeNeonUTwoShiftSReg<NVdupD, NVdupQ>( 1779 q, size, machInst, vd, vm, index); 1780 } 1781 } 1782 return new Unknown(machInst); 1783 } 1784 ''' 1785}}; 1786 1787def format ThumbNeonMem() {{ 1788 decode_block = ''' 1789 return decodeNeonMem(machInst); 1790 ''' 1791}}; 1792 1793def format ThumbNeonData() {{ 1794 decode_block = ''' 1795 return decodeNeonData(machInst); 1796 ''' 1797}}; 1798 1799let {{ 1800 header_output = ''' 1801 StaticInstPtr 1802 decodeExtensionRegLoadStore(ExtMachInst machInst); 1803 ''' 1804 decoder_output = ''' 1805 StaticInstPtr 1806 decodeExtensionRegLoadStore(ExtMachInst machInst) 1807 { 1808 const uint32_t opcode = bits(machInst, 24, 20); 1809 const uint32_t offset = bits(machInst, 7, 0); 1810 const bool single = (bits(machInst, 8) == 0); 1811 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1812 RegIndex vd; 1813 if (single) { 1814 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1815 bits(machInst, 22)); 1816 } else { 1817 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1818 (bits(machInst, 22) << 5)); 1819 } 1820 switch (bits(opcode, 4, 3)) { 1821 case 0x0: 1822 if (bits(opcode, 4, 1) == 0x2 && 1823 !(machInst.thumb == 1 && bits(machInst, 28) == 1) && 1824 !(machInst.thumb == 0 && machInst.condCode == 0xf)) { 1825 if ((bits(machInst, 7, 4) & 0xd) != 1) { 1826 break; 1827 } 1828 const IntRegIndex rt = 1829 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1830 const IntRegIndex rt2 = 1831 (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1832 const bool op = bits(machInst, 20); 1833 uint32_t vm; 1834 if (single) { 1835 vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5); 1836 } else { 1837 vm = (bits(machInst, 3, 0) << 1) | 1838 (bits(machInst, 5) << 5); 1839 } 1840 if (op) { 1841 return new Vmov2Core2Reg(machInst, rt, rt2, 1842 (IntRegIndex)vm); 1843 } else { 1844 return new Vmov2Reg2Core(machInst, (IntRegIndex)vm, 1845 rt, rt2); 1846 } 1847 } 1848 break; 1849 case 0x1: 1850 { 1851 if (offset == 0 || vd + offset/2 > NumFloatV7ArchRegs) { 1852 break; 1853 } 1854 switch (bits(opcode, 1, 0)) { 1855 case 0x0: 1856 return new VLdmStm(machInst, rn, vd, single, 1857 true, false, false, offset); 1858 case 0x1: 1859 return new VLdmStm(machInst, rn, vd, single, 1860 true, false, true, offset); 1861 case 0x2: 1862 return new VLdmStm(machInst, rn, vd, single, 1863 true, true, false, offset); 1864 case 0x3: 1865 // If rn == sp, then this is called vpop. 1866 return new VLdmStm(machInst, rn, vd, single, 1867 true, true, true, offset); 1868 default: 1869 M5_UNREACHABLE; 1870 } 1871 } 1872 case 0x2: 1873 if (bits(opcode, 1, 0) == 0x2) { 1874 // If rn == sp, then this is called vpush. 1875 return new VLdmStm(machInst, rn, vd, single, 1876 false, true, false, offset); 1877 } else if (bits(opcode, 1, 0) == 0x3) { 1878 return new VLdmStm(machInst, rn, vd, single, 1879 false, true, true, offset); 1880 } 1881 M5_FALLTHROUGH; 1882 case 0x3: 1883 const bool up = (bits(machInst, 23) == 1); 1884 const uint32_t imm = bits(machInst, 7, 0) << 2; 1885 if (single) { 1886 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1887 (bits(machInst, 22))); 1888 } else { 1889 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1890 (bits(machInst, 22) << 5)); 1891 } 1892 if (bits(opcode, 1, 0) == 0x0) { 1893 if (single) { 1894 if (up) { 1895 return new %(vstr_us)s(machInst, vd, rn, up, imm); 1896 } else { 1897 return new %(vstr_s)s(machInst, vd, rn, up, imm); 1898 } 1899 } else { 1900 if (up) { 1901 return new %(vstr_ud)s(machInst, vd, vd + 1, 1902 rn, up, imm); 1903 } else { 1904 return new %(vstr_d)s(machInst, vd, vd + 1, 1905 rn, up, imm); 1906 } 1907 } 1908 } else if (bits(opcode, 1, 0) == 0x1) { 1909 if (single) { 1910 if (up) { 1911 return new %(vldr_us)s(machInst, vd, rn, up, imm); 1912 } else { 1913 return new %(vldr_s)s(machInst, vd, rn, up, imm); 1914 } 1915 } else { 1916 if (up) { 1917 return new %(vldr_ud)s(machInst, vd, vd + 1, 1918 rn, up, imm); 1919 } else { 1920 return new %(vldr_d)s(machInst, vd, vd + 1, 1921 rn, up, imm); 1922 } 1923 } 1924 } 1925 } 1926 return new Unknown(machInst); 1927 } 1928 ''' % { 1929 "vldr_us" : "VLDR_" + loadImmClassName(False, True, False), 1930 "vldr_s" : "VLDR_" + loadImmClassName(False, False, False), 1931 "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False), 1932 "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False), 1933 "vstr_us" : "VSTR_" + storeImmClassName(False, True, False), 1934 "vstr_s" : "VSTR_" + storeImmClassName(False, False, False), 1935 "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False), 1936 "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False) 1937 } 1938}}; 1939 1940def format ExtensionRegLoadStore() {{ 1941 decode_block = ''' 1942 return decodeExtensionRegLoadStore(machInst); 1943 ''' 1944}}; 1945 1946let {{ 1947 header_output = ''' 1948 StaticInstPtr 1949 decodeShortFpTransfer(ExtMachInst machInst); 1950 ''' 1951 decoder_output = ''' 1952 StaticInstPtr 1953 decodeShortFpTransfer(ExtMachInst machInst) 1954 { 1955 const uint32_t l = bits(machInst, 20); 1956 const uint32_t c = bits(machInst, 8); 1957 const uint32_t a = bits(machInst, 23, 21); 1958 const uint32_t b = bits(machInst, 6, 5); 1959 if ((machInst.thumb == 1 && bits(machInst, 28) == 1) || 1960 (machInst.thumb == 0 && machInst.condCode == 0xf)) { 1961 // Determine if this is backported aarch64 FP instruction 1962 const bool b31_b24 = bits(machInst, 31, 24) == 0xFE; 1963 const bool b23 = bits(machInst, 23); 1964 const bool b21_b18 = bits(machInst, 21, 18) == 0xE; 1965 const bool b11_b9 = bits(machInst, 11, 9) == 0x5; 1966 const bool sz = bits(machInst, 8); 1967 const bool b7_b6 = bits(machInst, 7, 6) == 0x1; 1968 const bool b6 = bits(machInst, 6) == 0x0; 1969 const bool b4 = bits(machInst, 4) == 0x0; 1970 if (b31_b24 && b23 && b21_b18 && b11_b9 && b7_b6 && b4) { 1971 // VINT* Integer Rounding Instructon 1972 const uint32_t rm = bits(machInst, 17, 16); 1973 1974 if (sz) { 1975 const IntRegIndex vd = 1976 (IntRegIndex)((bits(machInst, 22) << 5) | 1977 (bits(machInst, 15, 12) << 1)); 1978 const IntRegIndex vm = 1979 (IntRegIndex)((bits(machInst, 5) << 5) | 1980 (bits(machInst, 3, 0) << 1)); 1981 switch(rm) { 1982 case 0x0: 1983 return decodeVfpRegRegOp<VRIntAD>(machInst, vd, vm, 1984 true); 1985 case 0x1: 1986 return decodeVfpRegRegOp<VRIntND>(machInst, vd, vm, 1987 true); 1988 case 0x2: 1989 return decodeVfpRegRegOp<VRIntPD>(machInst, vd, vm, 1990 true); 1991 case 0x3: 1992 return decodeVfpRegRegOp<VRIntMD>(machInst, vd, vm, 1993 true); 1994 default: return new Unknown(machInst); 1995 } 1996 } else { 1997 const IntRegIndex vd = 1998 (IntRegIndex)(bits(machInst, 22) | 1999 (bits(machInst, 15, 12) << 1)); 2000 const IntRegIndex vm = 2001 (IntRegIndex)(bits(machInst, 5) | 2002 (bits(machInst, 3, 0) << 1)); 2003 switch(rm) { 2004 case 0x0: 2005 return decodeVfpRegRegOp<VRIntAS>(machInst, vd, vm, 2006 false); 2007 case 0x1: 2008 return decodeVfpRegRegOp<VRIntNS>(machInst, vd, vm, 2009 false); 2010 case 0x2: 2011 return decodeVfpRegRegOp<VRIntPS>(machInst, vd, vm, 2012 false); 2013 case 0x3: 2014 return decodeVfpRegRegOp<VRIntMS>(machInst, vd, vm, 2015 false); 2016 default: return new Unknown(machInst); 2017 } 2018 } 2019 } else if (b31_b24 && !b23 && b11_b9 && b6 && b4){ 2020 // VSEL* floating point conditional select 2021 2022 ConditionCode cond; 2023 switch(bits(machInst, 21, 20)) { 2024 case 0x0: cond = COND_EQ; break; 2025 case 0x1: cond = COND_VS; break; 2026 case 0x2: cond = COND_GE; break; 2027 case 0x3: cond = COND_GT; break; 2028 } 2029 2030 if (sz) { 2031 const IntRegIndex vd = 2032 (IntRegIndex)((bits(machInst, 22) << 5) | 2033 (bits(machInst, 15, 12) << 1)); 2034 const IntRegIndex vm = 2035 (IntRegIndex)((bits(machInst, 5) << 5) | 2036 (bits(machInst, 3, 0) << 1)); 2037 const IntRegIndex vn = 2038 (IntRegIndex)((bits(machInst, 7) << 5) | 2039 (bits(machInst, 19, 16) << 1)); 2040 return new VselD(machInst, vd, vn, vm, cond); 2041 } else { 2042 const IntRegIndex vd = 2043 (IntRegIndex)(bits(machInst, 22) | 2044 (bits(machInst, 15, 12) << 1)); 2045 const IntRegIndex vm = 2046 (IntRegIndex)(bits(machInst, 5) | 2047 (bits(machInst, 3, 0) << 1)); 2048 const IntRegIndex vn = 2049 (IntRegIndex)((bits(machInst, 19, 16) << 1) | 2050 bits(machInst, 7)); 2051 return new VselS(machInst, vd, vn, vm, cond); 2052 } 2053 } else { 2054 return new Unknown(machInst); 2055 } 2056 } 2057 if (l == 0 && c == 0) { 2058 if (a == 0) { 2059 const uint32_t vn = (bits(machInst, 19, 16) << 1) | 2060 bits(machInst, 7); 2061 const IntRegIndex rt = 2062 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2063 if (bits(machInst, 20) == 1) { 2064 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn); 2065 } else { 2066 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt); 2067 } 2068 } else if (a == 0x7) { 2069 const IntRegIndex rt = 2070 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2071 uint32_t reg = bits(machInst, 19, 16); 2072 uint32_t specReg; 2073 switch (reg) { 2074 case 0: 2075 specReg = MISCREG_FPSID; 2076 break; 2077 case 1: 2078 specReg = MISCREG_FPSCR; 2079 break; 2080 case 6: 2081 specReg = MISCREG_MVFR1; 2082 break; 2083 case 7: 2084 specReg = MISCREG_MVFR0; 2085 break; 2086 case 8: 2087 specReg = MISCREG_FPEXC; 2088 break; 2089 default: 2090 return new Unknown(machInst); 2091 } 2092 if (specReg == MISCREG_FPSCR) { 2093 return new VmsrFpscr(machInst, (IntRegIndex)specReg, rt); 2094 } else { 2095 uint32_t iss = mcrMrcIssBuild(0, bits(machInst, 3, 0), rt, 2096 reg, a, bits(machInst, 7, 5)); 2097 return new Vmsr(machInst, (IntRegIndex)specReg, rt, iss); 2098 } 2099 } 2100 } else if (l == 0 && c == 1) { 2101 if (bits(a, 2) == 0) { 2102 uint32_t vd = (bits(machInst, 7) << 5) | 2103 (bits(machInst, 19, 16) << 1); 2104 // Handle accessing each single precision half of the vector. 2105 vd += bits(machInst, 21); 2106 const IntRegIndex rt = 2107 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2108 if (bits(machInst, 22) == 1) { 2109 return new VmovCoreRegB(machInst, (IntRegIndex)vd, 2110 rt, bits(machInst, 6, 5)); 2111 } else if (bits(machInst, 5) == 1) { 2112 return new VmovCoreRegH(machInst, (IntRegIndex)vd, 2113 rt, bits(machInst, 6)); 2114 } else if (bits(machInst, 6) == 0) { 2115 return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt); 2116 } else { 2117 return new Unknown(machInst); 2118 } 2119 } else if (bits(b, 1) == 0) { 2120 bool q = bits(machInst, 21); 2121 unsigned be = (bits(machInst, 22) << 1) | (bits(machInst, 5)); 2122 IntRegIndex vd = (IntRegIndex)(2 * (uint32_t) 2123 (bits(machInst, 19, 16) | (bits(machInst, 7) << 4))); 2124 IntRegIndex rt = (IntRegIndex)(uint32_t) 2125 bits(machInst, 15, 12); 2126 if (q) { 2127 switch (be) { 2128 case 0: 2129 return new NVdupQGpr<uint32_t>(machInst, vd, rt); 2130 case 1: 2131 return new NVdupQGpr<uint16_t>(machInst, vd, rt); 2132 case 2: 2133 return new NVdupQGpr<uint8_t>(machInst, vd, rt); 2134 case 3: 2135 return new Unknown(machInst); 2136 } 2137 } else { 2138 switch (be) { 2139 case 0: 2140 return new NVdupDGpr<uint32_t>(machInst, vd, rt); 2141 case 1: 2142 return new NVdupDGpr<uint16_t>(machInst, vd, rt); 2143 case 2: 2144 return new NVdupDGpr<uint8_t>(machInst, vd, rt); 2145 case 3: 2146 return new Unknown(machInst); 2147 } 2148 } 2149 } 2150 } else if (l == 1 && c == 0) { 2151 if (a == 0) { 2152 const uint32_t vn = (bits(machInst, 19, 16) << 1) | 2153 bits(machInst, 7); 2154 const IntRegIndex rt = 2155 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2156 if (bits(machInst, 20) == 1) { 2157 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn); 2158 } else { 2159 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt); 2160 } 2161 } else if (a == 7) { 2162 const IntRegIndex rt = 2163 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2164 uint32_t reg = bits(machInst, 19, 16); 2165 uint32_t specReg; 2166 switch (reg) { 2167 case 0: 2168 specReg = MISCREG_FPSID; 2169 break; 2170 case 1: 2171 specReg = MISCREG_FPSCR; 2172 break; 2173 case 6: 2174 specReg = MISCREG_MVFR1; 2175 break; 2176 case 7: 2177 specReg = MISCREG_MVFR0; 2178 break; 2179 case 8: 2180 specReg = MISCREG_FPEXC; 2181 break; 2182 default: 2183 return new Unknown(machInst); 2184 } 2185 if (rt == 0xf) { 2186 if (specReg == MISCREG_FPSCR) { 2187 return new VmrsApsrFpscr(machInst); 2188 } else { 2189 return new Unknown(machInst); 2190 } 2191 } else if (specReg == MISCREG_FPSCR) { 2192 return new VmrsFpscr(machInst, rt, (IntRegIndex)specReg); 2193 } else { 2194 uint32_t iss = mcrMrcIssBuild(l, bits(machInst, 3, 0), rt, 2195 reg, a, bits(machInst, 7, 5)); 2196 return new Vmrs(machInst, rt, (IntRegIndex)specReg, iss); 2197 } 2198 } 2199 } else { 2200 uint32_t vd = (bits(machInst, 7) << 5) | 2201 (bits(machInst, 19, 16) << 1); 2202 // Handle indexing into each single precision half of the vector. 2203 vd += bits(machInst, 21); 2204 uint32_t index; 2205 const IntRegIndex rt = 2206 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2207 const bool u = (bits(machInst, 23) == 1); 2208 if (bits(machInst, 22) == 1) { 2209 index = bits(machInst, 6, 5); 2210 if (u) { 2211 return new VmovRegCoreUB(machInst, rt, 2212 (IntRegIndex)vd, index); 2213 } else { 2214 return new VmovRegCoreSB(machInst, rt, 2215 (IntRegIndex)vd, index); 2216 } 2217 } else if (bits(machInst, 5) == 1) { 2218 index = bits(machInst, 6); 2219 if (u) { 2220 return new VmovRegCoreUH(machInst, rt, 2221 (IntRegIndex)vd, index); 2222 } else { 2223 return new VmovRegCoreSH(machInst, rt, 2224 (IntRegIndex)vd, index); 2225 } 2226 } else if (bits(machInst, 6) == 0 && !u) { 2227 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd); 2228 } else { 2229 return new Unknown(machInst); 2230 } 2231 } 2232 return new Unknown(machInst); 2233 } 2234 ''' 2235}}; 2236 2237def format ShortFpTransfer() {{ 2238 decode_block = ''' 2239 return decodeShortFpTransfer(machInst); 2240 ''' 2241}}; 2242 2243let {{ 2244 header_output = ''' 2245 StaticInstPtr 2246 decodeVfpData(ExtMachInst machInst); 2247 ''' 2248 decoder_output = ''' 2249 StaticInstPtr 2250 decodeVfpData(ExtMachInst machInst) 2251 { 2252 const uint32_t opc1 = bits(machInst, 23, 20); 2253 const uint32_t opc2 = bits(machInst, 19, 16); 2254 const uint32_t opc3 = bits(machInst, 7, 6); 2255 //const uint32_t opc4 = bits(machInst, 3, 0); 2256 const bool single = (bits(machInst, 8) == 0); 2257 // Used to select between vcmp and vcmpe. 2258 const bool e = (bits(machInst, 7) == 1); 2259 IntRegIndex vd; 2260 IntRegIndex vm; 2261 IntRegIndex vn; 2262 if (single) { 2263 vd = (IntRegIndex)(bits(machInst, 22) | 2264 (bits(machInst, 15, 12) << 1)); 2265 vm = (IntRegIndex)(bits(machInst, 5) | 2266 (bits(machInst, 3, 0) << 1)); 2267 vn = (IntRegIndex)(bits(machInst, 7) | 2268 (bits(machInst, 19, 16) << 1)); 2269 } else { 2270 vd = (IntRegIndex)((bits(machInst, 22) << 5) | 2271 (bits(machInst, 15, 12) << 1)); 2272 vm = (IntRegIndex)((bits(machInst, 5) << 5) | 2273 (bits(machInst, 3, 0) << 1)); 2274 vn = (IntRegIndex)((bits(machInst, 7) << 5) | 2275 (bits(machInst, 19, 16) << 1)); 2276 } 2277 switch (opc1 & 0xb /* 1011 */) { 2278 case 0x0: 2279 if (bits(machInst, 6) == 0) { 2280 if (single) { 2281 return decodeVfpRegRegRegOp<VmlaS>( 2282 machInst, vd, vn, vm, false); 2283 } else { 2284 return decodeVfpRegRegRegOp<VmlaD>( 2285 machInst, vd, vn, vm, true); 2286 } 2287 } else { 2288 if (single) { 2289 return decodeVfpRegRegRegOp<VmlsS>( 2290 machInst, vd, vn, vm, false); 2291 } else { 2292 return decodeVfpRegRegRegOp<VmlsD>( 2293 machInst, vd, vn, vm, true); 2294 } 2295 } 2296 case 0x1: 2297 if (bits(machInst, 6) == 1) { 2298 if (single) { 2299 return decodeVfpRegRegRegOp<VnmlaS>( 2300 machInst, vd, vn, vm, false); 2301 } else { 2302 return decodeVfpRegRegRegOp<VnmlaD>( 2303 machInst, vd, vn, vm, true); 2304 } 2305 } else { 2306 if (single) { 2307 return decodeVfpRegRegRegOp<VnmlsS>( 2308 machInst, vd, vn, vm, false); 2309 } else { 2310 return decodeVfpRegRegRegOp<VnmlsD>( 2311 machInst, vd, vn, vm, true); 2312 } 2313 } 2314 case 0x2: 2315 if ((opc3 & 0x1) == 0) { 2316 if (single) { 2317 return decodeVfpRegRegRegOp<VmulS>( 2318 machInst, vd, vn, vm, false); 2319 } else { 2320 return decodeVfpRegRegRegOp<VmulD>( 2321 machInst, vd, vn, vm, true); 2322 } 2323 } else { 2324 if (single) { 2325 return decodeVfpRegRegRegOp<VnmulS>( 2326 machInst, vd, vn, vm, false); 2327 } else { 2328 return decodeVfpRegRegRegOp<VnmulD>( 2329 machInst, vd, vn, vm, true); 2330 } 2331 } 2332 case 0x3: 2333 if ((opc3 & 0x1) == 0) { 2334 if (single) { 2335 return decodeVfpRegRegRegOp<VaddS>( 2336 machInst, vd, vn, vm, false); 2337 } else { 2338 return decodeVfpRegRegRegOp<VaddD>( 2339 machInst, vd, vn, vm, true); 2340 } 2341 } else { 2342 if (single) { 2343 return decodeVfpRegRegRegOp<VsubS>( 2344 machInst, vd, vn, vm, false); 2345 } else { 2346 return decodeVfpRegRegRegOp<VsubD>( 2347 machInst, vd, vn, vm, true); 2348 } 2349 } 2350 case 0x8: 2351 if ((opc3 & 0x1) == 0) { 2352 if (single) { 2353 return decodeVfpRegRegRegOp<VdivS>( 2354 machInst, vd, vn, vm, false); 2355 } else { 2356 return decodeVfpRegRegRegOp<VdivD>( 2357 machInst, vd, vn, vm, true); 2358 } 2359 } 2360 break; 2361 case 0x9: 2362 if ((opc3 & 0x1) == 0) { 2363 if (single) { 2364 return decodeVfpRegRegRegOp<VfnmaS>( 2365 machInst, vd, vn, vm, false); 2366 } else { 2367 return decodeVfpRegRegRegOp<VfnmaD>( 2368 machInst, vd, vn, vm, true); 2369 } 2370 } else { 2371 if (single) { 2372 return decodeVfpRegRegRegOp<VfnmsS>( 2373 machInst, vd, vn, vm, false); 2374 } else { 2375 return decodeVfpRegRegRegOp<VfnmsD>( 2376 machInst, vd, vn, vm, true); 2377 } 2378 } 2379 break; 2380 case 0xa: 2381 if ((opc3 & 0x1) == 0) { 2382 if (single) { 2383 return decodeVfpRegRegRegOp<VfmaS>( 2384 machInst, vd, vn, vm, false); 2385 } else { 2386 return decodeVfpRegRegRegOp<VfmaD>( 2387 machInst, vd, vn, vm, true); 2388 } 2389 } else { 2390 if (single) { 2391 return decodeVfpRegRegRegOp<VfmsS>( 2392 machInst, vd, vn, vm, false); 2393 } else { 2394 return decodeVfpRegRegRegOp<VfmsD>( 2395 machInst, vd, vn, vm, true); 2396 } 2397 } 2398 break; 2399 case 0xb: 2400 if ((opc3 & 0x1) == 0) { 2401 const uint32_t baseImm = 2402 bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4); 2403 if (single) { 2404 uint32_t imm = vfp_modified_imm(baseImm, FpDataType::Fp32); 2405 return decodeVfpRegImmOp<VmovImmS>( 2406 machInst, vd, imm, false); 2407 } else { 2408 uint64_t imm = vfp_modified_imm(baseImm, FpDataType::Fp64); 2409 return decodeVfpRegImmOp<VmovImmD>( 2410 machInst, vd, imm, true); 2411 } 2412 } 2413 switch (opc2) { 2414 case 0x0: 2415 if (opc3 == 1) { 2416 if (single) { 2417 return decodeVfpRegRegOp<VmovRegS>( 2418 machInst, vd, vm, false); 2419 } else { 2420 return decodeVfpRegRegOp<VmovRegD>( 2421 machInst, vd, vm, true); 2422 } 2423 } else { 2424 if (single) { 2425 return decodeVfpRegRegOp<VabsS>( 2426 machInst, vd, vm, false); 2427 } else { 2428 return decodeVfpRegRegOp<VabsD>( 2429 machInst, vd, vm, true); 2430 } 2431 } 2432 case 0x1: 2433 if (opc3 == 1) { 2434 if (single) { 2435 return decodeVfpRegRegOp<VnegS>( 2436 machInst, vd, vm, false); 2437 } else { 2438 return decodeVfpRegRegOp<VnegD>( 2439 machInst, vd, vm, true); 2440 } 2441 } else { 2442 if (single) { 2443 return decodeVfpRegRegOp<VsqrtS>( 2444 machInst, vd, vm, false); 2445 } else { 2446 return decodeVfpRegRegOp<VsqrtD>( 2447 machInst, vd, vm, true); 2448 } 2449 } 2450 case 0x2: 2451 case 0x3: 2452 { 2453 const bool toHalf = bits(machInst, 16); 2454 const bool top = bits(machInst, 7); 2455 if (top) { 2456 if (toHalf) { 2457 return new VcvtFpSFpHT(machInst, vd, vm); 2458 } else { 2459 return new VcvtFpHTFpS(machInst, vd, vm); 2460 } 2461 } else { 2462 if (toHalf) { 2463 return new VcvtFpSFpHB(machInst, vd, vm); 2464 } else { 2465 return new VcvtFpHBFpS(machInst, vd, vm); 2466 } 2467 } 2468 } 2469 case 0x4: 2470 if (single) { 2471 if (e) { 2472 return new VcmpeS(machInst, vd, vm); 2473 } else { 2474 return new VcmpS(machInst, vd, vm); 2475 } 2476 } else { 2477 if (e) { 2478 return new VcmpeD(machInst, vd, vm); 2479 } else { 2480 return new VcmpD(machInst, vd, vm); 2481 } 2482 } 2483 case 0x5: 2484 if (single) { 2485 if (e) { 2486 return new VcmpeZeroS(machInst, vd, 0); 2487 } else { 2488 return new VcmpZeroS(machInst, vd, 0); 2489 } 2490 } else { 2491 if (e) { 2492 return new VcmpeZeroD(machInst, vd, 0); 2493 } else { 2494 return new VcmpZeroD(machInst, vd, 0); 2495 } 2496 } 2497 case 0x7: 2498 if (opc3 == 0x3) { 2499 if (single) { 2500 vd = (IntRegIndex)((bits(machInst, 22) << 5) | 2501 (bits(machInst, 15, 12) << 1)); 2502 return new VcvtFpSFpD(machInst, vd, vm); 2503 } else { 2504 vd = (IntRegIndex)(bits(machInst, 22) | 2505 (bits(machInst, 15, 12) << 1)); 2506 return new VcvtFpDFpS(machInst, vd, vm); 2507 } 2508 } 2509 break; 2510 case 0x8: 2511 if (bits(machInst, 7) == 0) { 2512 if (single) { 2513 return new VcvtUIntFpS(machInst, vd, vm); 2514 } else { 2515 vm = (IntRegIndex)(bits(machInst, 5) | 2516 (bits(machInst, 3, 0) << 1)); 2517 return new VcvtUIntFpD(machInst, vd, vm); 2518 } 2519 } else { 2520 if (single) { 2521 return new VcvtSIntFpS(machInst, vd, vm); 2522 } else { 2523 vm = (IntRegIndex)(bits(machInst, 5) | 2524 (bits(machInst, 3, 0) << 1)); 2525 return new VcvtSIntFpD(machInst, vd, vm); 2526 } 2527 } 2528 case 0xa: 2529 { 2530 const bool half = (bits(machInst, 7) == 0); 2531 const uint32_t imm = bits(machInst, 5) | 2532 (bits(machInst, 3, 0) << 1); 2533 const uint32_t size = 2534 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2535 if (single) { 2536 if (half) { 2537 return new VcvtSHFixedFpS(machInst, vd, vd, size); 2538 } else { 2539 return new VcvtSFixedFpS(machInst, vd, vd, size); 2540 } 2541 } else { 2542 if (half) { 2543 return new VcvtSHFixedFpD(machInst, vd, vd, size); 2544 } else { 2545 return new VcvtSFixedFpD(machInst, vd, vd, size); 2546 } 2547 } 2548 } 2549 case 0xb: 2550 { 2551 const bool half = (bits(machInst, 7) == 0); 2552 const uint32_t imm = bits(machInst, 5) | 2553 (bits(machInst, 3, 0) << 1); 2554 const uint32_t size = 2555 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2556 if (single) { 2557 if (half) { 2558 return new VcvtUHFixedFpS(machInst, vd, vd, size); 2559 } else { 2560 return new VcvtUFixedFpS(machInst, vd, vd, size); 2561 } 2562 } else { 2563 if (half) { 2564 return new VcvtUHFixedFpD(machInst, vd, vd, size); 2565 } else { 2566 return new VcvtUFixedFpD(machInst, vd, vd, size); 2567 } 2568 } 2569 } 2570 case 0xc: 2571 if (bits(machInst, 7) == 0) { 2572 if (single) { 2573 return new VcvtFpUIntSR(machInst, vd, vm); 2574 } else { 2575 vd = (IntRegIndex)(bits(machInst, 22) | 2576 (bits(machInst, 15, 12) << 1)); 2577 return new VcvtFpUIntDR(machInst, vd, vm); 2578 } 2579 } else { 2580 if (single) { 2581 return new VcvtFpUIntS(machInst, vd, vm); 2582 } else { 2583 vd = (IntRegIndex)(bits(machInst, 22) | 2584 (bits(machInst, 15, 12) << 1)); 2585 return new VcvtFpUIntD(machInst, vd, vm); 2586 } 2587 } 2588 case 0xd: 2589 if (bits(machInst, 7) == 0) { 2590 if (single) { 2591 return new VcvtFpSIntSR(machInst, vd, vm); 2592 } else { 2593 vd = (IntRegIndex)(bits(machInst, 22) | 2594 (bits(machInst, 15, 12) << 1)); 2595 return new VcvtFpSIntDR(machInst, vd, vm); 2596 } 2597 } else { 2598 if (single) { 2599 return new VcvtFpSIntS(machInst, vd, vm); 2600 } else { 2601 vd = (IntRegIndex)(bits(machInst, 22) | 2602 (bits(machInst, 15, 12) << 1)); 2603 return new VcvtFpSIntD(machInst, vd, vm); 2604 } 2605 } 2606 case 0xe: 2607 { 2608 const bool half = (bits(machInst, 7) == 0); 2609 const uint32_t imm = bits(machInst, 5) | 2610 (bits(machInst, 3, 0) << 1); 2611 const uint32_t size = 2612 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2613 if (single) { 2614 if (half) { 2615 return new VcvtFpSHFixedS(machInst, vd, vd, size); 2616 } else { 2617 return new VcvtFpSFixedS(machInst, vd, vd, size); 2618 } 2619 } else { 2620 if (half) { 2621 return new VcvtFpSHFixedD(machInst, vd, vd, size); 2622 } else { 2623 return new VcvtFpSFixedD(machInst, vd, vd, size); 2624 } 2625 } 2626 } 2627 case 0xf: 2628 { 2629 const bool half = (bits(machInst, 7) == 0); 2630 const uint32_t imm = bits(machInst, 5) | 2631 (bits(machInst, 3, 0) << 1); 2632 const uint32_t size = 2633 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2634 if (single) { 2635 if (half) { 2636 return new VcvtFpUHFixedS(machInst, vd, vd, size); 2637 } else { 2638 return new VcvtFpUFixedS(machInst, vd, vd, size); 2639 } 2640 } else { 2641 if (half) { 2642 return new VcvtFpUHFixedD(machInst, vd, vd, size); 2643 } else { 2644 return new VcvtFpUFixedD(machInst, vd, vd, size); 2645 } 2646 } 2647 } 2648 } 2649 break; 2650 } 2651 return new Unknown(machInst); 2652 } 2653 ''' 2654}}; 2655 2656def format VfpData() {{ 2657 decode_block = ''' 2658 return decodeVfpData(machInst); 2659 ''' 2660}};
| 1639 case 0xc: 1640 case 0xe: 1641 if (b == 0x18) { 1642 if (size != 1 || (vm % 2)) 1643 return new Unknown(machInst); 1644 return new NVcvts2h<uint16_t>(machInst, vd, vm); 1645 } else if (b == 0x1c) { 1646 if (size != 1 || (vd % 2)) 1647 return new Unknown(machInst); 1648 return new NVcvth2s<uint16_t>(machInst, vd, vm); 1649 } else { 1650 return new Unknown(machInst); 1651 } 1652 default: 1653 return new Unknown(machInst); 1654 } 1655 case 0x3: 1656 if (bits(b, 4, 3) == 0x3) { 1657 if ((q && (vd % 2 || vm % 2)) || size != 2) { 1658 return new Unknown(machInst); 1659 } else { 1660 if (bits(b, 2)) { 1661 if (bits(b, 1)) { 1662 if (q) { 1663 return new NVcvt2ufxQ<float>( 1664 machInst, vd, vm, 0); 1665 } else { 1666 return new NVcvt2ufxD<float>( 1667 machInst, vd, vm, 0); 1668 } 1669 } else { 1670 if (q) { 1671 return new NVcvt2sfxQ<float>( 1672 machInst, vd, vm, 0); 1673 } else { 1674 return new NVcvt2sfxD<float>( 1675 machInst, vd, vm, 0); 1676 } 1677 } 1678 } else { 1679 if (bits(b, 1)) { 1680 if (q) { 1681 return new NVcvtu2fpQ<float>( 1682 machInst, vd, vm, 0); 1683 } else { 1684 return new NVcvtu2fpD<float>( 1685 machInst, vd, vm, 0); 1686 } 1687 } else { 1688 if (q) { 1689 return new NVcvts2fpQ<float>( 1690 machInst, vd, vm, 0); 1691 } else { 1692 return new NVcvts2fpD<float>( 1693 machInst, vd, vm, 0); 1694 } 1695 } 1696 } 1697 } 1698 } else if ((b & 0x1a) == 0x10) { 1699 if (bits(b, 2)) { 1700 if (q) { 1701 return new NVrecpeQFp<float>(machInst, vd, vm); 1702 } else { 1703 return new NVrecpeDFp<float>(machInst, vd, vm); 1704 } 1705 } else { 1706 if (q) { 1707 return new NVrecpeQ<uint32_t>(machInst, vd, vm); 1708 } else { 1709 return new NVrecpeD<uint32_t>(machInst, vd, vm); 1710 } 1711 } 1712 } else if ((b & 0x1a) == 0x12) { 1713 if (bits(b, 2)) { 1714 if (q) { 1715 return new NVrsqrteQFp<float>(machInst, vd, vm); 1716 } else { 1717 return new NVrsqrteDFp<float>(machInst, vd, vm); 1718 } 1719 } else { 1720 if (q) { 1721 return new NVrsqrteQ<uint32_t>(machInst, vd, vm); 1722 } else { 1723 return new NVrsqrteD<uint32_t>(machInst, vd, vm); 1724 } 1725 } 1726 } else { 1727 return new Unknown(machInst); 1728 } 1729 } 1730 return new Unknown(machInst); 1731 } 1732 1733 StaticInstPtr 1734 decodeNeonData(ExtMachInst machInst) 1735 { 1736 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 1737 const uint32_t a = bits(machInst, 23, 19); 1738 const uint32_t b = bits(machInst, 11, 8); 1739 const uint32_t c = bits(machInst, 7, 4); 1740 if (bits(a, 4) == 0) { 1741 return decodeNeonThreeRegistersSameLength(machInst); 1742 } else if ((c & 0x9) == 1) { 1743 if ((a & 0x7) == 0) { 1744 return decodeNeonOneRegModImm(machInst); 1745 } else { 1746 return decodeNeonTwoRegAndShift(machInst); 1747 } 1748 } else if ((c & 0x9) == 9) { 1749 return decodeNeonTwoRegAndShift(machInst); 1750 } else if (bits(a, 2, 1) != 0x3) { 1751 if ((c & 0x5) == 0) { 1752 return decodeNeonThreeRegDiffLengths(machInst); 1753 } else if ((c & 0x5) == 4) { 1754 return decodeNeonTwoRegScalar(machInst); 1755 } 1756 } else if ((a & 0x16) == 0x16) { 1757 const IntRegIndex vd = 1758 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1759 (bits(machInst, 22) << 4))); 1760 const IntRegIndex vn = 1761 (IntRegIndex)(2 * (bits(machInst, 19, 16) | 1762 (bits(machInst, 7) << 4))); 1763 const IntRegIndex vm = 1764 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 1765 (bits(machInst, 5) << 4))); 1766 if (!u) { 1767 if (bits(c, 0) == 0) { 1768 unsigned imm4 = bits(machInst, 11, 8); 1769 bool q = bits(machInst, 6); 1770 if (imm4 >= 16 && !q) 1771 return new Unknown(machInst); 1772 if (q) { 1773 return new NVextQ<uint8_t>(machInst, vd, vn, vm, imm4); 1774 } else { 1775 return new NVextD<uint8_t>(machInst, vd, vn, vm, imm4); 1776 } 1777 } 1778 } else if (bits(b, 3) == 0 && bits(c, 0) == 0) { 1779 return decodeNeonTwoRegMisc(machInst); 1780 } else if (bits(b, 3, 2) == 0x2 && bits(c, 0) == 0) { 1781 unsigned length = bits(machInst, 9, 8) + 1; 1782 if ((uint32_t)vn / 2 + length > 32) 1783 return new Unknown(machInst); 1784 if (bits(machInst, 6) == 0) { 1785 switch (length) { 1786 case 1: 1787 return new NVtbl1(machInst, vd, vn, vm); 1788 case 2: 1789 return new NVtbl2(machInst, vd, vn, vm); 1790 case 3: 1791 return new NVtbl3(machInst, vd, vn, vm); 1792 case 4: 1793 return new NVtbl4(machInst, vd, vn, vm); 1794 } 1795 } else { 1796 switch (length) { 1797 case 1: 1798 return new NVtbx1(machInst, vd, vn, vm); 1799 case 2: 1800 return new NVtbx2(machInst, vd, vn, vm); 1801 case 3: 1802 return new NVtbx3(machInst, vd, vn, vm); 1803 case 4: 1804 return new NVtbx4(machInst, vd, vn, vm); 1805 } 1806 } 1807 } else if (b == 0xc && (c & 0x9) == 0) { 1808 unsigned imm4 = bits(machInst, 19, 16); 1809 if (bits(imm4, 2, 0) == 0) 1810 return new Unknown(machInst); 1811 unsigned size = 0; 1812 while ((imm4 & 0x1) == 0) { 1813 size++; 1814 imm4 >>= 1; 1815 } 1816 unsigned index = imm4 >> 1; 1817 const bool q = bits(machInst, 6); 1818 return decodeNeonUTwoShiftSReg<NVdupD, NVdupQ>( 1819 q, size, machInst, vd, vm, index); 1820 } 1821 } 1822 return new Unknown(machInst); 1823 } 1824 ''' 1825}}; 1826 1827def format ThumbNeonMem() {{ 1828 decode_block = ''' 1829 return decodeNeonMem(machInst); 1830 ''' 1831}}; 1832 1833def format ThumbNeonData() {{ 1834 decode_block = ''' 1835 return decodeNeonData(machInst); 1836 ''' 1837}}; 1838 1839let {{ 1840 header_output = ''' 1841 StaticInstPtr 1842 decodeExtensionRegLoadStore(ExtMachInst machInst); 1843 ''' 1844 decoder_output = ''' 1845 StaticInstPtr 1846 decodeExtensionRegLoadStore(ExtMachInst machInst) 1847 { 1848 const uint32_t opcode = bits(machInst, 24, 20); 1849 const uint32_t offset = bits(machInst, 7, 0); 1850 const bool single = (bits(machInst, 8) == 0); 1851 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1852 RegIndex vd; 1853 if (single) { 1854 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1855 bits(machInst, 22)); 1856 } else { 1857 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1858 (bits(machInst, 22) << 5)); 1859 } 1860 switch (bits(opcode, 4, 3)) { 1861 case 0x0: 1862 if (bits(opcode, 4, 1) == 0x2 && 1863 !(machInst.thumb == 1 && bits(machInst, 28) == 1) && 1864 !(machInst.thumb == 0 && machInst.condCode == 0xf)) { 1865 if ((bits(machInst, 7, 4) & 0xd) != 1) { 1866 break; 1867 } 1868 const IntRegIndex rt = 1869 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1870 const IntRegIndex rt2 = 1871 (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1872 const bool op = bits(machInst, 20); 1873 uint32_t vm; 1874 if (single) { 1875 vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5); 1876 } else { 1877 vm = (bits(machInst, 3, 0) << 1) | 1878 (bits(machInst, 5) << 5); 1879 } 1880 if (op) { 1881 return new Vmov2Core2Reg(machInst, rt, rt2, 1882 (IntRegIndex)vm); 1883 } else { 1884 return new Vmov2Reg2Core(machInst, (IntRegIndex)vm, 1885 rt, rt2); 1886 } 1887 } 1888 break; 1889 case 0x1: 1890 { 1891 if (offset == 0 || vd + offset/2 > NumFloatV7ArchRegs) { 1892 break; 1893 } 1894 switch (bits(opcode, 1, 0)) { 1895 case 0x0: 1896 return new VLdmStm(machInst, rn, vd, single, 1897 true, false, false, offset); 1898 case 0x1: 1899 return new VLdmStm(machInst, rn, vd, single, 1900 true, false, true, offset); 1901 case 0x2: 1902 return new VLdmStm(machInst, rn, vd, single, 1903 true, true, false, offset); 1904 case 0x3: 1905 // If rn == sp, then this is called vpop. 1906 return new VLdmStm(machInst, rn, vd, single, 1907 true, true, true, offset); 1908 default: 1909 M5_UNREACHABLE; 1910 } 1911 } 1912 case 0x2: 1913 if (bits(opcode, 1, 0) == 0x2) { 1914 // If rn == sp, then this is called vpush. 1915 return new VLdmStm(machInst, rn, vd, single, 1916 false, true, false, offset); 1917 } else if (bits(opcode, 1, 0) == 0x3) { 1918 return new VLdmStm(machInst, rn, vd, single, 1919 false, true, true, offset); 1920 } 1921 M5_FALLTHROUGH; 1922 case 0x3: 1923 const bool up = (bits(machInst, 23) == 1); 1924 const uint32_t imm = bits(machInst, 7, 0) << 2; 1925 if (single) { 1926 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1927 (bits(machInst, 22))); 1928 } else { 1929 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1930 (bits(machInst, 22) << 5)); 1931 } 1932 if (bits(opcode, 1, 0) == 0x0) { 1933 if (single) { 1934 if (up) { 1935 return new %(vstr_us)s(machInst, vd, rn, up, imm); 1936 } else { 1937 return new %(vstr_s)s(machInst, vd, rn, up, imm); 1938 } 1939 } else { 1940 if (up) { 1941 return new %(vstr_ud)s(machInst, vd, vd + 1, 1942 rn, up, imm); 1943 } else { 1944 return new %(vstr_d)s(machInst, vd, vd + 1, 1945 rn, up, imm); 1946 } 1947 } 1948 } else if (bits(opcode, 1, 0) == 0x1) { 1949 if (single) { 1950 if (up) { 1951 return new %(vldr_us)s(machInst, vd, rn, up, imm); 1952 } else { 1953 return new %(vldr_s)s(machInst, vd, rn, up, imm); 1954 } 1955 } else { 1956 if (up) { 1957 return new %(vldr_ud)s(machInst, vd, vd + 1, 1958 rn, up, imm); 1959 } else { 1960 return new %(vldr_d)s(machInst, vd, vd + 1, 1961 rn, up, imm); 1962 } 1963 } 1964 } 1965 } 1966 return new Unknown(machInst); 1967 } 1968 ''' % { 1969 "vldr_us" : "VLDR_" + loadImmClassName(False, True, False), 1970 "vldr_s" : "VLDR_" + loadImmClassName(False, False, False), 1971 "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False), 1972 "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False), 1973 "vstr_us" : "VSTR_" + storeImmClassName(False, True, False), 1974 "vstr_s" : "VSTR_" + storeImmClassName(False, False, False), 1975 "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False), 1976 "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False) 1977 } 1978}}; 1979 1980def format ExtensionRegLoadStore() {{ 1981 decode_block = ''' 1982 return decodeExtensionRegLoadStore(machInst); 1983 ''' 1984}}; 1985 1986let {{ 1987 header_output = ''' 1988 StaticInstPtr 1989 decodeShortFpTransfer(ExtMachInst machInst); 1990 ''' 1991 decoder_output = ''' 1992 StaticInstPtr 1993 decodeShortFpTransfer(ExtMachInst machInst) 1994 { 1995 const uint32_t l = bits(machInst, 20); 1996 const uint32_t c = bits(machInst, 8); 1997 const uint32_t a = bits(machInst, 23, 21); 1998 const uint32_t b = bits(machInst, 6, 5); 1999 if ((machInst.thumb == 1 && bits(machInst, 28) == 1) || 2000 (machInst.thumb == 0 && machInst.condCode == 0xf)) { 2001 // Determine if this is backported aarch64 FP instruction 2002 const bool b31_b24 = bits(machInst, 31, 24) == 0xFE; 2003 const bool b23 = bits(machInst, 23); 2004 const bool b21_b18 = bits(machInst, 21, 18) == 0xE; 2005 const bool b11_b9 = bits(machInst, 11, 9) == 0x5; 2006 const bool sz = bits(machInst, 8); 2007 const bool b7_b6 = bits(machInst, 7, 6) == 0x1; 2008 const bool b6 = bits(machInst, 6) == 0x0; 2009 const bool b4 = bits(machInst, 4) == 0x0; 2010 if (b31_b24 && b23 && b21_b18 && b11_b9 && b7_b6 && b4) { 2011 // VINT* Integer Rounding Instructon 2012 const uint32_t rm = bits(machInst, 17, 16); 2013 2014 if (sz) { 2015 const IntRegIndex vd = 2016 (IntRegIndex)((bits(machInst, 22) << 5) | 2017 (bits(machInst, 15, 12) << 1)); 2018 const IntRegIndex vm = 2019 (IntRegIndex)((bits(machInst, 5) << 5) | 2020 (bits(machInst, 3, 0) << 1)); 2021 switch(rm) { 2022 case 0x0: 2023 return decodeVfpRegRegOp<VRIntAD>(machInst, vd, vm, 2024 true); 2025 case 0x1: 2026 return decodeVfpRegRegOp<VRIntND>(machInst, vd, vm, 2027 true); 2028 case 0x2: 2029 return decodeVfpRegRegOp<VRIntPD>(machInst, vd, vm, 2030 true); 2031 case 0x3: 2032 return decodeVfpRegRegOp<VRIntMD>(machInst, vd, vm, 2033 true); 2034 default: return new Unknown(machInst); 2035 } 2036 } else { 2037 const IntRegIndex vd = 2038 (IntRegIndex)(bits(machInst, 22) | 2039 (bits(machInst, 15, 12) << 1)); 2040 const IntRegIndex vm = 2041 (IntRegIndex)(bits(machInst, 5) | 2042 (bits(machInst, 3, 0) << 1)); 2043 switch(rm) { 2044 case 0x0: 2045 return decodeVfpRegRegOp<VRIntAS>(machInst, vd, vm, 2046 false); 2047 case 0x1: 2048 return decodeVfpRegRegOp<VRIntNS>(machInst, vd, vm, 2049 false); 2050 case 0x2: 2051 return decodeVfpRegRegOp<VRIntPS>(machInst, vd, vm, 2052 false); 2053 case 0x3: 2054 return decodeVfpRegRegOp<VRIntMS>(machInst, vd, vm, 2055 false); 2056 default: return new Unknown(machInst); 2057 } 2058 } 2059 } else if (b31_b24 && !b23 && b11_b9 && b6 && b4){ 2060 // VSEL* floating point conditional select 2061 2062 ConditionCode cond; 2063 switch(bits(machInst, 21, 20)) { 2064 case 0x0: cond = COND_EQ; break; 2065 case 0x1: cond = COND_VS; break; 2066 case 0x2: cond = COND_GE; break; 2067 case 0x3: cond = COND_GT; break; 2068 } 2069 2070 if (sz) { 2071 const IntRegIndex vd = 2072 (IntRegIndex)((bits(machInst, 22) << 5) | 2073 (bits(machInst, 15, 12) << 1)); 2074 const IntRegIndex vm = 2075 (IntRegIndex)((bits(machInst, 5) << 5) | 2076 (bits(machInst, 3, 0) << 1)); 2077 const IntRegIndex vn = 2078 (IntRegIndex)((bits(machInst, 7) << 5) | 2079 (bits(machInst, 19, 16) << 1)); 2080 return new VselD(machInst, vd, vn, vm, cond); 2081 } else { 2082 const IntRegIndex vd = 2083 (IntRegIndex)(bits(machInst, 22) | 2084 (bits(machInst, 15, 12) << 1)); 2085 const IntRegIndex vm = 2086 (IntRegIndex)(bits(machInst, 5) | 2087 (bits(machInst, 3, 0) << 1)); 2088 const IntRegIndex vn = 2089 (IntRegIndex)((bits(machInst, 19, 16) << 1) | 2090 bits(machInst, 7)); 2091 return new VselS(machInst, vd, vn, vm, cond); 2092 } 2093 } else { 2094 return new Unknown(machInst); 2095 } 2096 } 2097 if (l == 0 && c == 0) { 2098 if (a == 0) { 2099 const uint32_t vn = (bits(machInst, 19, 16) << 1) | 2100 bits(machInst, 7); 2101 const IntRegIndex rt = 2102 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2103 if (bits(machInst, 20) == 1) { 2104 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn); 2105 } else { 2106 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt); 2107 } 2108 } else if (a == 0x7) { 2109 const IntRegIndex rt = 2110 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2111 uint32_t reg = bits(machInst, 19, 16); 2112 uint32_t specReg; 2113 switch (reg) { 2114 case 0: 2115 specReg = MISCREG_FPSID; 2116 break; 2117 case 1: 2118 specReg = MISCREG_FPSCR; 2119 break; 2120 case 6: 2121 specReg = MISCREG_MVFR1; 2122 break; 2123 case 7: 2124 specReg = MISCREG_MVFR0; 2125 break; 2126 case 8: 2127 specReg = MISCREG_FPEXC; 2128 break; 2129 default: 2130 return new Unknown(machInst); 2131 } 2132 if (specReg == MISCREG_FPSCR) { 2133 return new VmsrFpscr(machInst, (IntRegIndex)specReg, rt); 2134 } else { 2135 uint32_t iss = mcrMrcIssBuild(0, bits(machInst, 3, 0), rt, 2136 reg, a, bits(machInst, 7, 5)); 2137 return new Vmsr(machInst, (IntRegIndex)specReg, rt, iss); 2138 } 2139 } 2140 } else if (l == 0 && c == 1) { 2141 if (bits(a, 2) == 0) { 2142 uint32_t vd = (bits(machInst, 7) << 5) | 2143 (bits(machInst, 19, 16) << 1); 2144 // Handle accessing each single precision half of the vector. 2145 vd += bits(machInst, 21); 2146 const IntRegIndex rt = 2147 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2148 if (bits(machInst, 22) == 1) { 2149 return new VmovCoreRegB(machInst, (IntRegIndex)vd, 2150 rt, bits(machInst, 6, 5)); 2151 } else if (bits(machInst, 5) == 1) { 2152 return new VmovCoreRegH(machInst, (IntRegIndex)vd, 2153 rt, bits(machInst, 6)); 2154 } else if (bits(machInst, 6) == 0) { 2155 return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt); 2156 } else { 2157 return new Unknown(machInst); 2158 } 2159 } else if (bits(b, 1) == 0) { 2160 bool q = bits(machInst, 21); 2161 unsigned be = (bits(machInst, 22) << 1) | (bits(machInst, 5)); 2162 IntRegIndex vd = (IntRegIndex)(2 * (uint32_t) 2163 (bits(machInst, 19, 16) | (bits(machInst, 7) << 4))); 2164 IntRegIndex rt = (IntRegIndex)(uint32_t) 2165 bits(machInst, 15, 12); 2166 if (q) { 2167 switch (be) { 2168 case 0: 2169 return new NVdupQGpr<uint32_t>(machInst, vd, rt); 2170 case 1: 2171 return new NVdupQGpr<uint16_t>(machInst, vd, rt); 2172 case 2: 2173 return new NVdupQGpr<uint8_t>(machInst, vd, rt); 2174 case 3: 2175 return new Unknown(machInst); 2176 } 2177 } else { 2178 switch (be) { 2179 case 0: 2180 return new NVdupDGpr<uint32_t>(machInst, vd, rt); 2181 case 1: 2182 return new NVdupDGpr<uint16_t>(machInst, vd, rt); 2183 case 2: 2184 return new NVdupDGpr<uint8_t>(machInst, vd, rt); 2185 case 3: 2186 return new Unknown(machInst); 2187 } 2188 } 2189 } 2190 } else if (l == 1 && c == 0) { 2191 if (a == 0) { 2192 const uint32_t vn = (bits(machInst, 19, 16) << 1) | 2193 bits(machInst, 7); 2194 const IntRegIndex rt = 2195 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2196 if (bits(machInst, 20) == 1) { 2197 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn); 2198 } else { 2199 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt); 2200 } 2201 } else if (a == 7) { 2202 const IntRegIndex rt = 2203 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2204 uint32_t reg = bits(machInst, 19, 16); 2205 uint32_t specReg; 2206 switch (reg) { 2207 case 0: 2208 specReg = MISCREG_FPSID; 2209 break; 2210 case 1: 2211 specReg = MISCREG_FPSCR; 2212 break; 2213 case 6: 2214 specReg = MISCREG_MVFR1; 2215 break; 2216 case 7: 2217 specReg = MISCREG_MVFR0; 2218 break; 2219 case 8: 2220 specReg = MISCREG_FPEXC; 2221 break; 2222 default: 2223 return new Unknown(machInst); 2224 } 2225 if (rt == 0xf) { 2226 if (specReg == MISCREG_FPSCR) { 2227 return new VmrsApsrFpscr(machInst); 2228 } else { 2229 return new Unknown(machInst); 2230 } 2231 } else if (specReg == MISCREG_FPSCR) { 2232 return new VmrsFpscr(machInst, rt, (IntRegIndex)specReg); 2233 } else { 2234 uint32_t iss = mcrMrcIssBuild(l, bits(machInst, 3, 0), rt, 2235 reg, a, bits(machInst, 7, 5)); 2236 return new Vmrs(machInst, rt, (IntRegIndex)specReg, iss); 2237 } 2238 } 2239 } else { 2240 uint32_t vd = (bits(machInst, 7) << 5) | 2241 (bits(machInst, 19, 16) << 1); 2242 // Handle indexing into each single precision half of the vector. 2243 vd += bits(machInst, 21); 2244 uint32_t index; 2245 const IntRegIndex rt = 2246 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2247 const bool u = (bits(machInst, 23) == 1); 2248 if (bits(machInst, 22) == 1) { 2249 index = bits(machInst, 6, 5); 2250 if (u) { 2251 return new VmovRegCoreUB(machInst, rt, 2252 (IntRegIndex)vd, index); 2253 } else { 2254 return new VmovRegCoreSB(machInst, rt, 2255 (IntRegIndex)vd, index); 2256 } 2257 } else if (bits(machInst, 5) == 1) { 2258 index = bits(machInst, 6); 2259 if (u) { 2260 return new VmovRegCoreUH(machInst, rt, 2261 (IntRegIndex)vd, index); 2262 } else { 2263 return new VmovRegCoreSH(machInst, rt, 2264 (IntRegIndex)vd, index); 2265 } 2266 } else if (bits(machInst, 6) == 0 && !u) { 2267 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd); 2268 } else { 2269 return new Unknown(machInst); 2270 } 2271 } 2272 return new Unknown(machInst); 2273 } 2274 ''' 2275}}; 2276 2277def format ShortFpTransfer() {{ 2278 decode_block = ''' 2279 return decodeShortFpTransfer(machInst); 2280 ''' 2281}}; 2282 2283let {{ 2284 header_output = ''' 2285 StaticInstPtr 2286 decodeVfpData(ExtMachInst machInst); 2287 ''' 2288 decoder_output = ''' 2289 StaticInstPtr 2290 decodeVfpData(ExtMachInst machInst) 2291 { 2292 const uint32_t opc1 = bits(machInst, 23, 20); 2293 const uint32_t opc2 = bits(machInst, 19, 16); 2294 const uint32_t opc3 = bits(machInst, 7, 6); 2295 //const uint32_t opc4 = bits(machInst, 3, 0); 2296 const bool single = (bits(machInst, 8) == 0); 2297 // Used to select between vcmp and vcmpe. 2298 const bool e = (bits(machInst, 7) == 1); 2299 IntRegIndex vd; 2300 IntRegIndex vm; 2301 IntRegIndex vn; 2302 if (single) { 2303 vd = (IntRegIndex)(bits(machInst, 22) | 2304 (bits(machInst, 15, 12) << 1)); 2305 vm = (IntRegIndex)(bits(machInst, 5) | 2306 (bits(machInst, 3, 0) << 1)); 2307 vn = (IntRegIndex)(bits(machInst, 7) | 2308 (bits(machInst, 19, 16) << 1)); 2309 } else { 2310 vd = (IntRegIndex)((bits(machInst, 22) << 5) | 2311 (bits(machInst, 15, 12) << 1)); 2312 vm = (IntRegIndex)((bits(machInst, 5) << 5) | 2313 (bits(machInst, 3, 0) << 1)); 2314 vn = (IntRegIndex)((bits(machInst, 7) << 5) | 2315 (bits(machInst, 19, 16) << 1)); 2316 } 2317 switch (opc1 & 0xb /* 1011 */) { 2318 case 0x0: 2319 if (bits(machInst, 6) == 0) { 2320 if (single) { 2321 return decodeVfpRegRegRegOp<VmlaS>( 2322 machInst, vd, vn, vm, false); 2323 } else { 2324 return decodeVfpRegRegRegOp<VmlaD>( 2325 machInst, vd, vn, vm, true); 2326 } 2327 } else { 2328 if (single) { 2329 return decodeVfpRegRegRegOp<VmlsS>( 2330 machInst, vd, vn, vm, false); 2331 } else { 2332 return decodeVfpRegRegRegOp<VmlsD>( 2333 machInst, vd, vn, vm, true); 2334 } 2335 } 2336 case 0x1: 2337 if (bits(machInst, 6) == 1) { 2338 if (single) { 2339 return decodeVfpRegRegRegOp<VnmlaS>( 2340 machInst, vd, vn, vm, false); 2341 } else { 2342 return decodeVfpRegRegRegOp<VnmlaD>( 2343 machInst, vd, vn, vm, true); 2344 } 2345 } else { 2346 if (single) { 2347 return decodeVfpRegRegRegOp<VnmlsS>( 2348 machInst, vd, vn, vm, false); 2349 } else { 2350 return decodeVfpRegRegRegOp<VnmlsD>( 2351 machInst, vd, vn, vm, true); 2352 } 2353 } 2354 case 0x2: 2355 if ((opc3 & 0x1) == 0) { 2356 if (single) { 2357 return decodeVfpRegRegRegOp<VmulS>( 2358 machInst, vd, vn, vm, false); 2359 } else { 2360 return decodeVfpRegRegRegOp<VmulD>( 2361 machInst, vd, vn, vm, true); 2362 } 2363 } else { 2364 if (single) { 2365 return decodeVfpRegRegRegOp<VnmulS>( 2366 machInst, vd, vn, vm, false); 2367 } else { 2368 return decodeVfpRegRegRegOp<VnmulD>( 2369 machInst, vd, vn, vm, true); 2370 } 2371 } 2372 case 0x3: 2373 if ((opc3 & 0x1) == 0) { 2374 if (single) { 2375 return decodeVfpRegRegRegOp<VaddS>( 2376 machInst, vd, vn, vm, false); 2377 } else { 2378 return decodeVfpRegRegRegOp<VaddD>( 2379 machInst, vd, vn, vm, true); 2380 } 2381 } else { 2382 if (single) { 2383 return decodeVfpRegRegRegOp<VsubS>( 2384 machInst, vd, vn, vm, false); 2385 } else { 2386 return decodeVfpRegRegRegOp<VsubD>( 2387 machInst, vd, vn, vm, true); 2388 } 2389 } 2390 case 0x8: 2391 if ((opc3 & 0x1) == 0) { 2392 if (single) { 2393 return decodeVfpRegRegRegOp<VdivS>( 2394 machInst, vd, vn, vm, false); 2395 } else { 2396 return decodeVfpRegRegRegOp<VdivD>( 2397 machInst, vd, vn, vm, true); 2398 } 2399 } 2400 break; 2401 case 0x9: 2402 if ((opc3 & 0x1) == 0) { 2403 if (single) { 2404 return decodeVfpRegRegRegOp<VfnmaS>( 2405 machInst, vd, vn, vm, false); 2406 } else { 2407 return decodeVfpRegRegRegOp<VfnmaD>( 2408 machInst, vd, vn, vm, true); 2409 } 2410 } else { 2411 if (single) { 2412 return decodeVfpRegRegRegOp<VfnmsS>( 2413 machInst, vd, vn, vm, false); 2414 } else { 2415 return decodeVfpRegRegRegOp<VfnmsD>( 2416 machInst, vd, vn, vm, true); 2417 } 2418 } 2419 break; 2420 case 0xa: 2421 if ((opc3 & 0x1) == 0) { 2422 if (single) { 2423 return decodeVfpRegRegRegOp<VfmaS>( 2424 machInst, vd, vn, vm, false); 2425 } else { 2426 return decodeVfpRegRegRegOp<VfmaD>( 2427 machInst, vd, vn, vm, true); 2428 } 2429 } else { 2430 if (single) { 2431 return decodeVfpRegRegRegOp<VfmsS>( 2432 machInst, vd, vn, vm, false); 2433 } else { 2434 return decodeVfpRegRegRegOp<VfmsD>( 2435 machInst, vd, vn, vm, true); 2436 } 2437 } 2438 break; 2439 case 0xb: 2440 if ((opc3 & 0x1) == 0) { 2441 const uint32_t baseImm = 2442 bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4); 2443 if (single) { 2444 uint32_t imm = vfp_modified_imm(baseImm, FpDataType::Fp32); 2445 return decodeVfpRegImmOp<VmovImmS>( 2446 machInst, vd, imm, false); 2447 } else { 2448 uint64_t imm = vfp_modified_imm(baseImm, FpDataType::Fp64); 2449 return decodeVfpRegImmOp<VmovImmD>( 2450 machInst, vd, imm, true); 2451 } 2452 } 2453 switch (opc2) { 2454 case 0x0: 2455 if (opc3 == 1) { 2456 if (single) { 2457 return decodeVfpRegRegOp<VmovRegS>( 2458 machInst, vd, vm, false); 2459 } else { 2460 return decodeVfpRegRegOp<VmovRegD>( 2461 machInst, vd, vm, true); 2462 } 2463 } else { 2464 if (single) { 2465 return decodeVfpRegRegOp<VabsS>( 2466 machInst, vd, vm, false); 2467 } else { 2468 return decodeVfpRegRegOp<VabsD>( 2469 machInst, vd, vm, true); 2470 } 2471 } 2472 case 0x1: 2473 if (opc3 == 1) { 2474 if (single) { 2475 return decodeVfpRegRegOp<VnegS>( 2476 machInst, vd, vm, false); 2477 } else { 2478 return decodeVfpRegRegOp<VnegD>( 2479 machInst, vd, vm, true); 2480 } 2481 } else { 2482 if (single) { 2483 return decodeVfpRegRegOp<VsqrtS>( 2484 machInst, vd, vm, false); 2485 } else { 2486 return decodeVfpRegRegOp<VsqrtD>( 2487 machInst, vd, vm, true); 2488 } 2489 } 2490 case 0x2: 2491 case 0x3: 2492 { 2493 const bool toHalf = bits(machInst, 16); 2494 const bool top = bits(machInst, 7); 2495 if (top) { 2496 if (toHalf) { 2497 return new VcvtFpSFpHT(machInst, vd, vm); 2498 } else { 2499 return new VcvtFpHTFpS(machInst, vd, vm); 2500 } 2501 } else { 2502 if (toHalf) { 2503 return new VcvtFpSFpHB(machInst, vd, vm); 2504 } else { 2505 return new VcvtFpHBFpS(machInst, vd, vm); 2506 } 2507 } 2508 } 2509 case 0x4: 2510 if (single) { 2511 if (e) { 2512 return new VcmpeS(machInst, vd, vm); 2513 } else { 2514 return new VcmpS(machInst, vd, vm); 2515 } 2516 } else { 2517 if (e) { 2518 return new VcmpeD(machInst, vd, vm); 2519 } else { 2520 return new VcmpD(machInst, vd, vm); 2521 } 2522 } 2523 case 0x5: 2524 if (single) { 2525 if (e) { 2526 return new VcmpeZeroS(machInst, vd, 0); 2527 } else { 2528 return new VcmpZeroS(machInst, vd, 0); 2529 } 2530 } else { 2531 if (e) { 2532 return new VcmpeZeroD(machInst, vd, 0); 2533 } else { 2534 return new VcmpZeroD(machInst, vd, 0); 2535 } 2536 } 2537 case 0x7: 2538 if (opc3 == 0x3) { 2539 if (single) { 2540 vd = (IntRegIndex)((bits(machInst, 22) << 5) | 2541 (bits(machInst, 15, 12) << 1)); 2542 return new VcvtFpSFpD(machInst, vd, vm); 2543 } else { 2544 vd = (IntRegIndex)(bits(machInst, 22) | 2545 (bits(machInst, 15, 12) << 1)); 2546 return new VcvtFpDFpS(machInst, vd, vm); 2547 } 2548 } 2549 break; 2550 case 0x8: 2551 if (bits(machInst, 7) == 0) { 2552 if (single) { 2553 return new VcvtUIntFpS(machInst, vd, vm); 2554 } else { 2555 vm = (IntRegIndex)(bits(machInst, 5) | 2556 (bits(machInst, 3, 0) << 1)); 2557 return new VcvtUIntFpD(machInst, vd, vm); 2558 } 2559 } else { 2560 if (single) { 2561 return new VcvtSIntFpS(machInst, vd, vm); 2562 } else { 2563 vm = (IntRegIndex)(bits(machInst, 5) | 2564 (bits(machInst, 3, 0) << 1)); 2565 return new VcvtSIntFpD(machInst, vd, vm); 2566 } 2567 } 2568 case 0xa: 2569 { 2570 const bool half = (bits(machInst, 7) == 0); 2571 const uint32_t imm = bits(machInst, 5) | 2572 (bits(machInst, 3, 0) << 1); 2573 const uint32_t size = 2574 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2575 if (single) { 2576 if (half) { 2577 return new VcvtSHFixedFpS(machInst, vd, vd, size); 2578 } else { 2579 return new VcvtSFixedFpS(machInst, vd, vd, size); 2580 } 2581 } else { 2582 if (half) { 2583 return new VcvtSHFixedFpD(machInst, vd, vd, size); 2584 } else { 2585 return new VcvtSFixedFpD(machInst, vd, vd, size); 2586 } 2587 } 2588 } 2589 case 0xb: 2590 { 2591 const bool half = (bits(machInst, 7) == 0); 2592 const uint32_t imm = bits(machInst, 5) | 2593 (bits(machInst, 3, 0) << 1); 2594 const uint32_t size = 2595 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2596 if (single) { 2597 if (half) { 2598 return new VcvtUHFixedFpS(machInst, vd, vd, size); 2599 } else { 2600 return new VcvtUFixedFpS(machInst, vd, vd, size); 2601 } 2602 } else { 2603 if (half) { 2604 return new VcvtUHFixedFpD(machInst, vd, vd, size); 2605 } else { 2606 return new VcvtUFixedFpD(machInst, vd, vd, size); 2607 } 2608 } 2609 } 2610 case 0xc: 2611 if (bits(machInst, 7) == 0) { 2612 if (single) { 2613 return new VcvtFpUIntSR(machInst, vd, vm); 2614 } else { 2615 vd = (IntRegIndex)(bits(machInst, 22) | 2616 (bits(machInst, 15, 12) << 1)); 2617 return new VcvtFpUIntDR(machInst, vd, vm); 2618 } 2619 } else { 2620 if (single) { 2621 return new VcvtFpUIntS(machInst, vd, vm); 2622 } else { 2623 vd = (IntRegIndex)(bits(machInst, 22) | 2624 (bits(machInst, 15, 12) << 1)); 2625 return new VcvtFpUIntD(machInst, vd, vm); 2626 } 2627 } 2628 case 0xd: 2629 if (bits(machInst, 7) == 0) { 2630 if (single) { 2631 return new VcvtFpSIntSR(machInst, vd, vm); 2632 } else { 2633 vd = (IntRegIndex)(bits(machInst, 22) | 2634 (bits(machInst, 15, 12) << 1)); 2635 return new VcvtFpSIntDR(machInst, vd, vm); 2636 } 2637 } else { 2638 if (single) { 2639 return new VcvtFpSIntS(machInst, vd, vm); 2640 } else { 2641 vd = (IntRegIndex)(bits(machInst, 22) | 2642 (bits(machInst, 15, 12) << 1)); 2643 return new VcvtFpSIntD(machInst, vd, vm); 2644 } 2645 } 2646 case 0xe: 2647 { 2648 const bool half = (bits(machInst, 7) == 0); 2649 const uint32_t imm = bits(machInst, 5) | 2650 (bits(machInst, 3, 0) << 1); 2651 const uint32_t size = 2652 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2653 if (single) { 2654 if (half) { 2655 return new VcvtFpSHFixedS(machInst, vd, vd, size); 2656 } else { 2657 return new VcvtFpSFixedS(machInst, vd, vd, size); 2658 } 2659 } else { 2660 if (half) { 2661 return new VcvtFpSHFixedD(machInst, vd, vd, size); 2662 } else { 2663 return new VcvtFpSFixedD(machInst, vd, vd, size); 2664 } 2665 } 2666 } 2667 case 0xf: 2668 { 2669 const bool half = (bits(machInst, 7) == 0); 2670 const uint32_t imm = bits(machInst, 5) | 2671 (bits(machInst, 3, 0) << 1); 2672 const uint32_t size = 2673 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2674 if (single) { 2675 if (half) { 2676 return new VcvtFpUHFixedS(machInst, vd, vd, size); 2677 } else { 2678 return new VcvtFpUFixedS(machInst, vd, vd, size); 2679 } 2680 } else { 2681 if (half) { 2682 return new VcvtFpUHFixedD(machInst, vd, vd, size); 2683 } else { 2684 return new VcvtFpUFixedD(machInst, vd, vd, size); 2685 } 2686 } 2687 } 2688 } 2689 break; 2690 } 2691 return new Unknown(machInst); 2692 } 2693 ''' 2694}}; 2695 2696def format VfpData() {{ 2697 decode_block = ''' 2698 return decodeVfpData(machInst); 2699 ''' 2700}};
|