aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2009-05-21 18:47:59 -0700
committerUlrich Drepper <drepper@redhat.com>2009-05-21 18:47:59 -0700
commitfa64b7f76b97930cd2aaf7bfd305cac3d925cd8f (patch)
tree575d7571ecebb6c21618c6e2633462f0e9380484
parentd2812fc6d26adc7fc74d85079874a8ee944343da (diff)
downloadglibc-fa64b7f76b97930cd2aaf7bfd305cac3d925cd8f.zip
glibc-fa64b7f76b97930cd2aaf7bfd305cac3d925cd8f.tar.gz
glibc-fa64b7f76b97930cd2aaf7bfd305cac3d925cd8f.tar.bz2
Fix IA-64 memchr read-ahead.
The latest stratcliff extension exposed a bug in the IA-64 memchr which uses non-speculative loads to prefetch data. Change the code to use speculative loads with appropriate fixup. Fixes BZ 10162.
-rw-r--r--ChangeLog5
-rw-r--r--sysdeps/ia64/memchr.S17
2 files changed, 21 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 5746ede..4247797 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
2009-05-21 H.J. Lu <hongjiu.lu@intel.com>
+ [BZ #10162]
+ * sysdeps/ia64/memchr.S: Use speculative load.
+
+2009-05-21 H.J. Lu <hongjiu.lu@intel.com>
+
* sysdeps/unix/sysv/linux/ia64/____longjmp_chk.S: New file.
* sysdeps/unix/sysv/linux/ia64/__longjmp.S: If CHECK_RSP is defined,
use it.
diff --git a/sysdeps/ia64/memchr.S b/sysdeps/ia64/memchr.S
index e9a7ba8..cd062b2 100644
--- a/sysdeps/ia64/memchr.S
+++ b/sysdeps/ia64/memchr.S
@@ -96,7 +96,8 @@ ENTRY(__memchr)
mov pr.rot = 1 << 16 ;;
.l2:
(p[0]) mov addr[0] = ret0
-(p[0]) ld8 value[0] = [ret0], 8
+(p[0]) ld8.s value[0] = [ret0], 8 // speculative load
+(p[MEMLAT]) chk.s value[MEMLAT], .recovery // check and recovery
(p[MEMLAT]) xor aux[0] = value[MEMLAT], chrx8
(p[MEMLAT+1]) czx1.r poschr[0] = aux[1]
(p[MEMLAT+2]) cmp.ne p7, p0 = 8, poschr[1]
@@ -124,6 +125,20 @@ ENTRY(__memchr)
mov ar.lc = saved_lc
br.ret.sptk.many b0
+.recovery:
+ adds ret0 = -((MEMLAT + 1) * 8), ret0;;
+(p[MEMLAT+1]) add ret0 = -8, ret0;;
+(p[MEMLAT+2]) add ret0 = -8, ret0;;
+.l4:
+ mov addr[MEMLAT+2] = ret0
+ ld8 tmp = [ret0];; // load the first unchecked 8byte
+ xor aux[1] = tmp, chrx8;;
+ czx1.r poschr[1] = aux[1];;
+ cmp.ne p7, p0 = 8, poschr[1]
+(p7) br.cond.spnt .foundit;;
+ adds ret0 = 8, ret0 // load the next unchecked 8byte
+ br.sptk .l4;;
+
END(__memchr)
weak_alias (__memchr, memchr)