mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-12 04:14:06 +00:00
Estimated hours taken: 0.2 Branches: main runtime/mercury_calls.h: runtime/mercury_prof.h: runtime/mercury_signal.h: runtime/mercury_string.h: runtime/mercury_thread.c: runtime/mercury_thread.h: Fix some layout issues in these files. There are no algorithmic changes.
175 lines
5.4 KiB
C
175 lines
5.4 KiB
C
/*
|
|
** Copyright (C) 1995-2000, 2004-2005 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_calls.h - definitions for calls and returns */
|
|
|
|
#ifndef MERCURY_CALLS_H
|
|
#define MERCURY_CALLS_H
|
|
|
|
#include "mercury_regs.h" /* for MR_succip */
|
|
#include "mercury_goto.h" /* calls are implemented using gotos */
|
|
#include "mercury_debug.h" /* we need to debug them */
|
|
#include "mercury_prof.h" /* we need to profile them */
|
|
|
|
/*
|
|
** The noprof (no profiling) versions of call, call_localret, localcall,
|
|
** tailcall, and localtailcall.
|
|
*/
|
|
|
|
/*
|
|
** On some systems [basically those using PIC (Position Independent Code)],
|
|
** if we're using gcc non-local gotos to jump between functions then
|
|
** we need to do ASM_FIXUP_REGS after each return from a procedure call.
|
|
** However, if we're using asm labels, then this is done in the
|
|
** MR_define_label(), MR_define_static(), and MR_define_Entry() macros,
|
|
** so there's no need to do it here.
|
|
** Also if we're using native gc, then the fixup_gp label below
|
|
** would stuff up the succip values, so we can't do it.
|
|
**
|
|
** For the non-asm `jump' and `fast' grades, we do in theory need
|
|
** to do something like this. However, doing ASM_FIXUP_REGS only
|
|
** on returns is *not* sufficient to ensure correctness in general.
|
|
** So the non-asm `jump' and `fast' grades are in theory broken,
|
|
** with or without this code. In practice they happen to work
|
|
** (for our current set of test cases!) either way.
|
|
** So it is simpler (and more efficient) to just comment it out.
|
|
*/
|
|
#if 0
|
|
#define MR_noprof_call(proc, succ_cont) \
|
|
({ \
|
|
__label__ fixup_gp; \
|
|
MR_debugcall((proc), (succ_cont)); \
|
|
MR_succip_word = (MR_Word) (&&fixup_gp); \
|
|
MR_GOTO(proc); \
|
|
fixup_gp: \
|
|
ASM_FIXUP_REGS \
|
|
MR_GOTO(succ_cont); \
|
|
})
|
|
/* same as above, but with MR_GOTO_LABEL rather than MR_GOTO */
|
|
#define MR_noprof_call_localret(proc, succ_cont) \
|
|
({ \
|
|
__label__ fixup_gp; \
|
|
MR_debugcall((proc), (succ_cont)); \
|
|
MR_succip_word = (MR_Word) (&&fixup_gp); \
|
|
MR_GOTO(proc); \
|
|
fixup_gp: \
|
|
ASM_FIXUP_REGS \
|
|
MR_GOTO_LABEL(succ_cont); \
|
|
})
|
|
#else
|
|
#define MR_noprof_call(proc, succ_cont) \
|
|
do { \
|
|
MR_debugcall((proc), (succ_cont)); \
|
|
MR_succip_word = (MR_Word) (succ_cont); \
|
|
MR_GOTO(proc); \
|
|
} while (0)
|
|
#define MR_noprof_call_localret(proc, succ_cont) \
|
|
MR_noprof_call((proc), MR_LABEL(succ_cont))
|
|
#endif
|
|
|
|
#define MR_noprof_localcall(label, succ_cont) \
|
|
do { \
|
|
MR_debugcall(MR_LABEL(label), (succ_cont)); \
|
|
MR_succip_word = (MR_Word) (succ_cont); \
|
|
MR_GOTO_LABEL(label); \
|
|
} while (0)
|
|
|
|
#define MR_noprof_tailcall(proc) \
|
|
do { \
|
|
MR_debugtailcall(proc); \
|
|
MR_GOTO(proc); \
|
|
} while (0)
|
|
|
|
#define MR_noprof_localtailcall(label) \
|
|
do { \
|
|
MR_debugtailcall(MR_LABEL(label)); \
|
|
MR_GOTO_LABEL(label); \
|
|
} while (0)
|
|
|
|
/*
|
|
** The shorthand versions of the non-profiling versions of
|
|
** call_localret, localcall, tailcall, and localtailcall.
|
|
** To a first approximation, just plain call doesn't occur at all,
|
|
** so it isn't worth a shorthand form.
|
|
*/
|
|
|
|
#define MR_np_call_localret(proc, succ_cont) \
|
|
MR_noprof_call_localret(MR_add_prefix(proc), MR_add_prefix(succ_cont))
|
|
|
|
#define MR_np_call_localret_ent(proc, succ_cont) \
|
|
MR_noprof_call_localret(MR_ENTRY_AP(proc), MR_add_prefix(succ_cont))
|
|
|
|
#define MR_np_localcall(label, succ_cont) \
|
|
MR_noprof_localcall(MR_add_prefix(label), MR_add_prefix(succ_cont))
|
|
|
|
#define MR_np_localcall_ent(label, succ_cont) \
|
|
MR_noprof_localcall(MR_add_prefix(label), MR_ENTRY_AP(succ_cont))
|
|
|
|
#define MR_np_localcall_lab(label, succ_cont) \
|
|
MR_noprof_localcall(MR_add_prefix(label), MR_LABEL_AP(succ_cont))
|
|
|
|
#define MR_np_tailcall(proc) \
|
|
MR_noprof_tailcall(MR_add_prefix(proc))
|
|
|
|
#define MR_np_tailcall_ent(proc) \
|
|
MR_noprof_tailcall(MR_ENTRY_AP(proc))
|
|
|
|
#define MR_np_localtailcall(label) \
|
|
MR_noprof_localtailcall(MR_add_prefix(label))
|
|
|
|
/*
|
|
** The plain (possibly profiling, depending on #defines) versions of
|
|
** call, call_localret, localcall, tailcall, and localtailcall.
|
|
** These take an extra argument, the current label.
|
|
*/
|
|
|
|
#define MR_call(proc, succ_cont, current_label) \
|
|
do { \
|
|
MR_PROFILE((proc), (current_label)); \
|
|
MR_set_prof_current_proc(proc); \
|
|
MR_noprof_call((proc), (succ_cont)); \
|
|
} while (0)
|
|
|
|
#define MR_call_localret(proc, succ_cont, current_label) \
|
|
do { \
|
|
MR_PROFILE((proc), (current_label)); \
|
|
MR_set_prof_current_proc(proc); \
|
|
MR_noprof_call_localret(proc, succ_cont);\
|
|
} while (0)
|
|
|
|
#define MR_localcall(label, succ_cont, current_label) \
|
|
do { \
|
|
MR_PROFILE(MR_LABEL(label), (current_label)); \
|
|
MR_set_prof_current_proc(MR_LABEL(label)); \
|
|
MR_noprof_localcall(label, succ_cont); \
|
|
} while (0)
|
|
|
|
#define MR_tailcall(proc, current_label) \
|
|
do { \
|
|
MR_PROFILE((proc), (current_label)); \
|
|
MR_set_prof_current_proc(proc); \
|
|
MR_noprof_tailcall(proc); \
|
|
} while (0)
|
|
|
|
#define MR_localtailcall(label, current_label) \
|
|
do { \
|
|
MR_PROFILE(MR_LABEL(label), (current_label)); \
|
|
MR_set_prof_current_proc(MR_LABEL(label)); \
|
|
MR_noprof_localtailcall(label); \
|
|
} while (0)
|
|
|
|
/*
|
|
** The macros for returning from calls from procedures.
|
|
*/
|
|
|
|
#define MR_proceed() \
|
|
do { \
|
|
MR_debugproceed(); \
|
|
MR_GOTO(MR_succip); \
|
|
} while (0)
|
|
|
|
#endif /* not MERCURY_CALLS_H */
|