[m-dev.] for review: use gcc's regparm attribute (was: fastcall for the x86)

Fergus Henderson fjh at cs.mu.OZ.AU
Sun Nov 26 12:31:49 AEDT 2000


Pete, could you please review this one?

This version bootstraps with the gcc 2.97 20001124 snapshot.
I've also changed it so that it puts `MR_CALL' after the
return type, for MSVC.  (This makes the relative diff huge,
I'm afraid, so I'm only posting a new complete diff.)
I've also cleaned up a few rough edges (e.g. including the calling
convention in the mangled grade).

----------

Estimated hours taken: 16

Add support for using a different C calling convention for the
C functions generated by the MLDS back-end, if you're on x86
and you define MR_USE_REGPARM.  The code do to this uses GNU C's
function attributes extension; it will only work if you have
the latest snapshot versions of gcc.  So MR_USE_REGPARM is
not enabled by default.

compiler/ml_call_gen.m:
	For higher-order calls and class method calls, assign the
	function pointer to a local variable.  This is needed for
	current versions of gcc, since gcc doesn't support function
	attributes on function types in function pointer type casts.

compiler/mlds_to_c.m:
	Output "MR_CALL" in function declarations
	and function pointer types.

runtime/mercury_std.h:
	Define MR_CALL.  This is a macro that can expand to some
	implementation-specific C extension to specify the
	calling convention used for the MLDS back-end.
	E.g. for gcc, on x86, if MR_USE_REGPARM is defined it
	expands to `__attribute__((__regparm__(3), __stdcall__))'.

runtime/mercury_conf_param.h:
	Document MR_USE_REGPARM.

runtime/mercury_grade.h:
	Encode the setting of MR_USE_REGPARM in the mangled grade name.

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.

Workspace: /home/pgrad/fjh/ws/hg3
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 -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 -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/25 16:49:01
@@ -599,7 +599,11 @@
 		ml_pragma_export(C_name, _MLDS_Name, Signature, Context)) -->
 	{ Name = qual(ModuleName, export(C_name)) },
 	mlds_indent(Context, Indent),
-	mlds_output_func_decl_ho(Indent, Name, Context, Signature,
+	% For functions exported using `pragma export',
+	% we use the default C calling convention.
+	{ CallingConvention = "" },
+	mlds_output_func_decl_ho(Indent, Name, Context,
+			CallingConvention, Signature,
 			mlds_output_pragma_export_type(prefix),
 			mlds_output_pragma_export_type(suffix)).
 
@@ -696,9 +700,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,16 +1232,19 @@
 :- mode mlds_output_func_decl(in, in, in, in, di, uo) is det.
 
 mlds_output_func_decl(Indent, QualifiedName, Context, Signature) -->
-	mlds_output_func_decl_ho(Indent, QualifiedName, Context, Signature,
+	{ CallingConvention = "MR_CALL " },
+	mlds_output_func_decl_ho(Indent, QualifiedName, Context, 
+			CallingConvention, Signature,
 			mlds_output_type_prefix, mlds_output_type_suffix).
 
 :- pred mlds_output_func_decl_ho(indent, qualified_entity_name, mlds__context,
-		func_params, output_type, output_type, io__state, io__state).
-:- mode mlds_output_func_decl_ho(in, in, in, in, in(output_type),
+		string, func_params, output_type, output_type,
+		io__state, io__state).
+:- mode mlds_output_func_decl_ho(in, in, in, in, in, in(output_type),
 		in(output_type), di, uo) is det.
 
-mlds_output_func_decl_ho(Indent, QualifiedName, Context, Signature,
-		OutputPrefix, OutputSuffix) -->
+mlds_output_func_decl_ho(Indent, QualifiedName, Context,
+		CallingConvention, Signature, OutputPrefix, OutputSuffix) -->
 	{ Signature = mlds__func_params(Parameters, RetTypes) },
 	( { RetTypes = [] } ->
 		io__write_string("void")
@@ -1250,6 +1255,7 @@
 		% { error("mlds_output_func: multiple return types") }
 	),
 	io__write_char(' '),
+	io__write_string(CallingConvention),
 	mlds_output_fully_qualified_name(QualifiedName),
 	{ QualifiedName = qual(ModuleName, _) },
 	mlds_output_params(OutputPrefix, OutputSuffix,
@@ -1307,7 +1313,7 @@
 	% Note that mlds__func_type actually corresponds to a
 	% function _pointer_ type in C.  This is necessary because
 	% function types in C are not first class.
-	io__write_string(" (*").
+	io__write_string(" MR_CALL (*").
 
 :- pred mlds_output_func_type_suffix(func_params, io__state, io__state).
 :- mode mlds_output_func_type_suffix(in, di, uo) is det.
@@ -1573,7 +1579,7 @@
 		)
 	;
 		% This case only happens for --nondet-copy-out
-		io__write_string("void (*")
+		io__write_string("void MR_CALL (*")
 	).
 mlds_output_type_prefix(mlds__commit_type) -->
 	globals__io_lookup_bool_option(gcc_local_labels, GCC_LocalLabels),
@@ -2397,9 +2403,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 +2416,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 +2577,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,10 +2716,16 @@
 :- mode mlds_output_cast_rval(in, in, di, uo) is det.
 	
 mlds_output_cast_rval(Type, Exprn) -->
+	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),
-	io__write_string(") "),
-	mlds_output_rval(Exprn).
+	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 +2770,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(")")
 	).
Index: library/array.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/array.m,v
retrieving revision 1.78
diff -u -d -r1.78 array.m
--- library/array.m	2000/11/23 01:59:51	1.78
+++ library/array.m	2000/11/25 15:25:53
@@ -331,14 +331,14 @@
 	return;
 }
 
-bool
+bool MR_CALL
 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
+void MR_CALL
 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 -r1.44 builtin.m
--- library/builtin.m	2000/11/23 01:59:53	1.44
+++ library/builtin.m	2000/11/25 15:26:07
@@ -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 *);
+  void MR_CALL mercury__builtin__copy_2_p_0(MR_Mercury_Type_Info, MR_Box, MR_Box *);
+  void MR_CALL mercury__builtin__copy_2_p_1(MR_Mercury_Type_Info, MR_Box, MR_Box *);
 #endif
 ").
 
@@ -407,7 +407,7 @@
 
 #ifdef MR_HIGHLEVEL_CODE
 
-void
+void MR_CALL
 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
+void MR_CALL
 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.35
diff -u -d -r1.35 exception.m
--- library/exception.m	2000/11/25 10:41:58	1.35
+++ library/exception.m	2000/11/26 00:56:34
@@ -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);
+	void MR_CALL 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(
+	void MR_CALL mercury__exception__builtin_throw_1_p_0(MR_Univ exception);
+	void MR_CALL 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(
+	bool MR_CALL 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(
+	void MR_CALL 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
@@ -533,7 +533,7 @@
 ML_call_goal_det(MR_Mercury_Type_Info type_info,
 	MR_Pred closure, MR_Box *result)
 {
-	typedef void DetFuncType(void *, MR_Box *);
+	typedef void MR_CALL DetFuncType(void *, MR_Box *);
 	DetFuncType *code = (DetFuncType *)
 		MR_field(MR_mktag(0), closure, (MR_Integer) 1);
 	(*code)((void *) closure, result);
@@ -543,7 +543,7 @@
 ML_call_goal_semi(MR_Mercury_Type_Info type_info,
 	MR_Pred closure, MR_Box *result)
 {
-	typedef bool SemidetFuncType(void *, MR_Box *);
+	typedef bool MR_CALL SemidetFuncType(void *, MR_Box *);
 	SemidetFuncType *code = (SemidetFuncType *)
 		MR_field(MR_mktag(0), closure, (MR_Integer) 1);
 	return (*code)((void *) closure, result);
@@ -555,7 +555,7 @@
 ML_call_goal_non(MR_Mercury_Type_Info type_info,
 	MR_Pred closure, MR_Box *result, MR_NestedCont cont)
 {
-	typedef void NondetFuncType(void *, MR_Box *, MR_NestedCont);
+	typedef void MR_CALL NondetFuncType(void *, MR_Box *, MR_NestedCont);
 	NondetFuncType *code = (NondetFuncType *)
 		MR_field(MR_mktag(0), closure, (MR_Integer) 1);
 	(*code)((void *) closure, result, cont);
@@ -567,7 +567,7 @@
 ML_call_goal_non(MR_Mercury_Type_Info type_info,
 	MR_Pred closure, MR_Box *result, MR_Cont cont, void *cont_env)
 {
-	typedef void NondetFuncType(void *, MR_Box *, MR_Cont, void *);
+	typedef void MR_CALL NondetFuncType(void *, MR_Box *, MR_Cont, void *);
 	NondetFuncType *code = (NondetFuncType *)
 		MR_field(MR_mktag(0), closure, (MR_Integer) 1);
 	(*code)((void *) closure, result, cont, cont_env);
@@ -581,7 +581,7 @@
 ML_call_handler_det(MR_Mercury_Type_Info type_info,
 	MR_Pred closure, MR_Univ exception, MR_Box *result)
 {
-	typedef void HandlerFuncType(void *, MR_Box, MR_Box *);
+	typedef void MR_CALL HandlerFuncType(void *, MR_Box, MR_Box *);
 	HandlerFuncType *code = (HandlerFuncType *)
 		MR_field(MR_mktag(0), closure, (MR_Integer) 1);
 	(*code)((void *) closure, (MR_Box) exception, result);
@@ -600,7 +600,7 @@
 
 ML_ExceptionHandler *ML_exception_handler;
 
-void
+void MR_CALL
 mercury__exception__builtin_throw_1_p_0(MR_Univ exception)
 {
 	if (ML_exception_handler == NULL) {
@@ -616,7 +616,7 @@
 	}
 }
 
-void
+void MR_CALL
 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
+bool MR_CALL
 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
+void MR_CALL
 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
+void MR_CALL
 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)
Index: runtime/mercury.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury.c,v
retrieving revision 1.16
diff -u -d -r1.16 mercury.c
--- runtime/mercury.c	2000/11/23 02:00:20	1.16
+++ runtime/mercury.c	2000/11/25 15:28:01
@@ -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 bool MR_CALL MR_UnifyFunc_0(MR_Box, MR_Box);
+typedef bool MR_CALL MR_UnifyFunc_1(MR_Mercury_Type_Info, MR_Box, MR_Box);
+typedef bool MR_CALL 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 bool MR_CALL 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 bool MR_CALL 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 bool MR_CALL 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 void MR_CALL MR_CompareFunc_0(MR_Comparison_Result *, MR_Box, MR_Box);
+typedef void MR_CALL MR_CompareFunc_1(MR_Mercury_Type_Info,
+			MR_Comparison_Result *, MR_Box, MR_Box);
+typedef void MR_CALL MR_CompareFunc_2(MR_Mercury_Type_Info,
+			MR_Mercury_Type_Info, MR_Comparison_Result *,
+			MR_Box, MR_Box);
+typedef void MR_CALL 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_CALL 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_CALL 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
+bool MR_CALL
 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
+void MR_CALL
 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
+void MR_CALL
 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
+void MR_CALL
 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
+void MR_CALL
 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
+bool MR_CALL
 mercury__builtin____Unify____int_0_0(MR_Integer x, MR_Integer y)
 {
 	return x == y;
 }
 
-bool
+bool MR_CALL
 mercury__builtin____Unify____string_0_0(MR_String x, MR_String y)
 {
 	return strcmp(x, y) == 0;
 }
 
-bool
+bool MR_CALL
 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
+bool MR_CALL
 mercury__builtin____Unify____character_0_0(MR_Char x, MR_Char y)
 {
 	return x == y;
 }
 
-bool
+bool MR_CALL
 mercury__builtin____Unify____void_0_0(MR_Void x, MR_Void y)
 {
 	MR_fatal_error("called unify for type `void'");
 }
 
-bool
+bool MR_CALL
 mercury__builtin____Unify____c_pointer_0_0(MR_C_Pointer x, MR_C_Pointer y)
 {
 	return (void *) x == (void *) y;
 }
 
-bool
+bool MR_CALL
 mercury__builtin____Unify____func_0_0(MR_Func x, MR_Func y)
 {
 	MR_fatal_error("called unify for `func' type");
 }
 
-bool
+bool MR_CALL
 mercury__builtin____Unify____pred_0_0(MR_Pred x, MR_Pred y)
 {
 	MR_fatal_error("called unify for `pred' type");
 }
 
-bool
+bool MR_CALL
 mercury__builtin____Unify____tuple_0_0(MR_Mercury_Type_Info ti,
 	MR_Tuple x, MR_Tuple y)
 {
@@ -438,7 +440,7 @@
 	return TRUE;
 }
 
-bool
+bool MR_CALL
 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
+bool MR_CALL
 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
+bool MR_CALL
 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
+bool MR_CALL
 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
+bool MR_CALL
 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
+bool MR_CALL
 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
+void MR_CALL
 mercury__builtin____Compare____int_0_0(
 	MR_Comparison_Result *result, MR_Integer x, MR_Integer y)
 {
@@ -518,7 +520,7 @@
 		  MR_COMPARE_LESS);
 }
 
-void
+void MR_CALL
 mercury__builtin____Compare____string_0_0(MR_Comparison_Result *result,
 	MR_String x, MR_String y)
 {
@@ -528,7 +530,7 @@
 		  MR_COMPARE_LESS);
 }
 
-void
+void MR_CALL
 mercury__builtin____Compare____float_0_0(
 	MR_Comparison_Result *result, MR_Float x, MR_Float y)
 {
@@ -540,7 +542,7 @@
 			  MR_COMPARE_EQUAL));
 }
 
-void
+void MR_CALL
 mercury__builtin____Compare____character_0_0(
 	MR_Comparison_Result *result, MR_Char x, MR_Char y)
 {
@@ -549,14 +551,14 @@
 		  MR_COMPARE_LESS);
 }
 
-void
+void MR_CALL
 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
+void MR_CALL
 mercury__builtin____Compare____c_pointer_0_0(
 	MR_Comparison_Result *result, MR_C_Pointer x, MR_C_Pointer y)
 {
@@ -567,21 +569,21 @@
 		);
 }
 
-void
+void MR_CALL
 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
+void MR_CALL
 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
+void MR_CALL
 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
+void MR_CALL
 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
+void MR_CALL
 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
+void MR_CALL
 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
+void MR_CALL
 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
+void MR_CALL
 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
+void MR_CALL
 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 bool MR_CALL
 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 bool MR_CALL
 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 bool MR_CALL
 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 bool MR_CALL
 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 bool MR_CALL
 mercury__builtin__do_unify__void_0_0(MR_Box x, MR_Box y)
 {
 	MR_fatal_error("called unify for type `void'");
 }
 
-static bool
+static bool MR_CALL
 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 bool MR_CALL
 mercury__builtin__do_unify__func_0_0(MR_Box x, MR_Box y)
 {
 	MR_fatal_error("called unify for `func' type");
 }
 
-static bool
+static bool MR_CALL
 mercury__builtin__do_unify__pred_0_0(MR_Box x, MR_Box y)
 {
 	MR_fatal_error("called unify for `pred' type");
 }
 
-static bool
+static bool MR_CALL
 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 bool MR_CALL
 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 bool MR_CALL
 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 bool MR_CALL
 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 bool MR_CALL
 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 bool MR_CALL
 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 bool MR_CALL
 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 bool MR_CALL
 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 void MR_CALL
 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 void MR_CALL
 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 void MR_CALL
 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 void MR_CALL
 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 void MR_CALL
 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 void MR_CALL
 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 void MR_CALL
 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 void MR_CALL
 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 void MR_CALL
 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 void MR_CALL
 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 void MR_CALL
 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 void MR_CALL
 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 void MR_CALL
 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 void MR_CALL
 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 void MR_CALL
 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 void MR_CALL
 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_conf_param.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_conf_param.h,v
retrieving revision 1.43
diff -u -d -r1.43 mercury_conf_param.h
--- runtime/mercury_conf_param.h	2000/11/19 04:27:57	1.43
+++ runtime/mercury_conf_param.h	2000/11/25 15:15:50
@@ -70,6 +70,13 @@
 **	Use C's `float' rather than C's `double' for the
 **	Mercury floating point type (`MR_Float').
 **
+** MR_USE_REGPARM:
+**	On x86, use a different (more efficient) calling convention.
+**	This requires the use of a very recent version of gcc --
+**	more recent that gcc 2.95.2.
+**	For details, see the definition of the MR_CALL macro in
+**	runtime/mercury_std.h.
+**
 ** PARALLEL
 **	Enable support for parallelism [not yet working].
 **
Index: runtime/mercury_grade.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_grade.h,v
retrieving revision 1.29
diff -u -d -r1.29 mercury_grade.h
--- runtime/mercury_grade.h	2000/10/23 13:45:31	1.29
+++ runtime/mercury_grade.h	2000/11/25 15:38:52
@@ -184,7 +184,9 @@
   #define MR_GRADE_PART_10	MR_GRADE_PART_9
 #endif
 
-#if defined(PIC_REG) && defined(USE_GCC_GLOBAL_REGISTERS) && defined(__i386__)
+#if defined(MR_USE_REGPARM) && defined(MR_HIGHLEVEL_CODE) && defined(__i386__)
+  #define MR_GRADE_PART_11	MR_PASTE2(MR_GRADE_PART_10, _regparm)
+#elif defined(PIC_REG) && defined(USE_GCC_GLOBAL_REGISTERS) && defined(__i386__)
   #define MR_GRADE_PART_11	MR_PASTE2(MR_GRADE_PART_10, _picreg)
 #else
   #define MR_GRADE_PART_11	MR_GRADE_PART_10
@@ -336,7 +338,9 @@
 ** So we don't bother to pass it on.
 */
 
-#if defined(PIC_REG) && defined(USE_GCC_GLOBAL_REGISTERS) && defined(__i386__)
+#if defined(MR_USE_REGPARM) && defined(MR_HIGHLEVEL_CODE) && defined(__i386__)
+  #define MR_GRADE_OPT_PART_11	MR_GRADE_OPT_PART_7 ".regparm"
+#elif defined(PIC_REG) && defined(USE_GCC_GLOBAL_REGISTERS) && defined(__i386__)
   #define MR_GRADE_OPT_PART_11	MR_GRADE_OPT_PART_7 ".picreg"
 #else
   #define MR_GRADE_OPT_PART_11	MR_GRADE_OPT_PART_7
Index: runtime/mercury.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury.h,v
retrieving revision 1.25
diff -u -d -r1.25 mercury.h
--- runtime/mercury.h	2000/11/06 10:43:40	1.25
+++ runtime/mercury.h	2000/11/25 15:28:37
@@ -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,
+bool MR_CALL mercury__builtin__unify_2_p_0(MR_Mercury_Type_Info,
+	MR_Box, MR_Box);
+void MR_CALL 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,
+void MR_CALL 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,
+void MR_CALL 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,
+void MR_CALL 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(
+bool MR_CALL mercury__builtin____Unify____int_0_0(MR_Integer x, MR_Integer y); 
+bool MR_CALL mercury__builtin____Unify____string_0_0(MR_String x, MR_String y); 
+bool MR_CALL mercury__builtin____Unify____float_0_0(MR_Float x, MR_Float y); 
+bool MR_CALL mercury__builtin____Unify____character_0_0(MR_Char x, MR_Char); 
+bool MR_CALL mercury__builtin____Unify____void_0_0(MR_Void x, MR_Void y); 
+bool MR_CALL 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(
+bool MR_CALL mercury__builtin____Unify____func_0_0(MR_Func x, MR_Func y); 
+bool MR_CALL mercury__builtin____Unify____pred_0_0(MR_Pred x, MR_Pred y); 
+bool MR_CALL mercury__builtin____Unify____tuple_0_0(
+	MR_Mercury_Type_Info type_info, MR_Tuple x, MR_Tuple y); 
+bool MR_CALL mercury__array____Unify____array_1_0(
+	MR_Mercury_Type_Info type_info, MR_Array x, MR_Array y);
+bool MR_CALL mercury__std_util____Unify____univ_0_0(MR_Univ x, MR_Univ y); 
+bool MR_CALL 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(
+bool MR_CALL 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(
+bool MR_CALL 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(
+bool MR_CALL 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(
+bool MR_CALL 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(
+void MR_CALL mercury__builtin____Compare____int_0_0(
 	MR_Comparison_Result *result, MR_Integer x, MR_Integer y);
-void mercury__builtin____Compare____string_0_0(
+void MR_CALL mercury__builtin____Compare____string_0_0(
 	MR_Comparison_Result *result, MR_String x, MR_String y);
-void mercury__builtin____Compare____float_0_0(
+void MR_CALL mercury__builtin____Compare____float_0_0(
 	MR_Comparison_Result *result, MR_Float x, MR_Float y);
-void mercury__builtin____Compare____character_0_0(
+void MR_CALL mercury__builtin____Compare____character_0_0(
 	MR_Comparison_Result *result, MR_Char x, MR_Char y);
-void mercury__builtin____Compare____void_0_0(
+void MR_CALL mercury__builtin____Compare____void_0_0(
 	MR_Comparison_Result *result, MR_Void x, MR_Void y);
-void mercury__builtin____Compare____c_pointer_0_0(
+void MR_CALL 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(
+void MR_CALL mercury__builtin____Compare____func_0_0(
 	MR_Comparison_Result *result, MR_Func x, MR_Func y);
-void mercury__builtin____Compare____pred_0_0(
+void MR_CALL 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(
+void MR_CALL mercury__builtin____Compare____tuple_0_0(
+	MR_Mercury_Type_Info type_info, MR_Comparison_Result *result,
+	MR_Tuple x, MR_Tuple y); 
+void MR_CALL mercury__array____Compare____array_1_0(MR_Mercury_Type_Info
+	type_info, MR_Comparison_Result *result, MR_Array x, MR_Array y);
+void MR_CALL 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(
+void MR_CALL 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(
+void MR_CALL 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(
+void MR_CALL 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(
+void MR_CALL 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(
+void MR_CALL 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_std.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_std.h,v
retrieving revision 1.14
diff -u -d -r1.14 mercury_std.h
--- runtime/mercury_std.h	2000/11/23 02:00:42	1.14
+++ runtime/mercury_std.h	2000/11/25 16:22:59
@@ -129,6 +129,37 @@
 
 /*---------------------------------------------------------------------------*/
 
+/* XXX FIXME temp hack! */
+#define MR_USE_REGPARM 1
+
+/*
+** MR_CALL:
+** A macro for specifying the calling convention to use
+** for C functions generated by the MLDS back-end
+** (and for builtins such as unification which must use
+** the same calling convention).
+** This can expand to whatever implementation-specific magic 
+** is required to tell the C compiler to use a different
+** calling convention.
+**
+** If MR_USE_REGPARM is defined, and we're using gcc on x86,
+** then we use a non-standard but more efficient calling
+** convention that passes parameters in registers.
+** Otherwise we just use the default C calling convention.
+**
+** Any changes here (e.g. adding additional calling conventions,
+** or adding support for other C compilers or other processors)
+** should be reflected in the mangled grade name produced by
+** runtime/mercury_grade.h.
+*/
+#if defined(MR_USE_REGPARM) && defined(__GNUC__) && defined(__i386__)
+  #define MR_CALL __attribute__((__stdcall__, __regparm__(3)))
+#else
+  #define MR_CALL
+#endif
+
+/*---------------------------------------------------------------------------*/
+
 /*
 ** C preprocessor tricks.
 */
Index: runtime/mercury_types.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_types.h,v
retrieving revision 1.23
diff -u -d -r1.23 mercury_types.h
--- runtime/mercury_types.h	2000/11/23 02:00:49	1.23
+++ runtime/mercury_types.h	2000/11/25 15:30:08
@@ -20,6 +20,7 @@
 #define MERCURY_TYPES_H
 
 #include "mercury_conf.h"
+#include "mercury_std.h"		/* for MR_CALL */
 
 /*
 ** This section defines types similar to C9X's <stdint.h> header.
@@ -93,8 +94,8 @@
 typedef const MR_Char *MR_ConstString;
 
 /* 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 void MR_CALL (*MR_NestedCont) (void); /* for --gcc-nested-functions */
+typedef void MR_CALL (*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 -r1.78 mercury_wrapper.c
--- runtime/mercury_wrapper.c	2000/11/23 02:00:50	1.78
+++ runtime/mercury_wrapper.c	2000/11/25 15:30:18
@@ -185,7 +185,7 @@
 #endif
 
 #ifdef MR_HIGHLEVEL_CODE
-void	(*MR_program_entry_point)(void);
+void MR_CALL (*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 -r1.38 mercury_wrapper.h
--- runtime/mercury_wrapper.h	2000/11/23 02:00:51	1.38
+++ runtime/mercury_wrapper.h	2000/11/25 15:30:28
@@ -65,7 +65,7 @@
 */
 
 #ifdef MR_HIGHLEVEL_CODE
-extern	void		(*MR_program_entry_point)(void);
+extern	void MR_CALL	(*MR_program_entry_point)(void);
 			/* normally main_2_p_0 */
 #else
 extern	MR_Code 	*MR_program_entry_point;
Index: util/mkinit.c
===================================================================
RCS file: /home/mercury1/repository/mercury/util/mkinit.c,v
retrieving revision 1.71
diff -u -d -r1.71 mkinit.c
--- util/mkinit.c	2000/11/23 06:33:25	1.71
+++ util/mkinit.c	2000/11/25 15:30:34
@@ -117,7 +117,7 @@
 	"#define MR_TRACE_ENABLED %d\n"
 	"\n"
 	"#ifdef MR_HIGHLEVEL_CODE\n"
-	"  extern void %s(void);\n"
+	"  extern void MR_CALL %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