Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6d5155c2 authored by Markos Chandras's avatar Markos Chandras Committed by Ralf Baechle
Browse files

MIPS: lib: memset: Use macro to build the __bzero symbol



Build the __bzero symbol using a macor. In EVA mode we will
need to use similar code to do the userspace load operations so
it is better if we use a macro to avoid code duplications.

Signed-off-by: default avatarMarkos Chandras <markos.chandras@imgtec.com>
parent 8483b14a
Loading
Loading
Loading
Loading
+60 −35
Original line number Diff line number Diff line
@@ -34,6 +34,9 @@
#define FILLPTRG t0
#endif

#define LEGACY_MODE 1
#define EVA_MODE    2

#define EX(insn,reg,addr,handler)			\
9:	insn	reg, addr;				\
	.section __ex_table,"a";			\
@@ -63,33 +66,23 @@
#endif
	.endm

/*
 * memset(void *s, int c, size_t n)
 *
 * a0: start of area to clear
 * a1: char to fill with
 * a2: size of area to clear
 */
	.set	noreorder
	.align	5
LEAF(memset)
	beqz		a1, 1f
	move		v0, a0			/* result */

	andi		a1, 0xff		/* spread fillword */
	LONG_SLL		t1, a1, 8
	or		a1, t1
	LONG_SLL		t1, a1, 16
#if LONGSIZE == 8
	or		a1, t1
	LONG_SLL		t1, a1, 32
#endif
	or		a1, t1
1:
	/*
	 * Macro to generate the __bzero{,_user} symbol
	 * Arguments:
	 * mode: LEGACY_MODE or EVA_MODE
	 */
	.macro __BUILD_BZERO mode
	/* Initialize __memset if this is the first time we call this macro */
	.ifnotdef __memset
	.set __memset, 1
	.hidden __memset /* Make sure it does not leak */
	.endif

FEXPORT(__bzero)
	sltiu		t0, a2, STORSIZE	/* very small region? */
	bnez		t0, .Lsmall_memset
	bnez		t0, .Lsmall_memset\@
	andi		t0, a0, STORMASK	/* aligned? */

#ifdef CONFIG_CPU_MICROMIPS
@@ -109,28 +102,28 @@ FEXPORT(__bzero)

	R10KCBARRIER(0(ra))
#ifdef __MIPSEB__
	EX(LONG_S_L, a1, (a0), .Lfirst_fixup)	/* make word/dword aligned */
	EX(LONG_S_L, a1, (a0), .Lfirst_fixup\@)	/* make word/dword aligned */
#endif
#ifdef __MIPSEL__
	EX(LONG_S_R, a1, (a0), .Lfirst_fixup)	/* make word/dword aligned */
	EX(LONG_S_R, a1, (a0), .Lfirst_fixup\@)	/* make word/dword aligned */
#endif
	PTR_SUBU	a0, t0			/* long align ptr */
	PTR_ADDU	a2, t0			/* correct size */

1:	ori		t1, a2, 0x3f		/* # of full blocks */
	xori		t1, 0x3f
	beqz		t1, .Lmemset_partial	/* no block to fill */
	beqz		t1, .Lmemset_partial\@	/* no block to fill */
	andi		t0, a2, 0x40-STORSIZE

	PTR_ADDU	t1, a0			/* end address */
	.set		reorder
1:	PTR_ADDIU	a0, 64
	R10KCBARRIER(0(ra))
	f_fill64 a0, -64, FILL64RG, .Lfwd_fixup
	f_fill64 a0, -64, FILL64RG, .Lfwd_fixup\@
	bne		t1, a0, 1b
	.set		noreorder

.Lmemset_partial:
.Lmemset_partial\@:
	R10KCBARRIER(0(ra))
	PTR_LA		t1, 2f			/* where to start */
#ifdef CONFIG_CPU_MICROMIPS
@@ -150,7 +143,8 @@ FEXPORT(__bzero)
	.set		push
	.set		noreorder
	.set		nomacro
	f_fill64 a0, -64, FILL64RG, .Lpartial_fixup	/* ... but first do longs ... */
	/* ... but first do longs ... */
	f_fill64 a0, -64, FILL64RG, .Lpartial_fixup\@
2:	.set		pop
	andi		a2, STORMASK		/* At most one long to go */

@@ -158,15 +152,15 @@ FEXPORT(__bzero)
	PTR_ADDU	a0, a2			/* What's left */
	R10KCBARRIER(0(ra))
#ifdef __MIPSEB__
	EX(LONG_S_R, a1, -1(a0), .Llast_fixup)
	EX(LONG_S_R, a1, -1(a0), .Llast_fixup\@)
#endif
#ifdef __MIPSEL__
	EX(LONG_S_L, a1, -1(a0), .Llast_fixup)
	EX(LONG_S_L, a1, -1(a0), .Llast_fixup\@)
#endif
1:	jr		ra
	move		a2, zero

.Lsmall_memset:
.Lsmall_memset\@:
	beqz		a2, 2f
	PTR_ADDU	t1, a0, a2

@@ -177,13 +171,17 @@ FEXPORT(__bzero)

2:	jr		ra			/* done */
	move		a2, zero
	.if __memset == 1
	END(memset)
	.set __memset, 0
	.hidden __memset
	.endif

.Lfirst_fixup:
.Lfirst_fixup\@:
	jr	ra
	nop

.Lfwd_fixup:
.Lfwd_fixup\@:
	PTR_L		t0, TI_TASK($28)
	andi		a2, 0x3f
	LONG_L		t0, THREAD_BUADDR(t0)
@@ -191,7 +189,7 @@ FEXPORT(__bzero)
	jr		ra
	LONG_SUBU	a2, t0

.Lpartial_fixup:
.Lpartial_fixup\@:
	PTR_L		t0, TI_TASK($28)
	andi		a2, STORMASK
	LONG_L		t0, THREAD_BUADDR(t0)
@@ -199,6 +197,33 @@ FEXPORT(__bzero)
	jr		ra
	LONG_SUBU	a2, t0

.Llast_fixup:
.Llast_fixup\@:
	jr		ra
	andi		v1, a2, STORMASK

	.endm

/*
 * memset(void *s, int c, size_t n)
 *
 * a0: start of area to clear
 * a1: char to fill with
 * a2: size of area to clear
 */

LEAF(memset)
	beqz		a1, 1f
	move		v0, a0			/* result */

	andi		a1, 0xff		/* spread fillword */
	LONG_SLL		t1, a1, 8
	or		a1, t1
	LONG_SLL		t1, a1, 16
#if LONGSIZE == 8
	or		a1, t1
	LONG_SLL		t1, a1, 32
#endif
	or		a1, t1
1:
FEXPORT(__bzero)
	__BUILD_BZERO LEGACY_MODE