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