/*
- * 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>
".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
for (i = 0; i < 8; i++)
if (v1[i] != w[i])
bug = 1;
-
+
if (bug == 0) {
printk("no.\n");
return;
for (i = 0; i < 8; i++)
if (v2[i] != w[i])
fix = 0;
-
+
if (fix == 1) {
printk("yes.\n");
return;
extern asmlinkage void handle_daddi_ov(void);
unsigned long flags;
void *handler;
- long v;
+ long v, tmp;
printk("Checking for the daddi bug... ");
".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);
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);
static inline void check_daddiu(void)
{
- long v, w;
+ long v, w, tmp;
printk("Checking for the daddiu bug... ");
".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");
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");