diff --git a/sysdeps/aarch64/memcmp.S b/sysdeps/aarch64/memcmp.S
index 4cfcb89297551a07fcfa055827564b833e86f8fb..b99c081bba2c7f26b5b53315d6b806ae22eaaafc 100644
--- a/sysdeps/aarch64/memcmp.S
+++ b/sysdeps/aarch64/memcmp.S
@@ -22,132 +22,98 @@
Â 
Â /* Assumptions:
Â  *
- * ARMv8-a, AArch64
+ * ARMv8-a, AArch64, unaligned accesses.
Â  */
Â 
Â /* Parameters and result.Â  */
Â #define src1Â Â Â Â Â Â Â Â Â Â Â  x0
Â #define src2Â Â Â Â Â Â Â Â Â Â Â  x1
Â #define limitÂ Â Â Â Â Â Â Â Â Â  x2
-#define resultÂ Â Â Â Â Â Â Â  x0
+#define resultÂ Â Â Â Â Â Â Â  w0
Â 
Â /* Internal variables.Â  */
Â #define data1Â Â Â Â Â Â Â Â Â Â  x3
Â #define data1wÂ Â Â Â Â Â Â Â Â  w3
Â #define data2Â Â Â Â Â Â Â Â Â Â  x4
Â #define data2wÂ Â Â Â Â Â Â Â Â  w4
-#define has_nulÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â  x5
-#define diffÂ Â Â Â Â Â Â Â Â Â  x6
-#define endloopÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â  x7
-#define tmp1Â Â Â Â Â Â Â Â Â Â  x8
-#define tmp2Â Â Â Â Â Â Â Â Â Â  x9
-#define tmp3Â Â Â Â Â Â Â Â Â Â  x10
-#define posÂ Â Â Â Â Â Â Â Â Â Â  x11
-#define limit_wdÂ Â Â Â Â Â  x12
-#define maskÂ Â Â Â Â Â Â Â Â Â  x13
+#define tmp1Â Â Â Â Â Â Â Â Â Â  x5
Â 
Â ENTRY_ALIGN (memcmp, 6)
Â Â Â Â Â Â Â Â  DELOUSE (0)
Â Â Â Â Â Â Â Â  DELOUSE (1)
Â Â Â Â Â Â Â Â  DELOUSE (2)
-Â Â Â Â Â Â  cbzÂ Â Â Â  limit, L(ret0)
-Â Â Â Â Â Â  eorÂ Â Â Â  tmp1, src1, src2
-Â Â Â Â Â Â  tstÂ Â Â Â  tmp1, #7
-Â Â Â Â Â Â  b.neÂ Â Â  L(misaligned8)
-Â Â Â Â Â Â  andsÂ Â Â  tmp1, src1, #7
-Â Â Â Â Â Â  b.neÂ Â Â  L(mutual_align)
-Â Â Â Â Â Â  addÂ Â Â Â  limit_wd, limit, #7
-Â Â Â Â Â Â  lsrÂ Â Â Â  limit_wd, limit_wd, #3
-Â Â Â Â Â Â  /* Start of performance-critical sectionÂ  -- one 64B cache line.Â  */
-L(loop_aligned):
-Â Â Â Â Â Â  ldrÂ Â Â Â  data1, [src1], #8
-Â Â Â Â Â Â  ldrÂ Â Â Â  data2, [src2], #8
-L(start_realigned):
-Â Â Â Â Â Â  subsÂ Â Â  limit_wd, limit_wd, #1
-Â Â Â Â Â Â  eorÂ Â Â Â  diff, data1, data2Â Â Â Â Â  /* Non-zero if differences found.Â  */
-Â Â Â Â Â Â  csinvÂ Â  endloop, diff, xzr, neÂ  /* Last Dword or differences.Â  */
-Â Â Â Â Â Â  cbzÂ Â Â Â  endloop, L(loop_aligned)
-Â Â Â Â Â Â  /* End of performance-critical sectionÂ  -- one 64B cache line.Â  */
-
-Â Â Â Â Â Â  /* Not reached the limit, must have found a diff.Â  */
-Â Â Â Â Â Â  cbnzÂ Â Â  limit_wd, L(not_limit)
-
-Â Â Â Â Â Â  /* Limit % 8 == 0 => all bytes significant.Â  */
-Â Â Â Â Â Â  andsÂ Â Â  limit, limit, #7
-Â Â Â Â Â Â  b.eqÂ Â Â  L(not_limit)
-
-Â Â Â Â Â Â  lslÂ Â Â Â  limit, limit, #3Â Â Â Â Â Â Â  /* Bits -> bytes.Â  */
-Â Â Â Â Â Â  movÂ Â Â Â  mask, #~0
-#ifdef __AARCH64EB__
-Â Â Â Â Â Â  lsrÂ Â Â Â  mask, mask, limit
-#else
-Â Â Â Â Â Â  lslÂ Â Â Â  mask, mask, limit
-#endif
-Â Â Â Â Â Â  bicÂ Â Â Â  data1, data1, mask
-Â Â Â Â Â Â  bicÂ Â Â Â  data2, data2, mask
-
-Â Â Â Â Â Â  orrÂ Â Â Â  diff, diff, mask
-L(not_limit):
Â 
-#ifndefÂ Â Â Â Â Â Â  __AARCH64EB__
-Â Â Â Â Â Â  revÂ Â Â Â  diff, diff
+Â Â Â Â Â Â  subsÂ Â Â  limit, limit, 8
+Â Â Â Â Â Â  b.loÂ Â Â  .Lless8
+
+Â Â Â Â Â Â  /* Limit >= 8, so check first 8 bytes using unaligned loads.Â  */
+Â Â Â Â Â Â  ldrÂ Â Â Â  data1, [src1], 8
+Â Â Â Â Â Â  ldrÂ Â Â Â  data2, [src2], 8
+Â Â Â Â Â Â  andÂ Â Â Â  tmp1, src1, 7
+Â Â Â Â Â Â  addÂ Â Â Â  limit, limit, tmp1
+Â Â Â Â Â Â  cmpÂ Â Â Â  data1, data2
+Â Â Â Â Â Â  bneÂ Â Â Â  .Lreturn
+
+Â Â Â Â Â Â  /* Align src1 and adjust src2 with bytes not yet done.Â  */
+Â Â Â Â Â Â  subÂ Â Â Â  src1, src1, tmp1
+Â Â Â Â Â Â  subÂ Â Â Â  src2, src2, tmp1
+
+Â Â Â Â Â Â  subsÂ Â Â  limit, limit, 8
+Â Â Â Â Â Â  b.lsÂ Â Â  .Llast_bytes
+
+Â Â Â Â Â Â  /* Loop performing 8 bytes per iteration using aligned src1.
+Â Â Â Â Â Â Â Â Â  Limit is pre-decremented by 8 and must be larger than zero.
+Â Â Â Â Â Â Â Â Â  Exit if <= 8 bytes left to do or if the data is not equal.Â  */
+Â Â Â Â Â Â  .p2align 4
+.Lloop8:
+Â Â Â Â Â Â  ldrÂ Â Â Â  data1, [src1], 8
+Â Â Â Â Â Â  ldrÂ Â Â Â  data2, [src2], 8
+Â Â Â Â Â Â  subsÂ Â Â  limit, limit, 8
+Â Â Â Â Â Â  ccmpÂ Â Â  data1, data2, 0, hiÂ  /* NZCV = 0b0000.Â  */
+Â Â Â Â Â Â  b.eqÂ Â Â  .Lloop8
+
+Â Â Â Â Â Â  cmpÂ Â Â Â  data1, data2
+Â Â Â Â Â Â  bneÂ Â Â Â  .Lreturn
+
+Â Â Â Â Â Â  /* Compare last 1-8 bytes using unaligned access.Â  */
+.Llast_bytes:
+Â Â Â Â Â Â  ldrÂ Â Â Â  data1, [src1, limit]
+Â Â Â Â Â Â  ldrÂ Â Â Â  data2, [src2, limit]
+
+Â Â Â Â Â Â  /* Compare data bytes and set return value to 0, -1 or 1.Â  */
+.Lreturn:
+#ifndef __AARCH64EB__
Â Â Â Â Â Â Â Â  revÂ Â Â Â  data1, data1
Â Â Â Â Â Â Â Â  revÂ Â Â Â  data2, data2
Â #endif
-Â Â Â Â Â Â  /* The MS-non-zero bit of DIFF marks either the first bit
-Â Â Â Â Â Â Â Â Â  that is different, or the end of the significant data.
-Â Â Â Â Â Â Â Â Â  Shifting left now will bring the critical information into the
-Â Â Â Â Â Â Â Â Â  top bits.Â  */
-Â Â Â Â Â Â  clzÂ Â Â Â  pos, diff
-Â Â Â Â Â Â  lslÂ Â Â Â  data1, data1, pos
-Â Â Â Â Â Â  lslÂ Â Â Â  data2, data2, pos
-Â Â Â Â Â Â  /* But we need to zero-extend (char is unsigned) the value and then
-Â Â Â Â Â Â Â Â Â  perform a signed 32-bit subtraction.Â  */
-Â Â Â Â Â Â  lsrÂ Â Â Â  data1, data1, #56
-Â Â Â Â Â Â  subÂ Â Â Â  result, data1, data2, lsr #56
-Â Â Â Â Â Â  RET
-
-L(mutual_align):
-Â Â Â Â Â Â  /* Sources are mutually aligned, but are not currently at an
-Â Â Â Â Â Â Â Â Â  alignment boundary.Â  Round down the addresses and then mask off
-Â Â Â Â Â Â Â Â Â  the bytes that precede the start point.Â  */
-Â Â Â Â Â Â  bicÂ Â Â Â  src1, src1, #7
-Â Â Â Â Â Â  bicÂ Â Â Â  src2, src2, #7
-Â Â Â Â Â Â  addÂ Â Â Â  limit, limit, tmp1Â Â Â Â Â  /* Adjust the limit for the extra.Â  */
-Â Â Â Â Â Â  lslÂ Â Â Â  tmp1, tmp1, #3Â Â Â Â Â Â Â Â Â  /* Bytes beyond alignment -> bits.Â  */
-Â Â Â Â Â Â  ldrÂ Â Â Â  data1, [src1], #8
-Â Â Â Â Â Â  negÂ Â Â Â  tmp1, tmp1Â Â Â Â Â Â Â Â Â Â Â Â Â  /* Bits to alignment -64.Â  */
-Â Â Â Â Â Â  ldrÂ Â Â Â  data2, [src2], #8
-Â Â Â Â Â Â  movÂ Â Â Â  tmp2, #~0
-#ifdef __AARCH64EB__
-Â Â Â Â Â Â  /* Big-endian.Â  Early bytes are at MSB.Â  */
-Â Â Â Â Â Â  lslÂ Â Â Â  tmp2, tmp2, tmp1Â Â Â Â Â Â Â  /* Shift (tmp1 & 63).Â  */
-#else
-Â Â Â Â Â Â  /* Little-endian.Â  Early bytes are at LSB.Â  */
-Â Â Â Â Â Â  lsrÂ Â Â Â  tmp2, tmp2, tmp1Â Â Â Â Â Â Â  /* Shift (tmp1 & 63).Â  */
-#endif
-Â Â Â Â Â Â  addÂ Â Â Â  limit_wd, limit, #7
-Â Â Â Â Â Â  orrÂ Â Â Â  data1, data1, tmp2
-Â Â Â Â Â Â  orrÂ Â Â Â  data2, data2, tmp2
-Â Â Â Â Â Â  lsrÂ Â Â Â  limit_wd, limit_wd, #3
-Â Â Â Â Â Â  bÂ Â Â Â Â Â  L(start_realigned)
-
-L(ret0):
-Â Â Â Â Â Â  movÂ Â Â Â  result, #0
-Â Â Â Â Â Â  RET
-
-Â Â Â Â Â Â  .p2align 6
-L(misaligned8):
-Â Â Â Â Â Â  subÂ Â Â Â  limit, limit, #1
-1:
-Â Â Â Â Â Â  /* Perhaps we can do better than this.Â  */
-Â Â Â Â Â Â  ldrbÂ Â Â  data1w, [src1], #1
-Â Â Â Â Â Â  ldrbÂ Â Â  data2w, [src2], #1
-Â Â Â Â Â Â  subsÂ Â Â  limit, limit, #1
-Â Â Â Â Â Â  ccmpÂ Â Â  data1w, data2w, #0, csÂ  /* NZCV = 0b0000.Â  */
-Â Â Â Â Â Â  b.eqÂ Â Â  1b
-Â Â Â Â Â Â  subÂ Â Â Â  result, data1, data2
-Â Â Â Â Â Â  RET
+Â Â Â Â Â Â  cmpÂ Â Â Â  data1, data2
+.Lret_eq:
+Â Â Â Â Â Â  csetÂ Â Â  result, ne
+Â Â Â Â Â Â  cnegÂ Â Â  result, result, lo
+Â Â Â Â Â Â  ret
+
+Â Â Â Â Â Â  .p2align 4
+Â Â Â Â Â Â  /* Compare up to 8 bytes.Â  Limit is [-8..-1].Â  */
+.Lless8:
+Â Â Â Â Â Â  addsÂ Â Â  limit, limit, 4
+Â Â Â Â Â Â  b.loÂ Â Â  .Lless4
+Â Â Â Â Â Â  ldrÂ Â Â Â  data1w, [src1], 4
+Â Â Â Â Â Â  ldrÂ Â Â Â  data2w, [src2], 4
+Â Â Â Â Â Â  cmpÂ Â Â Â  data1w, data2w
+Â Â Â Â Â Â  b.neÂ Â Â  .Lreturn
+Â Â Â Â Â Â  subÂ Â Â Â  limit, limit, 4
+.Lless4:
+Â Â Â Â Â Â  addsÂ Â Â  limit, limit, 4
+Â Â Â Â Â Â  beqÂ Â Â Â  .Lret_eq
+.Lbyte_loop:
+Â Â Â Â Â Â  ldrbÂ Â Â  data1w, [src1], 1
+Â Â Â Â Â Â  ldrbÂ Â Â  data2w, [src2], 1
+Â Â Â Â Â Â  subsÂ Â Â  limit, limit, 1
+Â Â Â Â Â Â  ccmpÂ Â Â  data1w, data2w, 0, neÂ Â  /* NZCV = 0b0000.Â  */
+Â Â Â Â Â Â  b.eqÂ Â Â  .Lbyte_loop
+Â Â Â Â Â Â  subÂ Â Â Â  result, data1w, data2w
+Â Â Â Â Â Â  ret
+
Â END (memcmp)
Â #undef bcmp
Â weak_alias (memcmp, bcmp)
