@ -22,6 +22,12 @@
# include " l i b a v u t i l / a r m / a s m . S "
/* override fpu so that NEON instructions are rejected */
# if H A V E _ V F P
.fpu vfp
ELF . e a b i _ a t t r i b u t e 1 0 , 0 @ suppress Tag_FP_arch
# endif
const r e g i s t e r _ i n i t , a l i g n =3
.quad 0x21f86d66c8ca00ce
.quad 0x75b6ba21077c48ad
@ -33,8 +39,12 @@ const register_init, align=3
.quad 0x249214109d5d1c88
endconst
const e r r o r _ m e s s a g e
.asciz " failed t o p r e s e r v e r e g i s t e r "
const e r r o r _ m e s s a g e _ f p s c r
.asciz " failed t o p r e s e r v e r e g i s t e r F P S C R , c h a n g e d b i t s : % x "
error_message_gpr :
.asciz " failed t o p r e s e r v e r e g i s t e r r % d "
error_message_vfp :
.asciz " failed t o p r e s e r v e r e g i s t e r d % d "
endconst
@ max number of args used by any asm function.
@ -79,39 +89,45 @@ function checkasm_checked_call_\variant, export=1
push { r0 , r1 }
movrel r12 , r e g i s t e r _ i n i t
mov r3 , #0
.ifc \ variant, v f p
.macro check_ r e g _ v f p , d r e g , i n c =8
ldrd r0 , r1 , [ r12 ] , #\ i n c
vmov r2 , l r , \ d r e g
eor r0 , r0 , r2
eor r1 , r1 , l r
orr r3 , r3 , r0
orr r3 , r3 , r1
.macro check_ r e g _ v f p , d r e g , o f f s e t
ldrd r2 , r3 , [ r12 , #8 * ( \ o f f s e t ) ]
vmov r0 , l r , \ d r e g
eor r2 , r2 , r0
eor r3 , r3 , l r
orrs r2 , r2 , r3
bne 4 f
.endm
.irp n, 8 , 9 , 1 0 , 1 1 , 1 2 , 1 3 , 1 4
check_ r e g _ v f p d \ n
.irp n, 8 , 9 , 1 0 , 1 1 , 1 2 , 1 3 , 1 4 , 1 5
@ keep track of the checked double/SIMD register
mov r1 , #\ n
check_ r e g _ v f p d \ n , \ n - 8
.endr
check_ r e g _ v f p d15 , - 5 6
.purgem check_reg_vfp
fmrx r0 , F P S C R
ldr r1 , [ s p , #8 ]
eor r0 , r0 , r1
fmrx r1 , F P S C R
ldr r3 , [ s p , #8 ]
eor r1 , r1 , r3
@ Ignore changes in bits 0-4 and 7
bic r1 , r1 , #0x9f
@ Ignore changes in the topmost 5 bits
lsl r0 , r0 , #5
orr r3 , r3 , r0
bics r1 , r1 , #0xf8000000
bne 3 f
.endif
@ keep track of the checked GPR
mov r1 , #4
.macro check_reg reg1 , r e g 2 =
ldrd r0 , r1 , [ r12 ] , #8
eor r0 , r0 , \ r e g 1
orrs r3 , r3 , r0
ldrd r2 , r3 , [ r12 ] , #8
eors r2 , r2 , \ r e g 1
bne 2 f
add r1 , r1 , #1
.ifnb \ reg2
eor r1 , r1 , \ r e g 2
orrs r3 , r3 , r1
eors r3 , r3 , \ r e g 2
bne 2 f
.endif
add r1 , r1 , #1
.endm
check_ r e g r4 , r5
check_ r e g r6 , r7
@ -124,9 +140,16 @@ function checkasm_checked_call_\variant, export=1
check_ r e g r10 , r11
.purgem check_reg
beq 0 f
movrel r0 , e r r o r _ m e s s a g e
b 0 f
4 :
movrel r0 , e r r o r _ m e s s a g e _ v f p
b 1 f
3 :
movrel r0 , e r r o r _ m e s s a g e _ f p s c r
b 1 f
2 :
movrel r0 , e r r o r _ m e s s a g e _ g p r
1 :
blx X ( c h e c k a s m _ f a i l _ f u n c )
0 :
pop { r0 , r1 }