cheackasm/arm: remove NEON instructions from checkasm_checked_call_vfp
[ffmpeg.git] / tests / checkasm / arm / checkasm.S
1 /****************************************************************************
2  * Assembly testing and benchmarking tool
3  * Copyright (c) 2015 Martin Storsjo
4  * Copyright (c) 2015 Janne Grunau
5  *
6  * This file is part of Libav.
7  *
8  * Libav is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * Libav is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
21  *****************************************************************************/
22
23 #include "libavutil/arm/asm.S"
24
25 /* override fpu so that NEON instructions are rejected */
26 #if HAVE_VFP
27 .fpu            vfp
28 ELF     .eabi_attribute 10, 0           @ suppress Tag_FP_arch
29 #endif
30
31 const register_init, align=3
32     .quad 0x21f86d66c8ca00ce
33     .quad 0x75b6ba21077c48ad
34     .quad 0xed56bb2dcb3c7736
35     .quad 0x8bda43d3fd1a7e06
36     .quad 0xb64a9c9e5d318408
37     .quad 0xdf9a54b303f1d3a3
38     .quad 0x4a75479abd64e097
39     .quad 0x249214109d5d1c88
40 endconst
41
42 const error_message_fpscr
43     .asciz "failed to preserve register FPSCR"
44 error_message_gpr:
45     .asciz "failed to preserve register r%d"
46 error_message_vfp:
47     .asciz "failed to preserve register d%d"
48 endconst
49
50 @ max number of args used by any asm function.
51 #define MAX_ARGS 15
52
53 #define ARG_STACK 4*(MAX_ARGS - 2)
54
55 @ align the used stack space to 8 to preserve the stack alignment
56 #define ARG_STACK_A (((ARG_STACK + pushed + 7) & ~7) - pushed)
57
58 .macro clobbercheck variant
59 .equ pushed, 4*9
60 function checkasm_checked_call_\variant, export=1
61     push        {r4-r11, lr}
62 .ifc \variant, vfp
63     vpush       {d8-d15}
64     fmrx        r4,  FPSCR
65     push        {r4}
66 .equ pushed, pushed + 16*4 + 4
67 .endif
68
69     movrel      r12, register_init
70 .ifc \variant, vfp
71     vldm        r12, {d8-d15}
72 .endif
73     ldm         r12, {r4-r11}
74
75     sub         sp,  sp,  #ARG_STACK_A
76 .equ pos, 0
77 .rept MAX_ARGS-2
78     ldr         r12, [sp, #ARG_STACK_A + pushed + 8 + pos]
79     str         r12, [sp, #pos]
80 .equ pos, pos + 4
81 .endr
82
83     mov         r12, r0
84     mov         r0,  r2
85     mov         r1,  r3
86     ldrd        r2,  r3,  [sp, #ARG_STACK_A + pushed]
87     blx         r12
88     add         sp,  sp,  #ARG_STACK_A
89
90     push        {r0, r1}
91     movrel      r12, register_init
92 .ifc \variant, vfp
93 .macro check_reg_vfp, dreg, offset
94     ldrd        r2,  r3,  [r12, #8 * (\offset)]
95     vmov        r0,  lr,  \dreg
96     eor         r2,  r2,  r0
97     eor         r3,  r3,  lr
98     orrs        r2,  r2,  r3
99     bne         4f
100 .endm
101
102 .irp n, 8, 9, 10, 11, 12, 13, 14, 15
103     @ keep track of the checked double/SIMD register
104     mov         r1,  #\n
105     check_reg_vfp d\n, \n-8
106 .endr
107 .purgem check_reg_vfp
108
109     fmrx        r0,  FPSCR
110     ldr         r3,  [sp, #8]
111     eor         r0,  r0,  r3
112     @ Ignore changes in the topmost 5 bits
113     lsls        r0,  r0,  #5
114     bne         3f
115 .endif
116
117     @ keep track of the checked GPR
118     mov         r1,  #4
119 .macro check_reg reg1, reg2=
120     ldrd        r2,  r3,  [r12], #8
121     eors        r2,  r2,  \reg1
122     bne         2f
123     add         r1,  r1,  #1
124 .ifnb \reg2
125     eors        r3,  r3,  \reg2
126     bne         2f
127 .endif
128     add         r1,  r1,  #1
129 .endm
130     check_reg   r4,  r5
131     check_reg   r6,  r7
132 @ r9 is a volatile register in the ios ABI
133 #ifdef __APPLE__
134     check_reg   r8
135 #else
136     check_reg   r8,  r9
137 #endif
138     check_reg   r10, r11
139 .purgem check_reg
140
141     b           0f
142 4:
143     movrel      r0, error_message_vfp
144     b           1f
145 3:
146     movrel      r0, error_message_fpscr
147     b           1f
148 2:
149     movrel      r0, error_message_gpr
150 1:
151     blx         X(checkasm_fail_func)
152 0:
153     pop         {r0, r1}
154 .ifc \variant, vfp
155     pop         {r2}
156     fmxr        FPSCR, r2
157     vpop        {d8-d15}
158 .endif
159     pop         {r4-r11, pc}
160 endfunc
161 .endm
162
163 #if HAVE_VFP || HAVE_NEON
164 clobbercheck vfp
165 #endif
166 clobbercheck novfp