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