938 lines
22 KiB
Scheme
938 lines
22 KiB
Scheme
; Lattice Mico32 CPU description. -*- Scheme -*-
|
||
; Copyright 2008-2013 Free Software Foundation, Inc.
|
||
; 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)
|
||
(CFG2 10)
|
||
(JTX 14) (JRX 15)
|
||
(BP0 16) (BP1 17) (BP2 18) (BP3 19)
|
||
(WP0 24) (WP1 25) (WP2 26) (WP3 27)
|
||
(PSW 29) (TLBVADDR 30) (TLBPADDR 31) (TLBBADVADDR 31)
|
||
)
|
||
)
|
||
() ()
|
||
)
|
||
|
||
|
||
; 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)))
|
||
)
|
||
(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)))
|
||
)
|
||
|
||
|
||
; 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))))))
|
||
()
|
||
)
|