Blame view

ffmpeg-4.2.2/tests/checkasm/arm/checkasm.S 4.32 KB
aac5773f   hucm   功能基本完成,接口待打磨
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
  /****************************************************************************
   * 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