diff options
Diffstat (limited to 'erts/emulator/hipe/hipe_x86_bifs.m4')
-rw-r--r-- | erts/emulator/hipe/hipe_x86_bifs.m4 | 635 |
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' |