diff options
Diffstat (limited to 'cpu/xstormy16.cpu')
-rw-r--r-- | cpu/xstormy16.cpu | 1965 |
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") + () +) |