2011-03-20  H.J. Lu  <hongjiu.lu@intel.com>

	[BZ #12597]
	* string/test-strncmp.c (do_page_test): New function.
	(check2): Likewise.
	(test_main): Call check2.
	* sysdeps/x86_64/multiarch/strcmp.S: Properly cross page boundary.

Index: glibc-2.11.3/string/test-strncmp.c
===================================================================
--- glibc-2.11.3.orig/string/test-strncmp.c
+++ glibc-2.11.3/string/test-strncmp.c
@@ -190,6 +190,27 @@ do_test (size_t align1, size_t align2, s
 }
 
 static void
+do_page_test (size_t offset1, size_t offset2, char *s2)
+{
+  char *s1;
+  int exp_result;
+
+  if (offset1 >= page_size || offset2 >= page_size)
+    return;
+
+  s1 = (char *) (buf1 + offset1);
+  s2 += offset2;
+
+  exp_result= *s1;
+  
+  FOR_EACH_IMPL (impl, 0)
+    {
+      check_result (impl, s1, s2, page_size, -exp_result);
+      check_result (impl, s2, s1, page_size, exp_result);
+    }
+}
+
+static void
 do_random_tests (void)
 {
   size_t i, j, n, align1, align2, pos, len1, len2, size;
@@ -283,6 +304,25 @@ do_random_tests (void)
     }
 }
 
+static void
+check2 (void)
+{
+  size_t i;
+  char *s1, *s2;
+
+  s1 = (char *) buf1;
+  for (i = 0; i < page_size - 1; i++)
+    s1[i] = 23;
+  s1[i] = 0;
+
+  s2 = strdup (s1);
+
+  for (i = 0; i < 64; ++i)
+    do_page_test (3990 + i, 2635, s2);
+
+  free (s2);
+}
+
 int
 test_main (void)
 {
@@ -290,6 +330,8 @@ test_main (void)
 
   test_init ();
 
+  check2 ();
+
   printf ("%23s", "");
   FOR_EACH_IMPL (impl, 0)
     printf ("\t%s", impl->name);
Index: glibc-2.11.3/sysdeps/x86_64/multiarch/strcmp.S
===================================================================
--- glibc-2.11.3.orig/sysdeps/x86_64/multiarch/strcmp.S
+++ glibc-2.11.3/sysdeps/x86_64/multiarch/strcmp.S
@@ -292,6 +292,7 @@ LABEL(loop_ashr_1_use_sse4_2):
 	add	$16, %r10
 	jg	LABEL(nibble_ashr_1_use_sse4_2)
 
+LABEL(nibble_ashr_1_use_sse4_2_restart):
 	movdqa	(%rdi, %rdx), %xmm0
 	palignr $1, -16(%rdi, %rdx), %xmm0
 	pcmpistri	$0x1a,(%rsi,%rdx), %xmm0
@@ -314,7 +315,7 @@ LABEL(nibble_ashr_1_use_sse4_2):
 	jae	LABEL(nibble_ashr_use_sse4_2_exit)
 #endif
 	cmp	$14, %ecx
-	ja	LABEL(loop_ashr_1_use_sse4_2)
+	ja	LABEL(nibble_ashr_1_use_sse4_2_restart)
 
 	jmp	LABEL(nibble_ashr_use_sse4_2_exit)
 
@@ -358,6 +359,7 @@ LABEL(loop_ashr_2_use_sse4_2):
 	add	$16, %r10
 	jg	LABEL(nibble_ashr_2_use_sse4_2)
 
+LABEL(nibble_ashr_2_use_sse4_2_restart):
 	movdqa	(%rdi, %rdx), %xmm0
 	palignr $2, -16(%rdi, %rdx), %xmm0
 	pcmpistri	$0x1a,(%rsi,%rdx), %xmm0
@@ -393,7 +395,7 @@ LABEL(nibble_ashr_2_use_sse4_2):
 	jae	LABEL(nibble_ashr_use_sse4_2_exit)
 #endif
 	cmp	$13, %ecx
-	ja	LABEL(loop_ashr_2_use_sse4_2)
+	ja	LABEL(nibble_ashr_2_use_sse4_2_restart)
 
 	jmp	LABEL(nibble_ashr_use_sse4_2_exit)
 
@@ -437,6 +439,7 @@ LABEL(loop_ashr_3_use_sse4_2):
 	add	$16, %r10
 	jg	LABEL(nibble_ashr_3_use_sse4_2)
 
+LABEL(nibble_ashr_3_use_sse4_2_restart):
 	movdqa	(%rdi, %rdx), %xmm0
 	palignr $3, -16(%rdi, %rdx), %xmm0
 	pcmpistri	$0x1a,(%rsi,%rdx), %xmm0
@@ -472,7 +475,7 @@ LABEL(nibble_ashr_3_use_sse4_2):
 	jae	LABEL(nibble_ashr_use_sse4_2_exit)
 #endif
 	cmp	$12, %ecx
-	ja	LABEL(loop_ashr_3_use_sse4_2)
+	ja	LABEL(nibble_ashr_3_use_sse4_2_restart)
 
 	jmp	LABEL(nibble_ashr_use_sse4_2_exit)
 
@@ -517,6 +520,7 @@ LABEL(loop_ashr_4_use_sse4_2):
 	add	$16, %r10
 	jg	LABEL(nibble_ashr_4_use_sse4_2)
 
+LABEL(nibble_ashr_4_use_sse4_2_restart):
 	movdqa	(%rdi, %rdx), %xmm0
 	palignr $4, -16(%rdi, %rdx), %xmm0
 	pcmpistri	$0x1a,(%rsi,%rdx), %xmm0
@@ -552,7 +556,7 @@ LABEL(nibble_ashr_4_use_sse4_2):
 	jae	LABEL(nibble_ashr_use_sse4_2_exit)
 #endif
 	cmp	$11, %ecx
-	ja	LABEL(loop_ashr_4_use_sse4_2)
+	ja	LABEL(nibble_ashr_4_use_sse4_2_restart)
 
 	jmp	LABEL(nibble_ashr_use_sse4_2_exit)
 
@@ -597,6 +601,7 @@ LABEL(loop_ashr_5_use_sse4_2):
 	add	$16, %r10
 	jg	LABEL(nibble_ashr_5_use_sse4_2)
 
+LABEL(nibble_ashr_5_use_sse4_2_restart):
 	movdqa	(%rdi, %rdx), %xmm0
 	palignr $5, -16(%rdi, %rdx), %xmm0
 	pcmpistri	$0x1a,(%rsi,%rdx), %xmm0
@@ -633,7 +638,7 @@ LABEL(nibble_ashr_5_use_sse4_2):
 	jae	LABEL(nibble_ashr_use_sse4_2_exit)
 #endif
 	cmp	$10, %ecx
-	ja	LABEL(loop_ashr_5_use_sse4_2)
+	ja	LABEL(nibble_ashr_5_use_sse4_2_restart)
 
 	jmp	LABEL(nibble_ashr_use_sse4_2_exit)
 
@@ -678,6 +683,7 @@ LABEL(loop_ashr_6_use_sse4_2):
 	add	$16, %r10
 	jg	LABEL(nibble_ashr_6_use_sse4_2)
 
+LABEL(nibble_ashr_6_use_sse4_2_restart):
 	movdqa	(%rdi, %rdx), %xmm0
 	palignr $6, -16(%rdi, %rdx), %xmm0
 	pcmpistri	$0x1a,(%rsi,%rdx), %xmm0
@@ -713,7 +719,7 @@ LABEL(nibble_ashr_6_use_sse4_2):
 	jae	LABEL(nibble_ashr_use_sse4_2_exit)
 #endif
 	cmp	$9, %ecx
-	ja	LABEL(loop_ashr_6_use_sse4_2)
+	ja	LABEL(nibble_ashr_6_use_sse4_2_restart)
 
 	jmp	LABEL(nibble_ashr_use_sse4_2_exit)
 
@@ -758,6 +764,7 @@ LABEL(loop_ashr_7_use_sse4_2):
 	add	$16, %r10
 	jg	LABEL(nibble_ashr_7_use_sse4_2)
 
+LABEL(nibble_ashr_7_use_sse4_2_restart):
 	movdqa	(%rdi, %rdx), %xmm0
 	palignr $7, -16(%rdi, %rdx), %xmm0
 	pcmpistri	$0x1a,(%rsi,%rdx), %xmm0
@@ -793,7 +800,7 @@ LABEL(nibble_ashr_7_use_sse4_2):
 	jae	LABEL(nibble_ashr_use_sse4_2_exit)
 #endif
 	cmp	$8, %ecx
-	ja	LABEL(loop_ashr_7_use_sse4_2)
+	ja	LABEL(nibble_ashr_7_use_sse4_2_restart)
 
 	jmp	LABEL(nibble_ashr_use_sse4_2_exit)
 
@@ -838,6 +845,7 @@ LABEL(loop_ashr_8_use_sse4_2):
 	add	$16, %r10
 	jg	LABEL(nibble_ashr_8_use_sse4_2)
 
+LABEL(nibble_ashr_8_use_sse4_2_restart):
 	movdqa	(%rdi, %rdx), %xmm0
 	palignr $8, -16(%rdi, %rdx), %xmm0
 	pcmpistri	$0x1a,(%rsi,%rdx), %xmm0
@@ -873,7 +881,7 @@ LABEL(nibble_ashr_8_use_sse4_2):
 	jae	LABEL(nibble_ashr_use_sse4_2_exit)
 #endif
 	cmp	$7, %ecx
-	ja	LABEL(loop_ashr_8_use_sse4_2)
+	ja	LABEL(nibble_ashr_8_use_sse4_2_restart)
 
 	jmp	LABEL(nibble_ashr_use_sse4_2_exit)
 
@@ -918,6 +926,7 @@ LABEL(loop_ashr_9_use_sse4_2):
 	add	$16, %r10
 	jg	LABEL(nibble_ashr_9_use_sse4_2)
 
+LABEL(nibble_ashr_9_use_sse4_2_restart):
 	movdqa	(%rdi, %rdx), %xmm0
 
 	palignr $9, -16(%rdi, %rdx), %xmm0
@@ -954,7 +963,7 @@ LABEL(nibble_ashr_9_use_sse4_2):
 	jae	LABEL(nibble_ashr_use_sse4_2_exit)
 #endif
 	cmp	$6, %ecx
-	ja	LABEL(loop_ashr_9_use_sse4_2)
+	ja	LABEL(nibble_ashr_9_use_sse4_2_restart)
 
 	jmp	LABEL(nibble_ashr_use_sse4_2_exit)
 
@@ -999,6 +1008,7 @@ LABEL(loop_ashr_10_use_sse4_2):
 	add	$16, %r10
 	jg	LABEL(nibble_ashr_10_use_sse4_2)
 
+LABEL(nibble_ashr_10_use_sse4_2_restart):
 	movdqa	(%rdi, %rdx), %xmm0
 	palignr $10, -16(%rdi, %rdx), %xmm0
 	pcmpistri	$0x1a,(%rsi,%rdx), %xmm0
@@ -1034,7 +1044,7 @@ LABEL(nibble_ashr_10_use_sse4_2):
 	jae	LABEL(nibble_ashr_use_sse4_2_exit)
 #endif
 	cmp	$5, %ecx
-	ja	LABEL(loop_ashr_10_use_sse4_2)
+	ja	LABEL(nibble_ashr_10_use_sse4_2_restart)
 
 	jmp	LABEL(nibble_ashr_use_sse4_2_exit)
 
@@ -1079,6 +1089,7 @@ LABEL(loop_ashr_11_use_sse4_2):
 	add	$16, %r10
 	jg	LABEL(nibble_ashr_11_use_sse4_2)
 
+LABEL(nibble_ashr_11_use_sse4_2_restart):
 	movdqa	(%rdi, %rdx), %xmm0
 	palignr $11, -16(%rdi, %rdx), %xmm0
 	pcmpistri	$0x1a,(%rsi,%rdx), %xmm0
@@ -1114,7 +1125,7 @@ LABEL(nibble_ashr_11_use_sse4_2):
 	jae	LABEL(nibble_ashr_use_sse4_2_exit)
 #endif
 	cmp	$4, %ecx
-	ja	LABEL(loop_ashr_11_use_sse4_2)
+	ja	LABEL(nibble_ashr_11_use_sse4_2_restart)
 
 	jmp	LABEL(nibble_ashr_use_sse4_2_exit)
 
@@ -1159,6 +1170,7 @@ LABEL(loop_ashr_12_use_sse4_2):
 	add	$16, %r10
 	jg	LABEL(nibble_ashr_12_use_sse4_2)
 
+LABEL(nibble_ashr_12_use_sse4_2_restart):
 	movdqa	(%rdi, %rdx), %xmm0
 	palignr $12, -16(%rdi, %rdx), %xmm0
 	pcmpistri	$0x1a,(%rsi,%rdx), %xmm0
@@ -1194,7 +1206,7 @@ LABEL(nibble_ashr_12_use_sse4_2):
 	jae	LABEL(nibble_ashr_use_sse4_2_exit)
 #endif
 	cmp	$3, %ecx
-	ja	LABEL(loop_ashr_12_use_sse4_2)
+	ja	LABEL(nibble_ashr_12_use_sse4_2_restart)
 
 	jmp	LABEL(nibble_ashr_use_sse4_2_exit)
 
@@ -1240,6 +1252,7 @@ LABEL(loop_ashr_13_use_sse4_2):
 	add	$16, %r10
 	jg	LABEL(nibble_ashr_13_use_sse4_2)
 
+LABEL(nibble_ashr_13_use_sse4_2_restart):
 	movdqa	(%rdi, %rdx), %xmm0
 	palignr $13, -16(%rdi, %rdx), %xmm0
 	pcmpistri	$0x1a,(%rsi,%rdx), %xmm0
@@ -1275,7 +1288,7 @@ LABEL(nibble_ashr_13_use_sse4_2):
 	jae	LABEL(nibble_ashr_use_sse4_2_exit)
 #endif
 	cmp	$2, %ecx
-	ja	LABEL(loop_ashr_13_use_sse4_2)
+	ja	LABEL(nibble_ashr_13_use_sse4_2_restart)
 
 	jmp	LABEL(nibble_ashr_use_sse4_2_exit)
 
@@ -1321,6 +1334,7 @@ LABEL(loop_ashr_14_use_sse4_2):
 	add	$16, %r10
 	jg	LABEL(nibble_ashr_14_use_sse4_2)
 
+LABEL(nibble_ashr_14_use_sse4_2_restart):
 	movdqa	(%rdi, %rdx), %xmm0
 	palignr $14, -16(%rdi, %rdx), %xmm0
 	pcmpistri	$0x1a,(%rsi,%rdx), %xmm0
@@ -1356,7 +1370,7 @@ LABEL(nibble_ashr_14_use_sse4_2):
 	jae	LABEL(nibble_ashr_use_sse4_2_exit)
 #endif
 	cmp	$1, %ecx
-	ja	LABEL(loop_ashr_14_use_sse4_2)
+	ja	LABEL(nibble_ashr_14_use_sse4_2_restart)
 
 	jmp	LABEL(nibble_ashr_use_sse4_2_exit)
 
@@ -1404,6 +1418,7 @@ LABEL(loop_ashr_15_use_sse4_2):
 	add	$16, %r10
 	jg	LABEL(nibble_ashr_15_use_sse4_2)
 
+LABEL(nibble_ashr_15_use_sse4_2_restart):
 	movdqa	(%rdi, %rdx), %xmm0
 	palignr $15, -16(%rdi, %rdx), %xmm0
 	pcmpistri      $0x1a,(%rsi,%rdx), %xmm0
@@ -1439,7 +1454,7 @@ LABEL(nibble_ashr_15_use_sse4_2):
 	jae	LABEL(nibble_ashr_use_sse4_2_exit)
 #endif
 	cmp	$0, %ecx
-	ja	LABEL(loop_ashr_15_use_sse4_2)
+	ja	LABEL(nibble_ashr_15_use_sse4_2_restart)
 
 LABEL(nibble_ashr_use_sse4_2_exit):
 	pcmpistri      $0x1a,(%rsi,%rdx), %xmm0
