Package: gcc-3.3 Version: 3.3.5-1 Severity: important While trying to run Debian on a SGI O200 Machine I found out that the inline assembly to handle atomic operations in libstdc++ is broken. The effect is very visible: "apt-get update" hangs in an endless loop on startup, same for every other c++ program I tried. This happens on machines with R10000 CPU, others may show degraded performance.
R10000 CPUs aren't yet officially supported in Debian, so I used serverity important for this bugreport. The problem is caused by inserting normal load operation in the atomic loop, which isn't guaranteed to work. The load is generated by the assembler to fulfill the memory reference, so it isn't visible in the source. The appended patch fixes it. It also changes the branch to the likely variant, this works around some breakage in early R10000 silicon. The patch is against gcc-3.3, newer gccs have the same problem, but have some apparently bogus changes in that area. Thiemo #! /bin/sh -e # All lines beginning with `# DPATCH:' are a description of the patch. # DP: Fix libstdc++ atomic ops for mips/mipsel dir= if [ $# -eq 3 -a "$2" = '-d' ]; then pdir="-d $3" dir="$3/" elif [ $# -ne 1 ]; then echo >&2 "`basename $0`: script expects -patch|-unpatch as argument" exit 1 fi case "$1" in -patch) patch $pdir -f --no-backup-if-mismatch -p0 < $0 #cd ${dir}gcc && autoconf ;; -unpatch) patch $pdir -f --no-backup-if-mismatch -R -p0 < $0 #rm ${dir}gcc/configure ;; *) echo >&2 "`basename $0`: script expects -patch|-unpatch as argument" exit 1 esac exit 0 --- libstdc++-v3/config/cpu/mips/atomicity.h.old 2003-06-02 20:04:54.000000000 +0200 +++ libstdc++-v3/config/cpu/mips/atomicity.h 2004-10-23 17:41:38.000000000 +0200 @@ -40,17 +40,19 @@ __exchange_and_add (volatile _Atomic_wor __asm__ __volatile__ ("/* Inline exchange & add */\n\t" - "1:\n\t" ".set push\n\t" ".set mips2\n\t" - "ll %0,%3\n\t" - "addu %1,%4,%0\n\t" - "sc %1,%2\n\t" + ".set noreorder\n\t" + ".set nomacro\n" + "1:\tll %0,(%2)\n\t" + "addu %1,%3,%0\n\t" + "sc %1,(%2)\n\t" + ".set reorder\n\t" + "beqzl %1,1b\n\t" ".set pop\n\t" - "beqz %1,1b\n\t" - "/* End exchange & add */" - : "=&r"(__result), "=&r"(__tmp), "=m"(*__mem) - : "m" (*__mem), "r"(__val) + "/* End exchange & add */\n" + : "=&r"(__result), "=&r"(__tmp), "+r"(__mem) + : "r"(__val) : "memory"); return __result; @@ -64,17 +66,19 @@ __atomic_add (volatile _Atomic_word *__m __asm__ __volatile__ ("/* Inline atomic add */\n\t" - "1:\n\t" ".set push\n\t" ".set mips2\n\t" - "ll %0,%2\n\t" - "addu %0,%3,%0\n\t" - "sc %0,%1\n\t" + ".set noreorder\n\t" + ".set nomacro\n" + "1:\tll %0,(%1)\n\t" + "addu %0,%2,%0\n\t" + "sc %0,(%1)\n\t" + ".set reorder\n\t" + "beqzl %0,1b\n\t" ".set pop\n\t" - "beqz %0,1b\n\t" - "/* End atomic add */" - : "=&r"(__result), "=m"(*__mem) - : "m" (*__mem), "r"(__val) + "/* End atomic add */\n" + : "=&r"(__result), "+r"(__mem) + : "r"(__val) : "memory"); }