Blame tests/amd64call.asm

Packit 5c3484
dnl  AMD64 calling conventions checking.
Packit 5c3484
Packit 5c3484
dnl  Copyright 2000, 2003, 2004, 2006, 2007, 2010 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
	mov	%rdi, -8(%rsp)
Packit 5c3484
	fldcw	-8(%rsp)
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
	movq	$0, -8(%rsp)
Packit 5c3484
	fstcw	-8(%rsp)
Packit 5c3484
	mov	-8(%rsp), %rax
Packit 5c3484
	ret
Packit 5c3484
EPILOGUE()
Packit 5c3484
Packit 5c3484
Packit 5c3484
dnl  Instrumented profiling won't come out quite right below, since we don't do
Packit 5c3484
dnl  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_RBX', eval(8*0)($1))
Packit 5c3484
define(`WANT_RBP', eval(8*1)($1))
Packit 5c3484
define(`WANT_R12', eval(8*2)($1))
Packit 5c3484
define(`WANT_R13', eval(8*3)($1))
Packit 5c3484
define(`WANT_R14', eval(8*4)($1))
Packit 5c3484
define(`WANT_R15', eval(8*5)($1))
Packit 5c3484
Packit 5c3484
define(`JUNK_RAX', eval(8*6)($1))
Packit 5c3484
define(`JUNK_R10', eval(8*7)($1))
Packit 5c3484
define(`JUNK_R11', eval(8*8)($1))
Packit 5c3484
Packit 5c3484
define(`SAVE_RBX', eval(8*9)($1))
Packit 5c3484
define(`SAVE_RBP', eval(8*10)($1))
Packit 5c3484
define(`SAVE_R12', eval(8*11)($1))
Packit 5c3484
define(`SAVE_R13', eval(8*12)($1))
Packit 5c3484
define(`SAVE_R14', eval(8*13)($1))
Packit 5c3484
define(`SAVE_R15', eval(8*14)($1))
Packit 5c3484
Packit 5c3484
define(`RETADDR',  eval(8*15)($1))
Packit 5c3484
Packit 5c3484
define(`RBX',	   eval(8*16)($1))
Packit 5c3484
define(`RBP',	   eval(8*17)($1))
Packit 5c3484
define(`R12',	   eval(8*18)($1))
Packit 5c3484
define(`R13',	   eval(8*19)($1))
Packit 5c3484
define(`R14',	   eval(8*20)($1))
Packit 5c3484
define(`R15',	   eval(8*21)($1))
Packit 5c3484
define(`RFLAGS',   eval(8*22)($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(32)
Packit 5c3484
PROLOGUE(calling_conventions)
Packit 5c3484
	mov	G(calling_conventions_values)@GOTPCREL(%rip), %rax
Packit 5c3484
	pop	RETADDR(%rax)
Packit 5c3484
Packit 5c3484
	mov	%rbx, SAVE_RBX(%rax)
Packit 5c3484
	mov	%rbp, SAVE_RBP(%rax)
Packit 5c3484
	mov	%r12, SAVE_R12(%rax)
Packit 5c3484
	mov	%r13, SAVE_R13(%rax)
Packit 5c3484
	mov	%r14, SAVE_R14(%rax)
Packit 5c3484
	mov	%r15, SAVE_R15(%rax)
Packit 5c3484
Packit 5c3484
	C Values we expect to see unchanged, as per amd64check.c
Packit 5c3484
	mov	WANT_RBX(%rax), %rbx
Packit 5c3484
	mov	WANT_RBP(%rax), %rbp
Packit 5c3484
	mov	WANT_R12(%rax), %r12
Packit 5c3484
	mov	WANT_R13(%rax), %r13
Packit 5c3484
	mov	WANT_R14(%rax), %r14
Packit 5c3484
	mov	WANT_R15(%rax), %r15
Packit 5c3484
Packit 5c3484
	C Try to provoke a problem by starting with junk in the caller-saves
Packit 5c3484
	C registers, especially %rax which will be the return value.
Packit 5c3484
C	mov	JUNK_RAX(%rax), %rax		C overwritten below anyway
Packit 5c3484
	mov	JUNK_R10(%rax), %r10
Packit 5c3484
	mov	JUNK_R11(%rax), %r11
Packit 5c3484
Packit 5c3484
	mov	G(calling_conventions_function)@GOTPCREL(%rip), %rax
Packit 5c3484
	call	*(%rax)
Packit 5c3484
Packit 5c3484
	mov	G(calling_conventions_values)@GOTPCREL(%rip), %rcx
Packit 5c3484
Packit 5c3484
	mov	%rbx, RBX(%rcx)
Packit 5c3484
	mov	%rbp, RBP(%rcx)
Packit 5c3484
	mov	%r12, R12(%rcx)
Packit 5c3484
	mov	%r13, R13(%rcx)
Packit 5c3484
	mov	%r14, R14(%rcx)
Packit 5c3484
	mov	%r15, R15(%rcx)
Packit 5c3484
Packit 5c3484
	pushf
Packit 5c3484
	pop	%rbx
Packit 5c3484
	mov	%rbx, RFLAGS(%rcx)
Packit 5c3484
Packit 5c3484
	mov	SAVE_RBX(%rcx), %rbx
Packit 5c3484
	mov	SAVE_RBP(%rcx), %rbp
Packit 5c3484
	mov	SAVE_R12(%rcx), %r12
Packit 5c3484
	mov	SAVE_R13(%rcx), %r13
Packit 5c3484
	mov	SAVE_R14(%rcx), %r14
Packit 5c3484
	mov	SAVE_R15(%rcx), %r15
Packit 5c3484
Packit 5c3484
	C Overwrite parameter registers
Packit 5c3484
C	mov	JUNK_R9(%rcx), %r9
Packit 5c3484
C	mov	JUNK_R8(%rcx), %r8
Packit 5c3484
C	mov	JUNK_RCX(%rcx), %rcx
Packit 5c3484
C	mov	JUNK_RDX(%rcx), %rdx
Packit 5c3484
C	mov	JUNK_RSI(%rcx), %rsi
Packit 5c3484
C	mov	JUNK_RDI(%rcx), %rdi
Packit 5c3484
Packit 5c3484
	push	RETADDR(%rcx)
Packit 5c3484
Packit 5c3484
	mov	G(calling_conventions_fenv)@GOTPCREL(%rip), %rcx
Packit 5c3484
	fstenv	(%rcx)
Packit 5c3484
	finit
Packit 5c3484
Packit 5c3484
	ret
Packit 5c3484
Packit 5c3484
EPILOGUE()