* PATCH: Fix 2 PPC/SYSV varargs problems
@ 1999-04-30 0:09 Franz Sirl
1999-04-30 2:48 ` Richard Henderson
1999-05-12 6:19 ` Jeffrey A Law
0 siblings, 2 replies; 13+ messages in thread
From: Franz Sirl @ 1999-04-30 0:09 UTC (permalink / raw)
To: egcs-patches; +Cc: rth, meissner, David Edelsohn, linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 706 bytes --]
Hi,
this patch is supposed to fix the following problems on PPC/SYSV:
1. the varargs save area calculation bug, this is a hack and Richard ;-)
probably won't like it, but maybe it's good enough for egcs-1.2
2. if you call a function that uses more then 8 float args before all
integer argument passing registers are consumed, egcs will missetup the
calling sequence. I introduced a new variable cum->sysv_fwords in the
CUMULATIVE_ARGS struct, which counts the saved float words and adjusted
cum->words where needed (I hope). There maybe better/nicer ways to
implement that, so tell me if you want a different solution. A testcase is
attached, the original problem happens with gnuplot.
Franz.
[-- Attachment #2: varargs.testcase.c --]
[-- Type: text/plain, Size: 2115 bytes --]
#include <stdarg.h>
inline void debug(const char *fp,const char *msg,...)
{
va_list ap;
double df;
if (*fp != '1')
abort();
if (*msg != '2')
abort();
va_start( ap, msg );
df = va_arg(ap,double);
if (df <1.09 || df >1.11)
abort();
df = va_arg(ap,double);
if (df <1.19 || df >1.21)
abort();
df = va_arg(ap,double);
if (df <1.29 || df >1.31)
abort();
df = va_arg(ap,double);
if (df <1.39 || df >1.41)
abort();
df = va_arg(ap,double);
if (df <1.49 || df >1.51)
abort();
if ( *va_arg(ap,char*) != '3')
abort();
if ( *va_arg(ap,char*) != '4')
abort();
if ( *va_arg(ap,char*) != '5')
abort();
df = va_arg(ap,double);
if (df <1.59 || df >1.61)
abort();
df = va_arg(ap,double);
if (df <1.69 || df >1.71)
abort();
df = va_arg(ap,double);
if (df <1.79 || df >1.81)
abort();
df = va_arg(ap,double);
if (df <1.89 || df >1.91)
abort();
if ( va_arg(ap,int) != 101)
abort();
if ( va_arg(ap,int) != 102)
abort();
if ( va_arg(ap,int) != 103)
abort();
if ( va_arg(ap,int) != 104)
abort();
if ( *va_arg(ap,char*) != '6')
abort();
if ( va_arg(ap,int) != 105)
abort();
if ( va_arg(ap,int) != 106)
abort();
if ( va_arg(ap,int) != 107)
abort();
if ( va_arg(ap,int) != 108)
abort();
if ( va_arg(ap,int) != 109)
abort();
if ( va_arg(ap,int) != 110)
abort();
va_end( ap );
}
int main(void)
{
debug("1 filepointer", "2 format", 1.1,1.2,1.3,1.4,1.5, "3","4","5", 1.6,1.7,1.8,1.9, 101,102,103,104, "6", 105,106,107,108,109,110);
exit(0);
}
[-- Attachment #3: varargsfix2.patch --]
[-- Type: text/plain, Size: 7744 bytes --]
Index: expr.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/expr.c,v
retrieving revision 1.141
diff -u -p -r1.141 expr.c
--- expr.c 1999/04/27 05:34:43 1.141
+++ gcc/expr.c 1999/04/28 22:23:47
@@ -8951,7 +8951,13 @@ expand_builtin (exp, target, subtarget,
if (wordnum < 0 || wordnum >= nwords || TREE_INT_CST_HIGH (arg))
error ("argument of `__builtin_args_info' out of range");
else
- return GEN_INT (word_ptr[wordnum]);
+ {
+#ifdef CUMULATIVE_ARG_INFO_IS_RTX
+ if (CUMULATIVE_ARG_INFO_IS_RTX(wordnum))
+ return word_ptr[wordnum];
+#endif
+ return GEN_INT (word_ptr[wordnum]);
+ }
}
}
else
Index: va-ppc.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/ginclude/va-ppc.h,v
retrieving revision 1.4
diff -u -p -r1.4 va-ppc.h
--- va-ppc.h 1998/12/16 21:19:40 1.4
+++ gcc/ginclude/va-ppc.h 1999/04/28 23:23:10
@@ -80,8 +80,7 @@ __extension__ ({ \
\
(AP)->gpr = (__words < 8) ? __words : 8; \
(AP)->fpr = __va_fregno - 33; \
- (AP)->reg_save_area = (((char *) __builtin_frame_address (0)) \
- + __va_varargs_offset); \
+ (AP)->reg_save_area = ((char *) __builtin_args_info (8)); \
__va_overflow(AP) = ((char *)__builtin_saveregs () \
+ (((__words >= 8) ? __words - 8 : 0) \
* sizeof (long))); \
Index: rs6000.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.45
diff -u -p -r1.45 rs6000.h
--- rs6000.h 1999/04/27 12:39:56 1.45
+++ gcc/config/rs6000/rs6000.h 1999/04/29 23:16:17
@@ -1445,15 +1445,19 @@ extern int rs6000_sysv_varargs_p;
typedef struct rs6000_args
{
- int words; /* # words uses for passing GP registers */
+ int words; /* # words uses for passing GP+FP registers */
int fregno; /* next available FP register */
int nargs_prototype; /* # args left in the current prototype */
int orig_nargs; /* Original value of nargs_prototype */
int varargs_offset; /* offset of the varargs save area */
int prototype; /* Whether a prototype was defined */
int call_cookie; /* Do special things for this call */
+ int sysv_fwords; /* # words uses for passing FP registers */
+ void *save_area; /* setup with rtx pointing to varargs_save_area */
} CUMULATIVE_ARGS;
+#define CUMULATIVE_ARG_INFO_IS_RTX(idx) ((idx) == 8)
+
/* Define intermediate macro to compute the size (in registers) of an argument
for the RS/6000. */
Index: rs6000.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.66
diff -u -p -r1.66 rs6000.c
--- rs6000.c 1999/04/27 12:39:58 1.66
+++ gcc/config/rs6000/rs6000.c 1999/04/29 23:16:29
@@ -1256,6 +1261,7 @@ init_cumulative_args (cum, fntype, libna
cum->fregno = FP_ARG_MIN_REG;
cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
cum->call_cookie = CALL_NORMAL;
+ cum->sysv_fwords = 0;
if (incoming)
{
@@ -1381,10 +1387,10 @@ function_arg_advance (cum, mode, type, n
/* Long longs must not be split between registers and stack */
if ((GET_MODE_CLASS (mode) != MODE_FLOAT || TARGET_SOFT_FLOAT)
&& type && !AGGREGATE_TYPE_P (type)
- && cum->words < GP_ARG_NUM_REG
- && cum->words + RS6000_ARG_SIZE (mode, type, named) > GP_ARG_NUM_REG)
+ && cum->words - cum->sysv_fwords < GP_ARG_NUM_REG
+ && cum->words - cum->sysv_fwords + RS6000_ARG_SIZE (mode, type, named) > GP_ARG_NUM_REG)
{
- cum->words = GP_ARG_NUM_REG;
+ cum->words = GP_ARG_NUM_REG + cum->sysv_fwords;
}
/* Aggregates get passed as pointers */
@@ -1399,7 +1405,11 @@ function_arg_advance (cum, mode, type, n
cum->fregno++;
else
- cum->words += RS6000_ARG_SIZE (mode, type, 1);
+ {
+ cum->words += RS6000_ARG_SIZE (mode, type, 1);
+ if (GET_MODE_CLASS (mode) == MODE_FLOAT)
+ cum->sysv_fwords += RS6000_ARG_SIZE (mode, type, 1);
+ }
}
else
if (named)
@@ -1411,8 +1421,8 @@ function_arg_advance (cum, mode, type, n
if (TARGET_DEBUG_ARG)
fprintf (stderr,
- "function_adv: words = %2d, fregno = %2d, nargs = %4d, proto = %d, mode = %4s, named = %d, align = %d\n",
- cum->words, cum->fregno, cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode), named, align);
+ "function_adv: words = %2d, sysv_fwords = %2d, fregno = %2d, nargs = %4d, proto = %d, mode = %4s, named = %d, align = %d\n",
+ cum->words, cum->sysv_fwords, cum->fregno, cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode), named, align);
}
\f
/* Determine where to put an argument to a function.
@@ -1451,8 +1461,8 @@ function_arg (cum, mode, type, named)
if (TARGET_DEBUG_ARG)
fprintf (stderr,
- "function_arg: words = %2d, fregno = %2d, nargs = %4d, proto = %d, mode = %4s, named = %d, align = %d\n",
- cum->words, cum->fregno, cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode), named, align);
+ "function_arg: words = %2d, sysv_fwords = %2d, fregno = %2d, nargs = %4d, proto = %d, mode = %4s, named = %d, align = %d\n",
+ cum->words, cum->sysv_fwords, cum->fregno, cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode), named, align);
/* Return a marker to indicate whether CR1 needs to set or clear the bit that V.4
uses to say fp args were passed in registers. Assume that we don't need the
@@ -1522,14 +1532,14 @@ function_arg (cum, mode, type, named)
/* Long longs won't be split between register and stack;
FP arguments get passed on the stack if they didn't get a register. */
else if ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) &&
- (align_words + RS6000_ARG_SIZE (mode, type, named) > GP_ARG_NUM_REG
+ (align_words - cum->sysv_fwords + RS6000_ARG_SIZE (mode, type, named) > GP_ARG_NUM_REG
|| (GET_MODE_CLASS (mode) == MODE_FLOAT && TARGET_HARD_FLOAT)))
{
return NULL_RTX;
}
- else if (align_words < GP_ARG_NUM_REG)
- return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
+ else if (align_words - cum->sysv_fwords < GP_ARG_NUM_REG)
+ return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words - cum->sysv_fwords);
return NULL_RTX;
}
@@ -1626,21 +1636,24 @@ setup_incoming_varargs (cum, mode, type,
if (TARGET_DEBUG_ARG)
fprintf (stderr,
- "setup_vararg: words = %2d, fregno = %2d, nargs = %4d, proto = %d, mode = %4s, no_rtl= %d\n",
- cum->words, cum->fregno, cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode), no_rtl);
+ "setup_vararg: words = %2d, sysv_fwords = %2d, fregno = %2d, nargs = %4d, proto = %d, mode = %4s, no_rtl= %d\n",
+ cum->words, cum->sysv_fwords, cum->fregno, cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode), no_rtl);
if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
{
rs6000_sysv_varargs_p = 1;
if (! no_rtl)
- save_area = plus_constant (frame_pointer_rtx, RS6000_VARARGS_OFFSET);
+ {
+ save_area = plus_constant (virtual_stack_vars_rtx, -RS6000_VARARGS_SIZE);
+ (rtx) cum->save_area = save_area;
+ }
}
else
rs6000_sysv_varargs_p = 0;
- if (cum->words < 8)
+ if (cum->words - cum->sysv_fwords < 8)
{
- int first_reg_offset = cum->words;
+ int first_reg_offset = cum->words - cum->sysv_fwords;
if (MUST_PASS_IN_STACK (mode, type))
first_reg_offset += RS6000_ARG_SIZE (TYPE_MODE (type), type, 1);
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: PATCH: Fix 2 PPC/SYSV varargs problems
1999-04-30 0:09 PATCH: Fix 2 PPC/SYSV varargs problems Franz Sirl
@ 1999-04-30 2:48 ` Richard Henderson
1999-04-30 2:55 ` Zack Weinberg
1999-04-30 13:42 ` Franz Sirl
1999-05-12 6:19 ` Jeffrey A Law
1 sibling, 2 replies; 13+ messages in thread
From: Richard Henderson @ 1999-04-30 2:48 UTC (permalink / raw)
To: Franz Sirl, egcs-patches; +Cc: meissner, David Edelsohn, linuxppc-dev
On Fri, Apr 30, 1999 at 02:09:09AM +0200, Franz Sirl wrote:
> 1. the varargs save area calculation bug, this is a hack and Richard ;-)
> probably won't like it, but maybe it's good enough for egcs-1.2
You're right -- I hate it. You'll have made it so I can't build a
ppc cross compiler on my Alphas, and you'll have killed the compiler
for a ppc64-linux.
Here's an implementation of what I'd suggested before. It looks ok
to the eye, but I don't have a ppc-linux box handy to try it out on.
r~
* va-ppc.h (__va_start_common): Let __builtin_saveregs do the work.
* rs6000.c (expand_builtin_saveregs): For SYSV, initialize a private
va_list struct, and return a pointer to it.
Index: ginclude/va-ppc.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/ginclude/va-ppc.h,v
retrieving revision 1.4
diff -c -p -d -r1.4 va-ppc.h
*** va-ppc.h 1998/12/16 21:19:40 1.4
--- va-ppc.h 1999/04/30 02:45:30
*************** typedef struct {
*** 59,92 ****
((TYPE *) (void *) (&(((__va_regsave_t *) \
(AP)->reg_save_area)->__gp_save[(int)(AP)->gpr])))
! /* Common code for va_start for both varargs and stdarg. This depends
! on the format of rs6000_args in rs6000.h. The fields used are:
!
! #0 WORDS # words used for GP regs/stack values
! #1 FREGNO next available FP register
! #2 NARGS_PROTOTYPE # args left in the current prototype
! #3 ORIG_NARGS original value of NARGS_PROTOTYPE
! #4 VARARGS_OFFSET offset from frame pointer of varargs area */
!
! #define __va_words __builtin_args_info (0)
! #define __va_fregno __builtin_args_info (1)
! #define __va_nargs __builtin_args_info (2)
! #define __va_orig_nargs __builtin_args_info (3)
! #define __va_varargs_offset __builtin_args_info (4)
! #define __va_start_common(AP, FAKE) \
! __extension__ ({ \
! register int __words = __va_words - FAKE; \
! \
! (AP)->gpr = (__words < 8) ? __words : 8; \
! (AP)->fpr = __va_fregno - 33; \
! (AP)->reg_save_area = (((char *) __builtin_frame_address (0)) \
! + __va_varargs_offset); \
! __va_overflow(AP) = ((char *)__builtin_saveregs () \
! + (((__words >= 8) ? __words - 8 : 0) \
! * sizeof (long))); \
! (void)0; \
! })
#ifdef _STDARG_H /* stdarg.h support */
--- 59,71 ----
((TYPE *) (void *) (&(((__va_regsave_t *) \
(AP)->reg_save_area)->__gp_save[(int)(AP)->gpr])))
! /* Common code for va_start for both varargs and stdarg. We allow all
! the work to be done by __builtin_saveregs. It returns a pointer to
! a va_list that was constructed on the stack; we must simply copy it
! to the user's variable. */
! #define __va_start_common(AP, FAKE) \
! __builtin_memcpy ((AP), __builtin_saveregs (), sizeof(__gnuc_va_list))
#ifdef _STDARG_H /* stdarg.h support */
Index: config/rs6000/rs6000.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.66
diff -c -p -d -r1.66 rs6000.c
*** rs6000.c 1999/04/27 12:39:58 1.66
--- rs6000.c 1999/04/30 02:45:30
*************** setup_incoming_varargs (cum, mode, type,
*** 1704,1716 ****
On the Power/PowerPC return the address of the area on the stack
used to hold arguments. Under AIX, this includes the 8 word register
! save area. Under V.4 this does not. */
struct rtx_def *
expand_builtin_saveregs (args)
tree args ATTRIBUTE_UNUSED;
{
! return virtual_incoming_args_rtx;
}
\f
--- 1704,1786 ----
On the Power/PowerPC return the address of the area on the stack
used to hold arguments. Under AIX, this includes the 8 word register
! save area.
!
! Under V.4, things are more complicated. We do not have access to
! all of the virtual registers required for va_start to do its job,
! so we construct the va_list in its entirity here, and reduce va_start
! to a block copy. This is similar to the way we do things on Alpha. */
struct rtx_def *
expand_builtin_saveregs (args)
tree args ATTRIBUTE_UNUSED;
{
! rtx block, mem_gpr_fpr, mem_reg_save_area, mem_overflow, tmp;
! tree fntype;
! int stdarg_p;
! HOST_WIDE_INT words, gpr, fpr;
!
! if (DEFAULT_ABI != ABI_V4 && DEFAULT_ABI != ABI_SOLARIS)
! return virtual_incoming_args_rtx;
!
! fntype = TREE_TYPE (current_function_decl);
! stdarg_p = (TYPE_ARG_TYPES (fntype) != 0
! && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
! != void_type_node));
!
! /* Allocate the va_list constructor. */
! block = assign_stack_local (BLKmode, 3 * UNITS_PER_WORD, BITS_PER_WORD);
! RTX_UNCHANGING_P (block) = 1;
! RTX_UNCHANGING_P (XEXP (block, 0)) = 1;
!
! mem_gpr_fpr = change_address (block, word_mode, XEXP (block, 0));
! mem_overflow = change_address (block, ptr_mode,
! plus_constant (XEXP (block, 0),
! UNITS_PER_WORD));
! mem_reg_save_area = change_address (block, ptr_mode,
! plus_constant (XEXP (block, 0),
! 2 * UNITS_PER_WORD));
!
! /* Construct the two characters of `gpr' and `fpr' as a unit. */
! words = current_function_args_info.words - !stdarg_p;
! gpr = (words > 8 ? 8 : words);
! fpr = current_function_args_info.fregno - 33;
!
! if (BYTES_BIG_ENDIAN)
! {
! HOST_WIDE_INT bits = gpr << 8 | fpr;
! if (HOST_BITS_PER_WIDE_INT >= BITS_PER_WORD)
! tmp = GEN_INT (bits << (BITS_PER_WORD - 16));
! else
! {
! bits <<= BITS_PER_WORD - HOST_BITS_PER_WIDE_INT - 16;
! tmp = immed_double_const (0, bits, word_mode);
! }
! }
! else
! tmp = GEN_INT (fpr << 8 | gpr);
!
! emit_move_insn (mem_gpr_fpr, tmp);
!
! /* Find the overflow area. */
! if (words <= 8)
! tmp = virtual_incoming_args_rtx;
! else
! tmp = expand_binop (Pmode, add_optab, virtual_incoming_args_rtx,
! GEN_INT ((words - 8) * UNITS_PER_WORD),
! mem_overflow, 0, OPTAB_WIDEN);
! if (tmp != mem_overflow)
! emit_move_insn (mem_overflow, tmp);
!
! /* Find the register save area. */
! tmp = expand_binop (Pmode, add_optab, virtual_stack_vars_rtx,
! GEN_INT (-RS6000_VARARGS_SIZE),
! mem_reg_save_area, 0, OPTAB_WIDEN);
! if (tmp != mem_reg_save_area)
! emit_move_insn (mem_reg_save_area, tmp);
!
! /* Return the address of the va_list constructor. */
! return XEXP (block, 0);
}
\f
[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. Please check http://lists.linuxppc.org/ ]]
[[ and http://www.linuxppc.org/ for useful information before posting. ]]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: PATCH: Fix 2 PPC/SYSV varargs problems
1999-04-30 2:48 ` Richard Henderson
@ 1999-04-30 2:55 ` Zack Weinberg
1999-04-30 3:02 ` Richard Henderson
1999-04-30 4:49 ` Gary Thomas
1999-04-30 13:42 ` Franz Sirl
1 sibling, 2 replies; 13+ messages in thread
From: Zack Weinberg @ 1999-04-30 2:55 UTC (permalink / raw)
To: Richard Henderson; +Cc: meissner, David Edelsohn, linuxppc-dev
On Thu, 29 Apr 1999 19:48:17 -0700, Richard Henderson wrote:
>On Fri, Apr 30, 1999 at 02:09:09AM +0200, Franz Sirl wrote:
>> 1. the varargs save area calculation bug, this is a hack and Richard ;-)
>> probably won't like it, but maybe it's good enough for egcs-1.2
>
>You're right -- I hate it. You'll have made it so I can't build a
>ppc cross compiler on my Alphas, and you'll have killed the compiler
>for a ppc64-linux.
ObDumbQuestion: Is this a bug we really need to fix for 1.2? It's
been around for awhile and all the proposed solutions are either dirty
kludges or too invasive.
zw
[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. Please check http://lists.linuxppc.org/ ]]
[[ and http://www.linuxppc.org/ for useful information before posting. ]]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: PATCH: Fix 2 PPC/SYSV varargs problems
1999-04-30 2:55 ` Zack Weinberg
@ 1999-04-30 3:02 ` Richard Henderson
1999-04-30 3:08 ` David Edelsohn
1999-04-30 4:49 ` Gary Thomas
1 sibling, 1 reply; 13+ messages in thread
From: Richard Henderson @ 1999-04-30 3:02 UTC (permalink / raw)
To: Zack Weinberg; +Cc: meissner, David Edelsohn, linuxppc-dev
On Thu, Apr 29, 1999 at 10:55:36PM -0400, Zack Weinberg wrote:
> ObDumbQuestion: Is this a bug we really need to fix for 1.2? It's
> been around for awhile and all the proposed solutions are either dirty
> kludges or too invasive.
A reasonable question. Though I don't think my last patch is either.
It certainly isn't invasive; as for kludginess, it's in good company
with the way the alpha port has done things for a long time. Infer
what you will with that. ;-)
r~
[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. Please check http://lists.linuxppc.org/ ]]
[[ and http://www.linuxppc.org/ for useful information before posting. ]]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: PATCH: Fix 2 PPC/SYSV varargs problems
1999-04-30 3:02 ` Richard Henderson
@ 1999-04-30 3:08 ` David Edelsohn
0 siblings, 0 replies; 13+ messages in thread
From: David Edelsohn @ 1999-04-30 3:08 UTC (permalink / raw)
To: Richard Henderson, Franz Sirl
Cc: Zack Weinberg, meissner, linuxppc-dev, egcs-patches
>>>>> Richard Henderson writes:
Richard> It certainly isn't invasive; as for kludginess, it's in good company
Richard> with the way the alpha port has done things for a long time. Infer
Richard> what you will with that. ;-)
I am much more comfortable with a patch along the lines of
Richard's proposal -- both in the short term for egcs-1.2 release and as a
long-term solution. I do not think that there is an elegant way to fix
this.
David
[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. Please check http://lists.linuxppc.org/ ]]
[[ and http://www.linuxppc.org/ for useful information before posting. ]]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: PATCH: Fix 2 PPC/SYSV varargs problems
1999-04-30 2:55 ` Zack Weinberg
1999-04-30 3:02 ` Richard Henderson
@ 1999-04-30 4:49 ` Gary Thomas
1 sibling, 0 replies; 13+ messages in thread
From: Gary Thomas @ 1999-04-30 4:49 UTC (permalink / raw)
To: Zack Weinberg; +Cc: linuxppc-dev, David Edelsohn, meissner, Richard Henderson
On 30-Apr-99 Zack Weinberg wrote:
>
> On Thu, 29 Apr 1999 19:48:17 -0700, Richard Henderson wrote:
>>On Fri, Apr 30, 1999 at 02:09:09AM +0200, Franz Sirl wrote:
>>> 1. the varargs save area calculation bug, this is a hack and Richard ;-)
>>> probably won't like it, but maybe it's good enough for egcs-1.2
>>
>>You're right -- I hate it. You'll have made it so I can't build a
>>ppc cross compiler on my Alphas, and you'll have killed the compiler
>>for a ppc64-linux.
>
> ObDumbQuestion: Is this a bug we really need to fix for 1.2? It's
> been around for awhile and all the proposed solutions are either dirty
> kludges or too invasive.
>
It's a serious problem that has caused trouble in the past. Fixing it
would be very nice, indeed.
However, I provide a patch for the compiler that detects potential
occurrances and print a warning. At least it's not a slient killer.
------------------------------------------------------------------------
Gary Thomas |
email: gdt@linuxppc.org | "Fine wine is a necessity of
... opinions expressed here are mine | life for me"
and no one else would claim them! |
| Thomas Jefferson
------------------------------------------------------------------------
[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. Please check http://lists.linuxppc.org/ ]]
[[ and http://www.linuxppc.org/ for useful information before posting. ]]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: PATCH: Fix 2 PPC/SYSV varargs problems
1999-04-30 2:48 ` Richard Henderson
1999-04-30 2:55 ` Zack Weinberg
@ 1999-04-30 13:42 ` Franz Sirl
1999-04-30 22:08 ` Richard Henderson
1 sibling, 1 reply; 13+ messages in thread
From: Franz Sirl @ 1999-04-30 13:42 UTC (permalink / raw)
To: Richard Henderson; +Cc: egcs-patches, meissner, David Edelsohn, linuxppc-dev
At 04:48 30.04.99 , Richard Henderson wrote:
>On Fri, Apr 30, 1999 at 02:09:09AM +0200, Franz Sirl wrote:
> > 1. the varargs save area calculation bug, this is a hack and Richard ;-)
> > probably won't like it, but maybe it's good enough for egcs-1.2
>
>You're right -- I hate it. You'll have made it so I can't build a
>ppc cross compiler on my Alphas, and you'll have killed the compiler
>for a ppc64-linux.
Yes, thought so ;-).
>Here's an implementation of what I'd suggested before. It looks ok
>to the eye, but I don't have a ppc-linux box handy to try it out on.
Yes, this looks good (such a patch is certainly above my current knowledge
of egcs :-) ) and works fine on powerpc-linux-gnu, I just bootstrapped and
checked the mainline with it. You just missed a small bit in
setup_incoming_varargs():
if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
{
rs6000_sysv_varargs_p = 1;
if (! no_rtl)
- save_area = plus_constant (frame_pointer_rtx, RS6000_VARARGS_OFFSET);
+ save_area = plus_constant (virtual_stack_vars_rtx,
-RS6000_VARARGS_SIZE);
}
Can you check in this stuff in that shape? And maybe the second part (the
gnuplot fix) of my patch if it is OK and the testcase?
Franz
[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. Please check http://lists.linuxppc.org/ ]]
[[ and http://www.linuxppc.org/ for useful information before posting. ]]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: PATCH: Fix 2 PPC/SYSV varargs problems
1999-04-30 13:42 ` Franz Sirl
@ 1999-04-30 22:08 ` Richard Henderson
1999-05-03 12:44 ` Franz Sirl
0 siblings, 1 reply; 13+ messages in thread
From: Richard Henderson @ 1999-04-30 22:08 UTC (permalink / raw)
To: Franz Sirl; +Cc: egcs-patches, meissner, David Edelsohn, linuxppc-dev
> Can you check in this stuff in that shape?
Done.
> And maybe the second part (the
> gnuplot fix) of my patch if it is OK and the testcase?
I'll look at this again later tonight or tomorrow -- despite
the subject line, I'd missed the fact that you were trying to
fix two separate problems.
r~
[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. Please check http://lists.linuxppc.org/ ]]
[[ and http://www.linuxppc.org/ for useful information before posting. ]]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: PATCH: Fix 2 PPC/SYSV varargs problems
1999-04-30 22:08 ` Richard Henderson
@ 1999-05-03 12:44 ` Franz Sirl
0 siblings, 0 replies; 13+ messages in thread
From: Franz Sirl @ 1999-05-03 12:44 UTC (permalink / raw)
To: Richard Henderson; +Cc: egcs-patches, meissner, David Edelsohn, linuxppc-dev
At 00:08 01.05.99 , Richard Henderson wrote:
> > Can you check in this stuff in that shape?
>
>Done.
Thanks.
> > And maybe the second part (the
> > gnuplot fix) of my patch if it is OK and the testcase?
>
>I'll look at this again later tonight or tomorrow -- despite
>the subject line, I'd missed the fact that you were trying to
>fix two separate problems.
I did look at the argument handling again yesterday, and I now think there
might be additional bugs in the handling of CUMULATIVE_ARGS->words for the
SYSV ABI case. I'll try to construct testcases for the suspect cases.
Franz.
[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. Please check http://lists.linuxppc.org/ ]]
[[ and http://www.linuxppc.org/ for useful information before posting. ]]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: PATCH: Fix 2 PPC/SYSV varargs problems
1999-04-30 0:09 PATCH: Fix 2 PPC/SYSV varargs problems Franz Sirl
1999-04-30 2:48 ` Richard Henderson
@ 1999-05-12 6:19 ` Jeffrey A Law
1999-05-12 6:48 ` Richard Henderson
1 sibling, 1 reply; 13+ messages in thread
From: Jeffrey A Law @ 1999-05-12 6:19 UTC (permalink / raw)
To: Franz Sirl; +Cc: egcs-patches, rth, meissner, David Edelsohn, linuxppc-dev
In message <4.2.0.37.19990430013458.0489a950@mail.lauterbach.com>you write:
> --=====================_53744284==_
> Content-Type: text/plain; charset="us-ascii"; format=flowed
>
> Hi,
>
> this patch is supposed to fix the following problems on PPC/SYSV:
>
> 1. the varargs save area calculation bug, this is a hack and Richard ;-)
> probably won't like it, but maybe it's good enough for egcs-1.2
>
> 2. if you call a function that uses more then 8 float args before all
> integer argument passing registers are consumed, egcs will missetup the
> calling sequence. I introduced a new variable cum->sysv_fwords in the
> CUMULATIVE_ARGS struct, which counts the saved float words and adjusted
> cum->words where needed (I hope). There maybe better/nicer ways to
> implement that, so tell me if you want a different solution. A testcase is
> attached, the original problem happens with gnuplot.
Has this problem been fixed? I see patch from Richard which looks like it
is related:
* va-ppc.h (__va_start_common): Let __builtin_saveregs do the work.
* rs6000.c (expand_builtin_saveregs): For V4, initialize a private
va_list struct, and return a pointer to it.
(setup_incoming_varargs): V4 save area based off virtual_stack_vars
instead of frame_pointer.
[ yes, I'm going through my backlog now trying to weed out issues that I
don't need to deal with :-) ]
jeff
[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. Please check http://lists.linuxppc.org/ ]]
[[ and http://www.linuxppc.org/ for useful information before posting. ]]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: PATCH: Fix 2 PPC/SYSV varargs problems
1999-05-12 6:19 ` Jeffrey A Law
@ 1999-05-12 6:48 ` Richard Henderson
1999-05-12 10:21 ` Franz Sirl
1999-05-12 15:24 ` David Edelsohn
0 siblings, 2 replies; 13+ messages in thread
From: Richard Henderson @ 1999-05-12 6:48 UTC (permalink / raw)
To: law, Franz Sirl; +Cc: egcs-patches, meissner, David Edelsohn, linuxppc-dev
On Wed, May 12, 1999 at 12:19:53AM -0600, Jeffrey A Law wrote:
> Has this problem been fixed? I see patch from Richard which looks like it
> is related:
No, this is a different, though related, problem. I need to sit
down with the ABI to properly evaluate the patch. PPC SVR4 varargs
seems needlessly complex.
Franz, could you point me at the test cases for this?
r~
[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. Please check http://lists.linuxppc.org/ ]]
[[ and http://www.linuxppc.org/ for useful information before posting. ]]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: PATCH: Fix 2 PPC/SYSV varargs problems
1999-05-12 6:48 ` Richard Henderson
@ 1999-05-12 10:21 ` Franz Sirl
1999-05-12 15:24 ` David Edelsohn
1 sibling, 0 replies; 13+ messages in thread
From: Franz Sirl @ 1999-05-12 10:21 UTC (permalink / raw)
To: Richard Henderson
Cc: law, egcs-patches, meissner, David Edelsohn, linuxppc-dev
At 08:48 12.05.99 , Richard Henderson wrote:
>On Wed, May 12, 1999 at 12:19:53AM -0600, Jeffrey A Law wrote:
> > Has this problem been fixed? I see patch from Richard which looks like it
> > is related:
>
>No, this is a different, though related, problem. I need to sit
>down with the ABI to properly evaluate the patch. PPC SVR4 varargs
>seems needlessly complex.
To me it looked more like some 95%-finished stuff with untested corner cases.
>Franz, could you point me at the test cases for this?
Oops, sure. I meant them to attach to my last mail, which contained my new
patch fixing both problems below.
Thanks again for your expand_builtin_saveregs() patch, it makes life a lot
easier on PPC :-).
Franz.
-----< testcase1
/* this testcase is a modified testcase from execute/980608-1.c.
It additionally tests the handling of float args. The varargs
handling on SYSV ABI contained a bug where using more than 8 float
args before all GP regs were consumed caused a wrong stack/register
layout to be passed by the caller. The overflowed (not fitting in FP
registers) float args virtually consumed args fitting in GP regs (counted
by cum->words).
This was uncovered in real world by gnuplot.
*/
#include <stdarg.h>
static int test=23;
void f1(int a1,int a2,int a3,int a4,int a5, int a6,int a7,int a8,int a9,
int a10)
{
test = a9;
return;
}
inline void debug(const char *fp,const char *msg,...)
{
int local_var[10] = {10,};
va_list ap;
double df;
local_var[0] += test;
if (*fp != '1')
abort();
if (*msg != '2')
abort();
f1(1,2,3,4,5,6,7,8,9,local_var[0]);
va_start( ap, msg );
df = va_arg(ap,double);
if (df <1.09 || df >1.11)
abort();
df = va_arg(ap,double);
if (df <1.19 || df >1.21)
abort();
df = va_arg(ap,double);
if (df <1.29 || df >1.31)
abort();
df = va_arg(ap,double);
if (df <1.39 || df >1.41)
abort();
df = va_arg(ap,double);
if (df <1.49 || df >1.51)
abort();
if ( *va_arg(ap,char*) != '3')
abort();
if ( *va_arg(ap,char*) != '4')
abort();
if ( *va_arg(ap,char*) != '5')
abort();
df = va_arg(ap,double);
if (df <1.59 || df >1.61)
abort();
df = va_arg(ap,double);
if (df <1.69 || df >1.71)
abort();
df = va_arg(ap,double);
if (df <1.79 || df >1.81)
abort();
df = va_arg(ap,double);
if (df <1.89 || df >1.91)
abort();
if ( va_arg(ap,int) != 101)
abort();
if ( va_arg(ap,int) != 102)
abort();
if ( va_arg(ap,int) != 103)
abort();
if ( va_arg(ap,int) != 104)
abort();
if ( *va_arg(ap,char*) != '6')
abort();
if ( va_arg(ap,int) != 105)
abort();
if ( va_arg(ap,int) != 106)
abort();
if ( va_arg(ap,int) != 107)
abort();
if ( va_arg(ap,int) != 108)
abort();
if ( va_arg(ap,int) != 109)
abort();
if ( va_arg(ap,int) != 110)
abort();
va_end( ap );
}
int main(void)
{
debug("1 filepointer", "2 format", 1.1,1.2,1.3,1.4,1.5, "3","4","5",
1.6,1.7,1.8,1.9, 101,102,103,104, "6", 105,106,107,108,109,110);
exit(0);
}
-----< testcase1
-----< testcase2
/* Yet another bug in PPC/SYSV ABI varargs handling.
If the float args overflowed from FP regs into stack space before the
varargs started, the calculation of the overflow_area pointer in va_list
was buggy.
Not uncovered in real world (yet?), constructed by staring at the varargs
code.
*/
#include <stdarg.h>
inline void debug2(const char *fp,
double d1,double d2,double d3,double d4,
double d5,double d6,double d7,double d8,double d9,
const char *msg,...)
{
va_list ap;
double df;
if (*fp != '1')
abort();
if (*msg != '2')
abort();
va_start( ap, msg );
df = va_arg(ap,double);
if (df <1.09 || df >1.11)
abort();
df = va_arg(ap,double);
if (df <1.19 || df >1.21)
abort();
df = va_arg(ap,double);
if (df <1.29 || df >1.31)
abort();
df = va_arg(ap,double);
if (df <1.39 || df >1.41)
abort();
df = va_arg(ap,double);
if (df <1.49 || df >1.51)
abort();
if ( *va_arg(ap,char*) != '3')
abort();
if ( *va_arg(ap,char*) != '4')
abort();
if ( *va_arg(ap,char*) != '5')
abort();
df = va_arg(ap,double);
if (df <1.59 || df >1.61)
abort();
df = va_arg(ap,double);
if (df <1.69 || df >1.71)
abort();
df = va_arg(ap,double);
if (df <1.79 || df >1.81)
abort();
df = va_arg(ap,double);
if (df <1.89 || df >1.91)
abort();
if ( va_arg(ap,int) != 101)
abort();
if ( va_arg(ap,int) != 102)
abort();
if ( va_arg(ap,int) != 103)
abort();
if ( va_arg(ap,int) != 104)
abort();
if ( *va_arg(ap,char*) != '6')
abort();
if ( va_arg(ap,int) != 105)
abort();
if ( va_arg(ap,int) != 106)
abort();
if ( va_arg(ap,int) != 107)
abort();
if ( va_arg(ap,int) != 108)
abort();
if ( va_arg(ap,int) != 109)
abort();
df = va_arg(ap,double);
if (df <1.99 || df >2.01)
abort();
if ( va_arg(ap,int) != 110)
abort();
va_end( ap );
}
int main(void)
{
debug2("1 filepointer", 20.1,20.2,20.3,20.4,20.5,20.6,20.7,20.8,20.9,
"2 format", 1.1,1.2,1.3,1.4,1.5, "3","4","5", 1.6,1.7,1.8,1.9,
101,102,103,104, "6", 105,106,107,108,109, 2.0, 110);
exit(0);
}
-----< testcase2
[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. Please check http://lists.linuxppc.org/ ]]
[[ and http://www.linuxppc.org/ for useful information before posting. ]]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: PATCH: Fix 2 PPC/SYSV varargs problems
1999-05-12 6:48 ` Richard Henderson
1999-05-12 10:21 ` Franz Sirl
@ 1999-05-12 15:24 ` David Edelsohn
1 sibling, 0 replies; 13+ messages in thread
From: David Edelsohn @ 1999-05-12 15:24 UTC (permalink / raw)
To: Richard Henderson; +Cc: law, Franz Sirl, egcs-patches, meissner, linuxppc-dev
>>>>> Richard Henderson writes:
Richard> On Wed, May 12, 1999 at 12:19:53AM -0600, Jeffrey A Law wrote:
>> Has this problem been fixed? I see patch from Richard which looks like it
>> is related:
Richard> No, this is a different, though related, problem. I need to sit
Richard> down with the ABI to properly evaluate the patch. PPC SVR4 varargs
Richard> seems needlessly complex.
That is an understatement! PPC SVR4 varargs is a monstrosity that
attempted to pack the registers as tightly as possible and created an
endless mess as a result.
David
[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. Please check http://lists.linuxppc.org/ ]]
[[ and http://www.linuxppc.org/ for useful information before posting. ]]
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~1999-05-12 15:24 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
1999-04-30 0:09 PATCH: Fix 2 PPC/SYSV varargs problems Franz Sirl
1999-04-30 2:48 ` Richard Henderson
1999-04-30 2:55 ` Zack Weinberg
1999-04-30 3:02 ` Richard Henderson
1999-04-30 3:08 ` David Edelsohn
1999-04-30 4:49 ` Gary Thomas
1999-04-30 13:42 ` Franz Sirl
1999-04-30 22:08 ` Richard Henderson
1999-05-03 12:44 ` Franz Sirl
1999-05-12 6:19 ` Jeffrey A Law
1999-05-12 6:48 ` Richard Henderson
1999-05-12 10:21 ` Franz Sirl
1999-05-12 15:24 ` David Edelsohn
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).