1 /****************************************************************************
2 * Assembly testing and benchmarking tool
3 * Copyright (c) 2015 Martin Storsjo
4 * Copyright (c) 2015 Janne Grunau
6 * This file is part of FFmpeg.
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.
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.
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 *****************************************************************************/
23 #include "libavutil/arm/asm.S"
25 /* override fpu so that NEON instructions are rejected */
28 ELF .eabi_attribute 10, 0 @ suppress Tag_FP_arch
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
42 const error_message_fpscr
43 .asciz "failed to preserve register FPSCR, changed bits: %x"
45 .asciz "failed to preserve register r%d"
47 .asciz "failed to preserve register d%d"
49 .asciz "failed to preserve stack"
52 @ max number of args used by any asm function.
55 #define ARG_STACK 4*(MAX_ARGS - 4)
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)
61 .macro clobbercheck variant
63 function checkasm_checked_call_\variant, export=1
69 .equ pushed, pushed + 16*4 + 4
72 movrel r12, register_init
78 sub sp, sp, #ARG_STACK_A
81 ldr r12, [sp, #ARG_STACK_A + pushed + 8 + pos]
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]
96 str r12, [sp, #ARG_STACK_A - 4]
101 ldrd r2, r3, [sp, #ARG_STACK_A + pushed]
102 @ Call the target function
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]
110 add sp, sp, #ARG_STACK_A
117 movrel r12, register_init
119 .macro check_reg_vfp, dreg, offset
120 ldrd r2, r3, [r12, #8 * (\offset)]
128 .irp n, 8, 9, 10, 11, 12, 13, 14, 15
129 @ keep track of the checked double/SIMD register
131 check_reg_vfp d\n, \n-8
133 .purgem check_reg_vfp
138 @ Ignore changes in bits 0-4 and 7
140 @ Ignore changes in the topmost 5 bits
141 bics r1, r1, #0xf8000000
145 @ keep track of the checked GPR
147 .macro check_reg reg1, reg2=
148 ldrd r2, r3, [r12], #8
160 @ r9 is a volatile register in the ios ABI
171 movrel r0, error_message_stack
174 movrel r0, error_message_vfp
177 movrel r0, error_message_fpscr
180 movrel r0, error_message_gpr
182 bl X(checkasm_fail_func)
194 #if HAVE_VFP || HAVE_NEON