diff --git a/tests/checkasm/arm/checkasm.S b/tests/checkasm/arm/checkasm.S
index f004af3b90e73b84c9887eb921c82bb49acf4df6..989f6136561cebe1da9359e85808c8a2d9a30a59 100644
--- a/tests/checkasm/arm/checkasm.S
+++ b/tests/checkasm/arm/checkasm.S
@@ -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}