mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 15:27:46 -04:00
179 lines
3.1 KiB
ArmAsm
179 lines
3.1 KiB
ArmAsm
|
|
@ vim:filetype=armasm
|
|
|
|
|
|
.global memcpy16 @ unsigned short *dest, unsigned short *src, int count
|
|
|
|
memcpy16:
|
|
eor r3, r0, r1
|
|
tst r3, #2
|
|
bne mcp16_cant_align
|
|
|
|
tst r0, #2
|
|
ldrneh r3, [r1], #2
|
|
subne r2, r2, #1
|
|
strneh r3, [r0], #2
|
|
|
|
subs r2, r2, #4
|
|
bmi mcp16_fin
|
|
|
|
mcp16_loop:
|
|
ldmia r1!, {r3,r12}
|
|
subs r2, r2, #4
|
|
stmia r0!, {r3,r12}
|
|
bpl mcp16_loop
|
|
|
|
mcp16_fin:
|
|
tst r2, #2
|
|
ldrne r3, [r1], #4
|
|
strne r3, [r0], #4
|
|
ands r2, r2, #1
|
|
bxeq lr
|
|
|
|
mcp16_cant_align:
|
|
ldrh r3, [r1], #2
|
|
subs r2, r2, #1
|
|
strh r3, [r0], #2
|
|
bne mcp16_cant_align
|
|
|
|
bx lr
|
|
|
|
|
|
|
|
@ 0x12345678 -> 0x34127856
|
|
@ r4=temp, lr=0x00ff00ff
|
|
.macro bswap reg
|
|
and r4, \reg, lr
|
|
and \reg, lr, \reg, lsr #8
|
|
orr \reg, \reg, r4, lsl #8
|
|
.endm
|
|
|
|
|
|
@ dest must be halfword aligned, src can be unaligned
|
|
.global memcpy16bswap @ unsigned short *dest, void *src, int count
|
|
|
|
memcpy16bswap:
|
|
tst r1, #1
|
|
bne mcp16bs_cant_align2
|
|
|
|
eor r3, r0, r1
|
|
tst r3, #2
|
|
bne mcp16bs_cant_align
|
|
|
|
tst r0, #2
|
|
beq mcp16bs_aligned
|
|
ldrh r3, [r1], #2
|
|
sub r2, r2, #1
|
|
orr r3, r3, r3, lsl #16
|
|
mov r3, r3, lsr #8
|
|
strh r3, [r0], #2
|
|
|
|
mcp16bs_aligned:
|
|
stmfd sp!, {r4,lr}
|
|
mov lr, #0xff
|
|
orr lr, lr, lr, lsl #16
|
|
|
|
subs r2, r2, #4
|
|
bmi mcp16bs_fin4
|
|
|
|
mcp16bs_loop:
|
|
ldmia r1!, {r3,r12}
|
|
subs r2, r2, #4
|
|
bswap r3
|
|
bswap r12
|
|
stmia r0!, {r3,r12}
|
|
bpl mcp16bs_loop
|
|
|
|
mcp16bs_fin4:
|
|
tst r2, #2
|
|
beq mcp16bs_fin2
|
|
ldr r3, [r1], #4
|
|
bswap r3
|
|
str r3, [r0], #4
|
|
|
|
mcp16bs_fin2:
|
|
ldmfd sp!, {r4,lr}
|
|
ands r2, r2, #1
|
|
bxeq lr
|
|
|
|
mcp16bs_cant_align:
|
|
ldrh r3, [r1], #2
|
|
subs r2, r2, #1
|
|
orr r3, r3, r3, lsl #16
|
|
mov r3, r3, lsr #8
|
|
strh r3, [r0], #2
|
|
bne mcp16bs_cant_align
|
|
bx lr
|
|
|
|
@ worst case
|
|
mcp16bs_cant_align2:
|
|
ldrb r3, [r1], #1
|
|
ldrb r12,[r1], #1
|
|
subs r2, r2, #1
|
|
mov r3, r3, lsl #8
|
|
orr r3, r3, r12
|
|
strh r3, [r0], #2
|
|
bne mcp16bs_cant_align2
|
|
bx lr
|
|
|
|
|
|
|
|
.global memcpy32 @ int *dest, int *src, int count
|
|
|
|
memcpy32:
|
|
stmfd sp!, {r4,lr}
|
|
|
|
subs r2, r2, #4
|
|
bmi mcp32_fin
|
|
|
|
mcp32_loop:
|
|
ldmia r1!, {r3,r4,r12,lr}
|
|
subs r2, r2, #4
|
|
stmia r0!, {r3,r4,r12,lr}
|
|
bpl mcp32_loop
|
|
|
|
mcp32_fin:
|
|
tst r2, #3
|
|
ldmeqfd sp!, {r4,pc}
|
|
tst r2, #1
|
|
ldrne r3, [r1], #4
|
|
strne r3, [r0], #4
|
|
|
|
mcp32_no_unal1:
|
|
tst r2, #2
|
|
ldmneia r1!, {r3,r12}
|
|
ldmfd sp!, {r4,lr}
|
|
stmneia r0!, {r3,r12}
|
|
bx lr
|
|
|
|
|
|
|
|
.global memset32 @ int *dest, int c, int count
|
|
|
|
memset32:
|
|
stmfd sp!, {lr}
|
|
|
|
mov r3, r1
|
|
subs r2, r2, #4
|
|
bmi mst32_fin
|
|
|
|
mov r12,r1
|
|
mov lr, r1
|
|
|
|
mst32_loop:
|
|
subs r2, r2, #4
|
|
stmia r0!, {r1,r3,r12,lr}
|
|
bpl mst32_loop
|
|
|
|
mst32_fin:
|
|
tst r2, #1
|
|
strne r1, [r0], #4
|
|
|
|
tst r2, #2
|
|
stmneia r0!, {r1,r3}
|
|
|
|
ldmfd sp!, {lr}
|
|
bx lr
|
|
|
|
|
|
|