espressif_tinyusb/hw/mcu/allwinner/f1c100s/lib/memset.S

80 lines
2.0 KiB
ArmAsm

/*
* memcpy.S
*/
.text
.global memset
.type memset, %function
.align 4
memset:
stmfd sp!, {r0} /* remember address for return value */
and r1, r1, #0x000000ff /* we write bytes */
cmp r2, #0x00000004 /* do we have less than 4 bytes */
blt .Lmemset_lessthanfour
/* first we will word align the address */
ands r3, r0, #0x00000003 /* get the bottom two bits */
beq .Lmemset_addraligned /* the address is word aligned */
rsb r3, r3, #0x00000004
sub r2, r2, r3
cmp r3, #0x00000002
strb r1, [r0], #0x0001 /* set 1 byte */
strgeb r1, [r0], #0x0001 /* set another byte */
strgtb r1, [r0], #0x0001 /* and a third */
cmp r2, #0x00000004
blt .Lmemset_lessthanfour
/* now we must be word aligned */
.Lmemset_addraligned:
orr r3, r1, r1, lsl #8 /* repeat the byte into a word */
orr r3, r3, r3, lsl #16
/* we know we have at least 4 bytes ... */
cmp r2, #0x00000020 /* if less than 32 then use words */
blt .Lmemset_lessthan32
/* we have at least 32 so lets use quad words */
stmfd sp!, {r4-r6} /* store registers */
mov r4, r3 /* duplicate data */
mov r5, r3
mov r6, r3
.Lmemset_loop16:
stmia r0!, {r3-r6} /* store 16 bytes */
sub r2, r2, #0x00000010 /* adjust count */
cmp r2, #0x00000010 /* still got at least 16 bytes ? */
bgt .Lmemset_loop16
ldmfd sp!, {r4-r6} /* restore registers */
/* do we need to set some words as well ? */
cmp r2, #0x00000004
blt .Lmemset_lessthanfour
/* have either less than 16 or less than 32 depending on route taken */
.Lmemset_lessthan32:
/* we have at least 4 bytes so copy as words */
.Lmemset_loop4:
str r3, [r0], #0x0004
sub r2, r2, #0x0004
cmp r2, #0x00000004
bge .Lmemset_loop4
.Lmemset_lessthanfour:
cmp r2, #0x00000000
ldmeqfd sp!, {r0}
moveq pc, lr /* zero length so exit */
cmp r2, #0x00000002
strb r1, [r0], #0x0001 /* set 1 byte */
strgeb r1, [r0], #0x0001 /* set another byte */
strgtb r1, [r0], #0x0001 /* and a third */
ldmfd sp!, {r0}
mov pc, lr /* exit */