Blame tests/x86call.asm

Packit 5c3484
dnl  x86 calling conventions checking.
Packit 5c3484
Packit 5c3484
dnl  Copyright 2000, 2003, 2010, 2013 Free Software Foundation, Inc.
Packit 5c3484
Packit 5c3484
dnl  This file is part of the GNU MP Library test suite.
Packit 5c3484
Packit 5c3484
dnl  The GNU MP Library test suite is free software; you can redistribute it
Packit 5c3484
dnl  and/or modify it under the terms of the GNU General Public License as
Packit 5c3484
dnl  published by the Free Software Foundation; either version 3 of the
Packit 5c3484
dnl  License, or (at your option) any later version.
Packit 5c3484
Packit 5c3484
dnl  The GNU MP Library test suite is distributed in the hope that it will be
Packit 5c3484
dnl  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 5c3484
dnl  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
Packit 5c3484
dnl  Public License for more details.
Packit 5c3484
Packit 5c3484
dnl  You should have received a copy of the GNU General Public License along
Packit 5c3484
dnl  with the GNU MP Library test suite.  If not, see
Packit 5c3484
dnl  https://www.gnu.org/licenses/.
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  The current version of the code attempts to keep the call/return
Packit 5c3484
dnl  prediction stack valid, but matching calls and returns.
Packit 5c3484
Packit 5c3484
include(`../config.m4')
Packit 5c3484
Packit 5c3484
Packit 5c3484
C void x86_fldcw (unsigned short cw);
Packit 5c3484
C
Packit 5c3484
C Execute an fldcw, setting the x87 control word to cw.
Packit 5c3484
Packit 5c3484
PROLOGUE(x86_fldcw)
Packit 5c3484
	fldcw	4(%esp)
Packit 5c3484
	ret
Packit 5c3484
EPILOGUE()
Packit 5c3484
Packit 5c3484
Packit 5c3484
C unsigned short x86_fstcw (void);
Packit 5c3484
C
Packit 5c3484
C Execute an fstcw, returning the current x87 control word.
Packit 5c3484
Packit 5c3484
PROLOGUE(x86_fstcw)
Packit 5c3484
	xor	%eax, %eax
Packit 5c3484
	push	%eax
Packit 5c3484
	fstcw	(%esp)
Packit 5c3484
	pop	%eax
Packit 5c3484
	ret
Packit 5c3484
EPILOGUE()
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Instrumented profiling doesn't come out quite right below, since we don't
Packit 5c3484
dnl  do an actual "ret".  There's only a few instructions here, so there's no
Packit 5c3484
dnl  great need to get them separately accounted, just let them get attributed
Packit 5c3484
dnl  to the caller.  FIXME this comment might no longer be true.
Packit 5c3484
Packit 5c3484
ifelse(WANT_PROFILING,instrument,
Packit 5c3484
`define(`WANT_PROFILING',no)')
Packit 5c3484
Packit 5c3484
Packit 5c3484
C int calling_conventions (...);
Packit 5c3484
C
Packit 5c3484
C The global variable "calling_conventions_function" is the function to
Packit 5c3484
C call, with the arguments as passed here.
Packit 5c3484
C
Packit 5c3484
C Perhaps the finit should be done only if the tags word isn't clear, but
Packit 5c3484
C nothing uses the rounding mode or anything at the moment.
Packit 5c3484
Packit 5c3484
define(`WANT_EBX', eval(4*0)($1))
Packit 5c3484
define(`WANT_EBP', eval(4*1)($1))
Packit 5c3484
define(`WANT_ESI', eval(4*2)($1))
Packit 5c3484
define(`WANT_EDI', eval(4*3)($1))
Packit 5c3484
Packit 5c3484
define(`JUNK_EAX', eval(4*4)($1))
Packit 5c3484
define(`JUNK_ECX', eval(4*5)($1))
Packit 5c3484
define(`JUNK_EDX', eval(4*6)($1))
Packit 5c3484
Packit 5c3484
define(`SAVE_EBX', eval(4*7)($1))
Packit 5c3484
define(`SAVE_EBP', eval(4*8)($1))
Packit 5c3484
define(`SAVE_ESI', eval(4*9)($1))
Packit 5c3484
define(`SAVE_EDI', eval(4*10)($1))
Packit 5c3484
Packit 5c3484
define(`RETADDR',  eval(4*11)($1))
Packit 5c3484
Packit 5c3484
define(`EBX',	   eval(4*12)($1))
Packit 5c3484
define(`EBP',	   eval(4*13)($1))
Packit 5c3484
define(`ESI',	   eval(4*14)($1))
Packit 5c3484
define(`EDI',	   eval(4*15)($1))
Packit 5c3484
define(`EFLAGS',   eval(4*16)($1))
Packit 5c3484
Packit 5c3484
Packit 5c3484
define(G,
Packit 5c3484
m4_assert_numargs(1)
Packit 5c3484
`GSYM_PREFIX`'$1')
Packit 5c3484
Packit 5c3484
	TEXT
Packit 5c3484
	ALIGN(8)
Packit 5c3484
PROLOGUE(calling_conventions)
Packit 5c3484
	LEA(	G(calling_conventions_values), %ecx)
Packit 5c3484
	pop	RETADDR(%ecx)
Packit 5c3484
Packit 5c3484
	mov	%ebx, SAVE_EBX(%ecx)
Packit 5c3484
	mov	%ebp, SAVE_EBP(%ecx)
Packit 5c3484
	mov	%esi, SAVE_ESI(%ecx)
Packit 5c3484
	mov	%edi, SAVE_EDI(%ecx)
Packit 5c3484
Packit 5c3484
	C Values we expect to see unchanged, as per amd64check.c
Packit 5c3484
	mov	WANT_EBX(%ecx), %ebx
Packit 5c3484
	mov	WANT_EBP(%ecx), %ebp
Packit 5c3484
	mov	WANT_ESI(%ecx), %esi
Packit 5c3484
	mov	WANT_EDI(%ecx), %edi
Packit 5c3484
Packit 5c3484
	C Try to provoke a problem by starting with junk in the caller-saves
Packit 5c3484
	C registers, especially in %eax and %edx which will be return values
Packit 5c3484
	mov	JUNK_EAX(%ecx), %eax
Packit 5c3484
	mov	JUNK_EDX(%ecx), %edx
Packit 5c3484
C	mov	JUNK_ECX(%ecx), %ecx
Packit 5c3484
Packit 5c3484
ifdef(`PIC',`
Packit 5c3484
	LEA(	G(calling_conventions_function), %ecx)
Packit 5c3484
	call	*(%ecx)
Packit 5c3484
',`
Packit 5c3484
	call	*G(calling_conventions_function)
Packit 5c3484
')
Packit 5c3484
Packit 5c3484
	LEA(	G(calling_conventions_values), %ecx)
Packit 5c3484
Packit 5c3484
	mov	%ebx, EBX(%ecx)
Packit 5c3484
	mov	%ebp, EBP(%ecx)
Packit 5c3484
	mov	%esi, ESI(%ecx)
Packit 5c3484
	mov	%edi, EDI(%ecx)
Packit 5c3484
Packit 5c3484
	pushf
Packit 5c3484
	pop	%ebx
Packit 5c3484
	mov	%ebx, EFLAGS(%ecx)
Packit 5c3484
Packit 5c3484
	mov	SAVE_EBX(%ecx), %ebx
Packit 5c3484
	mov	SAVE_ESI(%ecx), %esi
Packit 5c3484
	mov	SAVE_EDI(%ecx), %edi
Packit 5c3484
	mov	SAVE_EBP(%ecx), %ebp
Packit 5c3484
Packit 5c3484
	push	RETADDR(%ecx)
Packit 5c3484
Packit 5c3484
ifdef(`PIC',`
Packit 5c3484
	LEA(	G(calling_conventions_fenv), %ecx)
Packit 5c3484
	fstenv	(%ecx)
Packit 5c3484
',`
Packit 5c3484
	fstenv	G(calling_conventions_fenv)
Packit 5c3484
')
Packit 5c3484
	finit
Packit 5c3484
Packit 5c3484
	ret
Packit 5c3484
Packit 5c3484
EPILOGUE()
Packit 5c3484
ASM_END()