From f7dbd2895e0b726e86cc0745815209a014e27f99 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Fri, 7 May 2004 15:09:23 +0000 Subject: [PATCH] mips.c (mips_va_arg): Fix calculation of osize for EABI_FLOAT_VARARGS_P. * config/mips/mips.c (mips_va_arg): Fix calculation of osize for EABI_FLOAT_VARARGS_P. From-SVN: r81625 --- gcc/ChangeLog | 5 ++++ gcc/config/mips/mips.c | 53 +++++++++++++++++++++++++++--------------- 2 files changed, 39 insertions(+), 19 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6c3ba6ddaf2..5b036b28e81 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2004-05-07 Richard Sandiford + + * config/mips/mips.c (mips_va_arg): Fix calculation of osize for + EABI_FLOAT_VARARGS_P. + 2004-05-07 Richard Sandiford * config/mips/mips.h (ISA_HAS_BRANCHLIKELY): Remove TARGET_MIPS5500. diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 09d826a94d7..2925ffd3d96 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -4133,8 +4133,6 @@ mips_va_arg (tree valist, tree type) rsize = UNITS_PER_WORD; } - addr_rtx = gen_reg_rtx (Pmode); - if (!EABI_FLOAT_VARARGS_P) { /* Case of all args in a merged stack. No need to check bounds, @@ -4157,12 +4155,12 @@ mips_va_arg (tree valist, tree type) /* Emit code to set addr_rtx to the valist, and postincrement the valist by the size of the argument, rounded up to the - next word. */ + next word. Account for padding on big-endian targets. */ t = build (POSTINCREMENT_EXPR, TREE_TYPE (gpr), gpr, size_int (rsize)); - r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL); - if (r != addr_rtx) - emit_move_insn (addr_rtx, r); + addr_rtx = expand_expr (t, 0, Pmode, EXPAND_NORMAL); + if (BYTES_BIG_ENDIAN) + addr_rtx = plus_constant (addr_rtx, rsize - size); /* Flush the POSTINCREMENT. */ emit_queue(); @@ -4176,6 +4174,8 @@ mips_va_arg (tree valist, tree type) rtx lab_over = NULL_RTX, lab_false; HOST_WIDE_INT osize; + addr_rtx = gen_reg_rtx (Pmode); + f_ovfl = TYPE_FIELDS (va_list_type_node); f_gtop = TREE_CHAIN (f_ovfl); f_ftop = TREE_CHAIN (f_gtop); @@ -4226,6 +4226,25 @@ mips_va_arg (tree valist, tree type) each one will take up UNITS_PER_HWFPVALUE bytes, regardless of the float's precision. */ rsize = UNITS_PER_HWFPVALUE; + + /* Overflow arguments are padded to UNITS_PER_WORD bytes + (= PARM_BOUNDARY bits). This can be different from RSIZE + in two cases: + + (1) On 32-bit targets when TYPE is a structure such as: + + struct s { float f; }; + + Such structures are passed in paired FPRs, so RSIZE + will be 8 bytes. However, the structure only takes + up 4 bytes of memory, so OSIZE will only be 4. + + (2) In combinations such as -mgp64 -msingle-float + -fshort-double. Doubles passed in registers + will then take up 4 (UNITS_PER_HWFPVALUE) bytes, + but those passed on the stack take up + UNITS_PER_WORD bytes. */ + osize = MAX (GET_MODE_SIZE (TYPE_MODE (type)), UNITS_PER_WORD); } else { @@ -4239,14 +4258,8 @@ mips_va_arg (tree valist, tree type) t = build (MODIFY_EXPR, TREE_TYPE (off), off, t); expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); } + osize = rsize; } - /* Every overflow argument must take up at least UNITS_PER_WORD - bytes (= PARM_BOUNDARY bits). RSIZE can sometimes be smaller - than that, such as in the combination -mgp64 -msingle-float - -fshort-double. Doubles passed in registers will then take - up UNITS_PER_HWFPVALUE bytes, but those passed on the stack - take up UNITS_PER_WORD bytes. */ - osize = MAX (rsize, UNITS_PER_WORD); /* [2] Emit code to branch if off == 0. */ r = expand_expr (off, NULL_RTX, TYPE_MODE (TREE_TYPE (off)), @@ -4254,8 +4267,12 @@ mips_va_arg (tree valist, tree type) emit_cmp_and_jump_insns (r, const0_rtx, EQ, const1_rtx, GET_MODE (r), 1, lab_false); - /* [4] Emit code for: addr_rtx = top - off. */ + /* [4] Emit code for: addr_rtx = top - off. On big endian machines, + the argument has RSIZE - SIZE bytes of leading padding. */ t = build (MINUS_EXPR, TREE_TYPE (top), top, off); + if (BYTES_BIG_ENDIAN && rsize > size) + t = build (PLUS_EXPR, TREE_TYPE (t), t, + build_int_2 (rsize - size, 0)); r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL); if (r != addr_rtx) emit_move_insn (addr_rtx, r); @@ -4285,12 +4302,12 @@ mips_va_arg (tree valist, tree type) /* [10, 11]. Emit code to store ovfl in addr_rtx, then post-increment ovfl by osize. On big-endian machines, - the argument has OSIZE - RSIZE bytes of leading padding. */ + the argument has OSIZE - SIZE bytes of leading padding. */ t = build (POSTINCREMENT_EXPR, TREE_TYPE (ovfl), ovfl, size_int (osize)); - if (BYTES_BIG_ENDIAN && osize > rsize) + if (BYTES_BIG_ENDIAN && osize > size) t = build (PLUS_EXPR, TREE_TYPE (t), t, - build_int_2 (osize - rsize, 0)); + build_int_2 (osize - size, 0)); r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL); if (r != addr_rtx) emit_move_insn (addr_rtx, r); @@ -4298,8 +4315,6 @@ mips_va_arg (tree valist, tree type) emit_queue(); emit_label (lab_over); } - if (BYTES_BIG_ENDIAN && rsize != size) - addr_rtx = plus_constant (addr_rtx, rsize - size); if (indirect) { addr_rtx = force_reg (Pmode, addr_rtx); -- 2.30.2