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