]> git.sesse.net Git - ffmpeg/blob - tests/checkasm/arm/checkasm.S
avformat/avio: Add Metacube support
[ffmpeg] / 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 FFmpeg.
7  *
8  * FFmpeg 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  * FFmpeg 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     .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, changed bits: %x"
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 error_message_stack:
49         .asciz "failed to preserve stack"
50 endconst
51
52 @ max number of args used by any asm function.
53 #define MAX_ARGS 15
54
55 #define ARG_STACK 4*(MAX_ARGS - 4)
56
57 @ Align the used stack space to 8 to preserve the stack alignment.
58 @ +8 for stack canary reference.
59 #define ARG_STACK_A (((ARG_STACK + pushed + 7) & ~7) - pushed + 8)
60
61 .macro clobbercheck variant
62 .equ pushed, 4*9
63 function checkasm_checked_call_\variant, export=1
64         push            {r4-r11, lr}
65 .ifc \variant, vfp
66         vpush           {d8-d15}
67         fmrx            r4,  FPSCR
68         push            {r4}
69 .equ pushed, pushed + 16*4 + 4
70 .endif
71
72         movrel          r12, register_init
73 .ifc \variant, vfp
74         vldm            r12, {d8-d15}
75 .endif
76         ldm             r12, {r4-r11}
77
78         sub             sp,  sp,  #ARG_STACK_A
79 .equ pos, 0
80 .rept MAX_ARGS-4
81         ldr             r12, [sp, #ARG_STACK_A + pushed + 8 + pos]
82         str             r12, [sp, #pos]
83 .equ pos, pos + 4
84 .endr
85
86         @ For stack overflows, the callee is free to overwrite the parameters
87         @ that were passed on the stack (if any), so we can only check after
88         @ that point. First figure out how many parameters the function
89         @ really took on the stack:
90         ldr             r12, [sp, #ARG_STACK_A + pushed + 8 + 4*(MAX_ARGS-4)]
91         @ Load the first non-parameter value from the stack, that should be
92         @ left untouched by the function. Store a copy of it inverted, so that
93         @ e.g. overwriting everything with zero would be noticed.
94         ldr             r12, [sp, r12, lsl #2]
95         mvn             r12, r12
96         str             r12, [sp, #ARG_STACK_A - 4]
97
98         mov             r12, r0
99         mov             r0,  r2
100         mov             r1,  r3
101         ldrd            r2,  r3,  [sp, #ARG_STACK_A + pushed]
102         @ Call the target function
103         blx             r12
104
105         @ Load the number of stack parameters, stack canary and its reference
106         ldr             r12, [sp, #ARG_STACK_A + pushed + 8 + 4*(MAX_ARGS-4)]
107         ldr             r2,  [sp, r12, lsl #2]
108         ldr             r3,  [sp, #ARG_STACK_A - 4]
109
110         add             sp,  sp,  #ARG_STACK_A
111         push            {r0, r1}
112
113         mvn             r3,  r3
114         cmp             r2,  r3
115         bne             5f
116
117         movrel          r12, register_init
118 .ifc \variant, vfp
119 .macro check_reg_vfp, dreg, offset
120         ldrd            r2,  r3,  [r12, #8 * (\offset)]
121         vmov            r0,  lr,  \dreg
122         eor             r2,  r2,  r0
123         eor             r3,  r3,  lr
124         orrs            r2,  r2,  r3
125         bne             4f
126 .endm
127
128 .irp n, 8, 9, 10, 11, 12, 13, 14, 15
129         @ keep track of the checked double/SIMD register
130         mov             r1,  #\n
131         check_reg_vfp   d\n, \n-8
132 .endr
133 .purgem check_reg_vfp
134
135         fmrx            r1,  FPSCR
136         ldr             r3,  [sp, #8]
137         eor             r1,  r1,  r3
138         @ Ignore changes in bits 0-4 and 7
139         bic             r1,  r1,  #0x9f
140         @ Ignore changes in the topmost 5 bits
141         bics            r1,  r1,  #0xf8000000
142         bne             3f
143 .endif
144
145         @ keep track of the checked GPR
146         mov             r1,  #4
147 .macro check_reg reg1, reg2=
148         ldrd            r2,  r3,  [r12], #8
149         eors            r2,  r2,  \reg1
150         bne             2f
151         add             r1,  r1,  #1
152 .ifnb \reg2
153         eors            r3,  r3,  \reg2
154         bne             2f
155 .endif
156         add             r1,  r1,  #1
157 .endm
158         check_reg       r4,  r5
159         check_reg       r6,  r7
160 @ r9 is a volatile register in the ios ABI
161 #ifdef __APPLE__
162         check_reg       r8
163 #else
164         check_reg       r8,  r9
165 #endif
166         check_reg       r10, r11
167 .purgem check_reg
168
169         b               0f
170 5:
171         movrel          r0, error_message_stack
172         b               1f
173 4:
174         movrel          r0, error_message_vfp
175         b               1f
176 3:
177         movrel          r0, error_message_fpscr
178         b               1f
179 2:
180         movrel          r0, error_message_gpr
181 1:
182         bl              X(checkasm_fail_func)
183 0:
184         pop             {r0, r1}
185 .ifc \variant, vfp
186         pop             {r2}
187         fmxr            FPSCR, r2
188         vpop            {d8-d15}
189 .endif
190         pop             {r4-r11, pc}
191 endfunc
192 .endm
193
194 #if HAVE_VFP || HAVE_NEON
195 clobbercheck vfp
196 #endif
197 clobbercheck novfp