Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
52869 views
1
;*****************************************************************************
2
;* Assembly testing and benchmarking tool
3
;* Copyright (c) 2008 Loren Merritt
4
;* Copyright (c) 2012 Henrik Gramner
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
%define private_prefix checkasm
24
%include "libavutil/x86/x86inc.asm"
25
26
SECTION_RODATA
27
28
error_message: db "failed to preserve register", 0
29
error_message_emms: db "failed to issue emms", 0
30
31
%if ARCH_X86_64
32
; just random numbers to reduce the chance of incidental match
33
ALIGN 16
34
x6: dq 0x1a1b2550a612b48c,0x79445c159ce79064
35
x7: dq 0x2eed899d5a28ddcd,0x86b2536fcd8cf636
36
x8: dq 0xb0856806085e7943,0x3f2bf84fc0fcca4e
37
x9: dq 0xacbd382dcf5b8de2,0xd229e1f5b281303f
38
x10: dq 0x71aeaff20b095fd9,0xab63e2e11fa38ed9
39
x11: dq 0x89b0c0765892729a,0x77d410d5c42c882d
40
x12: dq 0xc45ea11a955d8dd5,0x24b3c1d2a024048b
41
x13: dq 0x2e8ec680de14b47c,0xdd7b8919edd42786
42
x14: dq 0x135ce6888fa02cbf,0x11e53e2b2ac655ef
43
x15: dq 0x011ff554472a7a10,0x6de8f4c914c334d5
44
n7: dq 0x21f86d66c8ca00ce
45
n8: dq 0x75b6ba21077c48ad
46
n9: dq 0xed56bb2dcb3c7736
47
n10: dq 0x8bda43d3fd1a7e06
48
n11: dq 0xb64a9c9e5d318408
49
n12: dq 0xdf9a54b303f1d3a3
50
n13: dq 0x4a75479abd64e097
51
n14: dq 0x249214109d5d1c88
52
%endif
53
54
SECTION .text
55
56
cextern fail_func
57
58
; max number of args used by any asm function.
59
; (max_args % 4) must equal 3 for stack alignment
60
%define max_args 15
61
62
%if ARCH_X86_64
63
64
;-----------------------------------------------------------------------------
65
; int checkasm_stack_clobber(uint64_t clobber, ...)
66
;-----------------------------------------------------------------------------
67
cglobal stack_clobber, 1,2
68
; Clobber the stack with junk below the stack pointer
69
%define argsize (max_args+6)*8
70
SUB rsp, argsize
71
mov r1, argsize-8
72
.loop:
73
mov [rsp+r1], r0
74
sub r1, 8
75
jge .loop
76
ADD rsp, argsize
77
RET
78
79
%if WIN64
80
%assign free_regs 7
81
DECLARE_REG_TMP 4
82
%else
83
%assign free_regs 9
84
DECLARE_REG_TMP 7
85
%endif
86
87
%macro report_fail 1
88
mov r9, rax
89
mov r10, rdx
90
lea r0, [%1]
91
xor eax, eax
92
call fail_func
93
mov rdx, r10
94
mov rax, r9
95
%endmacro
96
97
;-----------------------------------------------------------------------------
98
; void checkasm_checked_call(void *func, ...)
99
;-----------------------------------------------------------------------------
100
INIT_XMM
101
%macro CHECKED_CALL 0-1
102
cglobal checked_call%1, 2,15,16,max_args*8+8
103
mov t0, r0
104
105
; All arguments have been pushed on the stack instead of registers in order to
106
; test for incorrect assumptions that 32-bit ints are zero-extended to 64-bit.
107
mov r0, r6mp
108
mov r1, r7mp
109
mov r2, r8mp
110
mov r3, r9mp
111
%if UNIX64
112
mov r4, r10mp
113
mov r5, r11mp
114
%assign i 6
115
%rep max_args-6
116
mov r9, [rsp+stack_offset+(i+1)*8]
117
mov [rsp+(i-6)*8], r9
118
%assign i i+1
119
%endrep
120
%else ; WIN64
121
%assign i 4
122
%rep max_args-4
123
mov r9, [rsp+stack_offset+(i+7)*8]
124
mov [rsp+i*8], r9
125
%assign i i+1
126
%endrep
127
128
; Move possible floating-point arguments to the correct registers
129
movq m0, r0
130
movq m1, r1
131
movq m2, r2
132
movq m3, r3
133
134
%assign i 6
135
%rep 16-6
136
mova m %+ i, [x %+ i]
137
%assign i i+1
138
%endrep
139
%endif
140
141
%assign i 14
142
%rep 15-free_regs
143
mov r %+ i, [n %+ i]
144
%assign i i-1
145
%endrep
146
call t0
147
%assign i 14
148
%rep 15-free_regs
149
xor r %+ i, [n %+ i]
150
or r14, r %+ i
151
%assign i i-1
152
%endrep
153
154
%if WIN64
155
%assign i 6
156
%rep 16-6
157
pxor m %+ i, [x %+ i]
158
por m6, m %+ i
159
%assign i i+1
160
%endrep
161
packsswb m6, m6
162
movq r5, m6
163
or r14, r5
164
%endif
165
166
; Call fail_func() with a descriptive message to mark it as a failure
167
; if the called function didn't preserve all callee-saved registers.
168
; Save the return value located in rdx:rax first to prevent clobbering.
169
jz .clobber_ok
170
report_fail error_message
171
.clobber_ok:
172
%ifnid %1, _emms
173
fstenv [rsp]
174
cmp word [rsp + 8], 0xffff
175
je .emms_ok
176
report_fail error_message_emms
177
emms
178
.emms_ok:
179
%else
180
emms
181
%endif
182
RET
183
%endmacro
184
185
%else
186
187
; just random numbers to reduce the chance of incidental match
188
%define n3 dword 0x6549315c
189
%define n4 dword 0xe02f3e23
190
%define n5 dword 0xb78d0d1d
191
%define n6 dword 0x33627ba7
192
193
%macro report_fail 1
194
mov r3, eax
195
mov r4, edx
196
lea r0, [%1]
197
mov [esp], r0
198
call fail_func
199
mov edx, r4
200
mov eax, r3
201
%endmacro
202
203
%macro CHECKED_CALL 0-1
204
;-----------------------------------------------------------------------------
205
; void checkasm_checked_call(void *func, ...)
206
;-----------------------------------------------------------------------------
207
cglobal checked_call%1, 1,7
208
mov r3, n3
209
mov r4, n4
210
mov r5, n5
211
mov r6, n6
212
%rep max_args
213
PUSH dword [esp+20+max_args*4]
214
%endrep
215
call r0
216
xor r3, n3
217
xor r4, n4
218
xor r5, n5
219
xor r6, n6
220
or r3, r4
221
or r5, r6
222
or r3, r5
223
jz .clobber_ok
224
report_fail error_message
225
.clobber_ok:
226
%ifnid %1, _emms
227
fstenv [esp]
228
cmp word [esp + 8], 0xffff
229
je .emms_ok
230
report_fail error_message_emms
231
emms
232
.emms_ok:
233
%else
234
emms
235
%endif
236
add esp, max_args*4
237
REP_RET
238
%endmacro
239
240
%endif ; ARCH_X86_64
241
242
CHECKED_CALL
243
CHECKED_CALL _emms
244
245