[m-dev.] Re: fastcall for the x86

Fergus Henderson fjh at cs.mu.OZ.AU
Sat Nov 25 03:01:16 AEDT 2000


On 17-Nov-2000, Fergus Henderson <fjh at cs.mu.OZ.AU> wrote:
> On 17-Nov-2000, Tyson Dowd <trd at cs.mu.OZ.AU> wrote:
> > I was chatting to Pete on the phone and we got into a discussion of
> > using fastcall convention on the x86 in hlc grade.
> > gcc has a similar calling convention that can be enabled using the
> > regparm(X) attribute.  It might be worth trying this out in hlc.gc
> > for non-exported functions.
> 
> That won't work, since we take the address of non-exported functions
> and pass them to other modules.
> 
> But we could do it for all Mercury-generated functions
> (and for functions in the Mercury runtime or standard library that
> implement builtin unification/compare or Mercury procedures declared
> `:- external').

I tried this out.  But both the `regparm' and `stdcall' attributes are
broken in both gcc 2.95.2 and egcs 1.1.2 (in slightly different ways).
The symptoms include (1) silently ignoring such attributes when they
occur in function pointer type casts (and thus generating code which
crashes, due to mismatches with the places where the attributes are
not ignored); (2) gcc internal compiler errors; and (3) segmentation
fauls ("fatal signal 11") in cc1.  I just sent off three bug reports
against gcc 2.95.2.

The following diff has my efforts towards exploiting such attributes.
They may be useful for __fastcall with MSVC.  But they're not yet
useful for gcc, and I haven't been able to test them properly, so I
don't plan to commit this.  Pete, you might want to take this diff,
review it carefully for bugs (no doubt there are some ;-), and then
use it to try out __fastcall with MSVC.

----------

Estimated hours taken: 8

Add support for using a different C calling convention for the
C functions generated by the MLDS back-end.

runtime/ml_call_gen.m:
	For higher-order calls and class method calls, assign the
	function pointer to a local variable; XXX this is a hack
	needed for some versions of gcc and isn't sufficient anyway.

runtime/mlds_to_c.m:
	Output "MR_CALL" in function declarations.
	XXX But *not* for casts; this part is a hack needed for some
	versions of gcc and isn't sufficient anyway.

runtime/mercury_types.h:
	Define MR_CALL.  This is a macro that expands to some
	implementation-specific C extension to specify the calling
	convention.  E.g. for gcc it could be
	`__attribute__((__regparm__(3), __stdcall__))',
	except that gcc seems to be broken.

	XXX This should probably go in mercury_std.h.

runtime/mercury_types.h:
runtime/mercury.h:
runtime/mercury.c:
runtime/mercury_wrapper.h:
runtime/mercury_wrapper.c:
util/mkinit.c:
library/array.m:
library/builtin.m:
library/exception.m:
	Use MR_CALL for functions that should have the
	Mercury calling convention.
	XXX It would be cleaner to have an implicit `pragma export'
	for main/2 rather than the current scheme where we do it
	manually.

cvs diff: Diffing .
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/ml_call_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_call_gen.m,v
retrieving revision 1.18
diff -u -d -u -r1.18 ml_call_gen.m
--- compiler/ml_call_gen.m	2000/11/23 04:32:42	1.18
+++ compiler/ml_call_gen.m	2000/11/24 11:14:45
@@ -195,6 +195,23 @@
 	),
 
 	%
+	% Assign the function address rval to a new local variable.
+	% This makes the generated code slightly more readable.
+	% More importantly, this is also necessary when using a
+	% non-standard calling convention with GNU C, since GNU C
+	% (2.95.2) ignores the function attributes on function
+	% pointer types in casts.
+	% 
+	ml_gen_info_new_conv_var(ConvVarNum),
+	{ string__format("func_%d", [i(ConvVarNum)],
+		FuncVarName) },
+	{ FuncVarDecl = ml_gen_mlds_var_decl(var(FuncVarName), FuncType,
+		mlds__make_context(Context)) },
+	ml_qualify_var(FuncVarName, FuncVarLval),
+	{ AssignFuncVar = ml_gen_assign(FuncVarLval, FuncRval, Context) },
+	{ FuncVarRval = lval(FuncVarLval) },
+
+	%
 	% Generate code to box/unbox the arguments
 	% and compute the list of properly converted rvals/lvals
 	% to pass as the function call's arguments and return values
@@ -216,12 +233,12 @@
 	% which when called will generate it.)
 	%
 	{ ObjectRval = no },
-	{ DoGenCall = ml_gen_mlds_call(Signature, ObjectRval, FuncRval,
+	{ DoGenCall = ml_gen_mlds_call(Signature, ObjectRval, FuncVarRval,
 		[ClosureRval | InputRvals], OutputLvals, OutputTypes,
 		CodeModel, Context) },
 
 	( { ConvArgDecls = [], ConvOutputStatements = [] } ->
-		DoGenCall(MLDS_Decls, MLDS_Statements)
+		DoGenCall(MLDS_Decls0, MLDS_Statements0)
 	;
 		%
 		% Construct a closure to generate code to 
@@ -245,10 +262,11 @@
 		ml_combine_conj(CodeModel, Context,
 			DoGenCall, DoGenConvOutputAndSucceed,
 			CallAndConvOutputDecls, CallAndConvOutputStatements),
-		{ MLDS_Decls = list__append(ConvArgDecls,
-			CallAndConvOutputDecls) },
-		{ MLDS_Statements = CallAndConvOutputStatements }
-	).
+		{ MLDS_Decls0 = ConvArgDecls ++ CallAndConvOutputDecls },
+		{ MLDS_Statements0 = CallAndConvOutputStatements }
+	),
+	{ MLDS_Decls = [FuncVarDecl | MLDS_Decls0] },
+	{ MLDS_Statements = [AssignFuncVar | MLDS_Statements0] }.
 
 	%
 	% Generate code for the various parts that are needed for
Index: compiler/mlds_to_c.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_c.m,v
retrieving revision 1.71
diff -u -d -u -r1.71 mlds_to_c.m
--- compiler/mlds_to_c.m	2000/11/21 13:37:42	1.71
+++ compiler/mlds_to_c.m	2000/11/24 14:56:03
@@ -696,9 +696,7 @@
 		io__state::di, io__state::uo) is det.
 
 mlds_output_name_with_cast(ModuleName, Name - Type) -->
-	io__write_char('('),
-	mlds_output_type(Type),
-	io__write_string(") "),
+	mlds_output_cast(Type),
 	mlds_output_fully_qualified_name(qual(ModuleName, Name)).
 
 	%
@@ -1230,6 +1228,7 @@
 :- mode mlds_output_func_decl(in, in, in, in, di, uo) is det.
 
 mlds_output_func_decl(Indent, QualifiedName, Context, Signature) -->
+	mlds_output_calling_convention(output_for_decl),
 	mlds_output_func_decl_ho(Indent, QualifiedName, Context, Signature,
 			mlds_output_type_prefix, mlds_output_type_suffix).
 
@@ -1292,15 +1291,16 @@
 	mlds_output_data_decl_ho(OutputPrefix, OutputSuffix,
 			qual(ModuleName, Name), Type).
 
-:- pred mlds_output_func_type_prefix(func_params, io__state, io__state).
-:- mode mlds_output_func_type_prefix(in, di, uo) is det.
+:- pred mlds_output_func_type_prefix(func_params, output_for, io__state, io__state).
+:- mode mlds_output_func_type_prefix(in, in, di, uo) is det.
 
-mlds_output_func_type_prefix(Params) -->
+mlds_output_func_type_prefix(Params, OutputFor) -->
+	mlds_output_calling_convention(OutputFor),
 	{ Params = mlds__func_params(_Parameters, RetTypes) },
 	( { RetTypes = [] } ->
 		io__write_string("void")
 	; { RetTypes = [RetType] } ->
-		mlds_output_type(RetType)
+		mlds_output_type(RetType, OutputFor)
 	;
 		{ error("mlds_output_func_type_prefix: multiple return types") }
 	),
@@ -1505,24 +1505,65 @@
 % the part which goes after the variable name, e.g. the "[]"
 % for array types.
 %
+% Also, because of the further joys of GNU C syntax (with gcc version
+% egcs-1.1.2) function attributes for the function calling convention
+% (the `MR_CALL' macro) are needed on function types in declarations/
+% definitions, but must NOT be used on function types in casts.
+% 
+
+:- type output_for
+	--->	output_for_cast
+	;	output_for_decl.
+
+:- pred mlds_output_calling_convention(output_for, io__state, io__state).
+:- mode mlds_output_calling_convention(in, di, uo) is det.
+
+mlds_output_calling_convention(output_for_decl) -->
+	io__write_string("MR_CALL ").
+mlds_output_calling_convention(output_for_cast) -->
+	% GNU C doesn't require or even allow the calling
+	% convention to be specified in a cast to a function
+	% pointer type.  So we just output nothing here.
+	%
+	% Other C compilers might need something here, in which
+	% cast we could use
+	%	io__write_string("MR_CALL_IN_CAST ")
+	% here and define that macro appropriately for those compilers.
+	[].
 
 :- pred mlds_output_type(mlds__type, io__state, io__state).
 :- mode mlds_output_type(in, di, uo) is det.
 
 mlds_output_type(Type) -->
-	mlds_output_type_prefix(Type),
-	mlds_output_type_suffix(Type).
+	mlds_output_type(Type, output_for_decl).
 
 :- pred mlds_output_type_prefix(mlds__type, io__state, io__state).
 :- mode mlds_output_type_prefix(in, di, uo) is det.
 
-mlds_output_type_prefix(mercury_type(Type, TypeCategory)) -->
+mlds_output_type_prefix(Type) -->
+	mlds_output_type_prefix(Type, output_for_decl).
+
+:- pred mlds_output_type(mlds__type, output_for, io__state, io__state).
+:- mode mlds_output_type(in, in, di, uo) is det.
+
+mlds_output_type(Type, OutputFor) -->
+	mlds_output_type_prefix(Type, OutputFor),
+	mlds_output_type_suffix(Type).
+
+:- pred mlds_output_type_prefix(mlds__type, output_for, io__state, io__state).
+:- mode mlds_output_type_prefix(in, in, di, uo) is det.
+
+mlds_output_type_prefix(mercury_type(Type, TypeCategory), _) -->
 	mlds_output_mercury_type_prefix(Type, TypeCategory).
-mlds_output_type_prefix(mlds__native_int_type)   --> io__write_string("int").
-mlds_output_type_prefix(mlds__native_float_type) --> io__write_string("float").
-mlds_output_type_prefix(mlds__native_bool_type)  --> io__write_string("bool").
-mlds_output_type_prefix(mlds__native_char_type)  --> io__write_string("char").
-mlds_output_type_prefix(mlds__class_type(Name, Arity, ClassKind)) -->
+mlds_output_type_prefix(mlds__native_int_type,   _)  -->
+	io__write_string("int").
+mlds_output_type_prefix(mlds__native_float_type, _) -->
+	io__write_string("float").
+mlds_output_type_prefix(mlds__native_bool_type,  _) -->
+	io__write_string("bool").
+mlds_output_type_prefix(mlds__native_char_type,  _) -->
+	io__write_string("char").
+mlds_output_type_prefix(mlds__class_type(Name, Arity, ClassKind), _) -->
 	( { ClassKind = mlds__enum } ->
 		%
 		% We can't just use the enumeration type,
@@ -1547,22 +1588,22 @@
 		mlds_output_fully_qualified(Name, mlds_output_mangled_name),
 		io__format("_%d_s", [i(Arity)])
 	).
-mlds_output_type_prefix(mlds__ptr_type(Type)) -->
+mlds_output_type_prefix(mlds__ptr_type(Type), _) -->
 	mlds_output_type(Type),
 	io__write_string(" *").
-mlds_output_type_prefix(mlds__array_type(Type)) -->
+mlds_output_type_prefix(mlds__array_type(Type), _) -->
 	% Here we just output the element type.
 	% The "[]" goes in the type suffix.
 	mlds_output_type(Type).
-mlds_output_type_prefix(mlds__func_type(FuncParams)) -->
-	mlds_output_func_type_prefix(FuncParams).
-mlds_output_type_prefix(mlds__generic_type) -->
+mlds_output_type_prefix(mlds__func_type(FuncParams), OutputFor) -->
+	mlds_output_func_type_prefix(FuncParams, OutputFor).
+mlds_output_type_prefix(mlds__generic_type, _) -->
 	io__write_string("MR_Box").
-mlds_output_type_prefix(mlds__generic_env_ptr_type) -->
+mlds_output_type_prefix(mlds__generic_env_ptr_type, _) -->
 	io__write_string("void *").
-mlds_output_type_prefix(mlds__pseudo_type_info_type) -->
+mlds_output_type_prefix(mlds__pseudo_type_info_type, _) -->
 	io__write_string("MR_PseudoTypeInfo").
-mlds_output_type_prefix(mlds__cont_type(ArgTypes)) -->
+mlds_output_type_prefix(mlds__cont_type(ArgTypes), OutputFor) -->
 	( { ArgTypes = [] } ->
 		globals__io_lookup_bool_option(gcc_nested_functions,
 			GCC_NestedFuncs),
@@ -1573,16 +1614,17 @@
 		)
 	;
 		% This case only happens for --nondet-copy-out
+		mlds_output_calling_convention(OutputFor),
 		io__write_string("void (*")
 	).
-mlds_output_type_prefix(mlds__commit_type) -->
+mlds_output_type_prefix(mlds__commit_type, _) -->
 	globals__io_lookup_bool_option(gcc_local_labels, GCC_LocalLabels),
 	( { GCC_LocalLabels = yes } ->
 		io__write_string("__label__")
 	;
 		io__write_string("jmp_buf")
 	).
-mlds_output_type_prefix(mlds__rtti_type(RttiName)) -->
+mlds_output_type_prefix(mlds__rtti_type(RttiName), _) -->
 	io__write_string("MR_"),
 	io__write_string(mlds_rtti_type_name(RttiName)).
 
@@ -2397,9 +2439,7 @@
 	io__write_string(" = "),
 	( { MaybeTag = yes(Tag0) } ->
 		{ Tag = Tag0 },
-		io__write_string("("),
-		mlds_output_type(Type),
-		io__write_string(") "),
+		mlds_output_cast(Type),
 		io__write_string("MR_mkword("),
 		mlds_output_tag(Tag),
 		io__write_string(", "),
@@ -2412,9 +2452,7 @@
 		% in the call to MR_new_object() is not
 		% always correct.
 		%
-		io__write_string("("),
-		mlds_output_type(Type),
-		io__write_string(") "),
+		mlds_output_cast(Type),
 		{ EndMkword = "" }
 	),
 	io__write_string("MR_new_object("),
@@ -2575,9 +2613,8 @@
 		_FieldType, _PtrType)) -->
 	% XXX we shouldn't bother with this cast in the case where
 	% PtrType == CtorType
-	io__write_string("(("),
-	mlds_output_type(CtorType),
-	io__write_string(") "),
+	io__write_string("("),
+	mlds_output_cast(CtorType),
 	( { MaybeTag = yes(0) } ->
 		( { PtrRval = mem_addr(Lval) } ->
 			mlds_output_lval(Lval),
@@ -2715,11 +2752,17 @@
 :- mode mlds_output_cast_rval(in, in, di, uo) is det.
 	
 mlds_output_cast_rval(Type, Exprn) -->
-	io__write_string("("),
-	mlds_output_type(Type),
-	io__write_string(") "),
+	mlds_output_cast(Type),
 	mlds_output_rval(Exprn).
 
+:- pred mlds_output_cast(mlds__type, io__state, io__state).
+:- mode mlds_output_cast(in, di, uo) is det.
+	
+mlds_output_cast(Type) -->
+	io__write_string("("),
+	mlds_output_type(Type, output_for_cast),
+	io__write_string(") ").
+
 :- pred mlds_output_boxed_rval(mlds__type, mlds__rval, io__state, io__state).
 :- mode mlds_output_boxed_rval(in, in, di, uo) is det.
 	
@@ -2763,9 +2806,9 @@
 		% pointer to integer of different size" from gcc.
 		% XXX The generated code would be more readable if we
 		%     only did this for the cases where it was necessary.
-		io__write_string("(("),
-		mlds_output_type(Type),
-		io__write_string(") (MR_Word) "),
+		io__write_string("("),
+		mlds_output_cast(Type),
+		io__write_string("(MR_Word) "),
 		mlds_output_rval(Exprn),
 		io__write_string(")")
 	).
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing doc
cvs diff: Diffing extras
cvs diff: Diffing extras/aditi
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/concurrency
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/stream
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/xml
cvs diff: Diffing library
Index: library/array.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/array.m,v
retrieving revision 1.78
diff -u -d -u -r1.78 array.m
--- library/array.m	2000/11/23 01:59:51	1.78
+++ library/array.m	2000/11/24 12:37:12
@@ -331,14 +331,14 @@
 	return;
 }
 
-bool
+MR_CALL bool
 mercury__array____Unify____array_1_0(MR_Mercury_Type_Info type_info,
 	MR_Array x, MR_Array y)
 {
 	return mercury__array__array_equal_2_p_0(type_info, x, y);
 }
 
-void
+MR_CALL void
 mercury__array____Compare____array_1_0(
 	MR_Mercury_Type_Info type_info, MR_Comparison_Result *result,
 	MR_Array x, MR_Array y)
Index: library/builtin.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/builtin.m,v
retrieving revision 1.44
diff -u -d -u -r1.44 builtin.m
--- library/builtin.m	2000/11/23 01:59:53	1.44
+++ library/builtin.m	2000/11/24 15:46:15
@@ -398,8 +398,8 @@
 
 :- pragma c_header_code("
 #ifdef MR_HIGHLEVEL_CODE
-  void mercury__builtin__copy_2_p_0(MR_Mercury_Type_Info, MR_Box, MR_Box *);
-  void mercury__builtin__copy_2_p_1(MR_Mercury_Type_Info, MR_Box, MR_Box *);
+  MR_CALL void mercury__builtin__copy_2_p_0(MR_Mercury_Type_Info, MR_Box, MR_Box *);
+  MR_CALL void mercury__builtin__copy_2_p_1(MR_Mercury_Type_Info, MR_Box, MR_Box *);
 #endif
 ").
 
@@ -407,7 +407,7 @@
 
 #ifdef MR_HIGHLEVEL_CODE
 
-void
+MR_CALL void
 mercury__builtin__copy_2_p_0(MR_Mercury_Type_Info type_info,
 	MR_Box value, MR_Box * copy)
 {
@@ -415,7 +415,7 @@
 	*copy = (MR_Box) deep_copy(&val, (MR_TypeInfo) type_info, NULL, NULL);
 }
 
-void
+MR_CALL void
 mercury__builtin__copy_2_p_1(MR_Mercury_Type_Info type_info, MR_Box x, MR_Box * y)
 {
 	mercury__builtin__copy_2_p_0(type_info, x, y);
Index: library/exception.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/exception.m,v
retrieving revision 1.33
diff -u -d -u -r1.33 exception.m
--- library/exception.m	2000/11/23 01:59:54	1.33
+++ library/exception.m	2000/11/24 15:48:02
@@ -503,16 +503,16 @@
 	#define mercury__exception__builtin_catch_3_p_5 \
 		mercury__exception__builtin_catch_model_non
 
-	void mercury__exception__builtin_throw_1_p_0(MR_Univ);
+	MR_CALL void mercury__exception__builtin_throw_1_p_0(MR_Univ);
 
-	void mercury__exception__builtin_throw_1_p_0(MR_Univ exception);
-	void mercury__exception__builtin_catch_model_det(
+	MR_CALL void mercury__exception__builtin_throw_1_p_0(MR_Univ exception);
+	MR_CALL void mercury__exception__builtin_catch_model_det(
 		MR_Mercury_Type_Info type_info, MR_Pred pred, MR_Pred handler_pred,
 		MR_Box *output);
-	bool mercury__exception__builtin_catch_model_semi(
+	MR_CALL bool mercury__exception__builtin_catch_model_semi(
 		MR_Mercury_Type_Info type_info, MR_Pred pred, MR_Pred handler_pred,
 		MR_Box *output);
-	void mercury__exception__builtin_catch_model_non(
+	MR_CALL void mercury__exception__builtin_catch_model_non(
 		MR_Mercury_Type_Info type_info, MR_Pred pred, MR_Pred handler_pred,
 		MR_Box *output,
 #ifdef MR_USE_GCC_NESTED_FUNCTIONS
@@ -600,7 +600,7 @@
 
 ML_ExceptionHandler *ML_exception_handler;
 
-void
+MR_CALL void
 mercury__exception__builtin_throw_1_p_0(MR_Univ exception)
 {
 	if (ML_exception_handler == NULL) {
@@ -616,7 +616,7 @@
 	}
 }
 
-void
+MR_CALL void
 mercury__exception__builtin_catch_model_det(MR_Mercury_Type_Info type_info,
 	MR_Pred pred, MR_Pred handler_pred, MR_Box *output)
 {
@@ -644,7 +644,7 @@
 	}
 }
 
-bool
+MR_CALL bool
 mercury__exception__builtin_catch_model_semi(MR_Mercury_Type_Info type_info,
 	MR_Pred pred, MR_Pred handler_pred, MR_Box *output)
 {
@@ -676,7 +676,7 @@
 
 #ifdef MR_USE_GCC_NESTED_FUNCTIONS
 
-void
+MR_CALL void
 mercury__exception__builtin_catch_model_non(MR_Mercury_Type_Info type_info,
 	MR_Pred pred, MR_Pred handler_pred, MR_Box *output,
 	MR_NestedCont cont)
@@ -756,7 +756,7 @@
 	ML_exception_handler = &env->this_handler;
 }
 
-void
+MR_CALL void
 mercury__exception__builtin_catch_model_non(MR_Mercury_Type_Info type_info,
 	MR_Pred pred, MR_Pred handler_pred, MR_Box *output,
 	MR_Cont cont, void *cont_env)
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
Index: runtime/mercury.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury.c,v
retrieving revision 1.16
diff -u -d -u -r1.16 mercury.c
--- runtime/mercury.c	2000/11/23 02:00:20	1.16
+++ runtime/mercury.c	2000/11/24 12:04:13
@@ -35,34 +35,36 @@
 
 /* Types for the wrapper versions of type-specific unify/compare procedures. */
 
-typedef bool MR_UnifyFunc_0(MR_Box, MR_Box);
-typedef bool MR_UnifyFunc_1(MR_Mercury_Type_Info, MR_Box, MR_Box);
-typedef bool MR_UnifyFunc_2(MR_Mercury_Type_Info, MR_Mercury_Type_Info,
+typedef MR_CALL bool MR_UnifyFunc_0(MR_Box, MR_Box);
+typedef MR_CALL bool MR_UnifyFunc_1(MR_Mercury_Type_Info, MR_Box, MR_Box);
+typedef MR_CALL bool MR_UnifyFunc_2(MR_Mercury_Type_Info, MR_Mercury_Type_Info,
 			    MR_Box, MR_Box);
-typedef bool MR_UnifyFunc_3(MR_Mercury_Type_Info, MR_Mercury_Type_Info,
+typedef MR_CALL bool MR_UnifyFunc_3(MR_Mercury_Type_Info, MR_Mercury_Type_Info,
 			    MR_Mercury_Type_Info, MR_Box, MR_Box);
-typedef bool MR_UnifyFunc_4(MR_Mercury_Type_Info, MR_Mercury_Type_Info,
+typedef MR_CALL bool MR_UnifyFunc_4(MR_Mercury_Type_Info, MR_Mercury_Type_Info,
 			    MR_Mercury_Type_Info, MR_Mercury_Type_Info,
 			    MR_Box, MR_Box);
-typedef bool MR_UnifyFunc_5(MR_Mercury_Type_Info, MR_Mercury_Type_Info,
+typedef MR_CALL bool MR_UnifyFunc_5(MR_Mercury_Type_Info, MR_Mercury_Type_Info,
 			    MR_Mercury_Type_Info, MR_Mercury_Type_Info,
 			    MR_Mercury_Type_Info, MR_Box, MR_Box);
 
-typedef void MR_CompareFunc_0(MR_Comparison_Result *, MR_Box, MR_Box);
-typedef void MR_CompareFunc_1(MR_Mercury_Type_Info,
-			      MR_Comparison_Result *, MR_Box, MR_Box);
-typedef void MR_CompareFunc_2(MR_Mercury_Type_Info, MR_Mercury_Type_Info,
-			      MR_Comparison_Result *, MR_Box, MR_Box);
-typedef void MR_CompareFunc_3(MR_Mercury_Type_Info, MR_Mercury_Type_Info,
-			      MR_Mercury_Type_Info,
-			      MR_Comparison_Result *, MR_Box, MR_Box);
-typedef void MR_CompareFunc_4(MR_Mercury_Type_Info, MR_Mercury_Type_Info,
-			      MR_Mercury_Type_Info, MR_Mercury_Type_Info,
-			      MR_Comparison_Result *, MR_Box, MR_Box);
-typedef void MR_CompareFunc_5(MR_Mercury_Type_Info, MR_Mercury_Type_Info,
-			      MR_Mercury_Type_Info, MR_Mercury_Type_Info,
-			      MR_Mercury_Type_Info,
-			      MR_Comparison_Result *, MR_Box, MR_Box);
+typedef MR_CALL void MR_CompareFunc_0(MR_Comparison_Result *, MR_Box, MR_Box);
+typedef MR_CALL void MR_CompareFunc_1(MR_Mercury_Type_Info,
+			MR_Comparison_Result *, MR_Box, MR_Box);
+typedef MR_CALL void MR_CompareFunc_2(MR_Mercury_Type_Info,
+			MR_Mercury_Type_Info, MR_Comparison_Result *,
+			MR_Box, MR_Box);
+typedef MR_CALL void MR_CompareFunc_3(MR_Mercury_Type_Info,
+			MR_Mercury_Type_Info, MR_Mercury_Type_Info,
+			MR_Comparison_Result *, MR_Box, MR_Box);
+typedef MR_CALL void MR_CompareFunc_4(MR_Mercury_Type_Info,
+			MR_Mercury_Type_Info, MR_Mercury_Type_Info,
+			MR_Mercury_Type_Info, MR_Comparison_Result *,
+			MR_Box, MR_Box);
+typedef MR_CALL void MR_CompareFunc_5(MR_Mercury_Type_Info,
+			MR_Mercury_Type_Info, MR_Mercury_Type_Info,
+			MR_Mercury_Type_Info, MR_Mercury_Type_Info,
+			MR_Comparison_Result *, MR_Box, MR_Box);
 
 /*---------------------------------------------------------------------------*/
 /*
@@ -202,7 +204,7 @@
 ** Define the generic unify/2 and compare/3 functions.
 */
 
-bool
+MR_CALL bool
 mercury__builtin__unify_2_p_0(MR_Mercury_Type_Info ti, MR_Box x, MR_Box y)
 {
 	MR_TypeInfo		type_info;
@@ -259,7 +261,7 @@
 	}
 }
 
-void
+MR_CALL void
 mercury__builtin__compare_3_p_0(MR_Mercury_Type_Info ti,
 	MR_Comparison_Result *res, MR_Box x, MR_Box y)
 {
@@ -324,21 +326,21 @@
 	}
 }
 
-void
+MR_CALL void
 mercury__builtin__compare_3_p_1(
 	MR_Mercury_Type_Info type_info, MR_Comparison_Result *res, MR_Box x, MR_Box y)
 {
 	mercury__builtin__compare_3_p_0(type_info, res, x, y);
 }
 
-void
+MR_CALL void
 mercury__builtin__compare_3_p_2(
 	MR_Mercury_Type_Info type_info, MR_Comparison_Result *res, MR_Box x, MR_Box y)
 {
 	mercury__builtin__compare_3_p_0(type_info, res, x, y);
 }
 
-void
+MR_CALL void
 mercury__builtin__compare_3_p_3(
 	MR_Mercury_Type_Info type_info, MR_Comparison_Result *res, MR_Box x, MR_Box y)
 {
@@ -364,56 +366,56 @@
 ** Unification procedures with the arguments unboxed.
 */
 
-bool
+MR_CALL bool
 mercury__builtin____Unify____int_0_0(MR_Integer x, MR_Integer y)
 {
 	return x == y;
 }
 
-bool
+MR_CALL bool
 mercury__builtin____Unify____string_0_0(MR_String x, MR_String y)
 {
 	return strcmp(x, y) == 0;
 }
 
-bool
+MR_CALL bool
 mercury__builtin____Unify____float_0_0(MR_Float x, MR_Float y)
 {
 	/* XXX what should this function do when x and y are both NaNs? */
 	return x == y;
 }
 
-bool
+MR_CALL bool
 mercury__builtin____Unify____character_0_0(MR_Char x, MR_Char y)
 {
 	return x == y;
 }
 
-bool
+MR_CALL bool
 mercury__builtin____Unify____void_0_0(MR_Void x, MR_Void y)
 {
 	MR_fatal_error("called unify for type `void'");
 }
 
-bool
+MR_CALL bool
 mercury__builtin____Unify____c_pointer_0_0(MR_C_Pointer x, MR_C_Pointer y)
 {
 	return (void *) x == (void *) y;
 }
 
-bool
+MR_CALL bool
 mercury__builtin____Unify____func_0_0(MR_Func x, MR_Func y)
 {
 	MR_fatal_error("called unify for `func' type");
 }
 
-bool
+MR_CALL bool
 mercury__builtin____Unify____pred_0_0(MR_Pred x, MR_Pred y)
 {
 	MR_fatal_error("called unify for `pred' type");
 }
 
-bool
+MR_CALL bool
 mercury__builtin____Unify____tuple_0_0(MR_Mercury_Type_Info ti,
 	MR_Tuple x, MR_Tuple y)
 {
@@ -438,7 +440,7 @@
 	return TRUE;
 }
 
-bool
+MR_CALL bool
 mercury__std_util____Unify____univ_0_0(MR_Univ x, MR_Univ y)
 {
 	MR_TypeInfo     typeinfo_x, typeinfo_y;
@@ -458,7 +460,7 @@
 			(MR_Box) value_x, (MR_Box) value_y);
 }
 
-bool
+MR_CALL bool
 mercury__std_util____Unify____type_desc_0_0(MR_Type_Desc x, MR_Type_Desc y)
 {
 	int             comp;
@@ -468,7 +470,7 @@
 	return (comp == MR_COMPARE_EQUAL);
 }
 
-bool
+MR_CALL bool
 mercury__private_builtin____Unify____type_ctor_info_1_0(
 	MR_Mercury_Type_Info type_info,
 	MR_Mercury_Type_Ctor_Info x, MR_Mercury_Type_Ctor_Info y)
@@ -476,7 +478,7 @@
 	SORRY("unify for type_ctor_info");
 }
 
-bool
+MR_CALL bool
 mercury__private_builtin____Unify____type_info_1_0(
 	MR_Mercury_Type_Info type_info,
 	MR_Mercury_Type_Info x, MR_Mercury_Type_Info y)
@@ -488,7 +490,7 @@
 	return (comp == MR_COMPARE_EQUAL);
 }
 
-bool
+MR_CALL bool
 mercury__private_builtin____Unify____typeclass_info_1_0(
 	MR_Mercury_Type_Info type_info,
 	MR_Mercury_TypeClass_Info x, MR_Mercury_TypeClass_Info y)
@@ -496,7 +498,7 @@
 	MR_fatal_error("attempt to unify typeclass_info");
 }
 
-bool
+MR_CALL bool
 mercury__private_builtin____Unify____base_typeclass_info_1_0(
 	MR_Mercury_Type_Info type_info,
 	MR_Mercury_Base_TypeClass_Info x, MR_Mercury_Base_TypeClass_Info y)
@@ -509,7 +511,7 @@
 ** Comparison procedures with the arguments unboxed.
 */
 
-void
+MR_CALL void
 mercury__builtin____Compare____int_0_0(
 	MR_Comparison_Result *result, MR_Integer x, MR_Integer y)
 {
@@ -518,7 +520,7 @@
 		  MR_COMPARE_LESS);
 }
 
-void
+MR_CALL void
 mercury__builtin____Compare____string_0_0(MR_Comparison_Result *result,
 	MR_String x, MR_String y)
 {
@@ -528,7 +530,7 @@
 		  MR_COMPARE_LESS);
 }
 
-void
+MR_CALL void
 mercury__builtin____Compare____float_0_0(
 	MR_Comparison_Result *result, MR_Float x, MR_Float y)
 {
@@ -540,7 +542,7 @@
 			  MR_COMPARE_EQUAL));
 }
 
-void
+MR_CALL void
 mercury__builtin____Compare____character_0_0(
 	MR_Comparison_Result *result, MR_Char x, MR_Char y)
 {
@@ -549,14 +551,14 @@
 		  MR_COMPARE_LESS);
 }
 
-void
+MR_CALL void
 mercury__builtin____Compare____void_0_0(MR_Comparison_Result *result,
 	MR_Void x, MR_Void y)
 {
 	MR_fatal_error("called compare/3 for type `void'");
 }
 
-void
+MR_CALL void
 mercury__builtin____Compare____c_pointer_0_0(
 	MR_Comparison_Result *result, MR_C_Pointer x, MR_C_Pointer y)
 {
@@ -567,21 +569,21 @@
 		);
 }
 
-void
+MR_CALL void
 mercury__builtin____Compare____func_0_0(MR_Comparison_Result *result,
 	MR_Func x, MR_Func y)
 {
 	MR_fatal_error("called compare/3 for `func' type");
 }
 
-void
+MR_CALL void
 mercury__builtin____Compare____pred_0_0(MR_Comparison_Result *result,
 	MR_Pred x, MR_Pred y)
 {
 	MR_fatal_error("called compare/3 for `pred' type");
 }
 
-void
+MR_CALL void
 mercury__builtin____Compare____tuple_0_0(MR_Mercury_Type_Info ti,
 	MR_Comparison_Result *result, MR_Tuple x, MR_Tuple y)
 {
@@ -605,7 +607,7 @@
 	*result = MR_COMPARE_EQUAL;
 }
 
-void
+MR_CALL void
 mercury__std_util____Compare____univ_0_0(MR_Comparison_Result *result,
 	MR_Univ x, MR_Univ y)
 {
@@ -627,7 +629,7 @@
 			result, (MR_Box) value_x, (MR_Box) value_y);
 }
 
-void
+MR_CALL void
 mercury__std_util____Compare____type_desc_0_0(
 	MR_Comparison_Result *result, MR_Type_Desc x, MR_Type_Desc y)
 {
@@ -637,7 +639,7 @@
 	*result = comp;
 }
 
-void
+MR_CALL void
 mercury__private_builtin____Compare____type_ctor_info_1_0(
 	MR_Mercury_Type_Info type_info, MR_Comparison_Result *result,
 	MR_Mercury_Type_Ctor_Info x, MR_Mercury_Type_Ctor_Info y)
@@ -645,7 +647,7 @@
 	SORRY("compare for type_ctor_info");
 }
 
-void
+MR_CALL void
 mercury__private_builtin____Compare____type_info_1_0(
 	MR_Mercury_Type_Info type_info, MR_Comparison_Result *result,
 	MR_Mercury_Type_Info x, MR_Mercury_Type_Info y)
@@ -656,7 +658,7 @@
 	*result = comp;
 }
 
-void
+MR_CALL void
 mercury__private_builtin____Compare____typeclass_info_1_0(
 	MR_Mercury_Type_Info type_info, MR_Comparison_Result *result,
 	MR_Mercury_TypeClass_Info x, MR_Mercury_TypeClass_Info y)
@@ -664,7 +666,7 @@
 	MR_fatal_error("attempt to compare typeclass_info");
 }
 
-void
+MR_CALL void
 mercury__private_builtin____Compare____base_typeclass_info_1_0(
 	MR_Mercury_Type_Info type_info, MR_Comparison_Result *result,
 	MR_Mercury_Base_TypeClass_Info x, MR_Mercury_Base_TypeClass_Info y)
@@ -678,60 +680,60 @@
 ** These are just wrappers which call the unboxed version.
 */
 
-static bool
+static MR_CALL bool
 mercury__builtin__do_unify__int_0_0(MR_Box x, MR_Box y)
 {
 	return mercury__builtin____Unify____int_0_0(
 		(MR_Integer) x, (MR_Integer) y);
 }
 
-static bool
+static MR_CALL bool
 mercury__builtin__do_unify__string_0_0(MR_Box x, MR_Box y)
 {
 	return mercury__builtin____Unify____string_0_0(
 		(MR_String) x, (MR_String) y);
 }
 
-static bool
+static MR_CALL bool
 mercury__builtin__do_unify__float_0_0(MR_Box x, MR_Box y)
 {
 	return mercury__builtin____Unify____float_0_0(
 		MR_unbox_float(x), MR_unbox_float(y));
 }
 
-static bool
+static MR_CALL bool
 mercury__builtin__do_unify__character_0_0(MR_Box x, MR_Box y)
 {
 	return mercury__builtin____Unify____character_0_0(
 		(MR_Char) (MR_Word) x, (MR_Char) (MR_Word) y);
 }
 
-static bool
+static MR_CALL bool
 mercury__builtin__do_unify__void_0_0(MR_Box x, MR_Box y)
 {
 	MR_fatal_error("called unify for type `void'");
 }
 
-static bool
+static MR_CALL bool
 mercury__builtin__do_unify__c_pointer_0_0(MR_Box x, MR_Box y)
 {
 	return mercury__builtin____Unify____c_pointer_0_0(
 		(MR_C_Pointer) x, (MR_C_Pointer) y);
 }
 
-static bool
+static MR_CALL bool
 mercury__builtin__do_unify__func_0_0(MR_Box x, MR_Box y)
 {
 	MR_fatal_error("called unify for `func' type");
 }
 
-static bool
+static MR_CALL bool
 mercury__builtin__do_unify__pred_0_0(MR_Box x, MR_Box y)
 {
 	MR_fatal_error("called unify for `pred' type");
 }
 
-static bool
+static MR_CALL bool
 mercury__builtin__do_unify__tuple_0_0(MR_Mercury_Type_Info type_info,
 		MR_Box x, MR_Box y)
 {
@@ -739,7 +741,7 @@
 		type_info, (MR_Tuple) x, (MR_Tuple) y);
 }
 
-static bool
+static MR_CALL bool
 mercury__array__do_unify__array_1_0(MR_Mercury_Type_Info type_info,
 	MR_Box x, MR_Box y)
 {
@@ -747,21 +749,21 @@
 		type_info, (MR_Array) x, (MR_Array) y);
 }
 
-static bool
+static MR_CALL bool
 mercury__std_util__do_unify__univ_0_0(MR_Box x, MR_Box y)
 {
 	return mercury__std_util____Unify____univ_0_0(
 		(MR_Univ) x, (MR_Univ) y);
 }
 
-static bool
+static MR_CALL bool
 mercury__std_util__do_unify__type_desc_0_0(MR_Box x, MR_Box y)
 {
 	return mercury__std_util____Unify____type_desc_0_0(
 		(MR_Type_Desc) x, (MR_Type_Desc) y);
 }
 
-static bool
+static MR_CALL bool
 mercury__private_builtin__do_unify__type_ctor_info_1_0(
 	MR_Mercury_Type_Info type_info, MR_Box x, MR_Box y)
 {
@@ -769,7 +771,7 @@
 		type_info, (MR_Mercury_Type_Ctor_Info) x, (MR_Mercury_Type_Ctor_Info) y);
 }
 
-static bool
+static MR_CALL bool
 mercury__private_builtin__do_unify__type_info_1_0(
 	MR_Mercury_Type_Info type_info, MR_Box x, MR_Box y)
 {
@@ -777,7 +779,7 @@
 		type_info, (MR_Mercury_Type_Info) x, (MR_Mercury_Type_Info) y);
 }
 
-static bool
+static MR_CALL bool
 mercury__private_builtin__do_unify__typeclass_info_1_0(
 	MR_Mercury_Type_Info type_info, MR_Box x, MR_Box y)
 {
@@ -785,7 +787,7 @@
 		type_info, (MR_Mercury_TypeClass_Info) x, (MR_Mercury_TypeClass_Info) y);
 }
 
-static bool
+static MR_CALL bool
 mercury__private_builtin__do_unify__base_typeclass_info_1_0(
 	MR_Mercury_Type_Info type_info, MR_Box x, MR_Box y)
 {
@@ -801,7 +803,7 @@
 ** These are just wrappers which call the unboxed version.
 */
 
-static void
+static MR_CALL void
 mercury__builtin__do_compare__int_0_0(
 	MR_Comparison_Result *result, MR_Box x, MR_Box y)
 {
@@ -809,7 +811,7 @@
 		(MR_Integer) x, (MR_Integer) y);
 }
 
-static void
+static MR_CALL void
 mercury__builtin__do_compare__string_0_0(
 	MR_Comparison_Result *result, MR_Box x, MR_Box y)
 {
@@ -817,7 +819,7 @@
 		(MR_String) x, (MR_String) y);
 }
 
-static void
+static MR_CALL void
 mercury__builtin__do_compare__float_0_0(
 	MR_Comparison_Result *result, MR_Box x, MR_Box y)
 {
@@ -825,7 +827,7 @@
 		MR_unbox_float(x), MR_unbox_float(y));
 }
 
-static void
+static MR_CALL void
 mercury__builtin__do_compare__character_0_0(
 	MR_Comparison_Result *result, MR_Box x, MR_Box y)
 {
@@ -833,14 +835,14 @@
 		result, (MR_Char) (MR_Word) x, (MR_Char) (MR_Word) y);
 }
 
-static void
+static MR_CALL void
 mercury__builtin__do_compare__void_0_0(
 	MR_Comparison_Result *result, MR_Box x, MR_Box y)
 {
 	MR_fatal_error("called compare/3 for type `void'");
 }
 
-static void
+static MR_CALL void
 mercury__builtin__do_compare__c_pointer_0_0(
 	MR_Comparison_Result *result, MR_Box x, MR_Box y)
 {
@@ -848,21 +850,21 @@
 		result, (MR_C_Pointer) x, (MR_C_Pointer) y);
 }
 
-static void
+static MR_CALL void
 mercury__builtin__do_compare__func_0_0(
 	MR_Comparison_Result *result, MR_Box x, MR_Box y)
 {
 	MR_fatal_error("called compare/3 for func type");
 }
 
-static void
+static MR_CALL void
 mercury__builtin__do_compare__pred_0_0(MR_Comparison_Result *result,
 	MR_Box x, MR_Box y)
 {
 	MR_fatal_error("called compare/3 for pred type");
 }
 
-static void
+static MR_CALL void
 mercury__builtin__do_compare__tuple_0_0(
 	MR_Mercury_Type_Info type_info, MR_Comparison_Result *result,
 	MR_Box x, MR_Box y)
@@ -871,7 +873,7 @@
 		type_info, result, (MR_Tuple) x, (MR_Tuple) y);
 }
 
-static void
+static MR_CALL void
 mercury__array__do_compare__array_1_0(
 	MR_Mercury_Type_Info type_info, MR_Comparison_Result *result,
 	MR_Box x, MR_Box y)
@@ -880,7 +882,7 @@
 		type_info, result, (MR_Array) x, (MR_Array) y);
 }
 
-static void
+static MR_CALL void
 mercury__std_util__do_compare__univ_0_0(
 	MR_Comparison_Result *result, MR_Box x, MR_Box y)
 {
@@ -888,7 +890,7 @@
 		result, (MR_Univ) x, (MR_Univ) y);
 }
 
-static void
+static MR_CALL void
 mercury__std_util__do_compare__type_desc_0_0(
 	MR_Comparison_Result *result, MR_Box x, MR_Box y)
 {
@@ -896,7 +898,7 @@
 		result, (MR_Type_Desc) x, (MR_Type_Desc) y);
 }
 
-static void
+static MR_CALL void
 mercury__private_builtin__do_compare__type_ctor_info_1_0(
 	MR_Mercury_Type_Info type_info, MR_Comparison_Result *result,
 	MR_Box x, MR_Box y)
@@ -906,7 +908,7 @@
 		(MR_Mercury_Type_Ctor_Info) x, (MR_Mercury_Type_Ctor_Info) y);
 }
 
-static void
+static MR_CALL void
 mercury__private_builtin__do_compare__type_info_1_0(
 	MR_Mercury_Type_Info type_info, MR_Comparison_Result *result,
 	MR_Box x, MR_Box y)
@@ -915,7 +917,7 @@
 		type_info, result, (MR_Mercury_Type_Info) x, (MR_Mercury_Type_Info) y);
 }
 
-static void
+static MR_CALL void
 mercury__private_builtin__do_compare__typeclass_info_1_0(
 	MR_Mercury_Type_Info type_info, MR_Comparison_Result *result,
 	MR_Box x, MR_Box y)
@@ -925,7 +927,7 @@
 		(MR_Mercury_TypeClass_Info) x, (MR_Mercury_TypeClass_Info) y);
 }
 
-static void
+static MR_CALL void
 mercury__private_builtin__do_compare__base_typeclass_info_1_0(
 	MR_Mercury_Type_Info type_info, MR_Comparison_Result *result,
 	MR_Box x, MR_Box y)
Index: runtime/mercury.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury.h,v
retrieving revision 1.25
diff -u -d -u -r1.25 mercury.h
--- runtime/mercury.h	2000/11/06 10:43:40	1.25
+++ runtime/mercury.h	2000/11/24 04:10:49
@@ -360,79 +360,81 @@
 ** Function declarations
 */
 
-bool mercury__builtin__unify_2_p_0(MR_Mercury_Type_Info, MR_Box, MR_Box);
-void mercury__builtin__compare_3_p_0(MR_Mercury_Type_Info,
+MR_CALL bool mercury__builtin__unify_2_p_0(MR_Mercury_Type_Info,
+	MR_Box, MR_Box);
+MR_CALL void mercury__builtin__compare_3_p_0(MR_Mercury_Type_Info,
 	MR_Comparison_Result *, MR_Box, MR_Box);
-void mercury__builtin__compare_3_p_1(MR_Mercury_Type_Info,
+MR_CALL void mercury__builtin__compare_3_p_1(MR_Mercury_Type_Info,
 	MR_Comparison_Result *, MR_Box, MR_Box);
-void mercury__builtin__compare_3_p_2(MR_Mercury_Type_Info,
+MR_CALL void mercury__builtin__compare_3_p_2(MR_Mercury_Type_Info,
 	MR_Comparison_Result *, MR_Box, MR_Box);
-void mercury__builtin__compare_3_p_3(MR_Mercury_Type_Info,
+MR_CALL void mercury__builtin__compare_3_p_3(MR_Mercury_Type_Info,
 	MR_Comparison_Result *, MR_Box, MR_Box);
 
-bool mercury__builtin____Unify____int_0_0(MR_Integer x, MR_Integer y); 
-bool mercury__builtin____Unify____string_0_0(MR_String x, MR_String y); 
-bool mercury__builtin____Unify____float_0_0(MR_Float x, MR_Float y); 
-bool mercury__builtin____Unify____character_0_0(MR_Char x, MR_Char); 
-bool mercury__builtin____Unify____void_0_0(MR_Void x, MR_Void y); 
-bool mercury__builtin____Unify____c_pointer_0_0(
+MR_CALL bool mercury__builtin____Unify____int_0_0(MR_Integer x, MR_Integer y); 
+MR_CALL bool mercury__builtin____Unify____string_0_0(MR_String x, MR_String y); 
+MR_CALL bool mercury__builtin____Unify____float_0_0(MR_Float x, MR_Float y); 
+MR_CALL bool mercury__builtin____Unify____character_0_0(MR_Char x, MR_Char); 
+MR_CALL bool mercury__builtin____Unify____void_0_0(MR_Void x, MR_Void y); 
+MR_CALL bool mercury__builtin____Unify____c_pointer_0_0(
 	MR_C_Pointer x, MR_C_Pointer y); 
-bool mercury__builtin____Unify____func_0_0(MR_Func x, MR_Func y); 
-bool mercury__builtin____Unify____pred_0_0(MR_Pred x, MR_Pred y); 
-bool mercury__builtin____Unify____tuple_0_0(MR_Mercury_Type_Info type_info,
-	MR_Tuple x, MR_Tuple y); 
-bool mercury__array____Unify____array_1_0(MR_Mercury_Type_Info type_info,
-	MR_Array x, MR_Array y);
-bool mercury__std_util____Unify____univ_0_0(MR_Univ x, MR_Univ y); 
-bool mercury__std_util____Unify____type_desc_0_0(
+MR_CALL bool mercury__builtin____Unify____func_0_0(MR_Func x, MR_Func y); 
+MR_CALL bool mercury__builtin____Unify____pred_0_0(MR_Pred x, MR_Pred y); 
+MR_CALL bool mercury__builtin____Unify____tuple_0_0(
+	MR_Mercury_Type_Info type_info, MR_Tuple x, MR_Tuple y); 
+MR_CALL bool mercury__array____Unify____array_1_0(
+	MR_Mercury_Type_Info type_info, MR_Array x, MR_Array y);
+MR_CALL bool mercury__std_util____Unify____univ_0_0(MR_Univ x, MR_Univ y); 
+MR_CALL bool mercury__std_util____Unify____type_desc_0_0(
 	MR_Type_Desc x, MR_Type_Desc y); 
-bool mercury__private_builtin____Unify____type_ctor_info_1_0(
+MR_CALL bool mercury__private_builtin____Unify____type_ctor_info_1_0(
 	MR_Mercury_Type_Info type_info,
 	MR_Mercury_Type_Ctor_Info x, MR_Mercury_Type_Ctor_Info y); 
-bool mercury__private_builtin____Unify____type_info_1_0(
+MR_CALL bool mercury__private_builtin____Unify____type_info_1_0(
 	MR_Mercury_Type_Info type_info,
 	MR_Mercury_Type_Info x, MR_Mercury_Type_Info y); 
-bool mercury__private_builtin____Unify____typeclass_info_1_0(
+MR_CALL bool mercury__private_builtin____Unify____typeclass_info_1_0(
 	MR_Mercury_Type_Info type_info,
 	MR_Mercury_TypeClass_Info x, MR_Mercury_TypeClass_Info y); 
-bool mercury__private_builtin____Unify____base_typeclass_info_1_0(
+MR_CALL bool mercury__private_builtin____Unify____base_typeclass_info_1_0(
 	MR_Mercury_Type_Info type_info, MR_Mercury_Base_TypeClass_Info x,
 	MR_Mercury_Base_TypeClass_Info y); 
 
-void mercury__builtin____Compare____int_0_0(
+MR_CALL void mercury__builtin____Compare____int_0_0(
 	MR_Comparison_Result *result, MR_Integer x, MR_Integer y);
-void mercury__builtin____Compare____string_0_0(
+MR_CALL void mercury__builtin____Compare____string_0_0(
 	MR_Comparison_Result *result, MR_String x, MR_String y);
-void mercury__builtin____Compare____float_0_0(
+MR_CALL void mercury__builtin____Compare____float_0_0(
 	MR_Comparison_Result *result, MR_Float x, MR_Float y);
-void mercury__builtin____Compare____character_0_0(
+MR_CALL void mercury__builtin____Compare____character_0_0(
 	MR_Comparison_Result *result, MR_Char x, MR_Char y);
-void mercury__builtin____Compare____void_0_0(
+MR_CALL void mercury__builtin____Compare____void_0_0(
 	MR_Comparison_Result *result, MR_Void x, MR_Void y);
-void mercury__builtin____Compare____c_pointer_0_0(
+MR_CALL void mercury__builtin____Compare____c_pointer_0_0(
 	MR_Comparison_Result *result, MR_C_Pointer x, MR_C_Pointer y);
-void mercury__builtin____Compare____func_0_0(
+MR_CALL void mercury__builtin____Compare____func_0_0(
 	MR_Comparison_Result *result, MR_Func x, MR_Func y);
-void mercury__builtin____Compare____pred_0_0(
+MR_CALL void mercury__builtin____Compare____pred_0_0(
 	MR_Comparison_Result *result, MR_Pred x, MR_Pred y); 
-void mercury__builtin____Compare____tuple_0_0(MR_Mercury_Type_Info type_info,
-	MR_Comparison_Result *result, MR_Tuple x, MR_Tuple y); 
-void mercury__array____Compare____array_1_0(MR_Mercury_Type_Info type_info,
-	MR_Comparison_Result *result, MR_Array x, MR_Array y);
-void mercury__std_util____Compare____univ_0_0(
+MR_CALL void mercury__builtin____Compare____tuple_0_0(
+	MR_Mercury_Type_Info type_info, MR_Comparison_Result *result,
+	MR_Tuple x, MR_Tuple y); 
+MR_CALL void mercury__array____Compare____array_1_0(MR_Mercury_Type_Info
+	type_info, MR_Comparison_Result *result, MR_Array x, MR_Array y);
+MR_CALL void mercury__std_util____Compare____univ_0_0(
 	MR_Comparison_Result *result, MR_Univ x, MR_Univ y);
-void mercury__std_util____Compare____type_desc_0_0(
+MR_CALL void mercury__std_util____Compare____type_desc_0_0(
 	MR_Comparison_Result *result, MR_Type_Desc x, MR_Type_Desc y);
-void mercury__private_builtin____Compare____type_ctor_info_1_0(
+MR_CALL void mercury__private_builtin____Compare____type_ctor_info_1_0(
 	MR_Mercury_Type_Info type_info, MR_Comparison_Result *result,
 	MR_Mercury_Type_Ctor_Info x, MR_Mercury_Type_Ctor_Info y);
-void mercury__private_builtin____Compare____type_info_1_0(
+MR_CALL void mercury__private_builtin____Compare____type_info_1_0(
 	MR_Mercury_Type_Info type_info, MR_Comparison_Result *result,
 	MR_Mercury_Type_Info x, MR_Mercury_Type_Info y);
-void mercury__private_builtin____Compare____typeclass_info_1_0(
+MR_CALL void mercury__private_builtin____Compare____typeclass_info_1_0(
 	MR_Mercury_Type_Info type_info, MR_Comparison_Result *result,
 	MR_Mercury_TypeClass_Info x, MR_Mercury_TypeClass_Info y);
-void mercury__private_builtin____Compare____base_typeclass_info_1_0(
+MR_CALL void mercury__private_builtin____Compare____base_typeclass_info_1_0(
 	MR_Mercury_Type_Info type_info, MR_Comparison_Result *result,
 	MR_Mercury_Base_TypeClass_Info x, MR_Mercury_Base_TypeClass_Info y);
 
Index: runtime/mercury_types.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_types.h,v
retrieving revision 1.23
diff -u -d -u -r1.23 mercury_types.h
--- runtime/mercury_types.h	2000/11/23 02:00:49	1.23
+++ runtime/mercury_types.h	2000/11/24 12:00:42
@@ -92,9 +92,22 @@
 typedef MR_Char *MR_String;
 typedef const MR_Char *MR_ConstString;
 
+/*
+** If MR_USE_REGPARM is defined, and we're using gcc on x86,
+** then for the MLDS back-end we use a non-standard but more efficient
+** calling convention for the C functions that we generate.
+*/
+#ifndef MR_CALL
+  #if defined(MR_USE_REGPARM) && defined(__GNUC__) && defined(__i386)
+    #define MR_CALL __attribute__((__regparm__(2)))
+  #else
+    #define MR_CALL
+  #endif
+#endif
+
 /* continuation function type, for --high-level-code option */
-typedef void (*MR_NestedCont) (void);	/* for --gcc-nested-functions */
-typedef void (*MR_Cont) (void *);	/* for --no-gcc-nested-functions */
+typedef MR_CALL void (*MR_NestedCont) (void); /* for --gcc-nested-functions */
+typedef MR_CALL void (*MR_Cont) (void *); /* for --no-gcc-nested-functions */
 
 #ifndef MR_HIGHLEVEL_CODE
   /*
Index: runtime/mercury_wrapper.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_wrapper.c,v
retrieving revision 1.78
diff -u -d -u -r1.78 mercury_wrapper.c
--- runtime/mercury_wrapper.c	2000/11/23 02:00:50	1.78
+++ runtime/mercury_wrapper.c	2000/11/24 03:44:50
@@ -185,7 +185,7 @@
 #endif
 
 #ifdef MR_HIGHLEVEL_CODE
-void	(*MR_program_entry_point)(void);
+MR_CALL void (*MR_program_entry_point)(void);
 		/* normally main_2_p_0 (main/2) */
 #else
 MR_Code	*MR_program_entry_point;
Index: runtime/mercury_wrapper.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_wrapper.h,v
retrieving revision 1.38
diff -u -d -u -r1.38 mercury_wrapper.h
--- runtime/mercury_wrapper.h	2000/11/23 02:00:51	1.38
+++ runtime/mercury_wrapper.h	2000/11/24 03:44:23
@@ -65,7 +65,7 @@
 */
 
 #ifdef MR_HIGHLEVEL_CODE
-extern	void		(*MR_program_entry_point)(void);
+extern	MR_CALL void	(*MR_program_entry_point)(void);
 			/* normally main_2_p_0 */
 #else
 extern	MR_Code 	*MR_program_entry_point;
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
cvs diff: Diffing trial
cvs diff: Diffing util
Index: util/mkinit.c
===================================================================
RCS file: /home/mercury1/repository/mercury/util/mkinit.c,v
retrieving revision 1.71
diff -u -d -u -r1.71 mkinit.c
--- util/mkinit.c	2000/11/23 06:33:25	1.71
+++ util/mkinit.c	2000/11/24 03:44:16
@@ -117,7 +117,7 @@
 	"#define MR_TRACE_ENABLED %d\n"
 	"\n"
 	"#ifdef MR_HIGHLEVEL_CODE\n"
-	"  extern void %s(void);\n"
+	"  extern MR_CALL void %s(void);\n"
 	"#else\n"
 	"  MR_declare_entry(%s);\n"
 	"#endif\n"
-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
                                    |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------



More information about the developers mailing list