xref: /openbsd-src/lib/libm/arch/amd64/abi.h (revision 2f2c00629eff6a304ebffb255fc56f4fa7a1833b)
1*2f2c0062Sguenther /*	$OpenBSD: abi.h,v 1.5 2016/09/12 19:47:01 guenther Exp $	*/
23ccbf660Sderaadt /*	$NetBSD: abi.h,v 1.2 2003/09/14 21:26:14 fvdl Exp $	*/
33ccbf660Sderaadt 
43ccbf660Sderaadt /*
53ccbf660Sderaadt  * Written by Frank van der Linden (fvdl@wasabisystems.com)
63ccbf660Sderaadt  */
73ccbf660Sderaadt 
83ccbf660Sderaadt /*
93ccbf660Sderaadt  * The x86-64 ABI specifies that float, double and long double
103ccbf660Sderaadt  * arguments are passed in SSE2 (xmm) registers. Unfortunately,
113ccbf660Sderaadt  * there is no way to push those on to the FP stack, which is
12f83afa0aSderaadt  * where the fancier instructions get their arguments from.
133ccbf660Sderaadt  *
143ccbf660Sderaadt  * Define some prologues and epilogues to store and retrieve
153ccbf660Sderaadt  * xmm regs to local variables.
163ccbf660Sderaadt  */
173ccbf660Sderaadt 
183ccbf660Sderaadt #define ARG_DOUBLE_ONE		-8(%rsp)
193ccbf660Sderaadt #define ARG_DOUBLE_TWO		-16(%rsp)
203ccbf660Sderaadt #define ARG_FLOAT_ONE		-4(%rsp)
213ccbf660Sderaadt #define ARG_FLOAT_TWO		-8(%rsp)
223ccbf660Sderaadt 
233ccbf660Sderaadt #define XMM_ONE_ARG_DOUBLE_PROLOGUE \
243ccbf660Sderaadt 	movsd	%xmm0, ARG_DOUBLE_ONE
253ccbf660Sderaadt 
263ccbf660Sderaadt #define XMM_TWO_ARG_DOUBLE_PROLOGUE \
273ccbf660Sderaadt 	movsd	%xmm0, ARG_DOUBLE_ONE ; \
283ccbf660Sderaadt 	movsd	%xmm1, ARG_DOUBLE_TWO
293ccbf660Sderaadt 
303ccbf660Sderaadt #define XMM_ONE_ARG_FLOAT_PROLOGUE \
313ccbf660Sderaadt 	movss	%xmm0, ARG_FLOAT_ONE
323ccbf660Sderaadt 
333ccbf660Sderaadt #define XMM_TWO_ARG_FLOAT_PROLOGUE \
343ccbf660Sderaadt 	movss	%xmm0, ARG_FLOAT_ONE ; \
353ccbf660Sderaadt 	movss	%xmm1, ARG_FLOAT_TWO
363ccbf660Sderaadt 
373ccbf660Sderaadt #define XMM_DOUBLE_EPILOGUE \
383ccbf660Sderaadt 	fstpl ARG_DOUBLE_ONE ; \
393ccbf660Sderaadt 	movsd ARG_DOUBLE_ONE, %xmm0
403ccbf660Sderaadt 
413ccbf660Sderaadt #define XMM_FLOAT_EPILOGUE \
423ccbf660Sderaadt 	fstps ARG_FLOAT_ONE ; \
433ccbf660Sderaadt 	movss ARG_FLOAT_ONE, %xmm0
443ccbf660Sderaadt 
453ccbf660Sderaadt #define FLDL_VAR(x)	fldl x(%rip)
463ccbf660Sderaadt 
47*2f2c0062Sguenther 
48*2f2c0062Sguenther /*
49*2f2c0062Sguenther  * We define a hidden alias with the prefix "_libm_" for each global symbol
50*2f2c0062Sguenther  * that may be used internally.  By referencing _libm_x instead of x, other
51*2f2c0062Sguenther  * parts of libm prevent overriding by the application and avoid unnecessary
52*2f2c0062Sguenther  * relocations.
53*2f2c0062Sguenther  */
54*2f2c0062Sguenther #define _HIDDEN(x)		_libm_##x
55*2f2c0062Sguenther #define _HIDDEN_ALIAS(x,y)			\
56*2f2c0062Sguenther 	STRONG_ALIAS(_HIDDEN(x),y);		\
57*2f2c0062Sguenther 	.hidden _HIDDEN(x)
58*2f2c0062Sguenther #define _HIDDEN_FALIAS(x,y)			\
59*2f2c0062Sguenther 	_HIDDEN_ALIAS(x,y);			\
60*2f2c0062Sguenther 	.type _HIDDEN(x),@function
61*2f2c0062Sguenther 
62*2f2c0062Sguenther /*
63*2f2c0062Sguenther  * For functions implemented in ASM that are used internally
64*2f2c0062Sguenther  *   END_STD(x)	Like DEF_STD() in C; for standard/reserved C names
65*2f2c0062Sguenther  *   END_NONSTD(x)	Like DEF_NONSTD() in C; for non-ISO C names
66*2f2c0062Sguenther  */
67*2f2c0062Sguenther #define	END_STD(x)	END(x); _HIDDEN_FALIAS(x,x); END(_HIDDEN(x))
68*2f2c0062Sguenther #define	END_NONSTD(x)	END_STD(x); .weak x
69