aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/hipe/hipe_x86_bifs.m4
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/hipe/hipe_x86_bifs.m4')
-rw-r--r--erts/emulator/hipe/hipe_x86_bifs.m4635
1 files changed, 635 insertions, 0 deletions
diff --git a/erts/emulator/hipe/hipe_x86_bifs.m4 b/erts/emulator/hipe/hipe_x86_bifs.m4
new file mode 100644
index 0000000000..80be74f7b2
--- /dev/null
+++ b/erts/emulator/hipe/hipe_x86_bifs.m4
@@ -0,0 +1,635 @@
+changecom(`/*', `*/')dnl
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2001-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+/*
+ * $Id$
+ */
+
+include(`hipe/hipe_x86_asm.m4')
+#`include' "hipe_literals.h"
+
+`#if THE_NON_VALUE == 0
+#define TEST_GOT_EXN testl %eax,%eax
+#else
+#define TEST_GOT_EXN cmpl $THE_NON_VALUE,%eax
+#endif'
+
+`#define TEST_GOT_MBUF movl P_MBUF(P), %edx; testl %edx, %edx; jnz 3f; 2:
+#define JOIN3(A,B,C) A##B##C
+#define HANDLE_GOT_MBUF(ARITY) 3: call JOIN3(nbif_,ARITY,_gc_after_bif); jmp 2b'
+
+/*
+ * standard_bif_interface_1(nbif_name, cbif_name)
+ * standard_bif_interface_2(nbif_name, cbif_name)
+ * standard_bif_interface_3(nbif_name, cbif_name)
+ *
+ * Generate native interface for a BIF with 1-3 parameters and
+ * standard failure mode.
+ */
+define(standard_bif_interface_1,
+`
+#ifndef HAVE_$1
+#`define' HAVE_$1
+ TEXT
+ .align 4
+ GLOBAL(ASYM($1))
+ASYM($1):
+ /* copy native stack pointer */
+ NBIF_COPY_NSP(1)
+
+ /* switch to C stack */
+ SWITCH_ERLANG_TO_C
+
+ /* make the call on the C stack */
+ NBIF_ARG_REG(0,P)
+ NBIF_ARG(1,1,0)
+ call CSYM($2)
+ TEST_GOT_MBUF
+
+ /* switch to native stack */
+ SWITCH_C_TO_ERLANG
+
+ /* throw exception if failure, otherwise return */
+ TEST_GOT_EXN
+ jz nbif_1_simple_exception
+ NBIF_RET(1)
+ HANDLE_GOT_MBUF(1)
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
+#endif')
+
+define(standard_bif_interface_2,
+`
+#ifndef HAVE_$1
+#`define' HAVE_$1
+ TEXT
+ .align 4
+ GLOBAL(ASYM($1))
+ASYM($1):
+ /* copy native stack pointer */
+ NBIF_COPY_NSP(2)
+
+ /* switch to C stack */
+ SWITCH_ERLANG_TO_C
+
+ /* make the call on the C stack */
+ NBIF_ARG_REG(0,P)
+ NBIF_ARG(1,2,0)
+ NBIF_ARG(2,2,1)
+ call CSYM($2)
+ TEST_GOT_MBUF
+
+ /* switch to native stack */
+ SWITCH_C_TO_ERLANG
+
+ /* throw exception if failure, otherwise return */
+ TEST_GOT_EXN
+ jz nbif_2_simple_exception
+ NBIF_RET(2)
+ HANDLE_GOT_MBUF(2)
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
+#endif')
+
+define(standard_bif_interface_3,
+`
+#ifndef HAVE_$1
+#`define' HAVE_$1
+ TEXT
+ .align 4
+ GLOBAL(ASYM($1))
+ASYM($1):
+ /* copy native stack pointer */
+ NBIF_COPY_NSP(3)
+
+ /* switch to C stack */
+ SWITCH_ERLANG_TO_C
+
+ /* make the call on the C stack */
+ NBIF_ARG_REG(0,P)
+ NBIF_ARG(1,3,0)
+ NBIF_ARG(2,3,1)
+ NBIF_ARG(3,3,2)
+ call CSYM($2)
+ TEST_GOT_MBUF
+
+ /* switch to native stack */
+ SWITCH_C_TO_ERLANG
+
+ /* throw exception if failure, otherwise return */
+ TEST_GOT_EXN
+ jz nbif_3_simple_exception
+ NBIF_RET(3)
+ HANDLE_GOT_MBUF(3)
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
+#endif')
+
+/*
+ * fail_bif_interface_0(nbif_name, cbif_name)
+ *
+ * Generate native interface for a BIF with 0 parameters and
+ * standard failure mode.
+ */
+define(fail_bif_interface_0,
+`
+#ifndef HAVE_$1
+#`define' HAVE_$1
+ TEXT
+ .align 4
+ GLOBAL(ASYM($1))
+ASYM($1):
+ /* switch to C stack */
+ SWITCH_ERLANG_TO_C
+
+ /* make the call on the C stack */
+ NBIF_ARG_REG(0,P)
+ call CSYM($2)
+ TEST_GOT_MBUF
+
+ /* switch to native stack */
+ SWITCH_C_TO_ERLANG
+
+ /* throw exception if failure, otherwise return */
+ TEST_GOT_EXN
+ jz nbif_0_simple_exception
+ NBIF_RET(0)
+ HANDLE_GOT_MBUF(0)
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
+#endif')
+
+/*
+ * nofail_primop_interface_0(nbif_name, cbif_name)
+ * nofail_primop_interface_1(nbif_name, cbif_name)
+ * nofail_primop_interface_2(nbif_name, cbif_name)
+ * nofail_primop_interface_3(nbif_name, cbif_name)
+ *
+ * Generate native interface for a primop with implicit P
+ * parameter, 0-3 ordinary parameters and no failure mode.
+ * Also used for guard BIFs.
+ */
+define(nofail_primop_interface_0,
+`
+#ifndef HAVE_$1
+#`define' HAVE_$1
+ TEXT
+ .align 4
+ GLOBAL(ASYM($1))
+ASYM($1):
+ /* switch to C stack */
+ SWITCH_ERLANG_TO_C
+
+ /* make the call on the C stack */
+ NBIF_ARG_REG(0,P)
+ call CSYM($2)
+ TEST_GOT_MBUF
+
+ /* switch to native stack */
+ SWITCH_C_TO_ERLANG
+
+ /* return */
+ NBIF_RET(0)
+ HANDLE_GOT_MBUF(0)
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
+#endif')
+
+define(nofail_primop_interface_1,
+`
+#ifndef HAVE_$1
+#`define' HAVE_$1
+ TEXT
+ .align 4
+ GLOBAL(ASYM($1))
+ASYM($1):
+ /* copy native stack pointer */
+ NBIF_COPY_NSP(1)
+
+ /* switch to C stack */
+ SWITCH_ERLANG_TO_C
+
+ /* make the call on the C stack */
+ NBIF_ARG_REG(0,P)
+ NBIF_ARG(1,1,0)
+ call CSYM($2)
+ TEST_GOT_MBUF
+
+ /* switch to native stack */
+ SWITCH_C_TO_ERLANG
+
+ /* return */
+ NBIF_RET(1)
+ HANDLE_GOT_MBUF(1)
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
+#endif')
+
+define(nofail_primop_interface_2,
+`
+#ifndef HAVE_$1
+#`define' HAVE_$1
+ TEXT
+ .align 4
+ GLOBAL(ASYM($1))
+ASYM($1):
+ /* copy native stack pointer */
+ NBIF_COPY_NSP(2)
+
+ /* switch to C stack */
+ SWITCH_ERLANG_TO_C
+
+ /* make the call on the C stack */
+ NBIF_ARG_REG(0,P)
+ NBIF_ARG(1,2,0)
+ NBIF_ARG(2,2,1)
+ call CSYM($2)
+ TEST_GOT_MBUF
+
+ /* switch to native stack */
+ SWITCH_C_TO_ERLANG
+
+ /* return */
+ NBIF_RET(2)
+ HANDLE_GOT_MBUF(2)
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
+#endif')
+
+define(nofail_primop_interface_3,
+`
+#ifndef HAVE_$1
+#`define' HAVE_$1
+ TEXT
+ .align 4
+ GLOBAL(ASYM($1))
+ASYM($1):
+ /* copy native stack pointer */
+ NBIF_COPY_NSP(3)
+
+ /* switch to C stack */
+ SWITCH_ERLANG_TO_C
+
+ /* make the call on the C stack */
+ NBIF_ARG_REG(0,P)
+ NBIF_ARG(1,3,0)
+ NBIF_ARG(2,3,1)
+ NBIF_ARG(3,3,2)
+ call CSYM($2)
+ TEST_GOT_MBUF
+
+ /* switch to native stack */
+ SWITCH_C_TO_ERLANG
+
+ /* return */
+ NBIF_RET(3)
+ HANDLE_GOT_MBUF(3)
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
+#endif')
+
+/*
+ * nocons_nofail_primop_interface_0(nbif_name, cbif_name)
+ * nocons_nofail_primop_interface_1(nbif_name, cbif_name)
+ * nocons_nofail_primop_interface_2(nbif_name, cbif_name)
+ * nocons_nofail_primop_interface_3(nbif_name, cbif_name)
+ * nocons_nofail_primop_interface_5(nbif_name, cbif_name)
+ *
+ * Generate native interface for a primop with implicit P
+ * parameter, 0-3 or 5 ordinary parameters, and no failure mode.
+ * The primop cannot CONS or gc.
+ */
+define(nocons_nofail_primop_interface_0,
+`
+#ifndef HAVE_$1
+#`define' HAVE_$1
+ TEXT
+ .align 4
+ GLOBAL(ASYM($1))
+ASYM($1):
+ /* switch to C stack */
+ SWITCH_ERLANG_TO_C_QUICK
+
+ /* make the call on the C stack */
+ NBIF_ARG_REG(0,P)
+ call CSYM($2)
+
+ /* switch to native stack */
+ SWITCH_C_TO_ERLANG_QUICK
+
+ /* return */
+ NBIF_RET(0)
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
+#endif')
+
+define(nocons_nofail_primop_interface_1,
+`
+#ifndef HAVE_$1
+#`define' HAVE_$1
+ TEXT
+ .align 4
+ GLOBAL(ASYM($1))
+ASYM($1):
+ /* copy native stack pointer */
+ NBIF_COPY_NSP(1)
+
+ /* switch to C stack */
+ SWITCH_ERLANG_TO_C_QUICK
+
+ /* make the call on the C stack */
+ NBIF_ARG_REG(0,P)
+ NBIF_ARG(1,1,0)
+ call CSYM($2)
+
+ /* switch to native stack */
+ SWITCH_C_TO_ERLANG_QUICK
+
+ /* return */
+ NBIF_RET(1)
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
+#endif')
+
+define(nocons_nofail_primop_interface_2,
+`
+#ifndef HAVE_$1
+#`define' HAVE_$1
+ TEXT
+ .align 4
+ GLOBAL(ASYM($1))
+ASYM($1):
+ /* copy native stack pointer */
+ NBIF_COPY_NSP(2)
+
+ /* switch to C stack */
+ SWITCH_ERLANG_TO_C_QUICK
+
+ /* make the call on the C stack */
+ NBIF_ARG_REG(0,P)
+ NBIF_ARG(1,2,0)
+ NBIF_ARG(2,2,1)
+ call CSYM($2)
+
+ /* switch to native stack */
+ SWITCH_C_TO_ERLANG_QUICK
+
+ /* return */
+ NBIF_RET(2)
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
+#endif')
+
+define(nocons_nofail_primop_interface_3,
+`
+#ifndef HAVE_$1
+#`define' HAVE_$1
+ TEXT
+ .align 4
+ GLOBAL(ASYM($1))
+ASYM($1):
+ /* copy native stack pointer */
+ NBIF_COPY_NSP(3)
+
+ /* switch to C stack */
+ SWITCH_ERLANG_TO_C_QUICK
+
+ /* make the call on the C stack */
+ NBIF_ARG_REG(0,P)
+ NBIF_ARG(1,3,0)
+ NBIF_ARG(2,3,1)
+ NBIF_ARG(3,3,2)
+ call CSYM($2)
+
+ /* switch to native stack */
+ SWITCH_C_TO_ERLANG_QUICK
+
+ /* return */
+ NBIF_RET(3)
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
+#endif')
+
+define(nocons_nofail_primop_interface_5,
+`
+#ifndef HAVE_$1
+#`define' HAVE_$1
+ TEXT
+ .align 4
+ GLOBAL(ASYM($1))
+ASYM($1):
+ /* copy native stack pointer */
+ NBIF_COPY_NSP(5)
+
+ /* switch to C stack */
+ SWITCH_ERLANG_TO_C_QUICK
+
+ /* make the call on the C stack */
+ NBIF_ARG_REG(0,P)
+ NBIF_ARG(1,5,0)
+ NBIF_ARG(2,5,1)
+ NBIF_ARG(3,5,2)
+ NBIF_ARG(4,5,3)
+ NBIF_ARG(5,5,4)
+ call CSYM($2)
+
+ /* switch to native stack */
+ SWITCH_C_TO_ERLANG_QUICK
+
+ /* return */
+ NBIF_RET(5)
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
+#endif')
+
+/*
+ * noproc_primop_interface_0(nbif_name, cbif_name)
+ * noproc_primop_interface_1(nbif_name, cbif_name)
+ * noproc_primop_interface_2(nbif_name, cbif_name)
+ * noproc_primop_interface_3(nbif_name, cbif_name)
+ * noproc_primop_interface_5(nbif_name, cbif_name)
+ *
+ * Generate native interface for a primop with no implicit P
+ * parameter, 0-3 or 5 ordinary parameters, and no failure mode.
+ * The primop cannot CONS or gc.
+ */
+define(noproc_primop_interface_0,
+`
+#ifndef HAVE_$1
+#`define' HAVE_$1
+ TEXT
+ .align 4
+ GLOBAL(ASYM($1))
+ASYM($1):
+ /* switch to C stack */
+ SWITCH_ERLANG_TO_C_QUICK
+
+ /* make the call on the C stack */
+ call CSYM($2)
+
+ /* switch to native stack */
+ SWITCH_C_TO_ERLANG_QUICK
+
+ /* return */
+ NBIF_RET(0)
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
+#endif')
+
+define(noproc_primop_interface_1,
+`
+#ifndef HAVE_$1
+#`define' HAVE_$1
+ TEXT
+ .align 4
+ GLOBAL(ASYM($1))
+ASYM($1):
+ /* copy native stack pointer */
+ NBIF_COPY_NSP(1)
+
+ /* switch to C stack */
+ SWITCH_ERLANG_TO_C_QUICK
+
+ /* make the call on the C stack */
+ NBIF_ARG(0,1,0)
+ call CSYM($2)
+
+ /* switch to native stack */
+ SWITCH_C_TO_ERLANG_QUICK
+
+ /* return */
+ NBIF_RET(1)
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
+#endif')
+
+define(noproc_primop_interface_2,
+`
+#ifndef HAVE_$1
+#`define' HAVE_$1
+ TEXT
+ .align 4
+ GLOBAL(ASYM($1))
+ASYM($1):
+ /* copy native stack pointer */
+ NBIF_COPY_NSP(2)
+
+ /* switch to C stack */
+ SWITCH_ERLANG_TO_C_QUICK
+
+ /* make the call on the C stack */
+ NBIF_ARG(0,2,0)
+ NBIF_ARG(1,2,1)
+ call CSYM($2)
+
+ /* switch to native stack */
+ SWITCH_C_TO_ERLANG_QUICK
+
+ /* return */
+ NBIF_RET(2)
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
+#endif')
+
+define(noproc_primop_interface_3,
+`
+#ifndef HAVE_$1
+#`define' HAVE_$1
+ TEXT
+ .align 4
+ GLOBAL(ASYM($1))
+ASYM($1):
+ /* copy native stack pointer */
+ NBIF_COPY_NSP(3)
+
+ /* switch to C stack */
+ SWITCH_ERLANG_TO_C_QUICK
+
+ /* make the call on the C stack */
+ NBIF_ARG(0,3,0)
+ NBIF_ARG(1,3,1)
+ NBIF_ARG(2,3,2)
+ call CSYM($2)
+
+ /* switch to native stack */
+ SWITCH_C_TO_ERLANG_QUICK
+
+ /* return */
+ NBIF_RET(3)
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
+#endif')
+
+define(noproc_primop_interface_5,
+`
+#ifndef HAVE_$1
+#`define' HAVE_$1
+ TEXT
+ .align 4
+ GLOBAL(ASYM($1))
+ASYM($1):
+ /* copy native stack pointer */
+ NBIF_COPY_NSP(5)
+
+ /* switch to C stack */
+ SWITCH_ERLANG_TO_C_QUICK
+
+ /* make the call on the C stack */
+ NBIF_ARG(0,5,0)
+ NBIF_ARG(1,5,1)
+ NBIF_ARG(2,5,2)
+ NBIF_ARG(3,5,3)
+ NBIF_ARG(4,5,4)
+ call CSYM($2)
+
+ /* switch to native stack */
+ SWITCH_C_TO_ERLANG_QUICK
+
+ /* return */
+ NBIF_RET(5)
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
+#endif')
+
+/*
+ * x86-specific primops.
+ */
+noproc_primop_interface_0(nbif_handle_fp_exception, erts_restore_fpu)
+
+/*
+ * Implement gc_bif_interface_0 as nofail_primop_interface_0.
+ */
+define(gc_bif_interface_0,`nofail_primop_interface_0($1, $2)')
+
+/*
+ * Implement gc_bif_interface_N as standard_bif_interface_N (N=1,2).
+ */
+define(gc_bif_interface_1,`standard_bif_interface_1($1, $2)')
+define(gc_bif_interface_2,`standard_bif_interface_2($1, $2)')
+
+/*
+ * Implement gc_nofail_primop_interface_1 as nofail_primop_interface_1.
+ */
+define(gc_nofail_primop_interface_1,`nofail_primop_interface_1($1, $2)')
+
+include(`hipe/hipe_bif_list.m4')
+
+`#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif'