| ; 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 (mul value 2) (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") |
| () |
| ) |