xref: /netbsd-src/external/lgpl3/gmp/dist/tests/amd64call.asm (revision 413d532bcc3f62d122e56d92e13ac64825a40baf)
1dnl  AMD64 calling conventions checking.
2
3dnl  Copyright 2000, 2003, 2004, 2006, 2007, 2010 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  http://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	movq	%rdi, -8(%rsp)
34	fldcw	-8(%rsp)
35	ret
36EPILOGUE()
37
38
39C unsigned short x86_fstcw (void);
40C
41C Execute an fstcw, returning the current x87 control word.
42
43PROLOGUE(x86_fstcw)
44	movq	$0, -8(%rsp)
45	fstcw	-8(%rsp)
46	movq	-8(%rsp), %rax
47	ret
48EPILOGUE()
49
50
51dnl  Instrumented profiling won't come out quite right below, since we don't do
52dnl  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_RBX', eval(8*0)($1))
69define(`WANT_RBP', eval(8*1)($1))
70define(`WANT_R12', eval(8*2)($1))
71define(`WANT_R13', eval(8*3)($1))
72define(`WANT_R14', eval(8*4)($1))
73define(`WANT_R15', eval(8*5)($1))
74
75define(`JUNK_RAX', eval(8*6)($1))
76define(`JUNK_R10', eval(8*7)($1))
77define(`JUNK_R11', eval(8*8)($1))
78
79define(`SAVE_RBX', eval(8*9)($1))
80define(`SAVE_RBP', eval(8*10)($1))
81define(`SAVE_R12', eval(8*11)($1))
82define(`SAVE_R13', eval(8*12)($1))
83define(`SAVE_R14', eval(8*13)($1))
84define(`SAVE_R15', eval(8*14)($1))
85
86define(`RETADDR',  eval(8*15)($1))
87
88define(`RBX',	   eval(8*16)($1))
89define(`RBP',	   eval(8*17)($1))
90define(`R12',	   eval(8*18)($1))
91define(`R13',	   eval(8*19)($1))
92define(`R14',	   eval(8*20)($1))
93define(`R15',	   eval(8*21)($1))
94define(`RFLAGS',   eval(8*22)($1))
95
96
97define(G,
98m4_assert_numargs(1)
99`GSYM_PREFIX`'$1')
100
101	TEXT
102	ALIGN(32)
103PROLOGUE(calling_conventions)
104	movq	G(calling_conventions_values)@GOTPCREL(%rip), %rax
105	popq	RETADDR(%rax)
106
107	movq	%rbx, SAVE_RBX(%rax)
108	movq	%rbp, SAVE_RBP(%rax)
109	movq	%r12, SAVE_R12(%rax)
110	movq	%r13, SAVE_R13(%rax)
111	movq	%r14, SAVE_R14(%rax)
112	movq	%r15, SAVE_R15(%rax)
113
114	C Values we expect to see unchanged, as per amd64check.c
115	movq	WANT_RBX(%rax), %rbx
116	movq	WANT_RBP(%rax), %rbp
117	movq	WANT_R12(%rax), %r12
118	movq	WANT_R13(%rax), %r13
119	movq	WANT_R14(%rax), %r14
120	movq	WANT_R15(%rax), %r15
121
122	C Try to provoke a problem by starting with junk in the caller-saves
123	C registers, especially %rax which will be the return value.
124C	movq	JUNK_RAX(%rax), %rax		C overwritten below anyway
125	movq	JUNK_R10(%rax), %r10
126	movq	JUNK_R11(%rax), %r11
127
128	movq	G(calling_conventions_function)@GOTPCREL(%rip), %rax
129	call	*(%rax)
130
131	movq	G(calling_conventions_values)@GOTPCREL(%rip), %rcx
132
133	movq	%rbx, RBX(%rcx)
134	movq	%rbp, RBP(%rcx)
135	movq	%r12, R12(%rcx)
136	movq	%r13, R13(%rcx)
137	movq	%r14, R14(%rcx)
138	movq	%r15, R15(%rcx)
139
140	pushfq
141	popq	%rbx
142	movq	%rbx, RFLAGS(%rcx)
143
144	movq	SAVE_RBX(%rcx), %rbx
145	movq	SAVE_RBP(%rcx), %rbp
146	movq	SAVE_R12(%rcx), %r12
147	movq	SAVE_R13(%rcx), %r13
148	movq	SAVE_R14(%rcx), %r14
149	movq	SAVE_R15(%rcx), %r15
150
151	C Overwrite parameter registers
152C	mov	JUNK_R9(%rcx), %r9
153C	mov	JUNK_R8(%rcx), %r8
154C	mov	JUNK_RCX(%rcx), %rcx
155C	mov	JUNK_RDX(%rcx), %rdx
156C	mov	JUNK_RSI(%rcx), %rsi
157C	mov	JUNK_RDI(%rcx), %rdi
158
159	pushq	RETADDR(%rcx)
160
161	movq	G(calling_conventions_fenv)@GOTPCREL(%rip), %rcx
162	fstenv	(%rcx)
163	finit
164
165	ret
166
167EPILOGUE()
168