This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch, MIPS] Modify memset.S for mips32r6/mips64r6


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)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]