xref: /netbsd-src/external/lgpl3/gmp/dist/tests/x86call.asm (revision a24efa7dea9f1f56c3bdb15a927d3516792ace1c)
1dnl  x86 calling conventions checking.
2
3dnl  Copyright 2000, 2003, 2010 Free Software Foundation, Inc.
4
5dnl  This file is part of the GNU MP Library test suite.
6
7dnl  The GNU MP Library test suite is free software; you can redistribute it
8dnl  and/or modify it under the terms of the GNU General Public License as
9dnl  published by the Free Software Foundation; either version 3 of the
10dnl  License, or (at your option) any later version.
11
12dnl  The GNU MP Library test suite is distributed in the hope that it will be
13dnl  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14dnl  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
15dnl  Public License for more details.
16
17dnl  You should have received a copy of the GNU General Public License along
18dnl  with the GNU MP Library test suite.  If not, see
19dnl  http://www.gnu.org/licenses/.
20
21
22dnl  The current version of the code attempts to keep the call/return
23dnl  prediction stack valid, but matching calls and returns.
24
25include(`../config.m4')
26
27
28C void x86_fldcw (unsigned short cw);
29C
30C Execute an fldcw, setting the x87 control word to cw.
31
32PROLOGUE(x86_fldcw)
33	fldcw	4(%esp)
34	ret
35EPILOGUE()
36
37
38C unsigned short x86_fstcw (void);
39C
40C Execute an fstcw, returning the current x87 control word.
41
42PROLOGUE(x86_fstcw)
43	xorl	%eax, %eax
44	pushl	%eax
45	fstcw	(%esp)
46	popl	%eax
47	ret
48EPILOGUE()
49
50
51dnl  Instrumented profiling doesn't come out quite right below, since we don't
52dnl  do an actual "ret".  There's only a few instructions here, so there's no
53dnl  great need to get them separately accounted, just let them get attributed
54dnl  to the caller.  FIXME this comment might no longer be true.
55
56ifelse(WANT_PROFILING,instrument,
57`define(`WANT_PROFILING',no)')
58
59
60C int calling_conventions (...);
61C
62C The global variable "calling_conventions_function" is the function to
63C call, with the arguments as passed here.
64C
65C Perhaps the finit should be done only if the tags word isn't clear, but
66C nothing uses the rounding mode or anything at the moment.
67
68define(`WANT_EBX', eval(4*0)($1))
69define(`WANT_EBP', eval(4*1)($1))
70define(`WANT_ESI', eval(4*2)($1))
71define(`WANT_EDI', eval(4*3)($1))
72
73define(`JUNK_EAX', eval(4*4)($1))
74define(`JUNK_ECX', eval(4*5)($1))
75define(`JUNK_EDX', eval(4*6)($1))
76
77define(`SAVE_EBX', eval(4*7)($1))
78define(`SAVE_EBP', eval(4*8)($1))
79define(`SAVE_ESI', eval(4*9)($1))
80define(`SAVE_EDI', eval(4*10)($1))
81
82define(`RETADDR',  eval(4*11)($1))
83
84define(`EBX',	   eval(4*12)($1))
85define(`EBP',	   eval(4*13)($1))
86define(`ESI',	   eval(4*14)($1))
87define(`EDI',	   eval(4*15)($1))
88define(`EFLAGS',   eval(4*16)($1))
89
90
91define(G,
92m4_assert_numargs(1)
93`GSYM_PREFIX`'$1')
94
95	TEXT
96	ALIGN(8)
97PROLOGUE(calling_conventions)
98	LEA(	G(calling_conventions_values), %ecx)
99	popl	RETADDR(%ecx)
100
101	movl	%ebx, SAVE_EBX(%ecx)
102	movl	%ebp, SAVE_EBP(%ecx)
103	movl	%esi, SAVE_ESI(%ecx)
104	movl	%edi, SAVE_EDI(%ecx)
105
106	C Values we expect to see unchanged, as per amd64check.c
107	movl	WANT_EBX(%ecx), %ebx
108	movl	WANT_EBP(%ecx), %ebp
109	movl	WANT_ESI(%ecx), %esi
110	movl	WANT_EDI(%ecx), %edi
111
112	C Try to provoke a problem by starting with junk in the caller-saves
113	C registers, especially in %eax and %edx which will be return values
114	movl	JUNK_EAX(%ecx), %eax
115	movl	JUNK_EDX(%ecx), %edx
116C	movl	JUNK_ECX(%ecx), %ecx
117
118ifdef(`PIC',`
119	LEA(	G(calling_conventions_function), %ecx)
120	call	*(%ecx)
121',`
122	call	*G(calling_conventions_function)
123')
124
125	LEA(	G(calling_conventions_values), %ecx)
126
127	movl	%ebx, EBX(%ecx)
128	movl	%ebp, EBP(%ecx)
129	movl	%esi, ESI(%ecx)
130	movl	%edi, EDI(%ecx)
131
132	pushf
133	popl	%ebx
134	movl	%ebx, EFLAGS(%ecx)
135
136	movl	SAVE_EBX(%ecx), %ebx
137	movl	SAVE_ESI(%ecx), %esi
138	movl	SAVE_EDI(%ecx), %edi
139	movl	SAVE_EBP(%ecx), %ebp
140
141	pushl	RETADDR(%ecx)
142
143ifdef(`PIC',`
144	LEA(	G(calling_conventions_fenv), %ecx)
145	fstenv	(%ecx)
146',`
147	fstenv	G(calling_conventions_fenv)
148')
149	finit
150
151	ret
152
153EPILOGUE()
154