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