blob: dad77630282c1fde6ca2dc4d9fc8e7497bb15f28 [file] [log] [blame]
Austin Schuhdace2a62020-08-18 10:56:48 -07001dnl 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 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 mov %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 mov -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 mov G(calling_conventions_values)@GOTPCREL(%rip), %rax
105 pop RETADDR(%rax)
106
107 mov %rbx, SAVE_RBX(%rax)
108 mov %rbp, SAVE_RBP(%rax)
109 mov %r12, SAVE_R12(%rax)
110 mov %r13, SAVE_R13(%rax)
111 mov %r14, SAVE_R14(%rax)
112 mov %r15, SAVE_R15(%rax)
113
114 C Values we expect to see unchanged, as per amd64check.c
115 mov WANT_RBX(%rax), %rbx
116 mov WANT_RBP(%rax), %rbp
117 mov WANT_R12(%rax), %r12
118 mov WANT_R13(%rax), %r13
119 mov WANT_R14(%rax), %r14
120 mov 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 mov JUNK_RAX(%rax), %rax C overwritten below anyway
125 mov JUNK_R10(%rax), %r10
126 mov JUNK_R11(%rax), %r11
127
128 mov G(calling_conventions_function)@GOTPCREL(%rip), %rax
129 call *(%rax)
130
131 mov G(calling_conventions_values)@GOTPCREL(%rip), %rcx
132
133 mov %rbx, RBX(%rcx)
134 mov %rbp, RBP(%rcx)
135 mov %r12, R12(%rcx)
136 mov %r13, R13(%rcx)
137 mov %r14, R14(%rcx)
138 mov %r15, R15(%rcx)
139
140 pushf
141 pop %rbx
142 mov %rbx, RFLAGS(%rcx)
143
144 mov SAVE_RBX(%rcx), %rbx
145 mov SAVE_RBP(%rcx), %rbp
146 mov SAVE_R12(%rcx), %r12
147 mov SAVE_R13(%rcx), %r13
148 mov SAVE_R14(%rcx), %r14
149 mov 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 push RETADDR(%rcx)
160
161 mov G(calling_conventions_fenv)@GOTPCREL(%rip), %rcx
162 fstenv (%rcx)
163 finit
164
165 ret
166
167EPILOGUE()