| 
							- /****************************************************************************
 -  * Assembly testing and benchmarking tool
 -  * Copyright (c) 2015 Martin Storsjo
 -  * Copyright (c) 2015 Janne Grunau
 -  *
 -  * This file is part of FFmpeg.
 -  *
 -  * FFmpeg is free software; you can redistribute it and/or modify
 -  * it under the terms of the GNU General Public License as published by
 -  * the Free Software Foundation; either version 2 of the License, or
 -  * (at your option) any later version.
 -  *
 -  * FFmpeg is distributed in the hope that it will be useful,
 -  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 -  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 -  * GNU General Public License for more details.
 -  *
 -  * You should have received a copy of the GNU General Public License
 -  * along with this program; if not, write to the Free Software
 -  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
 -  *****************************************************************************/
 - 
 - #include "libavutil/arm/asm.S"
 - 
 - /* override fpu so that NEON instructions are rejected */
 - #if HAVE_VFP
 - FPU     .fpu            vfp
 - ELF     .eabi_attribute 10, 0           @ suppress Tag_FP_arch
 - #endif
 - 
 - const register_init, align=3
 -     .quad 0x21f86d66c8ca00ce
 -     .quad 0x75b6ba21077c48ad
 -     .quad 0xed56bb2dcb3c7736
 -     .quad 0x8bda43d3fd1a7e06
 -     .quad 0xb64a9c9e5d318408
 -     .quad 0xdf9a54b303f1d3a3
 -     .quad 0x4a75479abd64e097
 -     .quad 0x249214109d5d1c88
 - endconst
 - 
 - const error_message_fpscr
 -     .asciz "failed to preserve register FPSCR, changed bits: %x"
 - error_message_gpr:
 -     .asciz "failed to preserve register r%d"
 - error_message_vfp:
 -     .asciz "failed to preserve register d%d"
 - endconst
 - 
 - @ max number of args used by any asm function.
 - #define MAX_ARGS 15
 - 
 - #define ARG_STACK 4*(MAX_ARGS - 4)
 - 
 - @ align the used stack space to 8 to preserve the stack alignment
 - #define ARG_STACK_A (((ARG_STACK + pushed + 7) & ~7) - pushed)
 - 
 - .macro clobbercheck variant
 - .equ pushed, 4*9
 - function checkasm_checked_call_\variant, export=1
 -     push        {r4-r11, lr}
 - .ifc \variant, vfp
 -     vpush       {d8-d15}
 -     fmrx        r4,  FPSCR
 -     push        {r4}
 - .equ pushed, pushed + 16*4 + 4
 - .endif
 - 
 -     movrel      r12, register_init
 - .ifc \variant, vfp
 -     vldm        r12, {d8-d15}
 - .endif
 -     ldm         r12, {r4-r11}
 - 
 -     sub         sp,  sp,  #ARG_STACK_A
 - .equ pos, 0
 - .rept MAX_ARGS-4
 -     ldr         r12, [sp, #ARG_STACK_A + pushed + 8 + pos]
 -     str         r12, [sp, #pos]
 - .equ pos, pos + 4
 - .endr
 - 
 -     mov         r12, r0
 -     mov         r0,  r2
 -     mov         r1,  r3
 -     ldrd        r2,  r3,  [sp, #ARG_STACK_A + pushed]
 -     blx         r12
 -     add         sp,  sp,  #ARG_STACK_A
 - 
 -     push        {r0, r1}
 -     movrel      r12, register_init
 - .ifc \variant, vfp
 - .macro check_reg_vfp, dreg, offset
 -     ldrd        r2,  r3,  [r12, #8 * (\offset)]
 -     vmov        r0,  lr,  \dreg
 -     eor         r2,  r2,  r0
 -     eor         r3,  r3,  lr
 -     orrs        r2,  r2,  r3
 -     bne         4f
 - .endm
 - 
 - .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
 - .purgem check_reg_vfp
 - 
 -     fmrx        r1,  FPSCR
 -     ldr         r3,  [sp, #8]
 -     eor         r1,  r1,  r3
 -     @ Ignore changes in bits 0-4 and 7
 -     bic         r1,  r1,  #0x9f
 -     @ Ignore changes in the topmost 5 bits
 -     bics        r1,  r1,  #0xf8000000
 -     bne         3f
 - .endif
 - 
 -     @ keep track of the checked GPR
 -     mov         r1,  #4
 - .macro check_reg reg1, reg2=
 -     ldrd        r2,  r3,  [r12], #8
 -     eors        r2,  r2,  \reg1
 -     bne         2f
 -     add         r1,  r1,  #1
 - .ifnb \reg2
 -     eors        r3,  r3,  \reg2
 -     bne         2f
 - .endif
 -     add         r1,  r1,  #1
 - .endm
 -     check_reg   r4,  r5
 -     check_reg   r6,  r7
 - @ r9 is a volatile register in the ios ABI
 - #ifdef __APPLE__
 -     check_reg   r8
 - #else
 -     check_reg   r8,  r9
 - #endif
 -     check_reg   r10, r11
 - .purgem check_reg
 - 
 -     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}
 - .ifc \variant, vfp
 -     pop         {r2}
 -     fmxr        FPSCR, r2
 -     vpop        {d8-d15}
 - .endif
 -     pop         {r4-r11, pc}
 - endfunc
 - .endm
 - 
 - #if HAVE_VFP || HAVE_NEON
 - clobbercheck vfp
 - #endif
 - clobbercheck novfp
 
 
  |