2003-06-03 Andrew Cagney <cagney@redhat.com>
authorAndrew Cagney <cagney@redhat.com>
Tue, 3 Jun 2003 15:41:12 +0000 (15:41 +0000)
committerAndrew Cagney <cagney@redhat.com>
Tue, 3 Jun 2003 15:41:12 +0000 (15:41 +0000)
Contributed by Red Hat.
* frv.cpu: New file.  Written by Dave Brolley, Catherine Moore,
and Eric Christopher.
* frv.opc: New file.  Written by Catherine Moore, and Dave
Brolley.
* simplify.inc: New file.  Written by Doug Evans.

cpu/ChangeLog
cpu/frv.cpu [new file with mode: 0644]
cpu/frv.opc [new file with mode: 0644]
cpu/simplify.inc [new file with mode: 0644]

index c66cc4b7b952565fa1fde772e3eac1e29e3c36f1..bef4ff885e905d7a8a1825ad4030ccc34f4f058f 100644 (file)
@@ -1,3 +1,12 @@
+2003-06-03  Andrew Cagney  <cagney@redhat.com>
+
+       Contributed by Red Hat.
+       * frv.cpu: New file.  Written by Dave Brolley, Catherine Moore,
+       and Eric Christopher.
+       * frv.opc: New file.  Written by Catherine Moore, and Dave
+       Brolley.
+       * simplify.inc: New file.  Written by Doug Evans.
+
 2003-05-02  Andrew Cagney  <cagney@redhat.com>
 
        * New file.
diff --git a/cpu/frv.cpu b/cpu/frv.cpu
new file mode 100644 (file)
index 0000000..82a8817
--- /dev/null
@@ -0,0 +1,8078 @@
+; Fujitsu FRV opcode support, for GNU Binutils.  -*- Scheme -*-
+;
+; Copyright 2000, 2001 Free Software Foundation, Inc.
+;
+; Contributed by Red Hat Inc; developed under contract from Fujitsu.
+;
+; 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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+(include "simplify.inc")
+
+; define-arch must appear first
+
+(define-arch
+  (name frv) ; name of cpu architecture
+  (comment "Fujitsu FRV")
+  (insn-lsb0? #t)
+  (machs frv fr500 fr400 tomcat simple)
+  (isas frv)
+)
+
+(define-isa
+  (name frv)
+  (base-insn-bitsize 32)
+  ; Initial bitnumbers to decode insns by.
+  (decode-assist (24 23 22 21 20 19 18))
+  (liw-insns 1)       ; The frv fetches  up to 1 insns at a time.
+  (parallel-insns 4)  ; The frv executes up to 4 insns at a time.
+)
+
+; Cpu family definitions.
+;
+(define-cpu
+  ; cpu names must be distinct from the architecture name and machine names.
+  ; The "b" suffix stands for "base" and is the convention.
+  ; The "f" suffix stands for "family" and is the convention.
+  (name frvbf)
+  (comment "Fujitsu FRV base family")
+  (endian big)
+  (word-bitsize 32)
+)
+\f
+; Generic FR-V machine. Supports the entire architecture
+(define-mach
+  (name frv)
+  (comment "Generic FRV cpu")
+  (cpu frvbf)
+)
+(define-model
+  (name frv) (comment "Generic FRV model") (attrs)
+  (mach frv)
+
+  (pipeline all "" () ((fetch) (decode) (execute) (writeback)))
+
+  ; `state' is a list of variables for recording model state
+  ; (state)
+
+  (unit u-exec "Execution Unit" ()
+       1 1 ; issue done
+       () ; state
+       () ; inputs
+       () ; outputs
+       () ; profile action (default)
+       )
+)
+\f
+; FR500 machine.
+(define-mach
+  (name fr500)
+  (comment "FR500 cpu")
+  (cpu frvbf)
+)
+(define-model
+  (name fr500) (comment "FR500 model") (attrs)
+  (mach fr500)
+
+  (pipeline all "" () ((fetch) (decode) (execute) (writeback)))
+
+  ; `state' is a list of variables for recording model state
+  (state
+   ; State items
+   ; These are all masks with each bit representing one register.
+   (prev-fpop       DI) ; Previous use of FR register was floating point insn
+   (prev-media      DI) ; Previous use of FR register was a media insn
+   (prev-cc-complex DI) ; Previous use of ICC register was not simple
+   (cur-fpop        DI) ; Current use of FR register was floating point insn
+   (cur-media       DI) ; Current use of FR register was a media insn
+   (cur-cc-complex  DI) ; Current use of ICC register was not simple
+  )
+  ; Basic unit for instructions with no latency penalties
+  (unit u-exec "Execution Unit" ()
+       1 1 ; issue done
+       () ; state
+       () ; inputs
+       () ; outputs
+       () ; profile action (default)
+       )
+  ; Basic integer insn unit
+  (unit u-integer "Integer Unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRi INT -1) (GRj INT -1)) ; inputs
+       ((GRk INT -1) (ICCi_1 INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; Integer multiplication unit
+  (unit u-imul "Integer Multiplication Unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRi INT -1) (GRj INT -1)) ; inputs
+       ((GRdoublek INT -1) (ICCi_1 INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; Integer division unit
+  (unit u-idiv "Integer Division Unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRi INT -1) (GRj INT -1)) ; inputs
+       ((GRk INT -1) (ICCi_1 INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; Branch unit
+  (unit u-branch "Branch Unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRi INT -1) (GRj INT -1)
+        (ICCi_2 INT -1) (FCCi_2 INT -1)) ; inputs
+       ((pc)) ; outputs
+       () ; profile action (default)
+       )
+  ; Trap unit
+  (unit u-trap "Trap Unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRi INT -1) (GRj INT -1)
+        (ICCi_2 INT -1) (FCCi_2 INT -1)) ; inputs
+       () ; outputs
+       () ; profile action (default)
+       )
+  ; Condition code check unit
+  (unit u-check "Check Unit" ()
+       1 1 ; issue done
+       () ; state
+       ((ICCi_3 INT -1) (FCCi_3 INT -1)) ; inputs
+       () ; outputs
+       () ; profile action (default)
+       )
+  ; GR set half unit
+  (unit u-set-hilo "GR Set Half" ()
+       1 1 ; issue done
+       () ; state
+       () ; inputs
+       ((GRkhi INT -1) (GRklo INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; GR load unit -- TODO doesn't handle quad
+  (unit u-gr-load "GR Load Unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRi INT -1) (GRj INT -1)) ; inputs
+       ((GRk INT -1) (GRdoublek INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; GR store unit -- TODO doesn't handle quad
+  (unit u-gr-store "GR Store Unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRi INT -1) (GRj INT -1) (GRk INT -1) (GRdoublek INT -1)) ; inputs
+       () ; outputs
+       () ; profile action (default)
+       )
+  ; GR recovering store unit -- TODO doesn't handle quad
+  (unit u-gr-r-store "GR Recovering Store Unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRi INT -1) (GRj INT -1) (GRk INT -1) (GRdoublek INT -1)) ; inputs
+       () ; outputs
+       () ; profile action (default)
+       )
+  ; FR load unit -- TODO doesn't handle quad
+  (unit u-fr-load "FR Load Unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRi INT -1) (GRj INT -1)) ; inputs
+       ((FRintk INT -1) (FRdoublek INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; FR store unit -- TODO doesn't handle quad
+  (unit u-fr-store "FR Store Unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRi INT -1) (GRj INT -1) (FRintk INT -1) (FRdoublek INT -1)) ; inputs
+       () ; outputs
+       () ; profile action (default)
+       )
+  ; FR recovering store unit -- TODO doesn't handle quad
+  (unit u-fr-r-store "FR Recovering Store Unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRi INT -1) (GRj INT -1) (FRintk INT -1) (FRdoublek INT -1)) ; inputs
+       () ; outputs
+       () ; profile action (default)
+       )
+  ; Swap unit
+  (unit u-swap "Swap Unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRi INT -1) (GRj INT -1)) ; inputs
+       ((GRk INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; FR Move to FR unit
+  (unit u-fr2fr "FR Move to FR Unit" ()
+       1 1 ; issue done
+       () ; state
+       ((FRi INT -1)) ; inputs
+       ((FRk INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; FR Move to GR unit
+  (unit u-fr2gr "FR Move to GR Unit" ()
+       1 1 ; issue done
+       () ; state
+       ((FRintk INT -1)) ; inputs
+       ((GRj INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; SPR Move to GR unit
+  (unit u-spr2gr "SPR Move to GR Unit" ()
+       1 1 ; issue done
+       () ; state
+       ((spr INT -1)) ; inputs
+       ((GRj INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; GR Move to FR unit
+  (unit u-gr2fr "GR Move to FR Unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRj INT -1)) ; inputs
+       ((FRintk INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; GR Move to SPR unit
+  (unit u-gr2spr "GR Move to SPR Unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRj INT -1)) ; inputs
+       ((spr INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; Float Arithmetic unit
+  (unit u-float-arith "Float Arithmetic unit" ()
+       1 1 ; issue done
+       () ; state
+       ((FRi INT -1) (FRj INT -1) ; inputs
+        (FRdoublei INT -1) (FRdoublej INT -1)) ; inputs
+       ((FRk INT -1) (FRdoublek INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; Float Dual Arithmetic unit
+  (unit u-float-dual-arith "Float Arithmetic unit" ()
+       1 1 ; issue done
+       () ; state
+       ((FRi INT -1) (FRj INT -1) ; inputs
+        (FRdoublei INT -1) (FRdoublej INT -1)) ; inputs
+       ((FRk INT -1) (FRdoublek INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; Float Div unit
+  (unit u-float-div "Float Div unit" ()
+       1 1 ; issue done
+       () ; state
+       ((FRi INT -1) (FRj INT -1)) ; inputs
+       ((FRk INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; Float Square Root unit
+  (unit u-float-sqrt "Float Square Root unit" ()
+       1 1 ; issue done
+       () ; state
+       ((FRj INT -1) (FRdoublej INT -1)) ; inputs
+       ((FRk INT -1) (FRdoublek INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; Float Dual Square Root unit
+  (unit u-float-dual-sqrt "Float Dual Square Root unit" ()
+       1 1 ; issue done
+       () ; state
+       ((FRj INT -1)) ; inputs
+       ((FRk INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; Float Compare unit
+  (unit u-float-compare "Float Compare unit" ()
+       1 1 ; issue done
+       () ; state
+       ((FRi INT -1) (FRj INT -1)
+        (FRdoublei INT -1) (FRdoublej INT -1)) ; inputs
+       ((FCCi_2 INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; Dual Float Compare unit
+  (unit u-float-dual-compare "Float Dual Compare unit" ()
+       1 1 ; issue done
+       () ; state
+       ((FRi INT -1) (FRj INT -1)) ; inputs
+       ((FCCi_2 INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; Float Conversion unit
+  (unit u-float-convert "Float Conversion unit" ()
+       1 1 ; issue done
+       () ; state
+       ((FRj INT -1) (FRintj INT -1) (FRdoublej INT -1)) ; inputs
+       ((FRk INT -1) (FRintk INT -1) (FRdoublek INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; Dual Float Conversion unit
+  (unit u-float-dual-convert "Float Dual Conversion unit" ()
+       1 1 ; issue done
+       () ; state
+       ((FRj INT -1) (FRintj INT -1)) ; inputs
+       ((FRk INT -1) (FRintk INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; Media unit
+  (unit u-media "Media unit" ()
+       1 1 ; issue done
+       () ; state
+       ((FRinti INT -1) (FRintj INT -1) (ACC40Si INT -1) (ACCGi INT -1)) ; inputs
+       ((FRintk INT -1) (ACC40Sk INT -1) (ACC40Uk INT -1) (ACCGk INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; Media Quad Arithmetic unit
+  (unit u-media-quad-arith "Media Quad Arithmetic unit" ()
+       1 1 ; issue done
+       () ; state
+       ((FRinti INT -1) (FRintj INT -1)) ; inputs
+       ((FRintk INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; Media Dual Multiplication unit
+  (unit u-media-dual-mul "Media Dual Multiplication unit" ()
+       1 1 ; issue done
+       () ; state
+       ((FRinti INT -1) (FRintj INT -1)) ; inputs
+       ((ACC40Sk INT -1) (ACC40Uk INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; Media Quad Multiplication unit
+  (unit u-media-quad-mul "Media Quad Multiplication unit" ()
+       1 1 ; issue done
+       () ; state
+       ((FRinti INT -1) (FRintj INT -1)) ; inputs
+       ((ACC40Sk INT -1) (ACC40Uk INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; Media Quad Complex unit
+  (unit u-media-quad-complex "Media Quad Complex unit" ()
+       1 1 ; issue done
+       () ; state
+       ((FRinti INT -1) (FRintj INT -1)) ; inputs
+       ((ACC40Sk INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; Media Dual Expand unit
+  (unit u-media-dual-expand "Media Dual Expand unit" ()
+       1 1 ; issue done
+       () ; state
+       ((FRinti INT -1)) ; inputs
+       ((FRintk INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; Media Dual Unpack unit
+  (unit u-media-dual-unpack "Media Dual Unpack unit" ()
+       1 1 ; issue done
+       () ; state
+       ((FRinti INT -1)) ; inputs
+       ((FRintk INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; Media Dual byte to half unit
+  (unit u-media-dual-btoh "Media Byte to byte" ()
+       1 1 ; issue done
+       () ; state
+       ((FRintj INT -1)) ; inputs
+       ((FRintk INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; Media Dual half to byte unit
+  (unit u-media-dual-htob "Media Half to byte" ()
+       1 1 ; issue done
+       () ; state
+       ((FRintj INT -1)) ; inputs
+       ((FRintk INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; Media Dual byte to half unit extended
+  (unit u-media-dual-btohe "Media Byte to byte extended" ()
+       1 1 ; issue done
+       () ; state
+       ((FRintj INT -1)) ; inputs
+       ((FRintk INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; Barrier unit
+  (unit u-barrier "Barrier unit" ()
+       1 1 ; issue done
+       () ; state
+       () ; inputs
+       () ; outputs
+       () ; profile action (default)
+       )
+  ; Memory Barrier unit
+  (unit u-membar "Memory Barrier unit" ()
+       1 1 ; issue done
+       () ; state
+       () ; inputs
+       () ; outputs
+       () ; profile action (default)
+       )
+  ; Insn cache invalidate unit
+  (unit u-ici "Insn cache invalidate unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRi INT -1) (GRj INT -1)) ; inputs
+       () ; outputs
+       () ; profile action (default)
+       )
+  ; Data cache invalidate unit
+  (unit u-dci "Data cache invalidate unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRi INT -1) (GRj INT -1)) ; inputs
+       () ; outputs
+       () ; profile action (default)
+       )
+  ; Data cache flush unit
+  (unit u-dcf "Data cache flush unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRi INT -1) (GRj INT -1)) ; inputs
+       () ; outputs
+       () ; profile action (default)
+       )
+  ; Insn cache preload unit
+  (unit u-icpl "Insn cache preload unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRi INT -1) (GRj INT -1)) ; inputs
+       () ; outputs
+       () ; profile action (default)
+       )
+  ; Data cache preload unit
+  (unit u-dcpl "Data cache preload unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRi INT -1) (GRj INT -1)) ; inputs
+       () ; outputs
+       () ; profile action (default)
+       )
+  ; Insn cache unlock unit
+  (unit u-icul "Insn cache unlock unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRi INT -1) (GRj INT -1)) ; inputs
+       () ; outputs
+       () ; profile action (default)
+       )
+  ; Data cache unlock unit
+  (unit u-dcul "Data cache unlock unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRi INT -1) (GRj INT -1)) ; inputs
+       () ; outputs
+       () ; profile action (default)
+       )
+)
+\f
+; Tomcat machine. Early version of fr500 machine
+(define-mach
+  (name tomcat)
+  (comment "Tomcat -- early version of fr500")
+  (cpu frvbf)
+)
+(define-model
+  (name tomcat) (comment "Tomcat model") (attrs)
+  (mach tomcat)
+
+  (pipeline all "" () ((fetch) (decode) (execute) (writeback)))
+
+  ; `state' is a list of variables for recording model state
+  ; (state)
+
+  (unit u-exec "Execution Unit" ()
+       1 1 ; issue done
+       () ; state
+       () ; inputs
+       () ; outputs
+       () ; profile action (default)
+       )
+)
+\f
+; FR400 machine
+(define-mach
+  (name fr400)
+  (comment "FR400 cpu")
+  (cpu frvbf)
+)
+(define-model
+  (name fr400) (comment "FR400 model") (attrs)
+  (mach fr400)
+  (pipeline all "" () ((fetch) (decode) (execute) (writeback)))
+  ; `state' is a list of variables for recording model state
+  (state
+   ; State items
+   ; These are all masks with each bit representing one register.
+   (prev-fp-load    DI) ; Previous use of FR  register was floating point load
+   (prev-fr-p4      DI) ; Previous use of FR  register was media unit 4
+   (prev-fr-p6      DI) ; Previous use of FR  register was media unit 6
+   (prev-acc-p2     DI) ; Previous use of ACC register was media unit 2
+   (prev-acc-p4     DI) ; Previous use of ACC register was media unit 4
+   (cur-fp-load     DI) ; Current  use of FR  register is  floating point load
+   (cur-fr-p4       DI) ; Current  use of FR  register is  media unit 4
+   (cur-fr-p6       DI) ; Current  use of FR  register is  media unit 6
+   (cur-acc-p2      DI) ; Current  use of ACC register is  media unit 2
+   (cur-acc-p4      DI) ; Current  use of ACC register is  media unit 4
+  )
+  (unit u-exec "Execution Unit" ()
+       1 1 ; issue done
+       () ; state
+       () ; inputs
+       () ; outputs
+       () ; profile action (default)
+       )
+  ; Basic integer insn unit
+  (unit u-integer "Integer Unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRi INT -1) (GRj INT -1)) ; inputs
+       ((GRk INT -1) (ICCi_1 INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; Integer multiplication unit
+  (unit u-imul "Integer Multiplication Unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRi INT -1) (GRj INT -1)) ; inputs
+       ((GRdoublek INT -1) (ICCi_1 INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; Integer division unit
+  (unit u-idiv "Integer Division Unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRi INT -1) (GRj INT -1)) ; inputs
+       ((GRk INT -1) (ICCi_1 INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; Branch unit
+  (unit u-branch "Branch Unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRi INT -1) (GRj INT -1)
+        (ICCi_2 INT -1) (FCCi_2 INT -1)) ; inputs
+       ((pc)) ; outputs
+       () ; profile action (default)
+       )
+  ; Trap unit
+  (unit u-trap "Trap Unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRi INT -1) (GRj INT -1)
+        (ICCi_2 INT -1) (FCCi_2 INT -1)) ; inputs
+       () ; outputs
+       () ; profile action (default)
+       )
+  ; Condition code check unit
+  (unit u-check "Check Unit" ()
+       1 1 ; issue done
+       () ; state
+       ((ICCi_3 INT -1) (FCCi_3 INT -1)) ; inputs
+       () ; outputs
+       () ; profile action (default)
+       )
+  ; GR set half unit
+  (unit u-set-hilo "GR Set Half" ()
+       1 1 ; issue done
+       () ; state
+       () ; inputs
+       ((GRkhi INT -1) (GRklo INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; GR load unit -- TODO doesn't handle quad
+  (unit u-gr-load "GR Load Unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRi INT -1) (GRj INT -1)) ; inputs
+       ((GRk INT -1) (GRdoublek INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; GR store unit -- TODO doesn't handle quad
+  (unit u-gr-store "GR Store Unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRi INT -1) (GRj INT -1) (GRk INT -1) (GRdoublek INT -1)) ; inputs
+       () ; outputs
+       () ; profile action (default)
+       )
+  ; FR load unit -- TODO doesn't handle quad
+  (unit u-fr-load "FR Load Unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRi INT -1) (GRj INT -1)) ; inputs
+       ((FRintk INT -1) (FRdoublek INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; FR store unit -- TODO doesn't handle quad
+  (unit u-fr-store "FR Store Unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRi INT -1) (GRj INT -1) (FRintk INT -1) (FRdoublek INT -1)) ; inputs
+       () ; outputs
+       () ; profile action (default)
+       )
+  ; Swap unit
+  (unit u-swap "Swap Unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRi INT -1) (GRj INT -1)) ; inputs
+       ((GRk INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; FR Move to GR unit
+  (unit u-fr2gr "FR Move to GR Unit" ()
+       1 1 ; issue done
+       () ; state
+       ((FRintk INT -1)) ; inputs
+       ((GRj INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; SPR Move to GR unit
+  (unit u-spr2gr "SPR Move to GR Unit" ()
+       1 1 ; issue done
+       () ; state
+       ((spr INT -1)) ; inputs
+       ((GRj INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; GR Move to FR unit
+  (unit u-gr2fr "GR Move to FR Unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRj INT -1)) ; inputs
+       ((FRintk INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; GR Move to SPR unit
+  (unit u-gr2spr "GR Move to SPR Unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRj INT -1)) ; inputs
+       ((spr INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; Media unit M1 -- see table 13-8 in the fr400 LSI
+  (unit u-media-1 "Media-1 unit" ()
+       1 1 ; issue done
+       () ; state
+       ((FRinti INT -1) (FRintj INT -1)) ; inputs
+       ((FRintk INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  (unit u-media-1-quad "Media-1-quad unit" ()
+       1 1 ; issue done
+       () ; state
+       ((FRinti INT -1) (FRintj INT -1)) ; inputs
+       ((FRintk INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  (unit u-media-hilo "Media-hilo unit -- a variation of the Media-1 unit" ()
+       1 1 ; issue done
+       () ; state
+       () ; inputs
+       ((FRkhi INT -1) (FRklo INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; Media unit M2 -- see table 13-8 in the fr400 LSI
+  (unit u-media-2 "Media-2 unit" ()
+       1 1 ; issue done
+       () ; state
+       ((FRinti INT -1) (FRintj INT -1)) ; inputs
+       ((ACC40Sk INT -1) (ACC40Uk INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  (unit u-media-2-quad "Media-2-quad unit" ()
+       1 1 ; issue done
+       () ; state
+       ((FRinti INT -1) (FRintj INT -1)) ; inputs
+       ((ACC40Sk INT -1) (ACC40Uk INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  (unit u-media-2-acc "Media-2-acc unit" ()
+       1 1 ; issue done
+       () ; state
+       ((ACC40Si INT -1)) ; inputs
+       ((ACC40Sk INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  (unit u-media-2-acc-dual "Media-2-acc-dual unit" ()
+       1 1 ; issue done
+       () ; state
+       ((ACC40Si INT -1)) ; inputs
+       ((ACC40Sk INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  (unit u-media-2-add-sub "Media-2-add-sub unit" ()
+       1 1 ; issue done
+       () ; state
+       ((ACC40Si INT -1)) ; inputs
+       ((ACC40Sk INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  (unit u-media-2-add-sub-dual "Media-2-add-sub-dual unit" ()
+       1 1 ; issue done
+       () ; state
+       ((ACC40Si INT -1)) ; inputs
+       ((ACC40Sk INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; Media unit M3 -- see table 13-8 in the fr400 LSI
+  (unit u-media-3 "Media-3 unit" ()
+       1 1 ; issue done
+       () ; state
+       ((FRinti INT -1) (FRintj INT -1)) ; inputs
+       ((FRintk INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  (unit u-media-3-dual "Media-3-dual unit" ()
+       1 1 ; issue done
+       () ; state
+       ((FRinti INT -1)) ; inputs
+       ((FRintk INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  (unit u-media-3-quad "Media-3-quad unit" ()
+       1 1 ; issue done
+       () ; state
+       ((FRinti INT -1) (FRintj INT -1)) ; inputs
+       ((FRintk INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; Media unit M4 -- see table 13-8 in the fr400 LSI
+  (unit u-media-4 "Media-4 unit" ()
+       1 1 ; issue done
+       () ; state
+       ((ACC40Si INT -1) (FRintj INT -1)) ; inputs
+       ((ACC40Sk INT -1) (FRintk INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  (unit u-media-4-accg "Media-4-accg unit" ()
+       1 1 ; issue done
+       () ; state
+       ((ACCGi INT -1) (FRinti INT -1)) ; inputs
+       ((ACCGk INT -1) (FRintk INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  (unit u-media-4-acc-dual "Media-4-acc-dual unit" ()
+       1 1 ; issue done
+       () ; state
+       ((ACC40Si INT -1)) ; inputs
+       ((FRintk INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; Media unit M6 -- see table 13-8 in the fr400 LSI
+  (unit u-media-6 "Media-6 unit" ()
+       1 1 ; issue done
+       () ; state
+       ((FRinti INT -1)) ; inputs
+       ((FRintk INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; Media unit M7 -- see table 13-8 in the fr400 LSI
+  (unit u-media-7 "Media-1 unit" ()
+       1 1 ; issue done
+       () ; state
+       ((FRinti INT -1) (FRintj INT -1)) ; inputs
+       ((FCCk INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; Media Dual Expand unit
+  (unit u-media-dual-expand "Media Dual Expand unit" ()
+       1 1 ; issue done
+       () ; state
+       ((FRinti INT -1)) ; inputs
+       ((FRintk INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; Media Dual half to byte unit
+  (unit u-media-dual-htob "Media Half to byte" ()
+       1 1 ; issue done
+       () ; state
+       ((FRintj INT -1)) ; inputs
+       ((FRintk INT -1)) ; outputs
+       () ; profile action (default)
+       )
+  ; Barrier unit
+  (unit u-barrier "Barrier unit" ()
+       1 1 ; issue done
+       () ; state
+       () ; inputs
+       () ; outputs
+       () ; profile action (default)
+       )
+  ; Memory Barrier unit
+  (unit u-membar "Memory Barrier unit" ()
+       1 1 ; issue done
+       () ; state
+       () ; inputs
+       () ; outputs
+       () ; profile action (default)
+       )
+  ; Insn cache invalidate unit
+  (unit u-ici "Insn cache invalidate unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRi INT -1) (GRj INT -1)) ; inputs
+       () ; outputs
+       () ; profile action (default)
+       )
+  ; Data cache invalidate unit
+  (unit u-dci "Data cache invalidate unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRi INT -1) (GRj INT -1)) ; inputs
+       () ; outputs
+       () ; profile action (default)
+       )
+  ; Data cache flush unit
+  (unit u-dcf "Data cache flush unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRi INT -1) (GRj INT -1)) ; inputs
+       () ; outputs
+       () ; profile action (default)
+       )
+  ; Insn cache preload unit
+  (unit u-icpl "Insn cache preload unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRi INT -1) (GRj INT -1)) ; inputs
+       () ; outputs
+       () ; profile action (default)
+       )
+  ; Data cache preload unit
+  (unit u-dcpl "Data cache preload unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRi INT -1) (GRj INT -1)) ; inputs
+       () ; outputs
+       () ; profile action (default)
+       )
+  ; Insn cache unlock unit
+  (unit u-icul "Insn cache unlock unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRi INT -1) (GRj INT -1)) ; inputs
+       () ; outputs
+       () ; profile action (default)
+       )
+  ; Data cache unlock unit
+  (unit u-dcul "Data cache unlock unit" ()
+       1 1 ; issue done
+       () ; state
+       ((GRi INT -1) (GRj INT -1)) ; inputs
+       () ; outputs
+       () ; profile action (default)
+       )
+)
+\f
+; Simple machine - single issue integer machine
+(define-mach
+  (name simple)
+  (comment "Simple single issue integer cpu")
+  (cpu frvbf)
+)
+(define-model
+  (name simple) (comment "Simple model") (attrs)
+  (mach simple)
+  (pipeline all "" () ((fetch) (decode) (execute) (writeback)))
+  ; `state' is a list of variables for recording model state
+  (state)
+  (unit u-exec "Execution Unit" ()
+       1 1 ; issue done
+       () ; state
+       () ; inputs
+       () ; outputs
+       () ; profile action (default)
+       )
+)
+\f
+; 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))
+\f
+; An attribute to describe which unit an insn runs in.
+(define-attr
+  (for insn)
+  (type enum)
+  (name UNIT)
+  (comment "parallel execution pipeline selection")
+  ; The order of declaration is significant. Keep variations on the same unit
+  ; together and keep the '01' variation last within each unit.
+  (values NIL
+         I0 I1 I01
+         FM0 FM1 FM01
+         B0 B1 B01
+         C
+         MULT-DIV ; multiply/division slotted differently on different machines
+         LOAD     ; loads             slotted differently on different machines
+         NUM_UNITS
+  )
+)
+; Attributes to describe major categories of insns
+(define-attr
+  (for insn)
+  (type enum)
+  (name FR400-MAJOR)
+  (comment "fr400 major insn categories")
+  ; The order of declaration is significant. Keep variations on the same major
+  ; together.
+  (values NONE
+         I-1 I-2 I-3 I-4 I-5
+         B-1 B-2 B-3 B-4 B-5 B-6
+         C-1 C-2
+         M-1 M-2
+  )
+)
+(define-attr
+  (for insn)
+  (type enum)
+  (name FR500-MAJOR)
+  (comment "fr500 major insn categories")
+  ; The order of declaration is significant. Keep variations on the same major
+  ; together.
+  (values NONE
+         I-1 I-2 I-3 I-4 I-5 I-6
+         B-1 B-2 B-3 B-4 B-5 B-6
+         C-1 C-2
+         F-1 F-2 F-3 F-4 F-5 F-6 F-7 F-8
+         M-1 M-2 M-3 M-4 M-5 M-6 M-7 M-8
+  )
+)
+; Privileged insn
+(define-attr
+  (for insn)
+  (type boolean)
+  (name PRIVILEGED)
+  (comment "insn only allowed in supervisor mode")
+)
+; Non-Excepting insn
+(define-attr
+  (for insn)
+  (type boolean)
+  (name NON-EXCEPTING)
+  (comment "non-excepting insn")
+)
+; Conditional insn
+(define-attr
+  (for insn)
+  (type boolean)
+  (name CONDITIONAL)
+  (comment "conditional insn")
+)
+; insn accesses FR registers
+(define-attr
+  (for insn)
+  (type boolean)
+  (name FR-ACCESS)
+  (comment "insn accesses FR registers")
+)
+; insn preserves MSR.OVF
+(define-attr
+  (for insn)
+  (type boolean)
+  (name PRESERVE-OVF)
+  (comment "Preserve value of MSR.OVF")
+)
+; null attribute -- used as a place holder for where an attribue it required.
+(define-attr
+  (for insn)
+  (type boolean)
+  (name NA)
+  (comment "placeholder attribute")
+  (attrs META) ; do not define in any generated file for now
+)
+\f
+; 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-pack      "packing bit"                  () 31  1)
+(dnf f-op        "primary opcode"               () 24  7)
+(dnf f-ope1      "extended opcode"              () 11  6)
+(dnf f-ope2      "extended opcode"              ()  9  4)
+(dnf f-ope3      "extended opcode"              () 15  3)
+(dnf f-ope4      "extended opcode"              ()  7  2)
+
+(dnf f-GRi       "source register 1"            () 17  6)
+(dnf f-GRj       "source register 2"            ()  5  6)
+(dnf f-GRk       "destination register"         () 30  6)
+
+(dnf f-FRi       "source register 1"            () 17  6)
+(dnf f-FRj       "source register 2"            ()  5  6)
+(dnf f-FRk       "destination register"         () 30  6)
+
+(dnf f-CPRi      "source register 1"            () 17  6)
+(dnf f-CPRj      "source register 2"            ()  5  6)
+(dnf f-CPRk      "destination register"         () 30  6)
+
+(dnf f-ACCGi     "source register"              () 17  6)
+(dnf f-ACCGk     "destination register"         () 30  6)
+
+(dnf f-ACC40Si   "40 bit signed accumulator"    () 17  6)
+(dnf f-ACC40Ui   "40 bit unsigned accumulator"  () 17  6)
+(dnf f-ACC40Sk   "40 bit accumulator"           () 30  6)
+(dnf f-ACC40Uk   "40 bit accumulator"           () 30  6)
+
+(dnf f-CRi       "source      register"         () 14  3)
+(dnf f-CRj       "source      register"         ()  2  3)
+(dnf f-CRk       "destination register"         () 27  3)
+(dnf f-CCi       "condition   register"         () 11  3)
+
+(df  f-CRj_int   "target cr for ck insns"       () 26  2 UINT
+     ((value pc) (sub WI value 4))
+     ((value pc) (add WI value 4))
+)
+(dnf f-CRj_float "target cr for fck insns"      () 26  2)
+
+(dnf f-ICCi_1    "condition register"           () 11  2)
+(dnf f-ICCi_2    "condition register"           () 26  2)
+(dnf f-ICCi_3    "condition register"           ()  1  2)
+(dnf f-FCCi_1    "condition register"           () 11  2)
+(dnf f-FCCi_2    "condition register"           () 26  2)
+(dnf f-FCCi_3    "condition register"           ()  1  2)
+(dnf f-FCCk      "condition register"           () 26  2)
+(dnf f-eir       "exception insn register"      () 17  6)
+
+(df  f-s10       "10 bit sign extended"         ()  9 10  INT #f #f)
+(df  f-s12       "12 bit sign extended"         () 11 12  INT #f #f)
+(df  f-d12       "12 bit sign extended"         () 11 12  INT #f #f)
+(df  f-u16       "16 bit unsigned"              () 15 16 UINT #f #f)
+(df  f-s16       "16 bit sign extended"         () 15 16  INT #f #f)
+(df  f-s6        "6  bit   signed"              ()  5  6  INT #f #f)
+(df  f-s6_1      "6  bit   signed"              () 11  6  INT #f #f)
+(df  f-u6        "6  bit unsigned"              ()  5  6 UINT #f #f)
+(df  f-s5        "5  bit   signed"              ()  4  5  INT #f #f)
+
+(df  f-u12-h "upper 6 bits of u12"  () 17 6  INT #f #f)
+(df  f-u12-l "lower 6 bits of u12"  ()  5 6 UINT #f #f)
+(dnmf f-u12   "12 bit signed immediate" () INT
+      (f-u12-h f-u12-l)
+      (sequence () ; insert
+               (set (ifield f-u12-h) (sra SI (ifield f-u12) 6))
+               (set (ifield f-u12-l) (and (ifield f-u12) #x3f))
+               )
+      (sequence () ; extract
+               (set (ifield f-u12) (or (sll (ifield f-u12-h) 6)
+                                       (ifield f-u12-l)))
+               )
+)
+
+(dnf f-int-cc    "integer  branch conditions"   () 30  4)
+(dnf f-flt-cc    "floating branch conditions"   () 30  4)
+(df  f-cond      "conditional arithmetic"       ()  8  1 UINT #f #f)
+(df  f-ccond     "lr branch condition"          () 12  1 UINT #f #f)
+(df  f-hint      "2 bit branch prediction hint" () 17  2 UINT #f #f)
+(df  f-LI        "link indicator"               () 25  1 UINT #f #f)
+(df  f-lock      "cache lock indicator"         () 25  1 UINT #f #f)
+(df  f-debug     "debug mode indicator"         () 25  1 UINT #f #f)
+(df  f-A         "all accumulator bit"          () 17  1 UINT #f #f)
+(df  f-ae        "cache all entries indicator"  () 25  1 UINT #f #f)
+
+(dnf  f-spr-h "upper 6 bits of spr"  () 30  6)
+(dnf  f-spr-l "lower 6 bits of spr"  () 17  6)
+(dnmf f-spr   "special purpose register" () UINT
+      (f-spr-h f-spr-l)
+      (sequence () ; insert
+               (set (ifield f-spr-h) (srl (ifield f-spr) (const 6)))
+               (set (ifield f-spr-l) (and (ifield f-spr) (const #x3f)))
+               )
+      (sequence () ; extract
+               (set (ifield f-spr) (or (sll (ifield f-spr-h) (const 6))
+                                       (ifield f-spr-l)))
+               )
+)
+
+(df  f-label16    "18 bit pc relative signed offset" (PCREL-ADDR) 15 16 INT
+     ((value pc) (sra WI (sub WI value pc) (const 2)))
+     ((value pc) (add WI (sll WI value (const 2)) pc))
+)
+
+(df   f-labelH6   "upper 6  bits of label24"  () 30  6 INT #f #f)
+(dnf  f-labelL18  "lower 18 bits of label24"  () 17 18)
+(dnmf f-label24   "26 bit signed offset"     (PCREL-ADDR) INT
+      (f-labelH6 f-labelL18)
+      ; insert
+      (sequence ()
+               (set (ifield f-labelH6)
+                    (sra WI (sub (ifield f-label24) pc) (const 20)))
+               (set (ifield f-labelL18)
+                    (and (srl (sub (ifield f-label24) pc) (const 2))
+                         (const #x3ffff)))
+               )
+      ; extract
+      (sequence ()
+               (set (ifield f-label24)
+                    (add (sll (or (sll (ifield f-labelH6) (const 18))
+                                  (ifield f-labelL18))
+                              (const 2))
+                         pc)))
+)
+
+(dnf f-ICCi_1-null  "null field" (RESERVED) 11  2)
+(dnf f-ICCi_2-null  "null field" (RESERVED) 26  2)
+(dnf f-ICCi_3-null  "null field" (RESERVED)  1  2)
+(dnf f-FCCi_1-null  "null field" (RESERVED) 11  2)
+(dnf f-FCCi_2-null  "null field" (RESERVED) 26  2)
+(dnf f-FCCi_3-null  "null field" (RESERVED)  1  2)
+(dnf f-rs-null      "null field" (RESERVED) 17  6)
+(dnf f-GRi-null     "null field" (RESERVED) 17  6)
+(dnf f-GRj-null     "null field" (RESERVED)  5  6)
+(dnf f-GRk-null     "null field" (RESERVED) 30  6)
+(dnf f-FRi-null     "null field" (RESERVED) 17  6)
+(dnf f-FRj-null     "null field" (RESERVED)  5  6)
+(dnf f-ACCj-null    "null field" (RESERVED)  5  6)
+(dnf f-rd-null      "null field" (RESERVED) 30  6)
+(dnf f-cond-null    "null field" (RESERVED) 30  4)
+(dnf f-ccond-null   "null field" (RESERVED) 12  1)
+(dnf f-s12-null     "null field" (RESERVED) 11 12)
+(dnf f-label16-null "null field" (RESERVED) 15 16)
+(dnf f-misc-null-1  "null field" (RESERVED) 30  5)
+(dnf f-misc-null-2  "null field" (RESERVED) 11  6)
+(dnf f-misc-null-3  "null field" (RESERVED) 11  4)
+(dnf f-misc-null-4  "null field" (RESERVED) 17  2)
+(dnf f-misc-null-5  "null field" (RESERVED) 17 16)
+(dnf f-misc-null-6  "null field" (RESERVED) 30  3)
+(dnf f-misc-null-7  "null field" (RESERVED) 17  3)
+(dnf f-misc-null-8  "null field" (RESERVED)  5  3)
+(dnf f-misc-null-9  "null field" (RESERVED)  5  4)
+(dnf f-misc-null-10 "null field" (RESERVED) 16  5)
+(dnf f-misc-null-11 "null field" (RESERVED)  5  1)
+
+(dnf f-LI-off      "null field" (RESERVED) 25  1)
+(dnf f-LI-on       "null field" (RESERVED) 25  1)
+\f
+; Enums.
+
+; insn-op:
+; FIXME: should use die macro or some such
+(define-normal-insn-enum insn-op "insn op enums" () OP_ f-op
+ (
+ "00" "01" "02" "03" "04" "05" "06" "07" "08" "09" "0A" "0B" "0C" "0D" "0E" "0F"
+ "10" "11" "12" "13" "14" "15" "16" "17" "18" "19" "1A" "1B" "1C" "1D" "1E" "1F"
+ "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" "2A" "2B" "2C" "2D" "2E" "2F"
+ "30" "31" "32" "33" "34" "35" "36" "37" "38" "39" "3A" "3B" "3C" "3D" "3E" "3F"
+ "40" "41" "42" "43" "44" "45" "46" "47" "48" "49" "4A" "4B" "4C" "4D" "4E" "4F"
+ "50" "51" "52" "53" "54" "55" "56" "57" "58" "59" "5A" "5B" "5C" "5D" "5E" "5F"
+ "60" "61" "62" "63" "64" "65" "66" "67" "68" "69" "6A" "6B" "6C" "6D" "6E" "6F"
+ "70" "71" "72" "73" "74" "75" "76" "77" "78" "79" "7A" "7B" "7C" "7D" "7E" "7F"
+ )
+)
+
+(define-normal-insn-enum insn-ope1 "insn ope enums" () OPE1_ f-ope1
+ (
+ "00" "01" "02" "03" "04" "05" "06" "07" "08" "09" "0A" "0B" "0C" "0D" "0E" "0F"
+ "10" "11" "12" "13" "14" "15" "16" "17" "18" "19" "1A" "1B" "1C" "1D" "1E" "1F"
+ "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" "2A" "2B" "2C" "2D" "2E" "2F"
+ "30" "31" "32" "33" "34" "35" "36" "37" "38" "39" "3A" "3B" "3C" "3D" "3E" "3F"
+ )
+)
+
+(define-normal-insn-enum insn-ope2 "insn ope enums" () OPE2_ f-ope2
+ (
+ "00" "01" "02" "03" "04" "05" "06" "07" "08" "09" "0A" "0B" "0C" "0D" "0E" "0F"
+ )
+)
+
+(define-normal-insn-enum insn-ope3 "insn ope enums" () OPE3_ f-ope3
+ (
+ "00" "01" "02" "03" "04" "05" "06" "07"
+ )
+)
+
+(define-normal-insn-enum insn-ope4 "insn ope enums" () OPE4_ f-ope4
+ (
+ "0" "1" "2" "3"
+ )
+)
+
+; int-cc: integer branch conditions
+; FIXME: should use die macro or some such
+(define-normal-insn-enum int-cc "integer branch cond enums" () ICC_ f-int-cc
+  (
+   "nev" "c"  "v"  "lt" "eq" "ls" "n" "le"
+   "ra"  "nc" "nv" "ge" "ne" "hi" "p" "gt"
+  )
+)
+
+; flt-cc: floating-point/media branch conditions
+; FIXME: should use die macro or some such
+(define-normal-insn-enum flt-cc "float branch cond enums" () FCC_ f-flt-cc
+  ("nev" "u" "gt" "ug" "lt" "ul" "lg" "ne"
+   "eq" "ue" "ge" "uge" "le" "ule" "o" "ra")
+)
+\f
+; 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) () () ())
+
+; The PSR. The individual fields are referenced more than the entire
+; register, so reference them directly. We can assemble the
+; entire register contents when necessary.
+;
+(dsh h-psr_imple "PSR.IMPLE"   () (register UQI))
+(dsh h-psr_ver   "PSR.VER"     () (register UQI))
+(dsh h-psr_ice   "PSR.ICE bit" () (register BI))
+(dsh h-psr_nem   "PSR.NEM bit" () (register BI))
+(dsh h-psr_cm    "PSR.CM  bit" () (register BI))
+(dsh h-psr_be    "PSR.BE  bit" () (register BI))
+(dsh h-psr_esr   "PSR.ESR bit" () (register BI))
+(dsh h-psr_ef    "PSR.EF  bit" () (register BI))
+(dsh h-psr_em    "PSR.EM  bit" () (register BI))
+(dsh h-psr_pil   "PSR.PIL    " () (register UQI))
+(dsh h-psr_ps    "PSR.PS  bit" () (register BI))
+(dsh h-psr_et    "PSR.ET  bit" () (register BI))
+
+; PSR.S requires special handling because the shadow registers (SR0-SR4) must
+; be switched with GR4-GR7 when changing from user to supervisor mode or
+; vice-versa.
+(define-hardware
+  (name h-psr_s)
+  (comment "PSR.S bit")
+  (attrs)
+  (type register BI)
+  (get)
+  (set (newval) (c-call VOID "@cpu@_h_psr_s_set_handler" newval))
+)
+
+; The TBR. The individual bits are referenced more than the entire
+; register, so reference them directly. We can assemble the
+; entire register contents when necessary.
+;
+(dsh h-tbr_tba "TBR.TBA" () (register UWI))
+(dsh h-tbr_tt  "TBR.TT"  () (register UQI))
+
+; The BPSR. The individual bits are referenced more than the entire
+; register, so reference them directly. We can assemble the
+; entire register contents when necessary.
+;
+(dsh h-bpsr_bs   "PSR.S   bit" () (register BI))
+(dsh h-bpsr_bet  "PSR.ET  bit" () (register BI))
+
+; General registers
+;
+(define-keyword
+  (name gr-names)
+  (print-name h-gr)
+  (prefix "")
+  (values
+   (sp 1) (fp 2)
+   (gr0   0)(gr1   1)(gr2   2)(gr3   3)(gr4   4)(gr5   5)(gr6   6)(gr7   7)
+   (gr8   8)(gr9   9)(gr10 10)(gr11 11)(gr12 12)(gr13 13)(gr14 14)(gr15 15)
+   (gr16 16)(gr17 17)(gr18 18)(gr19 19)(gr20 20)(gr21 21)(gr22 22)(gr23 23)
+   (gr24 24)(gr25 25)(gr26 26)(gr27 27)(gr28 28)(gr29 29)(gr30 30)(gr31 31)
+   (gr32 32)(gr33 33)(gr34 34)(gr35 35)(gr36 36)(gr37 37)(gr38 38)(gr39 39)
+   (gr40 40)(gr41 41)(gr42 42)(gr43 43)(gr44 44)(gr45 45)(gr46 46)(gr47 47)
+   (gr48 48)(gr49 49)(gr50 50)(gr51 51)(gr52 52)(gr53 53)(gr54 54)(gr55 55)
+   (gr56 56)(gr57 57)(gr58 58)(gr59 59)(gr60 60)(gr61 61)(gr62 62)(gr63 63)
+  )
+)
+
+(define-hardware
+  (name h-gr)
+  (comment "general registers")
+  (attrs PROFILE)
+  (type register USI (64))
+  (indices extern-keyword gr-names)
+  (get (index) (c-call WI "@cpu@_h_gr_get_handler" index))
+  (set (index newval) (c-call VOID "@cpu@_h_gr_set_handler" index newval))
+)
+
+; General Registers as double words
+; These registers are shadowed onto h-gr
+(define-hardware
+  (name h-gr_double)
+  (comment "general registers as double words")
+  (attrs PROFILE VIRTUAL)
+  (type register DI (32))
+  ; FIXME: Need constraint to prohibit odd numbers.
+  (indices extern-keyword gr-names)
+  (get (index)
+       (c-call DI "@cpu@_h_gr_double_get_handler" index))
+  (set (index newval)
+       (c-call VOID "@cpu@_h_gr_double_set_handler" index newval))
+)
+
+; General Registers as high and low half words
+; These registers are shadowed onto h-gr
+(define-hardware
+  (name h-gr_hi)
+  (comment "general registers as high half word")
+  (attrs PROFILE VIRTUAL)
+  (type register UHI (64))
+  (indices extern-keyword gr-names)
+  (get (index) (c-call UHI "@cpu@_h_gr_hi_get_handler" index))
+  (set (index newval) (c-call VOID "@cpu@_h_gr_hi_set_handler" index newval))
+)
+(define-hardware
+  (name h-gr_lo)
+  (comment "general registers as low half word")
+  (attrs PROFILE VIRTUAL)
+  (type register UHI (64))
+  (indices extern-keyword gr-names)
+  (get (index) (c-call UHI "@cpu@_h_gr_lo_get_handler" index))
+  (set (index newval) (c-call VOID "@cpu@_h_gr_lo_set_handler" index newval))
+)
+
+; Floating Point Registers
+(define-keyword
+  (name fr-names)
+  (print-name h-fr)
+  (prefix "")
+  (values
+   (fr0   0)(fr1   1)(fr2   2)(fr3   3)(fr4   4)(fr5   5)(fr6   6)(fr7   7)
+   (fr8   8)(fr9   9)(fr10 10)(fr11 11)(fr12 12)(fr13 13)(fr14 14)(fr15 15)
+   (fr16 16)(fr17 17)(fr18 18)(fr19 19)(fr20 20)(fr21 21)(fr22 22)(fr23 23)
+   (fr24 24)(fr25 25)(fr26 26)(fr27 27)(fr28 28)(fr29 29)(fr30 30)(fr31 31)
+   (fr32 32)(fr33 33)(fr34 34)(fr35 35)(fr36 36)(fr37 37)(fr38 38)(fr39 39)
+   (fr40 40)(fr41 41)(fr42 42)(fr43 43)(fr44 44)(fr45 45)(fr46 46)(fr47 47)
+   (fr48 48)(fr49 49)(fr50 50)(fr51 51)(fr52 52)(fr53 53)(fr54 54)(fr55 55)
+   (fr56 56)(fr57 57)(fr58 58)(fr59 59)(fr60 60)(fr61 61)(fr62 62)(fr63 63)
+  )
+)
+
+(define-hardware
+  (name h-fr)
+  (comment "floating point registers")
+  (attrs PROFILE)
+  (type register SF (64))
+  (indices extern-keyword fr-names)
+  (get (index) (c-call SF "@cpu@_h_fr_get_handler" index))
+  (set (index newval) (c-call VOID "@cpu@_h_fr_set_handler" index newval))
+)
+
+; Floating Point Registers as double precision
+; These registers are shadowed onto h-fr
+
+(define-hardware
+  (name h-fr_double)
+  (comment "floating point registers as double precision")
+  (attrs PROFILE VIRTUAL)
+  (type register DF (32))
+  ; FIXME: Need constraint to prohibit odd numbers.
+  (indices extern-keyword fr-names)
+  (get (index)
+       (c-call DF "@cpu@_h_fr_double_get_handler" index))
+  (set (index newval)
+       (c-call VOID "@cpu@_h_fr_double_set_handler" index newval))
+)
+
+; Floating Point Registers as integer words.
+; These registers are shadowed onto h-fr
+
+(define-hardware
+  (name h-fr_int)
+  (comment "floating point registers as integers")
+  (attrs PROFILE VIRTUAL)
+  (type register USI (64))
+  (indices extern-keyword fr-names)
+  (get (index)
+       (c-call USI "@cpu@_h_fr_int_get_handler" index))
+  (set (index newval)
+       (c-call VOID "@cpu@_h_fr_int_set_handler" index newval))
+)
+
+; Floating Point Registers as high and low half words
+; These registers are shadowed onto h-fr
+(define-hardware
+  (name h-fr_hi)
+  (comment "floating point registers as unsigned high half word")
+  (attrs PROFILE VIRTUAL)
+  (type register UHI (64))
+  (indices extern-keyword fr-names)
+  (get (regno) (srl (reg h-fr_int regno) 16))
+  (set (regno newval) (set (reg h-fr_int regno)
+                          (or (and (reg h-fr_int regno) #xffff)
+                              (sll newval 16))))
+)
+(define-hardware
+  (name h-fr_lo)
+  (comment "floating point registers as unsigned low half word")
+  (attrs PROFILE VIRTUAL)
+  (type register UHI (64))
+  (indices extern-keyword fr-names)
+  (get (regno) (and (reg h-fr_int regno) #xffff))
+  (set (regno newval) (set (reg h-fr_int regno)
+                          (or (and (reg h-fr_int regno) #xffff0000)
+                              (and newval #xffff))))
+)
+
+; Floating Point Registers as unsigned bytes
+; These registers are shadowed onto h-fr
+(define-hardware
+  (name h-fr_0)
+  (comment "floating point registers as unsigned byte 0")
+  (attrs PROFILE VIRTUAL)
+  (type register UHI (64))
+  (indices extern-keyword fr-names)
+  (get (regno) (and (reg h-fr_int regno) #xff))
+  (set (regno newval)
+       (sequence ()
+                (if (gt USI newval #xff)
+                    (set newval #xff))
+                (set (reg h-fr_int regno) (or (and (reg h-fr_int regno) #xffffff00)
+                                          newval))))
+)
+(define-hardware
+  (name h-fr_1)
+  (comment "floating point registers as unsigned byte 1")
+  (attrs PROFILE VIRTUAL)
+  (type register UHI (64))
+  (indices extern-keyword fr-names)
+  (get (regno) (and (srl (reg h-fr_int regno) 8) #xff))
+  (set (regno newval)
+       (sequence ()
+                (if (gt USI newval #xff)
+                    (set newval #xff))
+                (set (reg h-fr_int regno) (or (and (reg h-fr_int regno) #xffff00ff) 
+                                          (sll newval 8)))))
+)
+(define-hardware
+  (name h-fr_2)
+  (comment "floating point registers as unsigned byte 2")
+  (attrs PROFILE VIRTUAL)
+  (type register UHI (64))
+  (indices extern-keyword fr-names)
+  (get (regno) (and (srl (reg h-fr_int regno) 16) #xff))
+  (set (regno newval)
+       (sequence ()
+                (if (gt USI newval #xff)
+                    (set newval #xff))
+                (set (reg h-fr_int regno) (or (and (reg h-fr_int regno) #xff00ffff) 
+                                          (sll newval 16)))))
+)
+(define-hardware
+  (name h-fr_3)
+  (comment "floating point registers as unsigned byte 3")
+  (attrs PROFILE VIRTUAL)
+  (type register UHI (64))
+  (indices extern-keyword fr-names)
+  (get (regno) (and (srl (reg h-fr_int regno) 24) #xff))
+  (set (regno newval)
+       (sequence ()
+                (if (gt USI newval #xff)
+                    (set newval #xff))
+                (set (reg h-fr_int regno) (or (and (reg h-fr_int regno) #x00ffffff) 
+                                          (sll newval 24)))))
+)
+; Coprocessor Registers
+;
+(define-keyword
+  (name cpr-names)
+  (print-name h-cpr)
+  (prefix "")
+  (values
+(cpr0   0)(cpr1   1)(cpr2   2)(cpr3   3)(cpr4   4)(cpr5   5)(cpr6   6)(cpr7   7)
+(cpr8   8)(cpr9   9)(cpr10 10)(cpr11 11)(cpr12 12)(cpr13 13)(cpr14 14)(cpr15 15)
+(cpr16 16)(cpr17 17)(cpr18 18)(cpr19 19)(cpr20 20)(cpr21 21)(cpr22 22)(cpr23 23)
+(cpr24 24)(cpr25 25)(cpr26 26)(cpr27 27)(cpr28 28)(cpr29 29)(cpr30 30)(cpr31 31)
+(cpr32 32)(cpr33 33)(cpr34 34)(cpr35 35)(cpr36 36)(cpr37 37)(cpr38 38)(cpr39 39)
+(cpr40 40)(cpr41 41)(cpr42 42)(cpr43 43)(cpr44 44)(cpr45 45)(cpr46 46)(cpr47 47)
+(cpr48 48)(cpr49 49)(cpr50 50)(cpr51 51)(cpr52 52)(cpr53 53)(cpr54 54)(cpr55 55)
+(cpr56 56)(cpr57 57)(cpr58 58)(cpr59 59)(cpr60 60)(cpr61 61)(cpr62 62)(cpr63 63)
+  )
+)
+
+(define-hardware
+  (name h-cpr)
+  (comment "coprocessor registers")
+  (attrs PROFILE (MACH frv))
+  (type register WI (64))
+  (indices extern-keyword cpr-names)
+)
+
+; Coprocessor Registers as double words
+; These registers are shadowed onto h-cpr
+(define-hardware
+  (name h-cpr_double)
+  (comment "coprocessor registers as double words")
+  (attrs PROFILE VIRTUAL (MACH frv))
+  (type register DI (32))
+  ; FIXME: Need constraint to prohibit odd numbers.
+  (indices extern-keyword cpr-names)
+  (get (index)
+       (c-call DI "@cpu@_h_cpr_double_get_handler" index))
+  (set (index newval)
+       (c-call VOID "@cpu@_h_cpr_double_set_handler" index newval))
+)
+
+; Special Purpose Registers
+;
+(define-keyword
+  (name spr-names)
+  (print-name h-spr)
+  (prefix "")
+  (values
+   (psr        0) (pcsr       1) (bpcsr      2) (tbr        3) (bpsr       4)
+
+   (hsr0      16) (hsr1      17) (hsr2      18) (hsr3      19)
+   (hsr4      20) (hsr5      21) (hsr6      22) (hsr7      23)
+   (hsr8      24) (hsr9      25) (hsr10     26) (hsr11     27)
+   (hsr12     28) (hsr13     29) (hsr14     30) (hsr15     31)
+   (hsr16     32) (hsr17     33) (hsr18     34) (hsr19     35)
+   (hsr20     36) (hsr21     37) (hsr22     38) (hsr23     39)
+   (hsr24     40) (hsr25     41) (hsr26     42) (hsr27     43)
+   (hsr28     44) (hsr29     45) (hsr30     46) (hsr31     47)
+   (hsr32     48) (hsr33     49) (hsr34     50) (hsr35     51)
+   (hsr36     52) (hsr37     53) (hsr38     54) (hsr39     55)
+   (hsr40     56) (hsr41     57) (hsr42     58) (hsr43     59)
+   (hsr44     60) (hsr45     61) (hsr46     62) (hsr47     63)
+   (hsr48     64) (hsr49     65) (hsr50     66) (hsr51     67)
+   (hsr52     68) (hsr53     69) (hsr54     70) (hsr55     71)
+   (hsr56     72) (hsr57     73) (hsr58     74) (hsr59     75)
+   (hsr60     76) (hsr61     77) (hsr62     78) (hsr63     79)
+
+   (ccr      256) (cccr     263) (lr       272) (lcr      273) (isr      288)
+
+   (neear0   352) (neear1   353) (neear2   354) (neear3   355)
+   (neear4   356) (neear5   357) (neear6   358) (neear7   359)
+   (neear8   360) (neear9   361) (neear10  362) (neear11  363)
+   (neear12  364) (neear13  365) (neear14  366) (neear15  367)
+   (neear16  368) (neear17  369) (neear18  370) (neear19  371)
+   (neear20  372) (neear21  373) (neear22  374) (neear23  375)
+   (neear24  376) (neear25  377) (neear26  378) (neear27  379)
+   (neear28  380) (neear29  381) (neear30  382) (neear31  383)
+
+   (nesr0    384) (nesr1    385) (nesr2    386) (nesr3    387)
+   (nesr4    388) (nesr5    389) (nesr6    390) (nesr7    391)
+   (nesr8    392) (nesr9    393) (nesr10   394) (nesr11   395)
+   (nesr12   396) (nesr13   397) (nesr14   398) (nesr15   399)
+   (nesr16   400) (nesr17   401) (nesr18   402) (nesr19   403)
+   (nesr20   404) (nesr21   405) (nesr22   406) (nesr23   407)
+   (nesr24   408) (nesr25   409) (nesr26   410) (nesr27   411)
+   (nesr28   412) (nesr29   413) (nesr30   414) (nesr31   415)
+
+   (necr     416)
+
+   (gner0    432) (gner1    433)
+
+   (fner0    434) (fner1    435)
+
+   (epcr0    512) (epcr1    513) (epcr2    514) (epcr3    515)
+   (epcr4    516) (epcr5    517) (epcr6    518) (epcr7    519)
+   (epcr8    520) (epcr9    521) (epcr10   522) (epcr11   523)
+   (epcr12   524) (epcr13   525) (epcr14   526) (epcr15   527)
+   (epcr16   528) (epcr17   529) (epcr18   530) (epcr19   531)
+   (epcr20   532) (epcr21   533) (epcr22   534) (epcr23   535)
+   (epcr24   536) (epcr25   537) (epcr26   538) (epcr27   539)
+   (epcr28   540) (epcr29   541) (epcr30   542) (epcr31   543)
+   (epcr32   544) (epcr33   545) (epcr34   546) (epcr35   547)
+   (epcr36   548) (epcr37   549) (epcr38   550) (epcr39   551)
+   (epcr40   552) (epcr41   553) (epcr42   554) (epcr43   555)
+   (epcr44   556) (epcr45   557) (epcr46   558) (epcr47   559)
+   (epcr48   560) (epcr49   561) (epcr50   562) (epcr51   563)
+   (epcr52   564) (epcr53   565) (epcr54   566) (epcr55   567)
+   (epcr56   568) (epcr57   569) (epcr58   570) (epcr59   571)
+   (epcr60   572) (epcr61   573) (epcr62   574) (epcr63   575)
+
+   (esr0     576) (esr1     577) (esr2     578) (esr3     579)
+   (esr4     580) (esr5     581) (esr6     582) (esr7     583)
+   (esr8     584) (esr9     585) (esr10    586) (esr11    587)
+   (esr12    588) (esr13    589) (esr14    590) (esr15    591)
+   (esr16    592) (esr17    593) (esr18    594) (esr19    595)
+   (esr20    596) (esr21    597) (esr22    598) (esr23    599)
+   (esr24    600) (esr25    601) (esr26    602) (esr27    603)
+   (esr28    604) (esr29    605) (esr30    606) (esr31    607)
+   (esr32    608) (esr33    609) (esr34    610) (esr35    611)
+   (esr36    612) (esr37    613) (esr38    614) (esr39    615)
+   (esr40    616) (esr41    617) (esr42    618) (esr43    619)
+   (esr44    620) (esr45    621) (esr46    622) (esr47    623)
+   (esr48    624) (esr49    625) (esr50    626) (esr51    627)
+   (esr52    628) (esr53    629) (esr54    630) (esr55    631)
+   (esr56    632) (esr57    633) (esr58    634) (esr59    635)
+   (esr60    636) (esr61    637) (esr62    638) (esr63    639)
+
+   (eir0     640) (eir1     641) (eir2     642) (eir3     643)
+   (eir4     644) (eir5     645) (eir6     646) (eir7     647)
+   (eir8     648) (eir9     649) (eir10    650) (eir11    651)
+   (eir12    652) (eir13    653) (eir14    654) (eir15    655)
+   (eir16    656) (eir17    657) (eir18    658) (eir19    659)
+   (eir20    660) (eir21    661) (eir22    662) (eir23    663)
+   (eir24    664) (eir25    665) (eir26    666) (eir27    667)
+   (eir28    668) (eir29    669) (eir30    670) (eir31    671)
+
+   (esfr0    672) (esfr1    673)
+
+   (sr0      768) (sr1      769) (sr2      770) (sr3      771) 
+
+   (fsr0    1024) (fsr1    1025) (fsr2    1026) (fsr3    1027)
+   (fsr4    1028) (fsr5    1029) (fsr6    1030) (fsr7    1031)
+   (fsr8    1032) (fsr9    1033) (fsr10   1034) (fsr11   1035)
+   (fsr12   1036) (fsr13   1037) (fsr14   1038) (fsr15   1039)
+   (fsr16   1040) (fsr17   1041) (fsr18   1042) (fsr19   1043)
+   (fsr20   1044) (fsr21   1045) (fsr22   1046) (fsr23   1047)
+   (fsr24   1048) (fsr25   1049) (fsr26   1050) (fsr27   1051)
+   (fsr28   1052) (fsr29   1053) (fsr30   1054) (fsr31   1055)
+   (fsr32   1056) (fsr33   1057) (fsr34   1058) (fsr35   1059)
+   (fsr36   1060) (fsr37   1061) (fsr38   1062) (fsr39   1063)
+   (fsr40   1064) (fsr41   1065) (fsr42   1066) (fsr43   1067)
+   (fsr44   1068) (fsr45   1069) (fsr46   1070) (fsr47   1071)
+   (fsr48   1072) (fsr49   1073) (fsr50   1074) (fsr51   1075)
+   (fsr52   1076) (fsr53   1077) (fsr54   1078) (fsr55   1079)
+   (fsr56   1080) (fsr57   1081) (fsr58   1082) (fsr59   1083)
+   (fsr60   1084) (fsr61   1085) (fsr62   1086) (fsr63   1087)
+
+   ; FQ0-FQ31 are 64 bit registers.
+   ; These names allow access to the upper 32 bits of the FQ registers.
+   (fqop0   1088) (fqop1   1090) (fqop2   1092) (fqop3   1094) 
+   (fqop4   1096) (fqop5   1098) (fqop6   1100) (fqop7   1102) 
+   (fqop8   1104) (fqop9   1106) (fqop10  1108) (fqop11  1110) 
+   (fqop12  1112) (fqop13  1114) (fqop14  1116) (fqop15  1118) 
+   (fqop16  1120) (fqop17  1122) (fqop18  1124) (fqop19  1126) 
+   (fqop20  1128) (fqop21  1130) (fqop22  1132) (fqop23  1134) 
+   (fqop24  1136) (fqop25  1138) (fqop26  1140) (fqop27  1142) 
+   (fqop28  1144) (fqop29  1146) (fqop30  1148) (fqop31  1150) 
+   ; These names allow access to the lower 32 bits of the FQ registers.
+   (fqst0   1089) (fqst1   1091) (fqst2   1093) (fqst3   1095) 
+   (fqst4   1097) (fqst5   1099) (fqst6   1101) (fqst7   1103) 
+   (fqst8   1105) (fqst9   1107) (fqst10  1109) (fqst11  1111) 
+   (fqst12  1113) (fqst13  1115) (fqst14  1117) (fqst15  1119) 
+   (fqst16  1121) (fqst17  1123) (fqst18  1125) (fqst19  1127) 
+   (fqst20  1129) (fqst21  1131) (fqst22  1133) (fqst23  1135) 
+   (fqst24  1137) (fqst25  1139) (fqst26  1141) (fqst27  1143) 
+   (fqst28  1145) (fqst29  1147) (fqst30  1149) (fqst31  1151) 
+   ; These also access the lower 32 bits of the FQ registers.
+   ; These are not accessible as spr registers (see LSI appendix - section 13.4)
+;  (fq0     1089) (fq1     1091) (fq2     1093) (fq3     1095) 
+;  (fq4     1097) (fq5     1099) (fq6     1101) (fq7     1103) 
+;  (fq8     1105) (fq9     1107) (fq10    1109) (fq11    1111) 
+;  (fq12    1113) (fq13    1115) (fq14    1117) (fq15    1119) 
+;  (fq16    1121) (fq17    1123) (fq18    1125) (fq19    1127) 
+;  (fq20    1129) (fq21    1131) (fq22    1133) (fq23    1135) 
+;  (fq24    1137) (fq25    1139) (fq26    1141) (fq27    1143) 
+;  (fq28    1145) (fq29    1147) (fq30    1149) (fq31    1151) 
+
+   (mcilr0  1272) (mcilr1  1273)
+
+   (msr0    1280) (msr1    1281) (msr2    1282) (msr3    1283)
+   (msr4    1284) (msr5    1285) (msr6    1286) (msr7    1287)
+   (msr8    1288) (msr9    1289) (msr10   1290) (msr11   1291)
+   (msr12   1292) (msr13   1293) (msr14   1294) (msr15   1295)
+   (msr16   1296) (msr17   1297) (msr18   1298) (msr19   1299)
+   (msr20   1300) (msr21   1301) (msr22   1302) (msr23   1303)
+   (msr24   1304) (msr25   1305) (msr26   1306) (msr27   1307)
+   (msr28   1308) (msr29   1309) (msr30   1310) (msr31   1311)
+   (msr32   1312) (msr33   1313) (msr34   1314) (msr35   1315)
+   (msr36   1316) (msr37   1317) (msr38   1318) (msr39   1319)
+   (msr40   1320) (msr41   1321) (msr42   1322) (msr43   1323)
+   (msr44   1324) (msr45   1325) (msr46   1326) (msr47   1327)
+   (msr48   1328) (msr49   1329) (msr50   1330) (msr51   1331)
+   (msr52   1332) (msr53   1333) (msr54   1334) (msr55   1335)
+   (msr56   1336) (msr57   1337) (msr58   1338) (msr59   1339)
+   (msr60   1340) (msr61   1341) (msr62   1342) (msr63   1343)
+
+   ; MQ0-MQ31 are 64 bit registers.
+   ; These names allow access to the upper 32 bits of the MQ registers.
+   (mqop0   1344) (mqop1   1346) (mqop2   1348) (mqop3   1350) 
+   (mqop4   1352) (mqop5   1354) (mqop6   1356) (mqop7   1358) 
+   (mqop8   1360) (mqop9   1362) (mqop10  1364) (mqop11  1366) 
+   (mqop12  1368) (mqop13  1370) (mqop14  1372) (mqop15  1374) 
+   (mqop16  1376) (mqop17  1378) (mqop18  1380) (mqop19  1382) 
+   (mqop20  1384) (mqop21  1386) (mqop22  1388) (mqop23  1390) 
+   (mqop24  1392) (mqop25  1394) (mqop26  1396) (mqop27  1398) 
+   (mqop28  1400) (mqop29  1402) (mqop30  1404) (mqop31  1406) 
+   ; These names allow access to the lower 32 bits of the MQ registers.
+   (mqst0   1345) (mqst1   1347) (mqst2   1349) (mqst3   1351) 
+   (mqst4   1353) (mqst5   1355) (mqst6   1357) (mqst7   1359) 
+   (mqst8   1361) (mqst9   1363) (mqst10  1365) (mqst11  1367) 
+   (mqst12  1369) (mqst13  1371) (mqst14  1373) (mqst15  1375) 
+   (mqst16  1377) (mqst17  1379) (mqst18  1381) (mqst19  1383) 
+   (mqst20  1385) (mqst21  1387) (mqst22  1389) (mqst23  1391) 
+   (mqst24  1393) (mqst25  1395) (mqst26  1397) (mqst27  1399) 
+   (mqst28  1401) (mqst29  1403) (mqst30  1405) (mqst31  1407) 
+   ; These also access the lower 32 bits of the MQ registers.
+   ; These are not accessible as spr registers (see LSI appendix - section 13.4)
+;  (mq0     1345) (mq1     1347) (mq2     1349) (mq3     1351) 
+;  (mq4     1353) (mq5     1355) (mq6     1357) (mq7     1359) 
+;  (mq8     1361) (mq9     1363) (mq10    1365) (mq11    1367) 
+;  (mq12    1369) (mq13    1371) (mq14    1373) (mq15    1375) 
+;  (mq16    1377) (mq17    1379) (mq18    1381) (mq19    1383) 
+;  (mq20    1385) (mq21    1387) (mq22    1389) (mq23    1391) 
+;  (mq24    1393) (mq25    1395) (mq26    1397) (mq27    1399) 
+;  (mq28    1401) (mq29    1403) (mq30    1405) (mq31    1407) 
+
+   ; These are not accessible as spr registers (see LSI appendix - section 13.4)
+;  (acc0    1408) (acc1    1409) (acc2    1410) (acc3    1411)
+;  (acc4    1412) (acc5    1413) (acc6    1414) (acc7    1415)
+;  (acc8    1416) (acc9    1417) (acc10   1418) (acc11   1419)
+;  (acc12   1420) (acc13   1421) (acc14   1422) (acc15   1423)
+;  (acc16   1424) (acc17   1425) (acc18   1426) (acc19   1427)
+;  (acc20   1428) (acc21   1429) (acc22   1430) (acc23   1431)
+;  (acc24   1432) (acc25   1433) (acc26   1434) (acc27   1435)
+;  (acc28   1436) (acc29   1437) (acc30   1438) (acc31   1439)
+;  (acc32   1440) (acc33   1441) (acc34   1442) (acc35   1443)
+;  (acc36   1444) (acc37   1445) (acc38   1446) (acc39   1447)
+;  (acc40   1448) (acc41   1449) (acc42   1450) (acc43   1451)
+;  (acc44   1452) (acc45   1453) (acc46   1454) (acc47   1455)
+;  (acc48   1456) (acc49   1457) (acc50   1458) (acc51   1459)
+;  (acc52   1460) (acc53   1461) (acc54   1462) (acc55   1463)
+;  (acc56   1464) (acc57   1465) (acc58   1466) (acc59   1467)
+;  (acc60   1468) (acc61   1469) (acc62   1470) (acc63   1471)
+
+;  (accg0   1472) (accg1   1473) (accg2   1474) (accg3   1475)
+;  (accg4   1476) (accg5   1477) (accg6   1478) (accg7   1479)
+;  (accg8   1480) (accg9   1481) (accg10  1482) (accg11  1483)
+;  (accg12  1484) (accg13  1485) (accg14  1486) (accg15  1487)
+;  (accg16  1488) (accg17  1489) (accg18  1490) (accg19  1491)
+;  (accg20  1492) (accg21  1493) (accg22  1494) (accg23  1495)
+;  (accg24  1496) (accg25  1497) (accg26  1498) (accg27  1499)
+;  (accg28  1500) (accg29  1501) (accg30  1502) (accg31  1503)
+;  (accg32  1504) (accg33  1505) (accg34  1506) (accg35  1507)
+;  (accg36  1508) (accg37  1509) (accg38  1510) (accg39  1511)
+;  (accg40  1512) (accg41  1513) (accg42  1514) (accg43  1515)
+;  (accg44  1516) (accg45  1517) (accg46  1518) (accg47  1519)
+;  (accg48  1520) (accg49  1521) (accg50  1522) (accg51  1523)
+;  (accg52  1524) (accg53  1525) (accg54  1526) (accg55  1527)
+;  (accg56  1528) (accg57  1529) (accg58  1530) (accg59  1531)
+;  (accg60  1532) (accg61  1533) (accg62  1534) (accg63  1535)
+
+   (ear0    1536) (ear1    1537) (ear2    1538) (ear3    1539)
+   (ear4    1540) (ear5    1541) (ear6    1542) (ear7    1543)
+   (ear8    1544) (ear9    1545) (ear10   1546) (ear11   1547)
+   (ear12   1548) (ear13   1549) (ear14   1550) (ear15   1551)
+   (ear16   1552) (ear17   1553) (ear18   1554) (ear19   1555)
+   (ear20   1556) (ear21   1557) (ear22   1558) (ear23   1559)
+   (ear24   1560) (ear25   1561) (ear26   1562) (ear27   1563)
+   (ear28   1564) (ear29   1565) (ear30   1566) (ear31   1567)
+   (ear32   1568) (ear33   1569) (ear34   1570) (ear35   1571)
+   (ear36   1572) (ear37   1573) (ear38   1574) (ear39   1575)
+   (ear40   1576) (ear41   1577) (ear42   1578) (ear43   1579)
+   (ear44   1580) (ear45   1581) (ear46   1582) (ear47   1583)
+   (ear48   1584) (ear49   1585) (ear50   1586) (ear51   1587)
+   (ear52   1588) (ear53   1589) (ear54   1590) (ear55   1591)
+   (ear56   1592) (ear57   1593) (ear58   1594) (ear59   1595)
+   (ear60   1596) (ear61   1597) (ear62   1598) (ear63   1599)
+
+   (edr0    1600) (edr1    1601) (edr2    1602) (edr3    1603)
+   (edr4    1604) (edr5    1605) (edr6    1606) (edr7    1607)
+   (edr8    1608) (edr9    1609) (edr10   1610) (edr11   1611)
+   (edr12   1612) (edr13   1613) (edr14   1614) (edr15   1615)
+   (edr16   1616) (edr17   1617) (edr18   1618) (edr19   1619)
+   (edr20   1620) (edr21   1621) (edr22   1622) (edr23   1623)
+   (edr24   1624) (edr25   1625) (edr26   1626) (edr27   1627)
+   (edr28   1628) (edr29   1629) (edr30   1630) (edr31   1631)
+   (edr32   1632) (edr33   1636) (edr34   1634) (edr35   1635)
+   (edr36   1636) (edr37   1637) (edr38   1638) (edr39   1639)
+   (edr40   1640) (edr41   1641) (edr42   1642) (edr43   1643)
+   (edr44   1644) (edr45   1645) (edr46   1646) (edr47   1647)
+   (edr48   1648) (edr49   1649) (edr50   1650) (edr51   1651)
+   (edr52   1652) (edr53   1653) (edr54   1654) (edr55   1655)
+   (edr56   1656) (edr57   1657) (edr58   1658) (edr59   1659)
+   (edr60   1660) (edr61   1661) (edr62   1662) (edr63   1663)
+
+   (iamlr0  1664) (iamlr1  1665) (iamlr2  1666) (iamlr3  1667)
+   (iamlr4  1668) (iamlr5  1669) (iamlr6  1670) (iamlr7  1671)
+   (iamlr8  1672) (iamlr9  1673) (iamlr10 1674) (iamlr11 1675)
+   (iamlr12 1676) (iamlr13 1677) (iamlr14 1678) (iamlr15 1679)
+   (iamlr16 1680) (iamlr17 1681) (iamlr18 1682) (iamlr19 1683)
+   (iamlr20 1684) (iamlr21 1685) (iamlr22 1686) (iamlr23 1687)
+   (iamlr24 1688) (iamlr25 1689) (iamlr26 1690) (iamlr27 1691)
+   (iamlr28 1692) (iamlr29 1693) (iamlr30 1694) (iamlr31 1695)
+   (iamlr32 1696) (iamlr33 1697) (iamlr34 1698) (iamlr35 1699)
+   (iamlr36 1700) (iamlr37 1701) (iamlr38 1702) (iamlr39 1703)
+   (iamlr40 1704) (iamlr41 1705) (iamlr42 1706) (iamlr43 1707)
+   (iamlr44 1708) (iamlr45 1709) (iamlr46 1710) (iamlr47 1711)
+   (iamlr48 1712) (iamlr49 1713) (iamlr50 1714) (iamlr51 1715)
+   (iamlr52 1716) (iamlr53 1717) (iamlr54 1718) (iamlr55 1719)
+   (iamlr56 1720) (iamlr57 1721) (iamlr58 1722) (iamlr59 1723)
+   (iamlr60 1724) (iamlr61 1725) (iamlr62 1726) (iamlr63 1727)
+
+   (iampr0  1728) (iampr1  1729) (iampr2  1730) (iampr3  1731)
+   (iampr4  1732) (iampr5  1733) (iampr6  1734) (iampr7  1735)
+   (iampr8  1736) (iampr9  1737) (iampr10 1738) (iampr11 1739)
+   (iampr12 1740) (iampr13 1741) (iampr14 1742) (iampr15 1743)
+   (iampr16 1744) (iampr17 1745) (iampr18 1746) (iampr19 1747)
+   (iampr20 1748) (iampr21 1749) (iampr22 1750) (iampr23 1751)
+   (iampr24 1752) (iampr25 1753) (iampr26 1754) (iampr27 1755)
+   (iampr28 1756) (iampr29 1757) (iampr30 1758) (iampr31 1759)
+   (iampr32 1760) (iampr33 1761) (iampr34 1762) (iampr35 1763)
+   (iampr36 1764) (iampr37 1765) (iampr38 1766) (iampr39 1767)
+   (iampr40 1768) (iampr41 1769) (iampr42 1770) (iampr43 1771)
+   (iampr44 1772) (iampr45 1773) (iampr46 1774) (iampr47 1775)
+   (iampr48 1776) (iampr49 1777) (iampr50 1778) (iampr51 1779)
+   (iampr52 1780) (iampr53 1781) (iampr54 1782) (iampr55 1783)
+   (iampr56 1784) (iampr57 1785) (iampr58 1786) (iampr59 1787)
+   (iampr60 1788) (iampr61 1789) (iampr62 1790) (iampr63 1791)
+
+   (damlr0  1792) (damlr1  1793) (damlr2  1794) (damlr3  1795)
+   (damlr4  1796) (damlr5  1797) (damlr6  1798) (damlr7  1799)
+   (damlr8  1800) (damlr9  1801) (damlr10 1802) (damlr11 1803)
+   (damlr12 1804) (damlr13 1805) (damlr14 1806) (damlr15 1807)
+   (damlr16 1808) (damlr17 1809) (damlr18 1810) (damlr19 1811)
+   (damlr20 1812) (damlr21 1813) (damlr22 1814) (damlr23 1815)
+   (damlr24 1816) (damlr25 1817) (damlr26 1818) (damlr27 1819)
+   (damlr28 1820) (damlr29 1821) (damlr30 1822) (damlr31 1823)
+   (damlr32 1824) (damlr33 1825) (damlr34 1826) (damlr35 1827)
+   (damlr36 1828) (damlr37 1829) (damlr38 1830) (damlr39 1831)
+   (damlr40 1832) (damlr41 1833) (damlr42 1834) (damlr43 1835)
+   (damlr44 1836) (damlr45 1837) (damlr46 1838) (damlr47 1839)
+   (damlr48 1840) (damlr49 1841) (damlr50 1842) (damlr51 1843)
+   (damlr52 1844) (damlr53 1845) (damlr54 1846) (damlr55 1847)
+   (damlr56 1848) (damlr57 1849) (damlr58 1850) (damlr59 1851)
+   (damlr60 1852) (damlr61 1853) (damlr62 1854) (damlr63 1855)
+
+   (dampr0  1856) (dampr1  1857) (dampr2  1858) (dampr3  1859)
+   (dampr4  1860) (dampr5  1861) (dampr6  1862) (dampr7  1863)
+   (dampr8  1864) (dampr9  1865) (dampr10 1866) (dampr11 1867)
+   (dampr12 1868) (dampr13 1869) (dampr14 1870) (dampr15 1871)
+   (dampr16 1872) (dampr17 1873) (dampr18 1874) (dampr19 1875)
+   (dampr20 1876) (dampr21 1877) (dampr22 1878) (dampr23 1879)
+   (dampr24 1880) (dampr25 1881) (dampr26 1882) (dampr27 1883)
+   (dampr28 1884) (dampr29 1885) (dampr30 1886) (dampr31 1887)
+   (dampr32 1888) (dampr33 1889) (dampr34 1890) (dampr35 1891)
+   (dampr36 1892) (dampr37 1893) (dampr38 1894) (dampr39 1895)
+   (dampr40 1896) (dampr41 1897) (dampr42 1898) (dampr43 1899)
+   (dampr44 1900) (dampr45 1901) (dampr46 1902) (dampr47 1903)
+   (dampr48 1904) (dampr49 1905) (dampr50 1906) (dampr51 1907)
+   (dampr52 1908) (dampr53 1909) (dampr54 1910) (dampr55 1911)
+   (dampr56 1912) (dampr57 1913) (dampr58 1914) (dampr59 1915)
+   (dampr60 1916) (dampr61 1917) (dampr62 1918) (dampr63 1919)
+
+   (amcr    1920) (stbar   1921) (mmcr    1922)
+   (dcr     2048) (brr     2049) (nmar    2050)
+
+   (ibar0   2052) (ibar1   2053) (ibar2   2054) (ibar3   2055)
+   (dbar0   2056) (dbar1   2057) (dbar2   2058) (dbar3   2059)
+
+   (dbdr00  2060) (dbdr01  2061) (dbdr02  2062) (dbdr03  2063)
+   (dbdr10  2064) (dbdr11  2065) (dbdr12  2066) (dbdr13  2067)
+   (dbdr20  2068) (dbdr21  2069) (dbdr22  2070) (dbdr23  2071)
+   (dbdr30  2072) (dbdr31  2073) (dbdr32  2074) (dbdr33  2075)
+
+   (dbmr00  2076) (dbmr01  2077) (dbmr02  2078) (dbmr03  2079)
+   (dbmr10  2080) (dbmr11  2081) (dbmr12  2082) (dbmr13  2083)
+   (dbmr20  2084) (dbmr21  2085) (dbmr22  2086) (dbmr23  2087)
+   (dbmr30  2088) (dbmr31  2089) (dbmr32  2090) (dbmr33  2091)
+
+   (cpcfr   2092) (cpcr    2093) (cpsr    2094)
+
+   (cpesr0  2096) (cpesr1  2097)
+   (cpemr0  2098) (cpemr1  2099)
+
+   (ihsr8   3848)
+  )
+)
+
+(define-hardware
+  (name h-spr)
+  (comment "special purpose registers")
+  (attrs PROFILE)
+  (type register UWI (4096))
+  (indices extern-keyword spr-names)
+  (get (index) (c-call UWI "@cpu@_h_spr_get_handler" index))
+  (set (index newval) (c-call VOID "@cpu@_h_spr_set_handler" index newval))
+)
+
+(define-pmacro (spr-pcsr)  (reg h-spr   1))
+(define-pmacro (spr-bpcsr) (reg h-spr   2))
+(define-pmacro (spr-lr)    (reg h-spr 272))
+(define-pmacro (spr-lcr)   (reg h-spr 273))
+(define-pmacro (spr-sr0)   (reg h-spr 768))
+(define-pmacro (spr-sr1)   (reg h-spr 769))
+(define-pmacro (spr-sr2)   (reg h-spr 770))
+(define-pmacro (spr-sr3)   (reg h-spr 771))
+
+; Accumulator guard. Actually a subset of the SPR registers, but those SPRs
+; are read-only in most insns. This hardware element is used by those insns
+; which have direct access (mwtaccg, mrdaccg).
+(define-keyword
+  (name accg-names)
+  (print-name h-accg)
+  (prefix "")
+  (values
+   (accg0   0)(accg1   1)(accg2   2)(accg3   3)
+   (accg4   4)(accg5   5)(accg6   6)(accg7   7)
+   (accg8   8)(accg9   9)(accg10 10)(accg11 11)
+   (accg12 12)(accg13 13)(accg14 14)(accg15 15)
+   (accg16 16)(accg17 17)(accg18 18)(accg19 19)
+   (accg20 20)(accg21 21)(accg22 22)(accg23 23)
+   (accg24 24)(accg25 25)(accg26 26)(accg27 27)
+   (accg28 28)(accg29 29)(accg30 30)(accg31 31)
+   (accg32 32)(accg33 33)(accg34 34)(accg35 35)
+   (accg36 36)(accg37 37)(accg38 38)(accg39 39)
+   (accg40 40)(accg41 41)(accg42 42)(accg43 43)
+   (accg44 44)(accg45 45)(accg46 46)(accg47 47)
+   (accg48 48)(accg49 49)(accg50 50)(accg51 51)
+   (accg52 52)(accg53 53)(accg54 54)(accg55 55)
+   (accg56 56)(accg57 57)(accg58 58)(accg59 59)
+   (accg60 60)(accg61 61)(accg62 62)(accg63 63)
+  )
+)
+
+(define-hardware
+  (name h-accg)
+  (comment "accumulator guard")
+  (attrs PROFILE VIRTUAL)
+  (type register UWI (64))
+  (indices extern-keyword accg-names)
+  (get (index)
+       (and (reg h-spr (add index 1472)) #xff))
+  (set (index newval)
+       (set (raw-reg UWI h-spr (add index 1472)) (and newval #xff)))
+)
+
+; 40 bit accumulator. Composed of ACCG and ACC registers concatenated, but
+; referenced more often as the composed 40 bits.
+(define-keyword
+  (name acc-names)
+  (print-name h-acc40)
+  (prefix "")
+  (values
+(acc0   0)(acc1   1)(acc2   2)(acc3   3)(acc4   4)(acc5   5)(acc6   6)(acc7   7)
+(acc8   8)(acc9   9)(acc10 10)(acc11 11)(acc12 12)(acc13 13)(acc14 14)(acc15 15)
+(acc16 16)(acc17 17)(acc18 18)(acc19 19)(acc20 20)(acc21 21)(acc22 22)(acc23 23)
+(acc24 24)(acc25 25)(acc26 26)(acc27 27)(acc28 28)(acc29 29)(acc30 30)(acc31 31)
+(acc32 32)(acc33 33)(acc34 34)(acc35 35)(acc36 36)(acc37 37)(acc38 38)(acc39 39)
+(acc40 40)(acc41 41)(acc42 42)(acc43 43)(acc44 44)(acc45 45)(acc46 46)(acc47 47)
+(acc48 48)(acc49 49)(acc50 50)(acc51 51)(acc52 52)(acc53 53)(acc54 54)(acc55 55)
+(acc56 56)(acc57 57)(acc58 58)(acc59 59)(acc60 60)(acc61 61)(acc62 62)(acc63 63)
+  )
+)
+
+(define-hardware
+  (name h-acc40S)
+  (comment "40 bit signed accumulator")
+  (attrs PROFILE VIRTUAL)
+  (type register DI (64))
+  (indices extern-keyword acc-names)
+  ; The accumlator is made up of two 32 bit registers, accgi/acci.
+  ; We want to extract this as a combined 40 signed bits
+  (get (index)
+       (or DI
+          (sll  DI (ext DI (trunc QI (reg h-spr (add index 1472))))
+                32)
+          (zext DI (reg h-spr (add index 1408)))))
+  ; Bits 40-63 are not written. raw-reg is used to bypass read-only restrictions
+  ; on ACC and ACCG registers
+  (set (index newval)
+       (sequence ()
+                (c-call VOID "frv_check_spr_write_access" (add index 1408))
+                (set (raw-reg UWI h-spr
+                              (add index 1472)) (and (srl newval 32) #xff))
+                (set (raw-reg UWI h-spr
+                              (add index 1408)) (trunc USI newval))))
+)
+
+(define-hardware
+  (name h-acc40U)
+  (comment "40 bit unsigned accumulator")
+  (attrs PROFILE VIRTUAL)
+  (type register UDI (64))
+  (indices extern-keyword acc-names)
+  ; The accumlator is made up of two 32 bit registers, accgi/acci.
+  ; We want to extract this as a combined 40 unsigned bits
+  (get (index)
+       (or DI
+          (sll  DI (zext DI (reg h-spr (add index 1472))) 32)
+          (zext DI (reg h-spr (add index 1408)))))
+  ; Bits 40-63 are not written. raw-reg is used to bypass read-only restrictions
+  ; on ACC and ACCG registers
+  (set (index newval)
+       (sequence ()
+                (c-call VOID "frv_check_spr_write_access" (add index 1408))
+                (set (raw-reg UWI h-spr
+                              (add index 1472)) (and (srl newval 32) #xff))
+                (set (raw-reg UWI h-spr
+                              (add index 1408)) (trunc USI newval))))
+)
+
+; Integer condition code registers (CCR)
+;
+; The individual sub registers bits of the CCR are referenced more often than
+; the entire register so set them directly. We can assemble the
+; entire register when necessary.
+;
+(define-keyword
+  (name iccr-names)
+  (print-name h-iccr)
+  (prefix "")
+  (values (icc0 0) (icc1 1) (icc2 2) (icc3 3))
+)
+
+(define-hardware
+  (name h-iccr)
+  (comment "Integer condition code registers")
+  (attrs PROFILE)
+  (type register UQI (4))
+  (indices extern-keyword iccr-names)
+)
+
+; Floating point condition code registers (CCR)
+;
+; The individual sub registers bits of the CCR are referenced more often than
+; the entire register so set them directly. We can assemble the
+; entire register when necessary.
+;
+(define-keyword
+  (name fccr-names)
+  (print-name h-fccr)
+  (prefix "")
+  (values (fcc0 0) (fcc1 1) (fcc2 2) (fcc3 3))
+)
+
+(define-hardware
+  (name h-fccr)
+  (comment "Integer condition code registers")
+  (attrs PROFILE)
+  (type register UQI (4))
+  (indices extern-keyword fccr-names)
+)
+
+; C condition code registers (CCCR)
+;
+(define-keyword
+  (name cccr-names)
+  (print-name h-cccr)
+  (prefix "")
+  (values (cc0 0) (cc1 1) (cc2 2) (cc3 3) (cc4 4) (cc5 5) (cc6 6) (cc7 7))
+)
+
+(define-hardware
+  (name h-cccr)
+  (comment "Condition code registers")
+  (attrs PROFILE)
+  (type register UQI (8))
+  (indices extern-keyword cccr-names)
+)
+\f
+; Dummy hardware used to define packing bit on insns
+;
+(define-hardware
+  (name h-pack)
+  (comment "Packing bit dummy hardware")
+  (type immediate (UINT 1))
+  (values keyword "" (("" 1) (".p" 0) (".P" 0)))
+)
+; Dummy hardware used to define hint field for branches always taken
+;
+(define-hardware
+  (name h-hint-taken)
+  (comment "Branch taken hint dummy hardware")
+  (type immediate (UINT 1))
+  ; The order of these is important. We want '2' to get written by default,
+  ; but we also want the docoder/disassembler to allow the values '0', '1' and
+  ; '3'.
+  (values keyword "" (("" 2) ("" 0) ("" 1) ("" 3)))
+)
+; Dummy hardware used to define hint field for branches never taken
+;
+(define-hardware
+  (name h-hint-not-taken)
+  (comment "Branch not taken hint dummy hardware")
+  (type immediate (UINT 1))
+  ; The order of these is important. We want '0' to get written by default,
+  ; but we also want the docoder/disassembler to allow the values '1', '2' and
+  ; '3'.
+  (values keyword "" (("" 0) ("" 1) ("" 2) ("" 3)))
+)
+\f
+; 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.
+
+; FRV 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.
+
+; dnmop: define-normal-mode-operand: temporary, pending potential removal
+; of modes from h/w.
+(define-pmacro (dnmop xname xcomment xattrs xtype xindex xmode)
+  (define-operand
+    (name xname)
+    (comment xcomment)
+    (.splice attrs (.unsplice xattrs))
+    (type xtype)
+    (index xindex)
+    (mode xmode)
+    )
+)
+
+(dnop  pack "packing bit" () h-pack f-pack)
+
+(dnmop GRi        "source register 1"      () h-gr        f-GRi  SI)
+(dnmop GRj        "source register 2"      () h-gr        f-GRj  SI)
+(dnmop GRk        "destination register"   () h-gr        f-GRk  SI)
+(dnmop GRkhi      "destination register"   () h-gr_hi     f-GRk  UHI)
+(dnmop GRklo      "destination register"   () h-gr_lo     f-GRk  UHI)
+(dnmop GRdoublek  "destination register"   () h-gr_double f-GRk  DI)
+(dnmop ACC40Si    "signed accumulator"     () h-acc40S    f-ACC40Si DI)
+(dnmop ACC40Ui    "unsigned accumulator"   () h-acc40U    f-ACC40Ui UDI)
+(dnmop ACC40Sk    "target accumulator"     () h-acc40S    f-ACC40Sk DI)
+(dnmop ACC40Uk    "target accumulator"     () h-acc40U    f-ACC40Uk UDI)
+(dnmop ACCGi      "source register"        () h-accg      f-ACCGi   UWI)
+(dnmop ACCGk      "target register"        () h-accg      f-ACCGk   UWI)
+
+(dnmop CPRi       "source register"        ((MACH frv)) h-cpr        f-CPRi SI)
+(dnmop CPRj       "source register"        ((MACH frv)) h-cpr        f-CPRj SI)
+(dnmop CPRk       "destination register"   ((MACH frv)) h-cpr        f-CPRk SI)
+(dnmop CPRdoublek "destination register"   ((MACH frv)) h-cpr_double f-CPRk DI)
+
+; floating point operands
+(dnmop FRinti    "source register 1"      () h-fr_int        f-FRi SI)
+(dnmop FRintj    "source register 2"      () h-fr_int        f-FRj SI)
+(dnmop FRintk    "target register"        () h-fr_int        f-FRk SI)
+(dnmop FRi       "source register 1"      () h-fr        f-FRi SF)
+(dnmop FRj       "source register 2"      () h-fr        f-FRj SF)
+(dnmop FRk       "destination register"   () h-fr        f-FRk SF)
+(dnmop FRkhi     "destination register"   () h-fr_hi     f-FRk UHI)
+(dnmop FRklo     "destination register"   () h-fr_lo     f-FRk UHI)
+(dnmop FRdoublei "source register 1"      () h-fr_double f-FRi DF)
+(dnmop FRdoublej "source register 2"      () h-fr_double f-FRj DF)
+(dnmop FRdoublek "target register"        () h-fr_double f-FRk DF)
+
+(dnop CRi       "source register 1"       () h-cccr f-CRi)
+(dnop CRj       "source register 2"       () h-cccr f-CRj)
+(dnop CRj_int   "destination register"    () h-cccr f-CRj_int)
+(dnop CRj_float "destination register"    () h-cccr f-CRj_float)
+(dnop CRk       "destination register"    () h-cccr f-CRk)
+(dnop CCi       "condition   register"    () h-cccr f-CCi)
+
+(dnop ICCi_1  "condition   register"      () h-iccr f-ICCi_1)
+(dnop ICCi_2  "condition   register"      () h-iccr f-ICCi_2)
+(dnop ICCi_3  "condition   register"      () h-iccr f-ICCi_3)
+(dnop FCCi_1  "condition   register"      () h-fccr f-FCCi_1)
+(dnop FCCi_2  "condition   register"      () h-fccr f-FCCi_2)
+(dnop FCCi_3  "condition   register"      () h-fccr f-FCCi_3)
+(dnop FCCk    "condition   register"      () h-fccr f-FCCk)
+
+(dnop eir     "exception insn reg"        () h-uint f-eir)
+(dnop s10     "10 bit signed immediate"   (HASH-PREFIX) h-sint f-s10)
+(dnop u16     "16 bit unsigned immediate" (HASH-PREFIX) h-uint f-u16)
+(dnop s16     "16 bit signed   immediate" (HASH-PREFIX) h-sint f-s16)
+(dnop s6      "6  bit signed   immediate" (HASH-PREFIX) h-sint f-s6)
+(dnop s6_1    "6  bit signed   immediate" (HASH-PREFIX) h-sint f-s6_1)
+(dnop u6      "6  bit unsigned immediate" (HASH-PREFIX) h-uint f-u6)
+(dnop s5      "5  bit signed   immediate" (HASH-PREFIX) h-sint f-s5)
+(dnop cond    "conditional arithmetic"    (HASH-PREFIX) h-uint f-cond)
+(dnop ccond   "lr branch condition"       (HASH-PREFIX) h-uint f-ccond)
+(dnop hint    "2 bit branch predictor"    (HASH-PREFIX) h-uint f-hint)
+(dnop hint_taken "2 bit branch predictor"     () h-hint-taken     f-hint)
+(dnop hint_not_taken "2 bit branch predictor" () h-hint-not-taken f-hint)
+
+(dnop LI      "link indicator"            () h-uint f-LI)
+(dnop lock    "cache lock indicator"      (HASH-PREFIX) h-uint f-lock)
+(dnop debug   "debug mode indicator"      (HASH-PREFIX) h-uint f-debug)
+(dnop A       "all accumulator indicator" (HASH-PREFIX) h-uint f-A)
+(dnop ae      "all entries indicator"     (HASH-PREFIX) h-uint f-ae)
+
+(dnop label16  "18 bit pc relative address" () h-iaddr f-label16)
+(dnop label24  "26 bit pc relative address" () h-iaddr f-label24)
+
+(define-operand
+  (name d12)
+  (comment "12 bit signed immediate")
+  (attrs)
+  (type h-sint)
+  (index f-d12)
+  (handlers (parse "d12"))
+)
+
+(define-operand
+  (name s12)
+  (comment "12 bit signed immediate")
+  (attrs HASH-PREFIX)
+  (type h-sint)
+  (index f-d12)
+  (handlers (parse "s12"))
+)
+
+(define-operand
+  (name u12)
+  (comment "12 bit signed immediate")
+  (attrs HASH-PREFIX)
+  (type h-sint)
+  (index f-u12)
+  (handlers (parse "u12"))
+)
+
+(define-operand 
+  (name spr)
+  (comment "special purpose register")
+  (attrs)
+  (type  h-spr)
+  (index f-spr)
+  (handlers (parse "spr") (print "spr"))
+)
+
+(define-operand
+  (name ulo16)
+  (comment "16 bit unsigned immediate, for #lo()")
+  (attrs)
+  (type h-uint)
+  (index f-u16)
+  (handlers (parse "ulo16") (print "lo"))
+)
+
+(define-operand
+  (name slo16)
+  (comment "16 bit unsigned immediate, for #lo()")
+  (attrs)
+  (type h-sint)
+  (index f-s16)
+  (handlers (parse "uslo16") (print "lo"))
+)
+
+(define-operand
+  (name uhi16)
+  (comment "16 bit unsigned immediate, for #hi()")
+  (attrs)
+  (type h-uint)
+  (index f-u16)
+  (handlers (parse "uhi16") (print "hi"))
+)
+
+; operands representing hardware
+;
+(dnop psr_esr "PSR.ESR bit" (SEM-ONLY) h-psr_esr f-nil)
+(dnop psr_s   "PSR.S   bit" (SEM-ONLY) h-psr_s   f-nil)
+(dnop psr_ps  "PSR.PS  bit" (SEM-ONLY) h-psr_ps  f-nil)
+(dnop psr_et  "PSR.ET  bit" (SEM-ONLY) h-psr_et  f-nil)
+
+(dnop bpsr_bs  "BPSR.BS  bit" (SEM-ONLY) h-bpsr_bs  f-nil)
+(dnop bpsr_bet "BPSR.BET bit" (SEM-ONLY) h-bpsr_bet f-nil)
+
+(dnop tbr_tba "TBR.TBA" (SEM-ONLY) h-tbr_tba f-nil)
+(dnop tbr_tt  "TBR.TT"  (SEM-ONLY) h-tbr_tt  f-nil)
+
+; Null operands
+;
+(define-pmacro (ICCi_1-null)  (f-ICCi_1-null 0))
+(define-pmacro (ICCi_2-null)  (f-ICCi_2-null 0))
+(define-pmacro (ICCi_3-null)  (f-ICCi_3-null 0))
+(define-pmacro (FCCi_1-null)  (f-FCCi_1-null 0))
+(define-pmacro (FCCi_2-null)  (f-FCCi_2-null 0))
+(define-pmacro (FCCi_3-null)  (f-FCCi_3-null 0))
+(define-pmacro (rs-null)      (f-rs-null     0))
+(define-pmacro (GRi-null)     (f-GRi-null    0))
+(define-pmacro (GRj-null)     (f-GRj-null    0))
+(define-pmacro (GRk-null)     (f-GRk-null    0))
+(define-pmacro (FRi-null)     (f-FRi-null    0))
+(define-pmacro (FRj-null)     (f-FRj-null    0))
+(define-pmacro (ACCj-null)    (f-ACCj-null   0))
+(define-pmacro (rd-null)      (f-rd-null     0))
+(define-pmacro (cond-null)    (f-cond-null   0))
+(define-pmacro (ccond-null)   (f-ccond-null  0))
+(define-pmacro (s12-null)     (f-s12-null    0))
+(define-pmacro (label16-null) (f-label16-null 0))
+(define-pmacro (misc-null-1)  (f-misc-null-1 0))
+(define-pmacro (misc-null-2)  (f-misc-null-2 0))
+(define-pmacro (misc-null-3)  (f-misc-null-3 0))
+(define-pmacro (misc-null-4)  (f-misc-null-4 0))
+(define-pmacro (misc-null-5)  (f-misc-null-5 0))
+(define-pmacro (misc-null-6)  (f-misc-null-6 0))
+(define-pmacro (misc-null-7)  (f-misc-null-7 0))
+(define-pmacro (misc-null-8)  (f-misc-null-8 0))
+(define-pmacro (misc-null-9)  (f-misc-null-9 0))
+(define-pmacro (misc-null-10) (f-misc-null-10 0))
+(define-pmacro (misc-null-11) (f-misc-null-11 0))
+
+(define-pmacro (LI-on)       (f-LI-on  1))
+(define-pmacro (LI-off)      (f-LI-off 0))
+\f
+; Instruction definitions.
+;
+; Notes:
+; - dni is short for "define-normal-instruction"
+; - Macros are used to represent each insn format. These should be used as much
+;   as possible unless an insn has exceptional behaviour
+;
+
+; Commonly used Macros
+;
+; Specific registers
+;
+
+; Integer condition code manipulation
+;
+(define-pmacro (set-z-and-n icc x)
+  (if (eq x 0)
+      (set icc (or (and icc #x7) #x4))
+      (if (lt x 0)
+         (set icc (or (and icc #xb) #x8))
+         (set icc (and icc #x3))))
+)
+
+(define-pmacro (set-n icc val)
+  (if (eq val 0)
+      (set icc (and icc #x7))
+      (set icc (or  icc #x8)))
+)
+
+(define-pmacro (set-z icc val)
+  (if (eq val 0)
+      (set icc (and icc #xb))
+      (set icc (or  icc #x4)))
+)
+
+(define-pmacro (set-v icc val)
+  (if (eq val 0)
+      (set icc (and icc #xd))
+      (set icc (or  icc #x2)))
+)
+
+(define-pmacro (set-c icc val)
+  (if (eq val 0)
+      (set icc (and icc #xe))
+      (set icc (or  icc #x1)))
+)
+
+(define-pmacro (nbit icc)
+  (trunc BI (srl (and icc #x8) 3))
+)
+
+(define-pmacro (zbit icc)
+  (trunc BI (srl (and icc #x4) 2))
+)
+
+(define-pmacro (vbit icc)
+  (trunc BI (srl (and icc #x2) 1))
+)
+
+(define-pmacro (cbit icc)
+  (trunc BI (and icc #x1))
+)
+
+(define-pmacro (ebit icc)
+  (trunc BI (srl (and icc #x8) 3))
+)
+
+(define-pmacro (lbit icc)
+  (trunc BI (srl (and icc #x4) 2))
+)
+
+(define-pmacro (gbit icc)
+  (trunc BI (srl (and icc #x2) 1))
+)
+
+(define-pmacro (ubit icc)
+  (trunc BI (and icc #x1))
+)
+
+; FRV specific insn attributes:
+;
+
+; Format: INT, Logic, Shift r-r
+;
+(define-pmacro (int-logic-r-r name operation op ope comment)
+  (dni name
+       (comment)
+       ((UNIT I01) (FR500-MAJOR I-1) (FR400-MAJOR I-1))
+       (.str name "$pack $GRi,$GRj,$GRk")
+       (+ pack GRk op GRi (ICCi_1-null) ope GRj)
+       (set GRk (operation GRi GRj))
+       ((fr400 (unit u-integer))
+       (fr500 (unit u-integer)))
+  )
+)
+
+(int-logic-r-r add  add   OP_00 OPE2_00 "add reg/reg")
+(int-logic-r-r sub  sub   OP_00 OPE2_04 "sub reg/reg")
+(int-logic-r-r and  and   OP_01 OPE2_00 "and reg/reg")
+(int-logic-r-r or   or    OP_01 OPE2_02 "or  reg/reg")
+(int-logic-r-r xor  xor   OP_01 OPE2_04 "xor reg/reg")
+
+(dni not
+     ("not")
+     ((UNIT I01) (FR500-MAJOR I-1) (FR400-MAJOR I-1))
+     ("not$pack $GRj,$GRk")
+     (+ pack GRk OP_01 (rs-null) (ICCi_1-null) OPE2_06 GRj)
+     (set GRk (inv GRj))
+     ((fr400 (unit u-integer))
+      (fr500 (unit u-integer)))
+)
+
+(dni sdiv
+     "signed division"
+     ((UNIT MULT-DIV) (FR500-MAJOR I-1) (FR400-MAJOR I-1))
+     "sdiv$pack $GRi,$GRj,$GRk"
+     (+ pack GRk OP_00 GRi (ICCi_1-null) OPE2_0E GRj)
+     (sequence ()
+              (c-call VOID "@cpu@_signed_integer_divide"
+                      GRi GRj (index-of GRk) 0)
+              (clobber GRk))
+     ((fr400 (unit u-idiv))
+      (fr500 (unit u-idiv)))
+)
+
+(dni nsdiv
+     "non excepting signed division"
+     ((UNIT MULT-DIV) (FR500-MAJOR I-1) NON-EXCEPTING
+      (MACH simple,tomcat,fr500,frv))
+     "nsdiv$pack $GRi,$GRj,$GRk"
+     (+ pack GRk OP_01 GRi (ICCi_1-null) OPE2_0E GRj)
+     (sequence ()
+              (c-call VOID "@cpu@_signed_integer_divide"
+                      GRi GRj (index-of GRk) 1)
+              (clobber GRk))
+     ((fr400 (unit u-idiv))
+      (fr500 (unit u-idiv)))
+)
+
+(dni udiv
+     "unsigned division reg/reg"
+     ((UNIT MULT-DIV) (FR500-MAJOR I-1) (FR400-MAJOR I-1))
+     "udiv$pack $GRi,$GRj,$GRk"
+     (+ pack GRk OP_00 GRi (ICCi_1-null) OPE2_0F GRj)
+     (sequence ()
+              (c-call VOID "@cpu@_unsigned_integer_divide"
+                      GRi GRj (index-of GRk) 0)
+              (clobber GRk))
+     ((fr400 (unit u-idiv))
+      (fr500 (unit u-idiv)))
+)
+
+(dni nudiv
+     "non excepting unsigned division"
+     ((UNIT MULT-DIV) (FR500-MAJOR I-1) NON-EXCEPTING
+      (MACH simple,tomcat,fr500,frv))
+     "nudiv$pack $GRi,$GRj,$GRk"
+     (+ pack GRk OP_01 GRi (ICCi_1-null) OPE2_0F GRj)
+     (sequence ()
+              (c-call VOID "@cpu@_unsigned_integer_divide"
+                      GRi GRj (index-of GRk) 1)
+              (clobber GRk))
+     ((fr400 (unit u-idiv))
+      (fr500 (unit u-idiv)))
+)
+
+; Multiplication
+;
+(define-pmacro (multiply-r-r name signop op ope comment)
+  (dni name
+       (comment)
+       ((UNIT MULT-DIV) (FR500-MAJOR I-1) (FR400-MAJOR I-1))
+       (.str name "$pack $GRi,$GRj,$GRdoublek")
+       (+ pack GRdoublek op GRi (ICCi_1-null) ope GRj) 
+       (set GRdoublek (mul DI (signop DI GRi) (signop DI GRj)))
+       ((fr400 (unit u-imul))
+       (fr500 (unit u-imul)))
+  )
+)
+
+(multiply-r-r smul ext  OP_00 OPE2_08 "signed   multiply reg/reg")
+(multiply-r-r umul zext OP_00 OPE2_0A "unsigned multiply reg/reg")
+
+(define-pmacro (int-shift-r-r name op ope comment)
+  (dni name
+       (comment)
+       ((UNIT I01) (FR500-MAJOR I-1) (FR400-MAJOR I-1))
+       (.str name "$pack $GRi,$GRj,$GRk")
+       (+ pack GRk op GRi (ICCi_1-null) ope GRj)
+       (set GRk (name GRi (and GRj #x1f)))
+       ((fr400 (unit u-integer))
+       (fr500 (unit u-integer)))
+  )
+)
+
+(int-shift-r-r sll OP_01 OPE2_08 "shift left  logical reg/reg")
+(int-shift-r-r srl OP_01 OPE2_0A "shift right logical reg/reg")
+(int-shift-r-r sra OP_01 OPE2_0C "shift right arith   reg/reg")
+
+(define-pmacro (scan-semantics arg1 arg2 targ)
+  (sequence ((WI tmp1) (WI tmp2))
+           (set tmp1 arg1)
+           (set tmp2 (sra arg2 1))
+           (set targ (c-call WI "@cpu@_scan_result" (xor tmp1 tmp2))))
+)
+
+(dni scan
+     "scan"
+     ((UNIT MULT-DIV) (FR500-MAJOR I-1) (FR400-MAJOR I-1))
+     "scan$pack $GRi,$GRj,$GRk"
+     (+ pack GRk OP_0B GRi (ICCi_1-null) OPE2_00 GRj)
+     (scan-semantics GRi GRj GRk)
+     ((fr400 (unit u-integer))
+      (fr500 (unit u-integer)))
+)
+
+; Format: conditional INT, Logic, Shift r-r
+;
+(define-pmacro (conditional-int-logic name operation op ope comment)
+  (dni name
+       (comment)
+       ((UNIT I01) (FR500-MAJOR I-1) (FR400-MAJOR I-1) CONDITIONAL)
+       (.str name "$pack $GRi,$GRj,$GRk,$CCi,$cond")
+       (+ pack GRk op GRi CCi cond ope GRj)
+       (if (eq CCi (or cond 2))
+          (set GRk (operation GRi GRj)))
+       ((fr400 (unit u-integer))
+       (fr500 (unit u-integer)))
+  )
+)
+
+(conditional-int-logic cadd  add  OP_58 OPE4_0 "conditional add")
+(conditional-int-logic csub  sub  OP_58 OPE4_1 "conditional sub")
+(conditional-int-logic cand  and  OP_5A OPE4_0 "conditional and")
+(conditional-int-logic cor   or   OP_5A OPE4_1 "conditional or")
+(conditional-int-logic cxor  xor  OP_5A OPE4_2 "conditional xor")
+
+(dni cnot
+     "conditional not"
+     ((UNIT I01) (FR500-MAJOR I-1) (FR400-MAJOR I-1) CONDITIONAL)
+     "cnot$pack $GRj,$GRk,$CCi,$cond"
+     (+ pack GRk OP_5A (rs-null) CCi cond OPE4_3 GRj)
+     (if (eq CCi (or cond 2))
+        (set GRk (inv GRj)))
+     ((fr400 (unit u-integer))
+      (fr500 (unit u-integer)))
+)
+
+(dni csmul
+     "conditional signed multiply"
+     ((UNIT MULT-DIV) (FR500-MAJOR I-1) (FR400-MAJOR I-1) CONDITIONAL)
+     "csmul$pack $GRi,$GRj,$GRdoublek,$CCi,$cond"
+     (+ pack GRdoublek OP_58 GRi CCi cond OPE4_2 GRj)
+     (if (eq CCi (or cond 2))
+        (set GRdoublek (mul DI (ext DI GRi) (ext DI GRj))))
+     ((fr400 (unit u-imul))
+      (fr500 (unit u-imul)))
+)
+
+(dni csdiv
+     "conditional signed division"
+     ((UNIT MULT-DIV) (FR500-MAJOR I-1) (FR400-MAJOR I-1) CONDITIONAL)
+     "csdiv$pack $GRi,$GRj,$GRk,$CCi,$cond"
+     (+ pack GRk OP_58 GRi CCi cond OPE4_3 GRj)
+     (if (eq CCi (or cond 2))
+        (sequence ()
+                  (c-call VOID "@cpu@_signed_integer_divide"
+                          GRi GRj (index-of GRk) 0)
+                  (clobber GRk)))
+     ((fr400 (unit u-idiv))
+      (fr500 (unit u-idiv)))
+)
+
+(dni cudiv
+     "conditional unsigned division"
+     ((UNIT MULT-DIV) (FR500-MAJOR I-1) (FR400-MAJOR I-1) CONDITIONAL)
+     "cudiv$pack $GRi,$GRj,$GRk,$CCi,$cond"
+     (+ pack GRk OP_59 GRi CCi cond OPE4_3 GRj)
+     (if (eq CCi (or cond 2))
+        (sequence ()
+                  (c-call VOID "@cpu@_unsigned_integer_divide"
+                          GRi GRj (index-of GRk) 0)
+                  (clobber GRk)))
+     ((fr400 (unit u-idiv))
+      (fr500 (unit u-idiv)))
+)
+
+(define-pmacro (conditional-shift name operation op ope comment)
+  (dni name
+       (comment)
+       ((UNIT I01) (FR500-MAJOR I-1) (FR400-MAJOR I-1) CONDITIONAL)
+       (.str name "$pack $GRi,$GRj,$GRk,$CCi,$cond")
+       (+ pack GRk op GRi CCi cond ope GRj)
+       (if (eq CCi (or cond 2))
+          (set GRk (operation GRi (and GRj #x1f))))
+       ((fr400 (unit u-integer))
+       (fr500 (unit u-integer)))
+  )
+)
+
+(conditional-shift csll sll OP_5C OPE4_0 "conditional shift left  logical")
+(conditional-shift csrl srl OP_5C OPE4_1 "conditional shift right logical")
+(conditional-shift csra sra OP_5C OPE4_2 "conditional shift right arith")
+
+(dni cscan
+     "conditional scan"
+     ((UNIT MULT-DIV) (FR500-MAJOR I-1) (FR400-MAJOR I-1) CONDITIONAL)
+     "cscan$pack $GRi,$GRj,$GRk,$CCi,$cond"
+     (+ pack GRk OP_65 GRi CCi cond OPE4_3 GRj)
+     (if (eq CCi (or cond 2))
+        (scan-semantics GRi GRj GRk))
+     ((fr400 (unit u-integer))
+      (fr500 (unit u-integer)))
+)
+
+; Format: INT, Logic, Shift, cc r-r
+;
+(define-pmacro (int-arith-cc-semantics operation icc)
+  (sequence ((BI tmp) (QI cc) (SI result))
+           (set cc icc)
+           (set tmp ((.sym operation -oflag) GRi GRj (const 0)))
+           (set-v cc tmp)
+           (set tmp ((.sym operation -cflag) GRi GRj (const 0)))
+           (set-c cc tmp)
+           (set result (operation GRi GRj))
+           (set-z-and-n cc result)
+           (set GRk result)
+           (set icc cc))
+)
+
+(define-pmacro (int-arith-cc-r-r name operation op ope comment)
+  (dni name
+       (comment)
+       ((UNIT I01) (FR500-MAJOR I-1) (FR400-MAJOR I-1))
+       (.str name "$pack $GRi,$GRj,$GRk,$ICCi_1")
+       (+ pack GRk op GRi ICCi_1 ope GRj)
+       (int-arith-cc-semantics operation ICCi_1)
+       ((fr400 (unit u-integer))
+       (fr500 (unit u-integer)))
+  )
+)
+
+(int-arith-cc-r-r addcc add OP_00 OPE2_01 "add reg/reg, set icc")
+(int-arith-cc-r-r subcc sub OP_00 OPE2_05 "sub reg/reg, set icc")
+
+(define-pmacro (int-logic-cc-semantics op icc)
+  (sequence ((SI tmp))
+           (set tmp (op GRi GRj))
+           (set GRk tmp)
+           (set-z-and-n icc tmp))
+)
+
+(define-pmacro (int-logic-cc-r-r name op ope comment)
+  (dni (.sym name cc)
+       (comment)
+       ((UNIT I01) (FR500-MAJOR I-1) (FR400-MAJOR I-1))
+       (.str (.sym name cc) "$pack $GRi,$GRj,$GRk,$ICCi_1")
+       (+ pack GRk op GRi ICCi_1 ope GRj)
+       (int-logic-cc-semantics name ICCi_1)
+       ((fr400 (unit u-integer))
+       (fr500 (unit u-integer)))
+  )
+)
+
+(int-logic-cc-r-r and OP_01 OPE2_01 "and reg/reg, set icc")
+(int-logic-cc-r-r or  OP_01 OPE2_03 "or  reg/reg, set icc")
+(int-logic-cc-r-r xor OP_01 OPE2_05 "xor reg/reg, set icc")
+
+(define-pmacro (int-shift-cc-semantics op l-r icc)
+  (sequence ((WI shift) (SI tmp) (QI cc))
+           (set shift (and GRj #x1f))
+           (set cc (c-call QI (.str "@cpu@_set_icc_for_shift_" l-r)
+                           GRi shift icc))
+           (set tmp (op GRi shift))
+           (set GRk tmp)
+           (set-z-and-n cc tmp)
+           (set icc cc))
+)
+
+(define-pmacro (int-shift-cc-r-r name l-r op ope comment)
+  (dni (.sym name cc)
+       (comment)
+       ((UNIT I01) (FR500-MAJOR I-1) (FR400-MAJOR I-1))
+       (.str (.sym name cc) "$pack $GRi,$GRj,$GRk,$ICCi_1")
+       (+ pack GRk op GRi ICCi_1 ope GRj)
+       (int-shift-cc-semantics name l-r ICCi_1)
+       ((fr400 (unit u-integer))
+       (fr500 (unit u-integer)))
+  )
+)
+
+(int-shift-cc-r-r sll left  OP_01 OPE2_09 "shift left  logical reg/reg,set icc")
+(int-shift-cc-r-r srl right OP_01 OPE2_0B "shift right logical reg/reg,set icc")
+(int-shift-cc-r-r sra right OP_01 OPE2_0D "shift right arith   reg/reg,set icc")
+
+(define-pmacro (multiply-cc-semantics signop arg1 arg2 targ icc)
+  (sequence ((DI tmp) (QI cc))
+           (set cc icc)
+           (set tmp (mul DI (signop DI arg1) (signop DI arg2)))
+           (set-n cc (srl DI tmp 63))
+           (set-z cc (eq tmp 0))
+           (set targ tmp)
+           (set icc cc))
+)
+
+(define-pmacro (multiply-cc-r-r name signop op ope comment)
+  (dni name
+       (comment)
+       ((UNIT MULT-DIV) (FR500-MAJOR I-1) (FR400-MAJOR I-1))
+       (.str name "$pack $GRi,$GRj,$GRdoublek,$ICCi_1")
+       (+ pack GRdoublek op GRi ICCi_1 ope GRj)
+       (multiply-cc-semantics signop GRi GRj GRdoublek ICCi_1)
+       ((fr400 (unit u-imul))
+       (fr500 (unit u-imul)))
+  )
+)
+
+(multiply-cc-r-r smulcc ext  OP_00 OPE2_09 "signed   multiply reg/reg")
+(multiply-cc-r-r umulcc zext OP_00 OPE2_0B "unsigned multiply reg/reg")
+
+
+; Format: conditional INT, Logic, Shift, cc r-r
+;
+(define-pmacro (conditional-int-arith-cc name operation op ope comment)
+  (dni name
+       (comment)
+       ((UNIT I01) (FR500-MAJOR I-1) (FR400-MAJOR I-1) CONDITIONAL)
+       (.str name "$pack $GRi,$GRj,$GRk,$CCi,$cond")
+       (+ pack GRk op GRi CCi cond ope GRj)
+       (if (eq CCi (or cond 2))
+          (int-arith-cc-semantics operation
+                                  (reg h-iccr (and (index-of CCi) 3))))
+       ((fr400 (unit u-integer))
+       (fr500 (unit u-integer)))
+  )
+)
+
+(conditional-int-arith-cc caddcc add OP_59 OPE4_0 "add, set icc")
+(conditional-int-arith-cc csubcc sub OP_59 OPE4_1 "sub, set icc")
+
+(dni csmulcc
+     "conditional signed multiply and set condition code"
+     ((UNIT MULT-DIV) (FR500-MAJOR I-1) (FR400-MAJOR I-1) CONDITIONAL)
+     "csmulcc$pack $GRi,$GRj,$GRdoublek,$CCi,$cond"
+     (+ pack GRdoublek OP_59 GRi CCi cond OPE4_2 GRj)
+     (if (eq CCi (or cond 2))
+        (multiply-cc-semantics ext GRi GRj GRdoublek
+                               (reg h-iccr (and (index-of CCi) 3))))
+     ((fr400 (unit u-imul))
+      (fr500 (unit u-imul)))
+)
+
+(define-pmacro (conditional-int-logic-cc name operation op ope comment)
+  (dni name
+       (comment)
+       ((UNIT I01) (FR500-MAJOR I-1) (FR400-MAJOR I-1) CONDITIONAL)
+       (.str name "$pack $GRi,$GRj,$GRk,$CCi,$cond")
+       (+ pack GRk op GRi CCi cond ope GRj)
+       (if (eq CCi (or cond 2))
+          (int-logic-cc-semantics operation
+                                  (reg h-iccr (and (index-of CCi) 3))))
+       ((fr400 (unit u-integer))
+       (fr500 (unit u-integer)))
+  )
+)
+
+(conditional-int-logic-cc candcc and OP_5B OPE4_0 "conditional and, set icc")
+(conditional-int-logic-cc corcc  or  OP_5B OPE4_1 "conditional or , set icc")
+(conditional-int-logic-cc cxorcc xor OP_5B OPE4_2 "conditional xor, set icc")
+
+(define-pmacro (conditional-int-shift-cc name l-r op ope comment)
+  (dni (.sym c name cc)
+       (comment)
+       ((UNIT I01) (FR500-MAJOR I-1) (FR400-MAJOR I-1) CONDITIONAL)
+       (.str (.sym c name cc) "$pack $GRi,$GRj,$GRk,$CCi,$cond")
+       (+ pack GRk op GRi CCi cond ope GRj)
+       (if (eq CCi (or cond 2))
+          (int-shift-cc-semantics name l-r
+                                  (reg h-iccr (and (index-of CCi) 3))))
+       ((fr400 (unit u-integer))
+       (fr500 (unit u-integer)))
+  )
+)
+
+(conditional-int-shift-cc sll left  OP_5D OPE4_0 "shift left  logical, set icc")
+(conditional-int-shift-cc srl right OP_5D OPE4_1 "shift right logical, set icc")
+(conditional-int-shift-cc sra right OP_5D OPE4_2 "shift right arith  , set icc")
+
+; Add and subtract with carry
+;
+(define-pmacro (int-arith-x-r-r name operation op ope comment)
+  (dni name
+       (comment)
+       ((UNIT I01) (FR500-MAJOR I-1) (FR400-MAJOR I-1))
+       (.str name "$pack $GRi,$GRj,$GRk,$ICCi_1")
+       (+ pack GRk op GRi ICCi_1 ope GRj)
+       (set GRk ((.sym operation c) GRi GRj (cbit ICCi_1)))
+       ((fr400 (unit u-integer))
+       (fr500 (unit u-integer)))
+  )
+)
+
+(int-arith-x-r-r addx add OP_00 OPE2_02 "Add reg/reg, with carry")
+(int-arith-x-r-r subx sub OP_00 OPE2_06 "Sub reg/reg, with carry")
+
+(define-pmacro (int-arith-x-cc-r-r name operation op ope comment)
+  (dni name
+       (comment)
+       ((UNIT I01) (FR500-MAJOR I-1) (FR400-MAJOR I-1))
+       (.str name "$pack $GRi,$GRj,$GRk,$ICCi_1")
+       (+ pack GRk op GRi ICCi_1 ope GRj)
+       (sequence ((WI tmp) (QI cc))
+                (set cc ICCi_1)
+                (set tmp ((.sym operation c) GRi GRj (cbit cc)))
+                (set-v cc ((.sym operation -oflag) GRi GRj (cbit cc)))
+                (set-c cc ((.sym operation -cflag) GRi GRj (cbit cc)))
+                (set-z-and-n cc tmp)
+                (set GRk tmp)
+                (set ICCi_1 cc))
+       ((fr400 (unit u-integer))
+       (fr500 (unit u-integer)))
+  )
+)
+
+(int-arith-x-cc-r-r addxcc add OP_00 OPE2_03 "Add reg/reg, use/set carry")
+(int-arith-x-cc-r-r subxcc sub OP_00 OPE2_07 "Sub reg/reg, use/set carry")
+
+; Format: INT, Logic, Shift r-simm
+;
+(define-pmacro (int-logic-r-simm name operation op comment)
+  (dni name
+       (comment)
+       ((UNIT I01) (FR500-MAJOR I-1) (FR400-MAJOR I-1))
+       (.str name "$pack $GRi,$s12,$GRk")
+       (+ pack GRk op GRi s12)
+       (set GRk (operation GRi s12))
+       ((fr400 (unit u-integer))
+       (fr500 (unit u-integer)))
+  )
+)
+
+(int-logic-r-simm addi  add   OP_10 "add reg/immed")
+(int-logic-r-simm subi  sub   OP_14 "sub reg/immed")
+(int-logic-r-simm andi  and   OP_20 "and reg/immed")
+(int-logic-r-simm ori   or    OP_22 "or  reg/immed")
+(int-logic-r-simm xori  xor   OP_24 "xor reg/immed")
+
+(dni sdivi
+     "signed division reg/immed"
+     ((UNIT MULT-DIV) (FR500-MAJOR I-1) (FR400-MAJOR I-1))
+     "sdivi$pack $GRi,$s12,$GRk"
+     (+ pack GRk OP_1E GRi s12)
+     (sequence ()
+              (c-call VOID "@cpu@_signed_integer_divide"
+                      GRi s12 (index-of GRk) 0)
+              (clobber GRk))
+     ((fr400 (unit u-idiv))
+      (fr500 (unit u-idiv)))
+)
+
+(dni nsdivi
+     "non excepting signed division reg/immed"
+     ((UNIT MULT-DIV) (FR500-MAJOR I-1) NON-EXCEPTING
+      (MACH simple,tomcat,fr500,frv))
+     "nsdivi$pack $GRi,$s12,$GRk"
+     (+ pack GRk OP_2E GRi s12)
+     (sequence ()
+              (c-call VOID "@cpu@_signed_integer_divide"
+                      GRi s12 (index-of GRk) 1)
+              (clobber GRk))
+     ((fr400 (unit u-idiv))
+      (fr500 (unit u-idiv)))
+)
+
+(dni udivi
+     "unsigned division reg/immed"
+     ((UNIT MULT-DIV) (FR500-MAJOR I-1) (FR400-MAJOR I-1))
+     "udivi$pack $GRi,$s12,$GRk"
+     (+ pack GRk OP_1F GRi s12)
+     (sequence ()
+              (c-call VOID "@cpu@_unsigned_integer_divide"
+                      GRi s12 (index-of GRk) 0)
+              (clobber GRk))
+     ((fr400 (unit u-idiv))
+      (fr500 (unit u-idiv)))
+)
+
+(dni nudivi
+     "non excepting unsigned division reg/immed"
+     ((UNIT MULT-DIV) (FR500-MAJOR I-1) NON-EXCEPTING
+      (MACH simple,tomcat,fr500,frv))
+     "nudivi$pack $GRi,$s12,$GRk"
+     (+ pack GRk OP_2F GRi s12)
+     (sequence ()
+              (c-call VOID "@cpu@_unsigned_integer_divide"
+                      GRi s12 (index-of GRk) 1)
+              (clobber GRk))
+     ((fr400 (unit u-idiv))
+      (fr500 (unit u-idiv)))
+)
+
+(define-pmacro (multiply-r-simm name signop op comment)
+  (dni name
+       (comment)
+       ((UNIT MULT-DIV) (FR500-MAJOR I-1) (FR400-MAJOR I-1))
+       (.str name "$pack $GRi,$s12,$GRdoublek")
+       (+ pack GRdoublek op GRi s12)
+       (set GRdoublek (mul DI (signop DI GRi) (signop DI s12)))
+       ((fr400 (unit u-imul))
+       (fr500 (unit u-imul)))
+  )
+)
+
+(multiply-r-simm smuli ext  OP_18 "signed   multiply reg/immed")
+(multiply-r-simm umuli zext OP_1A "unsigned multiply reg/immed")
+
+(define-pmacro (int-shift-r-simm name op comment)
+  (dni (.sym name i)
+       (comment)
+       ((UNIT I01) (FR500-MAJOR I-1) (FR400-MAJOR I-1))
+       (.str (.sym name i) "$pack $GRi,$s12,$GRk")
+       (+ pack GRk op GRi s12)
+       (set GRk (name GRi (and s12 #x1f)))
+       ((fr400 (unit u-integer))
+       (fr500 (unit u-integer)))
+  )
+)
+
+(int-shift-r-simm sll OP_28 "shift left  logical reg/immed")
+(int-shift-r-simm srl OP_2A "shift right logical reg/immed")
+(int-shift-r-simm sra OP_2C "shift right arith   reg/immed")
+
+(dni scani
+     "scan immediate"
+     ((UNIT MULT-DIV) (FR500-MAJOR I-1) (FR400-MAJOR I-1))
+     "scani$pack $GRi,$s12,$GRk"
+     (+ pack GRk OP_47 GRi s12)
+     (scan-semantics GRi s12 GRk)
+     ((fr400 (unit u-integer))
+      (fr500 (unit u-integer)))
+)
+
+; Format: INT, Logic, Shift cc r-simm
+;
+(define-pmacro (int-arith-cc-r-simm name operation op comment)
+  (dni name
+       (comment)
+       ((UNIT I01) (FR500-MAJOR I-1) (FR400-MAJOR I-1))
+       (.str name "$pack $GRi,$s10,$GRk,$ICCi_1")
+       (+ pack GRk op GRi ICCi_1 s10)
+       (sequence ((BI tmp) (QI cc) (SI result))
+                (set cc ICCi_1)
+                (set tmp ((.sym operation -oflag) GRi s10 (const 0)))
+                (set-v cc tmp)
+                (set tmp ((.sym operation -cflag) GRi s10 (const 0)))
+                (set-c cc tmp)
+                (set result (operation GRi s10))
+                (set-z-and-n cc result)
+                (set GRk result)
+                (set ICCi_1 cc))
+       ((fr400 (unit u-integer))
+       (fr500 (unit u-integer)))
+  )
+)
+
+(int-arith-cc-r-simm addicc add OP_11 "add reg/immed, set icc")
+(int-arith-cc-r-simm subicc sub OP_15 "sub reg/immed, set icc")
+
+(define-pmacro (int-logic-cc-r-simm name op comment)
+  (dni (.sym name icc)
+       (comment)
+       ((UNIT I01) (FR500-MAJOR I-1) (FR400-MAJOR I-1))
+       (.str (.sym name icc) "$pack $GRi,$s10,$GRk,$ICCi_1")
+       (+ pack GRk op GRi ICCi_1 s10)
+       (sequence ((SI tmp))
+                (set tmp (name GRi s10))
+                (set GRk tmp)
+                (set-z-and-n ICCi_1 tmp))
+       ((fr400 (unit u-integer))
+       (fr500 (unit u-integer)))
+  )
+)
+
+(int-logic-cc-r-simm and  OP_21 "and reg/immed, set icc")
+(int-logic-cc-r-simm or   OP_23 "or  reg/immed, set icc")
+(int-logic-cc-r-simm xor  OP_25 "xor reg/immed, set icc")
+
+(define-pmacro (multiply-cc-r-simm name signop op comment)
+  (dni name
+       (comment)
+       ((UNIT MULT-DIV) (FR500-MAJOR I-1) (FR400-MAJOR I-1))
+       (.str name "$pack $GRi,$s10,$GRdoublek,$ICCi_1")
+       (+ pack GRdoublek op GRi ICCi_1 s10)
+       (multiply-cc-semantics signop GRi s10 GRdoublek ICCi_1)
+       ((fr400 (unit u-imul))
+       (fr500 (unit u-imul)))
+  )
+)
+
+(multiply-cc-r-simm smulicc ext  OP_19 "signed   multiply reg/immed")
+(multiply-cc-r-simm umulicc zext OP_1B "unsigned multiply reg/immed")
+
+(define-pmacro (int-shift-cc-r-simm name l-r op comment)
+  (dni (.sym name icc)
+       (comment)
+       ((UNIT I01) (FR500-MAJOR I-1) (FR400-MAJOR I-1))
+       (.str (.sym name icc) "$pack $GRi,$s10,$GRk,$ICCi_1")
+       (+ pack GRk op GRi ICCi_1 s10)
+       (sequence ((WI shift) (SI tmp) (QI cc))
+                (set shift (and s10 #x1f))
+                (set cc (c-call QI (.str "@cpu@_set_icc_for_shift_" l-r)
+                                GRi shift ICCi_1))
+                (set tmp (name GRi shift))
+                (set GRk tmp)
+                (set-z-and-n cc tmp)
+                (set ICCi_1 cc))
+       ((fr400 (unit u-integer))
+       (fr500 (unit u-integer)))
+  )
+)
+
+(int-shift-cc-r-simm sll left  OP_29 "shift left  logical reg/immed, set icc")
+(int-shift-cc-r-simm srl right OP_2B "shift right logical reg/immed, set icc")
+(int-shift-cc-r-simm sra right OP_2D "shift right arith   reg/immed, set icc")
+
+(define-pmacro (int-arith-x-r-simm name operation op comment)
+  (dni name
+       (comment)
+       ((UNIT I01) (FR500-MAJOR I-1) (FR400-MAJOR I-1))
+       (.str name "$pack $GRi,$s10,$GRk,$ICCi_1")
+       (+ pack GRk op GRi ICCi_1 s10)
+       (set GRk ((.sym operation c) GRi s10 (cbit ICCi_1)))
+       ((fr400 (unit u-integer))
+       (fr500 (unit u-integer)))
+  )
+)
+
+(int-arith-x-r-simm addxi add OP_12 "Add reg/immed, with carry")
+(int-arith-x-r-simm subxi sub OP_16 "Sub reg/immed, with carry")
+
+(define-pmacro (int-arith-x-cc-r-simm name operation op comment)
+  (dni name
+       (comment)
+       ((UNIT I01) (FR500-MAJOR I-1) (FR400-MAJOR I-1))
+       (.str name "$pack $GRi,$s10,$GRk,$ICCi_1")
+       (+ pack GRk op GRi ICCi_1 s10)
+       (sequence ((WI tmp) (QI cc))
+                (set cc ICCi_1)
+                (set tmp ((.sym operation c) GRi s10 (cbit cc)))
+                (set-v cc ((.sym operation -oflag) GRi s10 (cbit cc)))
+                (set-c cc ((.sym operation -cflag) GRi s10 (cbit cc)))
+                (set-z-and-n cc tmp)
+                (set GRk tmp)
+                (set ICCi_1 cc))
+       ((fr400 (unit u-integer))
+       (fr500 (unit u-integer)))
+  )
+)
+
+(int-arith-x-cc-r-simm addxicc add OP_13 "Add reg/immed, with carry")
+(int-arith-x-cc-r-simm subxicc sub OP_17 "Sub reg/immed, with carry")
+
+; Byte compare insns
+
+(dni cmpb
+     "Compare bytes"
+     ((UNIT I01) (FR400-MAJOR I-1) (MACH fr400))
+     "cmpb$pack $GRi,$GRj,$ICCi_1"
+     (+ pack (GRk-null) OP_00 GRi ICCi_1 OPE2_0C GRj)
+     (sequence ((QI cc))
+              (set-n cc (eq (and GRi #xff000000) (and GRj #xff000000)))
+              (set-z cc (eq (and GRi #x00ff0000) (and GRj #x00ff0000)))
+              (set-v cc (eq (and GRi #x0000ff00) (and GRj #x0000ff00)))
+              (set-c cc (eq (and GRi #x000000ff) (and GRj #x000000ff)))
+              (set ICCi_1 cc))
+     ((fr400 (unit u-integer)))
+)
+
+(dni cmpba
+     "OR of Compare bytes"
+     ((UNIT I01) (FR400-MAJOR I-1) (MACH fr400))
+     "cmpba$pack $GRi,$GRj,$ICCi_1"
+     (+ pack (GRk-null) OP_00 GRi ICCi_1 OPE2_0D GRj)
+     (sequence ((QI cc))
+              (set cc 0)
+              (set-c cc
+                     (orif (eq (and GRi #xff000000) (and GRj #xff000000))
+                           (orif (eq (and GRi #x00ff0000) (and GRj #x00ff0000))
+                                 (orif (eq (and GRi #x0000ff00)
+                                           (and GRj #x0000ff00))
+                                        (eq (and GRi #x000000ff)
+                                           (and GRj #x000000ff))))))
+              (set ICCi_1 cc))
+     ((fr400 (unit u-integer)))
+)
+
+; Format: Load immediate
+;
+(dni setlo
+     "set low order bits"
+     ((UNIT I01) (FR500-MAJOR I-1) (FR400-MAJOR I-1))
+     "setlo$pack $ulo16,$GRklo"
+     (+ pack GRk OP_3D (misc-null-4) u16)
+     (set GRklo u16)
+     ((fr400 (unit u-set-hilo))
+      (fr500 (unit u-set-hilo)))
+)
+
+(dni sethi
+     "set high order bits"
+     ((UNIT I01) (FR500-MAJOR I-1) (FR400-MAJOR I-1))
+     "sethi$pack $uhi16,$GRkhi"
+     (+ pack GRkhi OP_3E (misc-null-4) u16)
+     (set GRkhi u16)
+     ((fr400 (unit u-set-hilo))
+      (fr500 (unit u-set-hilo)))
+)
+
+(dni setlos
+     "set low order bits and extend sign"
+     ((UNIT I01) (FR500-MAJOR I-1) (FR400-MAJOR I-1))
+     "setlos$pack $slo16,$GRk"
+     (+ pack GRk OP_3F (misc-null-4) s16)
+     (set GRk s16)
+     ((fr400 (unit u-integer))
+      (fr500 (unit u-integer)))
+)
+
+(define-pmacro (load-gr-r name mode op ope comment)
+  (dni name
+       (comment)
+       ((UNIT LOAD) (FR500-MAJOR I-2) (FR400-MAJOR I-2))
+       (.str name "$pack @($GRi,$GRj),$GRk")
+       (+ pack GRk op GRi ope GRj)
+       (set GRk (c-call mode (.str "@cpu@_read_mem_" mode) pc (add GRi GRj)))
+       ((fr400 (unit u-gr-load))
+       (fr500 (unit u-gr-load)))
+  )
+)
+
+(load-gr-r ldsb   QI OP_02 OPE1_00 "Load   signed byte")
+(load-gr-r ldub  UQI OP_02 OPE1_01 "Load unsigned byte")
+(load-gr-r ldsh   HI OP_02 OPE1_02 "Load   signed half")
+(load-gr-r lduh  UHI OP_02 OPE1_03 "Load unsigned half")
+(load-gr-r ld     SI OP_02 OPE1_04 "Load          word")
+
+(define-pmacro (load-fr-r name mode op ope comment)
+  (dni name
+       (comment)
+       ((UNIT LOAD) (FR500-MAJOR I-2) (FR400-MAJOR I-2) FR-ACCESS)
+       (.str name "$pack @($GRi,$GRj),$FRintk")
+       (+ pack FRintk op GRi ope GRj)
+       (set FRintk (c-call mode (.str "@cpu@_read_mem_" mode) pc (add GRi GRj)))
+       ((fr400 (unit u-fr-load))
+       (fr500 (unit u-fr-load)))
+  )
+)
+
+(load-fr-r ldbf UQI OP_02 OPE1_08 "Load byte   float")
+(load-fr-r ldhf UHI OP_02 OPE1_09 "Load half   float")
+(load-fr-r ldf   SI OP_02 OPE1_0A "Load word   float")
+
+(define-pmacro (load-cpr-r name mode op ope reg attr comment)
+  (dni name
+       (comment)
+       ((UNIT LOAD) (FR500-MAJOR I-2) attr)
+       (.str name "$pack @($GRi,$GRj),$" reg "k")
+       (+ pack (.sym reg k) op GRi ope GRj)
+       (set (.sym reg k)
+           (c-call mode (.str "@cpu@_read_mem_" mode) pc (add GRi GRj)))
+       ()
+  )
+)
+
+(load-cpr-r ldc SI OP_02 OPE1_0D CPR (MACH frv) "Load coprocessor word")
+
+; These correspond to enumerators in frv-sim.h
+(define-pmacro (ne-UQI-size) 0)
+(define-pmacro (ne-QI-size)  1)
+(define-pmacro (ne-UHI-size) 2)
+(define-pmacro (ne-HI-size)  3)
+(define-pmacro (ne-SI-size)  4)
+(define-pmacro (ne-DI-size)  5)
+(define-pmacro (ne-XI-size)  6)
+
+(define-pmacro (ne-load-semantics base dispix targ idisp size is_float action)
+  (sequence ((BI do_op))
+           (set do_op
+                (c-call BI "@cpu@_check_non_excepting_load"
+                         (index-of base) dispix (index-of targ)
+                         idisp size is_float))
+           (if do_op action))
+)
+
+(define-pmacro (ne-load-gr-r name mode op ope size comment)
+  (dni name
+       (comment)
+       ((UNIT LOAD) (FR500-MAJOR I-2) NON-EXCEPTING
+       (MACH simple,tomcat,fr500,frv))
+       (.str name "$pack @($GRi,$GRj),$GRk")
+       (+ pack GRk op GRi ope GRj)
+       (ne-load-semantics GRi (index-of GRj) GRk 0 size 0
+                         (set GRk
+                              (c-call mode (.str "@cpu@_read_mem_" mode)
+                                      pc (add GRi GRj))))
+       ((fr500 (unit u-gr-load)))
+  )
+)
+
+(ne-load-gr-r nldsb  QI OP_02 OPE1_20 (ne-QI-size)  "Load   signed byte")
+(ne-load-gr-r nldub UQI OP_02 OPE1_21 (ne-UQI-size) "Load unsigned byte")
+(ne-load-gr-r nldsh  HI OP_02 OPE1_22 (ne-HI-size)  "Load   signed half")
+(ne-load-gr-r nlduh UHI OP_02 OPE1_23 (ne-UHI-size) "Load unsigned half")
+(ne-load-gr-r nld    SI OP_02 OPE1_24 (ne-SI-size)  "Load          word")
+
+(define-pmacro (ne-load-fr-r name mode op ope size comment)
+  (dni name
+       (comment)
+       ((UNIT LOAD) (FR500-MAJOR I-2) NON-EXCEPTING FR-ACCESS
+       (MACH simple,tomcat,fr500,frv))
+       (.str name "$pack @($GRi,$GRj),$FRintk")
+       (+ pack FRintk op GRi ope GRj)
+       (ne-load-semantics GRi (index-of GRj) FRintk 0 size 1
+                         (set FRintk
+                              (c-call mode (.str "@cpu@_read_mem_" mode)
+                                      pc (add GRi GRj))))
+       ((fr500 (unit u-fr-load)))
+  )
+)
+
+(ne-load-fr-r nldbf UQI OP_02 OPE1_28 (ne-UQI-size) "Load byte float")
+(ne-load-fr-r nldhf UHI OP_02 OPE1_29 (ne-UHI-size) "Load half float")
+(ne-load-fr-r nldf   SI OP_02 OPE1_2A (ne-SI-size)  "Load word float")
+
+; Semantics for a load-double insn
+;
+(define-pmacro (load-double-semantics not_gr mode regtype address arg)
+  (if (orif not_gr (ne (index-of (.sym regtype doublek)) 0))
+      (sequence ()
+               (set address (add GRi arg))
+               (set (.sym regtype doublek)
+                    (c-call mode (.str "@cpu@_read_mem_" mode) pc address))))
+)
+
+(define-pmacro (load-double-r-r
+               name not_gr mode op ope regtype attr profile comment)
+  (dni name
+       (comment)
+       ((UNIT LOAD) (FR500-MAJOR I-2) (FR400-MAJOR I-2) attr)
+       (.str name "$pack @($GRi,$GRj),$" regtype "doublek")
+       (+ pack (.sym regtype doublek) op GRi ope GRj)
+       (sequence ((WI address))
+                (load-double-semantics not_gr mode regtype address GRj))
+       profile
+  )
+)
+
+(load-double-r-r ldd  0 DI OP_02 OPE1_05 GR  NA
+                ((fr400 (unit u-gr-load)) (fr500 (unit u-gr-load)))
+                "Load double word")
+(load-double-r-r lddf 1 DF OP_02 OPE1_0B FR  FR-ACCESS
+                ((fr400 (unit u-fr-load)) (fr500 (unit u-fr-load)))
+                "Load double float")
+(load-double-r-r lddc 1 DI OP_02 OPE1_0E CPR (MACH frv) ()
+                "Load coprocessor double")
+
+(define-pmacro (ne-load-double-r-r
+               name not_gr mode op ope regtype size is_float attr profile
+               comment)
+  (dni name
+       (comment)
+       ((UNIT LOAD) (FR500-MAJOR I-2) NON-EXCEPTING attr
+       (MACH simple,tomcat,fr500,frv))
+       (.str name "$pack @($GRi,$GRj),$" regtype "doublek")
+       (+ pack (.sym regtype doublek) op GRi ope GRj)
+       (sequence ((WI address))
+                (ne-load-semantics GRi (index-of GRj) (.sym regtype doublek)
+                                   0 size is_float
+                                   (load-double-semantics not_gr mode
+                                                          regtype
+                                                          address GRj)))
+       profile
+  )
+)
+
+(ne-load-double-r-r nldd  0 DI OP_02 OPE1_25 GR (ne-DI-size) 0 NA
+                   ((fr500 (unit u-gr-load))) "Load double   word")
+(ne-load-double-r-r nlddf 1 DF OP_02 OPE1_2B FR (ne-DI-size) 1 FR-ACCESS
+                   ((fr500 (unit u-fr-load))) "Load double float")
+
+; Semantics for a load-quad insn
+;
+(define-pmacro (load-quad-semantics regtype address arg)
+  (sequence ()
+           (set address (add GRi arg))
+           (c-call VOID (.str "@cpu@_load_quad_" regtype)
+                   pc address (index-of (.sym regtype k))))
+)
+
+(define-pmacro (load-quad-r-r name op ope regtype attr profile comment)
+  (dni name
+       (comment)
+       ((UNIT LOAD) (FR500-MAJOR I-2) (MACH frv) attr)
+       (.str name "$pack @($GRi,$GRj),$" regtype "k")
+       (+ pack (.sym regtype k) op GRi ope GRj)
+       (sequence ((WI address))
+                (load-quad-semantics regtype address GRj))
+       ; TODO regtype-k not referenced for profiling
+       profile
+  )
+)
+
+(load-quad-r-r ldq  OP_02 OPE1_06 GR    NA        ((fr500 (unit u-gr-load)))
+              "Load quad word")
+(load-quad-r-r ldqf OP_02 OPE1_0C FRint FR-ACCESS ((fr500 (unit u-fr-load)))
+              "Load quad float")
+(load-quad-r-r ldqc OP_02 OPE1_0F CPR   NA        () "Load coprocessor quad")
+
+(define-pmacro (ne-load-quad-r-r
+               name op ope regtype size is_float attr profile comment)
+  (dni name
+       (comment)
+       ((UNIT LOAD) (FR500-MAJOR I-2) (MACH frv) NON-EXCEPTING attr)
+       (.str name "$pack @($GRi,$GRj),$" regtype "k")
+       (+ pack (.sym regtype k) op GRi ope GRj)
+       (sequence ((WI address))
+                (ne-load-semantics GRi (index-of GRj) (.sym regtype k)
+                                   0 size is_float
+                                   (load-quad-semantics regtype address GRj)))
+       ; TODO regtype-k not referenced for profiling
+       profile
+  )
+)
+
+(ne-load-quad-r-r nldq  OP_02 OPE1_26 GR    (ne-XI-size) 0 NA
+                 ((fr500 (unit u-gr-load))) "Load quad word")
+(ne-load-quad-r-r nldqf OP_02 OPE1_2C FRint (ne-XI-size) 1 FR-ACCESS
+                 ((fr500 (unit u-fr-load))) "Load quad float")
+
+(define-pmacro (load-gr-u-semantics mode)
+  (sequence ((UWI address))
+           (set address (add GRi GRj))
+           (set GRk (c-call mode (.str "@cpu@_read_mem_" mode) pc address))
+           (if (ne (index-of GRi) (index-of GRk))
+               (sequence ()
+                         (set GRi address)
+                         (c-call VOID "@cpu@_force_update"))))
+)
+
+(define-pmacro (load-gr-u name mode op ope comment)
+  (dni name
+       (comment)
+       ((UNIT LOAD) (FR500-MAJOR I-2) (FR400-MAJOR I-2))
+       (.str name "$pack @($GRi,$GRj),$GRk")
+       (+ pack GRk op GRi ope GRj)
+       (load-gr-u-semantics mode)
+       ((fr400 (unit u-gr-load))
+       (fr500 (unit u-gr-load)))
+  )
+)
+
+(load-gr-u ldsbu   QI OP_02 OPE1_10 "Load   signed byte, update index")
+(load-gr-u ldubu  UQI OP_02 OPE1_11 "Load unsigned byte, update index")
+(load-gr-u ldshu   HI OP_02 OPE1_12 "Load   signed half, update index")
+(load-gr-u lduhu  UHI OP_02 OPE1_13 "Load unsigned half, update index")
+(load-gr-u ldu     SI OP_02 OPE1_14 "Load          word, update index")
+
+(define-pmacro (ne-load-gr-u name mode op ope size comment)
+  (dni name
+       (comment)
+       ((UNIT LOAD) (FR500-MAJOR I-2) NON-EXCEPTING
+       (MACH simple,tomcat,fr500,frv))
+       (.str name "$pack @($GRi,$GRj),$GRk")
+       (+ pack GRk op GRi ope GRj)
+       (ne-load-semantics GRi (index-of GRj) GRk 0 size 0 (load-gr-u-semantics mode))
+       ((fr500 (unit u-gr-load)))
+  )
+)
+
+(ne-load-gr-u nldsbu  QI OP_02 OPE1_30 (ne-QI-size)  "Load   signed byte, update index")
+(ne-load-gr-u nldubu UQI OP_02 OPE1_31 (ne-UQI-size) "Load unsigned byte, update index")
+(ne-load-gr-u nldshu  HI OP_02 OPE1_32 (ne-HI-size)  "Load   signed half, update index")
+(ne-load-gr-u nlduhu UHI OP_02 OPE1_33 (ne-UHI-size) "Load unsigned half, update index")
+(ne-load-gr-u nldu    SI OP_02 OPE1_34 (ne-SI-size)  "Load          word, update index")
+
+(define-pmacro (load-non-gr-u-semantics mode regtype)
+  (sequence ((UWI address))
+           (set address (add GRi GRj))
+           (set (.sym regtype k)
+                (c-call mode (.str "@cpu@_read_mem_" mode) pc address))
+           (set GRi address)
+           (c-call VOID "@cpu@_force_update"))
+)
+
+(define-pmacro (load-fr-u name mode op ope comment)
+  (dni name
+       (comment)
+       ((UNIT LOAD) (FR500-MAJOR I-2) (FR400-MAJOR I-2) FR-ACCESS)
+       (.str name "$pack @($GRi,$GRj),$FRintk")
+       (+ pack FRintk op GRi ope GRj)
+       (load-non-gr-u-semantics mode FRint)
+       ((fr400 (unit u-fr-load))
+       (fr500 (unit u-fr-load)))
+  )
+)
+
+(load-fr-u ldbfu  UQI OP_02 OPE1_18 "Load byte float, update index")
+(load-fr-u ldhfu  UHI OP_02 OPE1_19 "Load half float, update index")
+(load-fr-u ldfu    SI OP_02 OPE1_1A "Load word float, update index")
+
+(define-pmacro (load-cpr-u name mode op ope comment)
+  (dni name
+       (comment)
+       ((UNIT LOAD) (FR500-MAJOR I-2) (MACH frv))
+       (.str name "$pack @($GRi,$GRj),$CPRk")
+       (+ pack CPRk op GRi ope GRj)
+       (load-non-gr-u-semantics mode CPR)
+       ()
+  )
+)
+
+(load-cpr-u ldcu SI OP_02 OPE1_1D "Load coprocessor word float,update index")
+
+(define-pmacro (ne-load-non-gr-u name mode op ope regtype size comment)
+  (dni name
+       (comment)
+       ((UNIT LOAD) (FR500-MAJOR I-2) NON-EXCEPTING FR-ACCESS
+       (MACH simple,tomcat,fr500,frv))
+       (.str name "$pack @($GRi,$GRj),$" regtype "k")
+       (+ pack (.sym regtype k) op GRi ope GRj)
+       (ne-load-semantics GRi (index-of GRj) (.sym regtype k) 0 size 1
+                         (load-non-gr-u-semantics mode regtype))
+       ((fr500 (unit u-fr-load)))
+  )
+)
+
+(ne-load-non-gr-u nldbfu UQI OP_02 OPE1_38 FRint (ne-UQI-size) "Load byte float, update index")
+(ne-load-non-gr-u nldhfu UHI OP_02 OPE1_39 FRint (ne-UHI-size) "Load half float, update index")
+(ne-load-non-gr-u nldfu   SI OP_02 OPE1_3A FRint (ne-SI-size)  "Load word float, update index")
+
+(define-pmacro (load-double-gr-u-semantics)
+  (sequence ((WI address))
+           (load-double-semantics 0 DI GR address GRj)
+           (if (ne (index-of GRi) (index-of GRdoublek))
+               (sequence ()
+                         (set GRi address)
+                         (c-call VOID "@cpu@_force_update"))))
+)
+
+(define-pmacro (load-double-gr-u name op ope comment)
+  (dni name
+       (comment)
+       ((UNIT LOAD) (FR500-MAJOR I-2) (FR400-MAJOR I-2))
+       (.str name "$pack @($GRi,$GRj),$GRdoublek")
+       (+ pack GRdoublek op GRi ope GRj)
+       (load-double-gr-u-semantics)
+       ((fr400 (unit u-gr-load))
+       (fr500 (unit u-gr-load)))
+  )
+)
+
+(load-double-gr-u lddu  OP_02 OPE1_15 "Load double word, update index")
+
+(define-pmacro (ne-load-double-gr-u name op ope size comment)
+  (dni name
+       (comment)
+       ((UNIT LOAD) (FR500-MAJOR I-2) NON-EXCEPTING
+       (MACH simple,tomcat,fr500,frv))
+       (.str name "$pack @($GRi,$GRj),$GRdoublek")
+       (+ pack GRdoublek op GRi ope GRj)
+       (ne-load-semantics GRi (index-of GRj) GRdoublek 0 size 0
+                         (load-double-gr-u-semantics))
+       ((fr500 (unit u-gr-load)))
+
+  )
+)
+
+(ne-load-double-gr-u nlddu OP_02 OPE1_35 (ne-DI-size) "Load double word, update index")
+
+(define-pmacro (load-double-non-gr-u-semantics mode regtype)
+  (sequence ((WI address))
+           (load-double-semantics 1 mode regtype address GRj)
+           (set GRi address)
+           (c-call VOID "@cpu@_force_update"))
+)
+
+(define-pmacro (load-double-non-gr-u
+               name mode op ope regtype attr profile comment)
+  (dni name
+       (comment)
+       ((UNIT LOAD) (FR500-MAJOR I-2) (FR400-MAJOR I-2) attr)
+       (.str name "$pack @($GRi,$GRj),$" regtype "doublek")
+       (+ pack (.sym regtype doublek) op GRi ope GRj)
+       (load-double-non-gr-u-semantics mode regtype)
+       profile
+  )
+)
+
+(load-double-non-gr-u lddfu DF OP_02 OPE1_1B FR  FR-ACCESS
+                     ((fr400 (unit u-fr-load)) (fr500 (unit u-fr-load)))
+                     "Load double float, update index")
+(load-double-non-gr-u lddcu DI OP_02 OPE1_1E CPR (MACH frv)
+                     () "Load coprocessor double float, update index")
+
+(define-pmacro (ne-load-double-non-gr-u name mode op ope regtype size comment)
+  (dni name
+       (comment)
+       ((UNIT LOAD) (FR500-MAJOR I-2) NON-EXCEPTING FR-ACCESS
+       (MACH simple,tomcat,fr500,frv))
+       (.str name "$pack @($GRi,$GRj),$" regtype "doublek")
+       (+ pack (.sym regtype doublek) op GRi ope GRj)
+       (ne-load-semantics GRi (index-of GRj) (.sym regtype doublek) 0 size 1
+                         (load-double-non-gr-u-semantics mode regtype))
+       ((fr500 (unit u-fr-load)))
+  )
+)
+
+(ne-load-double-non-gr-u nlddfu DF OP_02 OPE1_3B FR (ne-DI-size) "Load double float, update index")
+
+(define-pmacro (load-quad-gr-u-semantics)
+  (sequence ((WI address))
+           (load-quad-semantics GR address GRj)
+           (if (ne (index-of GRi) (index-of GRk))
+               (sequence ()
+                         (set GRi address)
+                         (c-call VOID "@cpu@_force_update"))))
+)
+
+(define-pmacro (load-quad-gr-u name op ope comment)
+  (dni name
+       (comment)
+       ((UNIT LOAD) (FR500-MAJOR I-2) (MACH frv))
+       (.str name "$pack @($GRi,$GRj),$GRk")
+       (+ pack GRk op GRi ope GRj)
+       (load-quad-gr-u-semantics)
+       ; TODO - GRk not referenced here for profiling
+       ((fr500 (unit u-gr-load)))
+  )
+)
+
+(load-quad-gr-u ldqu  OP_02 OPE1_16 "Load quad word, update index")
+
+(define-pmacro (ne-load-quad-gr-u name op ope size comment)
+  (dni name
+       (comment)
+       ((UNIT LOAD) (FR500-MAJOR I-2) (MACH frv) NON-EXCEPTING)
+       (.str name "$pack @($GRi,$GRj),$GRk")
+       (+ pack GRk op GRi ope GRj)
+       (ne-load-semantics GRi (index-of GRj) GRk 0 size 0
+                         (load-quad-gr-u-semantics))
+       ; TODO - GRk not referenced here for profiling
+       ((fr500 (unit u-gr-load)))
+  )
+)
+
+(ne-load-quad-gr-u nldqu OP_02 OPE1_36 (ne-XI-size) "Load quad word, update index")
+
+(define-pmacro (load-quad-non-gr-u-semantics regtype)
+  (sequence ((WI address))
+           (load-quad-semantics regtype address GRj)
+           (set GRi address)
+           (c-call VOID "@cpu@_force_update"))
+)
+
+(define-pmacro (load-quad-non-gr-u name op ope regtype attr profile comment)
+  (dni name
+       (comment)
+       ((UNIT LOAD) (FR500-MAJOR I-2) (MACH frv) attr)
+       (.str name "$pack @($GRi,$GRj),$" regtype "k")
+       (+ pack (.sym regtype k) op GRi ope GRj)
+       (load-quad-non-gr-u-semantics regtype)
+       profile
+  )
+)
+
+(load-quad-non-gr-u ldqfu OP_02 OPE1_1C FRint FR-ACCESS
+                   ((fr500 (unit u-fr-load))) "Load quad float, update index")
+(load-quad-non-gr-u ldqcu OP_02 OPE1_1F CPR   NA
+                   () "Load coprocessor quad word, update index")
+
+(define-pmacro (ne-load-quad-non-gr-u name op ope regtype size comment)
+  (dni name
+       (comment)
+       ((UNIT LOAD) (FR500-MAJOR I-2) (MACH frv) NON-EXCEPTING FR-ACCESS)
+       (.str name "$pack @($GRi,$GRj),$" regtype "k")
+       (+ pack (.sym regtype k) op GRi ope GRj)
+       (ne-load-semantics GRi (index-of GRj) (.sym regtype k) 0 size 1
+                         (load-quad-non-gr-u-semantics regtype))
+       ((fr500 (unit u-fr-load)))
+  )
+)
+
+(ne-load-quad-non-gr-u nldqfu OP_02 OPE1_3C FRint (ne-XI-size) "Load quad float,update index")
+
+(define-pmacro (load-r-simm name mode op regtype attr profile comment)
+  (dni name
+       (comment)
+       ((UNIT LOAD) (FR500-MAJOR I-2) (FR400-MAJOR I-2) attr)
+       (.str name "$pack @($GRi,$d12),$" regtype "k")
+       (+ pack (.sym regtype k) op GRi d12)
+       (set (.sym regtype k)
+           (c-call mode (.str "@cpu@_read_mem_" mode) pc (add GRi d12)))
+       profile
+  )
+)
+
+(load-r-simm ldsbi  QI OP_30 GR NA
+            ((fr400 (unit u-gr-load)) (fr500 (unit u-gr-load)))
+            "Load   signed byte")
+(load-r-simm ldshi  HI OP_31 GR NA
+            ((fr400 (unit u-gr-load)) (fr500 (unit u-gr-load)))
+            "Load   signed half")
+(load-r-simm ldi    SI OP_32 GR NA
+            ((fr400 (unit u-gr-load)) (fr500 (unit u-gr-load)))
+            "Load          word")
+(load-r-simm ldubi UQI OP_35 GR NA
+            ((fr400 (unit u-gr-load)) (fr500 (unit u-gr-load)))
+            "Load unsigned byte")
+(load-r-simm lduhi UHI OP_36 GR NA
+            ((fr400 (unit u-gr-load)) (fr500 (unit u-gr-load)))
+            "Load unsigned half")
+
+(load-r-simm ldbfi UQI OP_38 FRint FR-ACCESS
+            ((fr400 (unit u-fr-load)) (fr500 (unit u-fr-load)))
+            "Load byte float")
+(load-r-simm ldhfi UHI OP_39 FRint FR-ACCESS
+            ((fr400 (unit u-fr-load)) (fr500 (unit u-fr-load)))
+            "Load half float")
+(load-r-simm ldfi   SI OP_3A FRint FR-ACCESS
+            ((fr400 (unit u-fr-load)) (fr500 (unit u-fr-load)))
+            "Load word float")
+
+(define-pmacro (ne-load-r-simm
+               name mode op regtype size is_float attr profile comment)
+  (dni name
+       (comment)
+       ((UNIT LOAD) (FR500-MAJOR I-2) NON-EXCEPTING attr
+       (MACH simple,tomcat,fr500,frv))
+       (.str name "$pack @($GRi,$d12),$" regtype "k")
+       (+ pack (.sym regtype k) op GRi d12)
+       (ne-load-semantics GRi -1 (.sym regtype k) d12 size is_float
+                         (set (.sym regtype k)
+                              (c-call mode (.str "@cpu@_read_mem_" mode)
+                                      pc (add GRi d12))))
+       profile
+  )
+)
+
+(ne-load-r-simm nldsbi  QI OP_40 GR (ne-QI-size)  0 NA
+               ((fr500 (unit u-gr-load))) "Load   signed byte")
+(ne-load-r-simm nldubi UQI OP_41 GR (ne-UQI-size) 0 NA
+               ((fr500 (unit u-gr-load))) "Load unsigned byte")
+(ne-load-r-simm nldshi  HI OP_42 GR (ne-HI-size)  0 NA
+               ((fr500 (unit u-gr-load))) "Load   signed half")
+(ne-load-r-simm nlduhi UHI OP_43 GR (ne-UHI-size) 0 NA
+               ((fr500 (unit u-gr-load))) "Load unsigned half")
+(ne-load-r-simm nldi    SI OP_44 GR (ne-SI-size)  0 NA
+               ((fr500 (unit u-gr-load))) "Load          word")
+
+(ne-load-r-simm nldbfi UQI OP_48 FRint (ne-UQI-size) 1 FR-ACCESS
+               ((fr500 (unit u-fr-load))) "Load byte float")
+(ne-load-r-simm nldhfi UHI OP_49 FRint (ne-UHI-size) 1 FR-ACCESS
+               ((fr500 (unit u-fr-load))) "Load half float")
+(ne-load-r-simm nldfi   SI OP_4A FRint (ne-SI-size)  1 FR-ACCESS
+               ((fr500 (unit u-fr-load))) "Load word float")
+
+(define-pmacro (load-double-r-simm
+               name not_gr mode op regtype attr profile comment)
+  (dni name
+       (comment)
+       ((UNIT LOAD) (FR500-MAJOR I-2) (FR400-MAJOR I-2) attr)
+       (.str name "$pack @($GRi,$d12),$" regtype "doublek")
+       (+ pack (.sym regtype doublek) op GRi d12)
+       (sequence ((WI address))
+                (load-double-semantics not_gr mode regtype address d12))
+       profile
+  )
+)
+
+(load-double-r-simm lddi  0 DI OP_33 GR NA
+                   ((fr400 (unit u-gr-load)) (fr500 (unit u-gr-load)))
+                   "Load double word")
+(load-double-r-simm lddfi 1 DF OP_3B FR FR-ACCESS
+                   ((fr400 (unit u-fr-load)) (fr500 (unit u-fr-load)))
+                   "Load double float")
+
+(define-pmacro (ne-load-double-r-simm
+               name not_gr mode op regtype size is_float attr profile comment)
+  (dni name
+       (comment)
+       ((UNIT LOAD) (FR500-MAJOR I-2) NON-EXCEPTING attr
+       (MACH simple,tomcat,fr500,frv))
+       (.str name "$pack @($GRi,$d12),$" regtype "doublek")
+       (+ pack (.sym regtype doublek) op GRi d12)
+       (sequence ((WI address))
+                (ne-load-semantics GRi -1 (.sym regtype doublek)
+                                   d12 size is_float
+                                   (load-double-semantics not_gr mode
+                                                          regtype
+                                                          address d12)))
+       profile
+  )
+)
+
+(ne-load-double-r-simm nlddi  0 DI OP_45 GR (ne-DI-size) 0 NA
+                      ((fr500 (unit u-gr-load))) "Load double word")
+(ne-load-double-r-simm nlddfi 1 DF OP_4B FR (ne-DI-size) 1 FR-ACCESS
+                      ((fr500 (unit u-fr-load))) "Load double float")
+
+(define-pmacro (load-quad-r-simm name op regtype attr profile comment)
+  (dni name
+       (comment)
+       ((UNIT LOAD) (FR500-MAJOR I-2) (MACH frv) attr)
+       (.str name "$pack @($GRi,$d12),$" regtype "k")
+       (+ pack (.sym regtype k) op GRi d12)
+       (sequence ((WI address))
+                (load-quad-semantics regtype address d12))
+       profile
+  )
+)
+
+(load-quad-r-simm ldqi  OP_34 GR    NA
+                 ((fr500 (unit u-gr-load))) "Load quad word")
+(load-quad-r-simm ldqfi OP_3C FRint FR-ACCESS
+                 ((fr500 (unit u-fr-load))) "Load quad float")
+
+(define-pmacro (ne-load-quad-r-simm
+               name op regtype size is_float attr profile comment)
+  (dni name
+       (comment)
+       ((UNIT LOAD) (FR500-MAJOR I-2) (MACH frv) NON-EXCEPTING attr)
+       (.str name "$pack @($GRi,$d12),$" regtype "k")
+       (+ pack (.sym regtype k) op GRi d12)
+       (sequence ((WI address))
+                (ne-load-semantics GRi -1 (.sym regtype k) d12 size is_float
+                                   (load-quad-semantics regtype address d12)))
+       profile
+  )
+)
+
+(ne-load-quad-r-simm nldqi  OP_46 GR    (ne-XI-size) 0 NA
+                    ((fr500 (unit u-gr-load))) "Load quad word")
+(ne-load-quad-r-simm nldqfi OP_4C FRint (ne-XI-size) 1 FR-ACCESS
+                    ((fr500 (unit u-fr-load))) "Load quad float")
+
+(define-pmacro (store-r-r name mode op ope reg attr profile comment)
+  (dni name
+       (comment)
+       ((UNIT I0) (FR500-MAJOR I-3) (FR400-MAJOR I-3) attr)
+       (.str name "$pack $" reg "k,@($GRi,$GRj)")
+       (+ pack (.sym reg k) op GRi ope GRj)
+       (c-call VOID (.str "@cpu@_write_mem_" mode)
+              pc (add GRi GRj) (.sym reg k))
+       profile
+  )
+)
+
+(store-r-r stb   QI OP_03 OPE1_00 GR NA
+          ((fr400 (unit u-gr-store)) (fr500 (unit u-gr-store)))
+          "Store unsigned byte")
+(store-r-r sth   HI OP_03 OPE1_01 GR NA
+          ((fr400 (unit u-gr-store)) (fr500 (unit u-gr-store)))
+          "Store unsigned half")
+(store-r-r st    SI OP_03 OPE1_02 GR NA
+          ((fr400 (unit u-gr-store)) (fr500 (unit u-gr-store)))
+          "Store          word")
+
+(store-r-r stbf  QI OP_03 OPE1_08 FRint FR-ACCESS
+          ((fr400 (unit u-fr-store)) (fr500 (unit u-fr-store)))
+          "Store byte float")
+(store-r-r sthf  HI OP_03 OPE1_09 FRint FR-ACCESS
+          ((fr400 (unit u-fr-store)) (fr500 (unit u-fr-store)))
+          "Store half float")
+(store-r-r stf   SI OP_03 OPE1_0A FRint FR-ACCESS
+          ((fr400 (unit u-fr-store)) (fr500 (unit u-fr-store)))
+          "Store word float")
+
+(store-r-r stc   SI OP_03 OPE1_25 CPR (MACH frv) () "Store coprocessor word")
+
+(define-pmacro (r-store name mode op ope reg size is_float profile comment)
+  (dni name
+       (comment)
+       ((UNIT I0) (FR500-MAJOR I-3) (MACH frv))
+       (.str name "$pack $" reg "k,@($GRi,$GRj)")
+       (+ pack (.sym reg k) op GRi ope GRj)
+       (sequence ((WI address))
+                (set address (add GRi GRj))
+                (c-call VOID (.str "@cpu@_write_mem_" mode)
+                        pc address (.sym reg k))
+                (c-call VOID "@cpu@_check_recovering_store"
+                        address (index-of (.sym reg k)) size is_float))
+       profile
+  )
+)
+
+(r-store rstb  QI OP_03 OPE1_20 GR 1 0
+        ((fr500 (unit u-gr-r-store))) "Store unsigned byte")
+(r-store rsth  HI OP_03 OPE1_21 GR 2 0
+        ((fr500 (unit u-gr-r-store))) "Store unsigned half")
+(r-store rst   SI OP_03 OPE1_22 GR 4 0
+        ((fr500 (unit u-gr-r-store))) "Store          word")
+
+(r-store rstbf QI OP_03 OPE1_28 FRint 1 1
+        ((fr500 (unit u-fr-r-store))) "Store byte float")
+(r-store rsthf HI OP_03 OPE1_29 FRint 2 1
+        ((fr500 (unit u-fr-r-store))) "Store half float")
+(r-store rstf  SI OP_03 OPE1_2A FRint 4 1
+        ((fr500 (unit u-fr-r-store))) "Store word float")
+
+; Semantics for a store-double insn
+;
+(define-pmacro (store-double-semantics mode regtype address arg)
+  (sequence ()
+           (set address (add GRi arg))
+           (c-call VOID (.str "@cpu@_write_mem_" mode)
+                   pc address (.sym regtype doublek)))
+)
+
+(define-pmacro (store-double-r-r name mode op ope regtype attr profile comment)
+  (dni name
+       (comment)
+       ((UNIT I0) (FR500-MAJOR I-3) (FR400-MAJOR I-3) attr)
+       (.str name "$pack $" regtype "k,@($GRi,$GRj)")
+       (+ pack (.sym regtype k) op GRi ope GRj)
+       (sequence ((WI address))
+                (store-double-semantics mode regtype address GRj))
+       profile
+  )
+)
+
+(store-double-r-r std  DI OP_03 OPE1_03 GR  NA
+                 ((fr400 (unit u-gr-store)) (fr500 (unit u-gr-store)))
+                 "Store double word")
+(store-double-r-r stdf DF OP_03 OPE1_0B FR  FR-ACCESS
+                 ((fr400 (unit u-fr-store)) (fr500 (unit u-fr-store)))
+                 "Store double float")
+
+(store-double-r-r stdc DI OP_03 OPE1_26 CPR (MACH frv)
+                 () "Store coprocessor double word")
+
+(define-pmacro (r-store-double
+               name mode op ope regtype is_float attr profile comment)
+  (dni name
+       (comment)
+       ((UNIT I0) (FR500-MAJOR I-3) (MACH frv) attr)
+       (.str name "$pack $" regtype "k,@($GRi,$GRj)")
+       (+ pack (.sym regtype k) op GRi ope GRj)
+       (sequence ((WI address))
+                (store-double-semantics mode regtype address GRj)
+                (c-call VOID "@cpu@_check_recovering_store"
+                        address (index-of (.sym regtype k)) 8 is_float))
+       profile
+  )
+)
+
+(r-store-double rstd  DI OP_03 OPE1_23 GR 0 NA
+               ((fr500 (unit u-gr-r-store))) "Store double word")
+(r-store-double rstdf DF OP_03 OPE1_2B FR 1 FR-ACCESS
+               ((fr500 (unit u-fr-r-store))) "Store double float")
+
+; Semantics for a store-quad insn
+;
+(define-pmacro (store-quad-semantics regtype address arg)
+  (sequence ()
+           (set address (add GRi arg))
+           (c-call VOID (.str "@cpu@_store_quad_" regtype)
+                    pc address (index-of (.sym regtype k))))
+)
+
+(define-pmacro (store-quad-r-r name op ope regtype attr profile comment)
+  (dni name
+       (comment)
+       ((UNIT I0) (FR500-MAJOR I-3) (MACH frv) attr)
+       (.str name "$pack $" regtype "k,@($GRi,$GRj)")
+       (+ pack (.sym regtype k) op GRi ope GRj)
+       (sequence ((WI address))
+                (store-quad-semantics regtype address GRj))
+       profile
+  )
+)
+
+(store-quad-r-r stq   OP_03 OPE1_04 GR    NA
+               ((fr500 (unit u-gr-store))) "Store quad word")
+(store-quad-r-r stqf  OP_03 OPE1_0C FRint FR-ACCESS
+               ((fr500 (unit u-fr-store)))
+               "Store quad float")
+(store-quad-r-r stqc  OP_03 OPE1_27 CPR   NA
+               () "Store coprocessor quad word")
+
+(define-pmacro (r-store-quad name op ope regtype is_float attr profile comment)
+  (dni name
+       (comment)
+       ((UNIT I0) (FR500-MAJOR I-3) (MACH frv) attr)
+       (.str name "$pack $" regtype "k,@($GRi,$GRj)")
+       (+ pack (.sym regtype k) op GRi ope GRj)
+       (sequence ((WI address))
+                (store-quad-semantics regtype address GRj)
+                (c-call VOID "@cpu@_check_recovering_store"
+                        address (index-of (.sym regtype k)) 16 is_float))
+       profile
+  )
+)
+
+(r-store-quad rstq  OP_03 OPE1_24 GR    0 NA
+             ((fr500 (unit u-gr-r-store))) "Store quad word")
+(r-store-quad rstqf OP_03 OPE1_2C FRint 1 FR-ACCESS
+             ((fr500 (unit u-fr-r-store))) "Store quad float")
+
+(define-pmacro (store-r-r-u name mode op ope regtype attr profile comment)
+  (dni name
+       (comment)
+       ((UNIT I0) (FR500-MAJOR I-3) (FR400-MAJOR I-3) attr)
+       (.str name "$pack $" regtype "k,@($GRi,$GRj)")
+       (+ pack (.sym regtype k) op GRi ope GRj)
+       (sequence ((UWI address))
+                (set address (add GRi GRj))
+                (c-call VOID (.str "@cpu@_write_mem_" mode)
+                        pc address (.sym regtype k))
+                (set GRi address))
+       profile
+  )
+)
+
+(store-r-r-u stbu  QI OP_03 OPE1_10 GR NA
+            ((fr400 (unit u-gr-store)) (fr500 (unit u-gr-store)))
+            "Store unsigned byte, update index")
+(store-r-r-u sthu  HI OP_03 OPE1_11 GR NA
+            ((fr400 (unit u-gr-store)) (fr500 (unit u-gr-store)))
+            "Store unsigned half, update index")
+(store-r-r-u stu   WI OP_03 OPE1_12 GR NA
+            ((fr400 (unit u-gr-store)) (fr500 (unit u-gr-store)))
+            "Store          word, update index")
+
+(store-r-r-u stbfu QI OP_03 OPE1_18 FRint FR-ACCESS
+            ((fr400 (unit u-fr-store)) (fr500 (unit u-fr-store)))
+            "Store byte float, update index")
+(store-r-r-u sthfu HI OP_03 OPE1_19 FRint FR-ACCESS
+            ((fr400 (unit u-fr-store)) (fr500 (unit u-fr-store)))
+            "Store half float, update index")
+(store-r-r-u stfu  SI OP_03 OPE1_1A FRint FR-ACCESS
+            ((fr400 (unit u-fr-store)) (fr500 (unit u-fr-store)))
+            "Store word float, update index")
+
+(store-r-r-u stcu  SI OP_03 OPE1_2D CPR (MACH frv) ()
+            "Store coprocessor word, update index")
+
+(define-pmacro (store-double-r-r-u
+               name mode op ope regtype attr profile comment)
+  (dni name
+       (comment)
+       ((UNIT I0) (FR500-MAJOR I-3) (FR400-MAJOR I-3) attr)
+       (.str name "$pack $" regtype "k,@($GRi,$GRj)")
+       (+ pack (.sym regtype k) op GRi ope GRj)
+       (sequence ((WI address))
+                (store-double-semantics mode regtype address GRj)
+                (set GRi address))
+       profile
+  )
+)
+
+(store-double-r-r-u stdu  DI OP_03 OPE1_13 GR  NA
+                   ((fr400 (unit u-gr-store)) (fr500 (unit u-gr-store)))
+                   "Store double word, update index")
+(store-double-r-r-u stdfu DF OP_03 OPE1_1B FR  FR-ACCESS
+                   ((fr400 (unit u-fr-store)) (fr500 (unit u-fr-store)))
+                   "Store double float,update index")
+(store-double-r-r-u stdcu DI OP_03 OPE1_2E CPR (MACH frv) ()
+                   "Store coprocessor double word, update index")
+
+(define-pmacro (store-quad-r-r-u name op ope regtype attr profile comment)
+  (dni name
+       (comment)
+       ((UNIT I0) (FR500-MAJOR I-3) (MACH frv) attr)
+       (.str name "$pack $" regtype "k,@($GRi,$GRj)")
+       (+ pack (.sym regtype k) op GRi ope GRj)
+       (sequence ((WI address))
+                (store-quad-semantics regtype address GRj)
+                (set GRi address))
+       profile
+  )
+)
+
+(store-quad-r-r-u stqu  OP_03 OPE1_14 GR    NA
+                 ((fr500 (unit u-gr-store)))
+                 "Store quad word, update index")
+(store-quad-r-r-u stqfu OP_03 OPE1_1C FRint FR-ACCESS
+                 ((fr500 (unit u-fr-store)))
+                 "Store quad float, update index")
+(store-quad-r-r-u stqcu OP_03 OPE1_2F CPR   NA ()
+                 "Store coprocessor quad   word, update index")
+
+(define-pmacro (conditional-load name mode op ope regtype profile comment)
+  (dni name
+       (comment)
+       ((UNIT LOAD) (FR500-MAJOR I-2) (FR400-MAJOR I-2) CONDITIONAL)
+       (.str name "$pack @($GRi,$GRj),$" regtype "k,$CCi,$cond")
+       (+ pack (.sym regtype k) op GRi CCi  cond ope GRj)
+       (if (eq CCi (or cond 2))
+          (set (.sym regtype k)
+               (c-call mode (.str "@cpu@_read_mem_" mode) pc (add GRi GRj))))
+       profile
+  )
+)
+
+(conditional-load cldsb  QI OP_5E OPE4_0 GR
+                 ((fr400 (unit u-gr-load)) (fr500 (unit u-gr-load)))
+                 "Load   signed byte")
+(conditional-load cldub UQI OP_5E OPE4_1 GR
+                 ((fr400 (unit u-gr-load)) (fr500 (unit u-gr-load)))
+                 "Load unsigned byte")
+(conditional-load cldsh  HI OP_5E OPE4_2 GR
+                 ((fr400 (unit u-gr-load)) (fr500 (unit u-gr-load)))
+                 "Load   signed half")
+(conditional-load clduh UHI OP_5E OPE4_3 GR
+                 ((fr400 (unit u-gr-load)) (fr500 (unit u-gr-load)))
+                 "Load unsigned half")
+(conditional-load cld    SI OP_5F OPE4_0 GR
+                 ((fr400 (unit u-gr-load)) (fr500 (unit u-gr-load)))
+                 "Load          word")
+
+(conditional-load cldbf UQI OP_60 OPE4_0 FRint
+                 ((fr400 (unit u-fr-load)) (fr500 (unit u-fr-load)))
+                 "Load byte float")
+(conditional-load cldhf UHI OP_60 OPE4_1 FRint
+                 ((fr400 (unit u-fr-load)) (fr500 (unit u-fr-load)))
+                 "Load half float")
+(conditional-load cldf   SI OP_60 OPE4_2 FRint
+                 ((fr400 (unit u-fr-load)) (fr500 (unit u-fr-load)))
+                 "Load word float")
+
+(define-pmacro (conditional-load-double
+               name not_gr mode op ope regtype attr profile comment)
+  (dni name
+       (comment)
+       ((UNIT LOAD) (FR500-MAJOR I-2) (FR400-MAJOR I-2) CONDITIONAL attr)
+       (.str name "$pack @($GRi,$GRj),$" regtype "doublek,$CCi,$cond")
+       (+ pack (.sym regtype doublek) op GRi CCi  cond ope GRj)
+       (if (eq CCi (or cond 2))
+          (sequence ((WI address))
+                    (load-double-semantics not_gr mode regtype address GRj)))
+       profile
+  )
+)
+
+(conditional-load-double cldd  0 DI OP_5F OPE4_1 GR NA
+                        ((fr400 (unit u-gr-load)) (fr500 (unit u-gr-load)))
+                        "Load double word")
+(conditional-load-double clddf 1 DF OP_60 OPE4_3 FR FR-ACCESS
+                        ((fr400 (unit u-gr-load)) (fr500 (unit u-gr-load)))
+                        "Load double float")
+
+(dni cldq
+     "conditional load quad integer"
+     ((UNIT LOAD) (FR500-MAJOR I-2) (MACH frv) CONDITIONAL)
+     "cldq$pack @($GRi,$GRj),$GRk,$CCi,$cond"
+     (+ pack GRk OP_5F GRi CCi cond OPE4_2 GRj)
+     (if (eq CCi (or cond 2))
+        (sequence ((WI address))
+                  (load-quad-semantics GR address GRj)))
+     ((fr500 (unit u-gr-load)))
+)
+
+(define-pmacro (conditional-load-gr-u name mode op ope comment)
+  (dni name
+       (comment)
+       ((UNIT LOAD) (FR500-MAJOR I-2) (FR400-MAJOR I-2) CONDITIONAL)
+       (.str name "$pack @($GRi,$GRj),$GRk,$CCi,$cond")
+       (+ pack GRk op GRi CCi  cond ope GRj)
+       (if (eq CCi (or cond 2))
+          (sequence ((WI address))
+                    (set address (add GRi GRj))
+                    (set GRk
+                         (c-call mode (.str "@cpu@_read_mem_" mode)
+                                 pc address))
+                    (if (ne (index-of GRi) (index-of GRk))
+                        (set GRi address))))
+       ((fr400 (unit u-gr-load))
+       (fr500 (unit u-gr-load)))
+  )
+)
+
+(conditional-load-gr-u cldsbu  QI OP_61 OPE4_0 "Load   signed byte, update")
+(conditional-load-gr-u cldubu UQI OP_61 OPE4_1 "Load unsigned byte, update")
+(conditional-load-gr-u cldshu  HI OP_61 OPE4_2 "Load   signed half, update")
+(conditional-load-gr-u clduhu UHI OP_61 OPE4_3 "Load unsigned half, update")
+(conditional-load-gr-u cldu    SI OP_62 OPE4_0 "Load          word, update")
+
+(define-pmacro (conditional-load-non-gr-u name mode op ope regtype comment)
+  (dni name
+       (comment)
+       ((UNIT LOAD) (FR500-MAJOR I-2) (FR400-MAJOR I-2) CONDITIONAL FR-ACCESS)
+       (.str name "$pack @($GRi,$GRj),$" regtype "k,$CCi,$cond")
+       (+ pack (.sym regtype k) op GRi CCi  cond ope GRj)
+       (if (eq CCi (or cond 2))
+          (sequence ((WI address))
+                    (set address (add GRi GRj))
+                    (set (.sym regtype k)
+                         (c-call mode (.str "@cpu@_read_mem_" mode)
+                                 pc address))
+                    (set GRi address)))
+       ((fr400 (unit u-fr-load))
+       (fr500 (unit u-fr-load)))
+  )
+)
+
+(conditional-load-non-gr-u cldbfu UQI OP_63 OPE4_0 FRint "Load byte float, update")
+(conditional-load-non-gr-u cldhfu UHI OP_63 OPE4_1 FRint "Load half float, update")
+(conditional-load-non-gr-u cldfu   SI OP_63 OPE4_2 FRint "Load word float, update")
+
+
+(dni clddu
+     "Load double word,  update"
+     ((UNIT LOAD) (FR500-MAJOR I-2) (FR400-MAJOR I-2) CONDITIONAL)
+     "clddu$pack @($GRi,$GRj),$GRdoublek,$CCi,$cond"
+     (+ pack GRdoublek OP_62 GRi CCi cond OPE4_1 GRj)
+     (if (eq CCi (or cond 2))
+        (sequence ((WI address))
+                  (load-double-semantics 0 DI GR address GRj)
+                  (if (ne (index-of GRi) (index-of GRdoublek))
+                      (set GRi address))))
+     ((fr400 (unit u-gr-load))
+      (fr500 (unit u-gr-load)))
+)
+
+(dni clddfu
+     "Load double float, update"
+     ((UNIT LOAD) (FR500-MAJOR I-2) (FR400-MAJOR I-2) CONDITIONAL FR-ACCESS)
+     "clddfu$pack @($GRi,$GRj),$FRdoublek,$CCi,$cond"
+     (+ pack FRdoublek OP_63 GRi CCi cond OPE4_3 GRj)
+     (if (eq CCi (or cond 2))
+        (sequence ((WI address))
+                  (load-double-semantics 1 DF FR address GRj)
+                  (set GRi address)))
+     ((fr400 (unit u-fr-load))
+      (fr500 (unit u-fr-load)))
+)
+
+(dni cldqu
+     "conditional load quad integer and update index"
+     ((UNIT LOAD) (FR500-MAJOR I-2) (MACH frv) CONDITIONAL)
+     "cldqu$pack @($GRi,$GRj),$GRk,$CCi,$cond"
+     (+ pack GRk OP_62 GRi CCi cond OPE4_2 GRj)
+     (if (eq CCi (or cond 2))
+        (sequence ((WI address))
+                  (load-quad-semantics GR address GRj)
+                  (if (ne (index-of GRi) (index-of GRk))
+                      (set GRi address))))
+     ((fr500 (unit u-gr-load)))
+)
+
+(define-pmacro (conditional-store name mode op ope regtype profile comment)
+  (dni name
+       (comment)
+       ((UNIT I0) (FR500-MAJOR I-3) (FR400-MAJOR I-3) CONDITIONAL)
+       (.str name "$pack $" regtype "k,@($GRi,$GRj),$CCi,$cond")
+       (+ pack (.sym regtype k) op GRi CCi cond ope GRj)
+       (if (eq CCi (or cond 2))
+          (c-call VOID (.str "@cpu@_write_mem_" mode)
+                  pc (add GRi GRj) (.sym regtype k)))
+       profile
+  )
+)
+
+(conditional-store cstb  QI OP_64 OPE4_0 GR
+                  ((fr400 (unit u-gr-store)) (fr500 (unit u-gr-store)))
+                  "Store unsigned byte")
+(conditional-store csth  HI OP_64 OPE4_1 GR
+                  ((fr400 (unit u-gr-store)) (fr500 (unit u-gr-store)))
+                  "Store unsigned half")
+(conditional-store cst   SI OP_64 OPE4_2 GR
+                  ((fr400 (unit u-gr-store)) (fr500 (unit u-gr-store)))
+                  "Store          word")
+
+(conditional-store cstbf QI OP_66 OPE4_0 FRint
+                  ((fr400 (unit u-fr-store)) (fr500 (unit u-fr-store)))
+                  "Store byte float")
+(conditional-store csthf HI OP_66 OPE4_1 FRint
+                  ((fr400 (unit u-fr-store)) (fr500 (unit u-fr-store)))
+                  "Store half float")
+(conditional-store cstf  SI OP_66 OPE4_2 FRint
+                  ((fr400 (unit u-fr-store)) (fr500 (unit u-fr-store)))
+                  "Store word float")
+
+(define-pmacro (conditional-store-double
+               name mode op ope regtype attr profile comment)
+  (dni name
+       (comment)
+       ((UNIT I0) (FR500-MAJOR I-3) (FR400-MAJOR I-3) CONDITIONAL attr)
+       (.str name "$pack $" regtype "k,@($GRi,$GRj),$CCi,$cond")
+       (+ pack (.sym regtype k) op GRi CCi  cond ope GRj)
+       (if (eq CCi (or cond 2))
+          (sequence ((WI address))
+                    (store-double-semantics mode regtype address GRj)))
+       profile
+  )
+)
+
+(conditional-store-double cstd  DI OP_64 OPE4_3 GR NA
+                         ((fr400 (unit u-gr-store)) (fr500 (unit u-gr-store)))
+                         "Store double word")
+(conditional-store-double cstdf DF OP_66 OPE4_3 FR FR-ACCESS
+                         ((fr400 (unit u-fr-store)) (fr500 (unit u-fr-store)))
+                         "Store double float")
+
+(dni cstq
+     "conditionally store quad word"
+     ((UNIT I0) (FR500-MAJOR I-3) (MACH frv) CONDITIONAL)
+     "cstq$pack $GRk,@($GRi,$GRj),$CCi,$cond"
+     (+ pack GRk OP_65 GRi CCi cond OPE4_0 GRj)
+     (if (eq CCi (or cond 2))
+        (sequence ((WI address))
+                  (store-quad-semantics GR address GRj)))
+     ((fr500 (unit u-gr-store)))
+)
+
+(define-pmacro (conditional-store-u
+               name mode op ope regtype attr profile comment)
+  (dni name
+       (comment)
+       ((UNIT I0) (FR500-MAJOR I-3) (FR400-MAJOR I-3) CONDITIONAL attr)
+       (.str name "$pack $" regtype "k,@($GRi,$GRj),$CCi,$cond")
+       (+ pack (.sym regtype k) op GRi CCi  cond ope GRj)
+       (if (eq CCi (or cond 2))
+          (sequence ((WI address))
+                    (set address (add GRi GRj))
+                    (c-call VOID (.str "@cpu@_write_mem_" mode)
+                            pc address (.sym regtype k))
+                    (set GRi address)))
+       profile
+  )
+)
+
+(conditional-store-u cstbu QI OP_67 OPE4_0 GR NA
+                    ((fr400 (unit u-gr-store)) (fr500 (unit u-gr-store)))
+                    "Store unsigned byte, update index")
+(conditional-store-u csthu HI OP_67 OPE4_1 GR NA
+                    ((fr400 (unit u-gr-store)) (fr500 (unit u-gr-store)))
+                    "Store unsigned half, update index")
+(conditional-store-u cstu  SI OP_67 OPE4_2 GR NA
+                    ((fr400 (unit u-gr-store)) (fr500 (unit u-gr-store)))
+                    "Store          word, update index")
+
+(conditional-store-u cstbfu QI OP_68 OPE4_0 FRint FR-ACCESS
+                    ((fr400 (unit u-fr-store)) (fr500 (unit u-fr-store)))
+                    "Store byte float, update index")
+(conditional-store-u csthfu HI OP_68 OPE4_1 FRint FR-ACCESS
+                    ((fr400 (unit u-fr-store)) (fr500 (unit u-fr-store)))
+                    "Store half float, update index")
+(conditional-store-u cstfu  SI OP_68 OPE4_2 FRint FR-ACCESS
+                    ((fr400 (unit u-fr-store)) (fr500 (unit u-fr-store)))
+                    "Store word float, update index")
+
+(define-pmacro (conditional-store-double-u
+               name mode op ope regtype attr profile comment)
+  (dni name
+       (comment)
+       ((UNIT I0) (FR500-MAJOR I-3) (FR400-MAJOR I-3) CONDITIONAL attr)
+       (.str name "$pack $" regtype "k,@($GRi,$GRj),$CCi,$cond")
+       (+ pack (.sym regtype k) op GRi CCi  cond ope GRj)
+       (if (eq CCi (or cond 2))
+          (sequence ((WI address))
+                    (store-double-semantics mode regtype address GRj)
+                    (set GRi address)))
+       profile
+  )
+)
+
+(conditional-store-double-u cstdu  DI OP_67 OPE4_3 GR NA
+                           ((fr400 (unit u-gr-store))
+                            (fr500 (unit u-gr-store)))
+                           "Store double word, update index")
+(conditional-store-double-u cstdfu DF OP_68 OPE4_3 FR FR-ACCESS
+                           ((fr400 (unit u-fr-store)) (fr500 (unit u-fr-store)))
+                           "Store double float, update index")
+
+(define-pmacro (store-r-simm name mode op regtype attr profile comment)
+  (dni name
+       (comment)
+       ((UNIT I0) (FR500-MAJOR I-3) (FR400-MAJOR I-3) attr)
+       (.str name "$pack $" regtype "k,@($GRi,$d12)")
+       (+ pack (.sym regtype k) op GRi d12)
+       (c-call VOID (.str "@cpu@_write_mem_" mode)
+              pc (add GRi d12) (.sym regtype k))
+       profile
+  )
+)
+
+(store-r-simm stbi QI OP_50 GR NA
+             ((fr400 (unit u-gr-store)) (fr500 (unit u-gr-store)))
+             "Store unsigned byte")
+(store-r-simm sthi HI OP_51 GR NA
+             ((fr400 (unit u-gr-store)) (fr500 (unit u-gr-store)))
+             "Store unsigned half")
+(store-r-simm sti  SI OP_52 GR NA
+             ((fr400 (unit u-gr-store)) (fr500 (unit u-gr-store)))
+             "Store          word")
+
+(store-r-simm stbfi QI OP_4E FRint FR-ACCESS
+             ((fr400 (unit u-fr-store)) (fr500 (unit u-fr-store)))
+             "Store byte float")
+(store-r-simm sthfi HI OP_4F FRint FR-ACCESS
+             ((fr400 (unit u-fr-store)) (fr500 (unit u-fr-store)))
+             "Store half float")
+(store-r-simm stfi  SI OP_55 FRint FR-ACCESS
+             ((fr400 (unit u-fr-store)) (fr500 (unit u-fr-store)))
+             "Store word float")
+
+(define-pmacro (store-double-r-simm name mode op regtype attr profile comment)
+  (dni name
+       (comment)
+       ((UNIT I0) (FR500-MAJOR I-3) (FR400-MAJOR I-3) attr)
+       (.str name "$pack $" regtype "k,@($GRi,$d12)")
+       (+ pack (.sym regtype k) op GRi d12)
+       (sequence ((WI address))
+                (store-double-semantics mode regtype address d12))
+       profile
+  )
+)
+
+(store-double-r-simm stdi  DI OP_53 GR NA
+                    ((fr400 (unit u-gr-store)) (fr500 (unit u-gr-store)))
+                    "Store double word")
+(store-double-r-simm stdfi DF OP_56 FR FR-ACCESS
+                    ((fr400 (unit u-fr-store)) (fr500 (unit u-fr-store)))
+                    "Store double float")
+
+(define-pmacro (store-quad-r-simm name op regtype attr profile comment)
+  (dni name
+       (comment)
+       ((UNIT I0) (FR500-MAJOR I-3) (MACH frv) attr)
+       (.str name "$pack $" regtype "k,@($GRi,$d12)")
+       (+ pack (.sym regtype k) op GRi d12)
+       (sequence ((WI address))
+                (store-quad-semantics regtype address d12))
+       profile
+  )
+)
+
+(store-quad-r-simm stqi  OP_54 GR    NA ((fr500 (unit u-gr-store)))
+                  "Store quad word")
+(store-quad-r-simm stqfi OP_57 FRint FR-ACCESS ()
+                  "Store quad float")
+
+(define-pmacro (swap-semantics base offset arg)
+  (sequence ((WI tmp) (WI address))
+           (set tmp arg)
+           (set address (add base offset))
+           (set arg (c-call WI "@cpu@_read_mem_WI" pc address))
+           (c-call VOID "@cpu@_write_mem_WI" pc address tmp))
+)
+
+(dni swap
+     "Swap contents of memory with GR"
+     ((UNIT C) (FR500-MAJOR C-2) (FR400-MAJOR C-2))
+     "swap$pack @($GRi,$GRj),$GRk"
+     (+ pack GRk OP_03 GRi OPE1_05 GRj)
+     (swap-semantics GRi GRj GRk)
+     ((fr400 (unit u-swap))
+      (fr500 (unit u-swap)))
+)
+
+(dni "swapi"
+     "Swap contents of memory with GR"
+     ((UNIT C) (FR500-MAJOR C-2) (FR400-MAJOR C-2))
+     ("swapi$pack @($GRi,$d12),$GRk")
+     (+ pack GRk OP_4D GRi d12)
+     (swap-semantics GRi d12 GRk)
+     ((fr400 (unit u-swap))
+      (fr500 (unit u-swap)))
+)
+
+(dni cswap
+     "Conditionally swap contents of memory with GR"
+     ((UNIT C) (FR500-MAJOR C-2) (FR400-MAJOR C-2) CONDITIONAL)
+     "cswap$pack @($GRi,$GRj),$GRk,$CCi,$cond"
+     (+ pack GRk OP_65 GRi CCi cond OPE4_2 GRj)
+     (if (eq CCi (or cond 2))
+        (swap-semantics GRi GRj GRk))
+     ((fr400 (unit u-swap))
+      (fr500 (unit u-swap)))
+)
+
+(define-pmacro (register-transfer
+               name op ope reg_src reg_targ pipe major1 major2 attr1 attr2
+               profile comment)
+  (dni name
+       (comment)
+       ((UNIT pipe) major1 major2 attr1 attr2)
+       (.str name "$pack $" reg_src ",$" reg_targ)
+       (+ pack reg_targ op (rs-null) ope reg_src)
+       (set reg_targ reg_src)
+       profile
+  )
+)
+
+(register-transfer movgf OP_03 OPE1_15
+                  GRj FRintk I0 (FR500-MAJOR I-4) (FR400-MAJOR I-4)
+                  FR-ACCESS NA
+                  ((fr400 (unit u-gr2fr)) (fr500 (unit u-gr2fr)))
+                  "transfer gr to fr")
+(register-transfer movfg OP_03 OPE1_0D
+                  FRintk GRj I0 (FR500-MAJOR I-4) (FR400-MAJOR I-4)
+                  FR-ACCESS NA
+                  ((fr400 (unit u-fr2gr)) (fr500 (unit u-fr2gr)))
+                  "transfer fr to gr")
+
+(define-pmacro (nextreg hw r offset) (reg hw (add (index-of r) offset)))
+
+(define-pmacro (register-transfer-double-from-gr-semantics cond)
+  (if cond
+      (if (eq (index-of GRj) 0)
+         (sequence ()
+                   (set FRintk 0)
+                   (set (nextreg h-fr_int FRintk 1) 0))
+         (sequence ()
+                   (set FRintk GRj)
+                   (set (nextreg h-fr_int FRintk 1) (nextreg h-gr GRj 1)))))
+)
+
+(dni movgfd
+     "move GR for FR double"
+     ((UNIT I0) (FR500-MAJOR I-4) (FR400-MAJOR I-4) FR-ACCESS)
+     "movgfd$pack $GRj,$FRintk"
+     (+ pack FRintk OP_03 (rs-null) OPE1_16 GRj)
+     (register-transfer-double-from-gr-semantics 1)
+     ; TODO -- doesn't handle second register in the pair
+     ((fr400 (unit u-gr2fr))
+      (fr500 (unit u-gr2fr)))
+)
+
+(define-pmacro (register-transfer-double-to-gr-semantics cond)
+  (if (andif (ne (index-of GRj) 0) cond)
+      (sequence ()
+               (set GRj FRintk)
+               (set (nextreg h-gr GRj 1) (nextreg h-fr_int FRintk 1))))
+)
+
+(dni movfgd
+     "move FR for GR double"
+     ((UNIT I0) (FR500-MAJOR I-4) (FR400-MAJOR I-4) FR-ACCESS)
+     "movfgd$pack $FRintk,$GRj"
+     (+ pack FRintk OP_03 (rs-null) OPE1_0E GRj)
+     (register-transfer-double-to-gr-semantics 1)
+     ; TODO -- doesn't handle second register in the pair
+     ((fr400 (unit u-fr2gr))
+      (fr500 (unit u-fr2gr)))
+)
+
+(dni movgfq
+     "move GR for FR quad"
+     ((UNIT I0) (FR500-MAJOR I-4) (MACH frv) FR-ACCESS)
+     "movgfq$pack $GRj,$FRintk"
+     (+ pack FRintk OP_03 (rs-null) OPE1_17 GRj)
+     (if (eq (index-of GRj) 0)
+        (sequence ()
+                  (set FRintk 0)
+                  (set (reg h-fr_int (add (index-of FRintk) 1)) 0)
+                  (set (reg h-fr_int (add (index-of FRintk) 2)) 0)
+                  (set (reg h-fr_int (add (index-of FRintk) 3)) 0))
+        (sequence ()
+                  (set FRintk GRj)
+                  (set (reg h-fr_int (add (index-of FRintk) 1))
+                       (reg h-gr (add (index-of GRj)    1)))
+                  (set (reg h-fr_int (add (index-of FRintk) 2))
+                       (reg h-gr (add (index-of GRj)    2)))
+                  (set (reg h-fr_int (add (index-of FRintk) 3))
+                       (reg h-gr (add (index-of GRj)    3)))))
+     ()
+)
+
+(dni movfgq
+     "move FR for GR quad"
+     ((UNIT I0) (FR500-MAJOR I-4) (MACH frv) FR-ACCESS)
+     "movfgq$pack $FRintk,$GRj"
+     (+ pack FRintk OP_03 (rs-null) OPE1_0F GRj)
+     (if (ne (index-of GRj) 0)
+        (sequence ()
+                  (set GRj FRintk)
+                  (set (reg h-gr (add (index-of GRj)    1))
+                       (reg h-fr_int (add (index-of FRintk) 1)))
+                  (set (reg h-gr (add (index-of GRj)    2))
+                       (reg h-fr_int (add (index-of FRintk) 2)))
+                  (set (reg h-gr (add (index-of GRj)    3))
+                       (reg h-fr_int (add (index-of FRintk) 3)))))
+     ()
+)
+
+(define-pmacro (conditional-register-transfer
+               name op ope reg_src reg_targ pipe major1 major2 mach
+               profile comment)
+  (dni name
+       (comment)
+       ((UNIT pipe) major1 major2 CONDITIONAL FR-ACCESS mach)
+       (.str name "$pack $" reg_src ",$" reg_targ ",$CCi,$cond")
+       (+ pack reg_targ op (rs-null) CCi cond ope reg_src)
+       (if (eq CCi (or cond 2))
+          (set reg_targ reg_src))
+       profile
+  )
+)
+
+(conditional-register-transfer cmovgf OP_69 OPE4_0 GRj FRintk I0
+                              (FR500-MAJOR I-4) (FR400-MAJOR I-4)
+                              NA
+                              ((fr400 (unit u-gr2fr)) (fr500 (unit u-gr2fr)))
+                              "transfer gr to fr")
+(conditional-register-transfer cmovfg OP_69 OPE4_2 FRintk GRj I0
+                              (FR500-MAJOR I-4) (FR400-MAJOR I-4)
+                              NA
+                              ((fr400 (unit u-fr2gr)) (fr500 (unit u-fr2gr)))
+                              "transfer fr to gr")
+
+
+(dni cmovgfd
+     "Conditional move GR to FR double"
+     ((UNIT I0) (FR500-MAJOR I-4) (FR400-MAJOR I-4) CONDITIONAL FR-ACCESS)
+     "cmovgfd$pack $GRj,$FRintk,$CCi,$cond"
+     (+ pack FRintk OP_69 (rs-null) CCi cond OPE4_1 GRj)
+     (register-transfer-double-from-gr-semantics (eq CCi (or cond 2)))
+     ; TODO -- doesn't handle extra registers in double
+     ((fr400 (unit u-gr2fr))
+      (fr500 (unit u-gr2fr)))
+)
+
+(dni cmovfgd
+     "Conditional move FR to GR double"
+     ((UNIT I0) (FR500-MAJOR I-4) (FR400-MAJOR I-4) CONDITIONAL FR-ACCESS)
+     "cmovfgd$pack $FRintk,$GRj,$CCi,$cond"
+     (+ pack FRintk OP_69 (rs-null) CCi cond OPE4_3 GRj)
+     (register-transfer-double-to-gr-semantics (eq CCi (or cond 2)))
+     ; TODO -- doesn't handle second register in the pair
+     ((fr400 (unit u-fr2gr))
+      (fr500 (unit u-fr2gr)))
+)
+
+(define-pmacro (register-transfer-spr
+               name op ope reg_src reg_targ unitname comment)
+  (dni name
+       (comment)
+       ((UNIT C) (FR500-MAJOR C-2) (FR400-MAJOR C-2))
+       (.str name "$pack $" reg_src ",$" reg_targ)
+       (+ pack reg_targ op ope reg_src)
+       (set reg_targ reg_src)
+       ((fr400 (unit unitname))
+       (fr500 (unit unitname)))
+  )
+)
+
+(register-transfer-spr movgs OP_03 OPE1_06 GRj spr u-gr2spr "transfer gr->spr")
+(register-transfer-spr movsg OP_03 OPE1_07 spr GRj u-spr2gr "transfer spr->gr")
+
+; Integer Branch Conditions
+(define-pmacro (Inev cc) (const BI 0))
+(define-pmacro (Ira  cc) (const BI 1))
+(define-pmacro (Ieq  cc) (     zbit cc))
+(define-pmacro (Ine  cc) (not (zbit cc)))
+(define-pmacro (Ile  cc) (     orif (zbit cc) (xor (nbit cc) (vbit cc))))
+(define-pmacro (Igt  cc) (not (orif (zbit cc) (xor (nbit cc) (vbit cc)))))
+(define-pmacro (Ilt  cc) (     xor  (nbit cc) (vbit cc)))
+(define-pmacro (Ige  cc) (not (xor  (nbit cc) (vbit cc))))
+(define-pmacro (Ils  cc) (     orif (cbit cc) (zbit cc)))
+(define-pmacro (Ihi  cc) (not (orif (cbit cc) (zbit cc))))
+(define-pmacro (Ic   cc) (     cbit cc))
+(define-pmacro (Inc  cc) (not (cbit cc)))
+(define-pmacro (In   cc) (     nbit cc))
+(define-pmacro (Ip   cc) (not (nbit cc)))
+(define-pmacro (Iv   cc) (     vbit cc))
+(define-pmacro (Inv  cc) (not (vbit cc)))
+
+; Float Branch Conditions
+(define-pmacro (Fnev cc) (const BI 0))
+(define-pmacro (Fra  cc) (const BI 1))
+(define-pmacro (Fne  cc) (orif (lbit cc) (orif (gbit cc) (ubit cc))))
+(define-pmacro (Feq  cc) (ebit cc))
+(define-pmacro (Flg  cc) (orif (lbit cc) (gbit cc)))
+(define-pmacro (Fue  cc) (orif (ebit cc) (ubit cc)))
+(define-pmacro (Ful  cc) (orif (lbit cc) (ubit cc)))
+(define-pmacro (Fge  cc) (orif (ebit cc) (gbit cc)))
+(define-pmacro (Flt  cc) (lbit cc))
+(define-pmacro (Fuge cc) (orif (ebit cc) (orif (gbit cc) (ubit cc))))
+(define-pmacro (Fug  cc) (orif (gbit cc) (ubit cc)))
+(define-pmacro (Fle  cc) (orif (ebit cc) (lbit cc)))
+(define-pmacro (Fgt  cc) (gbit cc))
+(define-pmacro (Fule cc) (orif (ebit cc) (orif (lbit cc) (ubit cc))))
+(define-pmacro (Fu   cc) (ubit cc))
+(define-pmacro (Fo   cc) (orif (ebit cc) (orif (lbit cc) (gbit cc))))
+
+(define-pmacro (conditional-branch-i prefix cc op cond comment)
+  (dni (.sym prefix cc)
+       (comment)
+       ((UNIT B01) (FR500-MAJOR B-1) (FR400-MAJOR B-1))
+       (.str (.sym prefix cc) "$pack $ICCi_2,$hint,$label16")
+       (+ pack (.sym ICC_ cc) ICCi_2 op hint label16)
+       (sequence ()
+                (c-call VOID "@cpu@_model_branch" label16 hint)
+                (if (cond ICCi_2)
+                    (set pc label16)))
+       ((fr400 (unit u-branch))
+       (fr500 (unit u-branch)))
+  )
+)
+
+(dni bra
+     "integer branch equal"
+      ((UNIT B01) (FR500-MAJOR B-1) (FR400-MAJOR B-1))
+      "bra$pack $hint_taken$label16"
+      (+ pack ICC_ra (ICCi_2-null) OP_06 hint_taken label16)
+      (sequence ()
+               (c-call VOID "@cpu@_model_branch" label16 hint_taken)
+               (set pc label16))
+      ((fr400 (unit u-branch))
+       (fr500 (unit u-branch)))
+)
+
+(dni bno
+     "integer branch never"
+      ((UNIT B01) (FR500-MAJOR B-1) (FR400-MAJOR B-1))
+      "bno$pack$hint_not_taken"
+      (+ pack ICC_nev (ICCi_2-null) OP_06 hint_not_taken (label16-null))
+      (c-call VOID "@cpu@_model_branch" label16 hint_not_taken)
+      ((fr400 (unit u-branch))
+       (fr500 (unit u-branch)))
+)
+
+(conditional-branch-i b eq  OP_06 Ieq  "integer branch equal")
+(conditional-branch-i b ne  OP_06 Ine  "integer branch not equal")
+(conditional-branch-i b le  OP_06 Ile  "integer branch less or equal")
+(conditional-branch-i b gt  OP_06 Igt  "integer branch greater")
+(conditional-branch-i b lt  OP_06 Ilt  "integer branch less")
+(conditional-branch-i b ge  OP_06 Ige  "integer branch greater or equal")
+(conditional-branch-i b ls  OP_06 Ils  "integer branch less or equal unsigned")
+(conditional-branch-i b hi  OP_06 Ihi  "integer branch greater unsigned")
+(conditional-branch-i b c   OP_06 Ic   "integer branch carry set")
+(conditional-branch-i b nc  OP_06 Inc  "integer branch carry clear")
+(conditional-branch-i b n   OP_06 In   "integer branch negative")
+(conditional-branch-i b p   OP_06 Ip   "integer branch positive")
+(conditional-branch-i b v   OP_06 Iv   "integer branch overflow set")
+(conditional-branch-i b nv  OP_06 Inv  "integer branch overflow clear")
+
+(define-pmacro (conditional-branch-f prefix cc op cond comment)
+  (dni (.sym prefix cc)
+       (comment)
+       ((UNIT B01) (FR500-MAJOR B-1) (FR400-MAJOR B-1) FR-ACCESS)
+       (.str (.sym prefix cc) "$pack $FCCi_2,$hint,$label16")
+       (+ pack (.sym FCC_ cc) FCCi_2 op hint label16)
+       (sequence ()
+                (c-call VOID "@cpu@_model_branch" label16 hint)
+                (if (cond FCCi_2) (set pc label16)))
+       ((fr400 (unit u-branch))
+       (fr500 (unit u-branch)))
+  )
+)
+
+(dni fbra
+     "float branch equal"
+      ((UNIT B01) (FR500-MAJOR B-1) (FR400-MAJOR B-1) FR-ACCESS)
+      "fbra$pack $hint_taken$label16"
+      (+ pack FCC_ra (FCCi_2-null) OP_07 hint_taken label16)
+      (sequence ()
+               (c-call VOID "@cpu@_model_branch" label16 hint_taken)
+               (set pc label16))
+      ((fr400 (unit u-branch))
+       (fr500 (unit u-branch)))
+)
+
+(dni fbno
+     "float branch never"
+      ((UNIT B01) (FR500-MAJOR B-1) (FR400-MAJOR B-1) FR-ACCESS)
+      "fbno$pack$hint_not_taken"
+      (+ pack FCC_nev (FCCi_2-null) OP_07 hint_not_taken (label16-null))
+      (c-call VOID "@cpu@_model_branch" label16 hint_not_taken)
+      ((fr400 (unit u-branch))
+       (fr500 (unit u-branch)))
+)
+
+(conditional-branch-f fb ne  OP_07 Fne  "float branch not equal")
+(conditional-branch-f fb eq  OP_07 Feq  "float branch equal")
+(conditional-branch-f fb lg  OP_07 Flg  "float branch less or greater")
+(conditional-branch-f fb ue  OP_07 Fue  "float branch unordered or equal")
+(conditional-branch-f fb ul  OP_07 Ful  "float branch unordered or less")
+(conditional-branch-f fb ge  OP_07 Fge  "float branch greater or equal")
+(conditional-branch-f fb lt  OP_07 Flt  "float branch less")
+(conditional-branch-f fb uge OP_07 Fuge "float branch unordered, greater,equal")
+(conditional-branch-f fb ug  OP_07 Fug  "float branch unordered or greater")
+(conditional-branch-f fb le  OP_07 Fle  "float branch less or equal")
+(conditional-branch-f fb gt  OP_07 Fgt  "float branch greater")
+(conditional-branch-f fb ule OP_07 Fule "float branch unordered, less or equal")
+(conditional-branch-f fb u   OP_07 Fu   "float branch unordered")
+(conditional-branch-f fb o   OP_07 Fo   "float branch ordered")
+
+(define-pmacro (ctrlr-branch-semantics cond ccond)
+  (sequence ((SI tmp))
+           (set tmp (sub (spr-lcr) 1))
+           (set (spr-lcr) tmp)
+           (if cond
+               (if (eq ccond 0)
+                   (if (ne tmp 0)
+                       (set pc (spr-lr)))
+                   (if (eq tmp 0)
+                       (set pc (spr-lr))))))
+)
+
+(dni bctrlr
+     "LCR conditional branch to lr"
+     ((UNIT B0) (FR500-MAJOR B-2) (FR400-MAJOR B-2))
+     ("bctrlr$pack $ccond,$hint")
+     (+ pack (cond-null) (ICCi_2-null) OP_0E hint OPE3_01 ccond (s12-null))
+     (sequence ()
+              (c-call VOID "@cpu@_model_branch" (spr-lr) hint)
+              (ctrlr-branch-semantics (const BI 1) ccond))
+     ((fr400 (unit u-branch))
+      (fr500 (unit u-branch)))
+)
+
+(define-pmacro (conditional-branch-cclr prefix cc i-f op ope cond attr comment)
+  (dni (.sym prefix cc lr)
+       (comment)
+       ((UNIT B01) (FR500-MAJOR B-3) (FR400-MAJOR B-3) attr)
+       (.str (.sym prefix cc lr) "$pack $" i-f "CCi_2,$hint")
+       (+ pack (.sym i-f CC_ cc) (.sym i-f CCi_2) op hint ope
+         (ccond-null) (s12-null))
+       (sequence ()
+                (c-call VOID "@cpu@_model_branch" (spr-lr) hint)
+                (if (cond (.sym i-f CCi_2)) (set pc (spr-lr))))
+       ((fr400 (unit u-branch))
+       (fr500 (unit u-branch)))
+  )
+)
+
+(dni bralr
+     "integer cclr branch always"
+     ((UNIT B01) (FR500-MAJOR B-3) (FR400-MAJOR B-3))
+     "bralr$pack$hint_taken"
+     (+ pack ICC_ra (ICCi_2-null) OP_0E hint_taken OPE3_02 (ccond-null) (s12-null))
+     (sequence ()
+              (c-call VOID "@cpu@_model_branch" (spr-lr) hint_taken)
+              (set pc (spr-lr)))
+     ((fr400 (unit u-branch))
+      (fr500 (unit u-branch)))
+)
+
+(dni bnolr
+     "integer cclr branch never"
+     ((UNIT B01) (FR500-MAJOR B-3) (FR400-MAJOR B-3))
+     "bnolr$pack$hint_not_taken"
+     (+ pack ICC_nev (ICCi_2-null) OP_0E hint_not_taken OPE3_02 (ccond-null) (s12-null))
+     (c-call VOID "@cpu@_model_branch" (spr-lr) hint_not_taken)
+     ((fr400 (unit u-branch))
+      (fr500 (unit u-branch)))
+)
+
+(conditional-branch-cclr b eq  I OP_0E OPE3_02 Ieq  NA "integer cclr branch equal")
+(conditional-branch-cclr b ne  I OP_0E OPE3_02 Ine  NA "integer cclr branch not equal")
+(conditional-branch-cclr b le  I OP_0E OPE3_02 Ile  NA "integer cclr branch less or equal")
+(conditional-branch-cclr b gt  I OP_0E OPE3_02 Igt  NA "integer cclr branch greater")
+(conditional-branch-cclr b lt  I OP_0E OPE3_02 Ilt  NA "integer cclr branch less")
+(conditional-branch-cclr b ge  I OP_0E OPE3_02 Ige  NA "integer cclr branch greater or equal")
+(conditional-branch-cclr b ls  I OP_0E OPE3_02 Ils  NA "integer cclr branch less or equal unsigned")
+(conditional-branch-cclr b hi  I OP_0E OPE3_02 Ihi  NA "integer cclr branch greater unsigned")
+(conditional-branch-cclr b c   I OP_0E OPE3_02 Ic   NA "integer cclr branch carry set")
+(conditional-branch-cclr b nc  I OP_0E OPE3_02 Inc  NA "integer cclr branch carry clear")
+(conditional-branch-cclr b n   I OP_0E OPE3_02 In   NA "integer cclr branch negative")
+(conditional-branch-cclr b p   I OP_0E OPE3_02 Ip   NA "integer cclr branch positive")
+(conditional-branch-cclr b v   I OP_0E OPE3_02 Iv   NA "integer cclr branch overflow set")
+(conditional-branch-cclr b nv  I OP_0E OPE3_02 Inv  NA "integer cclr branch overflow clear")
+
+(dni fbralr
+     "float cclr branch always"
+     ((UNIT B01) (FR500-MAJOR B-3) (FR400-MAJOR B-3) FR-ACCESS)
+     "fbralr$pack$hint_taken"
+     (+ pack FCC_ra (FCCi_2-null) OP_0E hint_taken OPE3_06 (ccond-null) (s12-null))
+     (sequence ()
+              (c-call VOID "@cpu@_model_branch" (spr-lr) hint_taken)
+              (set pc (spr-lr)))
+     ((fr400 (unit u-branch))
+      (fr500 (unit u-branch)))
+)
+
+(dni fbnolr
+     "float cclr branch never"
+     ((UNIT B01) (FR500-MAJOR B-3) (FR400-MAJOR B-3) FR-ACCESS)
+     "fbnolr$pack$hint_not_taken"
+     (+ pack FCC_nev (FCCi_2-null) OP_0E hint_not_taken OPE3_06 (ccond-null) (s12-null))
+     (c-call VOID "@cpu@_model_branch" (spr-lr) hint_not_taken)
+     ((fr400 (unit u-branch))
+      (fr500 (unit u-branch)))
+)
+
+(conditional-branch-cclr fb eq  F OP_0E OPE3_06 Feq  FR-ACCESS "float cclr branch equal")
+(conditional-branch-cclr fb ne  F OP_0E OPE3_06 Fne  FR-ACCESS "float cclr branch not equal")
+(conditional-branch-cclr fb lg  F OP_0E OPE3_06 Flg  FR-ACCESS "float branch less or greater")
+(conditional-branch-cclr fb ue  F OP_0E OPE3_06 Fue  FR-ACCESS "float branch unordered or equal")
+(conditional-branch-cclr fb ul  F OP_0E OPE3_06 Ful  FR-ACCESS "float branch unordered or less")
+(conditional-branch-cclr fb ge  F OP_0E OPE3_06 Fge  FR-ACCESS "float branch greater or equal")
+(conditional-branch-cclr fb lt  F OP_0E OPE3_06 Flt  FR-ACCESS "float branch less")
+(conditional-branch-cclr fb uge F OP_0E OPE3_06 Fuge FR-ACCESS "float branch unordered, greater, equal")
+(conditional-branch-cclr fb ug  F OP_0E OPE3_06 Fug  FR-ACCESS "float branch unordered or greater")
+(conditional-branch-cclr fb le  F OP_0E OPE3_06 Fle  FR-ACCESS "float branch less or equal")
+(conditional-branch-cclr fb gt  F OP_0E OPE3_06 Fgt  FR-ACCESS "float branch greater")
+(conditional-branch-cclr fb ule F OP_0E OPE3_06 Fule FR-ACCESS "float branch unordered, less or equal")
+(conditional-branch-cclr fb u   F OP_0E OPE3_06 Fu   FR-ACCESS "float branch unordered")
+(conditional-branch-cclr fb o   F OP_0E OPE3_06 Fo   FR-ACCESS "float branch ordered")
+
+(define-pmacro (conditional-branch-ctrlr prefix cc i-f op ope cond attr comment)
+  (dni (.sym prefix cc lr)
+       (comment)
+       ((UNIT B0) (FR500-MAJOR B-2) (FR400-MAJOR B-2) attr)
+       (.str (.sym prefix cc lr) "$pack $" i-f "CCi_2,$ccond,$hint")
+       (+ pack (.sym i-f CC_ cc) (.sym i-f CCi_2) op hint ope ccond (s12-null))
+       (sequence ()
+                (c-call VOID "@cpu@_model_branch" (spr-lr) hint)
+                (ctrlr-branch-semantics (cond (.sym i-f CCi_2)) ccond))
+       ((fr400 (unit u-branch))
+       (fr500 (unit u-branch)))
+  )
+)
+
+(dni bcralr
+     "integer ctrlr branch always"
+     ((UNIT B0) (FR500-MAJOR B-2) (FR400-MAJOR B-2))
+     "bcralr$pack $ccond$hint_taken"
+     (+ pack ICC_ra (ICCi_2-null) OP_0E hint_taken OPE3_03 ccond (s12-null))
+     (sequence ()
+              (c-call VOID "@cpu@_model_branch" (spr-lr) hint_taken)
+              (ctrlr-branch-semantics (const BI 1) ccond))
+     ((fr400 (unit u-branch))
+      (fr500 (unit u-branch)))
+)
+
+(dni bcnolr
+     "integer ctrlr branch never"
+     ((UNIT B0) (FR500-MAJOR B-2) (FR400-MAJOR B-2))
+     "bcnolr$pack$hint_not_taken"
+     (+ pack ICC_nev (ICCi_2-null) OP_0E hint_not_taken OPE3_03 (ccond-null) (s12-null))
+     (sequence ()
+              (c-call VOID "@cpu@_model_branch" (spr-lr) hint_not_taken)
+              (ctrlr-branch-semantics (const BI 0) ccond))
+     ((fr400 (unit u-branch))
+      (fr500 (unit u-branch)))
+)
+
+(conditional-branch-ctrlr bc eq  I OP_0E OPE3_03 Ieq  NA "integer ctrlr branch equal")
+(conditional-branch-ctrlr bc ne  I OP_0E OPE3_03 Ine  NA "integer ctrlr branch not equal")
+(conditional-branch-ctrlr bc le  I OP_0E OPE3_03 Ile  NA "integer ctrlr branch less equal")
+(conditional-branch-ctrlr bc gt  I OP_0E OPE3_03 Igt  NA "integer ctrlr branch greater")
+(conditional-branch-ctrlr bc lt  I OP_0E OPE3_03 Ilt  NA "integer ctrlr branch less")
+(conditional-branch-ctrlr bc ge  I OP_0E OPE3_03 Ige  NA "integer ctrlr branch greater equal")
+(conditional-branch-ctrlr bc ls  I OP_0E OPE3_03 Ils  NA "integer ctrlr branch less equal unsigned")
+(conditional-branch-ctrlr bc hi  I OP_0E OPE3_03 Ihi  NA "integer ctrlr branch greater unsigned")
+(conditional-branch-ctrlr bc c   I OP_0E OPE3_03 Ic   NA "integer ctrlr branch carry set")
+(conditional-branch-ctrlr bc nc  I OP_0E OPE3_03 Inc  NA "integer ctrlr branch carry clear")
+(conditional-branch-ctrlr bc n   I OP_0E OPE3_03 In   NA "integer ctrlr branch negative")
+(conditional-branch-ctrlr bc p   I OP_0E OPE3_03 Ip   NA "integer ctrlr branch positive")
+(conditional-branch-ctrlr bc v   I OP_0E OPE3_03 Iv   NA "integer ctrlr branch overflow set")
+(conditional-branch-ctrlr bc nv  I OP_0E OPE3_03 Inv  NA "integer ctrlr branch overflow clear")
+
+(dni fcbralr
+     "float ctrlr branch always"
+     ((UNIT B0) (FR500-MAJOR B-2) (FR400-MAJOR B-2) FR-ACCESS)
+     "fcbralr$pack $ccond$hint_taken"
+     (+ pack FCC_ra (FCCi_2-null) OP_0E hint_taken OPE3_07 ccond (s12-null))
+     (sequence ()
+              (c-call VOID "@cpu@_model_branch" (spr-lr) hint_taken)
+              (ctrlr-branch-semantics (const BI 1) ccond))
+     ((fr400 (unit u-branch))
+      (fr500 (unit u-branch)))
+)
+
+(dni fcbnolr
+     "float ctrlr branch never"
+     ((UNIT B0) (FR500-MAJOR B-2) (FR400-MAJOR B-2) FR-ACCESS)
+     "fcbnolr$pack$hint_not_taken"
+     (+ pack FCC_nev (FCCi_2-null) OP_0E hint_not_taken OPE3_07 (ccond-null) (s12-null))
+     (sequence ()
+              (c-call VOID "@cpu@_model_branch" (spr-lr) hint_not_taken)
+              (ctrlr-branch-semantics (const BI 0) ccond))
+     ((fr400 (unit u-branch))
+      (fr500 (unit u-branch)))
+)
+
+(conditional-branch-ctrlr fcb eq  F OP_0E OPE3_07 Feq  FR-ACCESS "float cclr branch equal")
+(conditional-branch-ctrlr fcb ne  F OP_0E OPE3_07 Fne  FR-ACCESS "float cclr branch not equal")
+(conditional-branch-ctrlr fcb lg  F OP_0E OPE3_07 Flg  FR-ACCESS "float branch less or greater")
+(conditional-branch-ctrlr fcb ue  F OP_0E OPE3_07 Fue  FR-ACCESS "float branch unordered or equal")
+(conditional-branch-ctrlr fcb ul  F OP_0E OPE3_07 Ful  FR-ACCESS "float branch unordered or less")
+(conditional-branch-ctrlr fcb ge  F OP_0E OPE3_07 Fge  FR-ACCESS "float branch greater or equal")
+(conditional-branch-ctrlr fcb lt  F OP_0E OPE3_07 Flt  FR-ACCESS "float branch less")
+(conditional-branch-ctrlr fcb uge F OP_0E OPE3_07 Fuge FR-ACCESS "float branch unordered, greater, equal")
+(conditional-branch-ctrlr fcb ug  F OP_0E OPE3_07 Fug  FR-ACCESS "float branch unordered or greater")
+(conditional-branch-ctrlr fcb le  F OP_0E OPE3_07 Fle  FR-ACCESS "float branch less or equal")
+(conditional-branch-ctrlr fcb gt  F OP_0E OPE3_07 Fgt  FR-ACCESS "float branch greater")
+(conditional-branch-ctrlr fcb ule F OP_0E OPE3_07 Fule FR-ACCESS "float branch unordered, less or equal")
+(conditional-branch-ctrlr fcb u   F OP_0E OPE3_07 Fu   FR-ACCESS "float branch unordered")
+(conditional-branch-ctrlr fcb o   F OP_0E OPE3_07 Fo   FR-ACCESS "float branch ordered")
+
+(define-pmacro (jump-and-link-semantics base offset LI)
+  (sequence ()
+           (if (eq LI 1)
+               (c-call VOID "@cpu@_set_write_next_vliw_addr_to_LR" 1))
+           ; Target address gets aligned here
+           (set pc (and (add base offset) #xfffffffc))
+           (c-call VOID "@cpu@_model_branch" pc #x2)) ; hint branch taken
+)
+
+(dni jmpl
+     "jump and link"
+     ((UNIT I0) (FR500-MAJOR I-5) (FR400-MAJOR I-5))
+     "jmpl$pack @($GRi,$GRj)"
+     (+ pack (misc-null-1) (LI-off) OP_0C GRi (misc-null-2) GRj)
+     (jump-and-link-semantics GRi GRj LI)
+     ((fr400 (unit u-branch))
+      (fr500 (unit u-branch)))
+)
+
+(dni calll
+     "call and link"
+     ((UNIT I0) (FR500-MAJOR I-5) (FR400-MAJOR I-5))
+     "calll$pack @($GRi,$GRj)"
+     (+ pack (misc-null-1) (LI-on) OP_0C GRi (misc-null-2) GRj)
+     (jump-and-link-semantics GRi GRj LI)
+     ((fr400 (unit u-branch))
+      (fr500 (unit u-branch)))
+)
+
+(dni jmpil
+     "jump immediate and link"
+     ((UNIT I0) (FR500-MAJOR I-5) (FR400-MAJOR I-5))
+     "jmpil$pack @($GRi,$s12)"
+     (+ pack (misc-null-1) (LI-off) OP_0D GRi s12)
+     (jump-and-link-semantics GRi s12 LI)
+     ((fr400 (unit u-branch))
+      (fr500 (unit u-branch)))
+)
+
+(dni callil
+     "call immediate and link"
+     ((UNIT I0) (FR500-MAJOR I-5) (FR400-MAJOR I-5))
+     "callil$pack @($GRi,$s12)"
+     (+ pack (misc-null-1) (LI-on) OP_0D GRi s12)
+     (jump-and-link-semantics GRi s12 LI)
+     ((fr400 (unit u-branch))
+      (fr500 (unit u-branch)))
+)
+
+(dni call
+     "call and link"
+     ((UNIT B0) (FR500-MAJOR B-4) (FR400-MAJOR B-4))
+     "call$pack $label24"
+     (+ pack OP_0F label24)
+     (sequence ()
+              (c-call VOID "@cpu@_set_write_next_vliw_addr_to_LR" 1)
+              (set pc label24)
+              (c-call VOID "@cpu@_model_branch" pc #x2)) ; hint branch taken
+     ((fr400 (unit u-branch))
+      (fr500 (unit u-branch)))
+)
+
+(dni rett
+    "return from trap"
+    ((UNIT C) (FR500-MAJOR C-2) (FR400-MAJOR C-2) PRIVILEGED)
+    "rett$pack $debug"
+    (+ pack (misc-null-1) debug OP_05 (rs-null) (s12-null))
+    ; frv_rett handles operating vs user mode
+    (sequence ()
+             (set pc (c-call UWI "frv_rett" pc debug))
+             (c-call VOID "@cpu@_model_branch" pc #x2)) ; hint branch taken
+    ()
+)
+
+(dni rei
+     "run exception instruction"
+     ((UNIT C) (FR500-MAJOR C-1) (MACH frv) PRIVILEGED)
+     "rei$pack $eir"
+     (+ pack (rd-null) OP_37 eir (s12-null))
+     (nop) ; for now
+     ()
+)
+
+(define-pmacro (trap-semantics cond base offset)
+  (if cond
+      (sequence ()
+               ; This is defered to frv_itrap because for the breakpoint
+               ; case we want to change as little of the machine state as
+               ; possible.
+               ;
+               ; PCSR=PC
+               ; PSR.PS=PSR.S
+               ; PSR.ET=0
+               ; if PSR.ESR==1
+               ;   SR0 through SR3=GR4 through GR7
+               ; TBR.TT=0x80 + ((GRi + s12) & 0x7f)
+               ; PC=TBR
+               ; We still should indicate what is modified by this insn.
+               (clobber (spr-pcsr))
+               (clobber psr_ps)
+               (clobber psr_et)
+               (clobber tbr_tt)
+               (if (ne psr_esr (const 0))
+                   (sequence ()
+                             (clobber (spr-sr0))
+                             (clobber (spr-sr1))
+                             (clobber (spr-sr2))
+                             (clobber (spr-sr3))))
+               ; frv_itrap handles operating vs user mode
+               (c-call VOID "frv_itrap" pc base offset)))
+)
+
+(define-pmacro (trap-r prefix cc i-f op ope cond attr comment)
+  (dni (.sym prefix cc)
+       (comment)
+       ((UNIT C) (FR500-MAJOR C-1) (FR400-MAJOR C-1) attr)
+       (.str (.sym prefix cc) "$pack $" i-f "CCi_2,$GRi,$GRj")
+       (+ pack (.sym i-f CC_ cc) (.sym i-f CCi_2) op GRi (misc-null-3) ope GRj)
+       (trap-semantics (cond (.sym i-f CCi_2)) GRi GRj)
+       ((fr400 (unit u-trap))
+       (fr500 (unit u-trap)))
+  )
+)
+
+(dni tra
+     "integer trap always"
+     ((UNIT C) (FR500-MAJOR C-1) (FR400-MAJOR C-1))
+     "tra$pack $GRi,$GRj"
+     (+ pack ICC_ra (ICCi_2-null) OP_04 GRi (misc-null-3) OPE4_0 GRj)
+     (trap-semantics (const BI 1) GRi GRj)
+     ((fr400 (unit u-trap))
+      (fr500 (unit u-trap)))
+)
+
+(dni tno
+     "integer trap never"
+     ((UNIT C) (FR500-MAJOR C-1) (FR400-MAJOR C-1))
+     "tno$pack"
+     (+ pack ICC_nev (ICCi_2-null) OP_04 (GRi-null) (misc-null-3) OPE4_0 (GRj-null))
+     (trap-semantics (const BI 0) GRi GRj)
+     ((fr400 (unit u-trap))
+      (fr500 (unit u-trap)))
+)
+
+(trap-r t eq  I OP_04 OPE4_0 Ieq  NA "integer trap equal")
+(trap-r t ne  I OP_04 OPE4_0 Ine  NA "integer trap not equal")
+(trap-r t le  I OP_04 OPE4_0 Ile  NA "integer trap less or equal")
+(trap-r t gt  I OP_04 OPE4_0 Igt  NA "integer trap greater")
+(trap-r t lt  I OP_04 OPE4_0 Ilt  NA "integer trap less")
+(trap-r t ge  I OP_04 OPE4_0 Ige  NA "integer trap greater or equal")
+(trap-r t ls  I OP_04 OPE4_0 Ils  NA "integer trap less or equal unsigned")
+(trap-r t hi  I OP_04 OPE4_0 Ihi  NA "integer trap greater unsigned")
+(trap-r t c   I OP_04 OPE4_0 Ic   NA "integer trap carry set")
+(trap-r t nc  I OP_04 OPE4_0 Inc  NA "integer trap carry clear")
+(trap-r t n   I OP_04 OPE4_0 In   NA "integer trap negative")
+(trap-r t p   I OP_04 OPE4_0 Ip   NA "integer trap positive")
+(trap-r t v   I OP_04 OPE4_0 Iv   NA "integer trap overflow set")
+(trap-r t nv  I OP_04 OPE4_0 Inv  NA "integer trap overflow clear")
+
+(dni ftra
+     "float trap always"
+     ((UNIT C) (FR500-MAJOR C-1) (FR400-MAJOR C-1) FR-ACCESS)
+     "ftra$pack $GRi,$GRj"
+     (+ pack FCC_ra (FCCi_2-null) OP_04 GRi (misc-null-3) OPE4_1 GRj)
+     (trap-semantics (const BI 1) GRi GRj)
+     ((fr400 (unit u-trap))
+      (fr500 (unit u-trap)))
+)
+
+(dni ftno
+     "flost trap never"
+     ((UNIT C) (FR500-MAJOR C-1) (FR400-MAJOR C-1) FR-ACCESS)
+     "ftno$pack"
+     (+ pack FCC_nev (FCCi_2-null) OP_04 (GRi-null) (misc-null-3) OPE4_1 (GRj-null))
+     (trap-semantics (const BI 0) GRi GRj)
+     ((fr400 (unit u-trap))
+      (fr500 (unit u-trap)))
+)
+
+(trap-r ft ne  F OP_04 OPE4_1 Fne  FR-ACCESS "float trap not equal")
+(trap-r ft eq  F OP_04 OPE4_1 Feq  FR-ACCESS "float trap equal")
+(trap-r ft lg  F OP_04 OPE4_1 Flg  FR-ACCESS "float trap greater or less")
+(trap-r ft ue  F OP_04 OPE4_1 Fue  FR-ACCESS "float trap unordered or equal")
+(trap-r ft ul  F OP_04 OPE4_1 Ful  FR-ACCESS "float trap unordered or less")
+(trap-r ft ge  F OP_04 OPE4_1 Fge  FR-ACCESS "float trap greater or equal")
+(trap-r ft lt  F OP_04 OPE4_1 Flt  FR-ACCESS "float trap less")
+(trap-r ft uge F OP_04 OPE4_1 Fuge FR-ACCESS "float trap unordered greater or equal")
+(trap-r ft ug  F OP_04 OPE4_1 Fug  FR-ACCESS "float trap unordered or greater")
+(trap-r ft le  F OP_04 OPE4_1 Fle  FR-ACCESS "float trap less or equal")
+(trap-r ft gt  F OP_04 OPE4_1 Fgt  FR-ACCESS "float trap greater")
+(trap-r ft ule F OP_04 OPE4_1 Fule FR-ACCESS "float trap unordered less or equal")
+(trap-r ft u   F OP_04 OPE4_1 Fu   FR-ACCESS "float trap unordered")
+(trap-r ft o   F OP_04 OPE4_1 Fo   FR-ACCESS "float trap ordered")
+
+(define-pmacro (trap-immed prefix cc i-f op cond attr comment)
+  (dni (.sym prefix cc)
+       (comment)
+       ((UNIT C) (FR500-MAJOR C-1) (FR400-MAJOR C-1) attr)
+       (.str (.sym prefix cc) "$pack $" i-f "CCi_2,$GRi,$s12")
+       (+ pack (.sym i-f CC_ cc) (.sym i-f CCi_2) op GRi s12)
+       (trap-semantics (cond (.sym i-f CCi_2)) GRi s12)
+       ((fr400 (unit u-trap))
+       (fr500 (unit u-trap)))
+  )
+)
+
+(dni tira
+     "integer trap always"
+     ((UNIT C) (FR500-MAJOR C-1) (FR400-MAJOR C-1))
+     "tira$pack $GRi,$s12"
+     (+ pack ICC_ra (ICCi_2-null) OP_1C GRi s12)
+     (trap-semantics (const BI 1) GRi s12)
+     ((fr400 (unit u-trap))
+      (fr500 (unit u-trap)))
+)
+
+(dni tino
+     "integer trap never"
+     ((UNIT C) (FR500-MAJOR C-1) (FR400-MAJOR C-1))
+     "tino$pack"
+     (+ pack ICC_nev (ICCi_2-null) OP_1C (GRi-null) (s12-null))
+     (trap-semantics (const BI 0) GRi s12)
+     ((fr400 (unit u-trap))
+      (fr500 (unit u-trap)))
+)
+
+(trap-immed ti eq  I OP_1C Ieq  NA "integer trap equal")
+(trap-immed ti ne  I OP_1C Ine  NA "integer trap not equal")
+(trap-immed ti le  I OP_1C Ile  NA "integer trap less or equal")
+(trap-immed ti gt  I OP_1C Igt  NA "integer trap greater")
+(trap-immed ti lt  I OP_1C Ilt  NA "integer trap less")
+(trap-immed ti ge  I OP_1C Ige  NA "integer trap greater or equal")
+(trap-immed ti ls  I OP_1C Ils  NA "integer trap less or equal unsigned")
+(trap-immed ti hi  I OP_1C Ihi  NA "integer trap greater unsigned")
+(trap-immed ti c   I OP_1C Ic   NA "integer trap carry set")
+(trap-immed ti nc  I OP_1C Inc  NA "integer trap carry clear")
+(trap-immed ti n   I OP_1C In   NA "integer trap negative")
+(trap-immed ti p   I OP_1C Ip   NA "integer trap positive")
+(trap-immed ti v   I OP_1C Iv   NA "integer trap overflow set")
+(trap-immed ti nv  I OP_1C Inv  NA "integer trap overflow clear")
+
+(dni ftira
+     "float trap always"
+     ((UNIT C) (FR500-MAJOR C-1) (FR400-MAJOR C-1) FR-ACCESS)
+     "ftira$pack $GRi,$s12"
+     (+ pack FCC_ra (ICCi_2-null) OP_1D GRi s12)
+     (trap-semantics (const BI 1) GRi s12)
+     ((fr400 (unit u-trap))
+      (fr500 (unit u-trap)))
+)
+
+(dni ftino
+     "float trap never"
+     ((UNIT C) (FR500-MAJOR C-1) (FR400-MAJOR C-1) FR-ACCESS)
+     "ftino$pack"
+     (+ pack FCC_nev (FCCi_2-null) OP_1D (GRi-null) (s12-null))
+     (trap-semantics (const BI 0) GRi s12)
+     ((fr400 (unit u-trap))
+      (fr500 (unit u-trap)))
+)
+
+(trap-immed fti ne  F OP_1D Fne  FR-ACCESS "float trap not equal")
+(trap-immed fti eq  F OP_1D Feq  FR-ACCESS "float trap equal")
+(trap-immed fti lg  F OP_1D Flg  FR-ACCESS "float trap greater or less")
+(trap-immed fti ue  F OP_1D Fue  FR-ACCESS "float trap unordered or equal")
+(trap-immed fti ul  F OP_1D Ful  FR-ACCESS "float trap unordered or less")
+(trap-immed fti ge  F OP_1D Fge  FR-ACCESS "float trap greater or equal")
+(trap-immed fti lt  F OP_1D Flt  FR-ACCESS "float trap less")
+(trap-immed fti uge F OP_1D Fuge FR-ACCESS "float trap unordered greater or equal")
+(trap-immed fti ug  F OP_1D Fug  FR-ACCESS "float trap unordered or greater")
+(trap-immed fti le  F OP_1D Fle  FR-ACCESS "float trap less or equal")
+(trap-immed fti gt  F OP_1D Fgt  FR-ACCESS "float trap greater")
+(trap-immed fti ule F OP_1D Fule FR-ACCESS "float trap unordered less or equal")
+(trap-immed fti u   F OP_1D Fu   FR-ACCESS "float trap unordered")
+(trap-immed fti o   F OP_1D Fo   FR-ACCESS "float trap ordered")
+
+(dni break
+     "break trap"
+     ((UNIT C) (FR500-MAJOR C-1) (FR400-MAJOR C-1))
+     "break$pack"
+     (+ pack (rd-null) OP_04 (rs-null) (misc-null-3) OPE4_3 (GRj-null))
+     (sequence ()
+              ; This is defered to frv_break because for the breakpoint
+              ; case we want to change as little of the machine state as
+              ; possible.
+              ;
+              ; BPCSR=PC
+              ; BPSR.BS=PSR.S
+              ; BPSR.BET=PSR.ET
+              ; PSR.S=1
+              ; PSR.ET=0
+              ; TBR.TT=0xff
+              ; PC=TBR
+              ; We still should indicate what is modified by this insn.
+              (clobber (spr-bpcsr))
+              (clobber bpsr_bs)
+              (clobber bpsr_bet)
+              (clobber psr_s)
+              (clobber psr_et)
+              (clobber tbr_tt)
+              (c-call VOID "frv_break"))
+     ()
+)
+
+(dni mtrap
+     "media trap"
+     ((UNIT C) (FR500-MAJOR C-1) (FR400-MAJOR C-1) FR-ACCESS)
+     "mtrap$pack"
+     (+ pack (rd-null) OP_04 (rs-null) (misc-null-3) OPE4_2 (GRj-null))
+     (c-call VOID "frv_mtrap")
+     ()
+)
+
+(define-pmacro (condition-code-logic name operation ope comment)
+  (dni name
+       (comment)
+       ((UNIT B01) (FR500-MAJOR B-6) (FR400-MAJOR B-6))
+       (.str name "$pack $CRi,$CRj,$CRk")
+       (+ pack (misc-null-6) CRk OP_0A (misc-null-7) CRi ope (misc-null-8) CRj)
+       (set CRk (c-call UQI "@cpu@_cr_logic" operation CRi CRj))
+       ()
+  )
+)
+(define-pmacro (op-andcr)   0)
+(define-pmacro (op-orcr)    1)
+(define-pmacro (op-xorcr)   2)
+(define-pmacro (op-nandcr)  3)
+(define-pmacro (op-norcr)   4)
+(define-pmacro (op-andncr)  5)
+(define-pmacro (op-orncr)   6)
+(define-pmacro (op-nandncr) 7)
+(define-pmacro (op-norncr)  8)
+
+(define-pmacro (cr-true)  3)
+(define-pmacro (cr-false) 2)
+(define-pmacro (cr-undefined) 0)
+
+(condition-code-logic andcr   (op-andcr)   OPE1_08 "and   condition code regs")
+(condition-code-logic orcr    (op-orcr)    OPE1_09 "or    condition code regs")
+(condition-code-logic xorcr   (op-xorcr)   OPE1_0A "xor   condition code regs")
+(condition-code-logic nandcr  (op-nandcr)  OPE1_0C "nand  condition code regs")
+(condition-code-logic norcr   (op-norcr)   OPE1_0D "nor   condition code regs")
+(condition-code-logic andncr  (op-andncr)  OPE1_10 "andn  condition code regs")
+(condition-code-logic orncr   (op-orncr)   OPE1_11 "orn   condition code regs")
+(condition-code-logic nandncr (op-nandncr) OPE1_14 "nandn condition code regs")
+(condition-code-logic norncr  (op-norncr)  OPE1_15 "norn  condition code regs")
+
+(dni notcr
+     ("not cccr register")
+     ((UNIT B01) (FR500-MAJOR B-6) (FR400-MAJOR B-6))
+     (.str notcr "$pack $CRj,$CRk")
+     (+ pack (misc-null-6) CRk OP_0A (rs-null) OPE1_0B (misc-null-8) CRj)
+     (set CRk (xor CRj 1))
+     ()
+)
+
+(define-pmacro (check-semantics cond cr)
+  (if cond (set cr (cr-true)) (set cr (cr-false)))
+)
+
+(define-pmacro (check-int-condition-code prefix cc op cond comment)
+  (dni (.sym prefix cc)
+       (comment)
+       ((UNIT B01) (FR500-MAJOR B-5) (FR400-MAJOR B-5))
+       (.str (.sym prefix cc) "$pack $ICCi_3,$CRj_int")
+       (+ pack (.sym ICC_ cc) CRj_int op (misc-null-5) ICCi_3)
+       (check-semantics (cond ICCi_3) CRj_int)
+       ((fr400 (unit u-check))
+       (fr500 (unit u-check)))
+  )
+)
+
+(dni ckra
+     "check integer cc always"
+     ((UNIT B01) (FR500-MAJOR B-5) (FR400-MAJOR B-5))
+     "ckra$pack $CRj_int"
+     (+ pack ICC_ra CRj_int OP_08 (misc-null-5) (ICCi_3-null))
+     (check-semantics (const BI 1) CRj_int)
+     ((fr400 (unit u-check))
+      (fr500 (unit u-check)))
+)
+
+(dni ckno
+     "check integer cc never"
+     ((UNIT B01) (FR500-MAJOR B-5) (FR400-MAJOR B-5))
+     "ckno$pack $CRj_int"
+     (+ pack ICC_nev CRj_int OP_08 (misc-null-5) (ICCi_3-null))
+     (check-semantics (const BI 0) CRj_int)
+     ((fr400 (unit u-check))
+      (fr500 (unit u-check)))
+)
+
+(check-int-condition-code ck eq  OP_08 Ieq  "check integer cc equal")
+(check-int-condition-code ck ne  OP_08 Ine  "check integer cc not equal")
+(check-int-condition-code ck le  OP_08 Ile  "check integer cc less or equal")
+(check-int-condition-code ck gt  OP_08 Igt  "check integer cc greater")
+(check-int-condition-code ck lt  OP_08 Ilt  "check integer cc less")
+(check-int-condition-code ck ge  OP_08 Ige  "check integer cc greater or equal")
+(check-int-condition-code ck ls  OP_08 Ils  "check integer cc less or equal unsigned")
+(check-int-condition-code ck hi  OP_08 Ihi  "check integer cc greater unsigned")
+(check-int-condition-code ck c   OP_08 Ic   "check integer cc carry set")
+(check-int-condition-code ck nc  OP_08 Inc  "check integer cc carry clear")
+(check-int-condition-code ck n   OP_08 In   "check integer cc negative")
+(check-int-condition-code ck p   OP_08 Ip   "check integer cc positive")
+(check-int-condition-code ck v   OP_08 Iv   "check integer cc overflow set")
+(check-int-condition-code ck nv  OP_08 Inv  "check integer cc overflow clear")
+
+(define-pmacro (check-float-condition-code prefix cc op cond comment)
+  (dni (.sym prefix cc)
+       (comment)
+       ((UNIT B01) (FR500-MAJOR B-5) (FR400-MAJOR B-5) FR-ACCESS)
+       (.str (.sym prefix cc) "$pack $FCCi_3,$CRj_float")
+       (+ pack (.sym FCC_ cc) CRj_float op (misc-null-5) FCCi_3)
+       (check-semantics (cond FCCi_3) CRj_float)
+       ((fr400 (unit u-check))
+       (fr500 (unit u-check)))
+  )
+)
+
+(dni fckra
+     "check float cc always"
+     ((UNIT B01) (FR500-MAJOR B-5) (FR400-MAJOR B-5) FR-ACCESS)
+     "fckra$pack $CRj_float"
+     (+ pack FCC_ra CRj_float OP_09 (misc-null-5) FCCi_3)
+     (check-semantics (const BI 1) CRj_float)
+     ((fr400 (unit u-check))
+      (fr500 (unit u-check)))
+)
+
+(dni fckno
+     "check float cc never"
+     ((UNIT B01) (FR500-MAJOR B-5) (FR400-MAJOR B-5) FR-ACCESS)
+     "fckno$pack $CRj_float"
+     (+ pack FCC_nev CRj_float OP_09 (misc-null-5) FCCi_3)
+     (check-semantics (const BI 0) CRj_float)
+     ((fr400 (unit u-check))
+      (fr500 (unit u-check)))
+)
+
+(check-float-condition-code fck ne  OP_09 Fne  "check float cc not equal")
+(check-float-condition-code fck eq  OP_09 Feq  "check float cc equal")
+(check-float-condition-code fck lg  OP_09 Flg  "check float cc greater or less")
+(check-float-condition-code fck ue  OP_09 Fue  "check float cc unordered or equal")
+(check-float-condition-code fck ul  OP_09 Ful  "check float cc unordered or less")
+(check-float-condition-code fck ge  OP_09 Fge  "check float cc greater or equal")
+(check-float-condition-code fck lt  OP_09 Flt  "check float cc less")
+(check-float-condition-code fck uge OP_09 Fuge "check float cc unordered greater or equal")
+(check-float-condition-code fck ug  OP_09 Fug  "check float cc unordered or greater")
+(check-float-condition-code fck le  OP_09 Fle  "check float cc less or equal")
+(check-float-condition-code fck gt  OP_09 Fgt  "check float cc greater")
+(check-float-condition-code fck ule OP_09 Fule "check float cc unordered less or equal")
+(check-float-condition-code fck u   OP_09 Fu   "check float cc unordered")
+(check-float-condition-code fck o   OP_09 Fo   "check float cc ordered")
+
+(define-pmacro (conditional-check-int-condition-code prefix cc op ope test comment)
+  (dni (.sym prefix cc)
+       (comment)
+       ((UNIT B01) (FR500-MAJOR B-5) (FR400-MAJOR B-5) CONDITIONAL)
+       (.str (.sym prefix cc) "$pack $ICCi_3,$CRj_int,$CCi,$cond")
+       (+ pack (.sym ICC_ cc) CRj_int op (rs-null) CCi cond ope
+         (misc-null-9) ICCi_3)
+       (if (eq CCi (or cond 2))
+          (check-semantics (test ICCi_3) CRj_int)
+          (set CRj_int (cr-undefined)))
+       ((fr400 (unit u-check))
+       (fr500 (unit u-check)))
+  )
+)
+
+(dni cckra
+     "conditional check integer cc always"
+     ((UNIT B01) (FR500-MAJOR B-5) (FR400-MAJOR B-5) CONDITIONAL)
+     "cckra$pack $CRj_int,$CCi,$cond"
+     (+ pack ICC_ra CRj_int OP_6A (rs-null) CCi cond OPE4_0
+       (misc-null-9) (ICCi_3-null))
+     (if (eq CCi (or cond 2))
+        (check-semantics (const BI 1) CRj_int)
+        (set CRj_int (cr-undefined)))
+     ((fr400 (unit u-check))
+      (fr500 (unit u-check)))
+)
+
+(dni cckno
+     "conditional check integer cc never"
+     ((UNIT B01) (FR500-MAJOR B-5) (FR400-MAJOR B-5) CONDITIONAL)
+     "cckno$pack $CRj_int,$CCi,$cond"
+     (+ pack ICC_nev CRj_int OP_6A (rs-null) CCi cond OPE4_0
+       (misc-null-9) (ICCi_3-null))
+     (if (eq CCi (or cond 2))
+        (check-semantics (const BI 0) CRj_int)
+        (set CRj_int (cr-undefined)))
+     ((fr400 (unit u-check))
+      (fr500 (unit u-check)))
+)
+
+(conditional-check-int-condition-code cck eq  OP_6A OPE4_0 Ieq  "check integer cc equal")
+(conditional-check-int-condition-code cck ne  OP_6A OPE4_0 Ine  "check integer cc not equal")
+(conditional-check-int-condition-code cck le  OP_6A OPE4_0 Ile  "check integer cc less or equal")
+(conditional-check-int-condition-code cck gt  OP_6A OPE4_0 Igt  "check integer cc greater")
+(conditional-check-int-condition-code cck lt  OP_6A OPE4_0 Ilt  "check integer cc less")
+(conditional-check-int-condition-code cck ge  OP_6A OPE4_0 Ige  "check integer cc greater or equal")
+(conditional-check-int-condition-code cck ls  OP_6A OPE4_0 Ils  "check integer cc less or equal unsigned")
+(conditional-check-int-condition-code cck hi  OP_6A OPE4_0 Ihi  "check integer cc greater unsigned")
+(conditional-check-int-condition-code cck c   OP_6A OPE4_0 Ic   "check integer cc carry set")
+(conditional-check-int-condition-code cck nc  OP_6A OPE4_0 Inc  "check integer cc carry clear")
+(conditional-check-int-condition-code cck n   OP_6A OPE4_0 In   "check integer cc negative")
+(conditional-check-int-condition-code cck p   OP_6A OPE4_0 Ip   "check integer cc positive")
+(conditional-check-int-condition-code cck v   OP_6A OPE4_0 Iv   "check integer cc overflow set")
+(conditional-check-int-condition-code cck nv  OP_6A OPE4_0 Inv  "check integer cc overflow clear")
+
+(define-pmacro (conditional-check-float-condition-code prefix cc op ope test comment)
+  (dni (.sym prefix cc)
+       (comment)
+       ((UNIT B01) (FR500-MAJOR B-5) (FR400-MAJOR B-5) CONDITIONAL FR-ACCESS)
+       (.str (.sym prefix cc) "$pack $FCCi_3,$CRj_float,$CCi,$cond")
+       (+ pack (.sym FCC_ cc) CRj_float op (rs-null) CCi cond ope
+         (misc-null-9) FCCi_3)
+       (if (eq CCi (or cond 2))
+          (check-semantics (test FCCi_3) CRj_float)
+          (set CRj_float (cr-undefined)))
+       ((fr400 (unit u-check))
+       (fr500 (unit u-check)))
+  )
+)
+
+(dni cfckra
+     "conditional check float cc always"
+     ((UNIT B01) (FR500-MAJOR B-5) (FR400-MAJOR B-5) CONDITIONAL FR-ACCESS)
+     "cfckra$pack $CRj_float,$CCi,$cond"
+     (+ pack FCC_ra CRj_float OP_6A (rs-null) CCi cond OPE4_1
+       (misc-null-9) (FCCi_3-null))
+     (if (eq CCi (or cond 2))
+        (check-semantics (const BI 1) CRj_float)
+        (set CRj_float (cr-undefined)))
+     ((fr400 (unit u-check))
+      (fr500 (unit u-check)))
+)
+
+(dni cfckno
+     "conditional check float cc never"
+     ((UNIT B01) (FR500-MAJOR B-5) (FR400-MAJOR B-5) CONDITIONAL FR-ACCESS)
+     "cfckno$pack $CRj_float,$CCi,$cond"
+     (+ pack FCC_nev CRj_float OP_6A (rs-null) CCi cond OPE4_1
+       (misc-null-9) (FCCi_3-null))
+     (if (eq CCi (or cond 2))
+        (check-semantics (const BI 0) CRj_float)
+        (set CRj_float (cr-undefined)))
+     ((fr400 (unit u-check))
+      (fr500 (unit u-check)))
+)
+
+(conditional-check-float-condition-code cfck ne  OP_6A OPE4_1 Fne  "check float cc not equal")
+(conditional-check-float-condition-code cfck eq  OP_6A OPE4_1 Feq  "check float cc equal")
+(conditional-check-float-condition-code cfck lg  OP_6A OPE4_1 Flg  "check float cc greater or less")
+(conditional-check-float-condition-code cfck ue  OP_6A OPE4_1 Fue  "check float cc unordered or equal")
+(conditional-check-float-condition-code cfck ul  OP_6A OPE4_1 Ful  "check float cc unordered or less")
+(conditional-check-float-condition-code cfck ge  OP_6A OPE4_1 Fge  "check float cc greater or equal")
+(conditional-check-float-condition-code cfck lt  OP_6A OPE4_1 Flt  "check float cc less")
+(conditional-check-float-condition-code cfck uge OP_6A OPE4_1 Fuge "check float cc unordered greater or equal")
+(conditional-check-float-condition-code cfck ug  OP_6A OPE4_1 Fug  "check float cc unordered or greater")
+(conditional-check-float-condition-code cfck le  OP_6A OPE4_1 Fle  "check float cc less or equal")
+(conditional-check-float-condition-code cfck gt  OP_6A OPE4_1 Fgt  "check float cc greater")
+(conditional-check-float-condition-code cfck ule OP_6A OPE4_1 Fule "check float cc unordered less or equal")
+(conditional-check-float-condition-code cfck u   OP_6A OPE4_1 Fu   "check float cc unordered")
+(conditional-check-float-condition-code cfck o   OP_6A OPE4_1 Fo   "check float cc ordered")
+
+(dni cjmpl
+     "conditional jump and link"
+     ((UNIT I0) (FR500-MAJOR I-5) (FR400-MAJOR I-5) CONDITIONAL)
+     "cjmpl$pack @($GRi,$GRj),$CCi,$cond"
+     (+ pack (misc-null-1) (LI-off) OP_6A GRi CCi cond OPE4_2 GRj)
+     (if (eq CCi (or cond 2))
+        (jump-and-link-semantics GRi GRj LI))
+     ((fr400 (unit u-branch))
+      (fr500 (unit u-branch)))
+)
+
+(dni ccalll
+     "conditional call and link"
+     ((UNIT I0) (FR500-MAJOR I-5) (FR400-MAJOR I-5) CONDITIONAL)
+     "ccalll$pack @($GRi,$GRj),$CCi,$cond"
+     (+ pack (misc-null-1) (LI-on) OP_6A GRi CCi cond OPE4_2 GRj)
+     (if (eq CCi (or cond 2))
+        (jump-and-link-semantics GRi GRj LI))
+     ((fr400 (unit u-branch))
+      (fr500 (unit u-branch)))
+)
+
+(define-pmacro (cache-invalidate name cache all op ope profile comment)
+  (dni name
+       (comment)
+       ((UNIT C) (FR500-MAJOR C-2) (FR400-MAJOR C-2))
+       (.str name "$pack @($GRi,$GRj)")
+       (+ pack (rd-null) op GRi ope GRj)
+       (c-call VOID (.str "@cpu@_" cache "_cache_invalidate") (add GRi GRj) all)
+       profile
+  )
+)
+
+(cache-invalidate ici insn 0 OP_03 OPE1_38
+                 ((fr400 (unit u-ici)) (fr500 (unit u-ici)))
+                 "invalidate insn cache")
+(cache-invalidate dci data 0 OP_03 OPE1_3C
+                 ((fr400 (unit u-dci)) (fr500 (unit u-dci)))
+                 "invalidate data cache")
+
+(define-pmacro (cache-invalidate-entry name cache op ope profile comment)
+  (dni name
+       (comment)
+       ((UNIT C) (FR400-MAJOR C-2) (MACH fr400))
+       (.str name "$pack @($GRi,$GRj),$ae")
+       (+ pack (misc-null-1) ae op GRi ope GRj)
+       (if (eq ae 0)
+          (c-call VOID (.str "@cpu@_" cache "_cache_invalidate") (add GRi GRj) -1) ; Invalid ae setting for this insn
+          (c-call VOID (.str "@cpu@_" cache "_cache_invalidate") (add GRi GRj) ae))
+       profile
+  )
+)
+
+(cache-invalidate-entry icei insn OP_03 OPE1_39
+                       ((fr400 (unit u-ici)))
+                       "invalidate insn cache entry")
+(cache-invalidate-entry dcei data OP_03 OPE1_3A
+                       ((fr400 (unit u-dci)))
+                       "invalidate data cache entry")
+
+(dni dcf
+     "Data cache flush"
+     ((UNIT C) (FR500-MAJOR C-2) (FR400-MAJOR C-2))
+     "dcf$pack @($GRi,$GRj)"
+     (+ pack (rd-null) OP_03 GRi OPE1_3D GRj)
+     (c-call VOID "@cpu@_data_cache_flush" (add GRi GRj) 0)
+     ((fr400 (unit u-dcf))
+      (fr500 (unit u-dcf)))
+)
+
+(dni dcef
+     "Data cache entry flush"
+     ((UNIT C) (FR400-MAJOR C-2) (MACH fr400))
+     "dcef$pack @($GRi,$GRj),$ae"
+     (+ pack (misc-null-1) ae OP_03 GRi OPE1_3B GRj)
+     (if (eq ae 0)
+        (c-call VOID "@cpu@_data_cache_flush" (add GRi GRj) -1)
+        (c-call VOID "@cpu@_data_cache_flush" (add GRi GRj) ae))
+     ((fr400 (unit u-dcf)))
+)
+
+(define-pmacro (write-TLB name insn op ope comment)
+  (dni name
+       (comment)
+       ((UNIT C) (FR500-MAJOR C-2) (MACH frv) PRIVILEGED)
+       (.str insn "$pack $GRk,@($GRi,$GRj)")
+       (+ pack GRk op GRi ope GRj)
+       (nop) ; for now
+       ()
+  )
+)
+
+(write-TLB witlb witlb OP_03 OPE1_32 "write for insn TLB")
+(write-TLB wdtlb wdtlb OP_03 OPE1_36 "write for data TLB")
+
+(define-pmacro (invalidate-TLB name insn op ope comment)
+  (dni name
+       (comment)
+       ((UNIT C) (FR500-MAJOR C-2) (MACH frv) PRIVILEGED)
+       (.str insn "$pack @($GRi,$GRj)")
+       (+ pack (rd-null) op GRi ope GRj)
+       (nop) ; for now
+       ()
+  )
+)
+
+(invalidate-TLB itlbi itlbi OP_03 OPE1_33 "invalidate insn TLB")
+(invalidate-TLB dtlbi dtlbi OP_03 OPE1_37 "invalidate data TLB")
+
+(define-pmacro (cache-preload name cache op ope profile comment)
+  (dni name
+       (comment)
+       ((UNIT C) (FR500-MAJOR C-2) (FR400-MAJOR C-2))
+       (.str name "$pack $GRi,$GRj,$lock")
+       (+ pack (misc-null-1) lock op GRi ope GRj)
+       (c-call VOID (.str "@cpu@_" cache "_cache_preload") GRi GRj lock)
+       profile
+  )
+)
+
+(cache-preload icpl insn OP_03 OPE1_30
+              ((fr400 (unit u-icpl)) (fr500 (unit u-icpl)))
+              "preload insn cache")
+(cache-preload dcpl data OP_03 OPE1_34
+              ((fr400 (unit u-dcpl)) (fr500 (unit u-dcpl)))
+              "preload data cache")
+
+(define-pmacro (cache-unlock name cache op ope profile comment)
+  (dni name
+       (comment)
+       ((UNIT C) (FR500-MAJOR C-2) (FR400-MAJOR C-2))
+       (.str name "$pack $GRi")
+       (+ pack (rd-null) op GRi ope (GRj-null))
+       (c-call VOID (.str "@cpu@_" cache "_cache_unlock") GRi)
+       profile
+  )
+)
+
+(cache-unlock icul insn OP_03 OPE1_31
+             ((fr400 (unit u-icul)) (fr500 (unit u-icul)))
+             "unlock insn cache")
+(cache-unlock dcul data OP_03 OPE1_35
+             ((fr400 (unit u-dcul)) (fr500 (unit u-dcul)))
+             "unlock data cache")
+
+(define-pmacro (barrier name insn op ope profile comment)
+  (dni name
+       (comment)
+       ((UNIT C) (FR500-MAJOR C-2) (FR400-MAJOR C-2))
+       (.str insn "$pack")
+       (+ pack (rd-null) op (rs-null) ope (GRj-null))
+       (nop) ; sufficient implementation
+       profile
+  )
+)
+
+(barrier bar    bar    OP_03 OPE1_3E
+        ((fr400 (unit u-barrier)) (fr500 (unit u-barrier)))
+        "barrier")
+(barrier membar membar OP_03 OPE1_3F
+        ((fr400 (unit u-membar)) (fr500 (unit u-membar)))
+        "memory barrier")
+
+; Coprocessor operations
+(define-pmacro (cop-op num op)
+  (dni (.sym cop num)
+       "Coprocessor operation"
+       ((UNIT C) (FR500-MAJOR C-2) (MACH frv))
+       (.str "cop" num "$pack $s6_1,$CPRi,$CPRj,$CPRk")
+       (+ pack CPRk op CPRi s6_1 CPRj)
+       (nop) ; sufficient implementation
+       ()
+  )
+)
+
+(cop-op 1 OP_7E)
+(cop-op 2 OP_7F)
+
+(define-pmacro (clear-ne-flag-semantics target_index is_float)
+  (c-call VOID "@cpu@_clear_ne_flags" target_index is_float)
+)
+
+(define-pmacro (clear-ne-flag-r name op ope reg is_float attr comment)
+  (dni name
+       (comment)
+       ((UNIT I01) (FR500-MAJOR I-6) (MACH simple,tomcat,fr500,frv) attr)
+       (.str name "$pack $" reg "k")
+       (+ pack (.sym reg k) op (rs-null) ope (GRj-null))
+       (clear-ne-flag-semantics (index-of (.sym reg k)) is_float)
+       ()
+  )
+)
+
+(clear-ne-flag-r clrgr OP_0A OPE1_00 GR 0 NA        "Clear GR NE flag")
+(clear-ne-flag-r clrfr OP_0A OPE1_02 FR 1 FR-ACCESS "Clear FR NE flag")
+
+(define-pmacro (clear-ne-flag-all name op ope is_float attr comment)
+  (dni name
+       (comment)
+       ((UNIT I01) (FR500-MAJOR I-6) (MACH simple,tomcat,fr500,frv) attr)
+       (.str name "$pack")
+       (+ pack (rd-null) op (rs-null) ope (GRj-null))
+       (clear-ne-flag-semantics -1 is_float)
+       ()
+  )
+)
+
+(clear-ne-flag-all clrga OP_0A OPE1_01 0 NA        "Clear GR NE flag ALL")
+(clear-ne-flag-all clrfa OP_0A OPE1_03 1 FR-ACCESS "Clear FR NE flag ALL")
+
+(define-pmacro (commit-semantics target_index is_float)
+  (c-call VOID "@cpu@_commit" target_index is_float)
+)
+
+(define-pmacro (commit-r name op ope reg is_float attr comment)
+  (dni name
+       (comment)
+       ((UNIT I01) (FR500-MAJOR I-6) (MACH frv,fr500) attr)
+       (.str name "$pack $" reg "k")
+       (+ pack (.sym reg k) op (rs-null) ope (GRj-null))
+       (commit-semantics (index-of (.sym reg k)) is_float)
+       ()
+  )
+)
+
+(commit-r commitgr OP_0A OPE1_04 GR 0 NA        "commit exceptions, specific GR")
+(commit-r commitfr OP_0A OPE1_06 FR 1 FR-ACCESS "commit exceptions, specific FR")
+
+(define-pmacro (commit name op ope is_float attr comment)
+  (dni name
+       (comment)
+       ((UNIT I01) (FR500-MAJOR I-6) (MACH frv,fr500) attr)
+       (.str name "$pack")
+       (+ pack (rd-null) op (rs-null) ope (GRj-null))
+       (commit-semantics -1 is_float)
+       ()
+  )
+)
+
+(commit commitga OP_0A OPE1_05 0 NA        "commit exceptions, any GR")
+(commit commitfa OP_0A OPE1_07 1 FR-ACCESS "commit exceptions, any FR")
+
+(define-pmacro (floating-point-conversion
+               name op ope conv mode src targ attr comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR F-1) (MACH simple,tomcat,fr500,frv) attr)
+       (.str name "$pack $" src ",$" targ)
+       (+ pack targ op (rs-null) ope src)
+       (set targ (conv mode src))
+       ((fr500 (unit u-float-convert)))
+  )
+)
+
+(floating-point-conversion fitos OP_79 OPE1_00 float SF FRintj FRk NA "Convert Integer to Single")
+(floating-point-conversion fstoi OP_79 OPE1_01 fix   SI FRj FRintk NA "Convert Single  to Integer")
+(floating-point-conversion fitod OP_7A OPE1_00 float DF FRintj FRdoublek (MACH frv) "Convert Integer to Double")
+(floating-point-conversion fdtoi OP_7A OPE1_01 fix   SI FRdoublej FRintk (MACH frv) "Convert Double to Integer")
+
+(define-pmacro (floating-point-dual-conversion
+               name op ope conv mode src src_hw targ targ_hw attr comment)
+  (dni name
+       (comment)
+       ((MACH frv) (UNIT FM01) (FR500-MAJOR F-1) attr)
+       (.str name "$pack $" src ",$" targ)
+       (+ pack targ op (rs-null) ope src)
+       (sequence ()
+                (set targ (conv mode src))
+                (set (nextreg targ_hw targ 1)
+                     (conv mode (nextreg src_hw src 1))))
+       ((fr500 (unit u-float-dual-convert)))
+  )
+)
+
+(floating-point-dual-conversion fditos OP_79 OPE1_10 float SF FRintj h-fr_int FRk h-fr NA "Dual Convert Integer to Single")
+(floating-point-dual-conversion fdstoi OP_79 OPE1_11 fix   SI FRj h-fr FRintk h-fr_int NA "Dual Convert Single  to Integer")
+
+(define-pmacro (ne-floating-point-dual-conversion
+               name op ope conv mode src src_hw targ targ_hw attr comment)
+  (dni name
+       (comment)
+       ((MACH frv) (UNIT FM01) (FR500-MAJOR F-1) NON-EXCEPTING attr)
+       (.str name "$pack $" src ",$" targ)
+       (+ pack targ op (rs-null) ope src)
+       (sequence ()
+                (c-call VOID "@cpu@_set_ne_index" (index-of targ))
+                (set targ (conv mode src))
+                (c-call VOID "@cpu@_set_ne_index" (add (index-of targ) 1))
+                (set (nextreg targ_hw targ 1)
+                     (conv mode (nextreg src_hw src 1))))
+       ((fr500 (unit u-float-dual-convert)))
+  )
+)
+
+(ne-floating-point-dual-conversion nfditos OP_79 OPE1_30 float SF FRintj h-fr_int FRk h-fr NA "Non excepting dual Convert Integer to Single")
+(ne-floating-point-dual-conversion nfdstoi OP_79 OPE1_31 fix   SI FRj h-fr FRintk h-fr_int NA "Non excepting dual Convert Single  to Integer")
+
+(define-pmacro (conditional-floating-point-conversion
+               name op ope conv mode src targ comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR F-1) (MACH simple,tomcat,fr500,frv))
+       (.str name "$pack $" src ",$" targ ",$CCi,$cond")
+       (+ pack targ op (rs-null) CCi cond ope src)
+       (if (eq CCi (or cond 2))
+          (set targ (conv mode src)))
+       ((fr500 (unit u-float-convert)))
+  )
+)
+
+(conditional-floating-point-conversion cfitos OP_6B OPE4_0 float SF FRintj FRk "Conditional convert Integer to Single")
+(conditional-floating-point-conversion cfstoi OP_6B OPE4_1 fix   SI FRj FRintk "Conditional convert Single to Integer")
+
+(define-pmacro (ne-floating-point-conversion 
+               name op ope conv mode src targ comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR F-1) (MACH simple,tomcat,fr500,frv))
+       (.str name "$pack $" src ",$" targ)
+       (+ pack targ op (rs-null) ope src)
+       (sequence ()
+                (c-call VOID "@cpu@_set_ne_index" (index-of targ))
+                (set targ (conv mode src)))
+       ((fr500 (unit u-float-convert)))
+  )
+)
+
+(ne-floating-point-conversion nfitos OP_79 OPE1_20 float SF FRintj FRk "NE convert Integer to Single")
+(ne-floating-point-conversion nfstoi OP_79 OPE1_21 fix   SI FRj FRintk "NE convert Single to Integer")
+
+(register-transfer fmovs OP_79 OPE1_02
+                  FRj FRk FM01 (FR500-MAJOR F-1) NA
+                  (MACH simple,tomcat,fr500,frv) NA
+                  ((fr500 (unit u-fr2fr)))
+                  "Move Single Float")
+(register-transfer fmovd OP_7A OPE1_02
+                  ; TODO -- unit doesn't handle extra register
+                  FRdoublej FRdoublek FM01 (FR500-MAJOR F-1) NA
+                  (MACH frv) NA
+                  ((fr500 (unit u-fr2fr)))
+                  "Move Double Float")
+
+(dni fdmovs
+     "Dual move single float"
+     ((MACH frv) (UNIT FM01) (FR500-MAJOR F-1))
+     "fdmovs$pack $FRj,$FRk"
+     (+ pack FRk OP_79 (rs-null) OPE1_12 FRj)
+     (sequence ()
+              (set FRk FRj)
+              (set (nextreg h-fr FRk 1) (nextreg h-fr FRj 1)))
+     ; TODO -- unit doesn't handle extra register
+     ((fr500 (unit u-fr2fr)))
+)
+
+(conditional-register-transfer cfmovs OP_6C OPE4_0 FRj FRk FM01
+                              (FR500-MAJOR F-1) NA
+                              (MACH simple,tomcat,fr500,frv)
+                              ((fr500 (unit u-fr2fr)))
+                              "Conditional move Single Float")
+
+(define-pmacro (floating-point-neg name src targ op ope attr comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR F-1) attr)
+       (.str name "$pack $" src ",$" targ)
+       (+ pack src op (rs-null) ope targ)
+       (set targ (neg src))
+       ((fr500 (unit u-float-arith)))
+  )
+)
+
+(floating-point-neg fnegs FRj FRk OP_79 OPE1_03 (MACH simple,tomcat,fr500,frv) "Floating point negate, single")
+(floating-point-neg fnegd FRdoublej FRdoublek OP_7A OPE1_03 (MACH frv) "Floating point negate, double")
+
+(dni fdnegs
+     "Floating point dual negate, single"
+     ((MACH frv) (UNIT FM01) (FR500-MAJOR F-1))
+     "fdnegs$pack $FRj,$FRk"
+     (+ pack FRk OP_79 (rs-null) OPE1_13 FRj)
+     (sequence ()
+              (set FRk (neg FRj))
+              (set (nextreg h-fr FRk 1) (neg (nextreg h-fr FRj 1))))
+     ((fr500 (unit u-float-dual-arith)))
+)
+
+(dni cfnegs
+     "Conditional floating point negate, single"
+     ((UNIT FM01) (FR500-MAJOR F-1) (MACH simple,tomcat,fr500,frv))
+     "cfnegs$pack $FRj,$FRk,$CCi,$cond"
+     (+ pack FRj OP_6C (rs-null) CCi cond OPE4_1 FRk)
+     (if (eq CCi (or cond 2))
+        (set FRk (neg FRj)))
+     ((fr500 (unit u-float-arith)))
+)
+
+(define-pmacro (float-abs name src targ op ope attr comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR F-1) attr)
+       (.str name "$pack $" src ",$" targ )
+       (+ pack targ op (rs-null) ope src)
+       (set targ (abs src))
+       ((fr500 (unit u-float-arith)))
+  )
+)
+
+(float-abs fabss FRj FRk OP_79 OPE1_04 (MACH simple,tomcat,fr500,frv) "Float absolute value, single")
+(float-abs fabsd FRdoublej FRdoublek OP_7A OPE1_04 (MACH frv) "Float absolute value, double")
+
+(dni fdabss
+     "Floating point dual absolute value, single"
+     ((MACH frv) (UNIT FM01) (FR500-MAJOR F-1))
+     "fdabss$pack $FRj,$FRk"
+     (+ pack FRk OP_79 (rs-null) OPE1_14 FRj)
+     (sequence ()
+              (set FRk (abs FRj))
+              (set (nextreg h-fr FRk 1) (abs (nextreg h-fr FRj 1))))
+     ((fr500 (unit u-float-dual-arith)))
+)
+
+(dni cfabss
+     "Conditional floating point absolute value, single"
+     ((UNIT FM01) (FR500-MAJOR F-1) (MACH simple,tomcat,fr500,frv))
+     "cfabss$pack $FRj,$FRk,$CCi,$cond"
+     (+ pack FRj OP_6C (rs-null) CCi cond OPE4_2 FRk)
+     (if (eq CCi (or cond 2))
+        (set FRk (abs FRj)))
+     ((fr500 (unit u-float-arith)))
+)
+
+(dni fsqrts
+     "Square root single"
+     ((UNIT FM01) (FR500-MAJOR F-4) (MACH simple,tomcat,fr500,frv))
+     "fsqrts$pack $FRj,$FRk"
+     (+ pack FRk OP_79 (rs-null) OPE1_05 FRj)
+     (set FRk (sqrt SF FRj))
+     ((fr500 (unit u-float-sqrt)))
+)
+
+(dni fdsqrts
+     "Dual square root single"
+     ((MACH frv) (UNIT FM01) (FR500-MAJOR F-4))
+     "fdsqrts$pack $FRj,$FRk"
+     (+ pack FRk OP_79 (rs-null) OPE1_15 FRj)
+     (sequence ()
+              (set FRk (sqrt SF FRj))
+              (set (nextreg h-fr FRk 1) (sqrt (nextreg h-fr FRj 1))))
+     ((fr500 (unit u-float-dual-sqrt)))
+)
+
+(dni nfdsqrts
+     "Non excepting Dual square root single"
+     ((MACH frv) (UNIT FM01) (FR500-MAJOR F-4) NON-EXCEPTING)
+     "nfdsqrts$pack $FRj,$FRk"
+     (+ pack FRk OP_79 (rs-null) OPE1_35 FRj)
+     (sequence ()
+              (c-call VOID "@cpu@_set_ne_index" (index-of FRk))
+              (set FRk (sqrt SF FRj))
+              (c-call VOID "@cpu@_set_ne_index" (add (index-of FRk) 1))
+              (set (nextreg h-fr FRk 1) (sqrt (nextreg h-fr FRj 1))))
+     ((fr500 (unit u-float-dual-sqrt)))
+)
+
+(dni fsqrtd
+     "Square root double"
+     ((UNIT FM01) (FR500-MAJOR F-4) (MACH frv))
+     "fsqrtd$pack $FRdoublej,$FRdoublek"
+     (+ pack FRdoublek OP_7A (rs-null) OPE1_05 FRdoublej)
+     (set FRdoublek (sqrt DF FRdoublej))
+     ((fr500 (unit u-float-sqrt)))
+)
+
+(dni cfsqrts
+     "Conditional square root single"
+     ((UNIT FM01) (FR500-MAJOR F-4) (MACH simple,tomcat,fr500,frv))
+     "cfsqrts$pack $FRj,$FRk,$CCi,$cond"
+     (+ pack FRk OP_6E (rs-null) CCi cond OPE4_2 FRj)
+     (if (eq CCi (or cond 2))
+        (set FRk (sqrt SF FRj)))
+     ((fr500 (unit u-float-sqrt)))
+)
+
+(dni nfsqrts
+     "Non exception square root, single"
+     ((UNIT FM01) (FR500-MAJOR F-4) (MACH simple,tomcat,fr500,frv))
+     "nfsqrts$pack $FRj,$FRk"
+     (+ pack FRk OP_79 (rs-null) OPE1_25 FRj)
+     (sequence ()
+              (c-call VOID "@cpu@_set_ne_index" (index-of FRk))
+              (set FRk (sqrt SF FRj)))
+     ((fr500 (unit u-float-sqrt)))
+)
+
+(define-pmacro (float-binary-op-s name operation op ope major comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR major) (MACH simple,tomcat,fr500,frv))
+       (.str name "$pack $FRi,$FRj,$FRk")
+       (+ pack FRk op FRi ope FRj)
+       (set FRk (operation FRi FRj))
+       ((fr500 (unit u-float-arith)))
+  )
+)
+
+(float-binary-op-s fadds add OP_79 OPE1_06 F-2 "add single float")
+(float-binary-op-s fsubs sub OP_79 OPE1_07 F-2 "sub single float")
+(float-binary-op-s fmuls mul OP_79 OPE1_08 F-3 "mul single float")
+
+(dni fdivs
+     "div single float"
+     ((UNIT FM01) (FR500-MAJOR F-4) (MACH simple,tomcat,fr500,frv))
+     "fdivs$pack $FRi,$FRj,$FRk"
+     (+ pack FRk OP_79 FRi OPE1_09 FRj)
+     (set FRk (div FRi FRj))
+     ((fr500 (unit u-float-div)))
+)
+
+(define-pmacro (float-binary-op-d name operation op ope major comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR major) (MACH frv))
+       (.str name "$pack $FRdoublei,$FRdoublej,$FRdoublek")
+       (+ pack FRdoublek op FRdoublei ope FRdoublej)
+       (set FRdoublek (operation FRdoublei FRdoublej))
+       ((fr500 (unit u-float-arith)))
+  )
+)
+
+(float-binary-op-d faddd add OP_7A OPE1_06 F-2 "add double float")
+(float-binary-op-d fsubd sub OP_7A OPE1_07 F-2 "sub double float")
+(float-binary-op-d fmuld mul OP_7A OPE1_08 F-3 "mul double float")
+(float-binary-op-d fdivd div OP_7A OPE1_09 F-4 "div double float")
+
+(define-pmacro (conditional-float-binary-op name operation op ope major comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR major) (MACH simple,tomcat,fr500,frv))
+       (.str name "$pack $FRi,$FRj,$FRk,$CCi,$cond")
+       (+ pack FRk op FRi CCi cond ope FRj)
+       (if (eq CCi (or cond 2))
+          (set FRk (operation FRi FRj)))
+       ((fr500 (unit u-float-arith)))
+  )
+)
+
+(conditional-float-binary-op cfadds add OP_6D OPE4_0 F-2 "cond add single")
+(conditional-float-binary-op cfsubs sub OP_6D OPE4_1 F-2 "cond sub single")
+(conditional-float-binary-op cfmuls mul OP_6E OPE4_0 F-3 "cond mul single")
+(conditional-float-binary-op cfdivs div OP_6E OPE4_1 F-4 "cond div single")
+
+(define-pmacro (ne-float-binary-op name operation op ope major comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR major) (MACH simple,tomcat,fr500,frv))
+       (.str name "$pack $FRi,$FRj,$FRk")
+       (+ pack FRk op FRi ope FRj)
+       (sequence ()
+                (c-call VOID "@cpu@_set_ne_index" (index-of FRk))
+                (set FRk (operation FRi FRj)))
+       ((fr500 (unit u-float-arith)))
+  )
+)
+
+(ne-float-binary-op nfadds add OP_79 OPE1_26 F-2 "ne add single")
+(ne-float-binary-op nfsubs sub OP_79 OPE1_27 F-2 "ne sub single")
+(ne-float-binary-op nfmuls mul OP_79 OPE1_28 F-3 "ne mul single")
+(ne-float-binary-op nfdivs div OP_79 OPE1_29 F-4 "ne div single")
+
+(define-pmacro (fcc-eq) 8)
+(define-pmacro (fcc-lt) 4)
+(define-pmacro (fcc-gt) 2)
+(define-pmacro (fcc-uo) 1)
+
+(define-pmacro (compare-and-set-fcc arg1 arg2 fcc)
+  (if (gt arg1 arg2)
+      (set fcc (fcc-gt))
+      (if (eq arg1 arg2)
+         (set fcc (fcc-eq))
+         (if (lt arg1 arg2)
+             (set fcc (fcc-lt))
+             (set fcc (fcc-uo)))))
+)
+
+(dni fcmps
+     "compare single float"
+     ((UNIT FM01) (FR500-MAJOR F-2) (MACH simple,tomcat,fr500,frv))
+     "fcmps$pack $FRi,$FRj,$FCCi_2"
+     (+ pack (cond-null) FCCi_2 OP_79 FRi OPE1_0A FRj)
+     (compare-and-set-fcc FRi FRj FCCi_2)
+     ((fr500 (unit u-float-compare)))
+)
+
+(dni fcmpd
+     "compare double float"
+     ((UNIT FM01) (FR500-MAJOR F-2) (MACH frv))
+     "fcmpd$pack $FRdoublei,$FRdoublej,$FCCi_2"
+     (+ pack (cond-null) FCCi_2 OP_7A FRdoublei OPE1_0A FRdoublej)
+     (compare-and-set-fcc FRdoublei FRdoublej FCCi_2)
+     ((fr500 (unit u-float-compare)))
+)
+
+(dni cfcmps
+     "Conditional compare single, float"
+     ((UNIT FM01) (FR500-MAJOR F-2) (MACH simple,tomcat,fr500,frv))
+     "cfcmps$pack $FRi,$FRj,$FCCi_2,$CCi,$cond"
+     (+ pack (cond-null) FCCi_2 OP_6D FRi CCi cond OPE4_2 FRj)
+     (if (eq CCi (or cond 2))
+        (compare-and-set-fcc FRi FRj FCCi_2))
+     ((fr500 (unit u-float-compare)))
+)
+
+(dni fdcmps
+     "float dual compare single"
+     ((UNIT FM01) (FR500-MAJOR F-6) (MACH simple,tomcat,fr500,frv))
+     "fdcmps$pack $FRi,$FRj,$FCCi_2"
+     (+ pack (cond-null) FCCi_2 OP_79 FRi OPE1_1A FRj)
+     (sequence ()
+              (compare-and-set-fcc FRi FRj FCCi_2)
+              (compare-and-set-fcc (nextreg h-fr FRi 1) (nextreg h-fr FRj 1)
+                                   (nextreg h-fccr FCCi_2 1)))
+     ((fr500 (unit u-float-dual-compare)))
+)
+
+(define-pmacro (float-mul-with-add name add_sub arg1 arg2 targ op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR F-5) (MACH frv))
+       (.str name "$pack $" arg1 ",$" arg2 ",$" targ)
+       (+ pack targ op arg1 ope arg2)
+       (set targ (add_sub (mul arg1 arg2) targ))
+       ((fr500 (unit u-float-dual-arith)))
+  )
+)
+
+(float-mul-with-add fmadds add FRi FRj FRk OP_79 OPE1_0B "mul with add, single")
+(float-mul-with-add fmsubs sub FRi FRj FRk OP_79 OPE1_0C "mul with sub, single")
+
+(float-mul-with-add fmaddd add FRdoublei FRdoublej FRdoublek OP_7A OPE1_0B "mul with add, double")
+(float-mul-with-add fmsubd sub FRdoublei FRdoublej FRdoublek OP_7A OPE1_0C "mul with sub, double")
+
+(dni fdmadds
+     "Float dual multiply with add"
+     ((UNIT FM01) (FR500-MAJOR F-5) (MACH frv))
+     "fdmadds$pack $FRi,$FRj,$FRk"
+     (+ pack FRk OP_79 FRi OPE1_1B FRj)
+     (sequence ()
+              (set FRk (add (mul FRi FRj) FRk))
+              (set (nextreg h-fr FRk 1)
+                   (add (mul (nextreg h-fr FRi 1) (nextreg h-fr FRj 1))
+                        (nextreg h-fr FRk 1))))
+     ; TODO dual registers not referenced for profiling
+     ((fr500 (unit u-float-dual-arith)))
+)
+
+(dni nfdmadds
+     "Non excepting float dual multiply with add"
+     ((UNIT FM01) (FR500-MAJOR F-5) (MACH frv))
+     "nfdmadds$pack $FRi,$FRj,$FRk"
+     (+ pack FRk OP_79 FRi OPE1_3B FRj)
+     (sequence ()
+              (c-call VOID "@cpu@_set_ne_index" (index-of FRk))
+              (set FRk (add (mul FRi FRj) FRk))
+              (c-call VOID "@cpu@_set_ne_index" (add (index-of FRk) 1))
+              (set (nextreg h-fr FRk 1)
+                   (add (mul (nextreg h-fr FRi 1) (nextreg h-fr FRj 1))
+                        (nextreg h-fr FRk 1))))
+     ; TODO dual registers not referenced for profiling
+     ((fr500 (unit u-float-dual-arith)))
+)
+
+(define-pmacro (conditional-float-mul-with-add
+               name add_sub arg1 arg2 targ op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR F-5) (MACH frv) CONDITIONAL)
+       (.str name "$pack $FRi,$FRj,$FRk,$CCi,$cond")
+       (+ pack FRk op FRi CCi cond ope FRj)
+       (if (eq CCi (or cond 2))
+          (set targ (add_sub (mul arg1 arg2) targ)))
+       ((fr500 (unit u-float-dual-arith)))
+  )
+)
+
+(conditional-float-mul-with-add cfmadds add FRi FRj FRk OP_6F OPE4_0 "conditional mul with add, single")
+(conditional-float-mul-with-add cfmsubs sub FRi FRj FRk OP_6F OPE4_1 "conditional mul with sub, single")
+
+(define-pmacro (ne-float-mul-with-add name add_sub arg1 arg2 targ op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR F-5) (MACH frv) NON-EXCEPTING)
+       (.str name "$pack $" arg1 ",$" arg2 ",$" targ)
+       (+ pack targ op arg1 ope arg2)
+       (sequence ()
+                (c-call VOID "@cpu@_set_ne_index" (index-of targ))
+                (set targ (add_sub (mul arg1 arg2) targ)))
+       ((fr500 (unit u-float-dual-arith)))
+  )
+)
+
+(ne-float-mul-with-add nfmadds add FRi FRj FRk OP_79 OPE1_2B "non excepting mul with add, single")
+(ne-float-mul-with-add nfmsubs sub FRi FRj FRk OP_79 OPE1_2C "non excepting mul with sub, single")
+
+(define-pmacro (float-parallel-mul-add-semantics cond add_sub arg1 arg2 targ)
+  (if cond
+      (sequence ()
+               (set targ (mul arg1 arg2))
+               (set (nextreg h-fr targ 1)
+                    (add_sub (nextreg h-fr arg1 1) (nextreg h-fr arg2 1)))))
+)
+
+(define-pmacro (float-parallel-mul-add
+               name add_sub arg1 arg2 targ op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR F-5) (MACH simple,tomcat,fr500,frv))
+       (.str name "$pack $" arg1 ",$" arg2 ",$" targ)
+       (+ pack targ op arg1 ope arg2)
+       (float-parallel-mul-add-semantics 1 add_sub arg1 arg2 targ)
+       ((fr500 (unit u-float-dual-arith)))
+  )
+)
+
+(float-parallel-mul-add fmas add FRi FRj FRk OP_79 OPE1_0E "parallel mul/add, single")
+(float-parallel-mul-add fmss sub FRi FRj FRk OP_79 OPE1_0F "parallel mul/sub, single")
+
+(define-pmacro (float-dual-parallel-mul-add-semantics add_sub arg1 arg2 targ)
+  (sequence ()
+           (set targ (mul arg1 arg2))
+           (set (nextreg h-fr targ 1)
+                (add_sub (nextreg h-fr arg1 1) (nextreg h-fr arg2 1)))
+           (set (nextreg h-fr targ 2)
+                (mul (nextreg h-fr arg1 2)     (nextreg h-fr arg2 2)))
+           (set (nextreg h-fr targ 3)
+                (add_sub (nextreg h-fr arg1 3) (nextreg h-fr arg2 3))))
+)
+
+(define-pmacro (float-dual-parallel-mul-add
+               name add_sub arg1 arg2 targ op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR F-5) (MACH frv))
+       (.str name "$pack $" arg1 ",$" arg2 ",$" targ)
+       (+ pack targ op arg1 ope arg2)
+       (float-dual-parallel-mul-add-semantics add_sub arg1 arg2 targ)
+       ()
+  )
+)
+
+(float-dual-parallel-mul-add fdmas add FRi FRj FRk OP_79 OPE1_1C "dual parallel mul/add, single")
+(float-dual-parallel-mul-add fdmss sub FRi FRj FRk OP_79 OPE1_1D "dual parallel mul/sub, single")
+
+(define-pmacro (ne-float-dual-parallel-mul-add-semantics add_sub arg1 arg2 targ)
+  (sequence ()
+           (c-call VOID "@cpu@_set_ne_index" (index-of targ))
+           (c-call VOID "@cpu@_set_ne_index" (add (index-of targ) 1))
+           (c-call VOID "@cpu@_set_ne_index" (add (index-of targ) 2))
+           (c-call VOID "@cpu@_set_ne_index" (add (index-of targ) 3))
+           (set targ (mul arg1 arg2))
+           (set (nextreg h-fr targ 1)
+                (add_sub (nextreg h-fr arg1 1) (nextreg h-fr arg2 1)))
+           (set (nextreg h-fr targ 2)
+                (mul (nextreg h-fr arg1 2)     (nextreg h-fr arg2 2)))
+           (set (nextreg h-fr targ 3)
+                (add_sub (nextreg h-fr arg1 3) (nextreg h-fr arg2 3))))
+)
+
+(define-pmacro (ne-float-dual-parallel-mul-add
+               name add_sub arg1 arg2 targ op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR F-5) (MACH frv))
+       (.str name "$pack $" arg1 ",$" arg2 ",$" targ)
+       (+ pack targ op arg1 ope arg2)
+       (ne-float-dual-parallel-mul-add-semantics add_sub arg1 arg2 targ)
+       ()
+  )
+)
+
+(ne-float-dual-parallel-mul-add nfdmas add FRi FRj FRk OP_79 OPE1_3C "non excepting dual parallel mul/add, single")
+(ne-float-dual-parallel-mul-add nfdmss sub FRi FRj FRk OP_79 OPE1_3D "non excepting dual parallel mul/sub, single")
+
+(define-pmacro (conditional-float-parallel-mul-add name add_sub op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR F-5) CONDITIONAL (MACH simple,tomcat,fr500,frv))
+       (.str name "$pack $FRi,$FRj,$FRk,$CCi,$cond")
+       (+ pack FRk op FRi CCi cond ope FRj)
+       (float-parallel-mul-add-semantics (eq CCi (or cond 2))
+                                        add_sub FRi FRj FRk)
+       ((fr500 (unit u-float-dual-arith)))
+  )
+)
+
+(conditional-float-parallel-mul-add cfmas add OP_6F OPE4_2 "conditional parallel mul/add, single")
+(conditional-float-parallel-mul-add cfmss sub OP_6F OPE4_3 "conditional parallel mul/sub, single")
+
+(define-pmacro (float-parallel-mul-add-double-semantics add_sub arg1 arg2 targ)
+  (sequence ()
+           (set targ (ftrunc SF (mul DF (fext DF arg1) (fext DF arg2))))
+           (set (nextreg h-fr targ 1)
+                (ftrunc SF (add_sub DF
+                                    (fext DF (nextreg h-fr arg1 1))
+                                    (fext DF (nextreg h-fr arg2 1))))))
+)
+
+(define-pmacro (float-parallel-mul-add-double
+               name add_sub arg1 arg2 targ op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR F-5) (MACH frv))
+       (.str name "$pack $" arg1 ",$" arg2 ",$" targ)
+       (+ pack targ op arg1 ope arg2)
+       (float-parallel-mul-add-double-semantics add_sub arg1 arg2 targ)
+       ()
+  )
+)
+
+(float-parallel-mul-add-double fmad add FRi FRj FRk OP_7A OPE1_0E "parallel mul/add, double")
+(float-parallel-mul-add-double fmsd sub FRi FRj FRk OP_7A OPE1_0F "parallel mul/sub, double")
+
+(define-pmacro (ne-float-parallel-mul-add name add_sub op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR F-5) (MACH simple,tomcat,fr500,frv))
+       (.str name "$pack $FRi,$FRj,$FRk")
+       (+ pack FRk op FRi ope FRj)
+       (sequence ()
+                (c-call VOID "@cpu@_set_ne_index" (index-of FRk))
+                (set FRk (mul FRi FRj))
+                (c-call VOID "@cpu@_set_ne_index" (add (index-of FRk) 1))
+                (set (nextreg h-fr FRk 1)
+                     (add_sub (nextreg h-fr FRi 1) (nextreg h-fr FRj 1))))
+       ((fr500 (unit u-float-dual-arith)))
+  )
+)
+
+(ne-float-parallel-mul-add nfmas add OP_79 OPE1_2E "ne parallel mul/add,single")
+(ne-float-parallel-mul-add nfmss sub OP_79 OPE1_2F "ne parallel mul/sub,single")
+
+(define-pmacro (float-dual-arith name major oper1 oper2 op ope attr comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR major) attr)
+       (.str name "$pack $FRi,$FRj,$FRk")
+       (+ pack FRk op FRi ope FRj)
+       (sequence ()
+                (set FRk (oper1 FRi FRj))
+                (set (nextreg h-fr FRk 1)
+                     (oper2 (nextreg h-fr FRi 1) (nextreg h-fr FRj 1))))
+       ((fr500 (unit u-float-dual-arith)))
+  )
+)
+
+(float-dual-arith fdadds F-6 add add OP_79 OPE1_16 (MACH simple,tomcat,fr500,frv) "dual add, single")
+(float-dual-arith fdsubs F-6 sub sub OP_79 OPE1_17 (MACH simple,tomcat,fr500,frv) "dual sub, single")
+(float-dual-arith fdmuls F-7 mul mul OP_79 OPE1_18 (MACH simple,tomcat,fr500,frv) "dual mul, single")
+(float-dual-arith fddivs F-7 div div OP_79 OPE1_19 (MACH frv) "dual div,single")
+(float-dual-arith fdsads F-6 add sub OP_79 OPE1_1E (MACH simple,tomcat,fr500,frv) "dual add/sub, single")
+
+(dni fdmulcs
+     "Float dual cross multiply single"
+     ((UNIT FM01) (FR500-MAJOR F-7) (MACH simple,tomcat,fr500,frv))
+     "fdmulcs$pack $FRi,$FRj,$FRk"
+     (+ pack FRk OP_79 FRi OPE1_1F FRj)
+     (sequence ()
+              (set FRk (mul FRi (nextreg h-fr FRj 1)))
+              (set (nextreg h-fr FRk 1) (mul (nextreg h-fr FRi 1) FRj)))
+     ((fr500 (unit u-float-dual-arith)))
+)
+
+(dni nfdmulcs
+     "NE float dual cross multiply single"
+     ((UNIT FM01) (FR500-MAJOR F-7) (MACH simple,tomcat,fr500,frv))
+     "nfdmulcs$pack $FRi,$FRj,$FRk"
+     (+ pack FRk OP_79 FRi OPE1_3F FRj)
+     (sequence ()
+              (c-call VOID "@cpu@_set_ne_index" (index-of FRk))
+              (set FRk (mul FRi (nextreg h-fr FRj 1)))
+              (c-call VOID "@cpu@_set_ne_index" (add (index-of FRk) 1))
+              (set (nextreg h-fr FRk 1) (mul (nextreg h-fr FRi 1) FRj)))
+     ((fr500 (unit u-float-dual-arith)))
+)
+
+(define-pmacro (ne-float-dual-arith name major oper1 oper2 op ope attr comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR major) attr)
+       (.str name "$pack $FRi,$FRj,$FRk")
+       (+ pack FRk op FRi ope FRj)
+       (sequence ()
+                (c-call VOID "@cpu@_set_ne_index" (index-of FRk))
+                (set FRk (oper1 FRi FRj))
+                (c-call VOID "@cpu@_set_ne_index" (add (index-of FRk) 1))
+                (set (nextreg h-fr FRk 1)
+                     (oper2 (nextreg h-fr FRi 1) (nextreg h-fr FRj 1))))
+       ((fr500 (unit u-float-dual-arith)))
+  )
+)
+
+(ne-float-dual-arith nfdadds F-6 add add OP_79 OPE1_36 (MACH simple,tomcat,fr500,frv) "ne dual add, single")
+(ne-float-dual-arith nfdsubs F-6 sub sub OP_79 OPE1_37 (MACH simple,tomcat,fr500,frv) "ne dual sub, single")
+(ne-float-dual-arith nfdmuls F-7 mul mul OP_79 OPE1_38 (MACH simple,tomcat,fr500,frv) "ne dual mul, single")
+(ne-float-dual-arith nfddivs F-7 div div OP_79 OPE1_39 (MACH frv) "ne dual div,single")
+(ne-float-dual-arith nfdsads F-6 add sub OP_79 OPE1_3E (MACH simple,tomcat,fr500,frv) "ne dual add/sub, single")
+
+(dni nfdcmps
+     "non-excepting dual float compare"
+     ((UNIT FM01) (FR500-MAJOR F-6) (MACH simple,tomcat,frv))
+     "nfdcmps$pack $FRi,$FRj,$FCCi_2"
+     (+ pack (cond-null) FCCi_2 OP_79 FRi OPE1_3A FRj)
+     (sequence ()
+              (c-call VOID "@cpu@_set_ne_index" (index-of FRk))
+              (compare-and-set-fcc FRi FRj FCCi_2)
+              (c-call VOID "@cpu@_set_ne_index" (add (index-of FRk) 1))
+              (compare-and-set-fcc (nextreg h-fr FRi 1) (nextreg h-fr FRj 1)
+                                   (nextreg h-fccr FCCi_2 1)))
+     ((fr500 (unit u-float-dual-compare)))
+)
+
+; Media Instructions
+;
+(define-pmacro (halfword hilo arg offset)
+  (reg (.sym h-fr_ hilo) (add (index-of arg) offset)))
+
+(dni mhsetlos
+     "Media set lower signed 12 bits"
+     ((UNIT FM01) (MACH fr400) (FR400-MAJOR M-1))
+     "mhsetlos$pack $u12,$FRklo"
+     (+ pack FRklo OP_78 OPE1_20 u12)
+     (set FRklo u12)
+     ((fr400 (unit u-media-hilo)))
+)
+
+(dni mhsethis
+     "Media set upper signed 12 bits"
+     ((UNIT FM01) (MACH fr400) (FR400-MAJOR M-1))
+     "mhsethis$pack $u12,$FRkhi"
+     (+ pack FRkhi OP_78 OPE1_22 u12)
+     (set FRkhi u12)
+     ((fr400 (unit u-media-hilo)))
+)
+
+(dni mhdsets
+     "Media dual set halfword signed 12 bits"
+     ((UNIT FM01) (MACH fr400) (FR400-MAJOR M-1))
+     "mhdsets$pack $u12,$FRintk"
+     (+ pack FRintk OP_78 OPE1_24 u12)
+     (sequence ()
+              ; hack to get FRintk passed to modelling functions
+              (set FRintk (c-raw-call SI "frv_ref_SI" FRintk))
+              (set (halfword hi FRintk 0) u12)
+              (set (halfword lo FRintk 0) u12))
+     ((fr400 (unit u-media-1)))
+)
+
+(define-pmacro (set-5-semantics target value)
+  (sequence ((HI tmp))
+           (set tmp target)
+           (set tmp (and tmp #x07ff))
+           (set tmp (or tmp (sll (and s5 #x1f) 11)))
+           (set target tmp))
+)
+
+(define-pmacro (media-set-5 name hilo op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (MACH fr400) (FR400-MAJOR M-1))
+       (.str name "$pack $s5,$FRk" hilo)
+       (+ pack (.sym FRk hilo) op (FRi-null) ope (misc-null-11) s5)
+       (set-5-semantics (.sym FRk hilo) s5)
+       ((fr400 (unit u-media-hilo)))
+  )
+)
+
+(media-set-5 mhsetloh lo OP_78 OPE1_21 "Media set upper 5 bits lo")
+(media-set-5 mhsethih hi OP_78 OPE1_23 "Media set upper 5 bits hi")
+
+(dni mhdseth
+     "Media dual set halfword upper 5 bits"
+     ((UNIT FM01) (MACH fr400) (FR400-MAJOR M-1))
+     "mhdseth$pack $s5,$FRintk"
+     (+ pack FRintk OP_78 (FRi-null) OPE1_25 (misc-null-11) s5)
+     (sequence ()
+              ; hack to get FRintk passed to modelling functions
+              (set FRintk (c-raw-call SI "frv_ref_SI" FRintk))
+              (set-5-semantics (halfword hi FRintk 0) s5)
+              (set-5-semantics (halfword lo FRintk 0) s5))
+     ((fr400 (unit u-media-1)))
+)
+
+(define-pmacro (media-logic-r-r name operation op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR M-1) (FR400-MAJOR M-1))
+       (.str name "$pack $FRinti,$FRintj,$FRintk")
+       (+ pack FRintk op FRinti ope FRintj)
+       (set FRintk (operation FRinti FRintj))
+       ((fr400 (unit u-media-1))
+       (fr500 (unit u-media)))
+  )
+)
+
+(media-logic-r-r mand and OP_7B OPE1_00 "and reg/reg")
+(media-logic-r-r mor  or  OP_7B OPE1_01 "or  reg/reg")
+(media-logic-r-r mxor xor OP_7B OPE1_02 "xor reg/reg")
+
+(define-pmacro (conditional-media-logic name operation op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR M-1) (FR400-MAJOR M-1) CONDITIONAL)
+       (.str name "$pack $FRinti,$FRintj,$FRintk,$CCi,$cond")
+       (+ pack FRintk op FRinti CCi cond ope FRintj)
+       (if (eq CCi (or cond 2))
+          (set FRintk (operation FRinti FRintj)))
+       ((fr400 (unit u-media-1))
+       (fr500 (unit u-media)))
+  )
+)
+
+(conditional-media-logic cmand and OP_70 OPE4_0 "conditional and reg/reg")
+(conditional-media-logic cmor  or  OP_70 OPE4_1 "conditional or  reg/reg")
+(conditional-media-logic cmxor xor OP_70 OPE4_2 "conditional xor reg/reg")
+
+(dni mnot
+     ("mnot")
+     ((UNIT FM01) (FR500-MAJOR M-1) (FR400-MAJOR M-1))
+     ("mnot$pack $FRintj,$FRintk")
+     (+ pack FRintk OP_7B (rs-null) OPE1_03 FRintj)
+     (set FRintk (inv FRintj))
+     ((fr400 (unit u-media-1))
+      (fr500 (unit u-media)))
+)
+
+(dni cmnot
+     ("cmnot")
+     ((UNIT FM01) (FR500-MAJOR M-1) (FR400-MAJOR M-1) CONDITIONAL)
+     ("cmnot$pack $FRintj,$FRintk,$CCi,$cond")
+     (+ pack FRintk OP_70 (rs-null) CCi cond OPE4_3 FRintj)
+     (if (eq CCi (or cond 2))
+        (set FRintk (inv FRintj)))
+     ((fr400 (unit u-media-1))
+      (fr500 (unit u-media)))
+)
+
+(define-pmacro (media-rotate-r-r name operation op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR M-2) (FR400-MAJOR M-1))
+       (.str name "$pack $FRinti,$u6,$FRintk")
+       (+ pack FRintk op FRinti ope u6)
+       (set FRintk (operation FRinti (and u6 #x1f)))
+       ((fr400 (unit u-media-3))
+       (fr500 (unit u-media)))
+  )
+)
+
+(media-rotate-r-r mrotli rol OP_7B OPE1_04 "rotate left reg/reg")
+(media-rotate-r-r mrotri ror OP_7B OPE1_05 "rotate right reg/reg")
+
+(define-pmacro (media-cut-r-r name arg op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR M-2) (FR400-MAJOR M-2))
+       (.str name "$pack $FRinti,$" arg ",$FRintk")
+       (+ pack FRintk op FRinti ope arg)
+       (set FRintk (c-call SI "@cpu@_cut" FRinti (nextreg h-fr_int FRinti 1) arg))
+       ((fr400 (unit u-media-3))
+       (fr500 (unit u-media)))
+  )
+)
+
+(media-cut-r-r mwcut  FRintj OP_7B OPE1_06 "media cut")
+(media-cut-r-r mwcuti u6     OP_7B OPE1_07 "media cut")
+
+(define-pmacro (media-cut-acc name arg op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR M-2) (FR400-MAJOR M-1))
+       (.str name "$pack $ACC40Si,$" arg ",$FRintk")
+       (+ pack FRintk op ACC40Si ope arg)
+       (set FRintk (c-call SI "@cpu@_media_cut" ACC40Si arg))
+       ((fr400 (unit u-media-4))
+       (fr500 (unit u-media)))
+  )
+)
+
+(media-cut-acc mcut  FRintj OP_7B OPE1_2C "media accumulator cut reg")
+(media-cut-acc mcuti s6     OP_7B OPE1_2E "media accumulator cut immed")
+
+(define-pmacro (media-cut-acc-ss name arg op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR M-2) (FR400-MAJOR M-1))
+       (.str name "$pack $ACC40Si,$" arg ",$FRintk")
+       (+ pack FRintk op ACC40Si ope arg)
+       (set FRintk (c-call SI "@cpu@_media_cut_ss" ACC40Si arg))
+       ((fr400 (unit u-media-4))
+       (fr500 (unit u-media)))
+  )
+)
+
+(media-cut-acc-ss mcutss  FRintj OP_7B OPE1_2D "media accumulator cut reg with saturation")
+(media-cut-acc-ss mcutssi s6     OP_7B OPE1_2F "media accumulator cut immed with saturation")
+
+; Dual Media Instructions
+;
+(define-pmacro (register-unaligned register alignment)
+  (and (index-of register) (sub alignment 1))
+)
+
+(dni mdcutssi
+     "Media dual cut with signed saturation"
+     ((UNIT FM0) (MACH fr400) (FR400-MAJOR M-2))
+     "mdcutssi$pack $ACC40Si,$s6,$FRintk"
+     (+ pack FRintk OP_78 ACC40Si OPE1_0E s6)
+     (if (register-unaligned ACC40Si 2)
+        (c-call VOID "@cpu@_media_acc_not_aligned")
+        (if (register-unaligned FRintk 2)
+            (c-call VOID "@cpu@_media_register_not_aligned")
+            (sequence ()
+                      (set FRintk (c-call SI "@cpu@_media_cut_ss" ACC40Si s6))
+                      (set (nextreg h-fr_int FRintk 1)
+                           (c-call SI "@cpu@_media_cut_ss"
+                                   (nextreg h-acc40S ACC40Si 1) s6)))))
+     ((fr400 (unit u-media-4-acc-dual)))
+)
+
+; The (add (xxxx) (mul arg 0)) is a hack to get a reference to arg generated
+; so it will be passed to the unit modelers.   YUCK!!!!!
+(define-pmacro (extract-hilo reg1 off1 reg2 off2 arg1hi arg1lo arg2hi arg2lo)
+  (sequence ()
+           (set arg1hi (add (halfword hi reg1 off1) (mul reg1 0)))
+           (set arg1lo (add (halfword lo reg1 off1) (mul reg1 0)))
+           (set arg2hi (add (halfword hi reg2 off2) (mul reg2 0)))
+           (set arg2lo (add (halfword lo reg2 off2) (mul reg2 0))))
+)
+
+(dni maveh
+     "Media dual average"
+     ((UNIT FM01) (FR500-MAJOR M-1) (FR400-MAJOR M-1))
+     "maveh$pack $FRinti,$FRintj,$FRintk"
+     (+ pack FRintk OP_7B FRinti OPE1_08 FRintj)
+     (set FRintk (c-call SI "@cpu@_media_average" FRinti FRintj))
+     ((fr400 (unit u-media-1))
+      (fr500 (unit u-media)))
+)
+
+(define-pmacro (media-dual-shift name operation op ope profile comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR M-2) (FR400-MAJOR M-1))
+       (.str name "$pack $FRinti,$u6,$FRintk")
+       (+ pack FRintk op FRinti ope u6)
+       (sequence ()
+                ; hack to get these referenced for profiling
+                (set FRinti (c-raw-call SI "frv_ref_SI" FRinti))
+                (set FRintk (c-raw-call SI "frv_ref_SI" FRintk))
+                (set (halfword hi FRintk 0)
+                     (operation (halfword hi FRinti 0) (and u6 #xf)))
+                (set (halfword lo FRintk 0)
+                     (operation (halfword lo FRinti 0) (and u6 #xf))))
+       profile
+  )
+)
+
+(media-dual-shift msllhi sll OP_7B OPE1_09
+                 ((fr400 (unit u-media-3)) (fr500 (unit u-media)))
+                 "Media dual shift left  logical")
+(media-dual-shift msrlhi srl OP_7B OPE1_0A
+                 ((fr400 (unit u-media-3)) (fr500 (unit u-media)))
+                 "Media dual shift right logical")
+(media-dual-shift msrahi sra OP_7B OPE1_0B
+                 ((fr400 (unit u-media-6)) (fr500 (unit u-media)))
+                 "Media dual shift right arithmetic")
+
+(define-pmacro (media-dual-word-rotate-r-r name operation op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM0) (MACH fr400) (FR400-MAJOR M-2))
+       (.str name "$pack $FRinti,$u6,$FRintk")
+       (+ pack FRintk op FRinti ope u6)
+       (if (orif (register-unaligned FRinti 2)
+                (register-unaligned FRintk 2))
+          (c-call VOID "@cpu@_media_register_not_aligned")
+          (sequence ()
+                    (set FRintk (operation FRinti (and u6 #x1f)))
+                    (set (nextreg h-fr_int FRintk 1)
+                         (operation (nextreg h-fr_int FRinti 1)
+                                    (and u6 #x1f)))))
+       ((fr400 (unit u-media-3-quad)))
+  )
+)
+
+(media-dual-word-rotate-r-r mdrotli rol OP_78 OPE1_0B "rotate left reg/reg")
+
+(dni mcplhi
+     "Media dual couple, halfword"
+     ((UNIT FM0) (MACH fr400) (FR400-MAJOR M-2))
+     "mcplhi$pack $FRinti,$u6,$FRintk"
+     (+ pack FRintk OP_78 FRinti OPE1_0C u6)
+     (sequence ((HI arg1) (HI arg2) (HI shift))
+              (set FRinti (c-raw-call SI "frv_ref_SI" FRinti))
+              (set FRintk (c-raw-call SI "frv_ref_SI" FRintk))
+              (set shift (and u6 #xf))
+              (set arg1 (sll (halfword hi FRinti 0) shift))
+              (if (ne shift 0)
+                  (sequence ()
+                            (set arg2 (halfword hi FRinti 1))
+                            (set arg2 (srl HI (sll HI arg2 (sub 15 shift))
+                                           (sub 15 shift)))
+                            (set arg1 (or HI arg1 arg2))))
+              (set (halfword hi FRintk 0) arg1))
+     ((fr400 (unit u-media-3-dual)))
+)
+
+(dni mcpli
+     "Media dual couple, word"
+     ((UNIT FM0) (MACH fr400) (FR400-MAJOR M-2))
+     "mcpli$pack $FRinti,$u6,$FRintk"
+     (+ pack FRintk OP_78 FRinti OPE1_0D u6)
+     (sequence ((SI tmp) (SI shift))
+              (set shift (and u6 #x1f))
+              (set tmp (sll FRinti shift))
+              (if (ne shift 0)
+                  (sequence ((SI tmp1))
+                            (set tmp1 (srl (sll (nextreg h-fr_int FRinti 1)
+                                                (sub 31 shift))
+                                           (sub 31 shift)))
+                            (set tmp (or tmp tmp1))))
+              (set FRintk tmp))
+     ((fr400 (unit u-media-3-dual)))
+)
+
+(define-pmacro (saturate arg max min result)
+  (if (gt arg max)
+      (set result max)
+      (if (lt arg min)
+         (set result min)
+         (set result arg)))
+)
+
+(dni msaths
+     "Media dual saturation signed"
+     ((UNIT FM01) (FR500-MAJOR M-1) (FR400-MAJOR M-1))
+     "msaths$pack $FRinti,$FRintj,$FRintk"
+     (+ pack FRintk OP_7B FRinti OPE1_0C FRintj)
+     (sequence ((HI argihi) (HI argilo) (HI argjhi) (HI argjlo))
+              (extract-hilo FRinti 0 FRintj 0 argihi argilo argjhi argjlo)
+              (saturate argihi argjhi (inv argjhi) (halfword hi FRintk 0))
+              (saturate argilo argjlo (inv argjlo) (halfword lo FRintk 0)))
+     ((fr400 (unit u-media-1))
+      (fr500 (unit u-media)))
+)
+
+(dni mqsaths
+     "Media quad saturation signed"
+     ((UNIT FM01) (MACH fr400) (FR400-MAJOR M-1))
+     "mqsaths$pack $FRinti,$FRintj,$FRintk"
+     (+ pack FRintk OP_78 FRinti OPE1_0F FRintj)
+     (if (orif (register-unaligned FRinti 2)
+              (orif (register-unaligned FRintj 2)
+                    (register-unaligned FRintk 2)))
+        (c-call VOID "@cpu@_media_register_not_aligned")
+        (sequence ((HI argihi) (HI argilo) (HI argjhi) (HI argjlo))
+                  ; hack to get FRintk referenced as a target for profiling
+                  (set FRintk (c-raw-call SI "frv_ref_SI" FRintk))
+                  (extract-hilo FRinti 0 FRintj 0 argihi argilo argjhi argjlo)
+                  (saturate argihi argjhi (inv argjhi) (halfword hi FRintk 0))
+                  (saturate argilo argjlo (inv argjlo) (halfword lo FRintk 0))
+                  (extract-hilo FRinti 1 FRintj 1 argihi argilo argjhi argjlo)
+                  (saturate argihi argjhi (inv argjhi) (halfword hi FRintk 1))
+                  (saturate argilo argjlo (inv argjlo) (halfword lo FRintk 1))))
+     ((fr400 (unit u-media-1-quad)))
+)
+
+(define-pmacro (saturate-unsigned arg max result)
+  (if (gt arg max)
+      (set result max)
+      (set result arg))
+)
+
+(dni msathu
+     "Media dual saturation unsigned"
+     ((UNIT FM01) (FR500-MAJOR M-1) (FR400-MAJOR M-1))
+     "msathu$pack $FRinti,$FRintj,$FRintk"
+     (+ pack FRintk OP_7B FRinti OPE1_0D FRintj)
+     (sequence ((UHI argihi) (UHI argilo) (UHI argjhi) (UHI argjlo))
+              (extract-hilo FRinti 0 FRintj 0 argihi argilo argjhi argjlo)
+              (saturate-unsigned argihi argjhi (halfword hi FRintk 0))
+              (saturate-unsigned argilo argjlo (halfword lo FRintk 0)))
+     ((fr400 (unit u-media-1))
+      (fr500 (unit u-media)))
+)
+
+(define-pmacro (media-dual-compare name mode op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR M-1) (FR400-MAJOR M-1))
+       (.str name "$pack $FRinti,$FRintj,$FCCk")
+       (+ pack (cond-null) FCCk op FRinti ope FRintj)
+       (if (register-unaligned FCCk 2)
+          (c-call VOID "@cpu@_media_cr_not_aligned")
+          (sequence ((mode argihi) (mode argilo) (mode argjhi) (mode argjlo))
+                    (extract-hilo FRinti 0 FRintj 0
+                                  argihi argilo argjhi argjlo)
+                    (compare-and-set-fcc argihi argjhi FCCk)
+                    (compare-and-set-fcc argilo argjlo (nextreg h-fccr FCCk 1))))
+       ; TODO - doesn't handle second FCC
+       ((fr400 (unit u-media-7))
+       (fr500 (unit u-media)))
+  )
+)
+
+(media-dual-compare mcmpsh HI  OP_7B OPE1_0E "Media dual compare signed")
+(media-dual-compare mcmpuh UHI OP_7B OPE1_0F "Media dual compare unsigned")
+
+; Bits for the MSR.SIE field
+(define-pmacro (msr-sie-nil)      0)
+(define-pmacro (msr-sie-fri-hi)   8)
+(define-pmacro (msr-sie-fri-lo)   4)
+(define-pmacro (msr-sie-fri-1-hi) 2)
+(define-pmacro (msr-sie-fri-1-lo) 1)
+(define-pmacro (msr-sie-acci)     8)
+(define-pmacro (msr-sie-acci-1)   4)
+(define-pmacro (msr-sie-acci-2)   2)
+(define-pmacro (msr-sie-acci-3)   1)
+
+(define-pmacro (saturate-v arg max min sie result)
+  (if (gt DI arg max)
+      (sequence ()
+               (set result max)
+               (c-call VOID "@cpu@_media_overflow" sie))
+      (if (lt DI arg min)
+         (sequence ()
+                   (set result min)
+                   (c-call VOID "@cpu@_media_overflow" sie))
+         (set result arg)))
+)
+
+(dni mabshs
+     "Media dual absolute value, halfword"
+     ((UNIT FM01) (MACH fr400) (FR400-MAJOR M-1))
+     "mabshs$pack $FRintj,$FRintk"
+     (+ pack FRintk OP_78 (FRi-null) OPE1_0A FRintj)
+     (sequence ((HI arghi) (HI arglo))
+              (set FRintj (c-raw-call SI "frv_ref_SI" FRintj))
+              (set FRintk (c-raw-call SI "frv_ref_SI" FRintk))
+              (set arghi (halfword hi FRintj 0))
+              (set arglo (halfword lo FRintj 0))
+              (saturate-v (abs arghi) 32767 -32768 (msr-sie-fri-hi)
+                          (halfword hi FRintk 0))
+              (saturate-v (abs arglo) 32767 -32768 (msr-sie-fri-lo)
+                          (halfword lo FRintk 0)))
+     ((fr400 (unit u-media-1)))
+)
+
+(define-pmacro (media-arith-sat-semantics
+               operation arg1 arg2 res mode max min sie)
+  (sequence ((DI tmp))
+           (set tmp (operation arg1 arg2))
+           (saturate-v tmp max min sie res))
+)
+
+(define-pmacro (media-dual-arith-sat-semantics operation mode max min)
+  (sequence ((mode argihi) (mode argilo) (mode argjhi) (mode argjlo))
+           (extract-hilo FRinti 0 FRintj 0 argihi argilo argjhi argjlo)
+           (media-arith-sat-semantics operation argihi argjhi
+                                      (halfword hi FRintk 0) mode max min
+                                      (msr-sie-fri-hi))
+           (media-arith-sat-semantics operation argilo argjlo
+                                      (halfword lo FRintk 0) mode max min
+                                      (msr-sie-fri-lo)))
+)
+
+(define-pmacro (media-dual-arith-sat name operation mode max min op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR M-1) (FR400-MAJOR M-1))
+       (.str name "$pack $FRinti,$FRintj,$FRintk")
+       (+ pack FRintk op FRinti ope FRintj)
+       (media-dual-arith-sat-semantics operation mode max min)
+       ((fr400 (unit u-media-1))
+       (fr500 (unit u-media)))
+  )
+)
+
+(media-dual-arith-sat maddhss add  HI 32767 -32768 OP_7B OPE1_10 "Media dual add signed with saturation")
+(media-dual-arith-sat maddhus add UHI 65535      0 OP_7B OPE1_11 "Media dual add unsigned with saturation")
+
+(media-dual-arith-sat msubhss sub  HI 32767 -32768 OP_7B OPE1_12 "Media dual sub signed with saturation")
+(media-dual-arith-sat msubhus sub UHI 65535      0 OP_7B OPE1_13 "Media dual sub unsigned with saturation")
+
+(define-pmacro (conditional-media-dual-arith-sat
+               name operation mode max min op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR M-1) (FR400-MAJOR M-1) CONDITIONAL)
+       (.str name "$pack $FRinti,$FRintj,$FRintk,$CCi,$cond")
+       (+ pack FRintk op FRinti CCi cond ope FRintj)
+       (if (eq CCi (or cond 2))
+          (media-dual-arith-sat-semantics operation mode max min))
+       ((fr400 (unit u-media-1))
+       (fr500 (unit u-media)))
+  )
+)
+
+(conditional-media-dual-arith-sat cmaddhss add  HI 32767 -32768 OP_71 OPE4_0 "Conditional Media dual add signed with saturation")
+(conditional-media-dual-arith-sat cmaddhus add UHI 65535      0 OP_71 OPE4_1 "Conditional Media dual add unsigned with saturation")
+
+(conditional-media-dual-arith-sat cmsubhss sub  HI 32767 -32768 OP_71 OPE4_2 "Conditional Media dual sub signed with saturation")
+(conditional-media-dual-arith-sat cmsubhus sub UHI 65535      0 OP_71 OPE4_3 "Conditional Media dual sub unsigned with saturation")
+
+(define-pmacro (media-quad-arith-sat-semantics cond operation mode max min)
+  (if (orif (register-unaligned FRinti 2)
+           (orif (register-unaligned FRintj 2)
+                 (register-unaligned FRintk 2)))
+      (c-call VOID "@cpu@_media_register_not_aligned")
+      (if cond
+         (sequence ((mode argihi) (mode argilo) (mode argjhi) (mode argjlo))
+                   ; hack to get FRintk referenced as a target for profiling
+                   (set FRintk (c-raw-call SI "frv_ref_SI" FRintk))
+                   (extract-hilo FRinti 0 FRintj 0
+                                 argihi argilo argjhi argjlo)
+                   (media-arith-sat-semantics operation argihi argjhi
+                                              (halfword hi FRintk 0) mode
+                                              max min (msr-sie-fri-hi))
+                   (media-arith-sat-semantics operation argilo argjlo
+                                              (halfword lo FRintk 0) mode
+                                              max min (msr-sie-fri-lo))
+                   (extract-hilo FRinti 1 FRintj 1
+                                 argihi argilo argjhi argjlo)
+                   (media-arith-sat-semantics operation argihi argjhi
+                                              (halfword hi FRintk 1) mode
+                                              max min  (msr-sie-fri-1-hi))
+                   (media-arith-sat-semantics operation argilo argjlo
+                                              (halfword lo FRintk 1) mode
+                                              max min (msr-sie-fri-1-lo)))))
+)
+
+(define-pmacro (media-quad-arith-sat name operation mode max min op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR M-1) (FR400-MAJOR M-2))
+       (.str name "$pack $FRinti,$FRintj,$FRintk")
+       (+ pack FRintk op FRinti ope FRintj)
+       (media-quad-arith-sat-semantics 1 operation mode max min)
+       ((fr400 (unit u-media-1-quad))
+       (fr500 (unit u-media-quad-arith)))
+  )
+)
+
+(media-quad-arith-sat mqaddhss add  HI 32767 -32768 OP_7B OPE1_18 "Media quad add signed with saturation")
+(media-quad-arith-sat mqaddhus add UHI 65535      0 OP_7B OPE1_19 "Media quad add unsigned with saturation")
+
+(media-quad-arith-sat mqsubhss sub  HI 32767 -32768 OP_7B OPE1_1A "Media quad sub signed with saturation")
+(media-quad-arith-sat mqsubhus sub UHI 65535      0 OP_7B OPE1_1B "Media quad sub unsigned with saturation")
+
+(define-pmacro (conditional-media-quad-arith-sat
+               name operation mode max min op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR M-1) (FR400-MAJOR M-2) CONDITIONAL)
+       (.str name "$pack $FRinti,$FRintj,$FRintk,$CCi,$cond")
+       (+ pack FRintk op FRinti CCi cond ope FRintj)
+       (media-quad-arith-sat-semantics (eq CCi (or cond 2))
+                                      operation mode max min)
+       ((fr400 (unit u-media-1-quad))
+       (fr500 (unit u-media-quad-arith)))
+  )
+)
+
+(conditional-media-quad-arith-sat cmqaddhss add  HI 32767 -32768 OP_73 OPE4_0 "Conditional Media quad add signed with saturation")
+(conditional-media-quad-arith-sat cmqaddhus add UHI 65535      0 OP_73 OPE4_1 "Conditional Media quad add unsigned with saturation")
+
+(conditional-media-quad-arith-sat cmqsubhss sub  HI 32767 -32768 OP_73 OPE4_2 "Conditional Media quad sub signed with saturation")
+(conditional-media-quad-arith-sat cmqsubhus sub UHI 65535      0 OP_73 OPE4_3 "Conditional Media quad sub unsigned with saturation")
+
+(define-pmacro (media-acc-arith-sat name operation mode max min op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (MACH fr400) (FR400-MAJOR M-1))
+       (.str name "$pack $ACC40Si,$ACC40Sk")
+       (+ pack ACC40Sk op ACC40Si ope (ACCj-null))
+       (if (register-unaligned ACC40Si 2)
+          (c-call VOID "@cpu@_media_acc_not_aligned")
+          (media-arith-sat-semantics operation ACC40Si
+                                     (nextreg h-acc40S ACC40Si 1)
+                                     ACC40Sk mode max min (msr-sie-acci)))
+       ((fr400 (unit u-media-2-acc)))
+  )
+)
+
+(media-acc-arith-sat maddaccs add DI #x7fffffffff (inv DI #x7fffffffff)
+                    OP_78 OPE1_04 "Media accumulator addition")
+(media-acc-arith-sat msubaccs sub DI #x7fffffffff (inv DI #x7fffffffff)
+                    OP_78 OPE1_05 "Media accumulator subtraction")
+
+(define-pmacro (media-dual-acc-arith-sat name operation mode max min op ope
+                                        comment)
+  (dni name
+       (comment)
+       ((UNIT FM0) (MACH fr400) (FR400-MAJOR M-2))
+       (.str name "$pack $ACC40Si,$ACC40Sk")
+       (+ pack ACC40Sk op ACC40Si ope (ACCj-null))
+       (if (register-unaligned ACC40Si 4)
+          (c-call VOID "@cpu@_media_acc_not_aligned")
+          (if (register-unaligned ACC40Sk 2)
+              (c-call VOID "@cpu@_media_acc_not_aligned")
+              (sequence ()
+                        (media-arith-sat-semantics operation ACC40Si
+                                                   (nextreg h-acc40S ACC40Si 1)
+                                                   ACC40Sk mode max min
+                                                   (msr-sie-acci))
+                        (media-arith-sat-semantics operation
+                                                   (nextreg h-acc40S ACC40Si 2)
+                                                   (nextreg h-acc40S ACC40Si 3)
+                                                   (nextreg h-acc40S ACC40Sk 1)
+                                                   mode max min
+                                                   (msr-sie-acci-1)))))
+       ((fr400 (unit u-media-2-acc-dual)))
+  )
+)
+
+(media-dual-acc-arith-sat mdaddaccs add DI #x7fffffffff (inv DI #x7fffffffff)
+                         OP_78 OPE1_06 "Media accumulator addition")
+(media-dual-acc-arith-sat mdsubaccs sub DI #x7fffffffff (inv DI #x7fffffffff)
+                         OP_78 OPE1_07 "Media accumulator subtraction")
+
+(dni masaccs
+     "Media add and subtract signed accumulator with saturation"
+       ((UNIT FM01) (MACH fr400) (FR400-MAJOR M-1))
+       "masaccs$pack $ACC40Si,$ACC40Sk"
+       (+ pack ACC40Sk OP_78 ACC40Si OPE1_08 (ACCj-null))
+       (if (register-unaligned ACC40Si 2)
+          (c-call VOID "@cpu@_media_acc_not_aligned")
+          (if (register-unaligned ACC40Sk 2)
+              (c-call VOID "@cpu@_media_acc_not_aligned")
+              (sequence ()
+                        (media-arith-sat-semantics add ACC40Si
+                                                   (nextreg h-acc40S ACC40Si 1)
+                                                   ACC40Sk DI
+                                                   #x7fffffffff
+                                                   (inv DI #x7fffffffff)
+                                                   (msr-sie-acci))
+                        (media-arith-sat-semantics sub ACC40Si
+                                                   (nextreg h-acc40S ACC40Si 1)
+                                                   (nextreg h-acc40S ACC40Sk 1)
+                                                   DI
+                                                   #x7fffffffff
+                                                   (inv DI #x7fffffffff)
+                                                   (msr-sie-acci-1)))))
+       ((fr400 (unit u-media-2-add-sub)))
+  )
+
+(dni mdasaccs
+     "Media add and subtract signed accumulator with saturation"
+       ((UNIT FM0) (MACH fr400) (FR400-MAJOR M-2))
+       "mdasaccs$pack $ACC40Si,$ACC40Sk"
+       (+ pack ACC40Sk OP_78 ACC40Si OPE1_09 (ACCj-null))
+       (if (register-unaligned ACC40Si 4)
+          (c-call VOID "@cpu@_media_acc_not_aligned")
+          (if (register-unaligned ACC40Sk 4)
+              (c-call VOID "@cpu@_media_acc_not_aligned")
+              (sequence ()
+                        (media-arith-sat-semantics add ACC40Si
+                                                   (nextreg h-acc40S ACC40Si 1)
+                                                   ACC40Sk DI
+                                                   #x7fffffffff
+                                                   (inv DI #x7fffffffff)
+                                                   (msr-sie-acci))
+                        (media-arith-sat-semantics sub ACC40Si
+                                                   (nextreg h-acc40S ACC40Si 1)
+                                                   (nextreg h-acc40S ACC40Sk 1)
+                                                   DI
+                                                   #x7fffffffff
+                                                   (inv DI #x7fffffffff)
+                                                   (msr-sie-acci-1))
+                        (media-arith-sat-semantics add
+                                                   (nextreg h-acc40S ACC40Si 2)
+                                                   (nextreg h-acc40S ACC40Si 3)
+                                                   (nextreg h-acc40S ACC40Sk 2)
+                                                   DI
+                                                   #x7fffffffff
+                                                   (inv DI #x7fffffffff)
+                                                   (msr-sie-acci-2))
+                        (media-arith-sat-semantics sub
+                                                   (nextreg h-acc40S ACC40Si 2)
+                                                   (nextreg h-acc40S ACC40Si 3)
+                                                   (nextreg h-acc40S ACC40Sk 3)
+                                                   DI
+                                                   #x7fffffffff
+                                                   (inv DI #x7fffffffff)
+                                                   (msr-sie-acci-3)))))
+       ((fr400 (unit u-media-2-add-sub-dual)))
+  )
+
+(define-pmacro (media-multiply-semantics conv arg1 arg2 res)
+  (set res (mul DI (conv DI arg1) (conv DI arg2)))
+)
+
+(define-pmacro (media-dual-multiply-semantics cond mode conv rhs1 rhs2)
+  (if (register-unaligned ACC40Sk 2)
+      (c-call VOID "@cpu@_media_acc_not_aligned")
+      (if cond
+         (sequence ((mode argihi) (mode argilo) (mode argjhi) (mode argjlo))
+                   (extract-hilo FRinti 0 FRintj 0
+                                 argihi argilo argjhi argjlo)
+                   (media-multiply-semantics conv argihi rhs1 ACC40Sk)
+                   (media-multiply-semantics conv argilo rhs2
+                                             (nextreg h-acc40S ACC40Sk 1)))))
+)
+
+(define-pmacro (media-dual-multiply name mode conv rhs1 rhs2 op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR M-4) (FR400-MAJOR M-1) PRESERVE-OVF)
+       (.str name "$pack $FRinti,$FRintj,$ACC40Sk")
+       (+ pack ACC40Sk op FRinti ope FRintj)
+       (media-dual-multiply-semantics 1 mode conv rhs1 rhs2)
+       ((fr400 (unit u-media-2))
+       (fr500 (unit u-media-dual-mul)))
+  )
+)
+
+(media-dual-multiply mmulhs  HI ext  argjhi argjlo OP_7B OPE1_14 "Media dual multiply signed")
+(media-dual-multiply mmulhu UHI zext argjhi argjlo OP_7B OPE1_15 "Media dual multiply unsigned")
+
+(media-dual-multiply mmulxhs  HI ext  argjlo argjhi OP_7B OPE1_28 "Media dual cross multiply signed")
+(media-dual-multiply mmulxhu UHI zext argjlo argjhi OP_7B OPE1_29 "Media dual cross multiply unsigned")
+
+(define-pmacro (conditional-media-dual-multiply
+               name mode conv rhs1 rhs2 op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR M-4) (FR400-MAJOR M-1)
+       PRESERVE-OVF CONDITIONAL)
+       (.str name "$pack $FRinti,$FRintj,$ACC40Sk,$CCi,$cond")
+       (+ pack ACC40Sk op FRinti CCi cond ope FRintj)
+       (media-dual-multiply-semantics (eq CCi (or cond 2)) mode conv rhs1 rhs2)
+       ((fr400 (unit u-media-2))
+       (fr500 (unit u-media-dual-mul)))
+  )
+)
+
+(conditional-media-dual-multiply cmmulhs  HI ext  argjhi argjlo OP_72 OPE4_0 "Conditional Media dual multiply signed")
+(conditional-media-dual-multiply cmmulhu UHI zext argjhi argjlo OP_72 OPE4_1 "Conditional Media dual multiply unsigned")
+
+(define-pmacro (media-quad-multiply-semantics cond mode conv rhs1 rhs2)
+  (if (register-unaligned ACC40Sk 4)
+      (c-call VOID "@cpu@_media_acc_not_aligned")
+      (if (orif (register-unaligned FRinti 2)
+               (register-unaligned FRintj 2))
+         (c-call VOID "@cpu@_media_register_not_aligned")
+         (if cond
+             (sequence ((mode argihi) (mode argilo)
+                        (mode argjhi) (mode argjlo))
+                       (extract-hilo FRinti 0 FRintj 0
+                                     argihi argilo argjhi argjlo)
+                       (media-multiply-semantics conv argihi rhs1 ACC40Sk)
+                       (media-multiply-semantics conv argilo rhs2
+                                                 (nextreg h-acc40S ACC40Sk 1))
+                       (extract-hilo FRinti 1 FRintj 1
+                                     argihi argilo argjhi argjlo)
+                       (media-multiply-semantics conv argihi rhs1
+                                                 (nextreg h-acc40S ACC40Sk 2))
+                       (media-multiply-semantics conv argilo rhs2
+                                                 (nextreg h-acc40S ACC40Sk 3))))))
+)
+
+(define-pmacro (media-quad-multiply name mode conv rhs1 rhs2 op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR M-4) (FR400-MAJOR M-2) PRESERVE-OVF)
+       (.str name "$pack $FRinti,$FRintj,$ACC40Sk")
+       (+ pack ACC40Sk op FRinti ope FRintj)
+       (media-quad-multiply-semantics 1 mode conv rhs1 rhs2) 
+       ((fr400 (unit u-media-2-quad))
+       (fr500 (unit u-media-quad-mul)))
+  )
+)
+
+(media-quad-multiply mqmulhs  HI ext  argjhi argjlo OP_7B OPE1_1C "Media quad multiply signed")
+(media-quad-multiply mqmulhu UHI zext argjhi argjlo OP_7B OPE1_1D "Media quad multiply unsigned")
+
+(media-quad-multiply mqmulxhs  HI ext  argjlo argjhi OP_7B OPE1_2A "Media quad cross multiply signed")
+(media-quad-multiply mqmulxhu UHI zext argjlo argjhi OP_7B OPE1_2B "Media quad cross multiply unsigned")
+
+(define-pmacro (conditional-media-quad-multiply
+               name mode conv rhs1 rhs2 op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR M-4) (FR400-MAJOR M-2)
+       PRESERVE-OVF CONDITIONAL)
+       (.str name "$pack $FRinti,$FRintj,$ACC40Sk,$CCi,$cond")
+       (+ pack ACC40Sk op FRinti CCi cond ope FRintj)
+       (media-quad-multiply-semantics (eq CCi (or cond 2)) mode conv rhs1 rhs2)
+       ((fr400 (unit u-media-2-quad))
+       (fr500 (unit u-media-quad-mul)))
+  )
+)
+
+(conditional-media-quad-multiply cmqmulhs  HI ext  argjhi argjlo OP_74 OPE4_0 "Conditional Media quad multiply signed")
+(conditional-media-quad-multiply cmqmulhu UHI zext argjhi argjlo OP_74 OPE4_1 "Conditional Media quad multiply unsigned")
+
+(define-pmacro (media-multiply-acc-semantics 
+               conv arg1 addop arg2 res max min sie)
+  (sequence ((DI tmp))
+           (set tmp (addop res (mul DI (conv DI arg1) (conv DI arg2))))
+           (saturate-v tmp max min sie res))
+)
+
+(define-pmacro (media-dual-multiply-acc-semantics
+               cond mode conv addop rhw res max min)
+  (if (register-unaligned res 2)
+      (c-call VOID "@cpu@_media_acc_not_aligned")
+      (if cond
+         (sequence ((mode argihi) (mode argilo) (mode argjhi) (mode argjlo))
+                   (extract-hilo FRinti 0 FRintj 0
+                                 argihi argilo argjhi argjlo)
+                   (media-multiply-acc-semantics conv argihi addop argjhi
+                                                 res
+                                                 max min (msr-sie-acci))
+                   (media-multiply-acc-semantics conv argilo addop argjlo
+                                                 (nextreg rhw res 1)
+                                                 max min (msr-sie-acci-1)))))
+)
+
+(define-pmacro (media-dual-multiply-acc
+               name mode conv addop rhw res max min op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR M-4) (FR400-MAJOR M-1))
+       (.str name "$pack $FRinti,$FRintj,$" res)
+       (+ pack res op FRinti ope FRintj)
+       (media-dual-multiply-acc-semantics 1 mode conv addop rhw res max min)
+       ((fr400 (unit u-media-2))
+       (fr500 (unit u-media-dual-mul)))
+  )
+)
+
+(media-dual-multiply-acc mmachs HI ext add h-acc40S ACC40Sk
+                        (const DI #x7fffffffff) (const DI #xffffff8000000000)
+                        OP_7B OPE1_16
+                        "Media dual multiply and accumulate signed")
+
+(media-dual-multiply-acc mmachu UHI zext add h-acc40U ACC40Uk
+                        (const DI #xffffffffff) (const DI 0)
+                        OP_7B OPE1_17
+                        "Media dual multiply and accumulate unsigned")
+
+(media-dual-multiply-acc mmrdhs HI ext sub h-acc40S ACC40Sk
+                        (const DI #x7fffffffff) (const DI #xffffff8000000000)
+                        OP_7B OPE1_30
+                        "Media dual multiply and reduce signed")
+
+(media-dual-multiply-acc mmrdhu UHI zext sub h-acc40U ACC40Uk
+                        (const DI #xffffffffff) (const DI 0)
+                        OP_7B OPE1_31
+                        "Media dual multiply and reduce unsigned")
+
+(define-pmacro (conditional-media-dual-multiply-acc
+               name mode conv addop rhw res max min op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR M-4) (FR400-MAJOR M-1) CONDITIONAL)
+       (.str name "$pack $FRinti,$FRintj,$" res ",$CCi,$cond")
+       (+ pack res op FRinti CCi cond ope FRintj)
+       (media-dual-multiply-acc-semantics (eq CCi (or cond 2))
+                                         mode conv addop rhw res max min)
+       ((fr400 (unit u-media-2))
+       (fr500 (unit u-media-dual-mul)))
+  )
+)
+
+(conditional-media-dual-multiply-acc cmmachs HI ext add h-acc40S ACC40Sk
+                        (const DI #x7fffffffff) (const DI #xffffff8000000000)
+                        OP_72 OPE4_2
+                        "Conditional Media dual multiply and accumulate signed")
+
+(conditional-media-dual-multiply-acc cmmachu UHI zext add  h-acc40U ACC40Uk
+                        (const DI #xffffffffff) (const DI 0)
+                        OP_72 OPE4_3
+                        "Conditional Media dual multiply and accumulate unsigned")
+
+(define-pmacro (media-quad-multiply-acc-semantics
+               cond mode conv addop rhw res max min)
+  (if (register-unaligned res 4)
+      (c-call VOID "@cpu@_media_acc_not_aligned")
+      (if (orif (register-unaligned FRinti 2)
+               (register-unaligned FRintj 2))
+         (c-call VOID "@cpu@_media_register_not_aligned")
+         (if cond
+             (sequence ((mode argihi) (mode argilo)
+                        (mode argjhi) (mode argjlo))
+                       (extract-hilo FRinti 0 FRintj 0
+                                     argihi argilo argjhi argjlo)
+                       (media-multiply-acc-semantics conv argihi addop argjhi
+                                                     res
+                                                     max min (msr-sie-acci))
+                       (media-multiply-acc-semantics conv argilo addop argjlo
+                                                     (nextreg rhw res 1)
+                                                     max min (msr-sie-acci-1))
+                       (extract-hilo FRinti 1 FRintj 1
+                                     argihi argilo argjhi argjlo)
+                       (media-multiply-acc-semantics conv argihi addop argjhi
+                                                     (nextreg rhw res 2)
+                                                     max min (msr-sie-acci-2))
+                       (media-multiply-acc-semantics conv argilo addop argjlo
+                                                     (nextreg rhw res 3)
+                                                     max min
+                                                     (msr-sie-acci-3))))))
+)
+
+(define-pmacro (media-quad-multiply-acc
+               name mode conv addop rhw res max min op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR M-4) (FR400-MAJOR M-2))
+       (.str name "$pack $FRinti,$FRintj,$" res)
+       (+ pack res op FRinti ope FRintj)
+       (media-quad-multiply-acc-semantics 1 mode conv addop rhw res max min)
+       ((fr400 (unit u-media-2-quad))
+       (fr500 (unit u-media-quad-mul)))
+  )
+)
+
+(media-quad-multiply-acc mqmachs HI ext add h-acc40S ACC40Sk
+                        (const DI #x7fffffffff) (const DI #xffffff8000000000)
+                        OP_7B OPE1_1E
+                        "Media quad multiply and accumulate signed")
+
+(media-quad-multiply-acc mqmachu UHI zext add h-acc40U ACC40Uk
+                        (const DI #xffffffffff) (const DI 0)
+                        OP_7B OPE1_1F
+                        "Media quad multiply and accumulate unsigned")
+
+(define-pmacro (conditional-media-quad-multiply-acc
+               name mode conv addop rhw res max min op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR M-4) (FR400-MAJOR M-2) CONDITIONAL)
+       (.str name "$pack $FRinti,$FRintj,$" res ",$CCi,$cond")
+       (+ pack res op FRinti CCi cond ope FRintj)
+       (media-quad-multiply-acc-semantics (eq CCi (or cond 2))
+                                         mode conv addop rhw res max min)
+       ((fr400 (unit u-media-2-quad))
+       (fr500 (unit u-media-quad-mul)))
+  )
+)
+
+(conditional-media-quad-multiply-acc cmqmachs HI ext add h-acc40S ACC40Sk
+                        (const DI #x7fffffffff) (const DI #xffffff8000000000)
+                        OP_74 OPE4_2
+                        "Conditional Media quad multiply and accumulate signed")
+
+(conditional-media-quad-multiply-acc cmqmachu UHI zext add h-acc40U ACC40Uk
+                        (const DI #xffffffffff) (const DI 0)
+                        OP_74 OPE4_3
+                        "Conditional media quad multiply and accumulate unsigned")
+
+(define-pmacro (media-quad-multiply-cross-acc-semantics
+               cond mode conv addop rhw res max min)
+  (if (register-unaligned res 4)
+      (c-call VOID "@cpu@_media_acc_not_aligned")
+      (if (orif (register-unaligned FRinti 2)
+               (register-unaligned FRintj 2))
+         (c-call VOID "@cpu@_media_register_not_aligned")
+         (if cond
+             (sequence ((mode argihi) (mode argilo)
+                        (mode argjhi) (mode argjlo))
+                       (extract-hilo FRinti 0 FRintj 0
+                                     argihi argilo argjhi argjlo)
+                       (media-multiply-acc-semantics conv argihi addop argjhi
+                                                     (nextreg rhw res 2)
+                                                     max min (msr-sie-acci-2))
+                       (media-multiply-acc-semantics conv argilo addop argjlo
+                                                     (nextreg rhw res 3)
+                                                     max min (msr-sie-acci-3))
+                       (extract-hilo FRinti 1 FRintj 1
+                                     argihi argilo argjhi argjlo)
+                       (media-multiply-acc-semantics conv argihi addop argjhi
+                                                     res
+                                                     max min (msr-sie-acci))
+                       (media-multiply-acc-semantics conv argilo addop argjlo
+                                                     (nextreg rhw res 1)
+                                                     max min
+                                                     (msr-sie-acci-1))))))
+)
+
+(define-pmacro (media-quad-multiply-cross-acc
+               name mode conv addop rhw res max min op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM0) (MACH fr400) (FR400-MAJOR M-2))
+       (.str name "$pack $FRinti,$FRintj,$" res)
+       (+ pack res op FRinti ope FRintj)
+       (media-quad-multiply-cross-acc-semantics 1 mode conv addop rhw res
+                                               max min)
+       ((fr400 (unit u-media-2-quad)))
+  )
+)
+
+(media-quad-multiply-cross-acc mqxmachs HI ext add h-acc40S ACC40Sk
+                        (const DI #x7fffffffff) (const DI #xffffff8000000000)
+                        OP_78 OPE1_00
+                        "Media quad multiply and cross accumulate signed")
+
+(define-pmacro (media-quad-cross-multiply-cross-acc-semantics
+               cond mode conv addop rhw res max min)
+  (if (register-unaligned res 4)
+      (c-call VOID "@cpu@_media_acc_not_aligned")
+      (if (orif (register-unaligned FRinti 2)
+               (register-unaligned FRintj 2))
+         (c-call VOID "@cpu@_media_register_not_aligned")
+         (if cond
+             (sequence ((mode argihi) (mode argilo)
+                        (mode argjhi) (mode argjlo))
+                       (extract-hilo FRinti 0 FRintj 0
+                                     argihi argilo argjhi argjlo)
+                       (media-multiply-acc-semantics conv argihi addop argjlo
+                                                     (nextreg rhw res 2)
+                                                     max min (msr-sie-acci-2))
+                       (media-multiply-acc-semantics conv argilo addop argjhi
+                                                     (nextreg rhw res 3)
+                                                     max min (msr-sie-acci-3))
+                       (extract-hilo FRinti 1 FRintj 1
+                                     argihi argilo argjhi argjlo)
+                       (media-multiply-acc-semantics conv argihi addop argjlo
+                                                     res
+                                                     max min (msr-sie-acci))
+                       (media-multiply-acc-semantics conv argilo addop argjhi
+                                                     (nextreg rhw res 1)
+                                                     max min
+                                                     (msr-sie-acci-1))))))
+)
+
+(define-pmacro (media-quad-cross-multiply-cross-acc
+               name mode conv addop rhw res max min op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM0) (MACH fr400) (FR400-MAJOR M-2))
+       (.str name "$pack $FRinti,$FRintj,$" res)
+       (+ pack res op FRinti ope FRintj)
+       (media-quad-cross-multiply-cross-acc-semantics 1 mode conv addop rhw res
+                                                     max min)
+       ((fr400 (unit u-media-2-quad)))
+  )
+)
+
+(media-quad-cross-multiply-cross-acc mqxmacxhs HI ext add h-acc40S ACC40Sk
+                       (const DI #x7fffffffff) (const DI #xffffff8000000000)
+                       OP_78 OPE1_01
+                       "Media quad cross multiply and cross accumulate signed")
+
+(define-pmacro (media-quad-cross-multiply-acc-semantics
+               cond mode conv addop rhw res max min)
+  (if (register-unaligned res 4)
+      (c-call VOID "@cpu@_media_acc_not_aligned")
+      (if (orif (register-unaligned FRinti 2)
+               (register-unaligned FRintj 2))
+         (c-call VOID "@cpu@_media_register_not_aligned")
+         (if cond
+             (sequence ((mode argihi) (mode argilo)
+                        (mode argjhi) (mode argjlo))
+                       (extract-hilo FRinti 0 FRintj 0
+                                     argihi argilo argjhi argjlo)
+                       (media-multiply-acc-semantics conv argihi addop argjlo
+                                                     res
+                                                     max min (msr-sie-acci))
+                       (media-multiply-acc-semantics conv argilo addop argjhi
+                                                     (nextreg rhw res 1)
+                                                     max min (msr-sie-acci-1))
+                       (extract-hilo FRinti 1 FRintj 1
+                                     argihi argilo argjhi argjlo)
+                       (media-multiply-acc-semantics conv argihi addop argjlo
+                                                     (nextreg rhw res 2)
+                                                     max min (msr-sie-acci-2))
+                       (media-multiply-acc-semantics conv argilo addop argjhi
+                                                     (nextreg rhw res 3)
+                                                     max min
+                                                     (msr-sie-acci-3))))))
+)
+
+(define-pmacro (media-quad-cross-multiply-acc
+               name mode conv addop rhw res max min op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM0) (MACH fr400) (FR400-MAJOR M-2))
+       (.str name "$pack $FRinti,$FRintj,$" res)
+       (+ pack res op FRinti ope FRintj)
+       (media-quad-cross-multiply-acc-semantics 1 mode conv addop rhw res
+                                               max min)
+       ((fr400 (unit u-media-2-quad)))
+  )
+)
+
+(media-quad-cross-multiply-acc mqmacxhs HI ext add h-acc40S ACC40Sk
+                       (const DI #x7fffffffff) (const DI #xffffff8000000000)
+                       OP_78 OPE1_02
+                       "Media quad cross multiply and accumulate signed")
+
+(define-pmacro (media-complex-semantics
+               conv lhs1 rhs1 lhs2 rhs2 res max min sie)
+  (sequence ((DI tmp1) (DI tmp2))
+           (media-multiply-semantics conv lhs1 rhs1 tmp1)
+           (media-multiply-semantics conv lhs2 rhs2 tmp2)
+           (set tmp1 (sub tmp1 tmp2))
+           (saturate-v tmp1 max min sie res))
+)
+
+(define-pmacro (media-complex-semantics-i
+               conv lhs1 rhs1 lhs2 rhs2 res max min sie)
+  (sequence ((DI tmp1) (DI tmp2))
+           (media-multiply-semantics conv lhs1 rhs1 tmp1)
+           (media-multiply-semantics conv lhs2 rhs2 tmp2)
+           (set tmp1 (add tmp1 tmp2))
+           (saturate-v tmp1 max min sie res))
+)
+
+(define-pmacro (media-dual-complex-semantics mode conv rhs1 rhs2 max min)
+  (sequence ((mode argihi) (mode argilo) (mode argjhi) (mode argjlo))
+           (extract-hilo FRinti 0 FRintj 0 argihi argilo argjhi argjlo)
+           (media-complex-semantics conv argihi rhs1 argilo rhs2 ACC40Sk
+                                    max min (msr-sie-acci)))
+)
+
+(define-pmacro (media-dual-complex-semantics-i mode conv rhs1 rhs2 max min)
+  (sequence ((mode argihi) (mode argilo) (mode argjhi) (mode argjlo))
+           (extract-hilo FRinti 0 FRintj 0 argihi argilo argjhi argjlo)
+           (media-complex-semantics-i conv argihi rhs1 argilo rhs2 ACC40Sk
+                                    max min (msr-sie-acci)))
+)
+
+(define-pmacro (media-dual-complex
+               name mode conv rhs1 rhs2 max min op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR M-4) (FR400-MAJOR M-1))
+       (.str name "$pack $FRinti,$FRintj,$ACC40Sk")
+       (+ pack ACC40Sk op FRinti ope FRintj)
+       (media-dual-complex-semantics mode conv rhs1 rhs2 max min)
+       ((fr400 (unit u-media-2))
+       (fr500 (unit u-media)))
+  )
+)
+
+(define-pmacro (media-dual-complex-i
+               name mode conv rhs1 rhs2 max min op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR M-4) (FR400-MAJOR M-1))
+       (.str name "$pack $FRinti,$FRintj,$ACC40Sk")
+       (+ pack ACC40Sk op FRinti ope FRintj)
+       (media-dual-complex-semantics-i mode conv rhs1 rhs2 max min)
+       ((fr400 (unit u-media-2))
+       (fr500 (unit u-media-dual-mul)))
+  )
+)
+
+(media-dual-complex mcpxrs HI ext argjhi argjlo
+                   (const DI #x7fffffffff) (const DI #xffffff8000000000)
+                   OP_7B OPE1_20
+                   "Media dual complex real signed with saturation")
+
+(media-dual-complex mcpxru UHI zext argjhi argjlo
+                   (const DI #xffffffffff) (const DI 0)
+                   OP_7B OPE1_21
+                   "Media dual complex real unsigned with saturation")
+
+(media-dual-complex-i mcpxis HI ext argjlo argjhi
+                   (const DI #x7fffffffff) (const DI #xffffff8000000000)
+                   OP_7B OPE1_22
+                   "Media dual complex imaginary signed with saturation")
+
+(media-dual-complex-i mcpxiu UHI zext argjlo argjhi
+                   (const DI #xffffffffff) (const DI 0)
+                   OP_7B OPE1_23
+                   "Media dual complex imaginary unsigned with saturation")
+
+(define-pmacro (conditional-media-dual-complex
+               name mode conv rhs1 rhs2 max min op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR M-4) (FR400-MAJOR M-1) CONDITIONAL)
+       (.str name "$pack $FRinti,$FRintj,$ACC40Sk,$CCi,$cond")
+       (+ pack ACC40Sk op FRinti CCi cond ope FRintj)
+       (if (eq CCi (or cond 2))
+          (media-dual-complex-semantics mode conv rhs1 rhs2 max min))
+       ((fr400 (unit u-media-2))
+       (fr500 (unit u-media)))
+  )
+)
+
+(define-pmacro (conditional-media-dual-complex-i
+               name mode conv rhs1 rhs2 max min op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR M-4) (FR400-MAJOR M-1) CONDITIONAL)
+       (.str name "$pack $FRinti,$FRintj,$ACC40Sk,$CCi,$cond")
+       (+ pack ACC40Sk op FRinti CCi cond ope FRintj)
+       (if (eq CCi (or cond 2))
+          (media-dual-complex-semantics-i mode conv rhs1 rhs2 max min))
+       ((fr400 (unit u-media-2))
+       (fr500 (unit u-media-dual-mul)))
+  )
+)
+
+(conditional-media-dual-complex cmcpxrs HI ext argjhi argjlo
+                   (const DI #x7fffffffff) (const DI #xffffff8000000000)
+                   OP_75 OPE4_0
+                   "Conditional Media dual complex real signed with saturation")
+
+(conditional-media-dual-complex cmcpxru UHI zext argjhi argjlo
+                   (const DI #xffffffffff) (const DI 0)
+                   OP_75 OPE4_1
+                   "Conditional Media dual complex real unsigned with saturation")
+
+(conditional-media-dual-complex-i cmcpxis HI ext argjlo argjhi
+                   (const DI #x7fffffffff) (const DI #xffffff8000000000)
+                   OP_75 OPE4_2
+                   "Conditional Media dual complex imaginary signed with saturation")
+
+(conditional-media-dual-complex-i cmcpxiu UHI zext argjlo argjhi
+                   (const DI #xffffffffff) (const DI 0)
+                   OP_75 OPE4_3
+                   "Conditional Media dual complex imaginary unsigned with saturation")
+
+(define-pmacro (media-quad-complex
+               name mode conv rhs1 rhs2 max min op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR M-4) (FR400-MAJOR M-2))
+       (.str name "$pack $FRinti,$FRintj,$ACC40Sk")
+       (+ pack ACC40Sk op FRinti ope FRintj)
+       (if (register-unaligned ACC40Sk 2)
+          (c-call VOID "@cpu@_media_acc_not_aligned")
+          (if (orif (register-unaligned FRinti 2)
+                    (register-unaligned FRintj 2))
+              (c-call VOID "@cpu@_media_register_not_aligned")
+              (sequence ((mode argihi) (mode argilo)
+                         (mode argjhi) (mode argjlo))
+                        (extract-hilo FRinti 0 FRintj 0
+                                      argihi argilo argjhi argjlo)
+                        (media-complex-semantics conv argihi rhs1 argilo rhs2
+                                                 ACC40Sk
+                                                 max min (msr-sie-acci))
+                        (extract-hilo FRinti 1 FRintj 1
+                                      argihi argilo argjhi argjlo)
+                        (media-complex-semantics conv argihi rhs1 argilo rhs2
+                                                 (nextreg h-acc40S ACC40Sk 1)
+                                                 max min (msr-sie-acci-1)))))
+       ((fr400 (unit u-media-2-quad))
+       (fr500 (unit u-media-quad-complex)))
+  )
+)
+
+(define-pmacro (media-quad-complex-i
+               name mode conv rhs1 rhs2 max min op ope comment)
+  (dni name
+       (comment)
+       ((UNIT FM01) (FR500-MAJOR M-4) (FR400-MAJOR M-2))
+       (.str name "$pack $FRinti,$FRintj,$ACC40Sk")
+       (+ pack ACC40Sk op FRinti ope FRintj)
+       (if (register-unaligned ACC40Sk 2)
+          (c-call VOID "@cpu@_media_acc_not_aligned")
+          (if (orif (register-unaligned FRinti 2)
+                    (register-unaligned FRintj 2))
+              (c-call VOID "@cpu@_media_register_not_aligned")
+              (sequence ((mode argihi) (mode argilo)
+                         (mode argjhi) (mode argjlo))
+                        (extract-hilo FRinti 0 FRintj 0
+                                      argihi argilo argjhi argjlo)
+                        (media-complex-semantics-i conv argihi rhs1 argilo rhs2
+                                                 ACC40Sk
+                                                 max min (msr-sie-acci))
+                        (extract-hilo FRinti 1 FRintj 1
+                                      argihi argilo argjhi argjlo)
+                        (media-complex-semantics-i conv argihi rhs1 argilo rhs2
+                                                 (nextreg h-acc40S ACC40Sk 1)
+                                                 max min (msr-sie-acci-1)))))
+       ((fr400 (unit u-media-2-quad))
+       (fr500 (unit u-media-quad-complex)))
+  )
+)
+
+(media-quad-complex mqcpxrs HI ext argjhi argjlo
+                   (const DI #x7fffffffff) (const DI #xffffff8000000000)
+                   OP_7B OPE1_24
+                   "Media quad complex real signed with saturation")
+
+(media-quad-complex mqcpxru UHI zext argjhi argjlo
+                   (const DI #xffffffffff) (const DI 0)
+                   OP_7B OPE1_25
+                   "Media quad complex real unsigned with saturation")
+
+(media-quad-complex-i mqcpxis HI ext argjlo argjhi
+                   (const DI #x7fffffffff) (const DI #xffffff8000000000)
+                   OP_7B OPE1_26
+                   "Media quad complex imaginary signed with saturation")
+
+(media-quad-complex-i mqcpxiu UHI zext argjlo argjhi
+                   (const DI #xffffffffff) (const DI 0)
+                   OP_7B OPE1_27
+                   "Media quad complex imaginary unsigned with saturation")
+
+(define-pmacro (media-pack src1 src2 targ offset)
+  (sequence ()
+           (set (halfword hi targ offset) (halfword lo src1 offset))
+           (set (halfword lo targ offset) (halfword lo src2 offset)))
+)
+
+(define-pmacro (media-expand-halfword-to-word-semantics cond)
+  (if cond
+      (sequence ((UHI tmp))
+               (if (and u6 1)
+                   (set tmp (halfword lo FRinti 0))
+                   (set tmp (halfword hi FRinti 0)))
+               (set (halfword hi FRintk 0) tmp)
+               (set (halfword lo FRintk 0) tmp)))
+)
+
+(dni mexpdhw
+     "Media expand halfword to word"
+     ((UNIT FM01) (FR500-MAJOR M-2) (FR400-MAJOR M-1))
+     "mexpdhw$pack $FRinti,$u6,$FRintk"
+     (+ pack FRintk OP_7B FRinti OPE1_32 u6)
+     (media-expand-halfword-to-word-semantics 1)
+     ((fr400 (unit u-media-3))
+      (fr500 (unit u-media)))
+)
+
+(dni cmexpdhw
+     "Conditional media expand halfword to word"
+     ((UNIT FM01) (FR500-MAJOR M-2) (FR400-MAJOR M-1) CONDITIONAL)
+     "cmexpdhw$pack $FRinti,$u6,$FRintk,$CCi,$cond"
+     (+ pack FRintk OP_76 FRinti CCi cond OPE4_2 u6)
+     (media-expand-halfword-to-word-semantics (eq CCi (or cond 2)))
+     ((fr400 (unit u-media-3))
+      (fr500 (unit u-media)))
+)
+
+(define-pmacro (media-expand-halfword-to-double-semantics cond)
+  (if (register-unaligned FRintk 2)
+      (c-call VOID "@cpu@_media_register_not_aligned")
+      (if cond
+         (sequence ((UHI tmp))
+                   ; a hack to get FRintk referenced for profiling
+                   (set FRintk (c-raw-call SI "frv_ref_SI" FRintk))
+                   (if (and u6 1)
+                       (set tmp (halfword lo FRinti 0))
+                       (set tmp (halfword hi FRinti 0)))
+                   (set (halfword hi FRintk 0) tmp)
+                   (set (halfword lo FRintk 0) tmp)
+                   (set (halfword hi FRintk 1) tmp)
+                   (set (halfword lo FRintk 1) tmp))))
+)
+
+(dni mexpdhd
+     "Media expand halfword to double"
+     ((UNIT FM01) (FR500-MAJOR M-2) (FR400-MAJOR M-2))
+     "mexpdhd$pack $FRinti,$u6,$FRintk"
+     (+ pack FRintk OP_7B FRinti OPE1_33 u6)
+     (media-expand-halfword-to-double-semantics 1)
+     ((fr400 (unit u-media-dual-expand))
+      (fr500 (unit u-media-dual-expand)))
+)
+
+(dni cmexpdhd
+     "Conditional media expand halfword to double"
+     ((UNIT FM01) (FR500-MAJOR M-2) (FR400-MAJOR M-2) CONDITIONAL)
+     "cmexpdhd$pack $FRinti,$u6,$FRintk,$CCi,$cond"
+     (+ pack FRintk OP_76 FRinti CCi cond OPE4_3 u6)
+     (media-expand-halfword-to-double-semantics (eq CCi (or cond 2)))
+     ((fr400 (unit u-media-dual-expand))
+      (fr500 (unit u-media-dual-expand)))
+)
+
+(dni mpackh
+     "Media halfword pack"
+     ((UNIT FM01) (FR500-MAJOR M-2) (FR400-MAJOR M-1))
+     "mpackh$pack $FRinti,$FRintj,$FRintk"
+     (+ pack FRintk OP_7B FRinti OPE1_34 FRintj)
+     (media-pack FRinti FRintj FRintk 0)
+     ((fr400 (unit u-media-3))
+      (fr500 (unit u-media)))
+)
+
+(dni mdpackh
+     "Media dual pack"
+     ((UNIT FM01) (FR500-MAJOR M-5) (FR400-MAJOR M-2))
+     "mdpackh$pack $FRinti,$FRintj,$FRintk"
+     (+ pack FRintk OP_7B FRinti OPE1_36 FRintj)
+     (if (orif (register-unaligned FRinti 2)
+              (orif (register-unaligned FRintj 2)
+                    (register-unaligned FRintk 2)))
+        (c-call VOID "@cpu@_media_register_not_aligned")
+        (sequence ()
+                  ; hack to get these referenced for profiling
+                  (set FRinti (c-raw-call SI "frv_ref_SI" FRinti))
+                  (set FRintj (c-raw-call SI "frv_ref_SI" FRintj))
+                  (set FRintk (c-raw-call SI "frv_ref_SI" FRintk))
+                  (media-pack FRinti FRintj FRintk 0)
+                  (media-pack FRinti FRintj FRintk 1)))
+     ((fr400 (unit u-media-3-quad))
+      (fr500 (unit u-media-quad-arith)))
+)
+
+(define-pmacro (media-unpack src soff targ toff)
+  (sequence ()
+           (set (halfword hi targ toff) (halfword hi src soff))
+           (set (halfword lo targ toff) (halfword hi src soff))
+           (set (halfword hi targ (add toff 1)) (halfword lo src soff))
+           (set (halfword lo targ (add toff 1)) (halfword lo src soff)))
+)
+
+(dni munpackh
+     "Media halfword unpack"
+     ((UNIT FM01) (FR500-MAJOR M-2) (FR400-MAJOR M-2))
+     "munpackh$pack $FRinti,$FRintk"
+     (+ pack FRintk OP_7B FRinti OPE1_35 (FRj-null))
+     (if (register-unaligned FRintk 2)
+        (c-call VOID "@cpu@_media_register_not_aligned")
+        (sequence ()
+                  ; hack to get these referenced for profiling
+                  (set FRinti (c-raw-call SI "frv_ref_SI" FRinti))
+                  (set FRintk (c-raw-call SI "frv_ref_SI" FRintk))
+                  (media-unpack FRinti 0 FRintk 0)))
+     ((fr400 (unit u-media-dual-expand))
+      (fr500 (unit u-media-dual-expand)))
+)
+
+(dni mdunpackh
+     "Media dual unpack"
+     ((UNIT FM01) (FR500-MAJOR M-7) (MACH simple,tomcat,frv))
+     "mdunpackh$pack $FRinti,$FRintk"
+     (+ pack FRintk OP_7B FRinti OPE1_37 (FRj-null))
+     (if (orif (register-unaligned FRinti 2) (register-unaligned FRintk 4))
+        (c-call VOID "@cpu@_media_register_not_aligned")
+        (sequence ()
+                  ; hack to get these referenced for profiling
+                  (set FRinti (c-raw-call SI "frv_ref_SI" FRinti))
+                  (set FRintk (c-raw-call SI "frv_ref_SI" FRintk))
+                  (media-unpack FRinti 0 FRintk 0)
+                  (media-unpack FRinti 1 FRintk 2)))
+     ((fr500 (unit u-media-dual-unpack)))
+)
+
+(define-pmacro (ubyte num arg offset)
+  (reg (.sym h-fr_ num) (add (index-of arg) offset)))
+
+(define-pmacro (mbtoh-semantics cond)
+  (if (register-unaligned FRintk 2)
+      (c-call VOID "@cpu@_media_register_not_aligned")
+      (if cond
+         (sequence ()
+                   (set (halfword hi FRintk 0) (ubyte 3 FRintj 0))
+                   (set (halfword lo FRintk 0) (ubyte 2 FRintj 0))
+                   (set (halfword hi FRintk 1) (ubyte 1 FRintj 0))
+                   (set (halfword lo FRintk 1) (ubyte 0 FRintj 0)))))
+)
+
+(dni mbtoh
+     "Media convert byte to halfword"
+     ((UNIT FM01) (FR500-MAJOR M-2) (FR400-MAJOR M-2))
+     "mbtoh$pack $FRintj,$FRintk"
+     (+ pack FRintk OP_7B (FRi-null) OPE1_38 FRintj)
+     (sequence ()
+              ; hack to get these referenced for profiling
+              (set FRintj (c-raw-call SI "frv_ref_SI" FRintj))
+              (set FRintk (c-raw-call SI "frv_ref_SI" FRintk))
+              (mbtoh-semantics 1))
+     ((fr400 (unit u-media-dual-expand))
+      (fr500 (unit u-media-dual-btoh)))
+)
+
+(dni cmbtoh
+     "Conditional media convert byte to halfword"
+     ((UNIT FM01) (FR500-MAJOR M-2) (FR400-MAJOR M-2) CONDITIONAL)
+     "cmbtoh$pack $FRintj,$FRintk,$CCi,$cond"
+     (+ pack FRintk OP_77 (FRi-null) CCi cond OPE4_0 FRintj)
+     (mbtoh-semantics (eq CCi (or cond 2)))
+     ((fr400 (unit u-media-dual-expand))
+      (fr500 (unit u-media-dual-btoh)))
+)
+
+(define-pmacro (mhtob-semantics cond)
+  (if (register-unaligned FRintj 2)
+      (c-call VOID "@cpu@_media_register_not_aligned")
+      (if cond
+         (sequence ()
+                   (set (ubyte 3 FRintk 0) (halfword hi FRintj 0))
+                   (set (ubyte 2 FRintk 0) (halfword lo FRintj 0))
+                   (set (ubyte 1 FRintk 0) (halfword hi FRintj 1))
+                   (set (ubyte 0 FRintk 0) (halfword lo FRintj 1)))))
+)
+
+(dni mhtob
+     "Media convert halfword to byte"
+     ((UNIT FM01) (FR500-MAJOR M-2) (FR400-MAJOR M-2))
+     "mhtob$pack $FRintj,$FRintk"
+     (+ pack FRintk OP_7B (FRi-null) OPE1_39 FRintj)
+     (sequence ()
+              ; hack to get these referenced for profiling
+              (set FRintj (c-raw-call SI "frv_ref_SI" FRintj))
+              (set FRintk (c-raw-call SI "frv_ref_SI" FRintk))
+              (mhtob-semantics 1))
+     ((fr400 (unit u-media-dual-htob))
+      (fr500 (unit u-media-dual-htob)))
+)
+
+(dni cmhtob
+     "Conditional media convert halfword to byte"
+     ((UNIT FM01) (FR500-MAJOR M-2) (FR400-MAJOR M-2) CONDITIONAL)
+     "cmhtob$pack $FRintj,$FRintk,$CCi,$cond"
+     (+ pack FRintk OP_77 (FRi-null) CCi cond OPE4_1 FRintj)
+     (sequence ()
+              ; hack to get these referenced for profiling
+              (set FRintj (c-raw-call SI "frv_ref_SI" FRintj))
+              (set FRintk (c-raw-call SI "frv_ref_SI" FRintk))
+              (mhtob-semantics (eq CCi (or cond 2))))
+     ((fr400 (unit u-media-dual-htob))
+      (fr500 (unit u-media-dual-htob)))
+)
+
+(define-pmacro (mbtohe-semantics cond)
+  (if (register-unaligned FRintk 4)
+      (c-call VOID "@cpu@_media_register_not_aligned")
+      (if cond
+         (sequence ()
+                   (set (halfword hi FRintk 0) (ubyte 3 FRintj 0))
+                   (set (halfword lo FRintk 0) (ubyte 3 FRintj 0))
+                   (set (halfword hi FRintk 1) (ubyte 2 FRintj 0))
+                   (set (halfword lo FRintk 1) (ubyte 2 FRintj 0))
+                   (set (halfword hi FRintk 2) (ubyte 1 FRintj 0))
+                   (set (halfword lo FRintk 2) (ubyte 1 FRintj 0))
+                   (set (halfword hi FRintk 3) (ubyte 0 FRintj 0))
+                   (set (halfword lo FRintk 3) (ubyte 0 FRintj 0)))))
+)
+
+(dni mbtohe
+     "Media convert byte to halfword extended"
+     ((UNIT FM01) (FR500-MAJOR M-7) (MACH simple,tomcat,frv))
+     "mbtohe$pack $FRintj,$FRintk"
+     (+ pack FRintk OP_7B (FRi-null) OPE1_3A FRintj)
+     (sequence ()
+              ; hack to get these referenced for profiling
+              (set FRintj (c-raw-call SI "frv_ref_SI" FRintj))
+              (set FRintk (c-raw-call SI "frv_ref_SI" FRintk))
+              (mbtohe-semantics 1))
+     ((fr500 (unit u-media-dual-btohe)))
+)
+
+(dni cmbtohe
+     "Conditional media convert byte to halfword extended"
+     ((UNIT FM01) (FR500-MAJOR M-7) CONDITIONAL (MACH simple,tomcat,frv))
+     "cmbtohe$pack $FRintj,$FRintk,$CCi,$cond"
+     (+ pack FRintk OP_77 (FRi-null) CCi cond OPE4_2 FRintj)
+     (sequence ()
+              ; hack to get these referenced for profiling
+              (set FRintj (c-raw-call SI "frv_ref_SI" FRintj))
+              (set FRintk (c-raw-call SI "frv_ref_SI" FRintk))
+              (mbtohe-semantics (eq CCi (or cond 2))))
+     ((fr500 (unit u-media-dual-btohe)))
+)
+
+(dni mclracc
+     "Media clear accumulator(s)"
+     ((UNIT FM01) (FR500-MAJOR M-3))
+     "mclracc$pack $ACC40Sk,$A"
+     (+ pack ACC40Sk OP_7B A (misc-null-10) OPE1_3B (FRj-null))
+     (c-call VOID "@cpu@_clear_accumulators" (index-of ACC40Sk) A)
+     ((fr400 (unit u-media-4))
+      (fr500 (unit u-media)))
+)
+
+(dni mrdacc
+     "Media read accumulator"
+     ((UNIT FM01) (FR500-MAJOR M-2) (FR400-MAJOR M-1))
+     "mrdacc$pack $ACC40Si,$FRintk"
+     (+ pack FRintk OP_7B ACC40Si OPE1_3C (FRj-null))
+     (set FRintk ACC40Si)
+     ((fr400 (unit u-media-4))
+      (fr500 (unit u-media)))
+)
+
+(dni mrdaccg
+     "Media read accumulator guard"
+     ((UNIT FM01) (FR500-MAJOR M-2) (FR400-MAJOR M-1))
+     "mrdaccg$pack $ACCGi,$FRintk"
+     (+ pack FRintk OP_7B ACCGi OPE1_3E (FRj-null))
+     (set FRintk ACCGi)
+     ((fr400 (unit u-media-4-accg))
+      (fr500 (unit u-media)))
+)
+
+(dni mwtacc
+     "Media write accumulator"
+     ((UNIT FM01) (FR500-MAJOR M-3) (FR400-MAJOR M-1))
+     "mwtacc$pack $FRinti,$ACC40Sk"
+     (+ pack ACC40Sk OP_7B FRinti OPE1_3D (FRj-null))
+     (set ACC40Sk (or (and ACC40Sk (const DI #xffffffff00000000))
+                    FRinti))
+     ((fr400 (unit u-media-4))
+      (fr500 (unit u-media)))
+)
+
+(dni mwtaccg
+     "Media write accumulator guard"
+     ((UNIT FM01) (FR500-MAJOR M-3) (FR400-MAJOR M-1))
+     "mwtaccg$pack $FRinti,$ACCGk"
+     (+ pack ACCGk OP_7B FRinti OPE1_3F (FRj-null))
+     (set ACCGk FRinti)
+     ((fr400 (unit u-media-4-accg))
+      (fr500 (unit u-media)))
+)
+
+(define-pmacro (media-cop num op)
+  (dni (.sym mcop num)
+       "Media custom instruction"
+       ((UNIT FM01) (FR500-MAJOR M-1) (MACH frv))
+       (.str "mcop" num "$pack $FRi,$FRj,$FRk")
+       (+ pack FRk op FRi OPE1_00 FRj)
+       (c-call VOID "@cpu@_media_cop" num)
+       ()
+  )
+)
+
+(media-cop 1 OP_7C)
+(media-cop 2 OP_7D)
+
+; nop
+; A nop is defined to be a "ori gr0,0,gr0"
+; This needn't be a macro-insn, but making it one greatly simplifies decode.c
+; On the other hand spending a little time in the decoder is often worth it.
+;
+(dnmi nop "nop"
+     ((UNIT I01) (FR500-MAJOR I-1) (FR400-MAJOR I-1))
+     "nop$pack"
+     (emit ori pack (GRi 0) (s12 0) (GRk 0))
+)
+
+; Floating point NOP
+(dni fnop
+     "Floating point nop"
+     ((UNIT FM01) (FR500-MAJOR F-8) (MACH simple,tomcat,fr500,frv))
+     "fnop$pack"
+     (+ pack (rd-null) OP_79 (FRi-null) OPE1_0D (FRj-null))
+     (nop)
+     ()
+)
+
+; Media NOP
+; A special case of mclracc
+(dnmi mnop "Media nop"
+      (NO-DIS (UNIT FM01) (FR500-MAJOR M-3))
+     "mnop$pack"
+     (emit mclracc pack (ACC40Sk 63) (A 1))
+)
+
+; A return instruction
+(dnmi ret "return"
+      (NO-DIS (UNIT B01) (FR500-MAJOR B-3) (FR400-MAJOR B-3))
+      "ret$pack"
+      (emit bralr pack (hint_taken 2))
+)
+
+(dnmi cmp "compare"
+      (NO-DIS (UNIT I01) (FR500-MAJOR I-1) (FR400-MAJOR I-1))
+      "cmp$pack $GRi,$GRj,$ICCi_1"
+      (emit subcc pack GRi GRj (GRk 0) ICCi_1)
+)
+
+(dnmi cmpi "compare immediate"
+      (NO-DIS (UNIT I01) (FR500-MAJOR I-1) (FR400-MAJOR I-1))
+      "cmpi$pack $GRi,$s10,$ICCi_1"
+      (emit subicc pack GRi s10 (GRk 0) ICCi_1)
+)
+
+(dnmi ccmp "conditional compare"
+      (NO-DIS (UNIT I01) (FR500-MAJOR I-1) (FR400-MAJOR I-1) CONDITIONAL)
+      "ccmp$pack $GRi,$GRj,$CCi,$cond"
+      (emit csubcc pack GRi GRj (GRk 0) CCi cond)
+)
+
+(dnmi mov "move"
+      (NO-DIS (UNIT I01) (FR500-MAJOR I-1) (FR400-MAJOR I-1))
+      "mov$pack $GRi,$GRk"
+      (emit ori pack GRi (s12 0) GRk)
+)   
+
+(dnmi cmov "conditional move"
+      (NO-DIS (UNIT I01) (FR500-MAJOR I-1) (FR400-MAJOR I-1) CONDITIONAL)
+      "cmov$pack $GRi,$GRk,$CCi,$cond"
+      (emit cor pack GRi (GRj 0) GRk CCi cond)
+)   
diff --git a/cpu/frv.opc b/cpu/frv.opc
new file mode 100644 (file)
index 0000000..c708a60
--- /dev/null
@@ -0,0 +1,946 @@
+/* Fujitsu FRV opcode support, for GNU Binutils.  -*- C -*-
+
+   Copyright 2003 Free Software Foundation, Inc.
+
+   Contributed by Red Hat Inc; developed under contract from Fujitsu.
+
+   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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+/* This file is an addendum to frv.cpu.  Heavy use of C code isn't
+   appropriate in .cpu files, so it resides here.  This especially applies
+   to assembly/disassembly where parsing/printing can be quite involved.
+   Such things aren't really part of the specification of the cpu, per se,
+   so .cpu files provide the general framework and .opc files handle the
+   nitty-gritty details as necessary.
+
+   Each section is delimited with start and end markers.
+
+   <arch>-opc.h additions use: "-- opc.h"
+   <arch>-opc.c additions use: "-- opc.c"
+   <arch>-asm.c additions use: "-- asm.c"
+   <arch>-dis.c additions use: "-- dis.c"
+   <arch>-ibd.h additions use: "-- ibd.h"
+*/
+\f
+/* -- opc.h */
+
+#undef CGEN_DIS_HASH_SIZE
+#define CGEN_DIS_HASH_SIZE 128
+#undef CGEN_DIS_HASH
+#define CGEN_DIS_HASH(buffer, value) (((value) >> 18) & 127)
+
+/* Vliw support.  */
+#define FRV_VLIW_SIZE 4 /* fr500 has largest vliw size of 4.  */
+typedef CGEN_ATTR_VALUE_TYPE VLIW_COMBO[FRV_VLIW_SIZE];
+
+typedef struct
+{
+  int                   next_slot;
+  int                   constraint_violation;
+  unsigned long         mach;
+  unsigned long         elf_flags;
+  CGEN_ATTR_VALUE_TYPE *unit_mapping;
+  VLIW_COMBO           *current_vliw;
+  CGEN_ATTR_VALUE_TYPE  major[FRV_VLIW_SIZE];
+} FRV_VLIW;
+
+int frv_is_branch_major PARAMS ((CGEN_ATTR_VALUE_TYPE, unsigned long));
+int frv_is_float_major  PARAMS ((CGEN_ATTR_VALUE_TYPE, unsigned long));
+int frv_is_media_major  PARAMS ((CGEN_ATTR_VALUE_TYPE, unsigned long));
+int frv_is_branch_insn  PARAMS ((const CGEN_INSN *));
+int frv_is_float_insn   PARAMS ((const CGEN_INSN *));
+int frv_is_media_insn   PARAMS ((const CGEN_INSN *));
+void frv_vliw_reset     PARAMS ((FRV_VLIW *, unsigned long mach, unsigned long elf_flags));
+int frv_vliw_add_insn   PARAMS ((FRV_VLIW *, const CGEN_INSN *));
+int spr_valid           PARAMS ((long));
+/* -- */
+\f
+/* -- opc.c */
+#include "elf/frv.h"
+
+static int match_unit
+  PARAMS ((FRV_VLIW *, CGEN_ATTR_VALUE_TYPE, CGEN_ATTR_VALUE_TYPE));
+static int match_vliw
+  PARAMS ((VLIW_COMBO *, VLIW_COMBO *, int));
+static VLIW_COMBO * add_next_to_vliw
+  PARAMS ((FRV_VLIW *, CGEN_ATTR_VALUE_TYPE));
+static int find_major_in_vliw
+  PARAMS ((FRV_VLIW *, CGEN_ATTR_VALUE_TYPE));
+static int fr400_check_insn_major_constraints
+  PARAMS ((FRV_VLIW *, CGEN_ATTR_VALUE_TYPE));
+static int fr500_check_insn_major_constraints
+  PARAMS ((FRV_VLIW *, CGEN_ATTR_VALUE_TYPE));
+static int check_insn_major_constraints
+  PARAMS ((FRV_VLIW *, CGEN_ATTR_VALUE_TYPE));
+
+int
+frv_is_branch_major (CGEN_ATTR_VALUE_TYPE major, unsigned long mach)
+{
+  switch (mach)
+    {
+    case bfd_mach_fr400:
+      if (major >= FR400_MAJOR_B_1 && major <= FR400_MAJOR_B_6)
+       return 1; /* is a branch */
+      break;
+    default:
+      if (major >= FR500_MAJOR_B_1 && major <= FR500_MAJOR_B_6)
+       return 1; /* is a branch */
+      break;
+    }
+
+  return 0; /* not a branch */
+}
+
+int
+frv_is_float_major (CGEN_ATTR_VALUE_TYPE major, unsigned long mach)
+{
+  switch (mach)
+    {
+    case bfd_mach_fr400:
+      return 0; /* No float insns */
+    default:
+      if (major >= FR500_MAJOR_F_1 && major <= FR500_MAJOR_F_8)
+       return 1; /* is a float insn */
+      break;
+    }
+
+  return 0; /* not a branch */
+}
+
+int
+frv_is_media_major (CGEN_ATTR_VALUE_TYPE major, unsigned long mach)
+{
+  switch (mach)
+    {
+    case bfd_mach_fr400:
+      if (major >= FR400_MAJOR_M_1 && major <= FR400_MAJOR_M_2)
+       return 1; /* is a media insn */
+      break;
+    default:
+      if (major >= FR500_MAJOR_M_1 && major <= FR500_MAJOR_M_8)
+       return 1; /* is a media insn */
+      break;
+    }
+
+  return 0; /* not a branch */
+}
+
+int
+frv_is_branch_insn (const CGEN_INSN *insn)
+{
+  if (frv_is_branch_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR400_MAJOR),
+                          bfd_mach_fr400))
+    return 1;
+  if (frv_is_branch_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR500_MAJOR),
+                          bfd_mach_fr500))
+    return 1;
+
+  return 0;
+}
+
+int
+frv_is_float_insn (const CGEN_INSN *insn)
+{
+  if (frv_is_float_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR400_MAJOR),
+                         bfd_mach_fr400))
+    return 1;
+  if (frv_is_float_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR500_MAJOR),
+                         bfd_mach_fr500))
+    return 1;
+
+  return 0;
+}
+
+int
+frv_is_media_insn (const CGEN_INSN *insn)
+{
+  if (frv_is_media_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR400_MAJOR),
+                         bfd_mach_fr400))
+    return 1;
+  if (frv_is_media_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR500_MAJOR),
+                         bfd_mach_fr500))
+    return 1;
+
+  return 0;
+}
+
+/* This table represents the allowable packing for vliw insns for the fr400.
+   The fr400 has only 2 vliw slots. Represent this by not allowing any insns
+   in slots 2 and 3.
+   Subsets of any given row are also allowed.  */
+static VLIW_COMBO fr400_allowed_vliw[] =
+{
+  /*  slot0       slot1       slot2       slot3    */
+  {  UNIT_I0,    UNIT_I1,    UNIT_NIL,   UNIT_NIL  },
+  {  UNIT_I0,    UNIT_FM0,   UNIT_NIL,   UNIT_NIL  },
+  {  UNIT_I0,    UNIT_B0,    UNIT_NIL,   UNIT_NIL  },
+  {  UNIT_FM0,   UNIT_FM1,   UNIT_NIL,   UNIT_NIL  },
+  {  UNIT_FM0,   UNIT_B0,    UNIT_NIL,   UNIT_NIL  },
+  {  UNIT_B0,    UNIT_NIL,   UNIT_NIL,   UNIT_NIL  },
+  {  UNIT_C,     UNIT_NIL,   UNIT_NIL,   UNIT_NIL  },
+  {  UNIT_NIL,   UNIT_NIL,   UNIT_NIL,   UNIT_NIL  }
+};
+
+/* This table represents the allowable packing for vliw insns for the fr500.
+   Subsets of any given row are also allowed.  */
+static VLIW_COMBO fr500_allowed_vliw[] =
+{
+  /*  slot0       slot1       slot2       slot3    */
+  {  UNIT_I0,    UNIT_FM0,   UNIT_I1,    UNIT_FM1  },
+  {  UNIT_I0,    UNIT_FM0,   UNIT_I1,    UNIT_B0   },
+  {  UNIT_I0,    UNIT_FM0,   UNIT_FM1,   UNIT_B0   },
+  {  UNIT_I0,    UNIT_FM0,   UNIT_B0,    UNIT_B1   },
+  {  UNIT_I0,    UNIT_I1,    UNIT_B0,    UNIT_B1   },
+  {  UNIT_I0,    UNIT_B0,    UNIT_B1,    UNIT_NIL  },
+  {  UNIT_FM0,   UNIT_FM1,   UNIT_B0,    UNIT_B1   },
+  {  UNIT_FM0,   UNIT_B0,    UNIT_B1,    UNIT_NIL  },
+  {  UNIT_B0,    UNIT_B1,    UNIT_NIL,   UNIT_NIL  },
+  {  UNIT_C,     UNIT_NIL,   UNIT_NIL,   UNIT_NIL  },
+  {  UNIT_NIL,   UNIT_NIL,   UNIT_NIL,   UNIT_NIL  }
+};
+
+/* Some insns are assigned specialized implementation units which map to
+   different actual implementation units on different machines.  These
+   tables perform that mapping.  */
+static CGEN_ATTR_VALUE_TYPE fr400_unit_mapping[] =
+{
+/* unit in insn    actual unit */
+/* NIL      */     UNIT_NIL,
+/* I0       */     UNIT_I0,
+/* I1       */     UNIT_I1,
+/* I01      */     UNIT_I01, 
+/* FM0      */     UNIT_FM0,
+/* FM1      */     UNIT_FM1,
+/* FM01     */     UNIT_FM01,
+/* B0       */     UNIT_B0,  /* branches only in B0 unit.  */
+/* B1       */     UNIT_B0,
+/* B01      */     UNIT_B0,
+/* C        */     UNIT_C,
+/* MULT-DIV */     UNIT_I0,  /* multiply and divide only in I0 unit.  */
+/* LOAD     */     UNIT_I0   /* load                only in I0 unit.  */
+};
+
+static CGEN_ATTR_VALUE_TYPE fr500_unit_mapping[] =
+{
+/* unit in insn    actual unit */
+/* NIL      */     UNIT_NIL,
+/* I0       */     UNIT_I0,
+/* I1       */     UNIT_I1,
+/* I01      */     UNIT_I01, 
+/* FM0      */     UNIT_FM0,
+/* FM1      */     UNIT_FM1,
+/* FM01     */     UNIT_FM01,
+/* B0       */     UNIT_B0,
+/* B1       */     UNIT_B1,
+/* B01      */     UNIT_B01,
+/* C        */     UNIT_C,
+/* MULT-DIV */     UNIT_I01, /* multiply and divide in I0 or I1 unit.  */
+/* LOAD     */     UNIT_I01  /* load                in I0 or I1 unit.  */
+};
+
+void
+frv_vliw_reset (FRV_VLIW *vliw, unsigned long mach, unsigned long elf_flags)
+{
+  vliw->next_slot = 0;
+  vliw->constraint_violation = 0;
+  vliw->mach = mach;
+  vliw->elf_flags = elf_flags;
+
+  switch (mach)
+    {
+    case bfd_mach_fr400:
+      vliw->current_vliw = fr400_allowed_vliw;
+      vliw->unit_mapping = fr400_unit_mapping;
+      break;
+    default:
+      vliw->current_vliw = fr500_allowed_vliw;
+      vliw->unit_mapping = fr500_unit_mapping;
+      break;
+    }
+}
+
+/* Return 1 if unit1 is a match for unit2.
+   Unit1 comes from the insn's UNIT attribute. unit2 comes from one of the
+   *_allowed_vliw tables above.  */
+static int
+match_unit (FRV_VLIW *vliw,
+           CGEN_ATTR_VALUE_TYPE unit1, CGEN_ATTR_VALUE_TYPE unit2)
+{
+  /* Map any specialized implementation units to actual ones.  */
+  unit1 = vliw->unit_mapping[unit1];
+
+  if (unit1 == unit2)
+    return 1;
+  if (unit1 < unit2)
+    return 0;
+
+  switch (unit1)
+    {
+    case UNIT_I01:
+    case UNIT_FM01:
+    case UNIT_B01:
+      /* The 01 versions of these units are within 2 enums of the 0 or 1
+        versions.  */
+      if (unit1 - unit2 <= 2)
+       return 1;
+      break;
+    default:
+      break;
+    }
+
+  return 0;
+}
+
+/* Return 1 if the vliws match, 0 otherwise.  */
+
+static int
+match_vliw (VLIW_COMBO *vliw1, VLIW_COMBO *vliw2, int vliw_size)
+{
+  int i;
+
+  for (i = 0; i < vliw_size; ++i)
+    {
+      if ((*vliw1)[i] != (*vliw2)[i])
+       return 0;
+    }
+
+  return 1;
+}
+
+/* Find the next vliw vliw in the table that can accomodate the new insn.
+   If one is found then return it. Otherwise return NULL.  */
+
+static VLIW_COMBO *
+add_next_to_vliw (FRV_VLIW *vliw, CGEN_ATTR_VALUE_TYPE unit)
+{
+  int           next    = vliw->next_slot;
+  VLIW_COMBO    *current = vliw->current_vliw;
+  VLIW_COMBO    *potential;
+
+  if (next <= 0)
+    abort (); /* Should never happen */
+
+  /* The table is sorted by units allowed within slots, so vliws with
+     identical starting sequences are together.  */
+  potential = current;
+  do
+    {
+      if (match_unit (vliw, unit, (*potential)[next]))
+       return potential;
+      ++potential;
+    }
+  while (match_vliw (potential, current, next));
+
+  return NULL;
+}
+
+/* Look for the given major insn type in the given vliw. Return 1 if found,
+   return 0 otherwise.  */
+
+static int
+find_major_in_vliw (FRV_VLIW *vliw, CGEN_ATTR_VALUE_TYPE major)
+{
+  int i;
+
+  for (i = 0; i < vliw->next_slot; ++i)
+    if (vliw->major[i] == major)
+      return 1;
+
+  return 0;
+}
+
+/* Check for constraints between the insns in the vliw due to major insn
+   types.  */
+
+static int
+fr400_check_insn_major_constraints (
+  FRV_VLIW *vliw, CGEN_ATTR_VALUE_TYPE major
+)
+{
+  /* In the cpu file, all media insns are represented as being allowed in
+     both media units. This makes it easier since this is the case for fr500.
+     Catch the invalid combinations here.  Insns of major class FR400_MAJOR_M_2
+     cannot coexist with any other media insn in a vliw.  */
+  switch (major)
+    {
+    case FR400_MAJOR_M_2:
+      return ! find_major_in_vliw (vliw, FR400_MAJOR_M_1)
+       &&   ! find_major_in_vliw (vliw, FR400_MAJOR_M_2);
+    default:
+      break;
+    }
+  return 1;
+}
+
+static int
+fr500_check_insn_major_constraints (
+  FRV_VLIW *vliw, CGEN_ATTR_VALUE_TYPE major
+)
+{
+  /* TODO: A table might be faster for some of the more complex instances
+     here.  */
+  switch (major)
+    {
+    case FR500_MAJOR_I_1:
+    case FR500_MAJOR_I_4:
+    case FR500_MAJOR_I_5:
+    case FR500_MAJOR_I_6:
+    case FR500_MAJOR_B_1:
+    case FR500_MAJOR_B_2:
+    case FR500_MAJOR_B_3:
+    case FR500_MAJOR_B_4:
+    case FR500_MAJOR_B_5:
+    case FR500_MAJOR_B_6:
+    case FR500_MAJOR_F_4:
+    case FR500_MAJOR_F_8:
+    case FR500_MAJOR_M_8:
+      return 1; /* OK */
+    case FR500_MAJOR_I_2:
+      /* Cannot coexist with I-3 insn.  */
+      return ! find_major_in_vliw (vliw, FR500_MAJOR_I_3);
+    case FR500_MAJOR_I_3:
+      /* Cannot coexist with I-2 insn.  */
+      return ! find_major_in_vliw (vliw, FR500_MAJOR_I_2);
+    case FR500_MAJOR_F_1:
+    case FR500_MAJOR_F_2:
+      /* Cannot coexist with F-5, F-6, or M-7 insn.  */
+      return ! find_major_in_vliw (vliw, FR500_MAJOR_F_5)
+       &&   ! find_major_in_vliw (vliw, FR500_MAJOR_F_6)
+       &&   ! find_major_in_vliw (vliw, FR500_MAJOR_M_7);
+    case FR500_MAJOR_F_3:
+      /* Cannot coexist with F-7, or M-7 insn.  */
+      return ! find_major_in_vliw (vliw, FR500_MAJOR_F_7)
+       &&   ! find_major_in_vliw (vliw, FR500_MAJOR_M_7);
+    case FR500_MAJOR_F_5:
+      /* Cannot coexist with F-1, F-2, F-6, F-7, or M-7 insn.  */
+      return ! find_major_in_vliw (vliw, FR500_MAJOR_F_1)
+       &&   ! find_major_in_vliw (vliw, FR500_MAJOR_F_2)
+       &&   ! find_major_in_vliw (vliw, FR500_MAJOR_F_6)
+       &&   ! find_major_in_vliw (vliw, FR500_MAJOR_F_7)
+       &&   ! find_major_in_vliw (vliw, FR500_MAJOR_M_7);
+    case FR500_MAJOR_F_6:
+      /* Cannot coexist with F-1, F-2, F-5, F-6, or M-7 insn.  */
+      return ! find_major_in_vliw (vliw, FR500_MAJOR_F_1)
+       &&   ! find_major_in_vliw (vliw, FR500_MAJOR_F_2)
+       &&   ! find_major_in_vliw (vliw, FR500_MAJOR_F_5)
+       &&   ! find_major_in_vliw (vliw, FR500_MAJOR_F_6)
+       &&   ! find_major_in_vliw (vliw, FR500_MAJOR_M_7);
+    case FR500_MAJOR_F_7:
+      /* Cannot coexist with F-3, F-5, F-7, or M-7 insn.  */
+      return ! find_major_in_vliw (vliw, FR500_MAJOR_F_3)
+       &&   ! find_major_in_vliw (vliw, FR500_MAJOR_F_5)
+       &&   ! find_major_in_vliw (vliw, FR500_MAJOR_F_7)
+       &&   ! find_major_in_vliw (vliw, FR500_MAJOR_M_7);
+    case FR500_MAJOR_M_1:
+      /* Cannot coexist with M-7 insn.  */
+      return ! find_major_in_vliw (vliw, FR500_MAJOR_M_7);
+    case FR500_MAJOR_M_2:
+    case FR500_MAJOR_M_3:
+      /* Cannot coexist with M-5, M-6 or M-7 insn.  */
+      return ! find_major_in_vliw (vliw, FR500_MAJOR_M_5)
+       &&   ! find_major_in_vliw (vliw, FR500_MAJOR_M_6)
+       &&   ! find_major_in_vliw (vliw, FR500_MAJOR_M_7);
+    case FR500_MAJOR_M_4:
+      /* Cannot coexist with M-6 insn.  */
+      return ! find_major_in_vliw (vliw, FR500_MAJOR_M_6);
+    case FR500_MAJOR_M_5:
+      /* Cannot coexist with M-2, M-3, M-5, M-6  or M-7 insn.  */
+      return ! find_major_in_vliw (vliw, FR500_MAJOR_M_2)
+       &&   ! find_major_in_vliw (vliw, FR500_MAJOR_M_3)
+       &&   ! find_major_in_vliw (vliw, FR500_MAJOR_M_5)
+       &&   ! find_major_in_vliw (vliw, FR500_MAJOR_M_6)
+       &&   ! find_major_in_vliw (vliw, FR500_MAJOR_M_7);
+    case FR500_MAJOR_M_6:
+      /* Cannot coexist with M-2, M-3, M-4, M-5, M-6  or M-7 insn.  */
+      return ! find_major_in_vliw (vliw, FR500_MAJOR_M_2)
+       &&   ! find_major_in_vliw (vliw, FR500_MAJOR_M_3)
+       &&   ! find_major_in_vliw (vliw, FR500_MAJOR_M_4)
+       &&   ! find_major_in_vliw (vliw, FR500_MAJOR_M_5)
+       &&   ! find_major_in_vliw (vliw, FR500_MAJOR_M_6)
+       &&   ! find_major_in_vliw (vliw, FR500_MAJOR_M_7);
+    case FR500_MAJOR_M_7:
+      /* Cannot coexist with M-1, M-2, M-3, M-5, M-6  or M-7 insn.  */
+      return ! find_major_in_vliw (vliw, FR500_MAJOR_M_1)
+       &&   ! find_major_in_vliw (vliw, FR500_MAJOR_M_2)
+       &&   ! find_major_in_vliw (vliw, FR500_MAJOR_M_3)
+       &&   ! find_major_in_vliw (vliw, FR500_MAJOR_M_5)
+       &&   ! find_major_in_vliw (vliw, FR500_MAJOR_M_6)
+       &&   ! find_major_in_vliw (vliw, FR500_MAJOR_M_7)
+       &&   ! find_major_in_vliw (vliw, FR500_MAJOR_F_1)
+       &&   ! find_major_in_vliw (vliw, FR500_MAJOR_F_2)
+       &&   ! find_major_in_vliw (vliw, FR500_MAJOR_F_3)
+       &&   ! find_major_in_vliw (vliw, FR500_MAJOR_F_5)
+       &&   ! find_major_in_vliw (vliw, FR500_MAJOR_F_6)
+       &&   ! find_major_in_vliw (vliw, FR500_MAJOR_F_7);
+    default:
+      abort ();
+      break;
+    }
+  return 1;
+}
+
+static int
+check_insn_major_constraints (
+  FRV_VLIW *vliw, CGEN_ATTR_VALUE_TYPE major
+)
+{
+  int rc;
+  switch (vliw->mach)
+    {
+    case bfd_mach_fr400:
+      rc = fr400_check_insn_major_constraints (vliw, major);
+      break;
+    default:
+      rc = fr500_check_insn_major_constraints (vliw, major);
+      break;
+    }
+  return rc;
+}
+
+/* Add in insn to the VLIW vliw if possible. Return 0 if successful,
+   non-zero otherwise.  */
+int
+frv_vliw_add_insn (FRV_VLIW *vliw, const CGEN_INSN *insn)
+{
+  int index;
+  CGEN_ATTR_VALUE_TYPE major;
+  CGEN_ATTR_VALUE_TYPE unit;
+  VLIW_COMBO *new_vliw;
+
+  if (vliw->constraint_violation || CGEN_INSN_INVALID_P (insn))
+    return 1;
+
+  index = vliw->next_slot;
+  if (index >= FRV_VLIW_SIZE)
+    return 1;
+
+  unit = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_UNIT);
+  if (unit == UNIT_NIL)
+    abort (); /* no UNIT specified for this insn in frv.cpu  */
+
+  if (vliw->mach == bfd_mach_fr400)
+    major = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR400_MAJOR);
+  else
+    major = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR500_MAJOR);
+
+  if (index <= 0)
+    {
+      /* Any insn can be added to slot 0.  */
+      while (! match_unit (vliw, unit, (*vliw->current_vliw)[0]))
+       ++vliw->current_vliw;
+      vliw->major[0] = major;
+      vliw->next_slot = 1;
+      return 0;
+    }
+
+  /* If there are already insns in the vliw(s) check to see that
+     this one can be added.  Do this by finding an allowable vliw
+     combination that can accept the new insn.  */
+  if (! (vliw->elf_flags & EF_FRV_NOPACK))
+    {
+      new_vliw = add_next_to_vliw (vliw, unit);
+      if (new_vliw && check_insn_major_constraints (vliw, major))
+       {
+         vliw->current_vliw = new_vliw;
+         vliw->major[index] = major;
+         vliw->next_slot++;
+         return 0;
+       }
+
+      /* The frv machine supports all packing conbinations.  If we fail,
+        to add the insn, then it could not be handled as if it was the fr500.
+        Just return as if it was handled ok.  */
+      if (vliw->mach == bfd_mach_frv)
+       return 0;
+    }
+
+  vliw->constraint_violation = 1;
+  return 1;
+}
+
+int
+spr_valid (regno)
+     long regno;
+{
+  if (regno < 0)     return 0;
+  if (regno <= 4095) return 1;
+  return 0;
+}
+/* -- */
+\f
+/* -- asm.c */
+static const char * parse_ulo16
+  PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
+static const char * parse_uslo16
+  PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
+static const char * parse_uhi16
+  PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
+static long parse_register_number
+  PARAMS ((const char **));
+static const char * parse_spr
+  PARAMS ((CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *));
+static const char * parse_d12
+  PARAMS ((CGEN_CPU_DESC, const char **, int, long *));
+static const char * parse_s12
+  PARAMS ((CGEN_CPU_DESC, const char **, int, long *));
+static const char * parse_u12
+  PARAMS ((CGEN_CPU_DESC, const char **, int, long *));
+
+static const char *
+parse_ulo16 (cd, strp, opindex, valuep)
+     CGEN_CPU_DESC cd;
+     const char **strp;
+     int opindex;
+     unsigned long *valuep;
+{
+  const char *errmsg;
+  enum cgen_parse_operand_result result_type;
+  bfd_vma value;
+  if (**strp == '#' || **strp == '%')
+    {
+      if (strncasecmp (*strp + 1, "lo(", 3) == 0)
+       {
+         *strp += 4;
+         errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_LO16,
+                                      &result_type, &value);
+         if (**strp != ')')
+           return "missing `)'";
+         ++*strp;
+         if (errmsg == NULL
+             && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
+           value &= 0xffff;
+         *valuep = value;
+         return errmsg;
+       }
+      if (strncasecmp (*strp + 1, "gprello(", 8) == 0)
+       {
+         *strp += 9;
+         errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPRELLO,
+                                      &result_type, &value);
+         if (**strp != ')')
+           return "missing ')'";
+         ++*strp;
+         if (errmsg == NULL
+             && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
+           value >>= 16;
+         *valuep = value;
+         return errmsg;
+       }
+    }
+  return cgen_parse_signed_integer (cd, strp, opindex, valuep);
+}
+
+static const char *
+parse_uslo16 (cd, strp, opindex, valuep)
+     CGEN_CPU_DESC cd;
+     const char **strp;
+     int opindex;
+     unsigned long *valuep;
+{
+  const char *errmsg;
+  enum cgen_parse_operand_result result_type;
+  bfd_vma value;
+  if (**strp == '#' || **strp == '%')
+    {
+      if (strncasecmp (*strp + 1, "lo(", 3) == 0)
+       {
+         *strp += 4;
+         errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_LO16,
+                                      &result_type, &value);
+         if (**strp != ')')
+           return "missing `)'";
+         ++*strp;
+         if (errmsg == NULL
+             && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
+           value &= 0xffff;
+         *valuep = value;
+         return errmsg;
+       }
+      else if (strncasecmp (*strp + 1, "gprello(", 8) == 0)
+       {
+         *strp += 9;
+         errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPRELLO,
+                                      &result_type, &value);
+         if (**strp != ')')
+           return "missing ')'";
+         ++*strp;
+         if (errmsg == NULL
+             && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
+           value &= 0xffff;
+         *valuep = value;
+         return errmsg;
+       }
+    }
+  return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
+}
+
+static const char *
+parse_uhi16 (cd, strp, opindex, valuep)
+     CGEN_CPU_DESC cd;
+     const char **strp;
+     int opindex;
+     unsigned long *valuep;
+{
+  const char *errmsg;
+  enum cgen_parse_operand_result result_type;
+  bfd_vma value;
+  if (**strp == '#' || **strp == '%')
+    {
+      if (strncasecmp (*strp + 1, "hi(", 3) == 0)
+       {
+         *strp += 4;
+         errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_HI16,
+                                      &result_type, &value);
+         if (**strp != ')')
+           return "missing `)'";
+         ++*strp;
+         if (errmsg == NULL
+             && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
+           value >>= 16;
+         *valuep = value;
+         return errmsg;
+       }
+      else if (strncasecmp (*strp + 1, "gprelhi(", 8) == 0)
+       {
+         *strp += 9;
+         errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPRELHI,
+                                      &result_type, &value);
+         if (**strp != ')')
+           return "missing ')'";
+         ++*strp;
+         if (errmsg == NULL
+             && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
+           value >>= 16;
+         *valuep = value;
+         return errmsg;
+       }
+    }
+  return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
+}
+
+static long
+parse_register_number (strp)
+     const char **strp;
+{
+  int regno;
+  if (**strp < '0' || **strp > '9')
+    return -1; /* error */
+
+  regno = **strp - '0';
+  for (++*strp; **strp >= '0' && **strp <= '9'; ++*strp)
+    regno = regno * 10 + (**strp - '0');
+
+  return regno;
+}
+
+static const char *
+parse_spr (cd, strp, table, valuep)
+     CGEN_CPU_DESC cd;
+     const char **strp;
+     CGEN_KEYWORD * table;
+     long *valuep;
+{
+  const char *save_strp;
+  long regno;
+
+  /* Check for spr index notation.  */
+  if (strncasecmp (*strp, "spr[", 4) == 0)
+    {
+      *strp += 4;
+      regno = parse_register_number (strp);
+      if (**strp != ']')
+        return "missing `]'";
+      ++*strp;
+      if (! spr_valid (regno))
+       return "Special purpose register number is out of range";
+      *valuep = regno;
+      return NULL;
+    }
+
+  save_strp = *strp;
+  regno = parse_register_number (strp);
+  if (regno != -1)
+    {
+      if (! spr_valid (regno))
+       return "Special purpose register number is out of range";
+      *valuep = regno;
+      return NULL;
+    }
+
+  *strp = save_strp;
+  return cgen_parse_keyword (cd, strp, table, valuep);
+}
+
+static const char *
+parse_d12 (cd, strp, opindex, valuep)
+     CGEN_CPU_DESC cd;
+     const char **strp;
+     int opindex;
+     long *valuep;
+{
+  const char *errmsg;
+  enum cgen_parse_operand_result result_type;
+  bfd_vma value;
+  /* Check for small data reference.  */
+  if (**strp == '#' || **strp == '%')
+    {
+      if (strncasecmp (*strp + 1, "gprel12(", 8) == 0)
+        {
+          *strp += 9;
+          errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPREL12,
+                                       &result_type, &value);
+          if (**strp != ')')
+            return "missing `)'";
+          ++*strp;
+          *valuep = value;
+          return errmsg;
+        }
+    }
+  return cgen_parse_signed_integer (cd, strp, opindex, valuep);
+}
+
+static const char *
+parse_s12 (cd, strp, opindex, valuep)
+     CGEN_CPU_DESC cd;
+     const char **strp;
+     int opindex;
+     long *valuep;
+{
+  const char *errmsg;
+  enum cgen_parse_operand_result result_type;
+  bfd_vma value;
+  /* Check for small data reference.  */
+  if ((**strp == '#' || **strp == '%')
+      && strncasecmp (*strp + 1, "gprel12(", 8) == 0)
+    {
+      *strp += 9;
+      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPREL12,
+                                    &result_type, &value);
+      if (**strp != ')')
+        return "missing `)'";
+      ++*strp;
+      *valuep = value;
+      return errmsg;
+    }
+  else
+    {
+      if (**strp == '#')
+        ++*strp;
+      return cgen_parse_signed_integer (cd, strp, opindex, valuep);
+    }
+}
+
+static const char *
+parse_u12 (cd, strp, opindex, valuep)
+     CGEN_CPU_DESC cd;
+     const char **strp;
+     int opindex;
+     long *valuep;
+{
+  const char *errmsg;
+  enum cgen_parse_operand_result result_type;
+  bfd_vma value;
+  /* Check for small data reference.  */
+  if ((**strp == '#' || **strp == '%')
+      && strncasecmp (*strp + 1, "gprel12(", 8) == 0)
+    {
+      *strp += 9;
+      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPRELU12,
+                                    &result_type, &value);
+      if (**strp != ')')
+        return "missing `)'";
+      ++*strp;
+      *valuep = value;
+      return errmsg;
+    }
+  else
+    {
+      if (**strp == '#')
+        ++*strp;
+      return cgen_parse_signed_integer (cd, strp, opindex, valuep);
+    }
+}
+
+/* -- */
+\f
+/* -- dis.c */
+static void print_spr
+  PARAMS ((CGEN_CPU_DESC, PTR, CGEN_KEYWORD *, long, unsigned));
+static void print_hi
+  PARAMS ((CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int));
+static void print_lo
+  PARAMS ((CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int));
+
+static void
+print_spr (cd, dis_info, names, regno, attrs)
+     CGEN_CPU_DESC cd;
+     PTR dis_info;
+     CGEN_KEYWORD *names;
+     long regno;
+     unsigned int attrs;
+{
+  /* Use the register index format for any unnamed registers.  */
+  if (cgen_keyword_lookup_value (names, regno) == NULL)
+    {
+      disassemble_info *info = (disassemble_info *) dis_info;
+      (*info->fprintf_func) (info->stream, "spr[%ld]", regno);
+    }
+  else
+    print_keyword (cd, dis_info, names, regno, attrs);
+}
+
+static void
+print_hi (cd, dis_info, value, attrs, pc, length)
+     CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
+     PTR dis_info;
+     long value;
+     unsigned int attrs ATTRIBUTE_UNUSED;
+     bfd_vma pc ATTRIBUTE_UNUSED;
+     int length ATTRIBUTE_UNUSED;
+{
+  disassemble_info *info = (disassemble_info *) dis_info;
+  if (value)
+    (*info->fprintf_func) (info->stream, "0x%lx", value);
+  else
+    (*info->fprintf_func) (info->stream, "hi(0x%lx)", value);
+}
+
+static void
+print_lo (cd, dis_info, value, attrs, pc, length)
+     CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
+     PTR dis_info;
+     long value;
+     unsigned int attrs ATTRIBUTE_UNUSED;
+     bfd_vma pc ATTRIBUTE_UNUSED;
+     int length ATTRIBUTE_UNUSED;
+{
+  disassemble_info *info = (disassemble_info *) dis_info;
+  if (value)
+    (*info->fprintf_func) (info->stream, "0x%lx", value);
+  else
+    (*info->fprintf_func) (info->stream, "lo(0x%lx)", value);
+}
+
+/* -- */
diff --git a/cpu/simplify.inc b/cpu/simplify.inc
new file mode 100644 (file)
index 0000000..12b05b7
--- /dev/null
@@ -0,0 +1,215 @@
+; Collection of macros, for GNU Binutils .cpu files. -*- Scheme -*-
+;
+; Copyright 2000 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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+\f
+; Enums.
+
+; Define a normal enum without using name/value pairs.
+; This is currently the same as define-full-enum but it needn't remain
+; that way (it's define-full-enum that would change).
+
+(define-pmacro (define-normal-enum name comment attrs prefix vals)
+  "\
+Define a normal enum, fixed number of arguments.
+"
+  (define-full-enum name comment attrs prefix vals)
+)
+
+; Define a normal insn enum.
+
+(define-pmacro (define-normal-insn-enum name comment attrs prefix fld vals)
+  "\
+Define a normal instruction opcode enum.
+"
+  (define-full-insn-enum name comment attrs prefix fld vals)
+)
+\f
+; Instruction fields.
+
+; Normally, fields are unsigned have no encode/decode needs.
+
+(define-pmacro (define-normal-ifield name comment attrs start length)
+  "Define a normal instruction field.\n"
+  (define-full-ifield name comment attrs start length UINT #f #f)
+)
+
+; For those who don't like typing.
+
+(define-pmacro df
+  "Shorthand form of define-full-ifield.\n"
+  define-full-ifield
+)
+(define-pmacro dnf
+  "Shorthand form of define-normal-ifield.\n"
+  define-normal-ifield
+)
+
+; Define a normal multi-ifield.
+; FIXME: The define-normal version for ifields doesn't include the mode.
+
+(define-pmacro (define-normal-multi-ifield name comment attrs
+                mode subflds insert extract)
+  "Define a normal multi-part instruction field.\n"
+  (define-full-multi-ifield name comment attrs mode subflds insert extract)
+)
+
+; For those who don't like typing.
+
+(define-pmacro dnmf
+  "Shorthand form of define-normal-multi-ifield.\n"
+  define-normal-multi-ifield
+)
+
+; Simple multi-ifields: mode is UINT, default insert/extract support.
+
+(define-pmacro (dsmf name comment attrs subflds)
+  "Define a simple multi-part instruction field.\n"
+  (define-full-multi-ifield name comment attrs UINT subflds #f #f)
+)
+\f
+; Hardware.
+
+; Simpler version for most hardware elements.
+; Allow special assembler support specification but no semantic-name or
+; get/set specs.
+
+(define-pmacro (define-normal-hardware name comment attrs type
+                indices values handlers)
+  "\
+Define a normal hardware element.
+"
+  (define-full-hardware name comment attrs name type
+    indices values handlers () () ())
+)
+
+; For those who don't like typing.
+
+(define-pmacro dnh
+  "Shorthand form of define-normal-hardware.\n"
+  define-normal-hardware
+)
+
+; Simpler version of dnh that leaves out the indices, values, handlers,
+; get, set, and layout specs.
+; This is useful for 1 bit registers.
+; ??? While dsh and dnh aren't that distinguishable when perusing a .cpu file,
+; they both take a fixed number of positional arguments, and dsh is a proper
+; subset of dnh with all arguments in the same positions, so methinks things
+; are ok.
+
+(define-pmacro (define-simple-hardware name comment attrs type)
+  "\
+Define a simple hardware element (usually a scalar register).
+"
+  (define-full-hardware name comment attrs name type () () () () () ())
+)
+
+(define-pmacro dsh
+  "Shorthand form of define-simple-hardware.\n"
+  define-simple-hardware
+)
+\f
+; Operands.
+
+(define-pmacro (define-normal-operand name comment attrs type index)
+  "Define a normal operand.\n"
+  (define-full-operand name comment attrs type DFLT index () () ())
+)
+
+; For those who don't like typing.
+; FIXME: dno?
+
+(define-pmacro dnop
+  "Shorthand form of define-normal-operand.\n"
+  define-normal-operand
+)
+
+(define-pmacro (dndo x-name x-mode x-args
+                    x-syntax x-base-ifield x-encoding x-ifield-assertion
+                    x-getter x-setter)
+  "Define a normal derived operand."
+  (define-derived-operand
+    (name x-name)
+    (mode x-mode)
+    (args x-args)
+    (syntax x-syntax)
+    (base-ifield x-base-ifield)
+    (encoding x-encoding)
+    (ifield-assertion x-ifield-assertion)
+    (getter x-getter)
+    (setter x-setter)
+    )
+)
+\f
+; Instructions.
+
+; Define an instruction object, normal version.
+; At present all fields must be specified.
+; Fields ifield-assertion is absent.
+
+(define-pmacro (define-normal-insn name comment attrs syntax fmt semantics timing)
+  "Define a normal instruction.\n"
+  (define-full-insn name comment attrs syntax fmt () semantics timing)
+)
+
+; To reduce the amount of typing.
+; Note that this is the same name as the D'ni in MYST.  Oooohhhh.....
+; this must be the right way to go. :-)
+
+(define-pmacro dni
+  "Shorthand form of define-normal-insn.\n"
+  define-normal-insn
+)
+\f
+; Macro instructions.
+
+; Define a macro-insn object, normal version.
+; This only supports expanding to one real insn.
+
+(define-pmacro (define-normal-macro-insn name comment attrs syntax expansion)
+  "Define a normal macro instruction.\n"
+  (define-full-minsn name comment attrs syntax expansion)
+)
+
+; To reduce the amount of typing.
+
+(define-pmacro dnmi
+  "Shorthand form of define-normal-macro-insn.\n"
+  define-normal-macro-insn
+)
+\f
+; Modes.
+; ??? Not currently available for use.
+;
+; Define Normal Mode
+;
+;(define-pmacro (define-normal-mode name comment attrs bits bytes
+;               non-mode-c-type printf-type sem-mode ptr-to host?)
+;  "Define a normal mode.\n"
+;  (define-full-mode name comment attrs bits bytes
+;    non-mode-c-type printf-type sem-mode ptr-to host?)
+;)
+;
+; For those who don't like typing.
+;(define-pmacro dnm
+;  "Shorthand form of define-normal-mode.\n"
+;  define-normal-mode
+;)