8sa1-gcc/gcc/testsuite/gcc.c-torture/execute/stdarg-4.c
Jakub Jelinek 9d30f3c190 tree.h (enum tree_index): Add TI_VA_LIST_GPR_COUNTER_FIELD and TI_VA_LIST_FPR_COUNTER_FIELD.
* tree.h (enum tree_index): Add TI_VA_LIST_GPR_COUNTER_FIELD
	and TI_VA_LIST_FPR_COUNTER_FIELD.
	(va_list_gpr_counter_field, va_list_fpr_counter_field): Define.
	* tree-pass.h (pass_stdarg): Add.
	* tree-optimize.c (init_tree_optimization_passes): Add pass_stdarg.
	* tree-stdarg.c: New file.
	* tree-stdarg.h: New file.
	* Makefile.in (OBJS-common): Add tree-stdarg.o.
	(tree-stdarg.o): Add dependencies.
	* function.h (struct function): Add va_list_gpr_size and
	va_list_fpr_size fields.
	* function.c (allocate_struct_function): Initialize them.
	* target.h (struct gcc_target): Add stdarg_optimize_hook.
	* target-def.h (TARGET_STDARG_OPTIMIZE_HOOK): Define.
	(TARGET_INITIALIZER): Add it.

	* config/i386/i386.c (ix86_build_builtin_va_list): Initialize
	va_list_{g,f}pr_counter_field.
	(ix86_setup_incoming_varargs): Don't do anything if reg_save
	area will not be used.  Only save registers that tree-stdarg.c
	detected they need saving.
	(ix86_va_start): Don't set up fields that won't be used.

	* config/rs6000/rs6000.c (rs6000_build_builtin_va_list): Initialize
	va_list_{g,f}pr_counter_field.
	(setup_incoming_varargs): Don't do anything if reg_save
	area will not be used.  Only save registers that tree-stdarg.c
	detected they need saving.
	(rs6000_va_start): Don't set up fields that won't be used.

	* config/alpha/alpha.c: Include tree-flow.h and tree-stdarg.h.
	(alpha_build_builtin_va_list): Initialize va_list_gpr_counter_field.
	(va_list_skip_additions, alpha_stdarg_optimize_hook): New functions.
	(TARGET_STDARG_OPTIMIZE_HOOK): Define.

	* gcc.dg/tree-ssa/stdarg-1.c: New test.
	* gcc.dg/tree-ssa/stdarg-2.c: New test.
	* gcc.dg/tree-ssa/stdarg-3.c: New test.
	* gcc.dg/tree-ssa/stdarg-4.c: New test.
	* gcc.dg/tree-ssa/stdarg-5.c: New test.
	* gcc.c-torture/execute/stdarg-4.c: New test.

	* gcc.dg/vmx/varargs-1.c (f1, f2, f3): Add missing va_end.

From-SVN: r97916
2005-04-09 19:19:58 +02:00

138 lines
2.2 KiB
C

#include <stdarg.h>
extern void abort (void);
long x, y;
inline void __attribute__((always_inline))
f1i (va_list ap)
{
x = va_arg (ap, double);
x += va_arg (ap, long);
x += va_arg (ap, double);
}
void
f1 (int i, ...)
{
va_list ap;
va_start (ap, i);
f1i (ap);
va_end (ap);
}
inline void __attribute__((always_inline))
f2i (va_list ap)
{
y = va_arg (ap, int);
y += va_arg (ap, long);
y += va_arg (ap, double);
f1i (ap);
}
void
f2 (int i, ...)
{
va_list ap;
va_start (ap, i);
f2i (ap);
va_end (ap);
}
long
f3h (int i, long arg0, long arg1, long arg2, long arg3)
{
return i + arg0 + arg1 + arg2 + arg3;
}
long
f3 (int i, ...)
{
long t, arg0, arg1, arg2, arg3;
va_list ap;
va_start (ap, i);
switch (i)
{
case 0:
t = f3h (i, 0, 0, 0, 0);
break;
case 1:
arg0 = va_arg (ap, long);
t = f3h (i, arg0, 0, 0, 0);
break;
case 2:
arg0 = va_arg (ap, long);
arg1 = va_arg (ap, long);
t = f3h (i, arg0, arg1, 0, 0);
break;
case 3:
arg0 = va_arg (ap, long);
arg1 = va_arg (ap, long);
arg2 = va_arg (ap, long);
t = f3h (i, arg0, arg1, arg2, 0);
break;
case 4:
arg0 = va_arg (ap, long);
arg1 = va_arg (ap, long);
arg2 = va_arg (ap, long);
arg3 = va_arg (ap, long);
t = f3h (i, arg0, arg1, arg2, arg3);
break;
default:
abort ();
}
va_end (ap);
return t;
}
void
f4 (int i, ...)
{
va_list ap;
va_start (ap, i);
switch (i)
{
case 4:
y = va_arg (ap, double);
break;
case 5:
y = va_arg (ap, double);
y += va_arg (ap, double);
break;
default:
abort ();
}
f1i (ap);
va_end (ap);
}
int
main (void)
{
f1 (3, 16.0, 128L, 32.0);
if (x != 176L)
abort ();
f2 (6, 5, 7L, 18.0, 19.0, 17L, 64.0);
if (x != 100L || y != 30L)
abort ();
if (f3 (0) != 0)
abort ();
if (f3 (1, 18L) != 19L)
abort ();
if (f3 (2, 18L, 100L) != 120L)
abort ();
if (f3 (3, 18L, 100L, 300L) != 421L)
abort ();
if (f3 (4, 18L, 71L, 64L, 86L) != 243L)
abort ();
f4 (4, 6.0, 9.0, 16L, 18.0);
if (x != 43L || y != 6L)
abort ();
f4 (5, 7.0, 21.0, 1.0, 17L, 126.0);
if (x != 144L || y != 28L)
abort ();
return 0;
}