| @@ -33,8 +33,12 @@ const register_init, align=3 | |||
| .quad 0x249214109d5d1c88 | |||
| endconst | |||
| const error_message | |||
| .asciz "failed to preserve register" | |||
| const error_message_fpscr | |||
| .asciz "failed to preserve register FPSCR" | |||
| const error_message_gpr | |||
| .asciz "failed to preserve register r%d" | |||
| const error_message_vfp | |||
| .asciz "failed to preserve register d%d" | |||
| endconst | |||
| @ max number of args used by any asm function. | |||
| @@ -79,39 +83,42 @@ function checkasm_checked_call_\variant, export=1 | |||
| push {r0, r1} | |||
| movrel r12, register_init | |||
| mov r3, #0 | |||
| .ifc \variant, vfp | |||
| .macro check_reg_vfp, dreg, inc=8 | |||
| ldrd r0, r1, [r12], #\inc | |||
| vmov r2, lr, \dreg | |||
| eor r0, r0, r2 | |||
| eor r1, r1, lr | |||
| orr r3, r3, r0 | |||
| orr r3, r3, r1 | |||
| .macro check_reg_vfp, dreg, offset | |||
| vldr d0, [r12, #8 * (\offset)] | |||
| veor d0, d0, \dreg | |||
| vmov r2, r3, d0 | |||
| orrs r2, r2, r3 | |||
| bne 4f | |||
| .endm | |||
| .irp n, 8, 9, 10, 11, 12, 13, 14 | |||
| check_reg_vfp d\n | |||
| .irp n, 8, 9, 10, 11, 12, 13, 14, 15 | |||
| @ keep track of the checked double/SIMD register | |||
| mov r1, #\n | |||
| check_reg_vfp d\n, \n-8 | |||
| .endr | |||
| check_reg_vfp d15, -56 | |||
| .purgem check_reg_vfp | |||
| fmrx r0, FPSCR | |||
| ldr r1, [sp, #8] | |||
| eor r0, r0, r1 | |||
| ldr r3, [sp, #8] | |||
| eor r0, r0, r3 | |||
| @ Ignore changes in the topmost 5 bits | |||
| lsl r0, r0, #5 | |||
| orr r3, r3, r0 | |||
| lsls r0, r0, #5 | |||
| bne 3f | |||
| .endif | |||
| @ keep track of the checked GPR | |||
| mov r1, #4 | |||
| .macro check_reg reg1, reg2= | |||
| ldrd r0, r1, [r12], #8 | |||
| eor r0, r0, \reg1 | |||
| orrs r3, r3, r0 | |||
| ldrd r2, r3, [r12], #8 | |||
| eors r2, r2, \reg1 | |||
| bne 2f | |||
| add r1, r1, #1 | |||
| .ifnb \reg2 | |||
| eor r1, r1, \reg2 | |||
| orrs r3, r3, r1 | |||
| eors r3, r3, \reg2 | |||
| bne 2f | |||
| .endif | |||
| add r1, r1, #1 | |||
| .endm | |||
| check_reg r4, r5 | |||
| check_reg r6, r7 | |||
| @@ -124,9 +131,16 @@ function checkasm_checked_call_\variant, export=1 | |||
| check_reg r10, r11 | |||
| .purgem check_reg | |||
| beq 0f | |||
| movrel r0, error_message | |||
| b 0f | |||
| 4: | |||
| movrel r0, error_message_vfp | |||
| b 1f | |||
| 3: | |||
| movrel r0, error_message_fpscr | |||
| b 1f | |||
| 2: | |||
| movrel r0, error_message_gpr | |||
| 1: | |||
| blx X(checkasm_fail_func) | |||
| 0: | |||
| pop {r0, r1} | |||