diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c9bf259a4bd..68eeab47a78 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2002-03-09 Alexandre Oliva + * config/mips/mips.c (function_arg_pass_by_reference): Force to 0 + in o32 and o64 ABIs. + * config/mips/abi64.h (MUST_PASS_IN_STACK): Define as in expr.h, + but getting fixed-size structs passed in registers regardless of + padding in o32 and o64 ABIs. + * config/mips/mips.c (mips_va_arg): Apply big-endianness address offset before loading address of argument passed by transparent reference. diff --git a/gcc/config/mips/abi64.h b/gcc/config/mips/abi64.h index 43887d532f5..653571792ed 100644 --- a/gcc/config/mips/abi64.h +++ b/gcc/config/mips/abi64.h @@ -86,6 +86,19 @@ Boston, MA 02111-1307, USA. */ || GET_MODE_CLASS (MODE) == MODE_INT))) \ ? downward : upward)) +/* Modified version of the macro in expr.h. */ +#define MUST_PASS_IN_STACK(MODE,TYPE) \ + ((TYPE) != 0 \ + && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST \ + || TREE_ADDRESSABLE (TYPE) \ + || ((MODE) == BLKmode \ + && mips_abi != ABI_32 && mips_abi != ABI_O64 \ + && ! ((TYPE) != 0 && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \ + && 0 == (int_size_in_bytes (TYPE) \ + % (PARM_BOUNDARY / BITS_PER_UNIT))) \ + && (FUNCTION_ARG_PADDING (MODE, TYPE) \ + == (BYTES_BIG_ENDIAN ? upward : downward))))) + /* Under the old (i.e., 32 and O64 ABIs) all BLKmode objects are returned in memory. Under the new (N32 and 64-bit MIPS ABIs) small structures are returned in a register. Objects with varying size diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 6cdbda5c8b2..72a1e9c1ac9 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -8069,6 +8069,9 @@ function_arg_pass_by_reference (cum, mode, type, named) { int size; + if (mips_abi == ABI_32 || mips_abi == ABI_O64) + return 0; + /* We must pass by reference if we would be both passing in registers and the stack. This is because any subsequent partial arg would be handled incorrectly in this case.