goodbye, MD_CALL_PROTOTYPES
Zack Weinberg
zack@wolery.cumb.org
Thu Feb 24 00:57:00 GMT 2000
This patch eliminates the MD_CALL_PROTOTYPES macro, and causes
gen_call and friends to be prototyped with the rest of the gen_insn
functions. With this done, an i386 native build has only 50 or so
-W(strict,missing)-prototypes warnings, most of which are in libgcc2.
MD_CALL_PROTOTYPES was avoiding a problem with our intermediate
representation. The 'call' insn is not an accurate model of any real
machine's subroutine-call instruction. calls.c imagines a call insn
that looks something like
gen_call (symbol, stack_space_for_args, next_arg_register, struct_value_size)
Most .md files have been written as if that function took only two
arguments. Rather than change them all, I chose to change calls.c and
builtins.c so that it does. For the seven platforms that need the
extra info, we now have "xcall" and "xcall_value" insns. (Suggestions
for better names will be gladly accepted.)
Note that there is no problem with call_pop/call_value_pop, despite
what genflags.c thinks, because it's nonsensical to write a call_pop
pattern that ignores the amount of stack to pop, and that's the _last_
argument - so we just have a function with some unused args in the
middle, not a prototype mismatch.
This has been tested as follows: first, I built a native i386-linux
compiler and ran the test suite (no regressions); then, for six of the
seven targets that use xcall, I configured a cross-compiler to that
target and made sure the build got far enough to blow up on libgcc2
because I didn't have a cross-assembler handy - meaning that the
compiler was generating valid output.
The picojava target has not been tested, because it doesn't compile
right now. Problems include lack of ASM_OUTPUT_INTERNAL_LABEL, and
uses of current_function rather than cfun.
The docs have not been updated; if the patch is OK, I will of course
update them before checking it in.
zw
* builtins.c (expand_builtin_apply): Handle HAVE_xcall_value
as well as HAVE_call_value. gen_call_value takes three
arguments.
* calls.c (emit_call_1): Handle HAVE_xcall/HAVE_xcall_value as
well as HAVE_call/HAVE_call_value. gen_call takes two
arguments, gen_call_value three.
* genflags.c (call_obstack, gen_nonproto): Delete.
(normal_obstack): Rename to insn_obstack.
(gen_insn): Put all insn ptrs on the same obstack.
(main): Generate prototypes for all gen_insn functions
unconditionally.
* a29k.md, alpha.md, arm.md, mips.md, pj.md, rs6000.md,
sparc.md (call, call_value): Rename to xcall and xcall_value
respectively.
* alpha.md, arm.md, mips.md, rs6000.md (untyped_call):
Use gen_xcall.
* a29k.md, arm.md, rs6000.md, sparc.md: Add missing USEs for
struct_value_size_rtx to xcall and xcall_value patterns.
* alpha.c (alpha_emit_xfloating_libcall): Use gen_xcall_value.
===================================================================
Index: builtins.c
--- builtins.c 2000/02/01 18:57:21 1.29
+++ builtins.c 2000/02/24 08:42:45
@@ -942,8 +942,7 @@ expand_builtin_apply (function, argument
result, result_vector (1, result)));
else
#endif
-#ifdef HAVE_call_value
- if (HAVE_call_value)
+#if defined HAVE_call_value || defined HAVE_xcall_value
{
rtx valreg = 0;
@@ -959,17 +958,29 @@ expand_builtin_apply (function, argument
valreg = gen_rtx_REG (mode, regno);
}
- emit_call_insn (gen_call_value (valreg,
- gen_rtx_MEM (FUNCTION_MODE, function),
- const0_rtx, NULL_RTX, const0_rtx));
+#ifdef HAVE_call_value
+ if (HAVE_call_value)
+ emit_call_insn (gen_call_value (valreg,
+ gen_rtx_MEM (FUNCTION_MODE, function),
+ const0_rtx));
+ else
+#endif
+#ifdef HAVE_xcall_value
+ if (HAVE_xcall_value)
+ emit_call_insn (gen_xcall_value (valreg,
+ gen_rtx_MEM (FUNCTION_MODE, function),
+ const0_rtx, NULL_RTX, const0_rtx));
+ else
+#endif
+ abort ();
emit_move_insn (change_address (result, GET_MODE (valreg),
XEXP (result, 0)),
valreg);
}
- else
-#endif
+#else
abort ();
+#endif
/* Find the CALL insn we just emitted. */
for (call_insn = get_last_insn ();
===================================================================
Index: calls.c
--- calls.c 2000/02/10 21:00:09 1.81
+++ calls.c 2000/02/24 08:42:46
@@ -395,7 +395,7 @@ emit_call_1 (funexp, fndecl, funtype, st
int is_const;
{
rtx rounded_stack_size_rtx = GEN_INT (rounded_stack_size);
-#if defined (HAVE_call) && defined (HAVE_call_value)
+#if defined (HAVE_xcall) && defined (HAVE_xcall_value)
rtx struct_value_size_rtx = GEN_INT (struct_value_size);
#endif
rtx call_insn;
@@ -416,9 +416,16 @@ emit_call_1 (funexp, fndecl, funtype, st
if no arguments are actually popped. If the target does not have
"call" or "call_value" insns, then we must use the popping versions
even if the call has no arguments to pop. */
+#if (defined (HAVE_call) && defined (HAVE_call_value)) \
+ || (defined (HAVE_xcall) && defined (HAVE_xcall_value))
+ if (1
#if defined (HAVE_call) && defined (HAVE_call_value)
- if (HAVE_call && HAVE_call_value && HAVE_call_pop && HAVE_call_value_pop
- && n_popped > 0)
+ && HAVE_call && HAVE_call_value
+#elif defined (HAVE_xcall) && defined (HAVE_xcall_value)
+ && HAVE_xcall && HAVE_xcall_value
+#endif
+ && HAVE_call_pop && HAVE_call_value_pop
+ && n_popped > 0)
#else
if (HAVE_call_pop && HAVE_call_value_pop)
#endif
@@ -450,12 +457,25 @@ emit_call_1 (funexp, fndecl, funtype, st
if (valreg)
emit_call_insn (gen_call_value (valreg,
gen_rtx_MEM (FUNCTION_MODE, funexp),
- rounded_stack_size_rtx, next_arg_reg,
- NULL_RTX));
+ rounded_stack_size_rtx));
else
emit_call_insn (gen_call (gen_rtx_MEM (FUNCTION_MODE, funexp),
- rounded_stack_size_rtx, next_arg_reg,
- struct_value_size_rtx));
+ rounded_stack_size_rtx));
+ }
+ else
+#endif
+#if defined (HAVE_xcall) && defined (HAVE_xcall_value)
+ if (HAVE_xcall && HAVE_xcall_value)
+ {
+ if (valreg)
+ emit_call_insn (gen_xcall_value (valreg,
+ gen_rtx_MEM (FUNCTION_MODE, funexp),
+ rounded_stack_size_rtx, next_arg_reg,
+ struct_value_size_rtx));
+ else
+ emit_call_insn (gen_xcall (gen_rtx_MEM (FUNCTION_MODE, funexp),
+ rounded_stack_size_rtx, next_arg_reg,
+ struct_value_size_rtx));
}
else
#endif
===================================================================
Index: genflags.c
--- genflags.c 2000/02/05 04:56:11 1.28
+++ genflags.c 2000/02/24 08:42:46
@@ -33,8 +33,8 @@ struct obstack *rtl_obstack = &obstack;
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
-/* Obstacks to remember normal, and call insns. */
-static struct obstack call_obstack, normal_obstack;
+/* Obstack to remember insns on. */
+static struct obstack insn_obstack;
/* Max size of names encountered. */
static int max_id_len;
@@ -45,7 +45,6 @@ static int max_opno;
static void max_operand_1 PARAMS ((rtx));
static int num_operands PARAMS ((rtx));
static void gen_proto PARAMS ((rtx));
-static void gen_nonproto PARAMS ((rtx));
static void gen_insn PARAMS ((rtx));
/* Count the number of match_operand's found. */
@@ -120,22 +119,12 @@ gen_proto (insn)
printf ("));\n");
}
-/* Print out a function declaration without a prototype. */
-
static void
-gen_nonproto (insn)
- rtx insn;
-{
- printf ("extern rtx gen_%s ();\n", XSTR (insn, 0));
-}
-
-static void
gen_insn (insn)
rtx insn;
{
char *name = XSTR (insn, 0);
char *p;
- struct obstack *obstack_ptr;
int len;
/* Don't mention instructions whose names are the null string
@@ -168,19 +157,9 @@ gen_insn (insn)
}
/* Save the current insn, so that we can later put out appropriate
- prototypes. At present, most md files have the wrong number of
- arguments for the call insns (call, call_value, call_pop,
- call_value_pop) ignoring the extra arguments that are passed for
- some machines, so by default, turn off the prototype. */
-
- obstack_ptr = (name[0] == 'c'
- && (!strcmp (name, "call")
- || !strcmp (name, "call_value")
- || !strcmp (name, "call_pop")
- || !strcmp (name, "call_value_pop")))
- ? &call_obstack : &normal_obstack;
+ prototypes. */
- obstack_grow (obstack_ptr, &insn, sizeof (rtx));
+ obstack_grow (&insn_obstack, &insn, sizeof (rtx));
}
PTR
@@ -219,16 +198,13 @@ main (argc, argv)
{
rtx desc;
rtx dummy;
- rtx *call_insns;
- rtx *normal_insns;
- rtx *insn_ptr;
+ rtx *insns;
FILE *infile;
register int c;
progname = "genflags";
- obstack_init (rtl_obstack);
- obstack_init (&call_obstack);
- obstack_init (&normal_obstack);
+ obstack_init (&obstack);
+ obstack_init (&insn_obstack);
if (argc <= 1)
fatal ("No input file name.");
@@ -241,8 +217,8 @@ main (argc, argv)
}
read_rtx_filename = argv[1];
- printf ("/* Generated automatically by the program `genflags'\n\
-from the machine description file `md'. */\n\n");
+ puts ("/* Generated automatically by the program `genflags'");
+ puts (" from the machine description file `md'. */\n");
/* Read the machine description. */
@@ -260,24 +236,12 @@ from the machine description file `md'.
/* Print out the prototypes now. */
dummy = (rtx) 0;
- obstack_grow (&call_obstack, &dummy, sizeof (rtx));
- call_insns = (rtx *) obstack_finish (&call_obstack);
-
- obstack_grow (&normal_obstack, &dummy, sizeof (rtx));
- normal_insns = (rtx *) obstack_finish (&normal_obstack);
-
- for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++)
- gen_proto (*insn_ptr);
-
- printf ("\n#ifdef MD_CALL_PROTOTYPES\n");
- for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
- gen_proto (*insn_ptr);
- printf ("\n#else /* !MD_CALL_PROTOTYPES */\n");
- for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
- gen_nonproto (*insn_ptr);
+ obstack_grow (&insn_obstack, &dummy, sizeof (rtx));
+ insns = (rtx *) obstack_finish (&insn_obstack);
- printf ("#endif /* !MD_CALL_PROTOTYPES */\n");
+ while (*insns)
+ gen_proto (*insns++);
fflush (stdout);
return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
===================================================================
Index: config/a29k/a29k.md
--- config/a29k/a29k.md 1999/10/15 06:38:01 1.4
+++ config/a29k/a29k.md 2000/02/24 08:42:47
@@ -119,10 +119,11 @@
;; We indicate that LR0 is clobbered in the CALL_INSN itself. Otherwise,
;; reorg will think it is just clobbered by the called function.
-(define_expand "call"
+(define_expand "xcall"
[(use (match_operand:SI 0 "" ""))
(use (match_operand 1 "" ""))
- (use (match_operand 2 "" ""))]
+ (use (match_operand 2 "" ""))
+ (use (match_operand 3 "" ""))]
""
"
{ rtx insn = emit_call_insn (gen_call_internal (operands[0], operands[1]));
@@ -149,11 +150,12 @@
force_reg (Pmode, XEXP (operands[0], 0)));
}")
-(define_expand "call_value"
+(define_expand "xcall_value"
[(use (match_operand:SI 0 "gpc_reg_operand" ""))
(use (match_operand:SI 1 "" ""))
(use (match_operand 2 "" ""))
- (use (match_operand 3 "" ""))]
+ (use (match_operand 3 "" ""))
+ (use (match_operand 4 "" ""))]
""
"
{ rtx insn = emit_call_insn (gen_call_value_internal (operands[0], operands[1],
===================================================================
Index: config/alpha/alpha.c
--- config/alpha/alpha.c 2000/02/19 01:26:59 1.117
+++ config/alpha/alpha.c 2000/02/24 08:42:48
@@ -1998,8 +1998,8 @@ alpha_emit_xfloating_libcall (func, targ
}
tmp = gen_rtx_MEM (QImode, gen_rtx_SYMBOL_REF (Pmode, (char *) func));
- tmp = emit_call_insn (gen_call_value (reg, tmp, const0_rtx,
- const0_rtx, const0_rtx));
+ tmp = emit_call_insn (gen_xcall_value (reg, tmp, const0_rtx,
+ const0_rtx, const0_rtx));
CALL_INSN_FUNCTION_USAGE (tmp) = usage;
tmp = get_insns ();
===================================================================
Index: config/alpha/alpha.md
--- config/alpha/alpha.md 2000/01/31 01:16:21 1.110
+++ config/alpha/alpha.md 2000/02/24 08:42:48
@@ -3686,7 +3686,7 @@
;; Here are the CALL and unconditional branch insns. Calls on NT and OSF
;; work differently, so we have different patterns for each.
-(define_expand "call"
+(define_expand "xcall"
[(use (match_operand:DI 0 "" ""))
(use (match_operand 1 "" ""))
(use (match_operand 2 "" ""))
@@ -3794,7 +3794,7 @@
}")
-(define_expand "call_value"
+(define_expand "xcall_value"
[(use (match_operand 0 "" ""))
(use (match_operand:DI 1 "" ""))
(use (match_operand 2 "" ""))
@@ -3951,7 +3951,7 @@
{
int i;
- emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
+ emit_call_insn (gen_xcall (operands[0], const0_rtx, NULL, const0_rtx));
for (i = 0; i < XVECLEN (operands[2], 0); i++)
{
===================================================================
Index: config/arm/arm.md
--- config/arm/arm.md 2000/02/11 22:39:49 1.43
+++ config/arm/arm.md 2000/02/24 08:42:49
@@ -4506,10 +4506,11 @@
return \"b%?\\t%l0\";
}")
-(define_expand "call"
+(define_expand "xcall"
[(parallel [(call (match_operand 0 "memory_operand" "")
(match_operand 1 "general_operand" ""))
(use (match_operand 2 "" ""))
+ (use (match_operand 3 "" ""))
(clobber (reg:SI 14))])]
""
"
@@ -4535,7 +4536,8 @@
(define_insn "*call_reg"
[(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
(match_operand 1 "" "g"))
- (use (match_operand:SI 2 "immediate_operand" "n"))
+ (use (match_operand:SI 2 "" ""))
+ (use (match_operand:SI 3 "" ""))
(clobber (reg:SI 14))]
""
"*
@@ -4549,6 +4551,7 @@
[(call (mem:SI (match_operand:SI 0 "memory_operand" "m"))
(match_operand 1 "general_operand" "g"))
(use (match_operand:SI 2 "" ""))
+ (use (match_operand:SI 3 "" ""))
(clobber (reg:SI 14))]
""
"*
@@ -4557,18 +4560,19 @@
[(set_attr "length" "12")
(set_attr "type" "call")])
-(define_expand "call_value"
+(define_expand "xcall_value"
[(parallel [(set (match_operand 0 "" "=rf")
(call (match_operand 1 "memory_operand" "m")
(match_operand 2 "general_operand" "g")))
(use (match_operand:SI 3 "" ""))
+ (use (match_operand:SI 4 "" ""))
(clobber (reg:SI 14))])]
""
"
{
rtx callee = XEXP (operands[1], 0);
- /* In an untyped call, we can get NULL for operand 2. */
+ /* In an untyped call, we can get NULL for operand 3. */
if (operands[3] == 0)
operands[3] = const0_rtx;
@@ -4584,6 +4588,7 @@
(call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
(match_operand 2 "general_operand" "g")))
(use (match_operand 3 "" ""))
+ (use (match_operand 4 "" ""))
(clobber (reg:SI 14))]
""
"*
@@ -4597,6 +4602,7 @@
(call (mem:SI (match_operand 1 "memory_operand" "m"))
(match_operand 2 "general_operand" "g")))
(use (match_operand 3 "" ""))
+ (use (match_operand 4 "" ""))
(clobber (reg:SI 14))]
"! CONSTANT_ADDRESS_P (XEXP (operands[1], 0))"
"*
@@ -4612,6 +4618,7 @@
[(call (mem:SI (match_operand:SI 0 "" "X"))
(match_operand:SI 1 "general_operand" "g"))
(use (match_operand 2 "" ""))
+ (use (match_operand 3 "" ""))
(clobber (reg:SI 14))]
"! arm_is_longcall_p (operands[0], INTVAL (operands[2]), 1)
&& GET_CODE (operands[0]) == SYMBOL_REF"
@@ -4626,6 +4633,7 @@
(call (mem:SI (match_operand:SI 1 "" "X"))
(match_operand:SI 2 "general_operand" "g")))
(use (match_operand 3 "" ""))
+ (use (match_operand 4 "" ""))
(clobber (reg:SI 14))]
"! arm_is_longcall_p (operands[1], INTVAL (operands[3]), 1)
&& GET_CODE (operands[1]) == SYMBOL_REF"
@@ -4706,7 +4714,7 @@
{
int i;
- emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
+ emit_call_insn (gen_xcall (operands[0], const0_rtx, NULL, const0_rtx));
for (i = 0; i < XVECLEN (operands[2], 0); i++)
{
===================================================================
Index: config/mips/mips.md
--- config/mips/mips.md 2000/01/25 15:51:20 1.77
+++ config/mips/mips.md 2000/02/24 08:42:50
@@ -9430,7 +9430,7 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\;j
;; calls.c now passes a third argument, make saber happy
-(define_expand "call"
+(define_expand "xcall"
[(parallel [(call (match_operand 0 "memory_operand" "m")
(match_operand 1 "" "i"))
(clobber (reg:SI 31))
@@ -9612,14 +9612,15 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\;j
(set_attr "mode" "none")
(set_attr "length" "8")])
-;; calls.c now passes a fourth argument, make saber happy
+;; calls.c now passes a fifth argument, make saber happy
-(define_expand "call_value"
+(define_expand "xcall_value"
[(parallel [(set (match_operand 0 "register_operand" "=df")
(call (match_operand 1 "memory_operand" "m")
(match_operand 2 "" "i")))
(clobber (reg:SI 31))
- (use (match_operand 3 "" ""))])] ;; next_arg_reg
+ (use (match_operand 3 "" "")) ;; next_arg_reg
+ (use (match_operand 4 "" ""))])]
""
"
{
@@ -9907,7 +9908,7 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\;j
{
int i;
- emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
+ emit_call_insn (gen_xcall (operands[0], const0_rtx, NULL, const0_rtx));
for (i = 0; i < XVECLEN (operands[2], 0); i++)
{
===================================================================
Index: config/pj/pj.md
--- config/pj/pj.md 2000/01/05 05:57:17 1.1
+++ config/pj/pj.md 2000/02/24 08:42:50
@@ -745,7 +745,7 @@
""
"%C1%E2%S1%S2%*call")
-(define_expand "call"
+(define_expand "xcall"
[(call (match_operand:SI 0 "pj_source_operand" "gS")
(match_operand:SI 1 "immediate_operand" "i"))
(use (match_operand:SI 2 "register_operand" "r"))
@@ -758,7 +758,7 @@
DONE;
}")
-(define_expand "call_value"
+(define_expand "xcall_value"
[(set (match_operand:SI 0 "nonimmediate_operand" "gS")
(call (match_operand:SI 1 "pj_source_operand" "gS")
(match_operand:SI 2 "immediate_operand" "i")))
===================================================================
Index: config/rs6000/rs6000.md
--- config/rs6000/rs6000.md 1999/12/15 07:24:19 1.79
+++ config/rs6000/rs6000.md 2000/02/24 08:42:51
@@ -8192,10 +8192,11 @@
(set_attr "length" "4,8")])
;; Now the definitions for the call and call_value insns
-(define_expand "call"
+(define_expand "xcall"
[(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
(match_operand 1 "" ""))
(use (match_operand 2 "" ""))
+ (use (match_operand 3 "" ""))
(clobber (scratch:SI))])]
""
"
@@ -8254,11 +8255,12 @@
}
}")
-(define_expand "call_value"
+(define_expand "xcall_value"
[(parallel [(set (match_operand 0 "" "")
(call (mem:SI (match_operand 1 "address_operand" ""))
(match_operand 2 "" "")))
(use (match_operand 3 "" ""))
+ (use (match_operand 4 "" ""))
(clobber (scratch:SI))])]
""
"
@@ -8570,7 +8572,7 @@
{
int i;
- emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx, const0_rtx));
+ emit_call_insn (gen_xcall (operands[0], const0_rtx, const0_rtx, const0_rtx));
for (i = 0; i < XVECLEN (operands[2], 0); i++)
{
===================================================================
Index: config/sparc/sparc.md
--- config/sparc/sparc.md 2000/02/20 13:43:58 1.101
+++ config/sparc/sparc.md 2000/02/24 08:42:52
@@ -8413,7 +8413,7 @@
; [(set_attr "type" "marker")])
;;- jump to subroutine
-(define_expand "call"
+(define_expand "xcall"
;; Note that this expression is not used for generating RTL.
;; All the RTL is generated explicitly below.
[(call (match_operand 0 "call_operand" "")
@@ -8583,7 +8583,7 @@
"call\\t%a0, %1\\n\\tnop\\n\\tnop"
[(set_attr "type" "call_no_delay_slot")])
-(define_expand "call_value"
+(define_expand "xcall_value"
;; Note that this expression is not used for generating RTL.
;; All the RTL is generated explicitly below.
[(set (match_operand 0 "register_operand" "=rf")
@@ -8673,7 +8673,7 @@
/* Pass constm1 to indicate that it may expect a structure value, but
we don't know what size it is. */
- emit_call_insn (gen_call (operands[0], const0_rtx, NULL, constm1_rtx));
+ emit_call_insn (gen_xcall (operands[0], const0_rtx, NULL, constm1_rtx));
for (i = 0; i < XVECLEN (operands[2], 0); i++)
{
More information about the Gcc-patches
mailing list