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