From mboxrd@z Thu Jan 1 00:00:00 1970 From: Geoffrey Keating To: cgen@sources.redhat.com Subject: xstormy16 port Date: Fri, 07 Dec 2001 14:04:00 -0000 Message-ID: <200112072203.fB7M3xk14741@thief.cygnus.com> X-SW-Source: 2001-q4/msg00046.html Message-ID: <20011207140400.PPkSHMqWjjG24078uypez-MGd2LIRlgoWo9-BjWKGaU@z> This patch adds the port to the Sanyo Xstormy16 CPU core to CGEN. It consists solely of new files. OK to commit? -- Geoff Keating ===File ~/patches/sanyo-contrib-cgen.patch================== 2001-11-26 Geoffrey Keating * cpu/xstormy16.cpu: New file. * cpu/xstormy16.opc: New file. Index: src/cgen/cpu/xstormy16.cpu =================================================================== RCS file: xstormy16.cpu diff -N xstormy16.cpu --- src/cgen/cpu/xstormy16.cpu Tue May 5 13:32:27 1998 +++ src/cgen/cpu/xstormy16.cpu Fri Dec 7 13:55:47 2001 @@ -0,0 +1,1849 @@ +; xstormy16 CPU core description. -*- Scheme -*- +; Copyright (C) 2001 Red Hat, Inc. +; This file is part of CGEN. +; See file COPYING.CGEN for details. + +(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) +) + +(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 + () () () ()) +) + +; Hardware elements. + +(dsh h-pc "program counter" (PC) (pc)) + +(define-keyword + (name gr-names) + (print-name 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-Rbj-names) + (print-name h-Rbj) + (values (r8 0) (r9 1))) + +(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) (set (raw-reg h-gr index) (and #xFFFF newval))) +) + +(define-hardware + (name h-Rbj) + (comment "Rbj registers") + (attrs VIRTUAL) + (type register SI(2)) + (indices extern-keyword gr-Rbj-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-gr 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) +(dnop imm16 "16 bit immediate" () h-uint f-imm16) + +(dnf f-lmem8 "8 bit unsigned low memory" (ABS-ADDR) 8 8) +(define-operand + (name lmem8) + (comment "8 bit unsigned immediate low memory") + (attrs) + (type h-uint) + (index f-lmem8) + (handlers (parse "mem8")) +) +(define-ifield + (name f-hmem8) + (comment "8 bit unsigned high memory") + (attrs ABS-ADDR) + (start 8) + (length 8) + (mode UINT) + (encode (value pc) (sub HI value #x7F00)) + (decode (value pc) (add HI value #x7F00)) +) +(define-operand + (name hmem8) + (comment "8 bit unsigned immediate high memory") + (attrs) + (type h-uint) + (index f-hmem8) + (handlers (parse "mem8")) +) + +(define-ifield + (name f-rel8-2) + (comment "8 bit relative address for 2-byte instruction") + (attrs PCREL-ADDR) + (start 8) + (length 8) + (mode INT) + (encode (value pc) (sub SI value (add SI pc 2))) + (decode (value pc) (add SI value (add SI pc 2))) +) +(dnop rel8-2 "8 bit relative address" () h-uint f-rel8-2) + +(define-ifield + (name f-rel8-4) + (comment "8 bit relative address for 4-byte instruction") + (attrs PCREL-ADDR) + (start 8) + (length 8) + (mode INT) + (encode (value pc) (sub SI value (add SI pc 4))) + (decode (value pc) (add SI value (add SI pc 4))) +) +(dnop rel8-4 "8 bit relative address" () h-uint f-rel8-4) + +(define-ifield + (name f-rel12) + (comment "12 bit relative address") + (attrs PCREL-ADDR) + (start 20) + (length 12) + (mode INT) + (encode (value pc) (sub SI value (add SI pc 4))) + (decode (value pc) (add SI value (add SI pc 4))) +) +(dnop rel12 "12 bit relative address" () h-uint f-rel12) + +(define-ifield + (name f-rel12a) + (comment "12 bit relative address") + (attrs PCREL-ADDR) + (start 4) + (length 11) + (mode INT) + (encode (value pc) (sra SI (sub SI value (add SI pc 2)) 1)) + (decode (value pc) (add SI (sll value 1) (add SI pc 2))) +) +(dnop rel12a "12 bit relative address" () h-uint f-rel12a) + +(dnf f-abs24-1 "abs24 low part" () 8 8) +(dnf f-abs24-2 "abs24 high part" () 16 16) +(define-multi-ifield + (name f-abs24) + (comment "Absolute address for jmpf instruction") + (attrs ABS-ADDR) + (mode UINT) + (subfields f-abs24-1 f-abs24-2) + (insert (sequence () + (set (ifield f-abs24-1) (and (ifield f-abs24) #xFF)) + (set (ifield f-abs24-2) (srl (ifield f-abs24) 8)))) + (extract (set (ifield f-abs24) (or (sll (ifield f-abs24-2) 8) f-abs24-1))) +) +(dnop abs24 "24 bit absolute address" () h-uint f-abs24) + +; Names for registers +(dnop psw "program status word" (SEM-ONLY) h-gr 14) +(dnop Rpsw "N0-N3 of the program status word" (SEM-ONLY) h-Rpsw f-nil) +(dnop sp "stack pointer" (SEM-ONLY) h-gr 15) +(dnop R0 "R0" (SEM-ONLY) h-gr 0) +(dnop R1 "R1" (SEM-ONLY) h-gr 1) +(dnop R2 "R2" (SEM-ONLY) h-gr 2) +(dnop R8 "R8" (SEM-ONLY) h-gr 8) + +; Useful macros. + +; THe Z8, Z16, PT, and S flags of the PSW. +(define-pmacro (basic-psw value) + (or (or (zflag (and value #xFF)) + (sll HI (zflag HI value) 1)) + (or (sll HI (c-call BI "parity" value) 5) + (sll HI (nflag HI value) 6)))) + + +; Update the PSW for destination register Rd, set Rd to value. +(define-pmacro (set-psw Rd index value) + (sequence ((HI nvalue)) + (set nvalue value) + (set psw (or (and psw #x0F9C) + (or (sll index 12) + (basic-psw nvalue)))) + (set (reg HI h-gr index) nvalue))) + +; Update the PSW for destination register Rd. +(define-pmacro (set-psw-nowrite index value) + (sequence ((HI nvalue)) + (set nvalue value) + (set psw (or (and psw #x0F9C) + (or (sll index 12) + (basic-psw nvalue)))))) + +; Update the PSW for destination non-register dest, set dest to value. +(define-pmacro (set-mem-psw dest value) + (sequence ((HI nvalue)) + (set nvalue value) + (set psw (or (and psw #xFF9C) + (basic-psw nvalue))) + (set dest nvalue))) + +; Update the PSW for destination non-register dest, set dest to value, +; ensuring to write the correct (weird) alignment. +(define-pmacro (set-mem-alignfix-psw dest value) + (sequence ((HI nvalue) (SI ndest)) + (set nvalue value) + (set ndest dest) + (set psw (or (and psw #xFF9C) + (basic-psw nvalue))) + (if (and ndest 1) + (sequence () + (set ndest (sub ndest 1)) + (set nvalue (or (and (sll nvalue 8) #xFF00) + (and (srl nvalue 8) #xFF))))) + (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) + (sequence ((HI nvalue)) + (set nvalue value) + (set psw (or (or (and psw #x0F98) + (sll carry 2)) + (or (sll index 12) + (basic-psw nvalue)))) + (set (reg HI h-gr index) nvalue))) + +; The all-purpose addition operation. +(define-pmacro (set-psw-add Rd index a b c) + (sequence ((HI value)) + (set value (addc a b c)) + (set psw (or (or (and psw #x0F80) + (basic-psw value)) + (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 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)) + (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)) + (set value (subc a b c)) + (set psw (or (or (and psw #x0F80) + (basic-psw value)) + (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))) + +; 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)))) + + +; Move Operations + +(define-pmacro (alignfix-mem where) + (if HI (and where 1) + (or HI + (and (sll (mem QI (sub where 1)) 8) #xFF00) + (and (mem QI where) #xFF)) + (mem HI where))) + +(define-pmacro (set-alignfix-mem where what) + (sequence ((SI nwhere) (HI nwhat)) + (set nwhere where) + (if (and nwhere 1) + (sequence () + (set nwhat (or HI + (and (sll what 8) #xFF00) + (and (srl what 8) #xFF))) + (set nwhere (sub nwhere 1))) + (set nwhat what)) + (set (mem HI nwhere) what))) + +(dni movlmemimm + "Move immediate to low memory" + () + ("mov$ws2 $lmem8,#$imm16") + (+ OP1_7 OP2A_8 ws2 lmem8 imm16) + (if ws2 + (set-mem-alignfix-psw (mem HI lmem8) imm16) + (set-mem-psw (mem QI lmem8) (and imm16 #xFF))) + () +) +(dni movhmemimm + "Move immediate to high memory" + () + ("mov$ws2 $hmem8,#$imm16") + (+ OP1_7 OP2A_A ws2 hmem8 imm16) + (if ws2 + (set-mem-alignfix-psw (mem HI hmem8) imm16) + (set-mem-psw (mem QI hmem8) (and imm16 #xFF))) + () +) + +(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)) + (set-psw Rm (index-of Rm) (mem QI lmem8))) + () +) +(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)) + (set-psw Rm (index-of Rm) (mem QI hmem8))) + () +) + +(dni movlmemgr + "Move low memory register to byte" + () + ("mov$ws2 $lmem8,$Rm") + (+ OP1_9 Rm ws2 lmem8) + (if ws2 + (set-mem-alignfix-psw (mem HI lmem8) Rm) + (set-mem-psw (mem QI lmem8) Rm)) + () +) +(dni movhmemgr + "Move high memory register to byte" + () + ("mov$ws2 $hmem8,$Rm") + (+ OP1_B Rm ws2 hmem8) + (if ws2 + (set-mem-alignfix-psw (mem HI lmem8) Rm) + (set-mem-psw (mem QI lmem8) Rm)) + () +) + +(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)) + (set-psw Rdm (index-of Rdm) (and #xFF (mem QI Rs)))) + () +) + +(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)) + (set-psw Rdm (index-of Rdm) (and #xFF (mem QI Rs)))) + (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)) + (set-psw Rdm (index-of Rdm) (and #xFF (mem QI Rs))))) + () +) + +(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 Rs) Rs)) + () +) + +(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 Rs (index-of 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-psw Rs (index-of Rs) (sub Rs (add ws2 1))) + (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))) + (set-psw Rdm (index-of Rdm) (and #xFF (mem QI (add Rs imm12))))) + () +) + +(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))) + (set-psw Rdm (index-of Rdm) (and #xFF (mem QI (add Rs imm12))))) + (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))) + (set-psw Rdm (index-of Rdm) (and #xFF (mem QI (add Rs imm12)))))) + () +) + +(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 Rs (index-of Rs) Rs)) + () +) + +(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 Rs (index-of Rs) (add Rs 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-psw Rs (index-of Rs) (sub Rs 1)) + (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) + () +) + +(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) + () +) + +(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) + () +) + +(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) + () +) + +(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))) + () +) + +(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))) + () +) + +(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 (or (sll SI R8 16) Rs))) + (set-psw Rdm (index-of Rdm) (and #xFF (mem QI (or (sll SI R8 16) Rs))))) + () +) + +(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 (join SI HI R8 Rs))) + (set-psw Rdm (index-of Rdm) (and #xFF (mem QI (join SI HI R8 Rs))))) + (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 (join SI HI R8 Rs))) + (set-psw Rdm (index-of Rdm) (and #xFF (mem QI (join SI HI R8 Rs)))))) + () +) + +(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-psw Rs (index-of Rs) (alignfix-mem (join SI HI R8 Rdm))) + (set-psw Rs (index-of Rs) (and #xFF (mem QI (join SI HI R8 Rdm))))) + (set-psw Rs (index-of Rs) Rs)) + () +) + +(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-psw Rs (index-of Rs) (alignfix-mem (join SI HI R8 Rdm))) + (set-psw Rs (index-of Rs) (and #xFF (mem QI (join SI HI R8 Rdm))))) + (set-psw Rs (index-of 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 Rs (index-of Rs) (sub Rs (add ws2 1))) + (if ws2 + (set-psw Rs (index-of Rs) (alignfix-mem (join SI HI R8 Rdm))) + (set-psw Rs (index-of Rs) (and #xFF (mem QI (join SI HI R8 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 (add (join SI HI Rb Rs) imm12))) + (set-psw Rdm (index-of Rdm) (and #xFF (mem QI (add (join SI HI Rb Rs) imm12))))) + () +) + +(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 (add (join SI HI Rb Rs) imm12))) + (set-psw Rdm (index-of Rdm) (and #xFF (mem QI (add (join SI HI Rb Rs) imm12))))) + (set Rs (add Rs (add ws2 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 () + (set Rs (sub Rs (add ws2 1))) + (if ws2 + (set-psw Rdm (index-of Rdm) (alignfix-mem (add (join SI HI Rb Rs) imm12))) + (set-psw Rdm (index-of Rdm) (and #xFF (mem QI (add (join SI HI Rb Rs) imm12)))))) + () +) + +(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 Rs (index-of Rs) Rs)) + () +) + + +(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 Rs (index-of Rs) (add Rs (add ws2 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 () + (set-psw Rs (index-of Rs) (sub Rs 1)) + (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))) + () +) + +(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))) + () +) + +; 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))) + () +) + +(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))) + () +) + +(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)) + () +) + +; 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)) + () +) + +(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)) + () +) + +(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)) + () +) + +(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)) + () +) + +(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)) + () +) + +(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)) + () +) + +(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)) + () +) + +(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)) + () +) + +(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)) + () +) + +(dni notgr + "NOT general register" + () + ("not $Rd") + (+ OP1_3 OP2_0 OP3_B Rd) + (set-psw Rd (index-of Rd) (inv Rd)) + () +) + +; 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))) + () +) + +(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))) + () +) + +; Logical Shift +(dni rrcgrgr + "Rotate right general register by general register" + () + ("rrc $Rd,$Rs") + (+ OP1_3 OP2_8 Rs Rd) + (set-psw-rotate17 Rd (index-of Rd) Rd psw-cy (neg (and Rs #xF))) + () +) + +(dni rrcgrimm4 + "Rotate right general register by immediate" + () + ("rrc $Rd,#$imm4") + (+ OP1_3 OP2_9 imm4 Rd) + (set-psw-rotate17 Rd (index-of Rd) Rd psw-cy (neg 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) + Rd + (srl Rd (sub (and Rs #xF) 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) + Rd + (srl Rd (sub imm4 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) + Rd + (sll Rd (sub (and Rs #xF) 1))) + 15)) + () +) + +(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) + Rd + (sll Rd (sub imm4 1))) + 15)) + () +) + +(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) + Rd + (srl Rd (sub (and Rs #xF) 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) + Rd + (srl Rd (sub imm4 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))) + () +) + +(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)))) + () +) + +(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))) + () +) +(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))) + () +) + +(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)))) + () +) + +(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))))) + () +) + +(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)))) + () +) +(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)))) + () +) + +; 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))) + () +) + +(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)))))))))))))))) + ) + () +) + +; 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)))) + (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))) + () +) + +; System Control + +(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 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") + () +) Index: src/cgen/cpu/xstormy16.opc =================================================================== RCS file: xstormy16.opc diff -N xstormy16.opc --- src/cgen/cpu/xstormy16.opc Tue May 5 13:32:27 1998 +++ src/cgen/cpu/xstormy16.opc Fri Dec 7 13:55:47 2001 @@ -0,0 +1,107 @@ +/* XSTORMY16 opcode support. -*- C -*- + Copyright (C) 2001 Red Hat, Inc. + This file is part of CGEN. */ + +/* This file is an addendum to xstormy16.cpu. Heavy use of C code isn't + appropriate in .cpu files, so it resides here. This especially applies + to assembly/disassembly where parsing/printing can be quite involved. + Such things aren't really part of the specification of the cpu, per se, + so .cpu files provide the general framework and .opc files handle the + nitty-gritty details as necessary. + + Each section is delimited with start and end markers. + + -opc.h additions use: "-- opc.h" + -opc.c additions use: "-- opc.c" + -asm.c additions use: "-- asm.c" + -dis.c additions use: "-- dis.c" + -ibd.h additions use: "-- ibd.h" +*/ + +/* -- opc.h */ + +/* Allows reason codes to be output when assembler errors occur. */ +#define CGEN_VERBOSE_ASSEMBLER_ERRORS + +/* We can't use the default hash size because many bits are used by + operands. */ +#define CGEN_DIS_HASH_SIZE 1 +#define CGEN_DIS_HASH(buf, value) 0 +/* -- */ + +/* -- asm.c */ +static const char * parse_mem8 + PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *)); +static const char * parse_small_immediate + PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *)); + +/* The machine-independent code doesn't know how to disambiguate + mov (foo),r3 + and + mov (r2),r3 + where 'foo' is a label. This helps it out. */ + +static const char * +parse_mem8 (cd, strp, opindex, valuep) + CGEN_CPU_DESC cd; + const char **strp; + int opindex; + unsigned long *valuep; +{ + if (**strp == '(') + { + const char *s = *strp; + + if (s[1] == '-' && s[2] == '-') + return _("Bad register in preincrement"); + + while (isalnum (*++s)) + ; + if (s[0] == '+' && s[1] == '+' && (s[2] == ')' || s[2] == ',')) + return _("Bad register in postincrement"); + if (s[0] == ',' || s[0] == ')') + return _("Bad register name"); + } + else if (cgen_parse_keyword (cd, strp, & xstormy16_cgen_opval_gr_names, + valuep) == NULL) + return _("Label conflicts with register name"); + else if (strncasecmp (*strp, "rx,", 3) == 0 + || strncasecmp (*strp, "rxl,", 3) == 0 + || strncasecmp (*strp, "rxh,", 3) == 0) + return _("Label conflicts with `Rx'"); + else if (**strp == '#') + return _("Bad immediate expression"); + + return cgen_parse_unsigned_integer (cd, strp, opindex, valuep); +} + +/* For the add and subtract instructions, there are two immediate forms, + one for small operands and one for large ones. We want to use + the small one when possible, but we do not want to generate relocs + of the small size. This is somewhat tricky. */ + +static const char * +parse_small_immediate (cd, strp, opindex, valuep) + CGEN_CPU_DESC cd; + const char **strp; + int opindex; + unsigned long *valuep; +{ + bfd_vma value; + enum cgen_parse_operand_result result; + const char *errmsg; + + errmsg = (* cd->parse_operand_fn) + (cd, CGEN_PARSE_OPERAND_INTEGER, strp, opindex, BFD_RELOC_NONE, + &result, &value); + + if (errmsg) + return errmsg; + + if (result != CGEN_PARSE_OPERAND_RESULT_NUMBER) + return _("Small operand was not an immediate number"); + + *valuep = value; + return NULL; +} +/* -- */ ============================================================