#
# memset(void *s1, int c, int len)
#
	.type	memset, @function
memset:	.globl  memset
	.set	noreorder
	.set	noat

        slti    $at, $a2, 12		# small amount to clear?
        bnez    $at, smallclr
	move	$v0, $a0		# save s1 for result

	sll	$t1, $a1, 8		# compute  c << 8 in t1
	or	$t1, $t1, $a1		# compute c << 8 | c in 11
	sll	$t2, $t1, 16		# shift that left 16
	or	$t1, $t2, $t1		# or together

	subu	$t0, $zero, $a0		# compute # bytes to word align address
	andi	$t0, $t0, 3
	beqz	$t0, 1f			# skip if word aligned
	subu	$a2, $a2, $t0		# subtract from remaining count
	SWHI	$t1, 0($a0)		# store 1, 2, or 3 bytes to align
	addu	$a0, $a0, $t0
1:
	andi	$v1, $a2, 3		# compute number of whole words left
	subu	$t0, $a2, $v1
	subu	$a2, $a2, $t0
	addu	$t0, $t0, $a0		# compute ending address
2:
	addiu	$a0, $a0, 4		# clear words
	bne	$a0, $t0, 2b		#  unrolling loop does not help
	sw	$t1, -4($a0)		#  since we are limited by memory speed

smallclr:
        blez    $a2, 2f
	addu	$t0, $a2, $a0		# compute ending address
1:
	addiu	$a0, $a0, 1		# clear bytes
	bne	$a0, $t0, 1b
	sb	$a1, -1($a0)
2:
	j	$ra
	nop
