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

Michael Snyder
2002-08-02T01:32:56Z

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?

Michael