RCSID("$NetBSD: bcopyinout_xscale.S,v 1.12 2022/10/20 06:58:38 skrll Exp $")
.text
.align 0
ENTRY(copyin)
cmp r2, #0x00
movle r0, #0x00
RETc(le)
push {r10-r11, lr}
GET_CURPCB(r10)
mov r3, #0x00
adr ip, .Lcopyin_fault
ldr r11, [r10, #PCB_ONFAULT]
str ip, [r10, #PCB_ONFAULT]
bl .Lcopyin_guts
str r11, [r10, #PCB_ONFAULT]
mov r0, #0x00
pop {r10-r11, pc}
.Lcopyin_fault:
str r11, [r10, #PCB_ONFAULT]
cmp r3, #0x00
popgt {r4-r7}
poplt {r4-r9}
pop {r10-r11, pc}
.Lcopyin_guts:
pld [r0]
ands ip, r1, #0x03
beq .Lcopyin_wordaligned
rsb ip, ip, #0x04
cmp r2, ip
blt .Lcopyin_l4_2
sub r2, r2, ip
rsbs ip, ip, #0x03
addne pc, pc, ip, lsl #3
nop
ldrbt ip, [r0], #0x01
strb ip, [r1], #0x01
ldrbt ip, [r0], #0x01
strb ip, [r1], #0x01
ldrbt ip, [r0], #0x01
strb ip, [r1], #0x01
cmp r2, #0x00
RETc(eq)
.Lcopyin_wordaligned:
ands ip, r0, #0x03
bne .Lcopyin_bad_align
cmp r2, #0x08
blt .Lcopyin_w_less_than8
tst r1, #0x07
ldrtne ip, [r0], #0x04
push {r4-r9}
mov r3, #-1
tst r1, #0x07
subne r2, r2, #0x04
strne ip, [r1], #0x04
subs r2, r2, #0x80
blt .Lcopyin_w_lessthan128
.Lcopyin_w_loop128:
ldrt r4, [r0], #0x04
ldrt r5, [r0], #0x04
pld [r0, #0x18]
ldrt r6, [r0], #0x04
ldrt r7, [r0], #0x04
ldrt r8, [r0], #0x04
ldrt r9, [r0], #0x04
strd r4, r5, [r1], #0x08
ldrt r4, [r0], #0x04
ldrt r5, [r0], #0x04
strd r6, r7, [r1], #0x08
ldrt r6, [r0], #0x04
ldrt r7, [r0], #0x04
pld [r0, #0x18]
strd r8, r9, [r1], #0x08
ldrt r8, [r0], #0x04
ldrt r9, [r0], #0x04
strd r4, r5, [r1], #0x08
ldrt r4, [r0], #0x04
ldrt r5, [r0], #0x04
strd r6, r7, [r1], #0x08
ldrt r6, [r0], #0x04
ldrt r7, [r0], #0x04
strd r8, r9, [r1], #0x08
ldrt r8, [r0], #0x04
ldrt r9, [r0], #0x04
pld [r0, #0x18]
strd r4, r5, [r1], #0x08
ldrt r4, [r0], #0x04
ldrt r5, [r0], #0x04
strd r6, r7, [r1], #0x08
ldrt r6, [r0], #0x04
ldrt r7, [r0], #0x04
strd r8, r9, [r1], #0x08
ldrt r8, [r0], #0x04
ldrt r9, [r0], #0x04
strd r4, r5, [r1], #0x08
ldrt r4, [r0], #0x04
ldrt r5, [r0], #0x04
pld [r0, #0x18]
strd r6, r7, [r1], #0x08
ldrt r6, [r0], #0x04
ldrt r7, [r0], #0x04
strd r8, r9, [r1], #0x08
ldrt r8, [r0], #0x04
ldrt r9, [r0], #0x04
strd r4, r5, [r1], #0x08
ldrt r4, [r0], #0x04
ldrt r5, [r0], #0x04
strd r6, r7, [r1], #0x08
strd r8, r9, [r1], #0x08
subs r2, r2, #0x80
strd r4, r5, [r1], #0x08
bge .Lcopyin_w_loop128
.Lcopyin_w_lessthan128:
adds r2, r2, #0x80
popeq {r4-r9}
RETc(eq)
subs r2, r2, #0x20
blt .Lcopyin_w_lessthan32
.Lcopyin_w_loop32:
ldrt r4, [r0], #0x04
ldrt r5, [r0], #0x04
pld [r0, #0x18]
ldrt r6, [r0], #0x04
ldrt r7, [r0], #0x04
ldrt r8, [r0], #0x04
ldrt r9, [r0], #0x04
strd r4, r5, [r1], #0x08
ldrt r4, [r0], #0x04
ldrt r5, [r0], #0x04
strd r6, r7, [r1], #0x08
strd r8, r9, [r1], #0x08
subs r2, r2, #0x20
strd r4, r5, [r1], #0x08
bge .Lcopyin_w_loop32
.Lcopyin_w_lessthan32:
adds r2, r2, #0x20
popeq {r4-r9}
RETc(eq)
and r4, r2, #0x18
rsb r5, r4, #0x18
subs r2, r2, r4
add pc, pc, r5, lsl #1
nop
ldrt r4, [r0], #0x04
ldrt r5, [r0], #0x04
nop
strd r4, r5, [r1], #0x08
ldrt r4, [r0], #0x04
ldrt r5, [r0], #0x04
nop
strd r4, r5, [r1], #0x08
ldrt r4, [r0], #0x04
ldrt r5, [r0], #0x04
nop
strd r4, r5, [r1], #0x08
pop {r4-r9}
RETc(eq)
mov r3, #0x00
.Lcopyin_w_less_than8:
subs r2, r2, #0x04
ldrtge ip, [r0], #0x04
strge ip, [r1], #0x04
RETc(eq)
addlt r2, r2, #0x04
ldrbt ip, [r0], #0x01
cmp r2, #0x02
ldrbtge r2, [r0], #0x01
strb ip, [r1], #0x01
ldrbtgt ip, [r0]
strbge r2, [r1], #0x01
strbgt ip, [r1]
RET
.Lcopyin_bad_align:
push {r4-r7}
mov r3, #0x01
bic r0, r0, #0x03
cmp ip, #2
ldrt ip, [r0], #0x04
bgt .Lcopyin_bad3
beq .Lcopyin_bad2
b .Lcopyin_bad1
.Lcopyin_bad1_loop16:
#ifdef __ARMEB__
mov r4, ip, lsl #8
#else
mov r4, ip, lsr #8
#endif
ldrt r5, [r0], #0x04
pld [r0, #0x018]
ldrt r6, [r0], #0x04
ldrt r7, [r0], #0x04
ldrt ip, [r0], #0x04
#ifdef __ARMEB__
orr r4, r4, r5, lsr #24
mov r5, r5, lsl #8
orr r5, r5, r6, lsr #24
mov r6, r6, lsl #8
orr r6, r6, r7, lsr #24
mov r7, r7, lsl #8
orr r7, r7, ip, lsr #24
#else
orr r4, r4, r5, lsl #24
mov r5, r5, lsr #8
orr r5, r5, r6, lsl #24
mov r6, r6, lsr #8
orr r6, r6, r7, lsl #24
mov r7, r7, lsr #8
orr r7, r7, ip, lsl #24
#endif
str r4, [r1], #0x04
str r5, [r1], #0x04
str r6, [r1], #0x04
str r7, [r1], #0x04
.Lcopyin_bad1:
subs r2, r2, #0x10
bge .Lcopyin_bad1_loop16
adds r2, r2, #0x10
popeq {r4-r7}
RETc(eq)
subs r2, r2, #0x04
sublt r0, r0, #0x03
blt .Lcopyin_l4
.Lcopyin_bad1_loop4:
#ifdef __ARMEB__
mov r4, ip, lsl #8
#else
mov r4, ip, lsr #8
#endif
ldrt ip, [r0], #0x04
subs r2, r2, #0x04
#ifdef __ARMEB__
orr r4, r4, ip, lsr #24
#else
orr r4, r4, ip, lsl #24
#endif
str r4, [r1], #0x04
bge .Lcopyin_bad1_loop4
sub r0, r0, #0x03
b .Lcopyin_l4
.Lcopyin_bad2_loop16:
#ifdef __ARMEB__
mov r4, ip, lsl #16
#else
mov r4, ip, lsr #16
#endif
ldrt r5, [r0], #0x04
pld [r0, #0x018]
ldrt r6, [r0], #0x04
ldrt r7, [r0], #0x04
ldrt ip, [r0], #0x04
#ifdef __ARMEB__
orr r4, r4, r5, lsr #16
mov r5, r5, lsl #16
orr r5, r5, r6, lsr #16
mov r6, r6, lsl #16
orr r6, r6, r7, lsr #16
mov r7, r7, lsl #16
orr r7, r7, ip, lsr #16
#else
orr r4, r4, r5, lsl #16
mov r5, r5, lsr #16
orr r5, r5, r6, lsl #16
mov r6, r6, lsr #16
orr r6, r6, r7, lsl #16
mov r7, r7, lsr #16
orr r7, r7, ip, lsl #16
#endif
str r4, [r1], #0x04
str r5, [r1], #0x04
str r6, [r1], #0x04
str r7, [r1], #0x04
.Lcopyin_bad2:
subs r2, r2, #0x10
bge .Lcopyin_bad2_loop16
adds r2, r2, #0x10
popeq {r4-r7}
RETc(eq)
subs r2, r2, #0x04
sublt r0, r0, #0x02
blt .Lcopyin_l4
.Lcopyin_bad2_loop4:
#ifdef __ARMEB__
mov r4, ip, lsl #16
#else
mov r4, ip, lsr #16
#endif
ldrt ip, [r0], #0x04
subs r2, r2, #0x04
#ifdef __ARMEB__
orr r4, r4, ip, lsr #16
#else
orr r4, r4, ip, lsl #16
#endif
str r4, [r1], #0x04
bge .Lcopyin_bad2_loop4
sub r0, r0, #0x02
b .Lcopyin_l4
.Lcopyin_bad3_loop16:
#ifdef __ARMEB__
mov r4, ip, lsl #24
#else
mov r4, ip, lsr #24
#endif
ldrt r5, [r0], #0x04
pld [r0, #0x018]
ldrt r6, [r0], #0x04
ldrt r7, [r0], #0x04
ldrt ip, [r0], #0x04
#ifdef __ARMEB__
orr r4, r4, r5, lsr #8
mov r5, r5, lsl #24
orr r5, r5, r6, lsr #8
mov r6, r6, lsl #24
orr r6, r6, r7, lsr #8
mov r7, r7, lsl #24
orr r7, r7, ip, lsr #8
#else
orr r4, r4, r5, lsl #8
mov r5, r5, lsr #24
orr r5, r5, r6, lsl #8
mov r6, r6, lsr #24
orr r6, r6, r7, lsl #8
mov r7, r7, lsr #24
orr r7, r7, ip, lsl #8
#endif
str r4, [r1], #0x04
str r5, [r1], #0x04
str r6, [r1], #0x04
str r7, [r1], #0x04
.Lcopyin_bad3:
subs r2, r2, #0x10
bge .Lcopyin_bad3_loop16
adds r2, r2, #0x10
popeq {r4-r7}
RETc(eq)
subs r2, r2, #0x04
sublt r0, r0, #0x01
blt .Lcopyin_l4
.Lcopyin_bad3_loop4:
#ifdef __ARMEB__
mov r4, ip, lsl #24
#else
mov r4, ip, lsr #24
#endif
ldrt ip, [r0], #0x04
subs r2, r2, #0x04
#ifdef __ARMEB__
orr r4, r4, ip, lsr #8
#else
orr r4, r4, ip, lsl #8
#endif
str r4, [r1], #0x04
bge .Lcopyin_bad3_loop4
sub r0, r0, #0x01
.Lcopyin_l4:
pop {r4-r7}
mov r3, #0x00
adds r2, r2, #0x04
RETc(eq)
.Lcopyin_l4_2:
rsbs r2, r2, #0x03
addne pc, pc, r2, lsl #3
nop
ldrbt ip, [r0], #0x01
strb ip, [r1], #0x01
ldrbt ip, [r0], #0x01
strb ip, [r1], #0x01
ldrbt ip, [r0]
strb ip, [r1]
RET
END(copyin)
ENTRY(copyout)
cmp r2, #0x00
movle r0, #0x00
RETc(le)
push {r10-r11, lr}
GET_CURPCB(r10)
mov r3, #0x00
adr ip, .Lcopyout_fault
ldr r11, [r10, #PCB_ONFAULT]
str ip, [r10, #PCB_ONFAULT]
bl .Lcopyout_guts
str r11, [r10, #PCB_ONFAULT]
mov r0, #0x00
pop {r10-r11, pc}
.Lcopyout_fault:
str r11, [r10, #PCB_ONFAULT]
cmp r3, #0x00
popgt {r4-r7}
poplt {r4-r9}
pop {r10-r11, pc}
.Lcopyout_guts:
pld [r0]
ands ip, r1, #0x03
beq .Lcopyout_wordaligned
rsb ip, ip, #0x04
cmp r2, ip
blt .Lcopyout_l4_2
sub r2, r2, ip
rsbs ip, ip, #0x03
addne pc, pc, ip, lsl #3
nop
ldrb ip, [r0], #0x01
strbt ip, [r1], #0x01
ldrb ip, [r0], #0x01
strbt ip, [r1], #0x01
ldrb ip, [r0], #0x01
strbt ip, [r1], #0x01
cmp r2, #0x00
RETc(eq)
.Lcopyout_wordaligned:
ands ip, r0, #0x03
bne .Lcopyout_bad_align
cmp r2, #0x08
blt .Lcopyout_w_less_than8
tst r1, #0x07
ldrne ip, [r0], #0x04
push {r4-r9}
mov r3, #-1
tst r1, #0x07
subne r2, r2, #0x04
strtne ip, [r1], #0x04
subs r2, r2, #0x80
blt .Lcopyout_w_lessthan128
.Lcopyout_w_loop128:
ldr r4, [r0], #0x04
ldr r5, [r0], #0x04
pld [r0, #0x18]
ldr r6, [r0], #0x04
ldr r7, [r0], #0x04
ldr r8, [r0], #0x04
ldr r9, [r0], #0x04
strt r4, [r1], #0x04
strt r5, [r1], #0x04
ldr r4, [r0], #0x04
ldr r5, [r0], #0x04
strt r6, [r1], #0x04
strt r7, [r1], #0x04
ldr r6, [r0], #0x04
ldr r7, [r0], #0x04
pld [r0, #0x18]
strt r8, [r1], #0x04
strt r9, [r1], #0x04
ldr r8, [r0], #0x04
ldr r9, [r0], #0x04
strt r4, [r1], #0x04
strt r5, [r1], #0x04
ldr r4, [r0], #0x04
ldr r5, [r0], #0x04
strt r6, [r1], #0x04
strt r7, [r1], #0x04
ldr r6, [r0], #0x04
ldr r7, [r0], #0x04
strt r8, [r1], #0x04
strt r9, [r1], #0x04
ldr r8, [r0], #0x04
ldr r9, [r0], #0x04
pld [r0, #0x18]
strt r4, [r1], #0x04
strt r5, [r1], #0x04
ldr r4, [r0], #0x04
ldr r5, [r0], #0x04
strt r6, [r1], #0x04
strt r7, [r1], #0x04
ldr r6, [r0], #0x04
ldr r7, [r0], #0x04
strt r8, [r1], #0x04
strt r9, [r1], #0x04
ldr r8, [r0], #0x04
ldr r9, [r0], #0x04
strt r4, [r1], #0x04
strt r5, [r1], #0x04
ldr r4, [r0], #0x04
ldr r5, [r0], #0x04
pld [r0, #0x18]
strt r6, [r1], #0x04
strt r7, [r1], #0x04
ldr r6, [r0], #0x04
ldr r7, [r0], #0x04
strt r8, [r1], #0x04
strt r9, [r1], #0x04
ldr r8, [r0], #0x04
ldr r9, [r0], #0x04
strt r4, [r1], #0x04
strt r5, [r1], #0x04
ldr r4, [r0], #0x04
ldr r5, [r0], #0x04
strt r6, [r1], #0x04
strt r7, [r1], #0x04
strt r8, [r1], #0x04
strt r9, [r1], #0x04
subs r2, r2, #0x80
strt r4, [r1], #0x04
strt r5, [r1], #0x04
bge .Lcopyout_w_loop128
.Lcopyout_w_lessthan128:
adds r2, r2, #0x80
popeq {r4-r9}
RETc(eq)
subs r2, r2, #0x20
blt .Lcopyout_w_lessthan32
.Lcopyout_w_loop32:
ldr r4, [r0], #0x04
ldr r5, [r0], #0x04
pld [r0, #0x18]
ldr r6, [r0], #0x04
ldr r7, [r0], #0x04
ldr r8, [r0], #0x04
ldr r9, [r0], #0x04
strt r4, [r1], #0x04
strt r5, [r1], #0x04
ldr r4, [r0], #0x04
ldr r5, [r0], #0x04
strt r6, [r1], #0x04
strt r7, [r1], #0x04
strt r8, [r1], #0x04
strt r9, [r1], #0x04
subs r2, r2, #0x20
strt r4, [r1], #0x04
strt r5, [r1], #0x04
bge .Lcopyout_w_loop32
.Lcopyout_w_lessthan32:
adds r2, r2, #0x20
popeq {r4-r9}
RETc(eq)
and r4, r2, #0x18
rsb r5, r4, #0x18
subs r2, r2, r4
add pc, pc, r5, lsl #1
nop
ldr r4, [r0], #0x04
ldr r5, [r0], #0x04
strt r4, [r1], #0x04
strt r5, [r1], #0x04
ldr r4, [r0], #0x04
ldr r5, [r0], #0x04
strt r4, [r1], #0x04
strt r5, [r1], #0x04
ldr r4, [r0], #0x04
ldr r5, [r0], #0x04
strt r4, [r1], #0x04
strt r5, [r1], #0x04
pop {r4-r9}
RETc(eq)
mov r3, #0x00
.Lcopyout_w_less_than8:
subs r2, r2, #0x04
ldrge ip, [r0], #0x04
strtge ip, [r1], #0x04
RETc(eq)
addlt r2, r2, #0x04
ldrb ip, [r0], #0x01
cmp r2, #0x02
ldrbge r2, [r0], #0x01
strbt ip, [r1], #0x01
ldrbgt ip, [r0]
strbtge r2, [r1], #0x01
strbtgt ip, [r1]
RET
.Lcopyout_bad_align:
push {r4-r7}
mov r3, #0x01
bic r0, r0, #0x03
cmp ip, #2
ldr ip, [r0], #0x04
bgt .Lcopyout_bad3
beq .Lcopyout_bad2
b .Lcopyout_bad1
.Lcopyout_bad1_loop16:
#ifdef __ARMEB__
mov r4, ip, lsl #8
#else
mov r4, ip, lsr #8
#endif
ldr r5, [r0], #0x04
pld [r0, #0x018]
ldr r6, [r0], #0x04
ldr r7, [r0], #0x04
ldr ip, [r0], #0x04
#ifdef __ARMEB__
orr r4, r4, r5, lsr #24
mov r5, r5, lsl #8
orr r5, r5, r6, lsr #24
mov r6, r6, lsl #8
orr r6, r6, r7, lsr #24
mov r7, r7, lsl #8
orr r7, r7, ip, lsr #24
#else
orr r4, r4, r5, lsl #24
mov r5, r5, lsr #8
orr r5, r5, r6, lsl #24
mov r6, r6, lsr #8
orr r6, r6, r7, lsl #24
mov r7, r7, lsr #8
orr r7, r7, ip, lsl #24
#endif
strt r4, [r1], #0x04
strt r5, [r1], #0x04
strt r6, [r1], #0x04
strt r7, [r1], #0x04
.Lcopyout_bad1:
subs r2, r2, #0x10
bge .Lcopyout_bad1_loop16
adds r2, r2, #0x10
popeq {r4-r7}
RETc(eq)
subs r2, r2, #0x04
sublt r0, r0, #0x03
blt .Lcopyout_l4
.Lcopyout_bad1_loop4:
#ifdef __ARMEB__
mov r4, ip, lsl #8
#else
mov r4, ip, lsr #8
#endif
ldr ip, [r0], #0x04
subs r2, r2, #0x04
#ifdef __ARMEB__
orr r4, r4, ip, lsr #24
#else
orr r4, r4, ip, lsl #24
#endif
strt r4, [r1], #0x04
bge .Lcopyout_bad1_loop4
sub r0, r0, #0x03
b .Lcopyout_l4
.Lcopyout_bad2_loop16:
#ifdef __ARMEB__
mov r4, ip, lsl #16
#else
mov r4, ip, lsr #16
#endif
ldr r5, [r0], #0x04
pld [r0, #0x018]
ldr r6, [r0], #0x04
ldr r7, [r0], #0x04
ldr ip, [r0], #0x04
#ifdef __ARMEB__
orr r4, r4, r5, lsr #16
mov r5, r5, lsl #16
orr r5, r5, r6, lsr #16
mov r6, r6, lsl #16
orr r6, r6, r7, lsr #16
mov r7, r7, lsl #16
orr r7, r7, ip, lsr #16
#else
orr r4, r4, r5, lsl #16
mov r5, r5, lsr #16
orr r5, r5, r6, lsl #16
mov r6, r6, lsr #16
orr r6, r6, r7, lsl #16
mov r7, r7, lsr #16
orr r7, r7, ip, lsl #16
#endif
strt r4, [r1], #0x04
strt r5, [r1], #0x04
strt r6, [r1], #0x04
strt r7, [r1], #0x04
.Lcopyout_bad2:
subs r2, r2, #0x10
bge .Lcopyout_bad2_loop16
adds r2, r2, #0x10
popeq {r4-r7}
RETc(eq)
subs r2, r2, #0x04
sublt r0, r0, #0x02
blt .Lcopyout_l4
.Lcopyout_bad2_loop4:
#ifdef __ARMEB__
mov r4, ip, lsl #16
#else
mov r4, ip, lsr #16
#endif
ldr ip, [r0], #0x04
subs r2, r2, #0x04
#ifdef __ARMEB__
orr r4, r4, ip, lsr #16
#else
orr r4, r4, ip, lsl #16
#endif
strt r4, [r1], #0x04
bge .Lcopyout_bad2_loop4
sub r0, r0, #0x02
b .Lcopyout_l4
.Lcopyout_bad3_loop16:
#ifdef __ARMEB__
mov r4, ip, lsl #24
#else
mov r4, ip, lsr #24
#endif
ldr r5, [r0], #0x04
pld [r0, #0x018]
ldr r6, [r0], #0x04
ldr r7, [r0], #0x04
ldr ip, [r0], #0x04
#ifdef __ARMEB__
orr r4, r4, r5, lsr #8
mov r5, r5, lsl #24
orr r5, r5, r6, lsr #8
mov r6, r6, lsl #24
orr r6, r6, r7, lsr #8
mov r7, r7, lsl #24
orr r7, r7, ip, lsr #8
#else
orr r4, r4, r5, lsl #8
mov r5, r5, lsr #24
orr r5, r5, r6, lsl #8
mov r6, r6, lsr #24
orr r6, r6, r7, lsl #8
mov r7, r7, lsr #24
orr r7, r7, ip, lsl #8
#endif
strt r4, [r1], #0x04
strt r5, [r1], #0x04
strt r6, [r1], #0x04
strt r7, [r1], #0x04
.Lcopyout_bad3:
subs r2, r2, #0x10
bge .Lcopyout_bad3_loop16
adds r2, r2, #0x10
popeq {r4-r7}
RETc(eq)
subs r2, r2, #0x04
sublt r0, r0, #0x01
blt .Lcopyout_l4
.Lcopyout_bad3_loop4:
#ifdef __ARMEB__
mov r4, ip, lsl #24
#else
mov r4, ip, lsr #24
#endif
ldr ip, [r0], #0x04
subs r2, r2, #0x04
#ifdef __ARMEB__
orr r4, r4, ip, lsr #8
#else
orr r4, r4, ip, lsl #8
#endif
strt r4, [r1], #0x04
bge .Lcopyout_bad3_loop4
sub r0, r0, #0x01
.Lcopyout_l4:
pop {r4-r7}
mov r3, #0x00
adds r2, r2, #0x04
RETc(eq)
.Lcopyout_l4_2:
rsbs r2, r2, #0x03
addne pc, pc, r2, lsl #3
nop
ldrb ip, [r0], #0x01
strbt ip, [r1], #0x01
ldrb ip, [r0], #0x01
strbt ip, [r1], #0x01
ldrb ip, [r0]
strbt ip, [r1]
RET
END(copyout)
ENTRY(kcopy)
cmp r2, #0x00
movle r0, #0x00
RETc(le)
push {r10-r11, lr}
GET_CURPCB(r10)
mov r3, #0x00
adr ip, .Lkcopy_fault
ldr r11, [r10, #PCB_ONFAULT]
str ip, [r10, #PCB_ONFAULT]
bl .Lkcopy_guts
str r11, [r10, #PCB_ONFAULT]
mov r0, #0x00
pop {r10-r11, pc}
.Lkcopy_fault:
str r11, [r10, #PCB_ONFAULT]
cmp r3, #0x00
popgt {r4-r7}
poplt {r4-r9}
pop {r10-r11, pc}
.Lkcopy_guts:
pld [r0]
ands ip, r1, #0x03
beq .Lkcopy_wordaligned
rsb ip, ip, #0x04
cmp r2, ip
blt .Lkcopy_bad_endgame2
sub r2, r2, ip
rsbs ip, ip, #0x03
addne pc, pc, ip, lsl #3
nop
ldrb ip, [r0], #0x01
strb ip, [r1], #0x01
ldrb ip, [r0], #0x01
strb ip, [r1], #0x01
ldrb ip, [r0], #0x01
strb ip, [r1], #0x01
cmp r2, #0x00
RETc(eq)
.Lkcopy_wordaligned:
ands ip, r0, #0x03
bne .Lkcopy_bad_align
cmp r2, #0x08
blt .Lkcopy_w_less_than8
tst r1, #0x07
ldrne ip, [r0], #0x04
push {r4-r9}
mov r3, #-1
subne r2, r2, #0x04
strne ip, [r1], #0x04
subs r2, r2, #0x80
blt .Lkcopy_w_lessthan128
.Lkcopy_w_loop128:
ldr r4, [r0], #0x04
ldr r5, [r0], #0x04
pld [r0, #0x18]
ldr r6, [r0], #0x04
ldr r7, [r0], #0x04
ldr r8, [r0], #0x04
ldr r9, [r0], #0x04
strd r4, r5, [r1], #0x08
ldr r4, [r0], #0x04
ldr r5, [r0], #0x04
strd r6, r7, [r1], #0x08
ldr r6, [r0], #0x04
ldr r7, [r0], #0x04
pld [r0, #0x18]
strd r8, r9, [r1], #0x08
ldr r8, [r0], #0x04
ldr r9, [r0], #0x04
strd r4, r5, [r1], #0x08
ldr r4, [r0], #0x04
ldr r5, [r0], #0x04
strd r6, r7, [r1], #0x08
ldr r6, [r0], #0x04
ldr r7, [r0], #0x04
strd r8, r9, [r1], #0x08
ldr r8, [r0], #0x04
ldr r9, [r0], #0x04
pld [r0, #0x18]
strd r4, r5, [r1], #0x08
ldr r4, [r0], #0x04
ldr r5, [r0], #0x04
strd r6, r7, [r1], #0x08
ldr r6, [r0], #0x04
ldr r7, [r0], #0x04
strd r8, r9, [r1], #0x08
ldr r8, [r0], #0x04
ldr r9, [r0], #0x04
strd r4, r5, [r1], #0x08
ldr r4, [r0], #0x04
ldr r5, [r0], #0x04
pld [r0, #0x18]
strd r6, r7, [r1], #0x08
ldr r6, [r0], #0x04
ldr r7, [r0], #0x04
strd r8, r9, [r1], #0x08
ldr r8, [r0], #0x04
ldr r9, [r0], #0x04
strd r4, r5, [r1], #0x08
ldr r4, [r0], #0x04
ldr r5, [r0], #0x04
strd r6, r7, [r1], #0x08
strd r8, r9, [r1], #0x08
subs r2, r2, #0x80
strd r4, r5, [r1], #0x08
bge .Lkcopy_w_loop128
.Lkcopy_w_lessthan128:
adds r2, r2, #0x80
popeq {r4-r9}
RETc(eq)
subs r2, r2, #0x20
blt .Lkcopy_w_lessthan32
.Lkcopy_w_loop32:
ldr r4, [r0], #0x04
ldr r5, [r0], #0x04
pld [r0, #0x18]
ldr r6, [r0], #0x04
ldr r7, [r0], #0x04
ldr r8, [r0], #0x04
ldr r9, [r0], #0x04
strd r4, r5, [r1], #0x08
ldr r4, [r0], #0x04
ldr r5, [r0], #0x04
strd r6, r7, [r1], #0x08
strd r8, r9, [r1], #0x08
subs r2, r2, #0x20
strd r4, r5, [r1], #0x08
bge .Lkcopy_w_loop32
.Lkcopy_w_lessthan32:
adds r2, r2, #0x20
popeq {r4-r9}
RETc(eq)
and r4, r2, #0x18
rsb r5, r4, #0x18
subs r2, r2, r4
add pc, pc, r5, lsl #1
nop
ldr r4, [r0], #0x04
ldr r5, [r0], #0x04
nop
strd r4, r5, [r1], #0x08
ldr r4, [r0], #0x04
ldr r5, [r0], #0x04
nop
strd r4, r5, [r1], #0x08
ldr r4, [r0], #0x04
ldr r5, [r0], #0x04
nop
strd r4, r5, [r1], #0x08
pop {r4-r9}
RETc(eq)
mov r3, #0x00
.Lkcopy_w_less_than8:
subs r2, r2, #0x04
ldrge ip, [r0], #0x04
strge ip, [r1], #0x04
RETc(eq)
addlt r2, r2, #0x04
ldrb ip, [r0], #0x01
cmp r2, #0x02
ldrbge r2, [r0], #0x01
strb ip, [r1], #0x01
ldrbgt ip, [r0]
strbge r2, [r1], #0x01
strbgt ip, [r1]
RET
.Lkcopy_bad_align:
push {r4-r7}
mov r3, #0x01
bic r0, r0, #0x03
cmp ip, #2
ldr ip, [r0], #0x04
bgt .Lkcopy_bad3
beq .Lkcopy_bad2
b .Lkcopy_bad1
.Lkcopy_bad1_loop16:
#ifdef __ARMEB__
mov r4, ip, lsl #8
#else
mov r4, ip, lsr #8
#endif
ldr r5, [r0], #0x04
pld [r0, #0x018]
ldr r6, [r0], #0x04
ldr r7, [r0], #0x04
ldr ip, [r0], #0x04
#ifdef __ARMEB__
orr r4, r4, r5, lsr #24
mov r5, r5, lsl #8
orr r5, r5, r6, lsr #24
mov r6, r6, lsl #8
orr r6, r6, r7, lsr #24
mov r7, r7, lsl #8
orr r7, r7, ip, lsr #24
#else
orr r4, r4, r5, lsl #24
mov r5, r5, lsr #8
orr r5, r5, r6, lsl #24
mov r6, r6, lsr #8
orr r6, r6, r7, lsl #24
mov r7, r7, lsr #8
orr r7, r7, ip, lsl #24
#endif
str r4, [r1], #0x04
str r5, [r1], #0x04
str r6, [r1], #0x04
str r7, [r1], #0x04
.Lkcopy_bad1:
subs r2, r2, #0x10
bge .Lkcopy_bad1_loop16
adds r2, r2, #0x10
popeq {r4-r7}
RETc(eq)
subs r2, r2, #0x04
sublt r0, r0, #0x03
blt .Lkcopy_bad_endgame
.Lkcopy_bad1_loop4:
#ifdef __ARMEB__
mov r4, ip, lsl #8
#else
mov r4, ip, lsr #8
#endif
ldr ip, [r0], #0x04
subs r2, r2, #0x04
#ifdef __ARMEB__
orr r4, r4, ip, lsr #24
#else
orr r4, r4, ip, lsl #24
#endif
str r4, [r1], #0x04
bge .Lkcopy_bad1_loop4
sub r0, r0, #0x03
b .Lkcopy_bad_endgame
.Lkcopy_bad2_loop16:
#ifdef __ARMEB__
mov r4, ip, lsl #16
#else
mov r4, ip, lsr #16
#endif
ldr r5, [r0], #0x04
pld [r0, #0x018]
ldr r6, [r0], #0x04
ldr r7, [r0], #0x04
ldr ip, [r0], #0x04
#ifdef __ARMEB__
orr r4, r4, r5, lsr #16
mov r5, r5, lsl #16
orr r5, r5, r6, lsr #16
mov r6, r6, lsl #16
orr r6, r6, r7, lsr #16
mov r7, r7, lsl #16
orr r7, r7, ip, lsr #16
#else
orr r4, r4, r5, lsl #16
mov r5, r5, lsr #16
orr r5, r5, r6, lsl #16
mov r6, r6, lsr #16
orr r6, r6, r7, lsl #16
mov r7, r7, lsr #16
orr r7, r7, ip, lsl #16
#endif
str r4, [r1], #0x04
str r5, [r1], #0x04
str r6, [r1], #0x04
str r7, [r1], #0x04
.Lkcopy_bad2:
subs r2, r2, #0x10
bge .Lkcopy_bad2_loop16
adds r2, r2, #0x10
popeq {r4-r7}
RETc(eq)
subs r2, r2, #0x04
sublt r0, r0, #0x02
blt .Lkcopy_bad_endgame
.Lkcopy_bad2_loop4:
#ifdef __ARMEB__
mov r4, ip, lsl #16
#else
mov r4, ip, lsr #16
#endif
ldr ip, [r0], #0x04
subs r2, r2, #0x04
#ifdef __ARMEB__
orr r4, r4, ip, lsr #16
#else
orr r4, r4, ip, lsl #16
#endif
str r4, [r1], #0x04
bge .Lkcopy_bad2_loop4
sub r0, r0, #0x02
b .Lkcopy_bad_endgame
.Lkcopy_bad3_loop16:
#ifdef __ARMEB__
mov r4, ip, lsl #24
#else
mov r4, ip, lsr #24
#endif
ldr r5, [r0], #0x04
pld [r0, #0x018]
ldr r6, [r0], #0x04
ldr r7, [r0], #0x04
ldr ip, [r0], #0x04
#ifdef __ARMEB__
orr r4, r4, r5, lsr #8
mov r5, r5, lsl #24
orr r5, r5, r6, lsr #8
mov r6, r6, lsl #24
orr r6, r6, r7, lsr #8
mov r7, r7, lsl #24
orr r7, r7, ip, lsr #8
#else
orr r4, r4, r5, lsl #8
mov r5, r5, lsr #24
orr r5, r5, r6, lsl #8
mov r6, r6, lsr #24
orr r6, r6, r7, lsl #8
mov r7, r7, lsr #24
orr r7, r7, ip, lsl #8
#endif
str r4, [r1], #0x04
str r5, [r1], #0x04
str r6, [r1], #0x04
str r7, [r1], #0x04
.Lkcopy_bad3:
subs r2, r2, #0x10
bge .Lkcopy_bad3_loop16
adds r2, r2, #0x10
popeq {r4-r7}
RETc(eq)
subs r2, r2, #0x04
sublt r0, r0, #0x01
blt .Lkcopy_bad_endgame
.Lkcopy_bad3_loop4:
#ifdef __ARMEB__
mov r4, ip, lsl #24
#else
mov r4, ip, lsr #24
#endif
ldr ip, [r0], #0x04
subs r2, r2, #0x04
#ifdef __ARMEB__
orr r4, r4, ip, lsr #8
#else
orr r4, r4, ip, lsl #8
#endif
str r4, [r1], #0x04
bge .Lkcopy_bad3_loop4
sub r0, r0, #0x01
.Lkcopy_bad_endgame:
pop {r4-r7}
mov r3, #0x00
adds r2, r2, #0x04
RETc(eq)
.Lkcopy_bad_endgame2:
rsbs r2, r2, #0x03
addne pc, pc, r2, lsl #3
nop
ldrb ip, [r0], #0x01
strb ip, [r1], #0x01
ldrb ip, [r0], #0x01
strb ip, [r1], #0x01
ldrb ip, [r0]
strb ip, [r1]
RET
END(kcopy)