722d746b8814517497c041fec3e1991e312ce260
[x262.git] / tools / checkasm-a.asm
1 ;*****************************************************************************
2 ;* checkasm-a.asm: assembly check tool
3 ;*****************************************************************************
4 ;* Copyright (C) 2008-2013 x264 project
5 ;*
6 ;* Authors: Loren Merritt <lorenm@u.washington.edu>
7 ;*          Henrik Gramner <henrik@gramner.com>
8 ;*
9 ;* This program is free software; you can redistribute it and/or modify
10 ;* it under the terms of the GNU General Public License as published by
11 ;* the Free Software Foundation; either version 2 of the License, or
12 ;* (at your option) any later version.
13 ;*
14 ;* This program is distributed in the hope that it will be useful,
15 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ;* GNU General Public License for more details.
18 ;*
19 ;* You should have received a copy of the GNU General Public License
20 ;* along with this program; if not, write to the Free Software
21 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
22 ;*
23 ;* This program is also available under a commercial proprietary license.
24 ;* For more information, contact us at licensing@x264.com.
25 ;*****************************************************************************
26
27 %include "x86inc.asm"
28
29 SECTION_RODATA
30
31 error_message: db "failed to preserve register", 0
32
33 %if ARCH_X86_64
34 ; just random numbers to reduce the chance of incidental match
35 ALIGN 16
36 x6:  ddq 0x79445c159ce790641a1b2550a612b48c
37 x7:  ddq 0x86b2536fcd8cf6362eed899d5a28ddcd
38 x8:  ddq 0x3f2bf84fc0fcca4eb0856806085e7943
39 x9:  ddq 0xd229e1f5b281303facbd382dcf5b8de2
40 x10: ddq 0xab63e2e11fa38ed971aeaff20b095fd9
41 x11: ddq 0x77d410d5c42c882d89b0c0765892729a
42 x12: ddq 0x24b3c1d2a024048bc45ea11a955d8dd5
43 x13: ddq 0xdd7b8919edd427862e8ec680de14b47c
44 x14: ddq 0x11e53e2b2ac655ef135ce6888fa02cbf
45 x15: ddq 0x6de8f4c914c334d5011ff554472a7a10
46 n7:   dq 0x21f86d66c8ca00ce
47 n8:   dq 0x75b6ba21077c48ad
48 n9:   dq 0xed56bb2dcb3c7736
49 n10:  dq 0x8bda43d3fd1a7e06
50 n11:  dq 0xb64a9c9e5d318408
51 n12:  dq 0xdf9a54b303f1d3a3
52 n13:  dq 0x4a75479abd64e097
53 n14:  dq 0x249214109d5d1c88
54 %endif
55
56 SECTION .text
57
58 cextern_naked puts
59
60 ; max number of args used by any x264 asm function.
61 ; (max_args % 4) must equal 3 for stack alignment
62 %define max_args 15
63
64 %if ARCH_X86_64
65
66 ;-----------------------------------------------------------------------------
67 ; void x264_checkasm_stack_clobber( uint64_t clobber, ... )
68 ;-----------------------------------------------------------------------------
69 cglobal checkasm_stack_clobber, 1,2
70     ; Clobber the stack with junk below the stack pointer
71     %define size (max_args+6)*8
72     SUB  rsp, size
73     mov   r1, size-8
74 .loop:
75     mov [rsp+r1], r0
76     sub   r1, 8
77     jge .loop
78     ADD  rsp, size
79     RET
80
81 %if WIN64
82     %assign free_regs 7
83 %else
84     %assign free_regs 9
85 %endif
86
87 ;-----------------------------------------------------------------------------
88 ; intptr_t x264_checkasm_call( intptr_t (*func)(), int *ok, ... )
89 ;-----------------------------------------------------------------------------
90 INIT_XMM
91 cglobal checkasm_call, 2,15,16,max_args*8+8
92     mov  r6, r0
93     mov  [rsp+max_args*8], r1
94
95     ; All arguments have been pushed on the stack instead of registers in order to
96     ; test for incorrect assumptions that 32-bit ints are zero-extended to 64-bit.
97     mov  r0, r6mp
98     mov  r1, r7mp
99     mov  r2, r8mp
100     mov  r3, r9mp
101 %if UNIX64
102     mov  r4, r10mp
103     mov  r5, r11mp
104     %assign i 6
105     %rep max_args-6
106         mov  r9, [rsp+stack_offset+(i+1)*8]
107         mov  [rsp+(i-6)*8], r9
108         %assign i i+1
109     %endrep
110 %else
111     %assign i 4
112     %rep max_args-4
113         mov  r9, [rsp+stack_offset+(i+7)*8]
114         mov  [rsp+i*8], r9
115         %assign i i+1
116     %endrep
117 %endif
118
119 %if WIN64
120     %assign i 6
121     %rep 16-6
122         mova m %+ i, [x %+ i]
123         %assign i i+1
124     %endrep
125 %endif
126
127 %assign i 14
128 %rep 15-free_regs
129     mov  r %+ i, [n %+ i]
130     %assign i i-1
131 %endrep
132     call r6
133 %assign i 14
134 %rep 15-free_regs
135     xor  r %+ i, [n %+ i]
136     or  r14, r %+ i
137     %assign i i-1
138 %endrep
139
140 %if WIN64
141     %assign i 6
142     %rep 16-6
143         pxor m %+ i, [x %+ i]
144         por  m6, m %+ i
145         %assign i i+1
146     %endrep
147     packsswb m6, m6
148     movq r5, m6
149     or  r14, r5
150 %endif
151
152     jz .ok
153     mov  r9, rax
154     lea  r0, [error_message]
155     call puts
156     mov  r1, [rsp+max_args*8]
157     mov  dword [r1], 0
158     mov  rax, r9
159 .ok:
160     RET
161
162 %else
163
164 ; just random numbers to reduce the chance of incidental match
165 %define n3 dword 0x6549315c
166 %define n4 dword 0xe02f3e23
167 %define n5 dword 0xb78d0d1d
168 %define n6 dword 0x33627ba7
169
170 ;-----------------------------------------------------------------------------
171 ; intptr_t x264_checkasm_call( intptr_t (*func)(), int *ok, ... )
172 ;-----------------------------------------------------------------------------
173 cglobal checkasm_call, 1,7
174     mov  r3, n3
175     mov  r4, n4
176     mov  r5, n5
177     mov  r6, n6
178 %rep max_args
179     push dword [esp+24+max_args*4]
180 %endrep
181     call r0
182     add  esp, max_args*4
183     xor  r3, n3
184     xor  r4, n4
185     xor  r5, n5
186     xor  r6, n6
187     or   r3, r4
188     or   r5, r6
189     or   r3, r5
190     jz .ok
191     mov  r3, eax
192     lea  r1, [error_message]
193     push r1
194     call puts
195     add  esp, 4
196     mov  r1, r1m
197     mov  dword [r1], 0
198     mov  eax, r3
199 .ok:
200     REP_RET
201
202 %endif ; ARCH_X86_64
203
204 ;-----------------------------------------------------------------------------
205 ; int x264_stack_pagealign( int (*func)(), int align )
206 ;-----------------------------------------------------------------------------
207 cglobal stack_pagealign, 2,2
208     movsxdifnidn r1, r1d
209     push rbp
210     mov  rbp, rsp
211 %if WIN64
212     sub  rsp, 32 ; shadow space
213 %endif
214     and  rsp, ~0xfff
215     sub  rsp, r1
216     call r0
217     leave
218     RET
219