10SN/Adnl  x86 calling conventions checking.
217645Sweijun
30SN/Adnl  Copyright 2000, 2003 Free Software Foundation, Inc.
40SN/Adnl
50SN/Adnl  This file is part of the GNU MP Library.
60SN/Adnl
72362SN/Adnl  The GNU MP Library is free software; you can redistribute it and/or
80SN/Adnl  modify it under the terms of the GNU Lesser General Public License as
92362SN/Adnl  published by the Free Software Foundation; either version 3 of the
100SN/Adnl  License, or (at your option) any later version.
110SN/Adnl
120SN/Adnl  The GNU MP Library is distributed in the hope that it will be useful,
130SN/Adnl  but WITHOUT ANY WARRANTY; without even the implied warranty of
140SN/Adnl  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
150SN/Adnl  Lesser General Public License for more details.
160SN/Adnl
170SN/Adnl  You should have received a copy of the GNU Lesser General Public License
180SN/Adnl  along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.
190SN/A
200SN/A
212362SN/Ainclude(`../config.m4')
222362SN/A
232362SN/A
240SN/AC void x86_fldcw (unsigned short cw);
250SN/AC
260SN/AC Execute an fldcw, setting the x87 control word to cw.
270SN/A
280SN/APROLOGUE(x86_fldcw)
290SN/A        fldcw   4(%esp)
300SN/A        ret
310SN/AEPILOGUE()
320SN/A
330SN/A
340SN/AC unsigned short x86_fstcw (void);
350SN/AC
360SN/AC Execute an fstcw, returning the current x87 control word.
3713303Schegar
380SN/APROLOGUE(x86_fstcw)
390SN/A        xorl    %eax, %eax
400SN/A        pushl   %eax
410SN/A        fstcw   (%esp)
420SN/A        popl    %eax
430SN/A        ret
440SN/AEPILOGUE()
450SN/A
460SN/A
470SN/Adnl  Instrumented profiling doesn't come out quite right below, since we
480SN/Adnl  don't do an actual "ret".  There's only a few instructions here, so
490SN/Adnl  there's no great need to get them separately accounted, just let them
500SN/Adnl  get attributed to the caller.
510SN/A
520SN/Aifelse(WANT_PROFILING,instrument,
530SN/A`define(`WANT_PROFILING',no)')
540SN/A
550SN/A
5611025SweijunC int calling_conventions (...);
5711025SweijunC
580SN/AC The global variable "calling_conventions_function" is the function to
5911025SweijunC call, with the arguments as passed here.
600SN/AC
610SN/AC Perhaps the finit should be done only if the tags word isn't clear, but
620SN/AC nothing uses the rounding mode or anything at the moment.
630SN/A
640SN/Adefine(G,
650SN/Am4_assert_numargs(1)
660SN/A`GSYM_PREFIX`'$1')
6713745Sweijun
6813745Sweijun	.text
6913745Sweijun	ALIGN(8)
700SN/APROLOGUE(calling_conventions)
710SN/A	movl	(%esp), %eax
720SN/A	movl	%eax, G(calling_conventions_retaddr)
730SN/A
740SN/A	movl	$L(return), (%esp)
750SN/A
760SN/A	movl	%ebx, G(calling_conventions_save_ebx)
770SN/A	movl	%esi, G(calling_conventions_save_esi)
780SN/A	movl	%edi, G(calling_conventions_save_edi)
790SN/A	movl	%ebp, G(calling_conventions_save_ebp)
800SN/A
810SN/A	movl	$0x01234567, %ebx
820SN/A	movl	$0x89ABCDEF, %esi
830SN/A	movl	$0xFEDCBA98, %edi
840SN/A	movl	$0x76543210, %ebp
850SN/A
860SN/A	C try to provoke a problem by starting with junk in the registers,
870SN/A	C especially in %eax and %edx which will be return values
880SN/A	movl	$0x70246135, %eax
890SN/A	movl	$0x8ACE9BDF, %ecx
900SN/A	movl	$0xFDB97531, %edx
910SN/A
920SN/A	jmp	*G(calling_conventions_function)
930SN/A
940SN/AL(return):
950SN/A	movl	%ebx, G(calling_conventions_ebx)
960SN/A	movl	%esi, G(calling_conventions_esi)
970SN/A	movl	%edi, G(calling_conventions_edi)
980SN/A	movl	%ebp, G(calling_conventions_ebp)
990SN/A
1000SN/A	pushf
1010SN/A	popl	%ebx
1020SN/A	movl	%ebx, G(calling_conventions_eflags)
1030SN/A
1040SN/A	fstenv	G(calling_conventions_fenv)
1050SN/A	finit
1067686SN/A
1070SN/A	movl	G(calling_conventions_save_ebx), %ebx
1080SN/A	movl	G(calling_conventions_save_esi), %esi
1090SN/A	movl	G(calling_conventions_save_edi), %edi
1100SN/A	movl	G(calling_conventions_save_ebp), %ebp
1110SN/A
1120SN/A	jmp	*G(calling_conventions_retaddr)
1130SN/A
1140SN/AEPILOGUE()
1150SN/A
1160SN/A