Workaround R10K ll/sc errata.
authorMatt Turner <mattst88@gmail.com>
Tue, 2 Aug 2011 15:18:06 +0000 (15:18 +0000)
committerJoseph Myers <joseph@codesourcery.com>
Tue, 2 Aug 2011 15:18:06 +0000 (15:18 +0000)
ChangeLog.mips
sysdeps/mips/bits/atomic.h

index aa29c02..b2998b8 100644 (file)
@@ -1,3 +1,7 @@
+2011-08-02  Matt Turner  <mattst88@gmail.com>
+
+       * sysdeps/mips/bits/atomic.h: Workaround R10K ll/sc errata.
+
 2011-07-25  Joseph Myers  <joseph@codesourcery.com>
 
        * sysdeps/unix/sysv/linux/mips/bits/socket.h (PF_NFC, AF_NFC):
index 11b3467..2bd723d 100644 (file)
@@ -49,6 +49,32 @@ typedef uintmax_t uatomic_max_t;
 # define MIPS_SYNC     sync
 #endif
 
+/* Certain revisions of the R10000 Processor need an LL/SC Workaround
+   enabled.  Revisions before 3.0 misbehave on atomic operations, and
+   Revs 2.6 and lower deadlock after several seconds due to other errata.
+
+   To quote the R10K Errata:
+      Workaround: The basic idea is to inhibit the four instructions
+      from simultaneously becoming active in R10000. Padding all
+      ll/sc sequences with nops or changing the looping branch in the
+      routines to a branch likely (which is always predicted taken
+      by R10000) will work. The nops should go after the loop, and the
+      number of them should be 28. This number could be decremented for
+      each additional instruction in the ll/sc loop such as the lock
+      modifier(s) between the ll and sc, the looping branch and its
+      delay slot. For typical short routines with one ll/sc loop, any
+      instructions after the loop could also count as a decrement. The
+      nop workaround pollutes the cache more but would be a few cycles
+      faster if all the code is in the cache and the looping branch
+      is predicted not taken.  */
+
+
+#ifdef _MIPS_ARCH_R10000
+#define R10K_BEQZ_INSN "beqzl"
+#else
+#define R10K_BEQZ_INSN "beqz"
+#endif
+
 #define MIPS_SYNC_STR_2(X) #X
 #define MIPS_SYNC_STR_1(X) MIPS_SYNC_STR_2(X)
 #define MIPS_SYNC_STR MIPS_SYNC_STR_1(MIPS_SYNC)
@@ -74,7 +100,7 @@ typedef uintmax_t uatomic_max_t;
      "bne      %0,%3,2f\n\t"                                                 \
      "move     %1,%4\n\t"                                                    \
      "sc       %1,%2\n\t"                                                    \
-     "beqz     %1,1b\n"                                                      \
+     R10K_BEQZ_INSN"   %1,1b\n"                                              \
      acq       "\n\t"                                                        \
      ".set     pop\n"                                                        \
      "2:\n\t"                                                                \
@@ -98,7 +124,7 @@ typedef uintmax_t uatomic_max_t;
      "bne      %0,%3,2f\n\t"                                                 \
      "move     %1,%4\n\t"                                                    \
      "scd      %1,%2\n\t"                                                    \
-     "beqz     %1,1b\n"                                                      \
+     R10K_BEQZ_INSN"   %1,1b\n"                                              \
      acq       "\n\t"                                                        \
      ".set     pop\n"                                                        \
      "2:\n\t"                                                                \
@@ -192,7 +218,7 @@ typedef uintmax_t uatomic_max_t;
      "ll       %0,%4\n\t"                                                    \
      "move     %1,%3\n\t"                                                    \
      "sc       %1,%2\n\t"                                                    \
-     "beqz     %1,1b\n"                                                      \
+     R10K_BEQZ_INSN"   %1,1b\n"                                              \
      acq       "\n\t"                                                        \
      ".set     pop\n"                                                        \
      "2:\n\t"                                                                \
@@ -216,7 +242,7 @@ typedef uintmax_t uatomic_max_t;
      "lld      %0,%4\n\t"                                                    \
      "move     %1,%3\n\t"                                                    \
      "scd      %1,%2\n\t"                                                    \
-     "beqz     %1,1b\n"                                                      \
+     R10K_BEQZ_INSN"   %1,1b\n"                                              \
      acq       "\n\t"                                                        \
      ".set     pop\n"                                                        \
      "2:\n\t"                                                                \
@@ -251,7 +277,7 @@ typedef uintmax_t uatomic_max_t;
      "ll       %0,%4\n\t"                                                    \
      "addu     %1,%0,%3\n\t"                                                 \
      "sc       %1,%2\n\t"                                                    \
-     "beqz     %1,1b\n"                                                      \
+     R10K_BEQZ_INSN"   %1,1b\n"                                              \
      acq       "\n\t"                                                        \
      ".set     pop\n"                                                        \
      "2:\n\t"                                                                \
@@ -275,7 +301,7 @@ typedef uintmax_t uatomic_max_t;
      "lld      %0,%4\n\t"                                                    \
      "daddu    %1,%0,%3\n\t"                                                 \
      "scd      %1,%2\n\t"                                                    \
-     "beqz     %1,1b\n"                                                      \
+     R10K_BEQZ_INSN"   %1,1b\n"                                              \
      acq       "\n\t"                                                        \
      ".set     pop\n"                                                        \
      "2:\n\t"                                                                \