mirror of
https://github.com/hathach/tinyusb.git
synced 2025-04-16 23:43:23 +00:00
80 lines
2.0 KiB
ArmAsm
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 */
|