summaryrefslogtreecommitdiff
path: root/src/mpfr-impl.h
diff options
context:
space:
mode:
authorvlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2014-07-07 12:43:59 +0000
committervlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2014-07-07 12:43:59 +0000
commit0042944a05c2bada008edd3f3bccecbedb98b746 (patch)
tree41407ff34314f00b2e51e7ed0d5cf4e110562f14 /src/mpfr-impl.h
parent8f2321df512efa7b6de2a71f6b48406053aa0671 (diff)
downloadmpfr-0042944a05c2bada008edd3f3bccecbedb98b746.tar.gz
Added debug of branch prediction / --enable-debug-prediction configure
option (patch from Patrick PĂ©lissier, with some changes). git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@9141 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'src/mpfr-impl.h')
-rw-r--r--src/mpfr-impl.h48
1 files changed, 45 insertions, 3 deletions
diff --git a/src/mpfr-impl.h b/src/mpfr-impl.h
index a56754b99..91f53ca74 100644
--- a/src/mpfr-impl.h
+++ b/src/mpfr-impl.h
@@ -1047,12 +1047,54 @@ typedef union { mp_size_t s; mp_limb_t l; } mpfr_size_limb_t;
/* Theses macros help the compiler to determine if a test is
likely or unlikely. The !! is necessary in case x is larger
than a long. */
-#if __MPFR_GNUC(3,0) || __MPFR_ICC(8,1,0)
-# define MPFR_LIKELY(x) (__builtin_expect(!!(x),1))
-# define MPFR_UNLIKELY(x) (__builtin_expect(!!(x),0))
+#if defined MPFR_DEBUG_PREDICTION && __MPFR_GNUC(3,0)
+
+/* Code to debug branch prediction, based on Ulrich Drepper's paper
+ * "What Every Programmer Should Know About Memory":
+ * http://people.freebsd.org/~lstewart/articles/cpumemory.pdf
+ */
+asm (".section predict_data, \"aw\"; .previous\n"
+ ".section predict_line, \"a\"; .previous\n"
+ ".section predict_file, \"a\"; .previous");
+# if defined __x86_64__
+# define MPFR_DEBUGPRED__(e,E) \
+ ({ long int _e = !!(e); \
+ asm volatile (".pushsection predict_data\n" \
+ "..predictcnt%=: .quad 0; .quad 0\n" \
+ ".section predict_line; .quad %c1\n" \
+ ".section predict_file; .quad %c2; .popsection\n" \
+ "addq $1,..predictcnt%=(,%0,8)" \
+ : : "r" (_e == E), "i" (__LINE__), "i" (__FILE__)); \
+ __builtin_expect (_e, E); \
+ })
+# elif defined __i386__
+# define MPFR_DEBUGPRED__(e,E) \
+ ({ long int _e = !!(e); \
+ asm volatile (".pushsection predict_data\n" \
+ "..predictcnt%=: .long 0; .long 0\n" \
+ ".section predict_line; .long %c1\n" \
+ ".section predict_file; .long %c2; .popsection\n" \
+ "incl ..predictcnt%=(,%0,4)" \
+ : : "r" (_e == E), "i" (__LINE__), "i" (__FILE__)); \
+ __builtin_expect (_e, E); \
+ })
+# else
+# error "MPFR_DEBUGPRED__ definition missing"
+# endif
+
+# define MPFR_LIKELY(x) MPFR_DEBUGPRED__ ((x), 1)
+# define MPFR_UNLIKELY(x) MPFR_DEBUGPRED__ ((x), 0)
+
+#elif __MPFR_GNUC(3,0) || __MPFR_ICC(8,1,0)
+
+# define MPFR_LIKELY(x) (__builtin_expect(!!(x), 1))
+# define MPFR_UNLIKELY(x) (__builtin_expect(!!(x), 0))
+
#else
+
# define MPFR_LIKELY(x) (x)
# define MPFR_UNLIKELY(x) (x)
+
#endif
/* Declare that some variable is initialized before being used (without a