const register_init
.quad 0x21f86d66c8ca00ce
.quad 0x75b6ba21077c48ad
.quad 0xed56bb2dcb3c7736
.quad 0x8bda43d3fd1a7e06
.quad 0xb64a9c9e5d318408
.quad 0xdf9a54b303f1d3a3
.quad 0x4a75479abd64e097
.quad 0x249214109d5d1c88
endconst
const error_message
.asciz "failed to preserve register"
endconst
@ max number of args used by any asm function.
.macro clobbercheck variant
.equ pushed, 4*9
function checkasm_checked_call_\variant, export=1
push {r4-r11, lr}
.ifc \variant, vfp
vpush {d8-d15}
fmrx r4, FPSCR
push {r4}
.equ pushed, pushed + 16*4 + 4
.endif
movrel r12, register_init
.ifc \variant, vfp
vldm r12, {d8-d15}
.endif
ldm r12, {r4-r11}
sub sp, sp,
.equ pos, 0
.rept MAX_ARGS-2
ldr r12, [sp,
str r12, [sp,
.equ pos, pos + 4
.endr
mov r12, r0
mov r0, r2
mov r1, r3
ldrd r2, r3, [sp,
blx r12
add sp, sp,
push {r0, r1}
movrel r12, register_init
mov r3,
.ifc \variant, vfp
.macro check_reg_vfp, dreg, inc=8
ldrd r0, r1, [r12],
vmov r2, lr, \dreg
eor r0, r0, r2
eor r1, r1, lr
orr r3, r3, r0
orr r3, r3, r1
.endm
.irp n, 8, 9, 10, 11, 12, 13, 14
check_reg_vfp d\n
.endr
check_reg_vfp d15, -56
.purgem check_reg_vfp
fmrx r0, FPSCR
ldr r1, [sp,
eor r0, r0, r1
@ Ignore changes in the topmost 5 bits
lsl r0, r0,
orr r3, r3, r0
.endif
.macro check_reg reg1, reg2=
ldrd r0, r1, [r12],
eor r0, r0, \reg1
orrs r3, r3, r0
.ifnb \reg2
eor r1, r1, \reg2
orrs r3, r3, r1
.endif
.endm
check_reg r4, r5
check_reg r6, r7
@ r9 is a volatile register in the ios ABI
check_reg r8
check_reg r8, r9
check_reg r10, r11
.purgem check_reg
beq 0f
movrel r0, error_message
blx X(checkasm_fail_func)
0:
pop {r0, r1}
.ifc \variant, vfp
pop {r2}
fmxr FPSCR, r2
vpop {d8-d15}
.endif
pop {r4-r11, pc}
endfunc
.endm
clobbercheck vfp
clobbercheck novfp