; Open questions: ; - why doesn't $size work in disassembly??? ; - why do we have to use base-insn-bitsize=16/32 ? ; - address/index registers are currently WI, but should be AI ; -> CGEN problem, even if HI -> semantic access to with mem doesn't work ; Mitsubishi M16C CPU description. -*- Scheme -*- ; Copyright (C) 2002 Manuel Kessler (include "simplify.inc") ; FIXME: Delete sign extension of accumulator results. ; Sign extension is done when accumulator is read. ; define-arch must appear first (define-arch (name m16c) ; name of cpu family (comment "Mitsubishi M16C") (default-alignment aligned) (insn-lsb0? #t) (machs m16c8x) (machs m16c6x m16c8x m32c8x) (isas m16c) ) ; Instruction set parameters. ; FIXME: I think 8/8/8 would be more correct, but constant fields seem to be ; not allowed beyond base-insn-bitsize, and it seems to work (mostly) ok ; this way. Perhaps come back to this issue later. (define-isa (name m16c) (default-insn-bitsize 16) (base-insn-bitsize 16) (default-insn-word-bitsize 16) ) ; Cpu family definitions. (define-cpu ; cpu names must be distinct from the architecture name and machine names. ; The "b" suffix stands for "base" and is the convention. ; The "f" suffix stands for "family" and is the convention. (name m16cbf) (comment "Mitsubishi M16C6x base family") (endian little) ) (define-cpu (name m32cf) (comment "Mitsubishi M16C8x/M32C8x family") (endian little) ; Generated files have an "x" suffix. (file-transform "x") ) (define-mach (name m16c6x) (comment "Generic M16C6x cpu") (cpu m16cbf) ) (define-mach (name m16c8x) (comment "Generic M16C8x cpu") (cpu m32cf) ) (define-mach (name m32c8x) (comment "Generic M32C8x cpu") (cpu m32cf) ) ; Model descriptions. (define-model (name m16c60) (comment "M16C/60") (attrs) (mach m16c6x) (pipeline all "" () ((fetch) (decode) (execute) (writeback))) (unit u-exec "Execution Unit" () 1 1 ; issue done () () () ()) ) (define-model (name m16c80) (comment "M16C/80") (attrs) (mach m16c8x) (pipeline all "" () ((fetch) (decode) (execute) (writeback))) (unit u-exec "Execution Unit" () 1 1 ; issue done () () () ()) ) (define-model (name m32c80) (comment "M32C/80") (attrs) (mach m32c8x) (pipeline all "" () ((fetch) (decode) (execute) (writeback))) (unit u-exec "Execution Unit" () 1 1 ; issue done () () () ()) ) ; register file definitions (define-keyword (name gr8-names) (print-name h-gr8) (prefix "") (values (r0h 0) (r1h 1) (r0l 2) (r1l 3)) ) (define-hardware (name h-gr8) (comment "8 bit general registers") (attrs VIRTUAL PROFILE) (type register QI (4)) (indices extern-keyword gr8-names) (get (index) (if (gt index 1) (reg QI h-gr index) (bitfield (reg h-gr (add index 2)) 15 8))) (set (index newval) (if (gt index 1) (set (bitfield (reg h-gr index) 8 8) newval) (set (bitfield (reg h-gr (add index 2)) 15 8) newval))) ) (define-keyword (name gr-names) (print-name h-gr) (prefix "") (values (r2 0) (r3 1) (r0 2) (r1 3)) ) (define-hardware (name h-gr) (comment "general registers") (attrs PROFILE CACHE-ADDR) (type register HI (4)) (indices extern-keyword gr-names) ) (define-keyword (name ar-names) (print-name h-ar) (prefix "") (values (a0 0) (a1 1)) ) (define-hardware (name h-ar) (comment "address registers") (attrs VIRTUAL PROFILE) (type register WI (2)) (indices extern-keyword ar-names) (get (index) (reg h-ir index)) (set (index newval) (set reg h-ir index newval)) ) (define-keyword (name br-names) (print-name h-br) (prefix "") (values (sb 0) (fb 1)) ) (define-hardware (name h-br) (comment "address registers") (attrs VIRTUAL PROFILE) (type register WI (2)) (indices extern-keyword br-names) (get (index) (reg h-ir (add index 2))) (set (index newval) (set reg h-ir (add index 2) newval)) ) (define-keyword (name ir-names) (print-name h-ir) (prefix "") (values (a0 0) (a1 1) (sb 2) (fb 3)) ) (define-hardware (name h-ir) (comment "index registers") (attrs PROFILE CACHE-ADDR) (type register WI (4)) (indices extern-keyword ir-names) ) (define-keyword (name gr32-names) (print-name h-gr32) (prefix "") (values (r2r0 0) (r3r1 1)) ) (define-hardware (name h-gr32) (comment "32 bit combined general registers") (attrs VIRTUAL PROFILE) (type register WI (16)) (indices extern-keyword gr32-names) (get (index) (add (reg HI h-gr (add (mul index 2) 1)) (sll (reg HI h-gr (mul index 2)) 16))) (set (index newval) (parallel ; FIXME do both halves?? (set (subword HI h-gr (reg h-gr index) 15 16) newval))) ) (define-keyword (name cr8-names) (print-name h-cr8) (prefix "") (values (dct0 0) (dct1 1) (flg 2) (svf 3) (drc0 4) (drc1 5) (dmd0 6) (dmd1 7)) ) (define-hardware (name h-cr8) (comment "8 bit control registers") (attrs PROFILE CACHE-ADDR) (type register QI (8)) (indices extern-keyword cr8-names) ) (define-keyword (name cr24a-names) (print-name h-cr24a) (prefix "") (values (intb 0) (sp 1) (sb 2) (fb 3) (svp 4) (vct 5) (isp 7)) ) (define-hardware (name h-cr24a) (comment "24 bit control registers") (attrs PROFILE CACHE-ADDR) (type register WI (8)) (indices extern-keyword cr24a-names) ) (define-keyword (name cr24b-names) (print-name h-cr24b) (prefix "") (values (dma0 2) (dma1 3) (dra0 4) (dra1 5) (dsa0 6) (dsa1 7)) ) (define-hardware (name h-cr24b) (comment "24 bit control registers") (attrs PROFILE CACHE-ADDR) (type register WI (8)) (indices extern-keyword cr24b-names) ) (define-hardware (name h-size) (comment "size suffix") (type immediate (UINT 1)) (values keyword "." ((b 0) (w 1) )) ) ; For condbit operand. FIXME: Need to allow spec of get/set of operands. ; Having this separate from h-psw keeps the parts that use it simpler ; [since they greatly outnumber those that use h-psw]. (dsh h-cond "condition bit" () (register BI)) (dnh h-pc "program counter" (PC PROFILE) (pc) () () ()) ; operand fields ; copied from ia32.cpu ; There currently doesn't exist shorthand macros for CISC ISA's, ; so define our own. ; DIF: define-ia32-field ; DNIF: define-normal-ia32-field (define-pmacro (dif x-name x-comment x-attrs x-word-offset x-word-length x-start x-length x-mode x-encode x-decode) (define-ifield (name x-name) (comment x-comment) (.splice attrs (.unsplice x-attrs)) (word-offset x-word-offset) (word-length x-word-length) (start x-start) (length x-length) (mode x-mode) (encode x-encode) (decode x-decode) ) ) (define-pmacro (dnif x-name x-comment x-attrs x-word-offset x-word-length x-start x-length) (dif x-name x-comment x-attrs x-word-offset x-word-length x-start x-length UINT #f #f) ) ; operand 1 mode select (dnf f-op1m "op1m" () 4 1) ; operand 1 displacement size select (dnf f-op1i "op1i" () 5 2) ; operand 1 register select (dnf f-op1r- "op1r" () 15 2) ; operand 1 address mode select (dnf f-op1am "op1am" () 15 1) ; operand 1 address register select (dnf f-op1ar "op1ar" () 14 1) (define-ifield (name f-op1r) (comment "op1r") (attrs) (word-offset 0) (word-length 8) (start 15) (length 2) (mode UINT) ) ; dito for operand 2 (dnf f-op2m "op2m" () 6 1) (dnf f-op2i "op2i" () 5 2) (dnf f-op2r "op2r" () 13 2) ;(dnmf f-op2 "op2" () UINT (f-op2m f-op2i f-op2r) #f #f) ; operand size select (dnf f-size "size" () 0 1) ; condition select (dnf f-cond "cond" () 12 4) (define-ifield (name f-disp8) (comment "disp8") (attrs) (word-offset 16) (word-length 8) (start 7) (length 8) (mode UINT) ) (df f-disp8- "disp8" () 23 8 INT #f #f) (df f-disp16 "disp16" () 31 16 INT #f #f) (df f-disp24 "disp24" () 39 24 INT #f #f) (dnop disp8 "disp8" () h-iaddr f-disp8) (dnop disp16 "disp16" () h-iaddr f-disp16) (dnop disp24 "disp24" () h-iaddr f-disp24) ; Instruction fields. (define-pmacro (build-hex1 num) (.hex num 1)) (define-pmacro (build-hex2 num) (.hex num 2)) (dnf f-opcode "single insn byte" () 7 8) (define-ifield (name f-opc1) (comment "opc1") (attrs) (word-offset 0) (word-length 8) (start 7) (length 4) (mode UINT) ) (define-ifield (name f-opc1b) (comment "opc1b") (attrs) (word-offset 0) (word-length 8) (start 13) (length 6) (mode UINT) ) (dnf f-opc1- "opcode single operand" () 7 4) (dnf f-opc1b- "opcode single operand #2" () 13 6) (dnf f-opc1m "opcode mode" () 3 3) (dnf f-opcs "opcode size" () 0 1) ; insn-opcode ; "00" ... "FF" ;(define-normal-insn-enum insn-opcode "insn opcode enums" () OP_ f-opcode ; (.map .upcase (.map build-hex2 (.iota 256))) ;) ; insn-op1: bits 7-4 (define-normal-insn-enum insn-op1 "insn opcode enums (1 op)" () OP1_ f-opc1 (.map .upcase (.map build-hex1 (.iota 16))) ) ; insn-op1: bits 13-8 ;(define-normal-insn-enum insn-op1b "insn opcode enums (1 op, #2)" () OP1B_ f-opc1b ; (.map .upcase (.map build-hex2 (.iota 64))) ;) ; insn-op1m: bits 3-1 (define-normal-insn-enum insn-op1m "insn opcode modes (1 op)" () OP1M_ f-opc1m ("A" "8A" "16A" "24A" "R") ) ; insn-op1s: bit 0 (define-normal-insn-enum insn-op1s "insn opcode size" () OPS_ f-opcs ("B" "W") ) ; insn-op1am: bit 15 (define-normal-insn-enum insn-op1am "insn opcode address mode (1 op)" () OP1AM_ f-op1am ("I" "D") ; direct/indirect a0/a1 respectively [a0]/[a1] ) (define-attr (for operand) (type boolean) (name HASH-PREFIX) (comment "immediates have an optional '#' prefix") ) (dnop sr "source register" () h-gr f-op2r) (dnop dr "destination register" () h-gr f-op1r) (dnop sr8 "source register" () h-gr8 f-op2r) (dnop dr8 "destination register" () h-gr8 f-op1r) (dnop ir "index register" () h-ir f-op1r) (dnop ar "address register" () h-ar f-op1ar) (dnop size "size suffix" () h-size f-opcs) ;(dnop si "source indirect" () h-gr f-op2r) ;(dnop di "destination indirect" () h-gr f-op1r) ; Instructions (dni nop "nop" () "nop" (+ (f-opcode #xDE)) (nop) () ) ;NEG.size 1010dddS dd101111 ; ddd=100 for r8/r16 (dni neg "neg" () "neg.w $dr" (+ (f-opc1 #xA) OP1M_R OPS_W (f-opc1b #x2f) dr) (set dr (neg dr)) () ) (dnmi neg- "neg alias" (NO-DIS) "neg $dr" (emit neg dr) ) (dni neg8 "neg8" () "neg.b $dr8" (+ (f-opc1 #xA) OP1M_R OPS_B (f-opc1b #x2f) dr8) (set dr8 (neg dr8)) () ) (dnmi neg8- "neg8 alias" (NO-DIS) "neg $dr8" (emit neg8 dr8) ) (dni nega "nega" () "neg.w $ar" (+ (f-opc1 #xA) OP1M_A OPS_W (f-opc1b #x2F) OP1AM_D ar) (set ar (and (neg ar) 65535)) () ) (dnmi nega- "nega alias" (NO-DIS) "neg $ar" (emit nega ar) ) ; ddd=0001 for a0/a1 (dni negaiw "negaiw" () "neg$size [$ar]" (+ (f-opc1 #xA) OP1M_A size (f-opc1b #x2F) OP1AM_I ar) (if size (set (mem HI ar) (neg (mem HI ar))) (set (mem QI ar) (neg (mem QI ar))) ) () ) (dni negi8 "negi8" (RELAXABLE) "neg$size $disp8[$ir]" (+ (f-opc1 #xA) OP1M_8A size (f-opc1b #x2F) ir disp8) (if size (set (mem HI (add ir disp8)) (neg (mem HI (add ir disp8)))) (set (mem QI (add ir disp8)) (neg (mem QI (add ir disp8)))) ) () ) ;(dnmi negb- "neg.X 0[$br] alias" ; (NO-DIS) ; "neg$size [$br]" ; (expand neg$1 0[$2]) ;) (dni negi16 "negi16" () "neg$size $disp16[$ir]" (+ (f-opc1 #xA) OP1M_16A size (f-opc1b #x2F) ir disp16) (if size (set (mem HI (add ir disp16)) (neg (mem HI (add ir disp16)))) (set (mem QI (add ir disp16)) (neg (mem QI (add ir disp16)))) ) () )