2008-01-11 Luis Machado Thiago Jung Bauermann * testsuite/gdb.base/callfuncs.c (t_float_many_args): New function. (t_double_many_args): New function. * testsuite/gdb.base/callfuncs.exp: Add tests for exceeding float and double parameters passed through the stack. * ppc-sysv-tdep.c: Convert spaces to tabs. (ppc_sysv_abi_push_dummy_call): Align floats to 4 bytes in the stack. Index: gdb/testsuite/gdb.base/callfuncs.c =================================================================== --- gdb.orig/testsuite/gdb.base/callfuncs.c 2008-01-11 09:59:22.000000000 -0800 +++ gdb/testsuite/gdb.base/callfuncs.c 2008-01-11 09:59:33.000000000 -0800 @@ -1,6 +1,6 @@ /* This testcase is part of GDB, the GNU debugger. - Copyright 1993, 1994, 1995, 1998, 1999, 2000, 2001, 2004, 2007, 2008 + Copyright 1993, 1994, 1995, 1998, 1999, 2000, 2001, 2004, 2007 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify @@ -46,9 +46,35 @@ float float_val1 = 3.14159; float float_val2 = -2.3765; +float float_val3 = 0.25; +float float_val4 = 1.25; +float float_val5 = 2.25; +float float_val6 = 3.25; +float float_val7 = 4.25; +float float_val8 = 5.25; +float float_val9 = 6.25; +float float_val10 = 7.25; +float float_val11 = 8.25; +float float_val12 = 9.25; +float float_val13 = 10.25; +float float_val14 = 11.25; +float float_val15 = 12.25; double double_val1 = 45.654; double double_val2 = -67.66; +double double_val3 = 0.25; +double double_val4 = 1.25; +double double_val5 = 2.25; +double double_val6 = 3.25; +double double_val7 = 4.25; +double double_val8 = 5.25; +double double_val9 = 6.25; +double double_val10 = 7.25; +double double_val11 = 8.25; +double double_val12 = 9.25; +double double_val13 = 10.25; +double double_val14 = 11.25; +double double_val15 = 12.25; #define DELTA (0.001) @@ -298,6 +324,39 @@ && (float_arg2 - float_val2) > -DELTA); } +/* This function has many arguments to force some of them to be passed via + the stack instead of registers, to test that GDB can construct correctly + the parameter save area. Note that Linux/ppc32 has 8 float registers to use + for float parameter passing and Linux/ppc64 has 13, so the number of + arguments has to be at least 14 to contemplate these platforms. */ + +float +#ifdef NO_PROTOTYPES +t_float_many_args (f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, + f14, f15) + float f1, float f2, float f3, float f4, float f5, float f6, float f7, + float f8, float f9, float f10, float f11, float f12, float f13, float f14, + float f15; +#else +t_float_many_args (float f1, float f2, float f3, float f4, float f5, float f6, + float f7, float f8, float f9, float f10, float f11, + float f12, float f13, float f14, float f15) +#endif +{ + float sum_args; + float sum_values; + + sum_args = f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 + f9 + f10 + f11 + f12 + + f13 + f14 + f15; + sum_values = float_val1 + float_val2 + float_val3 + float_val4 + float_val5 + + float_val6 + float_val7 + float_val8 + float_val9 + + float_val10 + float_val11 + float_val12 + float_val13 + + float_val14 + float_val15; + + return ((sum_args - sum_values) < DELTA + && (sum_args - sum_values) > -DELTA); +} + #ifdef PROTOTYPES int t_double_values (double double_arg1, double double_arg2) #else @@ -311,6 +370,39 @@ && (double_arg2 - double_val2) > -DELTA); } +/* This function has many arguments to force some of them to be passed via + the stack instead of registers, to test that GDB can construct correctly + the parameter save area. Note that Linux/ppc32 has 8 float registers to use + for float parameter passing and Linux/ppc64 has 13, so the number of + arguments has to be at least 14 to contemplate these platforms. */ + +double +#ifdef NO_PROTOTYPES +t_double_many_args (f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, + f14, f15) + double f1, double f2, double f3, double f4, double f5, double f6, + double f7, double f8, double f9, double f10, double f11, double f12, + double f13, double f14, double f15; +#else +t_double_many_args (double f1, double f2, double f3, double f4, double f5, + double f6, double f7, double f8, double f9, double f10, + double f11, double f12, double f13, double f14, double f15) +#endif +{ + double sum_args; + double sum_values; + + sum_args = f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 + f9 + f10 + f11 + f12 + + f13 + f14 + f15; + sum_values = double_val1 + double_val2 + double_val3 + double_val4 + + double_val5 + double_val6 + double_val7 + double_val8 + + double_val9 + double_val10 + double_val11 + double_val12 + + double_val13 + double_val14 + double_val15; + + return ((sum_args - sum_values) < DELTA + && (sum_args - sum_values) > -DELTA); +} + #ifdef PROTOTYPES int t_string_values (char *string_arg1, char *string_arg2) #else Index: gdb/testsuite/gdb.base/callfuncs.exp =================================================================== --- gdb.orig/testsuite/gdb.base/callfuncs.exp 2008-01-11 09:59:22.000000000 -0800 +++ gdb/testsuite/gdb.base/callfuncs.exp 2008-01-11 09:59:33.000000000 -0800 @@ -1,5 +1,5 @@ # Copyright 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, -# 2004, 2007, 2008 Free Software Foundation, Inc. +# 2004, 2007 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -155,6 +155,8 @@ gdb_test "p t_float_values2(3.14159,float_val2)" " = 1" + gdb_test "p t_float_many_args (float_val1, float_val2, float_val3, float_val4, float_val5, float_val6, float_val7, float_val8, float_val9, float_val10, float_val11, float_val12, float_val13, float_val14, float_val15)" " = 1" "Call function with many float arguments." + gdb_test "p t_small_values(1,2,3,4,5,6,7,8,9,10)" " = 55" gdb_test "p t_double_values(0.0,0.0)" " = 0" @@ -163,6 +165,8 @@ gdb_test "p t_double_values(45.654,double_val2)" " = 1" gdb_test "p t_double_values(double_val1,-67.66)" " = 1" + gdb_test "p t_double_many_args (double_val1, double_val2, double_val3, double_val4, double_val5, double_val6, double_val7, double_val8, double_val9, double_val10, double_val11, double_val12, double_val13, double_val14, double_val15)" " = 1" "Call function with many double arguments." + gdb_test "p t_double_int(99.0, 1)" " = 0" gdb_test "p t_double_int(99.0, 99)" " = 1" gdb_test "p t_int_double(99, 1.0)" " = 0" Index: gdb/ppc-sysv-tdep.c =================================================================== --- gdb.orig/ppc-sysv-tdep.c 2008-01-11 09:59:22.000000000 -0800 +++ gdb/ppc-sysv-tdep.c 2008-01-11 13:22:52.000000000 -0800 @@ -129,17 +129,35 @@ } else { - /* SysV ABI converts floats to doubles before - writing them to an 8 byte aligned stack location. */ - argoffset = align_up (argoffset, 8); + /* The ppc32 SysV ABI tells us to convert floats to doubles + before writing them to an 8 byte aligned stack location. + + NOTE: 2008/01/11: This is not exactly right. GCC does not + convert floats to doubles neither store floats into + 8 bytes aligned stack locations when we have a prototyped + float parameter. In this case GCC simply stores floats + into 4 bytes aligned locations. The promotion of floats + to doubles happens, for example, if we have functions with + float varargs (in which case the floats are converted to + doubles and we will see them as so). The ABI text needs + to be updated. */ + + /* Align to 4 bytes or 8 bytes depending on the type of + the argument (float or double). */ + argoffset = align_up (argoffset, len); + if (write_pass) { - char memval[8]; + char memval[len]; convert_typed_floating (val, type, memval, - builtin_type_ieee_double); + (len == 4)? + builtin_type_ieee_single + : builtin_type_ieee_double); write_memory (sp + argoffset, val, len); } - argoffset += 8; + /* Set offset according to the length of the argument's + type (float or double). */ + argoffset += len; } } else if (TYPE_CODE (type) == TYPE_CODE_FLT