Commit b11a9d5f by Richard Sandiford Committed by Richard Sandiford

mips.h (struct mips_args): Clarify comments.

	* config/mips/mips.h (struct mips_args): Clarify comments.
	* config/mips/mips.c (struct mips_arg_info): Likewise.
	(mips_arg_info): Don't allow fpr_p to affect the register or
	stack alignment.  Remove o64 silliness.
	(function_arg): Deal with the o32 float,float case specially.

From-SVN: r88090
parent 03eccdc8
2004-09-25 Richard Sandiford <rsandifo@redhat.com> 2004-09-25 Richard Sandiford <rsandifo@redhat.com>
* config/mips/mips.h (struct mips_args): Clarify comments.
* config/mips/mips.c (struct mips_arg_info): Likewise.
(mips_arg_info): Don't allow fpr_p to affect the register or
stack alignment. Remove o64 silliness.
(function_arg): Deal with the o32 float,float case specially.
2004-09-25 Richard Sandiford <rsandifo@redhat.com>
* config/mips/mips.md (loadx, storex): Define for V2SF. * config/mips/mips.md (loadx, storex): Define for V2SF.
2004-09-25 Ulrich Weigand <uweigand@de.ibm.com> 2004-09-25 Ulrich Weigand <uweigand@de.ibm.com>
......
...@@ -419,8 +419,12 @@ struct mips_arg_info ...@@ -419,8 +419,12 @@ struct mips_arg_info
/* The number of words passed in registers, rounded up. */ /* The number of words passed in registers, rounded up. */
unsigned int reg_words; unsigned int reg_words;
/* The offset of the first register from GP_ARG_FIRST or FP_ARG_FIRST, /* For EABI, the offset of the first register from GP_ARG_FIRST or
or MAX_ARGS_IN_REGISTERS if the argument is passed entirely FP_ARG_FIRST. For other ABIs, the offset of the first register from
the start of the ABI's argument structure (see the CUMULATIVE_ARGS
comment for details).
The value is MAX_ARGS_IN_REGISTERS if the argument is passed entirely
on the stack. */ on the stack. */
unsigned int reg_offset; unsigned int reg_offset;
...@@ -3046,7 +3050,7 @@ static void ...@@ -3046,7 +3050,7 @@ static void
mips_arg_info (const CUMULATIVE_ARGS *cum, enum machine_mode mode, mips_arg_info (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
tree type, int named, struct mips_arg_info *info) tree type, int named, struct mips_arg_info *info)
{ {
bool even_reg_p; bool doubleword_aligned_p;
unsigned int num_bytes, num_words, max_regs; unsigned int num_bytes, num_words, max_regs;
/* Work out the size of the argument. */ /* Work out the size of the argument. */
...@@ -3123,27 +3127,10 @@ mips_arg_info (const CUMULATIVE_ARGS *cum, enum machine_mode mode, ...@@ -3123,27 +3127,10 @@ mips_arg_info (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
gcc_unreachable (); gcc_unreachable ();
} }
/* Now decide whether the argument must go in an even-numbered register. /* See whether the argument has doubleword alignment. */
Usually this is determined by type alignment, but there are two doubleword_aligned_p = (type
exceptions: ? TYPE_ALIGN (type) > BITS_PER_WORD
: GET_MODE_UNIT_SIZE (mode) > UNITS_PER_WORD);
- Under the O64 ABI, the second float argument goes in $f14 if it
is single precision (doubles go in $f13 as expected).
- Floats passed in FPRs must be in an even-numbered register if
we're using paired FPRs. */
if (type)
even_reg_p = TYPE_ALIGN (type) > BITS_PER_WORD;
else
even_reg_p = GET_MODE_UNIT_SIZE (mode) > UNITS_PER_WORD;
if (info->fpr_p)
{
if (mips_abi == ABI_O64 && mode == SFmode)
even_reg_p = true;
if (FP_INC > 1)
even_reg_p = true;
}
/* Set REG_OFFSET to the register count we're interested in. /* Set REG_OFFSET to the register count we're interested in.
The EABI allocates the floating-point registers separately, The EABI allocates the floating-point registers separately,
...@@ -3152,12 +3139,13 @@ mips_arg_info (const CUMULATIVE_ARGS *cum, enum machine_mode mode, ...@@ -3152,12 +3139,13 @@ mips_arg_info (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
? cum->num_fprs ? cum->num_fprs
: cum->num_gprs); : cum->num_gprs);
if (even_reg_p) /* Advance to an even register if the argument is doubleword-aligned. */
if (doubleword_aligned_p)
info->reg_offset += info->reg_offset & 1; info->reg_offset += info->reg_offset & 1;
/* The alignment applied to registers is also applied to stack arguments. */ /* Work out the offset of a stack argument. */
info->stack_offset = cum->stack_words; info->stack_offset = cum->stack_words;
if (even_reg_p) if (doubleword_aligned_p)
info->stack_offset += info->stack_offset & 1; info->stack_offset += info->stack_offset & 1;
max_regs = MAX_ARGS_IN_REGISTERS - info->reg_offset; max_regs = MAX_ARGS_IN_REGISTERS - info->reg_offset;
...@@ -3311,10 +3299,14 @@ function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode, ...@@ -3311,10 +3299,14 @@ function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
return gen_rtx_PARALLEL (mode, gen_rtvec (2, real, imag)); return gen_rtx_PARALLEL (mode, gen_rtvec (2, real, imag));
} }
if (info.fpr_p) if (!info.fpr_p)
return gen_rtx_REG (mode, FP_ARG_FIRST + info.reg_offset);
else
return gen_rtx_REG (mode, GP_ARG_FIRST + info.reg_offset); return gen_rtx_REG (mode, GP_ARG_FIRST + info.reg_offset);
else if (info.reg_offset == 1)
/* This code handles the special o32 case in which the second word
of the argument structure is passed in floating-point registers. */
return gen_rtx_REG (mode, FP_ARG_FIRST + FP_INC);
else
return gen_rtx_REG (mode, FP_ARG_FIRST + info.reg_offset);
} }
......
...@@ -2180,11 +2180,11 @@ extern enum reg_class mips_char_to_class[256]; ...@@ -2180,11 +2180,11 @@ extern enum reg_class mips_char_to_class[256];
&& !fixed_regs[N]) && !fixed_regs[N])
/* This structure has to cope with two different argument allocation /* This structure has to cope with two different argument allocation
schemes. Most MIPS ABIs view the arguments as a struct, of which the schemes. Most MIPS ABIs view the arguments as a structure, of which
first N words go in registers and the rest go on the stack. If I < N, the first N words go in registers and the rest go on the stack. If I
the Ith word might go in Ith integer argument register or the < N, the Ith word might go in Ith integer argument register or in a
Ith floating-point one. For these ABIs, we only need to remember floating-point register. For these ABIs, we only need to remember
the number of words passed so far. the offset of the current argument into the structure.
The EABI instead allocates the integer and floating-point arguments The EABI instead allocates the integer and floating-point arguments
separately. The first N words of FP arguments go in FP registers, separately. The first N words of FP arguments go in FP registers,
...@@ -2212,9 +2212,9 @@ typedef struct mips_args { ...@@ -2212,9 +2212,9 @@ typedef struct mips_args {
/* The number of arguments seen so far. */ /* The number of arguments seen so far. */
unsigned int arg_number; unsigned int arg_number;
/* For EABI, the number of integer registers used so far. For other /* The number of integer registers used so far. For all ABIs except
ABIs, the number of words passed in registers (whether integer EABI, this is the number of words that have been added to the
or floating-point). */ argument structure, limited to MAX_ARGS_IN_REGISTERS. */
unsigned int num_gprs; unsigned int num_gprs;
/* For EABI, the number of floating-point registers used so far. */ /* For EABI, the number of floating-point registers used so far. */
......
2004-09-25 Richard Sandiford <rsandifo@redhat.com>
* gcc.c-torture/execute/va-arg-26.c: New test.
2004-09-24 Zack Weinberg <zack@codesourcery.com> 2004-09-24 Zack Weinberg <zack@codesourcery.com>
* objc.dg/proto-lossage-4.m: Use long instead of int to avoid * objc.dg/proto-lossage-4.m: Use long instead of int to avoid
......
#include <stdarg.h>
double f (float f1, float f2, float f3, float f4,
float f5, float f6, ...)
{
va_list ap;
double d;
va_start (ap, f6);
d = va_arg (ap, double);
va_end (ap);
return d;
}
int main ()
{
if (f (1, 2, 3, 4, 5, 6, 7.0) != 7.0)
abort ();
exit (0);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment