changecom(`/*', `*/')dnl
/*
* %CopyrightBegin%
*
* Copyright Ericsson AB 2004-2018. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* %CopyrightEnd%
*/
#`define ASM'
include(`hipe/hipe_ppc_asm.m4')
#`include' "config.h"
#`include' "hipe_literals.h"
`#if defined(ERTS_ENABLE_LOCK_CHECK)
# define CALL_BIF(F) STORE_IA(CSYM(nbif_impl_##F), P_BIF_CALLEE(P), r29); bl CSYM(hipe_debug_bif_wrapper)
#else
# define CALL_BIF(F) bl CSYM(nbif_impl_##F)
#endif'
.text
.p2align 2
define(TEST_GOT_MBUF,`LOAD r4, P_MBUF(P) /* `TEST_GOT_MBUF' */
CMPI r4, 0
bne- 3f
2:')
define(HANDLE_GOT_MBUF,`
3: bl CSYM(nbif_$1_gc_after_bif) /* `HANDLE_GOT_MBUF' */
b 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)
* standard_bif_interface_4(nbif_name, cbif_name)
* standard_bif_interface_0(nbif_name, cbif_name)
*
* Generate native interface for a BIF with 0-4 parameters and
* standard failure mode.
*/
define(standard_bif_interface_1,
`
#ifndef HAVE_$1
#`define' HAVE_$1
GLOBAL(ASYM($1))
ASYM($1):
/* Set up C argument registers. */
mr r3, P
NBIF_ARG(r4,1,0)
/* Save caller-save registers and call the C function. */
SAVE_CONTEXT_BIF
STORE r4, P_ARG0(r3) /* Store BIF__ARGS in def_arg_reg[] */
addi r4, r3, P_ARG0
CALL_BIF($2)
TEST_GOT_MBUF
/* Restore registers. Check for exception. */
CMPI r3, THE_NON_VALUE
RESTORE_CONTEXT_BIF
beq- 1f
NBIF_RET(1)
1: /* workaround for bc:s small offset operand */
b CSYM(nbif_1_simple_exception)
HANDLE_GOT_MBUF(1)
SET_SIZE(ASYM($1))
TYPE_FUNCTION(ASYM($1))
#endif')
define(standard_bif_interface_2,
`
#ifndef HAVE_$1
#`define' HAVE_$1
GLOBAL(ASYM($1))
ASYM($1):
/* Set up C argument registers. */
mr r3, P
NBIF_ARG(r4,2,0)
NBIF_ARG(r5,2,1)
/* Save caller-save registers and call the C function. */
SAVE_CONTEXT_BIF
STORE r4, P_ARG0(r3) /* Store BIF__ARGS in def_arg_reg[] */
STORE r5, P_ARG1(r3)
addi r4, r3, P_ARG0
CALL_BIF($2)
TEST_GOT_MBUF
/* Restore registers. Check for exception. */
CMPI r3, THE_NON_VALUE
RESTORE_CONTEXT_BIF
beq- 1f
NBIF_RET(2)
1: /* workaround for bc:s small offset operand */
b CSYM(nbif_2_simple_exception)
HANDLE_GOT_MBUF(2)
SET_SIZE(ASYM($1))
TYPE_FUNCTION(ASYM($1))
#endif')
define(standard_bif_interface_3,
`
#ifndef HAVE_$1
#`define' HAVE_$1
GLOBAL(ASYM($1))
ASYM($1):
/* Set up C argument registers. */
mr r3, P
NBIF_ARG(r4,3,0)
NBIF_ARG(r5,3,1)
NBIF_ARG(r6,3,2)
/* Save caller-save registers and call the C function. */
SAVE_CONTEXT_BIF
STORE r4, P_ARG0(r3) /* Store BIF__ARGS in def_arg_reg[] */
STORE r5, P_ARG1(r3)
STORE r6, P_ARG2(r3)
addi r4, r3, P_ARG0
CALL_BIF($2)
TEST_GOT_MBUF
/* Restore registers. Check for exception. */
CMPI r3, THE_NON_VALUE
RESTORE_CONTEXT_BIF
beq- 1f
NBIF_RET(3)
1: /* workaround for bc:s small offset operand */
b CSYM(nbif_3_simple_exception)
HANDLE_GOT_MBUF(3)
SET_SIZE(ASYM($1))
TYPE_FUNCTION(ASYM($1))
#endif')
define(standard_bif_interface_4,
`
#ifndef HAVE_$1
#`define' HAVE_$1
GLOBAL(ASYM($1))
ASYM($1):
/* Set up C argument registers. */
mr r3, P
NBIF_ARG(r4,4,0)
NBIF_ARG(r5,4,1)
NBIF_ARG(r6,4,2)
NBIF_ARG(r7,4,3)
/* Save caller-save registers and call the C function. */
SAVE_CONTEXT_BIF
STORE r4, P_ARG0(r3) /* Store BIF__ARGS in def_arg_reg[] */
STORE r5, P_ARG1(r3)
STORE r6, P_ARG2(r3)
STORE r7, P_ARG3(r3)
addi r4, r3, P_ARG0
CALL_BIF($2)
TEST_GOT_MBUF
/* Restore registers. Check for exception. */
CMPI r3, THE_NON_VALUE
RESTORE_CONTEXT_BIF
beq- 1f
NBIF_RET(4)
1: /* workaround for bc:s small offset operand */
b CSYM(nbif_4_simple_exception)
HANDLE_GOT_MBUF(4)
SET_SIZE(ASYM($1))
TYPE_FUNCTION(ASYM($1))
#endif')
define(standard_bif_interface_0,
`
#ifndef HAVE_$1
#`define' HAVE_$1
GLOBAL(ASYM($1))
ASYM($1):
/* Set up C argument registers. */
mr r3, P
/* Save caller-save registers and call the C function. */
SAVE_CONTEXT_BIF
/* ignore empty BIF__ARGS */
CALL_BIF($2)
TEST_GOT_MBUF
/* Restore registers. Check for exception. */
CMPI r3, THE_NON_VALUE
RESTORE_CONTEXT_BIF
beq- 1f
NBIF_RET(0)
1: /* workaround for bc:s small offset operand */
b CSYM(nbif_0_simple_exception)
HANDLE_GOT_MBUF(0)
SET_SIZE(ASYM($1))
TYPE_FUNCTION(ASYM($1))
#endif')
/*
* gc_bif_interface_0(nbif_name, cbif_name)
* gc_bif_interface_1(nbif_name, cbif_name)
* gc_bif_interface_2(nbif_name, cbif_name)
* gc_bif_interface_3(nbif_name, cbif_name)
*
* Generate native interface for a BIF with 0-3 parameters and
* standard failure mode.
* The BIF may do a GC.
*/
define(gc_bif_interface_0,
`
#ifndef HAVE_$1
#`define' HAVE_$1
GLOBAL(ASYM($1))
ASYM($1):
/* Set up C argument registers. */
mr r3, P
/* Save caller-save registers and call the C function. */
SAVE_CONTEXT_GC
/* ignore empty BIF__ARGS */
CALL_BIF($2)
TEST_GOT_MBUF
/* Restore registers. */
RESTORE_CONTEXT_GC
NBIF_RET(0)
HANDLE_GOT_MBUF(0)
SET_SIZE(ASYM($1))
TYPE_FUNCTION(ASYM($1))
#endif')
define(gc_bif_interface_1,
`
#ifndef HAVE_$1
#`define' HAVE_$1
GLOBAL(ASYM($1))
ASYM($1):
/* Set up C argument registers. */
mr r3, P
NBIF_ARG(r4,1,0)
/* Save caller-save registers and call the C function. */
SAVE_CONTEXT_GC
STORE r4, P_ARG0(r3) /* Store BIF__ARGS in def_arg_reg[] */
addi r4, r3, P_ARG0
CALL_BIF($2)
TEST_GOT_MBUF
/* Restore registers. Check for exception. */
CMPI r3, THE_NON_VALUE
RESTORE_CONTEXT_GC
beq- 1f
NBIF_RET(1)
1: /* workaround for bc:s small offset operand */
b CSYM(nbif_1_simple_exception)
HANDLE_GOT_MBUF(1)
SET_SIZE(ASYM($1))
TYPE_FUNCTION(ASYM($1))
#endif')
define(gc_bif_interface_2,
`
#ifndef HAVE_$1
#`define' HAVE_$1
GLOBAL(ASYM($1))
ASYM($1):
/* Set up C argument registers. */
mr r3, P
NBIF_ARG(r4,2,0)
NBIF_ARG(r5,2,1)
/* Save caller-save registers and call the C function. */
SAVE_CONTEXT_GC
STORE r4, P_ARG0(r3) /* Store BIF__ARGS in def_arg_reg[] */
STORE r5, P_ARG1(r3)
addi r4, r3, P_ARG0
CALL_BIF($2)
TEST_GOT_MBUF
/* Restore registers. Check for exception. */
CMPI r3, THE_NON_VALUE
RESTORE_CONTEXT_GC
beq- 1f
NBIF_RET(2)
1: /* workaround for bc:s small offset operand */
b CSYM(nbif_2_simple_exception)
HANDLE_GOT_MBUF(2)
SET_SIZE(ASYM($1))
TYPE_FUNCTION(ASYM($1))
#endif')
define(gc_bif_interface_3,
`
#ifndef HAVE_$1
#`define' HAVE_$1
GLOBAL(ASYM($1))
ASYM($1):
/* Set up C argument registers. */
mr r3, P
NBIF_ARG(r4,3,0)
NBIF_ARG(r5,3,1)
NBIF_ARG(r6,3,2)
/* Save caller-save registers and call the C function. */
SAVE_CONTEXT_GC
STORE r4, P_ARG0(r3) /* Store BIF__ARGS in def_arg_reg[] */
STORE r5, P_ARG1(r3)
STORE r6, P_ARG2(r3)
addi r4, r3, P_ARG0
CALL_BIF($2)
TEST_GOT_MBUF
/* Restore registers. Check for exception. */
CMPI r3, THE_NON_VALUE
RESTORE_CONTEXT_GC
beq- 1f
NBIF_RET(3)
1: /* workaround for bc:s small offset operand */
b CSYM(nbif_3_simple_exception)
HANDLE_GOT_MBUF(3)
SET_SIZE(ASYM($1))
TYPE_FUNCTION(ASYM($1))
#endif')
/*
* gc_nofail_primop_interface_1(nbif_name, cbif_name)
*
* Generate native interface for a primop with implicit P
* parameter, 1 ordinary parameter and no failure mode.
* The primop may do a GC.
*/
define(gc_nofail_primop_interface_1,
`
#ifndef HAVE_$1
#`define' HAVE_$1
GLOBAL(ASYM($1))
ASYM($1):
/* Set up C argument registers. */
mr r3, P
NBIF_ARG(r4,1,0)
/* Save caller-save registers and call the C function. */
SAVE_CONTEXT_GC
bl CSYM($2)
/* Restore registers. */
RESTORE_CONTEXT_GC
NBIF_RET(1)
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
GLOBAL(ASYM($1))
ASYM($1):
/* Set up C argument registers. */
mr r3, P
/* Save caller-save registers and call the C function. */
SAVE_CONTEXT_BIF
bl CSYM($2)
TEST_GOT_MBUF
/* Restore registers. */
RESTORE_CONTEXT_BIF
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
GLOBAL(ASYM($1))
ASYM($1):
/* Set up C argument registers. */
mr r3, P
NBIF_ARG(r4,1,0)
/* Save caller-save registers and call the C function. */
SAVE_CONTEXT_BIF
bl CSYM($2)
TEST_GOT_MBUF
/* Restore registers. */
RESTORE_CONTEXT_BIF
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
GLOBAL(ASYM($1))
ASYM($1):
/* Set up C argument registers. */
mr r3, P
NBIF_ARG(r4,2,0)
NBIF_ARG(r5,2,1)
/* Save caller-save registers and call the C function. */
SAVE_CONTEXT_BIF
bl CSYM($2)
TEST_GOT_MBUF
/* Restore registers. */
RESTORE_CONTEXT_BIF
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
GLOBAL(ASYM($1))
ASYM($1):
/* Set up C argument registers. */
mr r3, P
NBIF_ARG(r4,3,0)
NBIF_ARG(r5,3,1)
NBIF_ARG(r6,3,2)
/* Save caller-save registers and call the C function. */
SAVE_CONTEXT_BIF
bl CSYM($2)
TEST_GOT_MBUF
/* Restore registers. */
RESTORE_CONTEXT_BIF
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
GLOBAL(ASYM($1))
ASYM($1):
/* Set up C argument registers. */
mr r3, P
/* Perform a quick save;call;restore;ret sequence. */
QUICK_CALL_RET(CSYM($2),0)
SET_SIZE(ASYM($1))
TYPE_FUNCTION(ASYM($1))
#endif')
define(nocons_nofail_primop_interface_1,
`
#ifndef HAVE_$1
#`define' HAVE_$1
GLOBAL(ASYM($1))
ASYM($1):
/* Set up C argument registers. */
mr r3, P
NBIF_ARG(r4,1,0)
/* Perform a quick save;call;restore;ret sequence. */
QUICK_CALL_RET(CSYM($2),1)
SET_SIZE(ASYM($1))
TYPE_FUNCTION(ASYM($1))
#endif')
define(nocons_nofail_primop_interface_2,
`
#ifndef HAVE_$1
#`define' HAVE_$1
GLOBAL(ASYM($1))
ASYM($1):
/* Set up C argument registers. */
mr r3, P
NBIF_ARG(r4,2,0)
NBIF_ARG(r5,2,1)
/* Perform a quick save;call;restore;ret sequence. */
QUICK_CALL_RET(CSYM($2),2)
SET_SIZE(ASYM($1))
TYPE_FUNCTION(ASYM($1))
#endif')
define(nocons_nofail_primop_interface_3,
`
#ifndef HAVE_$1
#`define' HAVE_$1
GLOBAL(ASYM($1))
ASYM($1):
/* Set up C argument registers. */
mr r3, P
NBIF_ARG(r4,3,0)
NBIF_ARG(r5,3,1)
NBIF_ARG(r6,3,2)
/* Perform a quick save;call;restore;ret sequence. */
QUICK_CALL_RET(CSYM($2),3)
SET_SIZE(ASYM($1))
TYPE_FUNCTION(ASYM($1))
#endif')
define(nocons_nofail_primop_interface_5,
`
#ifndef HAVE_$1
#`define' HAVE_$1
GLOBAL(ASYM($1))
ASYM($1):
/* Set up C argument registers. */
mr r3, P
NBIF_ARG(r4,5,0)
NBIF_ARG(r5,5,1)
NBIF_ARG(r6,5,2)
NBIF_ARG(r7,5,3)
NBIF_ARG(r8,5,4)
/* Perform a quick save;call;restore;ret sequence. */
QUICK_CALL_RET(CSYM($2),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
GLOBAL(ASYM($1))
ASYM($1):
/* XXX: this case is always trivial; how to suppress the branch? */
/* Perform a quick save;call;restore;ret sequence. */
QUICK_CALL_RET(CSYM($2),0)
SET_SIZE(ASYM($1))
TYPE_FUNCTION(ASYM($1))
#endif')
define(noproc_primop_interface_1,
`
#ifndef HAVE_$1
#`define' HAVE_$1
GLOBAL(ASYM($1))
ASYM($1):
/* Set up C argument registers. */
NBIF_ARG(r3,1,0)
/* Perform a quick save;call;restore;ret sequence. */
QUICK_CALL_RET(CSYM($2),1)
SET_SIZE(ASYM($1))
TYPE_FUNCTION(ASYM($1))
#endif')
define(noproc_primop_interface_2,
`
#ifndef HAVE_$1
#`define' HAVE_$1
GLOBAL(ASYM($1))
ASYM($1):
/* Set up C argument registers. */
NBIF_ARG(r3,2,0)
NBIF_ARG(r4,2,1)
/* Perform a quick save;call;restore;ret sequence. */
QUICK_CALL_RET(CSYM($2),2)
SET_SIZE(ASYM($1))
TYPE_FUNCTION(ASYM($1))
#endif')
define(noproc_primop_interface_3,
`
#ifndef HAVE_$1
#`define' HAVE_$1
GLOBAL(ASYM($1))
ASYM($1):
/* Set up C argument registers. */
NBIF_ARG(r3,3,0)
NBIF_ARG(r4,3,1)
NBIF_ARG(r5,3,2)
/* Perform a quick save;call;restore;ret sequence. */
QUICK_CALL_RET(CSYM($2),3)
SET_SIZE(ASYM($1))
TYPE_FUNCTION(ASYM($1))
#endif')
define(noproc_primop_interface_5,
`
#ifndef HAVE_$1
#`define' HAVE_$1
GLOBAL(ASYM($1))
ASYM($1):
/* Set up C argument registers. */
NBIF_ARG(r3,5,0)
NBIF_ARG(r4,5,1)
NBIF_ARG(r5,5,2)
NBIF_ARG(r6,5,3)
NBIF_ARG(r7,5,4)
/* Perform a quick save;call;restore;ret sequence. */
QUICK_CALL_RET(CSYM($2),5)
SET_SIZE(ASYM($1))
TYPE_FUNCTION(ASYM($1))
#endif')
include(`hipe/hipe_bif_list.m4')
`#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif'