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