1/* 2 * Copyright (c) 2017-2019 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 11 * unmodified and in its entirety in all distributions of the software, 12 * modified or unmodified, in source code or in binary form. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions are 16 * met: redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer; 18 * redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution; 21 * neither the name of the copyright holders nor the names of its 22 * contributors may be used to endorse or promote products derived from 23 * this software without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 * 37 * Authors: Giacomo Gabrielli 38 */ 39 40// TODO: add support for suffixes of register specifiers in disasm strings. 41 42#include "arch/arm/insts/sve.hh" 43 44namespace ArmISA { 45 46const char* 47svePredTypeToStr(SvePredType pt) 48{ 49 switch (pt) { 50 case SvePredType::MERGE: 51 return "m"; 52 case SvePredType::ZERO: 53 return "z"; 54 default: 55 return ""; 56 } 57} 58 59std::string 60SvePredCountPredOp::generateDisassembly(Addr pc, 61 const SymbolTable *symtab) const 62{ 63 std::stringstream ss; 64 printMnemonic(ss, "", false); 65 printIntReg(ss, dest); 66 ccprintf(ss, ", "); 67 printVecPredReg(ss, gp); 68 ccprintf(ss, ", "); 69 printVecPredReg(ss, op1); 70 return ss.str(); 71} 72 73std::string 74SvePredCountOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 75{ 76 std::stringstream ss; 77 printMnemonic(ss, "", false); 78 if (destIsVec) { 79 printVecReg(ss, dest, true); 80 } else { 81 printIntReg(ss, dest); 82 } 83 ccprintf(ss, ", "); 84 uint8_t opWidth = 64; 85 printVecPredReg(ss, gp); 86 ccprintf(ss, ", "); 87 if (srcIs32b) 88 opWidth = 32; 89 printIntReg(ss, dest, opWidth); 90 return ss.str(); 91} 92 93std::string 94SveIndexIIOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 95{ 96 std::stringstream ss; 97 printMnemonic(ss, "", false); 98 printVecReg(ss, dest, true); 99 ccprintf(ss, ", #%d, #%d", imm1, imm2); 100 return ss.str(); 101} 102 103std::string 104SveIndexIROp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 105{ 106 std::stringstream ss; 107 printMnemonic(ss, "", false); 108 printVecReg(ss, dest, true); 109 ccprintf(ss, ", #%d, ", imm1); 110 printIntReg(ss, op2); 111 return ss.str(); 112} 113 114std::string 115SveIndexRIOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 116{ 117 std::stringstream ss; 118 printMnemonic(ss, "", false); 119 printVecReg(ss, dest, true); 120 ccprintf(ss, ", "); 121 printIntReg(ss, op1); 122 ccprintf(ss, ", #%d", imm2); 123 return ss.str(); 124} 125 126std::string 127SveIndexRROp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 128{ 129 std::stringstream ss; 130 printMnemonic(ss, "", false); 131 printVecReg(ss, dest, true); 132 ccprintf(ss, ", "); 133 printIntReg(ss, op1); 134 ccprintf(ss, ", "); 135 printIntReg(ss, op2); 136 return ss.str(); 137} 138 139std::string 140SveWhileOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 141{ 142 std::stringstream ss; 143 printMnemonic(ss, "", false); 144 printVecPredReg(ss, dest); 145 ccprintf(ss, ", "); 146 uint8_t opWidth; 147 if (srcIs32b) 148 opWidth = 32; 149 else 150 opWidth = 64; 151 printIntReg(ss, op1, opWidth); 152 ccprintf(ss, ", "); 153 printIntReg(ss, op2, opWidth); 154 return ss.str(); 155} 156 157std::string 158SveCompTermOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 159{ 160 std::stringstream ss; 161 printMnemonic(ss, "", false); 162 printIntReg(ss, op1); 163 ccprintf(ss, ", "); 164 printIntReg(ss, op2); 165 return ss.str(); 166} 167 168std::string 169SveUnaryPredOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 170{ 171 std::stringstream ss; 172 printMnemonic(ss, "", false); 173 printVecReg(ss, dest, true); 174 ccprintf(ss, ", "); 175 printVecPredReg(ss, gp); 176 ccprintf(ss, "/m, "); 177 printVecReg(ss, op1, true); 178 return ss.str(); 179} 180 181std::string 182SveUnaryUnpredOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 183{ 184 std::stringstream ss; 185 printMnemonic(ss, "", false); 186 printVecReg(ss, dest, true); 187 ccprintf(ss, ", "); 188 printVecReg(ss, op1, true); 189 return ss.str(); 190} 191 192std::string 193SveUnaryWideImmUnpredOp::generateDisassembly(Addr pc, 194 const SymbolTable *symtab) const 195{ 196 std::stringstream ss; 197 printMnemonic(ss, "", false); 198 printVecReg(ss, dest, true); 199 ccprintf(ss, ", #"); 200 ss << imm; 201 return ss.str(); 202} 203 204std::string 205SveUnaryWideImmPredOp::generateDisassembly(Addr pc, 206 const SymbolTable *symtab) const 207{ 208 std::stringstream ss; 209 printMnemonic(ss, "", false); 210 printVecReg(ss, dest, true); 211 ccprintf(ss, ", "); 212 printVecPredReg(ss, gp); 213 ccprintf(ss, (isMerging ? "/m" : "/z")); 214 ccprintf(ss, ", #"); 215 ss << imm; 216 return ss.str(); 217} 218 219std::string 220SveBinImmUnpredConstrOp::generateDisassembly(Addr pc, 221 const SymbolTable *symtab) const 222{ 223 std::stringstream ss; 224 printMnemonic(ss, "", false); 225 printVecReg(ss, dest, true); 226 ccprintf(ss, ", "); 227 printVecPredReg(ss, op1); 228 ccprintf(ss, ", #"); 229 ss << imm; 230 return ss.str(); 231} 232 233std::string 234SveBinImmPredOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 235{ 236 std::stringstream ss; 237 printMnemonic(ss, "", false); 238 printVecReg(ss, dest, true); 239 ccprintf(ss, ", "); 240 printVecPredReg(ss, gp); 241 ccprintf(ss, "/m, "); 242 printVecReg(ss, dest, true); 243 ccprintf(ss, ", #"); 244 ss << imm; 245 return ss.str(); 246} 247 248std::string 249SveBinWideImmUnpredOp::generateDisassembly(Addr pc, 250 const SymbolTable *symtab) const 251{ 252 std::stringstream ss; 253 printMnemonic(ss, "", false); 254 printVecReg(ss, dest, true); 255 ccprintf(ss, ", "); 256 printVecReg(ss, dest, true); 257 ccprintf(ss, ", #"); 258 ss << imm; 259 return ss.str(); 260} 261 262std::string 263SveBinDestrPredOp::generateDisassembly(Addr pc, 264 const SymbolTable *symtab) const 265{ 266 std::stringstream ss; 267 printMnemonic(ss, "", false); 268 printVecReg(ss, dest, true); 269 ccprintf(ss, ", "); 270 printVecPredReg(ss, gp); 271 ccprintf(ss, "/m, "); 272 printVecReg(ss, dest, true); 273 ccprintf(ss, ", "); 274 printVecReg(ss, op2, true); 275 return ss.str(); 276} 277 278std::string 279SveBinConstrPredOp::generateDisassembly(Addr pc, 280 const SymbolTable *symtab) const 281{ 282 std::stringstream ss; 283 printMnemonic(ss, "", false); 284 printVecReg(ss, dest, true); 285 ccprintf(ss, ", "); 286 printVecPredReg(ss, gp); 287 if (predType == SvePredType::MERGE || predType == SvePredType::ZERO) { 288 ccprintf(ss, "/%s", svePredTypeToStr(predType)); 289 } 290 ccprintf(ss, ", "); 291 printVecReg(ss, op1, true); 292 ccprintf(ss, ", "); 293 printVecReg(ss, op2, true); 294 return ss.str(); 295} 296 297std::string 298SveBinUnpredOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 299{ 300 std::stringstream ss; 301 printMnemonic(ss, "", false); 302 printVecReg(ss, dest, true); 303 ccprintf(ss, ", "); 304 printVecReg(ss, op1, true); 305 ccprintf(ss, ", "); 306 printVecReg(ss, op2, true); 307 return ss.str(); 308} 309 310std::string 311SveBinIdxUnpredOp::generateDisassembly(Addr pc, 312 const SymbolTable *symtab) const 313{ 314 std::stringstream ss; 315 printMnemonic(ss, "", false); 316 printVecReg(ss, dest, true); 317 ccprintf(ss, ", "); 318 printVecReg(ss, op1, true); 319 ccprintf(ss, ", "); 320 printVecReg(ss, op2, true); 321 ccprintf(ss, "["); 322 ss << (uint64_t)index; 323 ccprintf(ss, "]"); 324 return ss.str(); 325} 326 327std::string 328SvePredLogicalOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 329{ 330 std::stringstream ss; 331 printMnemonic(ss, "", false); 332 printVecReg(ss, dest, true); 333 ccprintf(ss, ", "); 334 printVecPredReg(ss, gp); 335 if (isSel) { 336 ccprintf(ss, ", "); 337 } else { 338 ccprintf(ss, "/z, "); 339 } 340 printVecPredReg(ss, op1); 341 ccprintf(ss, ", "); 342 printVecPredReg(ss, op2); 343 return ss.str(); 344} 345 346std::string 347SvePredBinPermOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 348{ 349 std::stringstream ss; 350 printMnemonic(ss, "", false); 351 printVecPredReg(ss, dest); 352 ccprintf(ss, ", "); 353 printVecPredReg(ss, op1); 354 ccprintf(ss, ", "); 355 printVecPredReg(ss, op2); 356 return ss.str(); 357} 358 359std::string 360SveCmpOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 361{ 362 std::stringstream ss; 363 printMnemonic(ss, "", false); 364 printVecPredReg(ss, dest); 365 ccprintf(ss, ", "); 366 printVecPredReg(ss, gp); 367 ccprintf(ss, "/z, "); 368 printVecReg(ss, op1, true); 369 ccprintf(ss, ", "); 370 printVecReg(ss, op2, true); 371 return ss.str(); 372} 373 374std::string 375SveCmpImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 376{ 377 std::stringstream ss; 378 printMnemonic(ss, "", false); 379 printVecPredReg(ss, dest); 380 ccprintf(ss, ", "); 381 printVecPredReg(ss, gp); 382 ccprintf(ss, "/z, "); 383 printVecReg(ss, op1, true); 384 ccprintf(ss, ", #"); 385 ss << imm; 386 return ss.str(); 387} 388 389std::string 390SveTerPredOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 391{ 392 std::stringstream ss; 393 printMnemonic(ss, "", false); 394 printVecReg(ss, dest, true); 395 ccprintf(ss, ", "); 396 printVecPredReg(ss, gp); 397 ccprintf(ss, "/m, "); 398 printVecReg(ss, op1, true); 399 ccprintf(ss, ", "); 400 printVecReg(ss, op2, true); 401 return ss.str(); 402} 403 404std::string 405SveTerImmUnpredOp::generateDisassembly(Addr pc, 406 const SymbolTable *symtab) const 407{ 408 std::stringstream ss; 409 printMnemonic(ss, "", false); 410 printVecReg(ss, dest, true); 411 ccprintf(ss, ", "); 412 printVecReg(ss, dest, true); 413 ccprintf(ss, ", "); 414 printVecReg(ss, op2, true); 415 ccprintf(ss, ", #"); 416 ss << imm; 417 return ss.str(); 418} 419 420std::string 421SveReducOp::generateDisassembly(Addr pc, 422 const SymbolTable *symtab) const 423{ 424 std::stringstream ss; 425 printMnemonic(ss, "", false); 426 printFloatReg(ss, dest); 427 ccprintf(ss, ", "); 428 printVecPredReg(ss, gp); 429 ccprintf(ss, ", "); 430 printVecReg(ss, op1, true); 431 return ss.str(); 432} 433 434std::string 435SveOrdReducOp::generateDisassembly(Addr pc, 436 const SymbolTable *symtab) const 437{ 438 std::stringstream ss; 439 printMnemonic(ss, "", false); 440 printFloatReg(ss, dest); 441 ccprintf(ss, ", "); 442 printVecPredReg(ss, gp); 443 ccprintf(ss, ", "); 444 printFloatReg(ss, dest); 445 ccprintf(ss, ", "); 446 printVecReg(ss, op1, true); 447 return ss.str(); 448} 449 450std::string 451SvePtrueOp::generateDisassembly(Addr pc, 452 const SymbolTable *symtab) const 453{ 454 std::stringstream ss; 455 printMnemonic(ss, "", false); 456 printVecPredReg(ss, dest); 457 if (imm != 0x1f) { 458 ccprintf(ss, ", "); 459 ss << sveDisasmPredCountImm(imm); 460 } 461 return ss.str(); 462} 463 464std::string 465SveIntCmpOp::generateDisassembly(Addr pc, 466 const SymbolTable *symtab) const 467{ 468 std::stringstream ss; 469 printMnemonic(ss, "", false); 470 printVecPredReg(ss, dest); 471 ccprintf(ss, ", "); 472 printVecPredReg(ss, gp); 473 ccprintf(ss, "/z, "); 474 printVecReg(ss, op1, true); 475 ccprintf(ss, ", "); 476 if (op2IsWide) { 477 printVecReg(ss, op2, true); 478 } else { 479 printVecReg(ss, op2, true); 480 } 481 return ss.str(); 482} 483 484std::string 485SveIntCmpImmOp::generateDisassembly(Addr pc, 486 const SymbolTable *symtab) const 487{ 488 std::stringstream ss; 489 printMnemonic(ss, "", false); 490 printVecPredReg(ss, dest); 491 ccprintf(ss, "/z, "); 492 printVecPredReg(ss, gp); 493 ccprintf(ss, ", "); 494 printVecReg(ss, op1, true); 495 ccprintf(ss, ", #"); 496 ss << imm; 497 return ss.str(); 498} 499 500std::string 501SveAdrOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 502{ 503 std::stringstream ss; 504 printMnemonic(ss, "", false); 505 printVecReg(ss, dest, true); 506 ccprintf(ss, ", ["); 507 printVecReg(ss, op1, true); 508 ccprintf(ss, ", "); 509 printVecReg(ss, op2, true); 510 if (offsetFormat == SveAdrOffsetUnpackedSigned) { 511 ccprintf(ss, ", sxtw"); 512 } else if (offsetFormat == SveAdrOffsetUnpackedUnsigned) { 513 ccprintf(ss, ", uxtw"); 514 } else if (mult != 1) { 515 ccprintf(ss, ", lsl"); 516 } 517 if (mult != 1) { 518 ss << __builtin_ctz(mult); 519 } 520 ccprintf(ss, "]"); 521 return ss.str(); 522} 523 524std::string 525SveElemCountOp::generateDisassembly(Addr pc, 526 const SymbolTable *symtab) const 527{ 528 static const char suffix[9] = 529 {'\0', 'b', 'h', '\0', 'w', '\0', '\0', '\0', 'd'}; 530 std::stringstream ss; 531 ss << " " << mnemonic << suffix[esize] << " "; 532 if (dstIsVec) { 533 printVecReg(ss, dest, true); 534 } else { 535 if (dstIs32b) { 536 printIntReg(ss, dest, 32); 537 } else { 538 printIntReg(ss, dest, 64); 539 } 540 } 541 if (pattern != 0x1f) { 542 ccprintf(ss, ", "); 543 ss << sveDisasmPredCountImm(pattern); 544 if (imm != 1) { 545 ccprintf(ss, ", mul #"); 546 ss << std::to_string(imm); 547 } 548 } 549 return ss.str(); 550} 551 552std::string 553SvePartBrkOp::generateDisassembly(Addr pc, 554 const SymbolTable *symtab) const 555{ 556 std::stringstream ss; 557 printMnemonic(ss, "", false); 558 printVecPredReg(ss, dest); 559 ccprintf(ss, ", "); 560 printVecPredReg(ss, gp); 561 ccprintf(ss, isMerging ? "/m, " : "/z, "); 562 printVecPredReg(ss, op1); 563 return ss.str(); 564} 565 566std::string 567SvePartBrkPropOp::generateDisassembly(Addr pc, 568 const SymbolTable *symtab) const 569{ 570 std::stringstream ss; 571 printMnemonic(ss, "", false); 572 printVecPredReg(ss, dest); 573 ccprintf(ss, ", "); 574 printVecPredReg(ss, gp); 575 ccprintf(ss, "/z, "); 576 printVecPredReg(ss, op1); 577 ccprintf(ss, ", "); 578 printVecPredReg(ss, op2); 579 return ss.str(); 580} 581 582std::string 583SveSelectOp::generateDisassembly(Addr pc, 584 const SymbolTable *symtab) const 585{ 586 std::stringstream ss; 587 printMnemonic(ss, "", false); 588 if (scalar) 589 printIntReg(ss, dest, scalar_width); 590 else if (simdFp) 591 printFloatReg(ss, dest); 592 else 593 printVecReg(ss, dest, true); 594 ccprintf(ss, ", "); 595 printVecPredReg(ss, gp); 596 if (conditional) { 597 ccprintf(ss, ", "); 598 if (scalar) 599 printIntReg(ss, dest, scalar_width); 600 else 601 printVecReg(ss, dest, true); 602 } 603 ccprintf(ss, ", "); 604 printVecReg(ss, op1, true); 605 return ss.str(); 606} 607 608std::string 609SveUnaryPredPredOp::generateDisassembly(Addr pc, 610 const SymbolTable *symtab) const 611{ 612 std::stringstream ss; 613 printMnemonic(ss, "", false); 614 printVecPredReg(ss, dest); 615 ccprintf(ss, ", "); 616 printVecPredReg(ss, gp); 617 ccprintf(ss, ", "); 618 printVecPredReg(ss, op1); 619 return ss.str(); 620} 621 622std::string 623SveTblOp::generateDisassembly(Addr pc, 624 const SymbolTable *symtab) const 625{ 626 std::stringstream ss; 627 printMnemonic(ss, "", false); 628 printVecReg(ss, dest, true); 629 ccprintf(ss, ", { "); 630 printVecReg(ss, op1, true); 631 ccprintf(ss, " }, "); 632 printVecReg(ss, op2, true); 633 return ss.str(); 634} 635 636std::string 637SveUnpackOp::generateDisassembly(Addr pc, 638 const SymbolTable *symtab) const 639{ 640 std::stringstream ss; 641 printMnemonic(ss, "", false); 642 printVecPredReg(ss, dest); 643 ccprintf(ss, ", "); 644 printVecPredReg(ss, op1); 645 return ss.str(); 646} 647 648std::string 649SvePredTestOp::generateDisassembly(Addr pc, 650 const SymbolTable *symtab) const 651{ 652 std::stringstream ss; 653 printMnemonic(ss, "", false); 654 printVecPredReg(ss, gp); 655 ccprintf(ss, ", "); 656 printVecPredReg(ss, op1); 657 return ss.str(); 658} 659 660std::string 661SvePredUnaryWImplicitSrcOp::generateDisassembly(Addr pc, 662 const SymbolTable *symtab) const 663{ 664 std::stringstream ss; 665 printMnemonic(ss, "", false); 666 printVecPredReg(ss, dest); 667 return ss.str(); 668} 669 670std::string 671SvePredUnaryWImplicitSrcPredOp::generateDisassembly(Addr pc, 672 const SymbolTable *symtab) const 673{ 674 std::stringstream ss; 675 printMnemonic(ss, "", false); 676 printVecPredReg(ss, dest); 677 ccprintf(ss, ", "); 678 printVecPredReg(ss, gp); 679 ccprintf(ss, "/z, "); 680 return ss.str(); 681} 682 683std::string 684SvePredUnaryWImplicitDstOp::generateDisassembly(Addr pc, 685 const SymbolTable *symtab) const 686{ 687 std::stringstream ss; 688 printMnemonic(ss, "", false); 689 printVecPredReg(ss, op1); 690 return ss.str(); 691} 692 693std::string 694SveWImplicitSrcDstOp::generateDisassembly(Addr pc, 695 const SymbolTable *symtab) const 696{ 697 std::stringstream ss; 698 printMnemonic(ss, "", false); 699 return ss.str(); 700} 701 702std::string 703SveBinImmUnpredDestrOp::generateDisassembly(Addr pc, 704 const SymbolTable *symtab) const 705{ 706 std::stringstream ss; 707 printMnemonic(ss, "", false); 708 printVecReg(ss, dest, true); 709 ccprintf(ss, ", "); 710 printVecReg(ss, dest, true); 711 ccprintf(ss, ", "); 712 printVecReg(ss, op1, true); 713 ccprintf(ss, ", #"); 714 ss << imm; 715 return ss.str(); 716} 717 718std::string 719SveBinImmIdxUnpredOp::generateDisassembly(Addr pc, 720 const SymbolTable *symtab) const 721{ 722 std::stringstream ss; 723 printMnemonic(ss, "", false); 724 printVecReg(ss, dest, true); 725 ccprintf(ss, ", "); 726 printVecReg(ss, op1, true); 727 ccprintf(ss, "["); 728 ss << imm; 729 ccprintf(ss, "]"); 730 return ss.str(); 731} 732 733std::string 734SveUnarySca2VecUnpredOp::generateDisassembly(Addr pc, 735 const SymbolTable *symtab) const 736{ 737 std::stringstream ss; 738 printMnemonic(ss, "", false); 739 printVecReg(ss, dest, true); 740 ccprintf(ss, ", "); 741 if (simdFp) { 742 printFloatReg(ss, op1); 743 } else { 744 printIntReg(ss, op1); 745 } 746 return ss.str(); 747} 748 749std::string 750SveDotProdIdxOp::generateDisassembly(Addr pc, 751 const SymbolTable *symtab) const 752{ 753 std::stringstream ss; 754 printMnemonic(ss, "", false); 755 printVecReg(ss, dest, true); 756 ccprintf(ss, ", "); 757 printVecReg(ss, op1, true); 758 ccprintf(ss, ", "); 759 printVecReg(ss, op2, true); 760 ccprintf(ss, "["); 761 ccprintf(ss, "%lu", imm); 762 ccprintf(ss, "]"); 763 return ss.str(); 764} 765 766std::string 767SveDotProdOp::generateDisassembly(Addr pc, 768 const SymbolTable *symtab) const 769{ 770 std::stringstream ss; 771 printMnemonic(ss, "", false); 772 printVecReg(ss, dest, true); 773 ccprintf(ss, ", "); 774 printVecReg(ss, op1, true); 775 ccprintf(ss, ", "); 776 printVecReg(ss, op2, true); 777 return ss.str(); 778} 779 780std::string 781SveComplexOp::generateDisassembly(Addr pc, 782 const SymbolTable *symtab) const 783{ 784 std::stringstream ss; 785 printMnemonic(ss, "", false); 786 printVecPredReg(ss, dest); 787 ccprintf(ss, ", "); 788 printVecPredReg(ss, gp); 789 ccprintf(ss, "/m, "); 790 printVecPredReg(ss, op1); 791 ccprintf(ss, ", "); 792 printVecPredReg(ss, op2); 793 ccprintf(ss, ", #"); 794 const char* rotstr[4] = {"0", "90", "180", "270"}; 795 ccprintf(ss, rotstr[rot]); 796 797 return ss.str(); 798} 799 800std::string 801SveComplexIdxOp::generateDisassembly(Addr pc, 802 const SymbolTable *symtab) const 803{ 804 std::stringstream ss; 805 printMnemonic(ss, "", false); 806 printVecPredReg(ss, dest); 807 ccprintf(ss, ", "); 808 printVecPredReg(ss, op1); 809 ccprintf(ss, ", "); 810 printVecPredReg(ss, op2); 811 ccprintf(ss, "["); 812 ss << imm; 813 ccprintf(ss, "], #"); 814 const char* rotstr[4] = {"0", "90", "180", "270"}; 815 ccprintf(ss, rotstr[rot]); 816 return ss.str(); 817} 818 819std::string 820sveDisasmPredCountImm(uint8_t imm) 821{ 822 switch (imm) { 823 case 0x0: 824 return "POW2"; 825 case 0x1: 826 case 0x2: 827 case 0x3: 828 case 0x4: 829 case 0x5: 830 case 0x6: 831 case 0x7: 832 return "VL" + std::to_string(imm); 833 case 0x8: 834 case 0x9: 835 case 0xa: 836 case 0xb: 837 case 0xc: 838 case 0xd: 839 return "VL" + std::to_string(1 << ((imm & 0x7) + 3)); 840 case 0x1d: 841 return "MUL4"; 842 case 0x1e: 843 return "MUL3"; 844 case 0x1f: 845 return "ALL"; 846 default: 847 return "#" + std::to_string(imm); 848 } 849} 850 851unsigned int 852sveDecodePredCount(uint8_t imm, unsigned int num_elems) 853{ 854 assert(num_elems > 0); 855 856 switch (imm) { 857 case 0x0: 858 // POW2 859 return 1 << (31 - __builtin_clz((uint32_t) num_elems)); 860 case 0x1: 861 case 0x2: 862 case 0x3: 863 case 0x4: 864 case 0x5: 865 case 0x6: 866 case 0x7: 867 // VL1, VL2, VL3, VL4, VL5, VL6, VL7 868 return (num_elems >= imm) ? imm : 0; 869 case 0x8: 870 case 0x9: 871 case 0xa: 872 case 0xb: 873 case 0xc: 874 case 0xd: 875 // VL8, VL16, VL32, VL64, VL128, VL256 876 { 877 unsigned int pcount = 1 << ((imm & 0x7) + 3); 878 return (num_elems >= pcount) ? pcount : 0; 879 } 880 case 0x1d: 881 // MUL4 882 return num_elems - (num_elems % 4); 883 case 0x1e: 884 // MUL3 885 return num_elems - (num_elems % 3); 886 case 0x1f: 887 // ALL 888 return num_elems; 889 default: 890 return 0; 891 } 892} 893 894uint64_t 895sveExpandFpImmAddSub(uint8_t imm, uint8_t size) 896{ 897 static constexpr uint16_t fpOne16 = 0x3c00; 898 static constexpr uint16_t fpPointFive16 = 0x3800; 899 static constexpr uint32_t fpOne32 = 0x3f800000; 900 static constexpr uint32_t fpPointFive32 = 0x3f000000; 901 static constexpr uint64_t fpOne64 = 0x3ff0000000000000; 902 static constexpr uint64_t fpPointFive64 = 0x3fe0000000000000; 903 904 switch (size) { 905 case 0x1: 906 return imm ? fpOne16 : fpPointFive16; 907 case 0x2: 908 return imm ? fpOne32 : fpPointFive32; 909 case 0x3: 910 return imm ? fpOne64 : fpPointFive64; 911 default: 912 panic("Unsupported size"); 913 } 914} 915 916uint64_t 917sveExpandFpImmMaxMin(uint8_t imm, uint8_t size) 918{ 919 static constexpr uint16_t fpOne16 = 0x3c00; 920 static constexpr uint32_t fpOne32 = 0x3f800000; 921 static constexpr uint64_t fpOne64 = 0x3ff0000000000000; 922 923 switch (size) { 924 case 0x1: 925 return imm ? fpOne16 : 0x0; 926 case 0x2: 927 return imm ? fpOne32 : 0x0; 928 case 0x3: 929 return imm ? fpOne64 : 0x0; 930 default: 931 panic("Unsupported size"); 932 } 933} 934 935uint64_t 936sveExpandFpImmMul(uint8_t imm, uint8_t size) 937{ 938 static constexpr uint16_t fpTwo16 = 0x4000; 939 static constexpr uint16_t fpPointFive16 = 0x3800; 940 static constexpr uint32_t fpTwo32 = 0x40000000; 941 static constexpr uint32_t fpPointFive32 = 0x3f000000; 942 static constexpr uint64_t fpTwo64 = 0x4000000000000000; 943 static constexpr uint64_t fpPointFive64 = 0x3fe0000000000000; 944 945 switch (size) { 946 case 0x1: 947 return imm ? fpTwo16 : fpPointFive16; 948 case 0x2: 949 return imm ? fpTwo32 : fpPointFive32; 950 case 0x3: 951 return imm ? fpTwo64 : fpPointFive64; 952 default: 953 panic("Unsupported size"); 954 } 955} 956 957} // namespace ArmISA 958