1dnl  x86 calling conventions checking.
2
3dnl  Copyright 2000, 2003, 2010, 2013 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  https://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	xor	%eax, %eax
44	push	%eax
45	fstcw	(%esp)
46	pop	%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	pop	RETADDR(%ecx)
100
101	mov	%ebx, SAVE_EBX(%ecx)
102	mov	%ebp, SAVE_EBP(%ecx)
103	mov	%esi, SAVE_ESI(%ecx)
104	mov	%edi, SAVE_EDI(%ecx)
105
106	C Values we expect to see unchanged, as per amd64check.c
107	mov	WANT_EBX(%ecx), %ebx
108	mov	WANT_EBP(%ecx), %ebp
109	mov	WANT_ESI(%ecx), %esi
110	mov	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	mov	JUNK_EAX(%ecx), %eax
115	mov	JUNK_EDX(%ecx), %edx
116C	mov	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	mov	%ebx, EBX(%ecx)
128	mov	%ebp, EBP(%ecx)
129	mov	%esi, ESI(%ecx)
130	mov	%edi, EDI(%ecx)
131
132	pushf
133	pop	%ebx
134	mov	%ebx, EFLAGS(%ecx)
135
136	mov	SAVE_EBX(%ecx), %ebx
137	mov	SAVE_ESI(%ecx), %esi
138	mov	SAVE_EDI(%ecx), %edi
139	mov	SAVE_EBP(%ecx), %ebp
140
141	push	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()
154ASM_END()
155