Skip to content
Snippets Groups Projects
lm32.cpu 21.5 KiB
Newer Older
Nick Clifton's avatar
Nick Clifton committed
; Lattice Mico32 CPU description.  -*- Scheme -*-
Nick Clifton's avatar
Nick Clifton committed
; Copyright 2008-2013  Free Software Foundation, Inc.
Nick Clifton's avatar
Nick Clifton committed
; Contributed by Jon Beniston <jon@beniston.com>
;
; This file is part of the GNU Binutils.
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 3 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, write to the Free Software
; Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
; MA 02110-1301, USA.

(include "simplify.inc")

(define-arch
  (name lm32) ; name of cpu family
  (comment "Lattice Mico32")
  (default-alignment aligned)
  (insn-lsb0? #t)
  (machs lm32)
  (isas lm32)
)


; Instruction sets.

(define-isa
  (name lm32)
  (comment "Lattice Mico32 ISA")
  (default-insn-word-bitsize 32)
  (default-insn-bitsize 32)
  (base-insn-bitsize 32)
  (decode-assist (31 30 29 28 27 26))
)


; Cpu family definitions.

(define-cpu
  ; cpu names must be distinct from the architecture name and machine name
  (name lm32bf)
  (comment "Lattice Mico32 CPU")
  (endian big)
  (word-bitsize 32)
)

(define-mach
  (name lm32)
  (comment "Lattice Mico32 MACH")
  (cpu lm32bf)
)

(define-model
  (name lm32)
  (comment "Lattice Mico32 reference implementation")
  (mach lm32)
  (unit u-exec "Execution unit" ()
    1 1 () () () ())
) 


; Hardware elements.

(dnh h-pc "Program counter" (PC) (pc) () () ())

(dnh h-gr "General purpose registers"
  ()
  (register SI (32))
  (keyword "" ( 
               (gp 26) (fp 27) (sp 28) (ra 29) (ea 30) (ba 31)
               (r0 0) (r1 1) (r2 2) (r3 3)
               (r4 4) (r5 5) (r6 6) (r7 7)
               (r8 8) (r9 9) (r10 10) (r11 11)
               (r12 12) (r13 13) (r14 14) (r15 15)
               (r16 16) (r17 17) (r18 18) (r19 19)
               (r20 20) (r21 21) (r22 22) (r23 23)
               (r24 24) (r25 25) (r26 26) (r27 27)
               (r28 28) (r29 29) (r30 30) (r31 31)                
              )
  )
  () ()
)
  
(dnh h-csr "Control and status registers"
  ()
  (register SI (32))
  (keyword "" (
               (IE 0) (IM 1) (IP 2) 
               (ICC 3) (DCC 4)
               (CC 5)
               (CFG 6)
               (EBA 7)
               (DC 8)
               (DEBA 9)
Nick Clifton's avatar
Nick Clifton committed
	       (CFG2 10)
Nick Clifton's avatar
Nick Clifton committed
               (JTX 14) (JRX 15)          
               (BP0 16) (BP1 17) (BP2 18) (BP3 19)
               (WP0 24) (WP1 25) (WP2 26) (WP3 27)     
Nick Clifton's avatar
Nick Clifton committed
               (PSW 29) (TLBVADDR 30) (TLBPADDR 31) (TLBBADVADDR 31)
Nick Clifton's avatar
Nick Clifton committed
              )
  )
  () ()
)              
  

; Instruction fields.

(dnf f-opcode   "opcode field"                () 31  6)
(dnf f-r0       "register index 0 field"      () 25  5)
(dnf f-r1       "register index 1 field"      () 20  5)
(dnf f-r2       "register index 2 field"      () 15  5)
(dnf f-resv0    "reserved"                    (RESERVED) 10 11)
(dnf f-shift    "shift amount field"          ()  4  5)
(df  f-imm      "signed immediate field"      () 15 16 INT #f #f)
(dnf f-uimm     "unsigned immediate field"    () 15 16)
(dnf f-csr      "csr field"                   () 25  5)
(dnf f-user     "user defined field"          () 10 11)
(dnf f-exception "exception field"            () 25 26)

(df f-branch "branch offset field" (PCREL-ADDR) 15 16 INT
        ((value pc) (sra SI (sub SI value pc) 2))
	((value pc) (add SI pc (sub (xor (sll (and value #xffff) 2)
					 #x20000)
				    #x20000)))
Nick Clifton's avatar
Nick Clifton committed
)
(df f-call "call offset field" (PCREL-ADDR) 25 26 INT 
        ((value pc) (sra SI (sub SI value pc) 2))
	((value pc) (add SI pc (sub (xor (sll (and value #x3ffffff) 2)
					 #x8000000)
				    #x8000000)))
Nick Clifton's avatar
Nick Clifton committed
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938
)


; Operands.

(dnop r0        "register 0"            () h-gr         f-r0)
(dnop r1        "register 1"            () h-gr         f-r1)
(dnop r2        "register 2"            () h-gr         f-r2)
(dnop shift     "shift amout"           () h-uint       f-shift)
(dnop imm       "signed immediate"      () h-sint       f-imm)
(dnop uimm      "unsigned immediate"    () h-uint       f-uimm)
(dnop branch    "branch offset"         () h-iaddr      f-branch)
(dnop call      "call offset"           () h-iaddr      f-call)
(dnop csr       "csr"                   () h-csr        f-csr)
(dnop user      "user"                  () h-uint       f-user)
(dnop exception "exception"             () h-uint       f-exception)
            
(define-operand
  (name hi16)
  (comment "high 16-bit immediate")
  (attrs)
  (type h-uint)
  (index f-uimm)
  (handlers (parse "hi16"))
)

(define-operand
  (name lo16)
  (comment "low 16-bit immediate")
  (attrs)
  (type h-uint)
  (index f-uimm)
  (handlers (parse "lo16"))
)

(define-operand
  (name gp16)
  (comment "gp relative 16-bit immediate")
  (attrs)
  (type h-sint)
  (index f-imm)
  (handlers (parse "gp16"))
)

(define-operand
  (name got16)
  (comment "got 16-bit immediate")
  (attrs)
  (type h-sint)
  (index f-imm)
  (handlers (parse "got16"))
)

(define-operand
  (name gotoffhi16)
  (comment "got offset high 16-bit immediate")
  (attrs)
  (type h-sint)
  (index f-imm)
  (handlers (parse "gotoff_hi16"))
)

(define-operand
  (name gotofflo16)
  (comment "got offset low 16-bit immediate")
  (attrs)
  (type h-sint)
  (index f-imm)
  (handlers (parse "gotoff_lo16"))
)


; Enumerations.

(define-normal-insn-enum
  opcodes "opcodes" () OP_ f-opcode
  (("ADD"       45)      
   ("ADDI"      13)      
   ("AND"       40)
   ("ANDI"      8)
   ("ANDHI"     24)
   ("B"         48)
   ("BI"        56)
   ("BE"        17)
   ("BG"        18)
   ("BGE"       19)
   ("BGEU"      20)
   ("BGU"       21)
   ("BNE"       23)
   ("CALL"      54)
   ("CALLI"     62)
   ("CMPE"      57)
   ("CMPEI"     25)
   ("CMPG"      58)
   ("CMPGI"     26)
   ("CMPGE"     59)
   ("CMPGEI"    27)
   ("CMPGEU"    60)
   ("CMPGEUI"   28)
   ("CMPGU"     61)
   ("CMPGUI"    29)
   ("CMPNE"     63)
   ("CMPNEI"    31)
   ("DIVU"      35)
   ("LB"        4)
   ("LBU"       16)
   ("LH"        7)
   ("LHU"       11)
   ("LW"        10)
   ("MODU"      49)
   ("MUL"       34)
   ("MULI"      2)
   ("NOR"       33)
   ("NORI"      1)
   ("OR"        46)
   ("ORI"       14)
   ("ORHI"      30)
   ("RAISE"     43)
   ("RCSR"      36)
   ("SB"        12)
   ("SEXTB"     44)
   ("SEXTH"     55)
   ("SH"        3)
   ("SL"        47)
   ("SLI"       15)
   ("SR"        37)
   ("SRI"       5)
   ("SRU"       32)
   ("SRUI"      0)
   ("SUB"       50)
   ("SW"        22)
   ("USER"      51)
   ("WCSR"      52)
   ("XNOR"      41)
   ("XNORI"     9)
   ("XOR"       38)
   ("XORI"      6)
  )
)
 

; Instructions. Note: Reg-reg must come before reg-imm.

(dni add "add" ()
        "add $r2,$r0,$r1"
        (+ OP_ADD r0 r1 r2 (f-resv0 0))
        (set r2 (add r0 r1))
        ()
)

(dni addi "add immediate" ()
        "addi $r1,$r0,$imm"  
        (+ OP_ADDI r0 r1 imm)
        (set r1 (add r0 (ext SI (trunc HI imm))))
        ()
)

(dni and "and" ()
        "and $r2,$r0,$r1"
        (+ OP_AND r0 r1 r2 (f-resv0 0))
        (set r2 (and r0 r1))
        ()
)

(dni andi "and immediate" ()
        "andi $r1,$r0,$uimm"  
        (+ OP_ANDI r0 r1 uimm)
        (set r1 (and r0 (zext SI uimm)))
        ()
)

(dni andhii "and high immediate" ()
        "andhi $r1,$r0,$hi16"  
        (+ OP_ANDHI r0 r1 hi16)
        (set r1 (and r0 (sll SI hi16 16)))
        ()
)

(dni b "branch" ()
        "b $r0"
        (+ OP_B r0 (f-r1 0) (f-r2 0) (f-resv0 0))
        (set pc (c-call USI "@cpu@_b_insn" r0 f-r0))
        ()
)

(dni bi "branch immediate" ()
        "bi $call"
        (+ OP_BI call)
        (set pc (ext SI call))
        ()
)

(dni be "branch equal" ()
        "be $r0,$r1,$branch"
        (+ OP_BE r0 r1 branch)
        (if (eq r0 r1)
            (set pc branch)
        )
        ()
)

(dni bg "branch greater" ()
        "bg $r0,$r1,$branch"
        (+ OP_BG r0 r1 branch)
        (if (gt r0 r1)
            (set pc branch)
        )
        ()
)

(dni bge "branch greater or equal" ()
        "bge $r0,$r1,$branch"
        (+ OP_BGE r0 r1 branch)
        (if (ge r0 r1)
            (set pc branch)
        )
        ()
)

(dni bgeu "branch greater or equal unsigned" ()
        "bgeu $r0,$r1,$branch"
        (+ OP_BGEU r0 r1 branch)
        (if (geu r0 r1)
            (set pc branch)
        )
        ()
)

(dni bgu "branch greater unsigned" ()
        "bgu $r0,$r1,$branch"
        (+ OP_BGU r0 r1 branch)
        (if (gtu r0 r1)
            (set pc branch)
        )
        ()
)

(dni bne "branch not equal" ()
        "bne $r0,$r1,$branch"
        (+ OP_BNE r0 r1 branch)
        (if (ne r0 r1)
            (set pc branch)
        )
        ()
)

(dni call "call" ()
        "call $r0"
        (+ OP_CALL r0 (f-r1 0) (f-r2 0) (f-resv0 0))
        (sequence ()
                (set (reg h-gr 29) (add pc 4))
                (set pc r0) 
        )
        ()
)

(dni calli "call immediate" ()
        "calli $call"
        (+ OP_CALLI call)
        (sequence ()
                (set (reg h-gr 29) (add pc 4))
                (set pc (ext SI call)) 
        )
        ()
)

(dni cmpe "compare equal" ()
        "cmpe $r2,$r0,$r1"  
        (+ OP_CMPE r0 r1 r2 (f-resv0 0))
        (set r2 (eq SI r0 r1))
        ()
)

(dni cmpei "compare equal immediate" ()
        "cmpei $r1,$r0,$imm"  
        (+ OP_CMPEI r0 r1 imm)
        (set r1 (eq SI r0 (ext SI (trunc HI imm))))
        ()
)

(dni cmpg "compare greater than" ()
        "cmpg $r2,$r0,$r1"  
        (+ OP_CMPG r0 r1 r2 (f-resv0 0))
        (set r2 (gt SI r0 r1))
        ()
)

(dni cmpgi "compare greater than immediate" ()
        "cmpgi $r1,$r0,$imm"  
        (+ OP_CMPGI r0 r1 imm)
        (set r1 (gt SI r0 (ext SI (trunc HI imm))))
        ()
)

(dni cmpge "compare greater or equal" ()
        "cmpge $r2,$r0,$r1"  
        (+ OP_CMPGE r0 r1 r2 (f-resv0 0))
        (set r2 (ge SI r0 r1))
        ()
)

(dni cmpgei "compare greater or equal immediate" ()
        "cmpgei $r1,$r0,$imm"  
        (+ OP_CMPGEI r0 r1 imm)
        (set r1 (ge SI r0 (ext SI (trunc HI imm))))
        ()
)

(dni cmpgeu "compare greater or equal unsigned" ()
        "cmpgeu $r2,$r0,$r1"  
        (+ OP_CMPGEU r0 r1 r2 (f-resv0 0))
        (set r2 (geu SI r0 r1))
        ()
)

(dni cmpgeui "compare greater or equal unsigned immediate" ()
        "cmpgeui $r1,$r0,$uimm"  
        (+ OP_CMPGEUI r0 r1 uimm)
        (set r1 (geu SI r0 (zext SI uimm)))
        ()
)

(dni cmpgu "compare greater than unsigned" ()
        "cmpgu $r2,$r0,$r1"  
        (+ OP_CMPGU r0 r1 r2 (f-resv0 0))
        (set r2 (gtu SI r0 r1))
        ()
)

(dni cmpgui "compare greater than unsigned immediate" ()
        "cmpgui $r1,$r0,$uimm"  
        (+ OP_CMPGUI r0 r1 uimm)
        (set r1 (gtu SI r0 (zext SI uimm)))
        ()
)

(dni cmpne "compare not equal" ()
        "cmpne $r2,$r0,$r1"  
        (+ OP_CMPNE r0 r1 r2 (f-resv0 0))
        (set r2 (ne SI r0 r1))
        ()
)

(dni cmpnei "compare not equal immediate" ()
        "cmpnei $r1,$r0,$imm"  
        (+ OP_CMPNEI r0 r1 imm)
        (set r1 (ne SI r0 (ext SI (trunc HI imm))))
        ()
)

(dni divu "unsigned divide" ()
        "divu $r2,$r0,$r1"
        (+ OP_DIVU r0 r1 r2 (f-resv0 0))
        (set pc (c-call USI "@cpu@_divu_insn" pc f-r0 f-r1 f-r2))
        ()
)

(dni lb "load byte" ()
        "lb $r1,($r0+$imm)"
        (+ OP_LB r0 r1 imm)
        (set r1 (ext SI (mem QI (add r0 (ext SI (trunc HI imm))))))
        ()
)

(dni lbu "load byte unsigned" ()
        "lbu $r1,($r0+$imm)"
        (+ OP_LBU r0 r1 imm)
        (set r1 (zext SI (mem QI (add r0 (ext SI (trunc HI imm))))))
        ()
)

(dni lh "load halfword" ()
        "lh $r1,($r0+$imm)"
        (+ OP_LH r0 r1 imm)
        (set r1 (ext SI (mem HI (add r0 (ext SI (trunc HI imm))))))
        ()
)

(dni lhu "load halfword unsigned" ()
        "lhu $r1,($r0+$imm)"
        (+ OP_LHU r0 r1 imm)
        (set r1 (zext SI (mem HI (add r0 (ext SI (trunc HI imm))))))
        ()
)

(dni lw "load word" ()
        "lw $r1,($r0+$imm)"
        (+ OP_LW r0 r1 imm)
        (set r1 (mem SI (add r0 (ext SI (trunc HI imm)))))
        ()
)

(dni modu "unsigned modulus" ()
        "modu $r2,$r0,$r1"
        (+ OP_MODU r0 r1 r2 (f-resv0 0))
        (set pc (c-call USI "@cpu@_modu_insn" pc f-r0 f-r1 f-r2))
        ()
)

(dni mul "mulitply" ()
        "mul $r2,$r0,$r1"
        (+ OP_MUL r0 r1 r2 (f-resv0 0))
        (set r2 (mul r0 r1))
        ()
)

(dni muli "multiply immediate" ()
        "muli $r1,$r0,$imm"  
        (+ OP_MULI r0 r1 imm)
        (set r1 (mul r0 (ext SI (trunc HI imm))))
        ()
)

(dni nor "nor" ()
        "nor $r2,$r0,$r1"
        (+ OP_NOR r0 r1 r2 (f-resv0 0))
        (set r2 (inv (or r0 r1)))
        ()
)

(dni nori "nor immediate" ()
        "nori $r1,$r0,$uimm"  
        (+ OP_NORI r0 r1 uimm)
        (set r1 (inv (or r0 (zext SI uimm))))
        ()
)

(dni or "or" ()
        "or $r2,$r0,$r1"
        (+ OP_OR r0 r1 r2 (f-resv0 0))
        (set r2 (or r0 r1))
        ()
)

(dni ori "or immediate" ()
        "ori $r1,$r0,$lo16"  
        (+ OP_ORI r0 r1 lo16)
        (set r1 (or r0 (zext SI lo16)))
        ()
)

(dni orhii "or high immediate" ()
        "orhi $r1,$r0,$hi16"  
        (+ OP_ORHI r0 r1 hi16)
        (set r1 (or r0 (sll SI hi16 16)))
        ()
)

(dni rcsr "read control or status register" ()
        "rcsr $r2,$csr"
        (+ OP_RCSR csr (f-r1 0) r2 (f-resv0 0))
        (set r2 csr) 
        ()
)

(dni sb "store byte" ()
        "sb ($r0+$imm),$r1"
        (+ OP_SB r0 r1 imm)
        (set (mem QI (add r0 (ext SI (trunc HI imm)))) r1)
        ()
)

(dni sextb "sign extend byte" ()
        "sextb $r2,$r0"
        (+ OP_SEXTB r0 (f-r1 0) r2 (f-resv0 0))
        (set r2 (ext SI (trunc QI r0)))
        ()
)

(dni sexth "sign extend half-word" ()
        "sexth $r2,$r0"
        (+ OP_SEXTH r0 (f-r1 0) r2 (f-resv0 0))
        (set r2 (ext SI (trunc HI r0)))
        ()
)

(dni sh "store halfword" ()
        "sh ($r0+$imm),$r1"
        (+ OP_SH r0 r1 imm)
        (set (mem HI (add r0 (ext SI (trunc HI imm)))) r1)
        ()
)

(dni sl "shift left" ()
        "sl $r2,$r0,$r1"
        (+ OP_SL r0 r1 r2 (f-resv0 0))
        (set r2 (sll SI r0 r1))
        ()
)

(dni sli "shift left immediate" ()
        "sli $r1,$r0,$imm"  
        (+ OP_SLI r0 r1 imm)
        (set r1 (sll SI r0 imm))
        ()
)

(dni sr "shift right" ()
        "sr $r2,$r0,$r1"
        (+ OP_SR r0 r1 r2 (f-resv0 0))
        (set r2 (sra SI r0 r1))
        ()
)

(dni sri "shift right immediate" ()
        "sri $r1,$r0,$imm"  
        (+ OP_SRI r0 r1 imm)
        (set r1 (sra SI r0 imm))
        ()
)

(dni sru "shift right unsigned" ()
        "sru $r2,$r0,$r1"
        (+ OP_SRU r0 r1 r2 (f-resv0 0))
        (set r2 (srl SI r0 r1))
        ()
)

(dni srui "shift right unsigned immediate" ()
        "srui $r1,$r0,$imm"  
        (+ OP_SRUI r0 r1 imm)
        (set r1 (srl SI r0 imm))
        ()
)

(dni sub "subtract" ()
        "sub $r2,$r0,$r1"
        (+ OP_SUB r0 r1 r2 (f-resv0 0))
        (set r2 (sub r0 r1))
        ()
)

(dni sw "store word" ()
        "sw ($r0+$imm),$r1"
        (+ OP_SW r0 r1 imm)
        (set (mem SI (add r0 (ext SI (trunc HI imm)))) r1)
        ()
)

(dni user "user defined instruction" ()
        "user $r2,$r0,$r1,$user"
        (+ OP_USER r0 r1 r2 user)
        (set r2 (c-call SI "@cpu@_user_insn" r0 r1 user))
        ()
)

(dni wcsr "write control or status register" ()
        "wcsr $csr,$r1"
        (+ OP_WCSR csr r1 (f-r2 0) (f-resv0 0))
        (c-call VOID "@cpu@_wcsr_insn" f-csr r1) 
        ()
)
    
(dni xor "xor" ()
        "xor $r2,$r0,$r1"
        (+ OP_XOR r0 r1 r2 (f-resv0 0))
        (set r2 (xor r0 r1))
        ()
)

(dni xori "xor immediate" ()
        "xori $r1,$r0,$uimm"  
        (+ OP_XORI r0 r1 uimm)
        (set r1 (xor r0 (zext SI uimm)))
        ()
)

(dni xnor "xnor" ()
        "xnor $r2,$r0,$r1"
        (+ OP_XNOR r0 r1 r2 (f-resv0 0))
        (set r2 (inv (xor r0 r1)))
        ()
)

(dni xnori "xnor immediate" ()
        "xnori $r1,$r0,$uimm"  
        (+ OP_XNORI r0 r1 uimm)
        (set r1 (inv (xor r0 (zext SI uimm))))
        ()
)

; Pseudo instructions

(dni break "breakpoint" ()
        "break"
        (+ OP_RAISE (f-exception 2))
        (set pc (c-call USI "@cpu@_break_insn" pc))
        ()
)

(dni scall "system call" ()
        "scall"
        (+ OP_RAISE (f-exception 7))
        (set pc (c-call USI "@cpu@_scall_insn" pc))
        ()
)

(dni bret "return from breakpoint" (ALIAS)
        "bret"
        (+ OP_B (f-r0 31) (f-r1 0) (f-r2 0) (f-resv0 0))
        (set pc (c-call USI "@cpu@_bret_insn" r0))
        ()
)

(dni eret "return from exception" (ALIAS)
        "eret"
        (+ OP_B (f-r0 30) (f-r1 0) (f-r2 0) (f-resv0 0))
        (set pc (c-call USI "@cpu@_eret_insn" r0))
        ()
)
    
(dni ret "return" (ALIAS)
        "ret"
        (+ OP_B (f-r0 29) (f-r1 0) (f-r2 0) (f-resv0 0))
        (set pc r0)
        ()
)

(dni mv "move" (ALIAS)
        "mv $r2,$r0"
        (+ OP_OR r0 (f-r1 0) r2 (f-resv0 0))
        (set r2 r0)
        ()
)

(dni mvi "move immediate" (ALIAS)
        "mvi $r1,$imm"
        (+ OP_ADDI (f-r0 0) r1 imm)
        (set r1 (add r0 (ext SI (trunc HI imm))))
        ()
)

(dni mvui "move unsigned immediate" (ALIAS)
        "mvu $r1,$lo16"
        (+ OP_ORI (f-r0 0) r1 lo16)
        (set r1 (zext SI lo16))
        ()
)

(dni mvhi "move high immediate" (ALIAS)
        "mvhi $r1,$hi16"
        (+ OP_ORHI (f-r0 0) r1 hi16)
        (set r1 (or r0 (sll SI hi16 16)))
        ()
)

(dni mva "move address" (ALIAS)
        "mva $r1,$gp16"
        (+ OP_ADDI (f-r0 26) r1 gp16)
        (set r1 (add r0 (ext SI (trunc HI gp16))))
        ()
)

(dni not "not" (ALIAS)
        "not $r2,$r0"
        (+ OP_XNOR r0 (f-r1 0) r2 (f-resv0 0))
        (set r2 (inv r0))
        ()
)

(dni nop "nop" (ALIAS)
        "nop"
        (+ OP_ADDI (f-r0 0) (f-r1 0) (f-imm 0))
        (set r0 r0)
        ()
)

(dni lbgprel "load byte gp relative" (ALIAS)
        "lb $r1,$gp16"
        (+ OP_LB (f-r0 26) r1 gp16)
        (set r1 (ext SI (mem QI (add r0 (ext SI (trunc HI gp16))))))
        ()
)

(dni lbugprel "load byte unsigned gp relative" (ALIAS)
        "lbu $r1,$gp16"
        (+ OP_LBU (f-r0 26) r1 gp16)
        (set r1 (zext SI (mem QI (add r0 (ext SI (trunc HI gp16))))))
        ()
)

(dni lhgprel "load halfword gp relative" (ALIAS)
        "lh $r1,$gp16"
        (+ OP_LH (f-r0 26) r1 gp16)
        (set r1 (ext SI (mem HI (add r0 (ext SI (trunc HI gp16))))))
        ()
)

(dni lhugprel "load halfword unsigned gp relative" (ALIAS)
        "lhu $r1,$gp16"
        (+ OP_LHU (f-r0 26) r1 gp16)
        (set r1 (zext SI (mem HI (add r0 (ext SI (trunc HI gp16))))))
        ()
)

(dni lwgprel "load word gp relative" (ALIAS)
        "lw $r1,$gp16"
        (+ OP_LW (f-r0 26) r1 gp16)
        (set r1 (mem SI (add r0 (ext SI (trunc HI gp16)))))
        ()
)

(dni sbgprel "store byte gp relative" (ALIAS)
        "sb $gp16,$r1"
        (+ OP_SB (f-r0 26) r1 gp16)
        (set (mem QI (add r0 (ext SI (trunc HI gp16)))) r1)
        ()
)

(dni shgprel "store halfword gp relative" (ALIAS)
        "sh $gp16,$r1"
        (+ OP_SH (f-r0 26) r1 gp16)
        (set (mem HI (add r0 (ext SI (trunc HI gp16)))) r1)
        ()
)

(dni swgprel "store word gp relative" (ALIAS)
        "sw $gp16,$r1"
        (+ OP_SW (f-r0 26) r1 gp16)
        (set (mem SI (add r0 (ext SI (trunc HI gp16)))) r1)
        ()
)

(dni lwgotrel "load word got relative" (ALIAS)
        "lw $r1,(gp+$got16)"
        (+ OP_LW (f-r0 26) r1 got16)
        (set r1 (mem SI (add r0 (ext SI (trunc HI got16)))))
        ()
)

(dni orhigotoffi "or high got offset immediate" (ALIAS)
        "orhi $r1,$r0,$gotoffhi16"  
        (+ OP_ORHI r0 r1 gotoffhi16)
        (set r1 (or r0 (sll SI gotoffhi16 16)))
        ()
)

(dni addgotoff "add got offset" (ALIAS)
        "addi $r1,$r0,$gotofflo16"  
        (+ OP_ADDI r0 r1 gotofflo16)
        (set r1 (add r0 (ext SI (trunc HI gotofflo16))))
        ()
)

(dni swgotoff "store word got offset" (ALIAS)
        "sw ($r0+$gotofflo16),$r1"
        (+ OP_SW r0 r1 gotofflo16)
        (set (mem SI (add r0 (ext SI (trunc HI gotofflo16)))) r1)
        ()
)

(dni lwgotoff "load word got offset" (ALIAS)
        "lw $r1,($r0+$gotofflo16)"
        (+ OP_LW r0 r1 gotofflo16)
        (set r1 (mem SI (add r0 (ext SI (trunc HI gotofflo16)))))
        ()
)

(dni shgotoff "store half word got offset" (ALIAS)
        "sh ($r0+$gotofflo16),$r1"
        (+ OP_SH r0 r1 gotofflo16)
        (set (mem HI (add r0 (ext SI (trunc HI gotofflo16)))) r1)
        ()
)

(dni lhgotoff "load half word got offset" (ALIAS)
        "lh $r1,($r0+$gotofflo16)"
        (+ OP_LH r0 r1 gotofflo16)
        (set r1 (ext SI (mem HI (add r0 (ext SI (trunc HI gotofflo16))))))
        ()
)

(dni lhugotoff "load half word got offset unsigned" (ALIAS)
        "lhu $r1,($r0+$gotofflo16)"
        (+ OP_LHU r0 r1 gotofflo16)
        (set r1 (zext SI (mem HI (add r0 (ext SI (trunc HI gotofflo16))))))
        ()
)

(dni sbgotoff "store byte got offset" (ALIAS)
        "sb ($r0+$gotofflo16),$r1"
        (+ OP_SB r0 r1 gotofflo16)
        (set (mem QI (add r0 (ext SI (trunc HI gotofflo16)))) r1)
        ()
)

(dni lbgotoff "load byte got offset" (ALIAS)
        "lb $r1,($r0+$gotofflo16)"
        (+ OP_LB r0 r1 gotofflo16)
        (set r1 (ext SI (mem QI (add r0 (ext SI (trunc HI gotofflo16))))))
        ()
)

(dni lbugotoff "load byte got offset unsigned" (ALIAS)
        "lbu $r1,($r0+$gotofflo16)"
        (+ OP_LBU r0 r1 gotofflo16)
        (set r1 (zext SI (mem QI (add r0 (ext SI (trunc HI gotofflo16))))))
        ()
)