r1950 - in trunk/src/host/qemu-neo1973: . fpu hw target-mips

andrew at sita.openmoko.org andrew at sita.openmoko.org
Sat May 12 16:16:54 CEST 2007


Author: andrew
Date: 2007-05-12 16:16:49 +0200 (Sat, 12 May 2007)
New Revision: 1950

Modified:
   trunk/src/host/qemu-neo1973/exec-all.h
   trunk/src/host/qemu-neo1973/fpu/softfloat-specialize.h
   trunk/src/host/qemu-neo1973/hw/neo1973.c
   trunk/src/host/qemu-neo1973/hw/pxa.h
   trunk/src/host/qemu-neo1973/hw/pxa2xx.c
   trunk/src/host/qemu-neo1973/hw/pxa2xx_lcd.c
   trunk/src/host/qemu-neo1973/hw/s3c.h
   trunk/src/host/qemu-neo1973/hw/s3c2410.c
   trunk/src/host/qemu-neo1973/hw/s3c24xx_gpio.c
   trunk/src/host/qemu-neo1973/hw/s3c24xx_mmci.c
   trunk/src/host/qemu-neo1973/hw/spitz.c
   trunk/src/host/qemu-neo1973/target-mips/op.c
   trunk/src/host/qemu-neo1973/target-mips/translate.c
   trunk/src/host/qemu-neo1973/target-mips/translate_init.c
Log:
Take into account some Bv3 -> Bv4 changes (aim for Bv4 compatibility now).  Make the USBPAD bit verbose.


Modified: trunk/src/host/qemu-neo1973/exec-all.h
===================================================================
--- trunk/src/host/qemu-neo1973/exec-all.h	2007-05-12 11:23:31 UTC (rev 1949)
+++ trunk/src/host/qemu-neo1973/exec-all.h	2007-05-12 14:16:49 UTC (rev 1950)
@@ -476,7 +476,7 @@
 	"1:	li	$1, 1		\n"
 	"	ll	%0, %1		\n"
 	"	sc	$1, %1		\n"
-	"	bnez	$1, 1b		\n"
+	"	beqz	$1, 1b		\n"
 	"	.set pop		"
 	: "=r" (ret), "+R" (*p)
 	:

Modified: trunk/src/host/qemu-neo1973/fpu/softfloat-specialize.h
===================================================================
--- trunk/src/host/qemu-neo1973/fpu/softfloat-specialize.h	2007-05-12 11:23:31 UTC (rev 1949)
+++ trunk/src/host/qemu-neo1973/fpu/softfloat-specialize.h	2007-05-12 14:16:49 UTC (rev 1950)
@@ -61,7 +61,11 @@
 /*----------------------------------------------------------------------------
 | The pattern for a default generated single-precision NaN.
 *----------------------------------------------------------------------------*/
+#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
+#define float32_default_nan 0xFF800000
+#else
 #define float32_default_nan 0xFFC00000
+#endif
 
 /*----------------------------------------------------------------------------
 | Returns 1 if the single-precision floating-point value `a' is a NaN;
@@ -70,9 +74,11 @@
 
 int float32_is_nan( float32 a )
 {
-
-    return ( 0xFF000000 < (bits32) ( a<<1 ) );
-
+#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
+    return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
+#else
+    return ( 0xFF800000 <= (bits32) ( a<<1 ) );
+#endif
 }
 
 /*----------------------------------------------------------------------------
@@ -82,9 +88,11 @@
 
 int float32_is_signaling_nan( float32 a )
 {
-
+#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
+    return ( 0xFF800000 <= (bits32) ( a<<1 ) );
+#else
     return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
-
+#endif
 }
 
 /*----------------------------------------------------------------------------
@@ -131,8 +139,13 @@
     aIsSignalingNaN = float32_is_signaling_nan( a );
     bIsNaN = float32_is_nan( b );
     bIsSignalingNaN = float32_is_signaling_nan( b );
+#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
+    a &= ~0x00400000;
+    b &= ~0x00400000;
+#else
     a |= 0x00400000;
     b |= 0x00400000;
+#endif
     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
     if ( aIsSignalingNaN ) {
         if ( bIsSignalingNaN ) goto returnLargerSignificand;
@@ -154,7 +167,11 @@
 /*----------------------------------------------------------------------------
 | The pattern for a default generated double-precision NaN.
 *----------------------------------------------------------------------------*/
+#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
+#define float64_default_nan LIT64( 0xFFF0000000000000 )
+#else
 #define float64_default_nan LIT64( 0xFFF8000000000000 )
+#endif
 
 /*----------------------------------------------------------------------------
 | Returns 1 if the double-precision floating-point value `a' is a NaN;
@@ -163,9 +180,13 @@
 
 int float64_is_nan( float64 a )
 {
-
-    return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) );
-
+#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
+    return
+           ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
+        && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
+#else
+    return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
+#endif
 }
 
 /*----------------------------------------------------------------------------
@@ -175,11 +196,13 @@
 
 int float64_is_signaling_nan( float64 a )
 {
-
+#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
+    return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
+#else
     return
            ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
         && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
-
+#endif
 }
 
 /*----------------------------------------------------------------------------
@@ -229,8 +252,13 @@
     aIsSignalingNaN = float64_is_signaling_nan( a );
     bIsNaN = float64_is_nan( b );
     bIsSignalingNaN = float64_is_signaling_nan( b );
+#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
+    a &= ~LIT64( 0x0008000000000000 );
+    b &= ~LIT64( 0x0008000000000000 );
+#else
     a |= LIT64( 0x0008000000000000 );
     b |= LIT64( 0x0008000000000000 );
+#endif
     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
     if ( aIsSignalingNaN ) {
         if ( bIsSignalingNaN ) goto returnLargerSignificand;

Modified: trunk/src/host/qemu-neo1973/hw/neo1973.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/neo1973.c	2007-05-12 11:23:31 UTC (rev 1949)
+++ trunk/src/host/qemu-neo1973/hw/neo1973.c	2007-05-12 14:16:49 UTC (rev 1950)
@@ -13,6 +13,8 @@
 #define neo_printf(format, ...)	\
     fprintf(stderr, "%s: " format, __FUNCTION__, ##__VA_ARGS__)
 
+#define GTA01Bv4		1
+
 /* Wiring common to all revisions */
 #define GTA01_GPIO_BACKLIGHT	S3C_GPB(0)
 #define GTA01_GPIO_GPS_PWRON	S3C_GPB(1)
@@ -30,7 +32,7 @@
 #define GTA01_IRQ_nSD_DETECT	S3C_EINT(5)
 #define GTA01_IRQ_911_KEY	S3C_EINT(6)
 #define GTA01_IRQ_HOLD_KEY	S3C_EINT(7)
-#define GTA01_IRQ_PCF50606      S3C_EINT(16)
+#define GTA01_IRQ_PCF50606	S3C_EINT(16)
 
 /* GTA01v3 */
 #define GTA01v3_GPIO_nGSM_EN	S3C_GPG(9)
@@ -54,6 +56,13 @@
 #define GTA01_GPIO_GPS_EN_3V	S3C_GPG(10)
 #define GTA01_GPIO_GPS_RESET	S3C_GPC(0)
 
+/* GTA01Bv4 */
+#define GTA01Bv4_GPIO_nNAND_WP	S3C_GPA(16)
+#define GTA01Bv4_GPIO_VIBRA_ON	S3C_GPB(3)
+#define GTA01Bv4_GPIO_PMU_IRQ	S3C_GPG(1)
+
+#define GTA01Bv4_IRQ_PCF50606	S3C_EINT(9)
+
 struct neo_board_s {
     struct s3c_state_s *cpu;
     i2c_slave *pmu;
@@ -122,7 +131,7 @@
 static void neo_gps_switch(void *opaque, int line, int level)
 {
     neo_printf("GPS %sV supply is now %s.\n",
-#ifdef GTA01Bv3
+#if defined(GTA01Bv3) || defined (GTA01Bv4)
                     line == GTA01_GPIO_GPS_EN_3V3 ? "3.3" : "3.0",
 #else
                     line == GTA01_GPIO_GPS_EN_2V8 ? "2.8" : "3.0",
@@ -146,6 +155,12 @@
 {
 }
 
+static void neo_nand_wp_switch(void *opaque, int line, int level)
+{
+    struct neo_board_s *s = (struct neo_board_s *) opaque;
+    s3c_nand_setwp(s->cpu, level);
+}
+
 /* Hardware keys */
 static void neo_kbd_handler(void *opaque, int keycode)
 {
@@ -169,6 +184,8 @@
 
 static void neo_gpio_setup(struct neo_board_s *s)
 {
+    qemu_irq vib_output = *qemu_allocate_irqs(neo_vib_switch, s, 1);
+
     s3c_gpio_out_set(s->cpu->io, GTA01_GPIO_BACKLIGHT,
                     *qemu_allocate_irqs(neo_bl_switch, s, 1));
     s3c_gpio_out_set(s->cpu->io, GTA01_GPIO_GPS_PWRON,
@@ -179,10 +196,15 @@
                     *qemu_allocate_irqs(neo_modem_switch, s, 1));
     s3c_gpio_out_set(s->cpu->io, GTA01_GPIO_LCD_RESET,
                     *qemu_allocate_irqs(neo_lcd_rst_switch, s, 1));
+#ifdef GTA01Bv4
+    s3c_gpio_out_set(s->cpu->io, GTA01Bv4_GPIO_VIBRA_ON,
+                    vib_output);
+#else
     s3c_gpio_out_set(s->cpu->io, GTA01_GPIO_VIBRATOR_ON,
-                    *qemu_allocate_irqs(neo_vib_switch, s, 1));
+                    vib_output);
     s3c_gpio_out_set(s->cpu->io, GTA01_GPIO_VIBRATOR_ON2,
-                    *qemu_allocate_irqs(neo_vib_switch, s, 1));
+                    vib_output);
+#endif
     s3c_gpio_out_set(s->cpu->io, GTA01v3_GPIO_nGSM_EN,
                     *qemu_allocate_irqs(neo_gsm_switch, s, 1));
     s3c_gpio_out_set(s->cpu->io, GTA01Bv2_GPIO_nGSM_EN,
@@ -197,6 +219,8 @@
                     *qemu_allocate_irqs(neo_gps_switch, s, 1));
     s3c_gpio_out_set(s->cpu->io, GTA01_GPIO_GPS_RESET,
                     *qemu_allocate_irqs(neo_gps_rst_switch, s, 1));
+    s3c_gpio_out_set(s->cpu->io, GTA01Bv4_GPIO_nNAND_WP,
+                    *qemu_allocate_irqs(neo_nand_wp_switch, s, 1));
 
     s3c_timers_cmp_handler_set(s->cpu->timers, 0, neo_bl_intensity, s);
 
@@ -278,7 +302,11 @@
 
     /* Attach a PCF50606 to the bus */
     s->pmu = pcf5060x_init(bus,
+#ifdef GTA01Bv4
+                    s3c_gpio_in_get(s->cpu->io)[GTA01Bv4_IRQ_PCF50606], 0);
+#else
                     s3c_gpio_in_get(s->cpu->io)[GTA01_IRQ_PCF50606], 0);
+#endif
     i2c_set_slave_address(s->pmu, NEO_PMU_ADDR);
 
     /* Attach a LM4857 to the bus */

Modified: trunk/src/host/qemu-neo1973/hw/pxa.h
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pxa.h	2007-05-12 11:23:31 UTC (rev 1949)
+++ trunk/src/host/qemu-neo1973/hw/pxa.h	2007-05-12 14:16:49 UTC (rev 1950)
@@ -59,6 +59,7 @@
 
 # define PXA2XX_SDRAM_BASE	0xa0000000
 # define PXA2XX_INTERNAL_BASE	0x5c000000
+# define PXA2XX_INTERNAL_SIZE	0x40000
 
 /* pxa2xx_pic.c */
 qemu_irq *pxa2xx_pic_init(target_phys_addr_t base, CPUState *env);

Modified: trunk/src/host/qemu-neo1973/hw/pxa2xx.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pxa2xx.c	2007-05-12 11:23:31 UTC (rev 1949)
+++ trunk/src/host/qemu-neo1973/hw/pxa2xx.c	2007-05-12 14:16:49 UTC (rev 1950)
@@ -1854,10 +1854,10 @@
     cpu_arm_set_model(s->env, "pxa255");
 
     /* SDRAM & Internal Memory Storage */
-    cpu_register_physical_memory(PXA2XX_SDRAM_BASE,
-                    sdram_size, qemu_ram_alloc(sdram_size) | IO_MEM_RAM);
-    cpu_register_physical_memory(PXA2XX_INTERNAL_BASE,
-                    0x40000, qemu_ram_alloc(0x40000) | IO_MEM_RAM);
+    cpu_register_physical_memory(PXA2XX_SDRAM_BASE, sdram_size,
+                    qemu_ram_alloc(sdram_size) | IO_MEM_RAM);
+    cpu_register_physical_memory(PXA2XX_INTERNAL_BASE, PXA2XX_INTERNAL_SIZE,
+                    qemu_ram_alloc(PXA2XX_INTERNAL_SIZE) | IO_MEM_RAM);
 
     s->pic = pxa2xx_pic_init(0x40d00000, s->env);
 

Modified: trunk/src/host/qemu-neo1973/hw/pxa2xx_lcd.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pxa2xx_lcd.c	2007-05-12 11:23:31 UTC (rev 1949)
+++ trunk/src/host/qemu-neo1973/hw/pxa2xx_lcd.c	2007-05-12 14:16:49 UTC (rev 1950)
@@ -737,8 +737,7 @@
                             dest, src, s->xres, s->dest_width);
             if (addr < start)
                 start = addr;
-            if (new_addr > end)
-                end = new_addr;
+            end = new_addr;
             if (y < *miny)
                 *miny = y;
             if (y >= *maxy)

Modified: trunk/src/host/qemu-neo1973/hw/s3c.h
===================================================================
--- trunk/src/host/qemu-neo1973/hw/s3c.h	2007-05-12 11:23:31 UTC (rev 1949)
+++ trunk/src/host/qemu-neo1973/hw/s3c.h	2007-05-12 14:16:49 UTC (rev 1950)
@@ -204,6 +204,7 @@
     uint8_t nfcmd;
     uint8_t nfaddr;
     struct ecc_state_s nfecc;
+    int nfwp;
 
     /* Clock & power management */
     target_phys_addr_t clkpwr_base;
@@ -214,6 +215,7 @@
 void s3c2410_reset(struct s3c_state_s *s);
 struct s3c_state_s *s3c2410_init(unsigned int sdram_size, DisplayState *ds);
 void s3c_nand_register(struct s3c_state_s *s, struct nand_flash_s *chip);
+void s3c_nand_setwp(struct s3c_state_s *s, int wp);
 
 struct s3c_i2s_state_s { /* XXX move to .c */
     target_phys_addr_t base;

Modified: trunk/src/host/qemu-neo1973/hw/s3c2410.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/s3c2410.c	2007-05-12 11:23:31 UTC (rev 1949)
+++ trunk/src/host/qemu-neo1973/hw/s3c2410.c	2007-05-12 14:16:49 UTC (rev 1950)
@@ -414,17 +414,17 @@
     case S3C_NFCMD:
         s->nfcmd = value & 0xff;
         if (s->nfconf & (1 << 15)) {
-            nand_setpins(s->nand, 1, 0, (s->nfconf >> 11) & 1, 1, 0);
+            nand_setpins(s->nand, 1, 0, (s->nfconf >> 11) & 1, s->nfwp, 0);
             nand_setio(s->nand, s->nfcmd);
-            nand_setpins(s->nand, 0, 0, (s->nfconf >> 11) & 1, 1, 0);
+            nand_setpins(s->nand, 0, 0, (s->nfconf >> 11) & 1, s->nfwp, 0);
         }
         break;
     case S3C_NFADDR:
         s->nfaddr = value & 0xff;
         if (s->nfconf & (1 << 15)) {
-            nand_setpins(s->nand, 0, 1, (s->nfconf >> 11) & 1, 1, 0);
+            nand_setpins(s->nand, 0, 1, (s->nfconf >> 11) & 1, s->nfwp, 0);
             nand_setio(s->nand, s->nfaddr);
-            nand_setpins(s->nand, 0, 0, (s->nfconf >> 11) & 1, 1, 0);
+            nand_setpins(s->nand, 0, 0, (s->nfconf >> 11) & 1, s->nfwp, 0);
         }
         break;
     case S3C_NFDATA:
@@ -441,6 +441,11 @@
     s->nand = chip;
 }
 
+void s3c_nand_setwp(struct s3c_state_s *s, int wp)
+{
+    s->nfwp = wp;
+}
+
 static CPUReadMemoryFunc *s3c_nand_readfn[] = {
     s3c_nand_read,
     s3c_nand_read,
@@ -2273,6 +2278,8 @@
         usb_ohci_init_memio(0x49000000, 3, -1, s->irq[S3C_PIC_USBH]);
     }
 
+    s3c_nand_setwp(s, 1);
+
     /* Power on reset */
     s3c_gpio_setpwrstat(s->io, 1);
     return s;

Modified: trunk/src/host/qemu-neo1973/hw/s3c24xx_gpio.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/s3c24xx_gpio.c	2007-05-12 11:23:31 UTC (rev 1949)
+++ trunk/src/host/qemu-neo1973/hw/s3c24xx_gpio.c	2007-05-12 14:16:49 UTC (rev 1950)
@@ -244,9 +244,12 @@
         s->inform[1] = value;
         break;
     case S3C_MISCCR:
+        if (value & (1 << 16))				/* nRSTCON */
+            printf("%s: software reset.\n", __FUNCTION__);
+        if ((value ^ s->misccr) & (1 << 3))		/* USBPAD */
+            printf("%s: now in USB %s mode.\n", __FUNCTION__,
+                            (value >> 3) & 1 ? "host" : "slave");
         s->misccr = value & 0x000f377b;
-        if (value & (1 << 16))
-            printf("%s: software reset.\n", __FUNCTION__);
         break;
     case S3C_DCLKCON:
         s->dclkcon = value & 0x0ff30ff3;

Modified: trunk/src/host/qemu-neo1973/hw/s3c24xx_mmci.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/s3c24xx_mmci.c	2007-05-12 11:23:31 UTC (rev 1949)
+++ trunk/src/host/qemu-neo1973/hw/s3c24xx_mmci.c	2007-05-12 14:16:49 UTC (rev 1950)
@@ -152,7 +152,7 @@
     }
 
     for (i = 0; i < rsplen; i ++)
-        s->resp[i >> 2] |= response[i] << ((i & 3) << 3);
+        s->resp[i >> 2] |= response[i] << ((~i & 3) << 3);
 
     s->cstatus |= 1 << 9;					/* RspFin */
     if (s->mask & (1 << 14))					/* RspEnd */

Modified: trunk/src/host/qemu-neo1973/hw/spitz.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/spitz.c	2007-05-12 11:23:31 UTC (rev 1949)
+++ trunk/src/host/qemu-neo1973/hw/spitz.c	2007-05-12 14:16:49 UTC (rev 1950)
@@ -1053,9 +1053,9 @@
         cpu_model = (model == terrier) ? "pxa270-c5" : "pxa270-c0";
 
     /* Setup CPU & memory */
-    if (ram_size < spitz_ram + spitz_rom) {
+    if (ram_size < spitz_ram + spitz_rom + PXA2XX_INTERNAL_SIZE) {
         fprintf(stderr, "This platform requires %i bytes of memory\n",
-                        spitz_ram + spitz_rom);
+                        spitz_ram + spitz_rom + PXA2XX_INTERNAL_SIZE);
         exit(1);
     }
     cpu = pxa270_init(spitz_ram, ds, cpu_model);

Modified: trunk/src/host/qemu-neo1973/target-mips/op.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-mips/op.c	2007-05-12 11:23:31 UTC (rev 1949)
+++ trunk/src/host/qemu-neo1973/target-mips/op.c	2007-05-12 14:16:49 UTC (rev 1950)
@@ -1965,6 +1965,9 @@
     set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
     DT2 = float64_round_to_int(FDT0, &env->fp_status);
     RESTORE_ROUNDING_MODE;
+    update_fcr31();
+    if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
+        DT2 = 0x7fffffffffffffffULL;
     DEBUG_FPU_STATE();
     RETURN();
 }
@@ -1973,6 +1976,9 @@
     set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
     DT2 = float32_round_to_int(FST0, &env->fp_status);
     RESTORE_ROUNDING_MODE;
+    update_fcr31();
+    if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
+        DT2 = 0x7fffffffffffffffULL;
     DEBUG_FPU_STATE();
     RETURN();
 }
@@ -1981,6 +1987,9 @@
     set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
     WT2 = float64_round_to_int(FDT0, &env->fp_status);
     RESTORE_ROUNDING_MODE;
+    update_fcr31();
+    if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
+        WT2 = 0x7fffffff;
     DEBUG_FPU_STATE();
     RETURN();
 }
@@ -1989,6 +1998,9 @@
     set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
     WT2 = float32_round_to_int(FST0, &env->fp_status);
     RESTORE_ROUNDING_MODE;
+    update_fcr31();
+    if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
+        WT2 = 0x7fffffff;
     DEBUG_FPU_STATE();
     RETURN();
 }
@@ -1996,24 +2008,36 @@
 FLOAT_OP(truncl, d)
 {
     DT2 = float64_to_int64_round_to_zero(FDT0, &env->fp_status);
+    update_fcr31();
+    if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
+        DT2 = 0x7fffffffffffffffULL;
     DEBUG_FPU_STATE();
     RETURN();
 }
 FLOAT_OP(truncl, s)
 {
     DT2 = float32_to_int64_round_to_zero(FST0, &env->fp_status);
+    update_fcr31();
+    if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
+        DT2 = 0x7fffffffffffffffULL;
     DEBUG_FPU_STATE();
     RETURN();
 }
 FLOAT_OP(truncw, d)
 {
     WT2 = float64_to_int32_round_to_zero(FDT0, &env->fp_status);
+    update_fcr31();
+    if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
+        WT2 = 0x7fffffff;
     DEBUG_FPU_STATE();
     RETURN();
 }
 FLOAT_OP(truncw, s)
 {
     WT2 = float32_to_int32_round_to_zero(FST0, &env->fp_status);
+    update_fcr31();
+    if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
+        WT2 = 0x7fffffff;
     DEBUG_FPU_STATE();
     RETURN();
 }
@@ -2023,6 +2047,9 @@
     set_float_rounding_mode(float_round_up, &env->fp_status);
     DT2 = float64_round_to_int(FDT0, &env->fp_status);
     RESTORE_ROUNDING_MODE;
+    update_fcr31();
+    if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
+        DT2 = 0x7fffffffffffffffULL;
     DEBUG_FPU_STATE();
     RETURN();
 }
@@ -2031,6 +2058,9 @@
     set_float_rounding_mode(float_round_up, &env->fp_status);
     DT2 = float32_round_to_int(FST0, &env->fp_status);
     RESTORE_ROUNDING_MODE;
+    update_fcr31();
+    if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
+        DT2 = 0x7fffffffffffffffULL;
     DEBUG_FPU_STATE();
     RETURN();
 }
@@ -2039,6 +2069,9 @@
     set_float_rounding_mode(float_round_up, &env->fp_status);
     WT2 = float64_round_to_int(FDT0, &env->fp_status);
     RESTORE_ROUNDING_MODE;
+    update_fcr31();
+    if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
+        WT2 = 0x7fffffff;
     DEBUG_FPU_STATE();
     RETURN();
 }
@@ -2047,6 +2080,9 @@
     set_float_rounding_mode(float_round_up, &env->fp_status);
     WT2 = float32_round_to_int(FST0, &env->fp_status);
     RESTORE_ROUNDING_MODE;
+    update_fcr31();
+    if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
+        WT2 = 0x7fffffff;
     DEBUG_FPU_STATE();
     RETURN();
 }
@@ -2056,6 +2092,9 @@
     set_float_rounding_mode(float_round_down, &env->fp_status);
     DT2 = float64_round_to_int(FDT0, &env->fp_status);
     RESTORE_ROUNDING_MODE;
+    update_fcr31();
+    if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
+        DT2 = 0x7fffffffffffffffULL;
     DEBUG_FPU_STATE();
     RETURN();
 }
@@ -2064,6 +2103,9 @@
     set_float_rounding_mode(float_round_down, &env->fp_status);
     DT2 = float32_round_to_int(FST0, &env->fp_status);
     RESTORE_ROUNDING_MODE;
+    update_fcr31();
+    if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
+        DT2 = 0x7fffffffffffffffULL;
     DEBUG_FPU_STATE();
     RETURN();
 }
@@ -2072,6 +2114,9 @@
     set_float_rounding_mode(float_round_down, &env->fp_status);
     WT2 = float64_round_to_int(FDT0, &env->fp_status);
     RESTORE_ROUNDING_MODE;
+    update_fcr31();
+    if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
+        WT2 = 0x7fffffff;
     DEBUG_FPU_STATE();
     RETURN();
 }
@@ -2080,6 +2125,9 @@
     set_float_rounding_mode(float_round_down, &env->fp_status);
     WT2 = float32_round_to_int(FST0, &env->fp_status);
     RESTORE_ROUNDING_MODE;
+    update_fcr31();
+    if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
+        WT2 = 0x7fffffff;
     DEBUG_FPU_STATE();
     RETURN();
 }
@@ -2185,6 +2233,7 @@
     FDT2 = float64_ ## name (FDT0, FDT1, &env->fp_status);    \
     update_fcr31();       \
     DEBUG_FPU_STATE();    \
+    RETURN();             \
 }                         \
 FLOAT_OP(name, s)         \
 {                         \
@@ -2192,6 +2241,7 @@
     FST2 = float32_ ## name (FST0, FST1, &env->fp_status);    \
     update_fcr31();       \
     DEBUG_FPU_STATE();    \
+    RETURN();             \
 }                         \
 FLOAT_OP(name, ps)        \
 {                         \
@@ -2200,6 +2250,7 @@
     FSTH2 = float32_ ## name (FSTH0, FSTH1, &env->fp_status); \
     update_fcr31();       \
     DEBUG_FPU_STATE();    \
+    RETURN();             \
 }
 FLOAT_BINOP(add)
 FLOAT_BINOP(sub)
@@ -2207,6 +2258,16 @@
 FLOAT_BINOP(div)
 #undef FLOAT_BINOP
 
+FLOAT_OP(addr, ps)
+{
+    set_float_exception_flags(0, &env->fp_status);
+    FST2 = float32_add (FST0, FSTH0, &env->fp_status);
+    FSTH2 = float32_add (FST1, FSTH1, &env->fp_status);
+    update_fcr31();
+    DEBUG_FPU_STATE();
+    RETURN();
+}
+
 /* ternary operations */
 #define FLOAT_TERNOP(name1, name2) \
 FLOAT_OP(name1 ## name2, d)        \
@@ -2214,12 +2275,14 @@
     FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fp_status);    \
     FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fp_status);    \
     DEBUG_FPU_STATE();             \
+    RETURN();                      \
 }                                  \
 FLOAT_OP(name1 ## name2, s)        \
 {                                  \
     FST0 = float32_ ## name1 (FST0, FST1, &env->fp_status);    \
     FST2 = float32_ ## name2 (FST0, FST2, &env->fp_status);    \
     DEBUG_FPU_STATE();             \
+    RETURN();                      \
 }                                  \
 FLOAT_OP(name1 ## name2, ps)       \
 {                                  \
@@ -2228,28 +2291,65 @@
     FST2 = float32_ ## name2 (FST0, FST2, &env->fp_status);    \
     FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fp_status); \
     DEBUG_FPU_STATE();             \
+    RETURN();                      \
 }
 FLOAT_TERNOP(mul, add)
 FLOAT_TERNOP(mul, sub)
 #undef FLOAT_TERNOP
 
+/* negated ternary operations */
+#define FLOAT_NTERNOP(name1, name2) \
+FLOAT_OP(n ## name1 ## name2, d)    \
+{                                   \
+    FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fp_status);    \
+    FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fp_status);    \
+    FDT2 ^= 1ULL << 63;             \
+    DEBUG_FPU_STATE();              \
+    RETURN();                       \
+}                                   \
+FLOAT_OP(n ## name1 ## name2, s)    \
+{                                   \
+    FST0 = float32_ ## name1 (FST0, FST1, &env->fp_status);    \
+    FST2 = float32_ ## name2 (FST0, FST2, &env->fp_status);    \
+    FST2 ^= 1 << 31;                \
+    DEBUG_FPU_STATE();              \
+    RETURN();                       \
+}                                   \
+FLOAT_OP(n ## name1 ## name2, ps)   \
+{                                   \
+    FST0 = float32_ ## name1 (FST0, FST1, &env->fp_status);    \
+    FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fp_status); \
+    FST2 = float32_ ## name2 (FST0, FST2, &env->fp_status);    \
+    FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fp_status); \
+    FST2 ^= 1 << 31;                \
+    FSTH2 ^= 1 << 31;               \
+    DEBUG_FPU_STATE();              \
+    RETURN();                       \
+}
+FLOAT_NTERNOP(mul, add)
+FLOAT_NTERNOP(mul, sub)
+#undef FLOAT_NTERNOP
+
 /* unary operations, modifying fp status  */
 #define FLOAT_UNOP(name)  \
 FLOAT_OP(name, d)         \
 {                         \
     FDT2 = float64_ ## name(FDT0, &env->fp_status);   \
     DEBUG_FPU_STATE();    \
+    RETURN();                      \
 }                         \
 FLOAT_OP(name, s)         \
 {                         \
     FST2 = float32_ ## name(FST0, &env->fp_status);   \
     DEBUG_FPU_STATE();    \
+    RETURN();                      \
 }                         \
 FLOAT_OP(name, ps)        \
 {                         \
     FST2 = float32_ ## name(FST0, &env->fp_status);   \
     FSTH2 = float32_ ## name(FSTH0, &env->fp_status); \
     DEBUG_FPU_STATE();    \
+    RETURN();                      \
 }
 FLOAT_UNOP(sqrt)
 #undef FLOAT_UNOP
@@ -2260,17 +2360,20 @@
 {                         \
     FDT2 = float64_ ## name(FDT0);   \
     DEBUG_FPU_STATE();    \
+    RETURN();             \
 }                         \
 FLOAT_OP(name, s)         \
 {                         \
     FST2 = float32_ ## name(FST0);   \
     DEBUG_FPU_STATE();    \
+    RETURN();             \
 }                         \
 FLOAT_OP(name, ps)        \
 {                         \
     FST2 = float32_ ## name(FST0);   \
     FSTH2 = float32_ ## name(FSTH0); \
     DEBUG_FPU_STATE();    \
+    RETURN();             \
 }
 FLOAT_UNOP(abs)
 FLOAT_UNOP(chs)
@@ -2341,6 +2444,20 @@
         CLEAR_FP_COND(PARAM1, env);            \
     DEBUG_FPU_STATE();                         \
     RETURN();                                  \
+}                                              \
+void op_cmpabs_d_ ## op (void)                 \
+{                                              \
+    int c;                                     \
+    FDT0 &= ~(1ULL << 63);                     \
+    FDT1 &= ~(1ULL << 63);                     \
+    c = cond;                                  \
+    update_fcr31();                            \
+    if (c)                                     \
+        SET_FP_COND(PARAM1, env);              \
+    else                                       \
+        CLEAR_FP_COND(PARAM1, env);            \
+    DEBUG_FPU_STATE();                         \
+    RETURN();                                  \
 }
 
 int float64_is_unordered(int sig, float64 a, float64 b STATUS_PARAM)
@@ -2389,6 +2506,20 @@
         CLEAR_FP_COND(PARAM1, env);            \
     DEBUG_FPU_STATE();                         \
     RETURN();                                  \
+}                                              \
+void op_cmpabs_s_ ## op (void)                 \
+{                                              \
+    int c;                                     \
+    FST0 &= ~(1 << 31);                        \
+    FST1 &= ~(1 << 31);                        \
+    c = cond;                                  \
+    update_fcr31();                            \
+    if (c)                                     \
+        SET_FP_COND(PARAM1, env);              \
+    else                                       \
+        CLEAR_FP_COND(PARAM1, env);            \
+    DEBUG_FPU_STATE();                         \
+    RETURN();                                  \
 }
 
 flag float32_is_unordered(int sig, float32 a, float32 b STATUS_PARAM)
@@ -2443,6 +2574,27 @@
         CLEAR_FP_COND(PARAM1 + 1, env);        \
     DEBUG_FPU_STATE();                         \
     RETURN();                                  \
+}                                              \
+void op_cmpabs_ps_ ## op (void)                \
+{                                              \
+    int cl, ch;                                \
+    FST0 &= ~(1 << 31);                        \
+    FSTH0 &= ~(1 << 31);                       \
+    FST1 &= ~(1 << 31);                        \
+    FSTH1 &= ~(1 << 31);                       \
+    cl = condl;                                \
+    ch = condh;                                \
+    update_fcr31();                            \
+    if (cl)                                    \
+        SET_FP_COND(PARAM1, env);              \
+    else                                       \
+        CLEAR_FP_COND(PARAM1, env);            \
+    if (ch)                                    \
+        SET_FP_COND(PARAM1 + 1, env);          \
+    else                                       \
+        CLEAR_FP_COND(PARAM1 + 1, env);        \
+    DEBUG_FPU_STATE();                         \
+    RETURN();                                  \
 }
 
 /* NOTE: the comma operator will make "cond" to eval to false,

Modified: trunk/src/host/qemu-neo1973/target-mips/translate.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-mips/translate.c	2007-05-12 11:23:31 UTC (rev 1949)
+++ trunk/src/host/qemu-neo1973/target-mips/translate.c	2007-05-12 14:16:49 UTC (rev 1950)
@@ -402,7 +402,7 @@
     OPC_MSUB_D  = 0x29 | OPC_CP3,
     OPC_MSUB_PS = 0x2E | OPC_CP3,
     OPC_NMADD_S = 0x30 | OPC_CP3,
-    OPC_NMADD_D = 0x32 | OPC_CP3,
+    OPC_NMADD_D = 0x31 | OPC_CP3,
     OPC_NMADD_PS= 0x36 | OPC_CP3,
     OPC_NMSUB_S = 0x38 | OPC_CP3,
     OPC_NMSUB_D = 0x39 | OPC_CP3,
@@ -490,33 +490,36 @@
 FGEN32(gen_op_load_fpr_WTH2,  gen_op_load_fpr_WTH2_fpr);
 FGEN32(gen_op_store_fpr_WTH2, gen_op_store_fpr_WTH2_fpr);
 
-#define FOP_CONDS(fmt) \
-static GenOpFunc1 * cond_ ## fmt ## _table[16] = {                      \
-    gen_op_cmp_ ## fmt ## _f,                                           \
-    gen_op_cmp_ ## fmt ## _un,                                          \
-    gen_op_cmp_ ## fmt ## _eq,                                          \
-    gen_op_cmp_ ## fmt ## _ueq,                                         \
-    gen_op_cmp_ ## fmt ## _olt,                                         \
-    gen_op_cmp_ ## fmt ## _ult,                                         \
-    gen_op_cmp_ ## fmt ## _ole,                                         \
-    gen_op_cmp_ ## fmt ## _ule,                                         \
-    gen_op_cmp_ ## fmt ## _sf,                                          \
-    gen_op_cmp_ ## fmt ## _ngle,                                        \
-    gen_op_cmp_ ## fmt ## _seq,                                         \
-    gen_op_cmp_ ## fmt ## _ngl,                                         \
-    gen_op_cmp_ ## fmt ## _lt,                                          \
-    gen_op_cmp_ ## fmt ## _nge,                                         \
-    gen_op_cmp_ ## fmt ## _le,                                          \
-    gen_op_cmp_ ## fmt ## _ngt,                                         \
+#define FOP_CONDS(type, fmt)                                            \
+static GenOpFunc1 * cond ## type ## _ ## fmt ## _table[16] = {          \
+    gen_op_cmp ## type ## _ ## fmt ## _f,                               \
+    gen_op_cmp ## type ## _ ## fmt ## _un,                              \
+    gen_op_cmp ## type ## _ ## fmt ## _eq,                              \
+    gen_op_cmp ## type ## _ ## fmt ## _ueq,                             \
+    gen_op_cmp ## type ## _ ## fmt ## _olt,                             \
+    gen_op_cmp ## type ## _ ## fmt ## _ult,                             \
+    gen_op_cmp ## type ## _ ## fmt ## _ole,                             \
+    gen_op_cmp ## type ## _ ## fmt ## _ule,                             \
+    gen_op_cmp ## type ## _ ## fmt ## _sf,                              \
+    gen_op_cmp ## type ## _ ## fmt ## _ngle,                            \
+    gen_op_cmp ## type ## _ ## fmt ## _seq,                             \
+    gen_op_cmp ## type ## _ ## fmt ## _ngl,                             \
+    gen_op_cmp ## type ## _ ## fmt ## _lt,                              \
+    gen_op_cmp ## type ## _ ## fmt ## _nge,                             \
+    gen_op_cmp ## type ## _ ## fmt ## _le,                              \
+    gen_op_cmp ## type ## _ ## fmt ## _ngt,                             \
 };                                                                      \
-static inline void gen_cmp_ ## fmt(int n, long cc)                      \
+static inline void gen_cmp ## type ## _ ## fmt(int n, long cc)          \
 {                                                                       \
-    cond_ ## fmt ## _table[n](cc);                                      \
+    cond ## type ## _ ## fmt ## _table[n](cc);                          \
 }
 
-FOP_CONDS(d)
-FOP_CONDS(s)
-FOP_CONDS(ps)
+FOP_CONDS(, d)
+FOP_CONDS(abs, d)
+FOP_CONDS(, s)
+FOP_CONDS(abs, s)
+FOP_CONDS(, ps)
+FOP_CONDS(abs, ps)
 
 typedef struct DisasContext {
     struct TranslationBlock *tb;
@@ -540,7 +543,7 @@
     BS_EXCP     = 3, /* We reached an exception condition */
 };
 
-#if defined MIPS_DEBUG_DISAS
+#ifdef MIPS_DEBUG_DISAS
 #define MIPS_DEBUG(fmt, args...)                                              \
 do {                                                                          \
     if (loglevel & CPU_LOG_TB_IN_ASM) {                                       \
@@ -710,7 +713,7 @@
 static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
                       int base, int16_t offset)
 {
-    const char *opn = "unk";
+    const char *opn = "ldst";
 
     if (base == 0) {
         GEN_LOAD_IMM_TN(T0, offset);
@@ -745,6 +748,7 @@
         save_cpu_state(ctx, 1);
         GEN_LOAD_REG_TN(T1, rt);
         op_ldst(scd);
+        GEN_STORE_TN_REG(rt, T0);
         opn = "scd";
         break;
     case OPC_LDL:
@@ -848,7 +852,7 @@
         opn = "sc";
         break;
     default:
-        MIPS_INVAL("load/store");
+        MIPS_INVAL(opn);
         generate_exception(ctx, EXCP_RI);
         return;
     }
@@ -859,7 +863,7 @@
 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
                       int base, int16_t offset)
 {
-    const char *opn = "unk";
+    const char *opn = "flt_ldst";
 
     if (base == 0) {
         GEN_LOAD_IMM_TN(T0, offset);
@@ -895,7 +899,7 @@
         opn = "sdc1";
         break;
     default:
-        MIPS_INVAL("float load/store");
+        MIPS_INVAL(opn);
         generate_exception(ctx, EXCP_RI);
         return;
     }
@@ -907,7 +911,7 @@
                            int rs, int16_t imm)
 {
     uint32_t uimm;
-    const char *opn = "unk";
+    const char *opn = "imm arith";
 
     if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
         /* if no destination, treat it as a NOP 
@@ -1072,7 +1076,7 @@
         break;
 #endif
     default:
-        MIPS_INVAL("imm arith");
+        MIPS_INVAL(opn);
         generate_exception(ctx, EXCP_RI);
         return;
     }
@@ -1084,7 +1088,7 @@
 static void gen_arith (DisasContext *ctx, uint32_t opc,
                        int rd, int rs, int rt)
 {
-    const char *opn = "unk";
+    const char *opn = "arith";
 
     if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
        && opc != OPC_DADD && opc != OPC_DSUB) {
@@ -1222,7 +1226,7 @@
         break;
 #endif
     default:
-        MIPS_INVAL("arith");
+        MIPS_INVAL(opn);
         generate_exception(ctx, EXCP_RI);
         return;
     }
@@ -1234,7 +1238,7 @@
 /* Arithmetic on HI/LO registers */
 static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
 {
-    const char *opn = "unk";
+    const char *opn = "hilo";
 
     if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
         /* Treat as a NOP */
@@ -1263,7 +1267,7 @@
         opn = "mtlo";
         break;
     default:
-        MIPS_INVAL("HILO");
+        MIPS_INVAL(opn);
         generate_exception(ctx, EXCP_RI);
         return;
     }
@@ -1273,7 +1277,7 @@
 static void gen_muldiv (DisasContext *ctx, uint32_t opc,
                         int rs, int rt)
 {
-    const char *opn = "unk";
+    const char *opn = "mul/div";
 
     GEN_LOAD_REG_TN(T0, rs);
     GEN_LOAD_REG_TN(T1, rt);
@@ -1329,7 +1333,7 @@
         opn = "msubu";
         break;
     default:
-        MIPS_INVAL("mul/div");
+        MIPS_INVAL(opn);
         generate_exception(ctx, EXCP_RI);
         return;
     }
@@ -1339,7 +1343,7 @@
 static void gen_cl (DisasContext *ctx, uint32_t opc,
                     int rd, int rs)
 {
-    const char *opn = "unk";
+    const char *opn = "CLx";
     if (rd == 0) {
         /* Treat as a NOP */
         MIPS_DEBUG("NOP");
@@ -1366,7 +1370,7 @@
         break;
 #endif
     default:
-        MIPS_INVAL("CLx");
+        MIPS_INVAL(opn);
         generate_exception(ctx, EXCP_RI);
         return;
     }
@@ -1430,7 +1434,7 @@
             /* Never trap: treat as NOP */
             return;
         default:
-            MIPS_INVAL("TRAP");
+            MIPS_INVAL("trap");
             generate_exception(ctx, EXCP_RI);
             return;
         }
@@ -1461,7 +1465,7 @@
             gen_op_ne();
             break;
         default:
-            MIPS_INVAL("TRAP");
+            MIPS_INVAL("trap");
             generate_exception(ctx, EXCP_RI);
             return;
         }
@@ -1498,12 +1502,13 @@
     int bcond = 0;
 
     if (ctx->hflags & MIPS_HFLAG_BMASK) {
+#ifdef MIPS_DEBUG_DISAS
         if (loglevel & CPU_LOG_TB_IN_ASM) {
             fprintf(logfile,
                     "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
                     ctx->pc);
 	}
-        MIPS_INVAL("branch/jump in bdelay slot");
+#endif
         generate_exception(ctx, EXCP_RI);
         return;
     }
@@ -1552,6 +1557,7 @@
         if (offset != 0 && offset != 16) {
             /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
                others are reserved. */
+            MIPS_INVAL("jump hint");
             generate_exception(ctx, EXCP_RI);
             return;
         }
@@ -1609,12 +1615,12 @@
             return;
         case OPC_J:
             ctx->hflags |= MIPS_HFLAG_B;
-            MIPS_DEBUG("j %08x", btarget);
+            MIPS_DEBUG("j " TARGET_FMT_lx, btarget);
             break;
         case OPC_JAL:
             blink = 31;
             ctx->hflags |= MIPS_HFLAG_B;
-            MIPS_DEBUG("jal %08x", btarget);
+            MIPS_DEBUG("jal " TARGET_FMT_lx, btarget);
             break;
         case OPC_JR:
             ctx->hflags |= MIPS_HFLAG_BR;
@@ -1634,70 +1640,70 @@
         switch (opc) {
         case OPC_BEQ:
             gen_op_eq();
-            MIPS_DEBUG("beq %s, %s, %08x",
+            MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
                        regnames[rs], regnames[rt], btarget);
             goto not_likely;
         case OPC_BEQL:
             gen_op_eq();
-            MIPS_DEBUG("beql %s, %s, %08x",
+            MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
                        regnames[rs], regnames[rt], btarget);
             goto likely;
         case OPC_BNE:
             gen_op_ne();
-            MIPS_DEBUG("bne %s, %s, %08x",
+            MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
                        regnames[rs], regnames[rt], btarget);
             goto not_likely;
         case OPC_BNEL:
             gen_op_ne();
-            MIPS_DEBUG("bnel %s, %s, %08x",
+            MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
                        regnames[rs], regnames[rt], btarget);
             goto likely;
         case OPC_BGEZ:
             gen_op_gez();
-            MIPS_DEBUG("bgez %s, %08x", regnames[rs], btarget);
+            MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btarget);
             goto not_likely;
         case OPC_BGEZL:
             gen_op_gez();
-            MIPS_DEBUG("bgezl %s, %08x", regnames[rs], btarget);
+            MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btarget);
             goto likely;
         case OPC_BGEZAL:
             gen_op_gez();
-            MIPS_DEBUG("bgezal %s, %08x", regnames[rs], btarget);
+            MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btarget);
             blink = 31;
             goto not_likely;
         case OPC_BGEZALL:
             gen_op_gez();
             blink = 31;
-            MIPS_DEBUG("bgezall %s, %08x", regnames[rs], btarget);
+            MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btarget);
             goto likely;
         case OPC_BGTZ:
             gen_op_gtz();
-            MIPS_DEBUG("bgtz %s, %08x", regnames[rs], btarget);
+            MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btarget);
             goto not_likely;
         case OPC_BGTZL:
             gen_op_gtz();
-            MIPS_DEBUG("bgtzl %s, %08x", regnames[rs], btarget);
+            MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btarget);
             goto likely;
         case OPC_BLEZ:
             gen_op_lez();
-            MIPS_DEBUG("blez %s, %08x", regnames[rs], btarget);
+            MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btarget);
             goto not_likely;
         case OPC_BLEZL:
             gen_op_lez();
-            MIPS_DEBUG("blezl %s, %08x", regnames[rs], btarget);
+            MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btarget);
             goto likely;
         case OPC_BLTZ:
             gen_op_ltz();
-            MIPS_DEBUG("bltz %s, %08x", regnames[rs], btarget);
+            MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btarget);
             goto not_likely;
         case OPC_BLTZL:
             gen_op_ltz();
-            MIPS_DEBUG("bltzl %s, %08x", regnames[rs], btarget);
+            MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btarget);
             goto likely;
         case OPC_BLTZAL:
             gen_op_ltz();
             blink = 31;
-            MIPS_DEBUG("bltzal %s, %08x", regnames[rs], btarget);
+            MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btarget);
         not_likely:
             ctx->hflags |= MIPS_HFLAG_BC;
             gen_op_set_bcond();
@@ -1705,7 +1711,7 @@
         case OPC_BLTZALL:
             gen_op_ltz();
             blink = 31;
-            MIPS_DEBUG("bltzall %s, %08x", regnames[rs], btarget);
+            MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btarget);
         likely:
             ctx->hflags |= MIPS_HFLAG_BL;
             gen_op_set_bcond();
@@ -1717,7 +1723,7 @@
             return;
         }
     }
-    MIPS_DEBUG("enter ds: link %d cond %02x target %08x",
+    MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
                blink, ctx->hflags, btarget);
     ctx->btarget = btarget;
     if (blink > 0) {
@@ -4160,7 +4166,7 @@
 
 static void gen_cp0 (DisasContext *ctx, uint32_t opc, int rt, int rd)
 {
-    const char *opn = "unk";
+    const char *opn = "ldst";
 
     switch (opc) {
     case OPC_MFC0:
@@ -4220,6 +4226,7 @@
     case OPC_DERET:
         opn = "deret";
         if (!(ctx->hflags & MIPS_HFLAG_DM)) {
+            MIPS_INVAL(opn);
             generate_exception(ctx, EXCP_RI);
         } else {
             save_cpu_state(ctx, 0);
@@ -4237,11 +4244,7 @@
         ctx->bstate = BS_EXCP;
         break;
     default:
-        if (loglevel & CPU_LOG_TB_IN_ASM) {
-            fprintf(logfile, "Invalid CP0 opcode: %08x %03x %03x %03x\n",
-                    ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
-                    ((ctx->opcode >> 16) & 0x1F));
-        }
+        MIPS_INVAL(opn);
         generate_exception(ctx, EXCP_RI);
         return;
     }
@@ -4253,25 +4256,26 @@
                                  int32_t cc, int32_t offset)
 {
     target_ulong btarget;
+    const char *opn = "cp1 cond branch";
 
     btarget = ctx->pc + 4 + offset;
 
     switch (op) {
     case OPC_BC1F:
         gen_op_bc1f(cc);
-        MIPS_DEBUG("bc1f " TARGET_FMT_lx, btarget);
+        opn = "bc1f";
         goto not_likely;
     case OPC_BC1FL:
         gen_op_bc1f(cc);
-        MIPS_DEBUG("bc1fl " TARGET_FMT_lx, btarget);
+        opn = "bc1fl";
         goto likely;
     case OPC_BC1T:
         gen_op_bc1t(cc);
-        MIPS_DEBUG("bc1t " TARGET_FMT_lx, btarget);
+        opn = "bc1t";
         goto not_likely;
     case OPC_BC1TL:
         gen_op_bc1t(cc);
-        MIPS_DEBUG("bc1tl " TARGET_FMT_lx, btarget);
+        opn = "bc1tl";
     likely:
         ctx->hflags |= MIPS_HFLAG_BL;
         gen_op_set_bcond();
@@ -4279,34 +4283,31 @@
         break;
     case OPC_BC1FANY2:
         gen_op_bc1fany2(cc);
-        MIPS_DEBUG("bc1fany2 " TARGET_FMT_lx, btarget);
+        opn = "bc1fany2";
         goto not_likely;
     case OPC_BC1TANY2:
         gen_op_bc1tany2(cc);
-        MIPS_DEBUG("bc1tany2 " TARGET_FMT_lx, btarget);
+        opn = "bc1tany2";
         goto not_likely;
     case OPC_BC1FANY4:
         gen_op_bc1fany4(cc);
-        MIPS_DEBUG("bc1fany4 " TARGET_FMT_lx, btarget);
+        opn = "bc1fany4";
         goto not_likely;
     case OPC_BC1TANY4:
         gen_op_bc1tany4(cc);
-        MIPS_DEBUG("bc1tany4 " TARGET_FMT_lx, btarget);
+        opn = "bc1tany4";
     not_likely:
         ctx->hflags |= MIPS_HFLAG_BC;
         gen_op_set_bcond();
         break;
     default:
-        MIPS_INVAL("cp1 branch");
+        MIPS_INVAL(opn);
         generate_exception (ctx, EXCP_RI);
         return;
     }
-
-    MIPS_DEBUG("enter ds: cond %02x target " TARGET_FMT_lx,
+    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
                ctx->hflags, btarget);
     ctx->btarget = btarget;
-
-    return;
 }
 
 /* Coprocessor 1 (FPU) */
@@ -4324,18 +4325,19 @@
  * FIXME: This is broken for R2, it needs to be checked at runtime, not
  * at translation time.
  */
-#define CHECK_FR(ctx, freg) do { \
+#define CHECK_FR(ctx, freg) do {                                      \
         if (!((ctx)->CP0_Status & (1 << CP0St_FR)) && ((freg) & 1)) { \
-            generate_exception (ctx, EXCP_RI); \
-            return; \
-        } \
+            MIPS_INVAL("FPU mode");                                   \
+            generate_exception (ctx, EXCP_RI);                        \
+            return;                                                   \
+        }                                                             \
     } while(0)
 
 #define FOP(func, fmt) (((fmt) << 21) | (func))
 
 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
 {
-    const char *opn = "unk";
+    const char *opn = "cp1 move";
 
     switch (opc) {
     case OPC_MFC1:
@@ -4389,11 +4391,7 @@
         opn = "mthc1";
         break;
     default:
-        if (loglevel & CPU_LOG_TB_IN_ASM) {
-            fprintf(logfile, "Invalid CP1 opcode: %08x %03x %03x %03x\n",
-                    ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
-                    ((ctx->opcode >> 16) & 0x1F));
-        }
+        MIPS_INVAL(opn);
         generate_exception (ctx, EXCP_RI);
         return;
     }
@@ -4439,7 +4437,7 @@
 static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
                         int fs, int fd, int cc)
 {
-    const char *opn = "unk";
+    const char *opn = "farith";
     const char *condnames[] = {
             "c.f",
             "c.un",
@@ -4458,7 +4456,25 @@
             "c.le",
             "c.ngt",
     };
-    int binary = 0;
+    const char *condnames_abs[] = {
+            "cabs.f",
+            "cabs.un",
+            "cabs.eq",
+            "cabs.ueq",
+            "cabs.olt",
+            "cabs.ult",
+            "cabs.ole",
+            "cabs.ule",
+            "cabs.sf",
+            "cabs.ngle",
+            "cabs.seq",
+            "cabs.ngl",
+            "cabs.lt",
+            "cabs.nge",
+            "cabs.le",
+            "cabs.ngt",
+    };
+    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
     uint32_t func = ctx->opcode & 0x3f;
 
     switch (ctx->opcode & FOP(0x3f, 0x1f)) {
@@ -4468,7 +4484,7 @@
         gen_op_float_add_s();
         GEN_STORE_FTN_FREG(fd, WT2);
         opn = "add.s";
-        binary = 1;
+        optype = BINOP;
         break;
     case FOP(1, 16):
         GEN_LOAD_FREG_FTN(WT0, fs);
@@ -4476,7 +4492,7 @@
         gen_op_float_sub_s();
         GEN_STORE_FTN_FREG(fd, WT2);
         opn = "sub.s";
-        binary = 1;
+        optype = BINOP;
         break;
     case FOP(2, 16):
         GEN_LOAD_FREG_FTN(WT0, fs);
@@ -4484,7 +4500,7 @@
         gen_op_float_mul_s();
         GEN_STORE_FTN_FREG(fd, WT2);
         opn = "mul.s";
-        binary = 1;
+        optype = BINOP;
         break;
     case FOP(3, 16):
         GEN_LOAD_FREG_FTN(WT0, fs);
@@ -4492,7 +4508,7 @@
         gen_op_float_div_s();
         GEN_STORE_FTN_FREG(fd, WT2);
         opn = "div.s";
-        binary = 1;
+        optype = BINOP;
         break;
     case FOP(4, 16):
         GEN_LOAD_FREG_FTN(WT0, fs);
@@ -4640,8 +4656,13 @@
     case FOP(63, 16):
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WT1, ft);
-        gen_cmp_s(func-48, cc);
-        opn = condnames[func-48];
+        if (ctx->opcode & (1 << 6)) {
+            gen_cmpabs_s(func-48, cc);
+            opn = condnames_abs[func-48];
+        } else {
+            gen_cmp_s(func-48, cc);
+            opn = condnames[func-48];
+        }
         break;
     case FOP(0, 17):
         CHECK_FR(ctx, fs | ft | fd);
@@ -4650,7 +4671,7 @@
         gen_op_float_add_d();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "add.d";
-        binary = 1;
+        optype = BINOP;
         break;
     case FOP(1, 17):
         CHECK_FR(ctx, fs | ft | fd);
@@ -4659,7 +4680,7 @@
         gen_op_float_sub_d();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "sub.d";
-        binary = 1;
+        optype = BINOP;
         break;
     case FOP(2, 17):
         CHECK_FR(ctx, fs | ft | fd);
@@ -4668,7 +4689,7 @@
         gen_op_float_mul_d();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "mul.d";
-        binary = 1;
+        optype = BINOP;
         break;
     case FOP(3, 17):
         CHECK_FR(ctx, fs | ft | fd);
@@ -4677,7 +4698,7 @@
         gen_op_float_div_d();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "div.d";
-        binary = 1;
+        optype = BINOP;
         break;
     case FOP(4, 17):
         CHECK_FR(ctx, fs | fd);
@@ -4806,8 +4827,13 @@
         CHECK_FR(ctx, fs | ft);
         GEN_LOAD_FREG_FTN(DT0, fs);
         GEN_LOAD_FREG_FTN(DT1, ft);
-        gen_cmp_d(func-48, cc);
-        opn = condnames[func-48];
+        if (ctx->opcode & (1 << 6)) {
+            gen_cmpabs_d(func-48, cc);
+            opn = condnames_abs[func-48];
+        } else {
+            gen_cmp_d(func-48, cc);
+            opn = condnames[func-48];
+        }
         break;
     case FOP(32, 17):
         CHECK_FR(ctx, fs);
@@ -4960,6 +4986,17 @@
         GEN_STORE_FTN_FREG(fd, WTH2);
         opn = "movn.ps";
         break;
+    case FOP(24, 22):
+        CHECK_FR(ctx, fs | fd | ft);
+        GEN_LOAD_FREG_FTN(WT0, fs);
+        GEN_LOAD_FREG_FTN(WTH0, fs);
+        GEN_LOAD_FREG_FTN(WT1, ft);
+        GEN_LOAD_FREG_FTN(WTH1, ft);
+        gen_op_float_addr_ps();
+        GEN_STORE_FTN_FREG(fd, WT2);
+        GEN_STORE_FTN_FREG(fd, WTH2);
+        opn = "addr.ps";
+        break;
     case FOP(32, 22):
         CHECK_FR(ctx, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
@@ -5036,29 +5073,37 @@
         GEN_LOAD_FREG_FTN(WTH0, fs);
         GEN_LOAD_FREG_FTN(WT1, ft);
         GEN_LOAD_FREG_FTN(WTH1, ft);
-        gen_cmp_ps(func-48, cc);
-        opn = condnames[func-48];
+        if (ctx->opcode & (1 << 6)) {
+            gen_cmpabs_ps(func-48, cc);
+            opn = condnames_abs[func-48];
+        } else {
+            gen_cmp_ps(func-48, cc);
+            opn = condnames[func-48];
+        }
         break;
     default:
-        if (loglevel & CPU_LOG_TB_IN_ASM) {
-            fprintf(logfile, "Invalid FP arith function: %08x %03x %03x %03x\n",
-                    ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
-                    ((ctx->opcode >> 16) & 0x1F));
-        }
+        MIPS_INVAL(opn);
         generate_exception (ctx, EXCP_RI);
         return;
     }
-    if (binary)
+    switch (optype) {
+    case BINOP:
         MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
-    else
+        break;
+    case CMPOP:
+        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
+        break;
+    default:
         MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
+        break;
+    }
 }
 
 /* Coprocessor 3 (FPU) */
 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, int fd,
                            int base, int index)
 {
-    const char *opn = "unk";
+    const char *opn = "extended float load/store";
 
     GEN_LOAD_REG_TN(T0, base);
     GEN_LOAD_REG_TN(T1, index);
@@ -5097,7 +5142,7 @@
         opn = "suxc1";
         break;
     default:
-        MIPS_INVAL("extended float load/store");
+        MIPS_INVAL(opn);
         generate_exception(ctx, EXCP_RI);
         return;
     }
@@ -5107,7 +5152,7 @@
 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, int fd,
                             int fr, int fs, int ft)
 {
-    const char *opn = "unk";
+    const char *opn = "flt3_arith";
 
     /* All of those work only on 64bit FPUs. */
     CHECK_FR(ctx, fd | fr | fs | ft);
@@ -5129,54 +5174,111 @@
         opn = "madd.s";
         break;
     case OPC_MADD_D:
-        generate_exception (ctx, EXCP_RI);
+        GEN_LOAD_FREG_FTN(DT0, fs);
+        GEN_LOAD_FREG_FTN(DT1, ft);
+        GEN_LOAD_FREG_FTN(DT2, fr);
+        gen_op_float_muladd_d();
+        GEN_STORE_FTN_FREG(fd, DT2);
         opn = "madd.d";
         break;
     case OPC_MADD_PS:
-        generate_exception (ctx, EXCP_RI);
+        GEN_LOAD_FREG_FTN(WT0, fs);
+        GEN_LOAD_FREG_FTN(WTH0, fs);
+        GEN_LOAD_FREG_FTN(WT1, ft);
+        GEN_LOAD_FREG_FTN(WTH1, ft);
+        GEN_LOAD_FREG_FTN(WT2, fr);
+        GEN_LOAD_FREG_FTN(WTH2, fr);
+        gen_op_float_muladd_ps();
+        GEN_STORE_FTN_FREG(fd, WT2);
+        GEN_STORE_FTN_FREG(fd, WTH2);
         opn = "madd.ps";
         break;
     case OPC_MSUB_S:
-        generate_exception (ctx, EXCP_RI);
+        GEN_LOAD_FREG_FTN(WT0, fs);
+        GEN_LOAD_FREG_FTN(WT1, ft);
+        GEN_LOAD_FREG_FTN(WT2, fr);
+        gen_op_float_mulsub_s();
+        GEN_STORE_FTN_FREG(fd, WT2);
         opn = "msub.s";
         break;
     case OPC_MSUB_D:
-        generate_exception (ctx, EXCP_RI);
+        GEN_LOAD_FREG_FTN(DT0, fs);
+        GEN_LOAD_FREG_FTN(DT1, ft);
+        GEN_LOAD_FREG_FTN(DT2, fr);
+        gen_op_float_mulsub_d();
+        GEN_STORE_FTN_FREG(fd, DT2);
         opn = "msub.d";
         break;
     case OPC_MSUB_PS:
-        generate_exception (ctx, EXCP_RI);
+        GEN_LOAD_FREG_FTN(WT0, fs);
+        GEN_LOAD_FREG_FTN(WTH0, fs);
+        GEN_LOAD_FREG_FTN(WT1, ft);
+        GEN_LOAD_FREG_FTN(WTH1, ft);
+        GEN_LOAD_FREG_FTN(WT2, fr);
+        GEN_LOAD_FREG_FTN(WTH2, fr);
+        gen_op_float_mulsub_ps();
+        GEN_STORE_FTN_FREG(fd, WT2);
+        GEN_STORE_FTN_FREG(fd, WTH2);
         opn = "msub.ps";
         break;
     case OPC_NMADD_S:
-        generate_exception (ctx, EXCP_RI);
+        GEN_LOAD_FREG_FTN(WT0, fs);
+        GEN_LOAD_FREG_FTN(WT1, ft);
+        GEN_LOAD_FREG_FTN(WT2, fr);
+        gen_op_float_nmuladd_s();
+        GEN_STORE_FTN_FREG(fd, WT2);
         opn = "nmadd.s";
         break;
     case OPC_NMADD_D:
-        generate_exception (ctx, EXCP_RI);
+        GEN_LOAD_FREG_FTN(DT0, fs);
+        GEN_LOAD_FREG_FTN(DT1, ft);
+        GEN_LOAD_FREG_FTN(DT2, fr);
+        gen_op_float_nmuladd_d();
+        GEN_STORE_FTN_FREG(fd, DT2);
         opn = "nmadd.d";
         break;
     case OPC_NMADD_PS:
-        generate_exception (ctx, EXCP_RI);
+        GEN_LOAD_FREG_FTN(WT0, fs);
+        GEN_LOAD_FREG_FTN(WTH0, fs);
+        GEN_LOAD_FREG_FTN(WT1, ft);
+        GEN_LOAD_FREG_FTN(WTH1, ft);
+        GEN_LOAD_FREG_FTN(WT2, fr);
+        GEN_LOAD_FREG_FTN(WTH2, fr);
+        gen_op_float_nmuladd_ps();
+        GEN_STORE_FTN_FREG(fd, WT2);
+        GEN_STORE_FTN_FREG(fd, WTH2);
         opn = "nmadd.ps";
         break;
     case OPC_NMSUB_S:
-        generate_exception (ctx, EXCP_RI);
+        GEN_LOAD_FREG_FTN(WT0, fs);
+        GEN_LOAD_FREG_FTN(WT1, ft);
+        GEN_LOAD_FREG_FTN(WT2, fr);
+        gen_op_float_nmulsub_s();
+        GEN_STORE_FTN_FREG(fd, WT2);
         opn = "nmsub.s";
         break;
     case OPC_NMSUB_D:
-        generate_exception (ctx, EXCP_RI);
+        GEN_LOAD_FREG_FTN(DT0, fs);
+        GEN_LOAD_FREG_FTN(DT1, ft);
+        GEN_LOAD_FREG_FTN(DT2, fr);
+        gen_op_float_nmulsub_d();
+        GEN_STORE_FTN_FREG(fd, DT2);
         opn = "nmsub.d";
         break;
     case OPC_NMSUB_PS:
-        generate_exception (ctx, EXCP_RI);
+        GEN_LOAD_FREG_FTN(WT0, fs);
+        GEN_LOAD_FREG_FTN(WTH0, fs);
+        GEN_LOAD_FREG_FTN(WT1, ft);
+        GEN_LOAD_FREG_FTN(WTH1, ft);
+        GEN_LOAD_FREG_FTN(WT2, fr);
+        GEN_LOAD_FREG_FTN(WTH2, fr);
+        gen_op_float_nmulsub_ps();
+        GEN_STORE_FTN_FREG(fd, WT2);
+        GEN_STORE_FTN_FREG(fd, WTH2);
         opn = "nmsub.ps";
         break;
-    default:    
-        if (loglevel & CPU_LOG_TB_IN_ASM) {
-            fprintf(logfile, "Invalid extended FP arith function: %08x %03x %03x\n",
-                    ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F);
-        }
+    default:
+        MIPS_INVAL(opn);
         generate_exception (ctx, EXCP_RI);
         return;
     }
@@ -5458,7 +5560,7 @@
             /* treat as noop */
             break;
         default:            /* Invalid */
-            MIPS_INVAL("REGIMM");
+            MIPS_INVAL("regimm");
             generate_exception(ctx, EXCP_RI);
             break;
         }
@@ -5493,7 +5595,7 @@
                 ctx->bstate = BS_STOP;
                 break;
             default:            /* Invalid */
-                MIPS_INVAL("MFMC0");
+                MIPS_INVAL("mfmc0");
                 generate_exception(ctx, EXCP_RI);
                 break;
             }
@@ -5505,10 +5607,13 @@
                 /* Shadow registers not implemented. */
                 GEN_LOAD_REG_TN(T0, rt);
                 GEN_STORE_TN_REG(rd, T0);
-            } else
+            } else {
+                MIPS_INVAL("shadow register move");
                 generate_exception(ctx, EXCP_RI);
+            }
             break;
         default:
+            MIPS_INVAL("cp0");
             generate_exception(ctx, EXCP_RI);
             break;
         }
@@ -5538,7 +5643,7 @@
         /* Treat as a noop */
         break;
 
-    /* Floating point.  */
+    /* Floating point (COP1). */
     case OPC_LWC1:
     case OPC_LDC1:
     case OPC_SWC1:
@@ -5571,6 +5676,8 @@
                 gen_cp1(ctx, op1, rt, rd);
                 break;
             case OPC_BC1:
+            case OPC_BC1ANY2:
+            case OPC_BC1ANY4:
                 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
                                     (rt >> 2) & 0x7, imm << 2);
                 return;
@@ -5583,6 +5690,7 @@
                            (imm >> 8) & 0x7);
                 break;
             default:
+                MIPS_INVAL("cp1");
                 generate_exception (ctx, EXCP_RI);
                 break;
             }
@@ -5634,6 +5742,7 @@
                 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
                 break;
             default:
+                MIPS_INVAL("cp3");
                 generate_exception (ctx, EXCP_RI);
                 break;
             }
@@ -5666,7 +5775,7 @@
         /* MDMX: Not implemented. */
 #endif
     default:            /* Invalid */
-        MIPS_INVAL("");
+        MIPS_INVAL("major opcode");
         generate_exception(ctx, EXCP_RI);
         break;
     }
@@ -5763,7 +5872,7 @@
         cpu_dump_state(env, logfile, fprintf, 0);
     }
 #endif
-#if defined MIPS_DEBUG_DISAS
+#ifdef MIPS_DEBUG_DISAS
     if (loglevel & CPU_LOG_TB_IN_ASM)
         fprintf(logfile, "\ntb %p super %d cond %04x\n",
                 tb, ctx.mem_idx, ctx.hflags);

Modified: trunk/src/host/qemu-neo1973/target-mips/translate_init.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-mips/translate_init.c	2007-05-12 11:23:31 UTC (rev 1949)
+++ trunk/src/host/qemu-neo1973/target-mips/translate_init.c	2007-05-12 14:16:49 UTC (rev 1950)
@@ -98,6 +98,7 @@
         .CP0_Config3 = MIPS_CONFIG3,
         .SYNCI_Step = 32,
         .CCRes = 2,
+        .Status_rw_bitmask = 0x3278FF17,
     },
     {
         .name = "4KEc",





More information about the commitlog mailing list