aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/mips
diff options
context:
space:
mode:
authorRichard Sandiford <rsandifo@redhat.com>2004-09-25 07:42:43 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2004-09-25 07:42:43 +0000
commitb11a9d5f3f9026dea9508e77eeeeffd28b5ae9dc (patch)
tree90430116073fbf3b6c8a83d28cfa69b716288c73 /gcc/config/mips
parent03eccdc8ffdc4c9fec9df4c1e7f8e5392478d7f9 (diff)
downloadgcc-b11a9d5f3f9026dea9508e77eeeeffd28b5ae9dc.zip
gcc-b11a9d5f3f9026dea9508e77eeeeffd28b5ae9dc.tar.gz
gcc-b11a9d5f3f9026dea9508e77eeeeffd28b5ae9dc.tar.bz2
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
Diffstat (limited to 'gcc/config/mips')
-rw-r--r--gcc/config/mips/mips.c52
-rw-r--r--gcc/config/mips/mips.h16
2 files changed, 30 insertions, 38 deletions
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index a1de622..242c2f7 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -419,8 +419,12 @@ struct mips_arg_info
/* The number of words passed in registers, rounded up. */
unsigned int reg_words;
- /* The offset of the first register from GP_ARG_FIRST or FP_ARG_FIRST,
- or MAX_ARGS_IN_REGISTERS if the argument is passed entirely
+ /* For EABI, the offset of the first register from GP_ARG_FIRST or
+ 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. */
unsigned int reg_offset;
@@ -3046,7 +3050,7 @@ static void
mips_arg_info (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
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;
/* Work out the size of the argument. */
@@ -3123,27 +3127,10 @@ mips_arg_info (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
gcc_unreachable ();
}
- /* Now decide whether the argument must go in an even-numbered register.
- Usually this is determined by type alignment, but there are two
- exceptions:
-
- - 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;
- }
+ /* See whether the argument has doubleword alignment. */
+ doubleword_aligned_p = (type
+ ? TYPE_ALIGN (type) > BITS_PER_WORD
+ : GET_MODE_UNIT_SIZE (mode) > UNITS_PER_WORD);
/* Set REG_OFFSET to the register count we're interested in.
The EABI allocates the floating-point registers separately,
@@ -3152,12 +3139,13 @@ mips_arg_info (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
? cum->num_fprs
: 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;
- /* 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;
- if (even_reg_p)
+ if (doubleword_aligned_p)
info->stack_offset += info->stack_offset & 1;
max_regs = MAX_ARGS_IN_REGISTERS - info->reg_offset;
@@ -3311,10 +3299,14 @@ function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
return gen_rtx_PARALLEL (mode, gen_rtvec (2, real, imag));
}
- if (info.fpr_p)
- return gen_rtx_REG (mode, FP_ARG_FIRST + info.reg_offset);
- else
+ if (!info.fpr_p)
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);
}
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index dbae270..fbfdc1f 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -2180,11 +2180,11 @@ extern enum reg_class mips_char_to_class[256];
&& !fixed_regs[N])
/* This structure has to cope with two different argument allocation
- schemes. Most MIPS ABIs view the arguments as a struct, of which the
- first N words go in registers and the rest go on the stack. If I < N,
- the Ith word might go in Ith integer argument register or the
- Ith floating-point one. For these ABIs, we only need to remember
- the number of words passed so far.
+ schemes. Most MIPS ABIs view the arguments as a structure, of which
+ the first N words go in registers and the rest go on the stack. If I
+ < N, the Ith word might go in Ith integer argument register or in a
+ floating-point register. For these ABIs, we only need to remember
+ the offset of the current argument into the structure.
The EABI instead allocates the integer and floating-point arguments
separately. The first N words of FP arguments go in FP registers,
@@ -2212,9 +2212,9 @@ typedef struct mips_args {
/* The number of arguments seen so far. */
unsigned int arg_number;
- /* For EABI, the number of integer registers used so far. For other
- ABIs, the number of words passed in registers (whether integer
- or floating-point). */
+ /* The number of integer registers used so far. For all ABIs except
+ EABI, this is the number of words that have been added to the
+ argument structure, limited to MAX_ARGS_IN_REGISTERS. */
unsigned int num_gprs;
/* For EABI, the number of floating-point registers used so far. */