This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[Patch, MIPS] Modify memset.S for mips32r6/mips64r6
- From: "Steve Ellcey " <sellcey at imgtec dot com>
- To: <libc-alpha at sourceware dot org>
- Date: Fri, 19 Dec 2014 15:26:44 -0800
- Subject: [Patch, MIPS] Modify memset.S for mips32r6/mips64r6
- Authentication-results: sourceware.org; auth=none
Here is the last of my patches for mips32r6/mips64r6 support. It updates
memset to use byte copies instead of stl or str to align the destination
because those instructions are not supported in mips32r6 or mips64r6.
It also avoids using the 'prepare for store' prefetch hint because that
is not supported on mips32r6 or mips64r6 either.
Tested with the mips32r6/mips64r6 GCC, binutils and qemu simulator.
OK to checkin?
Steve Ellcey
sellcey@imgtec.com
2014-12-19 Steve Ellcey <sellcey@imgtec.com>
* sysdeps/mips/memset.S (memset): Modify for mips32r6/mips64r6
to avoid using stl/str to align destination.
diff --git a/sysdeps/mips/memset.S b/sysdeps/mips/memset.S
index 9991480..4cc6dd7 100644
--- a/sysdeps/mips/memset.S
+++ b/sysdeps/mips/memset.S
@@ -54,6 +54,14 @@
# endif
#endif
+#if __mips_isa_rev > 5
+# if (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE)
+# undef PREFETCH_STORE_HINT
+# define PREFETCH_STORE_HINT PREFETCH_HINT_STORE_STREAMED
+# endif
+# define R6_CODE
+#endif
+
/* Some asm.h files do not have the L macro definition. */
#ifndef L
# if _MIPS_SIM == _ABIO32
@@ -72,6 +80,15 @@
# endif
#endif
+/* New R6 instructions that may not be in asm.h. */
+#ifndef PTR_LSA
+# if _MIPS_SIM == _ABI64
+# define PTR_LSA dlsa
+# else
+# define PTR_LSA lsa
+# endif
+#endif
+
/* Using PREFETCH_HINT_PREPAREFORSTORE instead of PREFETCH_STORE
or PREFETCH_STORE_STREAMED offers a large performance advantage
but PREPAREFORSTORE has some special restrictions to consider.
@@ -188,9 +205,9 @@ LEAF(MEMSET_NAME)
.set nomips16
.set noreorder
-/* If the size is less than 2*NSIZE (8 or 16), go to L(lastb). Regardless of
+/* If the size is less than 4*NSIZE (16 or 32), go to L(lastb). Regardless of
size, copy dst pointer to v0 for the return value. */
- slti t2,a2,(2 * NSIZE)
+ slti t2,a2,(4 * NSIZE)
bne t2,zero,L(lastb)
move v0,a0
@@ -231,11 +248,46 @@ LEAF(MEMSET_NAME)
/* If the destination address is not aligned do a partial store to get it
aligned. If it is already aligned just jump to L(aligned). */
L(set0):
+#if !defined (R6_CODE)
andi t2,a3,(NSIZE-1) /* word-unaligned address? */
beq t2,zero,L(aligned) /* t2 is the unalignment count */
PTR_SUBU a2,a2,t2
C_STHI a1,0(a0)
PTR_ADDU a0,a0,t2
+#else /* R6_CODE */
+ andi t2,a0,7
+ lapc t9,L(atable)
+ PTR_LSA t9,t2,t9,2
+ jrc t9
+L(atable):
+ bc L(aligned)
+ bc L(lb7)
+ bc L(lb6)
+ bc L(lb5)
+ bc L(lb4)
+ bc L(lb3)
+ bc L(lb2)
+ bc L(lb1)
+L(lb7):
+ sb a1,6(a0)
+L(lb6):
+ sb a1,5(a0)
+L(lb5):
+ sb a1,4(a0)
+L(lb4):
+ sb a1,3(a0)
+L(lb3):
+ sb a1,2(a0)
+L(lb2):
+ sb a1,1(a0)
+L(lb1):
+ sb a1,0(a0)
+
+ li t9,8
+ subu t2,t9,t2
+ PTR_SUBU a2,a2,t2
+ PTR_ADDU a0,a0,t2
+#endif /* R6_CODE */
L(aligned):
/* If USE_DOUBLE is not set we may still want to align the data on a 16
@@ -286,8 +338,12 @@ L(loop16w):
bgtz v1,L(skip_pref)
nop
#endif
+#if defined(R6_CODE)
+ PREFETCH_FOR_STORE (2, a0)
+#else
PREFETCH_FOR_STORE (4, a0)
PREFETCH_FOR_STORE (5, a0)
+#endif
L(skip_pref):
C_ST a1,UNIT(0)(a0)
C_ST a1,UNIT(1)(a0)