1863 lines
52 KiB
Scheme
1863 lines
52 KiB
Scheme
; Fujitsu FR30 CPU 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 must appear first
|
||
|
||
(define-arch
|
||
(name fr30) ; name of cpu family
|
||
(comment "Fujitsu FR30")
|
||
(default-alignment forced)
|
||
(insn-lsb0? #f)
|
||
(machs fr30)
|
||
(isas fr30)
|
||
)
|
||
|
||
(define-isa
|
||
(name fr30)
|
||
(base-insn-bitsize 16)
|
||
(decode-assist (0 1 2 3 4 5 6 7)) ; Initial bitnumbers to decode insns by.
|
||
(liw-insns 1) ; The fr30 fetches 1 insn at a time.
|
||
(parallel-insns 1) ; The fr30 executes 1 insn at a time.
|
||
)
|
||
|
||
(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 fr30bf)
|
||
(comment "Fujitsu FR30 base family")
|
||
(endian big)
|
||
(word-bitsize 32)
|
||
)
|
||
|
||
(define-mach
|
||
(name fr30)
|
||
(comment "Generic FR30 cpu")
|
||
(cpu fr30bf)
|
||
)
|
||
|
||
; Model descriptions.
|
||
;
|
||
(define-model
|
||
(name fr30-1) (comment "fr30-1") (attrs)
|
||
(mach fr30)
|
||
|
||
(pipeline all "" () ((fetch) (decode) (execute) (writeback)))
|
||
|
||
; `state' is a list of variables for recording model state
|
||
(state
|
||
; bit mask of h-gr registers loaded from memory by previous insn
|
||
(load-regs UINT)
|
||
; bit mask of h-gr registers loaded from memory by current insn
|
||
(load-regs-pending UINT)
|
||
)
|
||
|
||
(unit u-exec "Execution Unit" ()
|
||
1 1 ; issue done
|
||
() ; state
|
||
((Ri INT -1) (Rj INT -1)) ; inputs
|
||
((Ri INT -1)) ; outputs
|
||
() ; profile action (default)
|
||
)
|
||
(unit u-cti "Branch Unit" ()
|
||
1 1 ; issue done
|
||
() ; state
|
||
((Ri INT -1)) ; inputs
|
||
((pc)) ; outputs
|
||
() ; profile action (default)
|
||
)
|
||
(unit u-load "Memory Load Unit" ()
|
||
1 1 ; issue done
|
||
() ; state
|
||
((Rj INT -1)
|
||
;(ld-mem AI)
|
||
) ; inputs
|
||
((Ri INT -1)) ; outputs
|
||
() ; profile action (default)
|
||
)
|
||
(unit u-store "Memory Store Unit" ()
|
||
1 1 ; issue done
|
||
() ; state
|
||
((Ri INT -1) (Rj INT -1)) ; inputs
|
||
() ; ((st-mem AI)) ; outputs
|
||
() ; profile action (default)
|
||
)
|
||
(unit u-ldm "LDM Memory Load Unit" ()
|
||
1 1 ; issue done
|
||
() ; state
|
||
((reglist INT)) ; inputs
|
||
() ; outputs
|
||
() ; profile action (default)
|
||
)
|
||
(unit u-stm "STM Memory Store Unit" ()
|
||
1 1 ; issue done
|
||
() ; state
|
||
((reglist INT)) ; inputs
|
||
() ; outputs
|
||
() ; profile action (default)
|
||
)
|
||
)
|
||
|
||
; The instruction fetch/execute cycle.
|
||
;
|
||
; This is how to fetch and decode an instruction.
|
||
; Leave it out for now
|
||
|
||
; (define-extract (const SI 0))
|
||
|
||
; This is how to execute a decoded instruction.
|
||
; Leave it out for now
|
||
|
||
; (define-execute (const SI 0))
|
||
|
||
; Instruction fields.
|
||
;
|
||
; Attributes:
|
||
; PCREL-ADDR: pc relative value (for reloc and disassembly purposes)
|
||
; ABS-ADDR: absolute address (for reloc and disassembly purposes?)
|
||
; RESERVED: bits are not used to decode insn, must be all 0
|
||
|
||
(dnf f-op1 "1st 4 bits of opcode" () 0 4)
|
||
(dnf f-op2 "2nd 4 bits of opcode" () 4 4)
|
||
(dnf f-op3 "3rd 4 bits of opcode" () 8 4)
|
||
(dnf f-op4 "4th 4 bits of opcode" () 12 4)
|
||
(dnf f-op5 "5th bit of opcode" () 4 1)
|
||
(dnf f-cc "condition code" () 4 4)
|
||
(dnf f-ccc "coprocessor calc code" () 16 8)
|
||
(dnf f-Rj "register Rj" () 8 4)
|
||
(dnf f-Ri "register Ri" () 12 4)
|
||
(dnf f-Rs1 "register Rs" () 8 4)
|
||
(dnf f-Rs2 "register Rs" () 12 4)
|
||
(dnf f-Rjc "register Rj" () 24 4)
|
||
(dnf f-Ric "register Ri" () 28 4)
|
||
(dnf f-CRj "coprocessor register" () 24 4)
|
||
(dnf f-CRi "coprocessor register" () 28 4)
|
||
(dnf f-u4 "4 bit 0 extended" () 8 4)
|
||
(dnf f-u4c "4 bit 0 extended" () 12 4)
|
||
(df f-i4 "4 bit sign extended" () 8 4 INT #f #f)
|
||
(df f-m4 "4 bit minus extended" () 8 4 UINT
|
||
; ??? This field takes a value in the range [-16,-1] but there
|
||
; doesn't seem a way to tell CGEN that. Use an unsigned field and
|
||
; disable range checks on insertion by masking. Restore the sign
|
||
; on extraction. CGEN generated documentation for insns that use
|
||
; this field will be wrong.
|
||
((value pc) (and WI value (const #xf)))
|
||
((value pc) (or WI value (const -16)))
|
||
)
|
||
(dnf f-u8 "8 bit unsigned" () 8 8)
|
||
(dnf f-i8 "8 bit unsigned" () 4 8)
|
||
|
||
(dnf f-i20-4 "upper 4 bits of i20" () 8 4)
|
||
(dnf f-i20-16 "lower 16 bits of i20" () 16 16)
|
||
(dnmf f-i20 "20 bit unsigned" () UINT
|
||
(f-i20-4 f-i20-16)
|
||
(sequence () ; insert
|
||
(set (ifield f-i20-4) (srl (ifield f-i20) (const 16)))
|
||
(set (ifield f-i20-16) (and (ifield f-i20) (const #xffff)))
|
||
)
|
||
(sequence () ; extract
|
||
(set (ifield f-i20) (or (sll (ifield f-i20-4) (const 16))
|
||
(ifield f-i20-16)))
|
||
)
|
||
)
|
||
|
||
(dnf f-i32 "32 bit immediate" (SIGN-OPT) 16 32)
|
||
|
||
(df f-udisp6 "6 bit unsigned offset" () 8 4 UINT
|
||
((value pc) (srl UWI value (const 2)))
|
||
((value pc) (sll UWI value (const 2)))
|
||
)
|
||
(df f-disp8 "8 bit signed offset" () 4 8 INT #f #f)
|
||
(df f-disp9 "9 bit signed offset" () 4 8 INT
|
||
((value pc) (sra WI value (const 1)))
|
||
((value pc) (mul WI value (const 2)))
|
||
)
|
||
(df f-disp10 "10 bit signed offset" () 4 8 INT
|
||
((value pc) (sra WI value (const 2)))
|
||
((value pc) (mul WI value (const 4)))
|
||
)
|
||
(df f-s10 "10 bit signed offset" () 8 8 INT
|
||
((value pc) (sra WI value (const 2)))
|
||
((value pc) (mul WI value (const 4)))
|
||
)
|
||
(df f-u10 "10 bit unsigned offset" () 8 8 UINT
|
||
((value pc) (srl UWI value (const 2)))
|
||
((value pc) (sll UWI value (const 2)))
|
||
)
|
||
(df f-rel9 "9 pc relative signed offset" (PCREL-ADDR) 8 8 INT
|
||
((value pc) (sra WI (sub WI value (add WI pc (const 2))) (const 1)))
|
||
((value pc) (add WI (mul WI value (const 2)) (add WI pc (const 2))))
|
||
)
|
||
(dnf f-dir8 "8 bit direct address" () 8 8)
|
||
(df f-dir9 "9 bit direct address" () 8 8 UINT
|
||
((value pc) (srl UWI value (const 1)))
|
||
((value pc) (sll UWI value (const 1)))
|
||
)
|
||
(df f-dir10 "10 bit direct address" () 8 8 UINT
|
||
((value pc) (srl UWI value (const 2)))
|
||
((value pc) (sll UWI value (const 2)))
|
||
)
|
||
(df f-rel12 "12 bit pc relative signed offset" (PCREL-ADDR) 5 11 INT
|
||
((value pc) (sra WI (sub WI value (add WI pc (const 2))) (const 1)))
|
||
((value pc) (add WI (mul WI value (const 2)) (add WI pc (const 2))))
|
||
)
|
||
|
||
(dnf f-reglist_hi_st "8 bit register mask for stm" () 8 8)
|
||
(dnf f-reglist_low_st "8 bit register mask for stm" () 8 8)
|
||
(dnf f-reglist_hi_ld "8 bit register mask for ldm" () 8 8)
|
||
(dnf f-reglist_low_ld "8 bit register mask for ldm" () 8 8)
|
||
|
||
; Enums.
|
||
|
||
; insn-op1: bits 0-3
|
||
; FIXME: should use die macro or some such
|
||
(define-normal-insn-enum insn-op1 "insn op1 enums" () OP1_ f-op1
|
||
("0" "1" "2" "3" "4" "5" "6" "7"
|
||
"8" "9" "A" "B" "C" "D" "E" "F")
|
||
)
|
||
|
||
; insn-op2: bits 4-7
|
||
; FIXME: should use die macro or some such
|
||
(define-normal-insn-enum insn-op2 "insn op2 enums" () OP2_ f-op2
|
||
("0" "1" "2" "3" "4" "5" "6" "7"
|
||
"8" "9" "A" "B" "C" "D" "E" "F")
|
||
)
|
||
|
||
; insn-op3: bits 8-11
|
||
; FIXME: should use die macro or some such
|
||
(define-normal-insn-enum insn-op3 "insn op3 enums" () OP3_ f-op3
|
||
("0" "1" "2" "3" "4" "5" "6" "7"
|
||
"8" "9" "A" "B" "C" "D" "E" "F")
|
||
)
|
||
|
||
; insn-op4: bits 12-15
|
||
; FIXME: should use die macro or some such
|
||
(define-normal-insn-enum insn-op4 "insn op4 enums" () OP4_ f-op4
|
||
("0")
|
||
)
|
||
|
||
; insn-op5: bit 4 (5th bit origin 0)
|
||
; FIXME: should use die macro or some such
|
||
(define-normal-insn-enum insn-op5 "insn op5 enums" () OP5_ f-op5
|
||
("0" "1")
|
||
)
|
||
|
||
; insn-cc: condition codes
|
||
; FIXME: should use die macro or some such
|
||
(define-normal-insn-enum insn-cc "insn cc enums" () CC_ f-cc
|
||
("ra" "no" "eq" "ne" "c" "nc" "n" "p" "v" "nv" "lt" "ge" "le" "gt" "ls" "hi")
|
||
)
|
||
|
||
; Hardware pieces.
|
||
; These entries list the elements of the raw hardware.
|
||
; They're also used to provide tables and other elements of the assembly
|
||
; language.
|
||
|
||
(dnh h-pc "program counter" (PC PROFILE) (pc) () () ())
|
||
|
||
(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)
|
||
(ac 13) (fp 14) (sp 15))
|
||
)
|
||
|
||
(define-hardware
|
||
(name h-gr)
|
||
(comment "general registers")
|
||
(attrs PROFILE CACHE-ADDR)
|
||
(type register WI (16))
|
||
(indices extern-keyword gr-names)
|
||
)
|
||
|
||
(define-keyword
|
||
(name cr-names)
|
||
(enum-prefix H-CR-)
|
||
(values (cr0 0) (cr1 1) (cr2 2) (cr3 3)
|
||
(cr4 4) (cr5 5) (cr6 6) (cr7 7)
|
||
(cr8 8) (cr9 9) (cr10 10) (cr11 11)
|
||
(cr12 12) (cr13 13) (cr14 14) (cr15 15))
|
||
)
|
||
|
||
(define-hardware
|
||
(name h-cr)
|
||
(comment "coprocessor registers")
|
||
(attrs)
|
||
(type register WI (16))
|
||
(indices extern-keyword cr-names)
|
||
)
|
||
|
||
(define-keyword
|
||
(name dr-names)
|
||
(enum-prefix H-DR-)
|
||
(values (tbr 0) (rp 1) (ssp 2) (usp 3) (mdh 4) (mdl 5))
|
||
)
|
||
|
||
(define-hardware
|
||
(name h-dr)
|
||
(comment "dedicated registers")
|
||
(type register WI (6))
|
||
(indices extern-keyword dr-names)
|
||
(get (index) (c-call WI "@cpu@_h_dr_get_handler" index))
|
||
(set (index newval) (c-call VOID "@cpu@_h_dr_set_handler" index newval))
|
||
)
|
||
|
||
(define-hardware
|
||
(name h-ps)
|
||
(comment "processor status")
|
||
(type register UWI)
|
||
(indices keyword "" ((ps 0)))
|
||
(get () (c-call UWI "@cpu@_h_ps_get_handler"))
|
||
(set (newval) (c-call VOID "@cpu@_h_ps_set_handler" newval))
|
||
)
|
||
|
||
(dnh h-r13 "General Register 13 explicitly required"
|
||
()
|
||
(register WI)
|
||
(keyword "" ((r13 0)))
|
||
() ()
|
||
)
|
||
|
||
(dnh h-r14 "General Register 14 explicitly required"
|
||
()
|
||
(register WI)
|
||
(keyword "" ((r14 0)))
|
||
() ()
|
||
)
|
||
|
||
(dnh h-r15 "General Register 15 explicitly required"
|
||
()
|
||
(register WI)
|
||
(keyword "" ((r15 0)))
|
||
() ()
|
||
)
|
||
|
||
; These bits are actually part of the PS register but are accessed more
|
||
; often than the entire register, so define them directly. We can assemble
|
||
; the PS register from its components when necessary.
|
||
|
||
(dsh h-nbit "negative bit" () (register BI))
|
||
(dsh h-zbit "zero bit" () (register BI))
|
||
(dsh h-vbit "overflow bit" () (register BI))
|
||
(dsh h-cbit "carry bit" () (register BI))
|
||
(dsh h-ibit "interrupt enable bit" () (register BI))
|
||
(define-hardware
|
||
(name h-sbit)
|
||
(comment "stack bit")
|
||
(type register BI)
|
||
(get () (c-call BI "@cpu@_h_sbit_get_handler"))
|
||
(set (newval) (c-call VOID "@cpu@_h_sbit_set_handler" newval))
|
||
)
|
||
(dsh h-tbit "trace trap bit" () (register BI))
|
||
(dsh h-d0bit "division 0 bit" () (register BI))
|
||
(dsh h-d1bit "division 1 bit" () (register BI))
|
||
|
||
; These represent sub-registers within the program status register
|
||
|
||
(define-hardware
|
||
(name h-ccr)
|
||
(comment "condition code bits")
|
||
(type register UQI)
|
||
(get () (c-call UQI "@cpu@_h_ccr_get_handler"))
|
||
(set (newval) (c-call VOID "@cpu@_h_ccr_set_handler" newval))
|
||
)
|
||
(define-hardware
|
||
(name h-scr)
|
||
(comment "system condition bits")
|
||
(type register UQI)
|
||
(get () (c-call UQI "@cpu@_h_scr_get_handler"))
|
||
(set (newval) (c-call VOID "@cpu@_h_scr_set_handler" newval))
|
||
)
|
||
(define-hardware
|
||
(name h-ilm)
|
||
(comment "interrupt level mask")
|
||
(type register UQI)
|
||
(get () (c-call UQI "@cpu@_h_ilm_get_handler"))
|
||
(set (newval) (c-call VOID "@cpu@_h_ilm_set_handler" newval))
|
||
)
|
||
|
||
; Instruction Operands.
|
||
; These entries provide a layer between the assembler and the raw hardware
|
||
; description, and are used to refer to hardware elements in the semantic
|
||
; code. Usually there's a bit of over-specification, but in more complicated
|
||
; instruction sets there isn't.
|
||
|
||
; FR30 specific operand attributes:
|
||
|
||
(define-attr
|
||
(for operand)
|
||
(type boolean)
|
||
(name HASH-PREFIX)
|
||
(comment "immediates have an optional '#' prefix")
|
||
)
|
||
|
||
; ??? Convention says this should be o-sr, but then the insn definitions
|
||
; should refer to o-sr which is clumsy. The "o-" could be implicit, but
|
||
; then it should be implicit for all the symbols here, but then there would
|
||
; be confusion between (f-)simm8 and (h-)simm8.
|
||
; So for now the rule is exactly as it appears here.
|
||
|
||
(dnop Ri "destination register" () h-gr f-Ri)
|
||
(dnop Rj "source register" () h-gr f-Rj)
|
||
(dnop Ric "target register coproc insn" () h-gr f-Ric)
|
||
(dnop Rjc "source register coproc insn" () h-gr f-Rjc)
|
||
(dnop CRi "coprocessor register" () h-cr f-CRi)
|
||
(dnop CRj "coprocessor register" () h-cr f-CRj)
|
||
(dnop Rs1 "dedicated register" () h-dr f-Rs1)
|
||
(dnop Rs2 "dedicated register" () h-dr f-Rs2)
|
||
(dnop R13 "General Register 13" () h-r13 f-nil)
|
||
(dnop R14 "General Register 14" () h-r14 f-nil)
|
||
(dnop R15 "General Register 15" () h-r15 f-nil)
|
||
(dnop ps "Program Status register" () h-ps f-nil)
|
||
(dnop u4 "4 bit unsigned immediate" (HASH-PREFIX) h-uint f-u4)
|
||
(dnop u4c "4 bit unsigned immediate" (HASH-PREFIX) h-uint f-u4c)
|
||
(dnop u8 "8 bit unsigned immediate" (HASH-PREFIX) h-uint f-u8)
|
||
(dnop i8 "8 bit unsigned immediate" (HASH-PREFIX) h-uint f-i8)
|
||
(dnop udisp6 "6 bit unsigned immediate" (HASH-PREFIX) h-uint f-udisp6)
|
||
(dnop disp8 "8 bit signed immediate" (HASH-PREFIX) h-sint f-disp8)
|
||
(dnop disp9 "9 bit signed immediate" (HASH-PREFIX) h-sint f-disp9)
|
||
(dnop disp10 "10 bit signed immediate" (HASH-PREFIX) h-sint f-disp10)
|
||
|
||
(dnop s10 "10 bit signed immediate" (HASH-PREFIX) h-sint f-s10)
|
||
(dnop u10 "10 bit unsigned immediate" (HASH-PREFIX) h-uint f-u10)
|
||
(dnop i32 "32 bit immediate" (HASH-PREFIX) h-uint f-i32)
|
||
|
||
(define-operand
|
||
(name m4)
|
||
(comment "4 bit negative immediate")
|
||
(attrs HASH-PREFIX)
|
||
(type h-sint)
|
||
(index f-m4)
|
||
(handlers (print "m4"))
|
||
)
|
||
|
||
(define-operand
|
||
(name i20)
|
||
(comment "20 bit immediate")
|
||
(attrs HASH-PREFIX)
|
||
(type h-uint)
|
||
(index f-i20)
|
||
)
|
||
|
||
(dnop dir8 "8 bit direct address" () h-uint f-dir8)
|
||
(dnop dir9 "9 bit direct address" () h-uint f-dir9)
|
||
(dnop dir10 "10 bit direct address" () h-uint f-dir10)
|
||
|
||
(dnop label9 "9 bit pc relative address" () h-iaddr f-rel9)
|
||
(dnop label12 "12 bit pc relative address" () h-iaddr f-rel12)
|
||
|
||
(define-operand
|
||
(name reglist_low_ld)
|
||
(comment "8 bit low register mask for ldm")
|
||
(attrs)
|
||
(type h-uint)
|
||
(index f-reglist_low_ld)
|
||
(handlers (parse "low_register_list_ld")
|
||
(print "low_register_list_ld"))
|
||
)
|
||
|
||
(define-operand
|
||
(name reglist_hi_ld)
|
||
(comment "8 bit high register mask for ldm")
|
||
(attrs)
|
||
(type h-uint)
|
||
(index f-reglist_hi_ld)
|
||
(handlers (parse "hi_register_list_ld")
|
||
(print "hi_register_list_ld"))
|
||
)
|
||
|
||
(define-operand
|
||
(name reglist_low_st)
|
||
(comment "8 bit low register mask for stm")
|
||
(attrs)
|
||
(type h-uint)
|
||
(index f-reglist_low_st)
|
||
(handlers (parse "low_register_list_st")
|
||
(print "low_register_list_st"))
|
||
)
|
||
|
||
(define-operand
|
||
(name reglist_hi_st)
|
||
(comment "8 bit high register mask for stm")
|
||
(attrs)
|
||
(type h-uint)
|
||
(index f-reglist_hi_st)
|
||
(handlers (parse "hi_register_list_st")
|
||
(print "hi_register_list_st"))
|
||
)
|
||
|
||
(dnop cc "condition codes" () h-uint f-cc)
|
||
(dnop ccc "coprocessor calc" (HASH-PREFIX) h-uint f-ccc)
|
||
|
||
(dnop nbit "negative bit" (SEM-ONLY) h-nbit f-nil)
|
||
(dnop vbit "overflow bit" (SEM-ONLY) h-vbit f-nil)
|
||
(dnop zbit "zero bit" (SEM-ONLY) h-zbit f-nil)
|
||
(dnop cbit "carry bit" (SEM-ONLY) h-cbit f-nil)
|
||
(dnop ibit "interrupt bit" (SEM-ONLY) h-ibit f-nil)
|
||
(dnop sbit "stack bit" (SEM-ONLY) h-sbit f-nil)
|
||
(dnop tbit "trace trap bit" (SEM-ONLY) h-tbit f-nil)
|
||
(dnop d0bit "division 0 bit" (SEM-ONLY) h-d0bit f-nil)
|
||
(dnop d1bit "division 1 bit" (SEM-ONLY) h-d1bit f-nil)
|
||
|
||
(dnop ccr "condition code bits" (SEM-ONLY) h-ccr f-nil)
|
||
(dnop scr "system condition bits" (SEM-ONLY) h-scr f-nil)
|
||
(dnop ilm "interrupt level mask" (SEM-ONLY) h-ilm f-nil)
|
||
|
||
; Instruction definitions.
|
||
;
|
||
; Notes:
|
||
; - dni is short for "define-normal-instruction"
|
||
|
||
; FR30 specific insn attributes:
|
||
|
||
(define-attr
|
||
(for insn)
|
||
(type boolean)
|
||
(name NOT-IN-DELAY-SLOT)
|
||
(comment "insn can't go in delay slot")
|
||
)
|
||
|
||
; Sets zbit and nbit based on the value of x
|
||
;
|
||
(define-pmacro (set-z-and-n x)
|
||
(sequence ()
|
||
(set zbit (eq x (const 0)))
|
||
(set nbit (lt x (const 0))))
|
||
)
|
||
|
||
; Binary integer instruction which sets status bits
|
||
;
|
||
(define-pmacro (binary-int-op name insn comment opc1 opc2 op arg1 arg2)
|
||
(dni name
|
||
(.str insn " " comment)
|
||
()
|
||
(.str insn " $" arg1 ",$" arg2)
|
||
(+ opc1 opc2 arg1 arg2)
|
||
(sequence ()
|
||
(set vbit ((.sym op -oflag) arg2 arg1 (const 0)))
|
||
(set cbit ((.sym op -cflag) arg2 arg1 (const 0)))
|
||
(set arg2 (op arg2 arg1))
|
||
(set-z-and-n arg2))
|
||
()
|
||
)
|
||
)
|
||
|
||
; Binary integer instruction which does *not* set status bits
|
||
;
|
||
(define-pmacro (binary-int-op-n name insn comment opc1 opc2 op arg1 arg2)
|
||
(dni name
|
||
(.str insn " " comment)
|
||
()
|
||
(.str insn " $" arg1 ",$" arg2)
|
||
(+ opc1 opc2 arg1 arg2)
|
||
(set arg2 (op arg2 arg1))
|
||
()
|
||
)
|
||
)
|
||
|
||
; Binary integer instruction with carry which sets status bits
|
||
;
|
||
(define-pmacro (binary-int-op-c name insn comment opc1 opc2 op arg1 arg2)
|
||
(dni name
|
||
(.str insn " " comment)
|
||
()
|
||
(.str insn " $" arg1 ",$" arg2)
|
||
(+ opc1 opc2 arg1 arg2)
|
||
(sequence ((WI tmp))
|
||
(set tmp ((.sym op c) arg2 arg1 cbit))
|
||
(set vbit ((.sym op -oflag) arg2 arg1 cbit))
|
||
(set cbit ((.sym op -cflag) arg2 arg1 cbit))
|
||
(set arg2 tmp)
|
||
(set-z-and-n arg2))
|
||
()
|
||
)
|
||
)
|
||
|
||
(binary-int-op add add "reg/reg" OP1_A OP2_6 add Rj Ri)
|
||
(binary-int-op addi add "immed/reg" OP1_A OP2_4 add u4 Ri)
|
||
(binary-int-op add2 add2 "immed/reg" OP1_A OP2_5 add m4 Ri)
|
||
(binary-int-op-c addc addc "reg/reg" OP1_A OP2_7 add Rj Ri)
|
||
(binary-int-op-n addn addn "reg/reg" OP1_A OP2_2 add Rj Ri)
|
||
(binary-int-op-n addni addn "immed/reg" OP1_A OP2_0 add u4 Ri)
|
||
(binary-int-op-n addn2 addn2 "immed/reg" OP1_A OP2_1 add m4 Ri)
|
||
|
||
(binary-int-op sub sub "reg/reg" OP1_A OP2_C sub Rj Ri)
|
||
(binary-int-op-c subc subc "reg/reg" OP1_A OP2_D sub Rj Ri)
|
||
(binary-int-op-n subn subn "reg/reg" OP1_A OP2_E sub Rj Ri)
|
||
|
||
; Integer compare instruction
|
||
;
|
||
(define-pmacro (int-cmp name insn comment opc1 opc2 arg1 arg2)
|
||
(dni name
|
||
(.str insn " " comment)
|
||
()
|
||
(.str insn " $" arg1 ",$" arg2)
|
||
(+ opc1 opc2 arg1 arg2)
|
||
(sequence ((WI tmp1))
|
||
(set vbit (sub-oflag arg2 arg1 (const 0)))
|
||
(set cbit (sub-cflag arg2 arg1 (const 0)))
|
||
(set tmp1 (sub arg2 arg1))
|
||
(set-z-and-n tmp1)
|
||
)
|
||
()
|
||
)
|
||
)
|
||
|
||
(int-cmp cmp cmp "reg/reg" OP1_A OP2_A Rj Ri)
|
||
(int-cmp cmpi cmp "immed/reg" OP1_A OP2_8 u4 Ri)
|
||
(int-cmp cmp2 cmp2 "immed/reg" OP1_A OP2_9 m4 Ri)
|
||
|
||
; Binary logical instruction
|
||
;
|
||
(define-pmacro (binary-logical-op name insn comment opc1 opc2 op arg1 arg2)
|
||
(dni name
|
||
(.str insn " " comment)
|
||
()
|
||
(.str insn " $" arg1 ",$" arg2)
|
||
(+ opc1 opc2 arg1 arg2)
|
||
(sequence ()
|
||
(set arg2 (op arg2 arg1))
|
||
(set-z-and-n arg2))
|
||
()
|
||
)
|
||
)
|
||
|
||
(binary-logical-op and and "reg/reg" OP1_8 OP2_2 and Rj Ri)
|
||
(binary-logical-op or or "reg/reg" OP1_9 OP2_2 or Rj Ri)
|
||
(binary-logical-op eor eor "reg/reg" OP1_9 OP2_A xor Rj Ri)
|
||
|
||
(define-pmacro (les-units model) ; les: load-exec-store
|
||
(model (unit u-exec) (unit u-load) (unit u-store))
|
||
)
|
||
|
||
; Binary logical instruction to memory
|
||
;
|
||
(define-pmacro (binary-logical-op-m name insn comment opc1 opc2 mode op arg1 arg2)
|
||
(dni name
|
||
(.str insn " " comment)
|
||
(NOT-IN-DELAY-SLOT)
|
||
(.str insn " $" arg1 ",@$" arg2)
|
||
(+ opc1 opc2 arg1 arg2)
|
||
(sequence ((mode tmp))
|
||
(set mode tmp (op mode (mem mode arg2) arg1))
|
||
(set-z-and-n tmp)
|
||
(set mode (mem mode arg2) tmp))
|
||
((les-units fr30-1))
|
||
)
|
||
)
|
||
|
||
(binary-logical-op-m andm and "reg/mem" OP1_8 OP2_4 WI and Rj Ri)
|
||
(binary-logical-op-m andh andh "reg/mem" OP1_8 OP2_5 HI and Rj Ri)
|
||
(binary-logical-op-m andb andb "reg/mem" OP1_8 OP2_6 QI and Rj Ri)
|
||
(binary-logical-op-m orm or "reg/mem" OP1_9 OP2_4 WI or Rj Ri)
|
||
(binary-logical-op-m orh orh "reg/mem" OP1_9 OP2_5 HI or Rj Ri)
|
||
(binary-logical-op-m orb orb "reg/mem" OP1_9 OP2_6 QI or Rj Ri)
|
||
(binary-logical-op-m eorm eor "reg/mem" OP1_9 OP2_C WI xor Rj Ri)
|
||
(binary-logical-op-m eorh eorh "reg/mem" OP1_9 OP2_D HI xor Rj Ri)
|
||
(binary-logical-op-m eorb eorb "reg/mem" OP1_9 OP2_E QI xor Rj Ri)
|
||
|
||
; Binary logical instruction to low half of byte in memory
|
||
;
|
||
(dni bandl
|
||
"bandl #u4,@Ri"
|
||
(NOT-IN-DELAY-SLOT)
|
||
"bandl $u4,@$Ri"
|
||
(+ OP1_8 OP2_0 u4 Ri)
|
||
(set QI (mem QI Ri)
|
||
(and QI
|
||
(or QI u4 (const #xf0))
|
||
(mem QI Ri)))
|
||
((les-units fr30-1))
|
||
)
|
||
|
||
(dni borl
|
||
"borl #u4,@Ri"
|
||
(NOT-IN-DELAY-SLOT)
|
||
"borl $u4,@$Ri"
|
||
(+ OP1_9 OP2_0 u4 Ri)
|
||
(set QI (mem QI Ri) (or QI u4 (mem QI Ri)))
|
||
((les-units fr30-1))
|
||
)
|
||
|
||
(dni beorl
|
||
"beorl #u4,@Ri"
|
||
(NOT-IN-DELAY-SLOT)
|
||
"beorl $u4,@$Ri"
|
||
(+ OP1_9 OP2_8 u4 Ri)
|
||
(set QI (mem QI Ri) (xor QI u4 (mem QI Ri)))
|
||
((les-units fr30-1))
|
||
)
|
||
|
||
; Binary logical instruction to high half of byte in memory
|
||
;
|
||
(dni bandh
|
||
"bandh #u4,@Ri"
|
||
(NOT-IN-DELAY-SLOT)
|
||
"bandh $u4,@$Ri"
|
||
(+ OP1_8 OP2_1 u4 Ri)
|
||
(set QI (mem QI Ri)
|
||
(and QI
|
||
(or QI (sll QI u4 (const 4)) (const #x0f))
|
||
(mem QI Ri)))
|
||
((les-units fr30-1))
|
||
)
|
||
|
||
(define-pmacro (binary-or-op-mh name insn opc1 opc2 op arg1 arg2)
|
||
(dni name
|
||
(.str name " #" arg1 ",@" args)
|
||
(NOT-IN-DELAY-SLOT)
|
||
(.str name " $" arg1 ",@$" arg2)
|
||
(+ opc1 opc2 arg1 arg2)
|
||
(set QI (mem QI arg2)
|
||
(insn QI
|
||
(sll QI arg1 (const 4))
|
||
(mem QI arg2)))
|
||
((les-units fr30-1))
|
||
)
|
||
)
|
||
|
||
(binary-or-op-mh borh or OP1_9 OP2_1 or u4 Ri)
|
||
(binary-or-op-mh beorh xor OP1_9 OP2_9 xor u4 Ri)
|
||
|
||
(dni btstl
|
||
"btstl #u4,@Ri"
|
||
(NOT-IN-DELAY-SLOT)
|
||
"btstl $u4,@$Ri"
|
||
(+ OP1_8 OP2_8 u4 Ri)
|
||
(sequence ((QI tmp))
|
||
(set tmp (and QI u4 (mem QI Ri)))
|
||
(set zbit (eq tmp (const 0)))
|
||
(set nbit (const 0)))
|
||
((fr30-1 (unit u-load) (unit u-exec (cycles 2))))
|
||
)
|
||
|
||
(dni btsth
|
||
"btsth #u4,@Ri"
|
||
(NOT-IN-DELAY-SLOT)
|
||
"btsth $u4,@$Ri"
|
||
(+ OP1_8 OP2_9 u4 Ri)
|
||
(sequence ((QI tmp))
|
||
(set tmp (and QI (sll QI u4 (const 4)) (mem QI Ri)))
|
||
(set zbit (eq tmp (const 0)))
|
||
(set nbit (lt tmp (const 0))))
|
||
((fr30-1 (unit u-load) (unit u-exec (cycles 2))))
|
||
)
|
||
|
||
(dni mul
|
||
"mul Rj,Ri"
|
||
(NOT-IN-DELAY-SLOT)
|
||
"mul $Rj,$Ri"
|
||
(+ OP1_A OP2_F Rj Ri)
|
||
(sequence ((DI tmp))
|
||
(set tmp (mul DI (ext DI Rj) (ext DI Ri)))
|
||
(set (reg h-dr 5) (trunc WI tmp))
|
||
(set (reg h-dr 4) (trunc WI (srl tmp (const 32))))
|
||
(set nbit (lt (reg h-dr 5) (const 0)))
|
||
(set zbit (eq tmp (const DI 0)))
|
||
(set vbit (orif
|
||
(gt tmp (const DI #x7fffffff))
|
||
(lt tmp (neg (const DI #x80000000))))))
|
||
((fr30-1 (unit u-exec (cycles 5))))
|
||
)
|
||
|
||
(dni mulu
|
||
"mulu Rj,Ri"
|
||
(NOT-IN-DELAY-SLOT)
|
||
"mulu $Rj,$Ri"
|
||
(+ OP1_A OP2_B Rj Ri)
|
||
(sequence ((DI tmp))
|
||
(set tmp (mul DI (zext DI Rj) (zext DI Ri)))
|
||
(set (reg h-dr 5) (trunc WI tmp))
|
||
(set (reg h-dr 4) (trunc WI (srl tmp (const 32))))
|
||
(set nbit (lt (reg h-dr 4) (const 0)))
|
||
(set zbit (eq (reg h-dr 5) (const 0)))
|
||
(set vbit (ne (reg h-dr 4) (const 0))))
|
||
((fr30-1 (unit u-exec (cycles 5))))
|
||
)
|
||
|
||
(dni mulh
|
||
"mulh Rj,Ri"
|
||
(NOT-IN-DELAY-SLOT)
|
||
"mulh $Rj,$Ri"
|
||
(+ OP1_B OP2_F Rj Ri)
|
||
(sequence ()
|
||
(set (reg h-dr 5) (mul (trunc HI Rj) (trunc HI Ri)))
|
||
(set nbit (lt (reg h-dr 5) (const 0)))
|
||
(set zbit (ge (reg h-dr 5) (const 0))))
|
||
((fr30-1 (unit u-exec (cycles 3))))
|
||
)
|
||
|
||
(dni muluh
|
||
"muluh Rj,Ri"
|
||
(NOT-IN-DELAY-SLOT)
|
||
"muluh $Rj,$Ri"
|
||
(+ OP1_B OP2_B Rj Ri)
|
||
(sequence ()
|
||
(set (reg h-dr 5) (mul (and Rj (const #xffff))
|
||
(and Ri (const #xffff))))
|
||
(set nbit (lt (reg h-dr 5) (const 0)))
|
||
(set zbit (ge (reg h-dr 5) (const 0))))
|
||
((fr30-1 (unit u-exec (cycles 3))))
|
||
)
|
||
|
||
(dni div0s
|
||
"div0s Ri"
|
||
()
|
||
"div0s $Ri"
|
||
(+ OP1_9 OP2_7 OP3_4 Ri)
|
||
(sequence ()
|
||
(set d0bit (lt (reg h-dr 5) (const 0)))
|
||
(set d1bit (xor d0bit (lt Ri (const 0))))
|
||
(if (ne d0bit (const 0))
|
||
(set (reg h-dr 4) (const #xffffffff))
|
||
(set (reg h-dr 4) (const 0))))
|
||
()
|
||
)
|
||
|
||
(dni div0u
|
||
"div0u Ri"
|
||
()
|
||
"div0u $Ri"
|
||
(+ OP1_9 OP2_7 OP3_5 Ri)
|
||
(sequence ()
|
||
(set d0bit (const 0))
|
||
(set d1bit (const 0))
|
||
(set (reg h-dr 4) (const 0)))
|
||
()
|
||
)
|
||
|
||
(dni div1
|
||
"div1 Ri"
|
||
()
|
||
"div1 $Ri"
|
||
(+ OP1_9 OP2_7 OP3_6 Ri)
|
||
(sequence ((WI tmp))
|
||
(set (reg h-dr 4) (sll (reg h-dr 4) (const 1)))
|
||
(if (lt (reg h-dr 5) (const 0))
|
||
(set (reg h-dr 4) (add (reg h-dr 4) (const 1))))
|
||
(set (reg h-dr 5) (sll (reg h-dr 5) (const 1)))
|
||
(if (eq d1bit (const 1))
|
||
(sequence ()
|
||
(set tmp (add (reg h-dr 4) Ri))
|
||
(set cbit (add-cflag (reg h-dr 4) Ri (const 0))))
|
||
(sequence ()
|
||
(set tmp (sub (reg h-dr 4) Ri))
|
||
(set cbit (sub-cflag (reg h-dr 4) Ri (const 0)))))
|
||
(if (not (xor (xor d0bit d1bit) cbit))
|
||
(sequence ()
|
||
(set (reg h-dr 4) tmp)
|
||
(set (reg h-dr 5) (or (reg h-dr 5) (const 1)))))
|
||
(set zbit (eq (reg h-dr 4) (const 0))))
|
||
()
|
||
)
|
||
|
||
(dni div2
|
||
"div2 Ri"
|
||
()
|
||
"div2 $Ri"
|
||
(+ OP1_9 OP2_7 OP3_7 Ri)
|
||
(sequence ((WI tmp))
|
||
(if (eq d1bit (const 1))
|
||
(sequence ()
|
||
(set tmp (add (reg h-dr 4) Ri))
|
||
(set cbit (add-cflag (reg h-dr 4) Ri (const 0))))
|
||
(sequence ()
|
||
(set tmp (sub (reg h-dr 4) Ri))
|
||
(set cbit (sub-cflag (reg h-dr 4) Ri (const 0)))))
|
||
(if (eq tmp (const 0))
|
||
(sequence ()
|
||
(set zbit (const 1))
|
||
(set (reg h-dr 4) (const 0)))
|
||
(set zbit (const 0))))
|
||
()
|
||
)
|
||
|
||
(dni div3
|
||
"div3"
|
||
()
|
||
"div3"
|
||
(+ OP1_9 OP2_F OP3_6 OP4_0)
|
||
(if (eq zbit (const 1))
|
||
(set (reg h-dr 5) (add (reg h-dr 5) (const 1))))
|
||
()
|
||
)
|
||
|
||
(dni div4s
|
||
"div4s"
|
||
()
|
||
"div4s"
|
||
(+ OP1_9 OP2_F OP3_7 OP4_0)
|
||
(if (eq d1bit (const 1))
|
||
(set (reg h-dr 5) (neg (reg h-dr 5))))
|
||
()
|
||
)
|
||
|
||
(define-pmacro (leftshift-op name insn opc1 opc2 arg1 arg2 shift-expr)
|
||
(dni name
|
||
(.str insn " " arg1 "," arg2)
|
||
()
|
||
(.str insn " $" arg1 ",$" arg2)
|
||
(+ opc1 opc2 arg1 arg2)
|
||
(sequence ((WI shift))
|
||
(set shift shift-expr)
|
||
(if (ne shift (const 0))
|
||
(sequence ()
|
||
(set cbit (ne (and arg2
|
||
(sll (const 1)
|
||
(sub (const 32) shift)))
|
||
(const 0)))
|
||
(set arg2 (sll arg2 shift)))
|
||
(set cbit (const 0)))
|
||
(set nbit (lt arg2 (const 0)))
|
||
(set zbit (eq arg2 (const 0))))
|
||
()
|
||
)
|
||
)
|
||
(leftshift-op lsl lsl OP1_B OP2_6 Rj Ri (and Rj (const #x1f)))
|
||
(leftshift-op lsli lsl OP1_B OP2_4 u4 Ri u4)
|
||
(leftshift-op lsl2 lsl2 OP1_B OP2_5 u4 Ri (add u4 (const #x10)))
|
||
|
||
(define-pmacro (rightshift-op name insn opc1 opc2 op arg1 arg2 shift-expr)
|
||
(dni name
|
||
(.str insn " " arg1 "," arg2)
|
||
()
|
||
(.str insn " $" arg1 ",$" arg2)
|
||
(+ opc1 opc2 arg1 arg2)
|
||
(sequence ((WI shift))
|
||
(set shift shift-expr)
|
||
(if (ne shift (const 0))
|
||
(sequence ()
|
||
(set cbit (ne (and arg2
|
||
(sll (const 1)
|
||
(sub shift (const 1))))
|
||
(const 0)))
|
||
(set arg2 (op arg2 shift)))
|
||
(set cbit (const 0)))
|
||
(set nbit (lt arg2 (const 0)))
|
||
(set zbit (eq arg2 (const 0))))
|
||
()
|
||
)
|
||
)
|
||
(rightshift-op lsr lsr OP1_B OP2_2 srl Rj Ri (and Rj (const #x1f)))
|
||
(rightshift-op lsri lsr OP1_B OP2_0 srl u4 Ri u4)
|
||
(rightshift-op lsr2 lsr2 OP1_B OP2_1 srl u4 Ri (add u4 (const #x10)))
|
||
(rightshift-op asr asr OP1_B OP2_A sra Rj Ri (and Rj (const #x1f)))
|
||
(rightshift-op asri asr OP1_B OP2_8 sra u4 Ri u4)
|
||
(rightshift-op asr2 asr2 OP1_B OP2_9 sra u4 Ri (add u4 (const #x10)))
|
||
|
||
(dni ldi8
|
||
"load 8 bit unsigned immediate"
|
||
()
|
||
"ldi:8 $i8,$Ri"
|
||
(+ OP1_C i8 Ri)
|
||
(set Ri i8)
|
||
()
|
||
)
|
||
|
||
; Typing ldi:8 in in emacs is a pain.
|
||
(dnmi ldi8m "ldi:8 without the colon"
|
||
(NO-DIS)
|
||
"ldi8 $i8,$Ri"
|
||
(emit ldi8 i8 Ri)
|
||
)
|
||
|
||
(dni ldi20
|
||
"load 20 bit unsigned immediate"
|
||
(NOT-IN-DELAY-SLOT)
|
||
"ldi:20 $i20,$Ri"
|
||
(+ OP1_9 OP2_B Ri i20)
|
||
(set Ri i20)
|
||
((fr30-1 (unit u-exec (cycles 2))))
|
||
)
|
||
|
||
; Typing ldi:20 in in emacs is a pain.
|
||
(dnmi ldi20m "ldi:20 without the colon"
|
||
(NO-DIS)
|
||
"ldi20 $i20,$Ri"
|
||
(emit ldi20 i20 Ri)
|
||
)
|
||
|
||
(dni ldi32
|
||
"load 32 bit immediate"
|
||
(NOT-IN-DELAY-SLOT)
|
||
"ldi:32 $i32,$Ri"
|
||
(+ OP1_9 OP2_F OP3_8 Ri i32)
|
||
(set Ri i32)
|
||
((fr30-1 (unit u-exec (cycles 3))))
|
||
)
|
||
|
||
; Typing ldi:32 in in emacs is a pain.
|
||
(dnmi ldi32m "ldi:32 without the colon"
|
||
(NO-DIS)
|
||
"ldi32 $i32,$Ri"
|
||
(emit ldi32 i32 Ri)
|
||
)
|
||
|
||
(define-pmacro (basic-ld name insn opc1 opc2 mode arg1 arg2)
|
||
(dni name
|
||
(.str name " @" arg1 "," arg2)
|
||
()
|
||
(.str name " @$" arg1 ",$" arg2)
|
||
(+ opc1 opc2 arg1 arg2)
|
||
(set arg2 (mem mode arg1))
|
||
((fr30-1 (unit u-load)))
|
||
)
|
||
)
|
||
|
||
(basic-ld ld ld OP1_0 OP2_4 WI Rj Ri)
|
||
(basic-ld lduh lduh OP1_0 OP2_5 UHI Rj Ri)
|
||
(basic-ld ldub ldub OP1_0 OP2_6 UQI Rj Ri)
|
||
|
||
(define-pmacro (r13base-ld name insn opc1 opc2 mode arg1 arg2)
|
||
(dni name
|
||
(.str insn " @(R13," arg1 ")," arg2)
|
||
()
|
||
(.str insn " @($R13,$" arg1 "),$" arg2)
|
||
(+ opc1 opc2 arg1 arg2)
|
||
(set arg2 (mem mode (add arg1 (reg h-gr 13))))
|
||
((fr30-1 (unit u-load)))
|
||
)
|
||
)
|
||
|
||
(r13base-ld ldr13 ld OP1_0 OP2_0 WI Rj Ri)
|
||
(r13base-ld ldr13uh lduh OP1_0 OP2_1 UHI Rj Ri)
|
||
(r13base-ld ldr13ub ldub OP1_0 OP2_2 UQI Rj Ri)
|
||
|
||
(define-pmacro (r14base-ld name insn opc1 mode arg1 arg2)
|
||
(dni name
|
||
(.str insn " @(R14," arg1 ")," arg2)
|
||
()
|
||
(.str insn " @($R14,$" arg1 "),$" arg2)
|
||
(+ opc1 arg1 arg2)
|
||
(set arg2 (mem mode (add arg1 (reg h-gr 14))))
|
||
((fr30-1 (unit u-load)))
|
||
)
|
||
)
|
||
|
||
(r14base-ld ldr14 ld OP1_2 WI disp10 Ri)
|
||
(r14base-ld ldr14uh lduh OP1_4 UHI disp9 Ri)
|
||
(r14base-ld ldr14ub ldub OP1_6 UQI disp8 Ri)
|
||
|
||
(dni ldr15
|
||
"ld @(R15,udisp6),Ri mem/reg"
|
||
()
|
||
"ld @($R15,$udisp6),$Ri"
|
||
(+ OP1_0 OP2_3 udisp6 Ri)
|
||
(set Ri (mem WI (add udisp6 (reg h-gr 15))))
|
||
((fr30-1 (unit u-load)))
|
||
)
|
||
|
||
(dni ldr15gr
|
||
"ld @R15+,Ri"
|
||
()
|
||
"ld @$R15+,$Ri"
|
||
(+ OP1_0 OP2_7 OP3_0 Ri)
|
||
(sequence ()
|
||
(set Ri (mem WI (reg h-gr 15)))
|
||
(if (ne (ifield f-Ri) (const 15))
|
||
(set (reg h-gr 15) (add (reg h-gr 15) (const 4)))))
|
||
((fr30-1 (unit u-load)))
|
||
)
|
||
|
||
; This insn loads a value from where r15 points into the target register and
|
||
; then increments r15. If the target register is also r15, then the post
|
||
; increment is not performed.
|
||
;
|
||
(dni ldr15dr
|
||
"ld @R15+,Rs2"
|
||
()
|
||
"ld @$R15+,$Rs2"
|
||
(+ OP1_0 OP2_7 OP3_8 Rs2)
|
||
; This seems more straight forward, but doesn't work due to a problem in
|
||
; cgen. We're trying to not increment r15 if it is the target register.
|
||
; (sequence ()
|
||
; (set Rs2 (mem WI (reg h-gr 15)))
|
||
; (if (not (or (and (eq (ifield f-Rs2) (const 2))
|
||
; (eq sbit (const 0)))
|
||
; (and (eq (ifield f-Rs2) (const 3))
|
||
; (eq sbit (const 1)))))
|
||
; (set (reg h-gr 15) (add (reg h-gr 15) (const 4)))
|
||
; )
|
||
; )
|
||
(sequence ((WI tmp))
|
||
(set tmp (mem WI (reg h-gr 15))) ; save in case target is r15
|
||
(set (reg h-gr 15) (add (reg h-gr 15) (const 4)))
|
||
(set Rs2 tmp))
|
||
((fr30-1 (unit u-load)))
|
||
)
|
||
|
||
(dni ldr15ps
|
||
"ld @R15+,ps mem/reg"
|
||
(NOT-IN-DELAY-SLOT)
|
||
"ld @$R15+,$ps"
|
||
(+ OP1_0 OP2_7 OP3_9 OP4_0)
|
||
(sequence ()
|
||
(set ps (mem WI (reg h-gr 15)))
|
||
(set (reg h-gr 15) (add (reg h-gr 15) (const 4))))
|
||
((fr30-1 (unit u-load)))
|
||
)
|
||
|
||
(define-pmacro (basic-st name insn opc1 opc2 mode arg1 arg2)
|
||
(dni name
|
||
(.str name " " arg1 ",@" arg2)
|
||
()
|
||
(.str name " $" arg1 ",@$" arg2)
|
||
(+ opc1 opc2 arg1 arg2)
|
||
(set (mem mode arg2) arg1)
|
||
((fr30-1 (unit u-store)))
|
||
)
|
||
)
|
||
|
||
(basic-st st st OP1_1 OP2_4 WI Ri Rj)
|
||
(basic-st sth sth OP1_1 OP2_5 HI Ri Rj)
|
||
(basic-st stb stb OP1_1 OP2_6 QI Ri Rj)
|
||
|
||
(define-pmacro (r13base-st name insn opc1 opc2 mode arg1 arg2)
|
||
(dni name
|
||
(.str insn " " arg1 ",@(R13," arg2 ")")
|
||
()
|
||
(.str insn " $" arg1 ",@($R13,$" arg2 ")")
|
||
(+ opc1 opc2 arg1 arg2)
|
||
(set (mem mode (add arg2 (reg h-gr 13))) arg1)
|
||
((fr30-1 (unit u-store)))
|
||
)
|
||
)
|
||
|
||
(r13base-st str13 st OP1_1 OP2_0 WI Ri Rj)
|
||
(r13base-st str13h sth OP1_1 OP2_1 HI Ri Rj)
|
||
(r13base-st str13b stb OP1_1 OP2_2 QI Ri Rj)
|
||
|
||
(define-pmacro (r14base-st name insn opc1 mode arg1 arg2)
|
||
(dni name
|
||
(.str insn " " arg1 ",@(R14," arg2 ")")
|
||
()
|
||
(.str insn " $" arg1 ",@($R14,$" arg2 ")")
|
||
(+ opc1 arg1 arg2)
|
||
(set (mem mode (add arg2 (reg h-gr 14))) arg1)
|
||
((fr30-1 (unit u-store)))
|
||
)
|
||
)
|
||
|
||
(r14base-st str14 st OP1_3 WI Ri disp10)
|
||
(r14base-st str14h sth OP1_5 HI Ri disp9)
|
||
(r14base-st str14b stb OP1_7 QI Ri disp8)
|
||
|
||
(dni str15
|
||
"st Ri,@(R15,udisp6) reg/mem"
|
||
()
|
||
"st $Ri,@($R15,$udisp6)"
|
||
(+ OP1_1 OP2_3 udisp6 Ri)
|
||
(set (mem WI (add (reg h-gr 15) udisp6)) Ri)
|
||
((fr30-1 (unit u-store)))
|
||
)
|
||
|
||
; These store insns predecrement r15 and then store the contents of the source
|
||
; register where r15 then points. If the source register is also r15, then the
|
||
; original value of r15 is stored.
|
||
;
|
||
(dni str15gr
|
||
"st Ri,@-R15 reg/mem"
|
||
()
|
||
"st $Ri,@-$R15"
|
||
(+ OP1_1 OP2_7 OP3_0 Ri)
|
||
(sequence ((WI tmp))
|
||
(set tmp Ri) ; save in case it's r15
|
||
(set (reg h-gr 15) (sub (reg h-gr 15) (const 4)))
|
||
(set (mem WI (reg h-gr 15)) tmp))
|
||
((fr30-1 (unit u-store)))
|
||
)
|
||
|
||
(dni str15dr
|
||
"st Rs,@-R15 reg/mem"
|
||
()
|
||
"st $Rs2,@-$R15"
|
||
(+ OP1_1 OP2_7 OP3_8 Rs2)
|
||
(sequence ((WI tmp))
|
||
(set tmp Rs2) ; save in case it's r15
|
||
(set (reg h-gr 15) (sub (reg h-gr 15) (const 4)))
|
||
(set (mem WI (reg h-gr 15)) tmp))
|
||
((fr30-1 (unit u-store)))
|
||
)
|
||
|
||
(dni str15ps
|
||
"st ps,@-R15 reg/mem"
|
||
()
|
||
"st $ps,@-$R15"
|
||
(+ OP1_1 OP2_7 OP3_9 OP4_0)
|
||
(sequence ()
|
||
(set (reg h-gr 15) (sub (reg h-gr 15) (const 4)))
|
||
(set (mem WI (reg h-gr 15)) ps))
|
||
((fr30-1 (unit u-store)))
|
||
)
|
||
|
||
(define-pmacro (mov2gr name opc1 opc2 arg1 arg2)
|
||
(dni name
|
||
(.str "mov " arg1 "," arg2)
|
||
()
|
||
(.str "mov $" arg1 ",$" arg2)
|
||
(+ opc1 opc2 arg1 arg2)
|
||
(set arg2 arg1)
|
||
()
|
||
)
|
||
)
|
||
|
||
(mov2gr mov OP1_8 OP2_B Rj Ri)
|
||
(mov2gr movdr OP1_B OP2_7 Rs1 Ri)
|
||
|
||
(dni movps
|
||
"mov ps,Ri reg/reg"
|
||
()
|
||
"mov $ps,$Ri"
|
||
(+ OP1_1 OP2_7 OP3_1 Ri)
|
||
(set Ri ps)
|
||
()
|
||
)
|
||
|
||
(dni mov2dr
|
||
"mov Ri,Rs reg/reg"
|
||
()
|
||
"mov $Ri,$Rs1"
|
||
(+ OP1_B OP2_3 Rs1 Ri)
|
||
(set Rs1 Ri)
|
||
()
|
||
)
|
||
|
||
(dni mov2ps
|
||
"mov Ri,ps reg/reg"
|
||
()
|
||
"mov $Ri,$ps"
|
||
(+ OP1_0 OP2_7 OP3_1 Ri)
|
||
(set ps Ri)
|
||
()
|
||
)
|
||
|
||
(dni jmp
|
||
"jmp with no delay slot"
|
||
(NOT-IN-DELAY-SLOT)
|
||
"jmp @$Ri"
|
||
(+ OP1_9 OP2_7 OP3_0 Ri)
|
||
(set pc Ri)
|
||
((fr30-1 (unit u-cti)))
|
||
)
|
||
|
||
(dni jmpd "jmp with delay slot"
|
||
(NOT-IN-DELAY-SLOT)
|
||
"jmp:d @$Ri"
|
||
(+ OP1_9 OP2_F OP3_0 Ri)
|
||
(delay (const 1)
|
||
(set pc Ri))
|
||
((fr30-1 (unit u-cti)))
|
||
)
|
||
|
||
; These versions which use registers must appear before the other
|
||
; versions which use relative addresses due to a problem in cgen
|
||
; - DB.
|
||
(dni callr
|
||
"call @Ri"
|
||
(NOT-IN-DELAY-SLOT)
|
||
"call @$Ri"
|
||
(+ OP1_9 OP2_7 OP3_1 Ri)
|
||
(sequence ()
|
||
(set (reg h-dr 1) (add pc (const 2)))
|
||
(set pc Ri))
|
||
((fr30-1 (unit u-cti)))
|
||
)
|
||
(dni callrd
|
||
"call:d @Ri"
|
||
(NOT-IN-DELAY-SLOT)
|
||
"call:d @$Ri"
|
||
(+ OP1_9 OP2_F OP3_1 Ri)
|
||
(delay (const 1)
|
||
(sequence ()
|
||
(set (reg h-dr 1) (add pc (const 4)))
|
||
(set pc Ri)))
|
||
((fr30-1 (unit u-cti)))
|
||
)
|
||
; end of reordered insns
|
||
|
||
(dni call
|
||
"call relative to pc"
|
||
(NOT-IN-DELAY-SLOT)
|
||
"call $label12"
|
||
(+ OP1_D OP5_0 label12)
|
||
(sequence ()
|
||
(set (reg h-dr 1) (add pc (const 2)))
|
||
(set pc label12))
|
||
((fr30-1 (unit u-cti)))
|
||
)
|
||
(dni calld
|
||
"call relative to pc"
|
||
(NOT-IN-DELAY-SLOT)
|
||
"call:d $label12"
|
||
(+ OP1_D OP5_1 label12)
|
||
(delay (const 1)
|
||
(sequence ()
|
||
(set (reg h-dr 1) (add pc (const 4)))
|
||
(set pc label12)))
|
||
((fr30-1 (unit u-cti)))
|
||
)
|
||
|
||
(dni ret
|
||
"return from subroutine"
|
||
(NOT-IN-DELAY-SLOT)
|
||
"ret"
|
||
(+ OP1_9 OP2_7 OP3_2 OP4_0)
|
||
(set pc (reg h-dr 1))
|
||
((fr30-1 (unit u-cti)))
|
||
)
|
||
|
||
(dni ret:d
|
||
"return from subroutine with delay slot"
|
||
(NOT-IN-DELAY-SLOT)
|
||
"ret:d"
|
||
(+ OP1_9 OP2_F OP3_2 OP4_0)
|
||
(delay (const 1)
|
||
(set pc (reg h-dr 1)))
|
||
((fr30-1 (unit u-cti)))
|
||
)
|
||
|
||
(dni int
|
||
"interrupt"
|
||
(NOT-IN-DELAY-SLOT)
|
||
"int $u8"
|
||
(+ OP1_1 OP2_F u8)
|
||
(sequence ()
|
||
; This is defered to fr30_int because for the breakpoint case
|
||
; we want to change as little of the machine state as possible.
|
||
; Push PS onto the system stack
|
||
;(set (reg h-dr 2) (sub (reg h-dr 2) (const 4)))
|
||
;(set UWI (mem UWI (reg h-dr 2)) ps)
|
||
; Push the return address onto the system stack
|
||
;(set (reg h-dr 2) (sub (reg h-dr 2) (const 4)))
|
||
;(set UWI (mem UWI (reg h-dr 2)) (add pc (const 2)))
|
||
; Set status bits
|
||
;(set ibit (const 0))
|
||
;(set sbit (const 0))
|
||
|
||
; We still should indicate what is modified by this insn.
|
||
(clobber (reg h-dr 2))
|
||
(clobber ibit)
|
||
(clobber sbit)
|
||
; ??? (clobber memory)?
|
||
|
||
; fr30_int handles operating vs user mode
|
||
(set WI pc (c-call WI "fr30_int" pc u8))
|
||
)
|
||
; This is more properly a cti, but branch stall calculation is different.
|
||
((fr30-1 (unit u-exec (cycles 6))))
|
||
)
|
||
|
||
(dni inte
|
||
"interrupt for emulator"
|
||
(NOT-IN-DELAY-SLOT)
|
||
"inte"
|
||
(+ OP1_9 OP2_F OP3_3 OP4_0)
|
||
(sequence ()
|
||
; This is defered to fr30_inte because for the breakpoint case
|
||
; we want to change as little of the machine state as possible.
|
||
; Push PS onto the system stack
|
||
;(set (reg h-dr 2) (sub (reg h-dr 2) (const 4)))
|
||
;(set UWI (mem UWI (reg h-dr 2)) ps)
|
||
; Push the return address onto the system stack
|
||
;(set (reg h-dr 2) (sub (reg h-dr 2) (const 4)))
|
||
;(set UWI (mem UWI (reg h-dr 2)) (add pc (const 2)))
|
||
; Set status bits
|
||
;(set ibit (const 0))
|
||
;(set ilm (const 4))
|
||
|
||
; We still should indicate what is modified by this insn.
|
||
(clobber (reg h-dr 2))
|
||
(clobber ibit)
|
||
(clobber ilm)
|
||
; ??? (clobber memory)?
|
||
|
||
; fr30_int handles operating vs user mode
|
||
(set WI pc (c-call WI "fr30_inte" pc))
|
||
)
|
||
; This is more properly a cti, but branch stall calculation is different.
|
||
((fr30-1 (unit u-exec (cycles 6))))
|
||
)
|
||
|
||
(dni reti
|
||
"return from interrupt"
|
||
(NOT-IN-DELAY-SLOT)
|
||
"reti"
|
||
(+ OP1_9 OP2_7 OP3_3 OP4_0)
|
||
(if (eq sbit (const 0))
|
||
(sequence ()
|
||
; Pop the return address from the system stack
|
||
(set UWI pc (mem UWI (reg h-dr 2)))
|
||
(set (reg h-dr 2) (add (reg h-dr 2) (const 4)))
|
||
; Pop PS from the system stack
|
||
(set UWI ps (mem UWI (reg h-dr 2)))
|
||
(set (reg h-dr 2) (add (reg h-dr 2) (const 4)))
|
||
)
|
||
(sequence ()
|
||
; Pop the return address from the user stack
|
||
(set UWI pc (mem UWI (reg h-dr 3)))
|
||
(set (reg h-dr 3) (add (reg h-dr 3) (const 4)))
|
||
; Pop PS from the user stack
|
||
(set UWI ps (mem UWI (reg h-dr 3)))
|
||
(set (reg h-dr 3) (add (reg h-dr 3) (const 4)))
|
||
)
|
||
)
|
||
; This is more properly a cti, but branch stall calculation is different.
|
||
((fr30-1 (unit u-exec (cycles 4))))
|
||
)
|
||
|
||
; Conditional branches with and without delay slots
|
||
;
|
||
(define-pmacro (cond-branch cc condition)
|
||
(begin
|
||
(dni (.sym b cc d)
|
||
(.str (.sym b cc :d) " label9")
|
||
(NOT-IN-DELAY-SLOT)
|
||
(.str (.sym b cc :d) " $label9")
|
||
(+ OP1_F (.sym CC_ cc) label9)
|
||
(delay (const 1)
|
||
(if condition (set pc label9)))
|
||
((fr30-1 (unit u-cti)))
|
||
)
|
||
(dni (.sym b cc)
|
||
(.str (.sym b cc) " label9")
|
||
(NOT-IN-DELAY-SLOT)
|
||
(.str (.sym b cc) " $label9")
|
||
(+ OP1_E (.sym CC_ cc) label9)
|
||
(if condition (set pc label9))
|
||
((fr30-1 (unit u-cti)))
|
||
)
|
||
)
|
||
)
|
||
|
||
(cond-branch ra (const BI 1))
|
||
(cond-branch no (const BI 0))
|
||
(cond-branch eq zbit)
|
||
(cond-branch ne (not zbit))
|
||
(cond-branch c cbit)
|
||
(cond-branch nc (not cbit))
|
||
(cond-branch n nbit)
|
||
(cond-branch p (not nbit))
|
||
(cond-branch v vbit)
|
||
(cond-branch nv (not vbit))
|
||
(cond-branch lt (xor vbit nbit))
|
||
(cond-branch ge (not (xor vbit nbit)))
|
||
(cond-branch le (or (xor vbit nbit) zbit))
|
||
(cond-branch gt (not (or (xor vbit nbit) zbit)))
|
||
(cond-branch ls (or cbit zbit))
|
||
(cond-branch hi (not (or cbit zbit)))
|
||
|
||
(define-pmacro (dir2r13 name insn opc1 opc2 mode arg1)
|
||
(dni name
|
||
(.str insn " @" arg1 ",R13")
|
||
()
|
||
(.str insn " @$" arg1 ",$R13")
|
||
(+ opc1 opc2 arg1)
|
||
(set (reg h-gr 13) (mem mode arg1))
|
||
((fr30-1 (unit u-load)))
|
||
)
|
||
)
|
||
|
||
(define-pmacro (dir2r13-postinc name insn opc1 opc2 mode arg1 incr)
|
||
(dni name
|
||
(.str insn " @" arg1 ",@R13+")
|
||
(NOT-IN-DELAY-SLOT)
|
||
(.str insn " @$" arg1 ",@$R13+")
|
||
(+ opc1 opc2 arg1)
|
||
(sequence ()
|
||
(set (mem mode (reg h-gr 13)) (mem mode arg1))
|
||
(set (reg h-gr 13) (add (reg h-gr 13) incr)))
|
||
((fr30-1 (unit u-load) (unit u-store)))
|
||
)
|
||
)
|
||
|
||
(define-pmacro (r132dir name insn opc1 opc2 mode arg1)
|
||
(dni name
|
||
(.str insn " R13,@" arg1)
|
||
()
|
||
(.str insn " $R13,@$" arg1)
|
||
(+ opc1 opc2 arg1)
|
||
(set (mem mode arg1) (reg h-gr 13))
|
||
((fr30-1 (unit u-store)))
|
||
)
|
||
)
|
||
|
||
(define-pmacro (r13-postinc2dir name insn opc1 opc2 mode arg1 incr)
|
||
(dni name
|
||
(.str insn " @R13+,@" arg1)
|
||
(NOT-IN-DELAY-SLOT)
|
||
(.str insn " @$R13+,@$" arg1)
|
||
(+ opc1 opc2 arg1)
|
||
(sequence ()
|
||
(set (mem mode arg1) (mem mode (reg h-gr 13)))
|
||
(set (reg h-gr 13) (add (reg h-gr 13) incr)))
|
||
((fr30-1 (unit u-load) (unit u-store)))
|
||
)
|
||
)
|
||
|
||
; These versions which move from reg to mem must appear before the other
|
||
; versions which use immediate addresses due to a problem in cgen
|
||
; - DB.
|
||
(r132dir dmovr13 dmov OP1_1 OP2_8 WI dir10)
|
||
(r132dir dmovr13h dmovh OP1_1 OP2_9 HI dir9)
|
||
(r132dir dmovr13b dmovb OP1_1 OP2_A QI dir8)
|
||
|
||
(r13-postinc2dir dmovr13pi dmov OP1_1 OP2_C WI dir10 (const 4))
|
||
(r13-postinc2dir dmovr13pih dmovh OP1_1 OP2_D HI dir9 (const 2))
|
||
(r13-postinc2dir dmovr13pib dmovb OP1_1 OP2_E QI dir8 (const 1))
|
||
|
||
(dni dmovr15pi
|
||
"dmov @R15+,@dir10"
|
||
(NOT-IN-DELAY-SLOT)
|
||
"dmov @$R15+,@$dir10"
|
||
(+ OP1_1 OP2_B dir10)
|
||
(sequence ()
|
||
(set (mem WI dir10) (mem WI (reg h-gr 15)))
|
||
(set (reg h-gr 15) (add (reg h-gr 15) (const 4))))
|
||
((fr30-1 (unit u-load) (unit u-store)))
|
||
)
|
||
; End of reordered insns.
|
||
|
||
(dir2r13 dmov2r13 dmov OP1_0 OP2_8 WI dir10)
|
||
(dir2r13 dmov2r13h dmovh OP1_0 OP2_9 HI dir9)
|
||
(dir2r13 dmov2r13b dmovb OP1_0 OP2_A QI dir8)
|
||
|
||
(dir2r13-postinc dmov2r13pi dmov OP1_0 OP2_C WI dir10 (const 4))
|
||
(dir2r13-postinc dmov2r13pih dmovh OP1_0 OP2_D HI dir9 (const 2))
|
||
(dir2r13-postinc dmov2r13pib dmovb OP1_0 OP2_E QI dir8 (const 1))
|
||
|
||
(dni dmov2r15pd
|
||
"dmov @dir10,@-R15"
|
||
(NOT-IN-DELAY-SLOT)
|
||
"dmov @$dir10,@-$R15"
|
||
(+ OP1_0 OP2_B dir10)
|
||
(sequence ()
|
||
(set (reg h-gr 15) (sub (reg h-gr 15) (const 4)))
|
||
(set (mem WI (reg h-gr 15)) (mem WI dir10)))
|
||
((fr30-1 (unit u-load) (unit u-store)))
|
||
)
|
||
|
||
; Leave these insns as stubs for now, except for the increment of $Ri
|
||
;
|
||
(dni ldres
|
||
"ldres @Ri+,#u4"
|
||
()
|
||
"ldres @$Ri+,$u4"
|
||
(+ OP1_B OP2_C u4 Ri)
|
||
(set Ri (add Ri (const 4)))
|
||
()
|
||
)
|
||
|
||
(dni stres
|
||
"stres #u4,@Ri+"
|
||
()
|
||
"stres $u4,@$Ri+"
|
||
(+ OP1_B OP2_D u4 Ri)
|
||
(set Ri (add Ri (const 4)))
|
||
()
|
||
)
|
||
|
||
; Leave the coprocessor insns as stubs for now.
|
||
;
|
||
(define-pmacro (cop-stub name insn opc1 opc2 opc3 arg1 arg2)
|
||
(dni name
|
||
(.str insn " u4c,ccc,CRj," arg1 "," arg2)
|
||
(NOT-IN-DELAY-SLOT)
|
||
(.str insn " $u4c,$ccc,$" arg1 ",$" arg2)
|
||
(+ opc1 opc2 opc3 u4c ccc arg1 arg2)
|
||
(nop) ; STUB
|
||
()
|
||
)
|
||
)
|
||
|
||
(cop-stub copop copop OP1_9 OP2_F OP3_C CRj CRi)
|
||
(cop-stub copld copld OP1_9 OP2_F OP3_D Rjc CRi)
|
||
(cop-stub copst copst OP1_9 OP2_F OP3_E CRj Ric)
|
||
(cop-stub copsv copsv OP1_9 OP2_F OP3_F CRj Ric)
|
||
|
||
(dni nop
|
||
"nop"
|
||
()
|
||
"nop"
|
||
(+ OP1_9 OP2_F OP3_A OP4_0)
|
||
(nop)
|
||
()
|
||
)
|
||
|
||
(dni andccr
|
||
"andccr #u8"
|
||
()
|
||
"andccr $u8"
|
||
(+ OP1_8 OP2_3 u8)
|
||
(set ccr (and ccr u8))
|
||
()
|
||
)
|
||
|
||
(dni orccr
|
||
"orccr #u8"
|
||
()
|
||
"orccr $u8"
|
||
(+ OP1_9 OP2_3 u8)
|
||
(set ccr (or ccr u8))
|
||
()
|
||
)
|
||
|
||
(dni stilm
|
||
"stilm #u8"
|
||
()
|
||
"stilm $u8"
|
||
(+ OP1_8 OP2_7 u8)
|
||
(set ilm (and u8 (const #x1f)))
|
||
()
|
||
)
|
||
|
||
(dni addsp
|
||
"addsp #s10"
|
||
()
|
||
"addsp $s10"
|
||
(+ OP1_A OP2_3 s10)
|
||
(set (reg h-gr 15) (add (reg h-gr 15) s10))
|
||
()
|
||
)
|
||
|
||
(define-pmacro (ext-op name opc1 opc2 opc3 op mode mask)
|
||
(dni name
|
||
(.str name " Ri")
|
||
()
|
||
(.str name " $Ri")
|
||
(+ opc1 opc2 opc3 Ri)
|
||
(set Ri (op WI (and mode Ri mask)))
|
||
()
|
||
)
|
||
)
|
||
|
||
(ext-op extsb OP1_9 OP2_7 OP3_8 ext QI (const #xff))
|
||
(ext-op extub OP1_9 OP2_7 OP3_9 zext UQI (const #xff))
|
||
(ext-op extsh OP1_9 OP2_7 OP3_A ext HI (const #xffff))
|
||
(ext-op extuh OP1_9 OP2_7 OP3_B zext UHI (const #xffff))
|
||
|
||
(dni ldm0
|
||
"ldm0 (reglist_low_ld)"
|
||
(NOT-IN-DELAY-SLOT)
|
||
"ldm0 ($reglist_low_ld)"
|
||
(+ OP1_8 OP2_C reglist_low_ld)
|
||
(sequence ()
|
||
(if (and reglist_low_ld (const #x1))
|
||
(sequence ()
|
||
(set (reg h-gr 0) (mem WI (reg h-gr 15)))
|
||
(set (reg h-gr 15) (add (reg h-gr 15) (const 4)))))
|
||
(if (and reglist_low_ld (const #x2))
|
||
(sequence ()
|
||
(set (reg h-gr 1) (mem WI (reg h-gr 15)))
|
||
(set (reg h-gr 15) (add (reg h-gr 15) (const 4)))))
|
||
(if (and reglist_low_ld (const #x4))
|
||
(sequence ()
|
||
(set (reg h-gr 2) (mem WI (reg h-gr 15)))
|
||
(set (reg h-gr 15) (add (reg h-gr 15) (const 4)))))
|
||
(if (and reglist_low_ld (const #x8))
|
||
(sequence ()
|
||
(set (reg h-gr 3) (mem WI (reg h-gr 15)))
|
||
(set (reg h-gr 15) (add (reg h-gr 15) (const 4)))))
|
||
(if (and reglist_low_ld (const #x10))
|
||
(sequence ()
|
||
(set (reg h-gr 4) (mem WI (reg h-gr 15)))
|
||
(set (reg h-gr 15) (add (reg h-gr 15) (const 4)))))
|
||
(if (and reglist_low_ld (const #x20))
|
||
(sequence ()
|
||
(set (reg h-gr 5) (mem WI (reg h-gr 15)))
|
||
(set (reg h-gr 15) (add (reg h-gr 15) (const 4)))))
|
||
(if (and reglist_low_ld (const #x40))
|
||
(sequence ()
|
||
(set (reg h-gr 6) (mem WI (reg h-gr 15)))
|
||
(set (reg h-gr 15) (add (reg h-gr 15) (const 4)))))
|
||
(if (and reglist_low_ld (const #x80))
|
||
(sequence ()
|
||
(set (reg h-gr 7) (mem WI (reg h-gr 15)))
|
||
(set (reg h-gr 15) (add (reg h-gr 15) (const 4)))))
|
||
)
|
||
((fr30-1 (unit u-ldm)))
|
||
)
|
||
|
||
(dni ldm1
|
||
"ldm1 (reglist_hi_ld)"
|
||
(NOT-IN-DELAY-SLOT)
|
||
"ldm1 ($reglist_hi_ld)"
|
||
(+ OP1_8 OP2_D reglist_hi_ld)
|
||
(sequence ()
|
||
(if (and reglist_hi_ld (const #x1))
|
||
(sequence ()
|
||
(set (reg h-gr 8) (mem WI (reg h-gr 15)))
|
||
(set (reg h-gr 15) (add (reg h-gr 15) (const 4)))))
|
||
(if (and reglist_hi_ld (const #x2))
|
||
(sequence ()
|
||
(set (reg h-gr 9) (mem WI (reg h-gr 15)))
|
||
(set (reg h-gr 15) (add (reg h-gr 15) (const 4)))))
|
||
(if (and reglist_hi_ld (const #x4))
|
||
(sequence ()
|
||
(set (reg h-gr 10) (mem WI (reg h-gr 15)))
|
||
(set (reg h-gr 15) (add (reg h-gr 15) (const 4)))))
|
||
(if (and reglist_hi_ld (const #x8))
|
||
(sequence ()
|
||
(set (reg h-gr 11) (mem WI (reg h-gr 15)))
|
||
(set (reg h-gr 15) (add (reg h-gr 15) (const 4)))))
|
||
(if (and reglist_hi_ld (const #x10))
|
||
(sequence ()
|
||
(set (reg h-gr 12) (mem WI (reg h-gr 15)))
|
||
(set (reg h-gr 15) (add (reg h-gr 15) (const 4)))))
|
||
(if (and reglist_hi_ld (const #x20))
|
||
(sequence ()
|
||
(set (reg h-gr 13) (mem WI (reg h-gr 15)))
|
||
(set (reg h-gr 15) (add (reg h-gr 15) (const 4)))))
|
||
(if (and reglist_hi_ld (const #x40))
|
||
(sequence ()
|
||
(set (reg h-gr 14) (mem WI (reg h-gr 15)))
|
||
(set (reg h-gr 15) (add (reg h-gr 15) (const 4)))))
|
||
(if (and reglist_hi_ld (const #x80))
|
||
(set (reg h-gr 15) (mem WI (reg h-gr 15))))
|
||
)
|
||
((fr30-1 (unit u-ldm)))
|
||
)
|
||
|
||
(dni stm0
|
||
"stm0 (reglist_low_st)"
|
||
(NOT-IN-DELAY-SLOT)
|
||
"stm0 ($reglist_low_st)"
|
||
(+ OP1_8 OP2_E reglist_low_st)
|
||
(sequence ()
|
||
(if (and reglist_low_st (const #x1))
|
||
(sequence ()
|
||
(set (reg h-gr 15) (sub (reg h-gr 15) (const 4)))
|
||
(set (mem WI (reg h-gr 15)) (reg h-gr 7))))
|
||
(if (and reglist_low_st (const #x2))
|
||
(sequence ()
|
||
(set (reg h-gr 15) (sub (reg h-gr 15) (const 4)))
|
||
(set (mem WI (reg h-gr 15)) (reg h-gr 6))))
|
||
(if (and reglist_low_st (const #x4))
|
||
(sequence ()
|
||
(set (reg h-gr 15) (sub (reg h-gr 15) (const 4)))
|
||
(set (mem WI (reg h-gr 15)) (reg h-gr 5))))
|
||
(if (and reglist_low_st (const #x8))
|
||
(sequence ()
|
||
(set (reg h-gr 15) (sub (reg h-gr 15) (const 4)))
|
||
(set (mem WI (reg h-gr 15)) (reg h-gr 4))))
|
||
(if (and reglist_low_st (const #x10))
|
||
(sequence ()
|
||
(set (reg h-gr 15) (sub (reg h-gr 15) (const 4)))
|
||
(set (mem WI (reg h-gr 15)) (reg h-gr 3))))
|
||
(if (and reglist_low_st (const #x20))
|
||
(sequence ()
|
||
(set (reg h-gr 15) (sub (reg h-gr 15) (const 4)))
|
||
(set (mem WI (reg h-gr 15)) (reg h-gr 2))))
|
||
(if (and reglist_low_st (const #x40))
|
||
(sequence ()
|
||
(set (reg h-gr 15) (sub (reg h-gr 15) (const 4)))
|
||
(set (mem WI (reg h-gr 15)) (reg h-gr 1))))
|
||
(if (and reglist_low_st (const #x80))
|
||
(sequence ()
|
||
(set (reg h-gr 15) (sub (reg h-gr 15) (const 4)))
|
||
(set (mem WI (reg h-gr 15)) (reg h-gr 0))))
|
||
)
|
||
((fr30-1 (unit u-stm)))
|
||
)
|
||
|
||
(dni stm1
|
||
"stm1 (reglist_hi_st)"
|
||
(NOT-IN-DELAY-SLOT)
|
||
"stm1 ($reglist_hi_st)"
|
||
(+ OP1_8 OP2_F reglist_hi_st)
|
||
(sequence ()
|
||
(if (and reglist_hi_st (const #x1))
|
||
(sequence ((WI save-r15))
|
||
(set save-r15 (reg h-gr 15))
|
||
(set (reg h-gr 15) (sub (reg h-gr 15) (const 4)))
|
||
(set (mem WI (reg h-gr 15)) save-r15)))
|
||
(if (and reglist_hi_st (const #x2))
|
||
(sequence ()
|
||
(set (reg h-gr 15) (sub (reg h-gr 15) (const 4)))
|
||
(set (mem WI (reg h-gr 15)) (reg h-gr 14))))
|
||
(if (and reglist_hi_st (const #x4))
|
||
(sequence ()
|
||
(set (reg h-gr 15) (sub (reg h-gr 15) (const 4)))
|
||
(set (mem WI (reg h-gr 15)) (reg h-gr 13))))
|
||
(if (and reglist_hi_st (const #x8))
|
||
(sequence ()
|
||
(set (reg h-gr 15) (sub (reg h-gr 15) (const 4)))
|
||
(set (mem WI (reg h-gr 15)) (reg h-gr 12))))
|
||
(if (and reglist_hi_st (const #x10))
|
||
(sequence ()
|
||
(set (reg h-gr 15) (sub (reg h-gr 15) (const 4)))
|
||
(set (mem WI (reg h-gr 15)) (reg h-gr 11))))
|
||
(if (and reglist_hi_st (const #x20))
|
||
(sequence ()
|
||
(set (reg h-gr 15) (sub (reg h-gr 15) (const 4)))
|
||
(set (mem WI (reg h-gr 15)) (reg h-gr 10))))
|
||
(if (and reglist_hi_st (const #x40))
|
||
(sequence ()
|
||
(set (reg h-gr 15) (sub (reg h-gr 15) (const 4)))
|
||
(set (mem WI (reg h-gr 15)) (reg h-gr 9))))
|
||
(if (and reglist_hi_st (const #x80))
|
||
(sequence ()
|
||
(set (reg h-gr 15) (sub (reg h-gr 15) (const 4)))
|
||
(set (mem WI (reg h-gr 15)) (reg h-gr 8))))
|
||
)
|
||
((fr30-1 (unit u-stm)))
|
||
)
|
||
|
||
(dni enter
|
||
"enter #u10"
|
||
(NOT-IN-DELAY-SLOT)
|
||
"enter $u10"
|
||
(+ OP1_0 OP2_F u10)
|
||
(sequence ((WI tmp))
|
||
(set tmp (sub (reg h-gr 15) (const 4)))
|
||
(set (mem WI tmp) (reg h-gr 14))
|
||
(set (reg h-gr 14) tmp)
|
||
(set (reg h-gr 15) (sub (reg h-gr 15) u10)))
|
||
((fr30-1 (unit u-exec (cycles 2))))
|
||
)
|
||
|
||
(dni leave
|
||
"leave"
|
||
()
|
||
"leave"
|
||
(+ OP1_9 OP2_F OP3_9 OP4_0)
|
||
(sequence ()
|
||
(set (reg h-gr 15) (add (reg h-gr 14) (const 4)))
|
||
(set (reg h-gr 14) (mem WI (sub (reg h-gr 15) (const 4)))))
|
||
()
|
||
)
|
||
|
||
(dni xchb
|
||
"xchb @Rj,Ri"
|
||
(NOT-IN-DELAY-SLOT)
|
||
"xchb @$Rj,$Ri"
|
||
(+ OP1_8 OP2_A Rj Ri)
|
||
(sequence ((WI tmp))
|
||
(set tmp Ri)
|
||
(set Ri (mem UQI Rj))
|
||
(set (mem UQI Rj) tmp))
|
||
((fr30-1 (unit u-load) (unit u-store)))
|
||
)
|