1/* Copyright 2009-2023 Free Software Foundation, Inc. 2 3 This file is part of the Xilinx MicroBlaze simulator. 4 5 This library is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 3 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; if not, see <http://www.gnu.org/licenses/>. */ 17 18/* 19 * MICROBLAZE Instruction Set Architecture 20 * 21 * INSTRUCTION(NAME, 22 * OPCODE, 23 * TYPE, 24 * SEMANTICS) 25 * 26 */ 27 28INSTRUCTION(add, 29 0x00, 30 INST_TYPE_RD_RA_RB, 31 CARRY = C_calc(RA, RB, 0); 32 RD = RA + RB; 33 C_wr(CARRY); 34 PC += INST_SIZE) 35 36INSTRUCTION(rsub, 37 0x01, 38 INST_TYPE_RD_RA_RB, 39 CARRY = C_calc(RB, ~RA, 1); 40 RD = RB + ~RA + 1; 41 C_wr(CARRY); 42 PC += INST_SIZE) 43 44INSTRUCTION(addc, 45 0x02, 46 INST_TYPE_RD_RA_RB, 47 CARRY = C_calc(RA, RB, C_rd); 48 RD = RA + RB + C_rd; 49 C_wr(CARRY); 50 PC += INST_SIZE) 51 52INSTRUCTION(rsubc, 53 0x03, 54 INST_TYPE_RD_RA_RB, 55 CARRY = C_calc(RB, ~RA, C_rd); 56 RD = RB + ~RA + C_rd; 57 C_wr(CARRY); 58 PC += INST_SIZE) 59 60INSTRUCTION(addk, 61 0x04, 62 INST_TYPE_RD_RA_RB, 63 RD = RA + RB; 64 PC += INST_SIZE) 65 66INSTRUCTION(rsubk, 67 0x05, 68 INST_TYPE_RD_RA_RB, 69 RD = RB + ~RA + 1; 70 PC += INST_SIZE) 71 72INSTRUCTION(cmp, 73 0x05, 74 INST_TYPE_RD_RA_RB, 75 { 76 int tmp_reg = RB + ~RA + 1; 77 if ((RB & 0x80000000) ^ (RA & 0x80000000)) { 78 tmp_reg = ((tmp_reg & 0x7fffffff) | (RB & 0x80000000)); 79 } 80 RD = tmp_reg; 81 PC += INST_SIZE; 82 }) 83 84INSTRUCTION(cmpu, 85 0x05, 86 INST_TYPE_RD_RA_RB, 87 { 88 int tmp_reg = RB + ~RA + 1; 89 if ((RB & 0x80000000) ^ (RA & 0x80000000)) { 90 tmp_reg = ((tmp_reg & 0x7fffffff) | (RA & 0x80000000)); 91 } 92 RD = tmp_reg; 93 PC += INST_SIZE; 94 }) 95 96INSTRUCTION(addkc, 97 0x06, 98 INST_TYPE_RD_RA_RB, 99 RD = RA + RB + C_rd; 100 PC += INST_SIZE) 101 102INSTRUCTION(rsubkc, 103 0x07, 104 INST_TYPE_RD_RA_RB, 105 RD = RB + ~RA + C_rd; 106 PC += INST_SIZE) 107 108INSTRUCTION(addi, 109 0x08, 110 INST_TYPE_RD_RA_IMM, 111 CARRY = C_calc(RA, IMM, 0); 112 RD = RA + IMM; 113 TRACE_REGISTER (cpu, "r%i = r%i + %i", rd, ra, IMM); 114 C_wr(CARRY); 115 PC += INST_SIZE) 116 117INSTRUCTION(rsubi, 118 0x09, 119 INST_TYPE_RD_RA_IMM, 120 CARRY = C_calc(IMM, ~RA, 1); 121 RD = IMM + ~RA + 1; 122 C_wr(CARRY); 123 PC += INST_SIZE) 124 125INSTRUCTION(addic, 126 0x0A, 127 INST_TYPE_RD_RA_IMM, 128 CARRY = C_calc(RA, IMM, C_rd); 129 RD = RA + IMM + C_rd; 130 C_wr(CARRY); 131 PC += INST_SIZE) 132 133INSTRUCTION(rsubic, 134 0x0B, 135 INST_TYPE_RD_RA_IMM, 136 CARRY = C_calc(IMM, ~RA, C_rd); 137 RD = IMM + ~RA + C_rd; 138 C_wr(CARRY); 139 PC += INST_SIZE) 140 141INSTRUCTION(addik, 142 0x0C, 143 INST_TYPE_RD_RA_IMM, 144 RD = RA + IMM; 145 PC += INST_SIZE) 146 147INSTRUCTION(rsubik, 148 0x0D, 149 INST_TYPE_RD_RA_IMM, 150 RD = IMM + ~RA + 1; 151 PC += INST_SIZE) 152 153INSTRUCTION(addikc, 154 0x0E, 155 INST_TYPE_RD_RA_IMM, 156 RD = RA + IMM + C_rd; 157 PC += INST_SIZE) 158 159INSTRUCTION(rsubikc, 160 0x0F, 161 INST_TYPE_RD_RA_IMM, 162 RD = IMM + ~RA + C_rd; 163 PC += INST_SIZE) 164 165INSTRUCTION(mul, 166 0x10, 167 INST_TYPE_RD_RA_RB, 168 RD = RA * RB; 169 PC += INST_SIZE) 170 171INSTRUCTION(bsrl, 172 0x11, 173 INST_TYPE_RD_RA_RB, 174 RD = (unsigned_4)RA >> RB; 175 PC += INST_SIZE) 176 177INSTRUCTION(bsra, 178 0x11, 179 INST_TYPE_RD_RA_RB, 180 RD = (signed_4)RA >> RB; 181 PC += INST_SIZE) 182 183INSTRUCTION(bsll, 184 0x11, 185 INST_TYPE_RD_RA_RB, 186 RD = (unsigned_4)RA << RB; 187 PC += INST_SIZE) 188 189INSTRUCTION(idiv, 190 0x12, 191 INST_TYPE_RD_RA_RB, 192 RD = (signed_4) RB / (signed_4) RA; 193 PC += INST_SIZE) 194 195INSTRUCTION(idivu, 196 0x12, 197 INST_TYPE_RD_RA_RB, 198 RD = (unsigned_4) RB / (unsigned_4) RA; 199 PC += INST_SIZE) 200 201INSTRUCTION(muli, 202 0x18, 203 INST_TYPE_RD_RA_IMM, 204 RD = RA * IMM; 205 PC += INST_SIZE) 206 207INSTRUCTION(bsrli, 208 0x19, 209 INST_TYPE_RD_RA_IMM5, 210 RD = (unsigned_4)RA >> (IMM & 0x1F); 211 PC += INST_SIZE) 212 213INSTRUCTION(bsrai, 214 0x19, 215 INST_TYPE_RD_RA_IMM5, 216 RD = (signed_4)RA >> (IMM & 0x1F); 217 PC += INST_SIZE) 218 219INSTRUCTION(bslli, 220 0x19, 221 INST_TYPE_RD_RA_IMM5, 222 RD = (unsigned_4)RA << (IMM & 0x1F); 223 PC += INST_SIZE) 224 225INSTRUCTION(get, 226 0x1b, 227 INST_TYPE_RD_IMM12, 228 PC += INST_SIZE) 229 230INSTRUCTION(put, 231 0x1b, 232 INST_TYPE_R1_IMM12, 233 PC += INST_SIZE) 234 235INSTRUCTION(nget, 236 0x1b, 237 INST_TYPE_RD_IMM12, 238 PC += INST_SIZE) 239 240INSTRUCTION(nput, 241 0x1b, 242 INST_TYPE_R1_IMM12, 243 PC += INST_SIZE) 244 245INSTRUCTION(cget, 246 0x1b, 247 INST_TYPE_RD_IMM12, 248 PC += INST_SIZE) 249 250INSTRUCTION(cput, 251 0x1b, 252 INST_TYPE_R1_IMM12, 253 PC += INST_SIZE) 254 255INSTRUCTION(ncget, 256 0x1b, 257 INST_TYPE_RD_IMM12, 258 PC += INST_SIZE) 259 260INSTRUCTION(ncput, 261 0x1b, 262 INST_TYPE_R1_IMM12, 263 PC += INST_SIZE) 264 265INSTRUCTION(microblaze_or, 266 0x20, 267 INST_TYPE_RD_RA_RB, 268 RD = RA | RB; 269 PC += INST_SIZE) 270 271INSTRUCTION(microblaze_and, 272 0x21, 273 INST_TYPE_RD_RA_RB, 274 RD = RA & RB; 275 PC += INST_SIZE) 276 277INSTRUCTION(microblaze_xor, 278 0x22, 279 INST_TYPE_RD_RA_RB, 280 RD = RA ^ RB; 281 PC += INST_SIZE) 282 283INSTRUCTION(andn, 284 0x23, 285 INST_TYPE_RD_RA_RB, 286 RD = RA & ~RB; 287 PC += INST_SIZE) 288 289INSTRUCTION(sra, 290 0x24, 291 INST_TYPE_RD_RA, 292 CARRY = (RA & 0x1); 293 RD = (int) (RA >> 1); 294 C_wr(CARRY); 295 PC += INST_SIZE) 296 297INSTRUCTION(src, 298 0x24, 299 INST_TYPE_RD_RA, 300 CARRY = (RA & 0x1); 301 RD = ((((int) (RA >> 1)) & 0x7FFFFFFF) | (unsigned_4)(C_rd << 31)); 302 C_wr(CARRY); 303 PC += INST_SIZE) 304 305INSTRUCTION(srl, 306 0x24, 307 INST_TYPE_RD_RA, 308 CARRY = (RA & 0x1); 309 RD = (unsigned_4) ((RA >> 1) & 0x7FFFFFFF); 310 C_wr(CARRY); 311 PC += INST_SIZE) 312 313INSTRUCTION(sext8, 314 0x24, 315 INST_TYPE_RD_RA, 316 RD = MICROBLAZE_SEXT8(RA); 317 PC += INST_SIZE) 318 319INSTRUCTION(sext16, 320 0x24, 321 INST_TYPE_RD_RA, 322 RD = MICROBLAZE_SEXT16(RA); 323 PC += INST_SIZE) 324 325INSTRUCTION(wdc, 326 0x24, 327 INST_TYPE_RA_RB, 328 PC += INST_SIZE) 329 330INSTRUCTION(wic, 331 0x24, 332 INST_TYPE_RA_RB, 333 PC += INST_SIZE) 334 335INSTRUCTION(mts, 336 0x25, 337 INST_TYPE_SA_RA, 338 SA = RA; 339 PC += INST_SIZE) 340 341INSTRUCTION(mfs, 342 0x25, 343 INST_TYPE_RD_SA, 344 RD = SA; 345 PC += INST_SIZE) 346 347INSTRUCTION(br, 348 0x26, 349 INST_TYPE_RB, 350 PC += RB; 351 BRANCH) 352 353INSTRUCTION(brd, 354 0x26, 355 INST_TYPE_RB, 356 PC += RB; 357 BRANCH; 358 DELAY_SLOT) 359 360INSTRUCTION(brld, 361 0x26, 362 INST_TYPE_RD_RB, 363 RD = PC; 364 PC += RB; 365 BRANCH; 366 DELAY_SLOT) 367 368INSTRUCTION(bra, 369 0x26, 370 INST_TYPE_RB, 371 PC = RB; 372 BRANCH) 373 374INSTRUCTION(brad, 375 0x26, 376 INST_TYPE_RB, 377 PC = RB; 378 BRANCH; 379 DELAY_SLOT) 380 381INSTRUCTION(brald, 382 0x26, 383 INST_TYPE_RD_RB, 384 RD = PC; 385 PC = RB; 386 BRANCH; 387 DELAY_SLOT) 388 389INSTRUCTION(microblaze_brk, 390 0x26, 391 INST_TYPE_RD_RB, 392 RD = PC; 393 PC = RB; 394 MSR = MSR | BIP_MASK; 395 BRANCH) 396 397INSTRUCTION(beq, 398 0x27, 399 INST_TYPE_RA_RB, 400 if (RA == 0) { 401 PC += RB; 402 BRANCH; 403 } else { 404 PC += INST_SIZE; 405 }) 406 407INSTRUCTION(beqd, 408 0x27, 409 INST_TYPE_RA_RB, 410 if (RA == 0) { 411 PC += RB; 412 BRANCH; 413 } else { 414 PC += INST_SIZE; 415 } 416 DELAY_SLOT) 417 418INSTRUCTION(bne, 419 0x27, 420 INST_TYPE_RA_RB, 421 if (RA != 0) { 422 PC += RB; 423 BRANCH; 424 } else { 425 PC += INST_SIZE; 426 }) 427 428INSTRUCTION(bned, 429 0x27, 430 INST_TYPE_RA_RB, 431 if (RA != 0) { 432 PC += RB; 433 BRANCH; 434 } else { 435 PC += INST_SIZE; 436 } 437 DELAY_SLOT) 438 439INSTRUCTION(blt, 440 0x27, 441 INST_TYPE_RA_RB, 442 if (RA < 0) { 443 PC += RB; 444 BRANCH; 445 } else { 446 PC += INST_SIZE; 447 }) 448 449INSTRUCTION(bltd, 450 0x27, 451 INST_TYPE_RA_RB, 452 if (RA < 0) { 453 PC += RB; 454 BRANCH; 455 } else { 456 PC += INST_SIZE; 457 } 458 DELAY_SLOT) 459 460INSTRUCTION(ble, 461 0x27, 462 INST_TYPE_RA_RB, 463 if (RA <= 0) { 464 PC += RB; 465 BRANCH; 466 } else { 467 PC += INST_SIZE; 468 }) 469 470INSTRUCTION(bled, 471 0x27, 472 INST_TYPE_RA_RB, 473 if (RA <= 0) { 474 PC += RB; 475 BRANCH; 476 } else { 477 PC += INST_SIZE; 478 } 479 DELAY_SLOT) 480 481INSTRUCTION(bgt, 482 0x27, 483 INST_TYPE_RA_RB, 484 if (RA > 0) { 485 PC += RB; 486 BRANCH; 487 } else { 488 PC += INST_SIZE; 489 }) 490 491INSTRUCTION(bgtd, 492 0x27, 493 INST_TYPE_RA_RB, 494 if (RA > 0) { 495 PC += RB; 496 BRANCH; 497 } else { 498 PC += INST_SIZE; 499 } 500 DELAY_SLOT) 501 502INSTRUCTION(bge, 503 0x27, 504 INST_TYPE_RA_RB, 505 if (RA >= 0) { 506 PC += RB; 507 BRANCH; 508 } else { 509 PC += INST_SIZE; 510 }) 511 512INSTRUCTION(bged, 513 0x27, 514 INST_TYPE_RA_RB, 515 if (RA >= 0) { 516 PC += RB; 517 BRANCH; 518 } else { 519 PC += INST_SIZE; 520 } 521 DELAY_SLOT) 522 523INSTRUCTION(ori, 524 0x28, 525 INST_TYPE_RD_RA_IMM, 526 RD = RA | IMM; 527 PC += INST_SIZE) 528 529INSTRUCTION(andi, 530 0x29, 531 INST_TYPE_RD_RA_IMM, 532 RD = RA & IMM; 533 PC += INST_SIZE) 534 535INSTRUCTION(xori, 536 0x2A, 537 INST_TYPE_RD_RA_IMM, 538 RD = RA ^ IMM; 539 PC += INST_SIZE) 540 541INSTRUCTION(andni, 542 0x2B, 543 INST_TYPE_RD_RA_IMM, 544 RD = RA & ~IMM; 545 PC += INST_SIZE) 546 547INSTRUCTION(imm, 548 0x2C, 549 INST_TYPE_IMM, 550 IMM_H = IMM_L; 551 PC += INST_SIZE) 552 553INSTRUCTION(rtsd, 554 0x2D, 555 INST_TYPE_RA_IMM, 556 PC = RA + IMM; 557 BRANCH; 558 DELAY_SLOT) 559 560INSTRUCTION(rtid, 561 0x2D, 562 INST_TYPE_RA_IMM, 563 PC = RA + IMM; 564 MSR = MSR | INTR_EN_MASK; 565 BRANCH; 566 DELAY_SLOT) 567 568INSTRUCTION(rtbd, 569 0x2D, 570 INST_TYPE_RA_IMM, 571 PC = RA + IMM; 572 MSR = MSR & ~BIP_MASK; 573 BRANCH; 574 DELAY_SLOT;) 575 576INSTRUCTION(bri, 577 0x2E, 578 INST_TYPE_IMM, 579 PC += IMM; 580 BRANCH) 581 582INSTRUCTION(brid, 583 0x2E, 584 INST_TYPE_IMM, 585 PC += IMM; 586 BRANCH; 587 DELAY_SLOT) 588 589INSTRUCTION(brlid, 590 0x2E, 591 INST_TYPE_RD_IMM, 592 RD = PC; 593 PC += IMM; 594 BRANCH; 595 DELAY_SLOT) 596 597INSTRUCTION(brai, 598 0x2E, 599 INST_TYPE_IMM, 600 PC = IMM; 601 BRANCH) 602 603INSTRUCTION(braid, 604 0x2E, 605 INST_TYPE_IMM, 606 PC = IMM; 607 BRANCH; 608 DELAY_SLOT) 609 610INSTRUCTION(bralid, 611 0x2E, 612 INST_TYPE_RD_IMM, 613 RD = PC; 614 PC = IMM; 615 BRANCH; 616 DELAY_SLOT) 617 618INSTRUCTION(brki, 619 0x2E, 620 INST_TYPE_RD_IMM, 621 RD = PC; 622 PC = IMM; 623 MSR = MSR | BIP_MASK; 624 BRANCH) 625 626INSTRUCTION(beqi, 627 0x2F, 628 INST_TYPE_RA_IMM, 629 if (RA == 0) { 630 PC += IMM; 631 BRANCH; 632 } else { 633 PC += INST_SIZE; 634 }) 635 636INSTRUCTION(beqid, 637 0x2F, 638 INST_TYPE_RA_IMM, 639 if (RA == 0) { 640 PC += IMM; 641 BRANCH; 642 } else { 643 PC += INST_SIZE; 644 } 645 DELAY_SLOT) 646 647INSTRUCTION(bnei, 648 0x2F, 649 INST_TYPE_RA_IMM, 650 if (RA != 0) { 651 PC += IMM; 652 BRANCH; 653 } else { 654 PC += INST_SIZE; 655 }) 656 657INSTRUCTION(bneid, 658 0x2F, 659 INST_TYPE_RA_IMM, 660 if (RA != 0) { 661 PC += IMM; 662 BRANCH; 663 } else { 664 PC += INST_SIZE; 665 } 666 DELAY_SLOT) 667 668INSTRUCTION(blti, 669 0x2F, 670 INST_TYPE_RA_IMM, 671 if (RA < 0) { 672 PC += IMM; 673 BRANCH; 674 } else { 675 PC += INST_SIZE; 676 }) 677 678INSTRUCTION(bltid, 679 0x2F, 680 INST_TYPE_RA_IMM, 681 if (RA < 0) { 682 PC += IMM; 683 BRANCH; 684 } else { 685 PC += INST_SIZE; 686 } 687 DELAY_SLOT) 688 689INSTRUCTION(blei, 690 0x2F, 691 INST_TYPE_RA_IMM, 692 if (RA <= 0) { 693 PC += IMM; 694 BRANCH; 695 } else { 696 PC += INST_SIZE; 697 }) 698 699INSTRUCTION(bleid, 700 0x2F, 701 INST_TYPE_RA_IMM, 702 if (RA <= 0) { 703 PC += IMM; 704 BRANCH; 705 } else { 706 PC += INST_SIZE; 707 } 708 DELAY_SLOT) 709 710INSTRUCTION(bgti, 711 0x2F, 712 INST_TYPE_RA_IMM, 713 if (RA > 0) { 714 PC += IMM; 715 BRANCH; 716 } else { 717 PC += INST_SIZE; 718 }) 719 720INSTRUCTION(bgtid, 721 0x2F, 722 INST_TYPE_RA_IMM, 723 if (RA > 0) { 724 PC += IMM; 725 BRANCH; 726 } else { 727 PC += INST_SIZE; 728 } 729 DELAY_SLOT) 730 731INSTRUCTION(bgei, 732 0x2F, 733 INST_TYPE_RA_IMM, 734 if (RA >= 0) { 735 PC += IMM; 736 BRANCH; 737 } else { 738 PC += INST_SIZE; 739 }) 740 741INSTRUCTION(bgeid, 742 0x2F, 743 INST_TYPE_RA_IMM, 744 if (RA >= 0) { 745 PC += IMM; 746 BRANCH; 747 } else { 748 PC += INST_SIZE; 749 } 750 DELAY_SLOT) 751 752INSTRUCTION(lbu, 753 0x30, 754 INST_TYPE_RD_RA_RB, 755 RD = (MEM_RD_UBYTE(RA + RB)); 756 PC += INST_SIZE) 757 758INSTRUCTION(lhu, 759 0x31, 760 INST_TYPE_RD_RA_RB, 761 RD = (MEM_RD_UHALF((RA + RB) & ~0x1)); 762 PC += INST_SIZE) 763 764INSTRUCTION(lw, 765 0x32, 766 INST_TYPE_RD_RA_RB, 767 RD = (MEM_RD_WORD((RA + RB) & ~0x3)); 768 PC += INST_SIZE) 769 770INSTRUCTION(sb, 771 0x34, 772 INST_TYPE_RD_RA_RB, 773 MEM_WR_BYTE(RA + RB, RD); 774 PC += INST_SIZE) 775 776INSTRUCTION(sh, 777 0x35, 778 INST_TYPE_RD_RA_RB, 779 MEM_WR_HALF((RA + RB) & ~0x1, RD); 780 PC += INST_SIZE) 781 782INSTRUCTION(sw, 783 0x36, 784 INST_TYPE_RD_RA_RB, 785 MEM_WR_WORD((RA + RB) & ~0x3, RD); 786 PC += INST_SIZE) 787 788INSTRUCTION(lbui, 789 0x38, 790 INST_TYPE_RD_RA_IMM, 791 RD = (MEM_RD_UBYTE(RA + IMM)); 792 PC += INST_SIZE) 793 794INSTRUCTION(lhui, 795 0x39, 796 INST_TYPE_RD_RA_IMM, 797 RD = (MEM_RD_UHALF((RA+IMM) & ~0x1)); 798 PC += INST_SIZE) 799 800INSTRUCTION(lwi, 801 0x3A, 802 INST_TYPE_RD_RA_IMM, 803 RD = (MEM_RD_WORD((RA+IMM) & ~0x3)); 804 PC += INST_SIZE) 805 806INSTRUCTION(sbi, 807 0x3C, 808 INST_TYPE_RD_RA_IMM, 809 MEM_WR_BYTE(RA + IMM, RD); 810 PC += INST_SIZE) 811 812INSTRUCTION(shi, 813 0x3D, 814 INST_TYPE_RD_RA_IMM, 815 MEM_WR_HALF((RA + IMM) & ~0x1, RD); 816 PC += INST_SIZE) 817 818INSTRUCTION(swi, 819 0x3E, 820 INST_TYPE_RD_RA_IMM, 821 MEM_WR_WORD((RA + IMM) & ~0x3, RD); 822 PC += INST_SIZE) 823