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

Daniel Jacobowitz
2002-08-02T01:57:31Z

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.

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