Files
mercury/runtime/mercury_goto.h
Zoltan Somogyi 7a5817acad Fix comment layout.
Estimated hours taken: 0.1
Branches: main

runtime/mercury_goto.h:
	Fix comment layout.
2012-12-23 21:37:31 +00:00

1768 lines
63 KiB
C

/*
** Copyright (C) 1995-2001, 2003-2007, 2009, 2011-2012 The University of Melbourne.
** This file may only be copied under the terms of the GNU Library General
** Public License - see the file COPYING.LIB in the Mercury distribution.
*/
/* mercury_goto.h - definitions for the "portable assembler" non-local gotos */
#ifndef MERCURY_GOTO_H
#define MERCURY_GOTO_H
#include "mercury_conf.h"
#include "mercury_std.h" /* for MR_PASTE2 and MR_STRINGIFY */
#include "mercury_types.h" /* for `MR_Code *' */
#include "mercury_debug.h" /* for MR_debuggoto() */
#include "mercury_label.h" /* for MR_insert_{entry,internal}_label() */
#include "mercury_dummy.h" /* for MR_dummy_identify_function() */
/*---------------------------------------------------------------------------*/
/*
** Definitions for constructing the names of entry and internal labels,
** and the names of their layout structures.
*/
#define MR_entry(label) MR_PASTE2(_entry_,label)
#define MR_skip(label) MR_PASTE2(skip_,label)
#define MR_add_prefix(label) \
MR_PASTE2(mercury__, label)
#define MR_label_name(proc_label, label) \
MR_PASTE3(proc_label, _i, label)
#define MR_proc_entry_user_name_base(mod, name, arity, mode) \
MR_PASTE7(mod, __, name, _, arity, _, mode)
#define MR_proc_entry_uci_name_base(mod, name, type, arity, mode) \
MR_PASTE9(name, _, mod, __, type, _, arity, _, mode)
#define MR_proc_entry_user_name(mod, name, arity, mode) \
MR_PASTE2(mercury__, \
MR_proc_entry_user_name_base(mod, name, arity, mode))
#define MR_proc_entry_uci_name(mod, name, type, arity, mode) \
MR_PASTE2(mercury__, \
MR_proc_entry_uci_name_base(mod, name, type, arity, mode))
#define MR_proc_entry_user_name_str(mod, name, arity, mode) \
MR_STRINGIFY(MR_proc_entry_user_name(mod, name, arity, mode))
#define MR_proc_entry_uci_name_str(mod, name, type, arity, mode) \
MR_STRINGIFY(MR_proc_entry_uci_name(mod, name, type, arity, mode))
#define MR_proc_layout_user_name(mod, name, arity, mode) \
MR_PASTE2(mercury_data__proc_layout__, \
MR_proc_entry_user_name(mod, name, arity, mode))
#define MR_proc_layout_uci_name(mod, name, type, arity, mode) \
MR_PASTE2(mercury_data__proc_layout__, \
MR_proc_entry_uci_name(mod, name, type, arity, mode))
#define MR_label_user_name_base(mod, name, a, mode, num) \
MR_label_name(MR_proc_entry_user_name_base(mod, name, a, mode), \
num)
#define MR_label_uci_name_base(mod, name, type, a, mode, num) \
MR_label_name(MR_proc_entry_uci_name_base(mod, name, type, a, mode), \
num)
#define MR_label_user_name(mod, name, a, mode, num) \
MR_label_name(MR_proc_entry_user_name(mod, name, a, mode), \
num)
#define MR_label_uci_name(mod, name, type, a, mode, num) \
MR_label_name(MR_proc_entry_uci_name(mod, name, type, a, mode), \
num)
#define MR_label_user_name_str(mod, name, arity, mode, num) \
MR_STRINGIFY(MR_label_user_name(mod, name, arity, mode, num))
#define MR_label_uci_name_str(mod, name, type, arity, mode, num) \
MR_STRINGIFY(MR_label_uci_name(mod, name, type, arity, mode, num))
#define MR_label_layout_user_name(mod, name, a, mode, num) \
MR_PASTE2(mercury_data__label_layout__, \
MR_label_user_name(mod, name, a, mode, num))
#define MR_label_layout_uci_name(mod, name, type, a, mode, num) \
MR_PASTE2(mercury_data__label_layout__, \
MR_label_uci_name(mod, name, type, a, mode, num))
/*---------------------------------------------------------------------------*/
#define MR_PROC_LAYOUT_NAME(label) \
MR_PASTE2(mercury_data__proc_layout__,label)
#define MR_LABEL_LAYOUT_NAME(label) \
MR_PASTE2(mercury_data__label_layout__,label)
#define MR_USER_LAYOUT_NAME(label) \
MR_PASTE2(mercury_data__user_event_layout__,label)
#define MR_PROC_LAYOUT(label) \
((const MR_ProcLayout *) (MR_Word) &MR_PROC_LAYOUT_NAME(label))
#define MR_LABEL_LAYOUT(label) \
((const MR_LabelLayout *) (MR_Word) &MR_LABEL_LAYOUT_NAME(label))
#define MR_PROC_LAYOUT1(label) \
MR_PROC_LAYOUT(MR_add_prefix(label)),
#define MR_LABEL_LAYOUT1(e, ln1) \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln1)),
#define MR_LABEL_LAYOUT2(e, ln1, ln2) \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln1)), \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln2)),
#define MR_LABEL_LAYOUT3(e, ln1, ln2, ln3) \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln1)), \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln2)), \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln3)),
#define MR_LABEL_LAYOUT4(e, ln1, ln2, ln3, ln4) \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln1)), \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln2)), \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln3)), \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln4)),
#define MR_LABEL_LAYOUT5(e, ln1, ln2, ln3, ln4, ln5) \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln1)), \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln2)), \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln3)), \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln4)), \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln5)),
#define MR_LABEL_LAYOUT6(e, ln1, ln2, ln3, ln4, ln5, ln6) \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln1)), \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln2)), \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln3)), \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln4)), \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln5)), \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln6)),
#define MR_LABEL_LAYOUT7(e, ln1, ln2, ln3, ln4, ln5, ln6, ln7) \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln1)), \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln2)), \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln3)), \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln4)), \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln5)), \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln6)), \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln7)),
#define MR_LABEL_LAYOUT8(e, ln1, ln2, ln3, ln4, ln5, ln6, ln7, ln8) \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln1)), \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln2)), \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln3)), \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln4)), \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln5)), \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln6)), \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln7)), \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln8)),
#define MR_LABEL_LAYOUT9(e, ln1, ln2, ln3, ln4, ln5, ln6, ln7, ln8, ln9) \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln1)), \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln2)), \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln3)), \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln4)), \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln5)), \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln6)), \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln7)), \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln8)), \
MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln9)),
#define MR_DECL_LABEL_LAYOUT(label) \
static const MR_LabelLayout MR_LABEL_LAYOUT_NAME(label);
#define MR_DECL_LABEL_LAYOUT1(e, ln1) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln1))
#define MR_DECL_LABEL_LAYOUT2(e, ln1, ln2) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln1)) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln2))
#define MR_DECL_LABEL_LAYOUT3(e, ln1, ln2, ln3) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln1)) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln2)) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln3))
#define MR_DECL_LABEL_LAYOUT4(e, ln1, ln2, ln3, ln4) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln1)) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln2)) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln3)) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln4))
#define MR_DECL_LABEL_LAYOUT5(e, ln1, ln2, ln3, ln4, ln5) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln1)) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln2)) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln3)) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln4)) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln5))
#define MR_DECL_LABEL_LAYOUT6(e, ln1, ln2, ln3, ln4, ln5, ln6) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln1)) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln2)) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln3)) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln4)) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln5)) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln6))
#define MR_DECL_LABEL_LAYOUT7(e, ln1, ln2, ln3, ln4, ln5, ln6, ln7) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln1)) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln2)) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln3)) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln4)) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln5)) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln6)) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln7))
#define MR_DECL_LABEL_LAYOUT8(e, ln1, ln2, ln3, ln4, ln5, ln6, ln7, ln8) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln1)) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln2)) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln3)) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln4)) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln5)) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln6)) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln7)) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln8))
#define MR_DECL_LABEL_LAYOUT9(e, ln1, ln2, ln3, ln4, ln5, ln6, ln7, ln8, ln9) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln1)) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln2)) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln3)) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln4)) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln5)) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln6)) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln7)) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln8)) \
MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln9))
/*---------------------------------------------------------------------------*/
/*
** Passing the name of a label to MR_insert_{internal,entry}_label
** causes that name to be included in the executable as static readonly data.
** Since label names are quite big, we include them only when needed.
*/
#if defined(MR_INSERT_INTERNAL_LABEL_NAMES)
#define MR_insert_internal(n, a, l) MR_insert_internal_label(n, a, l)
#else
#define MR_insert_internal(n, a, l) MR_insert_internal_label(NULL, a, l)
#endif
#if defined(MR_INSERT_ENTRY_LABEL_NAMES)
#define MR_insert_entry(n, a, l) MR_insert_entry_label(n, a, l)
#else
#define MR_insert_entry(n, a, l) MR_insert_entry_label(NULL, a, l)
#endif
/*---------------------------------------------------------------------------*/
/*
** Taking the address of a label can inhibit gcc's optimization, because it
** assumes that anything can jump there. Therefore we want to do it only if
** we're debugging, or if we need the label address for profiling or for
** accurate garbage collection.
**
** The versions of the macros below with the _ai, _an or _sl suffix always
** insert the label into the label table, the difference between them being
** that the _ai and _an variants do not include a layout structure. If the
** label *has* a layout structure, use the _sl variant. The difference between
** the _ai and the _an variants is that the latter always inserts the name
** of the label as well. This is intended for a small number of labels that
** are frequently needed in debugging, e.g. MR_do_fail.
*/
#define MR_make_label_ai(n, a, l) MR_insert_internal(n, a, NULL)
#define MR_make_label_an(n, a, l) MR_insert_internal_label(n, a, NULL)
#define MR_make_label_sl(n, a, l) MR_insert_internal(n, a, l)
#define MR_make_local_ai(n, a, l) MR_insert_entry(n, a, NULL)
#define MR_make_local_an(n, a, l) MR_do_insert_entry_label(n, a, NULL)
#define MR_make_local_sl(n, a, l) MR_insert_entry(n, a, \
MR_PROC_LAYOUT(l))
#define MR_make_entry_ai(n, a, l) MR_insert_entry(n, a, NULL)
#define MR_make_entry_an(n, a, l) MR_do_insert_entry_label(n, a, NULL)
#define MR_make_entry_sl(n, a, l) MR_insert_entry(n, a, \
MR_PROC_LAYOUT(l))
/*---------------------------------------------------------------------------*/
#if defined(MR_INSERT_LABELS)
#define MR_make_label(n, a, l) MR_make_label_ai(n, a, l)
#else
#define MR_make_label(n, a, l) /* nothing */
#endif
#if defined(MR_INSERT_LABELS) || defined(MR_MPROF_PROFILE_CALLS)
#define MR_make_local(n, a, l) MR_make_local_ai(n, a, l)
#else
#define MR_make_local(n, a, l) /* nothing */
#endif
/*
** Note that for the MLDS back-end, the calls to MR_init_entry(),
** which eventually expand to MR_make_entry(), are only output if
** the right compiler options are enabled. So if you change the
** condition of this `#ifdef', and you want your changes to apply
** to the MLDS back-end too, you may also need to change the
** `need_to_init_entries' predicate in compiler/mlds_to_c.m.
*/
#if defined(MR_INSERT_LABELS) || defined(MR_MPROF_PROFILE_CALLS)
#define MR_make_entry(n, a, l) MR_make_entry_ai(n, a, l)
#else
#define MR_make_entry(n, a, l) /* nothing */
#endif
#ifdef MR_SPLIT_C_FILES
#define MR_MODULE_STATIC_OR_EXTERN extern
#else
#define MR_MODULE_STATIC_OR_EXTERN static
#endif
/*---------------------------------------------------------------------------*/
/* MACHINE SPECIFIC STUFF REQUIRED FOR NON-LOCAL GOTOS */
#if defined(__alpha__)
/* We need special handling for the "global pointer" (gp) register. */
/*
** When doing a jump, we need to set $27, the "procedure value" register,
** to the address we are jumping to, so that we can use an `ldgp'
** instruction on entry to the procedure to set up the right gp value.
*/
#define MR_ASM_JUMP(address) \
__asm__("bis %0, %0, $27\n\t" \
: : "r"(address) : "$27"); \
goto *(address)
/*
** Explanation:
** Move `address' to register $27,
** jump to `address'.
*/
/*
** on entry to a procedure, we need to load the $gp register
** with the correct value relative to the current address in $27
*/
#define MR_INLINE_ASM_FIXUP_REGS \
" ldgp $gp, 0($27)\n" : : : "memory"
/*
** on fall-thru, we need to skip the ldgp instruction
*/
#define MR_ASM_FALLTHROUGH(label) \
goto MR_skip(label);
#elif defined(__i386__) || defined(__mc68000__) || defined(__x86_64__)
/*
** This hack is to prevent gcc 4.x optimizing away stores to succip before
** jumping to a label in asm_fast.
*/
#if defined(MR_USE_GCC_GLOBAL_REGISTERS)
#define MR_FORCE_SUCCIP_STORE \
__asm__ __volatile__("" \
: "=r"(MR_succip_word) \
: "0"(MR_succip_word) \
)
#else
#define MR_FORCE_SUCCIP_STORE ((void) 0)
#endif
/*
** The following hack works around a stack leak on the i386.
** (and apparently the 68000 and x86_64 too).
**
** The problem is that gcc pushes function parameters onto
** the stack when calling C functions such as GC_malloc(),
** and only restores the stack pointer in the epilogue.
** With non-local gotos, we jump out of the function without
** executing its epilogue, so the stack pointer never gets
** restored. The result is a memory leak; for example,
** `mc --generate-dependencies mercury_compile' exceeds the
** Slackware Linux default stack space limit of 8M.
**
** GNU C has an option `-fno-defer-pop' which is supposed to
** avoid this sort of thing, but it doesn't work for our
** code using non-local gotos.
**
** We work around this using the dummy assembler code below, which
** pretends to use the stack pointer, forcing gcc to flush any updates
** of the stack pointer immediately, rather than deferring them until
** the function epilogue.
**
** I know this is awful. It wasn't _my_ idea to use non-local gotos ;-)
*/
#if defined(__i386__)
#define MR_ASM_JUMP(label) \
{ register int stack_pointer __asm__("esp"); \
__asm__("" : : "g"(stack_pointer)); } \
MR_FORCE_SUCCIP_STORE; \
goto *(label)
#elif defined(__x86_64__)
#define MR_ASM_JUMP(label) \
{ register int stack_pointer __asm__("rsp"); \
__asm__("" : : "g"(stack_pointer)); } \
MR_FORCE_SUCCIP_STORE; \
goto *(label)
#elif defined(__mc68000__)
#define MR_ASM_JUMP(label) \
{ register int stack_pointer __asm__("sp"); \
__asm__("" : : "g"(stack_pointer)); } \
goto *(label)
#endif
/*
** That hack above needs to be done for all non-local jumps,
** even if we're not using assembler labels.
*/
#define MR_JUMP(label) MR_ASM_JUMP(label)
/*
** If we're using position-independent code, then we need to
** set up the correct value of the GOT register (ebx on 386
** or a5 on m68000).
*/
#if MR_PIC
/*
** At each entry point, where we may have been jump to from
** code in a different C file, we need to set up `ebx'.
** We do this by pushing the IP register using a `call'
** instruction whose target is the very next label.
** We then pop this off the stack into `ebx', and
** then use the value obtained to compute the correct
** value of `ebx' by doing something with _GLOBAL_OFFSET_TABLE_
** (I don't understand the details exactly, this code is
** basically copied from the output of `gcc -fpic -S'.)
** Note that `0f' means the label `0:' following the current
** instruction, and `0b' means the label `0:' before the current
** instruction.
**
** Note: this code clobbers `ebx', which is a callee-save
** register. That means that it is essential that call_engine()
** save `ebx' before entering Mercury code, and restore it
** before returning to C code. However, gcc and/or
** setjmp()/longjmp() will do that for us automatically,
** precisely because it is a callee-save register.
*/
#if defined(__i386__)
#define MR_EBX "%%ebx"
#define MR_INLINE_ASM_FIXUP_REGS \
" call 0f\n" \
"0:\n" \
" popl " MR_EBX "\n" \
" addl $_GLOBAL_OFFSET_TABLE_+[.-0b]," MR_EBX "\n\t" \
: :
#if 0
/*
** The following doesn't seem to be necessary, and
** leaving it out might make gcc generate slightly better code.
*/
/* tell gcc we clobber ebx and memory */ \
: : : "%ebx", "memory"
#endif
#elif defined(__mc68000__)
/*
** This piece of magic thanks to Roman Hodek
** <Roman.Hodek@informatik.uni-erlangen.de>
*/
#define MR_INLINE_ASM_FIXUP_REGS \
" lea (%%pc,_GLOBAL_OFFSET_TABLE_@GOTPC),%%a5\n" : : : "memory"
#endif
/*
** It is safe to fall through into MR_INLINE_ASM_FIXUP_REGS,
** but it might be more efficient to branch past it.
** We should really measure both ways and find out which is
** better... for the moment, we just fall through, since
** that keeps the code smaller.
*/
#if 0
#define MR_ASM_FALLTHROUGH(label) \
goto MR_skip(label);
#endif
#endif /* MR_PIC */
/*
** For Linux-ELF shared libraries, we need to declare that the type of labels
** is @function (i.e. code, not data), otherwise the dynamic linker seems
** to get confused, and we end up jumping into the data section.
** Hence the `.type' directive below.
*/
#ifdef __ELF__
#define MR_INLINE_ASM_ENTRY_LABEL_TYPE(label) \
" .type _entry_" MR_STRINGIFY(label) ",@function\n"
#endif
#elif defined (__sparc)
/*
** If we're using position-independent code on the SPARC, then we need to
** set up the correct value of the GOT register (l7).
*/
#if (defined(__pic__) || defined(__PIC__)) && !defined(MR_PIC)
#define MR_PIC 1
#endif
#if MR_PIC
/*
** At each entry point, where we may have been jump to from
** code in a difference C file, we need to set up `l7'.
** We do this by getting the value the of the IP register using a `call'
** instruction whose target is the very next label; this will
** put the address of the call instruction in register `o7'.
** We then use the value obtained in register `o7' to compute the correct
** value of register `l7' by doing something with _GLOBAL_OFFSET_TABLE_
** (I don't understand the details exactly, this code is
** basically copied from the output of `gcc -fpic -S'.)
** Note that `1f' means the label `1:' following the current
** instruction, and `0b' means the label `0:' before the current
** instruction.
*/
#define MR_INLINE_ASM_FIXUP_REGS \
"0:\n" \
" call 1f\n" \
" nop\n" \
"1:\n" \
" sethi %%hi(_GLOBAL_OFFSET_TABLE_-(0b-.)),%%l7\n" \
" or %%l7,%%lo(_GLOBAL_OFFSET_TABLE_-(0b-.)),%%l7\n" \
" add %%l7,%%o7,%%l7\n" \
/* tell gcc we clobber l7, o7, and memory */ \
: : : "%l7", "%o7", "memory"
/*
** It is safe to fall through into MR_INLINE_ASM_FIXUP_REGS,
** but it might be more efficient to branch past it.
** We should really measure both ways and find out which is
** better... for the moment, we just fall through, since
** that keeps the code smaller.
*/
#if 0
#define MR_ASM_FALLTHROUGH(label) \
goto MR_skip(label);
#endif
#endif /* MR_PIC */
/*
** For Solaris 5.5.1, we need to declare that the type of labels is
** #function (i.e. code, not data), otherwise the dynamic linker seems
** to get confused, and we end up jumping into the data section.
** Hence the `.type' directive below.
*/
#ifndef MR_CANNOT_GROK_ASM_TYPE_DIRECTIVE
#define MR_INLINE_ASM_ENTRY_LABEL_TYPE(label) \
" .type _entry_" MR_STRINGIFY(label) ",#function\n"
#endif
#elif defined(__arm__)
/*
** The following code for supporting non-local gotos and PIC on ARM
** is thanks to Sergey Khorev <iamphet@nm.ru>.
*/
#if MR_PIC
/*
** At each entry point, where we may have been jumped to from
** code in a different C file, we need to set up the PIC register.
** We do this by adding _GLOBAL_OFFSET_TABLE_ value to the PC register
** Current instruction address is (PC - 8) hence -(0b + 8)
** (I don't understand the details exactly, this code is
** basically copied from the output of `gcc -fpic -S' for a function
** containing setjmp.)
** A little bit more detail can be obtained from GCC source
** (function arm_finalize_pic in gcc/config/arm/arm.c)
** Note that `0f' means the label `0:' following the current
** instruction, and `0b' means the label `0:' before the current
** instruction.
** GCC doesn't like it when we clobber the PIC register but it seems we
** can safely keep GCC uninformed because we just do GCC's work
** and the PIC register is saved over call
** Loading arbitrary immediate values into ARM registers is not possible
** directly hence the .word directive in the code section and the branch
** instruction bypassing it.
** If you change MR_ARM_PIC_REG, update CFLAGS_FOR_PIC (-mpic-register)
** in configure.in.
*/
#define MR_ARM_PIC_REG "sl"
#define MR_INLINE_ASM_FIXUP_REGS \
" ldr " MR_ARM_PIC_REG ", 1f\n" \
"0:\n" \
" add " MR_ARM_PIC_REG ", pc, " MR_ARM_PIC_REG "\n" \
" b 2f\n" \
"1:\n" \
" .word _GLOBAL_OFFSET_TABLE_-(0b+8)\n" \
"2:\n"
/*
** For Linux-ELF shared libraries, we need to declare that the type of
** labels is #function (i.e. code, not data), otherwise the dynamic
** linker seems to get confused, and we end up jumping into the data
** section. Hence the `.type' directive below.
*/
#ifdef __ELF__
#define MR_INLINE_ASM_ENTRY_LABEL_TYPE(label) \
" .type _entry_" MR_STRINGIFY(label) ",#function\n"
#endif
/*
** Save a few clock ticks branching past MR_INLINE_ASM_FIXUP_REGS
*/
#define MR_ASM_FALLTHROUGH(label) \
goto MR_skip(label);
#endif
#endif
/*---------------------------------------------------------------------------*/
/* for other architectures, these macros have default definitions */
/*
** MR_INLINE_ASM_FIXUP_REGS is used to fix up the value of
** any registers after an MR_ASM_JUMP to an entry point, if necessary.
** It is an assembler string, possibly followed by `: : : <clobbers>'
** where <clobbers> is an indication to gcc of what gets clobbered.
*/
#ifdef MR_INLINE_ASM_FIXUP_REGS
#define MR_ASM_FIXUP_REGS \
__asm__ __volatile__( \
MR_INLINE_ASM_FIXUP_REGS \
);
#else
#define MR_ASM_FIXUP_REGS
#define MR_INLINE_ASM_FIXUP_REGS
#endif
/*
** MR_ASM_FALLTHROUGH is executed when falling through into an entry point.
** It may call `goto MR_skip(label)' if it wishes to skip past the
** label and the MR_INLINE_ASM_FIXUP_REGS code.
*/
#ifndef MR_ASM_FALLTHROUGH
#define MR_ASM_FALLTHROUGH(label)
#endif
/*
** MR_INLINE_ASM_GLOBALIZE_LABEL is an assembler string to
** declare an entry label as global. The following definition
** using `.globl' should work with the GNU assembler and
** with most Unix assemblers.
*/
#ifndef MR_INLINE_ASM_GLOBALIZE_LABEL
#define MR_INLINE_ASM_GLOBALIZE_LABEL(label) \
" .globl _entry_" MR_STRINGIFY(label) "\n"
#endif
/*
** MR_INLINE_ASM_ENTRY_LABEL_TYPE is an assembler string to
** declare the "type" of a label as function (i.e. code), not data,
** if this is needed.
*/
#ifndef MR_INLINE_ASM_ENTRY_LABEL_TYPE
#define MR_INLINE_ASM_ENTRY_LABEL_TYPE(label)
#endif
/*
** MR_INLINE_ASM_ENTRY_LABEL is an assembler string to
** define an assembler entry label.
*/
#ifndef MR_INLINE_ASM_ENTRY_LABEL
#define MR_INLINE_ASM_ENTRY_LABEL(label) \
"_entry_" MR_STRINGIFY(label) ":\n"
#endif
/*
** MR_INLINE_ASM_COMMENT is an assembler string to
** define an assembler comment.
*/
#ifndef MR_INLINE_ASM_COMMENT
#define MR_INLINE_ASM_COMMENT(label) \
"/* " MR_STRINGIFY(label) "*/\n"
#endif
/*
** MR_ASM_JUMP is used to jump to an entry point defined with
** MR_ASM_ENTRY, MR_ASM_STATIC_ENTRY, or MR_ASM_LOCAL_ENTRY.
*/
#ifndef MR_ASM_JUMP
#define MR_ASM_JUMP(address) goto *(address)
#endif
/*---------------------------------------------------------------------------*/
/* The code from here on should be architecture-independent. */
/*---------------------------------------------------------------------------*/
/*
** MR_ASM_ENTRY is used to declare an external entry point
** using a (global) assembler label.
*/
#define MR_ASM_ENTRY(label) \
MR_ASM_FALLTHROUGH(label) \
MR_entry(label): \
__asm__ __volatile__( \
MR_INLINE_ASM_GLOBALIZE_LABEL(label) \
MR_INLINE_ASM_ENTRY_LABEL_TYPE(label) \
MR_INLINE_ASM_ENTRY_LABEL(label) \
MR_INLINE_ASM_FIXUP_REGS \
); \
MR_skip(label): ;
/*
** MR_ASM_STATIC_ENTRY is the same as MR_ASM_ENTRY,
** except that its scope is local to a C file, rather than global.
** Note that even static entry points must do MR_INLINE_ASM_FIXUP_REGS,
** since although there won't be any direct calls to them from another
** C file, their address may be taken and so there may be indirect
** calls.
*/
#define MR_ASM_STATIC_ENTRY(label) \
MR_ASM_FALLTHROUGH(label) \
MR_entry(label): \
__asm__ __volatile__( \
MR_INLINE_ASM_ENTRY_LABEL_TYPE(label) \
MR_INLINE_ASM_ENTRY_LABEL(label) \
MR_INLINE_ASM_FIXUP_REGS \
); \
MR_skip(label): ;
/*
** MR_ASM_LOCAL_ENTRY is the same as MR_ASM_ENTRY,
** except that its scope is local to a MR_BEGIN_MODULE...MR_END_MODULE
** block, rather than being global.
** Note that even local entry points must do MR_INLINE_ASM_FIXUP_REGS, since
** although there won't be any direct calls to them from another
** C file, their address may be taken and so there may be indirect
** calls.
**
** We need to use MR_ASM_COMMENT here to ensure that
** the code following each label is distinct; this is needed
** to ensure GCC doesn't try to merge two labels which point
** to identical code, but for which we have different information
** stored in the stack layout structs, etc.
*/
#define MR_ASM_LOCAL_ENTRY(label) \
MR_ASM_FALLTHROUGH(label) \
MR_entry(label): \
__asm__ __volatile__( \
MR_INLINE_ASM_COMMENT(label) \
MR_INLINE_ASM_FIXUP_REGS \
); \
MR_skip(label): ;
/*---------------------------------------------------------------------------*/
#if defined(MR_USE_GCC_NONLOCAL_GOTOS)
#ifndef MR_GNUC
#error "You must use gcc if you define MR_USE_GCC_NONLOCAL_GOTOS"
#endif
/* Define the type of a module initialization function */
typedef void MR_ModuleFunc(void);
/* The following macro expands to a dummy assembler statement which
** contains no code, but which tells gcc that it uses the specified
** address as an input value. This is used to trick gcc into
** thinking that the address is used, in order to suppress unwanted
** optimizations. (We used to use `volatile_global_pointer =
** address' to suppress optimization, but this way is better because
** it doesn't generate any code.)
*/
#define MR_PRETEND_ADDRESS_IS_USED(address) \
__asm__ __volatile__("" : : "g"(address))
/*
Explanation:
__asm__
__volatile__ don't optimize this asm away
(
"" empty assembler code
: no outputs
: "g" (address) one input value, `address';
"g" means that it can go in any
general-purpose register
)
*/
/*
** The following macro expands into a dummy assembler statement that
** contains no code. It is used to suppress optimizations in gcc 4
** and above that try to cache memory values in registers before labels
** that Mercury uses as the target of non-local gotos. It has no effect
** with versions of gcc before version 4.
*/
#define MR_PRETEND_REGS_ARE_USED \
__asm__ __volatile("":::"memory")
/*
Explanation:
__asm__
__volatile__ Don't optimize this asm away.
(
"" Empty assembler code.
: No outputs.
: No inputs.
:"memory" Tells gcc that this "instruction" might
clobber the register contents so it
shouldn't cache memory values in
registers.
)
*/
/*
** Since we're jumping into and out of the middle of functions,
** we need to make sure that gcc thinks that (1) the function's address
** is used (otherwise it may optimize the whole function away) and
** (2) the `return' statement is reachable (otherwise its dataflow
** analysis for delay slot scheduling may think that global
** register variables which are only assigned to in the function
** cannot be live, when in fact they really are).
** That is what the two occurrences of the MR_PRETEND_ADDRESS_IS_USED
** macro are for.
** For versions of gcc later than egcs 1.1.2 (which corresponds to gcc 2.91,
** according to __GNUC_MINOR__), and in particular for gcc 2.95,
** we also need to include at least one `goto *' with an unknown
** target, so that gcc doesn't optimize away all the labels
** because it thinks they are unreachable.
** The MR_dummy_identify_function() function just returns the address
** passed to it, so `goto *MR_dummy_identify_function(&& dummy_label);
** dummy_label:' is the same as `goto dummy_label; label:', i.e. it just
** falls through. For older versions of gcc, we don't do this, since it
** adds significantly to the code size.
*/
#if MR_GNUC > 2 || (MR_GNUC == 2 && __GNUC_MINOR__ > 91)
/* gcc version > egcs 1.1.2 */
#define MR_BEGIN_MODULE(module_name) \
MR_MODULE_STATIC_OR_EXTERN void module_name(void); \
MR_MODULE_STATIC_OR_EXTERN void module_name(void) { \
MR_PRETEND_ADDRESS_IS_USED(module_name); \
MR_PRETEND_ADDRESS_IS_USED( \
&&MR_PASTE2(module_name,_dummy_label)); \
goto *MR_dummy_identify_function( \
&&MR_PASTE2(module_name,_dummy_label)); \
MR_PASTE2(module_name,_dummy_label): \
{
#else /* gcc version <= egcs 1.1.2 */
#define MR_BEGIN_MODULE(module_name) \
MR_MODULE_STATIC_OR_EXTERN void module_name(void); \
MR_MODULE_STATIC_OR_EXTERN void module_name(void) { \
MR_PRETEND_ADDRESS_IS_USED(module_name); \
MR_PRETEND_ADDRESS_IS_USED( \
&&MR_PASTE2(module_name,_dummy_label)); \
MR_PASTE2(module_name,_dummy_label): \
{
#endif /* gcc version <= egcs 1.1.2 */
/* initialization code for module goes between MR_BEGIN_MODULE */
/* and MR_BEGIN_CODE */
#define MR_BEGIN_CODE } return; {
/* body of module goes between MR_BEGIN_CODE and MR_END_MODULE */
#define MR_END_MODULE } }
#if defined(MR_USE_ASM_LABELS)
#define MR_declare_entry(label) \
extern void label(void) __asm__("_entry_" MR_STRINGIFY(label))
#define MR_declare_static(label) \
static void label(void) __asm__("_entry_" MR_STRINGIFY(label))
#define MR_define_extern_entry(label) MR_declare_entry(label)
#define MR_define_entry(label) \
MR_ASM_ENTRY(label) \
} \
label: \
MR_PRETEND_ADDRESS_IS_USED(&&MR_entry(label)); \
{ \
MR_PRETEND_REGS_ARE_USED;
#define MR_define_static(label) \
MR_ASM_STATIC_ENTRY(label) \
} \
label: \
MR_PRETEND_ADDRESS_IS_USED(&&MR_entry(label)); \
{ \
MR_PRETEND_REGS_ARE_USED;
/*
** The MR_PRETEND_ADDRESS_IS_USED macro is necessary to
** prevent an over-zealous gcc from optimizing away `label'
** and the code that followed. The MR_PRETEND_REGS_ARE_USED
** macro is used to prevent gcc from caching values in registers
** before the label.
*/
#define MR_init_entry(label) \
MR_PRETEND_ADDRESS_IS_USED(&&label); \
MR_make_entry(MR_STRINGIFY(label), label, label)
#define MR_init_entry_ai(label) \
MR_PRETEND_ADDRESS_IS_USED(&&label); \
MR_make_entry_ai(MR_STRINGIFY(label), label, label)
#define MR_init_entry_an(label) \
MR_PRETEND_ADDRESS_IS_USED(&&label); \
MR_make_entry_an(MR_STRINGIFY(label), label, label)
#define MR_init_entry_sl(label) \
MR_PRETEND_ADDRESS_IS_USED(&&label); \
MR_make_entry_sl(MR_STRINGIFY(label), label, label)
#define MR_pretend_address_is_used(label) \
MR_PRETEND_ADDRESS_IS_USED(&&label);
#define MR_entry_addr_wrapper(label)
#define MR_ENTRY(label) (&label)
#ifndef MR_JUMP
#define MR_JUMP(label) MR_ASM_JUMP(label)
#endif
#else
/* !defined(MR_USE_ASM_LABELS) */
#define MR_declare_entry(label) extern MR_Code * MR_entry(label)
#define MR_declare_static(label) static MR_Code * MR_entry(label)
#define MR_define_extern_entry(label) MR_Code * MR_entry(label)
#define MR_define_entry(label) \
} \
MR_entry(label): \
label: \
{
#define MR_define_static(label) \
} \
MR_entry(label): \
label: \
{
#define MR_init_entry(label) \
MR_make_entry(MR_STRINGIFY(label), &&label, label); \
MR_entry(label) = &&label
#define MR_init_entry_ai(label) \
MR_make_entry_ai(MR_STRINGIFY(label), &&label, label); \
MR_entry(label) = &&label
#define MR_init_entry_an(label) \
MR_make_entry_an(MR_STRINGIFY(label), &&label, label); \
MR_entry(label) = &&label
#define MR_init_entry_sl(label) \
MR_make_entry_sl(MR_STRINGIFY(label), &&label, label); \
MR_entry(label) = &&label
#define MR_ENTRY(label) (MR_entry(label))
#ifndef MR_JUMP
#define MR_JUMP(label) goto *(label)
#endif
#endif /* !defined(MR_USE_ASM_LABELS) */
#define MR_declare_local(label) /* no declaration required */
#define MR_define_local(label) \
MR_ASM_LOCAL_ENTRY(label) \
} \
label: \
{
#define MR_init_local(label) \
MR_make_local(MR_STRINGIFY(label), &&MR_entry(label), label)
#define MR_init_local_ai(label) \
MR_make_local_ai(MR_STRINGIFY(label), &&MR_entry(label), label)
#define MR_init_local_an(label) \
MR_make_local_an(MR_STRINGIFY(label), &&MR_entry(label), label)
#define MR_init_local_sl(label) \
MR_make_local_sl(MR_STRINGIFY(label), &&MR_entry(label), label)
#define MR_define_label(label) MR_define_local(label)
#define MR_declare_label(label) /* no declaration required */
#define MR_init_label(label) \
MR_make_label(MR_STRINGIFY(label), &&MR_entry(label), \
MR_LABEL_LAYOUT(label))
#define MR_init_label_ai(label) \
MR_make_label_ai(MR_STRINGIFY(label), &&MR_entry(label), \
MR_LABEL_LAYOUT(label))
#define MR_init_label_an(label) \
MR_make_label_an(MR_STRINGIFY(label), &&MR_entry(label), \
MR_LABEL_LAYOUT(label))
#define MR_init_label_sl(label) \
MR_make_label_sl(MR_STRINGIFY(label), &&MR_entry(label), \
MR_LABEL_LAYOUT(label))
#define MR_init_label_ml(label, layout) \
MR_make_label(MR_STRINGIFY(label), &&MR_entry(label), layout)
#define MR_init_label_ml_ai(label, layout) \
MR_make_label_ai(MR_STRINGIFY(label), &&MR_entry(label), layout)
#define MR_init_label_ml_an(label, layout) \
MR_make_label_an(MR_STRINGIFY(label), &&MR_entry(label), layout)
#define MR_init_label_ml_sl(label, layout) \
MR_make_label_sl(MR_STRINGIFY(label), &&MR_entry(label), layout)
#define MR_LOCAL(label) (&&MR_entry(label))
#define MR_LABEL(label) (&&MR_entry(label))
#define MR_GOTO(label) do { \
MR_debuggoto(label); \
MR_JUMP(label); \
} while(0)
#define MR_GOTO_ENTRY(label) MR_GOTO(MR_ENTRY(label))
#define MR_GOTO_LOCAL(label) MR_GOTO_LABEL(label)
#define MR_GOTO_LABEL(label) do { \
MR_debuggoto(MR_LABEL(label)); \
goto label; \
} while(0)
/*
** MR_GOTO_LABEL(label) is the same as MR_GOTO(MR_LABEL(label)) except
** that it may allow gcc to generate slightly better code
*/
#else
/* !defined(MR_USE_GCC_NONLOCAL_GOTOS) */
/* Define the type of a module initialization function */
typedef MR_Code * MR_ModuleFunc(void);
#define MR_BEGIN_MODULE(module_name) \
MR_MODULE_STATIC_OR_EXTERN MR_Code * module_name(void); \
MR_MODULE_STATIC_OR_EXTERN MR_Code * module_name(void) {
#define MR_BEGIN_CODE return 0;
#define MR_END_MODULE }
#define MR_declare_entry(label) extern MR_Code *label(void)
#define MR_declare_static(label) static MR_Code *label(void)
#define MR_define_extern_entry(label) MR_Code *label(void)
#define MR_define_entry(label) \
MR_GOTO_LABEL(label); \
} \
MR_Code* label(void) {
#define MR_define_static(label) \
MR_GOTO_LABEL(label); \
} \
static MR_Code* label(void) {
#define MR_init_entry(label) \
MR_make_entry(MR_STRINGIFY(label), label, label)
#define MR_init_entry_ai(label) \
MR_make_entry_ai(MR_STRINGIFY(label), label, label)
#define MR_init_entry_an(label) \
MR_make_entry_an(MR_STRINGIFY(label), label, label)
#define MR_init_entry_sl(label) \
MR_make_entry_sl(MR_STRINGIFY(label), label, label)
#define MR_declare_local(label) static MR_Code *label(void)
#define MR_define_local(label) \
MR_GOTO_LABEL(label); \
} \
static MR_Code* label(void) {
#define MR_init_local(label) \
MR_make_local(MR_STRINGIFY(label), label, label)
#define MR_init_local_ai(label) \
MR_make_local_ai(MR_STRINGIFY(label), label, label)
#define MR_init_local_an(label) \
MR_make_local_an(MR_STRINGIFY(label), label, label)
#define MR_init_local_sl(label) \
MR_make_local_sl(MR_STRINGIFY(label), label, label)
#define MR_declare_label(label) static MR_Code *label(void)
#define MR_define_label(label) \
MR_GOTO_LABEL(label); \
} \
static MR_Code* label(void) {
#define MR_init_label(label) \
MR_make_label(MR_STRINGIFY(label), label, MR_LABEL_LAYOUT(label))
#define MR_init_label_ai(label) \
MR_make_label_ai(MR_STRINGIFY(label), label, MR_LABEL_LAYOUT(label))
#define MR_init_label_an(label) \
MR_make_label_an(MR_STRINGIFY(label), label, MR_LABEL_LAYOUT(label))
#define MR_init_label_sl(label) \
MR_make_label_sl(MR_STRINGIFY(label), label, MR_LABEL_LAYOUT(label))
#define MR_init_label_ml(label, layout) \
MR_make_label(MR_STRINGIFY(label), label, layout)
#define MR_init_label_ml_ai(label, layout) \
MR_make_label_ai(MR_STRINGIFY(label), label, layout)
#define MR_init_label_ml_an(label, layout) \
MR_make_label_an(MR_STRINGIFY(label), label, layout)
#define MR_init_label_ml_sl(label, layout) \
MR_make_label_sl(MR_STRINGIFY(label), label, layout)
#define MR_ENTRY(label) ((MR_Code *) (label))
#define MR_LOCAL(label) ((MR_Code *) (label))
#define MR_LABEL(label) ((MR_Code *) (label))
/*
** The call to MR_debuggoto() is in the driver function in mercury_engine.c,
** which is why the following definitions have no MR_debuggoto().
*/
#define MR_GOTO(label) return (label)
#define MR_GOTO_ENTRY(label) MR_GOTO(MR_ENTRY(label))
#define MR_GOTO_LOCAL(label) MR_GOTO(MR_LOCAL(label))
#define MR_GOTO_LABEL(label) MR_GOTO(MR_LABEL(label))
#endif /* !defined(MR_USE_GCC_NONLOCAL_GOTOS) */
/*---------------------------------------------------------------------------*/
#define MR_ENTRY_AP(label) MR_ENTRY(MR_add_prefix(label))
#define MR_LOCAL_AP(label) MR_LOCAL(MR_add_prefix(label))
#define MR_LABEL_AP(label) MR_LABEL(MR_add_prefix(label))
#define MR_GOTO_AP(label) MR_GOTO(MR_add_prefix(label))
#define MR_GOTO_ENT(label) MR_GOTO_ENTRY(MR_add_prefix(label))
#define MR_GOTO_LOC(label) MR_GOTO_LOCAL(MR_add_prefix(label))
#define MR_GOTO_LAB(label) MR_GOTO_LABEL(MR_add_prefix(label))
#define MR_decl_user_entry(mod, name, arity, mode) \
MR_declare_entry(MR_proc_entry_user_name(mod, name, arity, mode))
#define MR_decl_uci_entry(mod, name, type, arity, mode) \
MR_declare_entry(MR_proc_entry_uci_name(mod, name, type, arity, mode))
#define MR_decl_user_static(mod, name, arity, mode) \
MR_declare_static(MR_proc_entry_user_name(mod, name, arity, mode))
#define MR_decl_uci_static(mod, name, type, arity, mode) \
MR_declare_static(MR_proc_entry_uci_name(mod, name, type, arity, mode))
#define MR_def_user_extern_entry(mod, name, arity, mode) \
MR_define_extern_entry( \
MR_proc_entry_user_name(mod, name, arity, mode))
#define MR_def_uci_extern_entry(mod, name, type, arity, mode) \
MR_define_extern_entry( \
MR_proc_entry_uci_name(mod, name, type, arity, mode))
#define MR_def_user_entry(mod, name, arity, mode) \
MR_define_entry(MR_proc_entry_user_name(mod, name, arity, mode))
#define MR_def_uci_entry(mod, name, type, arity, mode) \
MR_define_entry(MR_proc_entry_uci_name(mod, name, type, arity, mode))
#define MR_def_user_static(mod, name, arity, mode) \
MR_define_static(MR_proc_entry_user_name(mod, name, arity, mode))
#define MR_def_uci_static(mod, name, type, arity, mode) \
MR_define_static(MR_proc_entry_uci_name(mod, name, type, arity, mode))
/*---------------------------------------------------------------------------*/
#if defined(MR_INSERT_LABELS) || defined(MR_MPROF_PROFILE_CALLS)
#define MR_need_insert_entry(ai) 1
#else
#define MR_need_insert_entry(ai) ai
#endif
#if defined(MR_INSERT_LABELS)
#define MR_need_insert_internal(ai) 1
#else
#define MR_need_insert_internal(ai) ai
#endif
#if defined(MR_INSERT_ENTRY_LABEL_NAMES)
#define MR_need_entry_label_names(an) 1
#else
#define MR_need_entry_label_names(an) an
#endif
#if defined(MR_INSERT_INTERNAL_LABEL_NAMES)
#define MR_need_internal_label_names(an) 1
#else
#define MR_need_internal_label_names(an) an
#endif
#define MR_init_entry_select(str, addr, layout, ai, an, sl) \
( MR_need_insert_entry(ai) ? \
MR_insert_entry_label( \
MR_need_entry_label_names(an) ? str : NULL, \
addr, sl ? layout : NULL) \
: (void) 0 )
#define MR_init_internal_select(str, addr, layout, ai, an, sl) \
( MR_need_insert_internal(ai) ? \
MR_insert_internal_label( \
MR_need_internal_label_names(an) ? str : NULL, \
addr, sl ? layout : NULL) \
: (void) 0 )
#define MR_init_user_entry_select(mod, name, arity, mode, ai, an, sl) \
MR_pretend_address_is_used( \
MR_proc_entry_user_name(mod, name, arity, mode)) \
MR_init_entry_select( \
MR_proc_entry_user_name_str(mod, name, arity, mode), \
MR_entry_addr_wrapper( \
MR_proc_entry_user_name(mod, name, arity, mode)),\
MR_proc_layout_user_name(mod, name, arity, mode), \
ai, an, sl)
#define MR_init_uci_entry_select(mod, name, type, arity, mode, ai, an, sl) \
MR_pretend_address_is_used( \
MR_proc_entry_uci_name(mod, name, type, arity, mode)) \
MR_init_entry_select( \
MR_proc_entry_uci_name_str(mod, name, type, arity, mode), \
MR_entry_addr_wrapper( \
MR_proc_entry_uci_name(mod, name, type, arity, mode)),\
MR_proc_layout_uci_name(mod, name, type, arity, mode), \
ai, an, sl)
#define MR_init_user_label_select(mod, name, arity, mode, num, ai, an, sl) \
MR_init_label_select( \
MR_label_user_name_str(mod, name, arity, mode, num), \
MR_entry_addr_wrapper( \
MR_label_user_name(mod, name, arity, mode, num)),\
MR_label_layout_user_name(mod, name, arity, mode, num), \
ai, an, sl)
#define MR_init_uci_label_select(mod, name, type, arity, mode, num, ai, an, sl)\
MR_init_label_select( \
MR_label_uci_name_str(mod, name, type, arity, mode, num), \
MR_entry_addr_wrapper( \
MR_label_uci_name(mod, name, type, arity, mode, num)),\
MR_label_layout_uci_name(mod, name, type, arity, mode, num), \
ai, an, sl)
#define MR_init_user_entry_ai(mod, name, arity, mode) \
MR_init_user_entry_select(mod, name, arity, mode, 1, 0, 0)
#define MR_init_user_entry_an(mod, name, arity, mode) \
MR_init_user_entry_select(mod, name, arity, mode, 1, 1, 0)
#define MR_init_user_entry_sl(mod, name, arity, mode) \
MR_init_user_entry_select(mod, name, arity, mode, 0, 0, 1)
#define MR_init_uci_entry_ai(mod, name, type, arity, mode) \
MR_init_uci_entry_select(mod, name, type, arity, mode, 1, 0, 0)
#define MR_init_uci_entry_an(mod, name, type, arity, mode) \
MR_init_uci_entry_select(mod, name, type, arity, mode, 1, 1, 0)
#define MR_init_uci_entry_sl(mod, name, type, arity, mode) \
MR_init_uci_entry_select(mod, name, type, arity, mode, 0, 0, 1)
#define MR_init_user_local_ai(mod, name, arity, mode, num) \
MR_init_user_local_select(mod, name, arity, mode, num, 1, 0, 0)
#define MR_init_user_local_an(mod, name, arity, mode, num) \
MR_init_user_local_select(mod, name, arity, mode, num, 1, 1, 0)
#define MR_init_user_local_sl(mod, name, arity, mode, num) \
MR_init_user_local_select(mod, name, arity, mode, num, 0, 0, 1)
#define MR_init_uci_local_ai(mod, name, type, arity, mode, num) \
MR_init_uci_local_select(mod, name, type, arity, mode, num, 1, 0, 0)
#define MR_init_uci_local_an(mod, name, type, arity, mode, num) \
MR_init_uci_local_select(mod, name, type, arity, mode, num, 1, 1, 0)
#define MR_init_uci_local_sl(mod, name, type, arity, mode, num) \
MR_init_uci_local_select(mod, name, type, arity, mode, num, 0, 0, 1)
#define MR_def_extern_entry(e) \
MR_define_extern_entry(MR_add_prefix(e));
#define MR_def_entry(e) \
MR_define_entry(MR_add_prefix(e));
#define MR_def_static(e) \
MR_define_static(MR_add_prefix(e));
#define MR_def_local(e) \
MR_define_local(MR_add_prefix(e));
#define MR_def_label(e, ln) \
MR_define_label(MR_label_name(MR_add_prefix(e), ln));
#define MR_init_entry1(e) \
MR_init_entry(MR_add_prefix(e));
#define MR_init_entry1_sl(e) \
MR_init_entry_sl(MR_add_prefix(e));
#define MR_init_local1(e) \
MR_init_local(MR_add_prefix(e));
#define MR_init_local1_sl(e) \
MR_init_local_sl(MR_add_prefix(e));
#define MR_init_label1_sl(e) \
MR_init_label_sl(MR_add_prefix(e));
/*---------------------------------------------------------------------------*/
#define MR_init_label1(e, l1) \
MR_init_label(MR_label_name(MR_add_prefix(e), l1));
#define MR_init_label2(e, l1, l2) \
MR_init_label1(e, l1) \
MR_init_label1(e, l2)
#define MR_init_label3(e, l1, l2, l3) \
MR_init_label1(e, l1) \
MR_init_label1(e, l2) \
MR_init_label1(e, l3)
#define MR_init_label4(e, l1, l2, l3, l4) \
MR_init_label1(e, l1) \
MR_init_label1(e, l2) \
MR_init_label1(e, l3) \
MR_init_label1(e, l4)
#define MR_init_label5(e, l1, l2, l3, l4, l5) \
MR_init_label1(e, l1) \
MR_init_label1(e, l2) \
MR_init_label1(e, l3) \
MR_init_label1(e, l4) \
MR_init_label1(e, l5)
#define MR_init_label6(e, l1, l2, l3, l4, l5, l6) \
MR_init_label1(e, l1) \
MR_init_label1(e, l2) \
MR_init_label1(e, l3) \
MR_init_label1(e, l4) \
MR_init_label1(e, l5) \
MR_init_label1(e, l6)
#define MR_init_label7(e, l1, l2, l3, l4, l5, l6, l7) \
MR_init_label1(e, l1) \
MR_init_label1(e, l2) \
MR_init_label1(e, l3) \
MR_init_label1(e, l4) \
MR_init_label1(e, l5) \
MR_init_label1(e, l6) \
MR_init_label1(e, l7)
#define MR_init_label8(e, l1, l2, l3, l4, l5, l6, l7, l8) \
MR_init_label1(e, l1) \
MR_init_label1(e, l2) \
MR_init_label1(e, l3) \
MR_init_label1(e, l4) \
MR_init_label1(e, l5) \
MR_init_label1(e, l6) \
MR_init_label1(e, l7) \
MR_init_label1(e, l8)
#define MR_init_label9(e, l1, l2, l3, l4, l5, l6, l7, l8, l9) \
MR_init_label1(e, l1) \
MR_init_label1(e, l2) \
MR_init_label1(e, l3) \
MR_init_label1(e, l4) \
MR_init_label1(e, l5) \
MR_init_label1(e, l6) \
MR_init_label1(e, l7) \
MR_init_label1(e, l8) \
MR_init_label1(e, l9)
#define MR_init_label10(e, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10) \
MR_init_label1(e, l1) \
MR_init_label1(e, l2) \
MR_init_label1(e, l3) \
MR_init_label1(e, l4) \
MR_init_label1(e, l5) \
MR_init_label1(e, l6) \
MR_init_label1(e, l7) \
MR_init_label1(e, l8) \
MR_init_label1(e, l9) \
MR_init_label1(e, l10)
/*---------------------------------------------------------------------------*/
#define MR_init_label_sl1(e, l1) \
MR_init_label_sl(MR_label_name(MR_add_prefix(e), l1));
#define MR_init_label_sl2(e, l1, l2) \
MR_init_label_sl1(e, l1) \
MR_init_label_sl1(e, l2)
#define MR_init_label_sl3(e, l1, l2, l3) \
MR_init_label_sl1(e, l1) \
MR_init_label_sl1(e, l2) \
MR_init_label_sl1(e, l3)
#define MR_init_label_sl4(e, l1, l2, l3, l4) \
MR_init_label_sl1(e, l1) \
MR_init_label_sl1(e, l2) \
MR_init_label_sl1(e, l3) \
MR_init_label_sl1(e, l4)
#define MR_init_label_sl5(e, l1, l2, l3, l4, l5) \
MR_init_label_sl1(e, l1) \
MR_init_label_sl1(e, l2) \
MR_init_label_sl1(e, l3) \
MR_init_label_sl1(e, l4) \
MR_init_label_sl1(e, l5)
#define MR_init_label_sl6(e, l1, l2, l3, l4, l5, l6) \
MR_init_label_sl1(e, l1) \
MR_init_label_sl1(e, l2) \
MR_init_label_sl1(e, l3) \
MR_init_label_sl1(e, l4) \
MR_init_label_sl1(e, l5) \
MR_init_label_sl1(e, l6)
#define MR_init_label_sl7(e, l1, l2, l3, l4, l5, l6, l7) \
MR_init_label_sl1(e, l1) \
MR_init_label_sl1(e, l2) \
MR_init_label_sl1(e, l3) \
MR_init_label_sl1(e, l4) \
MR_init_label_sl1(e, l5) \
MR_init_label_sl1(e, l6) \
MR_init_label_sl1(e, l7)
#define MR_init_label_sl8(e, l1, l2, l3, l4, l5, l6, l7, l8) \
MR_init_label_sl1(e, l1) \
MR_init_label_sl1(e, l2) \
MR_init_label_sl1(e, l3) \
MR_init_label_sl1(e, l4) \
MR_init_label_sl1(e, l5) \
MR_init_label_sl1(e, l6) \
MR_init_label_sl1(e, l7) \
MR_init_label_sl1(e, l8)
#define MR_init_label_sl9(e, l1, l2, l3, l4, l5, l6, l7, l8, l9) \
MR_init_label_sl1(e, l1) \
MR_init_label_sl1(e, l2) \
MR_init_label_sl1(e, l3) \
MR_init_label_sl1(e, l4) \
MR_init_label_sl1(e, l5) \
MR_init_label_sl1(e, l6) \
MR_init_label_sl1(e, l7) \
MR_init_label_sl1(e, l8) \
MR_init_label_sl1(e, l9)
#define MR_init_label_sl10(e, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10) \
MR_init_label_sl1(e, l1) \
MR_init_label_sl1(e, l2) \
MR_init_label_sl1(e, l3) \
MR_init_label_sl1(e, l4) \
MR_init_label_sl1(e, l5) \
MR_init_label_sl1(e, l6) \
MR_init_label_sl1(e, l7) \
MR_init_label_sl1(e, l8) \
MR_init_label_sl1(e, l9) \
MR_init_label_sl1(e, l10)
/*---------------------------------------------------------------------------*/
#define MR_init_label_nvi1(e, m, l1, s1) \
MR_init_label_ml_sl(MR_label_name(MR_add_prefix(e), l1), \
&MR_no_var_label_layouts(m)[s1]);
#define MR_init_label_nvi2(e, m, l1,s1, l2,s2) \
MR_init_label_nvi1(e, m, l1, s1) \
MR_init_label_nvi1(e, m, l2, s2)
#define MR_init_label_nvi3(e, m, l1,s1, l2,s2, l3,s3) \
MR_init_label_nvi1(e, m, l1, s1) \
MR_init_label_nvi1(e, m, l2, s2) \
MR_init_label_nvi1(e, m, l3, s3)
#define MR_init_label_nvi4(e, m, l1,s1, l2,s2, l3,s3, l4,s4) \
MR_init_label_nvi1(e, m, l1, s1) \
MR_init_label_nvi1(e, m, l2, s2) \
MR_init_label_nvi1(e, m, l3, s3) \
MR_init_label_nvi1(e, m, l4, s4)
#define MR_init_label_nvi5(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5) \
MR_init_label_nvi1(e, m, l1, s1) \
MR_init_label_nvi1(e, m, l2, s2) \
MR_init_label_nvi1(e, m, l3, s3) \
MR_init_label_nvi1(e, m, l4, s4) \
MR_init_label_nvi1(e, m, l5, s5)
#define MR_init_label_nvi6(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5, l6,s6) \
MR_init_label_nvi1(e, m, l1, s1) \
MR_init_label_nvi1(e, m, l2, s2) \
MR_init_label_nvi1(e, m, l3, s3) \
MR_init_label_nvi1(e, m, l4, s4) \
MR_init_label_nvi1(e, m, l5, s5) \
MR_init_label_nvi1(e, m, l6, s6)
#define MR_init_label_nvi7(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5, l6,s6, l7,s7) \
MR_init_label_nvi1(e, m, l1, s1) \
MR_init_label_nvi1(e, m, l2, s2) \
MR_init_label_nvi1(e, m, l3, s3) \
MR_init_label_nvi1(e, m, l4, s4) \
MR_init_label_nvi1(e, m, l5, s5) \
MR_init_label_nvi1(e, m, l6, s6) \
MR_init_label_nvi1(e, m, l7, s7)
#define MR_init_label_nvi8(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5, l6,s6, l7,s7, l8,s8) \
MR_init_label_nvi1(e, m, l1, s1) \
MR_init_label_nvi1(e, m, l2, s2) \
MR_init_label_nvi1(e, m, l3, s3) \
MR_init_label_nvi1(e, m, l4, s4) \
MR_init_label_nvi1(e, m, l5, s5) \
MR_init_label_nvi1(e, m, l6, s6) \
MR_init_label_nvi1(e, m, l7, s7) \
MR_init_label_nvi1(e, m, l8, s8)
#define MR_init_label_nvi9(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5, l6,s6, l7,s7, l8,s8, l9,s9) \
MR_init_label_nvi1(e, m, l1, s1) \
MR_init_label_nvi1(e, m, l2, s2) \
MR_init_label_nvi1(e, m, l3, s3) \
MR_init_label_nvi1(e, m, l4, s4) \
MR_init_label_nvi1(e, m, l5, s5) \
MR_init_label_nvi1(e, m, l6, s6) \
MR_init_label_nvi1(e, m, l7, s7) \
MR_init_label_nvi1(e, m, l8, s8) \
MR_init_label_nvi1(e, m, l9, s9)
#define MR_init_label_nvi10(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5, l6,s6, l7,s7, l8,s8, l9,s9, l10,s10) \
MR_init_label_nvi1(e, m, l1, s1) \
MR_init_label_nvi1(e, m, l2, s2) \
MR_init_label_nvi1(e, m, l3, s3) \
MR_init_label_nvi1(e, m, l4, s4) \
MR_init_label_nvi1(e, m, l5, s5) \
MR_init_label_nvi1(e, m, l6, s6) \
MR_init_label_nvi1(e, m, l7, s7) \
MR_init_label_nvi1(e, m, l8, s8) \
MR_init_label_nvi1(e, m, l9, s9) \
MR_init_label_nvi1(e, m, l10, s10)
/*---------------------------------------------------------------------------*/
#define MR_init_label_svi1(e, m, l1, s1) \
MR_init_label_ml_sl(MR_label_name(MR_add_prefix(e), l1), \
(MR_LabelLayout *) &MR_svar_label_layouts(m)[s1]);
#define MR_init_label_svi2(e, m, l1,s1, l2,s2) \
MR_init_label_svi1(e, m, l1, s1) \
MR_init_label_svi1(e, m, l2, s2)
#define MR_init_label_svi3(e, m, l1,s1, l2,s2, l3,s3) \
MR_init_label_svi1(e, m, l1, s1) \
MR_init_label_svi1(e, m, l2, s2) \
MR_init_label_svi1(e, m, l3, s3)
#define MR_init_label_svi4(e, m, l1,s1, l2,s2, l3,s3, l4,s4) \
MR_init_label_svi1(e, m, l1, s1) \
MR_init_label_svi1(e, m, l2, s2) \
MR_init_label_svi1(e, m, l3, s3) \
MR_init_label_svi1(e, m, l4, s4)
#define MR_init_label_svi5(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5) \
MR_init_label_svi1(e, m, l1, s1) \
MR_init_label_svi1(e, m, l2, s2) \
MR_init_label_svi1(e, m, l3, s3) \
MR_init_label_svi1(e, m, l4, s4) \
MR_init_label_svi1(e, m, l5, s5)
#define MR_init_label_svi6(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5, l6,s6) \
MR_init_label_svi1(e, m, l1, s1) \
MR_init_label_svi1(e, m, l2, s2) \
MR_init_label_svi1(e, m, l3, s3) \
MR_init_label_svi1(e, m, l4, s4) \
MR_init_label_svi1(e, m, l5, s5) \
MR_init_label_svi1(e, m, l6, s6)
#define MR_init_label_svi7(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5, l6,s6, l7,s7) \
MR_init_label_svi1(e, m, l1, s1) \
MR_init_label_svi1(e, m, l2, s2) \
MR_init_label_svi1(e, m, l3, s3) \
MR_init_label_svi1(e, m, l4, s4) \
MR_init_label_svi1(e, m, l5, s5) \
MR_init_label_svi1(e, m, l6, s6) \
MR_init_label_svi1(e, m, l7, s7)
#define MR_init_label_svi8(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5, l6,s6, l7,s7, l8,s8) \
MR_init_label_svi1(e, m, l1, s1) \
MR_init_label_svi1(e, m, l2, s2) \
MR_init_label_svi1(e, m, l3, s3) \
MR_init_label_svi1(e, m, l4, s4) \
MR_init_label_svi1(e, m, l5, s5) \
MR_init_label_svi1(e, m, l6, s6) \
MR_init_label_svi1(e, m, l7, s7) \
MR_init_label_svi1(e, m, l8, s8)
#define MR_init_label_svi9(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5, l6,s6, l7,s7, l8,s8, l9,s9) \
MR_init_label_svi1(e, m, l1, s1) \
MR_init_label_svi1(e, m, l2, s2) \
MR_init_label_svi1(e, m, l3, s3) \
MR_init_label_svi1(e, m, l4, s4) \
MR_init_label_svi1(e, m, l5, s5) \
MR_init_label_svi1(e, m, l6, s6) \
MR_init_label_svi1(e, m, l7, s7) \
MR_init_label_svi1(e, m, l8, s8) \
MR_init_label_svi1(e, m, l9, s9)
#define MR_init_label_svi10(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5, l6,s6, l7,s7, l8,s8, l9,s9, l10,s10) \
MR_init_label_svi1(e, m, l1, s1) \
MR_init_label_svi1(e, m, l2, s2) \
MR_init_label_svi1(e, m, l3, s3) \
MR_init_label_svi1(e, m, l4, s4) \
MR_init_label_svi1(e, m, l5, s5) \
MR_init_label_svi1(e, m, l6, s6) \
MR_init_label_svi1(e, m, l7, s7) \
MR_init_label_svi1(e, m, l8, s8) \
MR_init_label_svi1(e, m, l9, s9) \
MR_init_label_svi1(e, m, l10, s10)
/*---------------------------------------------------------------------------*/
#define MR_init_label_lvi1(e, m, l1, s1) \
MR_init_label_ml_sl(MR_label_name(MR_add_prefix(e), l1), \
&MR_lvar_label_layouts(m)[s1]);
#define MR_init_label_lvi2(e, m, l1,s1, l2,s2) \
MR_init_label_lvi1(e, m, l1, s1) \
MR_init_label_lvi1(e, m, l2, s2)
#define MR_init_label_lvi3(e, m, l1,s1, l2,s2, l3,s3) \
MR_init_label_lvi1(e, m, l1, s1) \
MR_init_label_lvi1(e, m, l2, s2) \
MR_init_label_lvi1(e, m, l3, s3)
#define MR_init_label_lvi4(e, m, l1,s1, l2,s2, l3,s3, l4,s4) \
MR_init_label_lvi1(e, m, l1, s1) \
MR_init_label_lvi1(e, m, l2, s2) \
MR_init_label_lvi1(e, m, l3, s3) \
MR_init_label_lvi1(e, m, l4, s4)
#define MR_init_label_lvi5(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5) \
MR_init_label_lvi1(e, m, l1, s1) \
MR_init_label_lvi1(e, m, l2, s2) \
MR_init_label_lvi1(e, m, l3, s3) \
MR_init_label_lvi1(e, m, l4, s4) \
MR_init_label_lvi1(e, m, l5, s5)
#define MR_init_label_lvi6(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5, l6,s6) \
MR_init_label_lvi1(e, m, l1, s1) \
MR_init_label_lvi1(e, m, l2, s2) \
MR_init_label_lvi1(e, m, l3, s3) \
MR_init_label_lvi1(e, m, l4, s4) \
MR_init_label_lvi1(e, m, l5, s5) \
MR_init_label_lvi1(e, m, l6, s6)
#define MR_init_label_lvi7(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5, l6,s6, l7,s7) \
MR_init_label_lvi1(e, m, l1, s1) \
MR_init_label_lvi1(e, m, l2, s2) \
MR_init_label_lvi1(e, m, l3, s3) \
MR_init_label_lvi1(e, m, l4, s4) \
MR_init_label_lvi1(e, m, l5, s5) \
MR_init_label_lvi1(e, m, l6, s6) \
MR_init_label_lvi1(e, m, l7, s7)
#define MR_init_label_lvi8(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5, l6,s6, l7,s7, l8,s8) \
MR_init_label_lvi1(e, m, l1, s1) \
MR_init_label_lvi1(e, m, l2, s2) \
MR_init_label_lvi1(e, m, l3, s3) \
MR_init_label_lvi1(e, m, l4, s4) \
MR_init_label_lvi1(e, m, l5, s5) \
MR_init_label_lvi1(e, m, l6, s6) \
MR_init_label_lvi1(e, m, l7, s7) \
MR_init_label_lvi1(e, m, l8, s8)
#define MR_init_label_lvi9(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5, l6,s6, l7,s7, l8,s8, l9,s9) \
MR_init_label_lvi1(e, m, l1, s1) \
MR_init_label_lvi1(e, m, l2, s2) \
MR_init_label_lvi1(e, m, l3, s3) \
MR_init_label_lvi1(e, m, l4, s4) \
MR_init_label_lvi1(e, m, l5, s5) \
MR_init_label_lvi1(e, m, l6, s6) \
MR_init_label_lvi1(e, m, l7, s7) \
MR_init_label_lvi1(e, m, l8, s8) \
MR_init_label_lvi1(e, m, l9, s9)
#define MR_init_label_lvi10(e, m, l1,s1, l2,s2, l3,s3, l4,s4, l5,s5, l6,s6, l7,s7, l8,s8, l9,s9, l10,s10) \
MR_init_label_lvi1(e, m, l1, s1) \
MR_init_label_lvi1(e, m, l2, s2) \
MR_init_label_lvi1(e, m, l3, s3) \
MR_init_label_lvi1(e, m, l4, s4) \
MR_init_label_lvi1(e, m, l5, s5) \
MR_init_label_lvi1(e, m, l6, s6) \
MR_init_label_lvi1(e, m, l7, s7) \
MR_init_label_lvi1(e, m, l8, s8) \
MR_init_label_lvi1(e, m, l9, s9) \
MR_init_label_lvi1(e, m, l10, s10)
/*---------------------------------------------------------------------------*/
#define MR_decl_extern_entry(e) \
MR_declare_extern_entry(MR_add_prefix(e));
#define MR_decl_entry(e) \
MR_declare_entry(MR_add_prefix(e));
#define MR_decl_static(e) \
MR_declare_static(MR_add_prefix(e));
#define MR_decl_local(e) \
MR_declare_local(MR_add_prefix(e));
#define MR_decl_label1(e, l1) \
MR_declare_label(MR_label_name(MR_add_prefix(e), l1));
#define MR_decl_label2(e, l1, l2) \
MR_decl_label1(e, l1) \
MR_decl_label1(e, l2)
#define MR_decl_label3(e, l1, l2, l3) \
MR_decl_label1(e, l1) \
MR_decl_label1(e, l2) \
MR_decl_label1(e, l3)
#define MR_decl_label4(e, l1, l2, l3, l4) \
MR_decl_label1(e, l1) \
MR_decl_label1(e, l2) \
MR_decl_label1(e, l3) \
MR_decl_label1(e, l4)
#define MR_decl_label5(e, l1, l2, l3, l4, l5) \
MR_decl_label1(e, l1) \
MR_decl_label1(e, l2) \
MR_decl_label1(e, l3) \
MR_decl_label1(e, l4) \
MR_decl_label1(e, l5)
#define MR_decl_label6(e, l1, l2, l3, l4, l5, l6) \
MR_decl_label1(e, l1) \
MR_decl_label1(e, l2) \
MR_decl_label1(e, l3) \
MR_decl_label1(e, l4) \
MR_decl_label1(e, l5) \
MR_decl_label1(e, l6)
#define MR_decl_label7(e, l1, l2, l3, l4, l5, l6, l7) \
MR_decl_label1(e, l1) \
MR_decl_label1(e, l2) \
MR_decl_label1(e, l3) \
MR_decl_label1(e, l4) \
MR_decl_label1(e, l5) \
MR_decl_label1(e, l6) \
MR_decl_label1(e, l7)
#define MR_decl_label8(e, l1, l2, l3, l4, l5, l6, l7, l8) \
MR_decl_label1(e, l1) \
MR_decl_label1(e, l2) \
MR_decl_label1(e, l3) \
MR_decl_label1(e, l4) \
MR_decl_label1(e, l5) \
MR_decl_label1(e, l6) \
MR_decl_label1(e, l7) \
MR_decl_label1(e, l8)
#define MR_decl_label9(e, l1, l2, l3, l4, l5, l6, l7, l8, l9) \
MR_decl_label1(e, l1) \
MR_decl_label1(e, l2) \
MR_decl_label1(e, l3) \
MR_decl_label1(e, l4) \
MR_decl_label1(e, l5) \
MR_decl_label1(e, l6) \
MR_decl_label1(e, l7) \
MR_decl_label1(e, l8) \
MR_decl_label1(e, l9)
#define MR_decl_label10(e, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10) \
MR_decl_label1(e, l1) \
MR_decl_label1(e, l2) \
MR_decl_label1(e, l3) \
MR_decl_label1(e, l4) \
MR_decl_label1(e, l5) \
MR_decl_label1(e, l6) \
MR_decl_label1(e, l7) \
MR_decl_label1(e, l8) \
MR_decl_label1(e, l9) \
MR_decl_label1(e, l10)
/*---------------------------------------------------------------------------*/
/* definitions for computed gotos */
#define MR_COMPUTED_GOTO(val, labels) \
{ \
static MR_Code *jump_table[] = { \
labels \
}; \
MR_GOTO(jump_table[val]); \
}
#define MR_AND , /* used to separate the labels */
#endif /* not MERCURY_GOTO_H */
/*---------------------------------------------------------------------------*/