Re: [RFC] Mips, N32, cc, gcc, and gdb (longish)

Daniel Jacobowitz
2002-08-02T02:45:52Z

On Thu, Aug 01, 2002 at 07:24:16PM -0700, Michael Snyder wrote:
> Daniel Jacobowitz wrote:
> >
> > On Thu, Aug 01, 2002 at 06:14:32PM -0700, Michael Snyder wrote:
> > > OK, I think I've made this as concise as practical. ;-)
> > >
> > > In case the difference between Irix cc and gcc does not get
> > > fixed (and I mean specifically the difference concerning
> > > alignment of small struct arguments), I'd like to discuss
> > > "fixing" gdb so that it will work correctly with both.
> > >
> > > I've found a testcase for this problem in call-ar-st.exp:
> > >
> > > (gdb) print print_long_arg_list (a, b, c, d, e, f, *struct1,
> > > *struct2, *struct3, *struct4, *flags, *flags_combo,
> > > *three_char, *five_char, *int_char_combo,
> > > *d1, *d2, *d3, *f1, *f2, *f3)
> > >
> > > This fails (or doesn't) depending on whether a small struct
> > > is left-justified or right-justified when it is pushed onto
> > > the stack (ie, when it is the 5th or higher argument).
> > >
> > > The code in mips_push_arguments that controls this is:
> > >
> > > if (MIPS_STACK_ARGSIZE == 8 &&
> > > (typecode == TYPE_CODE_INT ||
> > > typecode == TYPE_CODE_PTR ||
> > > typecode == TYPE_CODE_FLT) && len <= 4)
> > > longword_offset = MIPS_STACK_ARGSIZE - len;
> > > else if ((typecode == TYPE_CODE_STRUCT ||
> > > typecode == TYPE_CODE_UNION) &&
> > > TYPE_LENGTH (arg_type) < MIPS_STACK_ARGSIZE)
> > > longword_offset = MIPS_STACK_ARGSIZE - len;
> > > }
> > >
> > > As it is written, it "works" with gcc but fails with cc.
> > >
> > > Kevin proposed this change to me (I don't remember if
> > > he has submitted it yet):
> > >
> > > ***
> > > typecode == TYPE_CODE_UNION) &&
> > > ! TYPE_LENGTH (arg_type) < MIPS_STACK_ARGSIZE)
> > > longword_offset = MIPS_STACK_ARGSIZE - len;
> > > ---
> > > typecode == TYPE_CODE_UNION) &&
> > > ! TYPE_LENGTH (arg_type) < MIPS_STACK_ARGSIZE
> > > ! && tdep->mips_abi != MIPS_ABI_N32)
> > > longword_offset = MIPS_STACK_ARGSIZE - len;
> > > ***
> > >
> > > With this change, it "works" with cc, but fails with gcc.
> > >
> > > I want to discuss the following change, which should
> > > make it "work" with both cc and gcc (given the current
> > > behavior of both):
> > >
> > > ***
> > > typecode == TYPE_CODE_UNION) &&
> > > ! TYPE_LENGTH (arg_type) < MIPS_STACK_ARGSIZE)
> > > longword_offset = MIPS_STACK_ARGSIZE - len;
> > > ---
> > > typecode == TYPE_CODE_UNION) &&
> > > ! TYPE_LENGTH (arg_type) < MIPS_STACK_ARGSIZE
> > > ! && (gcc_p ||tdep->mips_abi != MIPS_ABI_N32))
> > > longword_offset = MIPS_STACK_ARGSIZE - len;
> > > ***
> > >
> > >
> > > This of course makes gdb's behavior dependent on which
> > > compiler it detects.
> > >
> > > There is one problem: there is no variable "gcc_p" within
> > > the scope of mips_push_arguments, because PUSH_ARGUMENTS
> > > does not pass it. So that would need to be solved,
> > > possibly by modifying the definition of PUSH_ARGUMENTS.
> > >
> > > Comments?
> >
> > Comment - you're on a slippery slope. I know of at least one other
> > variation in this area; for structures of less than a word SGI CC
> > shifts them in register only for big endian targets, and not for little
> > endian (on the old versions of CC which support little endian). There
> > comes a point where we just need to get GCC fixed, and I think this is
> > it.
>
> Right -- but this thread concerns what to do if that DOESN'T happen.
>
> In answer to your comment, I believe the code currently in GDB
> already handles the case you describe, both for CC and for GCC.
> So what I'm discussing here will bring stack-passing into line
> with register-passing.
>
> However, you may be right that I need to check for endian-ness
> in my proposed change. I haven't tested that.

I'm not actually sure if it's the same if statement. Certainly GDB and
GCC do not agree on mipsel-linux.

I'd say the proper thing to do is to see that GCC is fixed, not to lay
contingency plans...

--
Daniel Jacobowitz Carnegie Mellon University
MontaVista Software Debian GNU/Linux Developer