aboutsummaryrefslogtreecommitdiff
path: root/cpu/xstormy16.cpu
diff options
context:
space:
mode:
Diffstat (limited to 'cpu/xstormy16.cpu')
-rw-r--r--cpu/xstormy16.cpu1965
1 files changed, 1965 insertions, 0 deletions
diff --git a/cpu/xstormy16.cpu b/cpu/xstormy16.cpu
new file mode 100644
index 0000000..ae7e042
--- /dev/null
+++ b/cpu/xstormy16.cpu
@@ -0,0 +1,1965 @@
+; xstormy16 CPU core description. -*- Scheme -*-
+; Copyright 2011 Free Software Foundation, Inc.
+;
+; Contributed by Red Hat Inc;
+;
+; 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.
+
+(define-rtl-version 0 8)
+
+(include "simplify.inc")
+
+(define-arch
+ (name xstormy16)
+ (comment "Xstormy16 architecture")
+ (insn-lsb0? #f)
+ (machs xstormy16)
+ (isas xstormy16)
+)
+
+(define-isa
+ (name xstormy16)
+ (comment "Xstormy16 instruction set")
+ (default-insn-word-bitsize 32)
+ (default-insn-bitsize 32)
+ ; FIXME base-insn-bitsize should be 16 too, but at present CGEN has
+ ; no support for instruction sets with opcode bits past
+ ; base-insn-bitsize, so we must set it to at least 20.
+ (base-insn-bitsize 32)
+)
+
+(define-cpu
+ (name xstormy16)
+ (comment "Xstormy16 CPU core")
+ (endian little)
+ (insn-endian little)
+ (insn-chunk-bitsize 16)
+ (word-bitsize 32)
+)
+
+(define-mach
+ (name xstormy16)
+ (comment "Xstormy16 CPU core")
+ (cpu xstormy16)
+ (isas xstormy16)
+)
+
+(define-model
+ (name xstormy16)
+ (comment "Xstormy16 CPU core")
+ (unit u-exec "Execution Unit" ()
+ 1 1 ; issue done
+ () () () ())
+)
+
+; IDOC attribute for instruction documentation.
+
+(define-attr
+ (for insn)
+ (type enum)
+ (name IDOC)
+ (comment "insn kind for documentation")
+ (attrs META)
+ (values
+ (MEM - () "Memory")
+ (ALU - () "ALU")
+ (FPU - () "FPU")
+ (BR - () "Branch")
+ (PRIV - () "Priviledged")
+ (MISC - () "Miscellaneous")
+ )
+)
+
+; Hardware elements.
+
+(define-hardware
+ (name h-pc)
+ (comment "program counter")
+ (attrs PC)
+ (type pc)
+ (set (newval) (c-call "h_pc_set_handler" newval))
+)
+
+(define-keyword
+ (name gr-names)
+ (enum-prefix H-GR-)
+ (values (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)
+ (psw 14) (sp 15)))
+
+(define-keyword
+ (name gr-Rb-names)
+ (enum-prefix H-RBJ-)
+ (values (r8 0) (r9 1) (r10 2) (r11 3)
+ (r12 4) (r13 5) (r14 6) (r15 7)
+ (psw 6) (sp 7)))
+
+(define-hardware
+ (name h-gr)
+ (comment "registers")
+ (type register WI (16))
+ (indices extern-keyword gr-names)
+ (get (index) (and #xFFFF (raw-reg h-gr index)))
+ (set (index newval) (c-call "h_gr_set_handler" index newval))
+)
+
+(define-hardware
+ (name h-Rb)
+ (comment "Rb registers")
+ (attrs VIRTUAL)
+ (type register SI(8))
+ (indices extern-keyword gr-Rb-names)
+ (get (index) (reg h-gr (add index 8)))
+ (set (index newval) (set (reg h-gr (add index 8)) newval))
+)
+
+(define-hardware
+ (name h-Rbj)
+ (comment "Rbj registers")
+ (attrs VIRTUAL)
+ (type register SI(2))
+ (indices extern-keyword gr-Rb-names)
+ (get (index) (reg h-gr (add index 8)))
+ (set (index newval) (set (reg h-gr (add index 8)) newval))
+)
+
+(define-hardware
+ (name h-Rpsw)
+ (comment "Register number field of the PSW")
+ (attrs VIRTUAL)
+ (type register WI)
+ (get () (and #xF (srl psw 12)))
+ (set (newval) (set psw (or (and psw #xFFF)
+ (sll HI newval 12)))))
+
+(define-pmacro (define-psw-field fnam hnam index)
+ (define-hardware
+ (name hnam)
+ (attrs VIRTUAL)
+ (type register SI)
+ (get () (and 1 (srl psw index)))
+ (set (newval) (set psw (or (and psw (inv (sll HI 1 index)))
+ (sll HI newval index)))))
+ ;(dnop fnam "" (SEM-ONLY) hnam f-nil)
+)
+(define-psw-field psw-z8 h-z8 0)
+(dnop psw-z8 "" (SEM-ONLY) h-z8 f-nil)
+(define-psw-field psw-z16 h-z16 1)
+(dnop psw-z16 "" (SEM-ONLY) h-z16 f-nil)
+(define-psw-field psw-cy h-cy 2)
+(dnop psw-cy "" (SEM-ONLY) h-cy f-nil)
+(define-psw-field psw-hc h-hc 3)
+(dnop psw-hc "" (SEM-ONLY) h-hc f-nil)
+(define-psw-field psw-ov h-ov 4)
+(dnop psw-ov "" (SEM-ONLY) h-ov f-nil)
+(define-psw-field psw-pt h-pt 5)
+(dnop psw-pt "" (SEM-ONLY) h-pt f-nil)
+(define-psw-field psw-s h-s 6)
+(dnop psw-s "" (SEM-ONLY) h-s f-nil)
+
+(define-hardware
+ (name h-branchcond)
+ (comment "Condition of a branch instruction")
+ (type immediate (UINT 4))
+ (values keyword ""
+ (("ge" 0) ("nc" 1) ("lt" 2) ("c" 3)
+ ("gt" 4) ("hi" 5) ("le" 6) ("ls" 7)
+ ("pl" 8) ("nv" 9) ("mi" 10) ("v" 11)
+ ("nz.b" 12) ("nz" 13) ("z.b" 14) ("z" 15)))
+)
+
+(define-hardware
+ (name h-wordsize)
+ (comment "Data size")
+ (type immediate (UINT 1))
+ (values keyword "" ((".b" 0) (".w" 1) ("" 1)))
+)
+
+
+; Instruction fields, and the corresponding operands.
+; Register fields
+
+(dnf f-Rd "general register destination" () 12 4)
+(dnop Rd "general register destination" () h-gr f-Rd)
+
+(dnf f-Rdm "general register destination" () 13 3)
+(dnop Rdm "general register destination" () h-gr f-Rdm)
+
+(dnf f-Rm "general register for memory" () 4 3)
+(dnop Rm "general register for memory" () h-gr f-Rm)
+
+(dnf f-Rs "general register source" () 8 4)
+(dnop Rs "general register source" () h-gr f-Rs)
+
+(dnf f-Rb "base register" () 17 3)
+(dnop Rb "base register" () h-Rb f-Rb)
+
+(dnf f-Rbj "base register for jump" () 11 1)
+(dnop Rbj "base register for jump" () h-Rbj f-Rbj)
+
+; Main opcodes in 4 bit chunks
+
+(dnf f-op1 "opcode" () 0 4)
+(define-normal-insn-enum insn-op1 "insn op enums" () OP1_ f-op1
+ ( "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "A" "B" "C" "D" "E" "F" ))
+
+(dnf f-op2 "opcode" () 4 4)
+(define-normal-insn-enum insn-op2 "insn op enums" () OP2_ f-op2
+ ( "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "A" "B" "C" "D" "E" "F" ))
+(dnop bcond2 "branch condition opcode" () h-branchcond f-op2)
+
+(dnf f-op2a "opcode" () 4 3)
+(define-normal-insn-enum insn-op2a "insn op enums" () OP2A_ f-op2a
+ ( "0" "2" "4" "6" "8" "A" "C" "E" ))
+
+(dnf f-op2m "opcode" () 7 1)
+(define-normal-insn-enum insn-op2m "insn op enums" () OP2M_ f-op2m
+ ( "0" "1" ))
+(dnop ws2 "word size opcode" () h-wordsize f-op2m)
+
+(dnf f-op3 "opcode" () 8 4)
+(define-normal-insn-enum insn-op3 "insn op enums" () OP3_ f-op3
+ ( "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "A" "B" "C" "D" "E" "F" ))
+
+(dnf f-op3a "opcode" () 8 2)
+(define-normal-insn-enum insn-op3a "insn op enums" () OP3A_ f-op3a
+ ( "0" "1" "2" "3" ))
+
+(dnf f-op3b "opcode" () 8 3)
+(define-normal-insn-enum insn-op3b "insn op enums" () OP3B_ f-op3b
+ ( "0" "2" "4" "6" "8" "A" "C" "E" ))
+
+(dnf f-op4 "opcode" () 12 4)
+(define-normal-insn-enum insn-op4 "insn op enums" () OP4_ f-op4
+ ( "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "A" "B" "C" "D" "E" "F" ))
+
+(dnf f-op4m "opcode" () 12 1)
+(define-normal-insn-enum insn-op4m "insn op enums" () OP4M_ f-op4m
+ ( "0" "1" ))
+
+(dnf f-op4b "opcode" () 15 1)
+(define-normal-insn-enum insn-op4b "insn op enums" () OP4B_ f-op4b
+ ( "0" "1" ))
+
+(dnf f-op5 "opcode" () 16 4)
+(define-normal-insn-enum insn-op5 "insn op enums" () OP5_ f-op5
+ ( "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "A" "B" "C" "D" "E" "F" ))
+(dnop bcond5 "branch condition opcode" () h-branchcond f-op5)
+
+(dnf f-op5a "opcode" () 16 1)
+(define-normal-insn-enum insn-op5a "insn op enums" () OP5A_ f-op5a
+ ( "0" "1" ))
+
+; The whole first word
+(dnf f-op "opcode" () 0 16)
+
+; Immediate fields
+
+(dnf f-imm2 "2 bit unsigned" () 10 2)
+(dnop imm2 "2 bit unsigned immediate" () h-uint f-imm2)
+
+(dnf f-imm3 "3 bit unsigned" () 4 3)
+(dnop imm3 "3 bit unsigned immediate" () h-uint f-imm3)
+(dnf f-imm3b "3 bit unsigned for bit tests" () 17 3)
+(dnop imm3b "3 bit unsigned immediate for bit tests" () h-uint f-imm3b)
+
+(dnf f-imm4 "4 bit unsigned" () 8 4)
+(define-operand
+ (name imm4)
+ (comment "4 bit unsigned immediate")
+ (attrs)
+ (type h-uint)
+ (index f-imm4)
+ (handlers (parse "small_immediate"))
+)
+
+(dnf f-imm8 "8 bit unsigned" () 8 8)
+(dnop imm8 "8 bit unsigned immediate" () h-uint f-imm8)
+(define-operand
+ (name imm8small)
+ (comment "8 bit unsigned immediate")
+ (attrs)
+ (type h-uint)
+ (index f-imm8)
+ (handlers (parse "small_immediate"))
+)
+
+(define-ifield
+ (name f-imm12)
+ (comment "12 bit signed")
+ (attrs)
+ (start 20)
+ (length 12)
+ (mode INT)
+)
+(dnop imm12 "12 bit signed immediate" () h-sint f-imm12)
+
+(dnf f-imm16 "16 bit" (SIGN-OPT) 16 16)
+(define-operand
+ (name imm16)
+ (comment "16 bit immediate")
+ (attrs)
+ (type h-uint)
+ (index f-imm16)
+ (handlers (parse "immediate16"))
+)
+
+(dnf f-lmem8 "8 bit unsigned low memory" (ABS-ADDR) 8 8)
+(define-operand
+ (name lmem8)
+ (comment "8 bit unsigned immediate low memory")
+ (attrs)
+ (type h-uint)
+ (index f-lmem8)
+ (handlers (parse "mem8"))
+)
+(define-ifield
+ (name f-hmem8)
+ (comment "8 bit unsigned high memory")
+ (attrs ABS-ADDR)
+ (start 8)
+ (length 8)
+ (mode UINT)
+ (encode (value pc) (sub HI value #x7F00))
+ (decode (value pc) (add HI value #x7F00))
+)
+(define-operand
+ (name hmem8)
+ (comment "8 bit unsigned immediate high memory")
+ (attrs)
+ (type h-uint)
+ (index f-hmem8)
+ (handlers (parse "mem8"))
+)
+
+(define-ifield
+ (name f-rel8-2)
+ (comment "8 bit relative address for 2-byte instruction")
+ (attrs PCREL-ADDR)
+ (start 8)
+ (length 8)
+ (mode INT)
+ (encode (value pc) (sub SI value (add SI pc 2)))
+ (decode (value pc) (add SI value (add SI pc 2)))
+)
+(dnop rel8-2 "8 bit relative address" () h-uint f-rel8-2)
+
+(define-ifield
+ (name f-rel8-4)
+ (comment "8 bit relative address for 4-byte instruction")
+ (attrs PCREL-ADDR)
+ (start 8)
+ (length 8)
+ (mode INT)
+ (encode (value pc) (sub SI value (add SI pc 4)))
+ (decode (value pc) (add SI value (add SI pc 4)))
+)
+(dnop rel8-4 "8 bit relative address" () h-uint f-rel8-4)
+
+(define-ifield
+ (name f-rel12)
+ (comment "12 bit relative address")
+ (attrs PCREL-ADDR)
+ (start 20)
+ (length 12)
+ (mode INT)
+ (encode (value pc) (sub SI value (add SI pc 4)))
+ (decode (value pc) (add SI value (add SI pc 4)))
+)
+(dnop rel12 "12 bit relative address" () h-uint f-rel12)
+
+(define-ifield
+ (name f-rel12a)
+ (comment "12 bit relative address")
+ (attrs PCREL-ADDR)
+ (start 4)
+ (length 11)
+ (mode INT)
+ (encode (value pc) (sra SI (sub SI value (add SI pc 2)) 1))
+ (decode (value pc) (add SI (sll value 1) (add SI pc 2)))
+)
+(dnop rel12a "12 bit relative address" () h-uint f-rel12a)
+
+(dnf f-abs24-1 "abs24 low part" () 8 8)
+(dnf f-abs24-2 "abs24 high part" () 16 16)
+(define-multi-ifield
+ (name f-abs24)
+ (comment "Absolute address for jmpf instruction")
+ (attrs ABS-ADDR)
+ (mode UINT)
+ (subfields f-abs24-1 f-abs24-2)
+ (insert (sequence ()
+ (set (ifield f-abs24-1) (and (ifield f-abs24) #xFF))
+ (set (ifield f-abs24-2) (srl (ifield f-abs24) 8))))
+ (extract (set (ifield f-abs24) (or (sll (ifield f-abs24-2) 8) f-abs24-1)))
+)
+(dnop abs24 "24 bit absolute address" () h-uint f-abs24)
+
+; Names for registers
+(dnop psw "program status word" (SEM-ONLY) h-gr 14)
+(dnop Rpsw "N0-N3 of the program status word" (SEM-ONLY) h-Rpsw f-nil)
+(dnop sp "stack pointer" (SEM-ONLY) h-gr 15)
+(dnop R0 "R0" (SEM-ONLY) h-gr 0)
+(dnop R1 "R1" (SEM-ONLY) h-gr 1)
+(dnop R2 "R2" (SEM-ONLY) h-gr 2)
+(dnop R8 "R8" (SEM-ONLY) h-gr 8)
+
+; Useful macros.
+
+; THe Z8, Z16, PT, and S flags of the PSW.
+(define-pmacro (basic-psw value ws)
+ (or (or (zflag (and value #xFF))
+ (sll HI (zflag HI value) 1))
+ (or (sll HI (c-call BI "parity" value) 5)
+ (sll HI (nflag QI (srl value (mul ws 8))) 6))))
+
+
+; Update the PSW for destination register Rd, set Rd to value.
+(define-pmacro (set-psw Rd index value ws)
+ (sequence ((HI nvalue))
+ (set nvalue value)
+ (set (reg HI h-gr index) nvalue)
+ (set psw (or (and psw #x0F9C)
+ (or (sll index 12)
+ (basic-psw nvalue ws))))))
+
+; Update the PSW for destination register Rd.
+(define-pmacro (set-psw-nowrite index value ws)
+ (sequence ((HI nvalue))
+ (set nvalue value)
+ (set psw (or (and psw #x0F9C)
+ (or (sll index 12)
+ (basic-psw nvalue ws))))))
+
+; Update the PSW for destination non-register dest, set dest to value.
+(define-pmacro (set-mem-psw dest value ws)
+ (sequence ((HI nvalue))
+ (set nvalue value)
+ (set psw (or (and psw #xFF9C)
+ (basic-psw nvalue ws)))
+ (set dest nvalue)))
+
+; Update the PSW as with set-psw, but also set the carry flag.
+(define-pmacro (set-psw-carry Rd index value carry ws)
+ (sequence ((HI nvalue) (HI newpsw))
+ (set nvalue value)
+ (set newpsw (or (or (and psw #x0F98)
+ (sll (and carry #x1) 2))
+ (or (sll index 12)
+ (basic-psw nvalue ws))))
+ (set (reg HI h-gr index) nvalue)
+ (set psw newpsw)
+ ))
+
+; The all-purpose addition operation.
+(define-pmacro (set-psw-add Rd index a b c)
+ (sequence ((HI value) (HI newpsw))
+ (set value (addc a b c))
+ (set newpsw (or (or (and psw #x0F80)
+ (basic-psw value 1))
+ (or (or (sll HI (add-oflag HI a b c) 4)
+ (sll HI (add-cflag HI a b c) 2))
+ (or (and (srl HI (addc HI (and a #xF) (and b #xF) c)
+ 1) #x8)
+ (sll index 12)))))
+ (set (reg HI h-gr index) value)
+ (set psw newpsw)
+ ))
+
+; Set the PSW for a subtraction of a-b into Rd, but don't actually
+; do the subtract.
+(define-pmacro (set-psw-cmp Rd index a b)
+ (sequence ((HI value))
+ (set value (sub a b))
+ (set psw (or (or (and psw #x0F80)
+ (basic-psw value 1))
+ (or (or (sll HI (sub-oflag HI a b 0) 4)
+ (sll HI (sub-cflag HI a b 0) 2))
+ (or (and (srl HI (sub HI (and a #xF) (and b #xF))
+ 1) #x8)
+ (sll index 12)))))))
+
+; Likewise, for subtraction
+; (this chip has a borrow for subtraction, rather than
+; just using a carry for both).
+(define-pmacro (set-psw-sub Rd index a b c)
+ (sequence ((HI value) (HI newpsw))
+ (set value (subc a b c))
+ (set newpsw (or (or (and psw #x0F80)
+ (basic-psw value 1))
+ (or (or (sll HI (sub-oflag HI a b c) 4)
+ (sll HI (sub-cflag HI a b c) 2))
+ (or (and (srl HI (subc HI (and a #xF) (and b #xF) c)
+ 1) #x8)
+ (sll index 12)))))
+ (set (reg HI h-gr index) value)
+ (set psw newpsw)
+ ))
+
+; A 17-bit rotate-left operation
+(define-pmacro (set-psw-rotate17 Rd index src c rot)
+ (sequence ((SI tmpfoo))
+ (set tmpfoo (or (or (and (sll SI src 15) #x7FFE0000)
+ src)
+ (or (sll SI c 31)
+ (sll SI c 16))))
+ (set tmpfoo (rol tmpfoo (and rot #x1F)))
+ (set-psw-carry (reg HI h-gr index) index (trunc HI tmpfoo) (and (srl tmpfoo 16) 1) 1)))
+
+; A 17-bit rotate-right operation
+(define-pmacro (set-psw-rrotate17 Rd index src c rot)
+ (sequence ((SI tmpfoo))
+ (set tmpfoo (or (or (and (sll SI src 17) #xFFFE0000)
+ src)
+ (sll SI c 16)))
+ (set tmpfoo (ror tmpfoo (and rot #x0F)))
+ (set-psw-carry (reg HI h-gr index) index (trunc HI tmpfoo) (and (srl tmpfoo 16) 1) 1)))
+
+
+; Move Operations
+
+(define-pmacro (alignfix-mem where)
+ (mem HI (and where #xFFFE)))
+
+(define-pmacro (set-alignfix-mem where what)
+ (set (mem HI (and where #xFFFE)) what))
+
+(define-pmacro (alignfix-mem-far where)
+ (mem HI (and where #xFFFFFFFE)))
+
+(define-pmacro (set-alignfix-mem-far where what)
+ (set (mem HI (and where #xFFFFFFFE)) what))
+
+(dni movlmemimm
+ "Move immediate to low memory"
+ ()
+ ("mov$ws2 $lmem8,#$imm16")
+ (+ OP1_7 OP2A_8 ws2 lmem8 imm16)
+ (if ws2
+ (set-mem-psw (mem HI (and lmem8 #xFFFE)) imm16 ws2)
+ (set-mem-psw (mem QI lmem8) (and imm16 #xFF) ws2))
+ ()
+)
+(dni movhmemimm
+ "Move immediate to high memory"
+ ()
+ ("mov$ws2 $hmem8,#$imm16")
+ (+ OP1_7 OP2A_A ws2 hmem8 imm16)
+ (if ws2
+ (set-mem-psw (mem HI (and hmem8 #xFFFE)) imm16 ws2)
+ (set-mem-psw (mem QI hmem8) (and imm16 #xFF) ws2))
+ ()
+)
+
+(dni movlgrmem
+ "Move low memory to register"
+ ()
+ ("mov$ws2 $Rm,$lmem8")
+ (+ OP1_8 Rm ws2 lmem8)
+ (if ws2
+ (set-psw Rm (index-of Rm) (alignfix-mem lmem8) ws2)
+ (set-psw Rm (index-of Rm) (mem QI lmem8) ws2))
+ ()
+)
+(dni movhgrmem
+ "Move high memory to register"
+ ()
+ ("mov$ws2 $Rm,$hmem8")
+ (+ OP1_A Rm ws2 hmem8)
+ (if ws2
+ (set-psw Rm (index-of Rm) (alignfix-mem hmem8) ws2)
+ (set-psw Rm (index-of Rm) (mem QI hmem8) ws2))
+ ()
+)
+
+(dni movlmemgr
+ "Move low memory register to byte"
+ ()
+ ("mov$ws2 $lmem8,$Rm")
+ (+ OP1_9 Rm ws2 lmem8)
+ (if ws2
+ (set-mem-psw (mem HI (and lmem8 #xFFFE)) Rm ws2)
+ (set-mem-psw (mem QI lmem8) Rm ws2))
+ ()
+)
+(dni movhmemgr
+ "Move high memory register to byte"
+ ()
+ ("mov$ws2 $hmem8,$Rm")
+ (+ OP1_B Rm ws2 hmem8)
+ (if ws2
+ (set-mem-psw (mem HI (and hmem8 #xFFFE)) Rm ws2)
+ (set-mem-psw (mem QI hmem8) Rm ws2))
+ ()
+)
+
+(dni movgrgri
+ "Move memory addressed by register to register"
+ ()
+ ("mov$ws2 $Rdm,($Rs)")
+ (+ OP1_7 OP2A_0 ws2 Rs OP4M_0 Rdm)
+ (if ws2
+ (set-psw Rdm (index-of Rdm) (alignfix-mem Rs) ws2)
+ (set-psw Rdm (index-of Rdm) (and #xFF (mem QI Rs)) ws2))
+ ()
+)
+
+(dni movgrgripostinc
+ "Move memory addressed by postincrement register to register"
+ ()
+ ("mov$ws2 $Rdm,($Rs++)")
+ (+ OP1_6 OP2A_0 ws2 Rs OP4M_0 Rdm)
+ (sequence ()
+ (if ws2
+ (set-psw Rdm (index-of Rdm) (alignfix-mem Rs) ws2)
+ (set-psw Rdm (index-of Rdm) (and #xFF (mem QI Rs)) ws2))
+ (set Rs (add Rs (add 1 ws2))))
+ ()
+)
+
+(dni movgrgripredec
+ "Move memory addressed by predecrement register to register"
+ ()
+ ("mov$ws2 $Rdm,(--$Rs)")
+ (+ OP1_6 OP2A_8 ws2 Rs OP4M_0 Rdm)
+ (sequence ()
+ (set Rs (sub Rs (add 1 ws2)))
+ (if ws2
+ (set-psw Rdm (index-of Rdm) (alignfix-mem Rs) ws2)
+ (set-psw Rdm (index-of Rdm) (and #xFF (mem QI Rs)) ws2)))
+ ()
+)
+
+(dni movgrigr
+ "Move register to memory addressed by register"
+ ()
+ ("mov$ws2 ($Rs),$Rdm")
+ (+ OP1_7 OP2A_2 ws2 Rs OP4M_0 Rdm)
+ (sequence ()
+ (if ws2
+ (set-alignfix-mem Rs Rdm)
+ (set (mem QI Rs) Rdm))
+ (set-psw-nowrite (index-of Rdm) Rdm ws2))
+ ()
+)
+
+(dni movgripostincgr
+ "Move register to memory addressed by postincrement register"
+ ()
+ ("mov$ws2 ($Rs++),$Rdm")
+ (+ OP1_6 OP2A_2 ws2 Rs OP4M_0 Rdm)
+ (sequence ()
+ (if ws2
+ (set-alignfix-mem Rs Rdm)
+ (set (mem QI Rs) Rdm))
+ (set-psw-nowrite (index-of Rdm) Rdm ws2)
+ (set Rs (add Rs (add ws2 1))))
+ ()
+)
+
+(dni movgripredecgr
+ "Move register to memory addressed by predecrement register"
+ ()
+ ("mov$ws2 (--$Rs),$Rdm")
+ (+ OP1_6 OP2A_A ws2 Rs OP4M_0 Rdm)
+ (sequence ()
+ (set Rs (sub Rs (add ws2 1)))
+ (set-psw-nowrite (index-of Rdm) Rdm ws2)
+ (if ws2
+ (set-alignfix-mem Rs Rdm)
+ (set (mem QI Rs) Rdm)))
+ ()
+)
+
+(dni movgrgrii
+ "Move memory addressed by indexed register to register"
+ ()
+ ("mov$ws2 $Rdm,($Rs,$imm12)")
+ (+ OP1_7 OP2A_0 ws2 Rs OP4M_1 Rdm OP5_0 imm12)
+ (if ws2
+ (set-psw Rdm (index-of Rdm) (alignfix-mem (add Rs imm12)) ws2)
+ (set-psw Rdm (index-of Rdm) (and #xFF (mem QI (add Rs imm12))) ws2))
+ ()
+)
+
+(dni movgrgriipostinc
+ "Move memory addressed by indexed register postincrement to register"
+ ()
+ ("mov$ws2 $Rdm,($Rs++,$imm12)")
+ (+ OP1_6 OP2A_0 ws2 Rs OP4M_1 Rdm OP5_0 imm12)
+ (sequence ()
+ (if ws2
+ (set-psw Rdm (index-of Rdm) (alignfix-mem (add Rs imm12)) ws2)
+ (set-psw Rdm (index-of Rdm) (and #xFF (mem QI (add Rs imm12))) ws2))
+ (set Rs (add Rs (add ws2 1))))
+ ()
+)
+
+(dni movgrgriipredec
+ "Move memory addressed by indexed register predecrement to register"
+ ()
+ ("mov$ws2 $Rdm,(--$Rs,$imm12)")
+ (+ OP1_6 OP2A_8 ws2 Rs OP4M_1 Rdm OP5_0 imm12)
+ (sequence ()
+ (set Rs (sub Rs (add ws2 1)))
+ (if ws2
+ (set-psw Rdm (index-of Rdm) (alignfix-mem (add Rs imm12)) ws2)
+ (set-psw Rdm (index-of Rdm) (and #xFF (mem QI (add Rs imm12))) ws2)))
+ ()
+)
+
+(dni movgriigr
+ "Move register to memory addressed by indexed register"
+ ()
+ ("mov$ws2 ($Rs,$imm12),$Rdm")
+ (+ OP1_7 OP2A_2 ws2 Rs OP4M_1 Rdm OP5_0 imm12)
+ (sequence ()
+ (if ws2
+ (set-alignfix-mem (add Rs imm12) Rdm)
+ (set (mem QI (add Rs imm12)) Rdm))
+ (set-psw-nowrite (index-of Rdm) Rdm ws2))
+ ()
+)
+
+(dni movgriipostincgr
+ "Move register to memory addressed by indexed register postincrement"
+ ()
+ ("mov$ws2 ($Rs++,$imm12),$Rdm")
+ (+ OP1_6 OP2A_2 ws2 Rs OP4M_1 Rdm OP5_0 imm12)
+ (sequence ()
+ (if ws2
+ (set-alignfix-mem (add Rs imm12) Rdm)
+ (set (mem QI (add Rs imm12)) Rdm))
+ (set-psw-nowrite (index-of Rdm) Rdm ws2)
+ (set Rs (add Rs (add ws2 1))))
+ ()
+)
+
+(dni movgriipredecgr
+ "Move register to memory addressed by indexed register predecrement"
+ ()
+ ("mov$ws2 (--$Rs,$imm12),$Rdm")
+ (+ OP1_6 OP2A_A ws2 Rs OP4M_1 Rdm OP5_0 imm12)
+ (sequence ()
+ (set Rs (sub Rs (add ws2 1)))
+ (set-psw-nowrite (index-of Rdm) Rdm ws2)
+ (if ws2
+ (set-alignfix-mem (add Rs imm12) Rdm)
+ (set (mem QI (add Rs imm12)) Rdm)))
+ ()
+)
+
+(dni movgrgr
+ "Move general register to general register"
+ ()
+ ("mov $Rd,$Rs")
+ (+ OP1_4 OP2_6 Rs Rd)
+ (set-psw Rd (index-of Rd) Rs 1)
+ ()
+)
+
+(dnmi movimm8
+ "Move 8-bit immediate"
+ ()
+ ("mov Rx,#$imm8")
+ (emit movwimm8 imm8)
+)
+
+(dni movwimm8
+ "Move 8-bit immediate"
+ ()
+ ("mov.w Rx,#$imm8")
+ (+ OP1_4 OP2_7 imm8)
+ (set-psw (reg HI h-gr Rpsw) Rpsw imm8 1)
+ ()
+)
+
+(dnmi movgrimm8
+ "Move 8-bit immediate to general register"
+ ()
+ ("mov $Rm,#$imm8small")
+ (emit movwgrimm8 Rm imm8small)
+)
+
+(dni movwgrimm8
+ "Move 8-bit immediate to general register"
+ ()
+ ("mov.w $Rm,#$imm8small")
+ (+ OP1_2 Rm OP2M_1 imm8small)
+ (set-psw Rm (index-of Rm) imm8small 1)
+ ()
+)
+
+(dnmi movgrimm16
+ "Move 16-bit immediate to general register"
+ ()
+ ("mov $Rd,#$imm16")
+ (emit movwgrimm16 Rd imm16)
+)
+
+(dni movwgrimm16
+ "Move 16-bit immediate to general register"
+ ()
+ ("mov.w $Rd,#$imm16")
+ (+ OP1_3 OP2_1 OP3_3 Rd imm16)
+ (set-psw Rd (index-of Rd) imm16 1)
+ ()
+)
+
+(dni movlowgr
+ "Move 8 low bits to general register"
+ ()
+ ("mov.b $Rd,RxL")
+ (+ OP1_3 OP2_0 OP3_C Rd)
+ (set-psw Rd (index-of Rd) (or (and Rd #xFF00) (and (reg HI h-gr Rpsw) #xFF)) 0)
+ ()
+)
+
+(dni movhighgr
+ "Move 8 high bits to general register"
+ ()
+ ("mov.b $Rd,RxH")
+ (+ OP1_3 OP2_0 OP3_D Rd)
+ (set-psw Rd (index-of Rd) (or (and Rd #x00FF) (and (reg HI h-gr Rpsw) #xFF00)) 1)
+ ()
+)
+
+(dni movfgrgri
+ "Move far memory addressed by register to register"
+ ()
+ ("movf$ws2 $Rdm,($Rs)")
+ (+ OP1_7 OP2A_4 ws2 Rs OP4M_0 Rdm)
+ (if ws2
+ (set-psw Rdm (index-of Rdm) (alignfix-mem-far (or (sll SI R8 16) Rs)) ws2)
+ (set-psw Rdm (index-of Rdm) (and #xFF (mem QI (or (sll SI R8 16) Rs))) ws2))
+ ()
+)
+
+(dni movfgrgripostinc
+ "Move far memory addressed by postincrement register to register"
+ ()
+ ("movf$ws2 $Rdm,($Rs++)")
+ (+ OP1_6 OP2A_4 ws2 Rs OP4M_0 Rdm)
+ (sequence ()
+ (if ws2
+ (set-psw Rdm (index-of Rdm) (alignfix-mem-far (join SI HI R8 Rs)) ws2)
+ (set-psw Rdm (index-of Rdm) (and #xFF (mem QI (join SI HI R8 Rs))) ws2))
+ (set Rs (add Rs (add ws2 1))))
+ ()
+)
+
+(dni movfgrgripredec
+ "Move far memory addressed by predecrement register to register"
+ ()
+ ("movf$ws2 $Rdm,(--$Rs)")
+ (+ OP1_6 OP2A_C ws2 Rs OP4M_0 Rdm)
+ (sequence ()
+ (set Rs (sub Rs (add ws2 1)))
+ (if ws2
+ (set-psw Rdm (index-of Rdm) (alignfix-mem-far (join SI HI R8 Rs)) ws2)
+ (set-psw Rdm (index-of Rdm) (and #xFF (mem QI (join SI HI R8 Rs))) ws2)))
+ ()
+)
+
+(dni movfgrigr
+ "Move far register to memory addressed by register"
+ ()
+ ("movf$ws2 ($Rs),$Rdm")
+ (+ OP1_7 OP2A_6 ws2 Rs OP4M_0 Rdm)
+ (sequence ()
+ (if ws2
+ (set-alignfix-mem-far (join SI HI R8 Rs) Rdm)
+ (set (mem QI (join SI HI R8 Rs)) Rdm))
+ (set-psw-nowrite (index-of Rdm) Rdm ws2))
+ ()
+)
+
+(dni movfgripostincgr
+ "Move far register to memory addressed by postincrement register"
+ ()
+ ("movf$ws2 ($Rs++),$Rdm")
+ (+ OP1_6 OP2A_6 ws2 Rs OP4M_0 Rdm)
+ (sequence ()
+ (if ws2
+ (set-alignfix-mem-far (join SI HI R8 Rs) Rdm)
+ (set (mem QI (join SI HI R8 Rs)) Rdm))
+ (set-psw-nowrite (index-of Rdm) Rdm ws2)
+ (set Rs (add Rs (add ws2 1))))
+ ()
+)
+
+(dni movfgripredecgr
+ "Move far register to memory addressed by predecrement register"
+ ()
+ ("movf$ws2 (--$Rs),$Rdm")
+ (+ OP1_6 OP2A_E ws2 Rs OP4M_0 Rdm)
+ (sequence ()
+ (set-psw-nowrite (index-of Rdm) Rdm ws2)
+ (set Rs (sub Rs (add ws2 1)))
+ (if ws2
+ (set-alignfix-mem-far (join SI HI R8 Rs) Rdm)
+ (set (mem QI (join SI HI R8 Rs)) Rdm)))
+ ()
+)
+
+(dni movfgrgrii
+ "Move far memory addressed by indexed register to register"
+ ()
+ ("movf$ws2 $Rdm,($Rb,$Rs,$imm12)")
+ (+ OP1_7 OP2A_4 ws2 Rs OP4M_1 Rdm OP5A_0 Rb imm12)
+ (if ws2
+ (set-psw Rdm (index-of Rdm) (alignfix-mem-far (add (join SI HI Rb Rs) imm12)) ws2)
+ (set-psw Rdm (index-of Rdm) (and #xFF (mem QI (add (join SI HI Rb Rs) imm12))) ws2))
+ ()
+)
+
+(dni movfgrgriipostinc
+ "Move far memory addressed by indexed register postincrement to register"
+ ()
+ ("movf$ws2 $Rdm,($Rb,$Rs++,$imm12)")
+ (+ OP1_6 OP2A_4 ws2 Rs OP4M_1 Rdm OP5A_0 Rb imm12)
+ (sequence ()
+ (if ws2
+ (set-psw Rdm (index-of Rdm) (alignfix-mem-far (add (join SI HI Rb Rs) imm12)) ws2)
+ (set-psw Rdm (index-of Rdm) (and #xFF (mem QI (add (join SI HI Rb Rs) imm12))) ws2))
+ (set Rs (add Rs (add ws2 1)))
+ ; Note - despite the XStormy16 ISA documentation the
+ ; addition *is* propogated into the base register.
+ (if (eq Rs 0) (set Rb (add Rb 1)))
+ )
+ ()
+)
+
+(dni movfgrgriipredec
+ "Move far memory addressed by indexed register predecrement to register"
+ ()
+ ("movf$ws2 $Rdm,($Rb,--$Rs,$imm12)")
+ (+ OP1_6 OP2A_C ws2 Rs OP4M_1 Rdm OP5A_0 Rb imm12)
+ (sequence ()
+ ; Note - despite the XStormy16 ISA documentation the
+ ; subtraction *is* propogated into the base register.
+ (if (eq Rs 0) (set Rb (sub Rb 1)))
+ (set Rs (sub Rs (add ws2 1)))
+ (if ws2
+ (set-psw Rdm (index-of Rdm) (alignfix-mem-far (add (join SI HI Rb Rs) imm12)) ws2)
+ (set-psw Rdm (index-of Rdm) (and #xFF (mem QI (add (join SI HI Rb Rs) imm12))) ws2)))
+ ()
+)
+
+(dni movfgriigr
+ "Move far register to memory addressed by indexed register"
+ ()
+ ("movf$ws2 ($Rb,$Rs,$imm12),$Rdm")
+ (+ OP1_7 OP2A_6 ws2 Rs OP4M_1 Rdm OP5A_0 Rb imm12)
+ (sequence ()
+ (if ws2
+ (set (mem HI (and (add (join SI HI Rb Rs) imm12) #xFFFFFFFE))
+ Rdm)
+ (set (mem QI (add (join SI HI Rb Rs) imm12)) Rdm))
+ (set-psw-nowrite (index-of Rdm) Rdm ws2))
+ ()
+)
+
+
+(dni movfgriipostincgr
+ "Move far register to memory addressed by indexed register postincrement"
+ ()
+ ("movf$ws2 ($Rb,$Rs++,$imm12),$Rdm")
+ (+ OP1_6 OP2A_6 ws2 Rs OP4M_1 Rdm OP5A_0 Rb imm12)
+ (sequence ()
+ (if ws2
+ (set (mem HI (and (add (join SI HI Rb Rs) imm12) #xFFFFFFFE)) Rdm)
+ (set (mem QI (add (join SI HI Rb Rs) imm12)) Rdm))
+ (set-psw-nowrite (index-of Rdm) Rdm ws2)
+ (set Rs (add Rs (add ws2 1)))
+ ; Note - despite the XStormy16 ISA documentation the
+ ; addition *is* propogated into the base register.
+ (if (eq Rs 0) (set Rb (add Rb 1)))
+ )
+ ()
+)
+
+(dni movfgriipredecgr
+ "Move far register to memory addressed by indexed register predecrement"
+ ()
+ ("movf$ws2 ($Rb,--$Rs,$imm12),$Rdm")
+ (+ OP1_6 OP2A_E ws2 Rs OP4M_1 Rdm OP5A_0 Rb imm12)
+ (sequence ()
+ ; Note - despite the XStormy16 ISA documentation the
+ ; subtraction *is* propogated into the base register.
+ (if (eq Rs 0) (set Rb (sub Rb 1)))
+ (set Rs (sub Rs (add ws2 1)))
+ (set-psw-nowrite (index-of Rdm) Rdm ws2)
+ (if ws2
+ (set (mem HI (and (add (join SI HI Rb Rs) imm12) #xFFFFFFFE)) Rdm)
+ (set (mem QI (add (join SI HI Rb Rs) imm12)) Rdm)))
+ ()
+)
+
+(dni maskgrgr
+ "Mask insert controlled by general register"
+ ()
+ ("mask $Rd,$Rs")
+ (+ OP1_3 OP2_3 Rs Rd)
+ (set-psw Rd (index-of Rd) (or HI (and HI Rd (inv HI Rs)) (and (reg HI h-gr Rpsw) Rs)) 1)
+ ()
+)
+
+(dni maskgrimm16
+ "Mask insert controlled by immediate value"
+ ()
+ ("mask $Rd,#$imm16")
+ (+ OP1_3 OP2_0 OP3_E Rd imm16)
+ (set-psw Rd (index-of Rd) (or (and Rd (inv imm16)) (and (reg HI h-gr Rpsw) imm16)) 1)
+ ()
+)
+
+; Push, Pop
+(dni pushgr
+ "Push register"
+ ()
+ ("push $Rd")
+ (+ OP1_0 OP2_0 OP3_8 Rd)
+ (sequence ()
+ (set (mem HI sp) Rd)
+ (set sp (add sp 2)))
+ ()
+)
+
+(dni popgr
+ "Pop into a register"
+ ()
+ ("pop $Rd")
+ (+ OP1_0 OP2_0 OP3_9 Rd)
+ (sequence ()
+ (set sp (add sp -2))
+ (set Rd (mem HI sp)))
+ ()
+)
+
+; Swap
+(dni swpn
+ "Swap low nibbles"
+ ()
+ ("swpn $Rd")
+ (+ OP1_3 OP2_0 OP3_9 Rd)
+ (set-psw Rd (index-of Rd) (or (or (and (sll Rd 4) #xF0)
+ (and (srl Rd 4) #x0F))
+ (and Rd #xFF00)) 0)
+ ()
+)
+
+(dni swpb
+ "Swap bytes"
+ ()
+ ("swpb $Rd")
+ (+ OP1_3 OP2_0 OP3_8 Rd)
+ (set-psw Rd (index-of Rd) (or (sll Rd 8) (srl Rd 8)) 1)
+ ()
+)
+
+(dni swpw
+ "Swap words"
+ ()
+ ("swpw $Rd,$Rs")
+ (+ OP1_3 OP2_2 Rs Rd)
+ (sequence ((HI foo))
+ (set foo Rs)
+ (set Rs Rd)
+ (set-psw Rd (index-of Rd) foo 1))
+ ()
+)
+
+; Logical Operations
+(dni andgrgr
+ "AND general register with general register"
+ ()
+ ("and $Rd,$Rs")
+ (+ OP1_4 OP2_0 Rs Rd)
+ (set-psw Rd (index-of Rd) (and Rd Rs) 1)
+ ()
+)
+
+(dni andimm8
+ "AND with 8-bit immediate"
+ ()
+ ("and Rx,#$imm8")
+ (+ OP1_4 OP2_1 imm8)
+ (set-psw (reg HI h-gr Rpsw) Rpsw (and (reg HI h-gr Rpsw) imm8) 1)
+ ()
+)
+
+(dni andgrimm16
+ "AND general register with 16-bit immediate"
+ ()
+ ("and $Rd,#$imm16")
+ (+ OP1_3 OP2_1 OP3_0 Rd imm16)
+ (set-psw Rd (index-of Rd) (and Rd imm16) 1)
+ ()
+)
+
+(dni orgrgr
+ "OR general register with general register"
+ ()
+ ("or $Rd,$Rs")
+ (+ OP1_4 OP2_2 Rs Rd)
+ (set-psw Rd (index-of Rd) (or Rd Rs) 1)
+ ()
+)
+
+(dni orimm8
+ "OR with 8-bit immediate"
+ ()
+ ("or Rx,#$imm8")
+ (+ OP1_4 OP2_3 imm8)
+ (set-psw (reg HI h-gr Rpsw) Rpsw (or (reg HI h-gr Rpsw) imm8) 1)
+ ()
+)
+
+(dni orgrimm16
+ "OR general register with 16-bit immediate"
+ ()
+ ("or $Rd,#$imm16")
+ (+ OP1_3 OP2_1 OP3_1 Rd imm16)
+ (set-psw Rd (index-of Rd) (or Rd imm16) 1)
+ ()
+)
+
+(dni xorgrgr
+ "XOR general register with general register"
+ ()
+ ("xor $Rd,$Rs")
+ (+ OP1_4 OP2_4 Rs Rd)
+ (set-psw Rd (index-of Rd) (xor Rd Rs) 1)
+ ()
+)
+
+(dni xorimm8
+ "XOR with 8-bit immediate"
+ ()
+ ("xor Rx,#$imm8")
+ (+ OP1_4 OP2_5 imm8)
+ (set-psw (reg HI h-gr Rpsw) Rpsw (xor (reg HI h-gr Rpsw) imm8) 1)
+ ()
+)
+
+(dni xorgrimm16
+ "XOR general register with 16-bit immediate"
+ ()
+ ("xor $Rd,#$imm16")
+ (+ OP1_3 OP2_1 OP3_2 Rd imm16)
+ (set-psw Rd (index-of Rd) (xor Rd imm16) 1)
+ ()
+)
+
+(dni notgr
+ "NOT general register"
+ ()
+ ("not $Rd")
+ (+ OP1_3 OP2_0 OP3_B Rd)
+ (set-psw Rd (index-of Rd) (inv Rd) 1)
+ ()
+)
+
+; Arithmetic operations
+(dni addgrgr
+ "ADD general register to general register"
+ ()
+ ("add $Rd,$Rs")
+ (+ OP1_4 OP2_9 Rs Rd)
+ (set-psw-add Rd (index-of Rd) Rd Rs 0)
+ ()
+)
+
+(dni addgrimm4
+ "ADD 4-bit immediate to general register"
+ ()
+ ("add $Rd,#$imm4")
+ (+ OP1_5 OP2_1 imm4 Rd)
+ (set-psw-add Rd (index-of Rd) Rd imm4 0)
+ ()
+)
+
+(dni addimm8
+ "ADD 8-bit immediate"
+ ()
+ ("add Rx,#$imm8")
+ (+ OP1_5 OP2_9 imm8)
+ (set-psw-add (reg HI h-gr Rpsw) Rpsw (reg HI h-gr Rpsw) imm8 0)
+ ()
+)
+
+(dni addgrimm16
+ "ADD 16-bit immediate to general register"
+ ()
+ ("add $Rd,#$imm16")
+ (+ OP1_3 OP2_1 OP3_4 Rd imm16)
+ (set-psw-add Rd (index-of Rd) Rd imm16 0)
+ ()
+)
+
+(dni adcgrgr
+ "ADD carry and general register to general register"
+ ()
+ ("adc $Rd,$Rs")
+ (+ OP1_4 OP2_B Rs Rd)
+ (set-psw-add Rd (index-of Rd) Rd Rs psw-cy)
+ ()
+)
+
+(dni adcgrimm4
+ "ADD carry and 4-bit immediate to general register"
+ ()
+ ("adc $Rd,#$imm4")
+ (+ OP1_5 OP2_3 imm4 Rd)
+ (set-psw-add Rd (index-of Rd) Rd imm4 psw-cy)
+ ()
+)
+
+(dni adcimm8
+ "ADD carry and 8-bit immediate"
+ ()
+ ("adc Rx,#$imm8")
+ (+ OP1_5 OP2_B imm8)
+ (set-psw-add (reg HI h-gr Rpsw) Rpsw (reg HI h-gr Rpsw) imm8 psw-cy)
+ ()
+)
+
+(dni adcgrimm16
+ "ADD carry and 16-bit immediate to general register"
+ ()
+ ("adc $Rd,#$imm16")
+ (+ OP1_3 OP2_1 OP3_5 Rd imm16)
+ (set-psw-add Rd (index-of Rd) Rd imm16 psw-cy)
+ ()
+)
+
+(dni subgrgr
+ "SUB general register from general register"
+ ()
+ ("sub $Rd,$Rs")
+ (+ OP1_4 OP2_D Rs Rd)
+ (set-psw-sub Rd (index-of Rd) Rd Rs 0)
+ ()
+)
+
+(dni subgrimm4
+ "SUB 4-bit immediate from general register"
+ ()
+ ("sub $Rd,#$imm4")
+ (+ OP1_5 OP2_5 imm4 Rd)
+ (set-psw-sub Rd (index-of Rd) Rd imm4 0)
+ ()
+)
+
+(dni subimm8
+ "SUB 8-bit immediate"
+ ()
+ ("sub Rx,#$imm8")
+ (+ OP1_5 OP2_D imm8)
+ (set-psw-sub (reg HI h-gr Rpsw) Rpsw (reg HI h-gr Rpsw) imm8 0)
+ ()
+)
+
+(dni subgrimm16
+ "SUB 16-bit immediate from general register"
+ ()
+ ("sub $Rd,#$imm16")
+ (+ OP1_3 OP2_1 OP3_6 Rd imm16)
+ (set-psw-sub Rd (index-of Rd) Rd imm16 0)
+ ()
+)
+
+(dni sbcgrgr
+ "SUB carry and general register from general register"
+ ()
+ ("sbc $Rd,$Rs")
+ (+ OP1_4 OP2_F Rs Rd)
+ (set-psw-sub Rd (index-of Rd) Rd Rs psw-cy)
+ ()
+)
+
+(dni sbcgrimm4
+ "SUB carry and 4-bit immediate from general register"
+ ()
+ ("sbc $Rd,#$imm4")
+ (+ OP1_5 OP2_7 imm4 Rd)
+ (set-psw-sub Rd (index-of Rd) Rd imm4 psw-cy)
+ ()
+)
+
+(dni sbcgrimm8
+ "SUB carry and 8-bit immediate"
+ ()
+ ("sbc Rx,#$imm8")
+ (+ OP1_5 OP2_F imm8)
+ (set-psw-sub (reg HI h-gr Rpsw) Rpsw (reg HI h-gr Rpsw) imm8 psw-cy)
+ ()
+)
+
+(dni sbcgrimm16
+ "SUB carry and 16-bit immediate from general register"
+ ()
+ ("sbc $Rd,#$imm16")
+ (+ OP1_3 OP2_1 OP3_7 Rd imm16)
+ (set-psw-sub Rd (index-of Rd) Rd imm16 psw-cy)
+ ()
+)
+
+(dnmi incgr
+ "Increment general register"
+ ()
+ ("inc $Rd")
+ (emit incgrimm2 Rd (imm2 0))
+)
+
+(dni incgrimm2
+ "Increment general register by 2-bit immediate"
+ ()
+ ("inc $Rd,#$imm2")
+ (+ OP1_3 OP2_0 OP3A_0 imm2 Rd)
+ (set-psw Rd (index-of Rd) (add Rd (add imm2 1)) 1)
+ ()
+)
+
+(dnmi decgr
+ "Decrement general register"
+ ()
+ ("dec $Rd")
+ (emit decgrimm2 Rd (imm2 0))
+)
+
+(dni decgrimm2
+ "Decrement general register by 2-bit immediate"
+ ()
+ ("dec $Rd,#$imm2")
+ (+ OP1_3 OP2_0 OP3A_1 imm2 Rd)
+ (set-psw Rd (index-of Rd) (sub Rd (add imm2 1)) 1)
+ ()
+)
+
+; Logical Shift
+(dni rrcgrgr
+ "Rotate right general register by general register"
+ ()
+ ("rrc $Rd,$Rs")
+ (+ OP1_3 OP2_8 Rs Rd)
+ (set-psw-rrotate17 Rd (index-of Rd) Rd psw-cy Rs)
+ ()
+)
+
+(dni rrcgrimm4
+ "Rotate right general register by immediate"
+ ()
+ ("rrc $Rd,#$imm4")
+ (+ OP1_3 OP2_9 imm4 Rd)
+ (set-psw-rrotate17 Rd (index-of Rd) Rd psw-cy imm4)
+ ()
+)
+
+(dni rlcgrgr
+ "Rotate left general register by general register"
+ ()
+ ("rlc $Rd,$Rs")
+ (+ OP1_3 OP2_A Rs Rd)
+ (set-psw-rotate17 Rd (index-of Rd) Rd psw-cy (and Rs #xF))
+ ()
+)
+
+(dni rlcgrimm4
+ "Rotate left general register by immediate"
+ ()
+ ("rlc $Rd,#$imm4")
+ (+ OP1_3 OP2_B imm4 Rd)
+ (set-psw-rotate17 Rd (index-of Rd) Rd psw-cy imm4)
+ ()
+)
+
+(dni shrgrgr
+ "Shift right general register by general register"
+ ()
+ ("shr $Rd,$Rs")
+ (+ OP1_3 OP2_C Rs Rd)
+ (set-psw-carry Rd (index-of Rd)
+ (srl Rd (and Rs #xF))
+ (and SI (if SI (eq (and Rs #xF) 0)
+ psw-cy
+ (srl Rd (sub (and Rs #xF) 1)))
+ 1) 1)
+ ()
+)
+
+(dni shrgrimm
+ "Shift right general register by immediate"
+ ()
+ ("shr $Rd,#$imm4")
+ (+ OP1_3 OP2_D imm4 Rd)
+ (set-psw-carry Rd (index-of Rd)
+ (srl Rd imm4)
+ (and SI (if SI (eq imm4 0)
+ psw-cy
+ (srl Rd (sub imm4 1)))
+ 1) 1)
+ ()
+)
+
+(dni shlgrgr
+ "Shift left general register by general register"
+ ()
+ ("shl $Rd,$Rs")
+ (+ OP1_3 OP2_E Rs Rd)
+ (set-psw-carry Rd (index-of Rd)
+ (sll Rd (and Rs #xF))
+ (srl SI (if SI (eq (and Rs #xF) 0)
+ (sll psw-cy 15)
+ (sll Rd (sub (and Rs #xF) 1)))
+ 15) 1)
+ ()
+)
+
+(dni shlgrimm
+ "Shift left general register by immediate"
+ ()
+ ("shl $Rd,#$imm4")
+ (+ OP1_3 OP2_F imm4 Rd)
+ (set-psw-carry Rd (index-of Rd)
+ (sll Rd imm4)
+ (srl SI (if SI (eq imm4 0)
+ (sll psw-cy 15)
+ (sll Rd (sub imm4 1)))
+ 15) 1)
+ ()
+)
+
+(dni asrgrgr
+ "Arithmetic shift right general register by general register"
+ ()
+ ("asr $Rd,$Rs")
+ (+ OP1_3 OP2_6 Rs Rd)
+ (set-psw-carry Rd (index-of Rd)
+ (sra HI Rd (and Rs #xF))
+ (and SI (if SI (eq (and Rs #xF) 0)
+ psw-cy
+ (srl Rd (sub (and Rs #xF) 1)))
+ 1) 1)
+ ()
+)
+
+(dni asrgrimm
+ "Arithmetic shift right general register by immediate"
+ ()
+ ("asr $Rd,#$imm4")
+ (+ OP1_3 OP2_7 imm4 Rd)
+ (set-psw-carry Rd (index-of Rd)
+ (sra HI Rd imm4)
+ (and SI (if SI (eq imm4 0)
+ psw-cy
+ (srl Rd (sub imm4 1)))
+ 1) 1)
+ ()
+)
+
+; Bitwise operations
+(dni set1grimm
+ "Set bit in general register by immediate"
+ ()
+ ("set1 $Rd,#$imm4")
+ (+ OP1_0 OP2_9 imm4 Rd)
+ (set-psw Rd (index-of Rd) (or Rd (sll 1 imm4)) 1)
+ ()
+)
+
+(dni set1grgr
+ "Set bit in general register by general register"
+ ()
+ ("set1 $Rd,$Rs")
+ (+ OP1_0 OP2_B Rs Rd)
+ (set-psw Rd (index-of Rd) (or Rd (sll 1 (and Rs #xF))) 1)
+ ()
+)
+
+(dni set1lmemimm
+ "Set bit in low memory by immediate"
+ ()
+ ("set1 $lmem8,#$imm3")
+ (+ OP1_E imm3 OP2M_1 lmem8)
+ (set-mem-psw (mem QI lmem8) (or (mem QI lmem8) (sll 1 imm3)) 0)
+ ()
+)
+(dni set1hmemimm
+ "Set bit in high memory by immediate"
+ ()
+ ("set1 $hmem8,#$imm3")
+ (+ OP1_F imm3 OP2M_1 hmem8)
+ (set-mem-psw (mem QI hmem8) (or (mem QI hmem8) (sll 1 imm3)) 0)
+ ()
+)
+
+(dni clr1grimm
+ "Clear bit in general register by immediate"
+ ()
+ ("clr1 $Rd,#$imm4")
+ (+ OP1_0 OP2_8 imm4 Rd)
+ (set-psw Rd (index-of Rd) (and Rd (inv (sll 1 imm4))) 1)
+ ()
+)
+
+(dni clr1grgr
+ "Clear bit in general register by general register"
+ ()
+ ("clr1 $Rd,$Rs")
+ (+ OP1_0 OP2_A Rs Rd)
+ (set-psw Rd (index-of Rd) (and Rd (inv (sll 1 (and Rs #xF)))) 1)
+ ()
+)
+
+(dni clr1lmemimm
+ "Clear bit in low memory"
+ ()
+ ("clr1 $lmem8,#$imm3")
+ (+ OP1_E imm3 OP2M_0 lmem8)
+ (set-mem-psw (mem QI lmem8) (and (mem QI lmem8) (inv (sll 1 imm3))) 0)
+ ()
+)
+(dni clr1hmemimm
+ "Clear bit in high memory"
+ ()
+ ("clr1 $hmem8,#$imm3")
+ (+ OP1_F imm3 OP2M_0 hmem8)
+ (set-mem-psw (mem QI hmem8) (and (mem QI hmem8) (inv (sll 1 imm3))) 0)
+ ()
+)
+
+; Data conversion
+
+(dni cbwgr
+ "Sign-extend byte in general register"
+ ()
+ ("cbw $Rd")
+ (+ OP1_3 OP2_0 OP3_A Rd)
+ (set-psw Rd (index-of Rd) (ext HI (trunc QI Rd)) 1)
+ ()
+)
+
+(dni revgr
+ "Reverse bit pattern in general register"
+ ()
+ ("rev $Rd")
+ (+ OP1_3 OP2_0 OP3_F Rd)
+ (set-psw Rd (index-of Rd)
+ (or (sll (and Rd #x0001) 15)
+ (or (sll (and Rd #x0002) 13)
+ (or (sll (and Rd #x0004) 11)
+ (or (sll (and Rd #x0008) 9)
+ (or (sll (and Rd #x0010) 7)
+ (or (sll (and Rd #x0020) 5)
+ (or (sll (and Rd #x0040) 3)
+ (or (sll (and Rd #x0080) 1)
+ (or (srl (and Rd #x0100) 1)
+ (or (srl (and Rd #x0200) 3)
+ (or (srl (and Rd #x0400) 5)
+ (or (srl (and Rd #x0800) 7)
+ (or (srl (and Rd #x1000) 9)
+ (or (srl (and Rd #x2000) 11)
+ (or (srl (and Rd #x4000) 13)
+ (srl (and Rd #x8000) 15))))))))))))))))
+ 1)
+ ()
+)
+
+; Conditional Branches
+
+(define-pmacro (cbranch cond dest)
+ (sequence ((BI tmp))
+ (case cond
+ ((0) (set tmp (not (xor psw-s psw-ov)))) ; ge
+ ((1) (set tmp (not psw-cy))) ; nc
+ ((2) (set tmp (xor psw-s psw-ov))) ; lt
+ ((3) (set tmp psw-cy)) ; c
+ ((4) (set tmp (not (or (xor psw-s psw-ov) psw-z16)))) ; gt
+ ((5) (set tmp (not (or psw-cy psw-z16)))) ; hi
+ ((6) (set tmp (or (xor psw-s psw-ov) psw-z16))) ; le
+ ((7) (set tmp (or psw-cy psw-z16))) ; ls
+ ((8) (set tmp (not psw-s))) ; pl
+ ((9) (set tmp (not psw-ov))) ; nv
+ ((10) (set tmp psw-s)) ; mi
+ ((11) (set tmp psw-ov)) ; v
+ ((12) (set tmp (not psw-z8))) ; nz.b
+ ((13) (set tmp (not psw-z16))) ; nz
+ ((14) (set tmp psw-z8)) ; z.b
+ ((15) (set tmp psw-z16))) ; z
+ (if tmp (set pc dest)))
+)
+
+(dni bccgrgr
+ "Conditional branch comparing general register with general register"
+ ()
+ ("b$bcond5 $Rd,$Rs,$rel12")
+ (+ OP1_0 OP2_D Rs Rd bcond5 rel12)
+ (sequence ()
+ (set-psw-cmp Rd (index-of Rd) Rd Rs)
+ (cbranch bcond5 rel12))
+ ()
+)
+
+; 4 bytes
+(dni bccgrimm8
+ "Conditional branch comparing general register with 8-bit immediate"
+ ()
+ ("b$bcond5 $Rm,#$imm8,$rel12")
+ (+ OP1_2 OP2M_0 Rm imm8 bcond5 rel12)
+ (sequence ()
+ (set-psw-cmp Rm (index-of Rm) Rm imm8)
+ (cbranch bcond5 rel12))
+ ()
+)
+
+; 4 bytes
+(dni bccimm16
+ "Conditional branch comparing general register with 16-bit immediate"
+ ()
+ ("b$bcond2 Rx,#$imm16,${rel8-4}")
+ (+ OP1_C bcond2 rel8-4 imm16)
+ (sequence ()
+ (set-psw-cmp (reg HI h-gr Rpsw) Rpsw (reg HI h-gr Rpsw) imm16)
+ (cbranch bcond2 rel8-4))
+ ()
+)
+
+(dni bngrimm4
+ "Test bit in general register by immediate and branch if 0"
+ ()
+ ("bn $Rd,#$imm4,$rel12")
+ (+ OP1_0 OP2_4 imm4 Rd OP5_0 rel12)
+ (sequence ()
+ (set Rpsw (index-of Rd))
+ (if (eq (and Rd (sll 1 imm4)) 0)
+ (set pc rel12)))
+ ()
+)
+
+(dni bngrgr
+ "Test bit in general register by general register and branch if 0"
+ ()
+ ("bn $Rd,$Rs,$rel12")
+ (+ OP1_0 OP2_6 Rs Rd OP5_0 rel12)
+ (sequence ()
+ (set Rpsw (index-of Rd))
+ (if (eq (and Rd (sll 1 Rs)) 0)
+ (set pc rel12)))
+ ()
+)
+
+(dni bnlmemimm
+ "Test bit in memory by immediate and branch if 0"
+ ()
+ ("bn $lmem8,#$imm3b,$rel12")
+ (+ OP1_7 OP2_C lmem8 OP5A_0 imm3b rel12)
+ (if (eq (and (mem QI lmem8) (sll 1 imm3b)) 0)
+ (set pc rel12))
+ ()
+)
+
+(dni bnhmemimm
+ "Test bit in memory by immediate and branch if 0"
+ ()
+ ("bn $hmem8,#$imm3b,$rel12")
+ (+ OP1_7 OP2_E hmem8 OP5A_0 imm3b rel12)
+ (if (eq (and (mem QI hmem8) (sll 1 imm3b)) 0)
+ (set pc rel12))
+ ()
+)
+
+(dni bpgrimm4
+ "Test bit in general register by immediate and branch if 1"
+ ()
+ ("bp $Rd,#$imm4,$rel12")
+ (+ OP1_0 OP2_5 imm4 Rd OP5_0 rel12)
+ (sequence ()
+ (set Rpsw (index-of Rd))
+ (if (ne (and Rd (sll 1 imm4)) 0)
+ (set pc rel12)))
+ ()
+)
+
+(dni bpgrgr
+ "Test bit in general register by general register and branch if 1"
+ ()
+ ("bp $Rd,$Rs,$rel12")
+ (+ OP1_0 OP2_7 Rs Rd OP5_0 rel12)
+ (sequence ()
+ (set Rpsw (index-of Rd))
+ (if (ne (and Rd (sll 1 Rs)) 0)
+ (set pc rel12)))
+ ()
+)
+
+(dni bplmemimm
+ "Test bit in memory by immediate and branch if 1"
+ ()
+ ("bp $lmem8,#$imm3b,$rel12")
+ (+ OP1_7 OP2_D lmem8 OP5A_0 imm3b rel12)
+ (if (ne (and (mem QI lmem8) (sll 1 imm3b)) 0)
+ (set pc rel12))
+ ()
+)
+
+(dni bphmemimm
+ "Test bit in memory by immediate and branch if 1"
+ ()
+ ("bp $hmem8,#$imm3b,$rel12")
+ (+ OP1_7 OP2_F hmem8 OP5A_0 imm3b rel12)
+ (if (ne (and (mem QI hmem8) (sll 1 imm3b)) 0)
+ (set pc rel12))
+ ()
+)
+
+(dni bcc
+ "Conditional branch on flag registers"
+ ()
+ ("b$bcond2 ${rel8-2}")
+ (+ OP1_D bcond2 rel8-2)
+ (cbranch bcond2 rel8-2)
+ ()
+)
+
+; Unconditional Branching
+
+(dni bgr
+ "Branch to register"
+ ()
+ ("br $Rd")
+ (+ OP1_0 OP2_0 OP3_2 Rd)
+ (set pc (add (add pc 2) Rd))
+ ()
+)
+
+(dni br
+ "Branch"
+ ()
+ ("br $rel12a")
+ (+ OP1_1 rel12a OP4B_0)
+ (set pc rel12a)
+ ()
+)
+
+(dni jmp
+ "Jump"
+ ()
+ ("jmp $Rbj,$Rd")
+ (+ OP1_0 OP2_0 OP3B_4 Rbj Rd)
+ (set pc (join SI HI Rbj Rd))
+ ()
+)
+
+(dni jmpf
+ "Jump far"
+ ()
+ ("jmpf $abs24")
+ (+ OP1_0 OP2_2 abs24)
+ (set pc abs24)
+ ()
+)
+
+; Call instructions
+(define-pmacro (do-call dest ilen)
+ (sequence ()
+ (set (mem SI sp) (add pc ilen))
+ (set sp (add sp 4))
+ (set pc dest)))
+
+(dni callrgr
+ "Call relative to general register"
+ ()
+ ("callr $Rd")
+ (+ OP1_0 OP2_0 OP3_1 Rd)
+ (do-call (add Rd (add pc 2)) 2)
+ ()
+)
+
+(dni callrimm
+ "Call relative to immediate address"
+ ()
+ ("callr $rel12a")
+ (+ OP1_1 rel12a OP4B_1)
+ (do-call rel12a 2)
+ ()
+)
+
+(dni callgr
+ "Call to general registers"
+ ()
+ ("call $Rbj,$Rd")
+ (+ OP1_0 OP2_0 OP3B_A Rbj Rd)
+ (do-call (join SI HI Rbj Rd) 2)
+ ()
+)
+
+(dni callfimm
+ "Call far to absolute address"
+ ()
+ ("callf $abs24")
+ (+ OP1_0 OP2_1 abs24)
+ (do-call abs24 4)
+ ()
+)
+
+(define-pmacro (do-calli dest ilen)
+ (sequence ()
+ (set (mem SI sp) (add pc ilen))
+ (set (mem HI (add sp 4)) psw)
+ (set sp (add sp 6))
+ (set pc dest)))
+
+(dni icallrgr
+ "Call interrupt to general registers pc-relative"
+ ()
+ ("icallr $Rd")
+ (+ OP1_0 OP2_0 OP3_3 Rd)
+ (do-calli (add Rd (add pc 2)) 2)
+ ()
+)
+
+(dni icallgr
+ "Call interrupt to general registers"
+ ()
+ ("icall $Rbj,$Rd")
+ (+ OP1_0 OP2_0 OP3B_6 Rbj Rd)
+ (do-calli (join SI HI Rbj Rd) 2)
+ ()
+)
+
+(dni icallfimm
+ "Call interrupt far to absolute address"
+ ()
+ ("icallf $abs24")
+ (+ OP1_0 OP2_3 abs24)
+ (do-calli abs24 4)
+ ()
+)
+
+; Return instructions
+(dni iret
+ "Return from interrupt"
+ ()
+ ("iret")
+ (+ (f-op #x0002))
+ (sequence ()
+ (set sp (sub sp 6))
+ (set pc (mem SI sp))
+ (set psw (mem HI (add sp 4))))
+ ()
+)
+
+(dni ret
+ "Return"
+ ()
+ ("ret")
+ (+ (f-op #x0003))
+ (sequence ()
+ (set sp (sub sp 4))
+ (set pc (mem SI sp)))
+ ()
+)
+
+; Multiply and Divide instructions
+
+(dni mul
+ "Multiply"
+ ()
+ ("mul")
+ (+ (f-op #x00D0))
+ (sequence ((SI value))
+ (set value (mul SI (and SI R0 #xFFFF) (and SI R2 #xFFFF)))
+ (set psw (or (and psw #xFF9C)
+ (basic-psw (trunc HI value) 1)))
+ (set R0 (trunc HI value))
+ (set R1 (trunc HI (srl value 16))))
+ ()
+)
+(dni div
+ "Divide"
+ ()
+ ("div")
+ (+ (f-op #x00C0))
+ (sequence ()
+ (set R1 (umod R0 R2))
+ (set-mem-psw R0 (udiv R0 R2) 1))
+ ()
+)
+(dni sdiv
+ "Signed Divide"
+ ()
+ ("sdiv")
+ (+ (f-op #x00C8))
+ (sequence ()
+ (set R1 (mod HI R0 R2))
+ (set-mem-psw R0 (div HI R0 R2) 1))
+ ()
+)
+(dni sdivlh
+ "Divide 32/16"
+ ()
+ ("sdivlh")
+ (+ (f-op #x00E8))
+ (sequence ((SI value))
+ (set value (add SI (sll SI (and SI R1 #xffff) #x10) (and SI R0 #xffff)))
+ (set R1 (mod SI value (ext SI (trunc HI R2))))
+ (set-mem-psw R0 (div SI value (ext SI (trunc HI R2))) 1))
+ ()
+)
+(dni divlh
+ "Divide 32/16"
+ ()
+ ("divlh")
+ (+ (f-op #x00E0))
+ (sequence ((SI value))
+ (set value (add SI (sll SI (and SI R1 #xffff) #x10) (and SI R0 #xffff)))
+ (set R1 (umod SI value R2))
+ (set-mem-psw R0 (udiv SI value R2) 1))
+ ()
+)
+
+; System Control
+
+; added per sanyo's req -- eq to nop for the moment, but can
+; add function later
+(dni reset "reset" () ("reset") (+ (f-op #x000f)) (nop) ())
+
+(dni nop "nop" () ("nop") (+ (f-op #x0000)) (nop) ())
+
+(dni halt "halt" () ("halt") (+ (f-op #x0008)) (c-call VOID "do_halt") ())
+
+(dni hold "hold" () ("hold") (+ (f-op #x000A)) (c-call VOID "do_hold") ())
+
+(dni holdx "holdx" () ("holdx") (+ (f-op #x000B)) (c-call VOID "do_holdx") ())
+
+(dni brk "brk" () ("brk") (+ (f-op #x0005)) (c-call VOID "do_brk") ())
+
+; An instruction for test instrumentation.
+; Using a reserved opcode.
+(dni syscall
+ "simulator system call"
+ ()
+ ("--unused--")
+ (+ (f-op #x0001))
+ (c-call VOID "syscall")
+ ()
+)