fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / arch / mips / kernel / cpu-bugs64.c
index 31c17ce..c09337b 100644 (file)
@@ -1,18 +1,18 @@
 /*
- * Copyright (C) 2003  Maciej W. Rozycki
+ * Copyright (C) 2003, 2004  Maciej W. Rozycki
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version
  * 2 of the License, or (at your option) any later version.
  */
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/ptrace.h>
 #include <linux/stddef.h>
 
 #include <asm/bugs.h>
+#include <asm/compiler.h>
 #include <asm/cpu.h>
 #include <asm/fpu.h>
 #include <asm/mipsregs.h>
@@ -82,7 +82,7 @@ static inline void mult_sh_align_mod(long *v1, long *v2, long *w,
                ".set   pop"
                : "=&r" (lv1), "=r" (lw)
                : "r" (m1), "r" (m2), "r" (s), "I" (0)
-               : "hi", "lo", "accum");
+               : "hi", "lo", GCC_REG_ACCUM);
        /* We have to use single integers for m1 and m2 and a double
         * one for p to be sure the mulsidi3 gcc's RTL multiplication
         * instruction has the workaround applied.  Older versions of
@@ -136,7 +136,7 @@ static inline void check_mult_sh(void)
        for (i = 0; i < 8; i++)
                if (v1[i] != w[i])
                        bug = 1;
-               
+
        if (bug == 0) {
                printk("no.\n");
                return;
@@ -148,7 +148,7 @@ static inline void check_mult_sh(void)
        for (i = 0; i < 8; i++)
                if (v2[i] != w[i])
                        fix = 0;
-               
+
        if (fix == 1) {
                printk("yes.\n");
                return;
@@ -177,7 +177,7 @@ static inline void check_daddi(void)
        extern asmlinkage void handle_daddi_ov(void);
        unsigned long flags;
        void *handler;
-       long v;
+       long v, tmp;
 
        printk("Checking for the daddi bug... ");
 
@@ -197,13 +197,15 @@ static inline void check_daddi(void)
                ".set   noat\n\t"
                ".set   noreorder\n\t"
                ".set   nomacro\n\t"
+               "addiu  %1, $0, %2\n\t"
+               "dsrl   %1, %1, 1\n\t"
 #ifdef HAVE_AS_SET_DADDI
                ".set   daddi\n\t"
 #endif
-               "daddi  %0, %1, %2\n\t"
+               "daddi  %0, %1, %3\n\t"
                ".set   pop"
-               : "=r" (v)
-               : "r" (0x7fffffffffffedcd), "I" (0x1234));
+               : "=r" (v), "=&r" (tmp)
+               : "I" (0xffffffffffffdb9aUL), "I" (0x1234));
        set_except_vector(12, handler);
        local_irq_restore(flags);
 
@@ -217,9 +219,11 @@ static inline void check_daddi(void)
        local_irq_save(flags);
        handler = set_except_vector(12, handle_daddi_ov);
        asm volatile(
-               "daddi  %0, %1, %2"
-               : "=r" (v)
-               : "r" (0x7fffffffffffedcd), "I" (0x1234));
+               "addiu  %1, $0, %2\n\t"
+               "dsrl   %1, %1, 1\n\t"
+               "daddi  %0, %1, %3"
+               : "=r" (v), "=&r" (tmp)
+               : "I" (0xffffffffffffdb9aUL), "I" (0x1234));
        set_except_vector(12, handler);
        local_irq_restore(flags);
 
@@ -240,7 +244,7 @@ static inline void check_daddi(void)
 
 static inline void check_daddiu(void)
 {
-       long v, w;
+       long v, w, tmp;
 
        printk("Checking for the daddiu bug... ");
 
@@ -265,15 +269,17 @@ static inline void check_daddiu(void)
                ".set   noat\n\t"
                ".set   noreorder\n\t"
                ".set   nomacro\n\t"
+               "addiu  %2, $0, %3\n\t"
+               "dsrl   %2, %2, 1\n\t"
 #ifdef HAVE_AS_SET_DADDI
                ".set   daddi\n\t"
 #endif
-               "daddiu %0, %2, %3\n\t"
-               "addiu  %1, $0, %3\n\t"
+               "daddiu %0, %2, %4\n\t"
+               "addiu  %1, $0, %4\n\t"
                "daddu  %1, %2\n\t"
                ".set   pop"
-               : "=&r" (v), "=&r" (w)
-               : "r" (0x7fffffffffffedcd), "I" (0x1234));
+               : "=&r" (v), "=&r" (w), "=&r" (tmp)
+               : "I" (0xffffffffffffdb9aUL), "I" (0x1234));
 
        if (v == w) {
                printk("no.\n");
@@ -283,11 +289,13 @@ static inline void check_daddiu(void)
        printk("yes, workaround... ");
 
        asm volatile(
-               "daddiu %0, %2, %3\n\t"
-               "addiu  %1, $0, %3\n\t"
+               "addiu  %2, $0, %3\n\t"
+               "dsrl   %2, %2, 1\n\t"
+               "daddiu %0, %2, %4\n\t"
+               "addiu  %1, $0, %4\n\t"
                "daddu  %1, %2"
-               : "=&r" (v), "=&r" (w)
-               : "r" (0x7fffffffffffedcd), "I" (0x1234));
+               : "=&r" (v), "=&r" (w), "=&r" (tmp)
+               : "I" (0xffffffffffffdb9aUL), "I" (0x1234));
 
        if (v == w) {
                printk("yes.\n");