r2289 - in trunk/src/host/qemu-neo1973: . darwin-user fpu hw linux-user linux-user/alpha linux-user/i386 linux-user/mips linux-user/ppc target-alpha target-arm target-i386 target-m68k target-mips target-ppc target-sh4 target-sparc

andrew at sita.openmoko.org andrew at sita.openmoko.org
Sun Jun 17 18:55:48 CEST 2007


Author: andrew
Date: 2007-06-17 18:55:00 +0200 (Sun, 17 Jun 2007)
New Revision: 2289

Modified:
   trunk/src/host/qemu-neo1973/Changelog
   trunk/src/host/qemu-neo1973/Makefile.target
   trunk/src/host/qemu-neo1973/arm-semi.c
   trunk/src/host/qemu-neo1973/cocoa.m
   trunk/src/host/qemu-neo1973/configure
   trunk/src/host/qemu-neo1973/cpu-all.h
   trunk/src/host/qemu-neo1973/cpu-exec.c
   trunk/src/host/qemu-neo1973/darwin-user/mmap.c
   trunk/src/host/qemu-neo1973/disas.c
   trunk/src/host/qemu-neo1973/exec.c
   trunk/src/host/qemu-neo1973/fpu/softfloat.h
   trunk/src/host/qemu-neo1973/gdbstub.c
   trunk/src/host/qemu-neo1973/hw/acpi.c
   trunk/src/host/qemu-neo1973/hw/an5206.c
   trunk/src/host/qemu-neo1973/hw/apb_pci.c
   trunk/src/host/qemu-neo1973/hw/arm_gic.c
   trunk/src/host/qemu-neo1973/hw/arm_sysctl.c
   trunk/src/host/qemu-neo1973/hw/arm_timer.c
   trunk/src/host/qemu-neo1973/hw/cirrus_vga.c
   trunk/src/host/qemu-neo1973/hw/cs4231.c
   trunk/src/host/qemu-neo1973/hw/cuda.c
   trunk/src/host/qemu-neo1973/hw/dma.c
   trunk/src/host/qemu-neo1973/hw/ds1225y.c
   trunk/src/host/qemu-neo1973/hw/esp.c
   trunk/src/host/qemu-neo1973/hw/gt64xxx.c
   trunk/src/host/qemu-neo1973/hw/ide.c
   trunk/src/host/qemu-neo1973/hw/integratorcp.c
   trunk/src/host/qemu-neo1973/hw/mcf5206.c
   trunk/src/host/qemu-neo1973/hw/mips_malta.c
   trunk/src/host/qemu-neo1973/hw/mips_pica61.c
   trunk/src/host/qemu-neo1973/hw/mips_r4k.c
   trunk/src/host/qemu-neo1973/hw/ne2000.c
   trunk/src/host/qemu-neo1973/hw/parallel.c
   trunk/src/host/qemu-neo1973/hw/pc.c
   trunk/src/host/qemu-neo1973/hw/pci.c
   trunk/src/host/qemu-neo1973/hw/pckbd.c
   trunk/src/host/qemu-neo1973/hw/pcnet.c
   trunk/src/host/qemu-neo1973/hw/pflash_cfi02.c
   trunk/src/host/qemu-neo1973/hw/pl011.c
   trunk/src/host/qemu-neo1973/hw/pl050.c
   trunk/src/host/qemu-neo1973/hw/pl080.c
   trunk/src/host/qemu-neo1973/hw/pl110.c
   trunk/src/host/qemu-neo1973/hw/pl181.c
   trunk/src/host/qemu-neo1973/hw/pl190.c
   trunk/src/host/qemu-neo1973/hw/ppc405.h
   trunk/src/host/qemu-neo1973/hw/ppc405_boards.c
   trunk/src/host/qemu-neo1973/hw/ppc405_uc.c
   trunk/src/host/qemu-neo1973/hw/ppc_prep.c
   trunk/src/host/qemu-neo1973/hw/ptimer.c
   trunk/src/host/qemu-neo1973/hw/pxa.h
   trunk/src/host/qemu-neo1973/hw/pxa2xx.c
   trunk/src/host/qemu-neo1973/hw/pxa2xx_dma.c
   trunk/src/host/qemu-neo1973/hw/pxa2xx_gpio.c
   trunk/src/host/qemu-neo1973/hw/pxa2xx_lcd.c
   trunk/src/host/qemu-neo1973/hw/pxa2xx_mmci.c
   trunk/src/host/qemu-neo1973/hw/pxa2xx_pcmcia.c
   trunk/src/host/qemu-neo1973/hw/pxa2xx_pic.c
   trunk/src/host/qemu-neo1973/hw/pxa2xx_timer.c
   trunk/src/host/qemu-neo1973/hw/scsi-disk.c
   trunk/src/host/qemu-neo1973/hw/serial.c
   trunk/src/host/qemu-neo1973/hw/slavio_intctl.c
   trunk/src/host/qemu-neo1973/hw/slavio_misc.c
   trunk/src/host/qemu-neo1973/hw/slavio_serial.c
   trunk/src/host/qemu-neo1973/hw/slavio_timer.c
   trunk/src/host/qemu-neo1973/hw/sparc32_dma.c
   trunk/src/host/qemu-neo1973/hw/spitz.c
   trunk/src/host/qemu-neo1973/hw/sun4m.c
   trunk/src/host/qemu-neo1973/hw/sun4u.c
   trunk/src/host/qemu-neo1973/hw/tcx.c
   trunk/src/host/qemu-neo1973/hw/usb-ohci.c
   trunk/src/host/qemu-neo1973/hw/usb-uhci.c
   trunk/src/host/qemu-neo1973/hw/usb.h
   trunk/src/host/qemu-neo1973/hw/versatilepb.c
   trunk/src/host/qemu-neo1973/hw/vga.c
   trunk/src/host/qemu-neo1973/linux-user/alpha/syscall.h
   trunk/src/host/qemu-neo1973/linux-user/alpha/termbits.h
   trunk/src/host/qemu-neo1973/linux-user/elfload.c
   trunk/src/host/qemu-neo1973/linux-user/i386/syscall.h
   trunk/src/host/qemu-neo1973/linux-user/linuxload.c
   trunk/src/host/qemu-neo1973/linux-user/main.c
   trunk/src/host/qemu-neo1973/linux-user/mips/syscall.h
   trunk/src/host/qemu-neo1973/linux-user/mmap.c
   trunk/src/host/qemu-neo1973/linux-user/path.c
   trunk/src/host/qemu-neo1973/linux-user/ppc/syscall.h
   trunk/src/host/qemu-neo1973/linux-user/qemu.h
   trunk/src/host/qemu-neo1973/linux-user/syscall.c
   trunk/src/host/qemu-neo1973/linux-user/syscall_defs.h
   trunk/src/host/qemu-neo1973/mips-dis.c
   trunk/src/host/qemu-neo1973/osdep.c
   trunk/src/host/qemu-neo1973/osdep.h
   trunk/src/host/qemu-neo1973/qemu-doc.texi
   trunk/src/host/qemu-neo1973/qemu-img.texi
   trunk/src/host/qemu-neo1973/sdl.c
   trunk/src/host/qemu-neo1973/sparc-dis.c
   trunk/src/host/qemu-neo1973/target-alpha/cpu.h
   trunk/src/host/qemu-neo1973/target-alpha/exec.h
   trunk/src/host/qemu-neo1973/target-alpha/translate.c
   trunk/src/host/qemu-neo1973/target-arm/cpu.h
   trunk/src/host/qemu-neo1973/target-arm/exec.h
   trunk/src/host/qemu-neo1973/target-arm/translate.c
   trunk/src/host/qemu-neo1973/target-i386/cpu.h
   trunk/src/host/qemu-neo1973/target-i386/exec.h
   trunk/src/host/qemu-neo1973/target-i386/helper.c
   trunk/src/host/qemu-neo1973/target-i386/translate.c
   trunk/src/host/qemu-neo1973/target-m68k/cpu.h
   trunk/src/host/qemu-neo1973/target-m68k/exec.h
   trunk/src/host/qemu-neo1973/target-m68k/helper.c
   trunk/src/host/qemu-neo1973/target-m68k/op-hacks.h
   trunk/src/host/qemu-neo1973/target-m68k/op.c
   trunk/src/host/qemu-neo1973/target-m68k/op_helper.c
   trunk/src/host/qemu-neo1973/target-m68k/qregs.def
   trunk/src/host/qemu-neo1973/target-m68k/translate.c
   trunk/src/host/qemu-neo1973/target-mips/TODO
   trunk/src/host/qemu-neo1973/target-mips/cpu.h
   trunk/src/host/qemu-neo1973/target-mips/exec.h
   trunk/src/host/qemu-neo1973/target-mips/fop_template.c
   trunk/src/host/qemu-neo1973/target-mips/helper.c
   trunk/src/host/qemu-neo1973/target-mips/op.c
   trunk/src/host/qemu-neo1973/target-mips/op_helper.c
   trunk/src/host/qemu-neo1973/target-mips/op_mem.c
   trunk/src/host/qemu-neo1973/target-mips/op_template.c
   trunk/src/host/qemu-neo1973/target-mips/translate.c
   trunk/src/host/qemu-neo1973/target-mips/translate_init.c
   trunk/src/host/qemu-neo1973/target-ppc/cpu.h
   trunk/src/host/qemu-neo1973/target-ppc/exec.h
   trunk/src/host/qemu-neo1973/target-ppc/op_helper.c
   trunk/src/host/qemu-neo1973/target-ppc/translate.c
   trunk/src/host/qemu-neo1973/target-sh4/cpu.h
   trunk/src/host/qemu-neo1973/target-sh4/op_helper.c
   trunk/src/host/qemu-neo1973/target-sparc/cpu.h
   trunk/src/host/qemu-neo1973/target-sparc/exec.h
   trunk/src/host/qemu-neo1973/target-sparc/op.c
   trunk/src/host/qemu-neo1973/target-sparc/op_helper.c
   trunk/src/host/qemu-neo1973/target-sparc/translate.c
   trunk/src/host/qemu-neo1973/vl.c
   trunk/src/host/qemu-neo1973/vl.h
Log:
Merge last week's changes from cvs.savannah.nongnu.org:/sources/qemu


Modified: trunk/src/host/qemu-neo1973/Changelog
===================================================================
--- trunk/src/host/qemu-neo1973/Changelog	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/Changelog	2007-06-17 16:55:00 UTC (rev 2289)
@@ -5,6 +5,8 @@
   - CPU model selection support (J. Mayer, Paul Brook, Herve Poussineau)
   - Several Sparc fixes (Aurelien Jarno, Blue Swirl)
   - MIPS 64-bit FPU support (Thiemo Seufer)
+  - Xscale PDA emulation (Andrzei Zaborowski)
+  - ColdFire system emulation (Paul Brook)
 
 version 0.9.0:
 

Modified: trunk/src/host/qemu-neo1973/Makefile.target
===================================================================
--- trunk/src/host/qemu-neo1973/Makefile.target	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/Makefile.target	2007-06-17 16:55:00 UTC (rev 2289)
@@ -409,7 +409,7 @@
 
 # USB layer
 VL_OBJS+= usb.o usb-hub.o usb-linux.o usb-hid.o usb-ohci.o usb-msd.o usb-net.o
-VL_OBJS+= usb-linux-gadget.o usb-bt.o
+VL_OBJS+= usb-linux-gadget.o usb-bt.o usb-wacom.o
 
 # EEPROM emulation
 VL_OBJS += eeprom93xx.o
@@ -447,18 +447,18 @@
 VL_OBJS+= mips_r4k.o mips_malta.o mips_pica61.o
 VL_OBJS+= mips_timer.o mips_int.o dma.o vga.o serial.o i8254.o i8259.o
 VL_OBJS+= ide.o gt64xxx.o pckbd.o ps2.o fdc.o mc146818rtc.o usb-uhci.o acpi.o ds1225y.o
-VL_OBJS+= piix_pci.o parallel.o mixeng.o cirrus_vga.o $(SOUND_HW) $(AUDIODRV)
+VL_OBJS+= piix_pci.o smbus_eeprom.o parallel.o mixeng.o cirrus_vga.o $(SOUND_HW) $(AUDIODRV)
 CPPFLAGS += -DHAS_AUDIO
 endif
 ifeq ($(TARGET_BASE_ARCH), sparc)
 ifeq ($(TARGET_ARCH), sparc64)
 VL_OBJS+= sun4u.o ide.o pckbd.o ps2.o vga.o apb_pci.o
 VL_OBJS+= fdc.o mc146818rtc.o serial.o m48t59.o
-VL_OBJS+= cirrus_vga.o parallel.o
+VL_OBJS+= cirrus_vga.o parallel.o ptimer.o
 else
 VL_OBJS+= sun4m.o tcx.o pcnet.o iommu.o m48t59.o slavio_intctl.o
 VL_OBJS+= slavio_timer.o slavio_serial.o slavio_misc.o fdc.o esp.o sparc32_dma.o
-VL_OBJS+= cs4231.o
+VL_OBJS+= cs4231.o ptimer.o
 endif
 endif
 ifeq ($(TARGET_BASE_ARCH), arm)
@@ -479,7 +479,8 @@
 VL_OBJS+= shix.o sh7750.o sh7750_regnames.o tc58128.o
 endif
 ifeq ($(TARGET_BASE_ARCH), m68k)
-VL_OBJS+= an5206.o mcf5206.o ptimer.o
+VL_OBJS+= an5206.o mcf5206.o ptimer.o mcf_uart.o mcf_intc.o mcf5208.o mcf_fec.o
+VL_OBJS+= m68k-semi.o
 endif
 ifdef CONFIG_GDBSTUB
 VL_OBJS+=gdbstub.o 
@@ -603,6 +604,10 @@
 signal.o: signal.c
 	$(CC) $(HELPER_CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -c -o $@ $<
 
+vga.o: pixel_ops.h
+
+tcx.o: pixel_ops.h
+
 ifeq ($(TARGET_BASE_ARCH), i386)
 op.o: op.c opreg_template.h ops_template.h ops_template_mem.h ops_mem.h ops_sse.h
 endif
@@ -613,8 +618,10 @@
 endif
 
 ifeq ($(TARGET_BASE_ARCH), sparc)
-op.o: op.c op_template.h op_mem.h fop_template.h fbranch_template.h
-magic_load.o: elf_op.h
+helper.o: cpu.h exec-all.h
+op.o: op.c op_template.h op_mem.h fop_template.h fbranch_template.h exec.h cpu.h
+op_helper.o: exec.h softmmu_template.h cpu.h
+translate.o: cpu.h exec-all.h disas.h
 endif
 
 ifeq ($(TARGET_BASE_ARCH), ppc)

Modified: trunk/src/host/qemu-neo1973/arm-semi.c
===================================================================
--- trunk/src/host/qemu-neo1973/arm-semi.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/arm-semi.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -112,69 +112,26 @@
     return code;
 }
 
-static uint32_t softmmu_tget32(CPUState *env, uint32_t addr)
-{
-    uint32_t val;
-
-    cpu_memory_rw_debug(env, addr, (uint8_t *)&val, 4, 0);
-    return tswap32(val);
-}
-static uint32_t softmmu_tget8(CPUState *env, uint32_t addr)
-{
-    uint8_t val;
-
-    cpu_memory_rw_debug(env, addr, &val, 1, 0);
-    return val;
-}
-#define tget32(p) softmmu_tget32(env, p)
-#define tget8(p) softmmu_tget8(env, p)
-
-static void *softmmu_lock_user(CPUState *env, uint32_t addr, uint32_t len,
-                               int copy)
-{
-    char *p;
-    /* TODO: Make this something that isn't fixed size.  */
-    p = malloc(len);
-    if (copy)
-        cpu_memory_rw_debug(env, addr, p, len, 0);
-    return p;
-}
-#define lock_user(p, len, copy) softmmu_lock_user(env, p, len, copy)
-static char *softmmu_lock_user_string(CPUState *env, uint32_t addr)
-{
-    char *p;
-    char *s;
-    uint8_t c;
-    /* TODO: Make this something that isn't fixed size.  */
-    s = p = malloc(1024);
-    do {
-        cpu_memory_rw_debug(env, addr, &c, 1, 0);
-        addr++;
-        *(p++) = c;
-    } while (c);
-    return s;
-}
-#define lock_user_string(p) softmmu_lock_user_string(env, p)
-static void softmmu_unlock_user(CPUState *env, void *p, target_ulong addr,
-                                target_ulong len)
-{
-    if (len)
-        cpu_memory_rw_debug(env, addr, p, len, 1);
-    free(p);
-}
-#define unlock_user(s, args, len) softmmu_unlock_user(env, s, args, len)
+#include "softmmu-semi.h"
 #endif
 
 static target_ulong arm_semi_syscall_len;
 
+#if !defined(CONFIG_USER_ONLY)
+static target_ulong syscall_err;
+#endif
+
 static void arm_semi_cb(CPUState *env, target_ulong ret, target_ulong err)
 {
 #ifdef CONFIG_USER_ONLY
     TaskState *ts = env->opaque;
 #endif
+
     if (ret == (target_ulong)-1) {
 #ifdef CONFIG_USER_ONLY
         ts->swi_errno = err;
+#else
+	syscall_err = err;
 #endif
         env->regs[0] = ret;
     } else {
@@ -194,6 +151,20 @@
     }
 }
 
+static void arm_semi_flen_cb(CPUState *env, target_ulong ret, target_ulong err)
+{
+    /* The size is always stored in big-endian order, extract
+       the value. We assume the size always fit in 32 bits.  */
+    uint32_t size;
+    cpu_memory_rw_debug(env, env->regs[13]-64+32, (uint8_t *)&size, 4, 0);
+    env->regs[0] = be32_to_cpu(size);
+#ifdef CONFIG_USER_ONLY
+    ((TaskState *)env->opaque)->swi_errno = err;
+#else
+    syscall_err = err;
+#endif
+}
+
 #define ARG(n) tget32(args + (n) * 4)
 #define SET_ARG(n, val) tput32(args + (n) * 4,val)
 uint32_t do_arm_semihosting(CPUState *env)
@@ -223,8 +194,8 @@
                 return STDOUT_FILENO;
         }
         if (use_gdb_syscalls()) {
-            gdb_do_syscall(arm_semi_cb, "open,%s,%x,1a4", ARG(0), (int)ARG(2),
-                           gdb_open_modeflags[ARG(1)]);
+            gdb_do_syscall(arm_semi_cb, "open,%s,%x,1a4", ARG(0), 
+			   (int)ARG(2)+1, gdb_open_modeflags[ARG(1)]);
             return env->regs[0];
         } else {
             ret = set_swi_errno(ts, open(s, open_modeflags[ARG(1)], 0644));
@@ -302,7 +273,7 @@
         }
     case SYS_SEEK:
         if (use_gdb_syscalls()) {
-            gdb_do_syscall(arm_semi_cb, "fseek,%x,%x,0", ARG(0), ARG(1));
+            gdb_do_syscall(arm_semi_cb, "lseek,%x,%x,0", ARG(0), ARG(1));
             return env->regs[0];
         } else {
             ret = set_swi_errno(ts, lseek(ARG(0), ARG(1), SEEK_SET));
@@ -312,8 +283,9 @@
         }
     case SYS_FLEN:
         if (use_gdb_syscalls()) {
-            /* TODO: Use stat syscall.  */
-            return -1;
+            gdb_do_syscall(arm_semi_flen_cb, "fstat,%x,%x", 
+			   ARG(0), env->regs[13]-64);
+            return env->regs[0];
         } else {
             struct stat buf;
             ret = set_swi_errno(ts, fstat(ARG(0), &buf));
@@ -326,7 +298,7 @@
         return -1;
     case SYS_REMOVE:
         if (use_gdb_syscalls()) {
-            gdb_do_syscall(arm_semi_cb, "unlink,%s", ARG(0), (int)ARG(1));
+            gdb_do_syscall(arm_semi_cb, "unlink,%s", ARG(0), (int)ARG(1)+1);
             ret = env->regs[0];
         } else {
             s = lock_user_string(ARG(0));
@@ -337,7 +309,7 @@
     case SYS_RENAME:
         if (use_gdb_syscalls()) {
             gdb_do_syscall(arm_semi_cb, "rename,%s,%s",
-                           ARG(0), (int)ARG(1), ARG(2), (int)ARG(3));
+                           ARG(0), (int)ARG(1)+1, ARG(2), (int)ARG(3)+1);
             return env->regs[0];
         } else {
             char *s2;
@@ -354,7 +326,7 @@
         return set_swi_errno(ts, time(NULL));
     case SYS_SYSTEM:
         if (use_gdb_syscalls()) {
-            gdb_do_syscall(arm_semi_cb, "system,%s", ARG(0), (int)ARG(1));
+            gdb_do_syscall(arm_semi_cb, "system,%s", ARG(0), (int)ARG(1)+1);
             return env->regs[0];
         } else {
             s = lock_user_string(ARG(0));
@@ -365,7 +337,7 @@
 #ifdef CONFIG_USER_ONLY
         return ts->swi_errno;
 #else
-        return 0;
+        return syscall_err;
 #endif
     case SYS_GET_CMDLINE:
 #ifdef CONFIG_USER_ONLY

Modified: trunk/src/host/qemu-neo1973/cocoa.m
===================================================================
--- trunk/src/host/qemu-neo1973/cocoa.m	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/cocoa.m	2007-06-17 16:55:00 UTC (rev 2289)
@@ -164,7 +164,12 @@
     ds->depth = device_bpp;
     ds->width = w;
     ds->height = h;
-    
+#ifdef __LITTLE_ENDIAN__
+    ds->bgr = 1;
+#else
+    ds->bgr = 0;
+#endif
+
     current_ds = *ds;
 }
 

Modified: trunk/src/host/qemu-neo1973/configure
===================================================================
--- trunk/src/host/qemu-neo1973/configure	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/configure	2007-06-17 16:55:00 UTC (rev 2289)
@@ -920,23 +920,26 @@
 [ "$target_cpu" = "sh4eb" ] && target_bigendian=yes
 [ "$target_cpu" = "m68k" ] && target_bigendian=yes
 target_softmmu="no"
-if expr $target : '.*-softmmu' > /dev/null ; then
-  target_softmmu="yes"
-fi
 target_user_only="no"
-if expr $target : '.*-user' > /dev/null ; then
-  target_user_only="yes"
-fi
-
 target_linux_user="no"
-if expr $target : '.*-linux-user' > /dev/null ; then
-  target_linux_user="yes"
-fi
-
 target_darwin_user="no"
-if expr $target : '.*-darwin-user' > /dev/null ; then
-  target_darwin_user="yes"
-fi
+case "$target" in
+  ${target_cpu}-softmmu)
+    target_softmmu="yes"
+    ;;
+  ${target_cpu}-linux-user)
+    target_user_only="yes"
+    target_linux_user="yes"
+    ;;
+  ${target_cpu}-darwin-user)
+    target_user_only="yes"
+    target_darwin_user="yes"
+    ;;
+  *)
+    echo "ERROR: Target '$target' not recognised"
+    exit 1
+    ;;
+esac
 
 if test "$target_user_only" = "no" -a "$check_gfx" = "yes" \
         -a "$sdl" = "no" -a "$cocoa" = "no" ; then

Modified: trunk/src/host/qemu-neo1973/cpu-all.h
===================================================================
--- trunk/src/host/qemu-neo1973/cpu-all.h	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/cpu-all.h	2007-06-17 16:55:00 UTC (rev 2289)
@@ -692,77 +692,6 @@
 void page_set_flags(target_ulong start, target_ulong end, int flags);
 void page_unprotect_range(target_ulong data, target_ulong data_size);
 
-#define SINGLE_CPU_DEFINES
-#ifdef SINGLE_CPU_DEFINES
-
-#if defined(TARGET_I386)
-
-#define CPUState CPUX86State
-#define cpu_init cpu_x86_init
-#define cpu_exec cpu_x86_exec
-#define cpu_gen_code cpu_x86_gen_code
-#define cpu_signal_handler cpu_x86_signal_handler
-
-#elif defined(TARGET_ARM)
-
-#define CPUState CPUARMState
-#define cpu_init cpu_arm_init
-#define cpu_exec cpu_arm_exec
-#define cpu_gen_code cpu_arm_gen_code
-#define cpu_signal_handler cpu_arm_signal_handler
-
-#elif defined(TARGET_SPARC)
-
-#define CPUState CPUSPARCState
-#define cpu_init cpu_sparc_init
-#define cpu_exec cpu_sparc_exec
-#define cpu_gen_code cpu_sparc_gen_code
-#define cpu_signal_handler cpu_sparc_signal_handler
-
-#elif defined(TARGET_PPC)
-
-#define CPUState CPUPPCState
-#define cpu_init cpu_ppc_init
-#define cpu_exec cpu_ppc_exec
-#define cpu_gen_code cpu_ppc_gen_code
-#define cpu_signal_handler cpu_ppc_signal_handler
-
-#elif defined(TARGET_M68K)
-#define CPUState CPUM68KState
-#define cpu_init cpu_m68k_init
-#define cpu_exec cpu_m68k_exec
-#define cpu_gen_code cpu_m68k_gen_code
-#define cpu_signal_handler cpu_m68k_signal_handler
-
-#elif defined(TARGET_MIPS)
-#define CPUState CPUMIPSState
-#define cpu_init cpu_mips_init
-#define cpu_exec cpu_mips_exec
-#define cpu_gen_code cpu_mips_gen_code
-#define cpu_signal_handler cpu_mips_signal_handler
-
-#elif defined(TARGET_SH4)
-#define CPUState CPUSH4State
-#define cpu_init cpu_sh4_init
-#define cpu_exec cpu_sh4_exec
-#define cpu_gen_code cpu_sh4_gen_code
-#define cpu_signal_handler cpu_sh4_signal_handler
-
-#elif defined(TARGET_ALPHA)
-#define CPUState CPUAlphaState
-#define cpu_init cpu_alpha_init
-#define cpu_exec cpu_alpha_exec
-#define cpu_gen_code cpu_alpha_gen_code
-#define cpu_signal_handler cpu_alpha_signal_handler
-
-#else
-
-#error unsupported target CPU
-
-#endif
-
-#endif /* SINGLE_CPU_DEFINES */
-
 CPUState *cpu_copy(CPUState *env);
 
 void cpu_dump_state(CPUState *env, FILE *f, 
@@ -858,6 +787,7 @@
    exception, the write memory callback gets the ram offset instead of
    the physical address */
 #define IO_MEM_ROMD        (1)
+#define IO_MEM_SUBPAGE     (2)
 
 typedef void CPUWriteMemoryFunc(void *opaque, target_phys_addr_t addr, uint32_t value);
 typedef uint32_t CPUReadMemoryFunc(void *opaque, target_phys_addr_t addr);

Modified: trunk/src/host/qemu-neo1973/cpu-exec.c
===================================================================
--- trunk/src/host/qemu-neo1973/cpu-exec.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/cpu-exec.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -40,14 +40,14 @@
 //#define DEBUG_EXEC
 //#define DEBUG_SIGNAL
 
-#if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_M68K) || \
-    defined(TARGET_ALPHA)
-/* XXX: unify with i386 target */
 void cpu_loop_exit(void)
 {
+    /* NOTE: the register at this point must be saved by hand because
+       longjmp restore them */
+    regs_to_env();
     longjmp(env->jmp_env, 1);
 }
-#endif
+
 #if !(defined(TARGET_SPARC) || defined(TARGET_SH4) || defined(TARGET_M68K))
 #define reg_T2
 #endif
@@ -196,7 +196,9 @@
     cs_base = 0;
     pc = env->PC;
 #elif defined(TARGET_M68K)
-    flags = (env->fpcr & M68K_FPCR_PREC) | (env->sr & SR_S);
+    flags = (env->fpcr & M68K_FPCR_PREC)  /* Bit  6 */
+            | (env->sr & SR_S)            /* Bit  13 */
+            | ((env->macsr >> 4) & 0xf);  /* Bits 0-3 */
     cs_base = 0;
     pc = env->pc;
 #elif defined(TARGET_SH4)
@@ -247,65 +249,8 @@
     TranslationBlock *tb;
     uint8_t *tc_ptr;
 
-#if defined(TARGET_I386)
-    /* handle exit of HALTED state */
-    if (env1->hflags & HF_HALTED_MASK) {
-        /* disable halt condition */
-        if ((env1->interrupt_request & CPU_INTERRUPT_HARD) &&
-            (env1->eflags & IF_MASK)) {
-            env1->hflags &= ~HF_HALTED_MASK;
-        } else {
-            return EXCP_HALTED;
-        }
-    }
-#elif defined(TARGET_PPC)
-    if (env1->halted) {
-        if (env1->msr[MSR_EE] && 
-            (env1->interrupt_request & CPU_INTERRUPT_HARD)) {
-            env1->halted = 0;
-        } else {
-            return EXCP_HALTED;
-        }
-    }
-#elif defined(TARGET_SPARC)
-    if (env1->halted) {
-        if ((env1->interrupt_request & CPU_INTERRUPT_HARD) &&
-            (env1->psret != 0)) {
-            env1->halted = 0;
-        } else {
-            return EXCP_HALTED;
-        }
-    }
-#elif defined(TARGET_ARM)
-    if (env1->halted) {
-        /* An interrupt wakes the CPU even if the I and F CPSR bits are
-           set.  We use EXITTB to silently wake CPU without causing an
-           actual interrupt.  */
-        if (env1->interrupt_request &
-            (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB)) {
-            env1->halted = 0;
-        } else {
-            return EXCP_HALTED;
-        }
-    }
-#elif defined(TARGET_MIPS)
-    if (env1->halted) {
-        if (env1->interrupt_request &
-            (CPU_INTERRUPT_HARD | CPU_INTERRUPT_TIMER)) {
-            env1->halted = 0;
-        } else {
-            return EXCP_HALTED;
-        }
-    }
-#elif defined(TARGET_ALPHA) || defined(TARGET_M68K)
-    if (env1->halted) {
-        if (env1->interrupt_request & CPU_INTERRUPT_HARD) {
-            env1->halted = 0;
-        } else {
-            return EXCP_HALTED;
-        }
-    }
-#endif
+    if (cpu_halted(env1) == EXCP_HALTED)
+        return EXCP_HALTED;
 
     cpu_single_env = env1; 
 
@@ -318,28 +263,27 @@
     asm volatile ("mov %%i7, %0" : "=r" (saved_i7));
 #endif
 
-#if defined(TARGET_I386)
     env_to_regs();
+#if defined(TARGET_I386)
     /* put eflags in CPU temporary format */
     CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
     DF = 1 - (2 * ((env->eflags >> 10) & 1));
     CC_OP = CC_OP_EFLAGS;
     env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
-#elif defined(TARGET_ARM)
 #elif defined(TARGET_SPARC)
 #if defined(reg_REGWPTR)
     saved_regwptr = REGWPTR;
 #endif
-#elif defined(TARGET_PPC)
 #elif defined(TARGET_M68K)
     env->cc_op = CC_OP_FLAGS;
     env->cc_dest = env->sr & 0xf;
     env->cc_x = (env->sr >> 4) & 1;
+#elif defined(TARGET_ALPHA)
+#elif defined(TARGET_ARM)
+#elif defined(TARGET_PPC)
 #elif defined(TARGET_MIPS)
 #elif defined(TARGET_SH4)
     /* XXXXX */
-#elif defined(TARGET_ALPHA)
-    env_to_regs();
 #else
 #error unsupported target CPU
 #endif
@@ -577,32 +521,9 @@
                 }
 #ifdef DEBUG_EXEC
                 if ((loglevel & CPU_LOG_TB_CPU)) {
-#if defined(TARGET_I386)
                     /* restore flags in standard format */
-#ifdef reg_EAX
-                    env->regs[R_EAX] = EAX;
-#endif
-#ifdef reg_EBX
-                    env->regs[R_EBX] = EBX;
-#endif
-#ifdef reg_ECX
-                    env->regs[R_ECX] = ECX;
-#endif
-#ifdef reg_EDX
-                    env->regs[R_EDX] = EDX;
-#endif
-#ifdef reg_ESI
-                    env->regs[R_ESI] = ESI;
-#endif
-#ifdef reg_EDI
-                    env->regs[R_EDI] = EDI;
-#endif
-#ifdef reg_EBP
-                    env->regs[R_EBP] = EBP;
-#endif
-#ifdef reg_ESP
-                    env->regs[R_ESP] = ESP;
-#endif
+                    regs_to_env();
+#if defined(TARGET_I386)
                     env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
                     cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
                     env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
@@ -789,7 +710,7 @@
                     cpu_loop_exit();
                 }
 #endif
-            }
+            } /* for(;;) */
         } else {
             env_to_regs();
         }

Modified: trunk/src/host/qemu-neo1973/darwin-user/mmap.c
===================================================================
--- trunk/src/host/qemu-neo1973/darwin-user/mmap.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/darwin-user/mmap.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -199,7 +199,7 @@
 
     if (!(flags & MAP_FIXED)) {
 #if defined(__alpha__) || defined(__sparc__) || defined(__x86_64__)
-        /* tell the kenel to search at the same place as i386 */
+        /* tell the kernel to search at the same place as i386 */
         if (host_start == 0) {
             host_start = last_start;
             last_start += HOST_PAGE_ALIGN(len);

Modified: trunk/src/host/qemu-neo1973/disas.c
===================================================================
--- trunk/src/host/qemu-neo1973/disas.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/disas.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -134,7 +134,7 @@
 }
 #endif
 
-/* Disassemble this for me please... (debugging). 'flags' has teh following
+/* Disassemble this for me please... (debugging). 'flags' has the following
    values:
     i386 - nonzero means 16 bit code
     arm  - nonzero means thumb code 
@@ -308,8 +308,8 @@
 		continue;
 
 	    addr = sym[i].st_value;
-#ifdef TARGET_ARM
-            /* The bottom address bit marks a Thumb symbol.  */
+#if defined(TARGET_ARM) || defined (TARGET_MIPS)
+            /* The bottom address bit marks a Thumb or MIPS16 symbol.  */
             addr &= ~(target_ulong)1;
 #endif
 	    if (orig_addr >= addr

Modified: trunk/src/host/qemu-neo1973/exec.c
===================================================================
--- trunk/src/host/qemu-neo1973/exec.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/exec.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -48,6 +48,7 @@
 //#define DEBUG_TLB_CHECK 
 
 //#define DEBUG_IOPORT
+//#define DEBUG_SUBPAGE
 
 #if !defined(CONFIG_USER_ONLY)
 /* TB consistency checks only implemented for usermode emulation.  */
@@ -157,6 +158,14 @@
 static int tb_flush_count;
 static int tb_phys_invalidate_count;
 
+#define SUBPAGE_IDX(addr) ((addr) & ~TARGET_PAGE_MASK)
+typedef struct subpage_t {
+    target_phys_addr_t base;
+    CPUReadMemoryFunc **mem_read[TARGET_PAGE_SIZE];
+    CPUWriteMemoryFunc **mem_write[TARGET_PAGE_SIZE];
+    void *opaque[TARGET_PAGE_SIZE];
+} subpage_t;
+
 static void page_init(void)
 {
     /* NOTE: we can always suppose that qemu_host_page_size >=
@@ -1211,7 +1220,7 @@
     { CPU_LOG_EXEC, "exec",
       "show trace before each executed TB (lots of logs)" },
     { CPU_LOG_TB_CPU, "cpu",
-      "show CPU state before bloc translation" },
+      "show CPU state before block translation" },
 #ifdef TARGET_I386
     { CPU_LOG_PCALL, "pcall",
       "show protected mode far calls/returns/exceptions" },
@@ -1277,6 +1286,10 @@
     cpu_dump_state(env, stderr, fprintf, 0);
 #endif
     va_end(ap);
+    if (logfile) {
+        fflush(logfile);
+        fclose(logfile);
+    }
     abort();
 }
 
@@ -1898,6 +1911,30 @@
 }
 #endif /* defined(CONFIG_USER_ONLY) */
 
+static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
+                             int memory);
+static void *subpage_init (target_phys_addr_t base, uint32_t *phys,
+                           int orig_memory);
+#define CHECK_SUBPAGE(addr, start_addr, start_addr2, end_addr, end_addr2, \
+                      need_subpage)                                     \
+    do {                                                                \
+        if (addr > start_addr)                                          \
+            start_addr2 = 0;                                            \
+        else {                                                          \
+            start_addr2 = start_addr & ~TARGET_PAGE_MASK;               \
+            if (start_addr2 > 0)                                        \
+                need_subpage = 1;                                       \
+        }                                                               \
+                                                                        \
+        if ((start_addr + orig_size) - addr >= TARGET_PAGE_SIZE)        \
+            end_addr2 = TARGET_PAGE_SIZE - 1;                           \
+        else {                                                          \
+            end_addr2 = (start_addr + orig_size - 1) & ~TARGET_PAGE_MASK; \
+            if (end_addr2 < TARGET_PAGE_SIZE - 1)                       \
+                need_subpage = 1;                                       \
+        }                                                               \
+    } while (0)
+
 /* register physical memory. 'size' must be a multiple of the target
    page size. If (phys_offset & ~TARGET_PAGE_MASK) != 0, then it is an
    io memory page */
@@ -1908,15 +1945,56 @@
     target_phys_addr_t addr, end_addr;
     PhysPageDesc *p;
     CPUState *env;
+    unsigned long orig_size = size;
+    void *subpage;
 
     size = (size + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
-    end_addr = start_addr + size;
+    end_addr = start_addr + (target_phys_addr_t)size;
     for(addr = start_addr; addr != end_addr; addr += TARGET_PAGE_SIZE) {
-        p = phys_page_find_alloc(addr >> TARGET_PAGE_BITS, 1);
-        p->phys_offset = phys_offset;
-        if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM ||
-            (phys_offset & IO_MEM_ROMD))
-            phys_offset += TARGET_PAGE_SIZE;
+        p = phys_page_find(addr >> TARGET_PAGE_BITS);
+        if (p && p->phys_offset != IO_MEM_UNASSIGNED) {
+            unsigned long orig_memory = p->phys_offset;
+            target_phys_addr_t start_addr2, end_addr2;
+            int need_subpage = 0;
+
+            CHECK_SUBPAGE(addr, start_addr, start_addr2, end_addr, end_addr2,
+                          need_subpage);
+            if (need_subpage) {
+                if (!(orig_memory & IO_MEM_SUBPAGE)) {
+                    subpage = subpage_init((addr & TARGET_PAGE_MASK),
+                                           &p->phys_offset, orig_memory);
+                } else {
+                    subpage = io_mem_opaque[(orig_memory & ~TARGET_PAGE_MASK)
+                                            >> IO_MEM_SHIFT];
+                }
+                subpage_register(subpage, start_addr2, end_addr2, phys_offset);
+            } else {
+                p->phys_offset = phys_offset;
+                if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM ||
+                    (phys_offset & IO_MEM_ROMD))
+                    phys_offset += TARGET_PAGE_SIZE;
+            }
+        } else {
+            p = phys_page_find_alloc(addr >> TARGET_PAGE_BITS, 1);
+            p->phys_offset = phys_offset;
+            if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM ||
+                (phys_offset & IO_MEM_ROMD))
+                phys_offset += TARGET_PAGE_SIZE;
+            else {
+                target_phys_addr_t start_addr2, end_addr2;
+                int need_subpage = 0;
+
+                CHECK_SUBPAGE(addr, start_addr, start_addr2, end_addr,
+                              end_addr2, need_subpage);
+
+                if (need_subpage) {
+                    subpage = subpage_init((addr & TARGET_PAGE_MASK),
+                                           &p->phys_offset, IO_MEM_UNASSIGNED);
+                    subpage_register(subpage, start_addr2, end_addr2,
+                                     phys_offset);
+                }
+            }
+        }
     }
     
     /* since each CPU stores ram addresses in its TLB cache, we must
@@ -2158,6 +2236,149 @@
 };
 #endif
 
+static inline uint32_t subpage_readlen (subpage_t *mmio, target_phys_addr_t addr,
+                                 unsigned int len)
+{
+    CPUReadMemoryFunc **mem_read;
+    uint32_t ret;
+    unsigned int idx;
+
+    idx = SUBPAGE_IDX(addr - mmio->base);
+#if defined(DEBUG_SUBPAGE)
+    printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d\n", __func__,
+           mmio, len, addr, idx);
+#endif
+    mem_read = mmio->mem_read[idx];
+    ret = (*mem_read[len])(mmio->opaque[idx], addr);
+
+    return ret;
+}
+
+static inline void subpage_writelen (subpage_t *mmio, target_phys_addr_t addr,
+                              uint32_t value, unsigned int len)
+{
+    CPUWriteMemoryFunc **mem_write;
+    unsigned int idx;
+
+    idx = SUBPAGE_IDX(addr - mmio->base);
+#if defined(DEBUG_SUBPAGE)
+    printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d value %08x\n", __func__,
+           mmio, len, addr, idx, value);
+#endif
+    mem_write = mmio->mem_write[idx];
+    (*mem_write[len])(mmio->opaque[idx], addr, value);
+}
+
+static uint32_t subpage_readb (void *opaque, target_phys_addr_t addr)
+{
+#if defined(DEBUG_SUBPAGE)
+    printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
+#endif
+
+    return subpage_readlen(opaque, addr, 0);
+}
+
+static void subpage_writeb (void *opaque, target_phys_addr_t addr,
+                            uint32_t value)
+{
+#if defined(DEBUG_SUBPAGE)
+    printf("%s: addr " TARGET_FMT_plx " val %08x\n", __func__, addr, value);
+#endif
+    subpage_writelen(opaque, addr, value, 0);
+}
+
+static uint32_t subpage_readw (void *opaque, target_phys_addr_t addr)
+{
+#if defined(DEBUG_SUBPAGE)
+    printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
+#endif
+
+    return subpage_readlen(opaque, addr, 1);
+}
+
+static void subpage_writew (void *opaque, target_phys_addr_t addr,
+                            uint32_t value)
+{
+#if defined(DEBUG_SUBPAGE)
+    printf("%s: addr " TARGET_FMT_plx " val %08x\n", __func__, addr, value);
+#endif
+    subpage_writelen(opaque, addr, value, 1);
+}
+
+static uint32_t subpage_readl (void *opaque, target_phys_addr_t addr)
+{
+#if defined(DEBUG_SUBPAGE)
+    printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
+#endif
+
+    return subpage_readlen(opaque, addr, 2);
+}
+
+static void subpage_writel (void *opaque,
+                         target_phys_addr_t addr, uint32_t value)
+{
+#if defined(DEBUG_SUBPAGE)
+    printf("%s: addr " TARGET_FMT_plx " val %08x\n", __func__, addr, value);
+#endif
+    subpage_writelen(opaque, addr, value, 2);
+}
+
+static CPUReadMemoryFunc *subpage_read[] = {
+    &subpage_readb,
+    &subpage_readw,
+    &subpage_readl,
+};
+
+static CPUWriteMemoryFunc *subpage_write[] = {
+    &subpage_writeb,
+    &subpage_writew,
+    &subpage_writel,
+};
+
+static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
+                             int memory)
+{
+    int idx, eidx;
+
+    if (start >= TARGET_PAGE_SIZE || end >= TARGET_PAGE_SIZE)
+        return -1;
+    idx = SUBPAGE_IDX(start);
+    eidx = SUBPAGE_IDX(end);
+#if defined(DEBUG_SUBPAGE)
+    printf("%s: %p start %08x end %08x idx %08x eidx %08x mem %d\n", __func__,
+           mmio, start, end, idx, eidx, memory);
+#endif
+    memory >>= IO_MEM_SHIFT;
+    for (; idx <= eidx; idx++) {
+        mmio->mem_read[idx] = io_mem_read[memory];
+        mmio->mem_write[idx] = io_mem_write[memory];
+        mmio->opaque[idx] = io_mem_opaque[memory];
+    }
+
+    return 0;
+}
+
+static void *subpage_init (target_phys_addr_t base, uint32_t *phys,
+                           int orig_memory)
+{
+    subpage_t *mmio;
+    int subpage_memory;
+
+    mmio = qemu_mallocz(sizeof(subpage_t));
+    if (mmio != NULL) {
+        mmio->base = base;
+        subpage_memory = cpu_register_io_memory(0, subpage_read, subpage_write, mmio);
+#if defined(DEBUG_SUBPAGE)
+        printf("%s: %p base " TARGET_FMT_plx " len %08x %d\n", __func__,
+               mmio, base, TARGET_PAGE_SIZE, subpage_memory);
+#endif
+        *phys = subpage_memory | IO_MEM_SUBPAGE;
+        subpage_register(mmio, 0, TARGET_PAGE_SIZE - 1, orig_memory);
+    }
+
+    return mmio;
+}
+
 static void io_mem_init(void)
 {
     cpu_register_io_memory(IO_MEM_ROM >> IO_MEM_SHIFT, error_mem_read, unassigned_mem_write, NULL);

Modified: trunk/src/host/qemu-neo1973/fpu/softfloat.h
===================================================================
--- trunk/src/host/qemu-neo1973/fpu/softfloat.h	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/fpu/softfloat.h	2007-06-17 16:55:00 UTC (rev 2289)
@@ -242,8 +242,8 @@
 int float32_lt_quiet( float32, float32 STATUS_PARAM );
 int float32_compare( float32, float32 STATUS_PARAM );
 int float32_compare_quiet( float32, float32 STATUS_PARAM );
+int float32_is_nan( float32 );
 int float32_is_signaling_nan( float32 );
-int float64_is_nan( float64 a );
 
 INLINE float32 float32_abs(float32 a)
 {
@@ -293,6 +293,7 @@
 int float64_lt_quiet( float64, float64 STATUS_PARAM );
 int float64_compare( float64, float64 STATUS_PARAM );
 int float64_compare_quiet( float64, float64 STATUS_PARAM );
+int float64_is_nan( float64 a );
 int float64_is_signaling_nan( float64 );
 
 INLINE float64 float64_abs(float64 a)
@@ -336,6 +337,7 @@
 int floatx80_eq_signaling( floatx80, floatx80 STATUS_PARAM );
 int floatx80_le_quiet( floatx80, floatx80 STATUS_PARAM );
 int floatx80_lt_quiet( floatx80, floatx80 STATUS_PARAM );
+int floatx80_is_nan( floatx80 );
 int floatx80_is_signaling_nan( floatx80 );
 
 INLINE floatx80 floatx80_abs(floatx80 a)
@@ -383,6 +385,7 @@
 int float128_eq_signaling( float128, float128 STATUS_PARAM );
 int float128_le_quiet( float128, float128 STATUS_PARAM );
 int float128_lt_quiet( float128, float128 STATUS_PARAM );
+int float128_is_nan( float128 );
 int float128_is_signaling_nan( float128 );
 
 INLINE float128 float128_abs(float128 a)

Modified: trunk/src/host/qemu-neo1973/gdbstub.c
===================================================================
--- trunk/src/host/qemu-neo1973/gdbstub.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/gdbstub.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -549,41 +549,41 @@
     ptr = mem_buf;
     for (i = 0; i < 32; i++)
       {
-        *(uint32_t *)ptr = tswapl(env->gpr[i]);
-        ptr += 4;
+        *(target_ulong *)ptr = tswapl(env->gpr[i]);
+        ptr += sizeof(target_ulong);
       }
 
-    *(uint32_t *)ptr = tswapl(env->CP0_Status);
-    ptr += 4;
+    *(target_ulong *)ptr = tswapl(env->CP0_Status);
+    ptr += sizeof(target_ulong);
 
-    *(uint32_t *)ptr = tswapl(env->LO);
-    ptr += 4;
+    *(target_ulong *)ptr = tswapl(env->LO);
+    ptr += sizeof(target_ulong);
 
-    *(uint32_t *)ptr = tswapl(env->HI);
-    ptr += 4;
+    *(target_ulong *)ptr = tswapl(env->HI);
+    ptr += sizeof(target_ulong);
 
-    *(uint32_t *)ptr = tswapl(env->CP0_BadVAddr);
-    ptr += 4;
+    *(target_ulong *)ptr = tswapl(env->CP0_BadVAddr);
+    ptr += sizeof(target_ulong);
 
-    *(uint32_t *)ptr = tswapl(env->CP0_Cause);
-    ptr += 4;
+    *(target_ulong *)ptr = tswapl(env->CP0_Cause);
+    ptr += sizeof(target_ulong);
 
-    *(uint32_t *)ptr = tswapl(env->PC);
-    ptr += 4;
+    *(target_ulong *)ptr = tswapl(env->PC);
+    ptr += sizeof(target_ulong);
 
     if (env->CP0_Config1 & (1 << CP0C1_FP))
       {
         for (i = 0; i < 32; i++)
           {
-            *(uint32_t *)ptr = tswapl(env->fpr[i].fs[FP_ENDIAN_IDX]);
-            ptr += 4;
+            *(target_ulong *)ptr = tswapl(env->fpr[i].fs[FP_ENDIAN_IDX]);
+            ptr += sizeof(target_ulong);
           }
 
-        *(uint32_t *)ptr = tswapl(env->fcr31);
-        ptr += 4;
+        *(target_ulong *)ptr = tswapl(env->fcr31);
+        ptr += sizeof(target_ulong);
 
-        *(uint32_t *)ptr = tswapl(env->fcr0);
-        ptr += 4;
+        *(target_ulong *)ptr = tswapl(env->fcr0);
+        ptr += sizeof(target_ulong);
       }
 
     /* 32 FP registers, fsr, fir, fp.  Not yet implemented.  */
@@ -611,41 +611,41 @@
     ptr = mem_buf;
     for (i = 0; i < 32; i++)
       {
-        env->gpr[i] = tswapl(*(uint32_t *)ptr);
-        ptr += 4;
+        env->gpr[i] = tswapl(*(target_ulong *)ptr);
+        ptr += sizeof(target_ulong);
       }
 
-    env->CP0_Status = tswapl(*(uint32_t *)ptr);
-    ptr += 4;
+    env->CP0_Status = tswapl(*(target_ulong *)ptr);
+    ptr += sizeof(target_ulong);
 
-    env->LO = tswapl(*(uint32_t *)ptr);
-    ptr += 4;
+    env->LO = tswapl(*(target_ulong *)ptr);
+    ptr += sizeof(target_ulong);
 
-    env->HI = tswapl(*(uint32_t *)ptr);
-    ptr += 4;
+    env->HI = tswapl(*(target_ulong *)ptr);
+    ptr += sizeof(target_ulong);
 
-    env->CP0_BadVAddr = tswapl(*(uint32_t *)ptr);
-    ptr += 4;
+    env->CP0_BadVAddr = tswapl(*(target_ulong *)ptr);
+    ptr += sizeof(target_ulong);
 
-    env->CP0_Cause = tswapl(*(uint32_t *)ptr);
-    ptr += 4;
+    env->CP0_Cause = tswapl(*(target_ulong *)ptr);
+    ptr += sizeof(target_ulong);
 
-    env->PC = tswapl(*(uint32_t *)ptr);
-    ptr += 4;
+    env->PC = tswapl(*(target_ulong *)ptr);
+    ptr += sizeof(target_ulong);
 
     if (env->CP0_Config1 & (1 << CP0C1_FP))
       {
         for (i = 0; i < 32; i++)
           {
-            env->fpr[i].fs[FP_ENDIAN_IDX] = tswapl(*(uint32_t *)ptr);
-            ptr += 4;
+            env->fpr[i].fs[FP_ENDIAN_IDX] = tswapl(*(target_ulong *)ptr);
+            ptr += sizeof(target_ulong);
           }
 
-        env->fcr31 = tswapl(*(uint32_t *)ptr) & 0x0183FFFF;
-        ptr += 4;
+        env->fcr31 = tswapl(*(target_ulong *)ptr) & 0x0183FFFF;
+        ptr += sizeof(target_ulong);
 
-        env->fcr0 = tswapl(*(uint32_t *)ptr);
-        ptr += 4;
+        env->fcr0 = tswapl(*(target_ulong *)ptr);
+        ptr += sizeof(target_ulong);
 
         /* set rounding mode */
         RESTORE_ROUNDING_MODE;
@@ -908,8 +908,11 @@
         if (strncmp(p, "Offsets", 7) == 0) {
             TaskState *ts = env->opaque;
 
-            sprintf(buf, "Text=%x;Data=%x;Bss=%x", ts->info->code_offset,
-                ts->info->data_offset, ts->info->data_offset);
+            sprintf(buf,
+                    "Text=" TARGET_FMT_lx ";Data=" TARGET_FMT_lx ";Bss=" TARGET_FMT_lx,
+                    ts->info->code_offset,
+                    ts->info->data_offset,
+                    ts->info->data_offset);
             put_packet(s, buf);
             break;
         }
@@ -963,14 +966,16 @@
 
 /* Send a gdb syscall request.
    This accepts limited printf-style format specifiers, specifically:
-    %x - target_ulong argument printed in hex.
-    %s - string pointer (target_ulong) and length (int) pair.  */
+    %x  - target_ulong argument printed in hex.
+    %lx - 64-bit argument printed in hex.
+    %s  - string pointer (target_ulong) and length (int) pair.  */
 void gdb_do_syscall(gdb_syscall_complete_cb cb, char *fmt, ...)
 {
     va_list va;
     char buf[256];
     char *p;
     target_ulong addr;
+    uint64_t i64;
     GDBState *s;
 
     s = gdb_syscall_state;
@@ -993,11 +998,18 @@
                 addr = va_arg(va, target_ulong);
                 p += sprintf(p, TARGET_FMT_lx, addr);
                 break;
+            case 'l':
+                if (*(fmt++) != 'x')
+                    goto bad_format;
+                i64 = va_arg(va, uint64_t);
+                p += sprintf(p, "%" PRIx64, i64);
+                break;
             case 's':
                 addr = va_arg(va, target_ulong);
                 p += sprintf(p, TARGET_FMT_lx "/%x", addr, va_arg(va, int));
                 break;
             default:
+            bad_format:
                 fprintf(stderr, "gdbstub: Bad syscall format string '%s'\n",
                         fmt - 1);
                 break;

Modified: trunk/src/host/qemu-neo1973/hw/acpi.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/acpi.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/acpi.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -24,7 +24,6 @@
 #define PM_FREQ 3579545
 
 #define ACPI_DBG_IO_ADDR  0xb044
-#define SMB_IO_BASE       0xb100
 
 typedef struct PIIX4PMState {
     PCIDevice dev;
@@ -451,11 +450,10 @@
     return 0;
 }
 
-i2c_bus *piix4_pm_init(PCIBus *bus, int devfn)
+i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base)
 {
     PIIX4PMState *s;
     uint8_t *pci_conf;
-    uint32_t smb_io_base;
 
     s = (PIIX4PMState *)pci_register_device(bus,
                                          "PM", sizeof(PIIX4PMState),
@@ -486,7 +484,6 @@
     pci_conf[0x67] = (serial_hds[0] != NULL ? 0x08 : 0) |
 	(serial_hds[1] != NULL ? 0x90 : 0);
 
-    smb_io_base = SMB_IO_BASE;
     pci_conf[0x90] = smb_io_base | 1;
     pci_conf[0x91] = smb_io_base >> 8;
     pci_conf[0xd2] = 0x09;

Modified: trunk/src/host/qemu-neo1973/hw/an5206.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/an5206.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/an5206.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -40,7 +40,9 @@
     env = cpu_init();
     if (!cpu_model)
         cpu_model = "m5206";
-    cpu_m68k_set_model(env, cpu_model);
+    if (cpu_m68k_set_model(env, cpu_model)) {
+        cpu_abort(env, "Unable to find m68k CPU definition\n");
+    }
 
     /* Initialize CPU registers.  */
     env->vbr = 0;

Modified: trunk/src/host/qemu-neo1973/hw/apb_pci.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/apb_pci.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/apb_pci.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -206,13 +206,13 @@
     qemu_set_irq(pic[irq_num], level);
 }
 
-PCIBus *pci_apb_init(target_ulong special_base, target_ulong mem_base,
+PCIBus *pci_apb_init(target_phys_addr_t special_base,
+                     target_phys_addr_t mem_base,
                      qemu_irq *pic)
 {
     APBState *s;
     PCIDevice *d;
     int pci_mem_config, pci_mem_data, apb_config, pci_ioport;
-    PCIDevice *apb;
     PCIBus *secondary;
 
     s = qemu_mallocz(sizeof(APBState));

Modified: trunk/src/host/qemu-neo1973/hw/arm_gic.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/arm_gic.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/arm_gic.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -532,10 +532,10 @@
     if (base != 0xffffffff) {
         iomemtype = cpu_register_io_memory(0, gic_cpu_readfn,
                                            gic_cpu_writefn, s);
-        cpu_register_physical_memory(base, 0x00000fff, iomemtype);
+        cpu_register_physical_memory(base, 0x00001000, iomemtype);
         iomemtype = cpu_register_io_memory(0, gic_dist_readfn,
                                            gic_dist_writefn, s);
-        cpu_register_physical_memory(base + 0x1000, 0x00000fff, iomemtype);
+        cpu_register_physical_memory(base + 0x1000, 0x00001000, iomemtype);
         s->base = base;
     } else {
         s->base = 0;

Modified: trunk/src/host/qemu-neo1973/hw/arm_sysctl.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/arm_sysctl.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/arm_sysctl.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -202,7 +202,7 @@
     s->sys_id = sys_id;
     iomemtype = cpu_register_io_memory(0, arm_sysctl_readfn,
                                        arm_sysctl_writefn, s);
-    cpu_register_physical_memory(base, 0x00000fff, iomemtype);
+    cpu_register_physical_memory(base, 0x00001000, iomemtype);
     /* ??? Save/restore.  */
 }
 

Modified: trunk/src/host/qemu-neo1973/hw/arm_timer.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/arm_timer.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/arm_timer.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -233,7 +233,7 @@
     s->timer[1] = arm_timer_init(1000000, qi[1]);
     iomemtype = cpu_register_io_memory(0, sp804_readfn,
                                        sp804_writefn, s);
-    cpu_register_physical_memory(base, 0x00000fff, iomemtype);
+    cpu_register_physical_memory(base, 0x00001000, iomemtype);
     /* ??? Save/restore.  */
 }
 
@@ -301,7 +301,7 @@
 
     iomemtype = cpu_register_io_memory(0, icp_pit_readfn,
                                        icp_pit_writefn, s);
-    cpu_register_physical_memory(base, 0x00000fff, iomemtype);
+    cpu_register_physical_memory(base, 0x00001000, iomemtype);
     /* ??? Save/restore.  */
 }
 

Modified: trunk/src/host/qemu-neo1973/hw/cirrus_vga.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/cirrus_vga.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/cirrus_vga.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -2784,7 +2784,7 @@
 	case 0x09:
 	case 0x0c:
 	case 0x0d:
-	case 0x12:		/* veritcal display end */
+	case 0x12:		/* vertical display end */
 	    s->cr[s->cr_index] = val;
 	    break;
 

Modified: trunk/src/host/qemu-neo1973/hw/cs4231.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/cs4231.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/cs4231.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -30,6 +30,7 @@
  * In addition to Crystal CS4231 there is a DMA controller on Sparc.
  */
 #define CS_MAXADDR 0x3f
+#define CS_SIZE (CS_MAXADDR + 1)
 #define CS_REGS 16
 #define CS_DREGS 32
 #define CS_MAXDREG (CS_DREGS - 1)
@@ -173,7 +174,7 @@
         return;
 
     cs_io_memory = cpu_register_io_memory(0, cs_mem_read, cs_mem_write, s);
-    cpu_register_physical_memory(base, CS_MAXADDR, cs_io_memory);
+    cpu_register_physical_memory(base, CS_SIZE, cs_io_memory);
     register_savevm("cs4231", base, 1, cs_save, cs_load, s);
     qemu_register_reset(cs_reset, s);
     cs_reset(s);

Modified: trunk/src/host/qemu-neo1973/hw/cuda.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/cuda.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/cuda.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -445,9 +445,9 @@
             cuda_update_irq(s);
         } else {
             if (!(s->last_b & TIP)) {
-                /* handle end of host to cuda transfert */
+                /* handle end of host to cuda transfer */
                 packet_received = (s->data_out_index > 0);
-                /* always an IRQ at the end of transfert */
+                /* always an IRQ at the end of transfer */
                 s->ifr |= SR_INT;
                 cuda_update_irq(s);
             }

Modified: trunk/src/host/qemu-neo1973/hw/dma.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/dma.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/dma.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -383,7 +383,7 @@
 int DMA_read_memory (int nchan, void *buf, int pos, int len)
 {
     struct dma_regs *r = &dma_controllers[nchan > 3].regs[nchan & 3];
-    target_ulong addr = ((r->pageh & 0x7f) << 24) | (r->page << 16) | r->now[ADDR];
+    target_phys_addr_t addr = ((r->pageh & 0x7f) << 24) | (r->page << 16) | r->now[ADDR];
 
     if (r->mode & 0x20) {
         int i;
@@ -405,7 +405,7 @@
 int DMA_write_memory (int nchan, void *buf, int pos, int len)
 {
     struct dma_regs *r = &dma_controllers[nchan > 3].regs[nchan & 3];
-    target_ulong addr = ((r->pageh & 0x7f) << 24) | (r->page << 16) | r->now[ADDR];
+    target_phys_addr_t addr = ((r->pageh & 0x7f) << 24) | (r->page << 16) | r->now[ADDR];
 
     if (r->mode & 0x20) {
         int i;

Modified: trunk/src/host/qemu-neo1973/hw/ds1225y.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/ds1225y.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/ds1225y.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -33,7 +33,7 @@
 
 struct ds1225y_t
 {
-    target_ulong mem_base;
+    target_phys_addr_t mem_base;
     uint32_t capacity;
     const char *filename;
     QEMUFile *file;
@@ -99,7 +99,7 @@
 };
 
 /* Initialisation routine */
-ds1225y_t *ds1225y_init(target_ulong mem_base, const char *filename)
+ds1225y_t *ds1225y_init(target_phys_addr_t mem_base, const char *filename)
 {
     ds1225y_t *s;
     int mem_index1, mem_index2;

Modified: trunk/src/host/qemu-neo1973/hw/esp.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/esp.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/esp.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -41,7 +41,9 @@
 #define DPRINTF(fmt, args...)
 #endif
 
-#define ESP_MAXREG 0x3f
+#define ESP_MASK 0x3f
+#define ESP_REGS 16
+#define ESP_SIZE (ESP_REGS * 4)
 #define TI_BUFSZ 32
 /* The HBA is ID 7, so for simplicitly limit to 7 devices.  */
 #define ESP_MAX_DEVS      7
@@ -49,9 +51,10 @@
 typedef struct ESPState ESPState;
 
 struct ESPState {
+    qemu_irq irq;
     BlockDriverState **bd;
-    uint8_t rregs[ESP_MAXREG];
-    uint8_t wregs[ESP_MAXREG];
+    uint8_t rregs[ESP_REGS];
+    uint8_t wregs[ESP_REGS];
     int32_t ti_size;
     uint32_t ti_rptr, ti_wptr;
     uint8_t ti_buf[TI_BUFSZ];
@@ -124,7 +127,7 @@
 	s->rregs[4] = STAT_IN;
 	s->rregs[5] = INTR_DC;
 	s->rregs[6] = SEQ_0;
-	espdma_raise_irq(s->dma_opaque);
+	qemu_irq_raise(s->irq);
 	return 0;
     }
     s->current_dev = s->scsi_dev[target];
@@ -154,7 +157,7 @@
     }
     s->rregs[5] = INTR_BS | INTR_FC;
     s->rregs[6] = SEQ_CD;
-    espdma_raise_irq(s->dma_opaque);
+    qemu_irq_raise(s->irq);
 }
 
 static void handle_satn(ESPState *s)
@@ -176,7 +179,7 @@
         s->rregs[4] = STAT_IN | STAT_TC | STAT_CD;
         s->rregs[5] = INTR_BS | INTR_FC;
         s->rregs[6] = SEQ_CD;
-        espdma_raise_irq(s->dma_opaque);
+        qemu_irq_raise(s->irq);
     }
 }
 
@@ -196,7 +199,7 @@
 	s->ti_wptr = 0;
 	s->rregs[7] = 2;
     }
-    espdma_raise_irq(s->dma_opaque);
+    qemu_irq_raise(s->irq);
 }
 
 static void esp_dma_done(ESPState *s)
@@ -207,7 +210,7 @@
     s->rregs[7] = 0;
     s->rregs[0] = 0;
     s->rregs[1] = 0;
-    espdma_raise_irq(s->dma_opaque);
+    qemu_irq_raise(s->irq);
 }
 
 static void esp_do_dma(ESPState *s)
@@ -327,12 +330,12 @@
     }
 }
 
-void esp_reset(void *opaque)
+static void esp_reset(void *opaque)
 {
     ESPState *s = opaque;
 
-    memset(s->rregs, 0, ESP_MAXREG);
-    memset(s->wregs, 0, ESP_MAXREG);
+    memset(s->rregs, 0, ESP_REGS);
+    memset(s->wregs, 0, ESP_REGS);
     s->rregs[0x0e] = 0x4; // Indicate fas100a
     s->ti_size = 0;
     s->ti_rptr = 0;
@@ -346,7 +349,7 @@
     ESPState *s = opaque;
     uint32_t saddr;
 
-    saddr = (addr & ESP_MAXREG) >> 2;
+    saddr = (addr & ESP_MASK) >> 2;
     DPRINTF("read reg[%d]: 0x%2.2x\n", saddr, s->rregs[saddr]);
     switch (saddr) {
     case 2:
@@ -360,7 +363,7 @@
             } else {
                 s->rregs[2] = s->ti_buf[s->ti_rptr++];
             }
-            espdma_raise_irq(s->dma_opaque);
+            qemu_irq_raise(s->irq);
 	}
 	if (s->ti_size == 0) {
             s->ti_rptr = 0;
@@ -371,7 +374,7 @@
         // interrupt
         // Clear interrupt/error status bits
         s->rregs[4] &= ~(STAT_IN | STAT_GE | STAT_PE);
-	espdma_clear_irq(s->dma_opaque);
+	qemu_irq_lower(s->irq);
         break;
     default:
 	break;
@@ -384,7 +387,7 @@
     ESPState *s = opaque;
     uint32_t saddr;
 
-    saddr = (addr & ESP_MAXREG) >> 2;
+    saddr = (addr & ESP_MASK) >> 2;
     DPRINTF("write reg[%d]: 0x%2.2x -> 0x%2.2x\n", saddr, s->wregs[saddr], val);
     switch (saddr) {
     case 0:
@@ -434,7 +437,7 @@
 	    DPRINTF("Bus reset (%2.2x)\n", val);
 	    s->rregs[5] = INTR_RST;
             if (!(s->wregs[8] & 0x40)) {
-                espdma_raise_irq(s->dma_opaque);
+                qemu_irq_raise(s->irq);
             }
 	    break;
 	case 0x10:
@@ -501,8 +504,8 @@
 {
     ESPState *s = opaque;
 
-    qemu_put_buffer(f, s->rregs, ESP_MAXREG);
-    qemu_put_buffer(f, s->wregs, ESP_MAXREG);
+    qemu_put_buffer(f, s->rregs, ESP_REGS);
+    qemu_put_buffer(f, s->wregs, ESP_REGS);
     qemu_put_be32s(f, &s->ti_size);
     qemu_put_be32s(f, &s->ti_rptr);
     qemu_put_be32s(f, &s->ti_wptr);
@@ -523,8 +526,8 @@
     if (version_id != 3)
         return -EINVAL; // Cannot emulate 2
 
-    qemu_get_buffer(f, s->rregs, ESP_MAXREG);
-    qemu_get_buffer(f, s->wregs, ESP_MAXREG);
+    qemu_get_buffer(f, s->rregs, ESP_REGS);
+    qemu_get_buffer(f, s->wregs, ESP_REGS);
     qemu_get_be32s(f, &s->ti_size);
     qemu_get_be32s(f, &s->ti_rptr);
     qemu_get_be32s(f, &s->ti_wptr);
@@ -563,7 +566,7 @@
 }
 
 void *esp_init(BlockDriverState **bd, target_phys_addr_t espaddr,
-               void *dma_opaque)
+               void *dma_opaque, qemu_irq irq)
 {
     ESPState *s;
     int esp_io_memory;
@@ -573,10 +576,12 @@
         return NULL;
 
     s->bd = bd;
+    s->irq = irq;
     s->dma_opaque = dma_opaque;
+    sparc32_dma_set_reset_data(dma_opaque, esp_reset, s);
 
     esp_io_memory = cpu_register_io_memory(0, esp_mem_read, esp_mem_write, s);
-    cpu_register_physical_memory(espaddr, ESP_MAXREG*4, esp_io_memory);
+    cpu_register_physical_memory(espaddr, ESP_SIZE, esp_io_memory);
 
     esp_reset(s);
 

Modified: trunk/src/host/qemu-neo1973/hw/gt64xxx.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/gt64xxx.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/gt64xxx.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -23,9 +23,18 @@
  */
 
 #include "vl.h"
+
 typedef target_phys_addr_t pci_addr_t;
 #include "pci_host.h"
 
+//#define DEBUG
+
+#ifdef DEBUG
+#define dprintf(fmt, ...) fprintf(stderr, "%s: " fmt, __FUNCTION__, ##__VA_ARGS__)
+#else
+#define dprintf(fmt, ...)
+#endif
+
 #define GT_REGS			(0x1000 >> 2)
 
 /* CPU Configuration */
@@ -45,8 +54,6 @@
 #define GT_PCI0IOHD    		(0x050 >> 2)
 #define GT_PCI0M0LD    		(0x058 >> 2)
 #define GT_PCI0M0HD    		(0x060 >> 2)
-#define GT_ISD    		(0x068 >> 2)
-
 #define GT_PCI0M1LD    		(0x080 >> 2)
 #define GT_PCI0M1HD    		(0x088 >> 2)
 #define GT_PCI1IOLD    		(0x090 >> 2)
@@ -55,8 +62,7 @@
 #define GT_PCI1M0HD    		(0x0a8 >> 2)
 #define GT_PCI1M1LD    		(0x0b0 >> 2)
 #define GT_PCI1M1HD    		(0x0b8 >> 2)
-#define GT_PCI1M1LD    		(0x0b0 >> 2)
-#define GT_PCI1M1HD    		(0x0b8 >> 2)
+#define GT_ISD    		(0x068 >> 2)
 
 #define GT_SCS10AR    		(0x0d0 >> 2)
 #define GT_SCS32AR    		(0x0d8 >> 2)
@@ -330,6 +336,45 @@
 	/* Read-only registers, do nothing */
         break;
 
+    /* SDRAM and Device Address Decode */
+    case GT_SCS0LD:
+    case GT_SCS0HD:
+    case GT_SCS1LD:
+    case GT_SCS1HD:
+    case GT_SCS2LD:
+    case GT_SCS2HD:
+    case GT_SCS3LD:
+    case GT_SCS3HD:
+    case GT_CS0LD:
+    case GT_CS0HD:
+    case GT_CS1LD:
+    case GT_CS1HD:
+    case GT_CS2LD:
+    case GT_CS2HD:
+    case GT_CS3LD:
+    case GT_CS3HD:
+    case GT_BOOTLD:
+    case GT_BOOTHD:
+    case GT_ADERR:
+    /* SDRAM Configuration */
+    case GT_SDRAM_CFG:
+    case GT_SDRAM_OPMODE:
+    case GT_SDRAM_BM:
+    case GT_SDRAM_ADDRDECODE:
+        /* Accept and ignore SDRAM interleave configuration */
+        s->regs[saddr] = val;
+        break;
+
+    /* Device Parameters */
+    case GT_DEV_B0:
+    case GT_DEV_B1:
+    case GT_DEV_B2:
+    case GT_DEV_B3:
+    case GT_DEV_BOOT:
+        /* Not implemented */
+        dprintf ("Unimplemented device register offset 0x%x\n", saddr << 2);
+        break;
+
     /* ECC */
     case GT_ECC_ERRDATALO:
     case GT_ECC_ERRDATAHI:
@@ -339,18 +384,133 @@
         /* Read-only registers, do nothing */
         break;
 
+    /* DMA Record */
+    case GT_DMA0_CNT:
+    case GT_DMA1_CNT:
+    case GT_DMA2_CNT:
+    case GT_DMA3_CNT:
+    case GT_DMA0_SA:
+    case GT_DMA1_SA:
+    case GT_DMA2_SA:
+    case GT_DMA3_SA:
+    case GT_DMA0_DA:
+    case GT_DMA1_DA:
+    case GT_DMA2_DA:
+    case GT_DMA3_DA:
+    case GT_DMA0_NEXT:
+    case GT_DMA1_NEXT:
+    case GT_DMA2_NEXT:
+    case GT_DMA3_NEXT:
+    case GT_DMA0_CUR:
+    case GT_DMA1_CUR:
+    case GT_DMA2_CUR:
+    case GT_DMA3_CUR:
+        /* Not implemented */
+        dprintf ("Unimplemented DMA register offset 0x%x\n", saddr << 2);
+        break;
+
+    /* DMA Channel Control */
+    case GT_DMA0_CTRL:
+    case GT_DMA1_CTRL:
+    case GT_DMA2_CTRL:
+    case GT_DMA3_CTRL:
+        /* Not implemented */
+        dprintf ("Unimplemented DMA register offset 0x%x\n", saddr << 2);
+        break;
+
+    /* DMA Arbiter */
+    case GT_DMA_ARB:
+        /* Not implemented */
+        dprintf ("Unimplemented DMA register offset 0x%x\n", saddr << 2);
+        break;
+
+    /* Timer/Counter */
+    case GT_TC0:
+    case GT_TC1:
+    case GT_TC2:
+    case GT_TC3:
+    case GT_TC_CONTROL:
+        /* Not implemented */
+        dprintf ("Unimplemented timer register offset 0x%x\n", saddr << 2);
+        break;
+
     /* PCI Internal */
     case GT_PCI0_CMD:
     case GT_PCI1_CMD:
         s->regs[saddr] = val & 0x0401fc0f;
         break;
+    case GT_PCI0_TOR:
+    case GT_PCI0_BS_SCS10:
+    case GT_PCI0_BS_SCS32:
+    case GT_PCI0_BS_CS20:
+    case GT_PCI0_BS_CS3BT:
+    case GT_PCI1_IACK:
+    case GT_PCI0_IACK:
+    case GT_PCI0_BARE:
+    case GT_PCI0_PREFMBR:
+    case GT_PCI0_SCS10_BAR:
+    case GT_PCI0_SCS32_BAR:
+    case GT_PCI0_CS20_BAR:
+    case GT_PCI0_CS3BT_BAR:
+    case GT_PCI0_SSCS10_BAR:
+    case GT_PCI0_SSCS32_BAR:
+    case GT_PCI0_SCS3BT_BAR:
+    case GT_PCI1_TOR:
+    case GT_PCI1_BS_SCS10:
+    case GT_PCI1_BS_SCS32:
+    case GT_PCI1_BS_CS20:
+    case GT_PCI1_BS_CS3BT:
+    case GT_PCI1_BARE:
+    case GT_PCI1_PREFMBR:
+    case GT_PCI1_SCS10_BAR:
+    case GT_PCI1_SCS32_BAR:
+    case GT_PCI1_CS20_BAR:
+    case GT_PCI1_CS3BT_BAR:
+    case GT_PCI1_SSCS10_BAR:
+    case GT_PCI1_SSCS32_BAR:
+    case GT_PCI1_SCS3BT_BAR:
+    case GT_PCI1_CFGADDR:
+    case GT_PCI1_CFGDATA:
+        /* not implemented */
+        break;
     case GT_PCI0_CFGADDR:
         s->pci->config_reg = val & 0x80fffffc;
         break;
     case GT_PCI0_CFGDATA:
-        pci_host_data_writel(s->pci, 0, val);
+        if (s->pci->config_reg & (1u << 31))
+            pci_host_data_writel(s->pci, 0, val);
         break;
 
+    /* Interrupts */
+    case GT_INTRCAUSE:
+        /* not really implemented */
+        s->regs[saddr] = ~(~(s->regs[saddr]) | ~(val & 0xfffffffe));
+        s->regs[saddr] |= !!(s->regs[saddr] & 0xfffffffe);
+        dprintf("INTRCAUSE %x\n", val);
+        break;
+    case GT_INTRMASK:
+        s->regs[saddr] = val & 0x3c3ffffe;
+        dprintf("INTRMASK %x\n", val);
+        break;
+    case GT_PCI0_ICMASK:
+        s->regs[saddr] = val & 0x03fffffe;
+        dprintf("ICMASK %x\n", val);
+        break;
+    case GT_PCI0_SERR0MASK:
+        s->regs[saddr] = val & 0x0000003f;
+        dprintf("SERR0MASK %x\n", val);
+        break;
+
+    /* Reserved when only PCI_0 is configured. */
+    case GT_HINTRCAUSE:
+    case GT_CPU_INTSEL:
+    case GT_PCI0_INTSEL:
+    case GT_HINTRMASK:
+    case GT_PCI0_HICMASK:
+    case GT_PCI1_SERR1MASK:
+        /* not implemented */
+        break;
+
     /* SDRAM Parameters */
     case GT_SDRAM_B0:
     case GT_SDRAM_B1:
@@ -362,9 +522,7 @@
         break;
 
     default:
-#if 0
-        printf ("gt64120_writel: Bad register offset 0x%x\n", (int)addr);
-#endif
+        dprintf ("Bad register offset 0x%x\n", (int)addr);
         break;
     }
 }
@@ -420,6 +578,18 @@
         break;
 
     case GT_CPU:
+    case GT_SCS10LD:
+    case GT_SCS10HD:
+    case GT_SCS32LD:
+    case GT_SCS32HD:
+    case GT_CS20LD:
+    case GT_CS20HD:
+    case GT_CS3BOOTLD:
+    case GT_CS3BOOTHD:
+    case GT_SCS10AR:
+    case GT_SCS32AR:
+    case GT_CS20R:
+    case GT_CS3BOOTR:
     case GT_PCI0IOLD:
     case GT_PCI0M0LD:
     case GT_PCI0M1LD:
@@ -432,14 +602,13 @@
     case GT_PCI1IOHD:
     case GT_PCI1M0HD:
     case GT_PCI1M1HD:
-    case GT_PCI0_CMD:
-    case GT_PCI1_CMD:
     case GT_PCI0IOREMAP:
     case GT_PCI0M0REMAP:
     case GT_PCI0M1REMAP:
     case GT_PCI1IOREMAP:
     case GT_PCI1M0REMAP:
     case GT_PCI1M1REMAP:
+    case GT_ISD:
         val = s->regs[saddr];
         break;
     case GT_PCI0_IACK:
@@ -447,6 +616,37 @@
         val = pic_read_irq(isa_pic);
         break;
 
+    /* SDRAM and Device Address Decode */
+    case GT_SCS0LD:
+    case GT_SCS0HD:
+    case GT_SCS1LD:
+    case GT_SCS1HD:
+    case GT_SCS2LD:
+    case GT_SCS2HD:
+    case GT_SCS3LD:
+    case GT_SCS3HD:
+    case GT_CS0LD:
+    case GT_CS0HD:
+    case GT_CS1LD:
+    case GT_CS1HD:
+    case GT_CS2LD:
+    case GT_CS2HD:
+    case GT_CS3LD:
+    case GT_CS3HD:
+    case GT_BOOTLD:
+    case GT_BOOTHD:
+    case GT_ADERR:
+        val = s->regs[saddr];
+        break;
+
+    /* SDRAM Configuration */
+    case GT_SDRAM_CFG:
+    case GT_SDRAM_OPMODE:
+    case GT_SDRAM_BM:
+    case GT_SDRAM_ADDRDECODE:
+        val = s->regs[saddr];
+        break;
+
     /* SDRAM Parameters */
     case GT_SDRAM_B0:
     case GT_SDRAM_B1:
@@ -457,27 +657,146 @@
         val = s->regs[saddr];
         break;
 
+    /* Device Parameters */
+    case GT_DEV_B0:
+    case GT_DEV_B1:
+    case GT_DEV_B2:
+    case GT_DEV_B3:
+    case GT_DEV_BOOT:
+        val = s->regs[saddr];
+        break;
+
+    /* DMA Record */
+    case GT_DMA0_CNT:
+    case GT_DMA1_CNT:
+    case GT_DMA2_CNT:
+    case GT_DMA3_CNT:
+    case GT_DMA0_SA:
+    case GT_DMA1_SA:
+    case GT_DMA2_SA:
+    case GT_DMA3_SA:
+    case GT_DMA0_DA:
+    case GT_DMA1_DA:
+    case GT_DMA2_DA:
+    case GT_DMA3_DA:
+    case GT_DMA0_NEXT:
+    case GT_DMA1_NEXT:
+    case GT_DMA2_NEXT:
+    case GT_DMA3_NEXT:
+    case GT_DMA0_CUR:
+    case GT_DMA1_CUR:
+    case GT_DMA2_CUR:
+    case GT_DMA3_CUR:
+        val = s->regs[saddr];
+        break;
+
+    /* DMA Channel Control */
+    case GT_DMA0_CTRL:
+    case GT_DMA1_CTRL:
+    case GT_DMA2_CTRL:
+    case GT_DMA3_CTRL:
+        val = s->regs[saddr];
+        break;
+
+    /* DMA Arbiter */
+    case GT_DMA_ARB:
+        val = s->regs[saddr];
+        break;
+
+    /* Timer/Counter */
+    case GT_TC0:
+    case GT_TC1:
+    case GT_TC2:
+    case GT_TC3:
+    case GT_TC_CONTROL:
+        val = s->regs[saddr];
+        break;
+
     /* PCI Internal */
     case GT_PCI0_CFGADDR:
         val = s->pci->config_reg;
         break;
     case GT_PCI0_CFGDATA:
-        val = pci_host_data_readl(s->pci, 0);
+        if (!(s->pci->config_reg & (1u << 31)))
+            val = 0xffffffff;
+        else
+            val = pci_host_data_readl(s->pci, 0);
         break;
 
+    case GT_PCI0_CMD:
+    case GT_PCI0_TOR:
+    case GT_PCI0_BS_SCS10:
+    case GT_PCI0_BS_SCS32:
+    case GT_PCI0_BS_CS20:
+    case GT_PCI0_BS_CS3BT:
+    case GT_PCI1_IACK:
+    case GT_PCI0_BARE:
+    case GT_PCI0_PREFMBR:
+    case GT_PCI0_SCS10_BAR:
+    case GT_PCI0_SCS32_BAR:
+    case GT_PCI0_CS20_BAR:
+    case GT_PCI0_CS3BT_BAR:
+    case GT_PCI0_SSCS10_BAR:
+    case GT_PCI0_SSCS32_BAR:
+    case GT_PCI0_SCS3BT_BAR:
+    case GT_PCI1_CMD:
+    case GT_PCI1_TOR:
+    case GT_PCI1_BS_SCS10:
+    case GT_PCI1_BS_SCS32:
+    case GT_PCI1_BS_CS20:
+    case GT_PCI1_BS_CS3BT:
+    case GT_PCI1_BARE:
+    case GT_PCI1_PREFMBR:
+    case GT_PCI1_SCS10_BAR:
+    case GT_PCI1_SCS32_BAR:
+    case GT_PCI1_CS20_BAR:
+    case GT_PCI1_CS3BT_BAR:
+    case GT_PCI1_SSCS10_BAR:
+    case GT_PCI1_SSCS32_BAR:
+    case GT_PCI1_SCS3BT_BAR:
+    case GT_PCI1_CFGADDR:
+    case GT_PCI1_CFGDATA:
+        val = s->regs[saddr];
+        break;
+
+    /* Interrupts */
+    case GT_INTRCAUSE:
+        val = s->regs[saddr];
+        dprintf("INTRCAUSE %x\n", val);
+        break;
+    case GT_INTRMASK:
+        val = s->regs[saddr];
+        dprintf("INTRMASK %x\n", val);
+        break;
+    case GT_PCI0_ICMASK:
+        val = s->regs[saddr];
+        dprintf("ICMASK %x\n", val);
+        break;
+    case GT_PCI0_SERR0MASK:
+        val = s->regs[saddr];
+        dprintf("SERR0MASK %x\n", val);
+        break;
+
+    /* Reserved when only PCI_0 is configured. */
+    case GT_HINTRCAUSE:
+    case GT_CPU_INTSEL:
+    case GT_PCI0_INTSEL:
+    case GT_HINTRMASK:
+    case GT_PCI0_HICMASK:
+    case GT_PCI1_SERR1MASK:
+        val = s->regs[saddr];
+        break;
+
     default:
         val = s->regs[saddr];
-#if 0
-        printf ("gt64120_readl: Bad register offset 0x%x\n", (int)addr);
-#endif
+        dprintf ("Bad register offset 0x%x\n", (int)addr);
         break;
     }
 
 #ifdef TARGET_WORDS_BIGENDIAN
-    return bswap32(val);
-#else
+    val = bswap32(val);
+#endif
     return val;
-#endif
 }
 
 static CPUWriteMemoryFunc *gt64120_write[] = {
@@ -504,10 +823,10 @@
         return 3;
       /* AMD 79C973 Ethernet */
       case 11:
-        return 0;
+        return 1;
       /* Crystal 4281 Sound */
       case 12:
-        return 0;
+        return 2;
       /* PCI slot 1 to 4 */
       case 18 ... 21:
         return ((slot - 18) + irq_num) & 0x03;
@@ -546,19 +865,31 @@
 {
     GT64120State *s = opaque;
 
+    /* FIXME: Malta specific hw assumptions ahead */
+
     /* CPU Configuration */
 #ifdef TARGET_WORDS_BIGENDIAN
     s->regs[GT_CPU]           = 0x00000000;
 #else
     s->regs[GT_CPU]           = 0x00001000;
 #endif
-    s->regs[GT_MULTI]         = 0x00000000;
+    s->regs[GT_MULTI]         = 0x00000003;
 
-    /* CPU Address decode FIXME: not complete*/
+    /* CPU Address decode */
+    s->regs[GT_SCS10LD]       = 0x00000000;
+    s->regs[GT_SCS10HD]       = 0x00000007;
+    s->regs[GT_SCS32LD]       = 0x00000008;
+    s->regs[GT_SCS32HD]       = 0x0000000f;
+    s->regs[GT_CS20LD]        = 0x000000e0;
+    s->regs[GT_CS20HD]        = 0x00000070;
+    s->regs[GT_CS3BOOTLD]     = 0x000000f8;
+    s->regs[GT_CS3BOOTHD]     = 0x0000007f;
+
     s->regs[GT_PCI0IOLD]      = 0x00000080;
     s->regs[GT_PCI0IOHD]      = 0x0000000f;
     s->regs[GT_PCI0M0LD]      = 0x00000090;
     s->regs[GT_PCI0M0HD]      = 0x0000001f;
+    s->regs[GT_ISD]           = 0x000000a0;
     s->regs[GT_PCI0M1LD]      = 0x00000790;
     s->regs[GT_PCI0M1HD]      = 0x0000001f;
     s->regs[GT_PCI1IOLD]      = 0x00000100;
@@ -567,6 +898,12 @@
     s->regs[GT_PCI1M0HD]      = 0x0000001f;
     s->regs[GT_PCI1M1LD]      = 0x00000120;
     s->regs[GT_PCI1M1HD]      = 0x0000002f;
+
+    s->regs[GT_SCS10AR]       = 0x00000000;
+    s->regs[GT_SCS32AR]       = 0x00000008;
+    s->regs[GT_CS20R]         = 0x000000e0;
+    s->regs[GT_CS3BOOTR]      = 0x000000f8;
+
     s->regs[GT_PCI0IOREMAP]   = 0x00000080;
     s->regs[GT_PCI0M0REMAP]   = 0x00000090;
     s->regs[GT_PCI0M1REMAP]   = 0x00000790;
@@ -581,6 +918,43 @@
     s->regs[GT_CPUERR_DATAHI] = 0xffffffff;
     s->regs[GT_CPUERR_PARITY] = 0x000000ff;
 
+    /* CPU Sync Barrier */
+    s->regs[GT_PCI0SYNC]      = 0x00000000;
+    s->regs[GT_PCI1SYNC]      = 0x00000000;
+
+    /* SDRAM and Device Address Decode */
+    s->regs[GT_SCS0LD]        = 0x00000000;
+    s->regs[GT_SCS0HD]        = 0x00000007;
+    s->regs[GT_SCS1LD]        = 0x00000008;
+    s->regs[GT_SCS1HD]        = 0x0000000f;
+    s->regs[GT_SCS2LD]        = 0x00000010;
+    s->regs[GT_SCS2HD]        = 0x00000017;
+    s->regs[GT_SCS3LD]        = 0x00000018;
+    s->regs[GT_SCS3HD]        = 0x0000001f;
+    s->regs[GT_CS0LD]         = 0x000000c0;
+    s->regs[GT_CS0HD]         = 0x000000c7;
+    s->regs[GT_CS1LD]         = 0x000000c8;
+    s->regs[GT_CS1HD]         = 0x000000cf;
+    s->regs[GT_CS2LD]         = 0x000000d0;
+    s->regs[GT_CS2HD]         = 0x000000df;
+    s->regs[GT_CS3LD]         = 0x000000f0;
+    s->regs[GT_CS3HD]         = 0x000000fb;
+    s->regs[GT_BOOTLD]        = 0x000000fc;
+    s->regs[GT_BOOTHD]        = 0x000000ff;
+    s->regs[GT_ADERR]         = 0xffffffff;
+
+    /* SDRAM Configuration */
+    s->regs[GT_SDRAM_CFG]     = 0x00000200;
+    s->regs[GT_SDRAM_OPMODE]  = 0x00000000;
+    s->regs[GT_SDRAM_BM]      = 0x00000007;
+    s->regs[GT_SDRAM_ADDRDECODE] = 0x00000002;
+
+    /* SDRAM Parameters */
+    s->regs[GT_SDRAM_B0]      = 0x00000005;
+    s->regs[GT_SDRAM_B1]      = 0x00000005;
+    s->regs[GT_SDRAM_B2]      = 0x00000005;
+    s->regs[GT_SDRAM_B3]      = 0x00000005;
+
     /* ECC */
     s->regs[GT_ECC_ERRDATALO] = 0x00000000;
     s->regs[GT_ECC_ERRDATAHI] = 0x00000000;
@@ -588,23 +962,70 @@
     s->regs[GT_ECC_CALC]      = 0x00000000;
     s->regs[GT_ECC_ERRADDR]   = 0x00000000;
 
-    /* SDRAM Parameters */
-    s->regs[GT_SDRAM_B0]      = 0x00000005;    
-    s->regs[GT_SDRAM_B1]      = 0x00000005;    
-    s->regs[GT_SDRAM_B2]      = 0x00000005;    
-    s->regs[GT_SDRAM_B3]      = 0x00000005;    
+    /* Device Parameters */
+    s->regs[GT_DEV_B0]        = 0x386fffff;
+    s->regs[GT_DEV_B1]        = 0x386fffff;
+    s->regs[GT_DEV_B2]        = 0x386fffff;
+    s->regs[GT_DEV_B3]        = 0x386fffff;
+    s->regs[GT_DEV_BOOT]      = 0x146fffff;
 
-    /* PCI Internal FIXME: not complete*/
+    /* DMA registers are all zeroed at reset */
+
+    /* Timer/Counter */
+    s->regs[GT_TC0]           = 0xffffffff;
+    s->regs[GT_TC1]           = 0x00ffffff;
+    s->regs[GT_TC2]           = 0x00ffffff;
+    s->regs[GT_TC3]           = 0x00ffffff;
+    s->regs[GT_TC_CONTROL]    = 0x00000000;
+
+    /* PCI Internal */
 #ifdef TARGET_WORDS_BIGENDIAN
     s->regs[GT_PCI0_CMD]      = 0x00000000;
+#else
+    s->regs[GT_PCI0_CMD]      = 0x00010001;
+#endif
+    s->regs[GT_PCI0_TOR]      = 0x0000070f;
+    s->regs[GT_PCI0_BS_SCS10] = 0x00fff000;
+    s->regs[GT_PCI0_BS_SCS32] = 0x00fff000;
+    s->regs[GT_PCI0_BS_CS20]  = 0x01fff000;
+    s->regs[GT_PCI0_BS_CS3BT] = 0x00fff000;
+    s->regs[GT_PCI1_IACK]     = 0x00000000;
+    s->regs[GT_PCI0_IACK]     = 0x00000000;
+    s->regs[GT_PCI0_BARE]     = 0x0000000f;
+    s->regs[GT_PCI0_PREFMBR]  = 0x00000040;
+    s->regs[GT_PCI0_SCS10_BAR] = 0x00000000;
+    s->regs[GT_PCI0_SCS32_BAR] = 0x01000000;
+    s->regs[GT_PCI0_CS20_BAR] = 0x1c000000;
+    s->regs[GT_PCI0_CS3BT_BAR] = 0x1f000000;
+    s->regs[GT_PCI0_SSCS10_BAR] = 0x00000000;
+    s->regs[GT_PCI0_SSCS32_BAR] = 0x01000000;
+    s->regs[GT_PCI0_SCS3BT_BAR] = 0x1f000000;
+#ifdef TARGET_WORDS_BIGENDIAN
     s->regs[GT_PCI1_CMD]      = 0x00000000;
 #else
-    s->regs[GT_PCI0_CMD]      = 0x00010001;
     s->regs[GT_PCI1_CMD]      = 0x00010001;
 #endif
-    s->regs[GT_PCI0_IACK]     = 0x00000000;
-    s->regs[GT_PCI1_IACK]     = 0x00000000;
+    s->regs[GT_PCI1_TOR]      = 0x0000070f;
+    s->regs[GT_PCI1_BS_SCS10] = 0x00fff000;
+    s->regs[GT_PCI1_BS_SCS32] = 0x00fff000;
+    s->regs[GT_PCI1_BS_CS20]  = 0x01fff000;
+    s->regs[GT_PCI1_BS_CS3BT] = 0x00fff000;
+    s->regs[GT_PCI1_BARE]     = 0x0000000f;
+    s->regs[GT_PCI1_PREFMBR]  = 0x00000040;
+    s->regs[GT_PCI1_SCS10_BAR] = 0x00000000;
+    s->regs[GT_PCI1_SCS32_BAR] = 0x01000000;
+    s->regs[GT_PCI1_CS20_BAR] = 0x1c000000;
+    s->regs[GT_PCI1_CS3BT_BAR] = 0x1f000000;
+    s->regs[GT_PCI1_SSCS10_BAR] = 0x00000000;
+    s->regs[GT_PCI1_SSCS32_BAR] = 0x01000000;
+    s->regs[GT_PCI1_SCS3BT_BAR] = 0x1f000000;
+    s->regs[GT_PCI1_CFGADDR]  = 0x00000000;
+    s->regs[GT_PCI1_CFGDATA]  = 0x00000000;
+    s->regs[GT_PCI0_CFGADDR]  = 0x00000000;
+    s->regs[GT_PCI0_CFGDATA]  = 0x00000000;
 
+    /* Interrupt registers are all zeroed at reset */
+
     gt64120_pci_mapping(s);
 }
 
@@ -626,6 +1047,25 @@
     pci_default_write_config(d, address, val, len);
 }
 
+static void gt64120_save(QEMUFile* f, void *opaque)
+{
+    PCIDevice *d = opaque;
+    pci_device_save(d, f);
+}
+
+static int gt64120_load(QEMUFile* f, void *opaque, int version_id)
+{
+    PCIDevice *d = opaque;
+    int ret;
+
+    if (version_id != 1)
+        return -EINVAL;
+    ret = pci_device_load(d, f);
+    if (ret < 0)
+        return ret;
+    return 0;
+}
+
 PCIBus *pci_gt64120_init(qemu_irq *pic)
 {
     GT64120State *s;
@@ -646,28 +1086,34 @@
     d = pci_register_device(s->pci->bus, "GT64120 PCI Bus", sizeof(PCIDevice),
                             0, gt64120_read_config, gt64120_write_config);
 
+    /* FIXME: Malta specific hw assumptions ahead */
+
     d->config[0x00] = 0xab; // vendor_id
     d->config[0x01] = 0x11;
     d->config[0x02] = 0x20; // device_id
     d->config[0x03] = 0x46;
-    d->config[0x04] = 0x06;
+
+    d->config[0x04] = 0x00;
     d->config[0x05] = 0x00;
     d->config[0x06] = 0x80;
-    d->config[0x07] = 0xa2;
+    d->config[0x07] = 0x02;
+
     d->config[0x08] = 0x10;
     d->config[0x09] = 0x00;
-    d->config[0x0A] = 0x80;
-    d->config[0x0B] = 0x05;
-    d->config[0x0C] = 0x08;
-    d->config[0x0D] = 0x40;
-    d->config[0x0E] = 0x00;
-    d->config[0x0F] = 0x00;
-    d->config[0x17] = 0x08;
+    d->config[0x0A] = 0x00;
+    d->config[0x0B] = 0x06;
+
+    d->config[0x10] = 0x08;
+    d->config[0x14] = 0x08;
+    d->config[0x17] = 0x01;
     d->config[0x1B] = 0x1c;
     d->config[0x1F] = 0x1f;
     d->config[0x23] = 0x14;
+    d->config[0x24] = 0x01;
     d->config[0x27] = 0x14;
     d->config[0x3D] = 0x01;
 
+    register_savevm("GT64120 PCI Bus", 0, 1, gt64120_save, gt64120_load, d);
+
     return s->pci->bus;
 }

Modified: trunk/src/host/qemu-neo1973/hw/ide.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/ide.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/ide.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -376,6 +376,7 @@
 
 #define IDE_TYPE_PIIX3   0
 #define IDE_TYPE_CMD646  1
+#define IDE_TYPE_PIIX4   2
 
 /* CMD646 specific */
 #define MRDMODE		0x71
@@ -2875,6 +2876,44 @@
     register_savevm("ide", 0, 1, pci_ide_save, pci_ide_load, d);
 }
 
+/* hd_table must contain 4 block drivers */
+/* NOTE: for the PIIX4, the IRQs and IOports are hardcoded */
+void pci_piix4_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn,
+                        qemu_irq *pic)
+{
+    PCIIDEState *d;
+    uint8_t *pci_conf;
+
+    /* register a function 1 of PIIX4 */
+    d = (PCIIDEState *)pci_register_device(bus, "PIIX4 IDE",
+                                           sizeof(PCIIDEState),
+                                           devfn,
+                                           NULL, NULL);
+    d->type = IDE_TYPE_PIIX4;
+
+    pci_conf = d->dev.config;
+    pci_conf[0x00] = 0x86; // Intel
+    pci_conf[0x01] = 0x80;
+    pci_conf[0x02] = 0x11;
+    pci_conf[0x03] = 0x71;
+    pci_conf[0x09] = 0x80; // legacy ATA mode
+    pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
+    pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
+    pci_conf[0x0e] = 0x00; // header_type
+
+    piix3_reset(d);
+
+    pci_register_io_region((PCIDevice *)d, 4, 0x10,
+                           PCI_ADDRESS_SPACE_IO, bmdma_map);
+
+    ide_init2(&d->ide_if[0], hd_table[0], hd_table[1], pic[14]);
+    ide_init2(&d->ide_if[2], hd_table[2], hd_table[3], pic[15]);
+    ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
+    ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
+
+    register_savevm("ide", 0, 1, pci_ide_save, pci_ide_load, d);
+}
+
 /***********************************************************/
 /* MacIO based PowerPC IDE */
 

Modified: trunk/src/host/qemu-neo1973/hw/integratorcp.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/integratorcp.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/integratorcp.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -257,7 +257,7 @@
 
     iomemtype = cpu_register_io_memory(0, integratorcm_readfn,
                                        integratorcm_writefn, s);
-    cpu_register_physical_memory(0x10000000, 0x007fffff, iomemtype);
+    cpu_register_physical_memory(0x10000000, 0x00800000, iomemtype);
     integratorcm_do_remap(s, 1);
     /* ??? Save/restore.  */
 }
@@ -390,7 +390,7 @@
     s->parent_fiq = parent_fiq;
     iomemtype = cpu_register_io_memory(0, icp_pic_readfn,
                                        icp_pic_writefn, s);
-    cpu_register_physical_memory(base, 0x007fffff, iomemtype);
+    cpu_register_physical_memory(base, 0x00800000, iomemtype);
     /* ??? Save/restore.  */
     return qi;
 }
@@ -454,7 +454,7 @@
     s = (icp_control_state *)qemu_mallocz(sizeof(icp_control_state));
     iomemtype = cpu_register_io_memory(0, icp_control_readfn,
                                        icp_control_writefn, s);
-    cpu_register_physical_memory(base, 0x007fffff, iomemtype);
+    cpu_register_physical_memory(base, 0x00800000, iomemtype);
     s->base = base;
     /* ??? Save/restore.  */
 }
@@ -500,6 +500,9 @@
         if (nd_table[0].model == NULL
             || strcmp(nd_table[0].model, "smc91c111") == 0) {
             smc91c111_init(&nd_table[0], 0xc8000000, pic[27]);
+        } else if (strcmp(nd_table[0].model, "?") == 0) {
+            fprintf(stderr, "qemu: Supported NICs: smc91c111\n");
+            exit (1);
         } else {
             fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
             exit (1);

Modified: trunk/src/host/qemu-neo1973/hw/mcf5206.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/mcf5206.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/mcf5206.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -139,285 +139,12 @@
     return s;
 }
 
-/* UART */
-
-typedef struct {
-    uint8_t mr[2];
-    uint8_t sr;
-    uint8_t isr;
-    uint8_t imr;
-    uint8_t bg1;
-    uint8_t bg2;
-    uint8_t fifo[4];
-    uint8_t tb;
-    int current_mr;
-    int fifo_len;
-    int tx_enabled;
-    int rx_enabled;
-    qemu_irq irq;
-    CharDriverState *chr;
-} m5206_uart_state;
-
-/* UART Status Register bits.  */
-#define M5206_UART_RxRDY  0x01
-#define M5206_UART_FFULL  0x02
-#define M5206_UART_TxRDY  0x04
-#define M5206_UART_TxEMP  0x08
-#define M5206_UART_OE     0x10
-#define M5206_UART_PE     0x20
-#define M5206_UART_FE     0x40
-#define M5206_UART_RB     0x80
-
-/* Interrupt flags.  */
-#define M5206_UART_TxINT  0x01
-#define M5206_UART_RxINT  0x02
-#define M5206_UART_DBINT  0x04
-#define M5206_UART_COSINT 0x80
-
-/* UMR1 flags.  */
-#define M5206_UART_BC0    0x01
-#define M5206_UART_BC1    0x02
-#define M5206_UART_PT     0x04
-#define M5206_UART_PM0    0x08
-#define M5206_UART_PM1    0x10
-#define M5206_UART_ERR    0x20
-#define M5206_UART_RxIRQ  0x40
-#define M5206_UART_RxRTS  0x80
-
-static void m5206_uart_update(m5206_uart_state *s)
-{
-    s->isr &= ~(M5206_UART_TxINT | M5206_UART_RxINT);
-    if (s->sr & M5206_UART_TxRDY)
-        s->isr |= M5206_UART_TxINT;
-    if ((s->sr & ((s->mr[0] & M5206_UART_RxIRQ)
-                  ? M5206_UART_FFULL : M5206_UART_RxRDY)) != 0)
-        s->isr |= M5206_UART_RxINT;
-
-    qemu_set_irq(s->irq, (s->isr & s->imr) != 0);
-}
-
-static uint32_t m5206_uart_read(m5206_uart_state *s, uint32_t addr)
-{
-    switch (addr) {
-    case 0x00:
-        return s->mr[s->current_mr];
-    case 0x04:
-        return s->sr;
-    case 0x0c:
-        {
-            uint8_t val;
-            int i;
-
-            if (s->fifo_len == 0)
-                return 0;
-
-            val = s->fifo[0];
-            s->fifo_len--;
-            for (i = 0; i < s->fifo_len; i++)
-                s->fifo[i] = s->fifo[i + 1];
-            s->sr &= ~M5206_UART_FFULL;
-            if (s->fifo_len == 0)
-                s->sr &= ~M5206_UART_RxRDY;
-            m5206_uart_update(s);
-            return val;
-        }
-    case 0x10:
-        /* TODO: Implement IPCR.  */
-        return 0;
-    case 0x14:
-        return s->isr;
-    case 0x18:
-        return s->bg1;
-    case 0x1c:
-        return s->bg2;
-    default:
-        return 0;
-    }
-}
-
-/* Update TxRDY flag and set data if present and enabled.  */
-static void m5206_uart_do_tx(m5206_uart_state *s)
-{
-    if (s->tx_enabled && (s->sr & M5206_UART_TxEMP) == 0) {
-        if (s->chr)
-            qemu_chr_write(s->chr, (unsigned char *)&s->tb, 1);
-        s->sr |= M5206_UART_TxEMP;
-    }
-    if (s->tx_enabled) {
-        s->sr |= M5206_UART_TxRDY;
-    } else {
-        s->sr &= ~M5206_UART_TxRDY;
-    }
-}
-
-static void m5206_do_command(m5206_uart_state *s, uint8_t cmd)
-{
-    /* Misc command.  */
-    switch ((cmd >> 4) & 3) {
-    case 0: /* No-op.  */
-        break;
-    case 1: /* Reset mode register pointer.  */
-        s->current_mr = 0;
-        break;
-    case 2: /* Reset receiver.  */
-        s->rx_enabled = 0;
-        s->fifo_len = 0;
-        s->sr &= ~(M5206_UART_RxRDY | M5206_UART_FFULL);
-        break;
-    case 3: /* Reset transmitter.  */
-        s->tx_enabled = 0;
-        s->sr |= M5206_UART_TxEMP;
-        s->sr &= ~M5206_UART_TxRDY;
-        break;
-    case 4: /* Reset error status.  */
-        break;
-    case 5: /* Reset break-change interrupt.  */
-        s->isr &= ~M5206_UART_DBINT;
-        break;
-    case 6: /* Start break.  */
-    case 7: /* Stop break.  */
-        break;
-    }
-
-    /* Transmitter command.  */
-    switch ((cmd >> 2) & 3) {
-    case 0: /* No-op.  */
-        break;
-    case 1: /* Enable.  */
-        s->tx_enabled = 1;
-        m5206_uart_do_tx(s);
-        break;
-    case 2: /* Disable.  */
-        s->tx_enabled = 0;
-        m5206_uart_do_tx(s);
-        break;
-    case 3: /* Reserved.  */
-        fprintf(stderr, "m5206_uart: Bad TX command\n");
-        break;
-    }
-
-    /* Receiver command.  */
-    switch (cmd & 3) {
-    case 0: /* No-op.  */
-        break;
-    case 1: /* Enable.  */
-        s->rx_enabled = 1;
-        break;
-    case 2:
-        s->rx_enabled = 0;
-        break;
-    case 3: /* Reserved.  */
-        fprintf(stderr, "m5206_uart: Bad RX command\n");
-        break;
-    }
-}
-
-static void m5206_uart_write(m5206_uart_state *s, uint32_t addr, uint32_t val)
-{
-    switch (addr) {
-    case 0x00:
-        s->mr[s->current_mr] = val;
-        s->current_mr = 1;
-        break;
-    case 0x04:
-        /* CSR is ignored.  */
-        break;
-    case 0x08: /* Command Register.  */
-        m5206_do_command(s, val);
-        break;
-    case 0x0c: /* Transmit Buffer.  */
-        s->sr &= ~M5206_UART_TxEMP;
-        s->tb = val;
-        m5206_uart_do_tx(s);
-        break;
-    case 0x10:
-        /* ACR is ignored.  */
-        break;
-    case 0x14:
-        s->imr = val;
-        break;
-    default:
-        break;
-    }
-    m5206_uart_update(s);
-}
-
-static void m5206_uart_reset(m5206_uart_state *s)
-{
-    s->fifo_len = 0;
-    s->mr[0] = 0;
-    s->mr[1] = 0;
-    s->sr = M5206_UART_TxEMP;
-    s->tx_enabled = 0;
-    s->rx_enabled = 0;
-    s->isr = 0;
-    s->imr = 0;
-}
-
-static void m5206_uart_push_byte(m5206_uart_state *s, uint8_t data)
-{
-    /* Break events overwrite the last byte if the fifo is full.  */
-    if (s->fifo_len == 4)
-        s->fifo_len--;
-
-    s->fifo[s->fifo_len] = data;
-    s->fifo_len++;
-    s->sr |= M5206_UART_RxRDY;
-    if (s->fifo_len == 4)
-        s->sr |= M5206_UART_FFULL;
-
-    m5206_uart_update(s);
-}
-
-static void m5206_uart_event(void *opaque, int event)
-{
-    m5206_uart_state *s = (m5206_uart_state *)opaque;
-
-    switch (event) {
-    case CHR_EVENT_BREAK:
-        s->isr |= M5206_UART_DBINT;
-        m5206_uart_push_byte(s, 0);
-        break;
-    default:
-        break;
-    }
-}
-
-static int m5206_uart_can_receive(void *opaque)
-{
-    m5206_uart_state *s = (m5206_uart_state *)opaque;
-
-    return s->rx_enabled && (s->sr & M5206_UART_FFULL) == 0;
-}
-
-static void m5206_uart_receive(void *opaque, const uint8_t *buf, int size)
-{
-    m5206_uart_state *s = (m5206_uart_state *)opaque;
-
-    m5206_uart_push_byte(s, buf[0]);
-}
-
-static m5206_uart_state *m5206_uart_init(qemu_irq irq, CharDriverState *chr)
-{
-    m5206_uart_state *s;
-
-    s = qemu_mallocz(sizeof(m5206_uart_state));
-    s->chr = chr;
-    s->irq = irq;
-    if (chr) {
-        qemu_chr_add_handlers(chr, m5206_uart_can_receive, m5206_uart_receive,
-                              m5206_uart_event, s);
-    }
-    m5206_uart_reset(s);
-    return s;
-}
-
 /* System Integration Module.  */
 
 typedef struct {
     CPUState *env;
     m5206_timer_state *timer[2];
-    m5206_uart_state *uart[2];
+    void *uart[2];
     uint8_t scr;
     uint8_t icr[14];
     uint16_t imr; /* 1 == interrupt is masked.  */
@@ -540,9 +267,9 @@
     } else if (offset >= 0x120 && offset < 0x140) {
         return m5206_timer_read(s->timer[1], offset - 0x120);
     } else if (offset >= 0x140 && offset < 0x160) {
-        return m5206_uart_read(s->uart[0], offset - 0x140);
+        return mcf_uart_read(s->uart[0], offset - 0x140);
     } else if (offset >= 0x180 && offset < 0x1a0) {
-        return m5206_uart_read(s->uart[1], offset - 0x180);
+        return mcf_uart_read(s->uart[1], offset - 0x180);
     }
     switch (offset) {
     case 0x03: return s->scr;
@@ -580,10 +307,10 @@
         m5206_timer_write(s->timer[1], offset - 0x120, value);
         return;
     } else if (offset >= 0x140 && offset < 0x160) {
-        m5206_uart_write(s->uart[0], offset - 0x140, value);
+        mcf_uart_write(s->uart[0], offset - 0x140, value);
         return;
     } else if (offset >= 0x180 && offset < 0x1a0) {
-        m5206_uart_write(s->uart[1], offset - 0x180, value);
+        mcf_uart_write(s->uart[1], offset - 0x180, value);
         return;
     }
     switch (offset) {
@@ -798,13 +525,13 @@
     s = (m5206_mbar_state *)qemu_mallocz(sizeof(m5206_mbar_state));
     iomemtype = cpu_register_io_memory(0, m5206_mbar_readfn,
                                        m5206_mbar_writefn, s);
-    cpu_register_physical_memory(base, 0x00000fff, iomemtype);
+    cpu_register_physical_memory(base, 0x00001000, iomemtype);
 
     pic = qemu_allocate_irqs(m5206_mbar_set_irq, s, 14);
     s->timer[0] = m5206_timer_init(pic[9]);
     s->timer[1] = m5206_timer_init(pic[10]);
-    s->uart[0] = m5206_uart_init(pic[12], serial_hds[0]);
-    s->uart[1] = m5206_uart_init(pic[13], serial_hds[1]);
+    s->uart[0] = mcf_uart_init(pic[12], serial_hds[0]);
+    s->uart[1] = mcf_uart_init(pic[13], serial_hds[1]);
     s->env = env;
 
     m5206_mbar_reset(s);

Modified: trunk/src/host/qemu-neo1973/hw/mips_malta.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/mips_malta.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/mips_malta.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -42,7 +42,7 @@
 #define ENVP_NB_ENTRIES	 	16
 #define ENVP_ENTRY_SIZE	 	256
 
-
+extern int nographic;
 extern FILE *logfile;
 
 typedef struct {
@@ -67,16 +67,18 @@
     int i;
     MaltaFPGAState *s = opaque;
 
-    for (i = 7 ; i >= 0 ; i--) {
-        if (s->leds & (1 << i))
-            leds_text[i] = '#';
-	else
-            leds_text[i] = ' ';
+    if (!nographic) {
+        for (i = 7 ; i >= 0 ; i--) {
+            if (s->leds & (1 << i))
+                leds_text[i] = '#';
+            else
+                leds_text[i] = ' ';
+        }
+        leds_text[8] = '\0';
+
+        qemu_chr_printf(s->display, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", leds_text);
+        qemu_chr_printf(s->display, "\n\n\n\n|\e[31m%-8.8s\e[00m|", s->display_text);
     }
-    leds_text[8] = '\0';
-
-    qemu_chr_printf(s->display, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", leds_text);
-    qemu_chr_printf(s->display, "\n\n\n\n|\e[31m%-8.8s\e[00m|", s->display_text);
 }
 
 /*
@@ -236,17 +238,7 @@
         val = s->brk;
         break;
 
-    /* UART Registers */
-    case 0x00900:
-    case 0x00908:
-    case 0x00910:
-    case 0x00918:
-    case 0x00920:
-    case 0x00928:
-    case 0x00930:
-    case 0x00938:
-        val = serial_mm_readb(s->uart, addr);
-        break;
+    /* UART Registers are handled directly by the serial device */
 
     /* GPOUT Register */
     case 0x00a00:
@@ -348,17 +340,7 @@
         s->brk = val & 0xff;
         break;
 
-    /* UART Registers */
-    case 0x00900:
-    case 0x00908:
-    case 0x00910:
-    case 0x00918:
-    case 0x00920:
-    case 0x00928:
-    case 0x00930:
-    case 0x00938:
-        serial_mm_writeb(s->uart, addr, val);
-        break;
+    /* UART Registers are handled directly by the serial device */
 
     /* GPOUT Register */
     case 0x00a00:
@@ -430,22 +412,25 @@
     malta = cpu_register_io_memory(0, malta_fpga_read,
                                    malta_fpga_write, s);
 
-    cpu_register_physical_memory(base, 0x100000, malta);
+    cpu_register_physical_memory(base, 0x900, malta);
+    cpu_register_physical_memory(base + 0xa00, 0x100000 - 0xa00, malta);
 
-    s->display = qemu_chr_open("vc");
-    qemu_chr_printf(s->display, "\e[HMalta LEDBAR\r\n");
-    qemu_chr_printf(s->display, "+--------+\r\n");
-    qemu_chr_printf(s->display, "+        +\r\n");
-    qemu_chr_printf(s->display, "+--------+\r\n");
-    qemu_chr_printf(s->display, "\n");
-    qemu_chr_printf(s->display, "Malta ASCII\r\n");
-    qemu_chr_printf(s->display, "+--------+\r\n");
-    qemu_chr_printf(s->display, "+        +\r\n");
-    qemu_chr_printf(s->display, "+--------+\r\n");
+    if (!nographic) {
+        s->display = qemu_chr_open("vc");
+        qemu_chr_printf(s->display, "\e[HMalta LEDBAR\r\n");
+        qemu_chr_printf(s->display, "+--------+\r\n");
+        qemu_chr_printf(s->display, "+        +\r\n");
+        qemu_chr_printf(s->display, "+--------+\r\n");
+        qemu_chr_printf(s->display, "\n");
+        qemu_chr_printf(s->display, "Malta ASCII\r\n");
+        qemu_chr_printf(s->display, "+--------+\r\n");
+        qemu_chr_printf(s->display, "+        +\r\n");
+        qemu_chr_printf(s->display, "+--------+\r\n");
 
-    uart_chr = qemu_chr_open("vc");
-    qemu_chr_printf(uart_chr, "CBUS UART\r\n");
-    s->uart = serial_mm_init(base, 3, env->irq[2], uart_chr, 0);
+        uart_chr = qemu_chr_open("vc");
+        qemu_chr_printf(uart_chr, "CBUS UART\r\n");
+        s->uart = serial_mm_init(base + 0x900, 3, env->irq[2], uart_chr, 1);
+    }
 
     malta_fpga_reset(s);
     qemu_register_reset(malta_fpga_reset, s);
@@ -470,17 +455,8 @@
         s = AUD_init ();
         if (s) {
             for (c = soundhw; c->name; ++c) {
-                if (c->enabled) {
-                    if (c->isa) {
-                        fprintf(stderr, "qemu: Unsupported Sound Card: %s\n", c->name);
-                        exit(1);
-                    }
-                    else {
-                        if (pci_bus) {
-                            c->init.init_pci (pci_bus, s);
-                        }
-                    }
-                }
+                if (c->enabled)
+                    c->init.init_pci (pci_bus, s);
             }
         }
     }
@@ -558,9 +534,9 @@
     p = (uint32_t *) (phys_ram_base + bios_offset + 0x580);
     stl_raw(p++, 0x24040002);                                      /* addiu a0, zero, 2 */
     stl_raw(p++, 0x3c1d0000 | (((ENVP_ADDR - 64) >> 16) & 0xffff)); /* lui sp, high(ENVP_ADDR) */
-    stl_raw(p++, 0x37bd0000 | ((ENVP_ADDR - 64) & 0xffff));        /* ori sp, a0, low(ENVP_ADDR) */
+    stl_raw(p++, 0x37bd0000 | ((ENVP_ADDR - 64) & 0xffff));        /* ori sp, sp, low(ENVP_ADDR) */
     stl_raw(p++, 0x3c050000 | ((ENVP_ADDR >> 16) & 0xffff));       /* lui a1, high(ENVP_ADDR) */
-    stl_raw(p++, 0x34a50000 | (ENVP_ADDR & 0xffff));               /* ori a1, a0, low(ENVP_ADDR) */
+    stl_raw(p++, 0x34a50000 | (ENVP_ADDR & 0xffff));               /* ori a1, a1, low(ENVP_ADDR) */
     stl_raw(p++, 0x3c060000 | (((ENVP_ADDR + 8) >> 16) & 0xffff)); /* lui a2, high(ENVP_ADDR + 8) */
     stl_raw(p++, 0x34c60000 | ((ENVP_ADDR + 8) & 0xffff));         /* ori a2, a2, low(ENVP_ADDR + 8) */
     stl_raw(p++, 0x3c070000 | (env->ram_size >> 16));              /* lui a3, high(env->ram_size) */
@@ -699,7 +675,7 @@
                  &kernel_entry, &kernel_low, &kernel_high) < 0) {
         fprintf(stderr, "qemu: could not load kernel '%s'\n",
                 env->kernel_filename);
-      exit(1);
+        exit(1);
     }
 
     /* load initrd */
@@ -748,6 +724,7 @@
 {
     CPUState *env = opaque;
     cpu_reset(env);
+    cpu_mips_register(env, NULL);
 
     /* The bootload does not need to be rewritten as it is located in a
        read only location. The kernel location and the arguments table
@@ -775,11 +752,15 @@
     int ret;
     mips_def_t *def;
     qemu_irq *i8259;
+    int piix4_devfn;
+    uint8_t *eeprom_buf;
+    i2c_bus *smbus;
+    int i;
 
     /* init CPUs */
     if (cpu_model == NULL) {
 #ifdef TARGET_MIPS64
-        cpu_model = "R4000";
+        cpu_model = "20Kc";
 #else
         cpu_model = "24Kf";
 #endif
@@ -801,9 +782,35 @@
     cpu_register_physical_memory(0x1fc00000LL,
                                  BIOS_SIZE, bios_offset | IO_MEM_ROM);
 
-    /* Load a BIOS image except if a kernel image has been specified. In
-       the later case, just write a small bootloader to the flash
-       location. */
+    /* FPGA */
+    malta_fpga = malta_fpga_init(0x1f000000LL, env);
+
+    /* Load a BIOS image unless a kernel image has been specified. */
+    if (!kernel_filename) {
+        snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
+        ret = load_image(buf, phys_ram_base + bios_offset);
+        if (ret < 0 || ret > BIOS_SIZE) {
+            fprintf(stderr,
+                    "qemu: Could not load MIPS bios '%s', and no -kernel argument was specified\n",
+                    buf);
+            exit(1);
+        }
+        /* In little endian mode the 32bit words in the bios are swapped,
+           a neat trick which allows bi-endian firmware. */
+#ifndef TARGET_WORDS_BIGENDIAN
+        {
+            uint32_t *addr;
+            for (addr = (uint32_t *)(phys_ram_base + bios_offset);
+                 addr < (uint32_t *)(phys_ram_base + bios_offset + ret);
+		 addr++) {
+                *addr = bswap32(*addr);
+            }
+        }
+#endif
+    }
+
+    /* If a kernel image has been specified, write a small bootloader
+       to the flash location. */
     if (kernel_filename) {
         env->ram_size = ram_size;
         env->kernel_filename = kernel_filename;
@@ -812,14 +819,6 @@
         kernel_entry = load_kernel(env);
         env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL));
         write_bootloader(env, bios_offset, kernel_entry);
-    } else {
-        snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
-        ret = load_image(buf, phys_ram_base + bios_offset);
-        if (ret < 0 || ret > BIOS_SIZE) {
-            fprintf(stderr, "qemu: Warning, could not load MIPS bios '%s'\n",
-                    buf);
-            exit(1);
-        }
     }
 
     /* Board ID = 0x420 (Malta Board with CoreLV)
@@ -832,9 +831,6 @@
     cpu_mips_clock_init(env);
     cpu_mips_irqctrl_init();
 
-    /* FPGA */
-    malta_fpga = malta_fpga_init(0x1f000000LL, env);
-
     /* Interrupt controller */
     /* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */
     i8259 = i8259_init(env->irq[2]);
@@ -843,10 +839,15 @@
     pci_bus = pci_gt64120_init(i8259);
 
     /* Southbridge */
-    piix4_init(pci_bus, 80);
-    pci_piix3_ide_init(pci_bus, bs_table, 81, i8259);
-    usb_uhci_init(pci_bus, 82);
-    piix4_pm_init(pci_bus, 83);
+    piix4_devfn = piix4_init(pci_bus, 80);
+    pci_piix4_ide_init(pci_bus, bs_table, piix4_devfn + 1, i8259);
+    usb_uhci_piix4_init(pci_bus, piix4_devfn + 2);
+    smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100);
+    eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */
+    for (i = 0; i < 8; i++) {
+        /* TODO: Populate SPD eeprom data.  */
+        smbus_eeprom_device_init(smbus, 0x50 + i, eeprom_buf + (i * 256));
+    }
     pit = pit_init(0x40, i8259[0]);
     DMA_init(0);
 

Modified: trunk/src/host/qemu-neo1973/hw/mips_pica61.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/mips_pica61.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/mips_pica61.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -1,5 +1,5 @@
 /*
- * QEMU Malta board support
+ * QEMU Acer Pica Machine support
  *
  * Copyright (c) 2007 Hervé Poussineau
  *
@@ -51,6 +51,7 @@
 {
     CPUState *env = opaque;
     cpu_reset(env);
+    cpu_mips_register(env, NULL);
 }
 
 static

Modified: trunk/src/host/qemu-neo1973/hw/mips_r4k.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/mips_r4k.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/mips_r4k.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -128,6 +128,7 @@
 {
     CPUState *env = opaque;
     cpu_reset(env);
+    cpu_mips_register(env, NULL);
 
     if (env->kernel_filename)
         load_kernel (env, env->ram_size, env->kernel_filename,
@@ -227,6 +228,9 @@
         if (nd_table[0].model == NULL
             || strcmp(nd_table[0].model, "ne2k_isa") == 0) {
             isa_ne2000_init(0x300, i8259[9], &nd_table[0]);
+        } else if (strcmp(nd_table[0].model, "?") == 0) {
+            fprintf(stderr, "qemu: Supported NICs: ne2k_isa\n");
+            exit (1);
         } else {
             fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
             exit (1);

Modified: trunk/src/host/qemu-neo1973/hw/ne2000.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/ne2000.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/ne2000.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -325,7 +325,7 @@
         s->cmd = val;
         if (!(val & E8390_STOP)) { /* START bit makes no sense on RTL8029... */
             s->isr &= ~ENISR_RESET;
-            /* test specific case: zero length transfert */
+            /* test specific case: zero length transfer */
             if ((val & (E8390_RREAD | E8390_RWRITE)) &&
                 s->rcnt == 0) {
                 s->isr |= ENISR_RDC;
@@ -340,7 +340,7 @@
                 if (index + s->tcnt <= NE2000_PMEM_END) {
                     qemu_send_packet(s->vc, s->mem + index, s->tcnt);
                 }
-                /* signal end of transfert */
+                /* signal end of transfer */
                 s->tsr = ENTSR_PTX;
                 s->isr |= ENISR_TX;
                 s->cmd &= ~E8390_TRANS; 
@@ -550,7 +550,7 @@
 
     if (s->rcnt <= len) {
         s->rcnt = 0;
-        /* signal end of transfert */
+        /* signal end of transfer */
         s->isr |= ENISR_RDC;
         ne2000_update_irq(s);
     } else {

Modified: trunk/src/host/qemu-neo1973/hw/parallel.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/parallel.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/parallel.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -91,29 +91,29 @@
     addr &= 7;
     switch(addr) {
     case PARA_REG_DATA:
-	s->dataw = val;
-	parallel_update_irq(s);
+        s->dataw = val;
+        parallel_update_irq(s);
         break;
     case PARA_REG_CTR:
-	if ((val & PARA_CTR_INIT) == 0 ) {
-	    s->status = PARA_STS_BUSY;
-	    s->status |= PARA_STS_ACK;
-	    s->status |= PARA_STS_ONLINE;
-	    s->status |= PARA_STS_ERROR;
-	}
-	else if (val & PARA_CTR_SELECT) {
-	    if (val & PARA_CTR_STROBE) {
-		s->status &= ~PARA_STS_BUSY;
-		if ((s->control & PARA_CTR_STROBE) == 0)
-		    qemu_chr_write(s->chr, &s->dataw, 1);
-	    } else {
-		if (s->control & PARA_CTR_INTEN) {
-		    s->irq_pending = 1;
-		}
-	    }
-	}
-	parallel_update_irq(s);
-	s->control = val;
+        if ((val & PARA_CTR_INIT) == 0 ) {
+            s->status = PARA_STS_BUSY;
+            s->status |= PARA_STS_ACK;
+            s->status |= PARA_STS_ONLINE;
+            s->status |= PARA_STS_ERROR;
+        }
+        else if (val & PARA_CTR_SELECT) {
+            if (val & PARA_CTR_STROBE) {
+                s->status &= ~PARA_STS_BUSY;
+                if ((s->control & PARA_CTR_STROBE) == 0)
+                    qemu_chr_write(s->chr, &s->dataw, 1);
+            } else {
+                if (s->control & PARA_CTR_INTEN) {
+                    s->irq_pending = 1;
+                }
+            }
+        }
+        parallel_update_irq(s);
+        s->control = val;
         break;
     }
 }
@@ -132,52 +132,52 @@
     switch(addr) {
     case PARA_REG_DATA:
         if (s->dataw == val)
-	    return;
-	pdebug("wd%02x\n", val);
-	qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_WRITE_DATA, &parm);
-	s->dataw = val;
+            return;
+        pdebug("wd%02x\n", val);
+        qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_WRITE_DATA, &parm);
+        s->dataw = val;
         break;
     case PARA_REG_STS:
-	pdebug("ws%02x\n", val);
-	if (val & PARA_STS_TMOUT)
-	    s->epp_timeout = 0;
-	break;
+        pdebug("ws%02x\n", val);
+        if (val & PARA_STS_TMOUT)
+            s->epp_timeout = 0;
+        break;
     case PARA_REG_CTR:
         val |= 0xc0;
         if (s->control == val)
-	    return;
-	pdebug("wc%02x\n", val);
-	qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_WRITE_CONTROL, &parm);
-	s->control = val;
+            return;
+        pdebug("wc%02x\n", val);
+        qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_WRITE_CONTROL, &parm);
+        s->control = val;
         break;
     case PARA_REG_EPP_ADDR:
-	if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT)
-	    /* Controls not correct for EPP address cycle, so do nothing */
-	    pdebug("wa%02x s\n", val);
-	else {
-	    struct ParallelIOArg ioarg = { .buffer = &parm, .count = 1 };
-	    if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE_ADDR, &ioarg)) {
-		s->epp_timeout = 1;
-		pdebug("wa%02x t\n", val);
-	    }
-	    else
-		pdebug("wa%02x\n", val);
-	}
-	break;
+        if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT)
+            /* Controls not correct for EPP address cycle, so do nothing */
+            pdebug("wa%02x s\n", val);
+        else {
+            struct ParallelIOArg ioarg = { .buffer = &parm, .count = 1 };
+            if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE_ADDR, &ioarg)) {
+                s->epp_timeout = 1;
+                pdebug("wa%02x t\n", val);
+            }
+            else
+                pdebug("wa%02x\n", val);
+        }
+        break;
     case PARA_REG_EPP_DATA:
-	if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT)
-	    /* Controls not correct for EPP data cycle, so do nothing */
-	    pdebug("we%02x s\n", val);
-	else {
-	    struct ParallelIOArg ioarg = { .buffer = &parm, .count = 1 };
-	    if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg)) {
-		s->epp_timeout = 1;
-		pdebug("we%02x t\n", val);
-	    }
-	    else
-		pdebug("we%02x\n", val);
-	}
-	break;
+        if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT)
+            /* Controls not correct for EPP data cycle, so do nothing */
+            pdebug("we%02x s\n", val);
+        else {
+            struct ParallelIOArg ioarg = { .buffer = &parm, .count = 1 };
+            if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg)) {
+                s->epp_timeout = 1;
+                pdebug("we%02x t\n", val);
+            }
+            else
+                pdebug("we%02x\n", val);
+        }
+        break;
     }
 }
 
@@ -188,20 +188,20 @@
     uint16_t eppdata = cpu_to_le16(val);
     int err;
     struct ParallelIOArg ioarg = {
-	.buffer = &eppdata, .count = sizeof(eppdata)
+        .buffer = &eppdata, .count = sizeof(eppdata)
     };
     if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT) {
-	/* Controls not correct for EPP data cycle, so do nothing */
-	pdebug("we%04x s\n", val);
-	return;
+        /* Controls not correct for EPP data cycle, so do nothing */
+        pdebug("we%04x s\n", val);
+        return;
     }
     err = qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg);
     if (err) {
-	s->epp_timeout = 1;
-	pdebug("we%04x t\n", val);
+        s->epp_timeout = 1;
+        pdebug("we%04x t\n", val);
     }
     else
-	pdebug("we%04x\n", val);
+        pdebug("we%04x\n", val);
 }
 
 static void
@@ -211,20 +211,20 @@
     uint32_t eppdata = cpu_to_le32(val);
     int err;
     struct ParallelIOArg ioarg = {
-	.buffer = &eppdata, .count = sizeof(eppdata)
+        .buffer = &eppdata, .count = sizeof(eppdata)
     };
     if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT) {
-	/* Controls not correct for EPP data cycle, so do nothing */
-	pdebug("we%08x s\n", val);
-	return;
+        /* Controls not correct for EPP data cycle, so do nothing */
+        pdebug("we%08x s\n", val);
+        return;
     }
     err = qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg);
     if (err) {
-	s->epp_timeout = 1;
-	pdebug("we%08x t\n", val);
+        s->epp_timeout = 1;
+        pdebug("we%08x t\n", val);
     }
     else
-	pdebug("we%08x\n", val);
+        pdebug("we%08x\n", val);
 }
 
 static uint32_t parallel_ioport_read_sw(void *opaque, uint32_t addr)
@@ -235,25 +235,25 @@
     addr &= 7;
     switch(addr) {
     case PARA_REG_DATA:
-	if (s->control & PARA_CTR_DIR)
-	    ret = s->datar;
-	else
-	    ret = s->dataw;
+        if (s->control & PARA_CTR_DIR)
+            ret = s->datar;
+        else
+            ret = s->dataw;
         break;
     case PARA_REG_STS:
-	ret = s->status;
-	s->irq_pending = 0;
-	if ((s->status & PARA_STS_BUSY) == 0 && (s->control & PARA_CTR_STROBE) == 0) {
-	    /* XXX Fixme: wait 5 microseconds */
-	    if (s->status & PARA_STS_ACK)
-		s->status &= ~PARA_STS_ACK;
-	    else {
-		/* XXX Fixme: wait 5 microseconds */
-		s->status |= PARA_STS_ACK;
-		s->status |= PARA_STS_BUSY;
-	    }
-	}
-	parallel_update_irq(s);
+        ret = s->status;
+        s->irq_pending = 0;
+        if ((s->status & PARA_STS_BUSY) == 0 && (s->control & PARA_CTR_STROBE) == 0) {
+            /* XXX Fixme: wait 5 microseconds */
+            if (s->status & PARA_STS_ACK)
+                s->status &= ~PARA_STS_ACK;
+            else {
+                /* XXX Fixme: wait 5 microseconds */
+                s->status |= PARA_STS_ACK;
+                s->status |= PARA_STS_BUSY;
+            }
+        }
+        parallel_update_irq(s);
         break;
     case PARA_REG_CTR:
         ret = s->control;
@@ -270,63 +270,63 @@
     addr &= 7;
     switch(addr) {
     case PARA_REG_DATA:
-	qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_DATA, &ret);
-	if (s->last_read_offset != addr || s->datar != ret)
-	    pdebug("rd%02x\n", ret);
+        qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_DATA, &ret);
+        if (s->last_read_offset != addr || s->datar != ret)
+            pdebug("rd%02x\n", ret);
         s->datar = ret;
         break;
     case PARA_REG_STS:
-	qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_STATUS, &ret);
-	ret &= ~PARA_STS_TMOUT;
-	if (s->epp_timeout)
-	    ret |= PARA_STS_TMOUT;
-	if (s->last_read_offset != addr || s->status != ret)
-	    pdebug("rs%02x\n", ret);
-	s->status = ret;
+        qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_STATUS, &ret);
+        ret &= ~PARA_STS_TMOUT;
+        if (s->epp_timeout)
+            ret |= PARA_STS_TMOUT;
+        if (s->last_read_offset != addr || s->status != ret)
+            pdebug("rs%02x\n", ret);
+        s->status = ret;
         break;
     case PARA_REG_CTR:
         /* s->control has some bits fixed to 1. It is zero only when
-	   it has not been yet written to.  */
-	if (s->control == 0) {
-	    qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_CONTROL, &ret);
-	    if (s->last_read_offset != addr)
-		pdebug("rc%02x\n", ret);
-	    s->control = ret;
-	}
-	else {
-	    ret = s->control;
-	    if (s->last_read_offset != addr)
-		pdebug("rc%02x\n", ret);
-	}
+           it has not been yet written to.  */
+        if (s->control == 0) {
+            qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_CONTROL, &ret);
+            if (s->last_read_offset != addr)
+                pdebug("rc%02x\n", ret);
+            s->control = ret;
+        }
+        else {
+            ret = s->control;
+            if (s->last_read_offset != addr)
+                pdebug("rc%02x\n", ret);
+        }
         break;
     case PARA_REG_EPP_ADDR:
-	if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT))
-	    /* Controls not correct for EPP addr cycle, so do nothing */
-	    pdebug("ra%02x s\n", ret);
-	else {
-	    struct ParallelIOArg ioarg = { .buffer = &ret, .count = 1 };
-	    if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ_ADDR, &ioarg)) {
-		s->epp_timeout = 1;
-		pdebug("ra%02x t\n", ret);
-	    }
-	    else
-		pdebug("ra%02x\n", ret);
-	}
-	break;
+        if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT))
+            /* Controls not correct for EPP addr cycle, so do nothing */
+            pdebug("ra%02x s\n", ret);
+        else {
+            struct ParallelIOArg ioarg = { .buffer = &ret, .count = 1 };
+            if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ_ADDR, &ioarg)) {
+                s->epp_timeout = 1;
+                pdebug("ra%02x t\n", ret);
+            }
+            else
+                pdebug("ra%02x\n", ret);
+        }
+        break;
     case PARA_REG_EPP_DATA:
-	if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT))
-	    /* Controls not correct for EPP data cycle, so do nothing */
-	    pdebug("re%02x s\n", ret);
-	else {
-	    struct ParallelIOArg ioarg = { .buffer = &ret, .count = 1 };
-	    if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg)) {
-		s->epp_timeout = 1;
-		pdebug("re%02x t\n", ret);
-	    }
-	    else
-		pdebug("re%02x\n", ret);
-	}
-	break;
+        if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT))
+            /* Controls not correct for EPP data cycle, so do nothing */
+            pdebug("re%02x s\n", ret);
+        else {
+            struct ParallelIOArg ioarg = { .buffer = &ret, .count = 1 };
+            if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg)) {
+                s->epp_timeout = 1;
+                pdebug("re%02x t\n", ret);
+            }
+            else
+                pdebug("re%02x\n", ret);
+        }
+        break;
     }
     s->last_read_offset = addr;
     return ret;
@@ -340,22 +340,22 @@
     uint16_t eppdata = ~0;
     int err;
     struct ParallelIOArg ioarg = {
-	.buffer = &eppdata, .count = sizeof(eppdata)
+        .buffer = &eppdata, .count = sizeof(eppdata)
     };
     if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT)) {
-	/* Controls not correct for EPP data cycle, so do nothing */
-	pdebug("re%04x s\n", eppdata);
-	return eppdata;
+        /* Controls not correct for EPP data cycle, so do nothing */
+        pdebug("re%04x s\n", eppdata);
+        return eppdata;
     }
     err = qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg);
     ret = le16_to_cpu(eppdata);
 
     if (err) {
-	s->epp_timeout = 1;
-	pdebug("re%04x t\n", ret);
+        s->epp_timeout = 1;
+        pdebug("re%04x t\n", ret);
     }
     else
-	pdebug("re%04x\n", ret);
+        pdebug("re%04x\n", ret);
     return ret;
 }
 
@@ -367,22 +367,22 @@
     uint32_t eppdata = ~0U;
     int err;
     struct ParallelIOArg ioarg = {
-	.buffer = &eppdata, .count = sizeof(eppdata)
+        .buffer = &eppdata, .count = sizeof(eppdata)
     };
     if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT)) {
-	/* Controls not correct for EPP data cycle, so do nothing */
-	pdebug("re%08x s\n", eppdata);
-	return eppdata;
+        /* Controls not correct for EPP data cycle, so do nothing */
+        pdebug("re%08x s\n", eppdata);
+        return eppdata;
     }
     err = qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg);
     ret = le32_to_cpu(eppdata);
 
     if (err) {
-	s->epp_timeout = 1;
-	pdebug("re%08x t\n", ret);
+        s->epp_timeout = 1;
+        pdebug("re%08x t\n", ret);
     }
     else
-	pdebug("re%08x\n", ret);
+        pdebug("re%08x\n", ret);
     return ret;
 }
 
@@ -426,22 +426,22 @@
 
     if (qemu_chr_ioctl(chr, CHR_IOCTL_PP_READ_STATUS, &dummy) == 0) {
         s->hw_driver = 1;
-	s->status = dummy;
+        s->status = dummy;
     }
 
     if (s->hw_driver) {
-	register_ioport_write(base, 8, 1, parallel_ioport_write_hw, s);
-	register_ioport_read(base, 8, 1, parallel_ioport_read_hw, s);
-	register_ioport_write(base+4, 1, 2, parallel_ioport_eppdata_write_hw2, s);
-	register_ioport_read(base+4, 1, 2, parallel_ioport_eppdata_read_hw2, s);
-	register_ioport_write(base+4, 1, 4, parallel_ioport_eppdata_write_hw4, s);
-	register_ioport_read(base+4, 1, 4, parallel_ioport_eppdata_read_hw4, s);
-	register_ioport_write(base+0x400, 8, 1, parallel_ioport_ecp_write, s);
-	register_ioport_read(base+0x400, 8, 1, parallel_ioport_ecp_read, s);
+        register_ioport_write(base, 8, 1, parallel_ioport_write_hw, s);
+        register_ioport_read(base, 8, 1, parallel_ioport_read_hw, s);
+        register_ioport_write(base+4, 1, 2, parallel_ioport_eppdata_write_hw2, s);
+        register_ioport_read(base+4, 1, 2, parallel_ioport_eppdata_read_hw2, s);
+        register_ioport_write(base+4, 1, 4, parallel_ioport_eppdata_write_hw4, s);
+        register_ioport_read(base+4, 1, 4, parallel_ioport_eppdata_read_hw4, s);
+        register_ioport_write(base+0x400, 8, 1, parallel_ioport_ecp_write, s);
+        register_ioport_read(base+0x400, 8, 1, parallel_ioport_ecp_read, s);
     }
     else {
-	register_ioport_write(base, 8, 1, parallel_ioport_write_sw, s);
-	register_ioport_read(base, 8, 1, parallel_ioport_read_sw, s);
+        register_ioport_write(base, 8, 1, parallel_ioport_write_sw, s);
+        register_ioport_read(base, 8, 1, parallel_ioport_read_sw, s);
     }
     return s;
 }

Modified: trunk/src/host/qemu-neo1973/hw/pc.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pc.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/pc.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -865,7 +865,12 @@
         if (strcmp(nd->model, "ne2k_isa") == 0) {
             pc_init_ne2k_isa(nd, i8259);
         } else if (pci_enabled) {
+            if (strcmp(nd->model, "?") == 0)
+                fprintf(stderr, "qemu: Supported ISA NICs: ne2k_isa\n");
             pci_nic_init(pci_bus, nd, -1);
+        } else if (strcmp(nd->model, "?") == 0) {
+            fprintf(stderr, "qemu: Supported ISA NICs: ne2k_isa\n");
+            exit(1);
         } else {
             fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd->model);
             exit(1);
@@ -892,7 +897,7 @@
     cmos_init(ram_size, boot_device, bs_table);
 
     if (pci_enabled && usb_enabled) {
-        usb_uhci_init(pci_bus, piix3_devfn + 2);
+        usb_uhci_piix3_init(pci_bus, piix3_devfn + 2);
     }
 
     if (pci_enabled && acpi_enabled) {
@@ -900,7 +905,7 @@
         i2c_bus *smbus;
 
         /* TODO: Populate SPD eeprom data.  */
-        smbus = piix4_pm_init(pci_bus, piix3_devfn + 3);
+        smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100);
         for (i = 0; i < 8; i++) {
             smbus_eeprom_device_init(smbus, 0x50 + i, eeprom_buf + (i * 256));
         }

Modified: trunk/src/host/qemu-neo1973/hw/pci.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pci.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/pci.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -588,6 +588,10 @@
         pci_rtl8139_init(bus, nd, devfn);
     } else if (strcmp(nd->model, "pcnet") == 0) {
         pci_pcnet_init(bus, nd, devfn);
+    } else if (strcmp(nd->model, "?") == 0) {
+        fprintf(stderr, "qemu: Supported PCI NICs: i82551 i82557b i82559er"
+                        " ne2k_pci pcnet rtl8139\n");
+        exit (1);
     } else {
         fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd->model);
         exit (1);

Modified: trunk/src/host/qemu-neo1973/hw/pckbd.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pckbd.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/pckbd.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -421,8 +421,8 @@
     &kbd_mm_writeb,
 };
 
-void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq, target_ulong base,
-                   int it_shift)
+void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq,
+                   target_phys_addr_t base, int it_shift)
 {
     KBDState *s = &kbd_state;
     int s_io_memory;

Modified: trunk/src/host/qemu-neo1973/hw/pcnet.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pcnet.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/pcnet.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -1267,7 +1267,8 @@
             if (CSR_LOOP(s))
                 pcnet_receive(s, s->buffer, s->xmit_pos);
             else
-                qemu_send_packet(s->vc, s->buffer, s->xmit_pos);
+                if (s->vc)
+                    qemu_send_packet(s->vc, s->buffer, s->xmit_pos);
 
             s->csr[0] &= ~0x0008;   /* clear TDMD */
             s->csr[4] |= 0x0004;    /* set TXSTRT */
@@ -1554,7 +1555,7 @@
     return val;
 }
 
-void pcnet_h_reset(void *opaque)
+static void pcnet_h_reset(void *opaque)
 {
     PCNetState *s = opaque;
     int i;
@@ -1562,7 +1563,8 @@
 
     /* Initialize the PROM */
 
-    memcpy(s->prom, s->nd->macaddr, 6);
+    if (s->nd)
+        memcpy(s->prom, s->nd->macaddr, 6);
     s->prom[12] = s->prom[13] = 0x00;
     s->prom[14] = s->prom[15] = 0x57;
 
@@ -1898,18 +1900,21 @@
 
     d->nd = nd;
 
-    d->vc = qemu_new_vlan_client(nd->vlan, pcnet_receive, 
-                                 pcnet_can_receive, d);
-    
-    snprintf(d->vc->info_str, sizeof(d->vc->info_str),
-             "pcnet macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
-             d->nd->macaddr[0],
-             d->nd->macaddr[1],
-             d->nd->macaddr[2],
-             d->nd->macaddr[3],
-             d->nd->macaddr[4],
-             d->nd->macaddr[5]);
+    if (nd && nd->vlan) {
+        d->vc = qemu_new_vlan_client(nd->vlan, pcnet_receive,
+                                     pcnet_can_receive, d);
 
+        snprintf(d->vc->info_str, sizeof(d->vc->info_str),
+                 "pcnet macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
+                 d->nd->macaddr[0],
+                 d->nd->macaddr[1],
+                 d->nd->macaddr[2],
+                 d->nd->macaddr[3],
+                 d->nd->macaddr[4],
+                 d->nd->macaddr[5]);
+    } else {
+        d->vc = NULL;
+    }
     pcnet_h_reset(d);
     register_savevm("pcnet", 0, 2, pcnet_save, pcnet_load, d);
 }
@@ -2018,7 +2023,7 @@
     (CPUWriteMemoryFunc *)&pcnet_ioport_writew,
 };
 
-void *lance_init(NICInfo *nd, target_phys_addr_t leaddr, void *dma_opaque,
+void lance_init(NICInfo *nd, target_phys_addr_t leaddr, void *dma_opaque,
                  qemu_irq irq)
 {
     PCNetState *d;
@@ -2026,12 +2031,14 @@
 
     d = qemu_mallocz(sizeof(PCNetState));
     if (!d)
-        return NULL;
+        return;
 
     lance_io_memory =
         cpu_register_io_memory(0, lance_mem_read, lance_mem_write, d);
 
     d->dma_opaque = dma_opaque;
+    sparc32_dma_set_reset_data(dma_opaque, pcnet_h_reset, d);
+
     cpu_register_physical_memory(leaddr, 4, lance_io_memory);
 
     d->irq = irq;
@@ -2039,7 +2046,5 @@
     d->phys_mem_write = ledma_memory_write;
 
     pcnet_common_init(d, nd, "lance");
-
-    return d;
 }
 #endif /* TARGET_SPARC */

Modified: trunk/src/host/qemu-neo1973/hw/pflash_cfi02.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pflash_cfi02.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/pflash_cfi02.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -50,9 +50,9 @@
 
 struct pflash_t {
     BlockDriverState *bs;
-    target_ulong base;
-    target_ulong sector_len;
-    target_ulong total_len;
+    target_phys_addr_t base;
+    uint32_t sector_len;
+    uint32_t total_len;
     int width;
     int wcycle; /* if 0, the flash is read normally */
     int bypass;
@@ -85,9 +85,9 @@
     pfl->cmd = 0;
 }
 
-static uint32_t pflash_read (pflash_t *pfl, target_ulong offset, int width)
+static uint32_t pflash_read (pflash_t *pfl, uint32_t offset, int width)
 {
-    target_ulong boff;
+    uint32_t boff;
     uint32_t ret;
     uint8_t *p;
 
@@ -199,10 +199,10 @@
     }
 }
 
-static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value,
+static void pflash_write (pflash_t *pfl, uint32_t offset, uint32_t value,
                           int width)
 {
-    target_ulong boff;
+    uint32_t boff;
     uint8_t *p;
     uint8_t cmd;
 
@@ -219,7 +219,7 @@
     DPRINTF("%s: offset " TARGET_FMT_lx " %08x %d %d\n", __func__,
             offset, value, width, pfl->wcycle);
     if (pfl->wcycle == 0)
-        offset -= (target_ulong)(long)pfl->storage;
+        offset -= (uint32_t)(long)pfl->storage;
     else
         offset -= pfl->base;
         
@@ -521,14 +521,14 @@
     return ret;
 }
 
-pflash_t *pflash_register (target_ulong base, ram_addr_t off,
+pflash_t *pflash_register (target_phys_addr_t base, ram_addr_t off,
                            BlockDriverState *bs,
-                           target_ulong sector_len, int nb_blocs, int width,
+                           uint32_t sector_len, int nb_blocs, int width,
                            uint16_t id0, uint16_t id1, 
                            uint16_t id2, uint16_t id3)
 {
     pflash_t *pfl;
-    target_long total_len;
+    int32_t total_len;
 
     total_len = sector_len * nb_blocs;
     /* XXX: to be fixed */

Modified: trunk/src/host/qemu-neo1973/hw/pl011.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pl011.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/pl011.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -232,7 +232,7 @@
     s = (pl011_state *)qemu_mallocz(sizeof(pl011_state));
     iomemtype = cpu_register_io_memory(0, pl011_readfn,
                                        pl011_writefn, s);
-    cpu_register_physical_memory(base, 0x00000fff, iomemtype);
+    cpu_register_physical_memory(base, 0x00001000, iomemtype);
     s->base = base;
     s->irq = irq;
     s->chr = chr;

Modified: trunk/src/host/qemu-neo1973/hw/pl050.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pl050.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/pl050.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -131,7 +131,7 @@
     s = (pl050_state *)qemu_mallocz(sizeof(pl050_state));
     iomemtype = cpu_register_io_memory(0, pl050_readfn,
                                        pl050_writefn, s);
-    cpu_register_physical_memory(base, 0x00000fff, iomemtype);
+    cpu_register_physical_memory(base, 0x00001000, iomemtype);
     s->base = base;
     s->irq = irq;
     s->is_mouse = is_mouse;

Modified: trunk/src/host/qemu-neo1973/hw/pl080.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pl080.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/pl080.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -332,7 +332,7 @@
     s = (pl080_state *)qemu_mallocz(sizeof(pl080_state));
     iomemtype = cpu_register_io_memory(0, pl080_readfn,
                                        pl080_writefn, s);
-    cpu_register_physical_memory(base, 0x00000fff, iomemtype);
+    cpu_register_physical_memory(base, 0x00001000, iomemtype);
     s->base = base;
     s->irq = irq;
     s->nchannels = nchannels;

Modified: trunk/src/host/qemu-neo1973/hw/pl110.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pl110.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/pl110.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -407,7 +407,7 @@
     s = (pl110_state *)qemu_mallocz(sizeof(pl110_state));
     iomemtype = cpu_register_io_memory(0, pl110_readfn,
                                        pl110_writefn, s);
-    cpu_register_physical_memory(base, 0x00000fff, iomemtype);
+    cpu_register_physical_memory(base, 0x00001000, iomemtype);
     s->base = base;
     s->ds = ds;
     s->versatile = versatile;

Modified: trunk/src/host/qemu-neo1973/hw/pl181.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pl181.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/pl181.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -36,9 +36,14 @@
     uint32_t datacnt;
     uint32_t status;
     uint32_t mask[2];
-    uint32_t fifocnt;
     int fifo_pos;
     int fifo_len;
+    /* The linux 2.6.21 driver is buggy, and misbehaves if new data arrives
+       while it is reading the FIFO.  We hack around this be defering
+       subsequent transfers until after the driver polls the status word.
+       http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=4446/1
+     */
+    int linux_hack;
     uint32_t fifo[PL181_FIFO_LEN];
     qemu_irq irq[2];
 } pl181_state;
@@ -182,7 +187,8 @@
     int is_read;
 
     is_read = (s->datactrl & PL181_DATA_DIRECTION) != 0;
-    if (s->datacnt != 0 && (!is_read || sd_data_ready(s->card))) {
+    if (s->datacnt != 0 && (!is_read || sd_data_ready(s->card))
+            && !s->linux_hack) {
         limit = is_read ? PL181_FIFO_LEN : 0;
         n = 0;
         value = 0;
@@ -217,7 +223,7 @@
         s->status |= PL181_STATUS_DATABLOCKEND;
         DPRINTF("Transfer Complete\n");
     }
-    if (s->datacnt == 0 && s->fifocnt == 0) {
+    if (s->datacnt == 0 && s->fifo_len == 0) {
         s->datactrl &= ~PL181_DATA_ENABLE;
         DPRINTF("Data engine idle\n");
     } else {
@@ -252,6 +258,7 @@
 static uint32_t pl181_read(void *opaque, target_phys_addr_t offset)
 {
     pl181_state *s = (pl181_state *)opaque;
+    uint32_t tmp;
 
     offset -= s->base;
     if (offset >= 0xfe0 && offset < 0x1000) {
@@ -285,24 +292,42 @@
     case 0x30: /* DataCnt */
         return s->datacnt;
     case 0x34: /* Status */
-        return s->status;
+        tmp = s->status;
+        if (s->linux_hack) {
+            s->linux_hack = 0;
+            pl181_fifo_run(s);
+            pl181_update(s);
+        }
+        return tmp;
     case 0x3c: /* Mask0 */
         return s->mask[0];
     case 0x40: /* Mask1 */
         return s->mask[1];
     case 0x48: /* FifoCnt */
-        return s->fifocnt;
+        /* The documentation is somewhat vague about exactly what FifoCnt
+           does.  On real hardware it appears to be when decrememnted
+           when a word is transfered between the FIFO and the serial
+           data engine.  DataCnt is decremented after each byte is
+           transfered between the serial engine and the card.
+           We don't emulate this level of detail, so both can be the same.  */
+        tmp = (s->datacnt + 3) >> 2;
+        if (s->linux_hack) {
+            s->linux_hack = 0;
+            pl181_fifo_run(s);
+            pl181_update(s);
+        }
+        return tmp;
     case 0x80: case 0x84: case 0x88: case 0x8c: /* FifoData */
     case 0x90: case 0x94: case 0x98: case 0x9c:
     case 0xa0: case 0xa4: case 0xa8: case 0xac:
     case 0xb0: case 0xb4: case 0xb8: case 0xbc:
-        if (s->fifocnt == 0) {
+        if (s->fifo_len == 0) {
             fprintf(stderr, "pl181: Unexpected FIFO read\n");
             return 0;
         } else {
             uint32_t value;
-            s->fifocnt--;
             value = pl181_fifo_pop(s);
+            s->linux_hack = 1;
             pl181_fifo_run(s);
             pl181_update(s);
             return value;
@@ -356,7 +381,6 @@
         s->datactrl = value & 0xff;
         if (value & PL181_DATA_ENABLE) {
             s->datacnt = s->datalength;
-            s->fifocnt = (s->datalength + 3) >> 2;
             pl181_fifo_run(s);
         }
         break;
@@ -373,10 +397,9 @@
     case 0x90: case 0x94: case 0x98: case 0x9c:
     case 0xa0: case 0xa4: case 0xa8: case 0xac:
     case 0xb0: case 0xb4: case 0xb8: case 0xbc:
-        if (s->fifocnt == 0) {
+        if (s->datacnt == 0) {
             fprintf(stderr, "pl181: Unexpected FIFO write\n");
         } else {
-            s->fifocnt--;
             pl181_fifo_push(s, value);
             pl181_fifo_run(s);
         }
@@ -418,9 +441,9 @@
     s->datactrl = 0;
     s->datacnt = 0;
     s->status = 0;
+    s->linux_hack = 0;
     s->mask[0] = 0;
     s->mask[1] = 0;
-    s->fifocnt = 0;
 }
 
 void pl181_init(uint32_t base, BlockDriverState *bd,
@@ -432,7 +455,7 @@
     s = (pl181_state *)qemu_mallocz(sizeof(pl181_state));
     iomemtype = cpu_register_io_memory(0, pl181_readfn,
                                        pl181_writefn, s);
-    cpu_register_physical_memory(base, 0x00000fff, iomemtype);
+    cpu_register_physical_memory(base, 0x00001000, iomemtype);
     s->base = base;
     s->card = sd_init(bd);
     s->irq[0] = irq0;

Modified: trunk/src/host/qemu-neo1973/hw/pl190.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pl190.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/pl190.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -239,7 +239,7 @@
     s = (pl190_state *)qemu_mallocz(sizeof(pl190_state));
     iomemtype = cpu_register_io_memory(0, pl190_readfn,
                                        pl190_writefn, s);
-    cpu_register_physical_memory(base, 0x00000fff, iomemtype);
+    cpu_register_physical_memory(base, 0x00001000, iomemtype);
     qi = qemu_allocate_irqs(pl190_set_irq, s, 32);
     s->base = base;
     s->irq = irq;

Modified: trunk/src/host/qemu-neo1973/hw/ppc405.h
===================================================================
--- trunk/src/host/qemu-neo1973/hw/ppc405.h	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/ppc405.h	2007-06-17 16:55:00 UTC (rev 2289)
@@ -83,7 +83,8 @@
                        uint32_t dcr_base, int has_ssr, int has_vr);
 /* SDRAM controller */
 void ppc405_sdram_init (CPUState *env, qemu_irq irq, int nbanks,
-                        target_ulong *ram_bases, target_ulong *ram_sizes,
+                        target_phys_addr_t *ram_bases,
+                        target_phys_addr_t *ram_sizes,
                         int do_init);
 /* Peripheral controller */
 void ppc405_ebc_init (CPUState *env);
@@ -107,15 +108,17 @@
 /* Memory access layer */
 void ppc405_mal_init (CPUState *env, qemu_irq irqs[4]);
 /* PowerPC 405 microcontrollers */
-CPUState *ppc405cr_init (target_ulong ram_bases[4], target_ulong ram_sizes[4],
+CPUState *ppc405cr_init (target_phys_addr_t ram_bases[4],
+                         target_phys_addr_t ram_sizes[4],
                          uint32_t sysclk, qemu_irq **picp,
                          ram_addr_t *offsetp, int do_init);
-CPUState *ppc405ep_init (target_ulong ram_bases[2], target_ulong ram_sizes[2],
+CPUState *ppc405ep_init (target_phys_addr_t ram_bases[2],
+                         target_phys_addr_t ram_sizes[2],
                          uint32_t sysclk, qemu_irq **picp,
                          ram_addr_t *offsetp, int do_init);
 /* IBM STBxxx microcontrollers */
-CPUState *ppc_stb025_init (target_ulong ram_bases[2],
-                           target_ulong ram_sizes[2],
+CPUState *ppc_stb025_init (target_phys_addr_t ram_bases[2],
+                           target_phys_addr_t ram_sizes[2],
                            uint32_t sysclk, qemu_irq **picp,
                            ram_addr_t *offsetp);
 

Modified: trunk/src/host/qemu-neo1973/hw/ppc405_boards.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/ppc405_boards.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/ppc405_boards.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -184,7 +184,7 @@
     CPUPPCState *env;
     qemu_irq *pic;
     ram_addr_t sram_offset, bios_offset, bdloc;
-    target_ulong ram_bases[2], ram_sizes[2];
+    target_phys_addr_t ram_bases[2], ram_sizes[2];
     target_ulong sram_size, bios_size;
     //int phy_addr = 0;
     //static int phy_addr = 1;
@@ -506,7 +506,7 @@
     CPUPPCState *env;
     qemu_irq *pic;
     ram_addr_t bios_offset;
-    target_ulong ram_bases[2], ram_sizes[2];
+    target_phys_addr_t ram_bases[2], ram_sizes[2];
     target_ulong bios_size;
     target_ulong kernel_base, kernel_size, initrd_base, initrd_size;
     int linux_boot;

Modified: trunk/src/host/qemu-neo1973/hw/ppc405_uc.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/ppc405_uc.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/ppc405_uc.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -903,8 +903,8 @@
 struct ppc4xx_sdram_t {
     uint32_t addr;
     int nbanks;
-    target_ulong ram_bases[4];
-    target_ulong ram_sizes[4];
+    target_phys_addr_t ram_bases[4];
+    target_phys_addr_t ram_sizes[4];
     uint32_t besr0;
     uint32_t besr1;
     uint32_t bear;
@@ -924,7 +924,7 @@
     SDRAM0_CFGDATA = 0x011,
 };
 
-static uint32_t sdram_bcr (target_ulong ram_base, target_ulong ram_size)
+static uint32_t sdram_bcr (target_phys_addr_t ram_base, target_phys_addr_t ram_size)
 {
     uint32_t bcr;
 
@@ -960,7 +960,7 @@
     return bcr;
 }
 
-static inline target_ulong sdram_base (uint32_t bcr)
+static inline target_phys_addr_t sdram_base (uint32_t bcr)
 {
     return bcr & 0xFF800000;
 }
@@ -1206,7 +1206,8 @@
 }
 
 void ppc405_sdram_init (CPUState *env, qemu_irq irq, int nbanks,
-                        target_ulong *ram_bases, target_ulong *ram_sizes,
+                        target_phys_addr_t *ram_bases,
+                        target_phys_addr_t *ram_sizes,
                         int do_init)
 {
     ppc4xx_sdram_t *sdram;
@@ -1215,10 +1216,10 @@
     if (sdram != NULL) {
         sdram->irq = irq;
         sdram->nbanks = nbanks;
-        memset(sdram->ram_bases, 0, 4 * sizeof(target_ulong));
-        memcpy(sdram->ram_bases, ram_bases, nbanks * sizeof(target_ulong));
-        memset(sdram->ram_sizes, 0, 4 * sizeof(target_ulong));
-        memcpy(sdram->ram_sizes, ram_sizes, nbanks * sizeof(target_ulong));
+        memset(sdram->ram_bases, 0, 4 * sizeof(target_phys_addr_t));
+        memcpy(sdram->ram_bases, ram_bases, nbanks * sizeof(target_phys_addr_t));
+        memset(sdram->ram_sizes, 0, 4 * sizeof(target_phys_addr_t));
+        memcpy(sdram->ram_sizes, ram_sizes, nbanks * sizeof(target_phys_addr_t));
         sdram_reset(sdram);
         qemu_register_reset(&sdram_reset, sdram);
         ppc_dcr_register(env, SDRAM0_CFGADDR,
@@ -3017,7 +3018,8 @@
     }
 }
 
-CPUState *ppc405cr_init (target_ulong ram_bases[4], target_ulong ram_sizes[4],
+CPUState *ppc405cr_init (target_phys_addr_t ram_bases[4],
+                         target_phys_addr_t ram_sizes[4],
                          uint32_t sysclk, qemu_irq **picp,
                          ram_addr_t *offsetp, int do_init)
 {
@@ -3365,7 +3367,8 @@
     }
 }
 
-CPUState *ppc405ep_init (target_ulong ram_bases[2], target_ulong ram_sizes[2],
+CPUState *ppc405ep_init (target_phys_addr_t ram_bases[2],
+                         target_phys_addr_t ram_sizes[2],
                          uint32_t sysclk, qemu_irq **picp,
                          ram_addr_t *offsetp, int do_init)
 {

Modified: trunk/src/host/qemu-neo1973/hw/ppc_prep.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/ppc_prep.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/ppc_prep.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -626,6 +626,9 @@
         if (nd_table[0].model == NULL
             || strcmp(nd_table[0].model, "ne2k_isa") == 0) {
             isa_ne2000_init(ne2000_io[i], i8259[ne2000_irq[i]], &nd_table[i]);
+        } else if (strcmp(nd_table[0].model, "?") == 0) {
+            fprintf(stderr, "qemu: Supported NICs: ne2k_isa\n");
+            exit (1);
         } else {
             /* Why ? */
             cpu_abort(env, "qemu: Unsupported NIC: %s\n", nd_table[0].model);

Modified: trunk/src/host/qemu-neo1973/hw/ptimer.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/ptimer.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/ptimer.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -11,8 +11,8 @@
 struct ptimer_state
 {
     int enabled; /* 0 = disabled, 1 = periodic, 2 = oneshot.  */
-    uint32_t limit;
-    uint32_t delta;
+    uint64_t limit;
+    uint64_t delta;
     uint32_t period_frac;
     int64_t period;
     int64_t last_event;
@@ -61,10 +61,10 @@
     }
 }
 
-uint32_t ptimer_get_count(ptimer_state *s)
+uint64_t ptimer_get_count(ptimer_state *s)
 {
     int64_t now;
-    uint32_t counter;
+    uint64_t counter;
 
     if (s->enabled) {
         now = qemu_get_clock(vm_clock);
@@ -75,8 +75,8 @@
                triggered.  */
             counter = 0;
         } else {
-            int64_t rem;
-            int64_t div;
+            uint64_t rem;
+            uint64_t div;
 
             rem = s->next_event - now;
             div = s->period;
@@ -88,7 +88,7 @@
     return counter;
 }
 
-void ptimer_set_count(ptimer_state *s, uint32_t count)
+void ptimer_set_count(ptimer_state *s, uint64_t count)
 {
     s->delta = count;
     if (s->enabled) {
@@ -108,7 +108,7 @@
     ptimer_reload(s);
 }
 
-/* Pause a timer.  Note that this may cause it to "loose" time, even if it
+/* Pause a timer.  Note that this may cause it to "lose" time, even if it
    is immediately restarted.  */
 void ptimer_stop(ptimer_state *s)
 {
@@ -123,35 +123,62 @@
 /* Set counter increment interval in nanoseconds.  */
 void ptimer_set_period(ptimer_state *s, int64_t period)
 {
+    s->period = period;
+    s->period_frac = 0;
     if (s->enabled) {
-        fprintf(stderr, "FIXME: ptimer_set_period with running timer");
+        s->next_event = qemu_get_clock(vm_clock);
+        ptimer_reload(s);
     }
-    s->period = period;
-    s->period_frac = 0;
 }
 
 /* Set counter frequency in Hz.  */
 void ptimer_set_freq(ptimer_state *s, uint32_t freq)
 {
+    s->period = 1000000000ll / freq;
+    s->period_frac = (1000000000ll << 32) / freq;
     if (s->enabled) {
-        fprintf(stderr, "FIXME: ptimer_set_freq with running timer");
+        s->next_event = qemu_get_clock(vm_clock);
+        ptimer_reload(s);
     }
-    s->period = 1000000000ll / freq;
-    s->period_frac = (1000000000ll << 32) / freq;
 }
 
 /* Set the initial countdown value.  If reload is nonzero then also set
    count = limit.  */
-void ptimer_set_limit(ptimer_state *s, uint32_t limit, int reload)
+void ptimer_set_limit(ptimer_state *s, uint64_t limit, int reload)
 {
-    if (s->enabled) {
-        fprintf(stderr, "FIXME: ptimer_set_limit with running timer");
-    }
     s->limit = limit;
     if (reload)
         s->delta = limit;
+    if (s->enabled && reload) {
+        s->next_event = qemu_get_clock(vm_clock);
+        ptimer_reload(s);
+    }
 }
 
+void qemu_put_ptimer(QEMUFile *f, ptimer_state *s)
+{
+    qemu_put_byte(f, s->enabled);
+    qemu_put_be64s(f, &s->limit);
+    qemu_put_be64s(f, &s->delta);
+    qemu_put_be32s(f, &s->period_frac);
+    qemu_put_be64s(f, &s->period);
+    qemu_put_be64s(f, &s->last_event);
+    qemu_put_be64s(f, &s->next_event);
+    qemu_put_timer(f, s->timer);
+}
+
+void qemu_get_ptimer(QEMUFile *f, ptimer_state *s)
+{
+    s->enabled = qemu_get_byte(f);
+    qemu_get_be64s(f, &s->limit);
+    qemu_get_be64s(f, &s->delta);
+    qemu_get_be32s(f, &s->period_frac);
+    qemu_get_be64s(f, &s->period);
+    qemu_get_be64s(f, &s->last_event);
+    qemu_get_be64s(f, &s->next_event);
+    qemu_get_timer(f, s->timer);
+}
+
 ptimer_state *ptimer_init(QEMUBH *bh)
 {
     ptimer_state *s;

Modified: trunk/src/host/qemu-neo1973/hw/pxa.h
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pxa.h	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/pxa.h	2007-06-17 16:55:00 UTC (rev 2289)
@@ -117,7 +117,7 @@
 
 struct pxa2xx_i2c_s;
 struct pxa2xx_i2c_s *pxa2xx_i2c_init(target_phys_addr_t base,
-                qemu_irq irq, int ioregister);
+                qemu_irq irq, uint32_t page_size);
 i2c_bus *pxa2xx_i2c_bus(struct pxa2xx_i2c_s *s);
 
 struct pxa2xx_i2s_s;

Modified: trunk/src/host/qemu-neo1973/hw/pxa2xx.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pxa2xx.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/pxa2xx.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -69,16 +69,9 @@
 #define PCMD0	0x80	/* Power Manager I2C Command register File 0 */
 #define PCMD31	0xfc	/* Power Manager I2C Command register File 31 */
 
-static uint32_t pxa2xx_i2c_read(void *, target_phys_addr_t);
-static void pxa2xx_i2c_write(void *, target_phys_addr_t, uint32_t);
-
 static uint32_t pxa2xx_pm_read(void *opaque, target_phys_addr_t addr)
 {
     struct pxa2xx_state_s *s = (struct pxa2xx_state_s *) opaque;
-    if (addr > s->pm_base + PCMD31) {
-        /* Special case: PWRI2C registers appear in the same range.  */
-        return pxa2xx_i2c_read(s->i2c[1], addr);
-    }
     addr -= s->pm_base;
 
     switch (addr) {
@@ -99,11 +92,6 @@
                 uint32_t value)
 {
     struct pxa2xx_state_s *s = (struct pxa2xx_state_s *) opaque;
-    if (addr > s->pm_base + PCMD31) {
-        /* Special case: PWRI2C registers appear in the same range.  */
-        pxa2xx_i2c_write(s->i2c[1], addr, value);
-        return;
-    }
     addr -= s->pm_base;
 
     switch (addr) {
@@ -1484,7 +1472,7 @@
 }
 
 struct pxa2xx_i2c_s *pxa2xx_i2c_init(target_phys_addr_t base,
-                qemu_irq irq, int ioregister)
+                qemu_irq irq, uint32_t page_size)
 {
     int iomemtype;
     struct pxa2xx_i2c_s *s = (struct pxa2xx_i2c_s *)
@@ -1497,11 +1485,9 @@
     s->slave.send = pxa2xx_i2c_tx;
     s->bus = i2c_init_bus();
 
-    if (ioregister) {
-        iomemtype = cpu_register_io_memory(0, pxa2xx_i2c_readfn,
-                        pxa2xx_i2c_writefn, s);
-        cpu_register_physical_memory(s->base & 0xfffff000, 0xfff, iomemtype);
-    }
+    iomemtype = cpu_register_io_memory(0, pxa2xx_i2c_readfn,
+                    pxa2xx_i2c_writefn, s);
+    cpu_register_physical_memory(s->base & ~page_size, page_size, iomemtype);
 
     register_savevm("pxa2xx_i2c", base, 0,
                     pxa2xx_i2c_save, pxa2xx_i2c_load, s);
@@ -1739,7 +1725,7 @@
 
     iomemtype = cpu_register_io_memory(0, pxa2xx_i2s_readfn,
                     pxa2xx_i2s_writefn, s);
-    cpu_register_physical_memory(s->base & 0xfff00000, 0xfffff, iomemtype);
+    cpu_register_physical_memory(s->base & 0xfff00000, 0x100000, iomemtype);
 
     register_savevm("pxa2xx_i2s", base, 0,
                     pxa2xx_i2s_save, pxa2xx_i2s_load, s);
@@ -2002,7 +1988,7 @@
 
     iomemtype = cpu_register_io_memory(0, pxa2xx_fir_readfn,
                     pxa2xx_fir_writefn, s);
-    cpu_register_physical_memory(s->base, 0xfff, iomemtype);
+    cpu_register_physical_memory(s->base, 0x1000, iomemtype);
 
     if (chr)
         qemu_chr_add_handlers(chr, pxa2xx_fir_is_empty,
@@ -2075,7 +2061,7 @@
     s->clkcfg = 0x00000009;		/* Turbo mode active */
     iomemtype = cpu_register_io_memory(0, pxa2xx_cm_readfn,
                     pxa2xx_cm_writefn, s);
-    cpu_register_physical_memory(s->cm_base, 0xfff, iomemtype);
+    cpu_register_physical_memory(s->cm_base, 0x1000, iomemtype);
     register_savevm("pxa2xx_cm", 0, 0, pxa2xx_cm_save, pxa2xx_cm_load, s);
 
     cpu_arm_set_cp_io(s->env, 14, pxa2xx_cp14_read, pxa2xx_cp14_write, s);
@@ -2086,9 +2072,15 @@
     s->mm_regs[MECR >> 2] = 0x00000001;	/* Two PC Card sockets */
     iomemtype = cpu_register_io_memory(0, pxa2xx_mm_readfn,
                     pxa2xx_mm_writefn, s);
-    cpu_register_physical_memory(s->mm_base, 0xfff, iomemtype);
+    cpu_register_physical_memory(s->mm_base, 0x1000, iomemtype);
     register_savevm("pxa2xx_mm", 0, 0, pxa2xx_mm_save, pxa2xx_mm_load, s);
 
+    s->pm_base = 0x40f00000;
+    iomemtype = cpu_register_io_memory(0, pxa2xx_pm_readfn,
+                    pxa2xx_pm_writefn, s);
+    cpu_register_physical_memory(s->pm_base, 0x100, iomemtype);
+    register_savevm("pxa2xx_pm", 0, 0, pxa2xx_pm_save, pxa2xx_pm_load, s);
+
     for (i = 0; pxa27x_ssp[i].io_base; i ++);
     s->ssp = (struct pxa2xx_ssp_s **)
             qemu_mallocz(sizeof(struct pxa2xx_ssp_s *) * i);
@@ -2101,7 +2093,7 @@
 
         iomemtype = cpu_register_io_memory(0, pxa2xx_ssp_readfn,
                         pxa2xx_ssp_writefn, &ssp[i]);
-        cpu_register_physical_memory(ssp[i].base, 0xfff, iomemtype);
+        cpu_register_physical_memory(ssp[i].base, 0x1000, iomemtype);
         register_savevm("pxa2xx_ssp", i, 0,
                         pxa2xx_ssp_save, pxa2xx_ssp_load, s);
     }
@@ -2116,22 +2108,13 @@
     s->rtc_base = 0x40900000;
     iomemtype = cpu_register_io_memory(0, pxa2xx_rtc_readfn,
                     pxa2xx_rtc_writefn, s);
-    cpu_register_physical_memory(s->rtc_base, 0xfff, iomemtype);
+    cpu_register_physical_memory(s->rtc_base, 0x1000, iomemtype);
     pxa2xx_rtc_init(s);
     register_savevm("pxa2xx_rtc", 0, 0, pxa2xx_rtc_save, pxa2xx_rtc_load, s);
 
-    /* Note that PM registers are in the same page with PWRI2C registers.
-     * As a workaround we don't map PWRI2C into memory and we expect
-     * PM handlers to call PWRI2C handlers when appropriate.  */
-    s->i2c[0] = pxa2xx_i2c_init(0x40301600, s->pic[PXA2XX_PIC_I2C], 1);
-    s->i2c[1] = pxa2xx_i2c_init(0x40f00100, s->pic[PXA2XX_PIC_PWRI2C], 0);
+    s->i2c[0] = pxa2xx_i2c_init(0x40301600, s->pic[PXA2XX_PIC_I2C], 0xffff);
+    s->i2c[1] = pxa2xx_i2c_init(0x40f00100, s->pic[PXA2XX_PIC_PWRI2C], 0xff);
 
-    s->pm_base = 0x40f00000;
-    iomemtype = cpu_register_io_memory(0, pxa2xx_pm_readfn,
-                    pxa2xx_pm_writefn, s);
-    cpu_register_physical_memory(s->pm_base, 0xfff, iomemtype);
-    register_savevm("pxa2xx_pm", 0, 0, pxa2xx_pm_save, pxa2xx_pm_load, s);
-
     s->i2s = pxa2xx_i2s_init(0x40400000, s->pic[PXA2XX_PIC_I2S], s->dma);
 
     /* GPIO1 resets the processor */
@@ -2187,7 +2170,7 @@
     s->clkcfg = 0x00000009;		/* Turbo mode active */
     iomemtype = cpu_register_io_memory(0, pxa2xx_cm_readfn,
                     pxa2xx_cm_writefn, s);
-    cpu_register_physical_memory(s->cm_base, 0xfff, iomemtype);
+    cpu_register_physical_memory(s->cm_base, 0x1000, iomemtype);
     register_savevm("pxa2xx_cm", 0, 0, pxa2xx_cm_save, pxa2xx_cm_load, s);
 
     cpu_arm_set_cp_io(s->env, 14, pxa2xx_cp14_read, pxa2xx_cp14_write, s);
@@ -2198,9 +2181,15 @@
     s->mm_regs[MECR >> 2] = 0x00000001;	/* Two PC Card sockets */
     iomemtype = cpu_register_io_memory(0, pxa2xx_mm_readfn,
                     pxa2xx_mm_writefn, s);
-    cpu_register_physical_memory(s->mm_base, 0xfff, iomemtype);
+    cpu_register_physical_memory(s->mm_base, 0x1000, iomemtype);
     register_savevm("pxa2xx_mm", 0, 0, pxa2xx_mm_save, pxa2xx_mm_load, s);
 
+    s->pm_base = 0x40f00000;
+    iomemtype = cpu_register_io_memory(0, pxa2xx_pm_readfn,
+                    pxa2xx_pm_writefn, s);
+    cpu_register_physical_memory(s->pm_base, 0x100, iomemtype);
+    register_savevm("pxa2xx_pm", 0, 0, pxa2xx_pm_save, pxa2xx_pm_load, s);
+
     for (i = 0; pxa255_ssp[i].io_base; i ++);
     s->ssp = (struct pxa2xx_ssp_s **)
             qemu_mallocz(sizeof(struct pxa2xx_ssp_s *) * i);
@@ -2213,7 +2202,7 @@
 
         iomemtype = cpu_register_io_memory(0, pxa2xx_ssp_readfn,
                         pxa2xx_ssp_writefn, &ssp[i]);
-        cpu_register_physical_memory(ssp[i].base, 0xfff, iomemtype);
+        cpu_register_physical_memory(ssp[i].base, 0x1000, iomemtype);
         register_savevm("pxa2xx_ssp", i, 0,
                         pxa2xx_ssp_save, pxa2xx_ssp_load, s);
     }
@@ -2228,22 +2217,13 @@
     s->rtc_base = 0x40900000;
     iomemtype = cpu_register_io_memory(0, pxa2xx_rtc_readfn,
                     pxa2xx_rtc_writefn, s);
-    cpu_register_physical_memory(s->rtc_base, 0xfff, iomemtype);
+    cpu_register_physical_memory(s->rtc_base, 0x1000, iomemtype);
     pxa2xx_rtc_init(s);
     register_savevm("pxa2xx_rtc", 0, 0, pxa2xx_rtc_save, pxa2xx_rtc_load, s);
 
-    /* Note that PM registers are in the same page with PWRI2C registers.
-     * As a workaround we don't map PWRI2C into memory and we expect
-     * PM handlers to call PWRI2C handlers when appropriate.  */
-    s->i2c[0] = pxa2xx_i2c_init(0x40301600, s->pic[PXA2XX_PIC_I2C], 1);
-    s->i2c[1] = pxa2xx_i2c_init(0x40f00100, s->pic[PXA2XX_PIC_PWRI2C], 0);
+    s->i2c[0] = pxa2xx_i2c_init(0x40301600, s->pic[PXA2XX_PIC_I2C], 0xffff);
+    s->i2c[1] = pxa2xx_i2c_init(0x40f00100, s->pic[PXA2XX_PIC_PWRI2C], 0xff);
 
-    s->pm_base = 0x40f00000;
-    iomemtype = cpu_register_io_memory(0, pxa2xx_pm_readfn,
-                    pxa2xx_pm_writefn, s);
-    cpu_register_physical_memory(s->pm_base, 0xfff, iomemtype);
-    register_savevm("pxa2xx_pm", 0, 0, pxa2xx_pm_save, pxa2xx_pm_load, s);
-
     s->i2s = pxa2xx_i2s_init(0x40400000, s->pic[PXA2XX_PIC_I2S], s->dma);
 
     /* GPIO1 resets the processor */

Modified: trunk/src/host/qemu-neo1973/hw/pxa2xx_dma.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pxa2xx_dma.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/pxa2xx_dma.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -508,7 +508,7 @@
 
     iomemtype = cpu_register_io_memory(0, pxa2xx_dma_readfn,
                     pxa2xx_dma_writefn, s);
-    cpu_register_physical_memory(base, 0x0000ffff, iomemtype);
+    cpu_register_physical_memory(base, 0x00010000, iomemtype);
 
     register_savevm("pxa2xx_dma", 0, 0, pxa2xx_dma_save, pxa2xx_dma_load, s);
 

Modified: trunk/src/host/qemu-neo1973/hw/pxa2xx_gpio.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pxa2xx_gpio.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/pxa2xx_gpio.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -308,7 +308,7 @@
 
     iomemtype = cpu_register_io_memory(0, pxa2xx_gpio_readfn,
                     pxa2xx_gpio_writefn, s);
-    cpu_register_physical_memory(base, 0x00000fff, iomemtype);
+    cpu_register_physical_memory(base, 0x00001000, iomemtype);
 
     register_savevm("pxa2xx_gpio", 0, 0,
                     pxa2xx_gpio_save, pxa2xx_gpio_load, s);

Modified: trunk/src/host/qemu-neo1973/hw/pxa2xx_lcd.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pxa2xx_lcd.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/pxa2xx_lcd.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -8,6 +8,7 @@
  */
 
 #include "vl.h"
+#include "pixel_ops.h"
 
 typedef void (*drawfn)(uint32_t *, uint8_t *, const uint8_t *, int, int);
 
@@ -575,36 +576,6 @@
     pxa2xx_lcdc_write
 };
 
-static inline
-uint32_t rgb_to_pixel8(unsigned int r, unsigned int g, unsigned b)
-{
-    return ((r >> 5) << 5) | ((g >> 5) << 2) | (b >> 6);
-}
-
-static inline
-uint32_t rgb_to_pixel15(unsigned int r, unsigned int g, unsigned b)
-{
-    return ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);
-}
-
-static inline
-uint32_t rgb_to_pixel16(unsigned int r, unsigned int g, unsigned b)
-{
-    return ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
-}
-
-static inline
-uint32_t rgb_to_pixel24(unsigned int r, unsigned int g, unsigned b)
-{
-    return (r << 16) | (g << 8) | b;
-}
-
-static inline
-uint32_t rgb_to_pixel32(unsigned int r, unsigned int g, unsigned b)
-{
-    return (r << 16) | (g << 8) | b;
-}
-
 /* Load new palette for a given DMA channel, convert to internal format */
 static void pxa2xx_palette_parse(struct pxa2xx_lcdc_s *s, int ch, int bpp)
 {
@@ -1026,7 +997,7 @@
 
     iomemtype = cpu_register_io_memory(0, pxa2xx_lcdc_readfn,
                     pxa2xx_lcdc_writefn, s);
-    cpu_register_physical_memory(base, 0x000fffff, iomemtype);
+    cpu_register_physical_memory(base, 0x00100000, iomemtype);
 
     graphic_console_init(ds, pxa2xx_update_display,
                     pxa2xx_invalidate_display, pxa2xx_screen_dump, s);

Modified: trunk/src/host/qemu-neo1973/hw/pxa2xx_mmci.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pxa2xx_mmci.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/pxa2xx_mmci.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -534,7 +534,7 @@
 
     iomemtype = cpu_register_io_memory(0, pxa2xx_mmci_readfn,
                     pxa2xx_mmci_writefn, s);
-    cpu_register_physical_memory(base, 0x000fffff, iomemtype);
+    cpu_register_physical_memory(base, 0x00100000, iomemtype);
 
     /* Instantiate the actual storage */
     s->card = sd_init(sd_bdrv);

Modified: trunk/src/host/qemu-neo1973/hw/pxa2xx_pcmcia.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pxa2xx_pcmcia.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/pxa2xx_pcmcia.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -149,7 +149,7 @@
     s->io_base = base | 0x00000000;
     iomemtype = cpu_register_io_memory(0, pxa2xx_pcmcia_io_readfn,
                     pxa2xx_pcmcia_io_writefn, s);
-    cpu_register_physical_memory(s->io_base, 0x03ffffff, iomemtype);
+    cpu_register_physical_memory(s->io_base, 0x04000000, iomemtype);
 
     /* Then next 64 MB is reserved */
 
@@ -157,13 +157,13 @@
     s->attr_base = base | 0x08000000;
     iomemtype = cpu_register_io_memory(0, pxa2xx_pcmcia_attr_readfn,
                     pxa2xx_pcmcia_attr_writefn, s);
-    cpu_register_physical_memory(s->attr_base, 0x03ffffff, iomemtype);
+    cpu_register_physical_memory(s->attr_base, 0x04000000, iomemtype);
 
     /* Socket Common Memory Space */
     s->common_base = base | 0x0c000000;
     iomemtype = cpu_register_io_memory(0, pxa2xx_pcmcia_common_readfn,
                     pxa2xx_pcmcia_common_writefn, s);
-    cpu_register_physical_memory(s->common_base, 0x03ffffff, iomemtype);
+    cpu_register_physical_memory(s->common_base, 0x04000000, iomemtype);
 
     if (base == 0x30000000)
         s->slot.slot_string = "PXA PC Card Socket 1";

Modified: trunk/src/host/qemu-neo1973/hw/pxa2xx_pic.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pxa2xx_pic.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/pxa2xx_pic.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -306,7 +306,7 @@
     /* Enable IC memory-mapped registers access.  */
     iomemtype = cpu_register_io_memory(0, pxa2xx_pic_readfn,
                     pxa2xx_pic_writefn, s);
-    cpu_register_physical_memory(base, 0x000fffff, iomemtype);
+    cpu_register_physical_memory(base, 0x00100000, iomemtype);
 
     /* Enable IC coprocessor access.  */
     cpu_arm_set_cp_io(env, 6, pxa2xx_pic_cp_read, pxa2xx_pic_cp_write, s);

Modified: trunk/src/host/qemu-neo1973/hw/pxa2xx_timer.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pxa2xx_timer.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/pxa2xx_timer.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -458,7 +458,7 @@
 
     iomemtype = cpu_register_io_memory(0, pxa2xx_timer_readfn,
                     pxa2xx_timer_writefn, s);
-    cpu_register_physical_memory(base, 0x00000fff, iomemtype);
+    cpu_register_physical_memory(base, 0x00001000, iomemtype);
 
     register_savevm("pxa2xx_timer", 0, 0,
                     pxa2xx_timer_save, pxa2xx_timer_load, s);

Modified: trunk/src/host/qemu-neo1973/hw/scsi-disk.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/scsi-disk.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/scsi-disk.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -489,7 +489,7 @@
         is_write = 1;
         break;
     case 0x35:
-        DPRINTF("Syncronise cache (sector %d, count %d)\n", lba, len);
+        DPRINTF("Synchronise cache (sector %d, count %d)\n", lba, len);
         bdrv_flush(s->bdrv);
         break;
     case 0x43:

Modified: trunk/src/host/qemu-neo1973/hw/serial.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/serial.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/serial.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -86,7 +86,7 @@
     qemu_irq irq;
     CharDriverState *chr;
     int last_break_enable;
-    target_ulong base;
+    target_phys_addr_t base;
     int it_shift;
 };
 
@@ -384,30 +384,44 @@
 uint32_t serial_mm_readw (void *opaque, target_phys_addr_t addr)
 {
     SerialState *s = opaque;
+    uint32_t val;
 
-    return serial_ioport_read(s, (addr - s->base) >> s->it_shift) & 0xFFFF;
+    val = serial_ioport_read(s, (addr - s->base) >> s->it_shift) & 0xFFFF;
+#ifdef TARGET_WORDS_BIGENDIAN
+    val = bswap16(val);
+#endif
+    return val;
 }
 
 void serial_mm_writew (void *opaque,
                        target_phys_addr_t addr, uint32_t value)
 {
     SerialState *s = opaque;
-
+#ifdef TARGET_WORDS_BIGENDIAN
+    value = bswap16(value);
+#endif
     serial_ioport_write(s, (addr - s->base) >> s->it_shift, value & 0xFFFF);
 }
 
 uint32_t serial_mm_readl (void *opaque, target_phys_addr_t addr)
 {
     SerialState *s = opaque;
+    uint32_t val;
 
-    return serial_ioport_read(s, (addr - s->base) >> s->it_shift);
+    val = serial_ioport_read(s, (addr - s->base) >> s->it_shift);
+#ifdef TARGET_WORDS_BIGENDIAN
+    val = bswap32(val);
+#endif
+    return val;
 }
 
 void serial_mm_writel (void *opaque,
                        target_phys_addr_t addr, uint32_t value)
 {
     SerialState *s = opaque;
-
+#ifdef TARGET_WORDS_BIGENDIAN
+    value = bswap32(value);
+#endif
     serial_ioport_write(s, (addr - s->base) >> s->it_shift, value);
 }
 
@@ -423,7 +437,7 @@
     &serial_mm_writel,
 };
 
-SerialState *serial_mm_init (target_ulong base, int it_shift,
+SerialState *serial_mm_init (target_phys_addr_t base, int it_shift,
                              qemu_irq irq, CharDriverState *chr,
                              int ioregister)
 {

Modified: trunk/src/host/qemu-neo1973/hw/slavio_intctl.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/slavio_intctl.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/slavio_intctl.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -44,6 +44,7 @@
  */
 
 #define MAX_CPUS 16
+#define MAX_PILS 16
 
 typedef struct SLAVIO_INTCTLState {
     uint32_t intreg_pending[MAX_CPUS];
@@ -53,12 +54,16 @@
 #ifdef DEBUG_IRQ_COUNT
     uint64_t irq_count[32];
 #endif
-    CPUState *cpu_envs[MAX_CPUS];
+    qemu_irq *cpu_irqs[MAX_CPUS];
     const uint32_t *intbit_to_level;
+    uint32_t cputimer_bit;
+    uint32_t pil_out[MAX_CPUS];
 } SLAVIO_INTCTLState;
 
 #define INTCTL_MAXADDR 0xf
+#define INTCTL_SIZE (INTCTL_MAXADDR + 1)
 #define INTCTLM_MAXADDR 0x13
+#define INTCTLM_SIZE (INTCTLM_MAXADDR + 1)
 #define INTCTLM_MASK 0x1f
 static void slavio_check_interrupts(void *opaque);
 
@@ -66,18 +71,22 @@
 static uint32_t slavio_intctl_mem_readl(void *opaque, target_phys_addr_t addr)
 {
     SLAVIO_INTCTLState *s = opaque;
-    uint32_t saddr;
+    uint32_t saddr, ret;
     int cpu;
 
     cpu = (addr & (MAX_CPUS - 1) * TARGET_PAGE_SIZE) >> 12;
     saddr = (addr & INTCTL_MAXADDR) >> 2;
     switch (saddr) {
     case 0:
-	return s->intreg_pending[cpu];
+        ret = s->intreg_pending[cpu];
+        break;
     default:
-	break;
+        ret = 0;
+        break;
     }
-    return 0;
+    DPRINTF("read cpu %d reg 0x%x = %x\n", addr, ret);
+
+    return ret;
 }
 
 static void slavio_intctl_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
@@ -88,6 +97,7 @@
 
     cpu = (addr & (MAX_CPUS - 1) * TARGET_PAGE_SIZE) >> 12;
     saddr = (addr & INTCTL_MAXADDR) >> 2;
+    DPRINTF("write cpu %d reg 0x%x = %x\n", cpu, addr, val);
     switch (saddr) {
     case 1: // clear pending softints
 	if (val & 0x4000)
@@ -123,20 +133,26 @@
 static uint32_t slavio_intctlm_mem_readl(void *opaque, target_phys_addr_t addr)
 {
     SLAVIO_INTCTLState *s = opaque;
-    uint32_t saddr;
+    uint32_t saddr, ret;
 
     saddr = (addr & INTCTLM_MAXADDR) >> 2;
     switch (saddr) {
     case 0:
-	return s->intregm_pending & 0x7fffffff;
+        ret = s->intregm_pending & 0x7fffffff;
+        break;
     case 1:
-	return s->intregm_disabled;
+        ret = s->intregm_disabled;
+        break;
     case 4:
-	return s->target_cpu;
+        ret = s->target_cpu;
+        break;
     default:
-	break;
+        ret = 0;
+        break;
     }
-    return 0;
+    DPRINTF("read system reg 0x%x = %x\n", addr, ret);
+
+    return ret;
 }
 
 static void slavio_intctlm_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
@@ -145,6 +161,7 @@
     uint32_t saddr;
 
     saddr = (addr & INTCTLM_MASK) >> 2;
+    DPRINTF("write system reg 0x%x = %x\n", addr, val);
     switch (saddr) {
     case 2: // clear (enable)
 	// Force clear unused bits
@@ -210,67 +227,53 @@
 #endif
 }
 
+static void raise_pil(SLAVIO_INTCTLState *s, unsigned int pil,
+                      unsigned int cpu)
+{
+    qemu_irq irq;
+    unsigned int oldmax;
+
+    irq = s->cpu_irqs[cpu][pil];
+
+#ifdef DEBUG_IRQ_COUNT
+    s->irq_count[pil]++;
+#endif
+    oldmax = s->pil_out[cpu];
+    if (oldmax > 0 && oldmax != pil)
+        qemu_irq_lower(s->cpu_irqs[cpu][oldmax]);
+    s->pil_out[cpu] = pil;
+    if (pil > 0)
+        qemu_irq_raise(irq);
+    DPRINTF("cpu %d pil %d\n", cpu, pil);
+}
+
 static void slavio_check_interrupts(void *opaque)
 {
-    CPUState *env;
     SLAVIO_INTCTLState *s = opaque;
     uint32_t pending = s->intregm_pending;
     unsigned int i, j, max = 0;
 
     pending &= ~s->intregm_disabled;
 
-    if (pending && !(s->intregm_disabled & 0x80000000)) {
-	for (i = 0; i < 32; i++) {
-	    if (pending & (1 << i)) {
-		if (max < s->intbit_to_level[i])
-		    max = s->intbit_to_level[i];
-	    }
-	}
-        env = s->cpu_envs[s->target_cpu];
-        if (!env) {
-	    DPRINTF("No CPU %d, not triggered (pending %x)\n", s->target_cpu, pending);
-        }
-	else {
-            if (env->halted)
-                env->halted = 0;
-            if (env->interrupt_index == 0) {
-                DPRINTF("Triggered CPU %d pil %d\n", s->target_cpu, max);
-#ifdef DEBUG_IRQ_COUNT
-                s->irq_count[max]++;
-#endif
-                env->interrupt_index = TT_EXTINT | max;
-                cpu_interrupt(env, CPU_INTERRUPT_HARD);
-            }
-            else
-                DPRINTF("Not triggered (pending %x), pending exception %x\n", pending, env->interrupt_index);
-	}
-    }
-    else
-	DPRINTF("Not triggered (pending %x), disabled %x\n", pending, s->intregm_disabled);
-    
+    DPRINTF("pending %x disabled %x\n", pending, s->intregm_disabled);
     for (i = 0; i < MAX_CPUS; i++) {
         max = 0;
-        env = s->cpu_envs[i];
-        if (!env)
-            continue;
+        if (pending && !(s->intregm_disabled & 0x80000000) &&
+            (i == s->target_cpu)) {
+            for (j = 0; j < 32; j++) {
+                if (pending & (1 << j)) {
+                    if (max < s->intbit_to_level[j])
+                        max = s->intbit_to_level[j];
+                }
+            }
+        }
         for (j = 17; j < 32; j++) {
             if (s->intreg_pending[i] & (1 << j)) {
                 if (max < j - 16)
                     max = j - 16;
             }
         }
-	if (max > 0) {
-            if (env->halted)
-                env->halted = 0;
-            if (env->interrupt_index == 0) {
-                DPRINTF("Triggered softint %d for cpu %d (pending %x)\n", max, i, pending);
-#ifdef DEBUG_IRQ_COUNT
-                s->irq_count[max]++;
-#endif
-                env->interrupt_index = TT_EXTINT | max;
-                cpu_interrupt(env, CPU_INTERRUPT_HARD);
-            }
-        }
+        raise_pil(s, max, i);
     }
 }
 
@@ -278,48 +281,37 @@
  * "irq" here is the bit number in the system interrupt register to
  * separate serial and keyboard interrupts sharing a level.
  */
-void slavio_set_irq(void *opaque, int irq, int level)
+static void slavio_set_irq(void *opaque, int irq, int level)
 {
     SLAVIO_INTCTLState *s = opaque;
+    uint32_t mask = 1 << irq;
+    uint32_t pil = s->intbit_to_level[irq];
 
-    DPRINTF("Set cpu %d irq %d level %d\n", s->target_cpu, irq, level);
-    if (irq < 32) {
-	uint32_t mask = 1 << irq;
-	uint32_t pil = s->intbit_to_level[irq];
-	if (pil > 0) {
-	    if (level) {
-		s->intregm_pending |= mask;
-		s->intreg_pending[s->target_cpu] |= 1 << pil;
-		slavio_check_interrupts(s);
-	    }
-	    else {
-		s->intregm_pending &= ~mask;
-		s->intreg_pending[s->target_cpu] &= ~(1 << pil);
-	    }
-	}
+    DPRINTF("Set cpu %d irq %d -> pil %d level %d\n", s->target_cpu, irq, pil,
+            level);
+    if (pil > 0) {
+        if (level) {
+            s->intregm_pending |= mask;
+            s->intreg_pending[s->target_cpu] |= 1 << pil;
+        } else {
+            s->intregm_pending &= ~mask;
+            s->intreg_pending[s->target_cpu] &= ~(1 << pil);
+        }
+        slavio_check_interrupts(s);
     }
 }
 
-void pic_set_irq_cpu(void *opaque, int irq, int level, unsigned int cpu)
+static void slavio_set_timer_irq_cpu(void *opaque, int cpu, int level)
 {
     SLAVIO_INTCTLState *s = opaque;
 
-    DPRINTF("Set cpu %d local irq %d level %d\n", cpu, irq, level);
-    if (cpu == (unsigned int)-1) {
-        slavio_set_irq(opaque, irq, level);
-        return;
-    }
-    if (irq < 32) {
-	uint32_t pil = s->intbit_to_level[irq];
-    	if (pil > 0) {
-	    if (level) {
-		s->intreg_pending[cpu] |= 1 << pil;
-	    }
-	    else {
-		s->intreg_pending[cpu] &= ~(1 << pil);
-	    }
-	}
-    }
+    DPRINTF("Set cpu %d local timer level %d\n", cpu, level);
+
+    if (level)
+        s->intreg_pending[cpu] |= s->cputimer_bit;
+    else
+        s->intreg_pending[cpu] &= ~s->cputimer_bit;
+
     slavio_check_interrupts(s);
 }
 
@@ -366,15 +358,10 @@
     s->target_cpu = 0;
 }
 
-void slavio_intctl_set_cpu(void *opaque, unsigned int cpu, CPUState *env)
-{
-    SLAVIO_INTCTLState *s = opaque;
-    s->cpu_envs[cpu] = env;
-}
-
 void *slavio_intctl_init(target_phys_addr_t addr, target_phys_addr_t addrg,
                          const uint32_t *intbit_to_level,
-                         qemu_irq **irq)
+                         qemu_irq **irq, qemu_irq **cpu_irq,
+                         qemu_irq **parent_irq, unsigned int cputimer)
 {
     int slavio_intctl_io_memory, slavio_intctlm_io_memory, i;
     SLAVIO_INTCTLState *s;
@@ -386,15 +373,20 @@
     s->intbit_to_level = intbit_to_level;
     for (i = 0; i < MAX_CPUS; i++) {
 	slavio_intctl_io_memory = cpu_register_io_memory(0, slavio_intctl_mem_read, slavio_intctl_mem_write, s);
-	cpu_register_physical_memory(addr + i * TARGET_PAGE_SIZE, INTCTL_MAXADDR, slavio_intctl_io_memory);
+	cpu_register_physical_memory(addr + i * TARGET_PAGE_SIZE, INTCTL_SIZE,
+                                     slavio_intctl_io_memory);
+        s->cpu_irqs[i] = parent_irq[i];
     }
 
     slavio_intctlm_io_memory = cpu_register_io_memory(0, slavio_intctlm_mem_read, slavio_intctlm_mem_write, s);
-    cpu_register_physical_memory(addrg, INTCTLM_MAXADDR, slavio_intctlm_io_memory);
+    cpu_register_physical_memory(addrg, INTCTLM_SIZE, slavio_intctlm_io_memory);
 
     register_savevm("slavio_intctl", addr, 1, slavio_intctl_save, slavio_intctl_load, s);
     qemu_register_reset(slavio_intctl_reset, s);
     *irq = qemu_allocate_irqs(slavio_set_irq, s, 32);
+
+    *cpu_irq = qemu_allocate_irqs(slavio_set_timer_irq_cpu, s, MAX_CPUS);
+    s->cputimer_bit = 1 << s->intbit_to_level[cputimer];
     slavio_intctl_reset(s);
     return s;
 }

Modified: trunk/src/host/qemu-neo1973/hw/slavio_misc.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/slavio_misc.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/slavio_misc.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -47,7 +47,7 @@
     uint8_t diag, mctrl, sysctrl;
 } MiscState;
 
-#define MISC_MAXADDR 1
+#define MISC_SIZE 1
 
 static void slavio_misc_update_irq(void *opaque)
 {
@@ -224,19 +224,25 @@
 
     slavio_misc_io_memory = cpu_register_io_memory(0, slavio_misc_mem_read, slavio_misc_mem_write, s);
     // Slavio control
-    cpu_register_physical_memory(base + 0x1800000, MISC_MAXADDR, slavio_misc_io_memory);
+    cpu_register_physical_memory(base + 0x1800000, MISC_SIZE,
+                                 slavio_misc_io_memory);
     // AUX 1
-    cpu_register_physical_memory(base + 0x1900000, MISC_MAXADDR, slavio_misc_io_memory);
+    cpu_register_physical_memory(base + 0x1900000, MISC_SIZE,
+                                 slavio_misc_io_memory);
     // AUX 2
-    cpu_register_physical_memory(base + 0x1910000, MISC_MAXADDR, slavio_misc_io_memory);
+    cpu_register_physical_memory(base + 0x1910000, MISC_SIZE,
+                                 slavio_misc_io_memory);
     // Diagnostics
-    cpu_register_physical_memory(base + 0x1a00000, MISC_MAXADDR, slavio_misc_io_memory);
+    cpu_register_physical_memory(base + 0x1a00000, MISC_SIZE,
+                                 slavio_misc_io_memory);
     // Modem control
-    cpu_register_physical_memory(base + 0x1b00000, MISC_MAXADDR, slavio_misc_io_memory);
+    cpu_register_physical_memory(base + 0x1b00000, MISC_SIZE,
+                                 slavio_misc_io_memory);
     // System control
-    cpu_register_physical_memory(base + 0x1f00000, MISC_MAXADDR, slavio_misc_io_memory);
+    cpu_register_physical_memory(base + 0x1f00000, MISC_SIZE,
+                                 slavio_misc_io_memory);
     // Power management
-    cpu_register_physical_memory(power_base, MISC_MAXADDR, slavio_misc_io_memory);
+    cpu_register_physical_memory(power_base, MISC_SIZE, slavio_misc_io_memory);
 
     s->irq = irq;
 

Modified: trunk/src/host/qemu-neo1973/hw/slavio_serial.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/slavio_serial.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/slavio_serial.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -102,6 +102,7 @@
 };
 
 #define SERIAL_MAXADDR 7
+#define SERIAL_SIZE (SERIAL_MAXADDR + 1)
 
 static void handle_kbd_command(ChannelState *s, int val);
 static int serial_can_receive(void *opaque);
@@ -178,7 +179,7 @@
     int i;
 
     s->reg = 0;
-    for (i = 0; i < SERIAL_MAXADDR; i++) {
+    for (i = 0; i < SERIAL_SIZE; i++) {
 	s->rregs[i] = 0;
 	s->wregs[i] = 0;
     }
@@ -598,7 +599,7 @@
         return NULL;
 
     slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
-    cpu_register_physical_memory(base, SERIAL_MAXADDR, slavio_serial_io_memory);
+    cpu_register_physical_memory(base, SERIAL_SIZE, slavio_serial_io_memory);
 
     s->chn[0].chr = chr1;
     s->chn[1].chr = chr2;
@@ -723,7 +724,7 @@
     s->chn[1].type = kbd;
 
     slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
-    cpu_register_physical_memory(base, SERIAL_MAXADDR, slavio_serial_io_memory);
+    cpu_register_physical_memory(base, SERIAL_SIZE, slavio_serial_io_memory);
 
     qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0, "QEMU Sun Mouse");
     qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);

Modified: trunk/src/host/qemu-neo1973/hw/slavio_timer.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/slavio_timer.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/slavio_timer.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -48,61 +48,28 @@
  */
 
 typedef struct SLAVIO_TIMERState {
-    uint32_t limit, count, counthigh;
-    int64_t count_load_time;
-    int64_t expire_time;
-    int64_t stop_time, tick_offset;
-    QEMUTimer *irq_timer;
-    int irq;
-    int reached, stopped;
+    qemu_irq irq;
+    ptimer_state *timer;
+    uint32_t count, counthigh, reached;
+    uint64_t limit;
+    int stopped;
     int mode; // 0 = processor, 1 = user, 2 = system
-    unsigned int cpu;
-    void *intctl;
 } SLAVIO_TIMERState;
 
 #define TIMER_MAXADDR 0x1f
-#define CNT_FREQ 2000000
+#define TIMER_SIZE (TIMER_MAXADDR + 1)
 
 // Update count, set irq, update expire_time
+// Convert from ptimer countdown units
 static void slavio_timer_get_out(SLAVIO_TIMERState *s)
 {
-    int out;
-    int64_t diff, ticks, count;
-    uint32_t limit;
+    uint64_t count;
 
-    // There are three clock tick units: CPU ticks, register units
-    // (nanoseconds), and counter ticks (500 ns).
-    if (s->mode == 1 && s->stopped)
-	ticks = s->stop_time;
-    else
-	ticks = qemu_get_clock(vm_clock) - s->tick_offset;
-
-    out = (ticks > s->expire_time);
-    if (out)
-	s->reached = 0x80000000;
-    // Convert register units to counter ticks
-    limit = s->limit >> 9;
-
-    if (!limit)
-	limit = 0x7fffffff >> 9;
-
-    // Convert cpu ticks to counter ticks
-    diff = muldiv64(ticks - s->count_load_time, CNT_FREQ, ticks_per_sec);
-
-    // Calculate what the counter should be, convert to register
-    // units
-    count = diff % limit;
-    s->count = count << 9;
-    s->counthigh = count >> 22;
-
-    // Expire time: CPU ticks left to next interrupt
-    // Convert remaining counter ticks to CPU ticks
-    s->expire_time = ticks + muldiv64(limit - count, ticks_per_sec, CNT_FREQ);
-
-    DPRINTF("irq %d limit %d reached %d d %" PRId64 " count %d s->c %x diff %" PRId64 " stopped %d mode %d\n", s->irq, limit, s->reached?1:0, (ticks-s->count_load_time), count, s->count, s->expire_time - ticks, s->stopped, s->mode);
-
-    if (s->mode != 1)
-	pic_set_irq_cpu(s->intctl, s->irq, out, s->cpu);
+    count = s->limit - (ptimer_get_count(s->timer) << 9);
+    DPRINTF("get_out: limit %" PRIx64 " count %x%08x\n", s->limit, s->counthigh,
+            s->count);
+    s->count = count & 0xfffffe00;
+    s->counthigh = count >> 32;
 }
 
 // timer callback
@@ -110,17 +77,17 @@
 {
     SLAVIO_TIMERState *s = opaque;
 
-    if (!s->irq_timer)
-        return;
     slavio_timer_get_out(s);
+    DPRINTF("callback: count %x%08x\n", s->counthigh, s->count);
+    s->reached = 0x80000000;
     if (s->mode != 1)
-	qemu_mod_timer(s->irq_timer, s->expire_time);
+	qemu_irq_raise(s->irq);
 }
 
 static uint32_t slavio_timer_mem_readl(void *opaque, target_phys_addr_t addr)
 {
     SLAVIO_TIMERState *s = opaque;
-    uint32_t saddr;
+    uint32_t saddr, ret;
 
     saddr = (addr & TIMER_MAXADDR) >> 2;
     switch (saddr) {
@@ -129,62 +96,71 @@
 	// part of counter (user mode)
 	if (s->mode != 1) {
 	    // clear irq
-	    pic_set_irq_cpu(s->intctl, s->irq, 0, s->cpu);
+            qemu_irq_lower(s->irq);
 	    s->reached = 0;
-	    return s->limit;
+            ret = s->limit & 0x7fffffff;
 	}
 	else {
 	    slavio_timer_get_out(s);
-	    return s->counthigh & 0x7fffffff;
+            ret = s->counthigh & 0x7fffffff;
 	}
+        break;
     case 1:
 	// read counter and reached bit (system mode) or read lsbits
 	// of counter (user mode)
 	slavio_timer_get_out(s);
 	if (s->mode != 1)
-	    return (s->count & 0x7fffffff) | s->reached;
+            ret = (s->count & 0x7fffffff) | s->reached;
 	else
-	    return s->count;
+            ret = s->count;
+        break;
     case 3:
 	// read start/stop status
-	return s->stopped;
+        ret = s->stopped;
+        break;
     case 4:
 	// read user/system mode
-	return s->mode & 1;
+        ret = s->mode & 1;
+        break;
     default:
-	return 0;
+        ret = 0;
+        break;
     }
+    DPRINTF("read " TARGET_FMT_plx " = %08x\n", addr, ret);
+
+    return ret;
 }
 
 static void slavio_timer_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
 {
     SLAVIO_TIMERState *s = opaque;
     uint32_t saddr;
+    int reload = 0;
 
+    DPRINTF("write " TARGET_FMT_plx " %08x\n", addr, val);
     saddr = (addr & TIMER_MAXADDR) >> 2;
     switch (saddr) {
     case 0:
 	// set limit, reset counter
-	s->count_load_time = qemu_get_clock(vm_clock);
+        reload = 1;
+	qemu_irq_lower(s->irq);
 	// fall through
     case 2:
 	// set limit without resetting counter
-	if (!val)
-	    s->limit = 0x7fffffff;
-	else
-	    s->limit = val & 0x7fffffff;
-	slavio_timer_irq(s);
+        s->limit = val & 0x7ffffe00ULL;
+        if (!s->limit)
+            s->limit = 0x7ffffe00ULL;
+        ptimer_set_limit(s->timer, s->limit >> 9, reload);
 	break;
     case 3:
 	// start/stop user counter
 	if (s->mode == 1) {
 	    if (val & 1) {
-		s->stop_time = qemu_get_clock(vm_clock);
+                ptimer_stop(s->timer);
 		s->stopped = 1;
 	    }
 	    else {
-		if (s->stopped)
-		    s->tick_offset += qemu_get_clock(vm_clock) - s->stop_time;
+                ptimer_run(s->timer, 0);
 		s->stopped = 0;
 	    }
 	}
@@ -193,6 +169,11 @@
 	// bit 0: user (1) or system (0) counter mode
 	if (s->mode == 0 || s->mode == 1)
 	    s->mode = val & 1;
+        if (s->mode == 1) {
+            qemu_irq_lower(s->irq);
+            s->limit = -1ULL;
+        }
+        ptimer_set_limit(s->timer, s->limit >> 9, 1);
 	break;
     default:
 	break;
@@ -215,37 +196,33 @@
 {
     SLAVIO_TIMERState *s = opaque;
 
-    qemu_put_be32s(f, &s->limit);
+    qemu_put_be64s(f, &s->limit);
     qemu_put_be32s(f, &s->count);
     qemu_put_be32s(f, &s->counthigh);
-    qemu_put_be64s(f, &s->count_load_time);
-    qemu_put_be64s(f, &s->expire_time);
-    qemu_put_be64s(f, &s->stop_time);
-    qemu_put_be64s(f, &s->tick_offset);
-    qemu_put_be32s(f, &s->irq);
+    qemu_put_be32(f, 0); // Was irq
     qemu_put_be32s(f, &s->reached);
     qemu_put_be32s(f, &s->stopped);
     qemu_put_be32s(f, &s->mode);
+    qemu_put_ptimer(f, s->timer);
 }
 
 static int slavio_timer_load(QEMUFile *f, void *opaque, int version_id)
 {
     SLAVIO_TIMERState *s = opaque;
+    uint32_t tmp;
     
-    if (version_id != 1)
+    if (version_id != 2)
         return -EINVAL;
 
-    qemu_get_be32s(f, &s->limit);
+    qemu_get_be64s(f, &s->limit);
     qemu_get_be32s(f, &s->count);
     qemu_get_be32s(f, &s->counthigh);
-    qemu_get_be64s(f, &s->count_load_time);
-    qemu_get_be64s(f, &s->expire_time);
-    qemu_get_be64s(f, &s->stop_time);
-    qemu_get_be64s(f, &s->tick_offset);
-    qemu_get_be32s(f, &s->irq);
+    qemu_get_be32s(f, &tmp); // Was irq
     qemu_get_be32s(f, &s->reached);
     qemu_get_be32s(f, &s->stopped);
     qemu_get_be32s(f, &s->mode);
+    qemu_get_ptimer(f, s->timer);
+
     return 0;
 }
 
@@ -253,36 +230,35 @@
 {
     SLAVIO_TIMERState *s = opaque;
 
-    s->limit = 0;
+    s->limit = 0x7ffffe00ULL;
     s->count = 0;
-    s->count_load_time = qemu_get_clock(vm_clock);;
-    s->stop_time = s->count_load_time;
-    s->tick_offset = 0;
     s->reached = 0;
     s->mode &= 2;
+    ptimer_set_limit(s->timer, s->limit >> 9, 1);
+    ptimer_run(s->timer, 0);
     s->stopped = 1;
-    slavio_timer_irq(s);
+    qemu_irq_lower(s->irq);
 }
 
-void slavio_timer_init(target_phys_addr_t addr, int irq, int mode,
-                       unsigned int cpu, void *intctl)
+void slavio_timer_init(target_phys_addr_t addr, qemu_irq irq, int mode)
 {
     int slavio_timer_io_memory;
     SLAVIO_TIMERState *s;
+    QEMUBH *bh;
 
     s = qemu_mallocz(sizeof(SLAVIO_TIMERState));
     if (!s)
         return;
     s->irq = irq;
     s->mode = mode;
-    s->cpu = cpu;
-    s->irq_timer = qemu_new_timer(vm_clock, slavio_timer_irq, s);
-    s->intctl = intctl;
+    bh = qemu_bh_new(slavio_timer_irq, s);
+    s->timer = ptimer_init(bh);
+    ptimer_set_period(s->timer, 500ULL);
 
     slavio_timer_io_memory = cpu_register_io_memory(0, slavio_timer_mem_read,
 						    slavio_timer_mem_write, s);
-    cpu_register_physical_memory(addr, TIMER_MAXADDR, slavio_timer_io_memory);
-    register_savevm("slavio_timer", addr, 1, slavio_timer_save, slavio_timer_load, s);
+    cpu_register_physical_memory(addr, TIMER_SIZE, slavio_timer_io_memory);
+    register_savevm("slavio_timer", addr, 2, slavio_timer_save, slavio_timer_load, s);
     qemu_register_reset(slavio_timer_reset, s);
     slavio_timer_reset(s);
 }

Modified: trunk/src/host/qemu-neo1973/hw/sparc32_dma.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/sparc32_dma.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/sparc32_dma.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -41,22 +41,25 @@
 #define DPRINTF(fmt, args...)
 #endif
 
-#define DMA_REGS 8
-#define DMA_MAXADDR (DMA_REGS * 4 - 1)
+#define DMA_REGS 4
+#define DMA_SIZE (4 * sizeof(uint32_t))
+#define DMA_MAXADDR (DMA_SIZE - 1)
 
 #define DMA_VER 0xa0000000
 #define DMA_INTR 1
 #define DMA_INTREN 0x10
 #define DMA_WRITE_MEM 0x100
 #define DMA_LOADED 0x04000000
+#define DMA_DRAIN_FIFO 0x40
 #define DMA_RESET 0x80
 
 typedef struct DMAState DMAState;
 
 struct DMAState {
     uint32_t dmaregs[DMA_REGS];
-    qemu_irq espirq, leirq;
-    void *iommu, *esp_opaque, *lance_opaque;
+    qemu_irq irq;
+    void *iommu, *dev_opaque;
+    void (*dev_reset)(void *dev_opaque);
     qemu_irq *pic;
 };
 
@@ -69,7 +72,7 @@
 
     DPRINTF("DMA write, direction: %c, addr 0x%8.8x\n",
             s->dmaregs[0] & DMA_WRITE_MEM ? 'w': 'r', s->dmaregs[1]);
-    addr |= s->dmaregs[7];
+    addr |= s->dmaregs[3];
     if (do_bswap) {
         sparc_iommu_memory_read(s->iommu, addr, buf, len);
     } else {
@@ -91,7 +94,7 @@
 
     DPRINTF("DMA read, direction: %c, addr 0x%8.8x\n",
             s->dmaregs[0] & DMA_WRITE_MEM ? 'w': 'r', s->dmaregs[1]);
-    addr |= s->dmaregs[7];
+    addr |= s->dmaregs[3];
     if (do_bswap) {
         sparc_iommu_memory_write(s->iommu, addr, buf, len);
     } else {
@@ -112,24 +115,20 @@
     }
 }
 
-void espdma_raise_irq(void *opaque)
+static void dma_set_irq(void *opaque, int irq, int level)
 {
     DMAState *s = opaque;
-
-    DPRINTF("Raise ESP IRQ\n");
-    s->dmaregs[0] |= DMA_INTR;
-    qemu_irq_raise(s->espirq);
+    if (level) {
+        DPRINTF("Raise ESP IRQ\n");
+        s->dmaregs[0] |= DMA_INTR;
+        qemu_irq_raise(s->irq);
+    } else {
+        s->dmaregs[0] &= ~DMA_INTR;
+        DPRINTF("Lower ESP IRQ\n");
+        qemu_irq_lower(s->irq);
+    }
 }
 
-void espdma_clear_irq(void *opaque)
-{
-    DMAState *s = opaque;
-
-    s->dmaregs[0] &= ~DMA_INTR;
-    DPRINTF("Lower ESP IRQ\n");
-    qemu_irq_lower(s->espirq);
-}
-
 void espdma_memory_read(void *opaque, uint8_t *buf, int len)
 {
     DMAState *s = opaque;
@@ -158,7 +157,8 @@
     uint32_t saddr;
 
     saddr = (addr & DMA_MAXADDR) >> 2;
-    DPRINTF("read dmareg[%d]: 0x%8.8x\n", saddr, s->dmaregs[saddr]);
+    DPRINTF("read dmareg " TARGET_FMT_plx ": 0x%8.8x\n", addr,
+            s->dmaregs[saddr]);
 
     return s->dmaregs[saddr];
 }
@@ -169,37 +169,26 @@
     uint32_t saddr;
 
     saddr = (addr & DMA_MAXADDR) >> 2;
-    DPRINTF("write dmareg[%d]: 0x%8.8x -> 0x%8.8x\n", saddr, s->dmaregs[saddr], val);
+    DPRINTF("write dmareg " TARGET_FMT_plx ": 0x%8.8x -> 0x%8.8x\n", addr,
+            s->dmaregs[saddr], val);
     switch (saddr) {
     case 0:
         if (!(val & DMA_INTREN)) {
-            DPRINTF("Lower ESP IRQ\n");
-            qemu_irq_lower(s->espirq);
+            DPRINTF("Lower IRQ\n");
+            qemu_irq_lower(s->irq);
         }
         if (val & DMA_RESET) {
-            esp_reset(s->esp_opaque);
-        } else if (val & 0x40) {
-            val &= ~0x40;
+            s->dev_reset(s->dev_opaque);
+        } else if (val & DMA_DRAIN_FIFO) {
+            val &= ~DMA_DRAIN_FIFO;
         } else if (val == 0)
-            val = 0x40;
+            val = DMA_DRAIN_FIFO;
         val &= 0x0fffffff;
         val |= DMA_VER;
         break;
     case 1:
         s->dmaregs[0] |= DMA_LOADED;
         break;
-    case 4:
-        /* ??? Should this mask out the lance IRQ?  The NIC may re-assert
-           this IRQ unexpectedly.  */
-        if (!(val & DMA_INTREN)) {
-            DPRINTF("Lower Lance IRQ\n");
-            qemu_irq_lower(s->leirq);
-        }
-        if (val & DMA_RESET)
-            pcnet_h_reset(s->lance_opaque);
-        val &= 0x0fffffff;
-        val |= DMA_VER;
-        break;
     default:
         break;
     }
@@ -222,9 +211,8 @@
 {
     DMAState *s = opaque;
 
-    memset(s->dmaregs, 0, DMA_REGS * 4);
+    memset(s->dmaregs, 0, DMA_SIZE);
     s->dmaregs[0] = DMA_VER;
-    s->dmaregs[4] = DMA_VER;
 }
 
 static void dma_save(QEMUFile *f, void *opaque)
@@ -241,7 +229,7 @@
     DMAState *s = opaque;
     unsigned int i;
 
-    if (version_id != 1)
+    if (version_id != 2)
         return -EINVAL;
     for (i = 0; i < DMA_REGS; i++)
         qemu_get_be32s(f, &s->dmaregs[i]);
@@ -249,8 +237,8 @@
     return 0;
 }
 
-void *sparc32_dma_init(target_phys_addr_t daddr, qemu_irq espirq,
-                       qemu_irq leirq, void *iommu)
+void *sparc32_dma_init(target_phys_addr_t daddr, qemu_irq parent_irq,
+                       void *iommu, qemu_irq **dev_irq)
 {
     DMAState *s;
     int dma_io_memory;
@@ -259,24 +247,24 @@
     if (!s)
         return NULL;
 
-    s->espirq = espirq;
-    s->leirq = leirq;
+    s->irq = parent_irq;
     s->iommu = iommu;
 
     dma_io_memory = cpu_register_io_memory(0, dma_mem_read, dma_mem_write, s);
-    cpu_register_physical_memory(daddr, 16 * 2, dma_io_memory);
+    cpu_register_physical_memory(daddr, DMA_SIZE, dma_io_memory);
 
-    register_savevm("sparc32_dma", daddr, 1, dma_save, dma_load, s);
+    register_savevm("sparc32_dma", daddr, 2, dma_save, dma_load, s);
     qemu_register_reset(dma_reset, s);
+    *dev_irq = qemu_allocate_irqs(dma_set_irq, s, 1);
 
     return s;
 }
 
-void sparc32_dma_set_reset_data(void *opaque, void *esp_opaque,
-                                void *lance_opaque)
+void sparc32_dma_set_reset_data(void *opaque, void (*dev_reset)(void *opaque),
+                                void *dev_opaque)
 {
     DMAState *s = opaque;
 
-    s->esp_opaque = esp_opaque;
-    s->lance_opaque = lance_opaque;
+    s->dev_reset = dev_reset;
+    s->dev_opaque = dev_opaque;
 }

Modified: trunk/src/host/qemu-neo1973/hw/spitz.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/spitz.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/spitz.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -705,7 +705,7 @@
 
     iomemtype = cpu_register_io_memory(0, scoop_readfn,
                     scoop_writefn, &s[0]);
-    cpu_register_physical_memory(s[0].target_base, 0xfff, iomemtype);
+    cpu_register_physical_memory(s[0].target_base, 0x1000, iomemtype);
     register_savevm("scoop", 0, 0, scoop_save, scoop_load, &s[0]);
 
     if (count < 2)
@@ -713,7 +713,7 @@
 
     iomemtype = cpu_register_io_memory(0, scoop_readfn,
                     scoop_writefn, &s[1]);
-    cpu_register_physical_memory(s[1].target_base, 0xfff, iomemtype);
+    cpu_register_physical_memory(s[1].target_base, 0x1000, iomemtype);
     register_savevm("scoop", 1, 0, scoop_save, scoop_load, &s[1]);
 
     return s;

Modified: trunk/src/host/qemu-neo1973/hw/sun4m.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/sun4m.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/sun4m.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -22,6 +22,7 @@
  * THE SOFTWARE.
  */
 #include "vl.h"
+//#define DEBUG_IRQ
 
 /*
  * Sun4m architecture was used in the following machines:
@@ -38,6 +39,13 @@
  * See for example: http://www.sunhelp.org/faq/sunref1.html
  */
 
+#ifdef DEBUG_IRQ
+#define DPRINTF(fmt, args...)                           \
+    do { printf("CPUIRQ: " fmt , ##args); } while (0)
+#else
+#define DPRINTF(fmt, args...)
+#endif
+
 #define KERNEL_LOAD_ADDR     0x00004000
 #define CMDLINE_ADDR         0x007ff000
 #define INITRD_LOAD_ADDR     0x00800000
@@ -46,6 +54,7 @@
 #define PROM_FILENAME	     "openbios-sparc32"
 
 #define MAX_CPUS 16
+#define MAX_PILS 16
 
 struct hwdef {
     target_phys_addr_t iommu_base, slavio_base;
@@ -56,7 +65,7 @@
     long vram_size, nvram_size;
     // IRQ numbers are not PIL ones, but master interrupt controller register
     // bit numbers
-    int intctl_g_intr, esp_irq, le_irq, cpu_irq, clock_irq, clock1_irq;
+    int intctl_g_intr, esp_irq, le_irq, clock_irq, clock1_irq;
     int ser_irq, ms_kb_irq, fd_irq, me_irq, cs_irq;
     int machine_id; // For NVRAM
     uint32_t intbit_to_level[32];
@@ -233,6 +242,33 @@
     slavio_irq_info(slavio_intctl);
 }
 
+static void cpu_set_irq(void *opaque, int irq, int level)
+{
+    CPUState *env = opaque;
+
+    if (level) {
+        DPRINTF("Raise CPU IRQ %d\n", irq);
+
+        env->halted = 0;
+
+        if (env->interrupt_index == 0 ||
+            ((env->interrupt_index & ~15) == TT_EXTINT &&
+             (env->interrupt_index & 15) < irq)) {
+            env->interrupt_index = TT_EXTINT | irq;
+            cpu_interrupt(env, CPU_INTERRUPT_HARD);
+        } else {
+            DPRINTF("Not triggered, pending exception %d\n",
+                    env->interrupt_index);
+        }
+    } else {
+        DPRINTF("Lower CPU IRQ %d\n", irq);
+    }
+}
+
+static void dummy_cpu_set_irq(void *opaque, int irq, int level)
+{
+}
+
 static void *slavio_misc;
 
 void qemu_system_powerdown(void)
@@ -262,9 +298,10 @@
 {
     CPUState *env, *envs[MAX_CPUS];
     unsigned int i;
-    void *iommu, *dma, *main_esp, *main_lance = NULL;
+    void *iommu, *espdma, *ledma, *main_esp;
     const sparc_def_t *def;
-    qemu_irq *slavio_irq;
+    qemu_irq *cpu_irqs[MAX_CPUS], *slavio_irq, *slavio_cpu_irq,
+        *espdma_irq, *ledma_irq;
 
     /* init CPUs */
     sparc_find_by_name(cpu_model, &def);
@@ -272,6 +309,7 @@
         fprintf(stderr, "Unable to find Sparc CPU definition\n");
         exit(1);
     }
+
     for(i = 0; i < smp_cpus; i++) {
         env = cpu_init();
         cpu_sparc_register(env, def);
@@ -283,7 +321,12 @@
             env->halted = 1;
         }
         register_savevm("cpu", i, 3, cpu_save, cpu_load, env);
+        cpu_irqs[i] = qemu_allocate_irqs(cpu_set_irq, envs[i], MAX_PILS);
     }
+
+    for (i = smp_cpus; i < MAX_CPUS; i++)
+        cpu_irqs[i] = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, MAX_PILS);
+
     /* allocate RAM */
     cpu_register_physical_memory(0, ram_size, 0);
 
@@ -291,45 +334,49 @@
     slavio_intctl = slavio_intctl_init(hwdef->intctl_base,
                                        hwdef->intctl_base + 0x10000ULL,
                                        &hwdef->intbit_to_level[0],
-                                       &slavio_irq);
-    for(i = 0; i < smp_cpus; i++) {
-        slavio_intctl_set_cpu(slavio_intctl, i, envs[i]);
-    }
-    dma = sparc32_dma_init(hwdef->dma_base, slavio_irq[hwdef->esp_irq],
-                           slavio_irq[hwdef->le_irq], iommu);
+                                       &slavio_irq, &slavio_cpu_irq,
+                                       cpu_irqs,
+                                       hwdef->clock_irq);
 
+    espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[hwdef->esp_irq],
+                              iommu, &espdma_irq);
+    ledma = sparc32_dma_init(hwdef->dma_base + 16ULL,
+                             slavio_irq[hwdef->le_irq], iommu, &ledma_irq);
+
     if (graphic_depth != 8 && graphic_depth != 24) {
         fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
         exit (1);
     }
     tcx_init(ds, hwdef->tcx_base, phys_ram_base + ram_size, ram_size,
              hwdef->vram_size, graphic_width, graphic_height, graphic_depth);
-    if (nd_table[0].vlan) {
-        if (nd_table[0].model == NULL
-            || strcmp(nd_table[0].model, "lance") == 0) {
-            main_lance = lance_init(&nd_table[0], hwdef->le_base, dma,
-                                    slavio_irq[hwdef->le_irq]);
-        } else {
-            fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
-            exit (1);
-        }
+
+    if (nd_table[0].model == NULL
+        || strcmp(nd_table[0].model, "lance") == 0) {
+        lance_init(&nd_table[0], hwdef->le_base, ledma, *ledma_irq);
+    } else if (strcmp(nd_table[0].model, "?") == 0) {
+        fprintf(stderr, "qemu: Supported NICs: lance\n");
+        exit (1);
+    } else {
+        fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
+        exit (1);
     }
+
     nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0,
                         hwdef->nvram_size, 8);
     for (i = 0; i < MAX_CPUS; i++) {
         slavio_timer_init(hwdef->counter_base +
                           (target_phys_addr_t)(i * TARGET_PAGE_SIZE),
-                          hwdef->clock_irq, 0, i, slavio_intctl);
+                           slavio_cpu_irq[i], 0);
     }
-    slavio_timer_init(hwdef->counter_base + 0x10000ULL, hwdef->clock1_irq, 2,
-                      (unsigned int)-1, slavio_intctl);
+    slavio_timer_init(hwdef->counter_base + 0x10000ULL,
+                      slavio_irq[hwdef->clock1_irq], 2);
     slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[hwdef->ms_kb_irq]);
     // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
     // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
     slavio_serial_init(hwdef->serial_base, slavio_irq[hwdef->ser_irq],
                        serial_hds[1], serial_hds[0]);
     fdctrl_init(slavio_irq[hwdef->fd_irq], 0, 1, hwdef->fd_base, fd_table);
-    main_esp = esp_init(bs_table, hwdef->esp_base, dma);
+    main_esp = esp_init(bs_table, hwdef->esp_base, espdma, *espdma_irq);
 
     for (i = 0; i < MAX_DISKS; i++) {
         if (bs_table[i]) {
@@ -341,7 +388,6 @@
                                    slavio_irq[hwdef->me_irq]);
     if (hwdef->cs_base != (target_phys_addr_t)-1)
         cs_init(hwdef->cs_base, hwdef->cs_irq, slavio_intctl);
-    sparc32_dma_set_reset_data(dma, main_esp, main_lance);
 }
 
 static void sun4m_load_kernel(long vram_size, int ram_size, int boot_device,

Modified: trunk/src/host/qemu-neo1973/hw/sun4u.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/sun4u.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/sun4u.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -282,9 +282,37 @@
 static void main_cpu_reset(void *opaque)
 {
     CPUState *env = opaque;
+
     cpu_reset(env);
+    ptimer_set_limit(env->tick, 0x7fffffffffffffffULL, 1);
+    ptimer_run(env->tick, 0);
+    ptimer_set_limit(env->stick, 0x7fffffffffffffffULL, 1);
+    ptimer_run(env->stick, 0);
+    ptimer_set_limit(env->hstick, 0x7fffffffffffffffULL, 1);
+    ptimer_run(env->hstick, 0);
 }
 
+void tick_irq(void *opaque)
+{
+    CPUState *env = opaque;
+
+    cpu_interrupt(env, CPU_INTERRUPT_TIMER);
+}
+
+void stick_irq(void *opaque)
+{
+    CPUState *env = opaque;
+
+    cpu_interrupt(env, CPU_INTERRUPT_TIMER);
+}
+
+void hstick_irq(void *opaque)
+{
+    CPUState *env = opaque;
+
+    cpu_interrupt(env, CPU_INTERRUPT_TIMER);
+}
+
 static const int ide_iobase[2] = { 0x1f0, 0x170 };
 static const int ide_iobase2[2] = { 0x3f6, 0x376 };
 static const int ide_irq[2] = { 14, 15 };
@@ -311,6 +339,7 @@
     long prom_offset, initrd_size, kernel_size;
     PCIBus *pci_bus;
     const sparc_def_t *def;
+    QEMUBH *bh;
 
     linux_boot = (kernel_filename != NULL);
 
@@ -324,8 +353,20 @@
     }
     env = cpu_init();
     cpu_sparc_register(env, def);
+    bh = qemu_bh_new(tick_irq, env);
+    env->tick = ptimer_init(bh);
+    ptimer_set_period(env->tick, 1ULL);
+
+    bh = qemu_bh_new(stick_irq, env);
+    env->stick = ptimer_init(bh);
+    ptimer_set_period(env->stick, 1ULL);
+
+    bh = qemu_bh_new(hstick_irq, env);
+    env->hstick = ptimer_init(bh);
+    ptimer_set_period(env->hstick, 1ULL);
     register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
     qemu_register_reset(main_cpu_reset, env);
+    main_cpu_reset(env);
 
     /* allocate RAM */
     cpu_register_physical_memory(0, ram_size, 0);

Modified: trunk/src/host/qemu-neo1973/hw/tcx.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/tcx.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/tcx.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -22,6 +22,7 @@
  * THE SOFTWARE.
  */
 #include "vl.h"
+#include "pixel_ops.h"
 
 #define MAXX 1024
 #define MAXY 768
@@ -44,28 +45,9 @@
 
 static void tcx_screen_dump(void *opaque, const char *filename);
 static void tcx24_screen_dump(void *opaque, const char *filename);
+static void tcx_invalidate_display(void *opaque);
+static void tcx24_invalidate_display(void *opaque);
 
-/* XXX: unify with vga draw line functions */
-static inline unsigned int rgb_to_pixel8(unsigned int r, unsigned int g, unsigned b)
-{
-    return ((r >> 5) << 5) | ((g >> 5) << 2) | (b >> 6);
-}
-
-static inline unsigned int rgb_to_pixel15(unsigned int r, unsigned int g, unsigned b)
-{
-    return ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);
-}
-
-static inline unsigned int rgb_to_pixel16(unsigned int r, unsigned int g, unsigned b)
-{
-    return ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
-}
-
-static inline unsigned int rgb_to_pixel32(unsigned int r, unsigned int g, unsigned b)
-{
-    return (r << 16) | (g << 8) | b;
-}
-
 static void update_palette_entries(TCXState *s, int start, int end)
 {
     int i;
@@ -76,16 +58,29 @@
             s->palette[i] = rgb_to_pixel8(s->r[i], s->g[i], s->b[i]);
             break;
         case 15:
-            s->palette[i] = rgb_to_pixel15(s->r[i], s->g[i], s->b[i]);
+            if (s->ds->bgr)
+                s->palette[i] = rgb_to_pixel15bgr(s->r[i], s->g[i], s->b[i]);
+            else
+                s->palette[i] = rgb_to_pixel15(s->r[i], s->g[i], s->b[i]);
             break;
         case 16:
-            s->palette[i] = rgb_to_pixel16(s->r[i], s->g[i], s->b[i]);
+            if (s->ds->bgr)
+                s->palette[i] = rgb_to_pixel16bgr(s->r[i], s->g[i], s->b[i]);
+            else
+                s->palette[i] = rgb_to_pixel16(s->r[i], s->g[i], s->b[i]);
             break;
         case 32:
-            s->palette[i] = rgb_to_pixel32(s->r[i], s->g[i], s->b[i]);
+            if (s->ds->bgr)
+                s->palette[i] = rgb_to_pixel32bgr(s->r[i], s->g[i], s->b[i]);
+            else
+                s->palette[i] = rgb_to_pixel32(s->r[i], s->g[i], s->b[i]);
             break;
         }
     }
+    if (s->depth == 24)
+        tcx24_invalidate_display(s);
+    else
+        tcx_invalidate_display(s);
 }
 
 static void tcx_draw_line32(TCXState *s1, uint8_t *d, 
@@ -391,7 +386,10 @@
     qemu_get_8s(f, &s->dac_index);
     qemu_get_8s(f, &s->dac_state);
     update_palette_entries(s, 0, 256);
-    tcx_invalidate_display(s);
+    if (s->depth == 24)
+        tcx24_invalidate_display(s);
+    else
+        tcx_invalidate_display(s);
 
     return 0;
 }

Modified: trunk/src/host/qemu-neo1973/hw/usb-ohci.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/usb-ohci.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/usb-ohci.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -1345,5 +1345,5 @@
                   OHCI_TYPE_MEMIO, "OHCI USB");
     ohci->mem_base = base;
 
-    cpu_register_physical_memory(ohci->mem_base, 0xfff, ohci->mem);
+    cpu_register_physical_memory(ohci->mem_base, 0x1000, ohci->mem);
 }

Modified: trunk/src/host/qemu-neo1973/hw/usb-uhci.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/usb-uhci.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/usb-uhci.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -783,7 +783,7 @@
     register_ioport_read(addr, 32, 1, uhci_ioport_readb, s);
 }
 
-void usb_uhci_init(PCIBus *bus, int devfn)
+void usb_uhci_piix3_init(PCIBus *bus, int devfn)
 {
     UHCIState *s;
     uint8_t *pci_conf;
@@ -817,3 +817,39 @@
     pci_register_io_region(&s->dev, 4, 0x20, 
                            PCI_ADDRESS_SPACE_IO, uhci_map);
 }
+
+void usb_uhci_piix4_init(PCIBus *bus, int devfn)
+{
+    UHCIState *s;
+    uint8_t *pci_conf;
+    int i;
+
+    s = (UHCIState *)pci_register_device(bus,
+                                        "USB-UHCI", sizeof(UHCIState),
+                                        devfn, NULL, NULL);
+    pci_conf = s->dev.config;
+    pci_conf[0x00] = 0x86;
+    pci_conf[0x01] = 0x80;
+    pci_conf[0x02] = 0x12;
+    pci_conf[0x03] = 0x71;
+    pci_conf[0x08] = 0x01; // revision number
+    pci_conf[0x09] = 0x00;
+    pci_conf[0x0a] = 0x03;
+    pci_conf[0x0b] = 0x0c;
+    pci_conf[0x0e] = 0x00; // header_type
+    pci_conf[0x3d] = 4; // interrupt pin 3
+    pci_conf[0x60] = 0x10; // release number
+
+    for(i = 0; i < NB_PORTS; i++) {
+        qemu_register_usb_port(&s->ports[i].port, s, i, uhci_attach);
+    }
+    s->frame_timer = qemu_new_timer(vm_clock, uhci_frame_timer, s);
+
+    uhci_reset(s);
+
+    /* Use region 4 for consistency with real hardware.  BSD guests seem
+       to rely on this.  */
+    pci_register_io_region(&s->dev, 4, 0x20,
+                           PCI_ADDRESS_SPACE_IO, uhci_map);
+}
+

Modified: trunk/src/host/qemu-neo1973/hw/usb.h
===================================================================
--- trunk/src/host/qemu-neo1973/hw/usb.h	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/usb.h	2007-06-17 16:55:00 UTC (rev 2289)
@@ -204,7 +204,8 @@
 USBDevice *usb_hub_init(int nb_ports);
 
 /* usb-uhci.c */
-void usb_uhci_init(PCIBus *bus, int devfn);
+void usb_uhci_piix3_init(PCIBus *bus, int devfn);
+void usb_uhci_piix4_init(PCIBus *bus, int devfn);
 
 /* usb-ohci.c */
 void usb_ohci_init_pci(struct PCIBus *bus, int num_ports, int devfn);
@@ -231,3 +232,6 @@
 
 /* usb-bt.c */
 USBDevice *usb_bt_init(struct bt_piconet_s *net);
+
+/* usb-wacom.c */
+USBDevice *usb_wacom_init(void);

Modified: trunk/src/host/qemu-neo1973/hw/versatilepb.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/versatilepb.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/versatilepb.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -140,7 +140,7 @@
     s->irq = irq;
     iomemtype = cpu_register_io_memory(0, vpb_sic_readfn,
                                        vpb_sic_writefn, s);
-    cpu_register_physical_memory(base, 0x00000fff, iomemtype);
+    cpu_register_physical_memory(base, 0x00001000, iomemtype);
     /* ??? Save/restore.  */
     return qi;
 }

Modified: trunk/src/host/qemu-neo1973/hw/vga.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/vga.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/hw/vga.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -23,6 +23,7 @@
  */
 #include "vl.h"
 #include "vga_int.h"
+#include "pixel_ops.h"
 
 //#define DEBUG_VGA
 //#define DEBUG_VGA_MEM
@@ -346,7 +347,7 @@
         case 0x09:
         case 0x0c:
         case 0x0d:
-        case 0x12: /* veritcal display end */
+        case 0x12: /* vertical display end */
             s->cr[s->cr_index] = val;
             break;
         default:
@@ -812,40 +813,23 @@
 typedef void vga_draw_line_func(VGAState *s1, uint8_t *d, 
                                 const uint8_t *s, int width);
 
-static inline unsigned int rgb_to_pixel8(unsigned int r, unsigned int g, unsigned b)
-{
-    return ((r >> 5) << 5) | ((g >> 5) << 2) | (b >> 6);
-}
-
-static inline unsigned int rgb_to_pixel15(unsigned int r, unsigned int g, unsigned b)
-{
-    return ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);
-}
-
-static inline unsigned int rgb_to_pixel16(unsigned int r, unsigned int g, unsigned b)
-{
-    return ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
-}
-
-static inline unsigned int rgb_to_pixel32(unsigned int r, unsigned int g, unsigned b)
-{
-    return (r << 16) | (g << 8) | b;
-}
-
-static inline unsigned int rgb_to_pixel32bgr(unsigned int r, unsigned int g, unsigned b)
-{
-    return (b << 16) | (g << 8) | r;
-}
-
 #define DEPTH 8
 #include "vga_template.h"
 
 #define DEPTH 15
 #include "vga_template.h"
 
+#define BGR_FORMAT
+#define DEPTH 15
+#include "vga_template.h"
+
 #define DEPTH 16
 #include "vga_template.h"
 
+#define BGR_FORMAT
+#define DEPTH 16
+#include "vga_template.h"
+
 #define DEPTH 32
 #include "vga_template.h"
 
@@ -870,6 +854,15 @@
     return col;
 }
 
+static unsigned int rgb_to_pixel15bgr_dup(unsigned int r, unsigned int g,
+                                          unsigned int b)
+{
+    unsigned int col;
+    col = rgb_to_pixel15bgr(r, g, b);
+    col |= col << 16;
+    return col;
+}
+
 static unsigned int rgb_to_pixel16_dup(unsigned int r, unsigned int g, unsigned b)
 {
     unsigned int col;
@@ -878,6 +871,15 @@
     return col;
 }
 
+static unsigned int rgb_to_pixel16bgr_dup(unsigned int r, unsigned int g,
+                                          unsigned int b)
+{
+    unsigned int col;
+    col = rgb_to_pixel16bgr(r, g, b);
+    col |= col << 16;
+    return col;
+}
+
 static unsigned int rgb_to_pixel32_dup(unsigned int r, unsigned int g, unsigned b)
 {
     unsigned int col;
@@ -998,7 +1000,7 @@
     return full_update;
 }
 
-#define NB_DEPTHS 5
+#define NB_DEPTHS 7
 
 static inline int get_depth_index(DisplayState *s)
 {
@@ -1007,9 +1009,15 @@
     case 8:
         return 0;
     case 15:
-        return 1;
+        if (s->bgr)
+            return 5;
+        else
+            return 1;
     case 16:
-        return 2;
+        if (s->bgr)
+            return 6;
+        else
+            return 2;
     case 32:
         if (s->bgr)
             return 4;
@@ -1024,6 +1032,8 @@
     vga_draw_glyph8_16,
     vga_draw_glyph8_32,
     vga_draw_glyph8_32,
+    vga_draw_glyph8_16,
+    vga_draw_glyph8_16,
 };
 
 static vga_draw_glyph8_func *vga_draw_glyph16_table[NB_DEPTHS] = {
@@ -1032,6 +1042,8 @@
     vga_draw_glyph16_16,
     vga_draw_glyph16_32,
     vga_draw_glyph16_32,
+    vga_draw_glyph16_16,
+    vga_draw_glyph16_16,
 };
 
 static vga_draw_glyph9_func *vga_draw_glyph9_table[NB_DEPTHS] = {
@@ -1040,6 +1052,8 @@
     vga_draw_glyph9_16,
     vga_draw_glyph9_32,
     vga_draw_glyph9_32,
+    vga_draw_glyph9_16,
+    vga_draw_glyph9_16,
 };
     
 static const uint8_t cursor_glyph[32 * 4] = {
@@ -1260,60 +1274,80 @@
     vga_draw_line2_16,
     vga_draw_line2_32,
     vga_draw_line2_32,
+    vga_draw_line2_16,
+    vga_draw_line2_16,
 
     vga_draw_line2d2_8,
     vga_draw_line2d2_16,
     vga_draw_line2d2_16,
     vga_draw_line2d2_32,
     vga_draw_line2d2_32,
+    vga_draw_line2d2_16,
+    vga_draw_line2d2_16,
 
     vga_draw_line4_8,
     vga_draw_line4_16,
     vga_draw_line4_16,
     vga_draw_line4_32,
     vga_draw_line4_32,
+    vga_draw_line4_16,
+    vga_draw_line4_16,
 
     vga_draw_line4d2_8,
     vga_draw_line4d2_16,
     vga_draw_line4d2_16,
     vga_draw_line4d2_32,
     vga_draw_line4d2_32,
+    vga_draw_line4d2_16,
+    vga_draw_line4d2_16,
 
     vga_draw_line8d2_8,
     vga_draw_line8d2_16,
     vga_draw_line8d2_16,
     vga_draw_line8d2_32,
     vga_draw_line8d2_32,
+    vga_draw_line8d2_16,
+    vga_draw_line8d2_16,
 
     vga_draw_line8_8,
     vga_draw_line8_16,
     vga_draw_line8_16,
     vga_draw_line8_32,
     vga_draw_line8_32,
+    vga_draw_line8_16,
+    vga_draw_line8_16,
 
     vga_draw_line15_8,
     vga_draw_line15_15,
     vga_draw_line15_16,
     vga_draw_line15_32,
     vga_draw_line15_32bgr,
+    vga_draw_line15_15bgr,
+    vga_draw_line15_16bgr,
 
     vga_draw_line16_8,
     vga_draw_line16_15,
     vga_draw_line16_16,
     vga_draw_line16_32,
     vga_draw_line16_32bgr,
+    vga_draw_line16_15bgr,
+    vga_draw_line16_16bgr,
 
     vga_draw_line24_8,
     vga_draw_line24_15,
     vga_draw_line24_16,
     vga_draw_line24_32,
     vga_draw_line24_32bgr,
+    vga_draw_line24_15bgr,
+    vga_draw_line24_16bgr,
 
     vga_draw_line32_8,
     vga_draw_line32_15,
     vga_draw_line32_16,
     vga_draw_line32_32,
     vga_draw_line32_32bgr,
+    vga_draw_line32_15bgr,
+    vga_draw_line32_16bgr,
 };
 
 typedef unsigned int rgb_to_pixel_dup_func(unsigned int r, unsigned int g, unsigned b);
@@ -1324,6 +1358,8 @@
     rgb_to_pixel16_dup,
     rgb_to_pixel32_dup,
     rgb_to_pixel32bgr_dup,
+    rgb_to_pixel15bgr_dup,
+    rgb_to_pixel16bgr_dup,
 };
 
 static int vga_get_bpp(VGAState *s)

Modified: trunk/src/host/qemu-neo1973/linux-user/alpha/syscall.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/alpha/syscall.h	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/linux-user/alpha/syscall.h	2007-06-17 16:55:00 UTC (rev 2289)
@@ -38,78 +38,4 @@
         target_ulong unique;
 };
 
-#define TARGET_SEMOP           1
-#define TARGET_SEMGET          2
-#define TARGET_SEMCTL          3 
-#define TARGET_MSGSND          11 
-#define TARGET_MSGRCV          12
-#define TARGET_MSGGET          13
-#define TARGET_MSGCTL          14
-#define TARGET_SHMAT           21
-#define TARGET_SHMDT           22
-#define TARGET_SHMGET          23
-#define TARGET_SHMCTL          24
-
-struct target_msgbuf {
-	int mtype;
-	char mtext[1];
-};
-
-struct target_ipc_kludge {
-	unsigned int	msgp;	/* Really (struct msgbuf *) */
-	int msgtyp;
-};	
-
-struct target_ipc_perm {
-	int	key;
-	unsigned short	uid;
-	unsigned short	gid;
-	unsigned short	cuid;
-	unsigned short	cgid;
-	unsigned short	mode;
-	unsigned short	seq;
-};
-
-struct target_msqid_ds {
-	struct target_ipc_perm	msg_perm;
-	unsigned int		msg_first;	/* really struct target_msg* */
-	unsigned int		msg_last;	/* really struct target_msg* */
-	unsigned int		msg_stime;	/* really target_time_t */
-	unsigned int		msg_rtime;	/* really target_time_t */
-	unsigned int		msg_ctime;	/* really target_time_t */
-	unsigned int		wwait;		/* really struct wait_queue* */
-	unsigned int		rwait;		/* really struct wait_queue* */
-	unsigned short		msg_cbytes;
-	unsigned short		msg_qnum;
-	unsigned short		msg_qbytes;
-	unsigned short		msg_lspid;
-	unsigned short		msg_lrpid;
-};
-
-struct target_shmid_ds {
-	struct target_ipc_perm	shm_perm;
-	int			shm_segsz;
-	unsigned int		shm_atime;	/* really target_time_t */
-	unsigned int		shm_dtime;	/* really target_time_t */
-	unsigned int		shm_ctime;	/* really target_time_t */
-	unsigned short		shm_cpid;
-	unsigned short		shm_lpid;
-	short			shm_nattch;
-	unsigned short		shm_npages;
-	unsigned long		*shm_pages;
-	void 			*attaches;	/* really struct shm_desc * */
-};
-
-#define TARGET_IPC_RMID	0
-#define TARGET_IPC_SET	1
-#define TARGET_IPC_STAT	2
-
-union target_semun {
-    int val;
-    unsigned int buf;	/* really struct semid_ds * */
-    unsigned int array; /* really unsigned short * */
-    unsigned int __buf;	/* really struct seminfo * */
-    unsigned int __pad;	/* really void* */
-};
-
 #define UNAME_MACHINE "alpha"

Modified: trunk/src/host/qemu-neo1973/linux-user/alpha/termbits.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/alpha/termbits.h	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/linux-user/alpha/termbits.h	2007-06-17 16:55:00 UTC (rev 2289)
@@ -1,17 +1,17 @@
-typedef unsigned char	cc_t;
-typedef unsigned int	speed_t;
-typedef unsigned int	tcflag_t;
+typedef unsigned char	target_cc_t;
+typedef unsigned int	target_speed_t;
+typedef unsigned int	target_tcflag_t;
 
 #define TARGET_NCCS 19
 struct target_termios {
-	tcflag_t c_iflag;		/* input mode flags */
-	tcflag_t c_oflag;		/* output mode flags */
-	tcflag_t c_cflag;		/* control mode flags */
-	tcflag_t c_lflag;		/* local mode flags */
-	cc_t c_cc[TARGET_NCCS];		/* control characters */
-	cc_t c_line;			/* line discipline (== c_cc[19]) */
-	speed_t c_ispeed;		/* input speed */
-	speed_t c_ospeed;		/* output speed */
+	target_tcflag_t c_iflag;		/* input mode flags */
+	target_tcflag_t c_oflag;		/* output mode flags */
+	target_tcflag_t c_cflag;		/* control mode flags */
+	target_tcflag_t c_lflag;		/* local mode flags */
+	target_cc_t c_cc[TARGET_NCCS];		/* control characters */
+	target_cc_t c_line;			/* line discipline (== c_cc[19]) */
+	target_speed_t c_ispeed;		/* input speed */
+	target_speed_t c_ospeed;		/* output speed */
 };
 
 /* c_cc characters */

Modified: trunk/src/host/qemu-neo1973/linux-user/elfload.c
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/elfload.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/linux-user/elfload.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -799,7 +799,7 @@
 #endif
 
         if (interp_elf_ex->e_type == ET_DYN) {
-            /* in order to avoid harcoding the interpreter load
+            /* in order to avoid hardcoding the interpreter load
                address in qemu, we allocate a big enough memory zone */
             error = target_mmap(0, INTERP_MAP_SIZE,
                                 PROT_NONE, MAP_PRIVATE | MAP_ANON, 
@@ -1191,7 +1191,7 @@
                base, as well as whatever program they might try to exec.  This
                is because the brk will follow the loader, and is not movable.  */
             /* NOTE: for qemu, we do a big mmap to get enough space
-               without harcoding any address */
+               without hardcoding any address */
             error = target_mmap(0, ET_DYN_MAP_SIZE,
                                 PROT_NONE, MAP_PRIVATE | MAP_ANON, 
                                 -1, 0);

Modified: trunk/src/host/qemu-neo1973/linux-user/i386/syscall.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/i386/syscall.h	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/linux-user/i386/syscall.h	2007-06-17 16:55:00 UTC (rev 2289)
@@ -142,80 +142,4 @@
 	struct target_vm86plus_info_struct vm86plus;
 };
 
-/* ipcs */
-
-#define TARGET_SEMOP           1
-#define TARGET_SEMGET          2
-#define TARGET_SEMCTL          3 
-#define TARGET_MSGSND          11 
-#define TARGET_MSGRCV          12
-#define TARGET_MSGGET          13
-#define TARGET_MSGCTL          14
-#define TARGET_SHMAT           21
-#define TARGET_SHMDT           22
-#define TARGET_SHMGET          23
-#define TARGET_SHMCTL          24
-
-struct target_msgbuf {
-	int mtype;
-	char mtext[1];
-};
-
-struct target_ipc_kludge {
-	unsigned int	msgp;	/* Really (struct msgbuf *) */
-	int msgtyp;
-};	
-
-struct target_ipc_perm {
-	int	key;
-	unsigned short	uid;
-	unsigned short	gid;
-	unsigned short	cuid;
-	unsigned short	cgid;
-	unsigned short	mode;
-	unsigned short	seq;
-};
-
-struct target_msqid_ds {
-	struct target_ipc_perm	msg_perm;
-	unsigned int		msg_first;	/* really struct target_msg* */
-	unsigned int		msg_last;	/* really struct target_msg* */
-	unsigned int		msg_stime;	/* really target_time_t */
-	unsigned int		msg_rtime;	/* really target_time_t */
-	unsigned int		msg_ctime;	/* really target_time_t */
-	unsigned int		wwait;		/* really struct wait_queue* */
-	unsigned int		rwait;		/* really struct wait_queue* */
-	unsigned short		msg_cbytes;
-	unsigned short		msg_qnum;
-	unsigned short		msg_qbytes;
-	unsigned short		msg_lspid;
-	unsigned short		msg_lrpid;
-};
-
-struct target_shmid_ds {
-	struct target_ipc_perm	shm_perm;
-	int			shm_segsz;
-	unsigned int		shm_atime;	/* really target_time_t */
-	unsigned int		shm_dtime;	/* really target_time_t */
-	unsigned int		shm_ctime;	/* really target_time_t */
-	unsigned short		shm_cpid;
-	unsigned short		shm_lpid;
-	short			shm_nattch;
-	unsigned short		shm_npages;
-	unsigned long		*shm_pages;
-	void 			*attaches;	/* really struct shm_desc * */
-};
-
-#define TARGET_IPC_RMID	0
-#define TARGET_IPC_SET	1
-#define TARGET_IPC_STAT	2
-
-union target_semun {
-    int val;
-    unsigned int buf;	/* really struct semid_ds * */
-    unsigned int array; /* really unsigned short * */
-    unsigned int __buf;	/* really struct seminfo * */
-    unsigned int __pad;	/* really void* */
-};
-
 #define UNAME_MACHINE "i686"

Modified: trunk/src/host/qemu-neo1973/linux-user/linuxload.c
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/linuxload.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/linux-user/linuxload.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -1,4 +1,4 @@
-/* Code for loading Linux executables.  Mostly linux kenrel code.  */
+/* Code for loading Linux executables.  Mostly linux kernel code.  */
 
 #include <sys/types.h>
 #include <sys/stat.h>

Modified: trunk/src/host/qemu-neo1973/linux-user/main.c
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/main.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/linux-user/main.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -1502,9 +1502,9 @@
                 }
             }
             break;
-        case EXCP_HALTED:
+        case EXCP_HALT_INSN:
             /* Semihosing syscall.  */
-            env->pc += 2;
+            env->pc += 4;
             do_m68k_semihosting(env, env->dregs[0]);
             break;
         case EXCP_LINEA:
@@ -1633,7 +1633,7 @@
             call_pal(env, (trapnr >> 6) | 0x80);
             break;
         case EXCP_CALL_PALP ... (EXCP_CALL_PALE - 1):
-            fprintf(stderr, "Priviledged call to PALcode\n");
+            fprintf(stderr, "Privileged call to PALcode\n");
             exit(1);
             break;
         case EXCP_DEBUG:
@@ -1918,10 +1918,6 @@
         for(i = 0; i < 16; i++) {
             env->regs[i] = regs->uregs[i];
         }
-        ts->stack_base = info->start_stack;
-        ts->heap_base = info->brk;
-        /* This will be filled in on the first SYS_HEAPINFO call.  */
-        ts->heap_limit = 0;
     }
 #elif defined(TARGET_SPARC)
     {
@@ -1978,7 +1974,7 @@
 #elif defined(TARGET_M68K)
     {
         if (cpu_model == NULL)
-            cpu_model = "cfv4e";
+            cpu_model = "any";
         if (cpu_m68k_set_model(env, cpu_model)) {
             cpu_abort(cpu_single_env,
                       "Unable to find m68k CPU definition\n");
@@ -2020,9 +2016,6 @@
             env->gpr[i] = regs->regs[i];
         }
         env->PC = regs->cp0_epc;
-        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
-            env->CP0_Status |= (1 << CP0St_CU1);
-        }
     }
 #elif defined(TARGET_SH4)
     {
@@ -2049,6 +2042,13 @@
 #error unsupported target CPU
 #endif
 
+#if defined(TARGET_ARM) || defined(TARGET_M68K)
+    ts->stack_base = info->start_stack;
+    ts->heap_base = info->brk;
+    /* This will be filled in on the first SYS_HEAPINFO call.  */
+    ts->heap_limit = 0;
+#endif
+
     if (gdbstub_port) {
         gdbserver_start (gdbstub_port);
         gdb_handlesig(env, 0);

Modified: trunk/src/host/qemu-neo1973/linux-user/mips/syscall.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/mips/syscall.h	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/linux-user/mips/syscall.h	2007-06-17 16:55:00 UTC (rev 2289)
@@ -20,4 +20,207 @@
 	target_ulong cp0_epc;
 };
 
+/* Target errno definitions taken from asm-mips/errno.h */
+#undef TARGET_ENOMSG
+#define TARGET_ENOMSG          35      /* Identifier removed */
+#undef TARGET_EIDRM
+#define TARGET_EIDRM           36      /* Identifier removed */
+#undef TARGET_ECHRNG
+#define TARGET_ECHRNG          37      /* Channel number out of range */
+#undef TARGET_EL2NSYNC
+#define TARGET_EL2NSYNC        38      /* Level 2 not synchronized */
+#undef TARGET_EL3HLT
+#define TARGET_EL3HLT          39      /* Level 3 halted */
+#undef TARGET_EL3RST
+#define TARGET_EL3RST          40      /* Level 3 reset */
+#undef TARGET_ELNRNG
+#define TARGET_ELNRNG          41      /* Link number out of range */
+#undef TARGET_EUNATCH
+#define TARGET_EUNATCH         42      /* Protocol driver not attached */
+#undef TARGET_ENOCSI
+#define TARGET_ENOCSI          43      /* No CSI structure available */
+#undef TARGET_EL2HLT
+#define TARGET_EL2HLT          44      /* Level 2 halted */
+#undef TARGET_EDEADLK
+#define TARGET_EDEADLK         45      /* Resource deadlock would occur */
+#undef TARGET_ENOLCK
+#define TARGET_ENOLCK          46      /* No record locks available */
+#undef TARGET_EBADE
+#define TARGET_EBADE           50      /* Invalid exchange */
+#undef TARGET_EBADR
+#define TARGET_EBADR           51      /* Invalid request descriptor */
+#undef TARGET_EXFULL
+#define TARGET_EXFULL          52      /* TARGET_Exchange full */
+#undef TARGET_ENOANO
+#define TARGET_ENOANO          53      /* No anode */
+#undef TARGET_EBADRQC
+#define TARGET_EBADRQC         54      /* Invalid request code */
+#undef TARGET_EBADSLT
+#define TARGET_EBADSLT         55      /* Invalid slot */
+#undef TARGET_EDEADLOCK
+#define TARGET_EDEADLOCK       56      /* File locking deadlock error */
+#undef TARGET_EBFONT
+#define TARGET_EBFONT          59      /* Bad font file format */
+#undef TARGET_ENOSTR
+#define TARGET_ENOSTR          60      /* Device not a stream */
+#undef TARGET_ENODATA
+#define TARGET_ENODATA         61      /* No data available */
+#undef TARGET_ETIME
+#define TARGET_ETIME           62      /* Timer expired */
+#undef TARGET_ENOSR
+#define TARGET_ENOSR           63      /* Out of streams resources */
+#undef TARGET_ENONET
+#define TARGET_ENONET          64      /* Machine is not on the network */
+#undef TARGET_ENOPKG
+#define TARGET_ENOPKG          65      /* Package not installed */
+#undef TARGET_EREMOTE
+#define TARGET_EREMOTE         66      /* Object is remote */
+#undef TARGET_ENOLINK
+#define TARGET_ENOLINK         67      /* Link has been severed */
+#undef TARGET_EADV
+#define TARGET_EADV            68      /* Advertise error */
+#undef TARGET_ESRMNT
+#define TARGET_ESRMNT          69      /* Srmount error */
+#undef TARGET_ECOMM
+#define TARGET_ECOMM           70      /* Communication error on send */
+#undef TARGET_EPROTO
+#define TARGET_EPROTO          71      /* Protocol error */
+#undef TARGET_EDOTDOT
+#define TARGET_EDOTDOT         73      /* RFS specific error */
+#undef TARGET_EMULTIHOP
+#define TARGET_EMULTIHOP       74      /* Multihop attempted */
+#undef TARGET_EBADMSG
+#define TARGET_EBADMSG         77      /* Not a data message */
+#undef TARGET_ENAMETOOLONG
+#define TARGET_ENAMETOOLONG    78      /* File name too long */
+#undef TARGET_EOVERFLOW
+#define TARGET_EOVERFLOW       79      /* Value too large for defined data type */
+#undef TARGET_ENOTUNIQ
+#define TARGET_ENOTUNIQ        80      /* Name not unique on network */
+#undef TARGET_EBADFD
+#define TARGET_EBADFD          81      /* File descriptor in bad state */
+#undef TARGET_EREMCHG
+#define TARGET_EREMCHG         82      /* Remote address changed */
+#undef TARGET_ELIBACC
+#define TARGET_ELIBACC         83      /* Can not access a needed shared library */
+#undef TARGET_ELIBBAD
+#define TARGET_ELIBBAD         84      /* Accessing a corrupted shared library */
+#undef TARGET_ELIBSCN
+#define TARGET_ELIBSCN         85      /* .lib section in a.out corrupted */
+#undef TARGET_ELIBMAX
+#define TARGET_ELIBMAX         86      /* Attempting to link in too many shared libraries */
+#undef TARGET_ELIBEXEC
+#define TARGET_ELIBEXEC        87      /* Cannot exec a shared library directly */
+#undef TARGET_EILSEQ
+#define TARGET_EILSEQ          88      /* Illegal byte sequence */
+#undef TARGET_ENOSYS
+#define TARGET_ENOSYS          89      /* Function not implemented */
+#undef TARGET_ELOOP
+#define TARGET_ELOOP           90      /* Too many symbolic links encountered */
+#undef TARGET_ERESTART
+#define TARGET_ERESTART        91      /* Interrupted system call should be restarted */
+#undef TARGET_ESTRPIPE
+#define TARGET_ESTRPIPE        92      /* Streams pipe error */
+#undef TARGET_ENOTEMPTY
+#define TARGET_ENOTEMPTY       93      /* Directory not empty */
+#undef TARGET_EUSERS
+#define TARGET_EUSERS          94      /* Too many users */
+#undef TARGET_ENOTSOCK
+#define TARGET_ENOTSOCK        95      /* Socket operation on non-socket */
+#undef TARGET_EDESTADDRREQ
+#define TARGET_EDESTADDRREQ    96      /* Destination address required */
+#undef TARGET_EMSGSIZE
+#define TARGET_EMSGSIZE        97      /* Message too long */
+#undef TARGET_EPROTOTYPE
+#define TARGET_EPROTOTYPE      98      /* Protocol wrong type for socket */
+#undef TARGET_ENOPROTOOPT
+#define TARGET_ENOPROTOOPT     99      /* Protocol not available */
+#undef TARGET_EPROTONOSUPPORT
+#define TARGET_EPROTONOSUPPORT 120     /* Protocol not supported */
+#undef TARGET_ESOCKTNOSUPPORT
+#define TARGET_ESOCKTNOSUPPORT 121     /* Socket type not supported */
+#undef TARGET_EOPNOTSUPP
+#define TARGET_EOPNOTSUPP      122     /* Operation not supported on transport endpoint */
+#undef TARGET_EPFNOSUPPORT
+#define TARGET_EPFNOSUPPORT    123     /* Protocol family not supported */
+#undef TARGET_EAFNOSUPPORT
+#define TARGET_EAFNOSUPPORT    124     /* Address family not supported by protocol */
+#undef TARGET_EADDRINUSE
+#define TARGET_EADDRINUSE      125     /* Address already in use */
+#undef TARGET_EADDRNOTAVAIL
+#define TARGET_EADDRNOTAVAIL   126     /* Cannot assign requested address */
+#undef TARGET_ENETDOWN
+#define TARGET_ENETDOWN        127     /* Network is down */
+#undef TARGET_ENETUNREACH
+#define TARGET_ENETUNREACH     128     /* Network is unreachable */
+#undef TARGET_ENETRESET
+#define TARGET_ENETRESET       129     /* Network dropped connection because of reset */
+#undef TARGET_ECONNABORTED
+#define TARGET_ECONNABORTED    130     /* Software caused connection abort */
+#undef TARGET_ECONNRESET
+#define TARGET_ECONNRESET      131     /* Connection reset by peer */
+#undef TARGET_ENOBUFS
+#define TARGET_ENOBUFS         132     /* No buffer space available */
+#undef TARGET_EISCONN
+#define TARGET_EISCONN         133     /* Transport endpoint is already connected */
+#undef TARGET_ENOTCONN
+#define TARGET_ENOTCONN        134     /* Transport endpoint is not connected */
+#undef TARGET_EUCLEAN
+#define TARGET_EUCLEAN         135     /* Structure needs cleaning */
+#undef TARGET_ENOTNAM
+#define TARGET_ENOTNAM         137     /* Not a XENIX named type file */
+#undef TARGET_ENAVAIL
+#define TARGET_ENAVAIL         138     /* No XENIX semaphores available */
+#undef TARGET_EISNAM
+#define TARGET_EISNAM          139     /* Is a named type file */
+#undef TARGET_EREMOTEIO
+#define TARGET_EREMOTEIO       140     /* Remote I/O error */
+#undef TARGET_EINIT
+#define TARGET_EINIT           141     /* Reserved */
+#undef TARGET_EREMDEV
+#define TARGET_EREMDEV         142     /* TARGET_Error 142 */
+#undef TARGET_ESHUTDOWN
+#define TARGET_ESHUTDOWN       143     /* Cannot send after transport endpoint shutdown */
+#undef TARGET_ETOOMANYREFS
+#define TARGET_ETOOMANYREFS    144     /* Too many references: cannot splice */
+#undef TARGET_ETIMEDOUT
+#define TARGET_ETIMEDOUT       145     /* Connection timed out */
+#undef TARGET_ECONNREFUSED
+#define TARGET_ECONNREFUSED    146     /* Connection refused */
+#undef TARGET_EHOSTDOWN
+#define TARGET_EHOSTDOWN       147     /* Host is down */
+#undef TARGET_EHOSTUNREACH
+#define TARGET_EHOSTUNREACH    148     /* No route to host */
+#undef TARGET_EALREADY
+#define TARGET_EALREADY        149     /* Operation already in progress */
+#undef TARGET_EINPROGRESS
+#define TARGET_EINPROGRESS     150     /* Operation now in progress */
+#undef TARGET_ESTALE
+#define TARGET_ESTALE          151     /* Stale NFS file handle */
+#undef TARGET_ECANCELED
+#define TARGET_ECANCELED       158     /* AIO operation canceled */
+/*
+ * These error are Linux extensions.
+ */
+#undef TARGET_ENOMEDIUM
+#define TARGET_ENOMEDIUM       159     /* No medium found */
+#undef TARGET_EMEDIUMTYPE
+#define TARGET_EMEDIUMTYPE     160     /* Wrong medium type */
+#undef TARGET_ENOKEY
+#define TARGET_ENOKEY          161     /* Required key not available */
+#undef TARGET_EKEYEXPIRED
+#define TARGET_EKEYEXPIRED     162     /* Key has expired */
+#undef TARGET_EKEYREVOKED
+#define TARGET_EKEYREVOKED     163     /* Key has been revoked */
+#undef TARGET_EKEYREJECTED
+#define TARGET_EKEYREJECTED    164     /* Key was rejected by service */
+
+/* for robust mutexes */
+#undef TARGET_EOWNERDEAD
+#define TARGET_EOWNERDEAD      165     /* Owner died */
+#undef TARGET_ENOTRECOVERABLE
+#define TARGET_ENOTRECOVERABLE 166     /* State not recoverable */
+
+
+
 #define UNAME_MACHINE "mips"

Modified: trunk/src/host/qemu-neo1973/linux-user/mmap.c
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/mmap.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/linux-user/mmap.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -157,7 +157,7 @@
     target_ulong ret, end, real_start, real_end, retaddr, host_offset, host_len;
     long host_start;
 #if defined(__alpha__) || defined(__sparc__) || defined(__x86_64__) || \
-    defined(__ia64)
+        defined(__ia64) || defined(__mips__)
     static target_ulong last_start = 0x40000000;
 #elif defined(__CYGWIN__)
     /* Cygwin doesn't have a whole lot of address space.  */
@@ -202,8 +202,8 @@
 
     if (!(flags & MAP_FIXED)) {
 #if defined(__alpha__) || defined(__sparc__) || defined(__x86_64__) || \
-    defined(__ia64) || defined(__CYGWIN__)
-        /* tell the kenel to search at the same place as i386 */
+    defined(__ia64) || defined(__mips__) || defined(__CYGWIN__)
+        /* tell the kernel to search at the same place as i386 */
         if (real_start == 0) {
             real_start = last_start;
             last_start += HOST_PAGE_ALIGN(len);

Modified: trunk/src/host/qemu-neo1973/linux-user/path.c
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/path.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/linux-user/path.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -92,23 +92,6 @@
 	set_parents(child->entries[i], child);
 }
 
-void init_paths(const char *prefix)
-{
-    if (prefix[0] != '/' ||
-        prefix[0] == '\0' ||
-        !strcmp(prefix, "/"))
-        return;
-
-    base = new_entry("", NULL, prefix+1);
-    base = add_dir_maybe(base);
-    if (base->num_entries == 0) {
-        free (base);
-        base = NULL;
-    } else {
-        set_parents(base, base);
-    }
-}
-
 /* FIXME: Doesn't handle DIR/.. where DIR is not in emulated dir. */
 static const char *
 follow_path(const struct pathelem *cursor, const char *name)
@@ -135,6 +118,35 @@
     return NULL;
 }
 
+void init_paths(const char *prefix)
+{
+    char pref_buf[PATH_MAX];
+
+    if (prefix[0] == '\0' ||
+        !strcmp(prefix, "/"))
+        return;
+
+    if (prefix[0] != '/') {
+        char *cwd = get_current_dir_name();
+	if (!cwd)
+            abort();
+	strcpy(pref_buf, cwd);
+        strcat(pref_buf, "/");
+        strcat(pref_buf, prefix);
+        free(cwd);
+    } else
+        strcpy(pref_buf,prefix + 1);
+
+    base = new_entry("", NULL, pref_buf);
+    base = add_dir_maybe(base);
+    if (base->num_entries == 0) {
+        free (base);
+        base = NULL;
+    } else {
+        set_parents(base, base);
+    }
+}
+
 /* Look for path in emulation dir, otherwise return name. */
 const char *path(const char *name)
 {

Modified: trunk/src/host/qemu-neo1973/linux-user/ppc/syscall.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/ppc/syscall.h	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/linux-user/ppc/syscall.h	2007-06-17 16:55:00 UTC (rev 2289)
@@ -51,80 +51,4 @@
  * flags masks
  */
 
-/* ipcs */
-
-#define TARGET_SEMOP           1
-#define TARGET_SEMGET          2
-#define TARGET_SEMCTL          3 
-#define TARGET_MSGSND          11 
-#define TARGET_MSGRCV          12
-#define TARGET_MSGGET          13
-#define TARGET_MSGCTL          14
-#define TARGET_SHMAT           21
-#define TARGET_SHMDT           22
-#define TARGET_SHMGET          23
-#define TARGET_SHMCTL          24
-
-struct target_msgbuf {
-	int mtype;
-	char mtext[1];
-};
-
-struct target_ipc_kludge {
-	unsigned int	msgp;	/* Really (struct msgbuf *) */
-	int msgtyp;
-};	
-
-struct target_ipc_perm {
-	int	key;
-	unsigned short	uid;
-	unsigned short	gid;
-	unsigned short	cuid;
-	unsigned short	cgid;
-	unsigned short	mode;
-	unsigned short	seq;
-};
-
-struct target_msqid_ds {
-	struct target_ipc_perm	msg_perm;
-	unsigned int		msg_first;	/* really struct target_msg* */
-	unsigned int		msg_last;	/* really struct target_msg* */
-	unsigned int		msg_stime;	/* really target_time_t */
-	unsigned int		msg_rtime;	/* really target_time_t */
-	unsigned int		msg_ctime;	/* really target_time_t */
-	unsigned int		wwait;		/* really struct wait_queue* */
-	unsigned int		rwait;		/* really struct wait_queue* */
-	unsigned short		msg_cbytes;
-	unsigned short		msg_qnum;
-	unsigned short		msg_qbytes;
-	unsigned short		msg_lspid;
-	unsigned short		msg_lrpid;
-};
-
-struct target_shmid_ds {
-	struct target_ipc_perm	shm_perm;
-	int			shm_segsz;
-	unsigned int		shm_atime;	/* really target_time_t */
-	unsigned int		shm_dtime;	/* really target_time_t */
-	unsigned int		shm_ctime;	/* really target_time_t */
-	unsigned short		shm_cpid;
-	unsigned short		shm_lpid;
-	short			shm_nattch;
-	unsigned short		shm_npages;
-	unsigned long		*shm_pages;
-	void 			*attaches;	/* really struct shm_desc * */
-};
-
-#define TARGET_IPC_RMID	0
-#define TARGET_IPC_SET	1
-#define TARGET_IPC_STAT	2
-
-union target_semun {
-    int val;
-    unsigned int buf;	/* really struct semid_ds * */
-    unsigned int array; /* really unsigned short * */
-    unsigned int __buf;	/* really struct seminfo * */
-    unsigned int __pad;	/* really void* */
-};
-
 #define UNAME_MACHINE "ppc"

Modified: trunk/src/host/qemu-neo1973/linux-user/qemu.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/qemu.h	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/linux-user/qemu.h	2007-06-17 16:55:00 UTC (rev 2289)
@@ -62,10 +62,6 @@
 #ifdef TARGET_ARM
     /* FPA state */
     FPA11 fpa;
-    /* Extra fields for semihosted binaries.  */
-    uint32_t stack_base;
-    uint32_t heap_base;
-    uint32_t heap_limit;
     int swi_errno;
 #endif
 #if defined(TARGET_I386) && !defined(TARGET_X86_64)
@@ -78,6 +74,12 @@
 #ifdef TARGET_M68K
     int sim_syscalls;
 #endif
+#if defined(TARGET_ARM) || defined(TARGET_M68K)
+    /* Extra fields for semihosted binaries.  */
+    uint32_t stack_base;
+    uint32_t heap_base;
+    uint32_t heap_limit;
+#endif
     int used; /* non zero if used */
     struct image_info *info;
     uint8_t stack[0];

Modified: trunk/src/host/qemu-neo1973/linux-user/syscall.c
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/syscall.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/linux-user/syscall.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -181,10 +181,117 @@
 extern int getresgid(gid_t *, gid_t *, gid_t *);
 extern int setgroups(int, gid_t *);
 
+/*
+ * This list is the union of errno values overidden in asm-<arch>/errno.h
+ * minus the errnos that are not actually generic to all archs.
+ */
+static uint16_t host_to_target_errno_table[1200] = {
+    [EIDRM]		= TARGET_EIDRM,
+    [ECHRNG]		= TARGET_ECHRNG,
+    [EL2NSYNC]		= TARGET_EL2NSYNC,
+    [EL3HLT]		= TARGET_EL3HLT,
+    [EL3RST]		= TARGET_EL3RST,
+    [ELNRNG]		= TARGET_ELNRNG,
+    [EUNATCH]		= TARGET_EUNATCH,
+    [ENOCSI]		= TARGET_ENOCSI,
+    [EL2HLT]		= TARGET_EL2HLT,
+    [EDEADLK]		= TARGET_EDEADLK,
+    [ENOLCK]		= TARGET_ENOLCK,
+    [EBADE]		= TARGET_EBADE,
+    [EBADR]		= TARGET_EBADR,
+    [EXFULL]		= TARGET_EXFULL,
+    [ENOANO]		= TARGET_ENOANO,
+    [EBADRQC]		= TARGET_EBADRQC,
+    [EBADSLT]		= TARGET_EBADSLT,
+    [EBFONT]		= TARGET_EBFONT,
+    [ENOSTR]		= TARGET_ENOSTR,
+    [ENODATA]		= TARGET_ENODATA,
+    [ETIME]		= TARGET_ETIME,
+    [ENOSR]		= TARGET_ENOSR,
+    [ENONET]		= TARGET_ENONET,
+    [ENOPKG]		= TARGET_ENOPKG,
+    [EREMOTE]		= TARGET_EREMOTE,
+    [ENOLINK]		= TARGET_ENOLINK,
+    [EADV]		= TARGET_EADV,
+    [ESRMNT]		= TARGET_ESRMNT,
+    [ECOMM]		= TARGET_ECOMM,
+    [EPROTO]		= TARGET_EPROTO,
+    [EDOTDOT]		= TARGET_EDOTDOT,
+    [EMULTIHOP]		= TARGET_EMULTIHOP,
+    [EBADMSG]		= TARGET_EBADMSG,
+    [ENAMETOOLONG]	= TARGET_ENAMETOOLONG,
+    [EOVERFLOW]		= TARGET_EOVERFLOW,
+    [ENOTUNIQ]		= TARGET_ENOTUNIQ,
+    [EBADFD]		= TARGET_EBADFD,
+    [EREMCHG]		= TARGET_EREMCHG,
+    [ELIBACC]		= TARGET_ELIBACC,
+    [ELIBBAD]		= TARGET_ELIBBAD,
+    [ELIBSCN]		= TARGET_ELIBSCN,
+    [ELIBMAX]		= TARGET_ELIBMAX,
+    [ELIBEXEC]		= TARGET_ELIBEXEC,
+    [EILSEQ]		= TARGET_EILSEQ,
+    [ENOSYS]		= TARGET_ENOSYS,
+    [ELOOP]		= TARGET_ELOOP,
+    [ERESTART]		= TARGET_ERESTART,
+    [ESTRPIPE]		= TARGET_ESTRPIPE,
+    [ENOTEMPTY]		= TARGET_ENOTEMPTY,
+    [EUSERS]		= TARGET_EUSERS,
+    [ENOTSOCK]		= TARGET_ENOTSOCK,
+    [EDESTADDRREQ]	= TARGET_EDESTADDRREQ,
+    [EMSGSIZE]		= TARGET_EMSGSIZE,
+    [EPROTOTYPE]	= TARGET_EPROTOTYPE,
+    [ENOPROTOOPT]	= TARGET_ENOPROTOOPT,
+    [EPROTONOSUPPORT]	= TARGET_EPROTONOSUPPORT,
+    [ESOCKTNOSUPPORT]	= TARGET_ESOCKTNOSUPPORT,
+    [EOPNOTSUPP]	= TARGET_EOPNOTSUPP,
+    [EPFNOSUPPORT]	= TARGET_EPFNOSUPPORT,
+    [EAFNOSUPPORT]	= TARGET_EAFNOSUPPORT,
+    [EADDRINUSE]	= TARGET_EADDRINUSE,
+    [EADDRNOTAVAIL]	= TARGET_EADDRNOTAVAIL,
+    [ENETDOWN]		= TARGET_ENETDOWN,
+    [ENETUNREACH]	= TARGET_ENETUNREACH,
+    [ENETRESET]		= TARGET_ENETRESET,
+    [ECONNABORTED]	= TARGET_ECONNABORTED,
+    [ECONNRESET]	= TARGET_ECONNRESET,
+    [ENOBUFS]		= TARGET_ENOBUFS,
+    [EISCONN]		= TARGET_EISCONN,
+    [ENOTCONN]		= TARGET_ENOTCONN,
+    [EUCLEAN]		= TARGET_EUCLEAN,
+    [ENOTNAM]		= TARGET_ENOTNAM,
+    [ENAVAIL]		= TARGET_ENAVAIL,
+    [EISNAM]		= TARGET_EISNAM,
+    [EREMOTEIO]		= TARGET_EREMOTEIO,
+    [ESHUTDOWN]		= TARGET_ESHUTDOWN,
+    [ETOOMANYREFS]	= TARGET_ETOOMANYREFS,
+    [ETIMEDOUT]		= TARGET_ETIMEDOUT,
+    [ECONNREFUSED]	= TARGET_ECONNREFUSED,
+    [EHOSTDOWN]		= TARGET_EHOSTDOWN,
+    [EHOSTUNREACH]	= TARGET_EHOSTUNREACH,
+    [EALREADY]		= TARGET_EALREADY,
+    [EINPROGRESS]	= TARGET_EINPROGRESS,
+    [ESTALE]		= TARGET_ESTALE,
+    [ECANCELED]		= TARGET_ECANCELED,
+    [ENOMEDIUM]		= TARGET_ENOMEDIUM,
+    [EMEDIUMTYPE]	= TARGET_EMEDIUMTYPE,
+    [ENOKEY]		= TARGET_ENOKEY,
+    [EKEYEXPIRED]	= TARGET_EKEYEXPIRED,
+    [EKEYREVOKED]	= TARGET_EKEYREVOKED,
+    [EKEYREJECTED]	= TARGET_EKEYREJECTED,
+    [EOWNERDEAD]	= TARGET_EOWNERDEAD,
+    [ENOTRECOVERABLE]	= TARGET_ENOTRECOVERABLE,
+	};
+
+static inline int host_to_target_errno(int err)
+{
+    if(host_to_target_errno_table[err])
+        return host_to_target_errno_table[err];
+    return err;
+}
+
 static inline long get_errno(long ret)
 {
     if (ret == -1)
-        return -errno;
+        return -host_to_target_errno(errno);
     else
         return ret;
 }
@@ -1123,12 +1230,324 @@
     uint32_t	size;
 } shm_regions[N_SHM_REGIONS];
 
+struct target_ipc_perm
+{
+    target_long __key;
+    target_ulong uid;
+    target_ulong gid;
+    target_ulong cuid;
+    target_ulong cgid;
+    unsigned short int mode;
+    unsigned short int __pad1;
+    unsigned short int __seq;
+    unsigned short int __pad2;
+    target_ulong __unused1;
+    target_ulong __unused2;
+};
+
+struct target_semid_ds
+{
+  struct target_ipc_perm sem_perm;
+  target_ulong sem_otime;
+  target_ulong __unused1;
+  target_ulong sem_ctime;
+  target_ulong __unused2;
+  target_ulong sem_nsems;
+  target_ulong __unused3;
+  target_ulong __unused4;
+};
+
+static inline void target_to_host_ipc_perm(struct ipc_perm *host_ip,
+                                           target_ulong target_addr)
+{
+    struct target_ipc_perm *target_ip;
+    struct target_semid_ds *target_sd;
+
+    lock_user_struct(target_sd, target_addr, 1);
+    target_ip=&(target_sd->sem_perm);
+    host_ip->__key = tswapl(target_ip->__key);
+    host_ip->uid = tswapl(target_ip->uid);
+    host_ip->gid = tswapl(target_ip->gid);
+    host_ip->cuid = tswapl(target_ip->cuid);
+    host_ip->cgid = tswapl(target_ip->cgid);
+    host_ip->mode = tswapl(target_ip->mode);
+    unlock_user_struct(target_sd, target_addr, 0);
+}
+
+static inline void host_to_target_ipc_perm(target_ulong target_addr,
+                                           struct ipc_perm *host_ip)
+{
+    struct target_ipc_perm *target_ip;
+    struct target_semid_ds *target_sd;
+
+    lock_user_struct(target_sd, target_addr, 0);
+    target_ip = &(target_sd->sem_perm);
+    target_ip->__key = tswapl(host_ip->__key);
+    target_ip->uid = tswapl(host_ip->uid);
+    target_ip->gid = tswapl(host_ip->gid);
+    target_ip->cuid = tswapl(host_ip->cuid);
+    target_ip->cgid = tswapl(host_ip->cgid);
+    target_ip->mode = tswapl(host_ip->mode);
+    unlock_user_struct(target_sd, target_addr, 1);
+}
+
+static inline void target_to_host_semid_ds(struct semid_ds *host_sd,
+                                          target_ulong target_addr)
+{
+    struct target_semid_ds *target_sd;
+
+    lock_user_struct(target_sd, target_addr, 1);
+    target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr);
+    host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
+    host_sd->sem_otime = tswapl(target_sd->sem_otime);
+    host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
+    unlock_user_struct(target_sd, target_addr, 0);
+}
+
+static inline void host_to_target_semid_ds(target_ulong target_addr,
+                                           struct semid_ds *host_sd)
+{
+    struct target_semid_ds *target_sd;
+
+    lock_user_struct(target_sd, target_addr, 0);
+    host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm));
+    target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
+    target_sd->sem_otime = tswapl(host_sd->sem_otime);
+    target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
+    unlock_user_struct(target_sd, target_addr, 1);
+}
+
 union semun {
 	int val;
-	struct senid_ds *buf;
+	struct semid_ds *buf;
 	unsigned short *array;
 };
 
+union target_semun {
+	int val;
+	target_long buf;
+	unsigned short int *array;
+};
+
+static inline void target_to_host_semun(unsigned long cmd,
+                                        union semun *host_su,
+                                        target_ulong target_addr,
+                                        struct semid_ds *ds)
+{
+    union target_semun *target_su;
+
+    switch( cmd ) {
+	case IPC_STAT:
+	case IPC_SET:
+           lock_user_struct(target_su, target_addr, 1);
+	   target_to_host_semid_ds(ds,target_su->buf);
+	   host_su->buf = ds;
+           unlock_user_struct(target_su, target_addr, 0);
+	   break;
+	case GETVAL:
+	case SETVAL:
+           lock_user_struct(target_su, target_addr, 1);
+	   host_su->val = tswapl(target_su->val);
+           unlock_user_struct(target_su, target_addr, 0);
+	   break;
+	case GETALL:
+	case SETALL:
+           lock_user_struct(target_su, target_addr, 1);
+	   *host_su->array = tswap16(*target_su->array);
+           unlock_user_struct(target_su, target_addr, 0);
+	   break;
+	default:
+           gemu_log("semun operation not fully supported: %d\n", (int)cmd);
+    }
+}
+
+static inline void host_to_target_semun(unsigned long cmd,
+                                        target_ulong target_addr,
+                                        union semun *host_su,
+                                        struct semid_ds *ds)
+{
+    union target_semun *target_su;
+
+    switch( cmd ) {
+	case IPC_STAT:
+	case IPC_SET:
+           lock_user_struct(target_su, target_addr, 0);
+	   host_to_target_semid_ds(target_su->buf,ds);
+           unlock_user_struct(target_su, target_addr, 1);
+	   break;
+	case GETVAL:
+	case SETVAL:
+           lock_user_struct(target_su, target_addr, 0);
+	   target_su->val = tswapl(host_su->val);
+           unlock_user_struct(target_su, target_addr, 1);
+	   break;
+	case GETALL:
+	case SETALL:
+           lock_user_struct(target_su, target_addr, 0);
+	   *target_su->array = tswap16(*host_su->array);
+           unlock_user_struct(target_su, target_addr, 1);
+	   break;
+        default:
+           gemu_log("semun operation not fully supported: %d\n", (int)cmd);
+    }
+}
+
+static inline long do_semctl(long first, long second, long third, long ptr)
+{
+    union semun arg;
+    struct semid_ds dsarg;
+    int cmd = third&0xff;
+    long ret = 0;
+
+    switch( cmd ) {
+	case GETVAL:
+            target_to_host_semun(cmd,&arg,ptr,&dsarg);
+            ret = get_errno(semctl(first, second, cmd, arg));
+            host_to_target_semun(cmd,ptr,&arg,&dsarg);
+            break;
+	case SETVAL:
+            target_to_host_semun(cmd,&arg,ptr,&dsarg);
+            ret = get_errno(semctl(first, second, cmd, arg));
+            host_to_target_semun(cmd,ptr,&arg,&dsarg);
+            break;
+	case GETALL:
+            target_to_host_semun(cmd,&arg,ptr,&dsarg);
+            ret = get_errno(semctl(first, second, cmd, arg));
+            host_to_target_semun(cmd,ptr,&arg,&dsarg);
+            break;
+	case SETALL:
+            target_to_host_semun(cmd,&arg,ptr,&dsarg);
+            ret = get_errno(semctl(first, second, cmd, arg));
+            host_to_target_semun(cmd,ptr,&arg,&dsarg);
+            break;
+	case IPC_STAT:
+            target_to_host_semun(cmd,&arg,ptr,&dsarg);
+            ret = get_errno(semctl(first, second, cmd, arg));
+            host_to_target_semun(cmd,ptr,&arg,&dsarg);
+            break;
+	case IPC_SET:
+            target_to_host_semun(cmd,&arg,ptr,&dsarg);
+            ret = get_errno(semctl(first, second, cmd, arg));
+            host_to_target_semun(cmd,ptr,&arg,&dsarg);
+            break;
+    default:
+            ret = get_errno(semctl(first, second, cmd, arg));
+    }
+
+    return ret;
+}
+
+struct target_msqid_ds
+{
+  struct target_ipc_perm msg_perm;
+  target_ulong msg_stime;
+  target_ulong __unused1;
+  target_ulong msg_rtime;
+  target_ulong __unused2;
+  target_ulong msg_ctime;
+  target_ulong __unused3;
+  target_ulong __msg_cbytes;
+  target_ulong msg_qnum;
+  target_ulong msg_qbytes;
+  target_ulong msg_lspid;
+  target_ulong msg_lrpid;
+  target_ulong __unused4;
+  target_ulong __unused5;
+};
+
+static inline void target_to_host_msqid_ds(struct msqid_ds *host_md,
+                                          target_ulong target_addr)
+{
+    struct target_msqid_ds *target_md;
+
+    lock_user_struct(target_md, target_addr, 1);
+    target_to_host_ipc_perm(&(host_md->msg_perm),target_addr);
+    host_md->msg_stime = tswapl(target_md->msg_stime);
+    host_md->msg_rtime = tswapl(target_md->msg_rtime);
+    host_md->msg_ctime = tswapl(target_md->msg_ctime);
+    host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
+    host_md->msg_qnum = tswapl(target_md->msg_qnum);
+    host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
+    host_md->msg_lspid = tswapl(target_md->msg_lspid);
+    host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
+    unlock_user_struct(target_md, target_addr, 0);
+}
+
+static inline void host_to_target_msqid_ds(target_ulong target_addr,
+                                           struct msqid_ds *host_md)
+{
+    struct target_msqid_ds *target_md;
+
+    lock_user_struct(target_md, target_addr, 0);
+    host_to_target_ipc_perm(target_addr,&(host_md->msg_perm));
+    target_md->msg_stime = tswapl(host_md->msg_stime);
+    target_md->msg_rtime = tswapl(host_md->msg_rtime);
+    target_md->msg_ctime = tswapl(host_md->msg_ctime);
+    target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
+    target_md->msg_qnum = tswapl(host_md->msg_qnum);
+    target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
+    target_md->msg_lspid = tswapl(host_md->msg_lspid);
+    target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
+    unlock_user_struct(target_md, target_addr, 1);
+}
+
+static inline long do_msgctl(long first, long second, long ptr)
+{
+    struct msqid_ds dsarg;
+    int cmd = second&0xff;
+    long ret = 0;
+    switch( cmd ) {
+    case IPC_STAT:
+    case IPC_SET:
+        target_to_host_msqid_ds(&dsarg,ptr);
+        ret = get_errno(msgctl(first, cmd, &dsarg));
+        host_to_target_msqid_ds(ptr,&dsarg);
+    default:
+        ret = get_errno(msgctl(first, cmd, &dsarg));
+    }
+    return ret;
+}
+
+struct target_msgbuf {
+	target_ulong mtype;
+	char	mtext[1];
+};
+
+static inline long do_msgsnd(long msqid, long msgp, long msgsz, long msgflg)
+{
+    struct target_msgbuf *target_mb;
+    struct msgbuf *host_mb;
+    long ret = 0;
+
+    lock_user_struct(target_mb,msgp,0);
+    host_mb = malloc(msgsz+sizeof(long));
+    host_mb->mtype = tswapl(target_mb->mtype);
+    memcpy(host_mb->mtext,target_mb->mtext,msgsz);
+    ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
+    free(host_mb);
+    unlock_user_struct(target_mb, msgp, 0);
+
+    return ret;
+}
+
+static inline long do_msgrcv(long msqid, long msgp, long msgsz, long msgtype, long msgflg)
+{
+    struct target_msgbuf *target_mb;
+    struct msgbuf *host_mb;
+    long ret = 0;
+
+    lock_user_struct(target_mb, msgp, 0);
+    host_mb = malloc(msgsz+sizeof(long));
+    ret = get_errno(msgrcv(msqid, host_mb, msgsz, 1, msgflg));
+    if (ret > 0)
+    	memcpy(target_mb->mtext, host_mb->mtext, ret);
+    target_mb->mtype = tswapl(host_mb->mtype);
+    free(host_mb);
+    unlock_user_struct(target_mb, msgp, 0);
+
+    return ret;
+}
+
 /* ??? This only works with linear mappings.  */
 static long do_ipc(long call, long first, long second, long third,
 		   long ptr, long fifth)
@@ -1152,8 +1571,7 @@
         break;
 
     case IPCOP_semctl:
-        ret = get_errno(semctl(first, second, third, ((union semun*)ptr)->val));
-
+        ret = do_semctl(first, second, third, ptr);
         break;
 
     case IPCOP_semtimedop:
@@ -1166,27 +1584,27 @@
 		break;
 
 	case IPCOP_msgsnd:
-		ret = get_errno(msgsnd(first, (struct msgbuf *) ptr, second, third));
+		ret = do_msgsnd(first, ptr, second, third);
 		break;
 
 	case IPCOP_msgctl:
-		ret = get_errno(msgctl(first, second, (struct msqid_ds *) ptr));
+        	ret = do_msgctl(first, second, ptr);
 		break;
 
 	case IPCOP_msgrcv:
-		{
-			struct ipc_kludge
-			{
-				void *__unbounded msgp;
-				long int msgtyp;
-			};
+                {
+                      struct ipc_kludge
+                      {
+                              void *__unbounded msgp;
+                              long int msgtyp;
+                      };
 
-			struct ipc_kludge *foo = (struct ipc_kludge *) ptr;
-			struct msgbuf *msgp = (struct msgbuf *) foo->msgp;
+                      struct ipc_kludge *foo = (struct ipc_kludge *) ptr;
+                      struct msgbuf *msgp = (struct msgbuf *) foo->msgp;
 
-			ret = get_errno(msgrcv(first, msgp, second, 0, third));
+                      ret = do_msgrcv(first, (long)msgp, second, 0, third);
 
-		}
+                }
 		break;
 
     case IPCOP_shmat:
@@ -2338,8 +2756,13 @@
             int host_pipe[2];
             ret = get_errno(pipe(host_pipe));
             if (!is_error(ret)) {
+#if defined(TARGET_MIPS)
+		((CPUMIPSState*)cpu_env)->gpr[3] = host_pipe[1];
+		ret = host_pipe[0];
+#else
                 tput32(arg1, host_pipe[0]);
                 tput32(arg1 + 4, host_pipe[1]);
+#endif
             }
         }
         break;
@@ -3108,9 +3531,13 @@
         do_stat:
             if (!is_error(ret)) {
                 struct target_stat *target_st;
-                
+
                 lock_user_struct(target_st, arg2, 0);
+#if defined(TARGET_MIPS)
+                target_st->st_dev = tswap32(st.st_dev);
+#else
                 target_st->st_dev = tswap16(st.st_dev);
+#endif
                 target_st->st_ino = tswapl(st.st_ino);
 #if defined(TARGET_PPC) || defined(TARGET_MIPS)
                 target_st->st_mode = tswapl(st.st_mode); /* XXX: check this */
@@ -3121,8 +3548,14 @@
                 target_st->st_uid = tswap16(st.st_uid);
                 target_st->st_gid = tswap16(st.st_gid);
 #endif
+#if defined(TARGET_MIPS)
+		/* If this is the same on PPC, then just merge w/ the above ifdef */
+                target_st->st_nlink = tswapl(st.st_nlink);
+                target_st->st_rdev = tswapl(st.st_rdev);
+#else
                 target_st->st_nlink = tswap16(st.st_nlink);
                 target_st->st_rdev = tswap16(st.st_rdev);
+#endif
                 target_st->st_size = tswapl(st.st_size);
                 target_st->st_blksize = tswapl(st.st_blksize);
                 target_st->st_blocks = tswapl(st.st_blocks);

Modified: trunk/src/host/qemu-neo1973/linux-user/syscall_defs.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/syscall_defs.h	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/linux-user/syscall_defs.h	2007-06-17 16:55:00 UTC (rev 2289)
@@ -176,19 +176,14 @@
 static __inline__ struct target_cmsghdr *
 __target_cmsg_nxthdr (struct target_msghdr *__mhdr, struct target_cmsghdr *__cmsg)
 {
-  if (tswapl(__cmsg->cmsg_len) < sizeof (struct target_cmsghdr))
-    /* The kernel header does this so there may be a reason.  */
-    return 0;
+  struct target_cmsghdr *__ptr;
 
-  __cmsg = (struct target_cmsghdr *) ((unsigned char *) __cmsg
-                               + TARGET_CMSG_ALIGN (tswapl(__cmsg->cmsg_len)));
-  if ((unsigned char *) (__cmsg + 1) > ((unsigned char *) tswapl(__mhdr->msg_control)
-                                        + tswapl(__mhdr->msg_controllen))
-      || ((unsigned char *) __cmsg + TARGET_CMSG_ALIGN (tswapl(__cmsg->cmsg_len))
-          > ((unsigned char *) tswapl(__mhdr->msg_control) 
-             + tswapl(__mhdr->msg_controllen))))
+  __ptr = (struct target_cmsghdr *)((unsigned char *) __cmsg
+                                    + TARGET_CMSG_ALIGN (tswapl(__cmsg->cmsg_len)));
+  if ((unsigned long)((char *)(__ptr+1) - (char *)(size_t)tswapl(__mhdr->msg_control))
+      > tswapl(__mhdr->msg_controllen))
     /* No more entries.  */
-    return 0;
+    return (struct target_cmsghdr *)0;
   return __cmsg;
 }
 
@@ -1621,3 +1616,5 @@
 };
 
 #include "socket.h"
+
+#include "errno_defs.h"

Modified: trunk/src/host/qemu-neo1973/mips-dis.c
===================================================================
--- trunk/src/host/qemu-neo1973/mips-dis.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/mips-dis.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -207,12 +207,72 @@
 #define	OP_OP_SDC2		0x3e
 #define	OP_OP_SDC3		0x3f	/* a.k.a. sd */
 
+/* MIPS DSP ASE */
+#define OP_SH_DSPACC		11
+#define OP_MASK_DSPACC  	0x3
+#define OP_SH_DSPACC_S  	21
+#define OP_MASK_DSPACC_S	0x3
+#define OP_SH_DSPSFT		20
+#define OP_MASK_DSPSFT  	0x3f
+#define OP_SH_DSPSFT_7  	19
+#define OP_MASK_DSPSFT_7	0x7f
+#define OP_SH_SA3		21
+#define OP_MASK_SA3		0x7
+#define OP_SH_SA4		21
+#define OP_MASK_SA4		0xf
+#define OP_SH_IMM8		16
+#define OP_MASK_IMM8		0xff
+#define OP_SH_IMM10		16
+#define OP_MASK_IMM10		0x3ff
+#define OP_SH_WRDSP		11
+#define OP_MASK_WRDSP		0x3f
+#define OP_SH_RDDSP		16
+#define OP_MASK_RDDSP		0x3f
+#define OP_SH_BP		11
+#define OP_MASK_BP		0x3
+
+/* MIPS MT ASE */
+#define OP_SH_MT_U		5
+#define OP_MASK_MT_U		0x1
+#define OP_SH_MT_H		4
+#define OP_MASK_MT_H		0x1
+#define OP_SH_MTACC_T		18
+#define OP_MASK_MTACC_T		0x3
+#define OP_SH_MTACC_D		13
+#define OP_MASK_MTACC_D		0x3
+
+#define	OP_OP_COP0		0x10
+#define	OP_OP_COP1		0x11
+#define	OP_OP_COP2		0x12
+#define	OP_OP_COP3		0x13
+#define	OP_OP_LWC1		0x31
+#define	OP_OP_LWC2		0x32
+#define	OP_OP_LWC3		0x33	/* a.k.a. pref */
+#define	OP_OP_LDC1		0x35
+#define	OP_OP_LDC2		0x36
+#define	OP_OP_LDC3		0x37	/* a.k.a. ld */
+#define	OP_OP_SWC1		0x39
+#define	OP_OP_SWC2		0x3a
+#define	OP_OP_SWC3		0x3b
+#define	OP_OP_SDC1		0x3d
+#define	OP_OP_SDC2		0x3e
+#define	OP_OP_SDC3		0x3f	/* a.k.a. sd */
+
 /* Values in the 'VSEL' field.  */
 #define MDMX_FMTSEL_IMM_QH	0x1d
 #define MDMX_FMTSEL_IMM_OB	0x1e
 #define MDMX_FMTSEL_VEC_QH	0x15
 #define MDMX_FMTSEL_VEC_OB	0x16
 
+/* UDI */
+#define OP_SH_UDI1		6
+#define OP_MASK_UDI1		0x1f
+#define OP_SH_UDI2		6
+#define OP_MASK_UDI2		0x3ff
+#define OP_SH_UDI3		6
+#define OP_MASK_UDI3		0x7fff
+#define OP_SH_UDI4		6
+#define OP_MASK_UDI4		0xfffff
 /* This structure holds information for a particular instruction.  */
 
 struct mips_opcode
@@ -235,6 +295,8 @@
      of bits describing the instruction, notably any relevant hazard
      information.  */
   unsigned long pinfo;
+  /* A collection of additional bits describing the instruction. */
+  unsigned long pinfo2;
   /* A collection of bits describing the instruction sets of which this
      instruction or macro is a member. */
   unsigned long membership;
@@ -276,19 +338,20 @@
    "x" accept and ignore register name
    "z" must be zero register
    "K" 5 bit Hardware Register (rdhwr instruction) (OP_*_RD)
-   "+A" 5 bit ins/ext position, which becomes LSB (OP_*_SHAMT).
+   "+A" 5 bit ins/ext/dins/dext/dinsm/dextm position, which becomes
+        LSB (OP_*_SHAMT).
 	Enforces: 0 <= pos < 32.
-   "+B" 5 bit ins size, which becomes MSB (OP_*_INSMSB).
+   "+B" 5 bit ins/dins size, which becomes MSB (OP_*_INSMSB).
 	Requires that "+A" or "+E" occur first to set position.
 	Enforces: 0 < (pos+size) <= 32.
-   "+C" 5 bit ext size, which becomes MSBD (OP_*_EXTMSBD).
+   "+C" 5 bit ext/dext size, which becomes MSBD (OP_*_EXTMSBD).
 	Requires that "+A" or "+E" occur first to set position.
 	Enforces: 0 < (pos+size) <= 32.
 	(Also used by "dext" w/ different limits, but limits for
 	that are checked by the M_DEXT macro.)
-   "+E" 5 bit dins/dext position, which becomes LSB-32 (OP_*_SHAMT).
+   "+E" 5 bit dinsu/dextu position, which becomes LSB-32 (OP_*_SHAMT).
 	Enforces: 32 <= pos < 64.
-   "+F" 5 bit "dinsm" size, which becomes MSB-32 (OP_*_INSMSB).
+   "+F" 5 bit "dinsm/dinsu" size, which becomes MSB-32 (OP_*_INSMSB).
 	Requires that "+A" or "+E" occur first to set position.
 	Enforces: 32 < (pos+size) <= 64.
    "+G" 5 bit "dextm" size, which becomes MSBD-32 (OP_*_EXTMSBD).
@@ -336,6 +399,35 @@
    "Y"	MDMX source register (OP_*_FS)
    "Z"	MDMX source register (OP_*_FT)
 
+   DSP ASE usage:
+   "2" 2 bit unsigned immediate for byte align (OP_*_BP)
+   "3" 3 bit unsigned immediate (OP_*_SA3)
+   "4" 4 bit unsigned immediate (OP_*_SA4)
+   "5" 8 bit unsigned immediate (OP_*_IMM8)
+   "6" 5 bit unsigned immediate (OP_*_RS)
+   "7" 2 bit dsp accumulator register (OP_*_DSPACC)
+   "8" 6 bit unsigned immediate (OP_*_WRDSP)
+   "9" 2 bit dsp accumulator register (OP_*_DSPACC_S)
+   "0" 6 bit signed immediate (OP_*_DSPSFT)
+   ":" 7 bit signed immediate (OP_*_DSPSFT_7)
+   "'" 6 bit unsigned immediate (OP_*_RDDSP)
+   "@" 10 bit signed immediate (OP_*_IMM10)
+
+   MT ASE usage:
+   "!" 1 bit usermode flag (OP_*_MT_U)
+   "$" 1 bit load high flag (OP_*_MT_H)
+   "*" 2 bit dsp/smartmips accumulator register (OP_*_MTACC_T)
+   "&" 2 bit dsp/smartmips accumulator register (OP_*_MTACC_D)
+   "g" 5 bit coprocessor 1 and 2 destination register (OP_*_RD)
+   "+t" 5 bit coprocessor 0 destination register (OP_*_RT)
+   "+T" 5 bit coprocessor 0 destination register (OP_*_RT) - disassembly only
+
+   UDI immediates:
+   "+1" UDI immediate bits 6-10
+   "+2" UDI immediate bits 6-15
+   "+3" UDI immediate bits 6-20
+   "+4" UDI immediate bits 6-25
+
    Other:
    "()" parens surrounding optional value
    ","  separates operands
@@ -343,13 +435,16 @@
    "+"  Start of extension sequence.
 
    Characters used so far, for quick reference when adding more:
-   "%[]<>(),+"
+   "234567890"
+   "%[]<>(),+:'@!$*&"
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-   "abcdefhijklopqrstuvwxz"
+   "abcdefghijklopqrstuvwxz"
 
    Extension character sequences used so far ("+" followed by the
    following), for quick reference when adding more:
-   "ABCDEFGHI"
+   "1234"
+   "ABCDEFGHIT"
+   "t"
 */
 
 /* These are the bits which may be set in the pinfo field of an
@@ -419,11 +514,17 @@
 #define INSN_MULT                   0x40000000
 /* Instruction synchronize shared memory.  */
 #define INSN_SYNC		    0x80000000
-/* Instruction reads MDMX accumulator.  XXX FIXME: No bits left!  */
-#define INSN_READ_MDMX_ACC	    0
-/* Instruction writes MDMX accumulator.  XXX FIXME: No bits left!  */
-#define INSN_WRITE_MDMX_ACC	    0
 
+/* These are the bits which may be set in the pinfo2 field of an
+   instruction. */
+
+/* Instruction is a simple alias (I.E. "move" for daddu/addu/or) */
+#define	INSN2_ALIAS		    0x00000001
+/* Instruction reads MDMX accumulator. */
+#define INSN2_READ_MDMX_ACC	    0x00000002
+/* Instruction writes MDMX accumulator. */
+#define INSN2_WRITE_MDMX_ACC	    0x00000004
+
 /* Instruction is actually a macro.  It should be ignored by the
    disassembler, and requires special treatment by the assembler.  */
 #define INSN_MACRO                  0xffffffff
@@ -447,12 +548,13 @@
 /* Masks used for MIPS-defined ASEs.  */
 #define INSN_ASE_MASK		  0x0000f000
 
+/* DSP ASE */
+#define INSN_DSP                  0x00001000
+#define INSN_DSP64                0x00002000
 /* MIPS 16 ASE */
-#define INSN_MIPS16               0x00002000
+#define INSN_MIPS16               0x00004000
 /* MIPS-3D ASE */
-#define INSN_MIPS3D               0x00004000
-/* MDMX ASE */ 
-#define INSN_MDMX                 0x00008000
+#define INSN_MIPS3D               0x00008000
 
 /* Chip specific instructions.  These are bitmasks.  */
 
@@ -477,6 +579,15 @@
 /* NEC VR5500 instruction.  */
 #define INSN_5500		  0x02000000
 
+/* MDMX ASE */
+#define INSN_MDMX                 0x04000000
+/* MT ASE */
+#define INSN_MT                   0x08000000
+/* SmartMIPS ASE  */
+#define INSN_SMARTMIPS            0x10000000
+/* DSP R2 ASE  */
+#define INSN_DSPR2                0x20000000
+
 /* MIPS ISA defines, use instead of hardcoding ISA level.  */
 
 #define       ISA_UNKNOWN     0               /* Gas internal use.  */
@@ -533,6 +644,7 @@
     (((insn)->membership & isa) != 0					\
      || (cpu == CPU_R4650 && ((insn)->membership & INSN_4650) != 0)	\
      || (cpu == CPU_RM7000 && ((insn)->membership & INSN_4650) != 0)	\
+     || (cpu == CPU_RM9000 && ((insn)->membership & INSN_4650) != 0)	\
      || (cpu == CPU_R4010 && ((insn)->membership & INSN_4010) != 0)	\
      || (cpu == CPU_VR4100 && ((insn)->membership & INSN_4100) != 0)	\
      || (cpu == CPU_R3900 && ((insn)->membership & INSN_3900) != 0)	\
@@ -563,6 +675,7 @@
   M_ADD_I,
   M_ADDU_I,
   M_AND_I,
+  M_BALIGN,
   M_BEQ,
   M_BEQ_I,
   M_BEQL_I,
@@ -601,6 +714,7 @@
   M_BNE,
   M_BNE_I,
   M_BNEL_I,
+  M_CACHE_AB,
   M_DABS,
   M_DADD_I,
   M_DADDU_I,
@@ -907,6 +1021,11 @@
    "E" 5 bit PC relative address * 4 (MIPS16OP_*_IMM5)
    */
 
+/* Save/restore encoding for the args field when all 4 registers are
+   either saved as arguments or saved/restored as statics.  */
+#define MIPS16_ALL_ARGS    0xe
+#define MIPS16_ALL_STATICS 0xb
+
 /* For the mips16, we use the same opcode table format and a few of
    the same flags.  However, most of the flags are different.  */
 
@@ -1008,8 +1127,8 @@
 
 #define IS_M    INSN_MULT
 
-#define WR_MACC INSN_WRITE_MDMX_ACC
-#define RD_MACC INSN_READ_MDMX_ACC
+#define WR_MACC INSN2_WRITE_MDMX_ACC
+#define RD_MACC INSN2_READ_MDMX_ACC
 
 #define I1	INSN_ISA1
 #define I2	INSN_ISA2
@@ -1024,6 +1143,9 @@
 /* MIPS64 MIPS-3D ASE support.  */
 #define I16     INSN_MIPS16
 
+/* MIPS32 SmartMIPS ASE support.  */
+#define SMT	INSN_SMARTMIPS
+
 /* MIPS64 MIPS-3D ASE support.  */
 #define M3D     INSN_MIPS3D
 
@@ -1051,6 +1173,38 @@
 #define G3      (I4             \
                  )
 
+/* MIPS DSP ASE support.
+   NOTE:
+   1. MIPS DSP ASE includes 4 accumulators ($ac0 - $ac3).  $ac0 is the pair
+   of original HI and LO.  $ac1, $ac2 and $ac3 are new registers, and have
+   the same structure as $ac0 (HI + LO).  For DSP instructions that write or
+   read accumulators (that may be $ac0), we add WR_a (WR_HILO) or RD_a
+   (RD_HILO) attributes, such that HILO dependencies are maintained
+   conservatively.
+
+   2. For some mul. instructions that use integer registers as destinations
+   but destroy HI+LO as side-effect, we add WR_HILO to their attributes.
+
+   3. MIPS DSP ASE includes a new DSP control register, which has 6 fields
+   (ccond, outflag, EFI, c, scount, pos).  Many DSP instructions read or write
+   certain fields of the DSP control register.  For simplicity, we decide not
+   to track dependencies of these fields.
+   However, "bposge32" is a branch instruction that depends on the "pos"
+   field.  In order to make sure that GAS does not reorder DSP instructions
+   that writes the "pos" field and "bposge32", we add DSP_VOLA (INSN_TRAP)
+   attribute to those instructions that write the "pos" field.  */
+
+#define WR_a	WR_HILO	/* Write dsp accumulators (reuse WR_HILO)  */
+#define RD_a	RD_HILO	/* Read dsp accumulators (reuse RD_HILO)  */
+#define MOD_a	WR_a|RD_a
+#define DSP_VOLA	INSN_TRAP
+#define D32	INSN_DSP
+#define D33	INSN_DSPR2
+#define D64	INSN_DSP64
+
+/* MIPS MT ASE support.  */
+#define MT32	INSN_MT
+
 /* The order of overloaded instructions matters.  Label arguments and
    register arguments look the same. Instructions that can have either
    for arguments must apear in the correct order in this table for the
@@ -1070,1083 +1224,1524 @@
    them first.  The assemblers uses a hash table based on the
    instruction name anyhow.  */
 /* name,    args,	match,	    mask,	pinfo,          	membership */
-{"pref",    "k,o(b)",   0xcc000000, 0xfc000000, RD_b,           	I4|I32|G3	},
-{"prefx",   "h,t(b)",	0x4c00000f, 0xfc0007ff, RD_b|RD_t,		I4	},
-{"nop",     "",         0x00000000, 0xffffffff, 0,              	I1      }, /* sll */
-{"ssnop",   "",         0x00000040, 0xffffffff, 0,              	I32|N55	}, /* sll */
-{"ehb",     "",         0x000000c0, 0xffffffff, 0,              	I33	}, /* sll */
-{"li",      "t,j",      0x24000000, 0xffe00000, WR_t,			I1	}, /* addiu */
-{"li",	    "t,i",	0x34000000, 0xffe00000, WR_t,			I1	}, /* ori */
-{"li",      "t,I",	0,    (int) M_LI,	INSN_MACRO,		I1	},
-{"move",    "d,s",	0,    (int) M_MOVE,	INSN_MACRO,		I1	},
-{"move",    "d,s",	0x0000002d, 0xfc1f07ff, WR_d|RD_s,		I3	},/* daddu */
-{"move",    "d,s",	0x00000021, 0xfc1f07ff, WR_d|RD_s,		I1	},/* addu */
-{"move",    "d,s",	0x00000025, 0xfc1f07ff,	WR_d|RD_s,		I1	},/* or */
-{"b",       "p",	0x10000000, 0xffff0000,	UBD,			I1	},/* beq 0,0 */
-{"b",       "p",	0x04010000, 0xffff0000,	UBD,			I1	},/* bgez 0 */
-{"bal",     "p",	0x04110000, 0xffff0000,	UBD|WR_31,		I1	},/* bgezal 0*/
+{"pref",    "k,o(b)",   0xcc000000, 0xfc000000, RD_b,           	0,		I4|I32|G3	},
+{"prefx",   "h,t(b)",	0x4c00000f, 0xfc0007ff, RD_b|RD_t,		0,		I4|I33	},
+{"nop",     "",         0x00000000, 0xffffffff, 0,              	INSN2_ALIAS,	I1      }, /* sll */
+{"ssnop",   "",         0x00000040, 0xffffffff, 0,              	INSN2_ALIAS,	I32|N55	}, /* sll */
+{"ehb",     "",         0x000000c0, 0xffffffff, 0,              	INSN2_ALIAS,	I33	}, /* sll */
+{"li",      "t,j",      0x24000000, 0xffe00000, WR_t,			INSN2_ALIAS,	I1	}, /* addiu */
+{"li",	    "t,i",	0x34000000, 0xffe00000, WR_t,			INSN2_ALIAS,	I1	}, /* ori */
+{"li",      "t,I",	0,    (int) M_LI,	INSN_MACRO,		0,		I1	},
+{"move",    "d,s",	0,    (int) M_MOVE,	INSN_MACRO,		0,		I1	},
+{"move",    "d,s",	0x0000002d, 0xfc1f07ff, WR_d|RD_s,		INSN2_ALIAS,	I3	},/* daddu */
+{"move",    "d,s",	0x00000021, 0xfc1f07ff, WR_d|RD_s,		INSN2_ALIAS,	I1	},/* addu */
+{"move",    "d,s",	0x00000025, 0xfc1f07ff,	WR_d|RD_s,		INSN2_ALIAS,	I1	},/* or */
+{"b",       "p",	0x10000000, 0xffff0000,	UBD,			INSN2_ALIAS,	I1	},/* beq 0,0 */
+{"b",       "p",	0x04010000, 0xffff0000,	UBD,			INSN2_ALIAS,	I1	},/* bgez 0 */
+{"bal",     "p",	0x04110000, 0xffff0000,	UBD|WR_31,		INSN2_ALIAS,	I1	},/* bgezal 0*/
 
-{"abs",     "d,v",	0,    (int) M_ABS,	INSN_MACRO,		I1	},
-{"abs.s",   "D,V",	0x46000005, 0xffff003f,	WR_D|RD_S|FP_S,		I1	},
-{"abs.d",   "D,V",	0x46200005, 0xffff003f,	WR_D|RD_S|FP_D,		I1	},
-{"abs.ps",  "D,V",	0x46c00005, 0xffff003f,	WR_D|RD_S|FP_D,		I5	},
-{"add",     "d,v,t",	0x00000020, 0xfc0007ff,	WR_d|RD_s|RD_t,		I1	},
-{"add",     "t,r,I",	0,    (int) M_ADD_I,	INSN_MACRO,		I1	},
-{"add.s",   "D,V,T",	0x46000000, 0xffe0003f,	WR_D|RD_S|RD_T|FP_S,	I1	},
-{"add.d",   "D,V,T",	0x46200000, 0xffe0003f,	WR_D|RD_S|RD_T|FP_D,	I1	},
-{"add.ob",  "X,Y,Q",	0x7800000b, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	MX|SB1	},
-{"add.ob",  "D,S,T",	0x4ac0000b, 0xffe0003f,	WR_D|RD_S|RD_T,		N54	},
-{"add.ob",  "D,S,T[e]",	0x4800000b, 0xfe20003f,	WR_D|RD_S|RD_T,		N54	},
-{"add.ob",  "D,S,k",	0x4bc0000b, 0xffe0003f,	WR_D|RD_S|RD_T,		N54	},
-{"add.ps",  "D,V,T",	0x46c00000, 0xffe0003f,	WR_D|RD_S|RD_T|FP_D,	I5	},
-{"add.qh",  "X,Y,Q",	0x7820000b, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	MX	},
-{"adda.ob", "Y,Q",	0x78000037, 0xfc2007ff,	WR_MACC|RD_S|RD_T|FP_D,	MX|SB1	},
-{"adda.qh", "Y,Q",	0x78200037, 0xfc2007ff,	WR_MACC|RD_S|RD_T|FP_D,	MX	},
-{"addi",    "t,r,j",	0x20000000, 0xfc000000,	WR_t|RD_s,		I1	},
-{"addiu",   "t,r,j",	0x24000000, 0xfc000000,	WR_t|RD_s,		I1	},
-{"addl.ob", "Y,Q",	0x78000437, 0xfc2007ff,	WR_MACC|RD_S|RD_T|FP_D,	MX|SB1	},
-{"addl.qh", "Y,Q",	0x78200437, 0xfc2007ff,	WR_MACC|RD_S|RD_T|FP_D,	MX	},
-{"addr.ps", "D,S,T",	0x46c00018, 0xffe0003f,	WR_D|RD_S|RD_T|FP_D,	M3D	},
-{"addu",    "d,v,t",	0x00000021, 0xfc0007ff,	WR_d|RD_s|RD_t,		I1	},
-{"addu",    "t,r,I",	0,    (int) M_ADDU_I,	INSN_MACRO,		I1	},
-{"alni.ob", "X,Y,Z,O",	0x78000018, 0xff00003f,	WR_D|RD_S|RD_T|FP_D,	MX|SB1	},
-{"alni.ob", "D,S,T,%",	0x48000018, 0xff00003f,	WR_D|RD_S|RD_T, 	N54	},
-{"alni.qh", "X,Y,Z,O",	0x7800001a, 0xff00003f,	WR_D|RD_S|RD_T|FP_D,	MX	},
-{"alnv.ps", "D,V,T,s",	0x4c00001e, 0xfc00003f,	WR_D|RD_S|RD_T|FP_D,	I5	},
-{"alnv.ob", "X,Y,Z,s",	0x78000019, 0xfc00003f,	WR_D|RD_S|RD_T|RD_s|FP_D, MX|SB1	},
-{"alnv.qh", "X,Y,Z,s",	0x7800001b, 0xfc00003f,	WR_D|RD_S|RD_T|RD_s|FP_D, MX	},
-{"and",     "d,v,t",	0x00000024, 0xfc0007ff,	WR_d|RD_s|RD_t,		I1	},
-{"and",     "t,r,I",	0,    (int) M_AND_I,	INSN_MACRO,		I1	},
-{"and.ob",  "X,Y,Q",	0x7800000c, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	MX|SB1	},
-{"and.ob",  "D,S,T",	0x4ac0000c, 0xffe0003f,	WR_D|RD_S|RD_T,		N54	},
-{"and.ob",  "D,S,T[e]",	0x4800000c, 0xfe20003f,	WR_D|RD_S|RD_T,		N54	},
-{"and.ob",  "D,S,k",	0x4bc0000c, 0xffe0003f,	WR_D|RD_S|RD_T,		N54	},
-{"and.qh",  "X,Y,Q",	0x7820000c, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	MX	},
-{"andi",    "t,r,i",	0x30000000, 0xfc000000,	WR_t|RD_s,		I1	},
+{"abs",     "d,v",	0,    (int) M_ABS,	INSN_MACRO,		0,		I1	},
+{"abs.s",   "D,V",	0x46000005, 0xffff003f,	WR_D|RD_S|FP_S,		0,		I1	},
+{"abs.d",   "D,V",	0x46200005, 0xffff003f,	WR_D|RD_S|FP_D,		0,		I1	},
+{"abs.ps",  "D,V",	0x46c00005, 0xffff003f,	WR_D|RD_S|FP_D,		0,		I5|I33	},
+{"add",     "d,v,t",	0x00000020, 0xfc0007ff,	WR_d|RD_s|RD_t,		0,		I1	},
+{"add",     "t,r,I",	0,    (int) M_ADD_I,	INSN_MACRO,		0,		I1	},
+{"add.s",   "D,V,T",	0x46000000, 0xffe0003f,	WR_D|RD_S|RD_T|FP_S,	0,		I1	},
+{"add.d",   "D,V,T",	0x46200000, 0xffe0003f,	WR_D|RD_S|RD_T|FP_D,	0,		I1	},
+{"add.ob",  "X,Y,Q",	0x7800000b, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	0,		MX|SB1	},
+{"add.ob",  "D,S,T",	0x4ac0000b, 0xffe0003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"add.ob",  "D,S,T[e]",	0x4800000b, 0xfe20003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"add.ob",  "D,S,k",	0x4bc0000b, 0xffe0003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"add.ps",  "D,V,T",	0x46c00000, 0xffe0003f,	WR_D|RD_S|RD_T|FP_D,	0,		I5|I33	},
+{"add.qh",  "X,Y,Q",	0x7820000b, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	0,		MX	},
+{"adda.ob", "Y,Q",	0x78000037, 0xfc2007ff,	RD_S|RD_T|FP_D,		WR_MACC,	MX|SB1	},
+{"adda.qh", "Y,Q",	0x78200037, 0xfc2007ff,	RD_S|RD_T|FP_D,		WR_MACC,	MX	},
+{"addi",    "t,r,j",	0x20000000, 0xfc000000,	WR_t|RD_s,		0,		I1	},
+{"addiu",   "t,r,j",	0x24000000, 0xfc000000,	WR_t|RD_s,		0,		I1	},
+{"addl.ob", "Y,Q",	0x78000437, 0xfc2007ff,	RD_S|RD_T|FP_D,		WR_MACC,	MX|SB1	},
+{"addl.qh", "Y,Q",	0x78200437, 0xfc2007ff,	RD_S|RD_T|FP_D,		WR_MACC,	MX	},
+{"addr.ps", "D,S,T",	0x46c00018, 0xffe0003f,	WR_D|RD_S|RD_T|FP_D,	0,		M3D	},
+{"addu",    "d,v,t",	0x00000021, 0xfc0007ff,	WR_d|RD_s|RD_t,		0,		I1	},
+{"addu",    "t,r,I",	0,    (int) M_ADDU_I,	INSN_MACRO,		0,		I1	},
+{"alni.ob", "X,Y,Z,O",	0x78000018, 0xff00003f,	WR_D|RD_S|RD_T|FP_D,	0,		MX|SB1	},
+{"alni.ob", "D,S,T,%",	0x48000018, 0xff00003f,	WR_D|RD_S|RD_T, 	0,		N54	},
+{"alni.qh", "X,Y,Z,O",	0x7800001a, 0xff00003f,	WR_D|RD_S|RD_T|FP_D,	0,		MX	},
+{"alnv.ps", "D,V,T,s",	0x4c00001e, 0xfc00003f,	WR_D|RD_S|RD_T|FP_D,	0,		I5|I33	},
+{"alnv.ob", "X,Y,Z,s",	0x78000019, 0xfc00003f,	WR_D|RD_S|RD_T|RD_s|FP_D, 0,		MX|SB1	},
+{"alnv.qh", "X,Y,Z,s",	0x7800001b, 0xfc00003f,	WR_D|RD_S|RD_T|RD_s|FP_D, 0,		MX	},
+{"and",     "d,v,t",	0x00000024, 0xfc0007ff,	WR_d|RD_s|RD_t,		0,		I1	},
+{"and",     "t,r,I",	0,    (int) M_AND_I,	INSN_MACRO,		0,		I1	},
+{"and.ob",  "X,Y,Q",	0x7800000c, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	0,		MX|SB1	},
+{"and.ob",  "D,S,T",	0x4ac0000c, 0xffe0003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"and.ob",  "D,S,T[e]",	0x4800000c, 0xfe20003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"and.ob",  "D,S,k",	0x4bc0000c, 0xffe0003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"and.qh",  "X,Y,Q",	0x7820000c, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	0,		MX	},
+{"andi",    "t,r,i",	0x30000000, 0xfc000000,	WR_t|RD_s,		0,		I1	},
 /* b is at the top of the table.  */
 /* bal is at the top of the table.  */
-{"bc0f",    "p",	0x41000000, 0xffff0000,	CBD|RD_CC,		I1	},
-{"bc0fl",   "p",	0x41020000, 0xffff0000,	CBL|RD_CC,		I2|T3	},
-{"bc0t",    "p",	0x41010000, 0xffff0000,	CBD|RD_CC,		I1	},
-{"bc0tl",   "p",	0x41030000, 0xffff0000,	CBL|RD_CC,		I2|T3	},
-{"bc1any2f", "N,p",	0x45200000, 0xffe30000,	CBD|RD_CC|FP_S,		M3D	},
-{"bc1any2t", "N,p",	0x45210000, 0xffe30000,	CBD|RD_CC|FP_S,		M3D	},
-{"bc1any4f", "N,p",	0x45400000, 0xffe30000,	CBD|RD_CC|FP_S,		M3D	},
-{"bc1any4t", "N,p",	0x45410000, 0xffe30000,	CBD|RD_CC|FP_S,		M3D	},
-{"bc1f",    "p",	0x45000000, 0xffff0000,	CBD|RD_CC|FP_S,		I1	},
-{"bc1f",    "N,p",      0x45000000, 0xffe30000, CBD|RD_CC|FP_S, 	I4|I32	},
-{"bc1fl",   "p",	0x45020000, 0xffff0000,	CBL|RD_CC|FP_S,		I2|T3	},
-{"bc1fl",   "N,p",      0x45020000, 0xffe30000, CBL|RD_CC|FP_S, 	I4|I32	},
-{"bc1t",    "p",	0x45010000, 0xffff0000,	CBD|RD_CC|FP_S,		I1	},
-{"bc1t",    "N,p",      0x45010000, 0xffe30000, CBD|RD_CC|FP_S, 	I4|I32	},
-{"bc1tl",   "p",	0x45030000, 0xffff0000,	CBL|RD_CC|FP_S,		I2|T3	},
-{"bc1tl",   "N,p",      0x45030000, 0xffe30000, CBL|RD_CC|FP_S, 	I4|I32	},
+/* bc0[tf]l? are at the bottom of the table.  */
+{"bc1any2f", "N,p",	0x45200000, 0xffe30000,	CBD|RD_CC|FP_S,		0,		M3D	},
+{"bc1any2t", "N,p",	0x45210000, 0xffe30000,	CBD|RD_CC|FP_S,		0,		M3D	},
+{"bc1any4f", "N,p",	0x45400000, 0xffe30000,	CBD|RD_CC|FP_S,		0,		M3D	},
+{"bc1any4t", "N,p",	0x45410000, 0xffe30000,	CBD|RD_CC|FP_S,		0,		M3D	},
+{"bc1f",    "p",	0x45000000, 0xffff0000,	CBD|RD_CC|FP_S,		0,		I1	},
+{"bc1f",    "N,p",      0x45000000, 0xffe30000, CBD|RD_CC|FP_S, 	0,		I4|I32	},
+{"bc1fl",   "p",	0x45020000, 0xffff0000,	CBL|RD_CC|FP_S,		0,		I2|T3	},
+{"bc1fl",   "N,p",      0x45020000, 0xffe30000, CBL|RD_CC|FP_S, 	0,		I4|I32	},
+{"bc1t",    "p",	0x45010000, 0xffff0000,	CBD|RD_CC|FP_S,		0,		I1	},
+{"bc1t",    "N,p",      0x45010000, 0xffe30000, CBD|RD_CC|FP_S, 	0,		I4|I32	},
+{"bc1tl",   "p",	0x45030000, 0xffff0000,	CBL|RD_CC|FP_S,		0,		I2|T3	},
+{"bc1tl",   "N,p",      0x45030000, 0xffe30000, CBL|RD_CC|FP_S, 	0,		I4|I32	},
 /* bc2* are at the bottom of the table.  */
-{"bc3f",    "p",	0x4d000000, 0xffff0000,	CBD|RD_CC,		I1	},
-{"bc3fl",   "p",	0x4d020000, 0xffff0000,	CBL|RD_CC,		I2|T3	},
-{"bc3t",    "p",	0x4d010000, 0xffff0000,	CBD|RD_CC,		I1	},
-{"bc3tl",   "p",	0x4d030000, 0xffff0000,	CBL|RD_CC,		I2|T3	},
-{"beqz",    "s,p",	0x10000000, 0xfc1f0000,	CBD|RD_s,		I1	},
-{"beqzl",   "s,p",	0x50000000, 0xfc1f0000,	CBL|RD_s,		I2|T3	},
-{"beq",     "s,t,p",	0x10000000, 0xfc000000,	CBD|RD_s|RD_t,		I1	},
-{"beq",     "s,I,p",	0,    (int) M_BEQ_I,	INSN_MACRO,		I1	},
-{"beql",    "s,t,p",	0x50000000, 0xfc000000,	CBL|RD_s|RD_t,		I2|T3	},
-{"beql",    "s,I,p",	0,    (int) M_BEQL_I,	INSN_MACRO,		I2|T3	},
-{"bge",     "s,t,p",	0,    (int) M_BGE,	INSN_MACRO,		I1	},
-{"bge",     "s,I,p",	0,    (int) M_BGE_I,	INSN_MACRO,		I1	},
-{"bgel",    "s,t,p",	0,    (int) M_BGEL,	INSN_MACRO,		I2|T3	},
-{"bgel",    "s,I,p",	0,    (int) M_BGEL_I,	INSN_MACRO,		I2|T3	},
-{"bgeu",    "s,t,p",	0,    (int) M_BGEU,	INSN_MACRO,		I1	},
-{"bgeu",    "s,I,p",	0,    (int) M_BGEU_I,	INSN_MACRO,		I1	},
-{"bgeul",   "s,t,p",	0,    (int) M_BGEUL,	INSN_MACRO,		I2|T3	},
-{"bgeul",   "s,I,p",	0,    (int) M_BGEUL_I,	INSN_MACRO,		I2|T3	},
-{"bgez",    "s,p",	0x04010000, 0xfc1f0000,	CBD|RD_s,		I1	},
-{"bgezl",   "s,p",	0x04030000, 0xfc1f0000,	CBL|RD_s,		I2|T3	},
-{"bgezal",  "s,p",	0x04110000, 0xfc1f0000,	CBD|RD_s|WR_31,		I1	},
-{"bgezall", "s,p",	0x04130000, 0xfc1f0000,	CBL|RD_s|WR_31,		I2|T3	},
-{"bgt",     "s,t,p",	0,    (int) M_BGT,	INSN_MACRO,		I1	},
-{"bgt",     "s,I,p",	0,    (int) M_BGT_I,	INSN_MACRO,		I1	},
-{"bgtl",    "s,t,p",	0,    (int) M_BGTL,	INSN_MACRO,		I2|T3	},
-{"bgtl",    "s,I,p",	0,    (int) M_BGTL_I,	INSN_MACRO,		I2|T3	},
-{"bgtu",    "s,t,p",	0,    (int) M_BGTU,	INSN_MACRO,		I1	},
-{"bgtu",    "s,I,p",	0,    (int) M_BGTU_I,	INSN_MACRO,		I1	},
-{"bgtul",   "s,t,p",	0,    (int) M_BGTUL,	INSN_MACRO,		I2|T3	},
-{"bgtul",   "s,I,p",	0,    (int) M_BGTUL_I,	INSN_MACRO,		I2|T3	},
-{"bgtz",    "s,p",	0x1c000000, 0xfc1f0000,	CBD|RD_s,		I1	},
-{"bgtzl",   "s,p",	0x5c000000, 0xfc1f0000,	CBL|RD_s,		I2|T3	},
-{"ble",     "s,t,p",	0,    (int) M_BLE,	INSN_MACRO,		I1	},
-{"ble",     "s,I,p",	0,    (int) M_BLE_I,	INSN_MACRO,		I1	},
-{"blel",    "s,t,p",	0,    (int) M_BLEL,	INSN_MACRO,		I2|T3	},
-{"blel",    "s,I,p",	0,    (int) M_BLEL_I,	INSN_MACRO,		I2|T3	},
-{"bleu",    "s,t,p",	0,    (int) M_BLEU,	INSN_MACRO,		I1	},
-{"bleu",    "s,I,p",	0,    (int) M_BLEU_I,	INSN_MACRO,		I1	},
-{"bleul",   "s,t,p",	0,    (int) M_BLEUL,	INSN_MACRO,		I2|T3	},
-{"bleul",   "s,I,p",	0,    (int) M_BLEUL_I,	INSN_MACRO,		I2|T3	},
-{"blez",    "s,p",	0x18000000, 0xfc1f0000,	CBD|RD_s,		I1	},
-{"blezl",   "s,p",	0x58000000, 0xfc1f0000,	CBL|RD_s,		I2|T3	},
-{"blt",     "s,t,p",	0,    (int) M_BLT,	INSN_MACRO,		I1	},
-{"blt",     "s,I,p",	0,    (int) M_BLT_I,	INSN_MACRO,		I1	},
-{"bltl",    "s,t,p",	0,    (int) M_BLTL,	INSN_MACRO,		I2|T3	},
-{"bltl",    "s,I,p",	0,    (int) M_BLTL_I,	INSN_MACRO,		I2|T3	},
-{"bltu",    "s,t,p",	0,    (int) M_BLTU,	INSN_MACRO,		I1	},
-{"bltu",    "s,I,p",	0,    (int) M_BLTU_I,	INSN_MACRO,		I1	},
-{"bltul",   "s,t,p",	0,    (int) M_BLTUL,	INSN_MACRO,		I2|T3	},
-{"bltul",   "s,I,p",	0,    (int) M_BLTUL_I,	INSN_MACRO,		I2|T3	},
-{"bltz",    "s,p",	0x04000000, 0xfc1f0000,	CBD|RD_s,		I1	},
-{"bltzl",   "s,p",	0x04020000, 0xfc1f0000,	CBL|RD_s,		I2|T3	},
-{"bltzal",  "s,p",	0x04100000, 0xfc1f0000,	CBD|RD_s|WR_31,		I1	},
-{"bltzall", "s,p",	0x04120000, 0xfc1f0000,	CBL|RD_s|WR_31,		I2|T3	},
-{"bnez",    "s,p",	0x14000000, 0xfc1f0000,	CBD|RD_s,		I1	},
-{"bnezl",   "s,p",	0x54000000, 0xfc1f0000,	CBL|RD_s,		I2|T3	},
-{"bne",     "s,t,p",	0x14000000, 0xfc000000,	CBD|RD_s|RD_t,		I1	},
-{"bne",     "s,I,p",	0,    (int) M_BNE_I,	INSN_MACRO,		I1	},
-{"bnel",    "s,t,p",	0x54000000, 0xfc000000,	CBL|RD_s|RD_t, 		I2|T3	},
-{"bnel",    "s,I,p",	0,    (int) M_BNEL_I,	INSN_MACRO,		I2|T3	},
-{"break",   "",		0x0000000d, 0xffffffff,	TRAP,			I1	},
-{"break",   "c",	0x0000000d, 0xfc00ffff,	TRAP,			I1	},
-{"break",   "c,q",	0x0000000d, 0xfc00003f,	TRAP,			I1	},
-{"c.f.d",   "S,T",	0x46200030, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	I1	},
-{"c.f.d",   "M,S,T",    0x46200030, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D,   I4|I32	},
-{"c.f.s",   "S,T",      0x46000030, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S,   I1      },
-{"c.f.s",   "M,S,T",    0x46000030, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S,   I4|I32	},
-{"c.f.ps",  "S,T",	0x46c00030, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	I5	},
-{"c.f.ps",  "M,S,T",	0x46c00030, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	I5	},
-{"c.un.d",  "S,T",	0x46200031, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	I1	},
-{"c.un.d",  "M,S,T",    0x46200031, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D,   I4|I32	},
-{"c.un.s",  "S,T",      0x46000031, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S,   I1      },
-{"c.un.s",  "M,S,T",    0x46000031, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S,   I4|I32	},
-{"c.un.ps", "S,T",	0x46c00031, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	I5	},
-{"c.un.ps", "M,S,T",	0x46c00031, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	I5	},
-{"c.eq.d",  "S,T",	0x46200032, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	I1	},
-{"c.eq.d",  "M,S,T",    0x46200032, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D,   I4|I32	},
-{"c.eq.s",  "S,T",      0x46000032, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S,   I1      },
-{"c.eq.s",  "M,S,T",    0x46000032, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S,   I4|I32	},
-{"c.eq.ob", "Y,Q",	0x78000001, 0xfc2007ff,	WR_CC|RD_S|RD_T|FP_D,	MX|SB1	},
-{"c.eq.ob", "S,T",	0x4ac00001, 0xffe007ff,	WR_CC|RD_S|RD_T,	N54	},
-{"c.eq.ob", "S,T[e]",	0x48000001, 0xfe2007ff,	WR_CC|RD_S|RD_T,	N54	},
-{"c.eq.ob", "S,k",	0x4bc00001, 0xffe007ff,	WR_CC|RD_S|RD_T,	N54	},
-{"c.eq.ps", "S,T",	0x46c00032, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	I5	},
-{"c.eq.ps", "M,S,T",	0x46c00032, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	I5	},
-{"c.eq.qh", "Y,Q",	0x78200001, 0xfc2007ff,	WR_CC|RD_S|RD_T|FP_D,	MX	},
-{"c.ueq.d", "S,T",	0x46200033, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	I1	},
-{"c.ueq.d", "M,S,T",    0x46200033, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D,   I4|I32	},
-{"c.ueq.s", "S,T",      0x46000033, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S,   I1      },
-{"c.ueq.s", "M,S,T",    0x46000033, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S,   I4|I32	},
-{"c.ueq.ps","S,T",	0x46c00033, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	I5	},
-{"c.ueq.ps","M,S,T",	0x46c00033, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	I5	},
-{"c.olt.d", "S,T",      0x46200034, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D,   I1      },
-{"c.olt.d", "M,S,T",    0x46200034, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D,   I4|I32	},
-{"c.olt.s", "S,T",	0x46000034, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_S,	I1	},
-{"c.olt.s", "M,S,T",    0x46000034, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S,   I4|I32	},
-{"c.olt.ps","S,T",	0x46c00034, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	I5	},
-{"c.olt.ps","M,S,T",	0x46c00034, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	I5	},
-{"c.ult.d", "S,T",	0x46200035, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	I1	},
-{"c.ult.d", "M,S,T",    0x46200035, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D,   I4|I32	},
-{"c.ult.s", "S,T",      0x46000035, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S,   I1      },
-{"c.ult.s", "M,S,T",    0x46000035, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S,   I4|I32	},
-{"c.ult.ps","S,T",	0x46c00035, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	I5	},
-{"c.ult.ps","M,S,T",	0x46c00035, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	I5	},
-{"c.ole.d", "S,T",      0x46200036, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D,   I1      },
-{"c.ole.d", "M,S,T",    0x46200036, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D,   I4|I32	},
-{"c.ole.s", "S,T",      0x46000036, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S,   I1      },
-{"c.ole.s", "M,S,T",    0x46000036, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S,   I4|I32	},
-{"c.ole.ps","S,T",	0x46c00036, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	I5	},
-{"c.ole.ps","M,S,T",	0x46c00036, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	I5	},
-{"c.ule.d", "S,T",	0x46200037, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	I1	},
-{"c.ule.d", "M,S,T",    0x46200037, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D,   I4|I32	},
-{"c.ule.s", "S,T",      0x46000037, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S,   I1      },
-{"c.ule.s", "M,S,T",    0x46000037, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S,   I4|I32	},
-{"c.ule.ps","S,T",	0x46c00037, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	I5	},
-{"c.ule.ps","M,S,T",	0x46c00037, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	I5	},
-{"c.sf.d",  "S,T",	0x46200038, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	I1	},
-{"c.sf.d",  "M,S,T",    0x46200038, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D,   I4|I32	},
-{"c.sf.s",  "S,T",      0x46000038, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S,   I1      },
-{"c.sf.s",  "M,S,T",    0x46000038, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S,   I4|I32	},
-{"c.sf.ps", "S,T",	0x46c00038, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	I5	},
-{"c.sf.ps", "M,S,T",	0x46c00038, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	I5	},
-{"c.ngle.d","S,T",	0x46200039, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	I1	},
-{"c.ngle.d","M,S,T",    0x46200039, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D,   I4|I32	},
-{"c.ngle.s","S,T",      0x46000039, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S,   I1      },
-{"c.ngle.s","M,S,T",    0x46000039, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S,   I4|I32	},
-{"c.ngle.ps","S,T",	0x46c00039, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	I5	},
-{"c.ngle.ps","M,S,T",	0x46c00039, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	I5	},
-{"c.seq.d", "S,T",	0x4620003a, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	I1	},
-{"c.seq.d", "M,S,T",    0x4620003a, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D,   I4|I32	},
-{"c.seq.s", "S,T",      0x4600003a, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S,   I1      },
-{"c.seq.s", "M,S,T",    0x4600003a, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S,   I4|I32	},
-{"c.seq.ps","S,T",	0x46c0003a, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	I5	},
-{"c.seq.ps","M,S,T",	0x46c0003a, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	I5	},
-{"c.ngl.d", "S,T",	0x4620003b, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	I1	},
-{"c.ngl.d", "M,S,T",    0x4620003b, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D,   I4|I32	},
-{"c.ngl.s", "S,T",      0x4600003b, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S,   I1      },
-{"c.ngl.s", "M,S,T",    0x4600003b, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S,   I4|I32	},
-{"c.ngl.ps","S,T",	0x46c0003b, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	I5	},
-{"c.ngl.ps","M,S,T",	0x46c0003b, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	I5	},
-{"c.lt.d",  "S,T",	0x4620003c, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	I1	},
-{"c.lt.d",  "M,S,T",    0x4620003c, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D,   I4|I32	},
-{"c.lt.s",  "S,T",	0x4600003c, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_S,	I1	},
-{"c.lt.s",  "M,S,T",    0x4600003c, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S,   I4|I32	},
-{"c.lt.ob", "Y,Q",	0x78000004, 0xfc2007ff,	WR_CC|RD_S|RD_T|FP_D,	MX|SB1	},
-{"c.lt.ob", "S,T",	0x4ac00004, 0xffe007ff,	WR_CC|RD_S|RD_T,	N54	},
-{"c.lt.ob", "S,T[e]",	0x48000004, 0xfe2007ff,	WR_CC|RD_S|RD_T,	N54	},
-{"c.lt.ob", "S,k",	0x4bc00004, 0xffe007ff,	WR_CC|RD_S|RD_T,	N54	},
-{"c.lt.ps", "S,T",	0x46c0003c, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	I5	},
-{"c.lt.ps", "M,S,T",	0x46c0003c, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	I5	},
-{"c.lt.qh", "Y,Q",	0x78200004, 0xfc2007ff,	WR_CC|RD_S|RD_T|FP_D,	MX	},
-{"c.nge.d", "S,T",	0x4620003d, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	I1	},
-{"c.nge.d", "M,S,T",    0x4620003d, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D,   I4|I32	},
-{"c.nge.s", "S,T",      0x4600003d, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S,   I1      },
-{"c.nge.s", "M,S,T",    0x4600003d, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S,   I4|I32	},
-{"c.nge.ps","S,T",	0x46c0003d, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	I5	},
-{"c.nge.ps","M,S,T",	0x46c0003d, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	I5	},
-{"c.le.d",  "S,T",	0x4620003e, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	I1	},
-{"c.le.d",  "M,S,T",    0x4620003e, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D,   I4|I32	},
-{"c.le.s",  "S,T",	0x4600003e, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_S,	I1	},
-{"c.le.s",  "M,S,T",    0x4600003e, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S,   I4|I32	},
-{"c.le.ob", "Y,Q",	0x78000005, 0xfc2007ff,	WR_CC|RD_S|RD_T|FP_D,	MX|SB1	},
-{"c.le.ob", "S,T",	0x4ac00005, 0xffe007ff,	WR_CC|RD_S|RD_T,	N54	},
-{"c.le.ob", "S,T[e]",	0x48000005, 0xfe2007ff,	WR_CC|RD_S|RD_T,	N54	},
-{"c.le.ob", "S,k",	0x4bc00005, 0xffe007ff,	WR_CC|RD_S|RD_T,	N54	},
-{"c.le.ps", "S,T",	0x46c0003e, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	I5	},
-{"c.le.ps", "M,S,T",	0x46c0003e, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	I5	},
-{"c.le.qh", "Y,Q",	0x78200005, 0xfc2007ff,	WR_CC|RD_S|RD_T|FP_D,	MX	},
-{"c.ngt.d", "S,T",	0x4620003f, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	I1	},
-{"c.ngt.d", "M,S,T",    0x4620003f, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D,   I4|I32	},
-{"c.ngt.s", "S,T",      0x4600003f, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S,   I1      },
-{"c.ngt.s", "M,S,T",    0x4600003f, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S,   I4|I32	},
-{"c.ngt.ps","S,T",	0x46c0003f, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	I5	},
-{"c.ngt.ps","M,S,T",	0x46c0003f, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	I5	},
-{"cabs.eq.d",  "M,S,T",	0x46200072, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	M3D	},
-{"cabs.eq.ps", "M,S,T",	0x46c00072, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	M3D	},
-{"cabs.eq.s",  "M,S,T",	0x46000072, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_S,	M3D	},
-{"cabs.f.d",   "M,S,T",	0x46200070, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	M3D	},
-{"cabs.f.ps",  "M,S,T",	0x46c00070, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	M3D	},
-{"cabs.f.s",   "M,S,T",	0x46000070, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_S,	M3D	},
-{"cabs.le.d",  "M,S,T",	0x4620007e, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	M3D	},
-{"cabs.le.ps", "M,S,T",	0x46c0007e, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	M3D	},
-{"cabs.le.s",  "M,S,T",	0x4600007e, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_S,	M3D	},
-{"cabs.lt.d",  "M,S,T",	0x4620007c, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	M3D	},
-{"cabs.lt.ps", "M,S,T",	0x46c0007c, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	M3D	},
-{"cabs.lt.s",  "M,S,T",	0x4600007c, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_S,	M3D	},
-{"cabs.nge.d", "M,S,T",	0x4620007d, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	M3D	},
-{"cabs.nge.ps","M,S,T",	0x46c0007d, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	M3D	},
-{"cabs.nge.s", "M,S,T",	0x4600007d, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_S,	M3D	},
-{"cabs.ngl.d", "M,S,T",	0x4620007b, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	M3D	},
-{"cabs.ngl.ps","M,S,T",	0x46c0007b, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	M3D	},
-{"cabs.ngl.s", "M,S,T",	0x4600007b, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_S,	M3D	},
-{"cabs.ngle.d","M,S,T",	0x46200079, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	M3D	},
-{"cabs.ngle.ps","M,S,T",0x46c00079, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	M3D	},
-{"cabs.ngle.s","M,S,T",	0x46000079, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_S,	M3D	},
-{"cabs.ngt.d", "M,S,T",	0x4620007f, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	M3D	},
-{"cabs.ngt.ps","M,S,T",	0x46c0007f, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	M3D	},
-{"cabs.ngt.s", "M,S,T",	0x4600007f, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_S,	M3D	},
-{"cabs.ole.d", "M,S,T",	0x46200076, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	M3D	},
-{"cabs.ole.ps","M,S,T",	0x46c00076, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	M3D	},
-{"cabs.ole.s", "M,S,T",	0x46000076, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_S,	M3D	},
-{"cabs.olt.d", "M,S,T",	0x46200074, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	M3D	},
-{"cabs.olt.ps","M,S,T",	0x46c00074, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	M3D	},
-{"cabs.olt.s", "M,S,T",	0x46000074, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_S,	M3D	},
-{"cabs.seq.d", "M,S,T",	0x4620007a, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	M3D	},
-{"cabs.seq.ps","M,S,T",	0x46c0007a, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	M3D	},
-{"cabs.seq.s", "M,S,T",	0x4600007a, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_S,	M3D	},
-{"cabs.sf.d",  "M,S,T",	0x46200078, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	M3D	},
-{"cabs.sf.ps", "M,S,T",	0x46c00078, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	M3D	},
-{"cabs.sf.s",  "M,S,T",	0x46000078, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_S,	M3D	},
-{"cabs.ueq.d", "M,S,T",	0x46200073, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	M3D	},
-{"cabs.ueq.ps","M,S,T",	0x46c00073, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	M3D	},
-{"cabs.ueq.s", "M,S,T",	0x46000073, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_S,	M3D	},
-{"cabs.ule.d", "M,S,T",	0x46200077, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	M3D	},
-{"cabs.ule.ps","M,S,T",	0x46c00077, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	M3D	},
-{"cabs.ule.s", "M,S,T",	0x46000077, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_S,	M3D	},
-{"cabs.ult.d", "M,S,T",	0x46200075, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	M3D	},
-{"cabs.ult.ps","M,S,T",	0x46c00075, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	M3D	},
-{"cabs.ult.s", "M,S,T",	0x46000075, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_S,	M3D	},
-{"cabs.un.d",  "M,S,T",	0x46200071, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	M3D	},
-{"cabs.un.ps", "M,S,T",	0x46c00071, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	M3D	},
-{"cabs.un.s",  "M,S,T",	0x46000071, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_S,	M3D	},
-{"cache",   "k,o(b)",   0xbc000000, 0xfc000000, RD_b,           	I3|I32|T3},
-{"ceil.l.d", "D,S",	0x4620000a, 0xffff003f, WR_D|RD_S|FP_D,		I3	},
-{"ceil.l.s", "D,S",	0x4600000a, 0xffff003f, WR_D|RD_S|FP_S,		I3	},
-{"ceil.w.d", "D,S",	0x4620000e, 0xffff003f, WR_D|RD_S|FP_D,		I2	},
-{"ceil.w.s", "D,S",	0x4600000e, 0xffff003f, WR_D|RD_S|FP_S,		I2	},
-{"cfc0",    "t,G",	0x40400000, 0xffe007ff,	LCD|WR_t|RD_C0,		I1	},
-{"cfc1",    "t,G",	0x44400000, 0xffe007ff,	LCD|WR_t|RD_C1|FP_S,	I1	},
-{"cfc1",    "t,S",	0x44400000, 0xffe007ff,	LCD|WR_t|RD_C1|FP_S,	I1	},
+/* bc3* are at the bottom of the table.  */
+{"beqz",    "s,p",	0x10000000, 0xfc1f0000,	CBD|RD_s,		0,		I1	},
+{"beqzl",   "s,p",	0x50000000, 0xfc1f0000,	CBL|RD_s,		0,		I2|T3	},
+{"beq",     "s,t,p",	0x10000000, 0xfc000000,	CBD|RD_s|RD_t,		0,		I1	},
+{"beq",     "s,I,p",	0,    (int) M_BEQ_I,	INSN_MACRO,		0,		I1	},
+{"beql",    "s,t,p",	0x50000000, 0xfc000000,	CBL|RD_s|RD_t,		0,		I2|T3	},
+{"beql",    "s,I,p",	0,    (int) M_BEQL_I,	INSN_MACRO,		0,		I2|T3	},
+{"bge",     "s,t,p",	0,    (int) M_BGE,	INSN_MACRO,		0,		I1	},
+{"bge",     "s,I,p",	0,    (int) M_BGE_I,	INSN_MACRO,		0,		I1	},
+{"bgel",    "s,t,p",	0,    (int) M_BGEL,	INSN_MACRO,		0,		I2|T3	},
+{"bgel",    "s,I,p",	0,    (int) M_BGEL_I,	INSN_MACRO,		0,		I2|T3	},
+{"bgeu",    "s,t,p",	0,    (int) M_BGEU,	INSN_MACRO,		0,		I1	},
+{"bgeu",    "s,I,p",	0,    (int) M_BGEU_I,	INSN_MACRO,		0,		I1	},
+{"bgeul",   "s,t,p",	0,    (int) M_BGEUL,	INSN_MACRO,		0,		I2|T3	},
+{"bgeul",   "s,I,p",	0,    (int) M_BGEUL_I,	INSN_MACRO,		0,		I2|T3	},
+{"bgez",    "s,p",	0x04010000, 0xfc1f0000,	CBD|RD_s,		0,		I1	},
+{"bgezl",   "s,p",	0x04030000, 0xfc1f0000,	CBL|RD_s,		0,		I2|T3	},
+{"bgezal",  "s,p",	0x04110000, 0xfc1f0000,	CBD|RD_s|WR_31,		0,		I1	},
+{"bgezall", "s,p",	0x04130000, 0xfc1f0000,	CBL|RD_s|WR_31,		0,		I2|T3	},
+{"bgt",     "s,t,p",	0,    (int) M_BGT,	INSN_MACRO,		0,		I1	},
+{"bgt",     "s,I,p",	0,    (int) M_BGT_I,	INSN_MACRO,		0,		I1	},
+{"bgtl",    "s,t,p",	0,    (int) M_BGTL,	INSN_MACRO,		0,		I2|T3	},
+{"bgtl",    "s,I,p",	0,    (int) M_BGTL_I,	INSN_MACRO,		0,		I2|T3	},
+{"bgtu",    "s,t,p",	0,    (int) M_BGTU,	INSN_MACRO,		0,		I1	},
+{"bgtu",    "s,I,p",	0,    (int) M_BGTU_I,	INSN_MACRO,		0,		I1	},
+{"bgtul",   "s,t,p",	0,    (int) M_BGTUL,	INSN_MACRO,		0,		I2|T3	},
+{"bgtul",   "s,I,p",	0,    (int) M_BGTUL_I,	INSN_MACRO,		0,		I2|T3	},
+{"bgtz",    "s,p",	0x1c000000, 0xfc1f0000,	CBD|RD_s,		0,		I1	},
+{"bgtzl",   "s,p",	0x5c000000, 0xfc1f0000,	CBL|RD_s,		0,		I2|T3	},
+{"ble",     "s,t,p",	0,    (int) M_BLE,	INSN_MACRO,		0,		I1	},
+{"ble",     "s,I,p",	0,    (int) M_BLE_I,	INSN_MACRO,		0,		I1	},
+{"blel",    "s,t,p",	0,    (int) M_BLEL,	INSN_MACRO,		0,		I2|T3	},
+{"blel",    "s,I,p",	0,    (int) M_BLEL_I,	INSN_MACRO,		0,		I2|T3	},
+{"bleu",    "s,t,p",	0,    (int) M_BLEU,	INSN_MACRO,		0,		I1	},
+{"bleu",    "s,I,p",	0,    (int) M_BLEU_I,	INSN_MACRO,		0,		I1	},
+{"bleul",   "s,t,p",	0,    (int) M_BLEUL,	INSN_MACRO,		0,		I2|T3	},
+{"bleul",   "s,I,p",	0,    (int) M_BLEUL_I,	INSN_MACRO,		0,		I2|T3	},
+{"blez",    "s,p",	0x18000000, 0xfc1f0000,	CBD|RD_s,		0,		I1	},
+{"blezl",   "s,p",	0x58000000, 0xfc1f0000,	CBL|RD_s,		0,		I2|T3	},
+{"blt",     "s,t,p",	0,    (int) M_BLT,	INSN_MACRO,		0,		I1	},
+{"blt",     "s,I,p",	0,    (int) M_BLT_I,	INSN_MACRO,		0,		I1	},
+{"bltl",    "s,t,p",	0,    (int) M_BLTL,	INSN_MACRO,		0,		I2|T3	},
+{"bltl",    "s,I,p",	0,    (int) M_BLTL_I,	INSN_MACRO,		0,		I2|T3	},
+{"bltu",    "s,t,p",	0,    (int) M_BLTU,	INSN_MACRO,		0,		I1	},
+{"bltu",    "s,I,p",	0,    (int) M_BLTU_I,	INSN_MACRO,		0,		I1	},
+{"bltul",   "s,t,p",	0,    (int) M_BLTUL,	INSN_MACRO,		0,		I2|T3	},
+{"bltul",   "s,I,p",	0,    (int) M_BLTUL_I,	INSN_MACRO,		0,		I2|T3	},
+{"bltz",    "s,p",	0x04000000, 0xfc1f0000,	CBD|RD_s,		0,		I1	},
+{"bltzl",   "s,p",	0x04020000, 0xfc1f0000,	CBL|RD_s,		0,		I2|T3	},
+{"bltzal",  "s,p",	0x04100000, 0xfc1f0000,	CBD|RD_s|WR_31,		0,		I1	},
+{"bltzall", "s,p",	0x04120000, 0xfc1f0000,	CBL|RD_s|WR_31,		0,		I2|T3	},
+{"bnez",    "s,p",	0x14000000, 0xfc1f0000,	CBD|RD_s,		0,		I1	},
+{"bnezl",   "s,p",	0x54000000, 0xfc1f0000,	CBL|RD_s,		0,		I2|T3	},
+{"bne",     "s,t,p",	0x14000000, 0xfc000000,	CBD|RD_s|RD_t,		0,		I1	},
+{"bne",     "s,I,p",	0,    (int) M_BNE_I,	INSN_MACRO,		0,		I1	},
+{"bnel",    "s,t,p",	0x54000000, 0xfc000000,	CBL|RD_s|RD_t, 		0,		I2|T3	},
+{"bnel",    "s,I,p",	0,    (int) M_BNEL_I,	INSN_MACRO,		0,		I2|T3	},
+{"break",   "",		0x0000000d, 0xffffffff,	TRAP,			0,		I1	},
+{"break",   "c",	0x0000000d, 0xfc00ffff,	TRAP,			0,		I1	},
+{"break",   "c,q",	0x0000000d, 0xfc00003f,	TRAP,			0,		I1	},
+{"c.f.d",   "S,T",	0x46200030, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I1	},
+{"c.f.d",   "M,S,T",    0x46200030, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D,   0,		I4|I32	},
+{"c.f.s",   "S,T",      0x46000030, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S,   0,		I1      },
+{"c.f.s",   "M,S,T",    0x46000030, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S,   0,		I4|I32	},
+{"c.f.ps",  "S,T",	0x46c00030, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I5|I33	},
+{"c.f.ps",  "M,S,T",	0x46c00030, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I5|I33	},
+{"c.un.d",  "S,T",	0x46200031, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I1	},
+{"c.un.d",  "M,S,T",    0x46200031, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D,   0,		I4|I32	},
+{"c.un.s",  "S,T",      0x46000031, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S,   0,		I1      },
+{"c.un.s",  "M,S,T",    0x46000031, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S,   0,		I4|I32	},
+{"c.un.ps", "S,T",	0x46c00031, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I5|I33	},
+{"c.un.ps", "M,S,T",	0x46c00031, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I5|I33	},
+{"c.eq.d",  "S,T",	0x46200032, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I1	},
+{"c.eq.d",  "M,S,T",    0x46200032, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D,   0,		I4|I32	},
+{"c.eq.s",  "S,T",      0x46000032, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S,   0,		I1      },
+{"c.eq.s",  "M,S,T",    0x46000032, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S,   0,		I4|I32	},
+{"c.eq.ob", "Y,Q",	0x78000001, 0xfc2007ff,	WR_CC|RD_S|RD_T|FP_D,	0,		MX|SB1	},
+{"c.eq.ob", "S,T",	0x4ac00001, 0xffe007ff,	WR_CC|RD_S|RD_T,	0,		N54	},
+{"c.eq.ob", "S,T[e]",	0x48000001, 0xfe2007ff,	WR_CC|RD_S|RD_T,	0,		N54	},
+{"c.eq.ob", "S,k",	0x4bc00001, 0xffe007ff,	WR_CC|RD_S|RD_T,	0,		N54	},
+{"c.eq.ps", "S,T",	0x46c00032, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I5|I33	},
+{"c.eq.ps", "M,S,T",	0x46c00032, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I5|I33	},
+{"c.eq.qh", "Y,Q",	0x78200001, 0xfc2007ff,	WR_CC|RD_S|RD_T|FP_D,	0,		MX	},
+{"c.ueq.d", "S,T",	0x46200033, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I1	},
+{"c.ueq.d", "M,S,T",    0x46200033, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D,   0,		I4|I32	},
+{"c.ueq.s", "S,T",      0x46000033, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S,   0,		I1      },
+{"c.ueq.s", "M,S,T",    0x46000033, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S,   0,		I4|I32	},
+{"c.ueq.ps","S,T",	0x46c00033, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I5|I33	},
+{"c.ueq.ps","M,S,T",	0x46c00033, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I5|I33	},
+{"c.olt.d", "S,T",      0x46200034, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D,   0,		I1      },
+{"c.olt.d", "M,S,T",    0x46200034, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D,   0,		I4|I32	},
+{"c.olt.s", "S,T",	0x46000034, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_S,	0,		I1	},
+{"c.olt.s", "M,S,T",    0x46000034, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S,   0,		I4|I32	},
+{"c.olt.ps","S,T",	0x46c00034, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I5|I33	},
+{"c.olt.ps","M,S,T",	0x46c00034, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I5|I33	},
+{"c.ult.d", "S,T",	0x46200035, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I1	},
+{"c.ult.d", "M,S,T",    0x46200035, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D,   0,		I4|I32	},
+{"c.ult.s", "S,T",      0x46000035, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S,   0,		I1      },
+{"c.ult.s", "M,S,T",    0x46000035, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S,   0,		I4|I32	},
+{"c.ult.ps","S,T",	0x46c00035, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I5|I33	},
+{"c.ult.ps","M,S,T",	0x46c00035, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I5|I33	},
+{"c.ole.d", "S,T",      0x46200036, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D,   0,		I1      },
+{"c.ole.d", "M,S,T",    0x46200036, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D,   0,		I4|I32	},
+{"c.ole.s", "S,T",      0x46000036, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S,   0,		I1      },
+{"c.ole.s", "M,S,T",    0x46000036, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S,   0,		I4|I32	},
+{"c.ole.ps","S,T",	0x46c00036, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I5|I33	},
+{"c.ole.ps","M,S,T",	0x46c00036, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I5|I33	},
+{"c.ule.d", "S,T",	0x46200037, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I1	},
+{"c.ule.d", "M,S,T",    0x46200037, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D,   0,		I4|I32	},
+{"c.ule.s", "S,T",      0x46000037, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S,   0,		I1      },
+{"c.ule.s", "M,S,T",    0x46000037, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S,   0,		I4|I32	},
+{"c.ule.ps","S,T",	0x46c00037, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I5|I33	},
+{"c.ule.ps","M,S,T",	0x46c00037, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I5|I33	},
+{"c.sf.d",  "S,T",	0x46200038, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I1	},
+{"c.sf.d",  "M,S,T",    0x46200038, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D,   0,		I4|I32	},
+{"c.sf.s",  "S,T",      0x46000038, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S,   0,		I1      },
+{"c.sf.s",  "M,S,T",    0x46000038, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S,   0,		I4|I32	},
+{"c.sf.ps", "S,T",	0x46c00038, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I5|I33	},
+{"c.sf.ps", "M,S,T",	0x46c00038, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I5|I33	},
+{"c.ngle.d","S,T",	0x46200039, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I1	},
+{"c.ngle.d","M,S,T",    0x46200039, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D,   0,		I4|I32	},
+{"c.ngle.s","S,T",      0x46000039, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S,   0,		I1      },
+{"c.ngle.s","M,S,T",    0x46000039, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S,   0,		I4|I32	},
+{"c.ngle.ps","S,T",	0x46c00039, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I5|I33	},
+{"c.ngle.ps","M,S,T",	0x46c00039, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I5|I33	},
+{"c.seq.d", "S,T",	0x4620003a, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I1	},
+{"c.seq.d", "M,S,T",    0x4620003a, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D,   0,		I4|I32	},
+{"c.seq.s", "S,T",      0x4600003a, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S,   0,		I1      },
+{"c.seq.s", "M,S,T",    0x4600003a, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S,   0,		I4|I32	},
+{"c.seq.ps","S,T",	0x46c0003a, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I5|I33	},
+{"c.seq.ps","M,S,T",	0x46c0003a, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I5|I33	},
+{"c.ngl.d", "S,T",	0x4620003b, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I1	},
+{"c.ngl.d", "M,S,T",    0x4620003b, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D,   0,		I4|I32	},
+{"c.ngl.s", "S,T",      0x4600003b, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S,   0,		I1      },
+{"c.ngl.s", "M,S,T",    0x4600003b, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S,   0,		I4|I32	},
+{"c.ngl.ps","S,T",	0x46c0003b, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I5|I33	},
+{"c.ngl.ps","M,S,T",	0x46c0003b, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I5|I33	},
+{"c.lt.d",  "S,T",	0x4620003c, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I1	},
+{"c.lt.d",  "M,S,T",    0x4620003c, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D,   0,		I4|I32	},
+{"c.lt.s",  "S,T",	0x4600003c, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_S,	0,		I1	},
+{"c.lt.s",  "M,S,T",    0x4600003c, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S,   0,		I4|I32	},
+{"c.lt.ob", "Y,Q",	0x78000004, 0xfc2007ff,	WR_CC|RD_S|RD_T|FP_D,	0,		MX|SB1	},
+{"c.lt.ob", "S,T",	0x4ac00004, 0xffe007ff,	WR_CC|RD_S|RD_T,	0,		N54	},
+{"c.lt.ob", "S,T[e]",	0x48000004, 0xfe2007ff,	WR_CC|RD_S|RD_T,	0,		N54	},
+{"c.lt.ob", "S,k",	0x4bc00004, 0xffe007ff,	WR_CC|RD_S|RD_T,	0,		N54	},
+{"c.lt.ps", "S,T",	0x46c0003c, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I5|I33	},
+{"c.lt.ps", "M,S,T",	0x46c0003c, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I5|I33	},
+{"c.lt.qh", "Y,Q",	0x78200004, 0xfc2007ff,	WR_CC|RD_S|RD_T|FP_D,	0,		MX	},
+{"c.nge.d", "S,T",	0x4620003d, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I1	},
+{"c.nge.d", "M,S,T",    0x4620003d, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D,   0,		I4|I32	},
+{"c.nge.s", "S,T",      0x4600003d, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S,   0,		I1      },
+{"c.nge.s", "M,S,T",    0x4600003d, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S,   0,		I4|I32	},
+{"c.nge.ps","S,T",	0x46c0003d, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I5|I33	},
+{"c.nge.ps","M,S,T",	0x46c0003d, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I5|I33	},
+{"c.le.d",  "S,T",	0x4620003e, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I1	},
+{"c.le.d",  "M,S,T",    0x4620003e, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D,   0,		I4|I32	},
+{"c.le.s",  "S,T",	0x4600003e, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_S,	0,		I1	},
+{"c.le.s",  "M,S,T",    0x4600003e, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S,   0,		I4|I32	},
+{"c.le.ob", "Y,Q",	0x78000005, 0xfc2007ff,	WR_CC|RD_S|RD_T|FP_D,	0,		MX|SB1	},
+{"c.le.ob", "S,T",	0x4ac00005, 0xffe007ff,	WR_CC|RD_S|RD_T,	0,		N54	},
+{"c.le.ob", "S,T[e]",	0x48000005, 0xfe2007ff,	WR_CC|RD_S|RD_T,	0,		N54	},
+{"c.le.ob", "S,k",	0x4bc00005, 0xffe007ff,	WR_CC|RD_S|RD_T,	0,		N54	},
+{"c.le.ps", "S,T",	0x46c0003e, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I5|I33	},
+{"c.le.ps", "M,S,T",	0x46c0003e, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I5|I33	},
+{"c.le.qh", "Y,Q",	0x78200005, 0xfc2007ff,	WR_CC|RD_S|RD_T|FP_D,	0,		MX	},
+{"c.ngt.d", "S,T",	0x4620003f, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I1	},
+{"c.ngt.d", "M,S,T",    0x4620003f, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D,   0,		I4|I32	},
+{"c.ngt.s", "S,T",      0x4600003f, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S,   0,		I1      },
+{"c.ngt.s", "M,S,T",    0x4600003f, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S,   0,		I4|I32	},
+{"c.ngt.ps","S,T",	0x46c0003f, 0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I5|I33	},
+{"c.ngt.ps","M,S,T",	0x46c0003f, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		I5|I33	},
+{"cabs.eq.d",  "M,S,T",	0x46200072, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		M3D	},
+{"cabs.eq.ps", "M,S,T",	0x46c00072, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		M3D	},
+{"cabs.eq.s",  "M,S,T",	0x46000072, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_S,	0,		M3D	},
+{"cabs.f.d",   "M,S,T",	0x46200070, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		M3D	},
+{"cabs.f.ps",  "M,S,T",	0x46c00070, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		M3D	},
+{"cabs.f.s",   "M,S,T",	0x46000070, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_S,	0,		M3D	},
+{"cabs.le.d",  "M,S,T",	0x4620007e, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		M3D	},
+{"cabs.le.ps", "M,S,T",	0x46c0007e, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		M3D	},
+{"cabs.le.s",  "M,S,T",	0x4600007e, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_S,	0,		M3D	},
+{"cabs.lt.d",  "M,S,T",	0x4620007c, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		M3D	},
+{"cabs.lt.ps", "M,S,T",	0x46c0007c, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		M3D	},
+{"cabs.lt.s",  "M,S,T",	0x4600007c, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_S,	0,		M3D	},
+{"cabs.nge.d", "M,S,T",	0x4620007d, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		M3D	},
+{"cabs.nge.ps","M,S,T",	0x46c0007d, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		M3D	},
+{"cabs.nge.s", "M,S,T",	0x4600007d, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_S,	0,		M3D	},
+{"cabs.ngl.d", "M,S,T",	0x4620007b, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		M3D	},
+{"cabs.ngl.ps","M,S,T",	0x46c0007b, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		M3D	},
+{"cabs.ngl.s", "M,S,T",	0x4600007b, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_S,	0,		M3D	},
+{"cabs.ngle.d","M,S,T",	0x46200079, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		M3D	},
+{"cabs.ngle.ps","M,S,T",0x46c00079, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		M3D	},
+{"cabs.ngle.s","M,S,T",	0x46000079, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_S,	0,		M3D	},
+{"cabs.ngt.d", "M,S,T",	0x4620007f, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		M3D	},
+{"cabs.ngt.ps","M,S,T",	0x46c0007f, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		M3D	},
+{"cabs.ngt.s", "M,S,T",	0x4600007f, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_S,	0,		M3D	},
+{"cabs.ole.d", "M,S,T",	0x46200076, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		M3D	},
+{"cabs.ole.ps","M,S,T",	0x46c00076, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		M3D	},
+{"cabs.ole.s", "M,S,T",	0x46000076, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_S,	0,		M3D	},
+{"cabs.olt.d", "M,S,T",	0x46200074, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		M3D	},
+{"cabs.olt.ps","M,S,T",	0x46c00074, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		M3D	},
+{"cabs.olt.s", "M,S,T",	0x46000074, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_S,	0,		M3D	},
+{"cabs.seq.d", "M,S,T",	0x4620007a, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		M3D	},
+{"cabs.seq.ps","M,S,T",	0x46c0007a, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		M3D	},
+{"cabs.seq.s", "M,S,T",	0x4600007a, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_S,	0,		M3D	},
+{"cabs.sf.d",  "M,S,T",	0x46200078, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		M3D	},
+{"cabs.sf.ps", "M,S,T",	0x46c00078, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		M3D	},
+{"cabs.sf.s",  "M,S,T",	0x46000078, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_S,	0,		M3D	},
+{"cabs.ueq.d", "M,S,T",	0x46200073, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		M3D	},
+{"cabs.ueq.ps","M,S,T",	0x46c00073, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		M3D	},
+{"cabs.ueq.s", "M,S,T",	0x46000073, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_S,	0,		M3D	},
+{"cabs.ule.d", "M,S,T",	0x46200077, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		M3D	},
+{"cabs.ule.ps","M,S,T",	0x46c00077, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		M3D	},
+{"cabs.ule.s", "M,S,T",	0x46000077, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_S,	0,		M3D	},
+{"cabs.ult.d", "M,S,T",	0x46200075, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		M3D	},
+{"cabs.ult.ps","M,S,T",	0x46c00075, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		M3D	},
+{"cabs.ult.s", "M,S,T",	0x46000075, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_S,	0,		M3D	},
+{"cabs.un.d",  "M,S,T",	0x46200071, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		M3D	},
+{"cabs.un.ps", "M,S,T",	0x46c00071, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_D,	0,		M3D	},
+{"cabs.un.s",  "M,S,T",	0x46000071, 0xffe000ff,	RD_S|RD_T|WR_CC|FP_S,	0,		M3D	},
+/* CW4010 instructions which are aliases for the cache instruction.  */
+{"flushi",  "",		0xbc010000, 0xffffffff, 0,			0,		L1	},
+{"flushd",  "",		0xbc020000, 0xffffffff, 0, 			0,		L1	},
+{"flushid", "",		0xbc030000, 0xffffffff, 0, 			0,		L1	},
+{"wb", 	    "o(b)",	0xbc040000, 0xfc1f0000, SM|RD_b,		0,		L1	},
+{"cache",   "k,o(b)",   0xbc000000, 0xfc000000, RD_b,           	0,		I3|I32|T3},
+{"cache",   "k,A(b)",	0,    (int) M_CACHE_AB, INSN_MACRO,		0,		I3|I32|T3},
+{"ceil.l.d", "D,S",	0x4620000a, 0xffff003f, WR_D|RD_S|FP_D,		0,		I3|I33	},
+{"ceil.l.s", "D,S",	0x4600000a, 0xffff003f, WR_D|RD_S|FP_S|FP_D,	0,		I3|I33	},
+{"ceil.w.d", "D,S",	0x4620000e, 0xffff003f, WR_D|RD_S|FP_S|FP_D,	0,		I2	},
+{"ceil.w.s", "D,S",	0x4600000e, 0xffff003f, WR_D|RD_S|FP_S,		0,		I2	},
+{"cfc0",    "t,G",	0x40400000, 0xffe007ff,	LCD|WR_t|RD_C0,		0,		I1	},
+{"cfc1",    "t,G",	0x44400000, 0xffe007ff,	LCD|WR_t|RD_C1|FP_S,	0,		I1	},
+{"cfc1",    "t,S",	0x44400000, 0xffe007ff,	LCD|WR_t|RD_C1|FP_S,	0,		I1	},
 /* cfc2 is at the bottom of the table.  */
-{"cfc3",    "t,G",	0x4c400000, 0xffe007ff,	LCD|WR_t|RD_C3,		I1	},
-{"clo",     "U,s",      0x70000021, 0xfc0007ff, WR_d|WR_t|RD_s, 	I32|N55 },
-{"clz",     "U,s",      0x70000020, 0xfc0007ff, WR_d|WR_t|RD_s, 	I32|N55 },
-{"ctc0",    "t,G",	0x40c00000, 0xffe007ff,	COD|RD_t|WR_CC,		I1	},
-{"ctc1",    "t,G",	0x44c00000, 0xffe007ff,	COD|RD_t|WR_CC|FP_S,	I1	},
-{"ctc1",    "t,S",	0x44c00000, 0xffe007ff,	COD|RD_t|WR_CC|FP_S,	I1	},
+/* cfc3 is at the bottom of the table.  */
+{"cftc1",   "d,E",	0x41000023, 0xffe007ff, TRAP|LCD|WR_d|RD_C1|FP_S, 0,		MT32	},
+{"cftc1",   "d,T",	0x41000023, 0xffe007ff, TRAP|LCD|WR_d|RD_C1|FP_S, 0,		MT32	},
+{"cftc2",   "d,E",	0x41000025, 0xffe007ff, TRAP|LCD|WR_d|RD_C2,	0,		MT32	},
+{"clo",     "U,s",      0x70000021, 0xfc0007ff, WR_d|WR_t|RD_s, 	0,		I32|N55 },
+{"clz",     "U,s",      0x70000020, 0xfc0007ff, WR_d|WR_t|RD_s, 	0,		I32|N55 },
+{"ctc0",    "t,G",	0x40c00000, 0xffe007ff,	COD|RD_t|WR_CC,		0,		I1	},
+{"ctc1",    "t,G",	0x44c00000, 0xffe007ff,	COD|RD_t|WR_CC|FP_S,	0,		I1	},
+{"ctc1",    "t,S",	0x44c00000, 0xffe007ff,	COD|RD_t|WR_CC|FP_S,	0,		I1	},
 /* ctc2 is at the bottom of the table.  */
-{"ctc3",    "t,G",	0x4cc00000, 0xffe007ff,	COD|RD_t|WR_CC,		I1	},
-{"cvt.d.l", "D,S",	0x46a00021, 0xffff003f,	WR_D|RD_S|FP_D,		I3	},
-{"cvt.d.s", "D,S",	0x46000021, 0xffff003f,	WR_D|RD_S|FP_D|FP_S,	I1	},
-{"cvt.d.w", "D,S",	0x46800021, 0xffff003f,	WR_D|RD_S|FP_D,		I1	},
-{"cvt.l.d", "D,S",	0x46200025, 0xffff003f,	WR_D|RD_S|FP_D,		I3	},
-{"cvt.l.s", "D,S",	0x46000025, 0xffff003f,	WR_D|RD_S|FP_S,		I3	},
-{"cvt.s.l", "D,S",	0x46a00020, 0xffff003f,	WR_D|RD_S|FP_S,		I3	},
-{"cvt.s.d", "D,S",	0x46200020, 0xffff003f,	WR_D|RD_S|FP_S|FP_D,	I1	},
-{"cvt.s.w", "D,S",	0x46800020, 0xffff003f,	WR_D|RD_S|FP_S,		I1	},
-{"cvt.s.pl","D,S",	0x46c00028, 0xffff003f,	WR_D|RD_S|FP_S|FP_D,	I5	},
-{"cvt.s.pu","D,S",	0x46c00020, 0xffff003f,	WR_D|RD_S|FP_S|FP_D,	I5	},
-{"cvt.w.d", "D,S",	0x46200024, 0xffff003f,	WR_D|RD_S|FP_D,		I1	},
-{"cvt.w.s", "D,S",	0x46000024, 0xffff003f,	WR_D|RD_S|FP_S,		I1	},
-{"cvt.ps.pw", "D,S",	0x46800026, 0xffff003f,	WR_D|RD_S|FP_S|FP_D,	M3D	},
-{"cvt.ps.s","D,V,T",	0x46000026, 0xffe0003f,	WR_D|RD_S|RD_T|FP_D,	I5	},
-{"cvt.pw.ps", "D,S",	0x46c00024, 0xffff003f,	WR_D|RD_S|FP_S|FP_D,	M3D	},
-{"dabs",    "d,v",	0,    (int) M_DABS,	INSN_MACRO,		I3	},
-{"dadd",    "d,v,t",	0x0000002c, 0xfc0007ff, WR_d|RD_s|RD_t,		I3	},
-{"dadd",    "t,r,I",	0,    (int) M_DADD_I,	INSN_MACRO,		I3	},
-{"daddi",   "t,r,j",	0x60000000, 0xfc000000, WR_t|RD_s,		I3	},
-{"daddiu",  "t,r,j",	0x64000000, 0xfc000000, WR_t|RD_s,		I3	},
-{"daddu",   "d,v,t",	0x0000002d, 0xfc0007ff, WR_d|RD_s|RD_t,		I3	},
-{"daddu",   "t,r,I",	0,    (int) M_DADDU_I,	INSN_MACRO,		I3	},
-{"dbreak",  "",		0x7000003f, 0xffffffff,	0,			N5	},
-{"dclo",    "U,s",      0x70000025, 0xfc0007ff, RD_s|WR_d|WR_t, 	I64|N55 },
-{"dclz",    "U,s",      0x70000024, 0xfc0007ff, RD_s|WR_d|WR_t, 	I64|N55 },
+/* ctc3 is at the bottom of the table.  */
+{"cttc1",   "t,g",	0x41800023, 0xffe007ff, TRAP|COD|RD_t|WR_CC|FP_S, 0,		MT32	},
+{"cttc1",   "t,S",	0x41800023, 0xffe007ff, TRAP|COD|RD_t|WR_CC|FP_S, 0,		MT32	},
+{"cttc2",   "t,g",	0x41800025, 0xffe007ff, TRAP|COD|RD_t|WR_CC,	0,		MT32	},
+{"cvt.d.l", "D,S",	0x46a00021, 0xffff003f,	WR_D|RD_S|FP_D,		0,		I3|I33	},
+{"cvt.d.s", "D,S",	0x46000021, 0xffff003f,	WR_D|RD_S|FP_S|FP_D,	0,		I1	},
+{"cvt.d.w", "D,S",	0x46800021, 0xffff003f,	WR_D|RD_S|FP_S|FP_D,	0,		I1	},
+{"cvt.l.d", "D,S",	0x46200025, 0xffff003f,	WR_D|RD_S|FP_D,		0,		I3|I33	},
+{"cvt.l.s", "D,S",	0x46000025, 0xffff003f,	WR_D|RD_S|FP_S|FP_D,	0,		I3|I33	},
+{"cvt.s.l", "D,S",	0x46a00020, 0xffff003f,	WR_D|RD_S|FP_S|FP_D,	0,		I3|I33	},
+{"cvt.s.d", "D,S",	0x46200020, 0xffff003f,	WR_D|RD_S|FP_S|FP_D,	0,		I1	},
+{"cvt.s.w", "D,S",	0x46800020, 0xffff003f,	WR_D|RD_S|FP_S,		0,		I1	},
+{"cvt.s.pl","D,S",	0x46c00028, 0xffff003f,	WR_D|RD_S|FP_S|FP_D,	0,		I5|I33	},
+{"cvt.s.pu","D,S",	0x46c00020, 0xffff003f,	WR_D|RD_S|FP_S|FP_D,	0,		I5|I33	},
+{"cvt.w.d", "D,S",	0x46200024, 0xffff003f,	WR_D|RD_S|FP_S|FP_D,	0,		I1	},
+{"cvt.w.s", "D,S",	0x46000024, 0xffff003f,	WR_D|RD_S|FP_S,		0,		I1	},
+{"cvt.ps.pw", "D,S",	0x46800026, 0xffff003f,	WR_D|RD_S|FP_S|FP_D,	0,		M3D	},
+{"cvt.ps.s","D,V,T",	0x46000026, 0xffe0003f,	WR_D|RD_S|RD_T|FP_S|FP_D, 0,		I5|I33	},
+{"cvt.pw.ps", "D,S",	0x46c00024, 0xffff003f,	WR_D|RD_S|FP_S|FP_D,	0,		M3D	},
+{"dabs",    "d,v",	0,    (int) M_DABS,	INSN_MACRO,		0,		I3	},
+{"dadd",    "d,v,t",	0x0000002c, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		I3	},
+{"dadd",    "t,r,I",	0,    (int) M_DADD_I,	INSN_MACRO,		0,		I3	},
+{"daddi",   "t,r,j",	0x60000000, 0xfc000000, WR_t|RD_s,		0,		I3	},
+{"daddiu",  "t,r,j",	0x64000000, 0xfc000000, WR_t|RD_s,		0,		I3	},
+{"daddu",   "d,v,t",	0x0000002d, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		I3	},
+{"daddu",   "t,r,I",	0,    (int) M_DADDU_I,	INSN_MACRO,		0,		I3	},
+{"dbreak",  "",		0x7000003f, 0xffffffff,	0,			0,		N5	},
+{"dclo",    "U,s",      0x70000025, 0xfc0007ff, RD_s|WR_d|WR_t, 	0,		I64|N55 },
+{"dclz",    "U,s",      0x70000024, 0xfc0007ff, RD_s|WR_d|WR_t, 	0,		I64|N55 },
 /* dctr and dctw are used on the r5000.  */
-{"dctr",    "o(b)",	0xbc050000, 0xfc1f0000, RD_b,			I3	},
-{"dctw",    "o(b)",	0xbc090000, 0xfc1f0000, RD_b,			I3	},
-{"deret",   "",         0x4200001f, 0xffffffff, 0, 			I32|G2	},
-{"dext",    "t,r,I,+I",	0,    (int) M_DEXT,	INSN_MACRO,		I65	},
-{"dext",    "t,r,+A,+C", 0x7c000003, 0xfc00003f, WR_t|RD_s,    		I65	},
-{"dextm",   "t,r,+A,+G", 0x7c000001, 0xfc00003f, WR_t|RD_s,    		I65	},
-{"dextu",   "t,r,+E,+H", 0x7c000002, 0xfc00003f, WR_t|RD_s,    		I65	},
+{"dctr",    "o(b)",	0xbc050000, 0xfc1f0000, RD_b,			0,		I3	},
+{"dctw",    "o(b)",	0xbc090000, 0xfc1f0000, RD_b,			0,		I3	},
+{"deret",   "",         0x4200001f, 0xffffffff, 0, 			0,		I32|G2	},
+{"dext",    "t,r,I,+I",	0,    (int) M_DEXT,	INSN_MACRO,		0,		I65	},
+{"dext",    "t,r,+A,+C", 0x7c000003, 0xfc00003f, WR_t|RD_s,    		0,		I65	},
+{"dextm",   "t,r,+A,+G", 0x7c000001, 0xfc00003f, WR_t|RD_s,    		0,		I65	},
+{"dextu",   "t,r,+E,+H", 0x7c000002, 0xfc00003f, WR_t|RD_s,    		0,		I65	},
 /* For ddiv, see the comments about div.  */
-{"ddiv",    "z,s,t",    0x0000001e, 0xfc00ffff, RD_s|RD_t|WR_HILO,      I3      },
-{"ddiv",    "d,v,t",	0,    (int) M_DDIV_3,	INSN_MACRO,		I3	},
-{"ddiv",    "d,v,I",	0,    (int) M_DDIV_3I,	INSN_MACRO,		I3	},
+{"ddiv",    "z,s,t",    0x0000001e, 0xfc00ffff, RD_s|RD_t|WR_HILO,      0,		I3      },
+{"ddiv",    "d,v,t",	0,    (int) M_DDIV_3,	INSN_MACRO,		0,		I3	},
+{"ddiv",    "d,v,I",	0,    (int) M_DDIV_3I,	INSN_MACRO,		0,		I3	},
 /* For ddivu, see the comments about div.  */
-{"ddivu",   "z,s,t",    0x0000001f, 0xfc00ffff, RD_s|RD_t|WR_HILO,      I3      },
-{"ddivu",   "d,v,t",	0,    (int) M_DDIVU_3,	INSN_MACRO,		I3	},
-{"ddivu",   "d,v,I",	0,    (int) M_DDIVU_3I,	INSN_MACRO,		I3	},
-{"di",      "",		0x41606000, 0xffffffff,	WR_t|WR_C0,		I33	},
-{"di",      "t",	0x41606000, 0xffe0ffff,	WR_t|WR_C0,		I33	},
-{"dins",    "t,r,I,+I",	0,    (int) M_DINS,	INSN_MACRO,		I65	},
-{"dins",    "t,r,+A,+B", 0x7c000007, 0xfc00003f, WR_t|RD_s,    		I65	},
-{"dinsm",   "t,r,+A,+F", 0x7c000005, 0xfc00003f, WR_t|RD_s,    		I65	},
-{"dinsu",   "t,r,+E,+F", 0x7c000006, 0xfc00003f, WR_t|RD_s,    		I65	},
+{"ddivu",   "z,s,t",    0x0000001f, 0xfc00ffff, RD_s|RD_t|WR_HILO,      0,		I3      },
+{"ddivu",   "d,v,t",	0,    (int) M_DDIVU_3,	INSN_MACRO,		0,		I3	},
+{"ddivu",   "d,v,I",	0,    (int) M_DDIVU_3I,	INSN_MACRO,		0,		I3	},
+{"di",      "",		0x41606000, 0xffffffff,	WR_t|WR_C0,		0,		I33	},
+{"di",      "t",	0x41606000, 0xffe0ffff,	WR_t|WR_C0,		0,		I33	},
+{"dins",    "t,r,I,+I",	0,    (int) M_DINS,	INSN_MACRO,		0,		I65	},
+{"dins",    "t,r,+A,+B", 0x7c000007, 0xfc00003f, WR_t|RD_s,    		0,		I65	},
+{"dinsm",   "t,r,+A,+F", 0x7c000005, 0xfc00003f, WR_t|RD_s,    		0,		I65	},
+{"dinsu",   "t,r,+E,+F", 0x7c000006, 0xfc00003f, WR_t|RD_s,    		0,		I65	},
 /* The MIPS assembler treats the div opcode with two operands as
    though the first operand appeared twice (the first operand is both
    a source and a destination).  To get the div machine instruction,
    you must use an explicit destination of $0.  */
-{"div",     "z,s,t",    0x0000001a, 0xfc00ffff, RD_s|RD_t|WR_HILO,      I1      },
-{"div",     "z,t",      0x0000001a, 0xffe0ffff, RD_s|RD_t|WR_HILO,      I1      },
-{"div",     "d,v,t",	0,    (int) M_DIV_3,	INSN_MACRO,		I1	},
-{"div",     "d,v,I",	0,    (int) M_DIV_3I,	INSN_MACRO,		I1	},
-{"div.d",   "D,V,T",	0x46200003, 0xffe0003f,	WR_D|RD_S|RD_T|FP_D,	I1	},
-{"div.s",   "D,V,T",	0x46000003, 0xffe0003f,	WR_D|RD_S|RD_T|FP_S,	I1	},
-{"div.ps",  "D,V,T",	0x46c00003, 0xffe0003f,	WR_D|RD_S|RD_T|FP_D,	SB1	},
+{"div",     "z,s,t",    0x0000001a, 0xfc00ffff, RD_s|RD_t|WR_HILO,      0,		I1      },
+{"div",     "z,t",      0x0000001a, 0xffe0ffff, RD_s|RD_t|WR_HILO,      0,		I1      },
+{"div",     "d,v,t",	0,    (int) M_DIV_3,	INSN_MACRO,		0,		I1	},
+{"div",     "d,v,I",	0,    (int) M_DIV_3I,	INSN_MACRO,		0,		I1	},
+{"div.d",   "D,V,T",	0x46200003, 0xffe0003f,	WR_D|RD_S|RD_T|FP_D,	0,		I1	},
+{"div.s",   "D,V,T",	0x46000003, 0xffe0003f,	WR_D|RD_S|RD_T|FP_S,	0,		I1	},
+{"div.ps",  "D,V,T",	0x46c00003, 0xffe0003f,	WR_D|RD_S|RD_T|FP_D,	0,		SB1	},
 /* For divu, see the comments about div.  */
-{"divu",    "z,s,t",    0x0000001b, 0xfc00ffff, RD_s|RD_t|WR_HILO,      I1      },
-{"divu",    "z,t",      0x0000001b, 0xffe0ffff, RD_s|RD_t|WR_HILO,      I1      },
-{"divu",    "d,v,t",	0,    (int) M_DIVU_3,	INSN_MACRO,		I1	},
-{"divu",    "d,v,I",	0,    (int) M_DIVU_3I,	INSN_MACRO,		I1	},
-{"dla",     "t,A(b)",	0,    (int) M_DLA_AB,	INSN_MACRO,		I3	},
-{"dlca",    "t,A(b)",	0,    (int) M_DLCA_AB,	INSN_MACRO,		I3	},
-{"dli",     "t,j",      0x24000000, 0xffe00000, WR_t,			I3	}, /* addiu */
-{"dli",	    "t,i",	0x34000000, 0xffe00000, WR_t,			I3	}, /* ori */
-{"dli",     "t,I",	0,    (int) M_DLI,	INSN_MACRO,		I3	},
-{"dmacc",   "d,s,t",	0x00000029, 0xfc0007ff,	RD_s|RD_t|WR_LO|WR_d,	N412	},
-{"dmacchi", "d,s,t",	0x00000229, 0xfc0007ff, RD_s|RD_t|WR_LO|WR_d,	N412	},
-{"dmacchis", "d,s,t",	0x00000629, 0xfc0007ff, RD_s|RD_t|WR_LO|WR_d,	N412	},
-{"dmacchiu", "d,s,t",	0x00000269, 0xfc0007ff, RD_s|RD_t|WR_LO|WR_d,	N412	},
-{"dmacchius", "d,s,t",	0x00000669, 0xfc0007ff, RD_s|RD_t|WR_LO|WR_d,	N412	},
-{"dmaccs",  "d,s,t",	0x00000429, 0xfc0007ff,	RD_s|RD_t|WR_LO|WR_d,	N412	},
-{"dmaccu",  "d,s,t",	0x00000069, 0xfc0007ff,	RD_s|RD_t|WR_LO|WR_d,	N412	},
-{"dmaccus", "d,s,t",	0x00000469, 0xfc0007ff,	RD_s|RD_t|WR_LO|WR_d,	N412	},
-{"dmadd16", "s,t",      0x00000029, 0xfc00ffff, RD_s|RD_t|MOD_LO,       N411    },
-{"dmfc0",   "t,G",	0x40200000, 0xffe007ff, LCD|WR_t|RD_C0,		I3	},
-{"dmfc0",   "t,+D",     0x40200000, 0xffe007f8, LCD|WR_t|RD_C0, 	I64     },
-{"dmfc0",   "t,G,H",    0x40200000, 0xffe007f8, LCD|WR_t|RD_C0, 	I64     },
-{"dmtc0",   "t,G",	0x40a00000, 0xffe007ff, COD|RD_t|WR_C0|WR_CC,	I3	},
-{"dmtc0",   "t,+D",     0x40a00000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC,   I64     },
-{"dmtc0",   "t,G,H",    0x40a00000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC,   I64     },
-{"dmfc1",   "t,S",	0x44200000, 0xffe007ff, LCD|WR_t|RD_S|FP_S,	I3	},
-{"dmfc1",   "t,G",      0x44200000, 0xffe007ff, LCD|WR_t|RD_S|FP_S,     I3      },
-{"dmtc1",   "t,S",	0x44a00000, 0xffe007ff, COD|RD_t|WR_S|FP_S,	I3	},
-{"dmtc1",   "t,G",      0x44a00000, 0xffe007ff, COD|RD_t|WR_S|FP_S,     I3      },
+{"divu",    "z,s,t",    0x0000001b, 0xfc00ffff, RD_s|RD_t|WR_HILO,      0,		I1      },
+{"divu",    "z,t",      0x0000001b, 0xffe0ffff, RD_s|RD_t|WR_HILO,      0,		I1      },
+{"divu",    "d,v,t",	0,    (int) M_DIVU_3,	INSN_MACRO,		0,		I1	},
+{"divu",    "d,v,I",	0,    (int) M_DIVU_3I,	INSN_MACRO,		0,		I1	},
+{"dla",     "t,A(b)",	0,    (int) M_DLA_AB,	INSN_MACRO,		0,		I3	},
+{"dlca",    "t,A(b)",	0,    (int) M_DLCA_AB,	INSN_MACRO,		0,		I3	},
+{"dli",     "t,j",      0x24000000, 0xffe00000, WR_t,			0,		I3	}, /* addiu */
+{"dli",	    "t,i",	0x34000000, 0xffe00000, WR_t,			0,		I3	}, /* ori */
+{"dli",     "t,I",	0,    (int) M_DLI,	INSN_MACRO,		0,		I3	},
+{"dmacc",   "d,s,t",	0x00000029, 0xfc0007ff,	RD_s|RD_t|WR_LO|WR_d,	0,		N412	},
+{"dmacchi", "d,s,t",	0x00000229, 0xfc0007ff, RD_s|RD_t|WR_LO|WR_d,	0,		N412	},
+{"dmacchis", "d,s,t",	0x00000629, 0xfc0007ff, RD_s|RD_t|WR_LO|WR_d,	0,		N412	},
+{"dmacchiu", "d,s,t",	0x00000269, 0xfc0007ff, RD_s|RD_t|WR_LO|WR_d,	0,		N412	},
+{"dmacchius", "d,s,t",	0x00000669, 0xfc0007ff, RD_s|RD_t|WR_LO|WR_d,	0,		N412	},
+{"dmaccs",  "d,s,t",	0x00000429, 0xfc0007ff,	RD_s|RD_t|WR_LO|WR_d,	0,		N412	},
+{"dmaccu",  "d,s,t",	0x00000069, 0xfc0007ff,	RD_s|RD_t|WR_LO|WR_d,	0,		N412	},
+{"dmaccus", "d,s,t",	0x00000469, 0xfc0007ff,	RD_s|RD_t|WR_LO|WR_d,	0,		N412	},
+{"dmadd16", "s,t",      0x00000029, 0xfc00ffff, RD_s|RD_t|MOD_LO,       0,		N411    },
+{"dmfc0",   "t,G",	0x40200000, 0xffe007ff, LCD|WR_t|RD_C0,		0,		I3	},
+{"dmfc0",   "t,+D",     0x40200000, 0xffe007f8, LCD|WR_t|RD_C0, 	0,		I64     },
+{"dmfc0",   "t,G,H",    0x40200000, 0xffe007f8, LCD|WR_t|RD_C0, 	0,		I64     },
+{"dmt",     "",		0x41600bc1, 0xffffffff, TRAP,			0,		MT32	},
+{"dmt",     "t",	0x41600bc1, 0xffe0ffff, TRAP|WR_t,		0,		MT32	},
+{"dmtc0",   "t,G",	0x40a00000, 0xffe007ff, COD|RD_t|WR_C0|WR_CC,	0,		I3	},
+{"dmtc0",   "t,+D",     0x40a00000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC,   0,		I64     },
+{"dmtc0",   "t,G,H",    0x40a00000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC,   0,		I64     },
+{"dmfc1",   "t,S",	0x44200000, 0xffe007ff, LCD|WR_t|RD_S|FP_D,	0,		I3	},
+{"dmfc1",   "t,G",      0x44200000, 0xffe007ff, LCD|WR_t|RD_S|FP_D,     0,		I3      },
+{"dmtc1",   "t,S",	0x44a00000, 0xffe007ff, COD|RD_t|WR_S|FP_D,	0,		I3	},
+{"dmtc1",   "t,G",      0x44a00000, 0xffe007ff, COD|RD_t|WR_S|FP_D,     0,		I3      },
 /* dmfc2 is at the bottom of the table.  */
 /* dmtc2 is at the bottom of the table.  */
-{"dmfc3",   "t,G",      0x4c200000, 0xffe007ff, LCD|WR_t|RD_C3, 	I3      },
-{"dmfc3",   "t,G,H",    0x4c200000, 0xffe007f8, LCD|WR_t|RD_C3, 	I64     },
-{"dmtc3",   "t,G",      0x4ca00000, 0xffe007ff, COD|RD_t|WR_C3|WR_CC,   I3      },
-{"dmtc3",   "t,G,H",    0x4ca00000, 0xffe007f8, COD|RD_t|WR_C3|WR_CC,   I64     },
-{"dmul",    "d,v,t",	0,    (int) M_DMUL,	INSN_MACRO,		I3	},
-{"dmul",    "d,v,I",	0,    (int) M_DMUL_I,	INSN_MACRO,		I3	},
-{"dmulo",   "d,v,t",	0,    (int) M_DMULO,	INSN_MACRO,		I3	},
-{"dmulo",   "d,v,I",	0,    (int) M_DMULO_I,	INSN_MACRO,		I3	},
-{"dmulou",  "d,v,t",	0,    (int) M_DMULOU,	INSN_MACRO,		I3	},
-{"dmulou",  "d,v,I",	0,    (int) M_DMULOU_I,	INSN_MACRO,		I3	},
-{"dmult",   "s,t",      0x0000001c, 0xfc00ffff, RD_s|RD_t|WR_HILO,      I3	},
-{"dmultu",  "s,t",      0x0000001d, 0xfc00ffff, RD_s|RD_t|WR_HILO,      I3	},
-{"dneg",    "d,w",	0x0000002e, 0xffe007ff,	WR_d|RD_t,		I3	}, /* dsub 0 */
-{"dnegu",   "d,w",	0x0000002f, 0xffe007ff,	WR_d|RD_t,		I3	}, /* dsubu 0*/
-{"drem",    "z,s,t",    0x0000001e, 0xfc00ffff, RD_s|RD_t|WR_HILO,      I3      },
-{"drem",    "d,v,t",	3,    (int) M_DREM_3,	INSN_MACRO,		I3	},
-{"drem",    "d,v,I",	3,    (int) M_DREM_3I,	INSN_MACRO,		I3	},
-{"dremu",   "z,s,t",    0x0000001f, 0xfc00ffff, RD_s|RD_t|WR_HILO,      I3      },
-{"dremu",   "d,v,t",	3,    (int) M_DREMU_3,	INSN_MACRO,		I3	},
-{"dremu",   "d,v,I",	3,    (int) M_DREMU_3I,	INSN_MACRO,		I3	},
-{"dret",    "",		0x7000003e, 0xffffffff,	0,			N5	},
-{"drol",    "d,v,t",	0,    (int) M_DROL,	INSN_MACRO,		I3	},
-{"drol",    "d,v,I",	0,    (int) M_DROL_I,	INSN_MACRO,		I3	},
-{"dror",    "d,v,t",	0,    (int) M_DROR,	INSN_MACRO,		I3	},
-{"dror",    "d,v,I",	0,    (int) M_DROR_I,	INSN_MACRO,		I3	},
-{"dror",    "d,w,<",	0x0020003a, 0xffe0003f,	WR_d|RD_t,		N5|I65	},
-{"drorv",   "d,t,s",	0x00000056, 0xfc0007ff,	RD_t|RD_s|WR_d,		N5|I65	},
-{"dror32",  "d,w,<",	0x0020003e, 0xffe0003f,	WR_d|RD_t,		N5|I65	},
-{"drotl",   "d,v,t",	0,    (int) M_DROL,	INSN_MACRO,		I65	},
-{"drotl",   "d,v,I",	0,    (int) M_DROL_I,	INSN_MACRO,		I65	},
-{"drotr",   "d,v,t",	0,    (int) M_DROR,	INSN_MACRO,		I65	},
-{"drotr",   "d,v,I",	0,    (int) M_DROR_I,	INSN_MACRO,		I65	},
-{"drotrv",  "d,t,s",	0x00000056, 0xfc0007ff,	RD_t|RD_s|WR_d,		I65	},
-{"drotr32", "d,w,<",	0x0020003e, 0xffe0003f,	WR_d|RD_t,		I65	},
-{"dsbh",    "d,w",	0x7c0000a4, 0xffe007ff,	WR_d|RD_t,		I65	},
-{"dshd",    "d,w",	0x7c000164, 0xffe007ff,	WR_d|RD_t,		I65	},
-{"dsllv",   "d,t,s",	0x00000014, 0xfc0007ff,	WR_d|RD_t|RD_s,		I3	},
-{"dsll32",  "d,w,<",	0x0000003c, 0xffe0003f, WR_d|RD_t,		I3	},
-{"dsll",    "d,w,s",	0x00000014, 0xfc0007ff,	WR_d|RD_t|RD_s,		I3	}, /* dsllv */
-{"dsll",    "d,w,>",	0x0000003c, 0xffe0003f, WR_d|RD_t,		I3	}, /* dsll32 */
-{"dsll",    "d,w,<",	0x00000038, 0xffe0003f,	WR_d|RD_t,		I3	},
-{"dsrav",   "d,t,s",	0x00000017, 0xfc0007ff,	WR_d|RD_t|RD_s,		I3	},
-{"dsra32",  "d,w,<",	0x0000003f, 0xffe0003f, WR_d|RD_t,		I3	},
-{"dsra",    "d,w,s",	0x00000017, 0xfc0007ff,	WR_d|RD_t|RD_s,		I3	}, /* dsrav */
-{"dsra",    "d,w,>",	0x0000003f, 0xffe0003f, WR_d|RD_t,		I3	}, /* dsra32 */
-{"dsra",    "d,w,<",	0x0000003b, 0xffe0003f,	WR_d|RD_t,		I3	},
-{"dsrlv",   "d,t,s",	0x00000016, 0xfc0007ff,	WR_d|RD_t|RD_s,		I3	},
-{"dsrl32",  "d,w,<",	0x0000003e, 0xffe0003f, WR_d|RD_t,		I3	},
-{"dsrl",    "d,w,s",	0x00000016, 0xfc0007ff,	WR_d|RD_t|RD_s,		I3	}, /* dsrlv */
-{"dsrl",    "d,w,>",	0x0000003e, 0xffe0003f, WR_d|RD_t,		I3	}, /* dsrl32 */
-{"dsrl",    "d,w,<",	0x0000003a, 0xffe0003f,	WR_d|RD_t,		I3	},
-{"dsub",    "d,v,t",	0x0000002e, 0xfc0007ff,	WR_d|RD_s|RD_t,		I3	},
-{"dsub",    "d,v,I",	0,    (int) M_DSUB_I,	INSN_MACRO,		I3	},
-{"dsubu",   "d,v,t",	0x0000002f, 0xfc0007ff,	WR_d|RD_s|RD_t,		I3	},
-{"dsubu",   "d,v,I",	0,    (int) M_DSUBU_I,	INSN_MACRO,		I3	},
-{"ei",      "",		0x41606020, 0xffffffff,	WR_t|WR_C0,		I33	},
-{"ei",      "t",	0x41606020, 0xffe0ffff,	WR_t|WR_C0,		I33	},
-{"eret",    "",         0x42000018, 0xffffffff, 0,      		I3|I32	},
-{"ext",     "t,r,+A,+C", 0x7c000000, 0xfc00003f, WR_t|RD_s,    		I33	},
-{"floor.l.d", "D,S",	0x4620000b, 0xffff003f, WR_D|RD_S|FP_D,		I3	},
-{"floor.l.s", "D,S",	0x4600000b, 0xffff003f, WR_D|RD_S|FP_S,		I3	},
-{"floor.w.d", "D,S",	0x4620000f, 0xffff003f, WR_D|RD_S|FP_D,		I2	},
-{"floor.w.s", "D,S",	0x4600000f, 0xffff003f, WR_D|RD_S|FP_S,		I2	},
-{"flushi",  "",		0xbc010000, 0xffffffff, 0,			L1	},
-{"flushd",  "",		0xbc020000, 0xffffffff, 0, 			L1	},
-{"flushid", "",		0xbc030000, 0xffffffff, 0, 			L1	},
-{"hibernate","",        0x42000023, 0xffffffff,	0, 			V1	},
-{"ins",     "t,r,+A,+B", 0x7c000004, 0xfc00003f, WR_t|RD_s,    		I33	},
-{"jr",      "s",	0x00000008, 0xfc1fffff,	UBD|RD_s,		I1	},
-{"jr.hb",   "s",	0x00000408, 0xfc1fffff,	UBD|RD_s,		I33	},
-{"j",       "s",	0x00000008, 0xfc1fffff,	UBD|RD_s,		I1	}, /* jr */
+/* dmfc3 is at the bottom of the table.  */
+/* dmtc3 is at the bottom of the table.  */
+{"dmul",    "d,v,t",	0,    (int) M_DMUL,	INSN_MACRO,		0,		I3	},
+{"dmul",    "d,v,I",	0,    (int) M_DMUL_I,	INSN_MACRO,		0,		I3	},
+{"dmulo",   "d,v,t",	0,    (int) M_DMULO,	INSN_MACRO,		0,		I3	},
+{"dmulo",   "d,v,I",	0,    (int) M_DMULO_I,	INSN_MACRO,		0,		I3	},
+{"dmulou",  "d,v,t",	0,    (int) M_DMULOU,	INSN_MACRO,		0,		I3	},
+{"dmulou",  "d,v,I",	0,    (int) M_DMULOU_I,	INSN_MACRO,		0,		I3	},
+{"dmult",   "s,t",      0x0000001c, 0xfc00ffff, RD_s|RD_t|WR_HILO,      0,		I3	},
+{"dmultu",  "s,t",      0x0000001d, 0xfc00ffff, RD_s|RD_t|WR_HILO,      0,		I3	},
+{"dneg",    "d,w",	0x0000002e, 0xffe007ff,	WR_d|RD_t,		0,		I3	}, /* dsub 0 */
+{"dnegu",   "d,w",	0x0000002f, 0xffe007ff,	WR_d|RD_t,		0,		I3	}, /* dsubu 0*/
+{"drem",    "z,s,t",    0x0000001e, 0xfc00ffff, RD_s|RD_t|WR_HILO,      0,		I3      },
+{"drem",    "d,v,t",	3,    (int) M_DREM_3,	INSN_MACRO,		0,		I3	},
+{"drem",    "d,v,I",	3,    (int) M_DREM_3I,	INSN_MACRO,		0,		I3	},
+{"dremu",   "z,s,t",    0x0000001f, 0xfc00ffff, RD_s|RD_t|WR_HILO,      0,		I3      },
+{"dremu",   "d,v,t",	3,    (int) M_DREMU_3,	INSN_MACRO,		0,		I3	},
+{"dremu",   "d,v,I",	3,    (int) M_DREMU_3I,	INSN_MACRO,		0,		I3	},
+{"dret",    "",		0x7000003e, 0xffffffff,	0,			0,		N5	},
+{"drol",    "d,v,t",	0,    (int) M_DROL,	INSN_MACRO,		0,		I3	},
+{"drol",    "d,v,I",	0,    (int) M_DROL_I,	INSN_MACRO,		0,		I3	},
+{"dror",    "d,v,t",	0,    (int) M_DROR,	INSN_MACRO,		0,		I3	},
+{"dror",    "d,v,I",	0,    (int) M_DROR_I,	INSN_MACRO,		0,		I3	},
+{"dror",    "d,w,<",	0x0020003a, 0xffe0003f,	WR_d|RD_t,		0,		N5|I65	},
+{"drorv",   "d,t,s",	0x00000056, 0xfc0007ff,	RD_t|RD_s|WR_d,		0,		N5|I65	},
+{"dror32",  "d,w,<",	0x0020003e, 0xffe0003f,	WR_d|RD_t,		0,		N5|I65	},
+{"drotl",   "d,v,t",	0,    (int) M_DROL,	INSN_MACRO,		0,		I65	},
+{"drotl",   "d,v,I",	0,    (int) M_DROL_I,	INSN_MACRO,		0,		I65	},
+{"drotr",   "d,v,t",	0,    (int) M_DROR,	INSN_MACRO,		0,		I65	},
+{"drotr",   "d,v,I",	0,    (int) M_DROR_I,	INSN_MACRO,		0,		I65	},
+{"drotrv",  "d,t,s",	0x00000056, 0xfc0007ff,	RD_t|RD_s|WR_d,		0,		I65	},
+{"drotr32", "d,w,<",	0x0020003e, 0xffe0003f,	WR_d|RD_t,		0,		I65	},
+{"dsbh",    "d,w",	0x7c0000a4, 0xffe007ff,	WR_d|RD_t,		0,		I65	},
+{"dshd",    "d,w",	0x7c000164, 0xffe007ff,	WR_d|RD_t,		0,		I65	},
+{"dsllv",   "d,t,s",	0x00000014, 0xfc0007ff,	WR_d|RD_t|RD_s,		0,		I3	},
+{"dsll32",  "d,w,<",	0x0000003c, 0xffe0003f, WR_d|RD_t,		0,		I3	},
+{"dsll",    "d,w,s",	0x00000014, 0xfc0007ff,	WR_d|RD_t|RD_s,		0,		I3	}, /* dsllv */
+{"dsll",    "d,w,>",	0x0000003c, 0xffe0003f, WR_d|RD_t,		0,		I3	}, /* dsll32 */
+{"dsll",    "d,w,<",	0x00000038, 0xffe0003f,	WR_d|RD_t,		0,		I3	},
+{"dsrav",   "d,t,s",	0x00000017, 0xfc0007ff,	WR_d|RD_t|RD_s,		0,		I3	},
+{"dsra32",  "d,w,<",	0x0000003f, 0xffe0003f, WR_d|RD_t,		0,		I3	},
+{"dsra",    "d,w,s",	0x00000017, 0xfc0007ff,	WR_d|RD_t|RD_s,		0,		I3	}, /* dsrav */
+{"dsra",    "d,w,>",	0x0000003f, 0xffe0003f, WR_d|RD_t,		0,		I3	}, /* dsra32 */
+{"dsra",    "d,w,<",	0x0000003b, 0xffe0003f,	WR_d|RD_t,		0,		I3	},
+{"dsrlv",   "d,t,s",	0x00000016, 0xfc0007ff,	WR_d|RD_t|RD_s,		0,		I3	},
+{"dsrl32",  "d,w,<",	0x0000003e, 0xffe0003f, WR_d|RD_t,		0,		I3	},
+{"dsrl",    "d,w,s",	0x00000016, 0xfc0007ff,	WR_d|RD_t|RD_s,		0,		I3	}, /* dsrlv */
+{"dsrl",    "d,w,>",	0x0000003e, 0xffe0003f, WR_d|RD_t,		0,		I3	}, /* dsrl32 */
+{"dsrl",    "d,w,<",	0x0000003a, 0xffe0003f,	WR_d|RD_t,		0,		I3	},
+{"dsub",    "d,v,t",	0x0000002e, 0xfc0007ff,	WR_d|RD_s|RD_t,		0,		I3	},
+{"dsub",    "d,v,I",	0,    (int) M_DSUB_I,	INSN_MACRO,		0,		I3	},
+{"dsubu",   "d,v,t",	0x0000002f, 0xfc0007ff,	WR_d|RD_s|RD_t,		0,		I3	},
+{"dsubu",   "d,v,I",	0,    (int) M_DSUBU_I,	INSN_MACRO,		0,		I3	},
+{"dvpe",    "",		0x41600001, 0xffffffff, TRAP,			0,		MT32	},
+{"dvpe",    "t",	0x41600001, 0xffe0ffff, TRAP|WR_t,		0,		MT32	},
+{"ei",      "",		0x41606020, 0xffffffff,	WR_t|WR_C0,		0,		I33	},
+{"ei",      "t",	0x41606020, 0xffe0ffff,	WR_t|WR_C0,		0,		I33	},
+{"emt",     "",		0x41600be1, 0xffffffff, TRAP,			0,		MT32	},
+{"emt",     "t",	0x41600be1, 0xffe0ffff, TRAP|WR_t,		0,		MT32	},
+{"eret",    "",         0x42000018, 0xffffffff, 0,      		0,		I3|I32	},
+{"evpe",    "",		0x41600021, 0xffffffff, TRAP,			0,		MT32	},
+{"evpe",    "t",	0x41600021, 0xffe0ffff, TRAP|WR_t,		0,		MT32	},
+{"ext",     "t,r,+A,+C", 0x7c000000, 0xfc00003f, WR_t|RD_s,    		0,		I33	},
+{"floor.l.d", "D,S",	0x4620000b, 0xffff003f, WR_D|RD_S|FP_D,		0,		I3|I33	},
+{"floor.l.s", "D,S",	0x4600000b, 0xffff003f, WR_D|RD_S|FP_S|FP_D,	0,		I3|I33	},
+{"floor.w.d", "D,S",	0x4620000f, 0xffff003f, WR_D|RD_S|FP_S|FP_D,	0,		I2	},
+{"floor.w.s", "D,S",	0x4600000f, 0xffff003f, WR_D|RD_S|FP_S,		0,		I2	},
+{"hibernate","",        0x42000023, 0xffffffff,	0, 			0,		V1	},
+{"ins",     "t,r,+A,+B", 0x7c000004, 0xfc00003f, WR_t|RD_s,    		0,		I33	},
+{"jr",      "s",	0x00000008, 0xfc1fffff,	UBD|RD_s,		0,		I1	},
+/* jr.hb is officially MIPS{32,64}R2, but it works on R1 as jr with
+   the same hazard barrier effect.  */
+{"jr.hb",   "s",	0x00000408, 0xfc1fffff,	UBD|RD_s,		0,		I32	},
+{"j",       "s",	0x00000008, 0xfc1fffff,	UBD|RD_s,		0,		I1	}, /* jr */
 /* SVR4 PIC code requires special handling for j, so it must be a
    macro.  */
-{"j",	    "a",	0,     (int) M_J_A,	INSN_MACRO,		I1	},
+{"j",	    "a",	0,     (int) M_J_A,	INSN_MACRO,		0,		I1	},
 /* This form of j is used by the disassembler and internally by the
    assembler, but will never match user input (because the line above
    will match first).  */
-{"j",       "a",	0x08000000, 0xfc000000,	UBD,			I1	},
-{"jalr",    "s",	0x0000f809, 0xfc1fffff,	UBD|RD_s|WR_d,		I1	},
-{"jalr",    "d,s",	0x00000009, 0xfc1f07ff,	UBD|RD_s|WR_d,		I1	},
-{"jalr.hb", "s",	0x0000fc09, 0xfc1fffff,	UBD|RD_s|WR_d,		I33	},
-{"jalr.hb", "d,s",	0x00000409, 0xfc1f07ff,	UBD|RD_s|WR_d,		I33	},
+{"j",       "a",	0x08000000, 0xfc000000,	UBD,			0,		I1	},
+{"jalr",    "s",	0x0000f809, 0xfc1fffff,	UBD|RD_s|WR_d,		0,		I1	},
+{"jalr",    "d,s",	0x00000009, 0xfc1f07ff,	UBD|RD_s|WR_d,		0,		I1	},
+/* jalr.hb is officially MIPS{32,64}R2, but it works on R1 as jalr
+   with the same hazard barrier effect.  */
+{"jalr.hb", "s",	0x0000fc09, 0xfc1fffff,	UBD|RD_s|WR_d,		0,		I32	},
+{"jalr.hb", "d,s",	0x00000409, 0xfc1f07ff,	UBD|RD_s|WR_d,		0,		I32	},
 /* SVR4 PIC code requires special handling for jal, so it must be a
    macro.  */
-{"jal",     "d,s",	0,     (int) M_JAL_2,	INSN_MACRO,		I1	},
-{"jal",     "s",	0,     (int) M_JAL_1,	INSN_MACRO,		I1	},
-{"jal",     "a",	0,     (int) M_JAL_A,	INSN_MACRO,		I1	},
+{"jal",     "d,s",	0,     (int) M_JAL_2,	INSN_MACRO,		0,		I1	},
+{"jal",     "s",	0,     (int) M_JAL_1,	INSN_MACRO,		0,		I1	},
+{"jal",     "a",	0,     (int) M_JAL_A,	INSN_MACRO,		0,		I1	},
 /* This form of jal is used by the disassembler and internally by the
    assembler, but will never match user input (because the line above
    will match first).  */
-{"jal",     "a",	0x0c000000, 0xfc000000,	UBD|WR_31,		I1	},
-{"jalx",    "a",	0x74000000, 0xfc000000, UBD|WR_31,		I16     },
-{"la",      "t,A(b)",	0,    (int) M_LA_AB,	INSN_MACRO,		I1	},
-{"lb",      "t,o(b)",	0x80000000, 0xfc000000,	LDD|RD_b|WR_t,		I1	},
-{"lb",      "t,A(b)",	0,    (int) M_LB_AB,	INSN_MACRO,		I1	},
-{"lbu",     "t,o(b)",	0x90000000, 0xfc000000,	LDD|RD_b|WR_t,		I1	},
-{"lbu",     "t,A(b)",	0,    (int) M_LBU_AB,	INSN_MACRO,		I1	},
-{"lca",     "t,A(b)",	0,    (int) M_LCA_AB,	INSN_MACRO,		I1	},
-{"ld",	    "t,o(b)",   0xdc000000, 0xfc000000, WR_t|RD_b,		I3	},
-{"ld",      "t,o(b)",	0,    (int) M_LD_OB,	INSN_MACRO,		I1	},
-{"ld",      "t,A(b)",	0,    (int) M_LD_AB,	INSN_MACRO,		I1	},
-{"ldc1",    "T,o(b)",	0xd4000000, 0xfc000000, CLD|RD_b|WR_T|FP_D,	I2	},
-{"ldc1",    "E,o(b)",	0xd4000000, 0xfc000000, CLD|RD_b|WR_T|FP_D,	I2	},
-{"ldc1",    "T,A(b)",	0,    (int) M_LDC1_AB,	INSN_MACRO,		I2	},
-{"ldc1",    "E,A(b)",	0,    (int) M_LDC1_AB,	INSN_MACRO,		I2	},
-{"l.d",     "T,o(b)",	0xd4000000, 0xfc000000, CLD|RD_b|WR_T|FP_D,	I2	}, /* ldc1 */
-{"l.d",     "T,o(b)",	0,    (int) M_L_DOB,	INSN_MACRO,		I1	},
-{"l.d",     "T,A(b)",	0,    (int) M_L_DAB,	INSN_MACRO,		I1	},
-{"ldc2",    "E,o(b)",	0xd8000000, 0xfc000000, CLD|RD_b|WR_CC,		I2	},
-{"ldc2",    "E,A(b)",	0,    (int) M_LDC2_AB,	INSN_MACRO,		I2	},
-{"ldc3",    "E,o(b)",	0xdc000000, 0xfc000000, CLD|RD_b|WR_CC,		I2	},
-{"ldc3",    "E,A(b)",	0,    (int) M_LDC3_AB,	INSN_MACRO,		I2	},
-{"ldl",	    "t,o(b)",	0x68000000, 0xfc000000, LDD|WR_t|RD_b,		I3	},
-{"ldl",	    "t,A(b)",	0,    (int) M_LDL_AB,	INSN_MACRO,		I3	},
-{"ldr",	    "t,o(b)",	0x6c000000, 0xfc000000, LDD|WR_t|RD_b,		I3	},
-{"ldr",     "t,A(b)",	0,    (int) M_LDR_AB,	INSN_MACRO,		I3	},
-{"ldxc1",   "D,t(b)",	0x4c000001, 0xfc00f83f, LDD|WR_D|RD_t|RD_b,	I4	},
-{"lh",      "t,o(b)",	0x84000000, 0xfc000000,	LDD|RD_b|WR_t,		I1	},
-{"lh",      "t,A(b)",	0,    (int) M_LH_AB,	INSN_MACRO,		I1	},
-{"lhu",     "t,o(b)",	0x94000000, 0xfc000000,	LDD|RD_b|WR_t,		I1	},
-{"lhu",     "t,A(b)",	0,    (int) M_LHU_AB,	INSN_MACRO,		I1	},
+{"jal",     "a",	0x0c000000, 0xfc000000,	UBD|WR_31,		0,		I1	},
+{"jalx",    "a",	0x74000000, 0xfc000000, UBD|WR_31,		0,		I16     },
+{"la",      "t,A(b)",	0,    (int) M_LA_AB,	INSN_MACRO,		0,		I1	},
+{"lb",      "t,o(b)",	0x80000000, 0xfc000000,	LDD|RD_b|WR_t,		0,		I1	},
+{"lb",      "t,A(b)",	0,    (int) M_LB_AB,	INSN_MACRO,		0,		I1	},
+{"lbu",     "t,o(b)",	0x90000000, 0xfc000000,	LDD|RD_b|WR_t,		0,		I1	},
+{"lbu",     "t,A(b)",	0,    (int) M_LBU_AB,	INSN_MACRO,		0,		I1	},
+{"lca",     "t,A(b)",	0,    (int) M_LCA_AB,	INSN_MACRO,		0,		I1	},
+{"ld",	    "t,o(b)",   0xdc000000, 0xfc000000, WR_t|RD_b,		0,		I3	},
+{"ld",      "t,o(b)",	0,    (int) M_LD_OB,	INSN_MACRO,		0,		I1	},
+{"ld",      "t,A(b)",	0,    (int) M_LD_AB,	INSN_MACRO,		0,		I1	},
+{"ldc1",    "T,o(b)",	0xd4000000, 0xfc000000, CLD|RD_b|WR_T|FP_D,	0,		I2	},
+{"ldc1",    "E,o(b)",	0xd4000000, 0xfc000000, CLD|RD_b|WR_T|FP_D,	0,		I2	},
+{"ldc1",    "T,A(b)",	0,    (int) M_LDC1_AB,	INSN_MACRO,		0,		I2	},
+{"ldc1",    "E,A(b)",	0,    (int) M_LDC1_AB,	INSN_MACRO,		0,		I2	},
+{"l.d",     "T,o(b)",	0xd4000000, 0xfc000000, CLD|RD_b|WR_T|FP_D,	0,		I2	}, /* ldc1 */
+{"l.d",     "T,o(b)",	0,    (int) M_L_DOB,	INSN_MACRO,		0,		I1	},
+{"l.d",     "T,A(b)",	0,    (int) M_L_DAB,	INSN_MACRO,		0,		I1	},
+{"ldc2",    "E,o(b)",	0xd8000000, 0xfc000000, CLD|RD_b|WR_CC,		0,		I2	},
+{"ldc2",    "E,A(b)",	0,    (int) M_LDC2_AB,	INSN_MACRO,		0,		I2	},
+{"ldc3",    "E,o(b)",	0xdc000000, 0xfc000000, CLD|RD_b|WR_CC,		0,		I2	},
+{"ldc3",    "E,A(b)",	0,    (int) M_LDC3_AB,	INSN_MACRO,		0,		I2	},
+{"ldl",	    "t,o(b)",	0x68000000, 0xfc000000, LDD|WR_t|RD_b,		0,		I3	},
+{"ldl",	    "t,A(b)",	0,    (int) M_LDL_AB,	INSN_MACRO,		0,		I3	},
+{"ldr",	    "t,o(b)",	0x6c000000, 0xfc000000, LDD|WR_t|RD_b,		0,		I3	},
+{"ldr",     "t,A(b)",	0,    (int) M_LDR_AB,	INSN_MACRO,		0,		I3	},
+{"ldxc1",   "D,t(b)",	0x4c000001, 0xfc00f83f, LDD|WR_D|RD_t|RD_b|FP_D, 0,		I4|I33	},
+{"lh",      "t,o(b)",	0x84000000, 0xfc000000,	LDD|RD_b|WR_t,		0,		I1	},
+{"lh",      "t,A(b)",	0,    (int) M_LH_AB,	INSN_MACRO,		0,		I1	},
+{"lhu",     "t,o(b)",	0x94000000, 0xfc000000,	LDD|RD_b|WR_t,		0,		I1	},
+{"lhu",     "t,A(b)",	0,    (int) M_LHU_AB,	INSN_MACRO,		0,		I1	},
 /* li is at the start of the table.  */
-{"li.d",    "t,F",	0,    (int) M_LI_D,	INSN_MACRO,		I1	},
-{"li.d",    "T,L",	0,    (int) M_LI_DD,	INSN_MACRO,		I1	},
-{"li.s",    "t,f",	0,    (int) M_LI_S,	INSN_MACRO,		I1	},
-{"li.s",    "T,l",	0,    (int) M_LI_SS,	INSN_MACRO,		I1	},
-{"ll",	    "t,o(b)",	0xc0000000, 0xfc000000, LDD|RD_b|WR_t,		I2	},
-{"ll",	    "t,A(b)",	0,    (int) M_LL_AB,	INSN_MACRO,		I2	},
-{"lld",	    "t,o(b)",	0xd0000000, 0xfc000000, LDD|RD_b|WR_t,		I3	},
-{"lld",     "t,A(b)",	0,    (int) M_LLD_AB,	INSN_MACRO,		I3	},
-{"lui",     "t,u",	0x3c000000, 0xffe00000,	WR_t,			I1	},
-{"luxc1",   "D,t(b)",	0x4c000005, 0xfc00f83f, LDD|WR_D|RD_t|RD_b,	I5|N55	},
-{"lw",      "t,o(b)",	0x8c000000, 0xfc000000,	LDD|RD_b|WR_t,		I1	},
-{"lw",      "t,A(b)",	0,    (int) M_LW_AB,	INSN_MACRO,		I1	},
-{"lwc0",    "E,o(b)",	0xc0000000, 0xfc000000,	CLD|RD_b|WR_CC,		I1	},
-{"lwc0",    "E,A(b)",	0,    (int) M_LWC0_AB,	INSN_MACRO,		I1	},
-{"lwc1",    "T,o(b)",	0xc4000000, 0xfc000000,	CLD|RD_b|WR_T|FP_S,	I1	},
-{"lwc1",    "E,o(b)",	0xc4000000, 0xfc000000,	CLD|RD_b|WR_T|FP_S,	I1	},
-{"lwc1",    "T,A(b)",	0,    (int) M_LWC1_AB,	INSN_MACRO,		I1	},
-{"lwc1",    "E,A(b)",	0,    (int) M_LWC1_AB,	INSN_MACRO,		I1	},
-{"l.s",     "T,o(b)",	0xc4000000, 0xfc000000,	CLD|RD_b|WR_T|FP_S,	I1	}, /* lwc1 */
-{"l.s",     "T,A(b)",	0,    (int) M_LWC1_AB,	INSN_MACRO,		I1	},
-{"lwc2",    "E,o(b)",	0xc8000000, 0xfc000000,	CLD|RD_b|WR_CC,		I1	},
-{"lwc2",    "E,A(b)",	0,    (int) M_LWC2_AB,	INSN_MACRO,		I1	},
-{"lwc3",    "E,o(b)",	0xcc000000, 0xfc000000,	CLD|RD_b|WR_CC,		I1	},
-{"lwc3",    "E,A(b)",	0,    (int) M_LWC3_AB,	INSN_MACRO,		I1	},
-{"lwl",     "t,o(b)",	0x88000000, 0xfc000000,	LDD|RD_b|WR_t,		I1	},
-{"lwl",     "t,A(b)",	0,    (int) M_LWL_AB,	INSN_MACRO,		I1	},
-{"lcache",  "t,o(b)",	0x88000000, 0xfc000000,	LDD|RD_b|WR_t,		I2	}, /* same */
-{"lcache",  "t,A(b)",	0,    (int) M_LWL_AB,	INSN_MACRO,		I2	}, /* as lwl */
-{"lwr",     "t,o(b)",	0x98000000, 0xfc000000,	LDD|RD_b|WR_t,		I1	},
-{"lwr",     "t,A(b)",	0,    (int) M_LWR_AB,	INSN_MACRO,		I1	},
-{"flush",   "t,o(b)",	0x98000000, 0xfc000000,	LDD|RD_b|WR_t,		I2	}, /* same */
-{"flush",   "t,A(b)",	0,    (int) M_LWR_AB,	INSN_MACRO,		I2	}, /* as lwr */
-{"lwu",     "t,o(b)",	0x9c000000, 0xfc000000,	LDD|RD_b|WR_t,		I3	},
-{"lwu",     "t,A(b)",	0,    (int) M_LWU_AB,	INSN_MACRO,		I3	},
-{"lwxc1",   "D,t(b)",	0x4c000000, 0xfc00f83f, LDD|WR_D|RD_t|RD_b,	I4	},
-{"macc",    "d,s,t",	0x00000028, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, N412    },
-{"macc",    "d,s,t",	0x00000158, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d,	N5      },
-{"maccs",   "d,s,t",	0x00000428, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d, N412    },
-{"macchi",  "d,s,t",	0x00000228, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, N412    },
-{"macchi",  "d,s,t",	0x00000358, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d,	N5      },
-{"macchis", "d,s,t",	0x00000628, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d, N412    },
-{"macchiu", "d,s,t",	0x00000268, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d, N412    },
-{"macchiu", "d,s,t",	0x00000359, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d,	N5      },
-{"macchius","d,s,t",	0x00000668, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d, N412    },
-{"maccu",   "d,s,t",	0x00000068, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d, N412    },
-{"maccu",   "d,s,t",	0x00000159, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d,	N5      },
-{"maccus",  "d,s,t",	0x00000468, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d, N412    },
-{"mad",     "s,t",      0x70000000, 0xfc00ffff, RD_s|RD_t|MOD_HILO,     P3      },
-{"madu",    "s,t",      0x70000001, 0xfc00ffff, RD_s|RD_t|MOD_HILO,     P3      },
-{"madd.d",  "D,R,S,T",	0x4c000021, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D,    I4	},
-{"madd.s",  "D,R,S,T",	0x4c000020, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_S,    I4	},
-{"madd.ps", "D,R,S,T",	0x4c000026, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D,    I5	},
-{"madd",    "s,t",      0x0000001c, 0xfc00ffff, RD_s|RD_t|WR_HILO,           L1 },
-{"madd",    "s,t",      0x70000000, 0xfc00ffff, RD_s|RD_t|MOD_HILO,          I32|N55},
-{"madd",    "s,t",      0x70000000, 0xfc00ffff, RD_s|RD_t|WR_HILO|IS_M,      G1 },
-{"madd",    "d,s,t",    0x70000000, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d|IS_M, G1 },
-{"maddu",   "s,t",      0x0000001d, 0xfc00ffff, RD_s|RD_t|WR_HILO,           L1 },
-{"maddu",   "s,t",      0x70000001, 0xfc00ffff, RD_s|RD_t|MOD_HILO,          I32|N55},
-{"maddu",   "s,t",      0x70000001, 0xfc00ffff, RD_s|RD_t|WR_HILO|IS_M,      G1	},
-{"maddu",   "d,s,t",    0x70000001, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d|IS_M, G1	},
-{"madd16",  "s,t",      0x00000028, 0xfc00ffff, RD_s|RD_t|MOD_HILO,	N411    },
-{"max.ob",  "X,Y,Q",	0x78000007, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	MX|SB1	},
-{"max.ob",  "D,S,T",	0x4ac00007, 0xffe0003f,	WR_D|RD_S|RD_T,		N54	},
-{"max.ob",  "D,S,T[e]",	0x48000007, 0xfe20003f,	WR_D|RD_S|RD_T,		N54	},
-{"max.ob",  "D,S,k",	0x4bc00007, 0xffe0003f,	WR_D|RD_S|RD_T,		N54	},
-{"max.qh",  "X,Y,Q",	0x78200007, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	MX	},
-{"mfpc",    "t,P",	0x4000c801, 0xffe0ffc1,	LCD|WR_t|RD_C0,		M1|N5	},
-{"mfps",    "t,P",	0x4000c800, 0xffe0ffc1,	LCD|WR_t|RD_C0,		M1|N5	},
-{"mfc0",    "t,G",	0x40000000, 0xffe007ff,	LCD|WR_t|RD_C0,		I1	},
-{"mfc0",    "t,+D",     0x40000000, 0xffe007f8, LCD|WR_t|RD_C0, 	I32     },
-{"mfc0",    "t,G,H",    0x40000000, 0xffe007f8, LCD|WR_t|RD_C0, 	I32     },
-{"mfc1",    "t,S",	0x44000000, 0xffe007ff,	LCD|WR_t|RD_S|FP_S,	I1	},
-{"mfc1",    "t,G",	0x44000000, 0xffe007ff,	LCD|WR_t|RD_S|FP_S,	I1	},
-{"mfhc1",   "t,S",	0x44600000, 0xffe007ff,	LCD|WR_t|RD_S|FP_S,	I33	},
-{"mfhc1",   "t,G",	0x44600000, 0xffe007ff,	LCD|WR_t|RD_S|FP_S,	I33	},
+{"li.d",    "t,F",	0,    (int) M_LI_D,	INSN_MACRO,		0,		I1	},
+{"li.d",    "T,L",	0,    (int) M_LI_DD,	INSN_MACRO,		0,		I1	},
+{"li.s",    "t,f",	0,    (int) M_LI_S,	INSN_MACRO,		0,		I1	},
+{"li.s",    "T,l",	0,    (int) M_LI_SS,	INSN_MACRO,		0,		I1	},
+{"ll",	    "t,o(b)",	0xc0000000, 0xfc000000, LDD|RD_b|WR_t,		0,		I2	},
+{"ll",	    "t,A(b)",	0,    (int) M_LL_AB,	INSN_MACRO,		0,		I2	},
+{"lld",	    "t,o(b)",	0xd0000000, 0xfc000000, LDD|RD_b|WR_t,		0,		I3	},
+{"lld",     "t,A(b)",	0,    (int) M_LLD_AB,	INSN_MACRO,		0,		I3	},
+{"lui",     "t,u",	0x3c000000, 0xffe00000,	WR_t,			0,		I1	},
+{"luxc1",   "D,t(b)",	0x4c000005, 0xfc00f83f, LDD|WR_D|RD_t|RD_b|FP_D, 0,		I5|I33|N55},
+{"lw",      "t,o(b)",	0x8c000000, 0xfc000000,	LDD|RD_b|WR_t,		0,		I1	},
+{"lw",      "t,A(b)",	0,    (int) M_LW_AB,	INSN_MACRO,		0,		I1	},
+{"lwc0",    "E,o(b)",	0xc0000000, 0xfc000000,	CLD|RD_b|WR_CC,		0,		I1	},
+{"lwc0",    "E,A(b)",	0,    (int) M_LWC0_AB,	INSN_MACRO,		0,		I1	},
+{"lwc1",    "T,o(b)",	0xc4000000, 0xfc000000,	CLD|RD_b|WR_T|FP_S,	0,		I1	},
+{"lwc1",    "E,o(b)",	0xc4000000, 0xfc000000,	CLD|RD_b|WR_T|FP_S,	0,		I1	},
+{"lwc1",    "T,A(b)",	0,    (int) M_LWC1_AB,	INSN_MACRO,		0,		I1	},
+{"lwc1",    "E,A(b)",	0,    (int) M_LWC1_AB,	INSN_MACRO,		0,		I1	},
+{"l.s",     "T,o(b)",	0xc4000000, 0xfc000000,	CLD|RD_b|WR_T|FP_S,	0,		I1	}, /* lwc1 */
+{"l.s",     "T,A(b)",	0,    (int) M_LWC1_AB,	INSN_MACRO,		0,		I1	},
+{"lwc2",    "E,o(b)",	0xc8000000, 0xfc000000,	CLD|RD_b|WR_CC,		0,		I1	},
+{"lwc2",    "E,A(b)",	0,    (int) M_LWC2_AB,	INSN_MACRO,		0,		I1	},
+{"lwc3",    "E,o(b)",	0xcc000000, 0xfc000000,	CLD|RD_b|WR_CC,		0,		I1	},
+{"lwc3",    "E,A(b)",	0,    (int) M_LWC3_AB,	INSN_MACRO,		0,		I1	},
+{"lwl",     "t,o(b)",	0x88000000, 0xfc000000,	LDD|RD_b|WR_t,		0,		I1	},
+{"lwl",     "t,A(b)",	0,    (int) M_LWL_AB,	INSN_MACRO,		0,		I1	},
+{"lcache",  "t,o(b)",	0x88000000, 0xfc000000,	LDD|RD_b|WR_t,		0,		I2	}, /* same */
+{"lcache",  "t,A(b)",	0,    (int) M_LWL_AB,	INSN_MACRO,		0,		I2	}, /* as lwl */
+{"lwr",     "t,o(b)",	0x98000000, 0xfc000000,	LDD|RD_b|WR_t,		0,		I1	},
+{"lwr",     "t,A(b)",	0,    (int) M_LWR_AB,	INSN_MACRO,		0,		I1	},
+{"flush",   "t,o(b)",	0x98000000, 0xfc000000,	LDD|RD_b|WR_t,		0,		I2	}, /* same */
+{"flush",   "t,A(b)",	0,    (int) M_LWR_AB,	INSN_MACRO,		0,		I2	}, /* as lwr */
+{"fork",    "d,s,t",	0x7c000008, 0xfc0007ff, TRAP|WR_d|RD_s|RD_t,	0,		MT32	},
+{"lwu",     "t,o(b)",	0x9c000000, 0xfc000000,	LDD|RD_b|WR_t,		0,		I3	},
+{"lwu",     "t,A(b)",	0,    (int) M_LWU_AB,	INSN_MACRO,		0,		I3	},
+{"lwxc1",   "D,t(b)",	0x4c000000, 0xfc00f83f, LDD|WR_D|RD_t|RD_b|FP_D, 0,		I4|I33	},
+{"lwxs",    "d,t(b)",	0x70000088, 0xfc0007ff,	LDD|RD_b|RD_t|WR_d,	0,		SMT	},
+{"macc",    "d,s,t",	0x00000028, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0,		N412    },
+{"macc",    "d,s,t",	0x00000158, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d,	0,		N5      },
+{"maccs",   "d,s,t",	0x00000428, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d, 0,		N412    },
+{"macchi",  "d,s,t",	0x00000228, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0,		N412    },
+{"macchi",  "d,s,t",	0x00000358, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d,	0,		N5      },
+{"macchis", "d,s,t",	0x00000628, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d, 0,		N412    },
+{"macchiu", "d,s,t",	0x00000268, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d, 0,		N412    },
+{"macchiu", "d,s,t",	0x00000359, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d,	0,		N5      },
+{"macchius","d,s,t",	0x00000668, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d, 0,		N412    },
+{"maccu",   "d,s,t",	0x00000068, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d, 0,		N412    },
+{"maccu",   "d,s,t",	0x00000159, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d,	0,		N5      },
+{"maccus",  "d,s,t",	0x00000468, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d, 0,		N412    },
+{"mad",     "s,t",      0x70000000, 0xfc00ffff, RD_s|RD_t|MOD_HILO,     0,		P3      },
+{"madu",    "s,t",      0x70000001, 0xfc00ffff, RD_s|RD_t|MOD_HILO,     0,		P3      },
+{"madd.d",  "D,R,S,T",	0x4c000021, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D,    0,		I4|I33	},
+{"madd.s",  "D,R,S,T",	0x4c000020, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_S,    0,		I4|I33	},
+{"madd.ps", "D,R,S,T",	0x4c000026, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D,    0,		I5|I33	},
+{"madd",    "s,t",      0x0000001c, 0xfc00ffff, RD_s|RD_t|WR_HILO,           0,		L1	},
+{"madd",    "s,t",      0x70000000, 0xfc00ffff, RD_s|RD_t|MOD_HILO,          0,		I32|N55	},
+{"madd",    "s,t",      0x70000000, 0xfc00ffff, RD_s|RD_t|WR_HILO|IS_M,      0,		G1	},
+{"madd",    "7,s,t",	0x70000000, 0xfc00e7ff, MOD_a|RD_s|RD_t,             0,         D33	},
+{"madd",    "d,s,t",    0x70000000, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d|IS_M, 0,		G1	},
+{"maddp",   "s,t",      0x70000441, 0xfc00ffff,	RD_s|RD_t|MOD_HILO,	     0,		SMT	},
+{"maddu",   "s,t",      0x0000001d, 0xfc00ffff, RD_s|RD_t|WR_HILO,           0,		L1	},
+{"maddu",   "s,t",      0x70000001, 0xfc00ffff, RD_s|RD_t|MOD_HILO,          0,		I32|N55	},
+{"maddu",   "s,t",      0x70000001, 0xfc00ffff, RD_s|RD_t|WR_HILO|IS_M,      0,		G1	},
+{"maddu",   "7,s,t",	0x70000001, 0xfc00e7ff, MOD_a|RD_s|RD_t,             0,         D33	},
+{"maddu",   "d,s,t",    0x70000001, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d|IS_M, 0,		G1	},
+{"madd16",  "s,t",      0x00000028, 0xfc00ffff, RD_s|RD_t|MOD_HILO,	0,		N411    },
+{"max.ob",  "X,Y,Q",	0x78000007, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	0,		MX|SB1	},
+{"max.ob",  "D,S,T",	0x4ac00007, 0xffe0003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"max.ob",  "D,S,T[e]",	0x48000007, 0xfe20003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"max.ob",  "D,S,k",	0x4bc00007, 0xffe0003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"max.qh",  "X,Y,Q",	0x78200007, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	0,		MX	},
+{"mfpc",    "t,P",	0x4000c801, 0xffe0ffc1,	LCD|WR_t|RD_C0,		0,		M1|N5	},
+{"mfps",    "t,P",	0x4000c800, 0xffe0ffc1,	LCD|WR_t|RD_C0,		0,		M1|N5	},
+{"mftacx",  "d",	0x41020021, 0xffff07ff, TRAP|WR_d|RD_a,		0,		MT32	},
+{"mftacx",  "d,*",	0x41020021, 0xfff307ff, TRAP|WR_d|RD_a,		0,		MT32	},
+{"mftc0",   "d,+t",	0x41000000, 0xffe007ff, TRAP|LCD|WR_d|RD_C0,	0,		MT32	},
+{"mftc0",   "d,+T",	0x41000000, 0xffe007f8, TRAP|LCD|WR_d|RD_C0,	0,		MT32	},
+{"mftc0",   "d,E,H",	0x41000000, 0xffe007f8, TRAP|LCD|WR_d|RD_C0,	0,		MT32	},
+{"mftc1",   "d,T",	0x41000022, 0xffe007ff, TRAP|LCD|WR_d|RD_T|FP_S, 0,		MT32	},
+{"mftc1",   "d,E",	0x41000022, 0xffe007ff, TRAP|LCD|WR_d|RD_T|FP_S, 0,		MT32	},
+{"mftc2",   "d,E",	0x41000024, 0xffe007ff, TRAP|LCD|WR_d|RD_C2,	0,		MT32	},
+{"mftdsp",  "d",	0x41100021, 0xffff07ff, TRAP|WR_d,		0,		MT32	},
+{"mftgpr",  "d,t",	0x41000020, 0xffe007ff, TRAP|WR_d|RD_t,		0,		MT32	},
+{"mfthc1",  "d,T",	0x41000032, 0xffe007ff, TRAP|LCD|WR_d|RD_T|FP_D, 0,		MT32	},
+{"mfthc1",  "d,E",	0x41000032, 0xffe007ff, TRAP|LCD|WR_d|RD_T|FP_D, 0,		MT32	},
+{"mfthc2",  "d,E",	0x41000034, 0xffe007ff, TRAP|LCD|WR_d|RD_C2,	0,		MT32	},
+{"mfthi",   "d",	0x41010021, 0xffff07ff, TRAP|WR_d|RD_a,		0,		MT32	},
+{"mfthi",   "d,*",	0x41010021, 0xfff307ff, TRAP|WR_d|RD_a,		0,		MT32	},
+{"mftlo",   "d",	0x41000021, 0xffff07ff, TRAP|WR_d|RD_a,		0,		MT32	},
+{"mftlo",   "d,*",	0x41000021, 0xfff307ff, TRAP|WR_d|RD_a,		0,		MT32	},
+{"mftr",    "d,t,!,H,$", 0x41000000, 0xffe007c8, TRAP|WR_d,		0,		MT32	},
+{"mfc0",    "t,G",	0x40000000, 0xffe007ff,	LCD|WR_t|RD_C0,		0,		I1	},
+{"mfc0",    "t,+D",     0x40000000, 0xffe007f8, LCD|WR_t|RD_C0, 	0,		I32     },
+{"mfc0",    "t,G,H",    0x40000000, 0xffe007f8, LCD|WR_t|RD_C0, 	0,		I32     },
+{"mfc1",    "t,S",	0x44000000, 0xffe007ff,	LCD|WR_t|RD_S|FP_S,	0,		I1	},
+{"mfc1",    "t,G",	0x44000000, 0xffe007ff,	LCD|WR_t|RD_S|FP_S,	0,		I1	},
+{"mfhc1",   "t,S",	0x44600000, 0xffe007ff,	LCD|WR_t|RD_S|FP_D,	0,		I33	},
+{"mfhc1",   "t,G",	0x44600000, 0xffe007ff,	LCD|WR_t|RD_S|FP_D,	0,		I33	},
 /* mfc2 is at the bottom of the table.  */
 /* mfhc2 is at the bottom of the table.  */
-{"mfc3",    "t,G",	0x4c000000, 0xffe007ff,	LCD|WR_t|RD_C3,		I1	},
-{"mfc3",    "t,G,H",    0x4c000000, 0xffe007f8, LCD|WR_t|RD_C3, 	I32     },
-{"mfdr",    "t,G",	0x7000003d, 0xffe007ff,	LCD|WR_t|RD_C0,		N5      },
-{"mfhi",    "d",	0x00000010, 0xffff07ff,	WR_d|RD_HI,		I1	},
-{"mflo",    "d",	0x00000012, 0xffff07ff,	WR_d|RD_LO,		I1	},
-{"min.ob",  "X,Y,Q",	0x78000006, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	MX|SB1	},
-{"min.ob",  "D,S,T",	0x4ac00006, 0xffe0003f,	WR_D|RD_S|RD_T,		N54	},
-{"min.ob",  "D,S,T[e]",	0x48000006, 0xfe20003f,	WR_D|RD_S|RD_T,		N54	},
-{"min.ob",  "D,S,k",	0x4bc00006, 0xffe0003f,	WR_D|RD_S|RD_T,		N54	},
-{"min.qh",  "X,Y,Q",	0x78200006, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	MX	},
-{"mov.d",   "D,S",	0x46200006, 0xffff003f,	WR_D|RD_S|FP_D,		I1	},
-{"mov.s",   "D,S",	0x46000006, 0xffff003f,	WR_D|RD_S|FP_S,		I1	},
-{"mov.ps",  "D,S",	0x46c00006, 0xffff003f,	WR_D|RD_S|FP_D,		I5	},
-{"movf",    "d,s,N",    0x00000001, 0xfc0307ff, WR_d|RD_s|RD_CC|FP_D|FP_S, I4|I32},
-{"movf.d",  "D,S,N",    0x46200011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D,   I4|I32	},
-{"movf.l",  "D,S,N",	0x46a00011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D,	MX|SB1	},
-{"movf.l",  "X,Y,N",	0x46a00011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D,	MX|SB1	},
-{"movf.s",  "D,S,N",    0x46000011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_S,   I4|I32	},
-{"movf.ps", "D,S,N",	0x46c00011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D,	I5	},
-{"movn",    "d,v,t",    0x0000000b, 0xfc0007ff, WR_d|RD_s|RD_t, 	I4|I32	},
-{"ffc",     "d,v",	0x0000000b, 0xfc1f07ff,	WR_d|RD_s,		L1	},
-{"movn.d",  "D,S,t",    0x46200013, 0xffe0003f, WR_D|RD_S|RD_t|FP_D,    I4|I32	},
-{"movn.l",  "D,S,t",    0x46a00013, 0xffe0003f, WR_D|RD_S|RD_t|FP_D,    MX|SB1	},
-{"movn.l",  "X,Y,t",    0x46a00013, 0xffe0003f, WR_D|RD_S|RD_t|FP_D,    MX|SB1	},
-{"movn.s",  "D,S,t",    0x46000013, 0xffe0003f, WR_D|RD_S|RD_t|FP_S,    I4|I32	},
-{"movn.ps", "D,S,t",    0x46c00013, 0xffe0003f, WR_D|RD_S|RD_t|FP_D,    I5	},
-{"movt",    "d,s,N",    0x00010001, 0xfc0307ff, WR_d|RD_s|RD_CC,        I4|I32	},
-{"movt.d",  "D,S,N",    0x46210011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D,   I4|I32	},
-{"movt.l",  "D,S,N",    0x46a10011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D,   MX|SB1	},
-{"movt.l",  "X,Y,N",    0x46a10011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D,   MX|SB1	},
-{"movt.s",  "D,S,N",    0x46010011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_S,   I4|I32	},
-{"movt.ps", "D,S,N",	0x46c10011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D,	I5	},
-{"movz",    "d,v,t",    0x0000000a, 0xfc0007ff, WR_d|RD_s|RD_t, 	I4|I32	},
-{"ffs",     "d,v",	0x0000000a, 0xfc1f07ff,	WR_d|RD_s,		L1	},
-{"movz.d",  "D,S,t",    0x46200012, 0xffe0003f, WR_D|RD_S|RD_t|FP_D,    I4|I32	},
-{"movz.l",  "D,S,t",    0x46a00012, 0xffe0003f, WR_D|RD_S|RD_t|FP_D,    MX|SB1	},
-{"movz.l",  "X,Y,t",    0x46a00012, 0xffe0003f, WR_D|RD_S|RD_t|FP_D,    MX|SB1	},
-{"movz.s",  "D,S,t",    0x46000012, 0xffe0003f, WR_D|RD_S|RD_t|FP_S,    I4|I32	},
-{"movz.ps", "D,S,t",    0x46c00012, 0xffe0003f, WR_D|RD_S|RD_t|FP_D,    I5	},
-{"msac",    "d,s,t",	0x000001d8, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d,	N5	},
-{"msacu",   "d,s,t",	0x000001d9, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d,	N5	},
-{"msachi",  "d,s,t",	0x000003d8, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d,	N5	},
-{"msachiu", "d,s,t",	0x000003d9, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d,	N5	},
+/* mfc3 is at the bottom of the table.  */
+{"mfdr",    "t,G",	0x7000003d, 0xffe007ff,	LCD|WR_t|RD_C0,		0,		N5      },
+{"mfhi",    "d",	0x00000010, 0xffff07ff,	WR_d|RD_HI,		0,		I1	},
+{"mfhi",    "d,9",	0x00000010, 0xff9f07ff, WR_d|RD_HI,		0,		D32	},
+{"mflo",    "d",	0x00000012, 0xffff07ff,	WR_d|RD_LO,		0,		I1	},
+{"mflo",    "d,9",	0x00000012, 0xff9f07ff, WR_d|RD_LO,		0,		D32	},
+{"mflhxu",  "d",	0x00000052, 0xffff07ff,	WR_d|MOD_HILO,		0,		SMT	},
+{"min.ob",  "X,Y,Q",	0x78000006, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	0,		MX|SB1	},
+{"min.ob",  "D,S,T",	0x4ac00006, 0xffe0003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"min.ob",  "D,S,T[e]",	0x48000006, 0xfe20003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"min.ob",  "D,S,k",	0x4bc00006, 0xffe0003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"min.qh",  "X,Y,Q",	0x78200006, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	0,		MX	},
+{"mov.d",   "D,S",	0x46200006, 0xffff003f,	WR_D|RD_S|FP_D,		0,		I1	},
+{"mov.s",   "D,S",	0x46000006, 0xffff003f,	WR_D|RD_S|FP_S,		0,		I1	},
+{"mov.ps",  "D,S",	0x46c00006, 0xffff003f,	WR_D|RD_S|FP_D,		0,		I5|I33	},
+{"movf",    "d,s,N",    0x00000001, 0xfc0307ff, WR_d|RD_s|RD_CC|FP_S|FP_D, 0,		I4|I32  },
+{"movf.d",  "D,S,N",    0x46200011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D,   0,		I4|I32	},
+{"movf.l",  "D,S,N",	0x46a00011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D,	0,		MX|SB1	},
+{"movf.l",  "X,Y,N",	0x46a00011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D,	0,		MX|SB1	},
+{"movf.s",  "D,S,N",    0x46000011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_S,   0,		I4|I32	},
+{"movf.ps", "D,S,N",	0x46c00011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D,	0,		I5|I33	},
+{"movn",    "d,v,t",    0x0000000b, 0xfc0007ff, WR_d|RD_s|RD_t, 	0,		I4|I32	},
+{"ffc",     "d,v",	0x0000000b, 0xfc1f07ff,	WR_d|RD_s,		0,		L1	},
+{"movn.d",  "D,S,t",    0x46200013, 0xffe0003f, WR_D|RD_S|RD_t|FP_D,    0,		I4|I32	},
+{"movn.l",  "D,S,t",    0x46a00013, 0xffe0003f, WR_D|RD_S|RD_t|FP_D,    0,		MX|SB1	},
+{"movn.l",  "X,Y,t",    0x46a00013, 0xffe0003f, WR_D|RD_S|RD_t|FP_D,    0,		MX|SB1	},
+{"movn.s",  "D,S,t",    0x46000013, 0xffe0003f, WR_D|RD_S|RD_t|FP_S,    0,		I4|I32	},
+{"movn.ps", "D,S,t",    0x46c00013, 0xffe0003f, WR_D|RD_S|RD_t|FP_D,    0,		I5|I33	},
+{"movt",    "d,s,N",    0x00010001, 0xfc0307ff, WR_d|RD_s|RD_CC|FP_S|FP_D, 0,		I4|I32	},
+{"movt.d",  "D,S,N",    0x46210011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D,   0,		I4|I32	},
+{"movt.l",  "D,S,N",    0x46a10011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D,   0,		MX|SB1	},
+{"movt.l",  "X,Y,N",    0x46a10011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D,   0,		MX|SB1	},
+{"movt.s",  "D,S,N",    0x46010011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_S,   0,		I4|I32	},
+{"movt.ps", "D,S,N",	0x46c10011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D,	0,		I5|I33	},
+{"movz",    "d,v,t",    0x0000000a, 0xfc0007ff, WR_d|RD_s|RD_t, 	0,		I4|I32	},
+{"ffs",     "d,v",	0x0000000a, 0xfc1f07ff,	WR_d|RD_s,		0,		L1	},
+{"movz.d",  "D,S,t",    0x46200012, 0xffe0003f, WR_D|RD_S|RD_t|FP_D,    0,		I4|I32	},
+{"movz.l",  "D,S,t",    0x46a00012, 0xffe0003f, WR_D|RD_S|RD_t|FP_D,    0,		MX|SB1	},
+{"movz.l",  "X,Y,t",    0x46a00012, 0xffe0003f, WR_D|RD_S|RD_t|FP_D,    0,		MX|SB1	},
+{"movz.s",  "D,S,t",    0x46000012, 0xffe0003f, WR_D|RD_S|RD_t|FP_S,    0,		I4|I32	},
+{"movz.ps", "D,S,t",    0x46c00012, 0xffe0003f, WR_D|RD_S|RD_t|FP_D,    0,		I5|I33	},
+{"msac",    "d,s,t",	0x000001d8, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d,	0,		N5	},
+{"msacu",   "d,s,t",	0x000001d9, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d,	0,		N5	},
+{"msachi",  "d,s,t",	0x000003d8, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d,	0,		N5	},
+{"msachiu", "d,s,t",	0x000003d9, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d,	0,		N5	},
 /* move is at the top of the table.  */
-{"msgn.qh", "X,Y,Q",	0x78200000, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	MX	},
-{"msub.d",  "D,R,S,T",	0x4c000029, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, I4	},
-{"msub.s",  "D,R,S,T",	0x4c000028, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_S, I4	},
-{"msub.ps", "D,R,S,T",	0x4c00002e, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, I5	},
-{"msub",    "s,t",      0x0000001e, 0xfc00ffff, RD_s|RD_t|WR_HILO,	L1    	},
-{"msub",    "s,t",      0x70000004, 0xfc00ffff, RD_s|RD_t|MOD_HILO,     I32|N55 },
-{"msubu",   "s,t",      0x0000001f, 0xfc00ffff, RD_s|RD_t|WR_HILO,	L1	},
-{"msubu",   "s,t",      0x70000005, 0xfc00ffff, RD_s|RD_t|MOD_HILO,     I32|N55	},
-{"mtpc",    "t,P",	0x4080c801, 0xffe0ffc1,	COD|RD_t|WR_C0,		M1|N5	},
-{"mtps",    "t,P",	0x4080c800, 0xffe0ffc1,	COD|RD_t|WR_C0,		M1|N5	},
-{"mtc0",    "t,G",	0x40800000, 0xffe007ff,	COD|RD_t|WR_C0|WR_CC,	I1	},
-{"mtc0",    "t,+D",     0x40800000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC,   I32     },
-{"mtc0",    "t,G,H",    0x40800000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC,   I32     },
-{"mtc1",    "t,S",	0x44800000, 0xffe007ff,	COD|RD_t|WR_S|FP_S,	I1	},
-{"mtc1",    "t,G",	0x44800000, 0xffe007ff,	COD|RD_t|WR_S|FP_S,	I1	},
-{"mthc1",   "t,S",	0x44e00000, 0xffe007ff,	COD|RD_t|WR_S|FP_S,	I33	},
-{"mthc1",   "t,G",	0x44e00000, 0xffe007ff,	COD|RD_t|WR_S|FP_S,	I33	},
+{"msgn.qh", "X,Y,Q",	0x78200000, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	0,		MX	},
+{"msub.d",  "D,R,S,T",	0x4c000029, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, 0,		I4|I33	},
+{"msub.s",  "D,R,S,T",	0x4c000028, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_S, 0,		I4|I33	},
+{"msub.ps", "D,R,S,T",	0x4c00002e, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, 0,		I5|I33	},
+{"msub",    "s,t",      0x0000001e, 0xfc00ffff, RD_s|RD_t|WR_HILO,	0,		L1    	},
+{"msub",    "s,t",      0x70000004, 0xfc00ffff, RD_s|RD_t|MOD_HILO,     0,		I32|N55 },
+{"msub",    "7,s,t",	0x70000004, 0xfc00e7ff, MOD_a|RD_s|RD_t,        0,              D33	},
+{"msubu",   "s,t",      0x0000001f, 0xfc00ffff, RD_s|RD_t|WR_HILO,	0,		L1	},
+{"msubu",   "s,t",      0x70000005, 0xfc00ffff, RD_s|RD_t|MOD_HILO,     0,		I32|N55	},
+{"msubu",   "7,s,t",	0x70000005, 0xfc00e7ff, MOD_a|RD_s|RD_t,        0,              D33	},
+{"mtpc",    "t,P",	0x4080c801, 0xffe0ffc1,	COD|RD_t|WR_C0,		0,		M1|N5	},
+{"mtps",    "t,P",	0x4080c800, 0xffe0ffc1,	COD|RD_t|WR_C0,		0,		M1|N5	},
+{"mtc0",    "t,G",	0x40800000, 0xffe007ff,	COD|RD_t|WR_C0|WR_CC,	0,		I1	},
+{"mtc0",    "t,+D",     0x40800000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC,   0,		I32     },
+{"mtc0",    "t,G,H",    0x40800000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC,   0,		I32     },
+{"mtc1",    "t,S",	0x44800000, 0xffe007ff,	COD|RD_t|WR_S|FP_S,	0,		I1	},
+{"mtc1",    "t,G",	0x44800000, 0xffe007ff,	COD|RD_t|WR_S|FP_S,	0,		I1	},
+{"mthc1",   "t,S",	0x44e00000, 0xffe007ff,	COD|RD_t|WR_S|FP_D,	0,		I33	},
+{"mthc1",   "t,G",	0x44e00000, 0xffe007ff,	COD|RD_t|WR_S|FP_D,	0,		I33	},
 /* mtc2 is at the bottom of the table.  */
 /* mthc2 is at the bottom of the table.  */
-{"mtc3",    "t,G",	0x4c800000, 0xffe007ff,	COD|RD_t|WR_C3|WR_CC,	I1	},
-{"mtc3",    "t,G,H",    0x4c800000, 0xffe007f8, COD|RD_t|WR_C3|WR_CC,   I32     },
-{"mtdr",    "t,G",	0x7080003d, 0xffe007ff,	COD|RD_t|WR_C0,		N5	},
-{"mthi",    "s",	0x00000011, 0xfc1fffff,	RD_s|WR_HI,		I1	},
-{"mtlo",    "s",	0x00000013, 0xfc1fffff,	RD_s|WR_LO,		I1	},
-{"mul.d",   "D,V,T",	0x46200002, 0xffe0003f,	WR_D|RD_S|RD_T|FP_D,	I1	},
-{"mul.s",   "D,V,T",	0x46000002, 0xffe0003f,	WR_D|RD_S|RD_T|FP_S,	I1	},
-{"mul.ob",  "X,Y,Q",	0x78000030, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	MX|SB1	},
-{"mul.ob",  "D,S,T",	0x4ac00030, 0xffe0003f,	WR_D|RD_S|RD_T,		N54	},
-{"mul.ob",  "D,S,T[e]",	0x48000030, 0xfe20003f,	WR_D|RD_S|RD_T,		N54	},
-{"mul.ob",  "D,S,k",	0x4bc00030, 0xffe0003f,	WR_D|RD_S|RD_T,		N54	},
-{"mul.ps",  "D,V,T",	0x46c00002, 0xffe0003f,	WR_D|RD_S|RD_T|FP_D,	I5	},
-{"mul.qh",  "X,Y,Q",	0x78200030, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	MX	},
-{"mul",     "d,v,t",    0x70000002, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, I32|P3|N55},
-{"mul",     "d,s,t",	0x00000058, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d,	N54	},
-{"mul",     "d,v,t",	0,    (int) M_MUL,	INSN_MACRO,		I1	},
-{"mul",     "d,v,I",	0,    (int) M_MUL_I,	INSN_MACRO,		I1	},
-{"mula.ob", "Y,Q",	0x78000033, 0xfc2007ff,	WR_MACC|RD_S|RD_T|FP_D,	MX|SB1	},
-{"mula.ob", "S,T",	0x4ac00033, 0xffe007ff,	WR_CC|RD_S|RD_T,	N54	},
-{"mula.ob", "S,T[e]",	0x48000033, 0xfe2007ff,	WR_CC|RD_S|RD_T,	N54	},
-{"mula.ob", "S,k",	0x4bc00033, 0xffe007ff,	WR_CC|RD_S|RD_T,	N54	},
-{"mula.qh", "Y,Q",	0x78200033, 0xfc2007ff,	WR_MACC|RD_S|RD_T|FP_D,	MX	},
-{"mulhi",   "d,s,t",	0x00000258, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d,	N5	},
-{"mulhiu",  "d,s,t",	0x00000259, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d,	N5	},
-{"mull.ob", "Y,Q",	0x78000433, 0xfc2007ff,	WR_MACC|RD_S|RD_T|FP_D, MX|SB1	},
-{"mull.ob", "S,T",	0x4ac00433, 0xffe007ff,	WR_CC|RD_S|RD_T,	N54	},
-{"mull.ob", "S,T[e]",	0x48000433, 0xfe2007ff,	WR_CC|RD_S|RD_T,	N54	},
-{"mull.ob", "S,k",	0x4bc00433, 0xffe007ff,	WR_CC|RD_S|RD_T,	N54	},
-{"mull.qh", "Y,Q",	0x78200433, 0xfc2007ff,	WR_MACC|RD_S|RD_T|FP_D,	MX	},
-{"mulo",    "d,v,t",	0,    (int) M_MULO,	INSN_MACRO,		I1	},
-{"mulo",    "d,v,I",	0,    (int) M_MULO_I,	INSN_MACRO,		I1	},
-{"mulou",   "d,v,t",	0,    (int) M_MULOU,	INSN_MACRO,		I1	},
-{"mulou",   "d,v,I",	0,    (int) M_MULOU_I,	INSN_MACRO,		I1	},
-{"mulr.ps", "D,S,T",	0x46c0001a, 0xffe0003f,	WR_D|RD_S|RD_T|FP_D,	M3D	},
-{"muls",    "d,s,t",	0x000000d8, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d,	N5	},
-{"mulsu",   "d,s,t",	0x000000d9, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d,	N5	},
-{"mulshi",  "d,s,t",	0x000002d8, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d,	N5	},
-{"mulshiu", "d,s,t",	0x000002d9, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d,	N5	},
-{"muls.ob", "Y,Q",	0x78000032, 0xfc2007ff,	WR_MACC|RD_S|RD_T|FP_D,	MX|SB1	},
-{"muls.ob", "S,T",	0x4ac00032, 0xffe007ff,	WR_CC|RD_S|RD_T,	N54	},
-{"muls.ob", "S,T[e]",	0x48000032, 0xfe2007ff,	WR_CC|RD_S|RD_T,	N54	},
-{"muls.ob", "S,k",	0x4bc00032, 0xffe007ff,	WR_CC|RD_S|RD_T,	N54	},
-{"muls.qh", "Y,Q",	0x78200032, 0xfc2007ff,	WR_MACC|RD_S|RD_T|FP_D,	MX	},
-{"mulsl.ob", "Y,Q",	0x78000432, 0xfc2007ff,	WR_MACC|RD_S|RD_T|FP_D,	MX|SB1	},
-{"mulsl.ob", "S,T",	0x4ac00432, 0xffe007ff,	WR_CC|RD_S|RD_T,	N54	},
-{"mulsl.ob", "S,T[e]",	0x48000432, 0xfe2007ff,	WR_CC|RD_S|RD_T,	N54	},
-{"mulsl.ob", "S,k",	0x4bc00432, 0xffe007ff,	WR_CC|RD_S|RD_T,	N54	},
-{"mulsl.qh", "Y,Q",	0x78200432, 0xfc2007ff,	WR_MACC|RD_S|RD_T|FP_D,	MX	},
-{"mult",    "s,t",      0x00000018, 0xfc00ffff, RD_s|RD_t|WR_HILO|IS_M, I1	},
-{"mult",    "d,s,t",    0x00000018, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d|IS_M, G1	},
-{"multu",   "s,t",      0x00000019, 0xfc00ffff, RD_s|RD_t|WR_HILO|IS_M, I1	},
-{"multu",   "d,s,t",    0x00000019, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d|IS_M, G1	},
-{"mulu",    "d,s,t",	0x00000059, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d,	N5	},
-{"neg",     "d,w",	0x00000022, 0xffe007ff,	WR_d|RD_t,		I1	}, /* sub 0 */
-{"negu",    "d,w",	0x00000023, 0xffe007ff,	WR_d|RD_t,		I1	}, /* subu 0 */
-{"neg.d",   "D,V",	0x46200007, 0xffff003f,	WR_D|RD_S|FP_D,		I1	},
-{"neg.s",   "D,V",	0x46000007, 0xffff003f,	WR_D|RD_S|FP_S,		I1	},
-{"neg.ps",  "D,V",	0x46c00007, 0xffff003f,	WR_D|RD_S|FP_D,		I5	},
-{"nmadd.d", "D,R,S,T",	0x4c000031, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, I4	},
-{"nmadd.s", "D,R,S,T",	0x4c000030, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_S, I4	},
-{"nmadd.ps","D,R,S,T",	0x4c000036, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, I5	},
-{"nmsub.d", "D,R,S,T",	0x4c000039, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, I4	},
-{"nmsub.s", "D,R,S,T",	0x4c000038, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_S, I4	},
-{"nmsub.ps","D,R,S,T",	0x4c00003e, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, I5	},
+/* mtc3 is at the bottom of the table.  */
+{"mtdr",    "t,G",	0x7080003d, 0xffe007ff,	COD|RD_t|WR_C0,		0,		N5	},
+{"mthi",    "s",	0x00000011, 0xfc1fffff,	RD_s|WR_HI,		0,		I1	},
+{"mthi",    "s,7",	0x00000011, 0xfc1fe7ff, RD_s|WR_HI,		0,		D32	},
+{"mtlo",    "s",	0x00000013, 0xfc1fffff,	RD_s|WR_LO,		0,		I1	},
+{"mtlo",    "s,7",	0x00000013, 0xfc1fe7ff, RD_s|WR_LO,		0,		D32	},
+{"mtlhx",   "s",	0x00000053, 0xfc1fffff,	RD_s|MOD_HILO,		0,		SMT	},
+{"mttc0",   "t,G",	0x41800000, 0xffe007ff, TRAP|COD|RD_t|WR_C0|WR_CC, 0,		MT32	},
+{"mttc0",   "t,+D",	0x41800000, 0xffe007f8, TRAP|COD|RD_t|WR_C0|WR_CC, 0,		MT32	},
+{"mttc0",   "t,G,H",	0x41800000, 0xffe007f8, TRAP|COD|RD_t|WR_C0|WR_CC, 0,		MT32	},
+{"mttc1",   "t,S",	0x41800022, 0xffe007ff, TRAP|COD|RD_t|WR_S|FP_S, 0,		MT32	},
+{"mttc1",   "t,G",	0x41800022, 0xffe007ff, TRAP|COD|RD_t|WR_S|FP_S, 0,		MT32	},
+{"mttc2",   "t,g",	0x41800024, 0xffe007ff, TRAP|COD|RD_t|WR_C2|WR_CC, 0,		MT32	},
+{"mttacx",  "t",	0x41801021, 0xffe0ffff, TRAP|WR_a|RD_t,		0,		MT32	},
+{"mttacx",  "t,&",	0x41801021, 0xffe09fff, TRAP|WR_a|RD_t,		0,		MT32	},
+{"mttdsp",  "t",	0x41808021, 0xffe0ffff, TRAP|RD_t,		0,		MT32	},
+{"mttgpr",  "t,d",	0x41800020, 0xffe007ff, TRAP|WR_d|RD_t,		0,		MT32	},
+{"mtthc1",  "t,S",	0x41800032, 0xffe007ff, TRAP|COD|RD_t|WR_S|FP_D, 0,		MT32	},
+{"mtthc1",  "t,G",	0x41800032, 0xffe007ff, TRAP|COD|RD_t|WR_S|FP_D, 0,		MT32	},
+{"mtthc2",  "t,g",	0x41800034, 0xffe007ff, TRAP|COD|RD_t|WR_C2|WR_CC, 0,		MT32	},
+{"mtthi",   "t",	0x41800821, 0xffe0ffff, TRAP|WR_a|RD_t,		0,		MT32	},
+{"mtthi",   "t,&",	0x41800821, 0xffe09fff, TRAP|WR_a|RD_t,		0,		MT32	},
+{"mttlo",   "t",	0x41800021, 0xffe0ffff, TRAP|WR_a|RD_t,		0,		MT32	},
+{"mttlo",   "t,&",	0x41800021, 0xffe09fff, TRAP|WR_a|RD_t,		0,		MT32	},
+{"mttr",    "t,d,!,H,$", 0x41800000, 0xffe007c8, TRAP|RD_t,		0,		MT32	},
+{"mul.d",   "D,V,T",	0x46200002, 0xffe0003f,	WR_D|RD_S|RD_T|FP_D,	0,		I1	},
+{"mul.s",   "D,V,T",	0x46000002, 0xffe0003f,	WR_D|RD_S|RD_T|FP_S,	0,		I1	},
+{"mul.ob",  "X,Y,Q",	0x78000030, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	0,		MX|SB1	},
+{"mul.ob",  "D,S,T",	0x4ac00030, 0xffe0003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"mul.ob",  "D,S,T[e]",	0x48000030, 0xfe20003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"mul.ob",  "D,S,k",	0x4bc00030, 0xffe0003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"mul.ps",  "D,V,T",	0x46c00002, 0xffe0003f,	WR_D|RD_S|RD_T|FP_D,	0,		I5|I33	},
+{"mul.qh",  "X,Y,Q",	0x78200030, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	0,		MX	},
+{"mul",     "d,v,t",    0x70000002, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, 0,		I32|P3|N55},
+{"mul",     "d,s,t",	0x00000058, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d,	0,		N54	},
+{"mul",     "d,v,t",	0,    (int) M_MUL,	INSN_MACRO,		0,		I1	},
+{"mul",     "d,v,I",	0,    (int) M_MUL_I,	INSN_MACRO,		0,		I1	},
+{"mula.ob", "Y,Q",	0x78000033, 0xfc2007ff,	RD_S|RD_T|FP_D,		WR_MACC,	MX|SB1	},
+{"mula.ob", "S,T",	0x4ac00033, 0xffe007ff,	WR_CC|RD_S|RD_T,	0,		N54	},
+{"mula.ob", "S,T[e]",	0x48000033, 0xfe2007ff,	WR_CC|RD_S|RD_T,	0,		N54	},
+{"mula.ob", "S,k",	0x4bc00033, 0xffe007ff,	WR_CC|RD_S|RD_T,	0,		N54	},
+{"mula.qh", "Y,Q",	0x78200033, 0xfc2007ff,	RD_S|RD_T|FP_D,		WR_MACC,	MX	},
+{"mulhi",   "d,s,t",	0x00000258, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d,	0,		N5	},
+{"mulhiu",  "d,s,t",	0x00000259, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d,	0,		N5	},
+{"mull.ob", "Y,Q",	0x78000433, 0xfc2007ff,	RD_S|RD_T|FP_D, 	WR_MACC,	MX|SB1	},
+{"mull.ob", "S,T",	0x4ac00433, 0xffe007ff,	WR_CC|RD_S|RD_T,	0,		N54	},
+{"mull.ob", "S,T[e]",	0x48000433, 0xfe2007ff,	WR_CC|RD_S|RD_T,	0,		N54	},
+{"mull.ob", "S,k",	0x4bc00433, 0xffe007ff,	WR_CC|RD_S|RD_T,	0,		N54	},
+{"mull.qh", "Y,Q",	0x78200433, 0xfc2007ff,	RD_S|RD_T|FP_D,		WR_MACC,	MX	},
+{"mulo",    "d,v,t",	0,    (int) M_MULO,	INSN_MACRO,		0,		I1	},
+{"mulo",    "d,v,I",	0,    (int) M_MULO_I,	INSN_MACRO,		0,		I1	},
+{"mulou",   "d,v,t",	0,    (int) M_MULOU,	INSN_MACRO,		0,		I1	},
+{"mulou",   "d,v,I",	0,    (int) M_MULOU_I,	INSN_MACRO,		0,		I1	},
+{"mulr.ps", "D,S,T",	0x46c0001a, 0xffe0003f,	WR_D|RD_S|RD_T|FP_D,	0,		M3D	},
+{"muls",    "d,s,t",	0x000000d8, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d,	0,		N5	},
+{"mulsu",   "d,s,t",	0x000000d9, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d,	0,		N5	},
+{"mulshi",  "d,s,t",	0x000002d8, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d,	0,		N5	},
+{"mulshiu", "d,s,t",	0x000002d9, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d,	0,		N5	},
+{"muls.ob", "Y,Q",	0x78000032, 0xfc2007ff,	RD_S|RD_T|FP_D,		WR_MACC,	MX|SB1	},
+{"muls.ob", "S,T",	0x4ac00032, 0xffe007ff,	WR_CC|RD_S|RD_T,	0,		N54	},
+{"muls.ob", "S,T[e]",	0x48000032, 0xfe2007ff,	WR_CC|RD_S|RD_T,	0,		N54	},
+{"muls.ob", "S,k",	0x4bc00032, 0xffe007ff,	WR_CC|RD_S|RD_T,	0,		N54	},
+{"muls.qh", "Y,Q",	0x78200032, 0xfc2007ff,	RD_S|RD_T|FP_D,		WR_MACC,	MX	},
+{"mulsl.ob", "Y,Q",	0x78000432, 0xfc2007ff,	RD_S|RD_T|FP_D,		WR_MACC,	MX|SB1	},
+{"mulsl.ob", "S,T",	0x4ac00432, 0xffe007ff,	WR_CC|RD_S|RD_T,	0,		N54	},
+{"mulsl.ob", "S,T[e]",	0x48000432, 0xfe2007ff,	WR_CC|RD_S|RD_T,	0,		N54	},
+{"mulsl.ob", "S,k",	0x4bc00432, 0xffe007ff,	WR_CC|RD_S|RD_T,	0,		N54	},
+{"mulsl.qh", "Y,Q",	0x78200432, 0xfc2007ff,	RD_S|RD_T|FP_D,		WR_MACC,	MX	},
+{"mult",    "s,t",      0x00000018, 0xfc00ffff, RD_s|RD_t|WR_HILO|IS_M, 0,		I1	},
+{"mult",    "7,s,t",	0x00000018, 0xfc00e7ff, WR_a|RD_s|RD_t,         0,              D33	},
+{"mult",    "d,s,t",    0x00000018, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d|IS_M, 0,		G1	},
+{"multp",   "s,t",	0x00000459, 0xfc00ffff,	RD_s|RD_t|MOD_HILO,	0,		SMT	},
+{"multu",   "s,t",      0x00000019, 0xfc00ffff, RD_s|RD_t|WR_HILO|IS_M, 0,		I1	},
+{"multu",   "7,s,t",	0x00000019, 0xfc00e7ff, WR_a|RD_s|RD_t,         0,              D33	},
+{"multu",   "d,s,t",    0x00000019, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d|IS_M, 0,		G1	},
+{"mulu",    "d,s,t",	0x00000059, 0xfc0007ff,	RD_s|RD_t|WR_HILO|WR_d,	0,		N5	},
+{"neg",     "d,w",	0x00000022, 0xffe007ff,	WR_d|RD_t,		0,		I1	}, /* sub 0 */
+{"negu",    "d,w",	0x00000023, 0xffe007ff,	WR_d|RD_t,		0,		I1	}, /* subu 0 */
+{"neg.d",   "D,V",	0x46200007, 0xffff003f,	WR_D|RD_S|FP_D,		0,		I1	},
+{"neg.s",   "D,V",	0x46000007, 0xffff003f,	WR_D|RD_S|FP_S,		0,		I1	},
+{"neg.ps",  "D,V",	0x46c00007, 0xffff003f,	WR_D|RD_S|FP_D,		0,		I5|I33	},
+{"nmadd.d", "D,R,S,T",	0x4c000031, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, 0,		I4|I33	},
+{"nmadd.s", "D,R,S,T",	0x4c000030, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_S, 0,		I4|I33	},
+{"nmadd.ps","D,R,S,T",	0x4c000036, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, 0,		I5|I33	},
+{"nmsub.d", "D,R,S,T",	0x4c000039, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, 0,		I4|I33	},
+{"nmsub.s", "D,R,S,T",	0x4c000038, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_S, 0,		I4|I33	},
+{"nmsub.ps","D,R,S,T",	0x4c00003e, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, 0,		I5|I33	},
 /* nop is at the start of the table.  */
-{"nor",     "d,v,t",	0x00000027, 0xfc0007ff,	WR_d|RD_s|RD_t,		I1	},
-{"nor",     "t,r,I",	0,    (int) M_NOR_I,	INSN_MACRO,		I1	},
-{"nor.ob",  "X,Y,Q",	0x7800000f, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	MX|SB1	},
-{"nor.ob",  "D,S,T",	0x4ac0000f, 0xffe0003f,	WR_D|RD_S|RD_T,		N54	},
-{"nor.ob",  "D,S,T[e]",	0x4800000f, 0xfe20003f,	WR_D|RD_S|RD_T,		N54	},
-{"nor.ob",  "D,S,k",	0x4bc0000f, 0xffe0003f,	WR_D|RD_S|RD_T,		N54	},
-{"nor.qh",  "X,Y,Q",	0x7820000f, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	MX	},
-{"not",     "d,v",	0x00000027, 0xfc1f07ff,	WR_d|RD_s|RD_t,		I1	},/*nor d,s,0*/
-{"or",      "d,v,t",	0x00000025, 0xfc0007ff,	WR_d|RD_s|RD_t,		I1	},
-{"or",      "t,r,I",	0,    (int) M_OR_I,	INSN_MACRO,		I1	},
-{"or.ob",   "X,Y,Q",	0x7800000e, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	MX|SB1	},
-{"or.ob",   "D,S,T",	0x4ac0000e, 0xffe0003f,	WR_D|RD_S|RD_T,		N54	},
-{"or.ob",   "D,S,T[e]",	0x4800000e, 0xfe20003f,	WR_D|RD_S|RD_T,		N54	},
-{"or.ob",   "D,S,k",	0x4bc0000e, 0xffe0003f,	WR_D|RD_S|RD_T,		N54	},
-{"or.qh",   "X,Y,Q",	0x7820000e, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	MX	},
-{"ori",     "t,r,i",	0x34000000, 0xfc000000,	WR_t|RD_s,		I1	},
-{"pabsdiff.ob", "X,Y,Q",0x78000009, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	SB1	},
-{"pabsdiffc.ob", "Y,Q",	0x78000035, 0xfc2007ff,	WR_MACC|RD_S|RD_T|FP_D,	SB1	},
-{"pavg.ob", "X,Y,Q",	0x78000008, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	SB1	},
-{"pickf.ob", "X,Y,Q",	0x78000002, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	MX|SB1	},
-{"pickf.ob", "D,S,T",	0x4ac00002, 0xffe0003f,	WR_D|RD_S|RD_T,		N54	},
-{"pickf.ob", "D,S,T[e]",0x48000002, 0xfe20003f,	WR_D|RD_S|RD_T,		N54	},
-{"pickf.ob", "D,S,k",	0x4bc00002, 0xffe0003f,	WR_D|RD_S|RD_T,		N54	},
-{"pickf.qh", "X,Y,Q",	0x78200002, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	MX	},
-{"pickt.ob", "X,Y,Q",	0x78000003, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	MX|SB1	},
-{"pickt.ob", "D,S,T",	0x4ac00003, 0xffe0003f,	WR_D|RD_S|RD_T,		N54	},
-{"pickt.ob", "D,S,T[e]",0x48000003, 0xfe20003f,	WR_D|RD_S|RD_T,		N54	},
-{"pickt.ob", "D,S,k",	0x4bc00003, 0xffe0003f,	WR_D|RD_S|RD_T,		N54	},
-{"pickt.qh", "X,Y,Q",	0x78200003, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	MX	},
-{"pll.ps",  "D,V,T",	0x46c0002c, 0xffe0003f,	WR_D|RD_S|RD_T|FP_D,	I5	},
-{"plu.ps",  "D,V,T",	0x46c0002d, 0xffe0003f,	WR_D|RD_S|RD_T|FP_D,	I5	},
+{"nor",     "d,v,t",	0x00000027, 0xfc0007ff,	WR_d|RD_s|RD_t,		0,		I1	},
+{"nor",     "t,r,I",	0,    (int) M_NOR_I,	INSN_MACRO,		0,		I1	},
+{"nor.ob",  "X,Y,Q",	0x7800000f, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	0,		MX|SB1	},
+{"nor.ob",  "D,S,T",	0x4ac0000f, 0xffe0003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"nor.ob",  "D,S,T[e]",	0x4800000f, 0xfe20003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"nor.ob",  "D,S,k",	0x4bc0000f, 0xffe0003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"nor.qh",  "X,Y,Q",	0x7820000f, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	0,		MX	},
+{"not",     "d,v",	0x00000027, 0xfc1f07ff,	WR_d|RD_s|RD_t,		0,		I1	},/*nor d,s,0*/
+{"or",      "d,v,t",	0x00000025, 0xfc0007ff,	WR_d|RD_s|RD_t,		0,		I1	},
+{"or",      "t,r,I",	0,    (int) M_OR_I,	INSN_MACRO,		0,		I1	},
+{"or.ob",   "X,Y,Q",	0x7800000e, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	0,		MX|SB1	},
+{"or.ob",   "D,S,T",	0x4ac0000e, 0xffe0003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"or.ob",   "D,S,T[e]",	0x4800000e, 0xfe20003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"or.ob",   "D,S,k",	0x4bc0000e, 0xffe0003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"or.qh",   "X,Y,Q",	0x7820000e, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	0,		MX	},
+{"ori",     "t,r,i",	0x34000000, 0xfc000000,	WR_t|RD_s,		0,		I1	},
+{"pabsdiff.ob", "X,Y,Q",0x78000009, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	0,		SB1	},
+{"pabsdiffc.ob", "Y,Q",	0x78000035, 0xfc2007ff,	RD_S|RD_T|FP_D,		WR_MACC,	SB1	},
+{"pavg.ob", "X,Y,Q",	0x78000008, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	0,		SB1	},
+{"pickf.ob", "X,Y,Q",	0x78000002, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	0,		MX|SB1	},
+{"pickf.ob", "D,S,T",	0x4ac00002, 0xffe0003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"pickf.ob", "D,S,T[e]",0x48000002, 0xfe20003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"pickf.ob", "D,S,k",	0x4bc00002, 0xffe0003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"pickf.qh", "X,Y,Q",	0x78200002, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	0,		MX	},
+{"pickt.ob", "X,Y,Q",	0x78000003, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	0,		MX|SB1	},
+{"pickt.ob", "D,S,T",	0x4ac00003, 0xffe0003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"pickt.ob", "D,S,T[e]",0x48000003, 0xfe20003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"pickt.ob", "D,S,k",	0x4bc00003, 0xffe0003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"pickt.qh", "X,Y,Q",	0x78200003, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	0,		MX	},
+{"pll.ps",  "D,V,T",	0x46c0002c, 0xffe0003f,	WR_D|RD_S|RD_T|FP_D,	0,		I5|I33	},
+{"plu.ps",  "D,V,T",	0x46c0002d, 0xffe0003f,	WR_D|RD_S|RD_T|FP_D,	0,		I5|I33	},
   /* pref and prefx are at the start of the table.  */
-{"pul.ps",  "D,V,T",	0x46c0002e, 0xffe0003f,	WR_D|RD_S|RD_T|FP_D,	I5	},
-{"puu.ps",  "D,V,T",	0x46c0002f, 0xffe0003f,	WR_D|RD_S|RD_T|FP_D,	I5	},
-{"rach.ob", "X",	0x7a00003f, 0xfffff83f,	WR_D|RD_MACC|FP_D,	MX|SB1	},
-{"rach.ob", "D",	0x4a00003f, 0xfffff83f,	WR_D,			N54	},
-{"rach.qh", "X",	0x7a20003f, 0xfffff83f,	WR_D|RD_MACC|FP_D,	MX	},
-{"racl.ob", "X",	0x7800003f, 0xfffff83f,	WR_D|RD_MACC|FP_D,	MX|SB1	},
-{"racl.ob", "D",	0x4800003f, 0xfffff83f,	WR_D,			N54	},
-{"racl.qh", "X",	0x7820003f, 0xfffff83f,	WR_D|RD_MACC|FP_D,	MX	},
-{"racm.ob", "X",	0x7900003f, 0xfffff83f,	WR_D|RD_MACC|FP_D,	MX|SB1	},
-{"racm.ob", "D",	0x4900003f, 0xfffff83f,	WR_D,			N54	},
-{"racm.qh", "X",	0x7920003f, 0xfffff83f,	WR_D|RD_MACC|FP_D,	MX	},
-{"recip.d", "D,S",	0x46200015, 0xffff003f, WR_D|RD_S|FP_D,		I4	},
-{"recip.ps","D,S",	0x46c00015, 0xffff003f, WR_D|RD_S|FP_D,		SB1	},
-{"recip.s", "D,S",	0x46000015, 0xffff003f, WR_D|RD_S|FP_S,		I4	},
-{"recip1.d",  "D,S",	0x4620001d, 0xffff003f,	WR_D|RD_S|FP_D,		M3D	},
-{"recip1.ps", "D,S",	0x46c0001d, 0xffff003f,	WR_D|RD_S|FP_S,		M3D	},
-{"recip1.s",  "D,S",	0x4600001d, 0xffff003f,	WR_D|RD_S|FP_S,		M3D	},
-{"recip2.d",  "D,S,T",	0x4620001c, 0xffe0003f,	WR_D|RD_S|RD_T|FP_D,	M3D	},
-{"recip2.ps", "D,S,T",	0x46c0001c, 0xffe0003f,	WR_D|RD_S|RD_T|FP_S,	M3D	},
-{"recip2.s",  "D,S,T",	0x4600001c, 0xffe0003f,	WR_D|RD_S|RD_T|FP_S,	M3D	},
-{"rem",     "z,s,t",    0x0000001a, 0xfc00ffff, RD_s|RD_t|WR_HILO,      I1	},
-{"rem",     "d,v,t",	0,    (int) M_REM_3,	INSN_MACRO,		I1	},
-{"rem",     "d,v,I",	0,    (int) M_REM_3I,	INSN_MACRO,		I1	},
-{"remu",    "z,s,t",    0x0000001b, 0xfc00ffff, RD_s|RD_t|WR_HILO,      I1	},
-{"remu",    "d,v,t",	0,    (int) M_REMU_3,	INSN_MACRO,		I1	},
-{"remu",    "d,v,I",	0,    (int) M_REMU_3I,	INSN_MACRO,		I1	},
-{"rdhwr",   "t,K",	0x7c00003b, 0xffe007ff, WR_t,			I33	},
-{"rdpgpr",  "d,w",	0x41400000, 0xffe007ff, WR_d,			I33	},
-{"rfe",     "",		0x42000010, 0xffffffff,	0,			I1|T3	},
-{"rnas.qh", "X,Q",	0x78200025, 0xfc20f83f,	WR_D|RD_MACC|RD_T|FP_D,	MX	},
-{"rnau.ob", "X,Q",	0x78000021, 0xfc20f83f,	WR_D|RD_MACC|RD_T|FP_D,	MX|SB1	},
-{"rnau.qh", "X,Q",	0x78200021, 0xfc20f83f,	WR_D|RD_MACC|RD_T|FP_D,	MX	},
-{"rnes.qh", "X,Q",	0x78200026, 0xfc20f83f,	WR_D|RD_MACC|RD_T|FP_D,	MX	},
-{"rneu.ob", "X,Q",	0x78000022, 0xfc20f83f,	WR_D|RD_MACC|RD_T|FP_D,	MX|SB1	},
-{"rneu.qh", "X,Q",	0x78200022, 0xfc20f83f,	WR_D|RD_MACC|RD_T|FP_D,	MX	},
-{"rol",     "d,v,t",	0,    (int) M_ROL,	INSN_MACRO,		I1	},
-{"rol",     "d,v,I",	0,    (int) M_ROL_I,	INSN_MACRO,		I1	},
-{"ror",     "d,v,t",	0,    (int) M_ROR,	INSN_MACRO,		I1	},
-{"ror",     "d,v,I",	0,    (int) M_ROR_I,	INSN_MACRO,		I1	},
-{"ror",	    "d,w,<",	0x00200002, 0xffe0003f,	WR_d|RD_t,		N5|I33	},
-{"rorv",    "d,t,s",	0x00000046, 0xfc0007ff,	RD_t|RD_s|WR_d,		N5|I33	},
-{"rotl",    "d,v,t",	0,    (int) M_ROL,	INSN_MACRO,		I33	},
-{"rotl",    "d,v,I",	0,    (int) M_ROL_I,	INSN_MACRO,		I33	},
-{"rotr",    "d,v,t",	0,    (int) M_ROR,	INSN_MACRO,		I33	},
-{"rotr",    "d,v,I",	0,    (int) M_ROR_I,	INSN_MACRO,		I33	},
-{"rotrv",   "d,t,s",	0x00000046, 0xfc0007ff,	RD_t|RD_s|WR_d,		I33	},
-{"round.l.d", "D,S",	0x46200008, 0xffff003f, WR_D|RD_S|FP_D,		I3	},
-{"round.l.s", "D,S",	0x46000008, 0xffff003f, WR_D|RD_S|FP_S,		I3	},
-{"round.w.d", "D,S",	0x4620000c, 0xffff003f, WR_D|RD_S|FP_D,		I2	},
-{"round.w.s", "D,S",	0x4600000c, 0xffff003f, WR_D|RD_S|FP_S,		I2	},
-{"rsqrt.d", "D,S",	0x46200016, 0xffff003f, WR_D|RD_S|FP_D,		I4	},
-{"rsqrt.ps","D,S",	0x46c00016, 0xffff003f, WR_D|RD_S|FP_D,		SB1	},
-{"rsqrt.s", "D,S",	0x46000016, 0xffff003f, WR_D|RD_S|FP_S,		I4	},
-{"rsqrt1.d",  "D,S",	0x4620001e, 0xffff003f,	WR_D|RD_S|FP_D,		M3D	},
-{"rsqrt1.ps", "D,S",	0x46c0001e, 0xffff003f,	WR_D|RD_S|FP_S,		M3D	},
-{"rsqrt1.s",  "D,S",	0x4600001e, 0xffff003f,	WR_D|RD_S|FP_S,		M3D	},
-{"rsqrt2.d",  "D,S,T",	0x4620001f, 0xffe0003f,	WR_D|RD_S|RD_T|FP_D,	M3D	},
-{"rsqrt2.ps", "D,S,T",	0x46c0001f, 0xffe0003f,	WR_D|RD_S|RD_T|FP_S,	M3D	},
-{"rsqrt2.s",  "D,S,T",	0x4600001f, 0xffe0003f,	WR_D|RD_S|RD_T|FP_S,	M3D	},
-{"rzs.qh",  "X,Q",	0x78200024, 0xfc20f83f,	WR_D|RD_MACC|RD_T|FP_D,	MX	},
-{"rzu.ob",  "X,Q",	0x78000020, 0xfc20f83f,	WR_D|RD_MACC|RD_T|FP_D,	MX|SB1	},
-{"rzu.ob",  "D,k",	0x4bc00020, 0xffe0f83f,	WR_D|RD_S|RD_T,		N54	},
-{"rzu.qh",  "X,Q",	0x78200020, 0xfc20f83f,	WR_D|RD_MACC|RD_T|FP_D,	MX	},
-{"sb",      "t,o(b)",	0xa0000000, 0xfc000000,	SM|RD_t|RD_b,		I1	},
-{"sb",      "t,A(b)",	0,    (int) M_SB_AB,	INSN_MACRO,		I1	},
-{"sc",	    "t,o(b)",	0xe0000000, 0xfc000000, SM|RD_t|WR_t|RD_b,	I2	},
-{"sc",	    "t,A(b)",	0,    (int) M_SC_AB,	INSN_MACRO,		I2	},
-{"scd",	    "t,o(b)",	0xf0000000, 0xfc000000, SM|RD_t|WR_t|RD_b,	I3	},
-{"scd",	    "t,A(b)",	0,    (int) M_SCD_AB,	INSN_MACRO,		I3	},
-{"sd",	    "t,o(b)",	0xfc000000, 0xfc000000,	SM|RD_t|RD_b,		I3	},
-{"sd",      "t,o(b)",	0,    (int) M_SD_OB,	INSN_MACRO,		I1	},
-{"sd",      "t,A(b)",	0,    (int) M_SD_AB,	INSN_MACRO,		I1	},
-{"sdbbp",   "",		0x0000000e, 0xffffffff,	TRAP,           	G2	},
-{"sdbbp",   "c",	0x0000000e, 0xfc00ffff,	TRAP,			G2	},
-{"sdbbp",   "c,q",	0x0000000e, 0xfc00003f,	TRAP,			G2	},
-{"sdbbp",   "",         0x7000003f, 0xffffffff, TRAP,           	I32     },
-{"sdbbp",   "B",        0x7000003f, 0xfc00003f, TRAP,           	I32     },
-{"sdc1",    "T,o(b)",	0xf4000000, 0xfc000000, SM|RD_T|RD_b|FP_D,	I2	},
-{"sdc1",    "E,o(b)",	0xf4000000, 0xfc000000, SM|RD_T|RD_b|FP_D,	I2	},
-{"sdc1",    "T,A(b)",	0,    (int) M_SDC1_AB,	INSN_MACRO,		I2	},
-{"sdc1",    "E,A(b)",	0,    (int) M_SDC1_AB,	INSN_MACRO,		I2	},
-{"sdc2",    "E,o(b)",	0xf8000000, 0xfc000000, SM|RD_C2|RD_b,		I2	},
-{"sdc2",    "E,A(b)",	0,    (int) M_SDC2_AB,	INSN_MACRO,		I2	},
-{"sdc3",    "E,o(b)",	0xfc000000, 0xfc000000, SM|RD_C3|RD_b,		I2	},
-{"sdc3",    "E,A(b)",	0,    (int) M_SDC3_AB,	INSN_MACRO,		I2	},
-{"s.d",     "T,o(b)",	0xf4000000, 0xfc000000, SM|RD_T|RD_b|FP_D,	I2	},
-{"s.d",     "T,o(b)",	0,    (int) M_S_DOB,	INSN_MACRO,		I1	},
-{"s.d",     "T,A(b)",	0,    (int) M_S_DAB,	INSN_MACRO,		I1	},
-{"sdl",     "t,o(b)",	0xb0000000, 0xfc000000,	SM|RD_t|RD_b,		I3	},
-{"sdl",     "t,A(b)",	0,    (int) M_SDL_AB,	INSN_MACRO,		I3	},
-{"sdr",     "t,o(b)",	0xb4000000, 0xfc000000,	SM|RD_t|RD_b,		I3	},
-{"sdr",     "t,A(b)",	0,    (int) M_SDR_AB,	INSN_MACRO,		I3	},
-{"sdxc1",   "S,t(b)",   0x4c000009, 0xfc0007ff, SM|RD_S|RD_t|RD_b,	I4	},
-{"seb",     "d,w",	0x7c000420, 0xffe007ff,	WR_d|RD_t,		I33	},
-{"seh",     "d,w",	0x7c000620, 0xffe007ff,	WR_d|RD_t,		I33	},
-{"selsl",   "d,v,t",	0x00000005, 0xfc0007ff,	WR_d|RD_s|RD_t,		L1	},
-{"selsr",   "d,v,t",	0x00000001, 0xfc0007ff,	WR_d|RD_s|RD_t,		L1	},
-{"seq",     "d,v,t",	0,    (int) M_SEQ,	INSN_MACRO,		I1	},
-{"seq",     "d,v,I",	0,    (int) M_SEQ_I,	INSN_MACRO,		I1	},
-{"sge",     "d,v,t",	0,    (int) M_SGE,	INSN_MACRO,		I1	},
-{"sge",     "d,v,I",	0,    (int) M_SGE_I,	INSN_MACRO,		I1	},
-{"sgeu",    "d,v,t",	0,    (int) M_SGEU,	INSN_MACRO,		I1	},
-{"sgeu",    "d,v,I",	0,    (int) M_SGEU_I,	INSN_MACRO,		I1	},
-{"sgt",     "d,v,t",	0,    (int) M_SGT,	INSN_MACRO,		I1	},
-{"sgt",     "d,v,I",	0,    (int) M_SGT_I,	INSN_MACRO,		I1	},
-{"sgtu",    "d,v,t",	0,    (int) M_SGTU,	INSN_MACRO,		I1	},
-{"sgtu",    "d,v,I",	0,    (int) M_SGTU_I,	INSN_MACRO,		I1	},
-{"sh",      "t,o(b)",	0xa4000000, 0xfc000000,	SM|RD_t|RD_b,		I1	},
-{"sh",      "t,A(b)",	0,    (int) M_SH_AB,	INSN_MACRO,		I1	},
-{"shfl.bfla.qh", "X,Y,Z", 0x7a20001f, 0xffe0003f, WR_D|RD_S|RD_T|FP_D,	MX	},
-{"shfl.mixh.ob", "X,Y,Z", 0x7980001f, 0xffe0003f, WR_D|RD_S|RD_T|FP_D,	MX|SB1	},
-{"shfl.mixh.ob", "D,S,T", 0x4980001f, 0xffe0003f, WR_D|RD_S|RD_T, 	N54	},
-{"shfl.mixh.qh", "X,Y,Z", 0x7820001f, 0xffe0003f, WR_D|RD_S|RD_T|FP_D,	MX	},
-{"shfl.mixl.ob", "X,Y,Z", 0x79c0001f, 0xffe0003f, WR_D|RD_S|RD_T|FP_D,	MX|SB1	},
-{"shfl.mixl.ob", "D,S,T", 0x49c0001f, 0xffe0003f, WR_D|RD_S|RD_T, 	N54	},
-{"shfl.mixl.qh", "X,Y,Z", 0x78a0001f, 0xffe0003f, WR_D|RD_S|RD_T|FP_D,	MX	},
-{"shfl.pach.ob", "X,Y,Z", 0x7900001f, 0xffe0003f, WR_D|RD_S|RD_T|FP_D,	MX|SB1	},
-{"shfl.pach.ob", "D,S,T", 0x4900001f, 0xffe0003f, WR_D|RD_S|RD_T, 	N54	},
-{"shfl.pach.qh", "X,Y,Z", 0x7920001f, 0xffe0003f, WR_D|RD_S|RD_T|FP_D,	MX	},
-{"shfl.pacl.ob", "D,S,T", 0x4940001f, 0xffe0003f, WR_D|RD_S|RD_T, 	N54	},
-{"shfl.repa.qh", "X,Y,Z", 0x7b20001f, 0xffe0003f, WR_D|RD_S|RD_T|FP_D,	MX	},
-{"shfl.repb.qh", "X,Y,Z", 0x7ba0001f, 0xffe0003f, WR_D|RD_S|RD_T|FP_D,	MX	},
-{"shfl.upsl.ob", "X,Y,Z", 0x78c0001f, 0xffe0003f, WR_D|RD_S|RD_T|FP_D,	MX|SB1	},
-{"sle",     "d,v,t",	0,    (int) M_SLE,	INSN_MACRO,		I1	},
-{"sle",     "d,v,I",	0,    (int) M_SLE_I,	INSN_MACRO,		I1	},
-{"sleu",    "d,v,t",	0,    (int) M_SLEU,	INSN_MACRO,		I1	},
-{"sleu",    "d,v,I",	0,    (int) M_SLEU_I,	INSN_MACRO,		I1	},
-{"sllv",    "d,t,s",	0x00000004, 0xfc0007ff,	WR_d|RD_t|RD_s,		I1	},
-{"sll",     "d,w,s",	0x00000004, 0xfc0007ff,	WR_d|RD_t|RD_s,		I1	}, /* sllv */
-{"sll",     "d,w,<",	0x00000000, 0xffe0003f,	WR_d|RD_t,		I1	},
-{"sll.ob",  "X,Y,Q",	0x78000010, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	MX|SB1	},
-{"sll.ob",  "D,S,T[e]",	0x48000010, 0xfe20003f,	WR_D|RD_S|RD_T,		N54	},
-{"sll.ob",  "D,S,k",	0x4bc00010, 0xffe0003f,	WR_D|RD_S|RD_T,		N54	},
-{"sll.qh",  "X,Y,Q",	0x78200010, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	MX	},
-{"slt",     "d,v,t",	0x0000002a, 0xfc0007ff,	WR_d|RD_s|RD_t,		I1	},
-{"slt",     "d,v,I",	0,    (int) M_SLT_I,	INSN_MACRO,		I1	},
-{"slti",    "t,r,j",	0x28000000, 0xfc000000,	WR_t|RD_s,		I1	},
-{"sltiu",   "t,r,j",	0x2c000000, 0xfc000000,	WR_t|RD_s,		I1	},
-{"sltu",    "d,v,t",	0x0000002b, 0xfc0007ff,	WR_d|RD_s|RD_t,		I1	},
-{"sltu",    "d,v,I",	0,    (int) M_SLTU_I,	INSN_MACRO,		I1	},
-{"sne",     "d,v,t",	0,    (int) M_SNE,	INSN_MACRO,		I1	},
-{"sne",     "d,v,I",	0,    (int) M_SNE_I,	INSN_MACRO,		I1	},
-{"sqrt.d",  "D,S",	0x46200004, 0xffff003f, WR_D|RD_S|FP_D,		I2	},
-{"sqrt.s",  "D,S",	0x46000004, 0xffff003f, WR_D|RD_S|FP_S,		I2	},
-{"sqrt.ps", "D,S",	0x46c00004, 0xffff003f, WR_D|RD_S|FP_D,		SB1	},
-{"srav",    "d,t,s",	0x00000007, 0xfc0007ff,	WR_d|RD_t|RD_s,		I1	},
-{"sra",     "d,w,s",	0x00000007, 0xfc0007ff,	WR_d|RD_t|RD_s,		I1	}, /* srav */
-{"sra",     "d,w,<",	0x00000003, 0xffe0003f,	WR_d|RD_t,		I1	},
-{"sra.qh",  "X,Y,Q",	0x78200013, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	MX	},
-{"srlv",    "d,t,s",	0x00000006, 0xfc0007ff,	WR_d|RD_t|RD_s,		I1	},
-{"srl",     "d,w,s",	0x00000006, 0xfc0007ff,	WR_d|RD_t|RD_s,		I1	}, /* srlv */
-{"srl",     "d,w,<",	0x00000002, 0xffe0003f,	WR_d|RD_t,		I1	},
-{"srl.ob",  "X,Y,Q",	0x78000012, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	MX|SB1	},
-{"srl.ob",  "D,S,T[e]",	0x48000012, 0xfe20003f,	WR_D|RD_S|RD_T,		N54	},
-{"srl.ob",  "D,S,k",	0x4bc00012, 0xffe0003f,	WR_D|RD_S|RD_T,		N54	},
-{"srl.qh",  "X,Y,Q",	0x78200012, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	MX	},
+{"pul.ps",  "D,V,T",	0x46c0002e, 0xffe0003f,	WR_D|RD_S|RD_T|FP_D,	0,		I5|I33	},
+{"puu.ps",  "D,V,T",	0x46c0002f, 0xffe0003f,	WR_D|RD_S|RD_T|FP_D,	0,		I5|I33	},
+{"pperm",   "s,t",	0x70000481, 0xfc00ffff,	MOD_HILO|RD_s|RD_t,	0,		SMT	},
+{"rach.ob", "X",	0x7a00003f, 0xfffff83f,	WR_D|FP_D,		RD_MACC,	MX|SB1	},
+{"rach.ob", "D",	0x4a00003f, 0xfffff83f,	WR_D,			0,		N54	},
+{"rach.qh", "X",	0x7a20003f, 0xfffff83f,	WR_D|FP_D,		RD_MACC,	MX	},
+{"racl.ob", "X",	0x7800003f, 0xfffff83f,	WR_D|FP_D,		RD_MACC,	MX|SB1	},
+{"racl.ob", "D",	0x4800003f, 0xfffff83f,	WR_D,			0,		N54	},
+{"racl.qh", "X",	0x7820003f, 0xfffff83f,	WR_D|FP_D,		RD_MACC,	MX	},
+{"racm.ob", "X",	0x7900003f, 0xfffff83f,	WR_D|FP_D,		RD_MACC,	MX|SB1	},
+{"racm.ob", "D",	0x4900003f, 0xfffff83f,	WR_D,			0,		N54	},
+{"racm.qh", "X",	0x7920003f, 0xfffff83f,	WR_D|FP_D,		RD_MACC,	MX	},
+{"recip.d", "D,S",	0x46200015, 0xffff003f, WR_D|RD_S|FP_D,		0,		I4|I33	},
+{"recip.ps","D,S",	0x46c00015, 0xffff003f, WR_D|RD_S|FP_D,		0,		SB1	},
+{"recip.s", "D,S",	0x46000015, 0xffff003f, WR_D|RD_S|FP_S,		0,		I4|I33	},
+{"recip1.d",  "D,S",	0x4620001d, 0xffff003f,	WR_D|RD_S|FP_D,		0,		M3D	},
+{"recip1.ps", "D,S",	0x46c0001d, 0xffff003f,	WR_D|RD_S|FP_S,		0,		M3D	},
+{"recip1.s",  "D,S",	0x4600001d, 0xffff003f,	WR_D|RD_S|FP_S,		0,		M3D	},
+{"recip2.d",  "D,S,T",	0x4620001c, 0xffe0003f,	WR_D|RD_S|RD_T|FP_D,	0,		M3D	},
+{"recip2.ps", "D,S,T",	0x46c0001c, 0xffe0003f,	WR_D|RD_S|RD_T|FP_S,	0,		M3D	},
+{"recip2.s",  "D,S,T",	0x4600001c, 0xffe0003f,	WR_D|RD_S|RD_T|FP_S,	0,		M3D	},
+{"rem",     "z,s,t",    0x0000001a, 0xfc00ffff, RD_s|RD_t|WR_HILO,      0,		I1	},
+{"rem",     "d,v,t",	0,    (int) M_REM_3,	INSN_MACRO,		0,		I1	},
+{"rem",     "d,v,I",	0,    (int) M_REM_3I,	INSN_MACRO,		0,		I1	},
+{"remu",    "z,s,t",    0x0000001b, 0xfc00ffff, RD_s|RD_t|WR_HILO,      0,		I1	},
+{"remu",    "d,v,t",	0,    (int) M_REMU_3,	INSN_MACRO,		0,		I1	},
+{"remu",    "d,v,I",	0,    (int) M_REMU_3I,	INSN_MACRO,		0,		I1	},
+{"rdhwr",   "t,K",	0x7c00003b, 0xffe007ff, WR_t,			0,		I33	},
+{"rdpgpr",  "d,w",	0x41400000, 0xffe007ff, WR_d,			0,		I33	},
+{"rfe",     "",		0x42000010, 0xffffffff,	0,			0,		I1|T3	},
+{"rnas.qh", "X,Q",	0x78200025, 0xfc20f83f,	WR_D|RD_T|FP_D,		RD_MACC,	MX	},
+{"rnau.ob", "X,Q",	0x78000021, 0xfc20f83f,	WR_D|RD_T|FP_D,		RD_MACC,	MX|SB1	},
+{"rnau.qh", "X,Q",	0x78200021, 0xfc20f83f,	WR_D|RD_T|FP_D,		RD_MACC,	MX	},
+{"rnes.qh", "X,Q",	0x78200026, 0xfc20f83f,	WR_D|RD_T|FP_D,		RD_MACC,	MX	},
+{"rneu.ob", "X,Q",	0x78000022, 0xfc20f83f,	WR_D|RD_T|FP_D,		RD_MACC,	MX|SB1	},
+{"rneu.qh", "X,Q",	0x78200022, 0xfc20f83f,	WR_D|RD_T|FP_D,		RD_MACC,	MX	},
+{"rol",     "d,v,t",	0,    (int) M_ROL,	INSN_MACRO,		0,		I1	},
+{"rol",     "d,v,I",	0,    (int) M_ROL_I,	INSN_MACRO,		0,		I1	},
+{"ror",     "d,v,t",	0,    (int) M_ROR,	INSN_MACRO,		0,		I1	},
+{"ror",     "d,v,I",	0,    (int) M_ROR_I,	INSN_MACRO,		0,		I1	},
+{"ror",	    "d,w,<",	0x00200002, 0xffe0003f,	WR_d|RD_t,		0,		N5|I33|SMT },
+{"rorv",    "d,t,s",	0x00000046, 0xfc0007ff,	RD_t|RD_s|WR_d,		0,		N5|I33|SMT },
+{"rotl",    "d,v,t",	0,    (int) M_ROL,	INSN_MACRO,		0,		I33|SMT	},
+{"rotl",    "d,v,I",	0,    (int) M_ROL_I,	INSN_MACRO,		0,		I33|SMT	},
+{"rotr",    "d,v,t",	0,    (int) M_ROR,	INSN_MACRO,		0,		I33|SMT	},
+{"rotr",    "d,v,I",	0,    (int) M_ROR_I,	INSN_MACRO,		0,		I33|SMT	},
+{"rotrv",   "d,t,s",	0x00000046, 0xfc0007ff,	RD_t|RD_s|WR_d,		0,		I33|SMT	},
+{"round.l.d", "D,S",	0x46200008, 0xffff003f, WR_D|RD_S|FP_D,		0,		I3|I33	},
+{"round.l.s", "D,S",	0x46000008, 0xffff003f, WR_D|RD_S|FP_S|FP_D,	0,		I3|I33	},
+{"round.w.d", "D,S",	0x4620000c, 0xffff003f, WR_D|RD_S|FP_S|FP_D,	0,		I2	},
+{"round.w.s", "D,S",	0x4600000c, 0xffff003f, WR_D|RD_S|FP_S,		0,		I2	},
+{"rsqrt.d", "D,S",	0x46200016, 0xffff003f, WR_D|RD_S|FP_D,		0,		I4|I33	},
+{"rsqrt.ps","D,S",	0x46c00016, 0xffff003f, WR_D|RD_S|FP_D,		0,		SB1	},
+{"rsqrt.s", "D,S",	0x46000016, 0xffff003f, WR_D|RD_S|FP_S,		0,		I4|I33	},
+{"rsqrt1.d",  "D,S",	0x4620001e, 0xffff003f,	WR_D|RD_S|FP_D,		0,		M3D	},
+{"rsqrt1.ps", "D,S",	0x46c0001e, 0xffff003f,	WR_D|RD_S|FP_S,		0,		M3D	},
+{"rsqrt1.s",  "D,S",	0x4600001e, 0xffff003f,	WR_D|RD_S|FP_S,		0,		M3D	},
+{"rsqrt2.d",  "D,S,T",	0x4620001f, 0xffe0003f,	WR_D|RD_S|RD_T|FP_D,	0,		M3D	},
+{"rsqrt2.ps", "D,S,T",	0x46c0001f, 0xffe0003f,	WR_D|RD_S|RD_T|FP_S,	0,		M3D	},
+{"rsqrt2.s",  "D,S,T",	0x4600001f, 0xffe0003f,	WR_D|RD_S|RD_T|FP_S,	0,		M3D	},
+{"rzs.qh",  "X,Q",	0x78200024, 0xfc20f83f,	WR_D|RD_T|FP_D,		RD_MACC,	MX	},
+{"rzu.ob",  "X,Q",	0x78000020, 0xfc20f83f,	WR_D|RD_T|FP_D,		RD_MACC,	MX|SB1	},
+{"rzu.ob",  "D,k",	0x4bc00020, 0xffe0f83f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"rzu.qh",  "X,Q",	0x78200020, 0xfc20f83f,	WR_D|RD_T|FP_D,		RD_MACC,	MX	},
+{"sb",      "t,o(b)",	0xa0000000, 0xfc000000,	SM|RD_t|RD_b,		0,		I1	},
+{"sb",      "t,A(b)",	0,    (int) M_SB_AB,	INSN_MACRO,		0,		I1	},
+{"sc",	    "t,o(b)",	0xe0000000, 0xfc000000, SM|RD_t|WR_t|RD_b,	0,		I2	},
+{"sc",	    "t,A(b)",	0,    (int) M_SC_AB,	INSN_MACRO,		0,		I2	},
+{"scd",	    "t,o(b)",	0xf0000000, 0xfc000000, SM|RD_t|WR_t|RD_b,	0,		I3	},
+{"scd",	    "t,A(b)",	0,    (int) M_SCD_AB,	INSN_MACRO,		0,		I3	},
+{"sd",	    "t,o(b)",	0xfc000000, 0xfc000000,	SM|RD_t|RD_b,		0,		I3	},
+{"sd",      "t,o(b)",	0,    (int) M_SD_OB,	INSN_MACRO,		0,		I1	},
+{"sd",      "t,A(b)",	0,    (int) M_SD_AB,	INSN_MACRO,		0,		I1	},
+{"sdbbp",   "",		0x0000000e, 0xffffffff,	TRAP,           	0,		G2	},
+{"sdbbp",   "c",	0x0000000e, 0xfc00ffff,	TRAP,			0,		G2	},
+{"sdbbp",   "c,q",	0x0000000e, 0xfc00003f,	TRAP,			0,		G2	},
+{"sdbbp",   "",         0x7000003f, 0xffffffff, TRAP,           	0,		I32     },
+{"sdbbp",   "B",        0x7000003f, 0xfc00003f, TRAP,           	0,		I32     },
+{"sdc1",    "T,o(b)",	0xf4000000, 0xfc000000, SM|RD_T|RD_b|FP_D,	0,		I2	},
+{"sdc1",    "E,o(b)",	0xf4000000, 0xfc000000, SM|RD_T|RD_b|FP_D,	0,		I2	},
+{"sdc1",    "T,A(b)",	0,    (int) M_SDC1_AB,	INSN_MACRO,		0,		I2	},
+{"sdc1",    "E,A(b)",	0,    (int) M_SDC1_AB,	INSN_MACRO,		0,		I2	},
+{"sdc2",    "E,o(b)",	0xf8000000, 0xfc000000, SM|RD_C2|RD_b,		0,		I2	},
+{"sdc2",    "E,A(b)",	0,    (int) M_SDC2_AB,	INSN_MACRO,		0,		I2	},
+{"sdc3",    "E,o(b)",	0xfc000000, 0xfc000000, SM|RD_C3|RD_b,		0,		I2	},
+{"sdc3",    "E,A(b)",	0,    (int) M_SDC3_AB,	INSN_MACRO,		0,		I2	},
+{"s.d",     "T,o(b)",	0xf4000000, 0xfc000000, SM|RD_T|RD_b|FP_D,	0,		I2	},
+{"s.d",     "T,o(b)",	0,    (int) M_S_DOB,	INSN_MACRO,		0,		I1	},
+{"s.d",     "T,A(b)",	0,    (int) M_S_DAB,	INSN_MACRO,		0,		I1	},
+{"sdl",     "t,o(b)",	0xb0000000, 0xfc000000,	SM|RD_t|RD_b,		0,		I3	},
+{"sdl",     "t,A(b)",	0,    (int) M_SDL_AB,	INSN_MACRO,		0,		I3	},
+{"sdr",     "t,o(b)",	0xb4000000, 0xfc000000,	SM|RD_t|RD_b,		0,		I3	},
+{"sdr",     "t,A(b)",	0,    (int) M_SDR_AB,	INSN_MACRO,		0,		I3	},
+{"sdxc1",   "S,t(b)",   0x4c000009, 0xfc0007ff, SM|RD_S|RD_t|RD_b|FP_D,	0,		I4|I33	},
+{"seb",     "d,w",	0x7c000420, 0xffe007ff,	WR_d|RD_t,		0,		I33	},
+{"seh",     "d,w",	0x7c000620, 0xffe007ff,	WR_d|RD_t,		0,		I33	},
+{"selsl",   "d,v,t",	0x00000005, 0xfc0007ff,	WR_d|RD_s|RD_t,		0,		L1	},
+{"selsr",   "d,v,t",	0x00000001, 0xfc0007ff,	WR_d|RD_s|RD_t,		0,		L1	},
+{"seq",     "d,v,t",	0,    (int) M_SEQ,	INSN_MACRO,		0,		I1	},
+{"seq",     "d,v,I",	0,    (int) M_SEQ_I,	INSN_MACRO,		0,		I1	},
+{"sge",     "d,v,t",	0,    (int) M_SGE,	INSN_MACRO,		0,		I1	},
+{"sge",     "d,v,I",	0,    (int) M_SGE_I,	INSN_MACRO,		0,		I1	},
+{"sgeu",    "d,v,t",	0,    (int) M_SGEU,	INSN_MACRO,		0,		I1	},
+{"sgeu",    "d,v,I",	0,    (int) M_SGEU_I,	INSN_MACRO,		0,		I1	},
+{"sgt",     "d,v,t",	0,    (int) M_SGT,	INSN_MACRO,		0,		I1	},
+{"sgt",     "d,v,I",	0,    (int) M_SGT_I,	INSN_MACRO,		0,		I1	},
+{"sgtu",    "d,v,t",	0,    (int) M_SGTU,	INSN_MACRO,		0,		I1	},
+{"sgtu",    "d,v,I",	0,    (int) M_SGTU_I,	INSN_MACRO,		0,		I1	},
+{"sh",      "t,o(b)",	0xa4000000, 0xfc000000,	SM|RD_t|RD_b,		0,		I1	},
+{"sh",      "t,A(b)",	0,    (int) M_SH_AB,	INSN_MACRO,		0,		I1	},
+{"shfl.bfla.qh", "X,Y,Z", 0x7a20001f, 0xffe0003f, WR_D|RD_S|RD_T|FP_D,	0,		MX	},
+{"shfl.mixh.ob", "X,Y,Z", 0x7980001f, 0xffe0003f, WR_D|RD_S|RD_T|FP_D,	0,		MX|SB1	},
+{"shfl.mixh.ob", "D,S,T", 0x4980001f, 0xffe0003f, WR_D|RD_S|RD_T, 	0,		N54	},
+{"shfl.mixh.qh", "X,Y,Z", 0x7820001f, 0xffe0003f, WR_D|RD_S|RD_T|FP_D,	0,		MX	},
+{"shfl.mixl.ob", "X,Y,Z", 0x79c0001f, 0xffe0003f, WR_D|RD_S|RD_T|FP_D,	0,		MX|SB1	},
+{"shfl.mixl.ob", "D,S,T", 0x49c0001f, 0xffe0003f, WR_D|RD_S|RD_T, 	0,		N54	},
+{"shfl.mixl.qh", "X,Y,Z", 0x78a0001f, 0xffe0003f, WR_D|RD_S|RD_T|FP_D,	0,		MX	},
+{"shfl.pach.ob", "X,Y,Z", 0x7900001f, 0xffe0003f, WR_D|RD_S|RD_T|FP_D,	0,		MX|SB1	},
+{"shfl.pach.ob", "D,S,T", 0x4900001f, 0xffe0003f, WR_D|RD_S|RD_T, 	0,		N54	},
+{"shfl.pach.qh", "X,Y,Z", 0x7920001f, 0xffe0003f, WR_D|RD_S|RD_T|FP_D,	0,		MX	},
+{"shfl.pacl.ob", "D,S,T", 0x4940001f, 0xffe0003f, WR_D|RD_S|RD_T, 	0,		N54	},
+{"shfl.repa.qh", "X,Y,Z", 0x7b20001f, 0xffe0003f, WR_D|RD_S|RD_T|FP_D,	0,		MX	},
+{"shfl.repb.qh", "X,Y,Z", 0x7ba0001f, 0xffe0003f, WR_D|RD_S|RD_T|FP_D,	0,		MX	},
+{"shfl.upsl.ob", "X,Y,Z", 0x78c0001f, 0xffe0003f, WR_D|RD_S|RD_T|FP_D,	0,		MX|SB1	},
+{"sle",     "d,v,t",	0,    (int) M_SLE,	INSN_MACRO,		0,		I1	},
+{"sle",     "d,v,I",	0,    (int) M_SLE_I,	INSN_MACRO,		0,		I1	},
+{"sleu",    "d,v,t",	0,    (int) M_SLEU,	INSN_MACRO,		0,		I1	},
+{"sleu",    "d,v,I",	0,    (int) M_SLEU_I,	INSN_MACRO,		0,		I1	},
+{"sllv",    "d,t,s",	0x00000004, 0xfc0007ff,	WR_d|RD_t|RD_s,		0,		I1	},
+{"sll",     "d,w,s",	0x00000004, 0xfc0007ff,	WR_d|RD_t|RD_s,		0,		I1	}, /* sllv */
+{"sll",     "d,w,<",	0x00000000, 0xffe0003f,	WR_d|RD_t,		0,		I1	},
+{"sll.ob",  "X,Y,Q",	0x78000010, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	0,		MX|SB1	},
+{"sll.ob",  "D,S,T[e]",	0x48000010, 0xfe20003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"sll.ob",  "D,S,k",	0x4bc00010, 0xffe0003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"sll.qh",  "X,Y,Q",	0x78200010, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	0,		MX	},
+{"slt",     "d,v,t",	0x0000002a, 0xfc0007ff,	WR_d|RD_s|RD_t,		0,		I1	},
+{"slt",     "d,v,I",	0,    (int) M_SLT_I,	INSN_MACRO,		0,		I1	},
+{"slti",    "t,r,j",	0x28000000, 0xfc000000,	WR_t|RD_s,		0,		I1	},
+{"sltiu",   "t,r,j",	0x2c000000, 0xfc000000,	WR_t|RD_s,		0,		I1	},
+{"sltu",    "d,v,t",	0x0000002b, 0xfc0007ff,	WR_d|RD_s|RD_t,		0,		I1	},
+{"sltu",    "d,v,I",	0,    (int) M_SLTU_I,	INSN_MACRO,		0,		I1	},
+{"sne",     "d,v,t",	0,    (int) M_SNE,	INSN_MACRO,		0,		I1	},
+{"sne",     "d,v,I",	0,    (int) M_SNE_I,	INSN_MACRO,		0,		I1	},
+{"sqrt.d",  "D,S",	0x46200004, 0xffff003f, WR_D|RD_S|FP_D,		0,		I2	},
+{"sqrt.s",  "D,S",	0x46000004, 0xffff003f, WR_D|RD_S|FP_S,		0,		I2	},
+{"sqrt.ps", "D,S",	0x46c00004, 0xffff003f, WR_D|RD_S|FP_D,		0,		SB1	},
+{"srav",    "d,t,s",	0x00000007, 0xfc0007ff,	WR_d|RD_t|RD_s,		0,		I1	},
+{"sra",     "d,w,s",	0x00000007, 0xfc0007ff,	WR_d|RD_t|RD_s,		0,		I1	}, /* srav */
+{"sra",     "d,w,<",	0x00000003, 0xffe0003f,	WR_d|RD_t,		0,		I1	},
+{"sra.qh",  "X,Y,Q",	0x78200013, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	0,		MX	},
+{"srlv",    "d,t,s",	0x00000006, 0xfc0007ff,	WR_d|RD_t|RD_s,		0,		I1	},
+{"srl",     "d,w,s",	0x00000006, 0xfc0007ff,	WR_d|RD_t|RD_s,		0,		I1	}, /* srlv */
+{"srl",     "d,w,<",	0x00000002, 0xffe0003f,	WR_d|RD_t,		0,		I1	},
+{"srl.ob",  "X,Y,Q",	0x78000012, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	0,		MX|SB1	},
+{"srl.ob",  "D,S,T[e]",	0x48000012, 0xfe20003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"srl.ob",  "D,S,k",	0x4bc00012, 0xffe0003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"srl.qh",  "X,Y,Q",	0x78200012, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	0,		MX	},
 /* ssnop is at the start of the table.  */
-{"standby", "",         0x42000021, 0xffffffff,	0,			V1	},
-{"sub",     "d,v,t",	0x00000022, 0xfc0007ff,	WR_d|RD_s|RD_t,		I1	},
-{"sub",     "d,v,I",	0,    (int) M_SUB_I,	INSN_MACRO,		I1	},
-{"sub.d",   "D,V,T",	0x46200001, 0xffe0003f,	WR_D|RD_S|RD_T|FP_D,	I1	},
-{"sub.s",   "D,V,T",	0x46000001, 0xffe0003f,	WR_D|RD_S|RD_T|FP_S,	I1	},
-{"sub.ob",  "X,Y,Q",	0x7800000a, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	MX|SB1	},
-{"sub.ob",  "D,S,T",	0x4ac0000a, 0xffe0003f,	WR_D|RD_S|RD_T,		N54	},
-{"sub.ob",  "D,S,T[e]",	0x4800000a, 0xfe20003f,	WR_D|RD_S|RD_T,		N54	},
-{"sub.ob",  "D,S,k",	0x4bc0000a, 0xffe0003f,	WR_D|RD_S|RD_T,		N54	},
-{"sub.ps",  "D,V,T",	0x46c00001, 0xffe0003f,	WR_D|RD_S|RD_T|FP_D,	I5	},
-{"sub.qh",  "X,Y,Q",	0x7820000a, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	MX	},
-{"suba.ob", "Y,Q",	0x78000036, 0xfc2007ff,	WR_MACC|RD_S|RD_T|FP_D,	MX|SB1	},
-{"suba.qh", "Y,Q",	0x78200036, 0xfc2007ff,	WR_MACC|RD_S|RD_T|FP_D,	MX	},
-{"subl.ob", "Y,Q",	0x78000436, 0xfc2007ff,	WR_MACC|RD_S|RD_T|FP_D,	MX|SB1	},
-{"subl.qh", "Y,Q",	0x78200436, 0xfc2007ff,	WR_MACC|RD_S|RD_T|FP_D,	MX	},
-{"subu",    "d,v,t",	0x00000023, 0xfc0007ff,	WR_d|RD_s|RD_t,		I1	},
-{"subu",    "d,v,I",	0,    (int) M_SUBU_I,	INSN_MACRO,		I1	},
-{"suspend", "",         0x42000022, 0xffffffff,	0,			V1	},
-{"suxc1",   "S,t(b)",   0x4c00000d, 0xfc0007ff, SM|RD_S|RD_t|RD_b,	I5|N55	},
-{"sw",      "t,o(b)",	0xac000000, 0xfc000000,	SM|RD_t|RD_b,		I1	},
-{"sw",      "t,A(b)",	0,    (int) M_SW_AB,	INSN_MACRO,		I1	},
-{"swc0",    "E,o(b)",	0xe0000000, 0xfc000000,	SM|RD_C0|RD_b,		I1	},
-{"swc0",    "E,A(b)",	0,    (int) M_SWC0_AB,	INSN_MACRO,		I1	},
-{"swc1",    "T,o(b)",	0xe4000000, 0xfc000000,	SM|RD_T|RD_b|FP_S,	I1	},
-{"swc1",    "E,o(b)",	0xe4000000, 0xfc000000,	SM|RD_T|RD_b|FP_S,	I1	},
-{"swc1",    "T,A(b)",	0,    (int) M_SWC1_AB,	INSN_MACRO,		I1	},
-{"swc1",    "E,A(b)",	0,    (int) M_SWC1_AB,	INSN_MACRO,		I1	},
-{"s.s",     "T,o(b)",	0xe4000000, 0xfc000000,	SM|RD_T|RD_b|FP_S,	I1	}, /* swc1 */
-{"s.s",     "T,A(b)",	0,    (int) M_SWC1_AB,	INSN_MACRO,		I1	},
-{"swc2",    "E,o(b)",	0xe8000000, 0xfc000000,	SM|RD_C2|RD_b,		I1	},
-{"swc2",    "E,A(b)",	0,    (int) M_SWC2_AB,	INSN_MACRO,		I1	},
-{"swc3",    "E,o(b)",	0xec000000, 0xfc000000,	SM|RD_C3|RD_b,		I1	},
-{"swc3",    "E,A(b)",	0,    (int) M_SWC3_AB,	INSN_MACRO,		I1	},
-{"swl",     "t,o(b)",	0xa8000000, 0xfc000000,	SM|RD_t|RD_b,		I1	},
-{"swl",     "t,A(b)",	0,    (int) M_SWL_AB,	INSN_MACRO,		I1	},
-{"scache",  "t,o(b)",	0xa8000000, 0xfc000000,	RD_t|RD_b,		I2	}, /* same */
-{"scache",  "t,A(b)",	0,    (int) M_SWL_AB,	INSN_MACRO,		I2	}, /* as swl */
-{"swr",     "t,o(b)",	0xb8000000, 0xfc000000,	SM|RD_t|RD_b,		I1	},
-{"swr",     "t,A(b)",	0,    (int) M_SWR_AB,	INSN_MACRO,		I1	},
-{"invalidate", "t,o(b)",0xb8000000, 0xfc000000,	RD_t|RD_b,		I2	}, /* same */
-{"invalidate", "t,A(b)",0,    (int) M_SWR_AB,	INSN_MACRO,		I2	}, /* as swr */
-{"swxc1",   "S,t(b)",   0x4c000008, 0xfc0007ff, SM|RD_S|RD_t|RD_b,	I4	},
-{"sync",    "",		0x0000000f, 0xffffffff,	INSN_SYNC,		I2|G1	},
-{"sync.p",  "",		0x0000040f, 0xffffffff,	INSN_SYNC,		I2	},
-{"sync.l",  "",		0x0000000f, 0xffffffff,	INSN_SYNC,		I2	},
-{"synci",   "o(b)",	0x041f0000, 0xfc1f0000,	SM|RD_b,		I33	},
-{"syscall", "",		0x0000000c, 0xffffffff,	TRAP,			I1	},
-{"syscall", "B",	0x0000000c, 0xfc00003f,	TRAP,			I1	},
-{"teqi",    "s,j",	0x040c0000, 0xfc1f0000, RD_s|TRAP,		I2	},
-{"teq",	    "s,t",	0x00000034, 0xfc00ffff, RD_s|RD_t|TRAP,		I2	},
-{"teq",	    "s,t,q",	0x00000034, 0xfc00003f, RD_s|RD_t|TRAP,		I2	},
-{"teq",     "s,j",	0x040c0000, 0xfc1f0000, RD_s|TRAP,		I2	}, /* teqi */
-{"teq",     "s,I",	0,    (int) M_TEQ_I,	INSN_MACRO,		I2	},
-{"tgei",    "s,j",	0x04080000, 0xfc1f0000, RD_s|TRAP,		I2	},
-{"tge",	    "s,t",	0x00000030, 0xfc00ffff,	RD_s|RD_t|TRAP,		I2	},
-{"tge",	    "s,t,q",	0x00000030, 0xfc00003f,	RD_s|RD_t|TRAP,		I2	},
-{"tge",     "s,j",	0x04080000, 0xfc1f0000, RD_s|TRAP,		I2	}, /* tgei */
-{"tge",	    "s,I",	0,    (int) M_TGE_I,    INSN_MACRO,		I2	},
-{"tgeiu",   "s,j",	0x04090000, 0xfc1f0000, RD_s|TRAP,		I2	},
-{"tgeu",    "s,t",	0x00000031, 0xfc00ffff, RD_s|RD_t|TRAP,		I2	},
-{"tgeu",    "s,t,q",	0x00000031, 0xfc00003f, RD_s|RD_t|TRAP,		I2	},
-{"tgeu",    "s,j",	0x04090000, 0xfc1f0000, RD_s|TRAP,		I2	}, /* tgeiu */
-{"tgeu",    "s,I",	0,    (int) M_TGEU_I,	INSN_MACRO,		I2	},
-{"tlbp",    "",         0x42000008, 0xffffffff, INSN_TLB,       	I1   	},
-{"tlbr",    "",         0x42000001, 0xffffffff, INSN_TLB,       	I1   	},
-{"tlbwi",   "",         0x42000002, 0xffffffff, INSN_TLB,       	I1   	},
-{"tlbwr",   "",         0x42000006, 0xffffffff, INSN_TLB,       	I1   	},
-{"tlti",    "s,j",	0x040a0000, 0xfc1f0000,	RD_s|TRAP,		I2	},
-{"tlt",     "s,t",	0x00000032, 0xfc00ffff, RD_s|RD_t|TRAP,		I2	},
-{"tlt",     "s,t,q",	0x00000032, 0xfc00003f, RD_s|RD_t|TRAP,		I2	},
-{"tlt",     "s,j",	0x040a0000, 0xfc1f0000,	RD_s|TRAP,		I2	}, /* tlti */
-{"tlt",     "s,I",	0,    (int) M_TLT_I,	INSN_MACRO,		I2	},
-{"tltiu",   "s,j",	0x040b0000, 0xfc1f0000, RD_s|TRAP,		I2	},
-{"tltu",    "s,t",	0x00000033, 0xfc00ffff, RD_s|RD_t|TRAP,		I2	},
-{"tltu",    "s,t,q",	0x00000033, 0xfc00003f, RD_s|RD_t|TRAP,		I2	},
-{"tltu",    "s,j",	0x040b0000, 0xfc1f0000, RD_s|TRAP,		I2	}, /* tltiu */
-{"tltu",    "s,I",	0,    (int) M_TLTU_I,	INSN_MACRO,		I2	},
-{"tnei",    "s,j",	0x040e0000, 0xfc1f0000, RD_s|TRAP,		I2	},
-{"tne",     "s,t",	0x00000036, 0xfc00ffff, RD_s|RD_t|TRAP,		I2	},
-{"tne",     "s,t,q",	0x00000036, 0xfc00003f, RD_s|RD_t|TRAP,		I2	},
-{"tne",     "s,j",	0x040e0000, 0xfc1f0000, RD_s|TRAP,		I2	}, /* tnei */
-{"tne",     "s,I",	0,    (int) M_TNE_I,	INSN_MACRO,		I2	},
-{"trunc.l.d", "D,S",	0x46200009, 0xffff003f, WR_D|RD_S|FP_D,		I3	},
-{"trunc.l.s", "D,S",	0x46000009, 0xffff003f,	WR_D|RD_S|FP_S,		I3	},
-{"trunc.w.d", "D,S",	0x4620000d, 0xffff003f, WR_D|RD_S|FP_D,		I2	},
-{"trunc.w.d", "D,S,x",	0x4620000d, 0xffff003f, WR_D|RD_S|FP_D,		I2	},
-{"trunc.w.d", "D,S,t",	0,    (int) M_TRUNCWD,	INSN_MACRO,		I1	},
-{"trunc.w.s", "D,S",	0x4600000d, 0xffff003f,	WR_D|RD_S|FP_S,		I2	},
-{"trunc.w.s", "D,S,x",	0x4600000d, 0xffff003f,	WR_D|RD_S|FP_S,		I2	},
-{"trunc.w.s", "D,S,t",	0,    (int) M_TRUNCWS,	INSN_MACRO,		I1	},
-{"uld",     "t,o(b)",	0,    (int) M_ULD,	INSN_MACRO,		I3	},
-{"uld",     "t,A(b)",	0,    (int) M_ULD_A,	INSN_MACRO,		I3	},
-{"ulh",     "t,o(b)",	0,    (int) M_ULH,	INSN_MACRO,		I1	},
-{"ulh",     "t,A(b)",	0,    (int) M_ULH_A,	INSN_MACRO,		I1	},
-{"ulhu",    "t,o(b)",	0,    (int) M_ULHU,	INSN_MACRO,		I1	},
-{"ulhu",    "t,A(b)",	0,    (int) M_ULHU_A,	INSN_MACRO,		I1	},
-{"ulw",     "t,o(b)",	0,    (int) M_ULW,	INSN_MACRO,		I1	},
-{"ulw",     "t,A(b)",	0,    (int) M_ULW_A,	INSN_MACRO,		I1	},
-{"usd",     "t,o(b)",	0,    (int) M_USD,	INSN_MACRO,		I3	},
-{"usd",     "t,A(b)",	0,    (int) M_USD_A,	INSN_MACRO,		I3	},
-{"ush",     "t,o(b)",	0,    (int) M_USH,	INSN_MACRO,		I1	},
-{"ush",     "t,A(b)",	0,    (int) M_USH_A,	INSN_MACRO,		I1	},
-{"usw",     "t,o(b)",	0,    (int) M_USW,	INSN_MACRO,		I1	},
-{"usw",     "t,A(b)",	0,    (int) M_USW_A,	INSN_MACRO,		I1	},
-{"wach.ob", "Y",	0x7a00003e, 0xffff07ff,	WR_MACC|RD_S|FP_D,	MX|SB1	},
-{"wach.ob", "S",	0x4a00003e, 0xffff07ff,	RD_S,			N54	},
-{"wach.qh", "Y",	0x7a20003e, 0xffff07ff,	WR_MACC|RD_S|FP_D,	MX	},
-{"wacl.ob", "Y,Z",	0x7800003e, 0xffe007ff,	WR_MACC|RD_S|RD_T|FP_D,	MX|SB1	},
-{"wacl.ob", "S,T",	0x4800003e, 0xffe007ff,	RD_S|RD_T,		N54	},
-{"wacl.qh", "Y,Z",	0x7820003e, 0xffe007ff,	WR_MACC|RD_S|RD_T|FP_D,	MX	},
-{"wait",    "",         0x42000020, 0xffffffff, TRAP,   		I3|I32	},
-{"wait",    "J",        0x42000020, 0xfe00003f, TRAP,   		I32|N55	},
-{"waiti",   "",		0x42000020, 0xffffffff,	TRAP,			L1	},
-{"wb", 	    "o(b)",	0xbc040000, 0xfc1f0000, SM|RD_b,		L1	},
-{"wrpgpr",  "d,w",	0x41c00000, 0xffe007ff, RD_t,			I33	},
-{"wsbh",    "d,w",	0x7c0000a0, 0xffe007ff,	WR_d|RD_t,		I33	},
-{"xor",     "d,v,t",	0x00000026, 0xfc0007ff,	WR_d|RD_s|RD_t,		I1	},
-{"xor",     "t,r,I",	0,    (int) M_XOR_I,	INSN_MACRO,		I1	},
-{"xor.ob",  "X,Y,Q",	0x7800000d, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	MX|SB1	},
-{"xor.ob",  "D,S,T",	0x4ac0000d, 0xffe0003f,	WR_D|RD_S|RD_T,		N54	},
-{"xor.ob",  "D,S,T[e]",	0x4800000d, 0xfe20003f,	WR_D|RD_S|RD_T,		N54	},
-{"xor.ob",  "D,S,k",	0x4bc0000d, 0xffe0003f,	WR_D|RD_S|RD_T,		N54	},
-{"xor.qh",  "X,Y,Q",	0x7820000d, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	MX	},
-{"xori",    "t,r,i",	0x38000000, 0xfc000000,	WR_t|RD_s,		I1	},
+{"standby", "",         0x42000021, 0xffffffff,	0,			0,		V1	},
+{"sub",     "d,v,t",	0x00000022, 0xfc0007ff,	WR_d|RD_s|RD_t,		0,		I1	},
+{"sub",     "d,v,I",	0,    (int) M_SUB_I,	INSN_MACRO,		0,		I1	},
+{"sub.d",   "D,V,T",	0x46200001, 0xffe0003f,	WR_D|RD_S|RD_T|FP_D,	0,		I1	},
+{"sub.s",   "D,V,T",	0x46000001, 0xffe0003f,	WR_D|RD_S|RD_T|FP_S,	0,		I1	},
+{"sub.ob",  "X,Y,Q",	0x7800000a, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	0,		MX|SB1	},
+{"sub.ob",  "D,S,T",	0x4ac0000a, 0xffe0003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"sub.ob",  "D,S,T[e]",	0x4800000a, 0xfe20003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"sub.ob",  "D,S,k",	0x4bc0000a, 0xffe0003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"sub.ps",  "D,V,T",	0x46c00001, 0xffe0003f,	WR_D|RD_S|RD_T|FP_D,	0,		I5|I33	},
+{"sub.qh",  "X,Y,Q",	0x7820000a, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	0,		MX	},
+{"suba.ob", "Y,Q",	0x78000036, 0xfc2007ff,	RD_S|RD_T|FP_D,		WR_MACC,	MX|SB1	},
+{"suba.qh", "Y,Q",	0x78200036, 0xfc2007ff,	RD_S|RD_T|FP_D,		WR_MACC,	MX	},
+{"subl.ob", "Y,Q",	0x78000436, 0xfc2007ff,	RD_S|RD_T|FP_D,		WR_MACC,	MX|SB1	},
+{"subl.qh", "Y,Q",	0x78200436, 0xfc2007ff,	RD_S|RD_T|FP_D,		WR_MACC,	MX	},
+{"subu",    "d,v,t",	0x00000023, 0xfc0007ff,	WR_d|RD_s|RD_t,		0,		I1	},
+{"subu",    "d,v,I",	0,    (int) M_SUBU_I,	INSN_MACRO,		0,		I1	},
+{"suspend", "",         0x42000022, 0xffffffff,	0,			0,		V1	},
+{"suxc1",   "S,t(b)",   0x4c00000d, 0xfc0007ff, SM|RD_S|RD_t|RD_b,	0,		I5|I33|N55},
+{"sw",      "t,o(b)",	0xac000000, 0xfc000000,	SM|RD_t|RD_b,		0,		I1	},
+{"sw",      "t,A(b)",	0,    (int) M_SW_AB,	INSN_MACRO,		0,		I1	},
+{"swc0",    "E,o(b)",	0xe0000000, 0xfc000000,	SM|RD_C0|RD_b,		0,		I1	},
+{"swc0",    "E,A(b)",	0,    (int) M_SWC0_AB,	INSN_MACRO,		0,		I1	},
+{"swc1",    "T,o(b)",	0xe4000000, 0xfc000000,	SM|RD_T|RD_b|FP_S,	0,		I1	},
+{"swc1",    "E,o(b)",	0xe4000000, 0xfc000000,	SM|RD_T|RD_b|FP_S,	0,		I1	},
+{"swc1",    "T,A(b)",	0,    (int) M_SWC1_AB,	INSN_MACRO,		0,		I1	},
+{"swc1",    "E,A(b)",	0,    (int) M_SWC1_AB,	INSN_MACRO,		0,		I1	},
+{"s.s",     "T,o(b)",	0xe4000000, 0xfc000000,	SM|RD_T|RD_b|FP_S,	0,		I1	}, /* swc1 */
+{"s.s",     "T,A(b)",	0,    (int) M_SWC1_AB,	INSN_MACRO,		0,		I1	},
+{"swc2",    "E,o(b)",	0xe8000000, 0xfc000000,	SM|RD_C2|RD_b,		0,		I1	},
+{"swc2",    "E,A(b)",	0,    (int) M_SWC2_AB,	INSN_MACRO,		0,		I1	},
+{"swc3",    "E,o(b)",	0xec000000, 0xfc000000,	SM|RD_C3|RD_b,		0,		I1	},
+{"swc3",    "E,A(b)",	0,    (int) M_SWC3_AB,	INSN_MACRO,		0,		I1	},
+{"swl",     "t,o(b)",	0xa8000000, 0xfc000000,	SM|RD_t|RD_b,		0,		I1	},
+{"swl",     "t,A(b)",	0,    (int) M_SWL_AB,	INSN_MACRO,		0,		I1	},
+{"scache",  "t,o(b)",	0xa8000000, 0xfc000000,	RD_t|RD_b,		0,		I2	}, /* same */
+{"scache",  "t,A(b)",	0,    (int) M_SWL_AB,	INSN_MACRO,		0,		I2	}, /* as swl */
+{"swr",     "t,o(b)",	0xb8000000, 0xfc000000,	SM|RD_t|RD_b,		0,		I1	},
+{"swr",     "t,A(b)",	0,    (int) M_SWR_AB,	INSN_MACRO,		0,		I1	},
+{"invalidate", "t,o(b)",0xb8000000, 0xfc000000,	RD_t|RD_b,		0,		I2	}, /* same */
+{"invalidate", "t,A(b)",0,    (int) M_SWR_AB,	INSN_MACRO,		0,		I2	}, /* as swr */
+{"swxc1",   "S,t(b)",   0x4c000008, 0xfc0007ff, SM|RD_S|RD_t|RD_b|FP_S,	0,		I4|I33	},
+{"sync",    "",		0x0000000f, 0xffffffff,	INSN_SYNC,		0,		I2|G1	},
+{"sync.p",  "",		0x0000040f, 0xffffffff,	INSN_SYNC,		0,		I2	},
+{"sync.l",  "",		0x0000000f, 0xffffffff,	INSN_SYNC,		0,		I2	},
+{"synci",   "o(b)",	0x041f0000, 0xfc1f0000,	SM|RD_b,		0,		I33	},
+{"syscall", "",		0x0000000c, 0xffffffff,	TRAP,			0,		I1	},
+{"syscall", "B",	0x0000000c, 0xfc00003f,	TRAP,			0,		I1	},
+{"teqi",    "s,j",	0x040c0000, 0xfc1f0000, RD_s|TRAP,		0,		I2	},
+{"teq",	    "s,t",	0x00000034, 0xfc00ffff, RD_s|RD_t|TRAP,		0,		I2	},
+{"teq",	    "s,t,q",	0x00000034, 0xfc00003f, RD_s|RD_t|TRAP,		0,		I2	},
+{"teq",     "s,j",	0x040c0000, 0xfc1f0000, RD_s|TRAP,		0,		I2	}, /* teqi */
+{"teq",     "s,I",	0,    (int) M_TEQ_I,	INSN_MACRO,		0,		I2	},
+{"tgei",    "s,j",	0x04080000, 0xfc1f0000, RD_s|TRAP,		0,		I2	},
+{"tge",	    "s,t",	0x00000030, 0xfc00ffff,	RD_s|RD_t|TRAP,		0,		I2	},
+{"tge",	    "s,t,q",	0x00000030, 0xfc00003f,	RD_s|RD_t|TRAP,		0,		I2	},
+{"tge",     "s,j",	0x04080000, 0xfc1f0000, RD_s|TRAP,		0,		I2	}, /* tgei */
+{"tge",	    "s,I",	0,    (int) M_TGE_I,    INSN_MACRO,		0,		I2	},
+{"tgeiu",   "s,j",	0x04090000, 0xfc1f0000, RD_s|TRAP,		0,		I2	},
+{"tgeu",    "s,t",	0x00000031, 0xfc00ffff, RD_s|RD_t|TRAP,		0,		I2	},
+{"tgeu",    "s,t,q",	0x00000031, 0xfc00003f, RD_s|RD_t|TRAP,		0,		I2	},
+{"tgeu",    "s,j",	0x04090000, 0xfc1f0000, RD_s|TRAP,		0,		I2	}, /* tgeiu */
+{"tgeu",    "s,I",	0,    (int) M_TGEU_I,	INSN_MACRO,		0,		I2	},
+{"tlbp",    "",         0x42000008, 0xffffffff, INSN_TLB,       	0,		I1   	},
+{"tlbr",    "",         0x42000001, 0xffffffff, INSN_TLB,       	0,		I1   	},
+{"tlbwi",   "",         0x42000002, 0xffffffff, INSN_TLB,       	0,		I1   	},
+{"tlbwr",   "",         0x42000006, 0xffffffff, INSN_TLB,       	0,		I1   	},
+{"tlti",    "s,j",	0x040a0000, 0xfc1f0000,	RD_s|TRAP,		0,		I2	},
+{"tlt",     "s,t",	0x00000032, 0xfc00ffff, RD_s|RD_t|TRAP,		0,		I2	},
+{"tlt",     "s,t,q",	0x00000032, 0xfc00003f, RD_s|RD_t|TRAP,		0,		I2	},
+{"tlt",     "s,j",	0x040a0000, 0xfc1f0000,	RD_s|TRAP,		0,		I2	}, /* tlti */
+{"tlt",     "s,I",	0,    (int) M_TLT_I,	INSN_MACRO,		0,		I2	},
+{"tltiu",   "s,j",	0x040b0000, 0xfc1f0000, RD_s|TRAP,		0,		I2	},
+{"tltu",    "s,t",	0x00000033, 0xfc00ffff, RD_s|RD_t|TRAP,		0,		I2	},
+{"tltu",    "s,t,q",	0x00000033, 0xfc00003f, RD_s|RD_t|TRAP,		0,		I2	},
+{"tltu",    "s,j",	0x040b0000, 0xfc1f0000, RD_s|TRAP,		0,		I2	}, /* tltiu */
+{"tltu",    "s,I",	0,    (int) M_TLTU_I,	INSN_MACRO,		0,		I2	},
+{"tnei",    "s,j",	0x040e0000, 0xfc1f0000, RD_s|TRAP,		0,		I2	},
+{"tne",     "s,t",	0x00000036, 0xfc00ffff, RD_s|RD_t|TRAP,		0,		I2	},
+{"tne",     "s,t,q",	0x00000036, 0xfc00003f, RD_s|RD_t|TRAP,		0,		I2	},
+{"tne",     "s,j",	0x040e0000, 0xfc1f0000, RD_s|TRAP,		0,		I2	}, /* tnei */
+{"tne",     "s,I",	0,    (int) M_TNE_I,	INSN_MACRO,		0,		I2	},
+{"trunc.l.d", "D,S",	0x46200009, 0xffff003f, WR_D|RD_S|FP_D,		0,		I3|I33	},
+{"trunc.l.s", "D,S",	0x46000009, 0xffff003f,	WR_D|RD_S|FP_S|FP_D,	0,		I3|I33	},
+{"trunc.w.d", "D,S",	0x4620000d, 0xffff003f, WR_D|RD_S|FP_S|FP_D,	0,		I2	},
+{"trunc.w.d", "D,S,x",	0x4620000d, 0xffff003f, WR_D|RD_S|FP_S|FP_D,	0,		I2	},
+{"trunc.w.d", "D,S,t",	0,    (int) M_TRUNCWD,	INSN_MACRO,		0,		I1	},
+{"trunc.w.s", "D,S",	0x4600000d, 0xffff003f,	WR_D|RD_S|FP_S,		0,		I2	},
+{"trunc.w.s", "D,S,x",	0x4600000d, 0xffff003f,	WR_D|RD_S|FP_S,		0,		I2	},
+{"trunc.w.s", "D,S,t",	0,    (int) M_TRUNCWS,	INSN_MACRO,		0,		I1	},
+{"uld",     "t,o(b)",	0,    (int) M_ULD,	INSN_MACRO,		0,		I3	},
+{"uld",     "t,A(b)",	0,    (int) M_ULD_A,	INSN_MACRO,		0,		I3	},
+{"ulh",     "t,o(b)",	0,    (int) M_ULH,	INSN_MACRO,		0,		I1	},
+{"ulh",     "t,A(b)",	0,    (int) M_ULH_A,	INSN_MACRO,		0,		I1	},
+{"ulhu",    "t,o(b)",	0,    (int) M_ULHU,	INSN_MACRO,		0,		I1	},
+{"ulhu",    "t,A(b)",	0,    (int) M_ULHU_A,	INSN_MACRO,		0,		I1	},
+{"ulw",     "t,o(b)",	0,    (int) M_ULW,	INSN_MACRO,		0,		I1	},
+{"ulw",     "t,A(b)",	0,    (int) M_ULW_A,	INSN_MACRO,		0,		I1	},
+{"usd",     "t,o(b)",	0,    (int) M_USD,	INSN_MACRO,		0,		I3	},
+{"usd",     "t,A(b)",	0,    (int) M_USD_A,	INSN_MACRO,		0,		I3	},
+{"ush",     "t,o(b)",	0,    (int) M_USH,	INSN_MACRO,		0,		I1	},
+{"ush",     "t,A(b)",	0,    (int) M_USH_A,	INSN_MACRO,		0,		I1	},
+{"usw",     "t,o(b)",	0,    (int) M_USW,	INSN_MACRO,		0,		I1	},
+{"usw",     "t,A(b)",	0,    (int) M_USW_A,	INSN_MACRO,		0,		I1	},
+{"wach.ob", "Y",	0x7a00003e, 0xffff07ff,	RD_S|FP_D,		WR_MACC,	MX|SB1	},
+{"wach.ob", "S",	0x4a00003e, 0xffff07ff,	RD_S,			0,		N54	},
+{"wach.qh", "Y",	0x7a20003e, 0xffff07ff,	RD_S|FP_D,		WR_MACC,	MX	},
+{"wacl.ob", "Y,Z",	0x7800003e, 0xffe007ff,	RD_S|RD_T|FP_D,		WR_MACC,	MX|SB1	},
+{"wacl.ob", "S,T",	0x4800003e, 0xffe007ff,	RD_S|RD_T,		0,		N54	},
+{"wacl.qh", "Y,Z",	0x7820003e, 0xffe007ff,	RD_S|RD_T|FP_D,		WR_MACC,	MX	},
+{"wait",    "",         0x42000020, 0xffffffff, TRAP,   		0,		I3|I32	},
+{"wait",    "J",        0x42000020, 0xfe00003f, TRAP,   		0,		I32|N55	},
+{"waiti",   "",		0x42000020, 0xffffffff,	TRAP,			0,		L1	},
+{"wrpgpr",  "d,w",	0x41c00000, 0xffe007ff, RD_t,			0,		I33	},
+{"wsbh",    "d,w",	0x7c0000a0, 0xffe007ff,	WR_d|RD_t,		0,		I33	},
+{"xor",     "d,v,t",	0x00000026, 0xfc0007ff,	WR_d|RD_s|RD_t,		0,		I1	},
+{"xor",     "t,r,I",	0,    (int) M_XOR_I,	INSN_MACRO,		0,		I1	},
+{"xor.ob",  "X,Y,Q",	0x7800000d, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	0,		MX|SB1	},
+{"xor.ob",  "D,S,T",	0x4ac0000d, 0xffe0003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"xor.ob",  "D,S,T[e]",	0x4800000d, 0xfe20003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"xor.ob",  "D,S,k",	0x4bc0000d, 0xffe0003f,	WR_D|RD_S|RD_T,		0,		N54	},
+{"xor.qh",  "X,Y,Q",	0x7820000d, 0xfc20003f,	WR_D|RD_S|RD_T|FP_D,	0,		MX	},
+{"xori",    "t,r,i",	0x38000000, 0xfc000000,	WR_t|RD_s,		0,		I1	},
+{"yield",   "s",	0x7c000009, 0xfc1fffff, TRAP|RD_s,		0,		MT32	},
+{"yield",   "d,s",	0x7c000009, 0xfc1f07ff, TRAP|WR_d|RD_s,		0,		MT32	},
 
+/* User Defined Instruction.  */
+{"udi0",     "s,t,d,+1",0x70000010, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi0",     "s,t,+2",	0x70000010, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi0",     "s,+3",	0x70000010, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi0",     "+4",	0x70000010, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi1",     "s,t,d,+1",0x70000011, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi1",     "s,t,+2",	0x70000011, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi1",     "s,+3",	0x70000011, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi1",     "+4",	0x70000011, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi2",     "s,t,d,+1",0x70000012, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi2",     "s,t,+2",	0x70000012, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi2",     "s,+3",	0x70000012, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi2",     "+4",	0x70000012, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi3",     "s,t,d,+1",0x70000013, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi3",     "s,t,+2",	0x70000013, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi3",     "s,+3",	0x70000013, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi3",     "+4",	0x70000013, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi4",     "s,t,d,+1",0x70000014, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi4",     "s,t,+2",	0x70000014, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi4",     "s,+3",	0x70000014, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi4",     "+4",	0x70000014, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi5",     "s,t,d,+1",0x70000015, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi5",     "s,t,+2",	0x70000015, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi5",     "s,+3",	0x70000015, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi5",     "+4",	0x70000015, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi6",     "s,t,d,+1",0x70000016, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi6",     "s,t,+2",	0x70000016, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi6",     "s,+3",	0x70000016, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi6",     "+4",	0x70000016, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi7",     "s,t,d,+1",0x70000017, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi7",     "s,t,+2",	0x70000017, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi7",     "s,+3",	0x70000017, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi7",     "+4",	0x70000017, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi8",     "s,t,d,+1",0x70000018, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi8",     "s,t,+2",	0x70000018, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi8",     "s,+3",	0x70000018, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi8",     "+4",	0x70000018, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi9",     "s,t,d,+1",0x70000019, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi9",      "s,t,+2",	0x70000019, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi9",     "s,+3",	0x70000019, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi9",     "+4",	0x70000019, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi10",    "s,t,d,+1",0x7000001a, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi10",    "s,t,+2",	0x7000001a, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi10",    "s,+3",	0x7000001a, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi10",    "+4",	0x7000001a, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi11",    "s,t,d,+1",0x7000001b, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi11",    "s,t,+2",	0x7000001b, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi11",    "s,+3",	0x7000001b, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi11",    "+4",	0x7000001b, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi12",    "s,t,d,+1",0x7000001c, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi12",    "s,t,+2",	0x7000001c, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi12",    "s,+3",	0x7000001c, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi12",    "+4",	0x7000001c, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi13",    "s,t,d,+1",0x7000001d, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi13",    "s,t,+2",	0x7000001d, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi13",    "s,+3",	0x7000001d, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi13",    "+4",	0x7000001d, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi14",    "s,t,d,+1",0x7000001e, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi14",    "s,t,+2",	0x7000001e, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi14",    "s,+3",	0x7000001e, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi14",    "+4",	0x7000001e, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi15",    "s,t,d,+1",0x7000001f, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi15",    "s,t,+2",	0x7000001f, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi15",    "s,+3",	0x7000001f, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi15",    "+4",	0x7000001f, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+
 /* Coprocessor 2 move/branch operations overlap with VR5400 .ob format
    instructions so they are here for the latters to take precedence.  */
-{"bc2f",    "p",	0x49000000, 0xffff0000,	CBD|RD_CC,		I1	},
-{"bc2fl",   "p",	0x49020000, 0xffff0000,	CBL|RD_CC,		I2|T3	},
-{"bc2t",    "p",	0x49010000, 0xffff0000,	CBD|RD_CC,		I1	},
-{"bc2tl",   "p",	0x49030000, 0xffff0000,	CBL|RD_CC,		I2|T3	},
-{"cfc2",    "t,G",	0x48400000, 0xffe007ff,	LCD|WR_t|RD_C2,		I1	},
-{"ctc2",    "t,G",	0x48c00000, 0xffe007ff,	COD|RD_t|WR_CC,		I1	},
-{"dmfc2",   "t,G",	0x48200000, 0xffe007ff,	LCD|WR_t|RD_C2,		I3	},
-{"dmfc2",   "t,G,H",	0x48200000, 0xffe007f8,	LCD|WR_t|RD_C2,		I64	},
-{"dmtc2",   "t,G",	0x48a00000, 0xffe007ff,	COD|RD_t|WR_C2|WR_CC,	I3	},
-{"dmtc2",   "t,G,H",	0x48a00000, 0xffe007f8,	COD|RD_t|WR_C2|WR_CC,	I64	},
-{"mfc2",    "t,G",	0x48000000, 0xffe007ff,	LCD|WR_t|RD_C2,		I1	},
-{"mfc2",    "t,G,H",	0x48000000, 0xffe007f8,	LCD|WR_t|RD_C2,		I32	},
-{"mfhc2",   "t,i",	0x48600000, 0xffe00000,	LCD|WR_t|RD_C2,		I33	},
-{"mtc2",    "t,G",	0x48800000, 0xffe007ff,	COD|RD_t|WR_C2|WR_CC,	I1	},
-{"mtc2",    "t,G,H",	0x48800000, 0xffe007f8,	COD|RD_t|WR_C2|WR_CC,	I32	},
-{"mthc2",   "t,i",	0x48e00000, 0xffe00000,	COD|RD_t|WR_C2|WR_CC,	I33	},
+{"bc2f",    "p",	0x49000000, 0xffff0000,	CBD|RD_CC,		0,		I1	},
+{"bc2f",    "N,p",	0x49000000, 0xffe30000,	CBD|RD_CC,		0,		I32	},
+{"bc2fl",   "p",	0x49020000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3	},
+{"bc2fl",   "N,p",	0x49020000, 0xffe30000,	CBL|RD_CC,		0,		I32	},
+{"bc2t",    "p",	0x49010000, 0xffff0000,	CBD|RD_CC,		0,		I1	},
+{"bc2t",    "N,p",	0x49010000, 0xffe30000,	CBD|RD_CC,		0,		I32	},
+{"bc2tl",   "p",	0x49030000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3	},
+{"bc2tl",   "N,p",	0x49030000, 0xffe30000,	CBL|RD_CC,		0,		I32	},
+{"cfc2",    "t,G",	0x48400000, 0xffe007ff,	LCD|WR_t|RD_C2,		0,		I1	},
+{"ctc2",    "t,G",	0x48c00000, 0xffe007ff,	COD|RD_t|WR_CC,		0,		I1	},
+{"dmfc2",   "t,G",	0x48200000, 0xffe007ff,	LCD|WR_t|RD_C2,		0,		I3	},
+{"dmfc2",   "t,G,H",	0x48200000, 0xffe007f8,	LCD|WR_t|RD_C2,		0,		I64	},
+{"dmtc2",   "t,G",	0x48a00000, 0xffe007ff,	COD|RD_t|WR_C2|WR_CC,	0,		I3	},
+{"dmtc2",   "t,G,H",	0x48a00000, 0xffe007f8,	COD|RD_t|WR_C2|WR_CC,	0,		I64	},
+{"mfc2",    "t,G",	0x48000000, 0xffe007ff,	LCD|WR_t|RD_C2,		0,		I1	},
+{"mfc2",    "t,G,H",	0x48000000, 0xffe007f8,	LCD|WR_t|RD_C2,		0,		I32	},
+{"mfhc2",   "t,G",	0x48600000, 0xffe007ff,	LCD|WR_t|RD_C2,		0,		I33	},
+{"mfhc2",   "t,G,H",	0x48600000, 0xffe007f8,	LCD|WR_t|RD_C2,		0,		I33	},
+{"mfhc2",   "t,i",	0x48600000, 0xffe00000,	LCD|WR_t|RD_C2,		0,		I33	},
+{"mtc2",    "t,G",	0x48800000, 0xffe007ff,	COD|RD_t|WR_C2|WR_CC,	0,		I1	},
+{"mtc2",    "t,G,H",	0x48800000, 0xffe007f8,	COD|RD_t|WR_C2|WR_CC,	0,		I32	},
+{"mthc2",   "t,G",	0x48e00000, 0xffe007ff,	COD|RD_t|WR_C2|WR_CC,	0,		I33	},
+{"mthc2",   "t,G,H",	0x48e00000, 0xffe007f8,	COD|RD_t|WR_C2|WR_CC,	0,		I33	},
+{"mthc2",   "t,i",	0x48e00000, 0xffe00000,	COD|RD_t|WR_C2|WR_CC,	0,		I33	},
 
+/* Coprocessor 3 move/branch operations overlap with MIPS IV COP1X
+   instructions, so they are here for the latters to take precedence.  */
+{"bc3f",    "p",	0x4d000000, 0xffff0000,	CBD|RD_CC,		0,		I1	},
+{"bc3fl",   "p",	0x4d020000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3	},
+{"bc3t",    "p",	0x4d010000, 0xffff0000,	CBD|RD_CC,		0,		I1	},
+{"bc3tl",   "p",	0x4d030000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3	},
+{"cfc3",    "t,G",	0x4c400000, 0xffe007ff,	LCD|WR_t|RD_C3,		0,		I1	},
+{"ctc3",    "t,G",	0x4cc00000, 0xffe007ff,	COD|RD_t|WR_CC,		0,		I1	},
+{"dmfc3",   "t,G",	0x4c200000, 0xffe007ff, LCD|WR_t|RD_C3, 	0,		I3	},
+{"dmtc3",   "t,G",	0x4ca00000, 0xffe007ff, COD|RD_t|WR_C3|WR_CC,	0,		I3	},
+{"mfc3",    "t,G",	0x4c000000, 0xffe007ff,	LCD|WR_t|RD_C3,		0,		I1	},
+{"mfc3",    "t,G,H",    0x4c000000, 0xffe007f8, LCD|WR_t|RD_C3, 	0,		I32     },
+{"mtc3",    "t,G",	0x4c800000, 0xffe007ff,	COD|RD_t|WR_C3|WR_CC,	0,		I1	},
+{"mtc3",    "t,G,H",    0x4c800000, 0xffe007f8, COD|RD_t|WR_C3|WR_CC,   0,		I32     },
+
 /* No hazard protection on coprocessor instructions--they shouldn't
    change the state of the processor and if they do it's up to the
    user to put in nops as necessary.  These are at the end so that the
    disassembler recognizes more specific versions first.  */
-{"c0",      "C",	0x42000000, 0xfe000000,	0,			I1	},
-{"c1",      "C",	0x46000000, 0xfe000000,	0,			I1	},
-{"c2",      "C",	0x4a000000, 0xfe000000,	0,			I1	},
-{"c3",      "C",	0x4e000000, 0xfe000000,	0,			I1	},
-{"cop0",     "C",	0,    (int) M_COP0,	INSN_MACRO,		I1	},
-{"cop1",     "C",	0,    (int) M_COP1,	INSN_MACRO,		I1	},
-{"cop2",     "C",	0,    (int) M_COP2,	INSN_MACRO,		I1	},
-{"cop3",     "C",	0,    (int) M_COP3,	INSN_MACRO,		I1	},
-
+{"c0",      "C",	0x42000000, 0xfe000000,	0,			0,		I1	},
+{"c1",      "C",	0x46000000, 0xfe000000,	0,			0,		I1	},
+{"c2",      "C",	0x4a000000, 0xfe000000,	0,			0,		I1	},
+{"c3",      "C",	0x4e000000, 0xfe000000,	0,			0,		I1	},
+{"cop0",     "C",	0,    (int) M_COP0,	INSN_MACRO,		0,		I1	},
+{"cop1",     "C",	0,    (int) M_COP1,	INSN_MACRO,		0,		I1	},
+{"cop2",     "C",	0,    (int) M_COP2,	INSN_MACRO,		0,		I1	},
+{"cop3",     "C",	0,    (int) M_COP3,	INSN_MACRO,		0,		I1	},
   /* Conflicts with the 4650's "mul" instruction.  Nobody's using the
      4010 any more, so move this insn out of the way.  If the object
      format gave us more info, we could do this right.  */
-{"addciu",  "t,r,j",	0x70000000, 0xfc000000,	WR_t|RD_s,		L1	},
+{"addciu",  "t,r,j",	0x70000000, 0xfc000000,	WR_t|RD_s,		0,		L1	},
+/* MIPS DSP ASE */
+{"absq_s.ph", "d,t",	0x7c000252, 0xffe007ff, WR_d|RD_t,		0,		D32	},
+{"absq_s.pw", "d,t",	0x7c000456, 0xffe007ff, WR_d|RD_t,		0,		D64	},
+{"absq_s.qh", "d,t",	0x7c000256, 0xffe007ff, WR_d|RD_t,		0,		D64	},
+{"absq_s.w", "d,t",	0x7c000452, 0xffe007ff, WR_d|RD_t,		0,		D32	},
+{"addq.ph", "d,s,t",	0x7c000290, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D32	},
+{"addq.pw", "d,s,t",	0x7c000494, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D64	},
+{"addq.qh", "d,s,t",	0x7c000294, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D64	},
+{"addq_s.ph", "d,s,t",	0x7c000390, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D32	},
+{"addq_s.pw", "d,s,t",	0x7c000594, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D64	},
+{"addq_s.qh", "d,s,t",	0x7c000394, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D64	},
+{"addq_s.w", "d,s,t",	0x7c000590, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D32	},
+{"addsc",   "d,s,t",	0x7c000410, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D32	},
+{"addu.ob", "d,s,t",	0x7c000014, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D64	},
+{"addu.qb", "d,s,t",	0x7c000010, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D32	},
+{"addu_s.ob", "d,s,t",	0x7c000114, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D64	},
+{"addu_s.qb", "d,s,t",	0x7c000110, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D32	},
+{"addwc",   "d,s,t",	0x7c000450, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D32	},
+{"bitrev",  "d,t",	0x7c0006d2, 0xffe007ff, WR_d|RD_t,		0,		D32	},
+{"bposge32", "p",	0x041c0000, 0xffff0000, CBD,			0,		D32	},
+{"bposge64", "p",	0x041d0000, 0xffff0000, CBD,			0,		D64	},
+{"cmp.eq.ph", "s,t",	0x7c000211, 0xfc00ffff, RD_s|RD_t,		0,		D32	},
+{"cmp.eq.pw", "s,t",	0x7c000415, 0xfc00ffff, RD_s|RD_t,		0,		D64	},
+{"cmp.eq.qh", "s,t",	0x7c000215, 0xfc00ffff, RD_s|RD_t,		0,		D64	},
+{"cmpgu.eq.ob", "d,s,t", 0x7c000115, 0xfc0007ff, WR_d|RD_s|RD_t,	0,		D64	},
+{"cmpgu.eq.qb", "d,s,t", 0x7c000111, 0xfc0007ff, WR_d|RD_s|RD_t,	0,		D32	},
+{"cmpgu.le.ob", "d,s,t", 0x7c000195, 0xfc0007ff, WR_d|RD_s|RD_t,	0,		D64	},
+{"cmpgu.le.qb", "d,s,t", 0x7c000191, 0xfc0007ff, WR_d|RD_s|RD_t,	0,		D32	},
+{"cmpgu.lt.ob", "d,s,t", 0x7c000155, 0xfc0007ff, WR_d|RD_s|RD_t,	0,		D64	},
+{"cmpgu.lt.qb", "d,s,t", 0x7c000151, 0xfc0007ff, WR_d|RD_s|RD_t,	0,		D32	},
+{"cmp.le.ph", "s,t",	0x7c000291, 0xfc00ffff, RD_s|RD_t,		0,		D32	},
+{"cmp.le.pw", "s,t",	0x7c000495, 0xfc00ffff, RD_s|RD_t,		0,		D64	},
+{"cmp.le.qh", "s,t",	0x7c000295, 0xfc00ffff, RD_s|RD_t,		0,		D64	},
+{"cmp.lt.ph", "s,t",	0x7c000251, 0xfc00ffff, RD_s|RD_t,		0,		D32	},
+{"cmp.lt.pw", "s,t",	0x7c000455, 0xfc00ffff, RD_s|RD_t,		0,		D64	},
+{"cmp.lt.qh", "s,t",	0x7c000255, 0xfc00ffff, RD_s|RD_t,		0,		D64	},
+{"cmpu.eq.ob", "s,t",	0x7c000015, 0xfc00ffff, RD_s|RD_t,		0,		D64	},
+{"cmpu.eq.qb", "s,t",	0x7c000011, 0xfc00ffff, RD_s|RD_t,		0,		D32	},
+{"cmpu.le.ob", "s,t",	0x7c000095, 0xfc00ffff, RD_s|RD_t,		0,		D64	},
+{"cmpu.le.qb", "s,t",	0x7c000091, 0xfc00ffff, RD_s|RD_t,		0,		D32	},
+{"cmpu.lt.ob", "s,t",	0x7c000055, 0xfc00ffff, RD_s|RD_t,		0,		D64	},
+{"cmpu.lt.qb", "s,t",	0x7c000051, 0xfc00ffff, RD_s|RD_t,		0,		D32	},
+{"dextpdp", "t,7,6",	0x7c0002bc, 0xfc00e7ff, WR_t|RD_a|DSP_VOLA,	0,		D64	},
+{"dextpdpv", "t,7,s",	0x7c0002fc, 0xfc00e7ff, WR_t|RD_a|RD_s|DSP_VOLA, 0,		D64	},
+{"dextp",   "t,7,6",	0x7c0000bc, 0xfc00e7ff, WR_t|RD_a,		0,		D64	},
+{"dextpv",  "t,7,s",	0x7c0000fc, 0xfc00e7ff, WR_t|RD_a|RD_s,		0,		D64	},
+{"dextr.l", "t,7,6",	0x7c00043c, 0xfc00e7ff, WR_t|RD_a,		0,		D64	},
+{"dextr_r.l", "t,7,6",	0x7c00053c, 0xfc00e7ff, WR_t|RD_a,		0,		D64	},
+{"dextr_rs.l", "t,7,6",	0x7c0005bc, 0xfc00e7ff, WR_t|RD_a,		0,		D64	},
+{"dextr_rs.w", "t,7,6",	0x7c0001bc, 0xfc00e7ff, WR_t|RD_a,		0,		D64	},
+{"dextr_r.w", "t,7,6",	0x7c00013c, 0xfc00e7ff, WR_t|RD_a,		0,		D64	},
+{"dextr_s.h", "t,7,6",	0x7c0003bc, 0xfc00e7ff, WR_t|RD_a,		0,		D64	},
+{"dextrv.l", "t,7,s",	0x7c00047c, 0xfc00e7ff, WR_t|RD_a|RD_s,		0,		D64	},
+{"dextrv_r.l", "t,7,s",	0x7c00057c, 0xfc00e7ff, WR_t|RD_a|RD_s,		0,		D64	},
+{"dextrv_rs.l", "t,7,s", 0x7c0005fc, 0xfc00e7ff, WR_t|RD_a|RD_s,	0,		D64	},
+{"dextrv_rs.w", "t,7,s", 0x7c0001fc, 0xfc00e7ff, WR_t|RD_a|RD_s,	0,		D64	},
+{"dextrv_r.w", "t,7,s",	0x7c00017c, 0xfc00e7ff, WR_t|RD_a|RD_s,		0,		D64	},
+{"dextrv_s.h", "t,7,s",	0x7c0003fc, 0xfc00e7ff, WR_t|RD_a|RD_s,		0,		D64	},
+{"dextrv.w", "t,7,s",	0x7c00007c, 0xfc00e7ff, WR_t|RD_a|RD_s,		0,		D64	},
+{"dextr.w", "t,7,6",	0x7c00003c, 0xfc00e7ff, WR_t|RD_a,		0,		D64	},
+{"dinsv",   "t,s",	0x7c00000d, 0xfc00ffff, WR_t|RD_s,		0,		D64	},
+{"dmadd",   "7,s,t",	0x7c000674, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D64	},
+{"dmaddu",  "7,s,t",	0x7c000774, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D64	},
+{"dmsub",   "7,s,t",	0x7c0006f4, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D64	},
+{"dmsubu",  "7,s,t",	0x7c0007f4, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D64	},
+{"dmthlip", "s,7",	0x7c0007fc, 0xfc1fe7ff, RD_s|MOD_a|DSP_VOLA,	0,		D64	},
+{"dpaq_sa.l.pw", "7,s,t", 0x7c000334, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D64	},
+{"dpaq_sa.l.w", "7,s,t", 0x7c000330, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D32	},
+{"dpaq_s.w.ph", "7,s,t", 0x7c000130, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D32	},
+{"dpaq_s.w.qh", "7,s,t", 0x7c000134, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D64	},
+{"dpau.h.obl", "7,s,t",	0x7c0000f4, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D64	},
+{"dpau.h.obr", "7,s,t",	0x7c0001f4, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D64	},
+{"dpau.h.qbl", "7,s,t",	0x7c0000f0, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D32	},
+{"dpau.h.qbr", "7,s,t",	0x7c0001f0, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D32	},
+{"dpsq_sa.l.pw", "7,s,t", 0x7c000374, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D64	},
+{"dpsq_sa.l.w", "7,s,t", 0x7c000370, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D32	},
+{"dpsq_s.w.ph", "7,s,t", 0x7c000170, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D32	},
+{"dpsq_s.w.qh", "7,s,t", 0x7c000174, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D64	},
+{"dpsu.h.obl", "7,s,t",	0x7c0002f4, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D64	},
+{"dpsu.h.obr", "7,s,t",	0x7c0003f4, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D64	},
+{"dpsu.h.qbl", "7,s,t",	0x7c0002f0, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D32	},
+{"dpsu.h.qbr", "7,s,t",	0x7c0003f0, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D32	},
+{"dshilo",  "7,:",	0x7c0006bc, 0xfc07e7ff, MOD_a,			0,		D64	},
+{"dshilov", "7,s",	0x7c0006fc, 0xfc1fe7ff, MOD_a|RD_s,		0,		D64	},
+{"extpdp",  "t,7,6",	0x7c0002b8, 0xfc00e7ff, WR_t|RD_a|DSP_VOLA,	0,		D32	},
+{"extpdpv", "t,7,s",	0x7c0002f8, 0xfc00e7ff, WR_t|RD_a|RD_s|DSP_VOLA, 0,		D32	},
+{"extp",    "t,7,6",	0x7c0000b8, 0xfc00e7ff, WR_t|RD_a,		0,		D32	},
+{"extpv",   "t,7,s",	0x7c0000f8, 0xfc00e7ff, WR_t|RD_a|RD_s,		0,		D32	},
+{"extr_rs.w", "t,7,6",	0x7c0001b8, 0xfc00e7ff, WR_t|RD_a,		0,		D32	},
+{"extr_r.w", "t,7,6",	0x7c000138, 0xfc00e7ff, WR_t|RD_a,		0,		D32	},
+{"extr_s.h", "t,7,6",	0x7c0003b8, 0xfc00e7ff, WR_t|RD_a,		0,		D32	},
+{"extrv_rs.w", "t,7,s",	0x7c0001f8, 0xfc00e7ff, WR_t|RD_a|RD_s,		0,		D32	},
+{"extrv_r.w", "t,7,s",	0x7c000178, 0xfc00e7ff, WR_t|RD_a|RD_s,		0,		D32	},
+{"extrv_s.h", "t,7,s",	0x7c0003f8, 0xfc00e7ff, WR_t|RD_a|RD_s,		0,		D32	},
+{"extrv.w", "t,7,s",	0x7c000078, 0xfc00e7ff, WR_t|RD_a|RD_s,		0,		D32	},
+{"extr.w",  "t,7,6",	0x7c000038, 0xfc00e7ff, WR_t|RD_a,		0,		D32	},
+{"insv",    "t,s",	0x7c00000c, 0xfc00ffff, WR_t|RD_s,		0,		D32	},
+{"lbux",    "d,t(b)",	0x7c00018a, 0xfc0007ff, LDD|WR_d|RD_t|RD_b,	0,		D32	},
+{"ldx",     "d,t(b)",	0x7c00020a, 0xfc0007ff, LDD|WR_d|RD_t|RD_b,	0,		D64	},
+{"lhx",     "d,t(b)",	0x7c00010a, 0xfc0007ff, LDD|WR_d|RD_t|RD_b,	0,		D32	},
+{"lwx",     "d,t(b)",	0x7c00000a, 0xfc0007ff, LDD|WR_d|RD_t|RD_b,	0,		D32	},
+{"maq_sa.w.phl", "7,s,t", 0x7c000430, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D32	},
+{"maq_sa.w.phr", "7,s,t", 0x7c0004b0, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D32	},
+{"maq_sa.w.qhll", "7,s,t", 0x7c000434, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D64	},
+{"maq_sa.w.qhlr", "7,s,t", 0x7c000474, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D64	},
+{"maq_sa.w.qhrl", "7,s,t", 0x7c0004b4, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D64	},
+{"maq_sa.w.qhrr", "7,s,t", 0x7c0004f4, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D64	},
+{"maq_s.l.pwl", "7,s,t", 0x7c000734, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D64	},
+{"maq_s.l.pwr", "7,s,t", 0x7c0007b4, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D64	},
+{"maq_s.w.phl", "7,s,t", 0x7c000530, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D32	},
+{"maq_s.w.phr", "7,s,t", 0x7c0005b0, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D32	},
+{"maq_s.w.qhll", "7,s,t", 0x7c000534, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D64	},
+{"maq_s.w.qhlr", "7,s,t", 0x7c000574, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D64	},
+{"maq_s.w.qhrl", "7,s,t", 0x7c0005b4, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D64	},
+{"maq_s.w.qhrr", "7,s,t", 0x7c0005f4, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D64	},
+{"modsub",  "d,s,t",	0x7c000490, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D32	},
+{"mthlip",  "s,7",	0x7c0007f8, 0xfc1fe7ff, RD_s|MOD_a|DSP_VOLA,	0,		D32	},
+{"muleq_s.pw.qhl", "d,s,t", 0x7c000714, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, 0,		D64	},
+{"muleq_s.pw.qhr", "d,s,t", 0x7c000754, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, 0,		D64	},
+{"muleq_s.w.phl", "d,s,t", 0x7c000710, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, 0,		D32	},
+{"muleq_s.w.phr", "d,s,t", 0x7c000750, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, 0,		D32	},
+{"muleu_s.ph.qbl", "d,s,t", 0x7c000190, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, 0,		D32	},
+{"muleu_s.ph.qbr", "d,s,t", 0x7c0001d0, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, 0,		D32	},
+{"muleu_s.qh.obl", "d,s,t", 0x7c000194, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, 0,		D64	},
+{"muleu_s.qh.obr", "d,s,t", 0x7c0001d4, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, 0,		D64	},
+{"mulq_rs.ph", "d,s,t",	0x7c0007d0, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO,	0,		D32	},
+{"mulq_rs.qh", "d,s,t",	0x7c0007d4, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO,	0,		D64	},
+{"mulsaq_s.l.pw", "7,s,t", 0x7c0003b4, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D64	},
+{"mulsaq_s.w.ph", "7,s,t", 0x7c0001b0, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D32	},
+{"mulsaq_s.w.qh", "7,s,t", 0x7c0001b4, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,		D64	},
+{"packrl.ph", "d,s,t",	0x7c000391, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D32	},
+{"packrl.pw", "d,s,t",	0x7c000395, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D64	},
+{"pick.ob", "d,s,t",	0x7c0000d5, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D64	},
+{"pick.ph", "d,s,t",	0x7c0002d1, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D32	},
+{"pick.pw", "d,s,t",	0x7c0004d5, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D64	},
+{"pick.qb", "d,s,t",	0x7c0000d1, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D32	},
+{"pick.qh", "d,s,t",	0x7c0002d5, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D64	},
+{"preceq.pw.qhla", "d,t", 0x7c000396, 0xffe007ff, WR_d|RD_t,		0,		D64	},
+{"preceq.pw.qhl", "d,t", 0x7c000316, 0xffe007ff, WR_d|RD_t,		0,		D64	},
+{"preceq.pw.qhra", "d,t", 0x7c0003d6, 0xffe007ff, WR_d|RD_t,		0,		D64	},
+{"preceq.pw.qhr", "d,t", 0x7c000356, 0xffe007ff, WR_d|RD_t,		0,		D64	},
+{"preceq.s.l.pwl", "d,t", 0x7c000516, 0xffe007ff, WR_d|RD_t,		0,		D64	},
+{"preceq.s.l.pwr", "d,t", 0x7c000556, 0xffe007ff, WR_d|RD_t,		0,		D64	},
+{"precequ.ph.qbla", "d,t", 0x7c000192, 0xffe007ff, WR_d|RD_t,		0,		D32	},
+{"precequ.ph.qbl", "d,t", 0x7c000112, 0xffe007ff, WR_d|RD_t,		0,		D32	},
+{"precequ.ph.qbra", "d,t", 0x7c0001d2, 0xffe007ff, WR_d|RD_t,		0,		D32	},
+{"precequ.ph.qbr", "d,t", 0x7c000152, 0xffe007ff, WR_d|RD_t,		0,		D32	},
+{"precequ.pw.qhla", "d,t", 0x7c000196, 0xffe007ff, WR_d|RD_t,		0,		D64	},
+{"precequ.pw.qhl", "d,t", 0x7c000116, 0xffe007ff, WR_d|RD_t,		0,		D64	},
+{"precequ.pw.qhra", "d,t", 0x7c0001d6, 0xffe007ff, WR_d|RD_t,		0,		D64	},
+{"precequ.pw.qhr", "d,t", 0x7c000156, 0xffe007ff, WR_d|RD_t,		0,		D64	},
+{"preceq.w.phl", "d,t",	0x7c000312, 0xffe007ff, WR_d|RD_t,		0,		D32	},
+{"preceq.w.phr", "d,t",	0x7c000352, 0xffe007ff, WR_d|RD_t,		0,		D32	},
+{"preceu.ph.qbla", "d,t", 0x7c000792, 0xffe007ff, WR_d|RD_t,		0,		D32	},
+{"preceu.ph.qbl", "d,t", 0x7c000712, 0xffe007ff, WR_d|RD_t,		0,		D32	},
+{"preceu.ph.qbra", "d,t", 0x7c0007d2, 0xffe007ff, WR_d|RD_t,		0,		D32	},
+{"preceu.ph.qbr", "d,t", 0x7c000752, 0xffe007ff, WR_d|RD_t,		0,		D32	},
+{"preceu.qh.obla", "d,t", 0x7c000796, 0xffe007ff, WR_d|RD_t,		0,		D64	},
+{"preceu.qh.obl", "d,t", 0x7c000716, 0xffe007ff, WR_d|RD_t,		0,		D64	},
+{"preceu.qh.obra", "d,t", 0x7c0007d6, 0xffe007ff, WR_d|RD_t,		0,		D64	},
+{"preceu.qh.obr", "d,t", 0x7c000756, 0xffe007ff, WR_d|RD_t,		0,		D64	},
+{"precrq.ob.qh", "d,s,t", 0x7c000315, 0xfc0007ff, WR_d|RD_s|RD_t,	0,		D64	},
+{"precrq.ph.w", "d,s,t", 0x7c000511, 0xfc0007ff, WR_d|RD_s|RD_t,	0,		D32	},
+{"precrq.pw.l", "d,s,t", 0x7c000715, 0xfc0007ff, WR_d|RD_s|RD_t,	0,		D64	},
+{"precrq.qb.ph", "d,s,t", 0x7c000311, 0xfc0007ff, WR_d|RD_s|RD_t,	0,		D32	},
+{"precrq.qh.pw", "d,s,t", 0x7c000515, 0xfc0007ff, WR_d|RD_s|RD_t,	0,		D64	},
+{"precrq_rs.ph.w", "d,s,t", 0x7c000551, 0xfc0007ff, WR_d|RD_s|RD_t,	0,		D32	},
+{"precrq_rs.qh.pw", "d,s,t", 0x7c000555, 0xfc0007ff, WR_d|RD_s|RD_t,	0,		D64	},
+{"precrqu_s.ob.qh", "d,s,t", 0x7c0003d5, 0xfc0007ff, WR_d|RD_s|RD_t,	0,		D64	},
+{"precrqu_s.qb.ph", "d,s,t", 0x7c0003d1, 0xfc0007ff, WR_d|RD_s|RD_t,	0,		D32	},
+{"raddu.l.ob", "d,s",	0x7c000514, 0xfc1f07ff, WR_d|RD_s,		0,		D64	},
+{"raddu.w.qb", "d,s",	0x7c000510, 0xfc1f07ff, WR_d|RD_s,		0,		D32	},
+{"rddsp",   "d",	0x7fff04b8, 0xffff07ff, WR_d,			0,		D32	},
+{"rddsp",   "d,'",	0x7c0004b8, 0xffc007ff, WR_d,			0,		D32	},
+{"repl.ob", "d,5",	0x7c000096, 0xff0007ff, WR_d,			0,		D64	},
+{"repl.ph", "d,@",	0x7c000292, 0xfc0007ff, WR_d,			0,		D32	},
+{"repl.pw", "d,@",	0x7c000496, 0xfc0007ff, WR_d,			0,		D64	},
+{"repl.qb", "d,5",	0x7c000092, 0xff0007ff, WR_d,			0,		D32	},
+{"repl.qh", "d,@",	0x7c000296, 0xfc0007ff, WR_d,			0,		D64	},
+{"replv.ob", "d,t",	0x7c0000d6, 0xffe007ff, WR_d|RD_t,		0,		D64	},
+{"replv.ph", "d,t",	0x7c0002d2, 0xffe007ff, WR_d|RD_t,		0,		D32	},
+{"replv.pw", "d,t",	0x7c0004d6, 0xffe007ff, WR_d|RD_t,		0,		D64	},
+{"replv.qb", "d,t",	0x7c0000d2, 0xffe007ff, WR_d|RD_t,		0,		D32	},
+{"replv.qh", "d,t",	0x7c0002d6, 0xffe007ff, WR_d|RD_t,		0,		D64	},
+{"shilo",   "7,0",	0x7c0006b8, 0xfc0fe7ff, MOD_a,			0,		D32	},
+{"shilov",  "7,s",	0x7c0006f8, 0xfc1fe7ff, MOD_a|RD_s,		0,		D32	},
+{"shll.ob", "d,t,3",	0x7c000017, 0xff0007ff, WR_d|RD_t,		0,		D64	},
+{"shll.ph", "d,t,4",	0x7c000213, 0xfe0007ff, WR_d|RD_t,		0,		D32	},
+{"shll.pw", "d,t,6",	0x7c000417, 0xfc0007ff, WR_d|RD_t,		0,		D64	},
+{"shll.qb", "d,t,3",	0x7c000013, 0xff0007ff, WR_d|RD_t,		0,		D32	},
+{"shll.qh", "d,t,4",	0x7c000217, 0xfe0007ff, WR_d|RD_t,		0,		D64	},
+{"shll_s.ph", "d,t,4",	0x7c000313, 0xfe0007ff, WR_d|RD_t,		0,		D32	},
+{"shll_s.pw", "d,t,6",	0x7c000517, 0xfc0007ff, WR_d|RD_t,		0,		D64	},
+{"shll_s.qh", "d,t,4",	0x7c000317, 0xfe0007ff, WR_d|RD_t,		0,		D64	},
+{"shll_s.w", "d,t,6",	0x7c000513, 0xfc0007ff, WR_d|RD_t,		0,		D32	},
+{"shllv.ob", "d,t,s",	0x7c000097, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D64	},
+{"shllv.ph", "d,t,s",	0x7c000293, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D32	},
+{"shllv.pw", "d,t,s",	0x7c000497, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D64	},
+{"shllv.qb", "d,t,s",	0x7c000093, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D32	},
+{"shllv.qh", "d,t,s",	0x7c000297, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D64	},
+{"shllv_s.ph", "d,t,s",	0x7c000393, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D32	},
+{"shllv_s.pw", "d,t,s",	0x7c000597, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D64	},
+{"shllv_s.qh", "d,t,s",	0x7c000397, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D64	},
+{"shllv_s.w", "d,t,s",	0x7c000593, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D32	},
+{"shra.ph", "d,t,4",	0x7c000253, 0xfe0007ff, WR_d|RD_t,		0,		D32	},
+{"shra.pw", "d,t,6",	0x7c000457, 0xfc0007ff, WR_d|RD_t,		0,		D64	},
+{"shra.qh", "d,t,4",	0x7c000257, 0xfe0007ff, WR_d|RD_t,		0,		D64	},
+{"shra_r.ph", "d,t,4",	0x7c000353, 0xfe0007ff, WR_d|RD_t,		0,		D32	},
+{"shra_r.pw", "d,t,6",	0x7c000557, 0xfc0007ff, WR_d|RD_t,		0,		D64	},
+{"shra_r.qh", "d,t,4",	0x7c000357, 0xfe0007ff, WR_d|RD_t,		0,		D64	},
+{"shra_r.w", "d,t,6",	0x7c000553, 0xfc0007ff, WR_d|RD_t,		0,		D32	},
+{"shrav.ph", "d,t,s",	0x7c0002d3, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D32	},
+{"shrav.pw", "d,t,s",	0x7c0004d7, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D64	},
+{"shrav.qh", "d,t,s",	0x7c0002d7, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D64	},
+{"shrav_r.ph", "d,t,s",	0x7c0003d3, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D32	},
+{"shrav_r.pw", "d,t,s",	0x7c0005d7, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D64	},
+{"shrav_r.qh", "d,t,s",	0x7c0003d7, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D64	},
+{"shrav_r.w", "d,t,s",	0x7c0005d3, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D32	},
+{"shrl.ob", "d,t,3",	0x7c000057, 0xff0007ff, WR_d|RD_t,		0,		D64	},
+{"shrl.qb", "d,t,3",	0x7c000053, 0xff0007ff, WR_d|RD_t,		0,		D32	},
+{"shrlv.ob", "d,t,s",	0x7c0000d7, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D64	},
+{"shrlv.qb", "d,t,s",	0x7c0000d3, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D32	},
+{"subq.ph", "d,s,t",	0x7c0002d0, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D32	},
+{"subq.pw", "d,s,t",	0x7c0004d4, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D64	},
+{"subq.qh", "d,s,t",	0x7c0002d4, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D64	},
+{"subq_s.ph", "d,s,t",	0x7c0003d0, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D32	},
+{"subq_s.pw", "d,s,t",	0x7c0005d4, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D64	},
+{"subq_s.qh", "d,s,t",	0x7c0003d4, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D64	},
+{"subq_s.w", "d,s,t",	0x7c0005d0, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D32	},
+{"subu.ob", "d,s,t",	0x7c000054, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D64	},
+{"subu.qb", "d,s,t",	0x7c000050, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D32	},
+{"subu_s.ob", "d,s,t",	0x7c000154, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D64	},
+{"subu_s.qb", "d,s,t",	0x7c000150, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		D32	},
+{"wrdsp",   "s",	0x7c1ffcf8, 0xfc1fffff, RD_s|DSP_VOLA,		0,		D32	},
+{"wrdsp",   "s,8",	0x7c0004f8, 0xfc1e07ff, RD_s|DSP_VOLA,		0,		D32	},
+/* MIPS DSP ASE Rev2 */
+{"absq_s.qb", "d,t",	0x7c000052, 0xffe007ff, WR_d|RD_t,              0,              D33	},
+{"addu.ph", "d,s,t",	0x7c000210, 0xfc0007ff, WR_d|RD_s|RD_t,         0,              D33	},
+{"addu_s.ph", "d,s,t",	0x7c000310, 0xfc0007ff, WR_d|RD_s|RD_t,         0,              D33	},
+{"adduh.qb", "d,s,t",	0x7c000018, 0xfc0007ff, WR_d|RD_s|RD_t,         0,              D33	},
+{"adduh_r.qb", "d,s,t",	0x7c000098, 0xfc0007ff, WR_d|RD_s|RD_t,         0,              D33	},
+{"append",  "t,s,h",	0x7c000031, 0xfc0007ff, WR_t|RD_t|RD_s,         0,              D33	},
+{"balign",  "t,s,I",	0,    (int) M_BALIGN,	INSN_MACRO,             0,              D33	},
+{"balign",  "t,s,2",	0x7c000431, 0xfc00e7ff, WR_t|RD_t|RD_s,         0,              D33	},
+{"cmpgdu.eq.qb", "d,s,t", 0x7c000611, 0xfc0007ff, WR_d|RD_s|RD_t,       0,              D33	},
+{"cmpgdu.lt.qb", "d,s,t", 0x7c000651, 0xfc0007ff, WR_d|RD_s|RD_t,       0,              D33	},
+{"cmpgdu.le.qb", "d,s,t", 0x7c000691, 0xfc0007ff, WR_d|RD_s|RD_t,       0,              D33	},
+{"dpa.w.ph", "7,s,t",	0x7c000030, 0xfc00e7ff, MOD_a|RD_s|RD_t,        0,              D33	},
+{"dps.w.ph", "7,s,t",	0x7c000070, 0xfc00e7ff, MOD_a|RD_s|RD_t,        0,              D33	},
+{"mul.ph",  "d,s,t",	0x7c000318, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, 0,              D33	},
+{"mul_s.ph", "d,s,t",	0x7c000398, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, 0,              D33	},
+{"mulq_rs.w", "d,s,t",	0x7c0005d8, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, 0,              D33	},
+{"mulq_s.ph", "d,s,t",	0x7c000790, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, 0,              D33	},
+{"mulq_s.w", "d,s,t",	0x7c000598, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, 0,              D33	},
+{"mulsa.w.ph", "7,s,t",	0x7c0000b0, 0xfc00e7ff, MOD_a|RD_s|RD_t,        0,              D33	},
+{"precr.qb.ph", "d,s,t", 0x7c000351, 0xfc0007ff, WR_d|RD_s|RD_t,        0,              D33	},
+{"precr_sra.ph.w", "t,s,h", 0x7c000791, 0xfc0007ff, WR_t|RD_t|RD_s,     0,              D33	},
+{"precr_sra_r.ph.w", "t,s,h", 0x7c0007d1, 0xfc0007ff, WR_t|RD_t|RD_s,   0,              D33	},
+{"prepend", "t,s,h",	0x7c000071, 0xfc0007ff, WR_t|RD_t|RD_s,         0,              D33	},
+{"shra.qb", "d,t,3",	0x7c000113, 0xff0007ff, WR_d|RD_t,              0,              D33	},
+{"shra_r.qb", "d,t,3",	0x7c000153, 0xff0007ff, WR_d|RD_t,              0,              D33	},
+{"shrav.qb", "d,t,s",	0x7c000193, 0xfc0007ff, WR_d|RD_s|RD_t,         0,              D33	},
+{"shrav_r.qb", "d,t,s",	0x7c0001d3, 0xfc0007ff, WR_d|RD_s|RD_t,         0,              D33	},
+{"shrl.ph", "d,t,4",	0x7c000653, 0xfe0007ff, WR_d|RD_t,              0,              D33	},
+{"shrlv.ph", "d,t,s",	0x7c0006d3, 0xfc0007ff, WR_d|RD_s|RD_t,         0,              D33	},
+{"subu.ph", "d,s,t",	0x7c000250, 0xfc0007ff, WR_d|RD_s|RD_t,         0,              D33	},
+{"subu_s.ph", "d,s,t",	0x7c000350, 0xfc0007ff, WR_d|RD_s|RD_t,         0,              D33	},
+{"subuh.qb", "d,s,t",	0x7c000058, 0xfc0007ff, WR_d|RD_s|RD_t,         0,              D33	},
+{"subuh_r.qb", "d,s,t",	0x7c0000d8, 0xfc0007ff, WR_d|RD_s|RD_t,         0,              D33	},
+{"addqh.ph", "d,s,t",	0x7c000218, 0xfc0007ff, WR_d|RD_s|RD_t,		0,              D33	},
+{"addqh_r.ph", "d,s,t",	0x7c000298, 0xfc0007ff, WR_d|RD_s|RD_t,		0,              D33	},
+{"addqh.w", "d,s,t",	0x7c000418, 0xfc0007ff, WR_d|RD_s|RD_t,		0,              D33	},
+{"addqh_r.w", "d,s,t",	0x7c000498, 0xfc0007ff, WR_d|RD_s|RD_t,		0,              D33	},
+{"subqh.ph", "d,s,t",	0x7c000258, 0xfc0007ff, WR_d|RD_s|RD_t,		0,              D33	},
+{"subqh_r.ph", "d,s,t",	0x7c0002d8, 0xfc0007ff, WR_d|RD_s|RD_t,		0,              D33	},
+{"subqh.w", "d,s,t",	0x7c000458, 0xfc0007ff, WR_d|RD_s|RD_t,		0,              D33	},
+{"subqh_r.w", "d,s,t",	0x7c0004d8, 0xfc0007ff, WR_d|RD_s|RD_t,		0,              D33	},
+{"dpax.w.ph", "7,s,t",	0x7c000230, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,              D33	},
+{"dpsx.w.ph", "7,s,t",	0x7c000270, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,              D33	},
+{"dpaqx_s.w.ph", "7,s,t", 0x7c000630, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,              D33	},
+{"dpaqx_sa.w.ph", "7,s,t", 0x7c0006b0, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,              D33	},
+{"dpsqx_s.w.ph", "7,s,t", 0x7c000670, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,              D33	},
+{"dpsqx_sa.w.ph", "7,s,t", 0x7c0006f0, 0xfc00e7ff, MOD_a|RD_s|RD_t,	0,              D33	},
+/* Move bc0* after mftr and mttr to avoid opcode collision.  */
+{"bc0f",    "p",	0x41000000, 0xffff0000,	CBD|RD_CC,		0,		I1	},
+{"bc0fl",   "p",	0x41020000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3	},
+{"bc0t",    "p",	0x41010000, 0xffff0000,	CBD|RD_CC,		0,		I1	},
+{"bc0tl",   "p",	0x41030000, 0xffff0000,	CBL|RD_CC,		0,		I2|T3	},
 };
 
 #define MIPS_NUM_OPCODES \

Modified: trunk/src/host/qemu-neo1973/osdep.c
===================================================================
--- trunk/src/host/qemu-neo1973/osdep.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/osdep.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -264,3 +264,27 @@
 #endif
     return 0;
 }
+
+#ifdef _WIN32
+
+/* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */
+#define _W32_FT_OFFSET (116444736000000000ULL)
+
+int qemu_gettimeofday(qemu_timeval *tp)
+{
+  union {
+    unsigned long long ns100; /*time since 1 Jan 1601 in 100ns units */
+    FILETIME ft;
+  }  _now;
+
+  if(tp)
+    {
+      GetSystemTimeAsFileTime (&_now.ft);
+      tp->tv_usec=(long)((_now.ns100 / 10ULL) % 1000000ULL );
+      tp->tv_sec= (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000ULL);
+    }
+  /* Always return 0 as per Open Group Base Specifications Issue 6.
+     Do not set errno on error.  */
+  return 0;
+}
+#endif /* _WIN32 */

Modified: trunk/src/host/qemu-neo1973/osdep.h
===================================================================
--- trunk/src/host/qemu-neo1973/osdep.h	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/osdep.h	2007-06-17 16:55:00 UTC (rev 2289)
@@ -17,4 +17,15 @@
 
 int qemu_create_pidfile(const char *filename);
 
+#ifdef _WIN32
+typedef struct {
+    long tv_sec;
+    long tv_usec;
+} qemu_timeval;
+int qemu_gettimeofday(qemu_timeval *tp);
+#else
+typedef struct timeval qemu_timeval;
+#define qemu_gettimeofday(tp) gettimeofday(tp, NULL);
+#endif /* !_WIN32 */
+
 #endif

Modified: trunk/src/host/qemu-neo1973/qemu-doc.texi
===================================================================
--- trunk/src/host/qemu-neo1973/qemu-doc.texi	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/qemu-doc.texi	2007-06-17 16:55:00 UTC (rev 2289)
@@ -81,6 +81,7 @@
 @item ARM Versatile baseboard (ARM926E)
 @item ARM RealView Emulation baseboard (ARM926EJ-S)
 @item Spitz, Akita, Borzoi and Terrier PDAs (PXA270 processor)
+ at item Freescale MCF5208EVB (ColdFire V2).
 @item Arnewsh MCF5206 evaluation board (ColdFire V2).
 @end itemize
 
@@ -153,7 +154,7 @@
 @item
 Floppy disk
 @item 
-NE2000 PCI network adapters
+PCI/ISA PCI network adapters
 @item
 Serial ports
 @item
@@ -355,19 +356,20 @@
 
 @item -net nic[,vlan=n][,macaddr=addr][,model=type]
 Create a new Network Interface Card and connect it to VLAN @var{n} (@var{n}
-= 0 is the default). The NIC is currently an NE2000 on the PC
+= 0 is the default). The NIC is an ne2k_pci by default on the PC
 target. Optionally, the MAC address can be changed. If no
 @option{-net} option is specified, a single NIC is created.
 Qemu can emulate several different models of network card.
 Valid values for @var{type} are
 @code{i82551}, @code{i82557b}, @code{i82559er},
 @code{ne2k_pci}, @code{ne2k_isa}, @code{pcnet}, @code{rtl8139},
- at code{smc91c111} and @code{lance}.
-Not all devices are supported on all targets.
+ at code{smc91c111}, @code{lance} and @code{mcf_fec}.
+Not all devices are supported on all targets.  Use -net nic,model=?
+for a list of available devices for your target.
 
 @item -net user[,vlan=n][,hostname=name]
 Use the user mode network stack which requires no administrator
-priviledge to run.  @option{hostname=name} can be used to specify the client
+privilege to run.  @option{hostname=name} can be used to specify the client
 hostname reported by the builtin DHCP server.
 
 @item -net tap[,vlan=n][,fd=h][,ifname=name][,script=file]
@@ -422,7 +424,8 @@
 @item
 mcast support is compatible with User Mode Linux (argument @option{eth at var{N}=mcast}), see
 @url{http://user-mode-linux.sf.net}.
- at item Use @option{fd=h} to specify an already opened UDP multicast socket.
+ at item
+Use @option{fd=h} to specify an already opened UDP multicast socket.
 @end enumerate
 
 Example:
@@ -575,7 +578,7 @@
 @item COMn
 [Windows only] Use host serial port @var{n}
 @item udp:[remote_host]:remote_port[@@[src_ip]:src_port]
-This implements UDP Net Console.  When @var{remote_host} or @var{src_ip} are not specified they default to @code{0.0.0.0}.  When not using a specifed @var{src_port} a random port is automatically chosen.
+This implements UDP Net Console.  When @var{remote_host} or @var{src_ip} are not specified they default to @code{0.0.0.0}.  When not using a specified @var{src_port} a random port is automatically chosen.
 
 If you just want a simple readonly console you can use @code{netcat} or
 @code{nc}, by starting qemu with: @code{-serial udp::4555} and nc as:
@@ -608,7 +611,7 @@
 the @var{server} option QEMU will wait for a client socket application
 to connect to the port before continuing, unless the @code{nowait}
 option was specified.  The @code{nodelay} option disables the Nagle buffering
-algoritm.  If @var{host} is omitted, 0.0.0.0 is assumed. Only
+algorithm.  If @var{host} is omitted, 0.0.0.0 is assumed. Only
 one TCP connection at a time is accepted. You can use @code{telnet} to
 connect to the corresponding character device.
 @table @code
@@ -691,7 +694,7 @@
 Force hard disk 0 physical geometry (1 <= @var{c} <= 16383, 1 <=
 @var{h} <= 16, 1 <= @var{s} <= 63) and optionally force the BIOS
 translation mode (@var{t}=none, lba or auto). Usually QEMU can guess
-all thoses parameters. This option is useful for old MS-DOS disk
+all those parameters. This option is useful for old MS-DOS disk
 images.
 
 @item -L path
@@ -715,7 +718,11 @@
 Start right away with a saved state (@code{loadvm} in monitor)
 
 @item -semihosting
-Enable "Angel" semihosting interface (ARM target machines only).
+Enable semihosting syscall emulation (ARM and M68K target machines only).
+
+On ARM this implements the "Angel" interface.
+On M68K this implements the "ColdFire GDB" interface used by libgloss.
+
 Note that this allows guest direct access to the host filesystem,
 so should only be used with trusted guest OS.
 @end table
@@ -924,7 +931,7 @@
 is the number of items to be dumped.
 
 @item format
-can be x (hexa), d (signed decimal), u (unsigned decimal), o (octal),
+can be x (hex), d (signed decimal), u (unsigned decimal), o (octal),
 c (char) or i (asm instruction).
 
 @item size
@@ -1113,7 +1120,7 @@
 @subsubsection Linux
 
 On Linux, you can directly use the host device filename instead of a
-disk image filename provided you have enough proviledge to access
+disk image filename provided you have enough privileges to access
 it. For example, use @file{/dev/cdrom} to access to the CDROM or
 @file{/dev/fd0} for the floppy.
 
@@ -1140,7 +1147,7 @@
 
 @table @code
 @item CD
-The prefered syntax is the drive letter (e.g. @file{d:}). The
+The preferred syntax is the drive letter (e.g. @file{d:}). The
 alternate syntax @file{\\.\d:} is supported. @file{/dev/cdrom} is
 supported as an alias to the first CDROM drive.
 
@@ -1204,11 +1211,11 @@
 @node pcsys_network
 @section Network emulation
 
-QEMU can simulate several networks cards (NE2000 boards on the PC
+QEMU can simulate several network cards (PCI or ISA cards on the PC
 target) and can connect them to an arbitrary number of Virtual Local
 Area Networks (VLANs). Host TAP devices can be connected to any QEMU
 VLAN. VLAN can be connected between separate instances of QEMU to
-simulate large networks. For simpler usage, a non priviledged user mode
+simulate large networks. For simpler usage, a non privileged user mode
 network stack can replace the TAP device to have a basic network
 connection.
 
@@ -1248,7 +1255,7 @@
 
 By using the option @option{-net user} (default configuration if no
 @option{-net} option is specified), QEMU uses a completely user mode
-network stack (you don't need root priviledge to use the virtual
+network stack (you don't need root privilege to use the virtual
 network). The virtual network configuration is the following:
 
 @example
@@ -1271,7 +1278,7 @@
 10.0.2.x from the QEMU virtual DHCP server.
 
 Note that @code{ping} is not supported reliably to the internet as it
-would require root priviledges. It means you can only ping the local
+would require root privileges. It means you can only ping the local
 router (10.0.2.2).
 
 When using the built-in TFTP server, the router is also the TFTP
@@ -1351,6 +1358,10 @@
 @item @code{host:vendor_id:product_id}
 Pass through the host device identified by @var{vendor_id:product_id}
 (Linux only)
+ at item @code{wacom-tablet}
+Virtual Wacom PenPartner tablet.  This device is similar to the @code{tablet}
+above but it can be used with the tslib library because in addition to touch
+coordinates it reports touch pressure.
 @end table
 
 @node host_usb_devices
@@ -1460,7 +1471,7 @@
 When using a 2.6 guest Linux kernel, verify that the 4G/4G patch is
 not activated because QEMU is slower with this patch. The QEMU
 Accelerator Module is also much slower in this case. Earlier Fedora
-Core 3 Linux kernel (< 2.6.9-1.724_FC3) were known to incorporte this
+Core 3 Linux kernel (< 2.6.9-1.724_FC3) were known to incorporate this
 patch by default. Newer kernels don't have it.
 
 @subsection Windows
@@ -1542,7 +1553,7 @@
 
 QEMU is a generic emulator and it emulates many non PC
 machines. Most of the options are similar to the PC emulator. The
-differences are mentionned in the following sections.
+differences are mentioned in the following sections.
 
 @menu
 * QEMU PowerPC System emulator::
@@ -1622,7 +1633,7 @@
 @section Sparc32 System emulator invocation
 
 Use the executable @file{qemu-system-sparc} to simulate a SparcStation 5
-(sun4m architecture). The emulation is somewhat complete.
+or SparcStation 10 (sun4m architecture). The emulation is somewhat complete.
 
 QEMU emulates the following sun4m peripherals:
 
@@ -1642,6 +1653,8 @@
 ESP SCSI controller with hard disk and CD-ROM support
 @item
 Floppy drive
+ at item
+CS4231 sound device (only on SS-5, not working yet)
 @end itemize
 
 The number of peripherals is fixed in the architecture.
@@ -1657,13 +1670,14 @@
 
 @c man begin OPTIONS
 
-The following options are specific to the Sparc emulation:
+The following options are specific to the Sparc32 emulation:
 
 @table @option
 
- at item -g WxH
+ at item -g WxHx[xDEPTH]
 
-Set the initial TCX graphic mode. The default is 1024x768.
+Set the initial TCX graphic mode. The default is 1024x768x8, currently
+the only other possible mode is 1024x768x24.
 
 @item -prom-env string
 
@@ -1674,6 +1688,10 @@
  -prom-env 'boot-device=sd(0,2,0):d' -prom-env 'boot-args=linux single'
 @end example
 
+ at item -M [SS-5|SS-10]
+
+Set the emulated machine type. Default is SS-5.
+
 @end table
 
 @c man end 
@@ -1755,8 +1773,8 @@
 @item
 PCI host bridge.  Note the emulated PCI bridge only provides access to
 PCI memory space.  It does not provide access to PCI IO space.
-This means some devices (eg. ne2k_pci NIC) are not useable, and others
-(eg. rtl8139 NIC) are only useable when the guest drivers use the memory
+This means some devices (eg. ne2k_pci NIC) are not usable, and others
+(eg. rtl8139 NIC) are only usable when the guest drivers use the memory
 mapped control registers.
 @item
 PCI OHCI USB controller.
@@ -1829,10 +1847,22 @@
 
 Use the executable @file{qemu-system-m68k} to simulate a ColdFire machine.
 The emulator is able to boot a uClinux kernel.
-The following devices are emulated:
 
+The M5208EVB emulation includes the following devices:
+
 @itemize @minus
 @item 
+MCF5208 ColdFire V2 Microprocessor (ISA A+ with EMAC).
+ at item
+Three Two on-chip UARTs.
+ at item
+Fast Ethernet Controller (FEC)
+ at end itemize
+
+The AN5206 emulation includes the following devices:
+
+ at itemize @minus
+ at item 
 MCF5206 ColdFire V2 Microprocessor.
 @item
 Two on-chip UARTs.
@@ -1854,9 +1884,9 @@
 
 @itemize @minus
 @item
-Linux (refered as qemu-linux-user)
+Linux (referred as qemu-linux-user)
 @item
-Mac OS X/Darwin (refered as qemu-darwin-user)
+Mac OS X/Darwin (referred as qemu-darwin-user)
 @end itemize
 
 @node Linux User space emulator
@@ -2114,7 +2144,7 @@
 Linux distribution includes a gcc 4.x compiler, you can usually
 install an older version (it is invoked by @code{gcc32} or
 @code{gcc34}). The QEMU configure script automatically probes for
-these older versions so that usally you don't have to do anything.
+these older versions so that usually you don't have to do anything.
 
 @node Windows
 @section Windows
@@ -2166,7 +2196,7 @@
 ./configure --enable-mingw32
 @end example
 If necessary, you can change the cross-prefix according to the prefix
-choosen for the MinGW tools with --cross-prefix. You can also use
+chosen for the MinGW tools with --cross-prefix. You can also use
 --prefix to set the Win32 install path.
 
 @item You can install QEMU in the installation directory by typing 

Modified: trunk/src/host/qemu-neo1973/qemu-img.texi
===================================================================
--- trunk/src/host/qemu-neo1973/qemu-img.texi	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/qemu-img.texi	2007-06-17 16:55:00 UTC (rev 2289)
@@ -89,7 +89,7 @@
 @item convert [-c] [-e] [-f @var{fmt}] @var{filename} [-O @var{output_fmt}] @var{output_filename}
 
 Convert the disk image @var{filename} to disk image @var{output_filename}
-using format @var{output_fmt}. It can be optionnaly encrypted
+using format @var{output_fmt}. It can be optionally encrypted
 (@code{-e} option) or compressed (@code{-c} option).
 
 Only the format @code{qcow} supports encryption or compression. The

Modified: trunk/src/host/qemu-neo1973/sdl.c
===================================================================
--- trunk/src/host/qemu-neo1973/sdl.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/sdl.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -87,7 +87,7 @@
     ds->data = screen->pixels;
     ds->linesize = screen->pitch;
     ds->depth = screen->format->BitsPerPixel;
-    if (ds->depth == 32 && screen->format->Rshift == 0) {
+    if (screen->format->Bshift > screen->format->Rshift) {
         ds->bgr = 1;
     } else {
         ds->bgr = 0;
@@ -407,7 +407,8 @@
                         case SDLK_END: keysym = QEMU_KEY_END; break;
                         case SDLK_PAGEUP: keysym = QEMU_KEY_PAGEUP; break;
                         case SDLK_PAGEDOWN: keysym = QEMU_KEY_PAGEDOWN; break;
-                        case SDLK_BACKSPACE: keysym = QEMU_KEY_BACKSPACE; break;                        case SDLK_DELETE: keysym = QEMU_KEY_DELETE; break;
+                        case SDLK_BACKSPACE: keysym = QEMU_KEY_BACKSPACE; break;
+                        case SDLK_DELETE: keysym = QEMU_KEY_DELETE; break;
                         default: break;
                         }
                     }

Modified: trunk/src/host/qemu-neo1973/sparc-dis.c
===================================================================
--- trunk/src/host/qemu-neo1973/sparc-dis.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/sparc-dis.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -276,7 +276,7 @@
   { "v8", MASK_V6 | MASK_V7 | MASK_V8 },
   { "sparclet", MASK_V6 | MASK_V7 | MASK_V8 | MASK_SPARCLET },
   { "sparclite", MASK_V6 | MASK_V7 | MASK_V8 | MASK_SPARCLITE },
-  /* ??? Don't some v8 priviledged insns conflict with v9?  */
+  /* ??? Don't some v8 privileged insns conflict with v9?  */
   { "v9", MASK_V6 | MASK_V7 | MASK_V8 | MASK_V9 },
   /* v9 with ultrasparc additions */
   { "v9a", MASK_V6 | MASK_V7 | MASK_V8 | MASK_V9 | MASK_V9A },
@@ -2206,7 +2206,7 @@
 
 /* Handle membar masks.  */
 
-static arg membar_table[] =
+static const arg membar_table[] =
 {
   { 0x40, "#Sync" },
   { 0x20, "#MemIssue" },
@@ -2238,7 +2238,7 @@
 
 /* Handle prefetch args.  */
 
-static arg prefetch_table[] =
+static const arg prefetch_table[] =
 {
   { 0, "#n_reads" },
   { 1, "#one_read" },
@@ -2269,7 +2269,7 @@
 
 /* Handle sparclet coprocessor registers.  */
 
-static arg sparclet_cpreg_table[] =
+static const arg sparclet_cpreg_table[] =
 {
   { 0, "%ccsr" },
   { 1, "%ccfr" },
@@ -2320,7 +2320,7 @@
 /* It is important that we only look at insn code bits as that is how the
    opcode table is hashed.  OPCODE_BITS is a table of valid bits for each
    of the main types (0,1,2,3).  */
-static int opcode_bits[4] = { 0x01c00000, 0x0, 0x01f80000, 0x01f80000 };
+static const int opcode_bits[4] = { 0x01c00000, 0x0, 0x01f80000, 0x01f80000 };
 #define HASH_INSN(INSN) \
   ((((INSN) >> 24) & 0xc0) | (((INSN) & opcode_bits[((INSN) >> 30) & 3]) >> 19))
 struct opcode_hash {
@@ -2340,7 +2340,7 @@
 	((((int)(value)) << ((8 * sizeof (int)) - bits))	\
 			 >> ((8 * sizeof (int)) - bits) )
 
-static  char *reg_names[] =
+static const char * const reg_names[] =
 { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",	
   "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",	
   "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",	
@@ -2361,7 +2361,7 @@
 
 /* These are ordered according to there register number in
    rdpr and wrpr insns.  */
-static char *v9_priv_reg_names[] =
+static const char * const v9_priv_reg_names[] =
 {
   "tpc", "tnpc", "tstate", "tt", "tick", "tba", "pstate", "tl",
   "pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin",
@@ -2371,7 +2371,7 @@
 
 /* These are ordered according to there register number in
    rd and wr insns (-16).  */
-static char *v9a_asr_reg_names[] =
+static const char * const v9a_asr_reg_names[] =
 {
   "pcr", "pic", "dcr", "gsr", "set_softint", "clear_softint",
   "softint", "tick_cmpr", "sys_tick", "sys_tick_cmpr"

Modified: trunk/src/host/qemu-neo1973/target-alpha/cpu.h
===================================================================
--- trunk/src/host/qemu-neo1973/target-alpha/cpu.h	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-alpha/cpu.h	2007-06-17 16:55:00 UTC (rev 2289)
@@ -300,6 +300,12 @@
     pal_handler_t *pal_handler;
 };
 
+#define CPUState CPUAlphaState
+#define cpu_init cpu_alpha_init
+#define cpu_exec cpu_alpha_exec
+#define cpu_gen_code cpu_alpha_gen_code
+#define cpu_signal_handler cpu_alpha_signal_handler
+
 #include "cpu-all.h"
 
 enum {

Modified: trunk/src/host/qemu-neo1973/target-alpha/exec.h
===================================================================
--- trunk/src/host/qemu-neo1973/target-alpha/exec.h	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-alpha/exec.h	2007-06-17 16:55:00 UTC (rev 2289)
@@ -79,4 +79,14 @@
 
 void do_interrupt (CPUState *env);
 
+static inline int cpu_halted(CPUState *env) {
+    if (!env->halted)
+        return 0;
+    if (env->interrupt_request & CPU_INTERRUPT_HARD) {
+        env->halted = 0;
+        return 0;
+    }
+    return EXCP_HALTED;
+}
+
 #endif /* !defined (__ALPHA_EXEC_H__) */

Modified: trunk/src/host/qemu-neo1973/target-alpha/translate.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-alpha/translate.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-alpha/translate.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -232,10 +232,12 @@
 GEN_LD(q_l);
 GEN_ST(q_c);
 
+#if 0 /* currently unused */
 GEN_LD(f);
 GEN_ST(f);
 GEN_LD(g);
 GEN_ST(g);
+#endif /* 0 */
 GEN_LD(s);
 GEN_ST(s);
 GEN_LD(t);

Modified: trunk/src/host/qemu-neo1973/target-arm/cpu.h
===================================================================
--- trunk/src/host/qemu-neo1973/target-arm/cpu.h	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-arm/cpu.h	2007-06-17 16:55:00 UTC (rev 2289)
@@ -287,6 +287,13 @@
    architecture revisions.  Maybe an a configure option to disable them.  */
 #define TARGET_PAGE_BITS 10
 #endif
+
+#define CPUState CPUARMState
+#define cpu_init cpu_arm_init
+#define cpu_exec cpu_arm_exec
+#define cpu_gen_code cpu_arm_gen_code
+#define cpu_signal_handler cpu_arm_signal_handler
+
 #include "cpu-all.h"
 
 #endif

Modified: trunk/src/host/qemu-neo1973/target-arm/exec.h
===================================================================
--- trunk/src/host/qemu-neo1973/target-arm/exec.h	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-arm/exec.h	2007-06-17 16:55:00 UTC (rev 2289)
@@ -48,6 +48,20 @@
 int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
                               int is_user, int is_softmmu);
 
+static inline int cpu_halted(CPUState *env) {
+    if (!env->halted)
+        return 0;
+    /* An interrupt wakes the CPU even if the I and F CPSR bits are
+       set.  We use EXITTB to silently wake CPU without causing an
+       actual interrupt.  */
+    if (env->interrupt_request &
+        (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB)) {
+        env->halted = 0;
+        return 0;
+    }
+    return EXCP_HALTED;
+}
+
 #if !defined(CONFIG_USER_ONLY)
 #include "softmmu_exec.h"
 #endif

Modified: trunk/src/host/qemu-neo1973/target-arm/translate.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-arm/translate.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-arm/translate.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -2325,9 +2325,9 @@
 
             /* branch link/exchange thumb (blx) */
             val = (uint32_t)s->pc;
-            gen_op_movl_T0_im(val);
-            gen_movl_reg_T0(s, 14);
+            gen_op_movl_T1_im(val);
             gen_movl_T0_reg(s, rm);
+            gen_movl_reg_T1(s, 14);
             gen_bx(s);
             break;
         case 0x5: /* saturating add/subtract */
@@ -2837,8 +2837,8 @@
                         } else {
                             /* store */
                             if (i == 15) {
-                                /* special case: r15 = PC + 12 */
-                                val = (long)s->pc + 8;
+                                /* special case: r15 = PC + 8 */
+                                val = (long)s->pc + 4;
                                 gen_op_movl_TN_im[0](val);
                             } else if (user) {
                                 gen_op_movl_T0_user(i);

Modified: trunk/src/host/qemu-neo1973/target-i386/cpu.h
===================================================================
--- trunk/src/host/qemu-neo1973/target-i386/cpu.h	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-i386/cpu.h	2007-06-17 16:55:00 UTC (rev 2289)
@@ -661,6 +661,13 @@
 #endif
 
 #define TARGET_PAGE_BITS 12
+
+#define CPUState CPUX86State
+#define cpu_init cpu_x86_init
+#define cpu_exec cpu_x86_exec
+#define cpu_gen_code cpu_x86_gen_code
+#define cpu_signal_handler cpu_x86_signal_handler
+
 #include "cpu-all.h"
 
 #endif /* CPU_I386_H */

Modified: trunk/src/host/qemu-neo1973/target-i386/exec.h
===================================================================
--- trunk/src/host/qemu-neo1973/target-i386/exec.h	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-i386/exec.h	2007-06-17 16:55:00 UTC (rev 2289)
@@ -575,3 +575,16 @@
     env->regs[R_EDI] = EDI;
 #endif
 }
+
+static inline int cpu_halted(CPUState *env) {
+    /* handle exit of HALTED state */
+    if (!(env->hflags & HF_HALTED_MASK))
+        return 0;
+    /* disable halt condition */
+    if ((env->interrupt_request & CPU_INTERRUPT_HARD) &&
+        (env->eflags & IF_MASK)) {
+        env->hflags &= ~HF_HALTED_MASK;
+        return 0;
+    }
+    return EXCP_HALTED;
+}

Modified: trunk/src/host/qemu-neo1973/target-i386/helper.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-i386/helper.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-i386/helper.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -106,14 +106,6 @@
     spin_unlock(&global_cpu_lock);
 }
 
-void cpu_loop_exit(void)
-{
-    /* NOTE: the register at this point must be saved by hand because
-       longjmp restore them */
-    regs_to_env();
-    longjmp(env->jmp_env, 1);
-}
-
 /* return non zero if error */
 static inline int load_segment(uint32_t *e1_ptr, uint32_t *e2_ptr,
                                int selector)
@@ -687,7 +679,7 @@
     if (!(e2 & DESC_P_MASK))
         raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);
     if (!(e2 & DESC_C_MASK) && dpl < cpl) {
-        /* to inner priviledge */
+        /* to inner privilege */
         get_ss_esp_from_tss(&ss, &esp, dpl);
         if ((ss & 0xfffc) == 0)
             raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
@@ -708,7 +700,7 @@
         sp_mask = get_sp_mask(ss_e2);
         ssp = get_seg_base(ss_e1, ss_e2);
     } else if ((e2 & DESC_C_MASK) || dpl == cpl) {
-        /* to same priviledge */
+        /* to same privilege */
         if (env->eflags & VM_MASK)
             raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
         new_stack = 0;
@@ -901,7 +893,7 @@
     if (!(e2 & DESC_L_MASK) || (e2 & DESC_B_MASK))
         raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
     if ((!(e2 & DESC_C_MASK) && dpl < cpl) || ist != 0) {
-        /* to inner priviledge */
+        /* to inner privilege */
         if (ist != 0)
             esp = get_rsp_from_tss(ist + 3);
         else
@@ -910,7 +902,7 @@
         ss = 0;
         new_stack = 1;
     } else if ((e2 & DESC_C_MASK) || dpl == cpl) {
-        /* to same priviledge */
+        /* to same privilege */
         if (env->eflags & VM_MASK)
             raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
         new_stack = 0;
@@ -2208,7 +2200,7 @@
             raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);
 
         if (!(e2 & DESC_C_MASK) && dpl < cpl) {
-            /* to inner priviledge */
+            /* to inner privilege */
             get_ss_esp_from_tss(&ss, &sp, dpl);
 #ifdef DEBUG_PCALL
             if (loglevel & CPU_LOG_PCALL)
@@ -2255,7 +2247,7 @@
             }
             new_stack = 1;
         } else {
-            /* to same priviledge */
+            /* to same privilege */
             sp = ESP;
             sp_mask = get_sp_mask(env->segs[R_SS].flags);
             ssp = env->segs[R_SS].base;
@@ -2437,7 +2429,7 @@
                        get_seg_limit(e1, e2),
                        e2);
     } else {
-        /* return to different priviledge level */
+        /* return to different privilege level */
 #ifdef TARGET_X86_64
         if (shift == 2) {
             POPQ(sp, new_esp);

Modified: trunk/src/host/qemu-neo1973/target-i386/translate.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-i386/translate.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-i386/translate.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -2245,7 +2245,7 @@
 }
 
 /* an interrupt is different from an exception because of the
-   priviledge checks */
+   privilege checks */
 static void gen_interrupt(DisasContext *s, int intno, 
                           target_ulong cur_eip, target_ulong next_eip)
 {
@@ -6431,7 +6431,7 @@
 
     opc_ptr = opc_buf + opc_buf_len;
     /* live_flags contains the flags needed by the next instructions
-       in the code. At the end of the bloc, we consider that all the
+       in the code. At the end of the block, we consider that all the
        flags are live. */
     live_flags = CC_OSZAPC;
     while (opc_ptr > opc_buf) {

Modified: trunk/src/host/qemu-neo1973/target-m68k/cpu.h
===================================================================
--- trunk/src/host/qemu-neo1973/target-m68k/cpu.h	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-m68k/cpu.h	2007-06-17 16:55:00 UTC (rev 2289)
@@ -51,6 +51,7 @@
 #define EXCP_ICE            13
 
 #define EXCP_RTE            0x100
+#define EXCP_HALT_INSN      0x101
 
 typedef struct CPUM68KState {
     uint32_t dregs[8];
@@ -58,6 +59,10 @@
     uint32_t pc;
     uint32_t sr;
 
+    /* SSP and USP.  The current_sp is stored in aregs[7], the other here.  */
+    int current_sp;
+    uint32_t sp[2];
+
     /* Condition flags.  */
     uint32_t cc_op;
     uint32_t cc_dest;
@@ -70,6 +75,14 @@
     uint32_t fpsr;
     float_status fp_status;
 
+    uint64_t mactmp;
+    /* EMAC Hardware deals with 48-bit values composed of one 32-bit and
+       two 8-bit parts.  We store a single 64-bit value and
+       rearrange/extend this when changing modes.  */
+    uint64_t macc[4];
+    uint32_t macsr;
+    uint32_t mac_mask;
+
     /* Temporary storage for DIV helpers.  */
     uint32_t div1;
     uint32_t div2;
@@ -83,7 +96,10 @@
     uint32_t vbr;
     uint32_t mbar;
     uint32_t rambar0;
+    uint32_t cacr;
 
+    uint32_t features;
+
     /* ??? remove this.  */
     uint32_t t1;
 
@@ -140,14 +156,59 @@
 #define SR_S  0x2000
 #define SR_T  0x8000
 
+#define M68K_SSP    0
+#define M68K_USP    1
+
+/* CACR fields are implementation defined, but some bits are common.  */
+#define M68K_CACR_EUSP  0x10
+
+#define MACSR_PAV0  0x100
+#define MACSR_OMC   0x080
+#define MACSR_SU    0x040
+#define MACSR_FI    0x020
+#define MACSR_RT    0x010
+#define MACSR_N     0x008
+#define MACSR_Z     0x004
+#define MACSR_V     0x002
+#define MACSR_EV    0x001
+
 typedef struct m68k_def_t m68k_def_t;
 
 int cpu_m68k_set_model(CPUM68KState *env, const char * name);
 
 void m68k_set_irq_level(CPUM68KState *env, int level, uint8_t vector);
+void m68k_set_macsr(CPUM68KState *env, uint32_t val);
+void m68k_switch_sp(CPUM68KState *env);
 
 #define M68K_FPCR_PREC (1 << 6)
 
+void do_m68k_semihosting(CPUM68KState *env, int nr);
+
+/* There are 4 ColdFire core ISA revisions: A, A+, B and C.
+   Each feature covers the subset of instructions common to the
+   ISA revisions mentioned.  */
+
+enum m68k_features {
+    M68K_FEATURE_CF_ISA_A,
+    M68K_FEATURE_CF_ISA_B, /* (ISA B or C).  */
+    M68K_FEATURE_CF_ISA_APLUSC, /* BIT/BITREV, FF1, STRLDSR (ISA A+ or C).  */
+    M68K_FEATURE_BRAL, /* Long unconditional branch.  (ISA A+ or B).  */
+    M68K_FEATURE_CF_FPU,
+    M68K_FEATURE_CF_MAC,
+    M68K_FEATURE_CF_EMAC,
+    M68K_FEATURE_CF_EMAC_B, /* Revision B EMAC (dual accumulate).  */
+    M68K_FEATURE_USP, /* User Stack Pointer.  (ISA A+, B or C).  */
+    M68K_FEATURE_EXT_FULL, /* 68020+ full extension word.  */
+    M68K_FEATURE_WORD_INDEX /* word sized address index registers.  */
+};
+
+static inline int m68k_feature(CPUM68KState *env, int feature)
+{
+    return (env->features & (1u << feature)) != 0;
+}
+
+void register_m68k_insns (CPUM68KState *env);
+
 #ifdef CONFIG_USER_ONLY
 /* Linux uses 8k pages.  */
 #define TARGET_PAGE_BITS 13
@@ -155,6 +216,13 @@
 /* Smallest TLB entry size is 1k.  */ 
 #define TARGET_PAGE_BITS 10
 #endif
+
+#define CPUState CPUM68KState
+#define cpu_init cpu_m68k_init
+#define cpu_exec cpu_m68k_exec
+#define cpu_gen_code cpu_m68k_gen_code
+#define cpu_signal_handler cpu_m68k_signal_handler
+
 #include "cpu-all.h"
 
 #endif

Modified: trunk/src/host/qemu-neo1973/target-m68k/exec.h
===================================================================
--- trunk/src/host/qemu-neo1973/target-m68k/exec.h	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-m68k/exec.h	2007-06-17 16:55:00 UTC (rev 2289)
@@ -49,3 +49,13 @@
 void helper_movec(CPUM68KState *env, int reg, uint32_t val);
 
 void cpu_loop_exit(void);
+
+static inline int cpu_halted(CPUState *env) {
+    if (!env->halted)
+        return 0;
+    if (env->interrupt_request & CPU_INTERRUPT_HARD) {
+        env->halted = 0;
+        return 0;
+    }
+    return EXCP_HALTED;
+}

Modified: trunk/src/host/qemu-neo1973/target-m68k/helper.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-m68k/helper.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-m68k/helper.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -20,11 +20,88 @@
  */
 
 #include <stdio.h>
+#include <string.h>
 
 #include "config.h"
 #include "cpu.h"
 #include "exec-all.h"
 
+enum m68k_cpuid {
+    M68K_CPUID_M5206,
+    M68K_CPUID_M5208,
+    M68K_CPUID_CFV4E,
+    M68K_CPUID_ANY,
+};
+
+struct m68k_def_t {
+    const char * name;
+    enum m68k_cpuid id;
+};
+
+static m68k_def_t m68k_cpu_defs[] = {
+    {"m5206", M68K_CPUID_M5206}, 
+    {"m5208", M68K_CPUID_M5208}, 
+    {"cfv4e", M68K_CPUID_CFV4E},
+    {"any", M68K_CPUID_ANY},
+    {NULL, 0}, 
+};
+
+static void m68k_set_feature(CPUM68KState *env, int feature)
+{
+    env->features |= (1u << feature);
+}
+
+int cpu_m68k_set_model(CPUM68KState *env, const char * name)
+{
+    m68k_def_t *def;
+
+    for (def = m68k_cpu_defs; def->name; def++) {
+        if (strcmp(def->name, name) == 0)
+            break;
+    }
+    if (!def->name)
+        return 1;
+
+    switch (def->id) {
+    case M68K_CPUID_M5206:
+        m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
+        break;
+    case M68K_CPUID_M5208:
+        m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
+        m68k_set_feature(env, M68K_FEATURE_CF_ISA_APLUSC);
+        m68k_set_feature(env, M68K_FEATURE_BRAL);
+        m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
+        m68k_set_feature(env, M68K_FEATURE_USP);
+        break;
+    case M68K_CPUID_CFV4E:
+        m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
+        m68k_set_feature(env, M68K_FEATURE_CF_ISA_B);
+        m68k_set_feature(env, M68K_FEATURE_BRAL);
+        m68k_set_feature(env, M68K_FEATURE_CF_FPU);
+        m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
+        m68k_set_feature(env, M68K_FEATURE_USP);
+        break;
+    case M68K_CPUID_ANY:
+        m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
+        m68k_set_feature(env, M68K_FEATURE_CF_ISA_B);
+        m68k_set_feature(env, M68K_FEATURE_CF_ISA_APLUSC);
+        m68k_set_feature(env, M68K_FEATURE_BRAL);
+        m68k_set_feature(env, M68K_FEATURE_CF_FPU);
+        /* MAC and EMAC are mututally exclusive, so pick EMAC.
+           It's mostly backwards compatible.  */
+        m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
+        m68k_set_feature(env, M68K_FEATURE_CF_EMAC_B);
+        m68k_set_feature(env, M68K_FEATURE_USP);
+        m68k_set_feature(env, M68K_FEATURE_EXT_FULL);
+        m68k_set_feature(env, M68K_FEATURE_WORD_INDEX);
+        break;
+    }
+
+    register_m68k_insns(env);
+
+    return 0;
+}
+
 void cpu_m68k_flush_flags(CPUM68KState *env, int cc_op)
 {
     int flags;
@@ -152,8 +229,12 @@
 {
     switch (reg) {
     case 0x02: /* CACR */
-        /* Ignored.  */
+        env->cacr = val;
+        m68k_switch_sp(env);
         break;
+    case 0x04: case 0x05: case 0x06: case 0x07: /* ACR[0-3] */
+        /* TODO: Implement Access Control Registers.  */
+        break;
     case 0x801: /* VBR */
         env->vbr = val;
         break;
@@ -164,6 +245,51 @@
     }
 }
 
+void m68k_set_macsr(CPUM68KState *env, uint32_t val)
+{
+    uint32_t acc;
+    int8_t exthigh;
+    uint8_t extlow;
+    uint64_t regval;
+    int i;
+    if ((env->macsr ^ val) & (MACSR_FI | MACSR_SU)) {
+        for (i = 0; i < 4; i++) {
+            regval = env->macc[i];
+            exthigh = regval >> 40;
+            if (env->macsr & MACSR_FI) {
+                acc = regval >> 8;
+                extlow = regval;
+            } else {
+                acc = regval;
+                extlow = regval >> 32;
+            }
+            if (env->macsr & MACSR_FI) {
+                regval = (((uint64_t)acc) << 8) | extlow;
+                regval |= ((int64_t)exthigh) << 40;
+            } else if (env->macsr & MACSR_SU) {
+                regval = acc | (((int64_t)extlow) << 32);
+                regval |= ((int64_t)exthigh) << 40;
+            } else {
+                regval = acc | (((uint64_t)extlow) << 32);
+                regval |= ((uint64_t)(uint8_t)exthigh) << 40;
+            }
+            env->macc[i] = regval;
+        }
+    }
+    env->macsr = val;
+}
+
+void m68k_switch_sp(CPUM68KState *env)
+{
+    int new_sp;
+
+    env->sp[env->current_sp] = env->aregs[7];
+    new_sp = (env->sr & SR_S && env->cacr & M68K_CACR_EUSP)
+             ? M68K_SSP : M68K_USP;
+    env->aregs[7] = env->sp[new_sp];
+    env->current_sp = new_sp;
+}
+
 /* MMU */
 
 /* TODO: This will need fixing once the MMU is implemented.  */

Modified: trunk/src/host/qemu-neo1973/target-m68k/op-hacks.h
===================================================================
--- trunk/src/host/qemu-neo1973/target-m68k/op-hacks.h	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-m68k/op-hacks.h	2007-06-17 16:55:00 UTC (rev 2289)
@@ -103,3 +103,28 @@
         gen_op_goto_tb1(TBPARAM(tb));
     }
 }
+
+static inline void gen_op_jmp_z32(int val, int label)
+{
+    gen_op_set_T0_z32(val);
+    gen_op_jmp_T0(label);
+}
+
+static inline void gen_op_jmp_nz32(int val, int label)
+{
+    gen_op_set_T0_nz32(val);
+    gen_op_jmp_T0(label);
+}
+
+static inline void gen_op_jmp_s32(int val, int label)
+{
+    gen_op_set_T0_s32(val);
+    gen_op_jmp_T0(label);
+}
+
+static inline void gen_op_jmp_ns32(int val, int label)
+{
+    gen_op_set_T0_ns32(val);
+    gen_op_jmp_T0(label);
+}
+

Modified: trunk/src/host/qemu-neo1973/target-m68k/op.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-m68k/op.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-m68k/op.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -170,6 +170,16 @@
     FORCE_RET();
 }
 
+OP(ff1)
+{
+    uint32_t arg = get_op(PARAM2);
+    int n;
+    for (n = 32; arg; n--)
+        arg >>= 1;
+    set_op(PARAM1, n);
+    FORCE_RET();
+}
+
 OP(subx_cc)
 {
     uint32_t op1 = get_op(PARAM1);
@@ -275,6 +285,16 @@
     FORCE_RET();
 }
 
+OP(sar32)
+{
+    int32_t op2 = get_op(PARAM2);
+    uint32_t op3 = get_op(PARAM3);
+    uint32_t result;
+    result = op2 >> op3;
+    set_op(PARAM1, result);
+    FORCE_RET();
+}
+
 OP(sar_cc)
 {
     int32_t op1 = get_op(PARAM1);
@@ -318,10 +338,7 @@
 
 OP(flush_flags)
 {
-    int cc_op  = PARAM1;
-    if (cc_op == CC_OP_DYNAMIC)
-        cc_op = env->cc_op;
-    cpu_m68k_flush_flags(env, cc_op);
+    cpu_m68k_flush_flags(env, env->cc_op);
     FORCE_RET();
 }
 
@@ -383,8 +400,15 @@
     FORCE_RET();
 }
 
+/* Halt is special because it may be a semihosting call.  */
 OP(halt)
 {
+    RAISE_EXCEPTION(EXCP_HALT_INSN);
+    FORCE_RET();
+}
+
+OP(stop)
+{
     env->halted = 1;
     RAISE_EXCEPTION(EXCP_HLT);
     FORCE_RET();
@@ -451,45 +475,53 @@
     FORCE_RET();
 }
 
+OP(set_sr)
+{
+    env->sr = get_op(PARAM1) & 0xffff;
+    m68k_switch_sp(env);
+    FORCE_RET();
+}
+
 OP(jmp)
 {
     GOTO_LABEL_PARAM(1);
 }
 
-/* These ops involve a function call, which probably requires a stack frame
-   and breaks things on some hosts.  */
-OP(jmp_z32)
+OP(set_T0_z32)
 {
     uint32_t arg = get_op(PARAM1);
-    if (arg == 0)
-        GOTO_LABEL_PARAM(2);
+    T0 = (arg == 0);
     FORCE_RET();
 }
 
-OP(jmp_nz32)
+OP(set_T0_nz32)
 {
     uint32_t arg = get_op(PARAM1);
-    if (arg != 0)
-        GOTO_LABEL_PARAM(2);
+    T0 = (arg != 0);
     FORCE_RET();
 }
 
-OP(jmp_s32)
+OP(set_T0_s32)
 {
     int32_t arg = get_op(PARAM1);
-    if (arg < 0)
-        GOTO_LABEL_PARAM(2);
+    T0 = (arg > 0);
     FORCE_RET();
 }
 
-OP(jmp_ns32)
+OP(set_T0_ns32)
 {
     int32_t arg = get_op(PARAM1);
-    if (arg >= 0)
-        GOTO_LABEL_PARAM(2);
+    T0 = (arg >= 0);
     FORCE_RET();
 }
 
+OP(jmp_T0)
+{
+    if (T0)
+        GOTO_LABEL_PARAM(1);
+    FORCE_RET();
+}
+
 void OPPROTO op_goto_tb0(void)
 {
     GOTO_TB(op_goto_tb0, PARAM1, 0);
@@ -634,3 +666,410 @@
 #define MEMSUFFIX _kernel
 #include "op_mem.h"
 #endif
+
+/* MAC unit.  */
+/* TODO: The MAC instructions use 64-bit arithmetic fairly extensively.
+   This results in fairly large ops (and sometimes other issues) on 32-bit
+   hosts.  Maybe move most of them into helpers.  */
+OP(macmuls)
+{
+    uint32_t op1 = get_op(PARAM1);
+    uint32_t op2 = get_op(PARAM2);
+    int64_t product;
+    int64_t res;
+
+    product = (uint64_t)op1 * op2;
+    res = (product << 24) >> 24;
+    if (res != product) {
+        env->macsr |= MACSR_V;
+        if (env->macsr & MACSR_OMC) {
+            /* Make sure the accumulate operation overflows.  */
+            if (product < 0)
+                res = ~(1ll << 50);
+            else
+                res = 1ll << 50;
+        }
+    }
+    env->mactmp = res;
+    FORCE_RET();
+}
+
+OP(macmulu)
+{
+    uint32_t op1 = get_op(PARAM1);
+    uint32_t op2 = get_op(PARAM2);
+    uint64_t product;
+
+    product = (uint64_t)op1 * op2;
+    if (product & (0xffffffull << 40)) {
+        env->macsr |= MACSR_V;
+        if (env->macsr & MACSR_OMC) {
+            /* Make sure the accumulate operation overflows.  */
+            product = 1ll << 50;
+        } else {
+            product &= ((1ull << 40) - 1);
+        }
+    }
+    env->mactmp = product;
+    FORCE_RET();
+}
+
+OP(macmulf)
+{
+    int32_t op1 = get_op(PARAM1);
+    int32_t op2 = get_op(PARAM2);
+    uint64_t product;
+    uint32_t remainder;
+
+    product = (uint64_t)op1 * op2;
+    if (env->macsr & MACSR_RT) {
+        remainder = product & 0xffffff;
+        product >>= 24;
+        if (remainder > 0x800000)
+            product++;
+        else if (remainder == 0x800000)
+            product += (product & 1);
+    } else {
+        product >>= 24;
+    }
+    env->mactmp = product;
+    FORCE_RET();
+}
+
+OP(macshl)
+{
+    env->mactmp <<= 1;
+}
+
+OP(macshr)
+{
+    env->mactmp >>= 1;
+}
+
+OP(macadd)
+{
+    int acc = PARAM1;
+    env->macc[acc] += env->mactmp;
+    FORCE_RET();
+}
+
+OP(macsub)
+{
+    int acc = PARAM1;
+    env->macc[acc] -= env->mactmp;
+    FORCE_RET();
+}
+
+OP(macsats)
+{
+    int acc = PARAM1;
+    int64_t sum;
+    int64_t result;
+
+    sum = env->macc[acc];
+    result = (sum << 16) >> 16;
+    if (result != sum) {
+        env->macsr |= MACSR_V;
+    }
+    if (env->macsr & MACSR_V) {
+        env->macsr |= MACSR_PAV0 << acc;
+        if (env->macsr & MACSR_OMC) {
+            /* The result is saturated to 32 bits, despite overflow occuring
+               at 48 bits.  Seems weird, but that's what the hardware docs
+               say.  */
+            result = (result >> 63) ^ 0x7fffffff;
+        }
+    }
+    env->macc[acc] = result;
+    FORCE_RET();
+}
+
+OP(macsatu)
+{
+    int acc = PARAM1;
+    uint64_t sum;
+
+    sum = env->macc[acc];
+    if (sum & (0xffffull << 48)) {
+        env->macsr |= MACSR_V;
+    }
+    if (env->macsr & MACSR_V) {
+        env->macsr |= MACSR_PAV0 << acc;
+        if (env->macsr & MACSR_OMC) {
+            if (sum > (1ull << 53))
+                sum = 0;
+            else
+                sum = (1ull << 48) - 1;
+        } else {
+            sum &= ((1ull << 48) - 1);
+        }
+    }
+    FORCE_RET();
+}
+
+OP(macsatf)
+{
+    int acc = PARAM1;
+    int64_t sum;
+    int64_t result;
+
+    sum = env->macc[acc];
+    result = (sum << 16) >> 16;
+    if (result != sum) {
+        env->macsr |= MACSR_V;
+    }
+    if (env->macsr & MACSR_V) {
+        env->macsr |= MACSR_PAV0 << acc;
+        if (env->macsr & MACSR_OMC) {
+            result = (result >> 63) ^ 0x7fffffffffffll;
+        }
+    }
+    env->macc[acc] = result;
+    FORCE_RET();
+}
+
+OP(mac_clear_flags)
+{
+    env->macsr &= ~(MACSR_V | MACSR_Z | MACSR_N | MACSR_EV);
+}
+
+OP(mac_set_flags)
+{
+    int acc = PARAM1;
+    uint64_t val;
+    val = env->macc[acc];
+    if (val == 0)
+        env->macsr |= MACSR_Z;
+    else if (val & (1ull << 47));
+        env->macsr |= MACSR_N;
+    if (env->macsr & (MACSR_PAV0 << acc)) {
+        env->macsr |= MACSR_V;
+    }
+    if (env->macsr & MACSR_FI) {
+        val = ((int64_t)val) >> 40;
+        if (val != 0 && val != -1)
+            env->macsr |= MACSR_EV;
+    } else if (env->macsr & MACSR_SU) {
+        val = ((int64_t)val) >> 32;
+        if (val != 0 && val != -1)
+            env->macsr |= MACSR_EV;
+    } else {
+        if ((val >> 32) != 0)
+            env->macsr |= MACSR_EV;
+    }
+    FORCE_RET();
+}
+
+OP(get_macf)
+{
+    int acc = PARAM2;
+    int64_t val;
+    int rem;
+    uint32_t result;
+
+    val = env->macc[acc];
+    if (env->macsr & MACSR_SU) {
+        /* 16-bit rounding.  */
+        rem = val & 0xffffff;
+        val = (val >> 24) & 0xffffu;
+        if (rem > 0x800000)
+            val++;
+        else if (rem == 0x800000)
+            val += (val & 1);
+    } else if (env->macsr & MACSR_RT) {
+        /* 32-bit rounding.  */
+        rem = val & 0xff;
+        val >>= 8;
+        if (rem > 0x80)
+            val++;
+        else if (rem == 0x80)
+            val += (val & 1);
+    } else {
+        /* No rounding.  */
+        val >>= 8;
+    }
+    if (env->macsr & MACSR_OMC) {
+        /* Saturate.  */
+        if (env->macsr & MACSR_SU) {
+            if (val != (uint16_t) val) {
+                result = ((val >> 63) ^ 0x7fff) & 0xffff;
+            } else {
+                result = val & 0xffff;
+            }
+        } else {
+            if (val != (uint32_t)val) {
+                result = ((uint32_t)(val >> 63) & 0x7fffffff);
+            } else {
+                result = (uint32_t)val;
+            }
+        }
+    } else {
+        /* No saturation.  */
+        if (env->macsr & MACSR_SU) {
+            result = val & 0xffff;
+        } else {
+            result = (uint32_t)val;
+        }
+    }
+    set_op(PARAM1, result);
+    FORCE_RET();
+}
+
+OP(get_maci)
+{
+    int acc = PARAM2;
+    set_op(PARAM1, (uint32_t)env->macc[acc]);
+    FORCE_RET();
+}
+
+OP(get_macs)
+{
+    int acc = PARAM2;
+    int64_t val = env->macc[acc];
+    uint32_t result;
+    if (val == (int32_t)val) {
+        result = (int32_t)val;
+    } else {
+        result = (val >> 61) ^ 0x7fffffff;
+    }
+    set_op(PARAM1, result);
+    FORCE_RET();
+}
+
+OP(get_macu)
+{
+    int acc = PARAM2;
+    uint64_t val = env->macc[acc];
+    uint32_t result;
+    if ((val >> 32) == 0) {
+        result = (uint32_t)val;
+    } else {
+        result = 0xffffffffu;
+    }
+    set_op(PARAM1, result);
+    FORCE_RET();
+}
+
+OP(clear_mac)
+{
+    int acc = PARAM1;
+
+    env->macc[acc] = 0;
+    env->macsr &= ~(MACSR_PAV0 << acc);
+    FORCE_RET();
+}
+
+OP(move_mac)
+{
+    int dest = PARAM1;
+    int src = PARAM2;
+    uint32_t mask;
+    env->macc[dest] = env->macc[src];
+    mask = MACSR_PAV0 << dest;
+    if (env->macsr & (MACSR_PAV0 << src))
+        env->macsr |= mask;
+    else
+        env->macsr &= ~mask;
+    FORCE_RET();
+}
+
+OP(get_mac_extf)
+{
+    uint32_t val;
+    int acc = PARAM2;
+    val = env->macc[acc] & 0x00ff;
+    val = (env->macc[acc] >> 32) & 0xff00;
+    val |= (env->macc[acc + 1] << 16) & 0x00ff0000;
+    val |= (env->macc[acc + 1] >> 16) & 0xff000000;
+    set_op(PARAM1, val);
+    FORCE_RET();
+}
+
+OP(get_mac_exti)
+{
+    uint32_t val;
+    int acc = PARAM2;
+    val = (env->macc[acc] >> 32) & 0xffff;
+    val |= (env->macc[acc + 1] >> 16) & 0xffff0000;
+    set_op(PARAM1, val);
+    FORCE_RET();
+}
+
+OP(set_macf)
+{
+    int acc = PARAM2;
+    int32_t val = get_op(PARAM1);
+    env->macc[acc] = ((int64_t)val) << 8;
+    env->macsr &= ~(MACSR_PAV0 << acc);
+    FORCE_RET();
+}
+
+OP(set_macs)
+{
+    int acc = PARAM2;
+    int32_t val = get_op(PARAM1);
+    env->macc[acc] = val;
+    env->macsr &= ~(MACSR_PAV0 << acc);
+    FORCE_RET();
+}
+
+OP(set_macu)
+{
+    int acc = PARAM2;
+    uint32_t val = get_op(PARAM1);
+    env->macc[acc] = val;
+    env->macsr &= ~(MACSR_PAV0 << acc);
+    FORCE_RET();
+}
+
+OP(set_mac_extf)
+{
+    int acc = PARAM2;
+    int32_t val = get_op(PARAM1);
+    int64_t res;
+    int32_t tmp;
+    res = env->macc[acc] & 0xffffffff00ull;
+    tmp = (int16_t)(val & 0xff00);
+    res |= ((int64_t)tmp) << 32;
+    res |= val & 0xff;
+    env->macc[acc] = res;
+    res = env->macc[acc + 1] & 0xffffffff00ull;
+    tmp = (val & 0xff000000);
+    res |= ((int64_t)tmp) << 16;
+    res |= (val >> 16) & 0xff;
+    env->macc[acc + 1] = res;
+}
+
+OP(set_mac_exts)
+{
+    int acc = PARAM2;
+    int32_t val = get_op(PARAM1);
+    int64_t res;
+    int32_t tmp;
+    res = (uint32_t)env->macc[acc];
+    tmp = (int16_t)val;
+    res |= ((int64_t)tmp) << 32;
+    env->macc[acc] = res;
+    res = (uint32_t)env->macc[acc + 1];
+    tmp = val & 0xffff0000;
+    res |= (int64_t)tmp << 16;
+    env->macc[acc + 1] = res;
+}
+
+OP(set_mac_extu)
+{
+    int acc = PARAM2;
+    int32_t val = get_op(PARAM1);
+    uint64_t res;
+    res = (uint32_t)env->macc[acc];
+    res |= ((uint64_t)(val & 0xffff)) << 32;
+    env->macc[acc] = res;
+    res = (uint32_t)env->macc[acc + 1];
+    res |= (uint64_t)(val & 0xffff0000) << 16;
+    env->macc[acc + 1] = res;
+}
+
+OP(set_macsr)
+{
+    m68k_set_macsr(env, get_op(PARAM1));
+}

Modified: trunk/src/host/qemu-neo1973/target-m68k/op_helper.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-m68k/op_helper.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-m68k/op_helper.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -28,6 +28,8 @@
 
 #else
 
+extern int semihosting_enabled;
+
 #define MMUSUFFIX _mmu
 #define GETPC() (__builtin_return_address(0))
 
@@ -85,6 +87,7 @@
     env->pc = ldl_kernel(sp + 4);
     sp |= (fmt >> 28) & 3;
     env->sr = fmt & 0xffff;
+    m68k_switch_sp(env);
     env->aregs[7] = sp + 8;
 }
 
@@ -104,6 +107,20 @@
             /* Return from an exception.  */
             do_rte();
             return;
+        case EXCP_HALT_INSN:
+            if (semihosting_enabled
+                    && (env->sr & SR_S) != 0
+                    && (env->pc & 3) == 0
+                    && lduw_code(env->pc - 4) == 0x4e71
+                    && ldl_code(env->pc) == 0x4e7bf000) {
+                env->pc += 4;
+                do_m68k_semihosting(env, env->dregs[0]);
+                return;
+            }
+            env->halted = 1;
+            env->exception_index = EXCP_HLT;
+            cpu_loop_exit();
+            return;
         }
         if (env->exception_index >= EXCP_TRAP0
             && env->exception_index <= EXCP_TRAP15) {
@@ -112,16 +129,22 @@
         }
     }
 
-    /* TODO: Implement USP.  */
+    vector = env->exception_index << 2;
+
     sp = env->aregs[7];
 
-    vector = env->exception_index << 2;
-
     fmt |= 0x40000000;
     fmt |= (sp & 3) << 28;
     fmt |= vector << 16;
     fmt |= env->sr;
 
+    env->sr |= SR_S;
+    if (is_hw) {
+        env->sr = (env->sr & ~SR_I) | (env->pending_level << SR_I_SHIFT);
+        env->sr &= ~SR_M;
+    }
+    m68k_switch_sp(env);
+
     /* ??? This could cause MMU faults.  */
     sp &= ~3;
     sp -= 4;
@@ -129,10 +152,6 @@
     sp -= 4;
     stl_kernel(sp, fmt);
     env->aregs[7] = sp;
-    env->sr |= SR_S;
-    if (is_hw) {
-        env->sr = (env->sr & ~SR_I) | (env->pending_level << SR_I_SHIFT);
-    }
     /* Jump to vector.  */
     env->pc = ldl_kernel(env->vbr + vector);
 }

Modified: trunk/src/host/qemu-neo1973/target-m68k/qregs.def
===================================================================
--- trunk/src/host/qemu-neo1973/target-m68k/qregs.def	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-m68k/qregs.def	2007-06-17 16:55:00 UTC (rev 2289)
@@ -33,3 +33,5 @@
 DEFO32(DIV1, div1)
 DEFO32(DIV2, div2)
 DEFO32(EXCEPTION, exception_index)
+DEFO32(MACSR, macsr)
+DEFO32(MAC_MASK, mac_mask)

Modified: trunk/src/host/qemu-neo1973/target-m68k/translate.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-m68k/translate.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-m68k/translate.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -42,6 +42,8 @@
 
 /* internal defines */
 typedef struct DisasContext {
+    CPUM68KState *env;
+    target_ulong insn_pc; /* Start of the current instruction.  */
     target_ulong pc;
     int is_jmp;
     int cc_op;
@@ -49,6 +51,7 @@
     uint32_t fpcr;
     struct TranslationBlock *tb;
     int singlestep_enabled;
+    int is_mem;
 } DisasContext;
 
 #define DISAS_JUMP_NEXT 4
@@ -108,25 +111,6 @@
 #define AREG(insn, pos) (((insn >> pos) & 7) + QREG_A0)
 #define FREG(insn, pos) (((insn >> pos) & 7) + QREG_F0)
 
-#define M68K_INSN_CF_A    (1 << 0)
-#define M68K_INSN_CF_B    (1 << 1)
-#define M68K_INSN_CF_C    (1 << 2)
-#define M68K_INSN_CF_MAC  (1 << 3)
-#define M68K_INSN_CF_EMAC (1 << 4)
-#define M68K_INSN_CF_FPU  (1 << 5)
-
-struct m68k_def_t {
-    const char * name;
-    uint32_t insns;
-};
-
-static m68k_def_t m68k_cpu_defs[] = {
-    {"m5206", M68K_INSN_CF_A},
-    {"cfv4e", M68K_INSN_CF_A | M68K_INSN_CF_B | M68K_INSN_CF_C
-            | M68K_INSN_CF_MAC | M68K_INSN_CF_EMAC | M68K_INSN_CF_FPU},
-    {NULL, 0}, 
-};
-
 typedef void (*disas_proc)(DisasContext *, uint16_t);
 
 #ifdef DEBUG_DISPATCH
@@ -146,6 +130,7 @@
 static inline int gen_load(DisasContext * s, int opsize, int addr, int sign)
 {
     int tmp;
+    s->is_mem = 1;
     switch(opsize) {
     case OS_BYTE:
         tmp = gen_new_qreg(QMODE_I32);
@@ -183,6 +168,7 @@
 /* Generate a store.  */
 static inline void gen_store(DisasContext *s, int opsize, int addr, int val)
 {
+    s->is_mem = 1;
     switch(opsize) {
     case OS_BYTE:
         gen_st(s, 8, addr, val);
@@ -217,50 +203,139 @@
     }
 }
 
+/* Read a 32-bit immediate constant.  */
+static inline uint32_t read_im32(DisasContext *s)
+{
+    uint32_t im;
+    im = ((uint32_t)lduw_code(s->pc)) << 16;
+    s->pc += 2;
+    im |= lduw_code(s->pc);
+    s->pc += 2;
+    return im;
+}
+
+/* Calculate and address index.  */
+static int gen_addr_index(uint16_t ext, int tmp)
+{
+    int add;
+    int scale;
+
+    add = (ext & 0x8000) ? AREG(ext, 12) : DREG(ext, 12);
+    if ((ext & 0x800) == 0) {
+        gen_op_ext16s32(tmp, add);
+        add = tmp;
+    }
+    scale = (ext >> 9) & 3;
+    if (scale != 0) {
+        gen_op_shl32(tmp, add, gen_im32(scale));
+        add = tmp;
+    }
+    return add;
+}
+
 /* Handle a base + index + displacement effective addresss.  A base of
    -1 means pc-relative.  */
 static int gen_lea_indexed(DisasContext *s, int opsize, int base)
 {
-    int scale;
     uint32_t offset;
     uint16_t ext;
     int add;
     int tmp;
+    uint32_t bd, od;
 
     offset = s->pc;
     ext = lduw_code(s->pc);
     s->pc += 2;
-    tmp = ((ext >> 12) & 7) + ((ext & 0x8000) ? QREG_A0 : QREG_D0);
-    /* ??? Check W/L bit.  */
-    scale = (ext >> 9) & 3;
-    if (scale == 0) {
+
+    if ((ext & 0x800) == 0 && !m68k_feature(s->env, M68K_FEATURE_WORD_INDEX))
+        return -1;
+
+    if (ext & 0x100) {
+        /* full extension word format */
+        if (!m68k_feature(s->env, M68K_FEATURE_EXT_FULL))
+            return -1;
+
+        if ((ext & 0x30) > 0x10) {
+            /* base displacement */
+            if ((ext & 0x30) == 0x20) {
+                bd = (int16_t)lduw_code(s->pc);
+                s->pc += 2;
+            } else {
+                bd = read_im32(s);
+            }
+        } else {
+            bd = 0;
+        }
+        tmp = gen_new_qreg(QMODE_I32);
+        if ((ext & 0x44) == 0) {
+            /* pre-index */
+            add = gen_addr_index(ext, tmp);
+        } else {
+            add = QREG_NULL;
+        }
+        if ((ext & 0x80) == 0) {
+            /* base not suppressed */
+            if (base == -1) {
+                base = gen_im32(offset + bd);
+                bd = 0;
+            }
+            if (add) {
+                gen_op_add32(tmp, add, base);
+                add = tmp;
+            } else {
+                add = base;
+            }
+        }
+        if (add) {
+            if (bd != 0) {
+                gen_op_add32(tmp, add, gen_im32(bd));
+                add = tmp;
+            }
+        } else {
+            add = gen_im32(bd);
+        }
+        if ((ext & 3) != 0) {
+            /* memory indirect */
+            base = gen_load(s, OS_LONG, add, 0);
+            if ((ext & 0x44) == 4) {
+                add = gen_addr_index(ext, tmp);
+                gen_op_add32(tmp, add, base);
+                add = tmp;
+            } else {
+                add = base;
+            }
+            if ((ext & 3) > 1) {
+                /* outer displacement */
+                if ((ext & 3) == 2) {
+                    od = (int16_t)lduw_code(s->pc);
+                    s->pc += 2;
+                } else {
+                    od = read_im32(s);
+                }
+            } else {
+                od = 0;
+            }
+            if (od != 0) {
+                gen_op_add32(tmp, add, gen_im32(od));
+                add = tmp;
+            }
+        }
+    } else {
+        /* brief extension word format */
+        tmp = gen_new_qreg(QMODE_I32);
+        add = gen_addr_index(ext, tmp);
+        if (base != -1) {
+            gen_op_add32(tmp, add, base);
+            if ((int8_t)ext)
+                gen_op_add32(tmp, tmp, gen_im32((int8_t)ext));
+        } else {
+            gen_op_add32(tmp, add, gen_im32(offset + (int8_t)ext));
+        }
         add = tmp;
-    } else {
-        add = gen_new_qreg(QMODE_I32);
-        gen_op_shl32(add, tmp, gen_im32(scale));
     }
-    tmp = gen_new_qreg(QMODE_I32);
-    if (base != -1) {
-        gen_op_add32(tmp, base, gen_im32((int8_t)ext));
-        gen_op_add32(tmp, tmp, add);
-    } else {
-        gen_op_add32(tmp, add, gen_im32(offset + (int8_t)ext));
-    }
-    return tmp;
+    return add;
 }
 
-/* Read a 32-bit immediate constant.  */
-static inline uint32_t read_im32(DisasContext *s)
-{
-    uint32_t im;
-    im = ((uint32_t)lduw_code(s->pc)) << 16;
-    s->pc += 2;
-    im |= lduw_code(s->pc);
-    s->pc += 2;
-    return im;
-}
-
-
 /* Update the CPU env CC_OP state.  */
 static inline void gen_flush_cc_op(DisasContext *s)
 {
@@ -273,7 +348,8 @@
 {
     if (s->cc_op == CC_OP_FLAGS)
         return;
-    gen_op_flush_flags(s->cc_op);
+    gen_flush_cc_op(s);
+    gen_op_flush_flags();
     s->cc_op = CC_OP_FLAGS;
 }
 
@@ -366,8 +442,7 @@
     switch ((insn >> 3) & 7) {
     case 0: /* Data register direct.  */
     case 1: /* Address register direct.  */
-        /* ??? generate bad addressing mode fault.  */
-        qemu_assert(0, "invalid addressing mode");
+        return -1;
     case 2: /* Indirect register */
     case 3: /* Indirect postincrement.  */
         reg += QREG_A0;
@@ -406,8 +481,7 @@
             return gen_lea_indexed(s, opsize, -1);
         case 4: /* Immediate.  */
         default:
-            /* ??? generate bad addressing mode fault.  */
-            qemu_assert(0, "invalid addressing mode");
+            return -1;
         }
     }
     /* Should never happen.  */
@@ -425,6 +499,8 @@
         tmp = *addrp;
     } else {
         tmp = gen_lea(s, insn, opsize);
+        if (tmp == -1)
+            return -1;
         if (addrp)
             *addrp = tmp;
     }
@@ -477,6 +553,8 @@
                 tmp = *addrp;
             } else {
                 tmp = gen_lea(s, insn, opsize);
+                if (tmp == -1)
+                    return -1;
                 if (addrp)
                     *addrp = tmp;
             }
@@ -524,7 +602,7 @@
             }
             return gen_im32(offset);
         default:
-            qemu_assert(0, "invalid addressing mode");
+            return -1;
         }
     }
     /* Should never happen.  */
@@ -682,6 +760,27 @@
     gen_op_raise_exception(nr);
 }
 
+static inline void gen_addr_fault(DisasContext *s)
+{
+    gen_exception(s, s->insn_pc, EXCP_ADDRESS);
+}
+
+#define SRC_EA(result, opsize, val, addrp) do { \
+    result = gen_ea(s, insn, opsize, val, addrp); \
+    if (result == -1) { \
+        gen_addr_fault(s); \
+        return; \
+    } \
+    } while (0)
+
+#define DEST_EA(insn, opsize, val, addrp) do { \
+    int ea_result = gen_ea(s, insn, opsize, val, addrp); \
+    if (ea_result == -1) { \
+        gen_addr_fault(s); \
+        return; \
+    } \
+    } while (0)
+
 /* Generate a jump to an immediate address.  */
 static void gen_jmp_tb(DisasContext *s, int n, uint32_t dest)
 {
@@ -735,7 +834,7 @@
         gen_op_ext16s32(tmp, reg);
     else
         gen_op_ext16u32(tmp, reg);
-    src = gen_ea(s, insn, OS_WORD, sign ? -1 : 0, NULL);
+    SRC_EA(src, OS_WORD, sign ? -1 : 0, NULL);
     gen_op_mul32(tmp, tmp, src);
     gen_op_mov32(reg, tmp);
     /* Unlike m68k, coldfire always clears the overflow bit.  */
@@ -756,7 +855,7 @@
     } else {
         gen_op_ext16u32(QREG_DIV1, reg);
     }
-    src = gen_ea(s, insn, OS_WORD, sign ? -1 : 0, NULL);
+    SRC_EA(src, OS_WORD, sign ? -1 : 0, NULL);
     gen_op_mov32(QREG_DIV2, src);
     if (sign) {
         gen_op_divs(1);
@@ -789,7 +888,7 @@
     num = DREG(ext, 12);
     reg = DREG(ext, 0);
     gen_op_mov32(QREG_DIV1, num);
-    den = gen_ea(s, insn, OS_LONG, 0, NULL);
+    SRC_EA(den, OS_LONG, 0, NULL);
     gen_op_mov32(QREG_DIV2, den);
     if (ext & 0x0800) {
         gen_op_divs(2);
@@ -820,11 +919,11 @@
     reg = DREG(insn, 9);
     dest = gen_new_qreg(QMODE_I32);
     if (insn & 0x100) {
-        tmp = gen_ea(s, insn, OS_LONG, 0, &addr);
+        SRC_EA(tmp, OS_LONG, 0, &addr);
         src = reg;
     } else {
         tmp = reg;
-        src = gen_ea(s, insn, OS_LONG, 0, NULL);
+        SRC_EA(src, OS_LONG, 0, NULL);
     }
     if (add) {
         gen_op_add32(dest, tmp, src);
@@ -837,7 +936,7 @@
     }
     gen_op_update_cc_add(dest, src);
     if (insn & 0x100) {
-        gen_ea(s, insn, OS_LONG, dest, &addr);
+        DEST_EA(insn, OS_LONG, dest, &addr);
     } else {
         gen_op_mov32(reg, dest);
     }
@@ -895,7 +994,7 @@
     else
         opsize = OS_LONG;
     op = (insn >> 6) & 3;
-    src1 = gen_ea(s, insn, opsize, 0, op ? &addr: NULL);
+    SRC_EA(src1, opsize, 0, op ? &addr: NULL);
     src2 = DREG(insn, 9);
     dest = gen_new_qreg(QMODE_I32);
 
@@ -925,7 +1024,7 @@
         break;
     }
     if (op)
-        gen_ea(s, insn, opsize, dest, &addr);
+        DEST_EA(insn, opsize, dest, &addr);
 }
 
 DISAS_INSN(sats)
@@ -970,6 +1069,10 @@
     mask = lduw_code(s->pc);
     s->pc += 2;
     tmp = gen_lea(s, insn, OS_LONG);
+    if (tmp == -1) {
+        gen_addr_fault(s);
+        return;
+    }
     addr = gen_new_qreg(QMODE_I32);
     gen_op_mov32(addr, tmp);
     is_load = ((insn & 0x0400) != 0);
@@ -1015,7 +1118,7 @@
         return;
     }
 
-    src1 = gen_ea(s, insn, opsize, 0, op ? &addr: NULL);
+    SRC_EA(src1, opsize, 0, op ? &addr: NULL);
 
     gen_flush_flags(s);
     tmp = gen_new_qreg(QMODE_I32);
@@ -1045,7 +1148,7 @@
         break;
     }
     if (op)
-        gen_ea(s, insn, opsize, dest, &addr);
+        DEST_EA(insn, opsize, dest, &addr);
 }
 
 DISAS_INSN(arith_im)
@@ -1057,7 +1160,7 @@
     int addr;
 
     op = (insn >> 9) & 7;
-    src1 = gen_ea(s, insn, OS_LONG, 0, (op == 6) ? NULL : &addr);
+    SRC_EA(src1, OS_LONG, 0, (op == 6) ? NULL : &addr);
     src2 = gen_im32(read_im32(s));
     dest = gen_new_qreg(QMODE_I32);
     switch (op) {
@@ -1097,7 +1200,7 @@
         abort();
     }
     if (op != 6) {
-        gen_ea(s, insn, OS_LONG, dest, &addr);
+        DEST_EA(insn, OS_LONG, dest, &addr);
     }
 }
 
@@ -1129,7 +1232,7 @@
     default:
         abort();
     }
-    src = gen_ea(s, insn, opsize, -1, NULL);
+    SRC_EA(src, opsize, -1, NULL);
     op = (insn >> 6) & 7;
     if (op == 1) {
         /* movea */
@@ -1140,7 +1243,7 @@
         /* normal move */
         uint16_t dest_ea;
         dest_ea = ((insn >> 9) & 7) | (op << 3);
-        gen_ea(s, dest_ea, opsize, src, NULL);
+        DEST_EA(dest_ea, opsize, src, NULL);
         /* This will be correct because loads sign extend.  */
         gen_logic_cc(s, src);
     }
@@ -1176,6 +1279,10 @@
 
     reg = AREG(insn, 9);
     tmp = gen_lea(s, insn, OS_LONG);
+    if (tmp == -1) {
+        gen_addr_fault(s);
+        return;
+    }
     gen_op_mov32(reg, tmp);
 }
 
@@ -1196,7 +1303,7 @@
     default:
         abort();
     }
-    gen_ea (s, insn, opsize, gen_im32(0), NULL);
+    DEST_EA(insn, opsize, gen_im32(0), NULL);
     gen_logic_cc(s, gen_im32(0));
 }
 
@@ -1242,7 +1349,7 @@
     gen_op_logic_cc(gen_im32(val & 0xf));
     gen_op_update_xflag_tst(gen_im32((val & 0x10) >> 4));
     if (!ccr_only) {
-        gen_op_mov32(QREG_SR, gen_im32(val & 0xff00));
+        gen_op_set_sr(gen_im32(val & 0xff00));
     }
 }
 
@@ -1262,7 +1369,7 @@
         gen_op_and32(src1, src1, gen_im32(1));
         gen_op_update_xflag_tst(src1);
         if (!ccr_only) {
-            gen_op_and32(QREG_SR, reg, gen_im32(0xff00));
+            gen_op_set_sr(reg);
         }
       }
     else if ((insn & 0x3f) == 0x3c)
@@ -1313,6 +1420,10 @@
     int tmp;
 
     tmp = gen_lea(s, insn, OS_LONG);
+    if (tmp == -1) {
+        gen_addr_fault(s);
+        return;
+    }
     gen_push(s, tmp);
 }
 
@@ -1354,7 +1465,7 @@
     default:
         abort();
     }
-    tmp = gen_ea(s, insn, opsize, -1, NULL);
+    SRC_EA(tmp, opsize, -1, NULL);
     gen_logic_cc(s, tmp);
 }
 
@@ -1376,10 +1487,10 @@
     int addr;
 
     dest = gen_new_qreg(QMODE_I32);
-    src1 = gen_ea(s, insn, OS_BYTE, -1, &addr);
+    SRC_EA(src1, OS_BYTE, -1, &addr);
     gen_logic_cc(s, src1);
     gen_op_or32(dest, src1, gen_im32(0x80));
-    gen_ea(s, insn, OS_BYTE, dest, &addr);
+    DEST_EA(insn, OS_BYTE, dest, &addr);
 }
 
 DISAS_INSN(mull)
@@ -1398,7 +1509,7 @@
         return;
     }
     reg = DREG(ext, 12);
-    src1 = gen_ea(s, insn, OS_LONG, 0, NULL);
+    SRC_EA(src1, OS_LONG, 0, NULL);
     dest = gen_new_qreg(QMODE_I32);
     gen_op_mul32(dest, src1, reg);
     gen_op_mov32(reg, dest);
@@ -1457,6 +1568,10 @@
     /* Load the target address first to ensure correct exception
        behavior.  */
     tmp = gen_lea(s, insn, OS_LONG);
+    if (tmp == -1) {
+        gen_addr_fault(s);
+        return;
+    }
     if ((insn & 0x40) == 0) {
         /* jsr */
         gen_push(s, gen_im32(s->pc));
@@ -1472,7 +1587,7 @@
     int val;
     int addr;
 
-    src1 = gen_ea(s, insn, OS_LONG, 0, &addr);
+    SRC_EA(src1, OS_LONG, 0, &addr);
     val = (insn >> 9) & 7;
     if (val == 0)
         val = 8;
@@ -1499,7 +1614,7 @@
         }
         gen_op_update_cc_add(dest, src2);
     }
-    gen_ea(s, insn, OS_LONG, dest, &addr);
+    DEST_EA(insn, OS_LONG, dest, &addr);
 }
 
 DISAS_INSN(tpf)
@@ -1571,7 +1686,7 @@
         opsize = OS_WORD;
     else
         opsize = OS_BYTE;
-    src = gen_ea(s, insn, opsize, (insn & 0x80) ? 0 : -1, NULL);
+    SRC_EA(src, opsize, (insn & 0x80) ? 0 : -1, NULL);
     reg = DREG(insn, 9);
     gen_op_mov32(reg, src);
     gen_logic_cc(s, src);
@@ -1587,11 +1702,11 @@
     reg = DREG(insn, 9);
     dest = gen_new_qreg(QMODE_I32);
     if (insn & 0x100) {
-        src = gen_ea(s, insn, OS_LONG, 0, &addr);
+        SRC_EA(src, OS_LONG, 0, &addr);
         gen_op_or32(dest, src, reg);
-        gen_ea(s, insn, OS_LONG, dest, &addr);
+        DEST_EA(insn, OS_LONG, dest, &addr);
     } else {
-        src = gen_ea(s, insn, OS_LONG, 0, NULL);
+        SRC_EA(src, OS_LONG, 0, NULL);
         gen_op_or32(dest, src, reg);
         gen_op_mov32(reg, dest);
     }
@@ -1603,7 +1718,7 @@
     int src;
     int reg;
 
-    src = gen_ea(s, insn, OS_LONG, 0, NULL);
+    SRC_EA(src, OS_LONG, 0, NULL);
     reg = AREG(insn, 9);
     gen_op_sub32(reg, reg, src);
 }
@@ -1643,7 +1758,7 @@
         val = -1;
     src = gen_im32(val);
     gen_logic_cc(s, src);
-    gen_ea(s, insn, OS_LONG, src, NULL);
+    DEST_EA(insn, OS_LONG, src, NULL);
 }
 
 DISAS_INSN(cmp)
@@ -1671,7 +1786,7 @@
     default:
         abort();
     }
-    src = gen_ea(s, insn, opsize, -1, NULL);
+    SRC_EA(src, opsize, -1, NULL);
     reg = DREG(insn, 9);
     dest = gen_new_qreg(QMODE_I32);
     gen_op_sub32(dest, reg, src);
@@ -1690,7 +1805,7 @@
     } else {
         opsize = OS_WORD;
     }
-    src = gen_ea(s, insn, opsize, -1, NULL);
+    SRC_EA(src, opsize, -1, NULL);
     reg = AREG(insn, 9);
     dest = gen_new_qreg(QMODE_I32);
     gen_op_sub32(dest, reg, src);
@@ -1705,12 +1820,12 @@
     int dest;
     int addr;
 
-    src = gen_ea(s, insn, OS_LONG, 0, &addr);
+    SRC_EA(src, OS_LONG, 0, &addr);
     reg = DREG(insn, 9);
     dest = gen_new_qreg(QMODE_I32);
     gen_op_xor32(dest, src, reg);
     gen_logic_cc(s, dest);
-    gen_ea(s, insn, OS_LONG, dest, &addr);
+    DEST_EA(insn, OS_LONG, dest, &addr);
 }
 
 DISAS_INSN(and)
@@ -1723,11 +1838,11 @@
     reg = DREG(insn, 9);
     dest = gen_new_qreg(QMODE_I32);
     if (insn & 0x100) {
-        src = gen_ea(s, insn, OS_LONG, 0, &addr);
+        SRC_EA(src, OS_LONG, 0, &addr);
         gen_op_and32(dest, src, reg);
-        gen_ea(s, insn, OS_LONG, dest, &addr);
+        DEST_EA(insn, OS_LONG, dest, &addr);
     } else {
-        src = gen_ea(s, insn, OS_LONG, 0, NULL);
+        SRC_EA(src, OS_LONG, 0, NULL);
         gen_op_and32(dest, src, reg);
         gen_op_mov32(reg, dest);
     }
@@ -1739,7 +1854,7 @@
     int src;
     int reg;
 
-    src = gen_ea(s, insn, OS_LONG, 0, NULL);
+    SRC_EA(src, OS_LONG, 0, NULL);
     reg = AREG(insn, 9);
     gen_op_add32(reg, reg, src);
 }
@@ -1818,7 +1933,10 @@
 
 DISAS_INSN(ff1)
 {
-    cpu_abort(NULL, "Unimplemented insn: ff1");
+    int reg;
+    reg = DREG(insn, 0);
+    gen_logic_cc(s, reg);
+    gen_op_ff1(reg, reg);
 }
 
 static int gen_get_sr(DisasContext *s)
@@ -1901,7 +2019,6 @@
 
 DISAS_INSN(halt)
 {
-    gen_flush_cc_op(s);
     gen_jmp(s, gen_im32(s->pc));
     gen_op_halt();
 }
@@ -1919,7 +2036,8 @@
     s->pc += 2;
 
     gen_set_sr_im(s, ext, 0);
-    disas_halt(s, insn);
+    gen_jmp(s, gen_im32(s->pc));
+    gen_op_stop();
 }
 
 DISAS_INSN(rte)
@@ -2043,7 +2161,7 @@
         default:
             goto undef;
         }
-        gen_ea(s, insn, opsize, res, NULL);
+        DEST_EA(insn, opsize, res, NULL);
         return;
     case 4: /* fmove to control register.  */
         switch ((ext >> 10) & 7) {
@@ -2070,7 +2188,7 @@
                       (ext >> 10) & 7);
             goto undef;
         }
-        gen_ea(s, insn, OS_LONG, res, NULL);
+        DEST_EA(insn, OS_LONG, res, NULL);
         break;
     case 6: /* fmovem */ 
     case 7:
@@ -2080,12 +2198,17 @@
         if ((ext & 0x1f00) != 0x1000 || (ext & 0xff) == 0)
             goto undef;
         src = gen_lea(s, insn, OS_LONG);
+        if (src == -1) {
+            gen_addr_fault(s);
+            return;
+        }
         addr = gen_new_qreg(QMODE_I32);
         gen_op_mov32(addr, src);
         mask = 0x80;
         dest = QREG_F0;
         while (mask) {
             if (ext & mask) {
+                s->is_mem = 1;
                 if (ext & (1 << 13)) {
                     /* store */
                     gen_st(s, f64, addr, dest);
@@ -2115,7 +2238,7 @@
         default:
             goto undef;
         }
-        tmp = gen_ea(s, insn, opsize, -1, NULL);
+        SRC_EA(tmp, opsize, -1, NULL);
         if (opsize == OS_DOUBLE) {
             src = tmp;
         } else {
@@ -2315,6 +2438,283 @@
     qemu_assert(0, "FSAVE not implemented");
 }
 
+static inline int gen_mac_extract_word(DisasContext *s, int val, int upper)
+{
+    int tmp = gen_new_qreg(QMODE_I32);
+    if (s->env->macsr & MACSR_FI) {
+        if (upper)
+            gen_op_and32(tmp, val, gen_im32(0xffff0000));
+        else
+            gen_op_shl32(tmp, val, gen_im32(16));
+    } else if (s->env->macsr & MACSR_SU) {
+        if (upper)
+            gen_op_sar32(tmp, val, gen_im32(16));
+        else
+            gen_op_ext16s32(tmp, val);
+    } else {
+        if (upper)
+            gen_op_shr32(tmp, val, gen_im32(16));
+        else
+            gen_op_ext16u32(tmp, val);
+    }
+    return tmp;
+}
+
+DISAS_INSN(mac)
+{
+    int rx;
+    int ry;
+    uint16_t ext;
+    int acc;
+    int l1;
+    int tmp;
+    int addr;
+    int loadval;
+    int dual;
+    int saved_flags = -1;
+
+    ext = lduw_code(s->pc);
+    s->pc += 2;
+
+    acc = ((insn >> 7) & 1) | ((ext >> 3) & 2);
+    dual = ((insn & 0x30) != 0 && (ext & 3) != 0);
+    if (dual && !m68k_feature(s->env, M68K_FEATURE_CF_EMAC_B)) {
+        disas_undef(s, insn);
+        return;
+    }
+    if (insn & 0x30) {
+        /* MAC with load.  */
+        tmp = gen_lea(s, insn, OS_LONG);
+        addr = gen_new_qreg(QMODE_I32);
+        gen_op_and32(addr, tmp, QREG_MAC_MASK);
+        /* Load the value now to ensure correct exception behavior.
+           Perform writeback after reading the MAC inputs.  */
+        loadval = gen_load(s, OS_LONG, addr, 0);
+
+        acc ^= 1;
+        rx = (ext & 0x8000) ? AREG(ext, 12) : DREG(insn, 12);
+        ry = (ext & 8) ? AREG(ext, 0) : DREG(ext, 0);
+    } else {
+        loadval = addr = -1;
+        rx = (insn & 0x40) ? AREG(insn, 9) : DREG(insn, 9);
+        ry = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
+    }
+
+    gen_op_mac_clear_flags();
+    l1 = -1;
+    if ((s->env->macsr & MACSR_OMC) != 0 && !dual) {
+        /* Skip the multiply if we know we will ignore it.  */
+        l1 = gen_new_label();
+        tmp = gen_new_qreg(QMODE_I32);
+        gen_op_and32(tmp, QREG_MACSR, gen_im32(1 << (acc + 8)));
+        gen_op_jmp_nz32(tmp, l1);
+    }
+
+    if ((ext & 0x0800) == 0) {
+        /* Word.  */
+        rx = gen_mac_extract_word(s, rx, (ext & 0x80) != 0);
+        ry = gen_mac_extract_word(s, ry, (ext & 0x40) != 0);
+    }
+    if (s->env->macsr & MACSR_FI) {
+        gen_op_macmulf(rx, ry);
+    } else {
+        if (s->env->macsr & MACSR_SU)
+            gen_op_macmuls(rx, ry);
+        else
+            gen_op_macmulu(rx, ry);
+        switch ((ext >> 9) & 3) {
+        case 1:
+            gen_op_macshl();
+            break;
+        case 3:
+            gen_op_macshr();
+            break;
+        }
+    }
+
+    if (dual) {
+        /* Save the overflow flag from the multiply.  */
+        saved_flags = gen_new_qreg(QMODE_I32);
+        gen_op_mov32(saved_flags, QREG_MACSR);
+    }
+
+    if ((s->env->macsr & MACSR_OMC) != 0 && dual) {
+        /* Skip the accumulate if the value is already saturated.  */
+        l1 = gen_new_label();
+        tmp = gen_new_qreg(QMODE_I32);
+        gen_op_and32(tmp, QREG_MACSR, gen_im32(MACSR_PAV0 << acc));
+        gen_op_jmp_nz32(tmp, l1);
+    }
+
+    if (insn & 0x100)
+        gen_op_macsub(acc);
+    else
+        gen_op_macadd(acc);
+
+    if (s->env->macsr & MACSR_FI)
+        gen_op_macsatf(acc);
+    else if (s->env->macsr & MACSR_SU)
+        gen_op_macsats(acc);
+    else
+        gen_op_macsatu(acc);
+
+    if (l1 != -1)
+        gen_set_label(l1);
+
+    if (dual) {
+        /* Dual accumulate variant.  */
+        acc = (ext >> 2) & 3;
+        /* Restore the overflow flag from the multiplier.  */
+        gen_op_mov32(QREG_MACSR, saved_flags);
+        if ((s->env->macsr & MACSR_OMC) != 0) {
+            /* Skip the accumulate if the value is already saturated.  */
+            l1 = gen_new_label();
+            tmp = gen_new_qreg(QMODE_I32);
+            gen_op_and32(tmp, QREG_MACSR, gen_im32(MACSR_PAV0 << acc));
+            gen_op_jmp_nz32(tmp, l1);
+        }
+        if (ext & 2)
+            gen_op_macsub(acc);
+        else
+            gen_op_macadd(acc);
+        if (s->env->macsr & MACSR_FI)
+            gen_op_macsatf(acc);
+        else if (s->env->macsr & MACSR_SU)
+            gen_op_macsats(acc);
+        else
+            gen_op_macsatu(acc);
+        if (l1 != -1)
+            gen_set_label(l1);
+    }
+    gen_op_mac_set_flags(acc);
+
+    if (insn & 0x30) {
+        int rw;
+        rw = (insn & 0x40) ? AREG(insn, 9) : DREG(insn, 9);
+        gen_op_mov32(rw, loadval);
+        /* FIXME: Should address writeback happen with the masked or
+           unmasked value?  */
+        switch ((insn >> 3) & 7) {
+        case 3: /* Post-increment.  */
+            gen_op_add32(AREG(insn, 0), addr, gen_im32(4));
+            break;
+        case 4: /* Pre-decrement.  */
+            gen_op_mov32(AREG(insn, 0), addr);
+        }
+    }
+}
+
+DISAS_INSN(from_mac)
+{
+    int rx;
+    int acc;
+
+    rx = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
+    acc = (insn >> 9) & 3;
+    if (s->env->macsr & MACSR_FI) {
+        gen_op_get_macf(rx, acc);
+    } else if ((s->env->macsr & MACSR_OMC) == 0) {
+        gen_op_get_maci(rx, acc);
+    } else if (s->env->macsr & MACSR_SU) {
+        gen_op_get_macs(rx, acc);
+    } else {
+        gen_op_get_macu(rx, acc);
+    }
+    if (insn & 0x40)
+        gen_op_clear_mac(acc);
+}
+
+DISAS_INSN(move_mac)
+{
+    int src;
+    int dest;
+    src = insn & 3;
+    dest = (insn >> 9) & 3;
+    gen_op_move_mac(dest, src);
+    gen_op_mac_clear_flags();
+    gen_op_mac_set_flags(dest);
+}
+
+DISAS_INSN(from_macsr)
+{
+    int reg;
+
+    reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
+    gen_op_mov32(reg, QREG_MACSR);
+}
+
+DISAS_INSN(from_mask)
+{
+    int reg;
+    reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
+    gen_op_mov32(reg, QREG_MAC_MASK);
+}
+
+DISAS_INSN(from_mext)
+{
+    int reg;
+    int acc;
+    reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
+    acc = (insn & 0x400) ? 2 : 0;
+    if (s->env->macsr & MACSR_FI)
+        gen_op_get_mac_extf(reg, acc);
+    else
+        gen_op_get_mac_exti(reg, acc);
+}
+
+DISAS_INSN(macsr_to_ccr)
+{
+    gen_op_mov32(QREG_CC_X, gen_im32(0));
+    gen_op_and32(QREG_CC_DEST, QREG_MACSR, gen_im32(0xf));
+    s->cc_op = CC_OP_FLAGS;
+}
+
+DISAS_INSN(to_mac)
+{
+    int acc;
+    int val;
+    acc = (insn >>9) & 3;
+    SRC_EA(val, OS_LONG, 0, NULL);
+    if (s->env->macsr & MACSR_FI) {
+        gen_op_set_macf(val, acc);
+    } else if (s->env->macsr & MACSR_SU) {
+        gen_op_set_macs(val, acc);
+    } else {
+        gen_op_set_macu(val, acc);
+    }
+    gen_op_mac_clear_flags();
+    gen_op_mac_set_flags(acc);
+}
+
+DISAS_INSN(to_macsr)
+{
+    int val;
+    SRC_EA(val, OS_LONG, 0, NULL);
+    gen_op_set_macsr(val);
+    gen_lookup_tb(s);
+}
+
+DISAS_INSN(to_mask)
+{
+    int val;
+    SRC_EA(val, OS_LONG, 0, NULL);
+    gen_op_or32(QREG_MAC_MASK, val, gen_im32(0xffff0000));
+}
+
+DISAS_INSN(to_mext)
+{
+    int val;
+    int acc;
+    SRC_EA(val, OS_LONG, 0, NULL);
+    acc = (insn & 0x400) ? 2 : 0;
+    if (s->env->macsr & MACSR_FI)
+        gen_op_set_mac_extf(val, acc);
+    else if (s->env->macsr & MACSR_SU)
+        gen_op_set_mac_exts(val, acc);
+    else
+        gen_op_set_mac_extu(val, acc);
+}
+
 static disas_proc opcode_table[65536];
 
 static void
@@ -2325,8 +2725,12 @@
   int to;
 
   /* Sanity check.  All set bits must be included in the mask.  */
-  if (opcode & ~mask)
+  if (opcode & ~mask) {
+      fprintf(stderr,
+              "qemu internal error: bogus opcode definition %04x/%04x\n",
+              opcode, mask);
       abort();
+  }
   /* This could probably be cleverer.  For now just optimize the case where
      the top bits are known.  */
   /* Find the first zero bit in the mask.  */
@@ -2348,109 +2752,127 @@
 
 /* Register m68k opcode handlers.  Order is important.
    Later insn override earlier ones.  */
-static void
-register_m68k_insns (m68k_def_t *def)
+void register_m68k_insns (CPUM68KState *env)
 {
-    uint32_t iflags;
+#define INSN(name, opcode, mask, feature) do { \
+    if (m68k_feature(env, M68K_FEATURE_##feature)) \
+        register_opcode(disas_##name, 0x##opcode, 0x##mask); \
+    } while(0)
+    INSN(undef,     0000, 0000, CF_ISA_A);
+    INSN(arith_im,  0080, fff8, CF_ISA_A);
+    INSN(bitrev,    00c0, fff8, CF_ISA_APLUSC);
+    INSN(bitop_reg, 0100, f1c0, CF_ISA_A);
+    INSN(bitop_reg, 0140, f1c0, CF_ISA_A);
+    INSN(bitop_reg, 0180, f1c0, CF_ISA_A);
+    INSN(bitop_reg, 01c0, f1c0, CF_ISA_A);
+    INSN(arith_im,  0280, fff8, CF_ISA_A);
+    INSN(byterev,   02c0, fff8, CF_ISA_APLUSC);
+    INSN(arith_im,  0480, fff8, CF_ISA_A);
+    INSN(ff1,       04c0, fff8, CF_ISA_APLUSC);
+    INSN(arith_im,  0680, fff8, CF_ISA_A);
+    INSN(bitop_im,  0800, ffc0, CF_ISA_A);
+    INSN(bitop_im,  0840, ffc0, CF_ISA_A);
+    INSN(bitop_im,  0880, ffc0, CF_ISA_A);
+    INSN(bitop_im,  08c0, ffc0, CF_ISA_A);
+    INSN(arith_im,  0a80, fff8, CF_ISA_A);
+    INSN(arith_im,  0c00, ff38, CF_ISA_A);
+    INSN(move,      1000, f000, CF_ISA_A);
+    INSN(move,      2000, f000, CF_ISA_A);
+    INSN(move,      3000, f000, CF_ISA_A);
+    INSN(strldsr,   40e7, ffff, CF_ISA_APLUSC);
+    INSN(negx,      4080, fff8, CF_ISA_A);
+    INSN(move_from_sr, 40c0, fff8, CF_ISA_A);
+    INSN(lea,       41c0, f1c0, CF_ISA_A);
+    INSN(clr,       4200, ff00, CF_ISA_A);
+    INSN(undef,     42c0, ffc0, CF_ISA_A);
+    INSN(move_from_ccr, 42c0, fff8, CF_ISA_A);
+    INSN(neg,       4480, fff8, CF_ISA_A);
+    INSN(move_to_ccr, 44c0, ffc0, CF_ISA_A);
+    INSN(not,       4680, fff8, CF_ISA_A);
+    INSN(move_to_sr, 46c0, ffc0, CF_ISA_A);
+    INSN(pea,       4840, ffc0, CF_ISA_A);
+    INSN(swap,      4840, fff8, CF_ISA_A);
+    INSN(movem,     48c0, fbc0, CF_ISA_A);
+    INSN(ext,       4880, fff8, CF_ISA_A);
+    INSN(ext,       48c0, fff8, CF_ISA_A);
+    INSN(ext,       49c0, fff8, CF_ISA_A);
+    INSN(tst,       4a00, ff00, CF_ISA_A);
+    INSN(tas,       4ac0, ffc0, CF_ISA_B);
+    INSN(halt,      4ac8, ffff, CF_ISA_A);
+    INSN(pulse,     4acc, ffff, CF_ISA_A);
+    INSN(illegal,   4afc, ffff, CF_ISA_A);
+    INSN(mull,      4c00, ffc0, CF_ISA_A);
+    INSN(divl,      4c40, ffc0, CF_ISA_A);
+    INSN(sats,      4c80, fff8, CF_ISA_B);
+    INSN(trap,      4e40, fff0, CF_ISA_A);
+    INSN(link,      4e50, fff8, CF_ISA_A);
+    INSN(unlk,      4e58, fff8, CF_ISA_A);
+    INSN(move_to_usp, 4e60, fff8, USP);
+    INSN(move_from_usp, 4e68, fff8, USP);
+    INSN(nop,       4e71, ffff, CF_ISA_A);
+    INSN(stop,      4e72, ffff, CF_ISA_A);
+    INSN(rte,       4e73, ffff, CF_ISA_A);
+    INSN(rts,       4e75, ffff, CF_ISA_A);
+    INSN(movec,     4e7b, ffff, CF_ISA_A);
+    INSN(jump,      4e80, ffc0, CF_ISA_A);
+    INSN(jump,      4ec0, ffc0, CF_ISA_A);
+    INSN(addsubq,   5180, f1c0, CF_ISA_A);
+    INSN(scc,       50c0, f0f8, CF_ISA_A);
+    INSN(addsubq,   5080, f1c0, CF_ISA_A);
+    INSN(tpf,       51f8, fff8, CF_ISA_A);
 
-    iflags = def->insns;
-#define INSN(name, opcode, mask, isa) \
-    if (iflags & M68K_INSN_##isa) \
-        register_opcode(disas_##name, 0x##opcode, 0x##mask)
-    INSN(undef,     0000, 0000, CF_A);
-    INSN(arith_im,  0080, fff8, CF_A);
-    INSN(bitrev,    00c0, fff8, CF_C);
-    INSN(bitop_reg, 0100, f1c0, CF_A);
-    INSN(bitop_reg, 0140, f1c0, CF_A);
-    INSN(bitop_reg, 0180, f1c0, CF_A);
-    INSN(bitop_reg, 01c0, f1c0, CF_A);
-    INSN(arith_im,  0280, fff8, CF_A);
-    INSN(byterev,   02c0, fff8, CF_A);
-    INSN(arith_im,  0480, fff8, CF_A);
-    INSN(ff1,       04c0, fff8, CF_C);
-    INSN(arith_im,  0680, fff8, CF_A);
-    INSN(bitop_im,  0800, ffc0, CF_A);
-    INSN(bitop_im,  0840, ffc0, CF_A);
-    INSN(bitop_im,  0880, ffc0, CF_A);
-    INSN(bitop_im,  08c0, ffc0, CF_A);
-    INSN(arith_im,  0a80, fff8, CF_A);
-    INSN(arith_im,  0c00, ff38, CF_A);
-    INSN(move,      1000, f000, CF_A);
-    INSN(move,      2000, f000, CF_A);
-    INSN(move,      3000, f000, CF_A);
-    INSN(strldsr,   40e7, ffff, CF_A);
-    INSN(negx,      4080, fff8, CF_A);
-    INSN(move_from_sr, 40c0, fff8, CF_A);
-    INSN(lea,       41c0, f1c0, CF_A);
-    INSN(clr,       4200, ff00, CF_A);
-    INSN(undef,     42c0, ffc0, CF_A);
-    INSN(move_from_ccr, 42c0, fff8, CF_A);
-    INSN(neg,       4480, fff8, CF_A);
-    INSN(move_to_ccr, 44c0, ffc0, CF_A);
-    INSN(not,       4680, fff8, CF_A);
-    INSN(move_to_sr, 46c0, ffc0, CF_A);
-    INSN(pea,       4840, ffc0, CF_A);
-    INSN(swap,      4840, fff8, CF_A);
-    INSN(movem,     48c0, fbc0, CF_A);
-    INSN(ext,       4880, fff8, CF_A);
-    INSN(ext,       48c0, fff8, CF_A);
-    INSN(ext,       49c0, fff8, CF_A);
-    INSN(tst,       4a00, ff00, CF_A);
-    INSN(tas,       4ac0, ffc0, CF_B);
-    INSN(halt,      4ac8, ffff, CF_A);
-    INSN(pulse,     4acc, ffff, CF_A);
-    INSN(illegal,   4afc, ffff, CF_A);
-    INSN(mull,      4c00, ffc0, CF_A);
-    INSN(divl,      4c40, ffc0, CF_A);
-    INSN(sats,      4c80, fff8, CF_B);
-    INSN(trap,      4e40, fff0, CF_A);
-    INSN(link,      4e50, fff8, CF_A);
-    INSN(unlk,      4e58, fff8, CF_A);
-    INSN(move_to_usp, 4e60, fff8, CF_B);
-    INSN(move_from_usp, 4e68, fff8, CF_B);
-    INSN(nop,       4e71, ffff, CF_A);
-    INSN(stop,      4e72, ffff, CF_A);
-    INSN(rte,       4e73, ffff, CF_A);
-    INSN(rts,       4e75, ffff, CF_A);
-    INSN(movec,     4e7b, ffff, CF_A);
-    INSN(jump,      4e80, ffc0, CF_A);
-    INSN(jump,      4ec0, ffc0, CF_A);
-    INSN(addsubq,   5180, f1c0, CF_A);
-    INSN(scc,       50c0, f0f8, CF_A);
-    INSN(addsubq,   5080, f1c0, CF_A);
-    INSN(tpf,       51f8, fff8, CF_A);
-    INSN(branch,    6000, f000, CF_A);
-    INSN(moveq,     7000, f100, CF_A);
-    INSN(mvzs,      7100, f100, CF_B);
-    INSN(or,        8000, f000, CF_A);
-    INSN(divw,      80c0, f0c0, CF_A);
-    INSN(addsub,    9000, f000, CF_A);
-    INSN(subx,      9180, f1f8, CF_A);
-    INSN(suba,      91c0, f1c0, CF_A);
-    INSN(undef_mac, a000, f000, CF_A);
-    INSN(mov3q,     a140, f1c0, CF_B);
-    INSN(cmp,       b000, f1c0, CF_B); /* cmp.b */
-    INSN(cmp,       b040, f1c0, CF_B); /* cmp.w */
-    INSN(cmpa,      b0c0, f1c0, CF_B); /* cmpa.w */
-    INSN(cmp,       b080, f1c0, CF_A);
-    INSN(cmpa,      b1c0, f1c0, CF_A);
-    INSN(eor,       b180, f1c0, CF_A);
-    INSN(and,       c000, f000, CF_A);
-    INSN(mulw,      c0c0, f0c0, CF_A);
-    INSN(addsub,    d000, f000, CF_A);
-    INSN(addx,      d180, f1f8, CF_A);
-    INSN(adda,      d1c0, f1c0, CF_A);
-    INSN(shift_im,  e080, f0f0, CF_A);
-    INSN(shift_reg, e0a0, f0f0, CF_A);
-    INSN(undef_fpu, f000, f000, CF_A);
+    /* Branch instructions.  */
+    INSN(branch,    6000, f000, CF_ISA_A);
+    /* Disable long branch instructions, then add back the ones we want.  */
+    INSN(undef,     60ff, f0ff, CF_ISA_A); /* All long branches.  */
+    INSN(branch,    60ff, f0ff, CF_ISA_B);
+    INSN(undef,     60ff, ffff, CF_ISA_B); /* bra.l */
+    INSN(branch,    60ff, ffff, BRAL);
+
+    INSN(moveq,     7000, f100, CF_ISA_A);
+    INSN(mvzs,      7100, f100, CF_ISA_B);
+    INSN(or,        8000, f000, CF_ISA_A);
+    INSN(divw,      80c0, f0c0, CF_ISA_A);
+    INSN(addsub,    9000, f000, CF_ISA_A);
+    INSN(subx,      9180, f1f8, CF_ISA_A);
+    INSN(suba,      91c0, f1c0, CF_ISA_A);
+
+    INSN(undef_mac, a000, f000, CF_ISA_A);
+    INSN(mac,       a000, f100, CF_EMAC);
+    INSN(from_mac,  a180, f9b0, CF_EMAC);
+    INSN(move_mac,  a110, f9fc, CF_EMAC);
+    INSN(from_macsr,a980, f9f0, CF_EMAC);
+    INSN(from_mask, ad80, fff0, CF_EMAC);
+    INSN(from_mext, ab80, fbf0, CF_EMAC);
+    INSN(macsr_to_ccr, a9c0, ffff, CF_EMAC);
+    INSN(to_mac,    a100, f9c0, CF_EMAC);
+    INSN(to_macsr,  a900, ffc0, CF_EMAC);
+    INSN(to_mext,   ab00, fbc0, CF_EMAC);
+    INSN(to_mask,   ad00, ffc0, CF_EMAC);
+
+    INSN(mov3q,     a140, f1c0, CF_ISA_B);
+    INSN(cmp,       b000, f1c0, CF_ISA_B); /* cmp.b */
+    INSN(cmp,       b040, f1c0, CF_ISA_B); /* cmp.w */
+    INSN(cmpa,      b0c0, f1c0, CF_ISA_B); /* cmpa.w */
+    INSN(cmp,       b080, f1c0, CF_ISA_A);
+    INSN(cmpa,      b1c0, f1c0, CF_ISA_A);
+    INSN(eor,       b180, f1c0, CF_ISA_A);
+    INSN(and,       c000, f000, CF_ISA_A);
+    INSN(mulw,      c0c0, f0c0, CF_ISA_A);
+    INSN(addsub,    d000, f000, CF_ISA_A);
+    INSN(addx,      d180, f1f8, CF_ISA_A);
+    INSN(adda,      d1c0, f1c0, CF_ISA_A);
+    INSN(shift_im,  e080, f0f0, CF_ISA_A);
+    INSN(shift_reg, e0a0, f0f0, CF_ISA_A);
+    INSN(undef_fpu, f000, f000, CF_ISA_A);
     INSN(fpu,       f200, ffc0, CF_FPU);
     INSN(fbcc,      f280, ffc0, CF_FPU);
     INSN(frestore,  f340, ffc0, CF_FPU);
     INSN(fsave,     f340, ffc0, CF_FPU);
-    INSN(intouch,   f340, ffc0, CF_A);
-    INSN(cpushl,    f428, ff38, CF_A);
-    INSN(wddata,    fb00, ff00, CF_A);
-    INSN(wdebug,    fbc0, ffc0, CF_A);
+    INSN(intouch,   f340, ffc0, CF_ISA_A);
+    INSN(cpushl,    f428, ff38, CF_ISA_A);
+    INSN(wddata,    fb00, ff00, CF_ISA_A);
+    INSN(wdebug,    fbc0, ffc0, CF_ISA_A);
 #undef INSN
 }
 
@@ -2744,12 +3166,14 @@
     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
     gen_opparam_ptr = gen_opparam_buf;
 
+    dc->env = env;
     dc->is_jmp = DISAS_NEXT;
     dc->pc = pc_start;
     dc->cc_op = CC_OP_DYNAMIC;
     dc->singlestep_enabled = env->singlestep_enabled;
     dc->fpcr = env->fpcr;
     dc->user = (env->sr & SR_S) == 0;
+    dc->is_mem = 0;
     nb_gen_labels = 0;
     lj = -1;
     do {
@@ -2778,7 +3202,14 @@
             gen_opc_instr_start[lj] = 1;
         }
         last_cc_op = dc->cc_op;
+        dc->insn_pc = dc->pc;
 	disas_m68k_insn(env, dc);
+
+        /* Terminate the TB on memory ops if watchpoints are present.  */
+        /* FIXME: This should be replacd by the deterministic execution
+         * IRQ raising bits.  */
+        if (dc->is_mem && env->nb_watchpoints)
+            break;
     } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
              !env->singlestep_enabled &&
              (pc_offset) < (TARGET_PAGE_SIZE - 32));
@@ -2855,6 +3286,7 @@
 #if !defined (CONFIG_USER_ONLY)
     env->sr = 0x2700;
 #endif
+    m68k_switch_sp(env);
     /* ??? FP regs should be initialized to NaN.  */
     env->cc_op = CC_OP_FLAGS;
     /* TODO: We should set PC from the interrupt vector.  */
@@ -2880,22 +3312,6 @@
     free(env);
 }
 
-int cpu_m68k_set_model(CPUM68KState *env, const char * name)
-{
-    m68k_def_t *def;
-
-    for (def = m68k_cpu_defs; def->name; def++) {
-        if (strcmp(def->name, name) == 0)
-            break;
-    }
-    if (!def->name)
-        return 1;
-
-    register_m68k_insns(def);
-
-    return 0;
-}
-
 void cpu_dump_state(CPUState *env, FILE *f, 
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
                     int flags)

Modified: trunk/src/host/qemu-neo1973/target-mips/TODO
===================================================================
--- trunk/src/host/qemu-neo1973/target-mips/TODO	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-mips/TODO	2007-06-17 16:55:00 UTC (rev 2289)
@@ -7,16 +7,16 @@
 - Missing per-CPU instruction decoding, currently all implemented
   instructions are regarded as valid
 - Applications running on top of a emulated Linux segfault sometimes
-  when the Qemu FPU emulation is disabled. Also gdb inside the emulated
-  system does not work. Both problems are caused by insufficient
-  handling of self-modifying code.
-- Floating point exception emulation is incomplete.
+  when the Qemu FPU emulation is disabled, the tb misses a flush
+  in that case.
+- gdb breakpoints inside the emulated system work only due to a hack
+  which disassembles over the end of the current tb.
+- Floating point results of ceil/floor/round are wrong for IEEE cornercases.
+- recip/rsqrt FPU instructions are not implemented
 
 MIPS64
 ------
-- No 64bit TLB support
-- 64bit FPU not fully implemented
-- 64bit mul/div handling broken
+- Only lighly tested but apparently functional as of 2007-05-31.
 
 "Generic" 4Kc system emulation
 ------------------------------

Modified: trunk/src/host/qemu-neo1973/target-mips/cpu.h
===================================================================
--- trunk/src/host/qemu-neo1973/target-mips/cpu.h	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-mips/cpu.h	2007-06-17 16:55:00 UTC (rev 2289)
@@ -48,6 +48,8 @@
     target_ulong PFN[2];
 };
 
+typedef struct mips_def_t mips_def_t;
+
 typedef struct CPUMIPSState CPUMIPSState;
 struct CPUMIPSState {
     /* General integer registers */
@@ -256,10 +258,13 @@
     uint32_t hflags;    /* CPU State */
     /* TMASK defines different execution modes */
 #define MIPS_HFLAG_TMASK  0x007F
-#define MIPS_HFLAG_MODE   0x001F /* execution modes                    */
+#define MIPS_HFLAG_MODE   0x0007 /* execution modes                    */
 #define MIPS_HFLAG_UM     0x0001 /* user mode                          */
-#define MIPS_HFLAG_DM     0x0008 /* Debug mode                         */
-#define MIPS_HFLAG_SM     0x0010 /* Supervisor mode                    */
+#define MIPS_HFLAG_DM     0x0002 /* Debug mode                         */
+#define MIPS_HFLAG_SM     0x0004 /* Supervisor mode                    */
+#define MIPS_HFLAG_64     0x0008 /* 64-bit instructions enabled        */
+#define MIPS_HFLAG_FPU    0x0010 /* FPU enabled                        */
+#define MIPS_HFLAG_F64    0x0020 /* 64-bit FPU enabled                 */
 #define MIPS_HFLAG_RE     0x0040 /* Reversed endianness                */
     /* If translation is interrupted between the branch instruction and
      * the delay slot, record what type of branch it is so that we can
@@ -279,10 +284,8 @@
     int CCRes; /* Cycle count resolution/divisor */
     int Status_rw_bitmask; /* Read/write bits in CP0_Status */
 
-#if defined(CONFIG_USER_ONLY)
+#ifdef CONFIG_USER_ONLY
     target_ulong tls_value;
-#else
-    void *irq[8];
 #endif
 
     CPU_COMMON
@@ -292,6 +295,11 @@
     const char *kernel_cmdline;
     const char *initrd_filename;
 
+    mips_def_t *cpu_model;
+#ifndef CONFIG_USER_ONLY
+    void *irq[8];
+#endif
+
     struct QEMUTimer *timer; /* Internal timer */
 };
 
@@ -305,11 +313,16 @@
 void r4k_do_tlbwr (void);
 void r4k_do_tlbp (void);
 void r4k_do_tlbr (void);
-typedef struct mips_def_t mips_def_t;
 int mips_find_by_name (const unsigned char *name, mips_def_t **def);
 void mips_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
 int cpu_mips_register (CPUMIPSState *env, mips_def_t *def);
 
+#define CPUState CPUMIPSState
+#define cpu_init cpu_mips_init
+#define cpu_exec cpu_mips_exec
+#define cpu_gen_code cpu_mips_gen_code
+#define cpu_signal_handler cpu_mips_signal_handler
+
 #include "cpu-all.h"
 
 /* Memory access type :

Modified: trunk/src/host/qemu-neo1973/target-mips/exec.h
===================================================================
--- trunk/src/host/qemu-neo1973/target-mips/exec.h	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-mips/exec.h	2007-06-17 16:55:00 UTC (rev 2289)
@@ -56,14 +56,6 @@
 #include "softmmu_exec.h"
 #endif /* !defined(CONFIG_USER_ONLY) */
 
-static inline void env_to_regs(void)
-{
-}
-
-static inline void regs_to_env(void)
-{
-}
-
 #ifdef TARGET_MIPS64
 #if TARGET_LONG_BITS > HOST_LONG_BITS
 void do_dsll (void);
@@ -240,4 +232,23 @@
 FOP_PROTO(ngt)
 #undef FOP_PROTO
 
+static inline void env_to_regs(void)
+{
+}
+
+static inline void regs_to_env(void)
+{
+}
+
+static inline int cpu_halted(CPUState *env) {
+    if (!env->halted)
+        return 0;
+    if (env->interrupt_request &
+        (CPU_INTERRUPT_HARD | CPU_INTERRUPT_TIMER)) {
+        env->halted = 0;
+        return 0;
+    }
+    return EXCP_HALTED;
+}
+
 #endif /* !defined(__QEMU_MIPS_EXEC_H__) */

Modified: trunk/src/host/qemu-neo1973/target-mips/fop_template.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-mips/fop_template.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-mips/fop_template.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -49,7 +49,7 @@
 #define OP_DLOAD_FREG(treg, tregname, FREG)              \
     void glue(glue(op_load_fpr_,tregname), FREG) (void)  \
     {                                                    \
-        if (env->CP0_Status & (1 << CP0St_FR))           \
+        if (env->hflags & MIPS_HFLAG_F64)                \
             treg = env->fpr[FREG].fd;                    \
         else                                             \
             treg = (uint64_t)(env->fpr[FREG | 1].fs[FP_ENDIAN_IDX]) << 32 | \
@@ -60,7 +60,7 @@
 #define OP_DSTORE_FREG(treg, tregname, FREG)             \
     void glue(glue(op_store_fpr_,tregname), FREG) (void) \
     {                                                    \
-        if (env->CP0_Status & (1 << CP0St_FR))           \
+        if (env->hflags & MIPS_HFLAG_F64)                \
             env->fpr[FREG].fd = treg;                    \
         else {                                           \
             env->fpr[FREG | 1].fs[FP_ENDIAN_IDX] = treg >> 32; \

Modified: trunk/src/host/qemu-neo1973/target-mips/helper.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-mips/helper.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-mips/helper.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -370,6 +370,7 @@
         }
     enter_debug_mode:
         env->hflags |= MIPS_HFLAG_DM;
+        env->hflags |= MIPS_HFLAG_64;
         env->hflags &= ~MIPS_HFLAG_UM;
         /* EJTAG probe trap enable is not implemented... */
         if (!(env->CP0_Status & (1 << CP0St_EXL)))
@@ -395,6 +396,7 @@
             env->CP0_ErrorEPC = env->PC;
         }
         env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV);
+        env->hflags |= MIPS_HFLAG_64;
         env->hflags &= ~MIPS_HFLAG_UM;
         if (!(env->CP0_Status & (1 << CP0St_EXL)))
             env->CP0_Cause &= ~(1 << CP0Ca_BD);
@@ -493,6 +495,7 @@
                 env->CP0_Cause &= ~(1 << CP0Ca_BD);
             }
             env->CP0_Status |= (1 << CP0St_EXL);
+            env->hflags |= MIPS_HFLAG_64;
             env->hflags &= ~MIPS_HFLAG_UM;
         }
         env->hflags &= ~MIPS_HFLAG_BMASK;

Modified: trunk/src/host/qemu-neo1973/target-mips/op.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-mips/op.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-mips/op.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -976,6 +976,14 @@
     RETURN();
 }
 
+#ifdef TARGET_MIPS64
+void op_save_btarget64 (void)
+{
+    env->btarget = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2;
+    RETURN();
+}
+#endif
+
 /* Conditional branch */
 void op_set_bcond (void)
 {
@@ -1341,8 +1349,7 @@
     uint32_t val, old;
     uint32_t mask = env->Status_rw_bitmask;
 
-    /* No reverse endianness, no MDMX/DSP, no 64bit ops
-       implemented. */
+    /* No reverse endianness, no MDMX/DSP implemented. */
     val = T0 & mask;
     old = env->CP0_Status;
     if (!(val & (1 << CP0St_EXL)) &&
@@ -1350,6 +1357,20 @@
         !(env->hflags & MIPS_HFLAG_DM) &&
         (val & (1 << CP0St_UM)))
         env->hflags |= MIPS_HFLAG_UM;
+#ifdef TARGET_MIPS64
+    if ((env->hflags & MIPS_HFLAG_UM) &&
+        !(val & (1 << CP0St_PX)) &&
+        !(val & (1 << CP0St_UX)))
+        env->hflags &= ~MIPS_HFLAG_64;
+#endif
+    if (val & (1 << CP0St_CU1))
+        env->hflags |= MIPS_HFLAG_FPU;
+    else
+        env->hflags &= ~MIPS_HFLAG_FPU;
+    if (val & (1 << CP0St_FR))
+        env->hflags |= MIPS_HFLAG_F64;
+    else
+        env->hflags &= ~MIPS_HFLAG_F64;
     env->CP0_Status = (env->CP0_Status & ~mask) | val;
     if (loglevel & CPU_LOG_EXEC)
         CALL_FROM_TB2(do_mtc0_status_debug, old, val);
@@ -1592,41 +1613,6 @@
     RETURN();
 }
 
-void op_cp1_enabled(void)
-{
-    if (!(env->CP0_Status & (1 << CP0St_CU1))) {
-        CALL_FROM_TB2(do_raise_exception_err, EXCP_CpU, 1);
-    }
-    RETURN();
-}
-
-void op_cp1_64bitmode(void)
-{
-    if (!(env->CP0_Status & (1 << CP0St_FR))) {
-        CALL_FROM_TB1(do_raise_exception, EXCP_RI);
-    }
-    RETURN();
-}
-
-/*
- * Verify if floating point register is valid; an operation is not defined
- * if bit 0 of any register specification is set and the FR bit in the
- * Status register equals zero, since the register numbers specify an
- * even-odd pair of adjacent coprocessor general registers. When the FR bit
- * in the Status register equals one, both even and odd register numbers
- * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
- *
- * Multiple 64 bit wide registers can be checked by calling
- * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
- */
-void op_cp1_registers(void)
-{
-    if (!(env->CP0_Status & (1 << CP0St_FR)) && (PARAM1 & 1)) {
-        CALL_FROM_TB1(do_raise_exception, EXCP_RI);
-    }
-    RETURN();
-}
-
 void op_cfc1 (void)
 {
     switch (T1) {
@@ -2330,6 +2316,12 @@
         !(env->hflags & MIPS_HFLAG_DM) &&
         (env->CP0_Status & (1 << CP0St_UM)))
         env->hflags |= MIPS_HFLAG_UM;
+#ifdef TARGET_MIPS64
+    if ((env->hflags & MIPS_HFLAG_UM) &&
+        !(env->CP0_Status & (1 << CP0St_PX)) &&
+        !(env->CP0_Status & (1 << CP0St_UX)))
+        env->hflags &= ~MIPS_HFLAG_64;
+#endif
     if (loglevel & CPU_LOG_EXEC)
         CALL_FROM_TB0(debug_post_eret);
     env->CP0_LLAddr = 1;
@@ -2347,6 +2339,12 @@
         !(env->hflags & MIPS_HFLAG_DM) &&
         (env->CP0_Status & (1 << CP0St_UM)))
         env->hflags |= MIPS_HFLAG_UM;
+#ifdef TARGET_MIPS64
+    if ((env->hflags & MIPS_HFLAG_UM) &&
+        !(env->CP0_Status & (1 << CP0St_PX)) &&
+        !(env->CP0_Status & (1 << CP0St_UX)))
+        env->hflags &= ~MIPS_HFLAG_64;
+#endif
     if (loglevel & CPU_LOG_EXEC)
         CALL_FROM_TB0(debug_post_eret);
     env->CP0_LLAddr = 1;
@@ -2409,6 +2407,14 @@
     RETURN();
 }
 
+#ifdef TARGET_MIPS64
+void op_save_pc64 (void)
+{
+    env->PC = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2;
+    RETURN();
+}
+#endif
+
 void op_interrupt_restart (void)
 {
     if (!(env->CP0_Status & (1 << CP0St_EXL)) &&

Modified: trunk/src/host/qemu-neo1973/target-mips/op_helper.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-mips/op_helper.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-mips/op_helper.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -24,10 +24,6 @@
 
 /*****************************************************************************/
 /* Exceptions processing helpers */
-void cpu_loop_exit(void)
-{
-    longjmp(env->jmp_env, 1);
-}
 
 void do_raise_exception_err (uint32_t exception, int error_code)
 {
@@ -237,16 +233,16 @@
     }
 }
 
+#if TARGET_LONG_BITS > HOST_LONG_BITS
 void do_ddivu (void)
 {
     if (T1 != 0) {
-        /* XXX: lldivu? */
-        lldiv_t res = lldiv(T0, T1);
-        env->LO = (uint64_t)res.quot;
-        env->HI = (uint64_t)res.rem;
+        env->LO = T0 / T1;
+        env->HI = T0 % T1;
     }
 }
 #endif
+#endif /* TARGET_MIPS64 */
 
 #if defined(CONFIG_USER_ONLY) 
 void do_mfc0_random (void)
@@ -1147,7 +1143,6 @@
 
 flag float32_is_unordered(int sig, float32 a, float32 b STATUS_PARAM)
 {
-    extern flag float32_is_nan(float32 a);
     if (float32_is_signaling_nan(a) ||
         float32_is_signaling_nan(b) ||
         (sig && (float32_is_nan(a) || float32_is_nan(b)))) {

Modified: trunk/src/host/qemu-neo1973/target-mips/op_mem.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-mips/op_mem.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-mips/op_mem.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -63,7 +63,7 @@
 
 void glue(op_lwu, MEMSUFFIX) (void)
 {
-    T0 = glue(ldl, MEMSUFFIX)(T0);
+    T0 = (uint32_t)glue(ldl, MEMSUFFIX)(T0);
     RETURN();
 }
 

Modified: trunk/src/host/qemu-neo1973/target-mips/op_template.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-mips/op_template.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-mips/op_template.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -68,4 +68,20 @@
 SET_RESET(T2, _T2)
 
 #undef SET_RESET
+
+#ifdef TARGET_MIPS64
+#define SET64(treg, tregname)                               \
+    void glue(op_set64, tregname)(void)                     \
+    {                                                       \
+        treg = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2; \
+        RETURN();                                           \
+    }
+
+SET64(T0, _T0)
+SET64(T1, _T1)
+SET64(T2, _T2)
+
+#undef SET64
+
 #endif
+#endif

Modified: trunk/src/host/qemu-neo1973/target-mips/translate.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-mips/translate.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-mips/translate.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -569,14 +569,27 @@
     }                                                                         \
 } while (0)
 
+#ifdef TARGET_MIPS64
 #define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
 do {                                                                          \
     if (Imm == 0) {                                                           \
         glue(gen_op_reset_, Tn)();                                            \
+    } else if ((int32_t)Imm == Imm) {                                         \
+        glue(gen_op_set_, Tn)(Imm);                                           \
     } else {                                                                  \
+        glue(gen_op_set64_, Tn)(((uint64_t)Imm) >> 32, (uint32_t)Imm);        \
+    }                                                                         \
+} while (0)
+#else
+#define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
+do {                                                                          \
+    if (Imm == 0) {                                                           \
+        glue(gen_op_reset_, Tn)();                                            \
+    } else {                                                                  \
         glue(gen_op_set_, Tn)(Imm);                                           \
     }                                                                         \
 } while (0)
+#endif
 
 #define GEN_STORE_TN_REG(Rn, Tn)                                              \
 do {                                                                          \
@@ -595,6 +608,32 @@
     glue(gen_op_store_fpr_, FTn)(Fn);                                         \
 } while (0)
 
+static inline void gen_save_pc(target_ulong pc)
+{
+#ifdef TARGET_MIPS64
+    if (pc == (int32_t)pc) {
+        gen_op_save_pc(pc);
+    } else {
+        gen_op_save_pc64(pc >> 32, (uint32_t)pc);
+    }
+#else
+    gen_op_save_pc(pc);
+#endif
+}
+
+static inline void gen_save_btarget(target_ulong btarget)
+{
+#ifdef TARGET_MIPS64
+    if (btarget == (int32_t)btarget) {
+        gen_op_save_btarget(btarget);
+    } else {
+        gen_op_save_btarget64(btarget >> 32, (uint32_t)btarget);
+    }
+#else
+    gen_op_save_btarget(btarget);
+#endif
+}
+
 static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
 {
 #if defined MIPS_DEBUG_DISAS
@@ -604,7 +643,7 @@
     }
 #endif
     if (do_save_pc && ctx->pc != ctx->saved_pc) {
-        gen_op_save_pc(ctx->pc);
+        gen_save_pc(ctx->pc);
         ctx->saved_pc = ctx->pc;
     }
     if (ctx->hflags != ctx->saved_hflags) {
@@ -621,7 +660,7 @@
             /* bcond was already saved by the BL insn */
             /* fall through */
         case MIPS_HFLAG_B:
-            gen_op_save_btarget(ctx->btarget);
+            gen_save_btarget(ctx->btarget);
             break;
         }
     }
@@ -664,6 +703,43 @@
     generate_exception_err (ctx, excp, 0);
 }
 
+static inline void check_cp1_enabled(DisasContext *ctx)
+{
+    if (!(ctx->hflags & MIPS_HFLAG_FPU))
+        generate_exception_err(ctx, EXCP_CpU, 1);
+}
+
+static inline void check_cp1_64bitmode(DisasContext *ctx)
+{
+    if (!(ctx->hflags & MIPS_HFLAG_F64))
+        generate_exception(ctx, EXCP_RI);
+}
+
+/*
+ * Verify if floating point register is valid; an operation is not defined
+ * if bit 0 of any register specification is set and the FR bit in the
+ * Status register equals zero, since the register numbers specify an
+ * even-odd pair of adjacent coprocessor general registers. When the FR bit
+ * in the Status register equals one, both even and odd register numbers
+ * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
+ *
+ * Multiple 64 bit wide registers can be checked by calling
+ * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
+ */
+void check_cp1_registers(DisasContext *ctx, int regs)
+{
+    if (!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))
+        generate_exception(ctx, EXCP_RI);
+}
+
+/* This code generates a "reserved instruction" exception if the
+   CPU is not a MIPS R2 (or higher) CPU. */
+static inline void check_mips_r2(CPUState *env, DisasContext *ctx)
+{
+    if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) < (1 << CP0C0_AR))
+        generate_exception(ctx, EXCP_RI);
+}
+
 #if defined(CONFIG_USER_ONLY)
 #define op_ldst(name)        gen_op_##name##_raw()
 #define OP_LD_TABLE(width)
@@ -691,9 +767,9 @@
 OP_ST_TABLE(dr);
 OP_LD_TABLE(ld);
 OP_ST_TABLE(cd);
+OP_LD_TABLE(wu);
 #endif
 OP_LD_TABLE(w);
-OP_LD_TABLE(wu);
 OP_LD_TABLE(wl);
 OP_LD_TABLE(wr);
 OP_ST_TABLE(w);
@@ -734,6 +810,11 @@
      */
     switch (opc) {
 #ifdef TARGET_MIPS64
+    case OPC_LWU:
+        op_ldst(lwu);
+        GEN_STORE_TN_REG(rt, T0);
+        opn = "lwu";
+        break;
     case OPC_LD:
         op_ldst(ld);
         GEN_STORE_TN_REG(rt, T0);
@@ -784,11 +865,6 @@
         GEN_STORE_TN_REG(rt, T0);
         opn = "lw";
         break;
-    case OPC_LWU:
-        op_ldst(lwu);
-        GEN_STORE_TN_REG(rt, T0);
-        opn = "lwu";
-        break;
     case OPC_SW:
         GEN_LOAD_REG_TN(T1, rt);
         op_ldst(sw);
@@ -946,7 +1022,7 @@
         GEN_LOAD_IMM_TN(T1, uimm);
         break;
     case OPC_LUI:
-        GEN_LOAD_IMM_TN(T0, uimm << 16);
+        GEN_LOAD_IMM_TN(T0, imm << 16);
         break;
     case OPC_SLL:
     case OPC_SRA:
@@ -1491,10 +1567,10 @@
             gen_op_goto_tb0(TBPARAM(tb));
         else
             gen_op_goto_tb1(TBPARAM(tb));
-        gen_op_save_pc(dest);
+        gen_save_pc(dest);
         gen_op_set_T0((long)tb + n);
     } else {
-        gen_op_save_pc(dest);
+        gen_save_pc(dest);
         gen_op_reset_T0();
     }
     gen_op_exit_tb();
@@ -1556,7 +1632,7 @@
     case OPC_J:
     case OPC_JAL:
         /* Jump to immediate */
-        btarget = ((ctx->pc + 4) & (int32_t)0xF0000000) | offset;
+        btarget = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
         break;
     case OPC_JR:
     case OPC_JALR:
@@ -1602,12 +1678,12 @@
             MIPS_DEBUG("bnever (NOP)");
             return;
         case OPC_BLTZAL:  /* 0 < 0           */
-            gen_op_set_T0(ctx->pc + 8);
+            GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
             gen_op_store_T0_gpr(31);
             MIPS_DEBUG("bnever and link");
             return;
         case OPC_BLTZALL: /* 0 < 0 likely */
-            gen_op_set_T0(ctx->pc + 8);
+            GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
             gen_op_store_T0_gpr(31);
             /* Skip the instruction in the delay slot */
             MIPS_DEBUG("bnever, link and skip");
@@ -1732,9 +1808,10 @@
     }
     MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
                blink, ctx->hflags, btarget);
+
     ctx->btarget = btarget;
     if (blink > 0) {
-        gen_op_set_T0(ctx->pc + 8);
+        GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
         gen_op_store_T0_gpr(blink);
     }
 }
@@ -1797,7 +1874,7 @@
 }
 
 /* CP0 (MMU and control) */
-static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
+static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
 {
     const char *rn = "invalid";
 
@@ -1931,6 +2008,7 @@
             rn = "PageMask";
             break;
         case 1:
+            check_mips_r2(env, ctx);
             gen_op_mfc0_pagegrain();
             rn = "PageGrain";
             break;
@@ -1971,6 +2049,7 @@
     case 7:
         switch (sel) {
         case 0:
+            check_mips_r2(env, ctx);
             gen_op_mfc0_hwrena();
             rn = "HWREna";
             break;
@@ -2027,14 +2106,17 @@
             rn = "Status";
             break;
         case 1:
+            check_mips_r2(env, ctx);
             gen_op_mfc0_intctl();
             rn = "IntCtl";
             break;
         case 2:
+            check_mips_r2(env, ctx);
             gen_op_mfc0_srsctl();
             rn = "SRSCtl";
             break;
         case 3:
+            check_mips_r2(env, ctx);
             gen_op_mfc0_srsmap();
             rn = "SRSMap";
             break;
@@ -2069,6 +2151,7 @@
             rn = "PRid";
             break;
         case 1:
+            check_mips_r2(env, ctx);
             gen_op_mfc0_ebase();
             rn = "EBase";
             break;
@@ -2333,7 +2416,7 @@
     generate_exception(ctx, EXCP_RI);
 }
 
-static void gen_mtc0 (DisasContext *ctx, int reg, int sel)
+static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
 {
     const char *rn = "invalid";
 
@@ -2467,6 +2550,7 @@
             rn = "PageMask";
             break;
         case 1:
+            check_mips_r2(env, ctx);
             gen_op_mtc0_pagegrain();
             rn = "PageGrain";
             break;
@@ -2507,6 +2591,7 @@
     case 7:
         switch (sel) {
         case 0:
+            check_mips_r2(env, ctx);
             gen_op_mtc0_hwrena();
             rn = "HWREna";
             break;
@@ -2558,25 +2643,35 @@
         switch (sel) {
         case 0:
             gen_op_mtc0_status();
+            /* BS_STOP isn't good enough here, hflags may have changed. */
+            gen_save_pc(ctx->pc + 4);
+            ctx->bstate = BS_EXCP;
             rn = "Status";
             break;
         case 1:
+            check_mips_r2(env, ctx);
             gen_op_mtc0_intctl();
+            /* Stop translation as we may have switched the execution mode */
+            ctx->bstate = BS_STOP;
             rn = "IntCtl";
             break;
         case 2:
+            check_mips_r2(env, ctx);
             gen_op_mtc0_srsctl();
+            /* Stop translation as we may have switched the execution mode */
+            ctx->bstate = BS_STOP;
             rn = "SRSCtl";
             break;
         case 3:
+            check_mips_r2(env, ctx);
             gen_op_mtc0_srsmap();
+            /* Stop translation as we may have switched the execution mode */
+            ctx->bstate = BS_STOP;
             rn = "SRSMap";
             break;
         default:
             goto die;
         }
-        /* Stop translation as we may have switched the execution mode */
-        ctx->bstate = BS_STOP;
         break;
     case 13:
         switch (sel) {
@@ -2607,6 +2702,7 @@
             rn = "PRid";
             break;
         case 1:
+            check_mips_r2(env, ctx);
             gen_op_mtc0_ebase();
             rn = "EBase";
             break;
@@ -2712,29 +2808,40 @@
         switch (sel) {
         case 0:
             gen_op_mtc0_debug(); /* EJTAG support */
+            /* BS_STOP isn't good enough here, hflags may have changed. */
+            gen_save_pc(ctx->pc + 4);
+            ctx->bstate = BS_EXCP;
             rn = "Debug";
             break;
         case 1:
 //            gen_op_mtc0_tracecontrol(); /* PDtrace support */
             rn = "TraceControl";
+            /* Stop translation as we may have switched the execution mode */
+            ctx->bstate = BS_STOP;
 //            break;
         case 2:
 //            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
             rn = "TraceControl2";
+            /* Stop translation as we may have switched the execution mode */
+            ctx->bstate = BS_STOP;
 //            break;
         case 3:
+            /* Stop translation as we may have switched the execution mode */
+            ctx->bstate = BS_STOP;
 //            gen_op_mtc0_usertracedata(); /* PDtrace support */
             rn = "UserTraceData";
+            /* Stop translation as we may have switched the execution mode */
+            ctx->bstate = BS_STOP;
 //            break;
         case 4:
 //            gen_op_mtc0_debug(); /* PDtrace support */
+            /* Stop translation as we may have switched the execution mode */
+            ctx->bstate = BS_STOP;
             rn = "TraceBPC";
 //            break;
         default:
             goto die;
         }
-        /* Stop translation as we may have switched the execution mode */
-        ctx->bstate = BS_STOP;
         break;
     case 24:
         switch (sel) {
@@ -2883,7 +2990,7 @@
 }
 
 #ifdef TARGET_MIPS64
-static void gen_dmfc0 (DisasContext *ctx, int reg, int sel)
+static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
 {
     const char *rn = "invalid";
 
@@ -3017,6 +3124,7 @@
             rn = "PageMask";
             break;
         case 1:
+            check_mips_r2(env, ctx);
             gen_op_mfc0_pagegrain();
             rn = "PageGrain";
             break;
@@ -3057,6 +3165,7 @@
     case 7:
         switch (sel) {
         case 0:
+            check_mips_r2(env, ctx);
             gen_op_mfc0_hwrena();
             rn = "HWREna";
             break;
@@ -3113,14 +3222,17 @@
             rn = "Status";
             break;
         case 1:
+            check_mips_r2(env, ctx);
             gen_op_mfc0_intctl();
             rn = "IntCtl";
             break;
         case 2:
+            check_mips_r2(env, ctx);
             gen_op_mfc0_srsctl();
             rn = "SRSCtl";
             break;
         case 3:
+            check_mips_r2(env, ctx);
             gen_op_mfc0_srsmap(); /* shadow registers */
             rn = "SRSMap";
             break;
@@ -3155,6 +3267,7 @@
             rn = "PRid";
             break;
         case 1:
+            check_mips_r2(env, ctx);
             gen_op_mfc0_ebase();
             rn = "EBase";
             break;
@@ -3410,7 +3523,7 @@
     generate_exception(ctx, EXCP_RI);
 }
 
-static void gen_dmtc0 (DisasContext *ctx, int reg, int sel)
+static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
 {
     const char *rn = "invalid";
 
@@ -3544,6 +3657,7 @@
             rn = "PageMask";
             break;
         case 1:
+            check_mips_r2(env, ctx);
             gen_op_mtc0_pagegrain();
             rn = "PageGrain";
             break;
@@ -3584,6 +3698,7 @@
     case 7:
         switch (sel) {
         case 0:
+            check_mips_r2(env, ctx);
             gen_op_mtc0_hwrena();
             rn = "HWREna";
             break;
@@ -3635,25 +3750,35 @@
         switch (sel) {
         case 0:
             gen_op_mtc0_status();
+            /* BS_STOP isn't good enough here, hflags may have changed. */
+            gen_save_pc(ctx->pc + 4);
+            ctx->bstate = BS_EXCP;
             rn = "Status";
             break;
         case 1:
+            check_mips_r2(env, ctx);
             gen_op_mtc0_intctl();
+            /* Stop translation as we may have switched the execution mode */
+            ctx->bstate = BS_STOP;
             rn = "IntCtl";
             break;
         case 2:
+            check_mips_r2(env, ctx);
             gen_op_mtc0_srsctl();
+            /* Stop translation as we may have switched the execution mode */
+            ctx->bstate = BS_STOP;
             rn = "SRSCtl";
             break;
         case 3:
+            check_mips_r2(env, ctx);
             gen_op_mtc0_srsmap();
+            /* Stop translation as we may have switched the execution mode */
+            ctx->bstate = BS_STOP;
             rn = "SRSMap";
             break;
         default:
             goto die;
         }
-        /* Stop translation as we may have switched the execution mode */
-        ctx->bstate = BS_STOP;
         break;
     case 13:
         switch (sel) {
@@ -3684,6 +3809,7 @@
             rn = "PRid";
             break;
         case 1:
+            check_mips_r2(env, ctx);
             gen_op_mtc0_ebase();
             rn = "EBase";
             break;
@@ -3780,29 +3906,38 @@
         switch (sel) {
         case 0:
             gen_op_mtc0_debug(); /* EJTAG support */
+            /* BS_STOP isn't good enough here, hflags may have changed. */
+            gen_save_pc(ctx->pc + 4);
+            ctx->bstate = BS_EXCP;
             rn = "Debug";
             break;
         case 1:
 //            gen_op_mtc0_tracecontrol(); /* PDtrace support */
+            /* Stop translation as we may have switched the execution mode */
+            ctx->bstate = BS_STOP;
             rn = "TraceControl";
 //            break;
         case 2:
 //            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
+            /* Stop translation as we may have switched the execution mode */
+            ctx->bstate = BS_STOP;
             rn = "TraceControl2";
 //            break;
         case 3:
 //            gen_op_mtc0_usertracedata(); /* PDtrace support */
+            /* Stop translation as we may have switched the execution mode */
+            ctx->bstate = BS_STOP;
             rn = "UserTraceData";
 //            break;
         case 4:
 //            gen_op_mtc0_debug(); /* PDtrace support */
+            /* Stop translation as we may have switched the execution mode */
+            ctx->bstate = BS_STOP;
             rn = "TraceBPC";
 //            break;
         default:
             goto die;
         }
-        /* Stop translation as we may have switched the execution mode */
-        ctx->bstate = BS_STOP;
         break;
     case 24:
         switch (sel) {
@@ -3961,13 +4096,13 @@
             /* Treat as NOP */
             return;
         }
-        gen_mfc0(ctx, rd, ctx->opcode & 0x7);
+        gen_mfc0(env, ctx, rd, ctx->opcode & 0x7);
         gen_op_store_T0_gpr(rt);
         opn = "mfc0";
         break;
     case OPC_MTC0:
         GEN_LOAD_REG_TN(T0, rt);
-        gen_mtc0(ctx, rd, ctx->opcode & 0x7);
+        gen_mtc0(env, ctx, rd, ctx->opcode & 0x7);
         opn = "mtc0";
         break;
 #ifdef TARGET_MIPS64
@@ -3976,13 +4111,13 @@
             /* Treat as NOP */
             return;
         }
-        gen_dmfc0(ctx, rd, ctx->opcode & 0x7);
+        gen_dmfc0(env, ctx, rd, ctx->opcode & 0x7);
         gen_op_store_T0_gpr(rt);
         opn = "dmfc0";
         break;
     case OPC_DMTC0:
         GEN_LOAD_REG_TN(T0, rt);
-        gen_dmtc0(ctx, rd, ctx->opcode & 0x7);
+        gen_dmtc0(env,ctx, rd, ctx->opcode & 0x7);
         opn = "dmtc0";
         break;
 #endif
@@ -4203,8 +4338,8 @@
 GEN_MOVCF(ps);
 #undef GEN_MOVCF
 
-static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
-                        int fs, int fd, int cc)
+static void gen_farith (DisasContext *ctx, uint32_t op1,
+                        int ft, int fs, int fd, int cc)
 {
     const char *opn = "farith";
     const char *condnames[] = {
@@ -4304,28 +4439,28 @@
         opn = "neg.s";
         break;
     case FOP(8, 16):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         gen_op_float_roundl_s();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "round.l.s";
         break;
     case FOP(9, 16):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         gen_op_float_truncl_s();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "trunc.l.s";
         break;
     case FOP(10, 16):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         gen_op_float_ceill_s();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "ceil.l.s";
         break;
     case FOP(11, 16):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         gen_op_float_floorl_s();
         GEN_STORE_FTN_FREG(fd, DT2);
@@ -4392,7 +4527,7 @@
         opn = "rsqrt.s";
         break;
     case FOP(28, 16):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WT2, fd);
         gen_op_float_recip2_s();
@@ -4400,21 +4535,21 @@
         opn = "recip2.s";
         break;
     case FOP(29, 16):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         gen_op_float_recip1_s();
         GEN_STORE_FTN_FREG(fd, WT2);
         opn = "recip1.s";
         break;
     case FOP(30, 16):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         gen_op_float_rsqrt1_s();
         GEN_STORE_FTN_FREG(fd, WT2);
         opn = "rsqrt1.s";
         break;
     case FOP(31, 16):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WT2, fd);
         gen_op_float_rsqrt2_s();
@@ -4422,7 +4557,7 @@
         opn = "rsqrt2.s";
         break;
     case FOP(33, 16):
-        gen_op_cp1_registers(fd);
+        check_cp1_registers(ctx, fd);
         GEN_LOAD_FREG_FTN(WT0, fs);
         gen_op_float_cvtd_s();
         GEN_STORE_FTN_FREG(fd, DT2);
@@ -4435,14 +4570,14 @@
         opn = "cvt.w.s";
         break;
     case FOP(37, 16):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         gen_op_float_cvtl_s();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "cvt.l.s";
         break;
     case FOP(38, 16):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT1, fs);
         GEN_LOAD_FREG_FTN(WT0, ft);
         gen_op_float_cvtps_s();
@@ -4468,7 +4603,7 @@
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WT1, ft);
         if (ctx->opcode & (1 << 6)) {
-            gen_op_cp1_64bitmode();
+            check_cp1_64bitmode(ctx);
             gen_cmpabs_s(func-48, cc);
             opn = condnames_abs[func-48];
         } else {
@@ -4477,7 +4612,7 @@
         }
         break;
     case FOP(0, 17):
-        gen_op_cp1_registers(fs | ft | fd);
+        check_cp1_registers(ctx, fs | ft | fd);
         GEN_LOAD_FREG_FTN(DT0, fs);
         GEN_LOAD_FREG_FTN(DT1, ft);
         gen_op_float_add_d();
@@ -4486,7 +4621,7 @@
         optype = BINOP;
         break;
     case FOP(1, 17):
-        gen_op_cp1_registers(fs | ft | fd);
+        check_cp1_registers(ctx, fs | ft | fd);
         GEN_LOAD_FREG_FTN(DT0, fs);
         GEN_LOAD_FREG_FTN(DT1, ft);
         gen_op_float_sub_d();
@@ -4495,7 +4630,7 @@
         optype = BINOP;
         break;
     case FOP(2, 17):
-        gen_op_cp1_registers(fs | ft | fd);
+        check_cp1_registers(ctx, fs | ft | fd);
         GEN_LOAD_FREG_FTN(DT0, fs);
         GEN_LOAD_FREG_FTN(DT1, ft);
         gen_op_float_mul_d();
@@ -4504,7 +4639,7 @@
         optype = BINOP;
         break;
     case FOP(3, 17):
-        gen_op_cp1_registers(fs | ft | fd);
+        check_cp1_registers(ctx, fs | ft | fd);
         GEN_LOAD_FREG_FTN(DT0, fs);
         GEN_LOAD_FREG_FTN(DT1, ft);
         gen_op_float_div_d();
@@ -4513,84 +4648,84 @@
         optype = BINOP;
         break;
     case FOP(4, 17):
-        gen_op_cp1_registers(fs | fd);
+        check_cp1_registers(ctx, fs | fd);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_sqrt_d();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "sqrt.d";
         break;
     case FOP(5, 17):
-        gen_op_cp1_registers(fs | fd);
+        check_cp1_registers(ctx, fs | fd);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_abs_d();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "abs.d";
         break;
     case FOP(6, 17):
-        gen_op_cp1_registers(fs | fd);
+        check_cp1_registers(ctx, fs | fd);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_mov_d();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "mov.d";
         break;
     case FOP(7, 17):
-        gen_op_cp1_registers(fs | fd);
+        check_cp1_registers(ctx, fs | fd);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_chs_d();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "neg.d";
         break;
     case FOP(8, 17):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_roundl_d();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "round.l.d";
         break;
     case FOP(9, 17):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_truncl_d();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "trunc.l.d";
         break;
     case FOP(10, 17):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_ceill_d();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "ceil.l.d";
         break;
     case FOP(11, 17):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_floorl_d();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "floor.l.d";
         break;
     case FOP(12, 17):
-        gen_op_cp1_registers(fs);
+        check_cp1_registers(ctx, fs);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_roundw_d();
         GEN_STORE_FTN_FREG(fd, WT2);
         opn = "round.w.d";
         break;
     case FOP(13, 17):
-        gen_op_cp1_registers(fs);
+        check_cp1_registers(ctx, fs);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_truncw_d();
         GEN_STORE_FTN_FREG(fd, WT2);
         opn = "trunc.w.d";
         break;
     case FOP(14, 17):
-        gen_op_cp1_registers(fs);
+        check_cp1_registers(ctx, fs);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_ceilw_d();
         GEN_STORE_FTN_FREG(fd, WT2);
         opn = "ceil.w.d";
         break;
     case FOP(15, 17):
-        gen_op_cp1_registers(fs);
+        check_cp1_registers(ctx, fs);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_floorw_d();
         GEN_STORE_FTN_FREG(fd, WT2);
@@ -4621,21 +4756,21 @@
         opn = "movn.d";
         break;
     case FOP(21, 17):
-        gen_op_cp1_registers(fs | fd);
+        check_cp1_registers(ctx, fs | fd);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_recip_d();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "recip.d";
         break;
     case FOP(22, 17):
-        gen_op_cp1_registers(fs | fd);
+        check_cp1_registers(ctx, fs | fd);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_rsqrt_d();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "rsqrt.d";
         break;
     case FOP(28, 17):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(DT0, fs);
         GEN_LOAD_FREG_FTN(DT2, ft);
         gen_op_float_recip2_d();
@@ -4643,21 +4778,21 @@
         opn = "recip2.d";
         break;
     case FOP(29, 17):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_recip1_d();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "recip1.d";
         break;
     case FOP(30, 17):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_rsqrt1_d();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "rsqrt1.d";
         break;
     case FOP(31, 17):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(DT0, fs);
         GEN_LOAD_FREG_FTN(DT2, ft);
         gen_op_float_rsqrt2_d();
@@ -4683,31 +4818,31 @@
         GEN_LOAD_FREG_FTN(DT0, fs);
         GEN_LOAD_FREG_FTN(DT1, ft);
         if (ctx->opcode & (1 << 6)) {
-            gen_op_cp1_64bitmode();
+            check_cp1_64bitmode(ctx);
             gen_cmpabs_d(func-48, cc);
             opn = condnames_abs[func-48];
         } else {
-            gen_op_cp1_registers(fs | ft);
+            check_cp1_registers(ctx, fs | ft);
             gen_cmp_d(func-48, cc);
             opn = condnames[func-48];
         }
         break;
     case FOP(32, 17):
-        gen_op_cp1_registers(fs);
+        check_cp1_registers(ctx, fs);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_cvts_d();
         GEN_STORE_FTN_FREG(fd, WT2);
         opn = "cvt.s.d";
         break;
     case FOP(36, 17):
-        gen_op_cp1_registers(fs);
+        check_cp1_registers(ctx, fs);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_cvtw_d();
         GEN_STORE_FTN_FREG(fd, WT2);
         opn = "cvt.w.d";
         break;
     case FOP(37, 17):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_cvtl_d();
         GEN_STORE_FTN_FREG(fd, DT2);
@@ -4720,21 +4855,21 @@
         opn = "cvt.s.w";
         break;
     case FOP(33, 20):
-        gen_op_cp1_registers(fd);
+        check_cp1_registers(ctx, fd);
         GEN_LOAD_FREG_FTN(WT0, fs);
         gen_op_float_cvtd_w();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "cvt.d.w";
         break;
     case FOP(32, 21):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_cvts_l();
         GEN_STORE_FTN_FREG(fd, WT2);
         opn = "cvt.s.l";
         break;
     case FOP(33, 21):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_cvtd_l();
         GEN_STORE_FTN_FREG(fd, DT2);
@@ -4742,7 +4877,7 @@
         break;
     case FOP(38, 20):
     case FOP(38, 21):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
         gen_op_float_cvtps_pw();
@@ -4751,7 +4886,7 @@
         opn = "cvt.ps.pw";
         break;
     case FOP(0, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
         GEN_LOAD_FREG_FTN(WT1, ft);
@@ -4762,7 +4897,7 @@
         opn = "add.ps";
         break;
     case FOP(1, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
         GEN_LOAD_FREG_FTN(WT1, ft);
@@ -4773,7 +4908,7 @@
         opn = "sub.ps";
         break;
     case FOP(2, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
         GEN_LOAD_FREG_FTN(WT1, ft);
@@ -4784,7 +4919,7 @@
         opn = "mul.ps";
         break;
     case FOP(5, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
         gen_op_float_abs_ps();
@@ -4793,7 +4928,7 @@
         opn = "abs.ps";
         break;
     case FOP(6, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
         gen_op_float_mov_ps();
@@ -4802,7 +4937,7 @@
         opn = "mov.ps";
         break;
     case FOP(7, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
         gen_op_float_chs_ps();
@@ -4811,7 +4946,7 @@
         opn = "neg.ps";
         break;
     case FOP(17, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_REG_TN(T0, ft);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
@@ -4823,7 +4958,7 @@
         opn = "movcf.ps";
         break;
     case FOP(18, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_REG_TN(T0, ft);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
@@ -4835,7 +4970,7 @@
         opn = "movz.ps";
         break;
     case FOP(19, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_REG_TN(T0, ft);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
@@ -4847,7 +4982,7 @@
         opn = "movn.ps";
         break;
     case FOP(24, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, ft);
         GEN_LOAD_FREG_FTN(WTH0, ft);
         GEN_LOAD_FREG_FTN(WT1, fs);
@@ -4858,7 +4993,7 @@
         opn = "addr.ps";
         break;
     case FOP(26, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, ft);
         GEN_LOAD_FREG_FTN(WTH0, ft);
         GEN_LOAD_FREG_FTN(WT1, fs);
@@ -4869,7 +5004,7 @@
         opn = "mulr.ps";
         break;
     case FOP(28, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
         GEN_LOAD_FREG_FTN(WT2, fd);
@@ -4880,7 +5015,7 @@
         opn = "recip2.ps";
         break;
     case FOP(29, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
         gen_op_float_recip1_ps();
@@ -4889,7 +5024,7 @@
         opn = "recip1.ps";
         break;
     case FOP(30, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
         gen_op_float_rsqrt1_ps();
@@ -4898,7 +5033,7 @@
         opn = "rsqrt1.ps";
         break;
     case FOP(31, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
         GEN_LOAD_FREG_FTN(WT2, fd);
@@ -4909,14 +5044,14 @@
         opn = "rsqrt2.ps";
         break;
     case FOP(32, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WTH0, fs);
         gen_op_float_cvts_pu();
         GEN_STORE_FTN_FREG(fd, WT2);
         opn = "cvt.s.pu";
         break;
     case FOP(36, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
         gen_op_float_cvtpw_ps();
@@ -4925,14 +5060,14 @@
         opn = "cvt.pw.ps";
         break;
     case FOP(40, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         gen_op_float_cvts_pl();
         GEN_STORE_FTN_FREG(fd, WT2);
         opn = "cvt.s.pl";
         break;
     case FOP(44, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WT1, ft);
         gen_op_float_pll_ps();
@@ -4940,7 +5075,7 @@
         opn = "pll.ps";
         break;
     case FOP(45, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH1, ft);
         gen_op_float_plu_ps();
@@ -4948,7 +5083,7 @@
         opn = "plu.ps";
         break;
     case FOP(46, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WTH0, fs);
         GEN_LOAD_FREG_FTN(WT1, ft);
         gen_op_float_pul_ps();
@@ -4956,7 +5091,7 @@
         opn = "pul.ps";
         break;
     case FOP(47, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WTH0, fs);
         GEN_LOAD_FREG_FTN(WTH1, ft);
         gen_op_float_puu_ps();
@@ -4979,7 +5114,7 @@
     case FOP(61, 22):
     case FOP(62, 22):
     case FOP(63, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
         GEN_LOAD_FREG_FTN(WT1, ft);
@@ -5011,14 +5146,14 @@
 }
 
 /* Coprocessor 3 (FPU) */
-static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, int fd,
-                           int fs, int base, int index)
+static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
+                           int fd, int fs, int base, int index)
 {
     const char *opn = "extended float load/store";
     int store = 0;
 
     /* All of those work only on 64bit FPUs. */
-    gen_op_cp1_64bitmode();
+    check_cp1_64bitmode(ctx);
     if (base == 0) {
         if (index == 0)
             gen_op_reset_T0();
@@ -5077,13 +5212,13 @@
                regnames[index], regnames[base]);
 }
 
-static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, int fd,
-                            int fr, int fs, int ft)
+static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
+                            int fd, int fr, int fs, int ft)
 {
     const char *opn = "flt3_arith";
 
     /* All of those work only on 64bit FPUs. */
-    gen_op_cp1_64bitmode();
+    check_cp1_64bitmode(ctx);
     switch (opc) {
     case OPC_ALNV_PS:
         GEN_LOAD_REG_TN(T0, fr);
@@ -5323,7 +5458,7 @@
         case OPC_MOVCI:
             if (env->CP0_Config1 & (1 << CP0C1_FP)) {
                 save_cpu_state(ctx, 1);
-                gen_op_cp1_enabled();
+                check_cp1_enabled(ctx);
                 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
                           (ctx->opcode >> 16) & 1);
             } else {
@@ -5337,14 +5472,20 @@
         case OPC_DSRL ... OPC_DSRA:
         case OPC_DSLL32:
         case OPC_DSRL32 ... OPC_DSRA32:
+            if (!(ctx->hflags & MIPS_HFLAG_64))
+                generate_exception(ctx, EXCP_RI);
             gen_arith_imm(ctx, op1, rd, rt, sa);
             break;
         case OPC_DSLLV:
         case OPC_DSRLV ... OPC_DSRAV:
         case OPC_DADD ... OPC_DSUBU:
+            if (!(ctx->hflags & MIPS_HFLAG_64))
+                generate_exception(ctx, EXCP_RI);
             gen_arith(ctx, op1, rd, rs, rt);
             break;
         case OPC_DMULT ... OPC_DDIVU:
+            if (!(ctx->hflags & MIPS_HFLAG_64))
+                generate_exception(ctx, EXCP_RI);
             gen_muldiv(ctx, op1, rs, rt);
             break;
 #endif
@@ -5380,6 +5521,8 @@
             break;
 #ifdef TARGET_MIPS64
         case OPC_DCLZ ... OPC_DCLO:
+            if (!(ctx->hflags & MIPS_HFLAG_64))
+                generate_exception(ctx, EXCP_RI);
             gen_cl(ctx, op1, rd, rs);
             break;
 #endif
@@ -5390,6 +5533,7 @@
         }
         break;
     case OPC_SPECIAL3:
+         check_mips_r2(env, ctx);
          op1 = MASK_SPECIAL3(ctx->opcode);
          switch (op1) {
          case OPC_EXT:
@@ -5451,9 +5595,13 @@
 #ifdef TARGET_MIPS64
         case OPC_DEXTM ... OPC_DEXT:
         case OPC_DINSM ... OPC_DINS:
+            if (!(ctx->hflags & MIPS_HFLAG_64))
+                generate_exception(ctx, EXCP_RI);
             gen_bitops(ctx, op1, rt, rs, sa, rd);
             break;
         case OPC_DBSHFL:
+            if (!(ctx->hflags & MIPS_HFLAG_64))
+                generate_exception(ctx, EXCP_RI);
             op2 = MASK_DBSHFL(ctx->opcode);
             switch (op2) {
             case OPC_DSBH:
@@ -5489,6 +5637,7 @@
             gen_trap(ctx, op1, rs, -1, imm);
             break;
         case OPC_SYNCI:
+            check_mips_r2(env, ctx);
             /* treat as noop */
             break;
         default:            /* Invalid */
@@ -5514,6 +5663,7 @@
             gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
             break;
         case OPC_MFMC0:
+            check_mips_r2(env, ctx);
             op2 = MASK_MFMC0(ctx->opcode);
             switch (op2) {
             case OPC_DI:
@@ -5535,14 +5685,10 @@
             break;
         case OPC_RDPGPR:
         case OPC_WRPGPR:
-            if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) == (1 << CP0C0_AR)) {
-                /* Shadow registers not implemented. */
-                GEN_LOAD_REG_TN(T0, rt);
-                GEN_STORE_TN_REG(rd, T0);
-            } else {
-                MIPS_INVAL("shadow register move");
-                generate_exception(ctx, EXCP_RI);
-            }
+            check_mips_r2(env, ctx);
+            /* Shadow registers not implemented. */
+            GEN_LOAD_REG_TN(T0, rt);
+            GEN_STORE_TN_REG(rd, T0);
             break;
         default:
             MIPS_INVAL("cp0");
@@ -5582,7 +5728,7 @@
     case OPC_SDC1:
         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
             save_cpu_state(ctx, 1);
-            gen_op_cp1_enabled();
+            check_cp1_enabled(ctx);
             gen_flt_ldst(ctx, op, rt, rs, imm);
         } else {
             generate_exception_err(ctx, EXCP_CpU, 1);
@@ -5592,9 +5738,12 @@
     case OPC_CP1:
         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
             save_cpu_state(ctx, 1);
-            gen_op_cp1_enabled();
+            check_cp1_enabled(ctx);
             op1 = MASK_CP1(ctx->opcode);
             switch (op1) {
+            case OPC_MFHC1:
+            case OPC_MTHC1:
+                check_mips_r2(env, ctx);
             case OPC_MFC1:
             case OPC_CFC1:
             case OPC_MTC1:
@@ -5603,8 +5752,6 @@
             case OPC_DMFC1:
             case OPC_DMTC1:
 #endif
-            case OPC_MFHC1:
-            case OPC_MTHC1:
                 gen_cp1(ctx, op1, rt, rd);
                 break;
             case OPC_BC1:
@@ -5644,7 +5791,7 @@
     case OPC_CP3:
         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
             save_cpu_state(ctx, 1);
-            gen_op_cp1_enabled();
+            check_cp1_enabled(ctx);
             op1 = MASK_CP3(ctx->opcode);
             switch (op1) {
             case OPC_LWXC1:
@@ -5692,9 +5839,13 @@
     case OPC_LD:
     case OPC_SCD:
     case OPC_SD:
+        if (!(ctx->hflags & MIPS_HFLAG_64))
+            generate_exception(ctx, EXCP_RI);
         gen_ldst(ctx, op, rt, rs, imm);
         break;
     case OPC_DADDI ... OPC_DADDIU:
+        if (!(ctx->hflags & MIPS_HFLAG_64))
+            generate_exception(ctx, EXCP_RI);
         gen_arith_imm(ctx, op, rt, rs, imm);
         break;
 #endif
@@ -5758,7 +5909,7 @@
 gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
                                 int search_pc)
 {
-    DisasContext ctx, *ctxp = &ctx;
+    DisasContext ctx;
     target_ulong pc_start;
     uint16_t *gen_opc_end;
     int j, lj = -1;
@@ -5799,7 +5950,7 @@
         if (env->nb_breakpoints > 0) {
             for(j = 0; j < env->nb_breakpoints; j++) {
                 if (env->breakpoints[j] == ctx.pc) {
-                    save_cpu_state(ctxp, 1);
+                    save_cpu_state(&ctx, 1);
                     ctx.bstate = BS_BRANCH;
                     gen_op_debug();
                     goto done_generating;
@@ -5833,7 +5984,7 @@
 #endif
     }
     if (env->singlestep_enabled) {
-        save_cpu_state(ctxp, ctx.bstate == BS_NONE);
+        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
         gen_op_debug();
     } else {
 	switch (ctx.bstate) {
@@ -5842,7 +5993,7 @@
             gen_goto_tb(&ctx, 0, ctx.pc);
             break;
         case BS_NONE:
-            save_cpu_state(ctxp, 0);
+            save_cpu_state(&ctx, 0);
             gen_goto_tb(&ctx, 0, ctx.pc);
             break;
         case BS_EXCP:
@@ -5904,7 +6055,7 @@
                     int flags)
 {
     int i;
-    int is_fpu64 = !!(env->CP0_Status & (1 << CP0St_FR));
+    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
 
 #define printfpr(fp)                                                        \
     do {                                                                    \
@@ -5982,7 +6133,6 @@
                      int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
                      int flags)
 {
-    uint32_t c0_status;
     int i;
     
     cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
@@ -5995,13 +6145,11 @@
             cpu_fprintf(f, "\n");
     }
 
-    c0_status = env->CP0_Status;
-
     cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
-                c0_status, env->CP0_Cause, env->CP0_EPC);
+                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
     cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
                 env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
-    if (c0_status & (1 << CP0St_CU1))
+    if (env->hflags & MIPS_HFLAG_FPU)
         fpu_dump_state(env, f, cpu_fprintf, flags);
 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
     cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
@@ -6032,11 +6180,14 @@
         /* If the exception was raised from a delay slot,
          * come back to the jump.  */
         env->CP0_ErrorEPC = env->PC - 4;
-        env->hflags &= ~MIPS_HFLAG_BMASK;
     } else {
         env->CP0_ErrorEPC = env->PC;
     }
+#ifdef TARGET_MIPS64
+    env->hflags = MIPS_HFLAG_64;
+#else
     env->hflags = 0;
+#endif
     env->PC = (int32_t)0xBFC00000;
     env->CP0_Wired = 0;
     /* SMP not implemented */

Modified: trunk/src/host/qemu-neo1973/target-mips/translate_init.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-mips/translate_init.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-mips/translate_init.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -146,9 +146,59 @@
         .SYNCI_Step = 16,
         .CCRes = 2,
         .Status_rw_bitmask = 0x3678FFFF,
-        .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) |
+	/* The R4000 has a full 64bit FPU doesn't use the fcr0 bits. */
+        .CP1_fcr0 = (0x5 << FCR0_PRID) | (0x0 << FCR0_REV),
+    },
+    {
+        .name = "5Kc",
+        .CP0_PRid = 0x00018100,
+        .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AT),
+        .CP0_Config1 = MIPS_CONFIG1 | (31 << CP0C1_MMU) |
+		    (1 << CP0C1_IS) | (4 << CP0C1_IL) | (1 << CP0C1_IA) |
+		    (1 << CP0C1_DS) | (4 << CP0C1_DL) | (1 << CP0C1_DA) |
+		    (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
+        .CP0_Config2 = MIPS_CONFIG2,
+        .CP0_Config3 = MIPS_CONFIG3,
+        .SYNCI_Step = 32,
+        .CCRes = 2,
+        .Status_rw_bitmask = 0x32F8FFFF,
+    },
+    {
+        .name = "5Kf",
+        .CP0_PRid = 0x00018100,
+        .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AT),
+        .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (31 << CP0C1_MMU) |
+		    (1 << CP0C1_IS) | (4 << CP0C1_IL) | (1 << CP0C1_IA) |
+		    (1 << CP0C1_DS) | (4 << CP0C1_DL) | (1 << CP0C1_DA) |
+		    (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
+        .CP0_Config2 = MIPS_CONFIG2,
+        .CP0_Config3 = MIPS_CONFIG3,
+        .SYNCI_Step = 32,
+        .CCRes = 2,
+        .Status_rw_bitmask = 0x36F8FFFF,
+	/* The 5Kf has F64 / L / W but doesn't use the fcr0 bits. */
+        .CP1_fcr0 = (1 << FCR0_D) | (1 << FCR0_S) |
+                    (0x81 << FCR0_PRID) | (0x0 << FCR0_REV),
+    },
+    {
+        .name = "20Kc",
+	/* We emulate a later version of the 20Kc, earlier ones had a broken
+           WAIT instruction. */
+        .CP0_PRid = 0x000182a0,
+        .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AT) | (1 << CP0C0_VI),
+        .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (47 << CP0C1_MMU) |
+		    (2 << CP0C1_IS) | (4 << CP0C1_IL) | (3 << CP0C1_IA) |
+		    (2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) |
+		    (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
+        .CP0_Config2 = MIPS_CONFIG2,
+        .CP0_Config3 = MIPS_CONFIG3,
+        .SYNCI_Step = 32,
+        .CCRes = 2,
+        .Status_rw_bitmask = 0x36FBFFFF,
+	/* The 20Kc has F64 / L / W but doesn't use the fcr0 bits. */
+        .CP1_fcr0 = (1 << FCR0_3D) | (1 << FCR0_PS) |
                     (1 << FCR0_D) | (1 << FCR0_S) |
-                    (0x5 << FCR0_PRID) | (0x0 << FCR0_REV),
+                    (0x82 << FCR0_PRID) | (0x0 << FCR0_REV),
     },
 #endif
 };
@@ -207,12 +257,14 @@
 int cpu_mips_register (CPUMIPSState *env, mips_def_t *def)
 {
     if (!def)
+        def = env->cpu_model;
+    if (!def)
         cpu_abort(env, "Unable to find MIPS CPU definition\n");
+    env->cpu_model = def;
     env->CP0_PRid = def->CP0_PRid;
+    env->CP0_Config0 = def->CP0_Config0;
 #ifdef TARGET_WORDS_BIGENDIAN
-    env->CP0_Config0 = def->CP0_Config0 | (1 << CP0C0_BE);
-#else
-    env->CP0_Config0 = def->CP0_Config0;
+    env->CP0_Config0 |= (1 << CP0C0_BE);
 #endif
     env->CP0_Config1 = def->CP0_Config1;
     env->CP0_Config2 = def->CP0_Config2;
@@ -223,7 +275,16 @@
     env->CCRes = def->CCRes;
     env->Status_rw_bitmask = def->Status_rw_bitmask;
     env->fcr0 = def->CP1_fcr0;
-#ifndef CONFIG_USER_ONLY
+#ifdef CONFIG_USER_ONLY
+    if (env->CP0_Config1 & (1 << CP0C1_FP))
+        env->hflags |= MIPS_HFLAG_FPU;
+    if (env->fcr0 & (1 << FCR0_F64))
+        env->hflags |= MIPS_HFLAG_F64;
+#else
+    /* There are more full-featured MMU variants in older MIPS CPUs,
+       R3000, R6000 and R8000 come to mind. If we ever support them,
+       this check will need to look up a different place than those
+       newfangled config registers. */
     switch ((env->CP0_Config0 >> CP0C0_MT) & 3) {
         case 0:
             no_mmu_init(env, def);
@@ -235,7 +296,6 @@
             fixed_mmu_init(env, def);
             break;
         default:
-            /* Older CPUs like the R3000 may need nonstandard handling here. */
             cpu_abort(env, "MMU type not supported\n");
     }
     env->CP0_Random = env->nb_tlb - 1;

Modified: trunk/src/host/qemu-neo1973/target-ppc/cpu.h
===================================================================
--- trunk/src/host/qemu-neo1973/target-ppc/cpu.h	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-ppc/cpu.h	2007-06-17 16:55:00 UTC (rev 2289)
@@ -899,6 +899,12 @@
 int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, target_ulong *valp);
 int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val);
 
+#define CPUState CPUPPCState
+#define cpu_init cpu_ppc_init
+#define cpu_exec cpu_ppc_exec
+#define cpu_gen_code cpu_ppc_gen_code
+#define cpu_signal_handler cpu_ppc_signal_handler
+
 #include "cpu-all.h"
 
 /*****************************************************************************/

Modified: trunk/src/host/qemu-neo1973/target-ppc/exec.h
===================================================================
--- trunk/src/host/qemu-neo1973/target-ppc/exec.h	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-ppc/exec.h	2007-06-17 16:55:00 UTC (rev 2289)
@@ -122,4 +122,14 @@
 int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
                               int is_user, int is_softmmu);
 
+static inline int cpu_halted(CPUState *env) {
+    if (!env->halted)
+        return 0;
+    if (env->msr[MSR_EE] && (env->interrupt_request & CPU_INTERRUPT_HARD)) {
+        env->halted = 0;
+        return 0;
+    }
+    return EXCP_HALTED;
+}
+
 #endif /* !defined (__PPC_H__) */

Modified: trunk/src/host/qemu-neo1973/target-ppc/op_helper.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-ppc/op_helper.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-ppc/op_helper.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -40,10 +40,6 @@
 
 /*****************************************************************************/
 /* Exceptions processing helpers */
-void cpu_loop_exit (void)
-{
-    longjmp(env->jmp_env, 1);
-}
 
 void do_raise_exception_err (uint32_t exception, int error_code)
 {

Modified: trunk/src/host/qemu-neo1973/target-ppc/translate.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-ppc/translate.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-ppc/translate.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -3026,10 +3026,10 @@
         } else {
             /* Privilege exception */
             if (loglevel != 0) {
-                fprintf(logfile, "Trying to read priviledged spr %d %03x\n",
+                fprintf(logfile, "Trying to read privileged spr %d %03x\n",
                         sprn, sprn);
             }
-            printf("Trying to read priviledged spr %d %03x\n", sprn, sprn);
+            printf("Trying to read privileged spr %d %03x\n", sprn, sprn);
             RET_PRIVREG(ctx);
         }
     } else {
@@ -3132,10 +3132,10 @@
         } else {
             /* Privilege exception */
             if (loglevel != 0) {
-                fprintf(logfile, "Trying to write priviledged spr %d %03x\n",
+                fprintf(logfile, "Trying to write privileged spr %d %03x\n",
                         sprn, sprn);
             }
-            printf("Trying to write priviledged spr %d %03x\n", sprn, sprn);
+            printf("Trying to write privileged spr %d %03x\n", sprn, sprn);
             RET_PRIVREG(ctx);
         }
     } else {
@@ -4019,7 +4019,7 @@
 /* cli */
 GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER)
 {
-    /* Cache line invalidate: priviledged and treated as no-op */
+    /* Cache line invalidate: privileged and treated as no-op */
 #if defined(CONFIG_USER_ONLY)
     RET_PRIVOPC(ctx);
 #else

Modified: trunk/src/host/qemu-neo1973/target-sh4/cpu.h
===================================================================
--- trunk/src/host/qemu-neo1973/target-sh4/cpu.h	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-sh4/cpu.h	2007-06-17 16:55:00 UTC (rev 2289)
@@ -126,6 +126,12 @@
 
 #include "softfloat.h"
 
+#define CPUState CPUSH4State
+#define cpu_init cpu_sh4_init
+#define cpu_exec cpu_sh4_exec
+#define cpu_gen_code cpu_sh4_gen_code
+#define cpu_signal_handler cpu_sh4_signal_handler
+
 #include "cpu-all.h"
 
 /* Memory access type */

Modified: trunk/src/host/qemu-neo1973/target-sh4/op_helper.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-sh4/op_helper.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-sh4/op_helper.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -20,11 +20,6 @@
 #include <assert.h>
 #include "exec.h"
 
-void cpu_loop_exit(void)
-{
-    longjmp(env->jmp_env, 1);
-}
-
 void do_raise_exception(void)
 {
     cpu_loop_exit();

Modified: trunk/src/host/qemu-neo1973/target-sparc/cpu.h
===================================================================
--- trunk/src/host/qemu-neo1973/target-sparc/cpu.h	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-sparc/cpu.h	2007-06-17 16:55:00 UTC (rev 2289)
@@ -13,6 +13,8 @@
 #define TARGET_PAGE_BITS 12 /* XXX */
 #endif
 
+#define TARGET_PHYS_ADDR_BITS 64
+
 #include "cpu-defs.h"
 
 #include "softfloat.h"
@@ -40,6 +42,7 @@
 #define TT_DFAULT   0x09
 #define TT_TOVF     0x0a
 #define TT_EXTINT   0x10
+#define TT_CODE_ACCESS 0x21
 #define TT_DATA_ACCESS 0x29
 #define TT_DIV_ZERO 0x2a
 #define TT_NCP_INSN 0x24
@@ -47,6 +50,7 @@
 #else
 #define TT_TFAULT   0x08
 #define TT_TMISS    0x09
+#define TT_CODE_ACCESS 0x0a
 #define TT_ILL_INSN 0x10
 #define TT_PRIV_INSN 0x11
 #define TT_NFPU_INSN 0x20
@@ -226,10 +230,12 @@
     uint64_t mgregs[8]; /* mmu general registers */
     uint64_t fprs;
     uint64_t tick_cmpr, stick_cmpr;
+    void *tick, *stick;
     uint64_t gsr;
     uint32_t gl; // UA2005
     /* UA 2005 hyperprivileged registers */
     uint64_t hpstate, htstate[MAXTL], hintp, htba, hver, hstick_cmpr, ssr;
+    void *hstick; // UA 2005
 #endif
 #if !defined(TARGET_SPARC64) && !defined(reg_T2)
     target_ulong t2;
@@ -292,7 +298,16 @@
 void raise_exception(int tt);
 void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
                           int is_asi);
+void do_tick_set_count(void *opaque, uint64_t count);
+uint64_t do_tick_get_count(void *opaque);
+void do_tick_set_limit(void *opaque, uint64_t limit);
 
+#define CPUState CPUSPARCState
+#define cpu_init cpu_sparc_init
+#define cpu_exec cpu_sparc_exec
+#define cpu_gen_code cpu_sparc_gen_code
+#define cpu_signal_handler cpu_sparc_signal_handler
+
 #include "cpu-all.h"
 
 #endif

Modified: trunk/src/host/qemu-neo1973/target-sparc/exec.h
===================================================================
--- trunk/src/host/qemu-neo1973/target-sparc/exec.h	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-sparc/exec.h	2007-06-17 16:55:00 UTC (rev 2289)
@@ -115,4 +115,14 @@
 int cpu_sparc_handle_mmu_fault(CPUState *env, target_ulong address, int rw,
                                int is_user, int is_softmmu);
 
+static inline int cpu_halted(CPUState *env) {
+    if (!env->halted)
+        return 0;
+    if ((env->interrupt_request & CPU_INTERRUPT_HARD) && (env->psret != 0)) {
+        env->halted = 0;
+        return 0;
+    }
+    return EXCP_HALTED;
+}
+
 #endif

Modified: trunk/src/host/qemu-neo1973/target-sparc/op.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-sparc/op.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-sparc/op.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -1096,14 +1096,40 @@
 
 void OPPROTO op_rdtick(void)
 {
-    T0 = 0; // XXX read cycle counter and bit 31
+    T0 = do_tick_get_count(env->tick);
 }
 
 void OPPROTO op_wrtick(void)
 {
-    T0 = 0; // XXX write cycle counter and bit 31
+    do_tick_set_count(env->tick, T0);
 }
 
+void OPPROTO op_wrtick_cmpr(void)
+{
+    do_tick_set_limit(env->tick, T0);
+}
+
+void OPPROTO op_rdstick(void)
+{
+    T0 = do_tick_get_count(env->stick);
+}
+
+void OPPROTO op_wrstick(void)
+{
+    do_tick_set_count(env->stick, T0);
+    do_tick_set_count(env->hstick, T0);
+}
+
+void OPPROTO op_wrstick_cmpr(void)
+{
+    do_tick_set_limit(env->stick, T0);
+}
+
+void OPPROTO op_wrhstick_cmpr(void)
+{
+    do_tick_set_limit(env->hstick, T0);
+}
+
 void OPPROTO op_rdtpc(void)
 {
     T0 = env->tpc[env->tl];

Modified: trunk/src/host/qemu-neo1973/target-sparc/op_helper.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-sparc/op_helper.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-sparc/op_helper.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -1111,7 +1111,10 @@
         printf("Unassigned mem access to " TARGET_FMT_plx " from " TARGET_FMT_lx
                "\n", addr, env->pc);
 #endif
-        raise_exception(TT_DATA_ACCESS);
+        if (is_exec)
+            raise_exception(TT_CODE_ACCESS);
+        else
+            raise_exception(TT_DATA_ACCESS);
     }
     env = saved_env;
 }
@@ -1130,6 +1133,34 @@
            addr, env->pc);
     env = saved_env;
 #endif
-    raise_exception(TT_DATA_ACCESS);
+    if (is_exec)
+        raise_exception(TT_CODE_ACCESS);
+    else
+        raise_exception(TT_DATA_ACCESS);
 }
 #endif
+
+#ifdef TARGET_SPARC64
+void do_tick_set_count(void *opaque, uint64_t count)
+{
+#if !defined(CONFIG_USER_ONLY)
+    ptimer_set_count(opaque, -count);
+#endif
+}
+
+uint64_t do_tick_get_count(void *opaque)
+{
+#if !defined(CONFIG_USER_ONLY)
+    return -ptimer_get_count(opaque);
+#else
+    return 0;
+#endif
+}
+
+void do_tick_set_limit(void *opaque, uint64_t limit)
+{
+#if !defined(CONFIG_USER_ONLY)
+    ptimer_set_limit(opaque, -limit, 0);
+#endif
+}
+#endif

Modified: trunk/src/host/qemu-neo1973/target-sparc/translate.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-sparc/translate.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/target-sparc/translate.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -1202,7 +1202,7 @@
                     gen_movl_T0_reg(rd);
                     break;
 		case 0x18: /* System tick */
-                    gen_op_rdtick(); // XXX
+                    gen_op_rdstick();
                     gen_movl_T0_reg(rd);
                     break;
 		case 0x19: /* System tick compare */
@@ -1991,21 +1991,23 @@
 				if (!supervisor(dc))
 				    goto illegal_insn;
 #endif
-				gen_op_movtl_env_T0(offsetof(CPUSPARCState, tick_cmpr));
+                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, tick_cmpr));
+                                gen_op_wrtick_cmpr();
 				break;
 			    case 0x18: /* System tick */
 #if !defined(CONFIG_USER_ONLY)
 				if (!supervisor(dc))
 				    goto illegal_insn;
 #endif
-				gen_op_movtl_env_T0(offsetof(CPUSPARCState, stick_cmpr));
+                                gen_op_wrstick();
 				break;
 			    case 0x19: /* System tick compare */
 #if !defined(CONFIG_USER_ONLY)
 				if (!supervisor(dc))
 				    goto illegal_insn;
 #endif
-				gen_op_movtl_env_T0(offsetof(CPUSPARCState, stick_cmpr));
+                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, stick_cmpr));
+                                gen_op_wrstick_cmpr();
 				break;
 
 			    case 0x10: /* Performance Control */
@@ -2155,7 +2157,8 @@
                                 gen_op_movl_env_T0(offsetof(CPUSPARCState, htba));
                                 break;
                             case 31: // hstick_cmpr
-                                gen_op_movl_env_T0(offsetof(CPUSPARCState, hstick_cmpr));
+                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, hstick_cmpr));
+                                gen_op_wrhstick_cmpr();
                                 break;
                             case 6: // hver readonly
                             default:
@@ -2799,9 +2802,9 @@
 		}
 #endif
 	    }
-	    if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) || \
-		    (xop > 0x17 && xop <= 0x1d ) || \
-		    (xop > 0x2c && xop <= 0x33) || xop == 0x1f) {
+            if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) ||
+                (xop > 0x17 && xop <= 0x1d ) ||
+                (xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) {
 		switch (xop) {
 		case 0x0:	/* load word */
 		    gen_op_ldst(ld);

Modified: trunk/src/host/qemu-neo1973/vl.c
===================================================================
--- trunk/src/host/qemu-neo1973/vl.c	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/vl.c	2007-06-17 16:55:00 UTC (rev 2289)
@@ -153,7 +153,6 @@
 int pit_min_timer_count = 0;
 int nb_nics;
 NICInfo nd_table[MAX_NICS];
-QEMUTimer *gui_timer;
 int vm_running;
 int rtc_utc = 1;
 int cirrus_vga_enabled = 1;
@@ -4198,6 +4197,7 @@
         }
         nd->vlan = vlan;
         nb_nics++;
+        vlan->nb_guest_devs++;
         ret = 0;
     } else
     if (!strcmp(device, "none")) {
@@ -4210,6 +4210,7 @@
         if (get_param_value(buf, sizeof(buf), "hostname", p)) {
             pstrcpy(slirp_hostname, sizeof(slirp_hostname), buf);
         }
+        vlan->nb_host_devs++;
         ret = net_slirp_init(vlan);
     } else
 #endif
@@ -4220,6 +4221,7 @@
             fprintf(stderr, "tap: no interface name\n");
             return -1;
         }
+        vlan->nb_host_devs++;
         ret = tap_win32_init(vlan, ifname);
     } else
 #else
@@ -4227,6 +4229,7 @@
         char ifname[64];
         char setup_script[1024];
         int fd;
+        vlan->nb_host_devs++;
         if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
             fd = strtol(buf, NULL, 0);
             ret = -1;
@@ -4260,6 +4263,7 @@
             fprintf(stderr, "Unknown socket options: %s\n", p);
             return -1;
         }
+        vlan->nb_host_devs++;
     } else
     {
         fprintf(stderr, "Unknown network device: %s\n", device);
@@ -4374,6 +4378,8 @@
         if (nr >= (unsigned int) nb_nics || strcmp(nd_table[nr].model, "usb"))
             return -1;
         dev = usb_net_init(&nd_table[nr]);
+    } else if (!strcmp(devname, "wacom-tablet")) {
+        dev = usb_wacom_init();
     } else {
         return -1;
     }
@@ -4703,32 +4709,6 @@
 }
 
 /***********************************************************/
-/* dumb display */
-
-static void dumb_update(DisplayState *ds, int x, int y, int w, int h)
-{
-}
-
-static void dumb_resize(DisplayState *ds, int w, int h)
-{
-}
-
-static void dumb_refresh(DisplayState *ds)
-{
-    vga_hw_update();
-}
-
-void dumb_display_init(DisplayState *ds)
-{
-    ds->data = NULL;
-    ds->linesize = 0;
-    ds->depth = 0;
-    ds->dpy_update = dumb_update;
-    ds->dpy_resize = dumb_resize;
-    ds->dpy_refresh = dumb_refresh;
-}
-
-/***********************************************************/
 /* I/O handling */
 
 #define MAX_IO_HANDLERS 64
@@ -6406,8 +6386,9 @@
 
 void gui_update(void *opaque)
 {
-    display_state.dpy_refresh(&display_state);
-    qemu_mod_timer(gui_timer, GUI_REFRESH_INTERVAL + qemu_get_clock(rt_clock));
+    DisplayState *ds = opaque;
+    ds->dpy_refresh(ds);
+    qemu_mod_timer(ds->gui_timer, GUI_REFRESH_INTERVAL + qemu_get_clock(rt_clock));
 }
 
 struct vm_change_state_entry {
@@ -7081,7 +7062,7 @@
     { "show-cursor", 0, QEMU_OPTION_show_cursor },
     { "daemonize", 0, QEMU_OPTION_daemonize },
     { "option-rom", HAS_ARG, QEMU_OPTION_option_rom },
-#if defined(TARGET_ARM)
+#if defined(TARGET_ARM) || defined(TARGET_M68K)
     { "semihosting", 0, QEMU_OPTION_semihosting },
 #endif
     { "name", HAS_ARG, QEMU_OPTION_name },
@@ -7184,6 +7165,7 @@
 #elif defined(TARGET_ALPHA)
     /* XXX: TODO */
 #elif defined(TARGET_M68K)
+    qemu_register_machine(&mcf5208evb_machine);
     qemu_register_machine(&an5206_machine);
 #else
 #error unsupported CPU
@@ -7349,6 +7331,7 @@
     int usbgadget_enabled = 0;
     int fds[2];
     const char *pid_file = NULL;
+    VLANState *vlan;
 
     LIST_INIT (&vm_change_state_head);
 #ifndef _WIN32
@@ -7971,6 +7954,18 @@
         if (net_client_init(net_clients[i]) < 0)
             exit(1);
     }
+    for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
+        if (vlan->nb_guest_devs == 0 && vlan->nb_host_devs == 0)
+            continue;
+        if (vlan->nb_guest_devs == 0) {
+            fprintf(stderr, "Invalid vlan (%d) with no nics\n", vlan->id);
+            exit(1);
+        }
+        if (vlan->nb_host_devs == 0)
+            fprintf(stderr,
+                    "Warning: vlan %d is not connected to host network\n",
+                    vlan->id);
+    }
 
 #ifdef TARGET_I386
     if (boot_device == 'n') {
@@ -8101,17 +8096,16 @@
     init_ioports();
 
     /* terminal init */
+    memset(&display_state, 0, sizeof(display_state));
     if (nographic) {
-        dumb_display_init(ds);
+        /* nothing to do */
     } else if (vnc_display != NULL) {
-	vnc_display_init(ds, vnc_display);
+        vnc_display_init(ds, vnc_display);
     } else {
 #if defined(CONFIG_SDL)
         sdl_display_init(ds, full_screen, no_frame);
 #elif defined(CONFIG_COCOA)
         cocoa_display_init(ds, full_screen);
-#else
-        dumb_display_init(ds);
 #endif
     }
 
@@ -8187,8 +8181,10 @@
         }
     }
 
-    gui_timer = qemu_new_timer(rt_clock, gui_update, NULL);
-    qemu_mod_timer(gui_timer, qemu_get_clock(rt_clock));
+    if (display_state.dpy_refresh) {
+        display_state.gui_timer = qemu_new_timer(rt_clock, gui_update, &display_state);
+        qemu_mod_timer(display_state.gui_timer, qemu_get_clock(rt_clock));
+    }
 
 #ifdef CONFIG_GDBSTUB
     if (use_gdbstub) {

Modified: trunk/src/host/qemu-neo1973/vl.h
===================================================================
--- trunk/src/host/qemu-neo1973/vl.h	2007-06-17 08:53:53 UTC (rev 2288)
+++ trunk/src/host/qemu-neo1973/vl.h	2007-06-17 16:55:00 UTC (rev 2289)
@@ -391,6 +391,7 @@
     int id;
     VLANClientState *first_client;
     struct VLANState *next;
+    unsigned int nb_guest_devs, nb_host_devs;
 } VLANState;
 
 VLANState *qemu_find_vlan(int id);
@@ -852,7 +853,7 @@
 PCIBus *pci_pmac_init(qemu_irq *pic);
 
 /* apb_pci.c */
-PCIBus *pci_apb_init(target_ulong special_base, target_ulong mem_base,
+PCIBus *pci_apb_init(target_phys_addr_t special_base, target_phys_addr_t mem_base,
                      qemu_irq *pic);
 
 PCIBus *pci_vpb_init(qemu_irq *pic, int irq, int realview);
@@ -915,6 +916,7 @@
     int width;
     int height;
     void *opaque;
+    QEMUTimer *gui_timer;
 
     void (*dpy_update)(struct DisplayState *s, int x, int y, int w, int h);
     void (*dpy_resize)(struct DisplayState *s, int w, int h);
@@ -984,6 +986,8 @@
                          int secondary_ide_enabled);
 void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn,
                         qemu_irq *pic);
+void pci_piix4_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn,
+                        qemu_irq *pic);
 int pmac_ide_init (BlockDriverState **hd_table, qemu_irq irq);
 
 /* cdrom.c */
@@ -992,7 +996,7 @@
 
 /* ds1225y.c */
 typedef struct ds1225y_t ds1225y_t;
-ds1225y_t *ds1225y_init(target_ulong mem_base, const char *filename);
+ds1225y_t *ds1225y_init(target_phys_addr_t mem_base, const char *filename);
 
 /* es1370.c */
 int es1370_init (PCIBus *bus, AudioState *s);
@@ -1048,8 +1052,7 @@
 /* pcnet.c */
 
 void pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn);
-void pcnet_h_reset(void *opaque);
-void *lance_init(NICInfo *nd, target_phys_addr_t leaddr, void *dma_opaque,
+void lance_init(NICInfo *nd, target_phys_addr_t leaddr, void *dma_opaque,
                  qemu_irq irq);
 
 /* vmmouse.c */
@@ -1058,7 +1061,8 @@
 /* pckbd.c */
 
 void i8042_init(qemu_irq kbd_irq, qemu_irq mouse_irq, uint32_t io_base);
-void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq, target_ulong base, int it_shift);
+void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq,
+                   target_phys_addr_t base, int it_shift);
 
 /* mc146818rtc.c */
 
@@ -1073,7 +1077,7 @@
 
 typedef struct SerialState SerialState;
 SerialState *serial_init(int base, qemu_irq irq, CharDriverState *chr);
-SerialState *serial_mm_init (target_ulong base, int it_shift,
+SerialState *serial_mm_init (target_phys_addr_t base, int it_shift,
                              qemu_irq irq, CharDriverState *chr,
                              int ioregister);
 uint32_t serial_mm_readb (void *opaque, target_phys_addr_t addr);
@@ -1141,7 +1145,7 @@
 
 /* acpi.c */
 extern int acpi_enabled;
-i2c_bus *piix4_pm_init(PCIBus *bus, int devfn);
+i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base);
 void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr);
 void acpi_bios_init(void);
 
@@ -1240,11 +1244,10 @@
               int depth);
 
 /* slavio_intctl.c */
-void pic_set_irq_cpu(void *opaque, int irq, int level, unsigned int cpu);
 void *slavio_intctl_init(target_phys_addr_t addr, target_phys_addr_t addrg,
                          const uint32_t *intbit_to_level,
-                         qemu_irq **irq);
-void slavio_intctl_set_cpu(void *opaque, unsigned int cpu, CPUState *env);
+                         qemu_irq **irq, qemu_irq **cpu_irq,
+                         qemu_irq **parent_irq, unsigned int cputimer);
 void slavio_pic_info(void *opaque);
 void slavio_irq_info(void *opaque);
 
@@ -1257,8 +1260,7 @@
 int load_uboot(const char *filename, target_ulong *ep, int *is_linux);
 
 /* slavio_timer.c */
-void slavio_timer_init(target_phys_addr_t addr, int irq, int mode,
-                       unsigned int cpu, void *intctl);
+void slavio_timer_init(target_phys_addr_t addr, qemu_irq irq, int mode);
 
 /* slavio_serial.c */
 SerialState *slavio_serial_init(target_phys_addr_t base, qemu_irq irq,
@@ -1273,23 +1275,19 @@
 /* esp.c */
 void esp_scsi_attach(void *opaque, BlockDriverState *bd, int id);
 void *esp_init(BlockDriverState **bd, target_phys_addr_t espaddr,
-               void *dma_opaque);
-void esp_reset(void *opaque);
+               void *dma_opaque, qemu_irq irq);
 
 /* sparc32_dma.c */
-void *sparc32_dma_init(target_phys_addr_t daddr, qemu_irq espirq,
-                       qemu_irq leirq, void *iommu);
-void ledma_set_irq(void *opaque, int isr);
+void *sparc32_dma_init(target_phys_addr_t daddr, qemu_irq parent_irq,
+                       void *iommu, qemu_irq **dev_irq);
 void ledma_memory_read(void *opaque, target_phys_addr_t addr, 
                        uint8_t *buf, int len, int do_bswap);
 void ledma_memory_write(void *opaque, target_phys_addr_t addr, 
                         uint8_t *buf, int len, int do_bswap);
-void espdma_raise_irq(void *opaque);
-void espdma_clear_irq(void *opaque);
 void espdma_memory_read(void *opaque, uint8_t *buf, int len);
 void espdma_memory_write(void *opaque, uint8_t *buf, int len);
-void sparc32_dma_set_reset_data(void *opaque, void *esp_opaque,
-                                void *lance_opaque);
+void sparc32_dma_set_reset_data(void *opaque, void (*dev_reset)(void *opaque),
+                                void *dev_opaque);
 
 /* cs4231.c */
 void cs_init(target_phys_addr_t base, int irq, void *intctl);
@@ -1504,9 +1502,9 @@
 extern BlockDriverState *pflash_table[MAX_PFLASH];
 typedef struct pflash_t pflash_t;
 
-pflash_t *pflash_register (target_ulong base, ram_addr_t off,
+pflash_t *pflash_register (target_phys_addr_t base, ram_addr_t off,
                            BlockDriverState *bs,
-                           target_ulong sector_len, int nb_blocs, int width,
+                           uint32_t sector_len, int nb_blocs, int width,
                            uint16_t id0, uint16_t id1, 
                            uint16_t id2, uint16_t id3);
 
@@ -1611,23 +1609,41 @@
 ptimer_state *ptimer_init(QEMUBH *bh);
 void ptimer_set_period(ptimer_state *s, int64_t period);
 void ptimer_set_freq(ptimer_state *s, uint32_t freq);
-void ptimer_set_limit(ptimer_state *s, uint32_t limit, int reload);
-uint32_t ptimer_get_count(ptimer_state *s);
-void ptimer_set_count(ptimer_state *s, uint32_t count);
+void ptimer_set_limit(ptimer_state *s, uint64_t limit, int reload);
+uint64_t ptimer_get_count(ptimer_state *s);
+void ptimer_set_count(ptimer_state *s, uint64_t count);
 void ptimer_run(ptimer_state *s, int oneshot);
 void ptimer_stop(ptimer_state *s);
+void qemu_put_ptimer(QEMUFile *f, ptimer_state *s);
+void qemu_get_ptimer(QEMUFile *f, ptimer_state *s);
 
 #define unlikely(cond)	__builtin_expect(!!(cond), 0)
 
 #include "hw/pxa.h"
 #include "hw/s3c.h"
 
+/* mcf_uart.c */
+uint32_t mcf_uart_read(void *opaque, target_phys_addr_t addr);
+void mcf_uart_write(void *opaque, target_phys_addr_t addr, uint32_t val);
+void *mcf_uart_init(qemu_irq irq, CharDriverState *chr);
+void mcf_uart_mm_init(target_phys_addr_t base, qemu_irq irq,
+                      CharDriverState *chr);
+
+/* mcf_intc.c */
+qemu_irq *mcf_intc_init(target_phys_addr_t base, CPUState *env);
+
+/* mcf_fec.c */
+void mcf_fec_init(NICInfo *nd, target_phys_addr_t base, qemu_irq *irq);
+
 /* mcf5206.c */
 qemu_irq *mcf5206_init(uint32_t base, CPUState *env);
 
 /* an5206.c */
 extern QEMUMachine an5206_machine;
 
+/* mcf5208.c */
+extern QEMUMachine mcf5208evb_machine;
+
 #include "gdbstub.h"
 
 #endif /* defined(QEMU_TOOL) */





More information about the commitlog mailing list